Beispiel #1
0
/** Executes the algorithm
 *  @throw std::invalid_argument If the input workspaces do not meet the requirements of this algorithm
 */
void ConjoinWorkspaces::exec()
{
  // Retrieve the input workspaces
  MatrixWorkspace_const_sptr ws1 = getProperty("InputWorkspace1");
  MatrixWorkspace_const_sptr ws2 = getProperty("InputWorkspace2");
  event_ws1 = boost::dynamic_pointer_cast<const EventWorkspace>(ws1);
  event_ws2 = boost::dynamic_pointer_cast<const EventWorkspace>(ws2);

  //Make sure that we are not mis-matching EventWorkspaces and other types of workspaces
  if (((event_ws1) && (!event_ws2)) || ((!event_ws1) && (event_ws2)))
  {
    const std::string message("Only one of the input workspaces are of type EventWorkspace; please use matching workspace types (both EventWorkspace's or both Workspace2D's).");
    g_log.error(message);
    throw std::invalid_argument(message);
  }

  if (event_ws1 && event_ws2)
  {
    //Both are event workspaces. Use the special method
    this->execEvent();
    return;
  }

  // Check that the input workspaces meet the requirements for this algorithm
  this->validateInputs(ws1,ws2);

  // Create the output workspace
  const size_t totalHists = ws1->getNumberHistograms() + ws2->getNumberHistograms();
  MatrixWorkspace_sptr output = WorkspaceFactory::Instance().create("Workspace2D",totalHists,ws1->readX(0).size(),
                                                                             ws1->readY(0).size());
  // Copy over stuff from first input workspace
  WorkspaceFactory::Instance().initializeFromParent(ws1,output,true);

  // Create the X values inside a cow pointer - they will be shared in the output workspace
  cow_ptr<MantidVec> XValues;
  XValues.access() = ws1->readX(0);

  // Initialize the progress reporting object
  m_progress = new API::Progress(this, 0.0, 1.0, totalHists);

  // Loop over the input workspaces in turn copying the data into the output one
  const int64_t& nhist1 = ws1->getNumberHistograms();
  PARALLEL_FOR2(ws1, output)
  for (int64_t i = 0; i < nhist1; ++i)
  {
    PARALLEL_START_INTERUPT_REGION
    ISpectrum * outSpec = output->getSpectrum(i);
    const ISpectrum * inSpec = ws1->getSpectrum(i);

    // Copy X,Y,E
    outSpec->setX(XValues);
    outSpec->setData(inSpec->dataY(), inSpec->dataE());
    // Copy the spectrum number/detector IDs
    outSpec->copyInfoFrom(*inSpec);

    // Propagate masking, if needed
    if ( ws1->hasMaskedBins(i) )
    {
      const MatrixWorkspace::MaskList& inputMasks = ws1->maskedBins(i);
      MatrixWorkspace::MaskList::const_iterator it;
      for (it = inputMasks.begin(); it != inputMasks.end(); ++it)
      {
        output->flagMasked(i,(*it).first,(*it).second);
      }
    }    
    m_progress->report();
    PARALLEL_END_INTERUPT_REGION
  }
  PARALLEL_CHECK_INTERUPT_REGION


  //For second loop we use the offset from the first
  const int64_t& nhist2 = ws2->getNumberHistograms();

  PARALLEL_FOR2(ws2, output)
  for (int64_t j = 0; j < nhist2; ++j)
  {
    PARALLEL_START_INTERUPT_REGION
    // The spectrum in the output workspace
    ISpectrum * outSpec = output->getSpectrum(nhist1 + j);
    // Spectrum in the second workspace
    const ISpectrum * inSpec = ws2->getSpectrum(j);

    // Copy X,Y,E
    outSpec->setX(XValues);
    outSpec->setData(inSpec->dataY(), inSpec->dataE());
    // Copy the spectrum number/detector IDs
    outSpec->copyInfoFrom(*inSpec);

    // Propagate masking, if needed
    if ( ws2->hasMaskedBins(j) )
    {
      const MatrixWorkspace::MaskList& inputMasks = ws2->maskedBins(j);
      MatrixWorkspace::MaskList::const_iterator it;
      for (it = inputMasks.begin(); it != inputMasks.end(); ++it)
      {
        output->flagMasked(nhist1 + j,(*it).first,(*it).second);
      }
    }
    m_progress->report();
    PARALLEL_END_INTERUPT_REGION
  }
  PARALLEL_CHECK_INTERUPT_REGION

  this->fixSpectrumNumbers(ws1,ws2, output);

  // Delete the second input workspace from the ADS
  AnalysisDataService::Instance().remove(getPropertyValue("InputWorkspace2"));
  // Set the result workspace to the first input
  setProperty("InputWorkspace1",output);
}
Beispiel #2
0
/// Execute the algorithm in case of a histogrammed data.
void ExtractSpectra::execHistogram() {
  // Retrieve and validate the input properties
  this->checkProperties();

  // Create the output workspace
  MatrixWorkspace_sptr outputWorkspace = WorkspaceFactory::Instance().create(
      m_inputWorkspace, m_workspaceIndexList.size(), m_maxX - m_minX,
      m_maxX - m_minX - m_histogram);
  outputWorkspace->setIndexInfo(
      Indexing::extract(m_inputWorkspace->indexInfo(), m_workspaceIndexList));

  // If this is a Workspace2D, get the spectra axes for copying in the spectraNo
  // later
  Axis *inAxis1(nullptr);
  TextAxis *outTxtAxis(nullptr);
  NumericAxis *outNumAxis(nullptr);
  if (m_inputWorkspace->axes() > 1) {
    inAxis1 = m_inputWorkspace->getAxis(1);
    auto outAxis1 = outputWorkspace->getAxis(1);
    outTxtAxis = dynamic_cast<TextAxis *>(outAxis1);
    if (!outTxtAxis)
      outNumAxis = dynamic_cast<NumericAxis *>(outAxis1);
  }

  cow_ptr<HistogramData::HistogramX> newX(nullptr);
  if (m_commonBoundaries) {
    auto &oldX = m_inputWorkspace->x(m_workspaceIndexList.front());
    newX = make_cow<HistogramData::HistogramX>(oldX.begin() + m_minX,
                                               oldX.begin() + m_maxX);
  }

  bool doCrop = ((m_minX != 0) || (m_maxX != m_inputWorkspace->x(0).size()));

  Progress prog(this, 0.0, 1.0, (m_workspaceIndexList.size()));
  // Loop over the required workspace indices, copying in the desired bins
  for (int j = 0; j < static_cast<int>(m_workspaceIndexList.size()); ++j) {
    auto i = m_workspaceIndexList[j];

    bool hasDx = m_inputWorkspace->hasDx(i);

    // Preserve/restore sharing if X vectors are the same
    if (m_commonBoundaries) {
      outputWorkspace->setSharedX(j, newX);
      if (hasDx) {
        auto &oldDx = m_inputWorkspace->dx(i);
        outputWorkspace->setSharedDx(
            j,
            make_cow<HistogramData::HistogramDx>(
                oldDx.begin() + m_minX, oldDx.begin() + m_maxX - m_histogram));
      }
    } else {
      // Safe to just copy whole vector 'cos can't be cropping in X if not
      // common
      outputWorkspace->setSharedX(j, m_inputWorkspace->sharedX(i));
      outputWorkspace->setSharedDx(j, m_inputWorkspace->sharedDx(i));
    }

    if (doCrop) {
      auto &oldY = m_inputWorkspace->y(i);
      outputWorkspace->mutableY(j)
          .assign(oldY.begin() + m_minX, oldY.begin() + (m_maxX - m_histogram));
      auto &oldE = m_inputWorkspace->e(i);
      outputWorkspace->mutableE(j)
          .assign(oldE.begin() + m_minX, oldE.begin() + (m_maxX - m_histogram));
    } else {
      outputWorkspace->setSharedY(j, m_inputWorkspace->sharedY(i));
      outputWorkspace->setSharedE(j, m_inputWorkspace->sharedE(i));
    }

    // copy over the axis entry for each spectrum, regardless of the type of
    // axes present
    if (inAxis1) {
      if (outTxtAxis) {
        outTxtAxis->setLabel(j, inAxis1->label(i));
      } else if (outNumAxis) {
        outNumAxis->setValue(j, inAxis1->operator()(i));
      }
      // spectra axis is implicit in workspace creation
    }

    if (!m_commonBoundaries)
      this->cropRagged(outputWorkspace, static_cast<int>(i), j);

    // Propagate bin masking if there is any
    if (m_inputWorkspace->hasMaskedBins(i)) {
      const MatrixWorkspace::MaskList &inputMasks =
          m_inputWorkspace->maskedBins(i);
      MatrixWorkspace::MaskList::const_iterator it;
      for (it = inputMasks.begin(); it != inputMasks.end(); ++it) {
        const size_t maskIndex = (*it).first;
        if (maskIndex >= m_minX && maskIndex < m_maxX - m_histogram)
          outputWorkspace->flagMasked(j, maskIndex - m_minX, (*it).second);
      }
    }
    prog.report();
  }

  setProperty("OutputWorkspace", outputWorkspace);
}
/// Execute the algorithm in case of a histogrammed data.
void ExtractSpectra::execHistogram() {
  m_histogram = m_inputWorkspace->isHistogramData();
  // Check for common boundaries in input workspace
  m_commonBoundaries = WorkspaceHelpers::commonBoundaries(m_inputWorkspace);

  // Retrieve and validate the input properties
  this->checkProperties();

  // Create the output workspace
  MatrixWorkspace_sptr outputWorkspace = WorkspaceFactory::Instance().create(
      m_inputWorkspace, m_workspaceIndexList.size(), m_maxX - m_minX,
      m_maxX - m_minX - m_histogram);

  // If this is a Workspace2D, get the spectra axes for copying in the spectraNo
  // later
  Axis *inAxis1(nullptr);
  TextAxis *outTxtAxis(nullptr);
  NumericAxis *outNumAxis(nullptr);
  if (m_inputWorkspace->axes() > 1) {
    inAxis1 = m_inputWorkspace->getAxis(1);
    auto outAxis1 = outputWorkspace->getAxis(1);
    outTxtAxis = dynamic_cast<TextAxis *>(outAxis1);
    if (!outTxtAxis)
      outNumAxis = dynamic_cast<NumericAxis *>(outAxis1);
  }

  cow_ptr<MantidVec> newX;
  if (m_commonBoundaries) {
    const MantidVec &oldX =
        m_inputWorkspace->readX(m_workspaceIndexList.front());
    newX.access().assign(oldX.begin() + m_minX, oldX.begin() + m_maxX);
  }

  Progress prog(this, 0.0, 1.0, (m_workspaceIndexList.size()));
  // Loop over the required workspace indices, copying in the desired bins
  for (int j = 0; j < static_cast<int>(m_workspaceIndexList.size()); ++j) {
    auto i = m_workspaceIndexList[j];

    bool hasDx = m_inputWorkspace->hasDx(i);

    // Preserve/restore sharing if X vectors are the same
    if (m_commonBoundaries) {
      outputWorkspace->setX(j, newX);
      if (hasDx) {
        const MantidVec &oldDx = m_inputWorkspace->readDx(i);
        outputWorkspace->dataDx(j)
            .assign(oldDx.begin() + m_minX, oldDx.begin() + m_maxX);
      }
    } else {
      // Safe to just copy whole vector 'cos can't be cropping in X if not
      // common
      outputWorkspace->setX(j, m_inputWorkspace->refX(i));
      if (hasDx) {
        outputWorkspace->setDx(j, m_inputWorkspace->refDx(i));
      }
    }

    const MantidVec &oldY = m_inputWorkspace->readY(i);
    outputWorkspace->dataY(j)
        .assign(oldY.begin() + m_minX, oldY.begin() + (m_maxX - m_histogram));
    const MantidVec &oldE = m_inputWorkspace->readE(i);
    outputWorkspace->dataE(j)
        .assign(oldE.begin() + m_minX, oldE.begin() + (m_maxX - m_histogram));

    // copy over the axis entry for each spectrum, regardless of the type of
    // axes present
    if (inAxis1) {
      if (outTxtAxis) {
        outTxtAxis->setLabel(j, inAxis1->label(i));
      } else if (outNumAxis) {
        outNumAxis->setValue(j, inAxis1->operator()(i));
      }
      // spectra axis is handled by copyInfoFrom line
    }
    // Copy spectrum number & detectors
    outputWorkspace->getSpectrum(j)
        ->copyInfoFrom(*m_inputWorkspace->getSpectrum(i));

    if (!m_commonBoundaries)
      this->cropRagged(outputWorkspace, static_cast<int>(i), j);

    // Propagate bin masking if there is any
    if (m_inputWorkspace->hasMaskedBins(i)) {
      const MatrixWorkspace::MaskList &inputMasks =
          m_inputWorkspace->maskedBins(i);
      MatrixWorkspace::MaskList::const_iterator it;
      for (it = inputMasks.begin(); it != inputMasks.end(); ++it) {
        const size_t maskIndex = (*it).first;
        if (maskIndex >= m_minX && maskIndex < m_maxX - m_histogram)
          outputWorkspace->flagMasked(j, maskIndex - m_minX, (*it).second);
      }
    }
    prog.report();
  }

  setProperty("OutputWorkspace", outputWorkspace);
}