-
Notifications
You must be signed in to change notification settings - Fork 122
/
CompressEvents.cpp
132 lines (116 loc) · 5.94 KB
/
CompressEvents.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
// Mantid Repository : https://github.com/mantidproject/mantid
//
// Copyright © 2018 ISIS Rutherford Appleton Laboratory UKRI,
// NScD Oak Ridge National Laboratory, European Spallation Source,
// Institut Laue - Langevin & CSNS, Institute of High Energy Physics, CAS
// SPDX - License - Identifier: GPL - 3.0 +
#include "MantidDataHandling/CompressEvents.h"
#include "MantidAPI/Run.h"
#include "MantidDataObjects/EventWorkspace.h"
#include "MantidDataObjects/WorkspaceCreation.h"
#include "MantidKernel/ArrayProperty.h"
#include "MantidKernel/BoundedValidator.h"
#include "MantidKernel/DateAndTimeHelpers.h"
#include "MantidKernel/DateTimeValidator.h"
#include "tbb/parallel_for.h"
#include <numeric>
#include <set>
namespace Mantid::DataHandling {
// Register the algorithm into the algorithm factory
DECLARE_ALGORITHM(CompressEvents)
using namespace Kernel;
using namespace API;
using namespace DataObjects;
void CompressEvents::init() {
declareProperty(std::make_unique<WorkspaceProperty<EventWorkspace>>("InputWorkspace", "", Direction::Input),
"The name of the EventWorkspace on which to perform the algorithm");
declareProperty(std::make_unique<WorkspaceProperty<EventWorkspace>>("OutputWorkspace", "", Direction::Output),
"The name of the output EventWorkspace.");
// Tolerance must be >= 0.0
auto mustBePositive = std::make_shared<BoundedValidator<double>>();
mustBePositive->setLower(0.0);
declareProperty(std::make_unique<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.");
declareProperty(
std::make_unique<PropertyWithValue<double>>("WallClockTolerance", EMPTY_DBL(), mustBePositive, Direction::Input),
"The tolerance (in seconds) on the wall-clock time for comparison. Unset "
"means compressing all wall-clock times together disabling pulsetime "
"resolution.");
auto dateValidator = std::make_shared<DateTimeValidator>();
dateValidator->allowEmpty(true);
declareProperty("StartTime", "", dateValidator,
"An ISO formatted date/time string specifying the timestamp for "
"starting filtering. Ignored if WallClockTolerance is not specified. "
"Default is start of run",
Direction::Input);
}
void CompressEvents::exec() {
// Get the input workspace
EventWorkspace_sptr inputWS = getProperty("InputWorkspace");
EventWorkspace_sptr outputWS = getProperty("OutputWorkspace");
const double toleranceTof = getProperty("Tolerance");
const double toleranceWallClock = getProperty("WallClockTolerance");
const bool compressFat = !isEmpty(toleranceWallClock);
Types::Core::DateAndTime startTime;
if (compressFat) {
std::string startTimeProp = getProperty("StartTime");
if (startTimeProp.empty()) {
startTime = inputWS->run().startTime();
} else {
// the property returns ISO8601
startTime = DateAndTimeHelpers::createFromSanitizedISO8601(startTimeProp);
}
}
// Some starting things
bool inplace = (inputWS == outputWS);
const size_t noSpectra = 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. Compressing with wall clock does the sorting internally
if (!compressFat)
inputWS->sortAll(TOF_SORT, &prog);
// Are we making a copy of the input workspace?
if (!inplace) {
outputWS = create<EventWorkspace>(*inputWS, HistogramData::BinEdges(2));
// We DONT copy the data though
// Loop over the histograms (detector spectra)
tbb::parallel_for(tbb::blocked_range<size_t>(0, noSpectra),
[compressFat, toleranceTof, startTime, toleranceWallClock, &inputWS, &outputWS,
&prog](const tbb::blocked_range<size_t> &range) {
for (size_t index = range.begin(); index < range.end(); ++index) {
// The input event list
EventList &input_el = inputWS->getSpectrum(index);
// And on the output side
EventList &output_el = outputWS->getSpectrum(index);
// Copy other settings into output
output_el.setX(input_el.ptrX());
// The EventList method does the work.
if (compressFat)
input_el.compressFatEvents(toleranceTof, startTime, toleranceWallClock, &output_el);
else
input_el.compressEvents(toleranceTof, &output_el);
prog.report("Compressing");
}
});
} else { // inplace
tbb::parallel_for(tbb::blocked_range<size_t>(0, noSpectra),
[compressFat, toleranceTof, startTime, toleranceWallClock, &outputWS,
&prog](const tbb::blocked_range<size_t> &range) {
for (size_t index = range.begin(); index < range.end(); ++index) {
// The input (also output) event list
auto &output_el = outputWS->getSpectrum(index);
// The EventList method does the work.
if (compressFat)
output_el.compressFatEvents(toleranceTof, startTime, toleranceWallClock, &output_el);
else
output_el.compressEvents(toleranceTof, &output_el);
prog.report("Compressing");
}
});
}
// Cast to the matrixOutputWS and save it
this->setProperty("OutputWorkspace", outputWS);
}
} // namespace Mantid::DataHandling