14#include "MantidNexus/NexusFile.h"
19#include <boost/algorithm/string/split.hpp>
27#pragma warning(disable : 4805)
41template <
typename NumT>
42std::unique_ptr<Property> makeProperty(Nexus::File *file,
const std::string &
name,
43 const std::vector<Types::Core::DateAndTime> ×) {
44 std::vector<NumT> values;
45 file->getData(values);
47 if (values.size() == 1) {
48 return std::make_unique<PropertyWithValue<NumT>>(
name, values[0]);
50 return std::make_unique<ArrayProperty<NumT>>(
name, std::move(values));
53 auto prop = std::make_unique<TimeSeriesProperty<NumT>>(
name);
54 prop->addValues(times, values);
55 return std::unique_ptr<Property>(std::move(prop));
66std::unique_ptr<Property> makeTimeSeriesBoolProperty(Nexus::File *file,
const std::string &
name,
67 const std::vector<Types::Core::DateAndTime> ×) {
68 std::vector<uint8_t> savedValues;
69 file->getData(savedValues);
70 const size_t nvals = savedValues.size();
71 std::vector<bool> realValues(nvals);
72 for (
size_t i = 0; i < nvals; ++i) {
73 realValues[i] = (savedValues[i] != 0);
75 auto prop = std::make_unique<TimeSeriesProperty<bool>>(
name);
76 prop->addValues(times, realValues);
77 return std::unique_ptr<Property>(std::move(prop));
81std::unique_ptr<Property> makeStringProperty(Nexus::File *file,
const std::string &
name,
82 const std::vector<Types::Core::DateAndTime> ×) {
84 std::string bigString = file->getStrData();
85 return std::make_unique<PropertyWithValue<std::string>>(
name, bigString);
87 if (file->getInfo().dims.size() != 2)
88 throw std::runtime_error(
"NXlog loading failed on field " +
name +
". Expected rank 2.");
89 int64_t numStrings = file->getInfo().dims[0];
90 int64_t span = file->getInfo().dims[1];
91 auto data = std::make_unique<char[]>(numStrings * span);
92 file->getData(data.get());
93 std::vector<std::string> values;
94 values.reserve(
static_cast<size_t>(numStrings));
95 for (int64_t i = 0; i < numStrings; i++)
96 values.emplace_back(data.get() + i * span);
98 auto prop = std::make_unique<TimeSeriesProperty<std::string>>(
name);
99 prop->addValues(times, values);
100 return std::unique_ptr<Property>(std::move(prop));
106void getTimeAndStart(Nexus::File *file, std::vector<double> &timeSec, std::string &startStr) {
107 file->openData(
"time");
108 file->getData(timeSec);
111 file->getAttr(
"start", startStr);
126std::unique_ptr<Property> loadPropertyCommon(Nexus::File *file,
const std::string &
group,
127 const std::vector<double> &timeSec, std::string &startStr) {
128 std::vector<Types::Core::DateAndTime> times;
129 if (!timeSec.empty()) {
131 if (startStr.empty())
132 startStr =
"2000-01-01T00:00:00";
134 Types::Core::DateAndTime start(startStr);
135 times.reserve(timeSec.size());
136 std::transform(timeSec.cbegin(), timeSec.cend(), std::back_inserter(times),
137 [&start](
const auto &time) { return start + time; });
140 file->openData(
"value");
141 std::unique_ptr<Property> retVal =
nullptr;
142 switch (file->getInfo().type) {
144 retVal = makeProperty<float>(file,
group, times);
147 retVal = makeProperty<double>(file,
group, times);
150 retVal = makeProperty<int32_t>(file,
group, times);
153 retVal = makeProperty<uint32_t>(file,
group, times);
156 retVal = makeProperty<int64_t>(file,
group, times);
159 retVal = makeProperty<uint64_t>(file,
group, times);
162 retVal = makeStringProperty(file,
group, times);
167 const bool typeIsBool = file->hasAttr(
"boolean");
168 file->openData(
"value");
171 retVal = makeTimeSeriesBoolProperty(file,
group, times);
180 throw std::runtime_error(
"Invalid data type found.");
186 std::string unitsStr;
188 file->getAttr(
"units", unitsStr);
197 retVal->setUnits(unitsStr);
206 file->openGroup(
group,
"NXlog");
209 std::vector<double> timeSec;
210 std::string startStr;
214 getTimeAndStart(file, timeSec, startStr);
217 return loadPropertyCommon(file,
group, timeSec, startStr);
229 file->openGroup(
group,
"NXlog");
232 std::vector<double> timeSec;
233 std::string startStr;
236 std::map<std::string, std::string> entries = file->getEntries();
237 if (entries.find(
"time") != entries.end()) {
238 getTimeAndStart(file, timeSec, startStr);
241 return loadPropertyCommon(file,
group, timeSec, startStr);
Class that provides for a standard Nexus exception.
bool isEntry(const std::string &entryName, const std::string &groupClass) const noexcept
Checks if a full-address entry exists for a particular groupClass in a Nexus dataset.
static unsigned short constexpr UINT16
static unsigned short constexpr UINT64
static unsigned short constexpr INT8
static unsigned short constexpr INT64
static unsigned short constexpr INT16
static unsigned short constexpr UINT32
static unsigned short constexpr CHAR
static unsigned short constexpr UINT8
static unsigned short constexpr INT32
static unsigned short constexpr FLOAT32
static unsigned short constexpr BAD
static unsigned short constexpr FLOAT64
Namespace with helper methods for loading and saving Property's (logs) to NXS files.
DLLExport std::unique_ptr< Property > loadProperty(Nexus::File *file, const std::string &group, const Nexus::NexusDescriptor &fileInfo, const std::string &prefix)
Opens a NXlog group in a nexus file and creates the correct Property object from it.