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);
204std::unique_ptr<Property>
loadProperty(Nexus::File *file,
const std::string &
group,
const std::string &prefix) {
205 file->openGroup(
group,
"NXlog");
208 std::vector<double> timeSec;
209 std::string startStr;
212 if (file->hasAddress(prefix +
"/" +
group +
"/time")) {
213 getTimeAndStart(file, timeSec, startStr);
216 return loadPropertyCommon(file,
group, timeSec, startStr);
228 file->openGroup(
group,
"NXlog");
231 std::vector<double> timeSec;
232 std::string startStr;
235 std::string
const currentAddress = file->getAddress();
236 std::string timeAddress = currentAddress +
"/time";
237 if (file->hasAddress(timeAddress)) {
238 getTimeAndStart(file, timeSec, startStr);
241 return loadPropertyCommon(file,
group, timeSec, startStr);
Class that provides for a standard Nexus exception.
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 std::string &prefix)
Opens a NXlog group in a nexus file and creates the correct Property object from it.