Mantid
Loading...
Searching...
No Matches
LoadEventAndCompress.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 +
16
18
19using std::size_t;
20using std::string;
21using namespace Kernel;
22using namespace API;
23using namespace DataObjects;
24
25// Register the algorithm into the AlgorithmFactory
26DECLARE_ALGORITHM(LoadEventAndCompress)
27
28//----------------------------------------------------------------------------------------------
29
30
31const string LoadEventAndCompress::name() const { return "LoadEventAndCompress"; }
32
34int LoadEventAndCompress::version() const { return 1; }
35
37const string LoadEventAndCompress::category() const { return "Workflow\\DataHandling"; }
38
40const string LoadEventAndCompress::summary() const { return "Load an event workspace by chunks and compress"; }
41
42//----------------------------------------------------------------------------------------------
46 // algorithms to copy properties from
47 auto algLoadEventNexus = AlgorithmManager::Instance().createUnmanaged("LoadEventNexus");
48 algLoadEventNexus->initialize();
49 auto algDetermineChunking = AlgorithmManager::Instance().createUnmanaged("DetermineChunking");
50 algDetermineChunking->initialize();
51
52 // declare properties
53 copyProperty(algLoadEventNexus, "Filename");
54 copyProperty(algLoadEventNexus, "OutputWorkspace");
55 copyProperty(algDetermineChunking, "MaxChunkSize");
56 declareProperty("CompressTOFTolerance", .01);
57
58 copyProperty(algLoadEventNexus, "FilterByTofMin");
59 copyProperty(algLoadEventNexus, "FilterByTofMax");
60 copyProperty(algLoadEventNexus, "FilterByTimeStart");
61 copyProperty(algLoadEventNexus, "FilterByTimeStop");
62
63 std::string grp1 = "Filter Events";
64 setPropertyGroup("FilterByTofMin", grp1);
65 setPropertyGroup("FilterByTofMax", grp1);
66 setPropertyGroup("FilterByTimeStart", grp1);
67 setPropertyGroup("FilterByTimeStop", grp1);
68
69 copyProperty(algLoadEventNexus, "NXentryName");
70 copyProperty(algLoadEventNexus, "LoadMonitors");
71 copyProperty(algLoadEventNexus, "MonitorsLoadOnly");
72 copyProperty(algLoadEventNexus, "FilterMonByTofMin");
73 copyProperty(algLoadEventNexus, "FilterMonByTofMax");
74 copyProperty(algLoadEventNexus, "FilterMonByTimeStart");
75 copyProperty(algLoadEventNexus, "FilterMonByTimeStop");
76
77 setPropertySettings("MonitorsLoadOnly", std::make_unique<VisibleWhenProperty>("LoadMonitors", IS_EQUAL_TO, "1"));
78 auto asEventsIsOn = [] {
79 std::unique_ptr<IPropertySettings> settings =
80 std::make_unique<VisibleWhenProperty>("MonitorsLoadOnly", IS_EQUAL_TO, "1");
81 return settings;
82 };
83 setPropertySettings("FilterMonByTofMin", asEventsIsOn());
84 setPropertySettings("FilterMonByTofMax", asEventsIsOn());
85 setPropertySettings("FilterMonByTimeStart", asEventsIsOn());
86 setPropertySettings("FilterMonByTimeStop", asEventsIsOn());
87
88 std::string grp4 = "Monitors";
89 setPropertyGroup("LoadMonitors", grp4);
90 setPropertyGroup("MonitorsLoadOnly", grp4);
91 setPropertyGroup("FilterMonByTofMin", grp4);
92 setPropertyGroup("FilterMonByTofMax", grp4);
93 setPropertyGroup("FilterMonByTimeStart", grp4);
94 setPropertyGroup("FilterMonByTimeStop", grp4);
95
96 auto range = std::make_shared<BoundedValidator<double>>();
97 range->setBounds(0., 100.);
98 declareProperty("FilterBadPulses", 95., range);
99}
100
103 double maxChunkSize = getProperty("MaxChunkSize");
104
105 auto alg = createChildAlgorithm("DetermineChunking");
106 alg->setProperty("Filename", filename);
107 alg->setProperty("MaxChunkSize", maxChunkSize);
108 alg->executeAsChildAlg();
109 ITableWorkspace_sptr chunkingTable = alg->getProperty("OutputWorkspace");
110
111 if (chunkingTable->rowCount() > 1)
112 g_log.information() << "Will load data in " << chunkingTable->rowCount() << " chunks\n";
113 else
114 g_log.information("Not chunking");
115
116 return chunkingTable;
117}
118
121 g_log.debug() << "loadChunk(" << rowIndex << ")\n";
122
123 auto rowCount = static_cast<double>(m_chunkingTable->rowCount());
124 double progStart = static_cast<double>(rowIndex) / rowCount;
125 double progStop = static_cast<double>(rowIndex + 1) / rowCount;
126
127 auto alg = createChildAlgorithm("LoadEventNexus", progStart, progStop, true);
128 alg->setProperty<string>("Filename", getProperty("Filename"));
129 alg->setProperty<double>("FilterByTofMin", getProperty("FilterByTofMin"));
130 alg->setProperty<double>("FilterByTofMax", getProperty("FilterByTofMax"));
131 alg->setProperty<double>("FilterByTimeStart", getProperty("FilterByTimeStart"));
132 alg->setProperty<double>("FilterByTimeStop", getProperty("FilterByTimeStop"));
133
134 alg->setProperty<string>("NXentryName", getProperty("NXentryName"));
135 alg->setProperty<bool>("LoadMonitors", getProperty("LoadMonitors"));
136 alg->setProperty<string>("MonitorsLoadOnly", getProperty("MonitorsLoadOnly"));
137 alg->setProperty<double>("FilterMonByTofMin", getProperty("FilterMonByTofMin"));
138 alg->setProperty<double>("FilterMonByTofMax", getProperty("FilterMonByTofMax"));
139 alg->setProperty<double>("FilterMonByTimeStart", getProperty("FilterMonByTimeStart"));
140 alg->setProperty<double>("FilterMonByTimeStop", getProperty("FilterMonByTimeStop"));
141
142 // determine if loading logs - always load logs for first chunk or
143 // `FilterBadPulses` which will change delete some of the proton_charge log
144 // and change its value
145 bool loadLogs = (rowIndex == 0) || (m_filterBadPulses > 0.);
146 if (!loadLogs) {
147 // logs are needed for any of these
148 const double filterByTimeStart = getProperty("FilterByTimeStart");
149 const double filterByTimeStop = getProperty("FilterByTimeStop");
150 const double filterMonByTimeStart = getProperty("FilterMonByTimeStart");
151 const double filterMonByTimeStop = getProperty("FilterMonByTimeStop");
152 loadLogs = (!isEmpty(filterByTimeStart)) || (!isEmpty(filterByTimeStop)) || (!isEmpty(filterMonByTimeStart)) ||
153 (!isEmpty(filterMonByTimeStop));
154 }
155 alg->setProperty<bool>("LoadLogs", loadLogs);
156
157 // set chunking information
158 if (rowCount > 0.) {
159 const std::vector<string> COL_NAMES = m_chunkingTable->getColumnNames();
160 for (const auto &name : COL_NAMES) {
161 alg->setProperty(name, m_chunkingTable->getRef<int>(name, rowIndex));
162 }
163 }
164
165 alg->executeAsChildAlg();
166 Workspace_sptr wksp = alg->getProperty("OutputWorkspace");
167 return std::dynamic_pointer_cast<MatrixWorkspace>(wksp);
168}
169
174 EventWorkspace_sptr eventWS = std::dynamic_pointer_cast<EventWorkspace>(wksp);
175
176 if (m_filterBadPulses > 0.) {
177 auto filterBadPulsesAlgo = createChildAlgorithm("FilterBadPulses");
178 filterBadPulsesAlgo->setProperty("InputWorkspace", eventWS);
179 filterBadPulsesAlgo->setProperty("OutputWorkspace", eventWS);
180 filterBadPulsesAlgo->setProperty("LowerCutoff", m_filterBadPulses);
181 filterBadPulsesAlgo->executeAsChildAlg();
182 eventWS = filterBadPulsesAlgo->getProperty("OutputWorkspace");
183 }
184
185 auto compressEvents = createChildAlgorithm("CompressEvents");
186 compressEvents->setProperty("InputWorkspace", eventWS);
187 compressEvents->setProperty("OutputWorkspace", eventWS);
188 compressEvents->setProperty<double>("Tolerance", getProperty("CompressTOFTolerance"));
189 compressEvents->executeAsChildAlg();
190 eventWS = compressEvents->getProperty("OutputWorkspace");
191
192 return eventWS;
193}
194
195//----------------------------------------------------------------------------------------------
199 const std::string filename = getPropertyValue("Filename");
200 m_filterBadPulses = getProperty("FilterBadPulses");
201
203
204 Progress progress(this, 0.0, 1.0, 2);
205
206 // first run is free
207 progress.report("Loading Chunk");
208 MatrixWorkspace_sptr resultWS = loadChunk(0);
209 progress.report("Process Chunk");
210 resultWS = processChunk(resultWS);
211
212 // load the other chunks
213 const size_t numRows = m_chunkingTable->rowCount();
214
215 progress.resetNumSteps(numRows, 0, 1);
216
217 for (size_t i = 1; i < numRows; ++i) {
219 temp = processChunk(temp);
220
221 // remove logs
222 auto removeLogsAlg = createChildAlgorithm("RemoveLogs");
223 removeLogsAlg->setProperty("Workspace", temp);
224 removeLogsAlg->executeAsChildAlg();
225 temp = removeLogsAlg->getProperty("Workspace");
226
227 // accumulate data
228 auto plusAlg = createChildAlgorithm("Plus");
229 plusAlg->setProperty("LHSWorkspace", resultWS);
230 plusAlg->setProperty("RHSWorkspace", temp);
231 plusAlg->setProperty("OutputWorkspace", resultWS);
232 plusAlg->setProperty("ClearRHSWorkspace", true);
233 plusAlg->executeAsChildAlg();
234 resultWS = plusAlg->getProperty("OutputWorkspace");
235
236 progress.report();
237 }
238 Workspace_sptr total = assemble(resultWS);
239
240 // don't assume that any chunk had the correct binning so just reset it here
241 EventWorkspace_sptr totalEventWS = std::dynamic_pointer_cast<EventWorkspace>(total);
242 if (totalEventWS->getNEvents())
243 totalEventWS->resetAllXToSingleBin();
244
245 // Don't bother compressing combined workspace. DetermineChunking is designed
246 // to prefer loading full banks so no further savings should be available.
247
248 setProperty("OutputWorkspace", total);
249}
250
251Parallel::ExecutionMode
252LoadEventAndCompress::getParallelExecutionMode(const std::map<std::string, Parallel::StorageMode> &storageModes) const {
253 static_cast<void>(storageModes);
254 return Parallel::ExecutionMode::Distributed;
255}
256
257} // namespace Mantid::WorkflowAlgorithms
#define DECLARE_ALGORITHM(classname)
Definition: Algorithm.h:576
Workspace_sptr assemble(Workspace_sptr partialWS)
Assemble the partial workspaces from all MPI processes.
std::shared_ptr< Algorithm > createChildAlgorithm(const std::string &name, const double startProgress=-1., const double endProgress=-1., const bool enableLogging=true, const int &version=-1) override
Create a Child Algorithm.
void copyProperty(const API::Algorithm_sptr &alg, const std::string &name)
Copy a property from an existing algorithm.
Kernel::IPropertyManager::TypedValue getProperty(const std::string &name) const override
Get the property held by this object.
std::string getPropertyValue(const std::string &name) const override
Get the property held by this object.
Helper class for reporting progress from algorithms.
Definition: Progress.h:25
void debug(const std::string &msg)
Logs at debug level.
Definition: Logger.cpp:114
void information(const std::string &msg)
Logs at information level.
Definition: Logger.cpp:105
void resetNumSteps(int64_t nsteps, double start, double end)
Change the number of steps between start/end.
void report()
Increments the loop counter by 1, then sends the progress notification on behalf of its algorithm.
Definition: ProgressBase.h:51
static T & Instance()
Return a reference to the Singleton instance, creating it if it does not already exist Creation is do...
LoadEventAndCompress : TODO: DESCRIPTION.
const std::string name() const override
Algorithms name for identification.
API::MatrixWorkspace_sptr loadChunk(const size_t rowIndex) override
void init() override
Initialize the algorithm's properties.
const std::string summary() const override
Algorithm's summary for use in the GUI and help.
API::ITableWorkspace_sptr determineChunk(const std::string &filename) override
Parallel::ExecutionMode getParallelExecutionMode(const std::map< std::string, Parallel::StorageMode > &storageModes) const override
int version() const override
Algorithm's version for identification.
API::MatrixWorkspace_sptr processChunk(API::MatrixWorkspace_sptr &wksp)
Process a chunk in-place.
const std::string category() const override
Algorithm's category for identification.
std::shared_ptr< ITableWorkspace > ITableWorkspace_sptr
shared pointer to Mantid::API::ITableWorkspace
std::shared_ptr< Workspace > Workspace_sptr
shared pointer to Mantid::API::Workspace
Definition: Workspace_fwd.h:20
Kernel::Logger g_log("ExperimentInfo")
static logger object
std::shared_ptr< MatrixWorkspace > MatrixWorkspace_sptr
shared pointer to the matrix workspace base class
std::shared_ptr< EventWorkspace > EventWorkspace_sptr
shared pointer to the EventWorkspace class