Example #1
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);
}