Mantid
Loading...
Searching...
No Matches
LoadANSTOHelper.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 +
15
16#include <boost/filesystem.hpp>
17
18#include <algorithm>
19#include <numeric>
20
22
23// Extract datasets from the group that match a regex filter
24std::vector<std::string> filterDatasets(const Nexus::NXEntry &entry, const std::string &groupAddress,
25 const std::string &regexFilter) {
26 std::vector<std::string> fvalues;
27 auto group = entry.openNXGroup(groupAddress);
28 auto datasets = group.datasets();
29 for (auto nxi : datasets) {
30 if (std::regex_match(nxi.nxname, std::regex(regexFilter))) {
31 fvalues.emplace_back(nxi.nxname);
32 }
33 }
34
35 return fvalues;
36}
37
38// ProgressTracker
39ProgressTracker::ProgressTracker(API::Progress &progBar, const char *msg, int64_t target, size_t count)
40 : m_msg(msg), m_count(count), m_step(target / count), m_next(m_step), m_progBar(progBar) {
41
43}
46 while (m_next <= position) {
48
49 switch (m_count) {
50 case 0:
51 return;
52
53 case 1:
54 m_count = 0;
55 m_next = std::numeric_limits<int64_t>::max();
56 return;
57
58 default:
59 m_count--;
60 m_next += m_step;
61 }
62 }
63}
65 if (m_count != 0) {
67 m_count = 0;
68 }
69}
70
71void ProgressTracker::setTarget(int64_t target) {
72 if (m_count == 0) {
73 m_step = target;
74 m_next = m_step;
75 return;
76 }
77 m_step = std::max<int64_t>(1, target / m_count);
78 m_next = m_step;
79}
80
81// EventProcessor
82EventProcessor::EventProcessor(const std::vector<bool> &roi, const size_t stride, const double period,
83 const double phase, const int64_t startTime, const double tofMinBoundary,
84 const double tofMaxBoundary, const double timeMinBoundary, const double timeMaxBoundary)
85 : m_roi(roi), m_stride(stride), m_frames(0), m_framesValid(0), m_startTime(startTime), m_period(period),
86 m_phase(phase), m_tofMinBoundary(tofMinBoundary), m_tofMaxBoundary(tofMaxBoundary),
87 m_timeMinBoundary(timeMinBoundary), m_timeMaxBoundary(timeMaxBoundary) {}
89 // frame boundary
90 double frameTime = (static_cast<double>(m_frames) * m_period) * 1e-6; // in seconds
91
92 return (frameTime >= m_timeMinBoundary) && (frameTime <= m_timeMaxBoundary);
93}
95 m_frames++;
96 if (validFrame())
98}
99void EventProcessor::addEvent(size_t x, size_t y, double tof) {
100 // tof correction
101 if (m_period > 0.0) {
102 tof += m_phase;
103 while (tof > m_period)
104 tof -= m_period;
105 while (tof < 0)
106 tof += m_period;
107 }
108
109 // check if event is in valid range
110 if (!validFrame())
111 return;
112
113 // ToF boundary
114 if ((tof < m_tofMinBoundary) || (tof > m_tofMaxBoundary))
115 return;
116
117 // detector id
118 size_t id = m_stride * x + y;
119
120 // image size
121 if ((y >= m_stride) || (id >= m_roi.size()))
122 return;
123
124 // check if neutron is in region of intreset
125 if (m_roi[id]) {
126 // absolute pulse time in nanoseconds
127 auto frames = static_cast<double>(m_frames);
128 auto frameTime = static_cast<int64_t>(m_period * frames * 1.0e3);
129 int64_t pulse = m_startTime + frameTime;
130
131 addEventImpl(id, pulse, tof);
132 }
133}
134
135// EventCounter
136EventCounter::EventCounter(const std::vector<bool> &roi, const size_t stride, const double period, const double phase,
137 const int64_t startTime, const double tofMinBoundary, const double tofMaxBoundary,
138 const double timeMinBoundary, const double timeMaxBoundary, std::vector<size_t> &eventCounts)
139 : EventProcessor(roi, stride, period, phase, startTime, tofMinBoundary, tofMaxBoundary, timeMinBoundary,
140 timeMaxBoundary),
141 m_eventCounts(eventCounts), m_tofMin(std::numeric_limits<double>::max()),
142 m_tofMax(std::numeric_limits<double>::min()) {}
143size_t EventCounter::numFrames() const { return m_framesValid; }
144double EventCounter::tofMin() const { return m_tofMin <= m_tofMax ? m_tofMin : 0.0; }
145double EventCounter::tofMax() const { return m_tofMin <= m_tofMax ? m_tofMax : 0.0; }
146void EventCounter::addEventImpl(size_t id, int64_t pulse, double tof) {
147 UNUSED_ARG(pulse);
148 if (m_tofMin > tof)
149 m_tofMin = tof;
150 if (m_tofMax < tof)
151 m_tofMax = tof;
152
153 m_eventCounts[id]++;
154}
155
156// EventAssigner
157EventAssigner::EventAssigner(const std::vector<bool> &roi, const size_t stride, const double period, const double phase,
158 const int64_t startTime, const double tofMinBoundary, const double tofMaxBoundary,
159 const double timeMinBoundary, const double timeMaxBoundary,
160 std::vector<EventVector_pt> &eventVectors)
161 : EventProcessor(roi, stride, period, phase, startTime, tofMinBoundary, tofMaxBoundary, timeMinBoundary,
162 timeMaxBoundary),
163 m_eventVectors(eventVectors) {}
164void EventAssigner::addEventImpl(size_t id, int64_t pulse, double tof) {
165 m_eventVectors[id]->emplace_back(tof, Types::Core::DateAndTime(pulse));
166}
167
168// EventAssignerFixedWavelength
169EventAssignerFixedWavelength::EventAssignerFixedWavelength(const std::vector<bool> &roi, const size_t stride,
170 const double wavelength, const double period,
171 const double phase, const int64_t startTime,
172 const double tofMinBoundary, const double tofMaxBoundary,
173 const double timeMinBoundary, const double timeMaxBoundary,
174 std::vector<EventVector_pt> &eventVectors)
175 : EventAssigner(roi, stride, period, phase, startTime, tofMinBoundary, tofMaxBoundary, timeMinBoundary,
176 timeMaxBoundary, eventVectors),
177 m_wavelength(wavelength) {}
178void EventAssignerFixedWavelength::addEventImpl(size_t id, int64_t pulse, double /*tof*/) {
179 m_eventVectors[id]->emplace_back(m_wavelength, Types::Core::DateAndTime(pulse));
180}
181
182// ISISRawOnlyFile
183#ifdef _WIN32
184FastReadOnlyFile::FastReadOnlyFile(const char *filename) {
185 m_handle = CreateFileA(filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
186}
188void *FastReadOnlyFile::handle() const { return m_handle; }
190 CloseHandle(m_handle);
191 m_handle = NULL;
192}
193bool FastReadOnlyFile::read(void *buffer, uint32_t size) {
194 DWORD bytesRead;
195 return (FALSE != ReadFile(m_handle, buffer, size, &bytesRead, NULL)) && (bytesRead == size);
196}
197bool FastReadOnlyFile::seek(int64_t offset, int whence, int64_t *newPosition) {
198 return FALSE != SetFilePointerEx(m_handle, *(LARGE_INTEGER *)&offset, (LARGE_INTEGER *)newPosition, whence);
199}
200#else
201FastReadOnlyFile::FastReadOnlyFile(const char *filename) { m_handle = fopen(filename, "rb"); }
203void *FastReadOnlyFile::handle() const { return m_handle; }
205 fclose(m_handle);
206 m_handle = nullptr;
207}
208bool FastReadOnlyFile::read(void *buffer, uint32_t size) {
209 return 1 == fread(buffer, static_cast<size_t>(size), 1, m_handle);
210}
211bool FastReadOnlyFile::seek(int64_t offset, int whence, int64_t *newPosition) {
212 return (0 == fseek(m_handle, offset, whence)) &&
213 ((newPosition == nullptr) || (0 <= (*newPosition = static_cast<int64_t>(ftell(m_handle)))));
214}
215#endif
216
217namespace Tar {
218
220 memset(Checksum, ' ', sizeof(Checksum));
221 size_t value = std::accumulate(reinterpret_cast<const char *>(this),
222 reinterpret_cast<const char *>(this) + sizeof(EntryHeader), static_cast<size_t>(0));
223
224 std::ostringstream buffer;
225
226 buffer << std::oct << std::setfill('0') << std::setw(static_cast<int>(sizeof(Checksum)) - 1) << value;
227 std::string string = buffer.str();
228
229 std::copy(string.cbegin(), string.cend(), Checksum);
230 Checksum[string.size()] = 0;
231}
233 std::ostringstream buffer;
234
235 buffer << std::oct << std::setfill('0') << std::setw(static_cast<int>(sizeof(FileSize)) - 1) << value;
236 std::string string = buffer.str();
237
238 std::copy(string.cbegin(), string.cend(), FileSize);
239 FileSize[string.size()] = 0;
240}
242 int64_t result = 0;
243 const char *p = FileSize;
244 for (size_t n = sizeof(FileSize) - 1; n != 0; --n) { // last character is '\0'
245 char c = *p++;
246 if (('0' <= c) && (c <= '9'))
247 result = result * 8 + (c - '0');
248 }
249 return result;
250}
251
252// construction
253File::File(const std::string &path)
254 : m_good(true), m_file(path.c_str()), m_selected(static_cast<size_t>(-1)), m_position(0), m_size(0),
255 m_bufferPosition(0), m_bufferAvailable(0) {
256
257 m_good = m_file.handle() != nullptr;
258 while (m_good) {
259 EntryHeader header;
260 int64_t position;
261
262 m_good &= m_file.read(&header, sizeof(EntryHeader));
263 m_good &= m_file.seek(512 - sizeof(EntryHeader), SEEK_CUR, &position);
264 if (!m_good)
265 break;
266
267 std::string fileName(header.FileName);
268 if (fileName.length() == 0)
269 return;
270
271 FileInfo fileInfo;
272 fileInfo.Offset = position;
273 fileInfo.Size = header.readFileSize();
274
275 if (header.TypeFlag == TarTypeFlag_NormalFile) {
276 m_fileNames.emplace_back(fileName);
277 m_fileInfos.emplace_back(fileInfo);
278 }
279
280 auto offset = static_cast<size_t>(fileInfo.Size % 512);
281 if (offset != 0)
282 offset = 512 - offset;
283
284 m_good &= m_file.seek(fileInfo.Size + offset, SEEK_CUR);
285 }
286}
288 m_good = false;
289 m_file.close();
290 m_fileNames.clear();
291 m_fileInfos.clear();
292 m_selected = static_cast<size_t>(-1);
293 m_position = 0;
294 m_size = 0;
297}
298
299// properties
300bool File::good() const { return m_good; }
301const std::vector<std::string> &File::files() const { return m_fileNames; }
302const std::string &File::selected_name() const { return m_fileNames[m_selected]; }
303int64_t File::selected_position() const { return m_position; }
304int64_t File::selected_size() const { return m_size; }
305
306// methods
307bool File::select(const char *file) {
308 if (!m_good)
309 return false;
310
311 // reset buffer
314
315 auto it = std::find(m_fileNames.cbegin(), m_fileNames.cend(), file);
316 if (it != m_fileNames.cend()) {
317 size_t i = std::distance(m_fileNames.cbegin(), it);
318 const FileInfo &info = m_fileInfos[i];
319
320 m_selected = i;
321 m_position = 0;
322 m_size = info.Size;
323
324 return m_good &= m_file.seek(info.Offset, SEEK_SET);
325 }
326
327 m_selected = static_cast<size_t>(-1);
328 m_position = 0;
329 m_size = 0;
330 return false;
331}
332bool File::skip(uint64_t offset) {
333 if (!m_good || (m_selected == static_cast<size_t>(-1)))
334 return false;
335
336 bool overrun = offset > static_cast<uint64_t>(m_size - m_position);
337 if (overrun)
338 offset = m_size - m_position;
339
340 m_position += offset;
341
342 uint64_t bufferPosition = static_cast<uint64_t>(m_bufferPosition) + offset;
343 if (bufferPosition <= m_bufferAvailable)
344 m_bufferPosition = static_cast<size_t>(bufferPosition);
345 else {
346 m_good &= m_file.seek(bufferPosition - m_bufferAvailable, SEEK_CUR);
347
350 }
351
352 return m_good && !overrun;
353}
354size_t File::read(void *dst, size_t size) {
355 if (!m_good || (m_selected == static_cast<size_t>(-1)))
356 return 0;
357
358 if (static_cast<int64_t>(size) > (m_size - m_position))
359 size = static_cast<size_t>(m_size - m_position);
360
361 auto ptr = reinterpret_cast<uint8_t *>(dst);
362 size_t result = 0;
363
366 if (result > size)
367 result = size;
368
369 memcpy(ptr, m_buffer, result);
370 ptr += result;
371
372 size -= result;
373 m_position += result;
374 m_bufferPosition += result;
375 }
376
377 while (size != 0) {
378 auto bytesToRead = static_cast<uint32_t>(std::min<size_t>(size, std::numeric_limits<uint32_t>::max()));
379
380 m_good &= m_file.read(ptr, bytesToRead);
381 if (!m_good)
382 break;
383
384 ptr += bytesToRead;
385
386 size -= bytesToRead;
387 result += bytesToRead;
388 m_position += bytesToRead;
389 }
390
391 return result;
392}
394 if (!m_good || (m_selected == static_cast<size_t>(-1)))
395 return -1;
396
398 if (m_position >= m_size)
399 return -1;
400
403
404 uint32_t size = static_cast<uint32_t>(std::min<int64_t>(sizeof(m_buffer), m_size - m_position));
405 m_good &= m_file.read(m_buffer, size);
406
407 if (m_good)
408 m_bufferAvailable = size;
409 else
410 return -1;
411 }
412
413 m_position++;
414 return m_buffer[m_bufferPosition++];
415}
416bool File::append(const std::string &path, const std::string &name, const void *buffer, size_t size) {
417 std::unique_ptr<FILE, decltype(&fclose)> handle(fopen(path.c_str(), "rb+"), fclose);
418
419 if (handle == nullptr)
420 return false;
421
422 int64_t lastHeaderPosition = 0;
423 int64_t targetPosition = -1;
424
425 bool fileStatus = true;
426 while (fileStatus) {
427 EntryHeader header;
428 int64_t position;
429
430 lastHeaderPosition = static_cast<int64_t>(ftell(handle.get()));
431
432 fileStatus &= 1 == fread(&header, sizeof(EntryHeader), 1, handle.get());
433 fileStatus &= 0 == fseek(handle.get(), 512 - sizeof(EntryHeader), SEEK_CUR);
434 fileStatus &= 0 <= (position = static_cast<int64_t>(ftell(handle.get())));
435
436 if (!fileStatus)
437 return false;
438
439 std::string fileName(header.FileName);
440 if (fileName.length() == 0)
441 break;
442
443 if (fileName == name)
444 targetPosition = lastHeaderPosition;
445 else if (targetPosition != -1)
446 throw std::runtime_error("format exception"); // it has to be the last file in the archive
447
448 auto fileSize = header.readFileSize();
449
450 auto offset = static_cast<size_t>(fileSize % 512);
451 if (offset != 0)
452 offset = 512 - offset;
453
454 fileStatus &= 0 == fseek(handle.get(), static_cast<long>(fileSize + offset), SEEK_CUR);
455 }
456
457 if (targetPosition < 0)
458 targetPosition = lastHeaderPosition;
459
460 // empty buffer
461 char padding[512];
462 memset(padding, 0, 512);
463
464 // prepare new header
465 EntryHeader header;
466 memset(&header, 0, sizeof(EntryHeader));
467 memcpy(header.FileName, name.c_str(), name.size());
468 memset(header.FileMode, '0', sizeof(header.FileMode) - 1);
469 memset(header.OwnerUserID, '0', sizeof(header.OwnerUserID) - 1);
470 memset(header.OwnerGroupID, '0', sizeof(header.OwnerGroupID) - 1);
471 memset(header.LastModification, '0', sizeof(header.LastModification) - 1);
472
473 header.TypeFlag = TarTypeFlag_NormalFile;
474 header.writeFileSize(size);
475 header.writeChecksum();
476
477 // write header
478 fileStatus &= 0 == fseek(handle.get(), static_cast<long>(targetPosition), SEEK_SET);
479 fileStatus &= 1 == fwrite(&header, sizeof(EntryHeader), 1, handle.get());
480 fileStatus &= 1 == fwrite(padding, 512 - sizeof(EntryHeader), 1, handle.get());
481
482 // write content
483 fileStatus &= 1 == fwrite(buffer, size, 1, handle.get());
484
485 // write padding
486 auto offset = static_cast<size_t>(size % 512);
487 if (offset != 0) {
488 offset = 512 - offset;
489
490 fileStatus &= 1 == fwrite(padding, offset, 1, handle.get());
491 }
492
493 // write final
494 fileStatus &= 1 == fwrite(padding, 512, 1, handle.get());
495
496 return fileStatus;
497}
498
499} // namespace Tar
500
501namespace Anxs {
502
503int64_t epochRelDateTimeBase(int64_t epochInNanoSeconds) {
504 auto retval = epochInNanoSeconds - static_cast<int64_t>(Types::Core::DateAndTime::EPOCH_DIFF) * 1'000'000'000;
505 return retval;
506}
507
508std::string extractWorkspaceTitle(const std::string &nxsFile) {
509 namespace fs = boost::filesystem;
510 fs::path p = nxsFile;
511 for (; !p.extension().empty();)
512 p = p.stem();
513 return p.generic_string();
514}
515
516// load nx dataset
517template <class T> bool loadNXDataSet(const Nexus::NXEntry &entry, const std::string &path, T &value, int index) {
518 try {
519 Nexus::NXDataSetTyped<T> dataSet = entry.openNXDataSet<T>(path);
520 dataSet.load();
521
522 // if negative index go from the end
523 if (index < 0) {
524 auto N = dataSet.dim0();
525 value = dataSet[N + index];
526 } else {
527 value = dataSet[index];
528 }
529 return true;
530 } catch (std::runtime_error &) {
531 return false;
532 }
533}
534
535bool loadNXString(const Nexus::NXEntry &entry, const std::string &path, std::string &value) {
536 try {
537 Nexus::NXChar dataSet = entry.openNXChar(path);
538 dataSet.load();
539
540 value = std::string(dataSet(), dataSet.dim0());
541 return true;
542 } catch (std::runtime_error &) {
543 return false;
544 }
545}
546
547bool isTimedDataSet(const Nexus::NXEntry &entry, const std::string &path) {
548 auto newEntry = entry.openNXGroup(path);
549 auto datasets = newEntry.datasets();
550 auto valid = (datasets.size() == 2 && newEntry.containsDataSet("time") && newEntry.containsDataSet("value"));
551 return valid;
552}
553
554// Extract the start and end time in nsecs from the nexus file
555// based on entry/scan_dataset/[time, value]
556//
557// The time is the start time value is duration in nsec for each dataset
558//
559std::pair<uint64_t, uint64_t> getTimeScanLimits(const Nexus::NXEntry &entry, int datasetIx) {
560
561 auto timestamp = entry.openNXDataSet<uint64_t>("scan_dataset/time");
562 timestamp.load();
563 auto offset = entry.openNXDataSet<int64_t>("scan_dataset/value");
564 offset.load();
565 try {
566 auto start = timestamp[datasetIx];
567 auto end = start + offset[datasetIx];
568 return {start, end};
569 } catch (std::runtime_error &) {
570 return {0, 0};
571 }
572}
573
574// Extract the start and end time in nsecs from the nexus file
575// based on entry/scan_dataset/[time, value]
576//
577// The time is the start time value is duration in nsec for each dataset
578//
579std::pair<uint64_t, uint64_t> getHMScanLimits(const Nexus::NXEntry &entry, int datasetIx) {
580
581 auto timestamp = entry.openNXDataSet<uint64_t>("hmscan/time");
582 timestamp.load();
583 auto offset = entry.openNXDataSet<int64_t>("hmscan/value");
584 offset.load();
585 try {
586 auto start = timestamp[datasetIx];
587 auto end = start + offset[datasetIx];
588 return {start, end};
589 } catch (std::runtime_error &) {
590 return {0, 0};
591 }
592}
593
594// Extract the relevant timestamped data. Get the timestamp first to
595// determine the index limits (it assumed the timestamp is ordered).
596// Then extract the value from that range.
597// The start index is the first entry where the timestamp is less than
598// or equal to to the start time. The start index may occur before the
599// startT time but it is the parameter value at the start time as all
600// subsequenet values occur after the start time. This logic is needed
601// as the recorded value is only captured on the change in value an if
602// the value did not change in the window there would no logged value
603// in the period.
604
605template <typename T>
606uint64_t extractTimedDataSet(const Nexus::NXEntry &entry, const std::string &path, uint64_t startTime, uint64_t endTime,
607 std::vector<uint64_t> &times, std::vector<T> &events, std::string &units) {
608
609 auto timeStamp = entry.openNXDataSet<uint64_t>(path + "/time");
610 timeStamp.load();
611 size_t maxn = timeStamp.size();
612 uint64_t startIx{0}, endIx{0};
613 auto itt = timeStamp();
614 for (size_t i = 0; i < maxn; i++) {
615 auto v = itt[i];
616 if (v <= startTime)
617 startIx = i;
618 if (v < endTime)
619 endIx = i + 1;
620 }
621 times.assign(itt + startIx, itt + endIx);
622
623 auto values = entry.openNXDataSet<T>(path + "/value");
624 units = values.attributes("units");
625 values.load();
626 auto itv = values();
627 events.assign(itv + startIx, itv + endIx);
628
629 return endIx - startIx;
630}
631
632template <typename T>
633bool extractTimedDataSet(const Nexus::NXEntry &entry, const std::string &path, uint64_t startTime, uint64_t endTime,
634 ScanLog valueOption, uint64_t &eventTime, T &eventValue, std::string &units) {
635 eventTime = 0;
636 eventValue = 0;
637 std::vector<uint64_t> times;
638 std::vector<T> values;
639 auto n = extractTimedDataSet<T>(entry, path, startTime, endTime, times, values, units);
640 if (n == 0)
641 return false;
642
643 bool retn = true;
644 switch (valueOption) {
645 case ScanLog::Mean:
646 eventValue = std::accumulate(values.cbegin(), values.cend(), T{0}) / static_cast<T>(n);
647 eventTime = std::accumulate(times.cbegin(), times.cend(), uint64_t{0}) / n;
648 break;
649 case ScanLog::Start:
650 eventValue = values[0];
651 eventTime = times[0];
652 break;
653 case ScanLog::End:
654 eventValue = values[n - 1];
655 eventTime = times[n - 1];
656 break;
657 default:
658 retn = false;
659 }
660 return retn;
661}
662
663void ReadEventData(ProgressTracker &prog, const Nexus::NXEntry &entry, EventProcessor *handler, uint64_t start_nsec,
664 uint64_t end_nsec, const std::string &neutron_path, int tube_resolution) {
665
666 // the detector event time zero is the actual chopper time and all the events are
667 // relative to this base
668
669 // Get the event index, base values and values but check if there is data available
670 auto eventID = entry.openNXDataSet<uint32_t>(neutron_path + "/event_id");
671 if (eventID.dim0() == 0)
672 return;
673 eventID.load();
674 auto eventIndex = entry.openNXDataSet<uint32_t>(neutron_path + "/event_time_zero_index");
675 eventIndex.load();
676 auto zeroOffset = entry.openNXDataSet<uint64_t>(neutron_path + "/event_time_zero");
677 zeroOffset.load();
678 auto offsetValues = entry.openNXDataSet<uint32_t>(neutron_path + "/event_time_offset");
679 offsetValues.load();
680 uint32_t numPulses = static_cast<uint32_t>(eventIndex.size());
681 uint32_t totalEvents = static_cast<uint32_t>(offsetValues.size());
682
683 prog.setTarget(numPulses);
684
685 // The chopper times are monotonically increasing but there may be duplicate
686 // pulse times when a 'efu' buffer is full mid pulse. In this case the buffer
687 // is sent but the next buffer uses the same pulse time. Only send the frame
688 // event when it changes.
689
690 uint64_t lastFrameTS{0};
691
692 // Run through the data and forward the event data if the pulse time occurs between
693 // start and end time. To be clear the start and end time relates to the pulse times.
694 for (uint32_t ix = 0; ix < numPulses; ix++) {
695 auto pulseTime = zeroOffset[ix];
696 if (start_nsec <= pulseTime && pulseTime < end_nsec) {
697 if (pulseTime > lastFrameTS) {
698 handler->newFrame();
699 lastFrameTS = pulseTime;
700 }
701 auto baseIndex = eventIndex[ix];
702 auto lastIndex = (ix + 1 < numPulses ? eventIndex[ix + 1] : totalEvents);
703 for (uint32_t j = baseIndex; j < lastIndex; j++) {
704 // convert tof to microseconds as double and pixel as (x,y)
705 // and send to handler
706 double tof = offsetValues[j] * 1.0e-3;
707 auto pixel = eventID[j];
708 size_t y = pixel % tube_resolution;
709 size_t x = (pixel - y) / tube_resolution;
710 handler->addEvent(x, y, tof);
711 }
712 }
713 prog.update(ix);
714 }
715}
716
717// template instantiation
718template bool loadNXDataSet<float>(const Nexus::NXEntry &entry, const std::string &path, float &value, int index);
719template bool loadNXDataSet<double>(const Nexus::NXEntry &entry, const std::string &path, double &value, int index);
720template bool loadNXDataSet<int>(const Nexus::NXEntry &entry, const std::string &path, int &value, int index);
721template bool loadNXDataSet<uint64_t>(const Nexus::NXEntry &entry, const std::string &path, uint64_t &value, int index);
722template bool loadNXDataSet<int64_t>(const Nexus::NXEntry &entry, const std::string &path, int64_t &value, int index);
723template uint64_t extractTimedDataSet<float>(const Nexus::NXEntry &entry, const std::string &path, uint64_t startTime,
724 uint64_t endTime, std::vector<uint64_t> &times, std::vector<float> &events,
725 std::string &units);
726template uint64_t extractTimedDataSet<double>(const Nexus::NXEntry &entry, const std::string &path, uint64_t startTime,
727 uint64_t endTime, std::vector<uint64_t> &times,
728 std::vector<double> &events, std::string &units);
729
730template bool extractTimedDataSet<float>(const Nexus::NXEntry &entry, const std::string &path, uint64_t startTime,
731 uint64_t endTime, ScanLog valueOption, uint64_t &eventTime, float &eventValue,
732 std::string &units);
733template bool extractTimedDataSet<double>(const Nexus::NXEntry &entry, const std::string &path, uint64_t startTime,
734 uint64_t endTime, ScanLog valueOption, uint64_t &eventTime,
735 double &eventValue, std::string &units);
736
737} // namespace Anxs
738
739} // namespace Mantid::DataHandling::ANSTO
std::string name
Definition Run.cpp:60
std::vector< uint32_t > m_count
sum of all events seen in an individual bin
size_t m_size
Maximum size of the store.
double value
The value of the point.
Definition FitMW.cpp:51
double position
Definition GetAllEi.cpp:154
std::map< DeltaEMode::Type, std::string > index
#define TarTypeFlag_NormalFile
int count
counter
Definition Matrix.cpp:37
#define UNUSED_ARG(x)
Function arguments are sometimes unused in certain implmentations but are required for documentation ...
Definition System.h:48
Helper class for reporting progress from algorithms.
Definition Progress.h:25
void doReport(const std::string &msg="") override
Actually do the reporting, without changing the loop counter.
Definition Progress.cpp:70
EventAssignerFixedWavelength(const std::vector< bool > &roi, const size_t stride, const double wavelength, const double period, const double phase, const int64_t startTime, const double tofMinBoundary, const double tofMaxBoundary, const double timeMinBoundary, const double timeMaxBoundary, std::vector< EventVector_pt > &eventVectors)
void addEventImpl(size_t id, int64_t pulse, double tof) override
EventAssigner(const std::vector< bool > &roi, const size_t stride, const double period, const double phase, int64_t startTime, const double tofMinBoundary, const double tofMaxBoundary, const double timeMinBoundary, const double timeMaxBoundary, std::vector< EventVector_pt > &eventVectors)
void addEventImpl(size_t id, int64_t pulse, double tof) override
std::vector< EventVector_pt > & m_eventVectors
void addEventImpl(size_t id, int64_t pulse, double tof) override
EventCounter(const std::vector< bool > &roi, const size_t stride, const double period, const double phase, const int64_t startTime, const double tofMinBoundary, const double tofMaxBoundary, const double timeMinBoundary, const double timeMaxBoundary, std::vector< size_t > &eventCounts)
virtual void addEventImpl(size_t id, int64_t pulse, double tof)=0
void addEvent(size_t x, size_t y, double tof)
EventProcessor(const std::vector< bool > &roi, size_t stride, const double period, const double phase, const int64_t startTime, const double tofMinBoundary, const double tofMaxBoundary, const double timeMinBoundary, const double timeMaxBoundary)
bool seek(int64_t offset, int whence, int64_t *newPosition=nullptr)
helper class to keep track of progress
ProgressTracker(API::Progress &progBar, const char *msg, int64_t target, size_t count)
std::vector< std::string > m_fileNames
const std::string & selected_name() const
size_t read(void *dst, size_t size)
const std::vector< std::string > & files() const
static bool append(const std::string &path, const std::string &name, const void *buffer, size_t size)
void reportIncrement(int inc, const std::string &msg="")
Sends the progress notification and increment the loop counter by more than one.
void report()
Increments the loop counter by 1, then sends the progress notification on behalf of its algorithm.
std::vector< NXInfo > & datasets() const
Returns a list of all datasets in this NXClass.
NXClass openNXGroup(const std::string &name) const
Creates and opens an arbitrary (non-standard) class (group).
NXChar openNXChar(const std::string &name) const
Creates and opens a char dataset.
NXDataSetTyped< T > openNXDataSet(const std::string &name) const
Templated method for creating datasets.
Templated class implementation of NXDataSet.
void load()
Read all of the datablock in.
dimsize_t dim0() const
Returns the number of elements along the first dimension.
Implements NXentry Nexus class.
template bool loadNXDataSet< float >(const Nexus::NXEntry &entry, const std::string &path, float &value, int index)
template bool loadNXDataSet< int >(const Nexus::NXEntry &entry, const std::string &path, int &value, int index)
template bool loadNXDataSet< double >(const Nexus::NXEntry &entry, const std::string &path, double &value, int index)
bool isTimedDataSet(const Nexus::NXEntry &entry, const std::string &path)
template uint64_t extractTimedDataSet< float >(const Nexus::NXEntry &entry, const std::string &path, uint64_t startTime, uint64_t endTime, std::vector< uint64_t > &times, std::vector< float > &events, std::string &units)
std::string extractWorkspaceTitle(const std::string &nxsFile)
void ReadEventData(ProgressTracker &prog, const Nexus::NXEntry &entry, EventProcessor *handler, uint64_t start_nsec, uint64_t end_nsec, const std::string &neutron_path, int tube_resolution=1024)
bool loadNXString(const Nexus::NXEntry &entry, const std::string &path, std::string &value)
int64_t epochRelDateTimeBase(int64_t epochInNanoSeconds)
template bool loadNXDataSet< uint64_t >(const Nexus::NXEntry &entry, const std::string &path, uint64_t &value, int index)
bool loadNXDataSet(const Nexus::NXEntry &entry, const std::string &path, T &value, int index)
std::pair< uint64_t, uint64_t > getHMScanLimits(const Nexus::NXEntry &entry, int datasetIx)
template uint64_t extractTimedDataSet< double >(const Nexus::NXEntry &entry, const std::string &path, uint64_t startTime, uint64_t endTime, std::vector< uint64_t > &times, std::vector< double > &events, std::string &units)
uint64_t extractTimedDataSet(const Nexus::NXEntry &entry, const std::string &path, uint64_t startTime, uint64_t endTime, std::vector< uint64_t > &times, std::vector< T > &events, std::string &units)
std::pair< uint64_t, uint64_t > getTimeScanLimits(const Nexus::NXEntry &entry, int datasetIx)
template bool loadNXDataSet< int64_t >(const Nexus::NXEntry &entry, const std::string &path, int64_t &value, int index)
std::vector< std::string > filterDatasets(const Nexus::NXEntry &entry, const std::string &groupAddress, const std::string &regexFilter)
extract datasets from a group that match a regex filter
NXDataSetTyped< char > NXChar
The char dataset type.
STL namespace.