8#include "MantidNexus/NexusFile.h"
35 : startTime(DEFAULT_START_TIME), pulseTimes(times), have_period_info(false), m_sorting_info(PulseSorting::UNKNOWN) {
41 const std::vector<int> &periodNumbers)
42 : startTime(DEFAULT_START_TIME), periodNumbers(periodNumbers), pulseTimes(times), have_period_info(true),
43 m_sorting_info(PulseSorting::UNKNOWN) {
54 : startTime(DEFAULT_START_TIME), periodNumbers(periodNumbers), have_period_info(true),
55 m_sorting_info(PulseSorting::UNKNOWN) {
59 file.openData(
"event_time_zero");
60 }
catch (
const std::exception &) {
61 file.openData(
"pulse_time");
66 if (file.hasAttr(
"offset"))
69 Mantid::Types::Core::DateAndTime start(
startTime);
72 const auto dataInfo = file.getInfo();
73 const uint64_t numValues =
74 std::accumulate(dataInfo.dims.cbegin(), dataInfo.dims.cend(), uint64_t{1}, std::multiplies<>());
76 throw std::runtime_error(
"event_time_zero field has no data!");
78 const auto heldTimeZeroType = dataInfo.type;
83 this->readData<double>(file, numValues, start);
85 this->readData<uint64_t>(file, numValues, start);
87 throw std::invalid_argument(
"Unsupported type for event_time_zero");
94template <
typename ValueType>
97 Nexus::DimVector indexStep{std::min(numValues, std::size_t(12 * 3600 * 60))};
100 std::vector<ValueType> rawData(indexStep[0]);
103 while ((indexStep[0] > 0) && (indexStart[0] < numValues)) {
104 file.getSlab(rawData.data(), indexStart, indexStep);
107 std::transform(rawData.cbegin(), rawData.cend(), std::back_inserter(
pulseTimes),
108 [start](ValueType incremental_time) { return start + incremental_time; });
111 indexStart[0] += indexStep[0];
112 indexStep[0] = std::min(indexStep[0], numValues - indexStart[0]);
114 rawData.resize(indexStep[0]);
168std::size_t getFirstIncludedIndex(
const std::vector<Mantid::Types::Core::DateAndTime> &pulseTimes,
169 const std::size_t startIndex,
const Mantid::Types::Core::DateAndTime &start,
170 const Mantid::Types::Core::DateAndTime &stop) {
171 const auto NUM_PULSES{pulseTimes.size()};
172 if (startIndex >= NUM_PULSES)
175 for (
size_t i = startIndex; i < NUM_PULSES; ++i) {
176 const auto pulseTime = pulseTimes[i];
177 if (pulseTime >= start && pulseTime < stop)
183std::size_t getFirstExcludedIndex(
const std::vector<Mantid::Types::Core::DateAndTime> &pulseTimes,
184 const std::size_t startIndex,
const Mantid::Types::Core::DateAndTime &start,
185 const Mantid::Types::Core::DateAndTime &stop) {
186 const auto NUM_PULSES{pulseTimes.size()};
187 if (startIndex >= NUM_PULSES)
190 for (
size_t i = startIndex; i < NUM_PULSES; ++i) {
191 const auto pulseTime = pulseTimes[i];
192 if (pulseTime < start || pulseTime > stop)
201 const Mantid::Types::Core::DateAndTime &stop)
const {
202 std::vector<size_t> roi;
205 const bool includeStart = start <= this->pulseTimes.front();
206 const bool includeStop = stop >= this->pulseTimes.back();
207 if (!(includeStart && includeStop)) {
213 roi.push_back(getFirstIncludedIndex(this->pulseTimes, 0, start, stop));
217 roi.push_back(this->pulseTimes.size());
219 const auto start_index = roi.front();
221 for (
size_t index = this->pulseTimes.size() - 1;
index > start_index; --
index) {
223 roi.push_back(
index + 1);
231 const auto [min_ele, max_ele] = std::minmax_element(this->pulseTimes.cbegin(), this->pulseTimes.cend());
232 const bool includeStart = (start <= *min_ele);
233 const bool includeStop = (stop >= *max_ele);
236 if (!(includeStart && includeStop)) {
237 const auto NUM_PULSES = this->pulseTimes.size();
238 std::size_t firstInclude = getFirstIncludedIndex(this->pulseTimes, 0, start, stop);
239 while (firstInclude < NUM_PULSES) {
240 auto firstExclude = getFirstExcludedIndex(this->pulseTimes, firstInclude + 1, start, stop);
241 if (firstInclude != firstExclude) {
242 roi.push_back(firstInclude);
243 roi.push_back(firstExclude);
244 firstInclude = getFirstIncludedIndex(this->pulseTimes, firstExclude + 1, start, stop);
250 if ((!roi.empty()) && (roi.size() % 2 != 0)) {
251 std::stringstream msg;
252 msg <<
"Invalid state for ROI. Has odd number of values: " << roi.size();
253 throw std::runtime_error(msg.str());
260 std::vector<size_t> roi;
261 size_t start_index{0};
262 for (
const auto &splitter : splitters) {
264 roi.push_back(start_index =
265 getFirstIncludedIndex(this->pulseTimes, start_index, splitter.start(), splitter.stop()));
267 roi.push_back(start_index =
268 getFirstExcludedIndex(this->pulseTimes, start_index, splitter.start(), splitter.stop()) - 1);
284 return ((this->
startTime == otherStartTime) && (this->pulseTimes.size() == otherNumPulse));
std::map< DeltaEMode::Type, std::string > index
std::vector< size_t > getPulseIndices(const Mantid::Types::Core::DateAndTime &start, const Mantid::Types::Core::DateAndTime &stop) const
Return a vector of [include,exclude) indices into the pulse vectors that are between the start and st...
size_t numberOfPulses() const
The number of pulses being held.
void readData(Nexus::File &file, std::size_t numValues, Mantid::Types::Core::DateAndTime &start)
int periodNumber(const size_t index) const
The raw number from the period stored in the logs.
bool arePulseTimesIncreasing() const
Threadsafe method to access cached information about sorting.
std::string startTime
String describing the start time.
std::vector< Mantid::Types::Core::DateAndTime > pulseTimes
Array of the pulse times.
void updateStartTime()
This determines the start time by finding the minimum value in the array.
std::mutex m_sortingMutex
const Mantid::Types::Core::DateAndTime & pulseTime(const size_t index) const
The wall clock time of the pulse.
bool equals(size_t otherNumPulse, const std::string &otherStartTime)
Equals.
static const int FIRST_PERIOD
Starting number for assigning periods.
std::vector< int > periodNumbers
Vector of period numbers corresponding to each pulse.
BankPulseTimes(Nexus::File &file, const std::vector< int > &periodNumbers)
Constructor with Nexus::File.
static const std::string DEFAULT_START_TIME
Unix epoch used as default epoch when the file does not specify one.
void finalizePeriodNumbers()
Ensure that we always have a consistency between nPulses and periodNumbers containers.
static unsigned short constexpr UINT64
static unsigned short constexpr FLOAT64
std::vector< dimsize_t > DimVector