isce3 0.25.0
Loading...
Searching...
No Matches
IH5.icc
1#if !defined(ISCE_IO_IH5_ICC)
2#error "IH5.icc is an implementation detail of class IDataset/IGroup/IH5File"
3#endif
4
5#include <type_traits>
6
7namespace {
8using namespace H5;
9using DT = DataType;
10using PT = PredType;
11using namespace isce3::core;
12
13inline DT getH5StrType(size_t strlen) {
14 // HDF5 doesn't seem to support zero-length strings.
15 if (strlen == 0) {
16 throw isce3::except::InvalidArgument(ISCE_SRCINFO(),
17 "string length must be > 0");
18 }
19 return StrType(PT::C_S1, strlen);
20}
21
22inline DT getH5Type(const std::string& str) { return getH5StrType(str.size()); }
23
24template<typename T> DT getH5Type();
25
26template<> inline DT getH5Type<char>() { return PT::NATIVE_CHAR; }
27template<> inline DT getH5Type<signed char>() { return PT::NATIVE_UCHAR; }
28template<> inline DT getH5Type<unsigned char>() { return PT::NATIVE_SCHAR; }
29template<> inline DT getH5Type<short>() { return PT::NATIVE_SHORT; }
30template<> inline DT getH5Type<unsigned short>() { return PT::NATIVE_USHORT; }
31template<> inline DT getH5Type<int>() { return PT::NATIVE_INT; }
32template<> inline DT getH5Type<unsigned int>() { return PT::NATIVE_UINT; }
33template<> inline DT getH5Type<long>() { return PT::NATIVE_LONG; }
34template<> inline DT getH5Type<unsigned long>() { return PT::NATIVE_ULONG; }
35template<> inline DT getH5Type<long long>() { return PT::NATIVE_LLONG; }
36template<> inline DT getH5Type<float>() { return PT::NATIVE_FLOAT; }
37template<> inline DT getH5Type<double>() { return PT::NATIVE_DOUBLE; }
38template<> inline DT getH5Type<long double>() { return PT::NATIVE_LDOUBLE; }
39
40template<typename T> inline DT getH5Type() {
41
42 // Disallow usage for string or char[] objects. We need to know the length of the
43 // string in order to construct an appropriate H5::DataType.
44 using U = std::decay_t<T>;
45 static_assert(!std::is_same<U, std::string>(),
46 "getH5Type<std::string>() is not supported -- use"
47 " getH5Type(const std::string&) instead");
48 static_assert(!std::is_same<U, char*>(),
49 "getH5Type<char*>() is not supported -- use"
50 " getH5Type(const std::string&) instead");
51
52 if (std::is_same<T, isce3::io::n1bit>()) {
53 H5::IntType datatype(H5::PredType::NATIVE_UINT8);
54 datatype.setOffset(0);
55 datatype.setPrecision(1);
56 return datatype;
57 }
58 if (std::is_same<T, isce3::io::n2bit>()) {
59 H5::IntType datatype(H5::PredType::NATIVE_UINT8);
60 datatype.setOffset(0);
61 datatype.setPrecision(2);
62 return datatype;
63 }
64 if (std::is_same<T, isce3::io::float16>()) {
65 H5::FloatType datatype(H5::PredType::NATIVE_FLOAT);
66 datatype.setFields(15, 10, 5, 0, 10);
67 datatype.setOffset(0);
68 datatype.setPrecision(16);
69 datatype.setEbias(15);
70 datatype.setInpad(H5T_PAD_ZERO);
71 return datatype;
72 }
73 if (std::is_same<T, std::complex<float>>()) {
74 H5::CompType comp(2 * sizeof(float));
75 comp.insertMember("r", 0, H5::PredType::NATIVE_FLOAT);
76 comp.insertMember("i", sizeof(float), H5::PredType::NATIVE_FLOAT);
77 return comp;
78 }
79 if (std::is_same<T, std::complex<short>>()) {
80 H5::CompType comp(2 * sizeof(short));
81 comp.insertMember("r", 0, H5::PredType::NATIVE_SHORT);
82 comp.insertMember("i", sizeof(short), H5::PredType::NATIVE_SHORT);
83 return comp;
84 }
85 if (std::is_same<T, std::complex<int>>()) {
86 H5::CompType comp(2 * sizeof(int));
87 comp.insertMember("r", 0, H5::PredType::NATIVE_INT);
88 comp.insertMember("i", sizeof(int), H5::PredType::NATIVE_INT);
89 return comp;
90 }
91 if (std::is_same<T, std::complex<isce3::io::float16>>()) {
92 H5::FloatType datatype(H5::PredType::NATIVE_FLOAT);
93 datatype.setFields(15, 10, 5, 0, 10);
94 datatype.setOffset(0);
95 datatype.setPrecision(16);
96 datatype.setEbias(15);
97 datatype.setInpad(H5T_PAD_ZERO);
98
99 H5::CompType comp(2 * sizeof(float));
100 comp.insertMember("r", 0, datatype);
101 comp.insertMember("i", sizeof(float), datatype);
102 return comp;
103 }
104 if (std::is_same<T, std::complex<double>>()) {
105 H5::CompType comp(2 * sizeof(double));
106 comp.insertMember("r", 0, H5::PredType::NATIVE_DOUBLE);
107 comp.insertMember("i", sizeof(double), H5::PredType::NATIVE_DOUBLE);
108 return comp;
109 }
110 throw isce3::except::InvalidArgument(
111 ISCE_SRCINFO(), "Type '" + std::string(typeid(T).name()) +
112 "' unrecognized for H5 container");
113}
114} // namespace
115
116template<typename T> inline H5::DataSpace getMemorySpace(const T nbElements) {
117 // Create a memory dataSpace describing the dataspace of the memory buffer
118 // that will receive the data. It's set up as a 1D array.
119 hsize_t memDims[1] = {static_cast<hsize_t>(nbElements)};
120 return H5::DataSpace(1, memDims);
121}
122
123template<typename T, size_t S>
124inline H5::DataSpace getMemorySpace(const std::array<T, S>& dims) {
125 // Create a memory dataSpace describing the dataspace of the memory buffer
126 hsize_t mem_dims[S];
127 for (int i = 0; i < S; i++)
128 mem_dims[i] = static_cast<hsize_t>(dims[i]);
129
130 return H5::DataSpace(S, mem_dims);
131}
132
133// TODO: All "read" functions below need some templating to tighten the code
134
142template<typename T>
143void isce3::io::IDataSet::read(T& v, const std::string& att) {
144
145 // Check that the parameter that will receive the data read from the file
146 // is a numeric variable
147 // static_assert(std::is_arithmetic<T>::value, "Expected a numeric scalar");
148
149 // Check that the dataset/attribute contains a scalar, i.e., rank=0
150 if (getRank(att) != 0)
151 throw isce3::except::InvalidArgument(ISCE_SRCINFO(),
152 "Dataset/attribute must be scalar");
153
154 if (att.empty()) {
155 H5::DataSet::read(&v, getH5Type<T>());
156 return;
157 }
158
159 if (not attrExists(att)) {
160 throw isce3::except::InvalidArgument(
161 ISCE_SRCINFO(), "Attribute '" + att + "' not found");
162 }
163
164 // Read the attribute from file
165 // Order of parameter is reversed compared to dataset read
166 openAttribute(att).read(getH5Type<T>(), &v);
167}
168
192// TODO: check what happen if starts is set but no count - countis defaults to
193// full which should be larger than what's available given start
194
195template<typename T>
196void isce3::io::IDataSet::read(T* buffer, const int* start, const int* count,
197 const int* stride) {
198 // Read dataset subset to memory
199 read(buffer, getDataSpace(start, count, stride));
200}
201
207template<typename T>
209 const std::vector<std::slice>* slices) {
210 // Read dataset subset to memory
211 read(buffer, getDataSpace(slices));
212}
213
218template<typename T>
219void isce3::io::IDataSet::read(T* buffer, const std::gslice* gsliceIn) {
220 // Read dataset subset to memory
221 read(buffer, getDataSpace(gsliceIn));
222}
223
228template<typename T>
229void isce3::io::IDataSet::read(T* buffer, const H5::DataSpace& dspace) {
230 // Check that the selection is valid (no out of bound)
231 if (not dspace.selectValid()) {
232 throw isce3::except::InvalidArgument(ISCE_SRCINFO(),
233 "Invalid dataset subselection");
234 }
235
236 // Get total number of elements to read
237 const hssize_t nbElements = dspace.getSelectNpoints();
238
239 // Format the dataspace of the memory to receive the data read from file
240 const H5::DataSpace memspace = getMemorySpace((hsize_t) nbElements);
241
242 // Read the dataset to memory
243 H5::DataSet::read(buffer, getH5Type<T>(), memspace, dspace);
244}
245
252template<typename T> void isce3::io::IDataSet::read(std::vector<T>& buffer) {
253 read(buffer, nullptr, nullptr, nullptr);
254}
255
274template<typename T>
275void isce3::io::IDataSet::read(std::vector<T>& buffer,
276 const std::vector<int>* start,
277 const std::vector<int>* count,
278 const std::vector<int>* stride) {
279
280 // Format a dataspace according to the input parameters
281 const auto dspace = getDataSpace(start ? start->data() : nullptr,
282 count ? count->data() : nullptr,
283 stride ? stride->data() : nullptr);
284
285 // Check that vector is sized correctly. Adjust size if necessary
286 if (buffer.size() < dspace.getSelectNpoints())
287 buffer.resize(dspace.getSelectNpoints());
288
289 // Read the data to memory
290 read(buffer.data(), dspace);
291}
292
301template<typename T>
302void isce3::io::IDataSet::read(std::vector<T>& buffer,
303 const std::vector<std::slice>* slices) {
304
305 // Format a dataspace according to the input parameters
306 H5::DataSpace dspace = getDataSpace(slices);
307
308 // Check that vector is sized correctly. Adjust size if necessary
309 if (buffer.size() < dspace.getSelectNpoints())
310 buffer.resize(dspace.getSelectNpoints());
311
312 // Read the dataset to memory
313 read(buffer.data(), dspace);
314}
315
323template<typename T>
324void isce3::io::IDataSet::read(std::vector<T>& buffer,
325 const std::gslice* gsliceIn) {
326
327 // Format a dataspace according to the input parameters
328 H5::DataSpace dspace = getDataSpace(gsliceIn);
329
330 // Check that vector is sized correctly. Adjust size if necessary
331 if (buffer.size() < dspace.getSelectNpoints())
332 buffer.resize(dspace.getSelectNpoints());
333
334 // Read the dataset to memory
335 read(buffer.data(), dspace);
336}
337
344template<typename T> void isce3::io::IDataSet::read(std::valarray<T>& buffer) {
345 read(buffer, nullptr, nullptr, nullptr);
346}
347
366template<typename T>
367void isce3::io::IDataSet::read(std::valarray<T>& buffer,
368 const std::valarray<int>* start,
369 const std::valarray<int>* count,
370 const std::valarray<int>* stride) {
371
372 // Format a dataspace according to the input parameters
373 H5::DataSpace dspace = getDataSpace(start ? &(*start)[0] : nullptr,
374 count ? &(*count)[0] : nullptr,
375 stride ? &(*stride)[0] : nullptr);
376
377 // Check that vector is sized correctly. Adjust size if necessary
378 if (buffer.size() < dspace.getSelectNpoints())
379 buffer.resize(dspace.getSelectNpoints());
380
381 // Read the dataset to memory
382 read(&buffer[0], dspace);
383}
384
393template<typename T>
394void isce3::io::IDataSet::read(std::valarray<T>& buffer,
395 const std::vector<std::slice>* slicesIn) {
396
397 // Format a dataspace according to the input parameters
398 H5::DataSpace dspace = getDataSpace(slicesIn);
399
400 // Check that vector is sized correctly. Adjust size if necessary
401 if (buffer.size() < dspace.getSelectNpoints())
402 buffer.resize(dspace.getSelectNpoints());
403
404 // Read the dataset to memory
405 read(&buffer[0], dspace);
406}
407
415template<typename T>
416void isce3::io::IDataSet::read(std::valarray<T>& buffer,
417 const std::gslice* gsliceIn) {
418
419 // Format a dataspace according to the input parameters
420 H5::DataSpace dspace = getDataSpace(gsliceIn);
421
422 // Check that vector is sized correctly. Adjust size if necessary
423 if (buffer.size() < dspace.getSelectNpoints())
424 buffer.resize(dspace.getSelectNpoints());
425
426 // Read the dataset to memory
427 read(&buffer[0], dspace);
428}
429
434template<typename T>
435void isce3::io::IDataSet::read(T* buffer, const std::string& att) {
436
437 // Check that attribute name is not null or empty
438 if (not attrExists(att)) {
439 throw isce3::except::InvalidArgument(
440 ISCE_SRCINFO(), "Attribute '" + att + "' not found");
441 }
442
443 // read(buffer, getH5Type<T>(), att);
444 // read(buffer, att);
445
446 // Open the attribute
447 H5::Attribute a = openAttribute(att);
448
449 // Read the dataset to memory
450 a.read(getH5Type<T>(), buffer);
451}
452
460template<typename T>
461void isce3::io::IDataSet::read(std::vector<T>& buffer, const std::string& att) {
462
463 if (not attrExists(att)) {
464 throw isce3::except::InvalidArgument(
465 ISCE_SRCINFO(), "Attribute '" + att + "' not found");
466 }
467
468 if (buffer.size() < getNumElements(att))
469 buffer.resize(getNumElements(att));
470
471 // read((T*)buffer.data(), getH5Type<T>(), att);
472 read((T*) buffer.data(), att);
473}
474
482template<typename T>
483void isce3::io::IDataSet::read(std::valarray<T>& buffer,
484 const std::string& att) {
485
486 if (not attrExists(att)) {
487 throw isce3::except::InvalidArgument(
488 ISCE_SRCINFO(), "Attribute '" + att + "' not found");
489 }
490
491 if (buffer.size() < getNumElements(att))
492 buffer.resize(getNumElements(att));
493
494 // read((T*)&buffer[0], getH5Type<T>(), att);
495 read((T*) &buffer[0], att);
496}
497
502template<typename T>
503void isce3::io::IDataSet::write(const T* buf, const H5::DataSpace& dspace) {
504
505 // Check that the selection is valid (no out of bound)
506 if (!dspace.selectValid()) {
507 throw isce3::except::InvalidArgument(ISCE_SRCINFO(),
508 "Invalid dataset subselection");
509 }
510
511 // Construct the memory dataspace (i.e., dataspace of buf). For now, and
512 // that may change in a the future, there is no possibility to subset buf.
513 // The full content of buf is to be selected. Buf dataspace is set to a 1D
514 // array of size equals to the number of elements in the vector.
515 H5::DataSpace mspace = getMemorySpace(dspace.getSelectNpoints());
516
517 // write the data to dataset
518 H5::DataSet::write(buf, getH5Type<T>(), mspace, dspace);
519}
520
525template<typename T> void isce3::io::IDataSet::write(const std::vector<T>& buf) {
526 // Construct the dataSpace of the file dataset. It's the full size dataset
527 H5::DataSpace dspace = getSpace();
528
529 if (buf.size() != dspace.getSelectNpoints()) {
530 throw isce3::except::InvalidArgument(
531 ISCE_SRCINFO(), "Vector container does not have same number of "
532 "elements as dataset");
533 }
534
535 write(buf.data(), dspace);
536}
537
546template<typename T, size_t S>
547void isce3::io::IDataSet::write(const std::vector<T>& buf,
548 const std::array<int, S>& start,
549 const std::array<int, S>& count,
550 const std::array<int, S>& stride) {
551
552 // Construct the dataSpace of the file dataset, based on input parameters.
553 // Contrary to the memory dataspace, specific parts of the file dataset can
554 // be selected for writing into.
555 H5::DataSpace dspace =
556 getDataSpace(start.data(), count.data(), stride.data());
557
558 write(buf.data(), dspace);
559}
560
565template<typename T>
566void isce3::io::IDataSet::write(const std::vector<T>& buf,
567 const std::vector<std::slice>* slicesIn) {
568
569 // Construct the dataSpace of the file dataset, based on input parameters.
570 // Contrary to the memory dataspace, specific parts of the file dataset can
571 // be selected for writing into.
572 H5::DataSpace dspace = getDataSpace(slicesIn);
573
574 write(buf.data(), dspace);
575}
576
580template<typename T>
581void isce3::io::IDataSet::write(const std::vector<T>& buf,
582 const std::gslice* gsliceIn) {
583
584 // Construct the dataSpace of the file dataset, based on input parameters.
585 // Contrary to the memory dataspace, specific parts of the file dataset can
586 // be selected for writing into.
587 H5::DataSpace dspace = getDataSpace(gsliceIn);
588
589 write(buf.data(), dspace);
590}
591
596template<typename T>
597void isce3::io::IDataSet::write(const std::valarray<T>& buf) {
598 // Construct the dataSpace of the file dataset. It's the full size dataset
599 H5::DataSpace dspace = getSpace();
600
601 if (buf.size() != dspace.getSelectNpoints()) {
602 throw isce3::except::InvalidArgument(
603 ISCE_SRCINFO(), "Valarray container does not have same number "
604 "of elements as dataset");
605 }
606
607 write(&buf[0], dspace);
608}
609
618template<typename T, size_t S>
619void isce3::io::IDataSet::write(const std::valarray<T>& buf,
620 const std::array<int, S>& startIn,
621 const std::array<int, S>& countIn,
622 const std::array<int, S>& strideIn) {
623
624 // Construct the dataSpace of the file dataset, based on input parameters.
625 // Contrary to the memory dataspace, specific parts of the file dataset can
626 // be selected for writing into.
627 H5::DataSpace dspace =
628 getDataSpace(startIn.data(), countIn.data(), strideIn.data());
629 write(&buf[0], dspace);
630}
631
636template<typename T>
637void isce3::io::IDataSet::write(const std::valarray<T>& buf,
638 const std::vector<std::slice>* slicesIn) {
639
640 // Construct the dataSpace of the file dataset, based on input parameters.
641 // Contrary to the memory dataspace, specific parts of the file dataset can
642 // be selected for writing into.
643 write(&buf[0], getDataSpace(slicesIn));
644}
645
649template<typename T>
650void isce3::io::IDataSet::write(const std::valarray<T>& buf,
651 const std::gslice* gsliceIn) {
652
653 // Construct the dataSpace of the file dataset, based on input parameters.
654 // Contrary to the memory dataspace, specific parts of the file dataset can
655 // be selected for writing into.
656 write(&buf[0], getDataSpace(gsliceIn));
657}
658
662template<typename T>
663void isce3::io::IDataSet::write(const T* buf, const size_t sz) {
664
665 // Construct the dataSpace of the file dataset. It's the full size dataset
666 H5::DataSpace dspace = getSpace();
667
668 if (sz != dspace.getSelectNpoints()) {
669 throw isce3::except::InvalidArgument(
670 ISCE_SRCINFO(), "Buffer size does not match dataset size");
671 }
672
673 write(buf, dspace);
674}
675
688template<typename T, size_t S>
689void isce3::io::IDataSet::write(const T* buf, const std::array<int, S>& startIn,
690 const std::array<int, S>& countIn,
691 const std::array<int, S>& strideIn) {
692
693 // Construct the dataSpace of the file dataset, based on input parameters.
694 // Contrary to the memory dataspace, specific parts of the file dataset can
695 // be selected for writing into.
696 H5::DataSpace dspace =
697 getDataSpace(startIn.data(), countIn.data(), strideIn.data());
698
699 write(buf, dspace);
700
701 dspace.close();
702}
703
712template<typename T>
714 const std::vector<std::slice>* slicesIn) {
715 // Construct the dataSpace of the file dataset, based on inputs. Contrary to
716 // the memory dataspace, specific parts of the file dataset can be selected
717 // for writing into.
718 write(buf, getDataSpace(slicesIn));
719}
720
728template<typename T>
729void isce3::io::IDataSet::write(const T* buf, const std::gslice* gsliceIn) {
730 // Construct the dataSpace of the file dataset, based on inputs. Contrary to
731 // the memory dataspace, specific parts of the file dataset can be selected
732 // for writing into.
733 write(buf, getDataSpace(gsliceIn));
734}
735
745template<typename T>
746void isce3::io::IDataSet::createAttribute(const std::string& name,
747 const H5::DataType& datatype,
748 const H5::DataSpace& dataspace,
749 const T* buffer) {
750
751 if (name.empty()) {
752 throw isce3::except::InvalidArgument(ISCE_SRCINFO(),
753 "Attribute name cannot be empty");
754 }
755 if (attrExists(name.c_str())) {
756 throw isce3::except::InvalidArgument(
757 ISCE_SRCINFO(), "Attribute '" + name + "' already exists");
758 }
759
760 // Create the attribute and write its data.
761 H5::H5Object::createAttribute(name, datatype, dataspace)
762 .write(datatype, buffer);
763}
764
770template<typename T, typename T2, size_t S>
771inline void isce3::io::IDataSet::createAttribute(const std::string& name,
772 const std::array<T2, S>& dims,
773 const std::vector<T>& buffer) {
774
775 createAttribute(name, getH5Type<T>(), getMemorySpace(dims), buffer.data());
776}
777
783template<typename T, typename T2, size_t S>
784inline void
786 const std::array<T2, S>& dims,
787 const std::valarray<T>& buffer) {
788
789 createAttribute(name, getH5Type<T>(), getMemorySpace(dims), &buffer[0]);
790}
791
797template<typename T, typename T2, size_t S>
798inline void isce3::io::IDataSet::createAttribute(const std::string& name,
799 const std::array<T2, S>& dims,
800 const T* buffer) {
801
802 createAttribute(name, getH5Type<T>(), getMemorySpace(dims), buffer);
803}
804
811template<typename T>
812inline void isce3::io::IDataSet::createAttribute(const std::string& name,
813 const std::vector<T>& data) {
814
815 std::array<hsize_t, 1> dims = {static_cast<hsize_t>(data.size())};
816 createAttribute(name, dims, data);
817}
818
825template<typename T>
826inline void isce3::io::IDataSet::createAttribute(const std::string& name,
827 const std::valarray<T>& data) {
828 std::array<hsize_t, 1> dims = {static_cast<hsize_t>(data.size())};
829 createAttribute(name, dims, data);
830}
831
836template<typename T>
837inline void isce3::io::IDataSet::createAttribute(const std::string& name,
838 const T& data) {
839
840 createAttribute(name, getH5Type<T>(), H5::DataSpace(), &data);
841}
842
843namespace isce3 { namespace io {
844
849template<>
850inline void IDataSet::createAttribute(const std::string& name,
851 const std::string& data) {
852
853 createAttribute(name, getH5Type(data), H5::DataSpace(),
854 data.c_str());
855}
856
857}}
858
865template<typename T> void isce3::io::IGroup::read(T& v, const std::string& att) {
866 // Check that the parameter that will receive the data read from the file
867 // is a numeric variable
868 // static_assert(std::is_arithmetic<T>::value, "Expected a numeric scalar");
869 if (not attrExists(att)) {
870 throw isce3::except::InvalidArgument(
871 ISCE_SRCINFO(), "Attribute '" + att + "' not found");
872 }
873 // Open the attribute
874 H5::Attribute a = openAttribute(att);
875
876 // Get the dataSpace of the attribute
877 H5::DataSpace dspace = a.getSpace();
878
879 // If attribute contains a scalar or a 1-element array, read the attribute's
880 // value
881 if (dspace.getSimpleExtentNdims() != 0) {
882 throw isce3::except::InvalidArgument(ISCE_SRCINFO(),
883 "Dataset/attribute must be scalar");
884 }
885
886 a.read(getH5Type<T>(), &v);
887}
888
893template<typename T>
894void isce3::io::IGroup::read(T* buffer, const std::string& att) {
895
896 // Check that attribute name is not null or empty
897 if (not attrExists(att)) {
898 throw isce3::except::InvalidArgument(
899 ISCE_SRCINFO(), "Attribute '" + att + "' not found");
900 }
901
902 openAttribute(att).read(getH5Type<T>(), buffer);
903}
904
912template<typename T>
913void isce3::io::IGroup::read(std::vector<T>& buffer, const std::string& att) {
914
915 if (not attrExists(att)) {
916 throw isce3::except::InvalidArgument(
917 ISCE_SRCINFO(), "Attribute '" + att + "' not found");
918 }
919
920 if (buffer.size() < getNumElements(att))
921 buffer.resize(getNumElements(att));
922
923 read(buffer.data(), att);
924}
925
933template<typename T>
934void isce3::io::IGroup::read(std::valarray<T>& buffer, const std::string& att) {
935
936 if (not attrExists(att)) {
937 throw isce3::except::InvalidArgument(
938 ISCE_SRCINFO(), "Attribute '" + att + "' does not exist");
939 }
940
941 if (buffer.size() < getNumElements(att))
942 buffer.resize(getNumElements(att));
943
944 read(&buffer[0], att);
945}
946
953template<typename T>
955isce3::io::IGroup::createDataSet(const std::string& name, const T& data) {
956
957 const auto dtype = getH5Type<T>();
958 H5::DataSet dset = H5::Group::createDataSet(name, dtype, H5::DataSpace());
959 dset.write(&data, dtype);
960 return dset;
961}
962
971template<typename T>
973isce3::io::IGroup::createDataSet(const std::string& name,
974 const std::vector<T>& data) {
975
976 // Default to 1D array dataset with this interface
977 std::array<hsize_t, 1> dims {{data.size()}};
978 return createDataSet(name, data, dims);
979}
980
989template<typename T>
991isce3::io::IGroup::createDataSet(const std::string& name,
992 const std::valarray<T>& data) {
993
994 // Default to 1D array dataset with this interface
995 std::array<hsize_t, 1> dims {{data.size()}};
996 return createDataSet(name, data, dims);
997}
998
1007template<typename T>
1009isce3::io::IGroup::createDataSet(const std::string& name, const T* data,
1010 const size_t sz) {
1011
1012 // Default to 1D array dataset with this interface
1013 std::array<hsize_t, 1> dims {{sz}};
1014
1015 return createDataSet(name, data, dims);
1016}
1017
1025template<typename T, typename T2, size_t S>
1027isce3::io::IGroup::createDataSet(const std::string& name,
1028 const std::vector<T>& data,
1029 const std::array<T2, S>& dims) {
1030
1031 IDataSet dset = createDataSet<T>(name, dims);
1032 dset.write(data);
1033 return dset;
1034}
1035
1043template<typename T, typename T2, size_t S>
1045isce3::io::IGroup::createDataSet(const std::string& name,
1046 const std::valarray<T>& data,
1047 const std::array<T2, S>& dims) {
1048
1049 IDataSet dset = createDataSet<T>(name, dims);
1050 dset.write(data);
1051 return dset;
1052}
1053
1061template<typename T, typename T2, size_t S>
1063isce3::io::IGroup::createDataSet(const std::string& name, const T* data,
1064 const std::array<T2, S>& dims) {
1065
1066 IDataSet dset = createDataSet<T>(name, dims);
1067 dset.write(data, dset.getSpace().getSimpleExtentNpoints());
1068 return dset;
1069}
1070
1086template<typename T, typename T2, size_t S>
1088isce3::io::IGroup::createDataSet(const std::string& name,
1089 const std::array<T2, S>& dims, const int chunk,
1090 const int shuffle, const int deflate) {
1091
1092 if (name.empty()) {
1093 throw isce3::except::InvalidArgument(ISCE_SRCINFO(),
1094 "Attribute name cannot be empty");
1095 }
1096
1097 // Create the dataspace
1098 std::vector<hsize_t> dims2(dims.size());
1099 for (int i = 0; i < dims.size(); i++)
1100 dims2[i] = (hsize_t) dims[i];
1101 H5::DataSpace dataSpace((int) dims.size(), dims2.data());
1102
1103 // Create the dataset creation properties.
1104 H5::DSetCreatPropList cparms;
1105
1106 // Adjust dataset creation properties if necessary. This is only the case if
1107 // one of the three last parameters is activated (!=0).
1108 if (chunk != 0 || shuffle != 0 || deflate != 0) {
1109
1110 // No matter which option was used, chunking is mandatory. Only chunk
1111 // the first 2 dimensions, which corresponds to X, Y. The third
1112 // dimension (the "band" one) and others doe not get chunked
1113 std::vector<hsize_t> chunks(dims.size());
1114 std::fill_n(chunks.data(), dims.size(), 1);
1115 chunks[0] = chunkSizeX;
1116 if (dims.size() > 1)
1117 chunks[1] = chunkSizeY;
1118 cparms.setChunk(dims.size(), chunks.data());
1119
1120 // Set the NBIT compression.
1121 // Only if the datatype is of nbit precision (float16, complex
1122 // float16,..). Otherwise tests show degraded compression performance
1123 if (std::is_same<T, isce3::io::float16>::value or
1124 std::is_same<T, std::complex<isce3::io::float16>>::value or
1125 std::is_same<T, isce3::io::n1bit>::value or
1126 std::is_same<T, isce3::io::n2bit>::value)
1127 cparms.setNbit();
1128
1129 // Set the byte shuffling if asked for
1130 if (shuffle != 0)
1131 cparms.setShuffle();
1132
1133 // Set the compression level if asked for
1134 if (deflate != 0) {
1135 if (deflate < 0) {
1136 std::cout << "Dataset Deflate compression factor should be "
1137 "[0..9] - defaulting to 0"
1138 << std::endl;
1139 cparms.setDeflate(0);
1140 } else if (deflate > 9) {
1141 std::cout << "Dataset Deflate compression factor should be "
1142 "[0..9] - defaulting to 9"
1143 << std::endl;
1144 cparms.setDeflate(9);
1145 } else
1146 cparms.setDeflate(deflate);
1147 }
1148 }
1149
1150 // Create the dataset
1151 return H5::Group::createDataSet(name, getH5Type<T>(), dataSpace, cparms);
1152}
1153
1163template<typename T>
1164void isce3::io::IGroup::createAttribute(const std::string& name,
1165 const H5::DataType& datatype,
1166 const H5::DataSpace& dataspace,
1167 const T* buffer) {
1168
1169 if (name.empty()) {
1170 throw isce3::except::InvalidArgument(ISCE_SRCINFO(),
1171 "Attribute name cannot be empty");
1172 }
1173
1174 if (attrExists(name.c_str())) {
1175 throw isce3::except::InvalidArgument(
1176 ISCE_SRCINFO(), "Attribute '" + name + "' already exists");
1177 }
1178
1179 // Create the attribute and write its data.
1180 H5::H5Object::createAttribute(name, datatype, dataspace)
1181 .write(datatype, buffer);
1182}
1183
1189template<typename T, typename T2, size_t S>
1190inline void isce3::io::IGroup::createAttribute(const std::string& name,
1191 const std::array<T2, S>& dims,
1192 const std::vector<T>& buffer) {
1193 createAttribute(name, getH5Type<T>(), getMemorySpace(dims), buffer.data());
1194}
1195
1201template<typename T, typename T2, size_t S>
1202inline void isce3::io::IGroup::createAttribute(const std::string& name,
1203 const std::array<T2, S>& dims,
1204 const std::valarray<T>& buffer) {
1205 createAttribute(name, getH5Type<T>(), getMemorySpace(dims), &buffer[0]);
1206}
1207
1213template<typename T, typename T2, size_t S>
1214inline void isce3::io::IGroup::createAttribute(const std::string& name,
1215 const std::array<T2, S>& dims,
1216 const T* buffer) {
1217 createAttribute(name, getH5Type<T>(), getMemorySpace(dims), buffer);
1218}
1219
1226template<typename T>
1227inline void isce3::io::IGroup::createAttribute(const std::string& name,
1228 const std::vector<T>& data) {
1229 std::array<hsize_t, 1> dims = {static_cast<hsize_t>(data.size())};
1230 createAttribute(name, dims, data);
1231}
1232
1239template<typename T>
1240inline void isce3::io::IGroup::createAttribute(const std::string& name,
1241 const std::valarray<T>& data) {
1242 std::array<hsize_t, 1> dims = {static_cast<hsize_t>(data.size())};
1243 createAttribute(name, dims, data);
1244}
1245
1250template<typename T>
1251inline void isce3::io::IGroup::createAttribute(const std::string& name,
1252 const T& data) {
1253 createAttribute(name, getH5Type<T>(), H5::DataSpace(), &data);
1254}
1255
1256namespace isce3 { namespace io {
1257
1262template<>
1263inline void IGroup::createAttribute(const std::string& name,
1264 const std::string& data) {
1265 createAttribute(name, getH5Type(data), H5::DataSpace(),
1266 data.c_str());
1267}
1268
1269}}
Our derived dataset structure that includes utility functions.
Definition IH5.h:41
void write(const std::vector< T > &buf)
Writing std::vector data into a dataset.
Definition IH5.icc:525
H5::DataSpace getDataSpace(const std::string &v="")
Get a HDF5 DataSpace object corresponding to dataset or given attribute.
Definition IH5.cpp:127
void read(T &v, const std::string &att="")
Reading scalar (non string) dataset or attributes.
Definition IH5.icc:143
int getNumElements(const std::string &v="")
Get the total number of elements contained in dataset or given attribute.
Definition IH5.cpp:160
int getRank(const std::string &v="")
Get the number of dimension of dataset or given attribute.
Definition IH5.cpp:150
void createAttribute(const std::string &name, const T &data)
Creating and writing a scalar as an attribute.
Definition IH5.icc:837
IDataSet createDataSet(const std::string &name, const std::string &data)
Create a string scalar dataset and simultaneously write the data.
Definition IH5.cpp:782
int getNumElements(const std::string &name)
Return the number of elements in the given attribute.
Definition IH5.cpp:701
void createAttribute(const std::string &name, const T &data)
Creating and writing a scalar as an attribute.
Definition IH5.icc:1251
void read(T &v, const std::string &att)
Reading scalar attribute given by name.
Definition IH5.icc:865
The isce3::io namespace.
Definition Constants.h:14
base interpolator is an abstract base class
Definition BinarySearchFunc.cpp:5

Generated for ISCE3.0 by doxygen 1.13.2.