14
14
#include " MantidAPI/WorkspaceFactory.h"
15
15
#include " MantidDataHandling/LoadEventNexus.h"
16
16
#include " MantidDataHandling/LoadEventNexusIndexSetup.h"
17
+ #include " MantidDataHandling/PulseIndexer.h"
17
18
#include " MantidDataObjects/Workspace2D.h"
18
19
#include " MantidKernel/ListValidator.h"
20
+ #include " MantidKernel/TimeROI.h"
19
21
#include " MantidKernel/TimeSeriesProperty.h"
20
22
#include " MantidKernel/UnitFactory.h"
21
23
#include " MantidNexus/NexusIOHelper.h"
22
-
23
24
#include < regex>
24
25
25
26
namespace Mantid {
@@ -32,6 +33,7 @@ using Mantid::Kernel::PropertyWithValue;
32
33
using Mantid::Kernel::StringListValidator;
33
34
using Mantid::Kernel::TimeSeriesProperty;
34
35
using Mantid::Kernel::UnitFactory;
36
+ // using Mantid::Kernel::TimeROI;
35
37
// Register the algorithm into the AlgorithmFactory
36
38
DECLARE_ALGORITHM (LoadEventAsWorkspace2D)
37
39
@@ -69,6 +71,14 @@ void LoadEventAsWorkspace2D::init() {
69
71
" of times-of-flight. "
70
72
" This is the maximum accepted value in microseconds. Keep "
71
73
" blank to load all events." );
74
+ declareProperty (
75
+ std::make_unique<PropertyWithValue<double >>(" FilterByTimeStart" , EMPTY_DBL (), Direction::Input),
76
+ " Optional: To only include events after the provided start "
77
+ " time, in seconds (relative to the start of the run). If left empty, it will take start time as default." );
78
+ declareProperty (std::make_unique<PropertyWithValue<double >>(" FilterByTimeStop" , EMPTY_DBL (), Direction::Input),
79
+ " Optional: To only include events before the provided stop "
80
+ " time, in seconds (relative to the start of the run). if left empty, it will take run end time or "
81
+ " last pulse time as default." );
72
82
declareProperty (std::make_unique<PropertyWithValue<std::vector<std::string>>>(
73
83
" LogAllowList" , std::vector<std::string>(), Direction::Input),
74
84
" If specified, only these logs will be loaded from the file (each "
@@ -123,6 +133,7 @@ std::map<std::string, std::string> LoadEventAsWorkspace2D::validateInputs() {
123
133
124
134
return results;
125
135
}
136
+
126
137
// ----------------------------------------------------------------------------------------------
127
138
/* * Execute the algorithm.
128
139
*/
@@ -200,6 +211,32 @@ void LoadEventAsWorkspace2D::exec() {
200
211
const double tof_max = getProperty (" FilterByTofMax" );
201
212
const bool tof_filtering = (tof_min != EMPTY_DBL () && tof_max != EMPTY_DBL ());
202
213
214
+ double filter_time_start_sec, filter_time_stop_sec;
215
+ filter_time_start_sec = getProperty (" FilterByTimeStart" );
216
+ filter_time_stop_sec = getProperty (" FilterByTimeStop" );
217
+
218
+ // get the start time
219
+ if (!WS->run ().hasProperty (" start_time" )) {
220
+ g_log.warning (" This NXS file does not have a start time, first pulse time is used instead." );
221
+ }
222
+
223
+ Types::Core::DateAndTime runstart (WS->run ().hasProperty (" start_time" ) ? WS->run ().getProperty (" start_time" )->value ()
224
+ : WS->run ().getFirstPulseTime ());
225
+
226
+ // get end time, to account for some older DAS issue where last pulse time can be slightly greater than end time, use
227
+ // last pulse time in this case and check if WS has "proton_charge" property otherwise last pulse time doesn't exist.
228
+ Types::Core::DateAndTime endtime;
229
+ if (WS->run ().hasProperty (" proton_charge" ) &&
230
+ WS->run ().getLastPulseTime () > WS->run ().getProperty (" end_time" )->value ()) {
231
+ endtime = WS->run ().getLastPulseTime ();
232
+ g_log.warning (" Last pulse time is used because the last pulse time is greater than the end time!" );
233
+ } else {
234
+ endtime = WS->run ().getProperty (" end_time" )->value ();
235
+ }
236
+
237
+ Types::Core::DateAndTime filter_time_start;
238
+ Types::Core::DateAndTime filter_time_stop;
239
+
203
240
// vector to stored to integrated counts by detector ID
204
241
std::vector<uint32_t > Y (max_detid - min_detid + 1 , 0 );
205
242
@@ -212,24 +249,19 @@ void LoadEventAsWorkspace2D::exec() {
212
249
const std::map<std::string, std::set<std::string>> &allEntries = descriptor.getAllEntries ();
213
250
214
251
prog->doReport (" Reading and integrating data" );
215
-
216
252
auto itClassEntries = allEntries.find (" NXevent_data" );
217
-
218
253
if (itClassEntries != allEntries.end ()) {
219
254
220
255
const std::set<std::string> &classEntries = itClassEntries->second ;
221
256
const std::regex classRegex (" (/entry/)([^/]*)" );
222
257
std::smatch groups;
223
-
224
258
for (const std::string &classEntry : classEntries) {
225
259
226
260
if (std::regex_match (classEntry, groups, classRegex)) {
227
261
const std::string entry_name (groups[2 ].str ());
228
-
229
262
// skip entries with junk data
230
263
if (entry_name == " bank_error_events" || entry_name == " bank_unmapped_events" )
231
264
continue ;
232
-
233
265
g_log.debug () << " Loading bank " << entry_name << ' \n ' ;
234
266
h5file.openGroup (entry_name, " NXevent_data" );
235
267
@@ -240,6 +272,39 @@ void LoadEventAsWorkspace2D::exec() {
240
272
else
241
273
event_ids = Mantid::NeXus::NeXusIOHelper::readNexusVector<uint32_t >(h5file, " event_pixel_id" );
242
274
275
+ // closeGroup and skip this bank if there is no event
276
+ if (event_ids.size () <= 1 ) {
277
+ h5file.closeGroup ();
278
+ continue ;
279
+ }
280
+
281
+ // Load "h5file" into BankPulseTimes using a shared ptr
282
+ const auto bankPulseTimes = std::make_shared<BankPulseTimes>(boost::ref (h5file), std::vector<int >());
283
+
284
+ // Get event_index from the "h5file"
285
+ const auto event_index = std::make_shared<std::vector<uint64_t >>(
286
+ Mantid::NeXus::NeXusIOHelper::readNexusVector<uint64_t >(h5file, " event_index" ));
287
+
288
+ // if "filterTimeStart" is empty, use run start time as default
289
+ if (filter_time_start_sec != EMPTY_DBL ()) {
290
+ filter_time_start = runstart + filter_time_start_sec;
291
+ } else {
292
+ filter_time_start = runstart;
293
+ }
294
+
295
+ // if "filterTimeStop" is empty, use end time as default
296
+ if (filter_time_stop_sec != EMPTY_DBL ()) {
297
+ filter_time_stop = runstart + filter_time_stop_sec;
298
+ } else {
299
+ filter_time_stop = endtime;
300
+ }
301
+
302
+ // Use filter_time_start time as starting reference in time and create a TimeROI using bankPulseTimes
303
+ const auto TimeROI = bankPulseTimes->getPulseIndices (filter_time_start, filter_time_stop);
304
+
305
+ // set up PulseIndexer and give previous TimeROI to pulseIndexer
306
+ const PulseIndexer pulseIndexer (event_index, event_index->at (0 ), event_ids.size (), entry_name, TimeROI);
307
+
243
308
std::vector<float > event_times;
244
309
if (tof_filtering) {
245
310
if (descriptor.isEntry (" /entry/" + entry_name + " /event_time_offset" , " SDS" ))
@@ -248,20 +313,24 @@ void LoadEventAsWorkspace2D::exec() {
248
313
event_times = Mantid::NeXus::NeXusIOHelper::readNexusVector<float >(h5file, " event_time_of_flight" );
249
314
}
250
315
251
- for (size_t i = 0 ; i < event_ids.size (); i++) {
252
- if (tof_filtering) {
253
- const auto tof = event_times[i];
254
- if (tof < tof_min || tof > tof_max)
316
+ // Nested loop to loop through all the relavent pulses and relavent event_ids.
317
+ // For someone new to this, every pulse creates an entry in event_index, event_index.size() = # of pulses,
318
+ // the value of event_index[i] points to the index of event_ids. In short, event_ids[event_index[i]] is the
319
+ // detector id from the i-th pulse. See NXevent_data description for more details.
320
+ for (const auto &pulse : pulseIndexer) {
321
+ for (size_t i = pulse.eventIndexStart ; i < pulse.eventIndexStop ; i++) {
322
+ // for (size_t i = 0; i < event_ids.size(); i++) {
323
+ if (tof_filtering) {
324
+ const auto tof = event_times[i];
325
+ if (tof < tof_min || tof > tof_max)
326
+ continue ;
327
+ }
328
+ const detid_t det_id = event_ids[i];
329
+ if (det_id < min_detid || det_id > max_detid)
255
330
continue ;
331
+ Y[det_id - min_detid]++;
256
332
}
257
-
258
- const detid_t det_id = event_ids[i];
259
- if (det_id < min_detid || det_id > max_detid)
260
- continue ;
261
-
262
- Y[det_id - min_detid]++;
263
333
}
264
-
265
334
h5file.closeGroup ();
266
335
}
267
336
}
0 commit comments