16#include <nexus/NeXusFile.hpp>
17#include <nexus/NeXusException.hpp>
38 const std::size_t
numEvents,
const bool oldNeXusFileNames,
41 : m_loader(loader), entry_name(
std::move(entry_name)), entry_type(
std::move(entry_type)), prog(prog),
42 scheduler(scheduler), m_loadError(false), m_oldNexusFileNames(oldNeXusFileNames), m_have_weight(false),
43 m_framePeriodNumbers(
std::move(framePeriodNumbers)) {
46 m_min_id = std::numeric_limits<uint32_t>::max();
56 file.openData(
"event_time_zero");
57 }
catch (::NeXus::Exception &) {
63 std::string thisStartTime;
64 size_t thispulseTimes = 0;
66 if (!file.hasAttr(
"offset")) {
67 thisStartTime =
"1970-01-01T00:00:00Z";
69 "event_time_zero, using UNIX epoch instead\n";
71 file.getAttr(
"offset", thisStartTime);
74 if (!file.getInfo().dims.empty())
75 thispulseTimes = file.getInfo().dims[0];
81 if (bankPulseTime->equals(thispulseTimes, thisStartTime)) {
102 auto event_index = Mantid::NeXus::NeXusIOHelper::readNexusVector<uint64_t>(file,
"event_index");
105 if (event_index.size() == 1) {
106 if (event_index[0] == 0) {
124 const std::vector<uint64_t> &event_index) {
127 file.openData(
"event_pixel_id");
129 file.openData(
"event_id");
132 start_event = event_index[0];
133 ::NeXus::Info id_info = file.getInfo();
149 if (stop_event > dim0)
162 ::NeXus::Info id_info = file.getInfo();
166 auto event_id = std::make_unique<std::vector<uint32_t>>(
m_loadSize[0]);
181 if (id_info.type == ::NeXus::UINT32)
185 <<
"Entry " <<
entry_name <<
"'s event_id field is not UINT32! It will be skipped.\n";
222 auto event_time_of_flight = std::make_unique<std::vector<float>>(
m_loadSize[0]);
225 std::string key, tof_unit;
227 key =
"event_time_offset";
229 key =
"event_time_of_flight";
233 ::NeXus::Info tof_info = file.getInfo();
237 <<
"'s event_time_offset field is too small "
238 "to load the desired data.\n";
247 auto vec = Mantid::NeXus::NeXusIOHelper::readNexusSlab<float, Mantid::NeXus::NeXusIOHelper::AllowNarrowing>(
249 file.getAttr(
"units", tof_unit);
253 std::copy(vec.begin(), vec.end(), event_time_of_flight->data());
255 return event_time_of_flight;
266 file.openData(
"event_weight");
267 }
catch (::NeXus::Exception &) {
270 return std::unique_ptr<std::vector<float>>();
276 auto event_weight = std::make_unique<std::vector<float>>(
m_loadSize[0]);
278 ::NeXus::Info weight_info = file.getInfo();
282 <<
"'s event_weight field is too small to load the desired data.\n";
287 if (weight_info.type == ::NeXus::FLOAT32)
291 <<
"'s event_weight field is not FLOAT32! It will be skipped.\n";
313 std::unique_ptr<std::vector<uint32_t>> event_id;
314 std::unique_ptr<std::vector<float>> event_time_of_flight;
315 std::unique_ptr<std::vector<float>> event_weight;
316 std::vector<uint64_t> event_index;
337 <<
" has a mismatch between the number of event_index entries "
338 "and the number of pulse times in event_time_zero.\n";
341 int64_t start_event = 0;
342 int64_t stop_event = 0;
359 event_time_of_flight = this->
loadTof(file);
368 <<
"Loading bank " <<
entry_name <<
" is stopped due to either zero/negative loading size ("
376 catch (std::exception &e) {
397 const auto emptyInt =
static_cast<uint32_t
>(
EMPTY_INT());
400 if (minSpectraToLoad != emptyInt &&
m_min_id < minSpectraToLoad) {
408 if (maxSpectraToLoad != emptyInt &&
m_max_id > maxSpectraToLoad) {
431 auto startAt =
static_cast<size_t>(
m_loadStart[0]);
434 std::shared_ptr<std::vector<uint32_t>> event_id_shrd(event_id.release());
435 std::shared_ptr<std::vector<float>> event_time_of_flight_shrd(event_time_of_flight.release());
436 std::shared_ptr<std::vector<float>> event_weight_shrd(event_weight.release());
437 auto event_index_shrd = std::make_shared<std::vector<uint64_t>>(std::move(event_index));
439 std::shared_ptr<Task> newTask1 = std::make_shared<ProcessBankData>(
444 std::shared_ptr<Task> newTask2 = std::make_shared<ProcessBankData>(
459 const int64_t shift = int64_t(1) << 32;
bool getCancel() const
Returns the cancellation state.
Kernel::Logger & getLogger() const
Returns a reference to the logger.
Helper class for reporting progress from algorithms.
Helper class for LoadEventNexus that is specific to the current default loading code for NXevent_data...
int32_t eventid_max
Maximum (inclusive) event ID possible for this instrument.
std::vector< std::shared_ptr< BankPulseTimes > > m_bankPulseTimes
One entry of pulse times for each preprocessor.
detid_t pixelID_to_wi_offset
Offset in the pixelID_to_wi_vector to use.
bool splitProcessing
whether or not to launch multiple ProcessBankData jobs per bank
size_t eventsPerChunk
number of chunks per bank
int firstChunkForBank
for multiple chunks per bank
bool m_haveWeights
Flag for dealing with a simulated file.
bool m_oldNexusFileNames
Old names in the file?
void run() override
Main method that performs the work for the task.
bool m_have_weight
Flag for simulated data.
int64_t recalculateDataSize(const int64_t &size)
Interpret the value describing the number of events.
uint32_t m_max_id
Maximum pixel ID in this data.
Kernel::ThreadScheduler & scheduler
ThreadScheduler running this task.
void loadPulseTimes(::NeXus::File &file)
Load the pulse times, if needed.
std::string entry_name
NXS path to bank.
std::vector< int64_t > m_loadSize
How much to load in the file.
uint32_t m_min_id
Minimum pixel ID in this data.
void prepareEventId(::NeXus::File &file, int64_t &start_event, int64_t &stop_event, const std::vector< uint64_t > &event_index)
Open the event_id field and validate the contents.
API::Progress * prog
Progress reporting.
std::vector< int64_t > m_loadStart
Index to load start at in the file.
LoadBankFromDiskTask(DefaultEventLoader &loader, std::string entry_name, std::string entry_type, const std::size_t numEvents, const bool oldNeXusFileNames, API::Progress *prog, std::shared_ptr< std::mutex > ioMutex, Kernel::ThreadScheduler &scheduler, std::vector< int > framePeriodNumbers)
Constructor.
const std::vector< int > m_framePeriodNumbers
Frame period numbers.
std::shared_ptr< BankPulseTimes > thisBankPulseTimes
Object with the pulse times for this bank.
DefaultEventLoader & m_loader
Algorithm being run.
std::unique_ptr< std::vector< float > > loadTof(::NeXus::File &file)
Open and load the times-of-flight data.
std::vector< uint64_t > loadEventIndex(::NeXus::File &file)
Load the event_index field (a list of size of # of pulses giving the index in the event list for that...
std::string entry_type
NXS type.
bool m_loadError
Did we get an error in loading.
std::unique_ptr< std::vector< uint32_t > > loadEventId(::NeXus::File &file)
Load the event_id field, which has been opened.
std::unique_ptr< std::vector< float > > loadEventWeights(::NeXus::File &file)
Load weight of weigthed events if they exist.
int32_t m_specMax
Maximum spectrum to load.
std::string m_filename
The name and path of the input file.
std::shared_ptr< BankPulseTimes > m_allBanksPulseTimes
Pulse times for ALL banks, taken from proton_charge log.
int32_t m_specMin
Minimum spectrum to load.
std::string m_top_entry_name
name of top level NXentry to use
void debug(const std::string &msg)
Logs at debug level.
void error(const std::string &msg)
Logs at error level.
void warning(const std::string &msg)
Logs at warning level.
void report()
Increments the loop counter by 1, then sends the progress notification on behalf of its algorithm.
double m_cost
Cached computational cost for the thread.
void setMutex(const std::shared_ptr< std::mutex > &mutex)
Set the mutex object for this Task.
The ThreadScheduler object defines how tasks are allocated to threads and in what order.
virtual void push(std::shared_ptr< Task > newTask)=0
Add a Task to the queue.
std::size_t numEvents(::NeXus::File &file, bool &hasTotalCounts, bool &oldNeXusFileNames, const std::string &prefix, const NexusHDF5Descriptor &descriptor)
Get the number of events in the currently opened group.
void timeConversionVector(std::vector< T > &vec, const std::string &input_unit, const std::string &output_unit)
constexpr int EMPTY_INT() noexcept
Returns what we consider an "empty" integer within a property.