BankPulseTimes.cpp 3.76 KB
Newer Older
1
2
3
// Mantid Repository : https://github.com/mantidproject/mantid
//
// Copyright © 2018 ISIS Rutherford Appleton Laboratory UKRI,
4
5
//   NScD Oak Ridge National Laboratory, European Spallation Source,
//   Institut Laue - Langevin & CSNS, Institute of High Energy Physics, CAS
6
// SPDX - License - Identifier: GPL - 3.0 +
7
8
#include "MantidDataHandling/BankPulseTimes.h"

9
using namespace Mantid::Kernel;
10
11
12
13
14
15
16
17
18
//===============================================================================================
// BankPulseTimes
//===============================================================================================

/// The first period
const unsigned int BankPulseTimes::FirstPeriod = 1;

//----------------------------------------------------------------------------------------------
/** Constructor. Loads the pulse times from the bank entry of the file
LamarMoore's avatar
LamarMoore committed
19
20
21
22
 *
 * @param file :: nexus file open in the right bank entry
 * @param pNumbers :: Period numbers to index into. Index via frame/pulse
 */
Samuel Jones's avatar
Samuel Jones committed
23
BankPulseTimes::BankPulseTimes(::NeXus::File &file, const std::vector<int> &pNumbers) : periodNumbers(pNumbers) {
24
25
  file.openData("event_time_zero");
  // Read the offset (time zero)
Neil Vaytet's avatar
Neil Vaytet committed
26
  // If the offset is not present, use Unix epoch
27
28
29
30
  if (!file.hasAttr("offset"))
    startTime = "1970-01-01T00:00:00Z";
  else
    file.getAttr("offset", startTime);
31
  Mantid::Types::Core::DateAndTime start(startTime);
32
33
  // Load the seconds offsets

34
  const auto heldTimeZeroType = file.getInfo().type;
35
36
  // Nexus only requires event_time_zero to be a NXNumber, we support two
  // possilites
37
38
39
40
41
  if (heldTimeZeroType == ::NeXus::FLOAT64) {
    std::vector<double> seconds;
    file.getData(seconds);
    file.closeData();
    // Now create the pulseTimes
42
    if (seconds.size() == 0)
43
44
      throw std::runtime_error("event_time_zero field has no data!");

45
46
    std::transform(seconds.cbegin(), seconds.cend(), std::back_inserter(pulseTimes),
                   [start](double seconds) { return start + seconds; });
47
48
49
50
51
  } else if (heldTimeZeroType == ::NeXus::UINT64) {
    std::vector<uint64_t> nanoseconds;
    file.getData(nanoseconds);
    file.closeData();
    // Now create the pulseTimes
52
    if (nanoseconds.size() == 0)
53
54
      throw std::runtime_error("event_time_zero field has no data!");

55
56
    std::transform(nanoseconds.cbegin(), nanoseconds.cend(), std::back_inserter(pulseTimes),
                   [start](int64_t nanoseconds) { return start + nanoseconds; });
57
58
59
60
61
  } else {
    throw std::invalid_argument("Unsupported type for event_time_zero");
  }
  // Ensure that we always have a consistency between nPulses and
  // periodNumbers containers
62
63
  if (pulseTimes.size() != pNumbers.size()) {
    periodNumbers = std::vector<int>(pulseTimes.size(), FirstPeriod);
64
65
66
67
68
69
    ;
  }
}

//----------------------------------------------------------------------------------------------
/** Constructor. Build from a vector of date and times.
LamarMoore's avatar
LamarMoore committed
70
71
 *  Handles a zero-sized vector
 *  @param times
LamarMoore's avatar
LamarMoore committed
72
 */
Samuel Jones's avatar
Samuel Jones committed
73
BankPulseTimes::BankPulseTimes(const std::vector<Mantid::Types::Core::DateAndTime> &times) {
74
  if (times.size() == 0)
75
76
    return;

77
78
79
  pulseTimes = times;
  periodNumbers = std::vector<int>(pulseTimes.size(), FirstPeriod); // TODO we are fixing this at 1 period for all
}
80
81
82

//----------------------------------------------------------------------------------------------
/** Comparison. Is this bank's pulse times array the same as another one.
LamarMoore's avatar
LamarMoore committed
83
84
85
86
87
88
89
 *
 * @param otherNumPulse :: number of pulses in the OTHER bank event_time_zero.
 * @param otherStartTime :: "offset" attribute of the OTHER bank
 * event_time_zero.
 * @return true if the pulse times are the same and so don't need to be
 * reloaded.
 */
Samuel Jones's avatar
Samuel Jones committed
90
bool BankPulseTimes::equals(size_t otherNumPulse, const std::string &otherStartTime) {
91
  return ((this->startTime == otherStartTime) && (this->pulseTimes.size() == otherNumPulse));
92
}