Skip to content
Snippets Groups Projects
CreateFlatEventWorkspace.cpp 5.76 KiB
Newer Older
#include "MantidAlgorithms/CreateFlatEventWorkspace.h"

#include "MantidDataObjects/EventWorkspace.h"

using namespace Mantid::API;
using namespace Mantid::DataObjects;

namespace Mantid {
namespace Algorithms {

// Register the algorithm into the AlgorithmFactory
DECLARE_ALGORITHM(CreateFlatEventWorkspace)

//----------------------------------------------------------------------------------------------
/// Algorithm's name for identification. @see Algorithm::name
const std::string CreateFlatEventWorkspace::name() const {
  return "CreateFlatEventWorkspace";

/// Algorithm's version for identification. @see Algorithm::version
int CreateFlatEventWorkspace::version() const { return 1; }

/// Algorithm's category for identification. @see Algorithm::category
const std::string CreateFlatEventWorkspace::category() const {
  return "CorrectionFunctions\\BackgroundCorrections";
}

//----------------------------------------------------------------------------------------------

//----------------------------------------------------------------------------------------------
/** Initialize the algorithm's properties.
 */
void CreateFlatEventWorkspace::init() {
  this->declareProperty(
      Kernel::make_unique<Mantid::API::WorkspaceProperty<EventWorkspace>>(
          "InputWorkspace", "", Mantid::Kernel::Direction::Input),
      "An input event workspace to use as a source for the events.");

  this->declareProperty("RangeStart", EMPTY_DBL(),
                        "Set the lower bound for sampling the background.");
  this->declareProperty("RangeEnd", EMPTY_DBL(),
                        "Set the upper bound for sampling the background.");

  this->declareProperty(
      Kernel::make_unique<Mantid::API::WorkspaceProperty<>>(
          "OutputWorkspace", "", Mantid::Kernel::Direction::Output),
      "Output event workspace containing a flat background.");
}

//----------------------------------------------------------------------------------------------
/** Execute the algorithm.
 */
void CreateFlatEventWorkspace::exec() {
  // Get the workspaces
  EventWorkspace_sptr inputWS = getProperty("InputWorkspace");
  MatrixWorkspace_sptr outputWS;

  // Get the background region start/end
  double start = getProperty("RangeStart");
  double end = getProperty("RangeEnd");

  double sampleRange = end - start;
  g_log.debug() << "Total Range = " << sampleRange << '\n';

  // What are the min/max values for the experimental data ?
  double dataMin, dataMax;
  inputWS->getEventXMinMax(dataMin, dataMax);

Hahn, Steven's avatar
Hahn, Steven committed
  g_log.debug() << "Data Range (" << dataMin << " < x < " << dataMax << ")\n";

  // How many times do we need to replicate the extracted background region in
  // order to fill up
  // the entire tof/x range covered by the data ?
  int nRegions = static_cast<int>((dataMax - dataMin) / sampleRange);

  g_log.debug() << "We will need to replicate the selected region " << nRegions
                << " times.\n";

  // Extract the region we are using for the background
  IAlgorithm_sptr crop_alg = this->createChildAlgorithm("CropWorkspace");
  crop_alg->setProperty("InputWorkspace", inputWS);
  crop_alg->setProperty("XMin", start);
  crop_alg->setProperty("XMax", end);
  crop_alg->setPropertyValue("OutputWorkspace", "__extracted_chunk");
  crop_alg->execute();
  MatrixWorkspace_sptr chunkws = crop_alg->getProperty("OutputWorkspace");

  // Now lets shift the region to the start of the data.
  IAlgorithm_sptr shift_alg = this->createChildAlgorithm("ChangeBinOffset");
  shift_alg->setProperty("InputWorkspace", chunkws);
  // shift_alg->setPropertyValue("OutputWorkspace", outputWsName);
  shift_alg->setProperty("Offset", -(start - dataMin));
  shift_alg->executeAsChildAlg();
  outputWS = shift_alg->getProperty("OutputWorkspace");

  IAlgorithm_sptr clone = this->createChildAlgorithm("CloneWorkspace");
  clone->setProperty("InputWorkspace", outputWS);
  clone->setPropertyValue("OutputWorkspace", "__background_chunk");
  clone->executeAsChildAlg();
  Workspace_sptr tmp = clone->getProperty("OutputWorkspace");
  MatrixWorkspace_sptr tmpChunkWs =
      boost::dynamic_pointer_cast<MatrixWorkspace>(tmp);

  Progress progress(this, 0.0, 1.0, nRegions);
  for (int i = 0; i < nRegions; ++i) {

    IAlgorithm_sptr shiftchunk = this->createChildAlgorithm("ChangeBinOffset");
    shiftchunk->setProperty("InputWorkspace", tmpChunkWs);
    shiftchunk->setProperty("OutputWorkspace", tmpChunkWs);
    shiftchunk->setProperty("Offset", sampleRange);
    shiftchunk->executeAsChildAlg();
    tmpChunkWs = shiftchunk->getProperty("OutputWorkspace");

    // Now add this chunk onto the output
    IAlgorithm_sptr plus_alg = this->createChildAlgorithm("Plus");
    plus_alg->setProperty("LHSWorkspace", outputWS);
    plus_alg->setProperty("RHSWorkspace", tmpChunkWs);
    plus_alg->setProperty("OutputWorkspace", outputWS);
    plus_alg->executeAsChildAlg();
    outputWS = plus_alg->getProperty("OutputWorkspace");
    tmpChunkWs = plus_alg->getProperty("RHSWorkspace");
    progress.report();
  // Crop the output workspace to be the same range as the input data
  IAlgorithm_sptr finalcrop_alg = this->createChildAlgorithm("CropWorkspace");
  finalcrop_alg->setProperty("InputWorkspace", outputWS);
  finalcrop_alg->setProperty("XMin", dataMin);
  finalcrop_alg->setProperty("XMax", dataMax);
  finalcrop_alg->execute();
  outputWS = finalcrop_alg->getProperty("OutputWorkspace");

  EventWorkspace_sptr outputEWS =
      boost::dynamic_pointer_cast<EventWorkspace>(outputWS);
  outputEWS->clearMRU();

  // Need to reset the matrixworkspace/histogram representation to be the
  // whole xrange (rather than just the extracted chunk).
  outputEWS->getEventXMinMax(dataMin, dataMax);
  outputEWS->setAllX(HistogramData::BinEdges{dataMin, dataMax});

  this->setProperty("OutputWorkspace", outputWS);
}

} // namespace Algorithms
} // namespace Mantid