Mantid
Loading...
Searching...
No Matches
H5Util.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 +
9#include <Poco/Logger.h>
10
11#include <H5Cpp.h>
12
13#include <algorithm>
14#include <array>
15#include <boost/numeric/conversion/cast.hpp>
16#include <sstream>
17#include <stdexcept>
18#include <string>
19
20using namespace H5;
21
22namespace Mantid::Nexus::H5Util {
23
24namespace {
26const auto g_log = &Poco::Logger::get("H5Util");
27
28const std::string NX_ATTR_CLASS("NX_class");
29const std::string CAN_SAS_ATTR_CLASS("canSAS_class");
30} // namespace
31
32// -------------------------------------------------------------------
33// convert primitives to HDF5 enum
34// -------------------------------------------------------------------
35
36template <typename NumT> DataType getType() { throw DataTypeIException(); }
37
38template <> MANTID_NEXUS_DLL DataType getType<float>() { return PredType::NATIVE_FLOAT; }
39
40template <> MANTID_NEXUS_DLL DataType getType<double>() { return PredType::NATIVE_DOUBLE; }
41
42template <> MANTID_NEXUS_DLL DataType getType<int8_t>() { return PredType::NATIVE_INT8; }
43
44template <> MANTID_NEXUS_DLL DataType getType<uint8_t>() { return PredType::NATIVE_UINT8; }
45
46template <> MANTID_NEXUS_DLL DataType getType<int16_t>() { return PredType::NATIVE_INT16; }
47
48template <> MANTID_NEXUS_DLL DataType getType<uint16_t>() { return PredType::NATIVE_UINT16; }
49
50template <> MANTID_NEXUS_DLL DataType getType<int32_t>() { return PredType::NATIVE_INT32; }
51
52template <> MANTID_NEXUS_DLL DataType getType<uint32_t>() { return PredType::NATIVE_UINT32; }
53
54template <> MANTID_NEXUS_DLL DataType getType<int64_t>() { return PredType::NATIVE_INT64; }
55
56template <> MANTID_NEXUS_DLL DataType getType<uint64_t>() { return PredType::NATIVE_UINT64; }
57
58template <> MANTID_NEXUS_DLL DataType getType<char>() { return PredType::C_S1; }
59
60template <> MANTID_NEXUS_DLL DataType getType<std::string>() { return PredType::C_S1; }
61
62template <> MANTID_NEXUS_DLL DataType getType<bool>() { return PredType::NATIVE_HBOOL; }
63
65namespace {
66
67template <typename InT, typename OutT>
68inline void narrowingVectorCast(std::vector<InT> const &input, std::vector<OutT> &output) {
69 output.resize(input.size());
70 std::transform(input.cbegin(), input.cend(), output.begin(),
71 [](const auto &a) { return boost::numeric_cast<OutT>(a); });
72}
73
74template <typename InT, typename OutT, Narrowing narrow> inline void throwIfUnallowedNarrowing() {
75 if constexpr (sizeof(OutT) < sizeof(InT) && narrow == Narrowing::Prevent) {
76 std::string msg = "H5Util: narrowing from " + getType<InT>().fromClass();
77 msg += " to " + getType<OutT>().fromClass() + " is prevented.";
78 throw DataTypeIException(msg);
79 }
80}
81
82} // namespace
83
90#define RUN_H5UTIL_FUNCTION(dataType, func_name, ...) \
91 if (dataType == PredType::NATIVE_FLOAT) { \
92 func_name<float, OutT, narrow>(__VA_ARGS__); \
93 } else if (dataType == PredType::NATIVE_DOUBLE) { \
94 func_name<double, OutT, narrow>(__VA_ARGS__); \
95 } else if (dataType == PredType::NATIVE_INT8) { \
96 func_name<int8_t, OutT, narrow>(__VA_ARGS__); \
97 } else if (dataType == PredType::NATIVE_UINT8) { \
98 func_name<uint8_t, OutT, narrow>(__VA_ARGS__); \
99 } else if (dataType == PredType::NATIVE_INT16) { \
100 func_name<int16_t, OutT, narrow>(__VA_ARGS__); \
101 } else if (dataType == PredType::NATIVE_UINT16) { \
102 func_name<uint16_t, OutT, narrow>(__VA_ARGS__); \
103 } else if (dataType == PredType::NATIVE_INT32) { \
104 func_name<int32_t, OutT, narrow>(__VA_ARGS__); \
105 } else if (dataType == PredType::NATIVE_UINT32) { \
106 func_name<uint32_t, OutT, narrow>(__VA_ARGS__); \
107 } else if (dataType == PredType::NATIVE_INT64) { \
108 func_name<int64_t, OutT, narrow>(__VA_ARGS__); \
109 } else if (dataType == PredType::NATIVE_UINT64) { \
110 func_name<uint64_t, OutT, narrow>(__VA_ARGS__); \
111 } else if (dataType == PredType::C_S1) { \
112 func_name<char, OutT, narrow>(__VA_ARGS__); \
113 } else { \
114 std::string msg = "H5Util: error in narrowing, unknown H5Cpp PredType "; \
115 msg += dataType.fromClass() + "."; \
116 throw DataTypeIException(msg); \
117 }
118
119H5::FileAccPropList defaultFileAcc() {
120 H5::FileAccPropList access_plist;
121 access_plist.setFcloseDegree(H5F_CLOSE_STRONG);
122 return access_plist;
123}
124
125bool isHdf5(std::string const &filename) {
126 // Calls C routine H5Fis_accessible to determine whether the file is in
127 // HDF5 format. It returns positive value, 0, or negative value
128 // Copies the function in H5Cpp, but using the correct access level
130 htri_t ret_value = H5Fis_accessible(filename.c_str(), plist);
131 plist.reset(); // explicit closure
132
133 if (ret_value > 0)
134 return true;
135 else if (ret_value == 0)
136 return false;
137 else // Raise exception when H5Fis_accessible returns a negative value
138 {
139 throw H5::FileIException("H5File::isHdf5", "H5Fis_accessible returned negative value");
140 }
141}
142
143DataSpace getDataSpace(const size_t length) {
144 hsize_t dims[] = {length};
145 return DataSpace(1, dims);
146}
147
148namespace {
149
150template <typename NumT> H5::DataSet writeScalarDataSet(Group &group, const std::string &name, const NumT &value) {
151 static_assert(std::is_integral<NumT>::value || std::is_floating_point<NumT>::value,
152 "The writeNumAttribute function only accepts integral of "
153 "floating point values.");
154 auto dataType = getType<NumT>();
155 DataSpace dataSpace = getDataSpace(1);
156 H5::DataSet data = group.createDataSet(name, dataType, dataSpace);
157 data.write(&value, dataType);
158 return data;
159}
160
161template <>
162H5::DataSet writeScalarDataSet<std::string>(Group &group, const std::string &name, const std::string &value) {
163 StrType dataType(0, value.length() + 1);
164 DataSpace dataSpace = getDataSpace(1);
165 H5::DataSet data = group.createDataSet(name, dataType, dataSpace);
166 data.write(value, dataType);
167 return data;
168}
169
170} // namespace
171
172// -------------------------------------------------------------------
173// write methods
174// -------------------------------------------------------------------
175
176Group createGroupNXS(H5File &file, const std::string &name, const std::string &nxtype) {
177 auto group = file.createGroup(name);
178 writeStrAttribute(group, NX_ATTR_CLASS, nxtype);
179 return group;
180}
181
182Group createGroupNXS(Group &group, const std::string &name, const std::string &nxtype) {
183 auto outGroup = group.createGroup(name);
184 writeStrAttribute(outGroup, NX_ATTR_CLASS, nxtype);
185 return outGroup;
186}
187
188Group createGroupCanSAS(H5File &file, const std::string &name, const std::string &nxtype, const std::string &cstype) {
189 auto outGroup = createGroupNXS(file, name, nxtype);
190 writeStrAttribute(outGroup, CAN_SAS_ATTR_CLASS, cstype);
191 return outGroup;
192}
193
194Group createGroupCanSAS(Group &group, const std::string &name, const std::string &nxtype, const std::string &cstype) {
195 auto outGroup = createGroupNXS(group, name, nxtype);
196 writeStrAttribute(outGroup, CAN_SAS_ATTR_CLASS, cstype);
197 return outGroup;
198}
199
200DSetCreatPropList setCompressionAttributes(const std::size_t length, const int deflateLevel) {
201 DSetCreatPropList propList;
202 hsize_t chunk_dims[1] = {length};
203 propList.setChunk(1, chunk_dims);
204 propList.setDeflate(deflateLevel);
205 return propList;
206}
207
208void writeStrAttribute(const H5::H5Object &object, const std::string &name, const std::string &value) {
209 StrType attrType(0, H5T_VARIABLE);
210 DataSpace attrSpace(H5S_SCALAR);
211 auto attribute = object.createAttribute(name, attrType, attrSpace);
212 attribute.write(attrType, value);
213}
214
215template <typename NumT>
216void writeNumAttribute(const H5::H5Object &object, const std::string &name, const NumT &value) {
217 static_assert(std::is_integral<NumT>::value || std::is_floating_point<NumT>::value,
218 "The writeNumAttribute function only accepts integral or "
219 "floating point values.");
220 auto attrType = getType<NumT>();
221 DataSpace attrSpace(H5S_SCALAR);
222
223 auto attribute = object.createAttribute(name, attrType, attrSpace);
224 // Wrap the data set in an array
225 std::array<NumT, 1> valueArray = {{value}};
226 attribute.write(attrType, valueArray.data());
227}
228
229template <typename NumT>
230void writeNumAttribute(const H5::H5Object &object, const std::string &name, const std::vector<NumT> &value) {
231 static_assert(std::is_integral<NumT>::value || std::is_floating_point<NumT>::value,
232 "The writeNumAttribute function only accepts integral of "
233 "floating point values.");
234 auto attrType = getType<NumT>();
235 DataSpace attrSpace = getDataSpace(value.size());
236
237 auto attribute = object.createAttribute(name, attrType, attrSpace);
238 attribute.write(attrType, value.data());
239}
240
241void write(Group &group, const std::string &name, const std::string &value) { writeScalarDataSet(group, name, value); }
242
243template <typename T>
244void writeScalarDataSetWithStrAttributes(H5::Group &group, const std::string &name, const T &value,
245 const std::map<std::string, std::string> &attributes) {
246 auto data = writeScalarDataSet(group, name, value);
247 for (const auto &attribute : attributes) {
248 writeStrAttribute(data, attribute.first, attribute.second);
249 }
250}
251
252template <typename NumT> void writeArray1D(Group &group, const std::string &name, const std::vector<NumT> &values) {
253 DataType dataType(getType<NumT>());
254 DataSpace dataSpace = getDataSpace(values.size());
255
256 DSetCreatPropList propList = setCompressionAttributes(values.size());
257
258 auto data = group.createDataSet(name, dataType, dataSpace, propList);
259 data.write(values.data(), dataType);
260}
261
262// -------------------------------------------------------------------
263// read methods
264// -------------------------------------------------------------------
265
266std::string readString(H5::H5File &file, const std::string &address) {
267 try {
268 auto data = file.openDataSet(address);
269 return readString(data);
270 } catch (const H5::FileIException &e) {
271 UNUSED_ARG(e);
272 return "";
273 } catch (const H5::GroupIException &e) {
274 UNUSED_ARG(e);
275 return "";
276 }
277}
278
279std::string readString(const H5::Group &group, const std::string &name) {
280 try {
281 const auto data = group.openDataSet(name);
282 return readString(data);
283 } catch (const H5::GroupIException &e) {
284 UNUSED_ARG(e);
285 return "";
286 }
287}
288
289std::string readString(const H5::DataSet &dataset) {
290 std::string value;
291 dataset.read(value, dataset.getDataType(), dataset.getSpace());
292
293#if H5_VERSION_GE(1, 14, 0)
294 // hdf5 >=1.14 puts the null terminator in the string
295 // this strips that out
296 if (const auto pos = value.rfind('\0'); pos != std::string::npos)
297 value.erase(pos);
298#endif
299
300 return value;
301}
302
309std::vector<std::string> readStringVector(Group &group, const std::string &name) {
310 DataSet dataset = group.openDataSet(name);
311 return readStringVector(dataset);
312}
313
314std::vector<std::string> readStringVector(DataSet &dataset) {
315 hsize_t dims[1];
316 char **rdata;
317 std::vector<std::string> result;
318 DataSpace dataspace = dataset.getSpace();
319 DataType datatype = dataset.getDataType();
320
321 dataspace.getSimpleExtentDims(dims, nullptr);
322 result.reserve(dims[0]);
323
324 rdata = new char *[dims[0]];
325 dataset.read(rdata, datatype);
326
327 for (size_t i = 0; i < dims[0]; ++i)
328 result.emplace_back(std::string(rdata[i]));
329
330 dataset.vlenReclaim(rdata, datatype, dataspace);
331 dataset.close();
332 delete[] rdata;
333
334 return result;
335}
336
337bool hasAttribute(const H5::H5Object &object, const char *attributeName) {
338 const htri_t exists = H5Aexists(object.getId(), attributeName);
339 return exists > 0;
340}
341
342void readStringAttribute(const H5::H5Object &object, const std::string &attributeName, std::string &output) {
343 const auto attribute = object.openAttribute(attributeName);
344 attribute.read(attribute.getDataType(), output);
345}
346
347// This method avoids a copy on return so should be preferred to its sibling method
348template <typename OutT, Narrowing narrow>
349void readArray1DCoerce(const H5::Group &group, const std::string &name, std::vector<OutT> &output) {
350 try {
351 DataSet dataset = group.openDataSet(name);
352 readArray1DCoerce<OutT, narrow>(dataset, output);
353 } catch (const H5::GroupIException &) {
354 g_log->information("Failed to open dataset \"" + name + "\"");
355 } catch (const H5::DataTypeIException &) {
356 g_log->information("DataSet \"" + name + "\" should be double");
357 }
358}
359
360template <typename OutT, Narrowing narrow>
361std::vector<OutT> readArray1DCoerce(const H5::Group &group, const std::string &name) {
362 std::vector<OutT> result;
363 try {
364 DataSet dataset = group.openDataSet(name);
365 readArray1DCoerce<OutT, narrow>(dataset, result);
366 } catch (const H5::GroupIException &) {
367 g_log->information("Failed to open dataset \"" + name + "\"");
368 } catch (const H5::DataTypeIException &) {
369 g_log->information("DataSet \"" + name + "\" should be double");
370 }
371
372 return result;
373}
374
375namespace {
376template <typename InT, typename OutT, Narrowing narrow>
377void convertingVectorRead(const DataSet &dataset, const DataType &dataType, std::vector<OutT> &output,
378 const DataSpace &memspace, const DataSpace &filespace) {
379 throwIfUnallowedNarrowing<InT, OutT, narrow>();
380
381 std::size_t dataSize = filespace.getSelectNpoints();
382 if constexpr (std::is_same_v<InT, OutT>) {
383 output.resize(dataSize);
384 dataset.read(output.data(), dataType, memspace, filespace);
385 } else {
386 std::vector<InT> temp(dataSize);
387 dataset.read(temp.data(), dataType, memspace, filespace);
388 narrowingVectorCast<InT, OutT>(temp, output);
389 }
390}
391
392template <typename InT, typename OutT, Narrowing narrow>
393void convertingNumArrayAttributeRead(Attribute &attribute, DataType const &dataType, std::vector<OutT> &value) {
394 throwIfUnallowedNarrowing<InT, OutT, narrow>();
395
396 std::size_t dataSize = (attribute.getSpace()).getSelectNpoints();
397 if constexpr (std::is_same_v<InT, OutT>) {
398 value.resize(dataSize);
399 attribute.read(dataType, value.data());
400 } else {
401 std::vector<InT> temp(dataSize);
402 attribute.read(dataType, temp.data());
403 narrowingVectorCast<InT, OutT>(temp, value);
404 }
405}
406
407template <typename InT, typename OutT, Narrowing narrow>
408void convertingScalarRead(Attribute &attribute, const DataType &dataType, OutT &value) {
409 throwIfUnallowedNarrowing<InT, OutT, narrow>();
410
411 if constexpr (std::is_same_v<InT, OutT>) {
412 attribute.read(dataType, &value);
413 } else {
414 InT temp;
415 attribute.read(dataType, &temp);
416 value = boost::numeric_cast<OutT>(temp);
417 }
418}
419
420} // namespace
421
426template <typename OutT, Narrowing narrow>
427OutT readNumAttributeCoerce(const H5::H5Object &object, const std::string &attributeName) {
428 auto attribute = object.openAttribute(attributeName);
429 auto dataType = attribute.getDataType();
430
431 OutT value;
432 RUN_H5UTIL_FUNCTION(dataType, convertingScalarRead, attribute, dataType, value);
433 return value;
434}
435
440template <typename OutT, Narrowing narrow>
441std::vector<OutT> readNumArrayAttributeCoerce(const H5::H5Object &object, const std::string &attributeName) {
442 auto attribute = object.openAttribute(attributeName);
443 auto dataType = attribute.getDataType();
444
445 std::vector<OutT> value;
446 RUN_H5UTIL_FUNCTION(dataType, convertingNumArrayAttributeRead, attribute, dataType, value);
447 // RUN_H5UTIL_FUNCTION(dataType, narrow, convertingNumArrayAttributeRead, attribute, dataType, value);
448 return value;
449}
450
455template <typename OutT, Narrowing narrow>
456void readArray1DCoerce(const H5::DataSet &dataset, std::vector<OutT> &output, const size_t length,
457 const size_t offset) {
458 DataSpace filespace = dataset.getSpace();
459 const auto length_actual = static_cast<size_t>(filespace.getSelectNpoints());
460
461 if (offset >= length_actual && offset != 0) {
462 std::stringstream msg;
463 msg << "Tried to read offset=" << offset << " into array that is only lenght=" << length_actual << " long";
464 throw std::runtime_error(msg.str());
465 }
466
467 // set extent and offset in DataSpace
468 const hsize_t rankedoffset[1] = {static_cast<hsize_t>(offset)};
469 const hsize_t rankedextent[1] = {
470 static_cast<hsize_t>(std::min(length, length_actual - offset))}; // don't read past the end
471 // select a part of filespace if appropriate
472 if (rankedextent[0] < length_actual)
473 filespace.selectHyperslab(H5S_SELECT_SET, rankedextent, rankedoffset);
474
475 // size of thing being read out
476 DataSpace memspace(1, rankedextent);
477
478 // do the actual read
479 const DataType dataType = dataset.getDataType();
480 RUN_H5UTIL_FUNCTION(dataType, convertingVectorRead, dataset, dataType, output, memspace, filespace);
481}
482
484bool groupExists(H5::H5Object const &h5, const std::string &groupAddress) {
485 bool status = true;
486 // Unfortunately, this is actually the approach recommended by the HDF Group.
487 try {
488 h5.openGroup(groupAddress);
489 } catch (const H5::Exception &) {
490 status = false;
491 }
492 return status;
493}
494
496bool keyHasValue(H5::H5Object const &h5, const std::string &key, const std::string &value) {
497 bool status = true;
498 try {
499 Attribute attr = h5.openAttribute(key);
500 std::string value_;
501 attr.read(attr.getDataType(), value_);
502 if (value_ != value)
503 status = false;
504 } catch (const H5::Exception &) {
505 status = false;
506 }
507 return status;
508}
509
510void copyGroup(H5::H5Object &dest, const std::string &destGroupAddress, H5::H5Object &src,
511 const std::string &srcGroupAddress) {
512 // Source group must exist, and destination group must not exist.
513 if (!groupExists(src, srcGroupAddress) || groupExists(dest, destGroupAddress))
514 throw std::invalid_argument(std::string("H5Util::copyGroup: source group '") + srcGroupAddress +
515 "' must exist and " + "destination group '" + destGroupAddress + "' must not exist.");
516
517 // TODO: check that source file must have at least read access and destination file must have write access.
518
519 // Note that in the HDF5 API:
520 // C++ API support for these HDF5 methods does not yet exist.
521
522 // Create intermediate groups, if necessary
523 Mantid::Nexus::UniqueID<&H5Pclose> lcpl = H5Pcreate(H5P_LINK_CREATE);
524 if (H5Pset_create_intermediate_group(lcpl, 1) < 0)
525 throw std::runtime_error("H5Util::copyGroup: 'H5Pset_create_intermediate_group' error return.");
526
527 if (H5Ocopy(src.getId(), srcGroupAddress.c_str(), dest.getId(), destGroupAddress.c_str(), H5P_DEFAULT, lcpl) < 0)
528 throw std::runtime_error("H5Util::copyGroup: 'H5Ocopy' error return.");
529 lcpl.reset(); // explicit closure
530}
531
532void deleteObjectLink(H5::H5Object &h5, const std::string &target) {
533 // Note that in the HDF5 API:
534 // C++ API support for this HDF5 method does not yet exist.
535
536 // Target object must exist
537 if (H5Ldelete(h5.getId(), target.c_str(), H5P_DEFAULT) < 0)
538 throw std::runtime_error("H5Util::deleteObjectLink: 'H5Ldelete' error return.");
539}
540
541// -------------------------------------------------------------------
542// instantiations for writeNumAttribute
543// -------------------------------------------------------------------
544
545template MANTID_NEXUS_DLL void writeNumAttribute(const H5::H5Object &object, const std::string &name,
546 const float &value);
547template MANTID_NEXUS_DLL void writeNumAttribute(const H5::H5Object &object, const std::string &name,
548 const double &value);
549template MANTID_NEXUS_DLL void writeNumAttribute(const H5::H5Object &object, const std::string &name,
550 const int8_t &value);
551template MANTID_NEXUS_DLL void writeNumAttribute(const H5::H5Object &object, const std::string &name,
552 const uint8_t &value);
553template MANTID_NEXUS_DLL void writeNumAttribute(const H5::H5Object &object, const std::string &name,
554 const int16_t &value);
555template MANTID_NEXUS_DLL void writeNumAttribute(const H5::H5Object &object, const std::string &name,
556 const uint16_t &value);
557template MANTID_NEXUS_DLL void writeNumAttribute(const H5::H5Object &object, const std::string &name,
558 const int32_t &value);
559template MANTID_NEXUS_DLL void writeNumAttribute(const H5::H5Object &object, const std::string &name,
560 const uint32_t &value);
561template MANTID_NEXUS_DLL void writeNumAttribute(const H5::H5Object &object, const std::string &name,
562 const int64_t &value);
563template MANTID_NEXUS_DLL void writeNumAttribute(const H5::H5Object &object, const std::string &name,
564 const uint64_t &value);
565template MANTID_NEXUS_DLL void writeNumAttribute(const H5::H5Object &object, const std::string &name,
566 const char &value);
567
568template MANTID_NEXUS_DLL void writeNumAttribute(const H5::H5Object &object, const std::string &name,
569 const std::vector<float> &value);
570template MANTID_NEXUS_DLL void writeNumAttribute(const H5::H5Object &object, const std::string &name,
571 const std::vector<double> &value);
572template MANTID_NEXUS_DLL void writeNumAttribute(const H5::H5Object &object, const std::string &name,
573 const std::vector<int8_t> &value);
574template MANTID_NEXUS_DLL void writeNumAttribute(const H5::H5Object &object, const std::string &name,
575 const std::vector<uint8_t> &value);
576template MANTID_NEXUS_DLL void writeNumAttribute(const H5::H5Object &object, const std::string &name,
577 const std::vector<int16_t> &value);
578template MANTID_NEXUS_DLL void writeNumAttribute(const H5::H5Object &object, const std::string &name,
579 const std::vector<uint16_t> &value);
580template MANTID_NEXUS_DLL void writeNumAttribute(const H5::H5Object &object, const std::string &name,
581 const std::vector<int32_t> &value);
582template MANTID_NEXUS_DLL void writeNumAttribute(const H5::H5Object &object, const std::string &name,
583 const std::vector<uint32_t> &value);
584template MANTID_NEXUS_DLL void writeNumAttribute(const H5::H5Object &object, const std::string &name,
585 const std::vector<int64_t> &value);
586template MANTID_NEXUS_DLL void writeNumAttribute(const H5::H5Object &object, const std::string &name,
587 const std::vector<uint64_t> &value);
588template MANTID_NEXUS_DLL void writeNumAttribute(const H5::H5Object &object, const std::string &name,
589 const std::vector<char> &value);
590
591// -------------------------------------------------------------------
592// instantiations for readNumAttributeCoerce
593// -------------------------------------------------------------------
594
595/* NOTE these instantiations are for case Narrowing::Allow
596/ To use Narrowing:Prevent, will need to instantiate and export those methods
597*/
598
599template MANTID_NEXUS_DLL float readNumAttributeCoerce(const H5::H5Object &object, const std::string &attributeName);
600template MANTID_NEXUS_DLL double readNumAttributeCoerce(const H5::H5Object &object, const std::string &attributeName);
601template MANTID_NEXUS_DLL int8_t readNumAttributeCoerce(const H5::H5Object &object, const std::string &attributeName);
602template MANTID_NEXUS_DLL uint8_t readNumAttributeCoerce(const H5::H5Object &object, const std::string &attributeName);
603template MANTID_NEXUS_DLL int16_t readNumAttributeCoerce(const H5::H5Object &object, const std::string &attributeName);
604template MANTID_NEXUS_DLL uint16_t readNumAttributeCoerce(const H5::H5Object &object, const std::string &attributeName);
605template MANTID_NEXUS_DLL int32_t readNumAttributeCoerce(const H5::H5Object &object, const std::string &attributeName);
606template MANTID_NEXUS_DLL uint32_t readNumAttributeCoerce(const H5::H5Object &object, const std::string &attributeName);
607template MANTID_NEXUS_DLL int64_t readNumAttributeCoerce(const H5::H5Object &object, const std::string &attributeName);
608template MANTID_NEXUS_DLL uint64_t readNumAttributeCoerce(const H5::H5Object &object, const std::string &attributeName);
609template MANTID_NEXUS_DLL char readNumAttributeCoerce(const H5::H5Object &object, const std::string &attributeName);
610
611// -------------------------------------------------------------------
612// instantiations for readNumArrayAttributeCoerce
613// -------------------------------------------------------------------
614
615/* NOTE these instantiations are for case Narrowing::Allow
616/ To use Narrowing:Prevent, will need to instantiate and export those methods
617*/
618
619template MANTID_NEXUS_DLL std::vector<float> readNumArrayAttributeCoerce(const H5::H5Object &object,
620 const std::string &attributeName);
621template MANTID_NEXUS_DLL std::vector<double> readNumArrayAttributeCoerce(const H5::H5Object &object,
622 const std::string &attributeName);
623template MANTID_NEXUS_DLL std::vector<int32_t> readNumArrayAttributeCoerce(const H5::H5Object &object,
624 const std::string &attributeName);
625template MANTID_NEXUS_DLL std::vector<uint32_t> readNumArrayAttributeCoerce(const H5::H5Object &object,
626 const std::string &attributeName);
627template MANTID_NEXUS_DLL std::vector<int64_t> readNumArrayAttributeCoerce(const H5::H5Object &object,
628 const std::string &attributeName);
629template MANTID_NEXUS_DLL std::vector<uint64_t> readNumArrayAttributeCoerce(const H5::H5Object &object,
630 const std::string &attributeName);
631
632// -------------------------------------------------------------------
633// instantiations for writeArray1D
634// -------------------------------------------------------------------
635
636/* NOTE these instantiations are for case Narrowing::Allow
637/ To use Narrowing:Prevent, will need to instantiate and export those methods
638*/
639
640template MANTID_NEXUS_DLL void writeArray1D(H5::Group &group, const std::string &name,
641 const std::vector<float> &values);
642template MANTID_NEXUS_DLL void writeArray1D(H5::Group &group, const std::string &name,
643 const std::vector<double> &values);
644template MANTID_NEXUS_DLL void writeArray1D(H5::Group &group, const std::string &name,
645 const std::vector<int32_t> &values);
646template MANTID_NEXUS_DLL void writeArray1D(H5::Group &group, const std::string &name,
647 const std::vector<uint32_t> &values);
648template MANTID_NEXUS_DLL void writeArray1D(H5::Group &group, const std::string &name,
649 const std::vector<int64_t> &values);
650template MANTID_NEXUS_DLL void writeArray1D(H5::Group &group, const std::string &name,
651 const std::vector<uint64_t> &values);
652
653// -------------------------------------------------------------------
654// Instantiations for writeScalarWithStrAttributes
655// -------------------------------------------------------------------
656template MANTID_NEXUS_DLL void
657writeScalarDataSetWithStrAttributes(H5::Group &group, const std::string &name, const std::string &value,
658 const std::map<std::string, std::string> &attributes);
659template MANTID_NEXUS_DLL void
660writeScalarDataSetWithStrAttributes(H5::Group &group, const std::string &name, const float &value,
661 const std::map<std::string, std::string> &attributes);
662template MANTID_NEXUS_DLL void
663writeScalarDataSetWithStrAttributes(H5::Group &group, const std::string &name, const double &value,
664 const std::map<std::string, std::string> &attributes);
665template MANTID_NEXUS_DLL void
666writeScalarDataSetWithStrAttributes(H5::Group &group, const std::string &name, const int32_t &value,
667 const std::map<std::string, std::string> &attributes);
668template MANTID_NEXUS_DLL void
669writeScalarDataSetWithStrAttributes(H5::Group &group, const std::string &name, const uint32_t &value,
670 const std::map<std::string, std::string> &attributes);
671template MANTID_NEXUS_DLL void
672writeScalarDataSetWithStrAttributes(H5::Group &group, const std::string &name, const int64_t &value,
673 const std::map<std::string, std::string> &attributes);
674template MANTID_NEXUS_DLL void
675writeScalarDataSetWithStrAttributes(H5::Group &group, const std::string &name, const uint64_t &value,
676 const std::map<std::string, std::string> &attributes);
677
678// -------------------------------------------------------------------
679// instantiations for readArray1DCoerce
680// -------------------------------------------------------------------
681template MANTID_NEXUS_DLL void readArray1DCoerce(const H5::Group &group, const std::string &name,
682 std::vector<float> &output);
683template MANTID_NEXUS_DLL void readArray1DCoerce(const H5::Group &group, const std::string &name,
684 std::vector<double> &output);
685template MANTID_NEXUS_DLL void readArray1DCoerce(const H5::Group &group, const std::string &name,
686 std::vector<int32_t> &output);
687template MANTID_NEXUS_DLL void readArray1DCoerce(const H5::Group &group, const std::string &name,
688 std::vector<uint32_t> &output);
689template MANTID_NEXUS_DLL void readArray1DCoerce(const H5::Group &group, const std::string &name,
690 std::vector<int64_t> &output);
691template MANTID_NEXUS_DLL void readArray1DCoerce(const H5::Group &group, const std::string &name,
692 std::vector<uint64_t> &output);
693
694template MANTID_NEXUS_DLL std::vector<float> readArray1DCoerce(const H5::Group &group, const std::string &name);
695template MANTID_NEXUS_DLL std::vector<double> readArray1DCoerce(const H5::Group &group, const std::string &name);
696template MANTID_NEXUS_DLL std::vector<int32_t> readArray1DCoerce(const H5::Group &group, const std::string &name);
697template MANTID_NEXUS_DLL std::vector<uint32_t> readArray1DCoerce(const H5::Group &group, const std::string &name);
698template MANTID_NEXUS_DLL std::vector<int64_t> readArray1DCoerce(const H5::Group &group, const std::string &name);
699template MANTID_NEXUS_DLL std::vector<uint64_t> readArray1DCoerce(const H5::Group &group, const std::string &name);
700
701template MANTID_NEXUS_DLL void readArray1DCoerce(const DataSet &dataset, std::vector<float> &output,
702 const size_t length, const size_t offset);
703template MANTID_NEXUS_DLL void readArray1DCoerce(const DataSet &dataset, std::vector<double> &output,
704 const size_t length, const size_t offset);
705template MANTID_NEXUS_DLL void readArray1DCoerce(const DataSet &dataset, std::vector<int8_t> &output,
706 const size_t length, const size_t offset);
707template MANTID_NEXUS_DLL void readArray1DCoerce(const DataSet &dataset, std::vector<uint8_t> &output,
708 const size_t length, const size_t offset);
709template MANTID_NEXUS_DLL void readArray1DCoerce(const DataSet &dataset, std::vector<int16_t> &output,
710 const size_t length, const size_t offset);
711template MANTID_NEXUS_DLL void readArray1DCoerce(const DataSet &dataset, std::vector<uint16_t> &output,
712 const size_t length, const size_t offset);
713template MANTID_NEXUS_DLL void readArray1DCoerce(const DataSet &dataset, std::vector<int32_t> &output,
714 const size_t length, const size_t offset);
715template MANTID_NEXUS_DLL void readArray1DCoerce(const DataSet &dataset, std::vector<uint32_t> &output,
716 const size_t length, const size_t offset);
717template MANTID_NEXUS_DLL void readArray1DCoerce(const DataSet &dataset, std::vector<int64_t> &output,
718 const size_t length, const size_t offset);
719template MANTID_NEXUS_DLL void readArray1DCoerce(const DataSet &dataset, std::vector<uint64_t> &output,
720 const size_t length, const size_t offset);
721template MANTID_NEXUS_DLL void readArray1DCoerce(const DataSet &dataset, std::vector<char> &output, const size_t length,
722 const size_t offset);
723} // namespace Mantid::Nexus::H5Util
std::string name
Definition Run.cpp:60
double value
The value of the point.
Definition FitMW.cpp:51
#define RUN_H5UTIL_FUNCTION(dataType, func_name,...)
This macro matches the dataType in terms of PredType, with the actual primitive datatype.
Definition H5Util.cpp:90
uint64_t hsize_t
#define UNUSED_ARG(x)
Function arguments are sometimes unused in certain implmentations but are required for documentation ...
Definition System.h:48
Attribute is a non-fitting parameter.
Definition IFunction.h:285
The class Group represents a set of symmetry operations (or symmetry group).
Definition Group.h:135
void information(const std::string &msg)
Logs at information level.
Definition Logger.cpp:136
A wrapper class for managing HDF5 object handles (hid_t).
Definition UniqueID.h:29
void reset(hid_t const id=INVALID_ID)
Close the existing ID and replace with the new ID; or, set to invalid.
Definition UniqueID.h:109
Kernel::Logger g_log("ExperimentInfo")
static logger object
bool exists(Nexus::File &file, const std::string &name)
Operations for help with narrowing casts.
Definition H5Util.h:30
MANTID_NEXUS_DLL DataType getType< uint64_t >()
Definition H5Util.cpp:56
MANTID_NEXUS_DLL void readStringAttribute(const H5::H5Object &object, const std::string &attributeName, std::string &output)
Definition H5Util.cpp:342
MANTID_NEXUS_DLL bool groupExists(H5::H5Object const &h5, const std::string &groupAddress)
Test if a group already exists within an HDF5 file or parent group.
Definition H5Util.cpp:484
MANTID_NEXUS_DLL std::string readString(H5::H5File &file, const std::string &address)
Definition H5Util.cpp:266
MANTID_NEXUS_DLL DataType getType< bool >()
Definition H5Util.cpp:62
void writeArray1D(H5::Group &group, const std::string &name, const std::vector< NumT > &values)
MANTID_NEXUS_DLL void writeStrAttribute(const H5::H5Object &object, const std::string &name, const std::string &value)
Definition H5Util.cpp:208
MANTID_NEXUS_DLL bool hasAttribute(const H5::H5Object &object, const char *attributeName)
Definition H5Util.cpp:337
MANTID_NEXUS_DLL H5::FileAccPropList defaultFileAcc()
Default file access is H5F_CLOSE_STRONG.
Definition H5Util.cpp:119
void writeNumAttribute(const H5::H5Object &object, const std::string &name, const NumT &value)
Definition H5Util.cpp:216
MANTID_NEXUS_DLL bool isHdf5(std::string const &filename)
Determine if a given file can be opened with HDF5 using the CORRECT file access level (H5F_CLOSE_STRO...
Definition H5Util.cpp:125
MANTID_NEXUS_DLL H5::DataSpace getDataSpace(const size_t length)
Create a 1D data-space to hold data of length.
Definition H5Util.cpp:143
MANTID_NEXUS_DLL void deleteObjectLink(H5::H5Object &h5, const std::string &target)
Delete a target link for a group or dataset from a parent group.
Definition H5Util.cpp:532
MANTID_NEXUS_DLL DataType getType< uint8_t >()
Definition H5Util.cpp:44
MANTID_NEXUS_DLL DataType getType< int64_t >()
Definition H5Util.cpp:54
MANTID_NEXUS_DLL DataType getType< char >()
Definition H5Util.cpp:58
std::vector< NumT > readNumArrayAttributeCoerce(const H5::H5Object &object, const std::string &attributeName)
Read a numerical array from an attribute, coerced to type of OutT.
Definition H5Util.cpp:441
MANTID_NEXUS_DLL DataType getType< std::string >()
Definition H5Util.cpp:60
MANTID_NEXUS_DLL DataType getType< uint32_t >()
Definition H5Util.cpp:52
MANTID_NEXUS_DLL H5::Group createGroupCanSAS(H5::Group &group, const std::string &name, const std::string &nxtype, const std::string &cstype)
NumT readNumAttributeCoerce(const H5::H5Object &object, const std::string &attributeName)
Read a single quantity from an attribute, coerced to type of OutT.
Definition H5Util.cpp:427
MANTID_NEXUS_DLL bool keyHasValue(H5::H5Object const &h5, const std::string &key, const std::string &value)
Test if an attribute is present and has a specific string value for an HDF5 group or dataset.
Definition H5Util.cpp:496
MANTID_NEXUS_DLL H5::Group createGroupNXS(H5::H5File &file, const std::string &name, const std::string &nxtype)
MANTID_NEXUS_DLL DataType getType< int8_t >()
Definition H5Util.cpp:42
void readArray1DCoerce(const H5::Group &group, const std::string &name, std::vector< NumT > &output)
MANTID_NEXUS_DLL DataType getType< float >()
Definition H5Util.cpp:38
MANTID_NEXUS_DLL DataType getType< double >()
Definition H5Util.cpp:40
MANTID_NEXUS_DLL void copyGroup(H5::H5Object &dest, const std::string &destGroupAddress, H5::H5Object &src, const std::string &srcGroupAddress)
Copy a group and all of its contents, between the same or different HDF5 files or groups.
Definition H5Util.cpp:510
H5::DataType getType()
Convert a primitive type to the appropriate H5::DataType.
Definition H5Util.cpp:36
MANTID_NEXUS_DLL DataType getType< uint16_t >()
Definition H5Util.cpp:48
MANTID_NEXUS_DLL std::vector< std::string > readStringVector(H5::Group &, const std::string &)
MANTID_NEXUS_DLL void write(H5::Group &group, const std::string &name, const std::string &value)
void writeScalarDataSetWithStrAttributes(H5::Group &group, const std::string &name, const T &value, const std::map< std::string, std::string > &attributes)
Definition H5Util.cpp:244
MANTID_NEXUS_DLL DataType getType< int32_t >()
Definition H5Util.cpp:50
MANTID_NEXUS_DLL H5::DSetCreatPropList setCompressionAttributes(const std::size_t length, const int deflateLevel=6)
Sets up the chunking and compression rate.
Definition H5Util.cpp:200
MANTID_NEXUS_DLL DataType getType< int16_t >()
Definition H5Util.cpp:46