Skip to content

Commit c94d1da

Browse files
Refactor code in preparation of having a loading task
1 parent 422bcb9 commit c94d1da

File tree

2 files changed

+137
-115
lines changed

2 files changed

+137
-115
lines changed

Framework/DataHandling/inc/MantidDataHandling/AlignAndFocusPowderSlim.h

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -44,11 +44,6 @@ class MANTID_DATAHANDLING_DLL AlignAndFocusPowderSlim : public API::Algorithm {
4444

4545
void initCalibrationConstants(API::MatrixWorkspace_sptr &wksp);
4646

47-
void loadTOF(std::unique_ptr<std::vector<float>> &data, ::NeXus::File &h5file);
48-
void loadDetid(std::unique_ptr<std::vector<uint32_t>> &data, ::NeXus::File &h5file);
49-
void loadPulseTimes(std::unique_ptr<std::vector<double>> &data, ::NeXus::File &h5file);
50-
void loadEventIndex(std::unique_ptr<std::vector<uint64_t>> &data, ::NeXus::File &h5file);
51-
5247
void loadCalFile(const Mantid::API::Workspace_sptr &inputWS, const std::string &filename);
5348

5449
std::map<detid_t, double> m_calibration; // detid: 1/difc

Framework/DataHandling/src/AlignAndFocusPowderSlim.cpp

Lines changed: 137 additions & 110 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,134 @@ const std::vector<std::string> AlignAndFocusPowderSlim::seeAlso() const { return
8383

8484
//----------------------------------------------------------------------------------------------
8585
namespace { // anonymous
86+
class NexusLoader {
87+
public:
88+
NexusLoader(const bool is_time_filtered, const size_t pulse_start_index, const size_t pulse_stop_index)
89+
: m_is_time_filtered(is_time_filtered), m_pulse_start_index(pulse_start_index),
90+
m_pulse_stop_index(pulse_stop_index) {}
91+
92+
static void loadPulseTimes(std::unique_ptr<std::vector<double>> &data, ::NeXus::File &h5file) {
93+
// /entry/DASlogs/frequency/time
94+
h5file.openGroup("DASlogs", "NXcollection");
95+
h5file.openGroup("frequency", "NXlog");
96+
h5file.openData("time");
97+
98+
// This is the data size
99+
::NeXus::Info id_info = h5file.getInfo();
100+
const auto dim0 = static_cast<size_t>(LoadBankFromDiskTask::recalculateDataSize(id_info.dims[0]));
101+
data->resize(dim0);
102+
103+
Mantid::NeXus::NeXusIOHelper::readNexusVector<double>(*data, h5file, "time");
104+
105+
// close the sds
106+
h5file.closeData();
107+
h5file.closeGroup();
108+
h5file.closeGroup();
109+
}
110+
111+
void loadTOF(std::unique_ptr<std::vector<float>> &data, ::NeXus::File &h5file,
112+
const std::pair<uint64_t, uint64_t> &eventRange) {
113+
// g_log.information(NxsFieldNames::TIME_OF_FLIGHT);
114+
h5file.openData(NxsFieldNames::TIME_OF_FLIGHT);
115+
116+
// This is the data size
117+
::NeXus::Info id_info = h5file.getInfo();
118+
const auto dim0 = static_cast<size_t>(LoadBankFromDiskTask::recalculateDataSize(id_info.dims[0]));
119+
120+
if (m_is_time_filtered) {
121+
// These are the arguments to getSlab()
122+
std::vector<int64_t> loadStart(1, eventRange.first);
123+
int64_t slabsize = (eventRange.second == std::numeric_limits<size_t>::max())
124+
? dim0 - eventRange.first
125+
: eventRange.second - eventRange.first;
126+
std::vector<int64_t> loadSize(1, slabsize);
127+
128+
data->resize(loadSize[0]);
129+
Mantid::NeXus::NeXusIOHelper::readNexusSlab<float, Mantid::NeXus::NeXusIOHelper::PreventNarrowing>(
130+
*data, h5file, NxsFieldNames::TIME_OF_FLIGHT, loadStart, loadSize);
131+
} else {
132+
data->resize(dim0);
133+
Mantid::NeXus::NeXusIOHelper::readNexusVector<float>(*data, h5file, NxsFieldNames::TIME_OF_FLIGHT);
134+
}
135+
136+
// get the units
137+
std::string tof_unit;
138+
h5file.getAttr("units", tof_unit);
139+
140+
// close the sds
141+
h5file.closeData();
142+
143+
// Convert Tof to microseconds
144+
if (tof_unit != MICROSEC)
145+
Kernel::Units::timeConversionVector(*data, tof_unit, MICROSEC);
146+
}
147+
148+
void loadDetid(std::unique_ptr<std::vector<uint32_t>> &data, ::NeXus::File &h5file,
149+
const std::pair<uint64_t, uint64_t> &eventRange) {
150+
// g_log.information(NxsFieldNames::DETID);
151+
h5file.openData(NxsFieldNames::DETID);
152+
153+
// This is the data size
154+
::NeXus::Info id_info = h5file.getInfo();
155+
const auto dim0 = static_cast<size_t>(LoadBankFromDiskTask::recalculateDataSize(id_info.dims[0]));
156+
157+
if (m_is_time_filtered) {
158+
// These are the arguments to getSlab()
159+
std::vector<int64_t> loadStart(1, eventRange.first);
160+
int64_t slabsize = (eventRange.second == std::numeric_limits<size_t>::max())
161+
? dim0 - eventRange.first
162+
: eventRange.second - eventRange.first;
163+
std::vector<int64_t> loadSize(1, slabsize);
164+
165+
data->resize(loadSize[0]);
166+
Mantid::NeXus::NeXusIOHelper::readNexusSlab<uint32_t, Mantid::NeXus::NeXusIOHelper::PreventNarrowing>(
167+
*data, h5file, NxsFieldNames::DETID, loadStart, loadSize);
168+
} else {
169+
data->resize(dim0);
170+
Mantid::NeXus::NeXusIOHelper::readNexusVector<uint32_t>(*data, h5file, NxsFieldNames::DETID);
171+
}
172+
173+
// close the sds
174+
h5file.closeData();
175+
}
176+
177+
private:
178+
void loadEventIndex(std::unique_ptr<std::vector<uint64_t>> &data, ::NeXus::File &h5file) {
179+
// g_log.information(NxsFieldNames::INDEX_ID);
180+
h5file.openData(NxsFieldNames::INDEX_ID);
181+
182+
// This is the data size
183+
::NeXus::Info id_info = h5file.getInfo();
184+
const auto dim0 = static_cast<size_t>(LoadBankFromDiskTask::recalculateDataSize(id_info.dims[0]));
185+
data->resize(dim0);
186+
187+
Mantid::NeXus::NeXusIOHelper::readNexusVector<uint64_t>(*data, h5file, NxsFieldNames::INDEX_ID);
188+
189+
// close the sds
190+
h5file.closeData();
191+
}
192+
193+
public:
194+
std::pair<uint64_t, uint64_t> getEventIndexRange(::NeXus::File &h5file) {
195+
uint64_t start_event = 0;
196+
uint64_t stop_event = std::numeric_limits<uint64_t>::max();
197+
if (m_is_time_filtered) {
198+
std::unique_ptr<std::vector<uint64_t>> event_index = std::make_unique<std::vector<uint64_t>>();
199+
this->loadEventIndex(event_index, h5file);
200+
201+
start_event = event_index->at(m_pulse_stop_index);
202+
if (m_pulse_stop_index != std::numeric_limits<size_t>::max())
203+
stop_event = event_index->at(m_pulse_stop_index);
204+
}
205+
return {start_event, stop_event};
206+
}
207+
208+
private:
209+
const bool m_is_time_filtered;
210+
const size_t m_pulse_start_index;
211+
const size_t m_pulse_stop_index;
212+
};
213+
86214
class Histogrammer {
87215
public:
88216
Histogrammer(const std::vector<double> *binedges, const double width, const bool linear_bins) : m_binedges(binedges) {
@@ -296,7 +424,7 @@ void AlignAndFocusPowderSlim::exec() {
296424
is_time_filtered = true;
297425
g_log.information() << "Filtering pulses from " << filter_time_start_sec << " to " << filter_time_stop_sec << "s\n";
298426
std::unique_ptr<std::vector<double>> pulse_times = std::make_unique<std::vector<double>>();
299-
loadPulseTimes(pulse_times, h5file);
427+
NexusLoader::loadPulseTimes(pulse_times, h5file);
300428
g_log.information() << "Pulse times from " << pulse_times->front() << " to " << pulse_times->back()
301429
<< " with length " << pulse_times->size() << '\n';
302430
if (!std::is_sorted(pulse_times->cbegin(), pulse_times->cend())) {
@@ -356,6 +484,8 @@ void AlignAndFocusPowderSlim::exec() {
356484
}
357485
}
358486

487+
NexusLoader loader(is_time_filtered, pulse_start_index, pulse_stop_index);
488+
359489
size_t specnum = 0;
360490
for (const std::string &entry_name : bankEntryNames) {
361491
std::cout << "ENTRY: " << entry_name << std::endl;
@@ -365,28 +495,20 @@ void AlignAndFocusPowderSlim::exec() {
365495
std::unique_ptr<std::vector<uint32_t>> event_detid = std::make_unique<std::vector<uint32_t>>();
366496
std::unique_ptr<std::vector<float>> event_time_of_flight = std::make_unique<std::vector<float>>();
367497
// TODO std::unique_ptr<std::vector<float>> event_weight; some other time
368-
std::unique_ptr<std::vector<uint64_t>> event_index = std::make_unique<std::vector<uint64_t>>();
369498
g_log.information() << "Loading bank " << entry_name << '\n';
370499
h5file.openGroup(entry_name, "NXevent_data");
371500

372-
if (is_time_filtered) {
373-
const auto startTime = std::chrono::high_resolution_clock::now();
374-
loadEventIndex(event_index, h5file);
375-
addTimer("loadEventIndex" + entry_name, startTime, std::chrono::high_resolution_clock::now());
376-
start_event = event_index->at(pulse_start_index);
377-
if (pulse_stop_index != std::numeric_limits<size_t>::max())
378-
stop_event = event_index->at(pulse_stop_index);
379-
g_log.debug() << "Loading events from " << start_event << " to " << stop_event << '\n';
380-
}
501+
// get filtering range
502+
const auto eventRange = loader.getEventIndexRange(h5file);
381503

382504
{
383505
const auto startTime = std::chrono::high_resolution_clock::now();
384-
loadTOF(event_time_of_flight, h5file);
506+
loader.loadTOF(event_time_of_flight, h5file, eventRange);
385507
addTimer("readTOF" + entry_name, startTime, std::chrono::high_resolution_clock::now());
386508
}
387509
{
388510
const auto startTime = std::chrono::high_resolution_clock::now();
389-
loadDetid(event_detid, h5file);
511+
loader.loadDetid(event_detid, h5file, eventRange);
390512
addTimer("readDetID" + entry_name, startTime, std::chrono::high_resolution_clock::now());
391513
}
392514

@@ -409,9 +531,10 @@ void AlignAndFocusPowderSlim::exec() {
409531
addTimer("setup" + entry_name, startTimeSetup, std::chrono::high_resolution_clock::now());
410532

411533
const auto startTimeProcess = std::chrono::high_resolution_clock::now();
534+
constexpr size_t GRAINSIZE_EVENT{2000};
412535
ProcessEventsTask task(&histogrammer, event_detid.get(), event_time_of_flight.get(), &calibration, &y_temp,
413536
&m_masked);
414-
tbb::parallel_for(tbb::blocked_range<size_t>(0, numEvent), task);
537+
tbb::parallel_for(tbb::blocked_range<size_t>(0, numEvent, GRAINSIZE_EVENT), task);
415538
auto &y_values = spectrum.dataY();
416539
std::copy(y_temp.cbegin(), y_temp.cend(), y_values.begin());
417540
addTimer("proc" + entry_name, startTimeProcess, std::chrono::high_resolution_clock::now());
@@ -442,102 +565,6 @@ void AlignAndFocusPowderSlim::initCalibrationConstants(API::MatrixWorkspace_sptr
442565
}
443566
}
444567

445-
void AlignAndFocusPowderSlim::loadTOF(std::unique_ptr<std::vector<float>> &data, ::NeXus::File &h5file) {
446-
g_log.information(NxsFieldNames::TIME_OF_FLIGHT);
447-
h5file.openData(NxsFieldNames::TIME_OF_FLIGHT);
448-
449-
// This is the data size
450-
::NeXus::Info id_info = h5file.getInfo();
451-
const auto dim0 = static_cast<size_t>(LoadBankFromDiskTask::recalculateDataSize(id_info.dims[0]));
452-
453-
if (is_time_filtered) {
454-
// These are the arguments to getSlab()
455-
loadStart[0] = start_event;
456-
if (stop_event == std::numeric_limits<size_t>::max())
457-
loadSize[0] = dim0 - start_event;
458-
else
459-
loadSize[0] = stop_event - start_event;
460-
data->resize(loadSize[0]);
461-
Mantid::NeXus::NeXusIOHelper::readNexusSlab<float, Mantid::NeXus::NeXusIOHelper::PreventNarrowing>(
462-
*data, h5file, NxsFieldNames::TIME_OF_FLIGHT, loadStart, loadSize);
463-
} else {
464-
data->resize(dim0);
465-
Mantid::NeXus::NeXusIOHelper::readNexusVector<float>(*data, h5file, NxsFieldNames::TIME_OF_FLIGHT);
466-
}
467-
468-
// get the units
469-
std::string tof_unit;
470-
h5file.getAttr("units", tof_unit);
471-
472-
// close the sds
473-
h5file.closeData();
474-
475-
// Convert Tof to microseconds
476-
if (tof_unit != MICROSEC)
477-
Kernel::Units::timeConversionVector(*data, tof_unit, MICROSEC);
478-
}
479-
480-
void AlignAndFocusPowderSlim::loadDetid(std::unique_ptr<std::vector<uint32_t>> &data, ::NeXus::File &h5file) {
481-
g_log.information(NxsFieldNames::DETID);
482-
h5file.openData(NxsFieldNames::DETID);
483-
484-
// This is the data size
485-
::NeXus::Info id_info = h5file.getInfo();
486-
const auto dim0 = static_cast<size_t>(LoadBankFromDiskTask::recalculateDataSize(id_info.dims[0]));
487-
488-
if (is_time_filtered) {
489-
// These are the arguments to getSlab()
490-
loadStart[0] = start_event;
491-
if (stop_event == std::numeric_limits<size_t>::max())
492-
loadSize[0] = dim0 - start_event;
493-
else
494-
loadSize[0] = stop_event - start_event;
495-
data->resize(loadSize[0]);
496-
Mantid::NeXus::NeXusIOHelper::readNexusSlab<uint32_t, Mantid::NeXus::NeXusIOHelper::PreventNarrowing>(
497-
*data, h5file, NxsFieldNames::DETID, loadStart, loadSize);
498-
} else {
499-
data->resize(dim0);
500-
Mantid::NeXus::NeXusIOHelper::readNexusVector<uint32_t>(*data, h5file, NxsFieldNames::DETID);
501-
}
502-
503-
// close the sds
504-
h5file.closeData();
505-
}
506-
507-
void AlignAndFocusPowderSlim::loadPulseTimes(std::unique_ptr<std::vector<double>> &data, ::NeXus::File &h5file) {
508-
// /entry/DASlogs/frequency/time
509-
h5file.openGroup("DASlogs", "NXcollection");
510-
h5file.openGroup("frequency", "NXlog");
511-
h5file.openData("time");
512-
513-
// This is the data size
514-
::NeXus::Info id_info = h5file.getInfo();
515-
const auto dim0 = static_cast<size_t>(LoadBankFromDiskTask::recalculateDataSize(id_info.dims[0]));
516-
data->resize(dim0);
517-
518-
Mantid::NeXus::NeXusIOHelper::readNexusVector<double>(*data, h5file, "time");
519-
520-
// close the sds
521-
h5file.closeData();
522-
h5file.closeGroup();
523-
h5file.closeGroup();
524-
}
525-
526-
void AlignAndFocusPowderSlim::loadEventIndex(std::unique_ptr<std::vector<uint64_t>> &data, ::NeXus::File &h5file) {
527-
g_log.information(NxsFieldNames::INDEX_ID);
528-
h5file.openData(NxsFieldNames::INDEX_ID);
529-
530-
// This is the data size
531-
::NeXus::Info id_info = h5file.getInfo();
532-
const auto dim0 = static_cast<size_t>(LoadBankFromDiskTask::recalculateDataSize(id_info.dims[0]));
533-
data->resize(dim0);
534-
535-
Mantid::NeXus::NeXusIOHelper::readNexusVector<uint64_t>(*data, h5file, NxsFieldNames::INDEX_ID);
536-
537-
// close the sds
538-
h5file.closeData();
539-
}
540-
541568
void AlignAndFocusPowderSlim::loadCalFile(const Mantid::API::Workspace_sptr &inputWS, const std::string &filename) {
542569
auto alg = createChildAlgorithm("LoadDiffCal");
543570
alg->setProperty("InputWorkspace", inputWS);

0 commit comments

Comments
 (0)