Mantid
Loading...
Searching...
No Matches
CompressEvents.cpp
Go to the documentation of this file.
1// Mantid Repository : https://github.com/mantidproject/mantid
2//
3// Copyright © 2018 ISIS Rutherford Appleton Laboratory UKRI,
4// NScD Oak Ridge National Laboratory, European Spallation Source,
5// Institut Laue - Langevin & CSNS, Institute of High Energy Physics, CAS
6// SPDX - License - Identifier: GPL - 3.0 +
8#include "MantidAPI/Run.h"
15
16#include "tbb/parallel_for.h"
17
18#include <numeric>
19#include <set>
20
21namespace Mantid::DataHandling {
22// Register the algorithm into the algorithm factory
23DECLARE_ALGORITHM(CompressEvents)
24
25using namespace Kernel;
26using namespace API;
27using namespace DataObjects;
28
30 declareProperty(std::make_unique<WorkspaceProperty<EventWorkspace>>("InputWorkspace", "", Direction::Input),
31 "The name of the EventWorkspace on which to perform the algorithm");
32
33 declareProperty(std::make_unique<WorkspaceProperty<EventWorkspace>>("OutputWorkspace", "", Direction::Output),
34 "The name of the output EventWorkspace.");
35
36 // Tolerance must be >= 0.0
37 auto mustBePositive = std::make_shared<BoundedValidator<double>>();
38 mustBePositive->setLower(0.0);
39 declareProperty(std::make_unique<PropertyWithValue<double>>("Tolerance", 1e-5, mustBePositive, Direction::Input),
40 "The tolerance on each event's X value (normally TOF, but may be a "
41 "different unit if you have used ConvertUnits).\n"
42 "Any events within Tolerance will be summed into a single event.");
43
45 std::make_unique<PropertyWithValue<double>>("WallClockTolerance", EMPTY_DBL(), mustBePositive, Direction::Input),
46 "The tolerance (in seconds) on the wall-clock time for comparison. Unset "
47 "means compressing all wall-clock times together disabling pulsetime "
48 "resolution.");
49
50 auto dateValidator = std::make_shared<DateTimeValidator>();
51 dateValidator->allowEmpty(true);
52 declareProperty("StartTime", "", dateValidator,
53 "An ISO formatted date/time string specifying the timestamp for "
54 "starting filtering. Ignored if WallClockTolerance is not specified. "
55 "Default is start of run",
57}
58
60 // Get the input workspace
61 EventWorkspace_sptr inputWS = getProperty("InputWorkspace");
62 EventWorkspace_sptr outputWS = getProperty("OutputWorkspace");
63 const double toleranceTof = getProperty("Tolerance");
64 const double toleranceWallClock = getProperty("WallClockTolerance");
65 const bool compressFat = !isEmpty(toleranceWallClock);
66 Types::Core::DateAndTime startTime;
67
68 if (compressFat) {
69 std::string startTimeProp = getProperty("StartTime");
70 if (startTimeProp.empty()) {
71 startTime = inputWS->run().startTime();
72 } else {
73 // the property returns ISO8601
74 startTime = DateAndTimeHelpers::createFromSanitizedISO8601(startTimeProp);
75 }
76 }
77
78 // Some starting things
79 bool inplace = (inputWS == outputWS);
80 const size_t noSpectra = inputWS->getNumberHistograms();
81 Progress prog(this, 0.0, 1.0, noSpectra * 2);
82
83 // Sort the input workspace in-place by TOF. This can be faster if there are
84 // few event lists. Compressing with wall clock does the sorting internally
85 if (!compressFat)
86 inputWS->sortAll(TOF_SORT, &prog);
87
88 // Are we making a copy of the input workspace?
89 if (!inplace) {
90 outputWS = create<EventWorkspace>(*inputWS, HistogramData::BinEdges(2));
91 // We DONT copy the data though
92 // Loop over the histograms (detector spectra)
93 tbb::parallel_for(tbb::blocked_range<size_t>(0, noSpectra),
94 [compressFat, toleranceTof, startTime, toleranceWallClock, &inputWS, &outputWS,
95 &prog](const tbb::blocked_range<size_t> &range) {
96 for (size_t index = range.begin(); index < range.end(); ++index) {
97 // The input event list
98 EventList &input_el = inputWS->getSpectrum(index);
99 // And on the output side
100 EventList &output_el = outputWS->getSpectrum(index);
101 // Copy other settings into output
102 output_el.setX(input_el.ptrX());
103 // The EventList method does the work.
104 if (compressFat)
105 input_el.compressFatEvents(toleranceTof, startTime, toleranceWallClock, &output_el);
106 else
107 input_el.compressEvents(toleranceTof, &output_el);
108 prog.report("Compressing");
109 }
110 });
111 } else { // inplace
112 tbb::parallel_for(tbb::blocked_range<size_t>(0, noSpectra),
113 [compressFat, toleranceTof, startTime, toleranceWallClock, &outputWS,
114 &prog](const tbb::blocked_range<size_t> &range) {
115 for (size_t index = range.begin(); index < range.end(); ++index) {
116 // The input (also output) event list
117 auto &output_el = outputWS->getSpectrum(index);
118 // The EventList method does the work.
119 if (compressFat)
120 output_el.compressFatEvents(toleranceTof, startTime, toleranceWallClock, &output_el);
121 else
122 output_el.compressEvents(toleranceTof, &output_el);
123 prog.report("Compressing");
124 }
125 });
126 }
127
128 // Cast to the matrixOutputWS and save it
129 this->setProperty("OutputWorkspace", outputWS);
130}
131
132} // namespace Mantid::DataHandling
#define DECLARE_ALGORITHM(classname)
Definition: Algorithm.h:576
std::map< DeltaEMode::Type, std::string > index
Definition: DeltaEMode.cpp:19
void declareProperty(std::unique_ptr< Kernel::Property > p, const std::string &doc="") override
Add a property to the list of managed properties.
Definition: Algorithm.cpp:1913
TypedValue getProperty(const std::string &name) const override
Get the value of a property.
Definition: Algorithm.cpp:2076
static bool isEmpty(const NumT toCheck)
checks that the value was not set by users, uses the value in empty double/int.
Helper class for reporting progress from algorithms.
Definition: Progress.h:25
A property class for workspaces.
void init() override
Virtual method - must be overridden by concrete algorithm.
void exec() override
Virtual method - must be overridden by concrete algorithm.
IPropertyManager * setProperty(const std::string &name, const T &value)
Templated method to set the value of a PropertyWithValue.
The concrete, templated class for properties.
std::shared_ptr< EventWorkspace > EventWorkspace_sptr
shared pointer to the EventWorkspace class
MANTID_KERNEL_DLL Types::Core::DateAndTime createFromSanitizedISO8601(const std::string &date)
Creates a DateAndTime object from a date string even if the string does not exactly conform to ISO860...
constexpr double EMPTY_DBL() noexcept
Returns what we consider an "empty" double within a property.
Definition: EmptyValues.h:43
@ Input
An input workspace.
Definition: Property.h:53
@ Output
An output workspace.
Definition: Property.h:54