Skip to content
Snippets Groups Projects
  • Janik Zikovsky's avatar
    0c5e87e9
    - Refs #3203: Implemented ISpectrum. It is the base class of EventList and... · 0c5e87e9
    Janik Zikovsky authored
    - Refs #3203: Implemented ISpectrum. It is the base class of EventList and Histogram and contains the spectrum number and list of detector IDs for a given spectrum.
    - ISpectrum return X/Y/E vectors. EventList, e.g. calculates the histogram on the fly.
    - Moved the EventWorkspace MRU list of histograms to be contained within the EventList; better code separation. Made a EventWorkspaceMRU class to encapsulate this more easily.
    - Workspaces must implement getSpectrum (const/not const) to return a ISpectrum object. dataX(i), etc. methods on MatrixWorkspaces no longer need to be overridden since they call getSpectrum()
    - Got rid of EventWorkspace::getEventListatPixelID() and doneLoadingData()
    - replaceSpectraMap() methods offers backwards-compatibility with SpectraDetectorMaps by setting the specNo and detector list when called. Must be called AFTER creating all the spectra in a workspace.
    - Refs #3318: maskWorkspaceIndex() implemented as part of ISpectrum.
    
    
    
    0c5e87e9
    History
    - Refs #3203: Implemented ISpectrum. It is the base class of EventList and...
    Janik Zikovsky authored
    - Refs #3203: Implemented ISpectrum. It is the base class of EventList and Histogram and contains the spectrum number and list of detector IDs for a given spectrum.
    - ISpectrum return X/Y/E vectors. EventList, e.g. calculates the histogram on the fly.
    - Moved the EventWorkspace MRU list of histograms to be contained within the EventList; better code separation. Made a EventWorkspaceMRU class to encapsulate this more easily.
    - Workspaces must implement getSpectrum (const/not const) to return a ISpectrum object. dataX(i), etc. methods on MatrixWorkspaces no longer need to be overridden since they call getSpectrum()
    - Got rid of EventWorkspace::getEventListatPixelID() and doneLoadingData()
    - replaceSpectraMap() methods offers backwards-compatibility with SpectraDetectorMaps by setting the specNo and detector list when called. Must be called AFTER creating all the spectra in a workspace.
    - Refs #3318: maskWorkspaceIndex() implemented as part of ISpectrum.
    
    
    
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
CompressEvents.cpp 4.51 KiB
//----------------------------------------------------------------------
// Includes
//----------------------------------------------------------------------
#include "MantidDataHandling/CompressEvents.h"
#include "MantidDataObjects/EventWorkspace.h"
#include "MantidAPI/WorkspaceValidators.h"
#include "MantidAPI/SpectraDetectorMap.h"
#include "MantidAPI/MemoryManager.h"
#include "MantidKernel/ArrayProperty.h"
#include "MantidKernel/BoundedValidator.h"
#include <set>
#include <numeric>

namespace Mantid
{
namespace DataHandling
{
// Register the algorithm into the algorithm factory
DECLARE_ALGORITHM(CompressEvents)

/// Sets documentation strings for this algorithm
void CompressEvents::initDocs()
{
  this->setWikiSummary("Reduce the number of events in an [[EventWorkspace]] by grouping together events with identical or similar X-values (time-of-flight). ");
  this->setOptionalMessage("Reduce the number of events in an EventWorkspace by grouping together events with identical or similar X-values (time-of-flight).");
}


using namespace Kernel;
using namespace API;
using namespace DataObjects;

/// (Empty) Constructor
CompressEvents::CompressEvents() {}

/// Destructor
CompressEvents::~CompressEvents() {}

void CompressEvents::init()
{
  declareProperty(new WorkspaceProperty<EventWorkspace>("InputWorkspace","",Direction::InOut),
    "The name of the EventWorkspace on which to perform the algorithm");

  declareProperty(new WorkspaceProperty<EventWorkspace>("OutputWorkspace","",Direction::Output),
    "The name of the output EventWorkspace.");

  // Tolerance must be >= 0.0
  BoundedValidator<double> *mustBePositive = new BoundedValidator<double> ();
  mustBePositive->setLower(0.0);
  declareProperty(  new PropertyWithValue<double>("Tolerance", 1e-5, mustBePositive, Direction::Input),
    "The tolerance on each event's X value (normally TOF, but may be a different unit if you have used ConvertUnits).\n"
    "Any events within Tolerance will be summed into a single event.");
}


void CompressEvents::exec()
{
  // Get the input workspace
  EventWorkspace_sptr inputWS = getProperty("InputWorkspace");
  EventWorkspace_sptr outputWS = getProperty("OutputWorkspace");
  double tolerance = getProperty("Tolerance");

  // Some starting things
  bool inplace = (getPropertyValue("InputWorkspace") == getPropertyValue("OutputWorkspace"));
  const int noSpectra = static_cast<int>(inputWS->getNumberHistograms());
  Progress prog(this,0.0,1.0, noSpectra*2);

  // Sort the input workspace in-place by TOF. This can be faster if there are few event lists.
  inputWS->sortAll(TOF_SORT, &prog);
  // Are we making a copy of the input workspace?
  if (!inplace)
  {
    //Make a brand new EventWorkspace
    outputWS = boost::dynamic_pointer_cast<EventWorkspace>(
        API::WorkspaceFactory::Instance().create("EventWorkspace", inputWS->getNumberHistograms(), 2, 1));
    //Copy geometry over.
    API::WorkspaceFactory::Instance().initializeFromParent(inputWS, outputWS, false);
    // We DONT copy the data though

    // Loop over the histograms (detector spectra)
    PARALLEL_FOR_NO_WSP_CHECK()
    for (int i = 0; i < noSpectra; ++i)
    {
      PARALLEL_START_INTERUPT_REGION
      //the loop variable i can't be signed because of OpenMp rules inforced in Linux. Using this signed type suppresses warnings below
      const size_t index = static_cast<size_t>(i);
      // The input event list
      EventList& input_el = inputWS->getEventList(index);
      // And on the output side
      EventList & output_el = outputWS->getOrAddEventList(index);
      // Copy other settings into output
      output_el.setX( input_el.ptrX() );

      // The EventList method does the work.
      input_el.compressEvents(tolerance, &output_el);

      prog.report("Compressing");
      PARALLEL_END_INTERUPT_REGION
    }
    PARALLEL_CHECK_INTERUPT_REGION

  }

  else
  {
    // ---- In-place -----
    // Loop over the histograms (detector spectra)
    PARALLEL_FOR_NO_WSP_CHECK()
    for (int64_t i = 0; i < noSpectra; ++i)
    {
      PARALLEL_START_INTERUPT_REGION
      // The input (also output) event list
      EventList * output_el =outputWS->getEventListPtr(static_cast<size_t>(i));
      if (output_el)
      {
        // The EventList method does the work.
        output_el->compressEvents(tolerance, output_el);
      }
      prog.report("Compressing");
      PARALLEL_END_INTERUPT_REGION
    }
    PARALLEL_CHECK_INTERUPT_REGION
  }

  //Cast to the matrixOutputWS and save it
  this->setProperty("OutputWorkspace", outputWS);



}

} // namespace DataHandling
} // namespace Mantid