1#if !defined(ISCE_IO_IH5_ICC)
2#error "IH5.icc is an implementation detail of class IDataset/IGroup/IH5File"
11using namespace isce3::core;
13inline DT getH5StrType(
size_t strlen) {
16 throw isce3::except::InvalidArgument(ISCE_SRCINFO(),
17 "string length must be > 0");
19 return StrType(PT::C_S1, strlen);
22inline DT getH5Type(
const std::string& str) {
return getH5StrType(str.size()); }
24template<
typename T> DT getH5Type();
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; }
40template<
typename T>
inline DT getH5Type() {
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");
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);
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);
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);
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);
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);
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);
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);
99 H5::CompType comp(2 *
sizeof(
float));
100 comp.insertMember(
"r", 0, datatype);
101 comp.insertMember(
"i",
sizeof(
float), datatype);
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);
110 throw isce3::except::InvalidArgument(
111 ISCE_SRCINFO(),
"Type '" + std::string(
typeid(T).name()) +
112 "' unrecognized for H5 container");
116template<
typename T>
inline H5::DataSpace getMemorySpace(
const T nbElements) {
119 hsize_t memDims[1] = {
static_cast<hsize_t
>(nbElements)};
120 return H5::DataSpace(1, memDims);
123template<
typename T,
size_t S>
124inline H5::DataSpace getMemorySpace(
const std::array<T, S>& dims) {
127 for (
int i = 0; i < S; i++)
128 mem_dims[i] =
static_cast<hsize_t
>(dims[i]);
130 return H5::DataSpace(S, mem_dims);
151 throw isce3::except::InvalidArgument(ISCE_SRCINFO(),
152 "Dataset/attribute must be scalar");
155 H5::DataSet::read(&v, getH5Type<T>());
159 if (not attrExists(att)) {
160 throw isce3::except::InvalidArgument(
161 ISCE_SRCINFO(),
"Attribute '" + att +
"' not found");
166 openAttribute(att).read(getH5Type<T>(), &v);
209 const std::vector<std::slice>* slices) {
231 if (not dspace.selectValid()) {
232 throw isce3::except::InvalidArgument(ISCE_SRCINFO(),
233 "Invalid dataset subselection");
237 const hssize_t nbElements = dspace.getSelectNpoints();
240 const H5::DataSpace memspace = getMemorySpace((hsize_t) nbElements);
243 H5::DataSet::read(buffer, getH5Type<T>(), memspace, dspace);
253 read(buffer,
nullptr,
nullptr,
nullptr);
276 const std::vector<int>* start,
277 const std::vector<int>* count,
278 const std::vector<int>* stride) {
281 const auto dspace =
getDataSpace(start ? start->data() :
nullptr,
282 count ? count->data() :
nullptr,
283 stride ? stride->data() :
nullptr);
286 if (buffer.size() < dspace.getSelectNpoints())
287 buffer.resize(dspace.getSelectNpoints());
290 read(buffer.data(), dspace);
303 const std::vector<std::slice>* slices) {
309 if (buffer.size() < dspace.getSelectNpoints())
310 buffer.resize(dspace.getSelectNpoints());
313 read(buffer.data(), dspace);
325 const std::gslice* gsliceIn) {
331 if (buffer.size() < dspace.getSelectNpoints())
332 buffer.resize(dspace.getSelectNpoints());
335 read(buffer.data(), dspace);
345 read(buffer,
nullptr,
nullptr,
nullptr);
368 const std::valarray<int>* start,
369 const std::valarray<int>* count,
370 const std::valarray<int>* stride) {
373 H5::DataSpace dspace =
getDataSpace(start ? &(*start)[0] :
nullptr,
374 count ? &(*count)[0] :
nullptr,
375 stride ? &(*stride)[0] :
nullptr);
378 if (buffer.size() < dspace.getSelectNpoints())
379 buffer.resize(dspace.getSelectNpoints());
382 read(&buffer[0], dspace);
395 const std::vector<std::slice>* slicesIn) {
401 if (buffer.size() < dspace.getSelectNpoints())
402 buffer.resize(dspace.getSelectNpoints());
405 read(&buffer[0], dspace);
417 const std::gslice* gsliceIn) {
423 if (buffer.size() < dspace.getSelectNpoints())
424 buffer.resize(dspace.getSelectNpoints());
427 read(&buffer[0], dspace);
438 if (not attrExists(att)) {
439 throw isce3::except::InvalidArgument(
440 ISCE_SRCINFO(),
"Attribute '" + att +
"' not found");
447 H5::Attribute a = openAttribute(att);
450 a.read(getH5Type<T>(), buffer);
463 if (not attrExists(att)) {
464 throw isce3::except::InvalidArgument(
465 ISCE_SRCINFO(),
"Attribute '" + att +
"' not found");
472 read((T*) buffer.data(), att);
484 const std::string& att) {
486 if (not attrExists(att)) {
487 throw isce3::except::InvalidArgument(
488 ISCE_SRCINFO(),
"Attribute '" + att +
"' not found");
495 read((T*) &buffer[0], att);
506 if (!dspace.selectValid()) {
507 throw isce3::except::InvalidArgument(ISCE_SRCINFO(),
508 "Invalid dataset subselection");
515 H5::DataSpace mspace = getMemorySpace(dspace.getSelectNpoints());
518 H5::DataSet::write(buf, getH5Type<T>(), mspace, dspace);
527 H5::DataSpace dspace = getSpace();
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");
535 write(buf.data(), dspace);
546template<
typename T,
size_t S>
548 const std::array<int, S>& start,
549 const std::array<int, S>& count,
550 const std::array<int, S>& stride) {
555 H5::DataSpace dspace =
556 getDataSpace(start.data(), count.data(), stride.data());
558 write(buf.data(), dspace);
567 const std::vector<std::slice>* slicesIn) {
574 write(buf.data(), dspace);
582 const std::gslice* gsliceIn) {
589 write(buf.data(), dspace);
599 H5::DataSpace dspace = getSpace();
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");
607 write(&buf[0], dspace);
618template<
typename T,
size_t S>
620 const std::array<int, S>& startIn,
621 const std::array<int, S>& countIn,
622 const std::array<int, S>& strideIn) {
627 H5::DataSpace dspace =
628 getDataSpace(startIn.data(), countIn.data(), strideIn.data());
629 write(&buf[0], dspace);
638 const std::vector<std::slice>* slicesIn) {
651 const std::gslice* gsliceIn) {
666 H5::DataSpace dspace = getSpace();
668 if (sz != dspace.getSelectNpoints()) {
669 throw isce3::except::InvalidArgument(
670 ISCE_SRCINFO(),
"Buffer size does not match dataset size");
688template<
typename T,
size_t S>
690 const std::array<int, S>& countIn,
691 const std::array<int, S>& strideIn) {
696 H5::DataSpace dspace =
697 getDataSpace(startIn.data(), countIn.data(), strideIn.data());
714 const std::vector<std::slice>* slicesIn) {
747 const H5::DataType& datatype,
748 const H5::DataSpace& dataspace,
752 throw isce3::except::InvalidArgument(ISCE_SRCINFO(),
753 "Attribute name cannot be empty");
755 if (attrExists(name.c_str())) {
756 throw isce3::except::InvalidArgument(
757 ISCE_SRCINFO(),
"Attribute '" + name +
"' already exists");
761 H5::H5Object::createAttribute(name, datatype, dataspace)
762 .write(datatype, buffer);
770template<
typename T,
typename T2,
size_t S>
772 const std::array<T2, S>& dims,
773 const std::vector<T>& buffer) {
775 createAttribute(name, getH5Type<T>(), getMemorySpace(dims), buffer.data());
783template<
typename T,
typename T2,
size_t S>
786 const std::array<T2, S>& dims,
787 const std::valarray<T>& buffer) {
789 createAttribute(name, getH5Type<T>(), getMemorySpace(dims), &buffer[0]);
797template<
typename T,
typename T2,
size_t S>
799 const std::array<T2, S>& dims,
813 const std::vector<T>& data) {
815 std::array<hsize_t, 1> dims = {
static_cast<hsize_t
>(data.size())};
827 const std::valarray<T>& data) {
828 std::array<hsize_t, 1> dims = {
static_cast<hsize_t
>(data.size())};
843namespace isce3 {
namespace io {
851 const std::string& data) {
869 if (not attrExists(att)) {
870 throw isce3::except::InvalidArgument(
871 ISCE_SRCINFO(),
"Attribute '" + att +
"' not found");
874 H5::Attribute a = openAttribute(att);
877 H5::DataSpace dspace = a.getSpace();
881 if (dspace.getSimpleExtentNdims() != 0) {
882 throw isce3::except::InvalidArgument(ISCE_SRCINFO(),
883 "Dataset/attribute must be scalar");
886 a.read(getH5Type<T>(), &v);
897 if (not attrExists(att)) {
898 throw isce3::except::InvalidArgument(
899 ISCE_SRCINFO(),
"Attribute '" + att +
"' not found");
902 openAttribute(att).read(getH5Type<T>(), buffer);
915 if (not attrExists(att)) {
916 throw isce3::except::InvalidArgument(
917 ISCE_SRCINFO(),
"Attribute '" + att +
"' not found");
923 read(buffer.data(), att);
936 if (not attrExists(att)) {
937 throw isce3::except::InvalidArgument(
938 ISCE_SRCINFO(),
"Attribute '" + att +
"' does not exist");
944 read(&buffer[0], att);
957 const auto dtype = getH5Type<T>();
958 H5::DataSet dset = H5::Group::createDataSet(name, dtype, H5::DataSpace());
959 dset.write(&data, dtype);
974 const std::vector<T>& data) {
977 std::array<hsize_t, 1> dims {{data.size()}};
992 const std::valarray<T>& data) {
995 std::array<hsize_t, 1> dims {{data.size()}};
1013 std::array<hsize_t, 1> dims {{sz}};
1025template<
typename T,
typename T2,
size_t S>
1028 const std::vector<T>& data,
1029 const std::array<T2, S>& dims) {
1043template<
typename T,
typename T2,
size_t S>
1046 const std::valarray<T>& data,
1047 const std::array<T2, S>& dims) {
1061template<
typename T,
typename T2,
size_t S>
1064 const std::array<T2, S>& dims) {
1067 dset.
write(data, dset.getSpace().getSimpleExtentNpoints());
1086template<
typename T,
typename T2,
size_t S>
1089 const std::array<T2, S>& dims,
const int chunk,
1090 const int shuffle,
const int deflate) {
1093 throw isce3::except::InvalidArgument(ISCE_SRCINFO(),
1094 "Attribute name cannot be empty");
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());
1104 H5::DSetCreatPropList cparms;
1108 if (chunk != 0 || shuffle != 0 || deflate != 0) {
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());
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)
1131 cparms.setShuffle();
1136 std::cout <<
"Dataset Deflate compression factor should be "
1137 "[0..9] - defaulting to 0"
1139 cparms.setDeflate(0);
1140 }
else if (deflate > 9) {
1141 std::cout <<
"Dataset Deflate compression factor should be "
1142 "[0..9] - defaulting to 9"
1144 cparms.setDeflate(9);
1146 cparms.setDeflate(deflate);
1151 return H5::Group::createDataSet(name, getH5Type<T>(), dataSpace, cparms);
1165 const H5::DataType& datatype,
1166 const H5::DataSpace& dataspace,
1170 throw isce3::except::InvalidArgument(ISCE_SRCINFO(),
1171 "Attribute name cannot be empty");
1174 if (attrExists(name.c_str())) {
1175 throw isce3::except::InvalidArgument(
1176 ISCE_SRCINFO(),
"Attribute '" + name +
"' already exists");
1180 H5::H5Object::createAttribute(name, datatype, dataspace)
1181 .write(datatype, buffer);
1189template<
typename T,
typename T2,
size_t S>
1191 const std::array<T2, S>& dims,
1192 const std::vector<T>& buffer) {
1193 createAttribute(name, getH5Type<T>(), getMemorySpace(dims), buffer.data());
1201template<
typename T,
typename T2,
size_t S>
1203 const std::array<T2, S>& dims,
1204 const std::valarray<T>& buffer) {
1205 createAttribute(name, getH5Type<T>(), getMemorySpace(dims), &buffer[0]);
1213template<
typename T,
typename T2,
size_t S>
1215 const std::array<T2, S>& dims,
1228 const std::vector<T>& data) {
1229 std::array<hsize_t, 1> dims = {
static_cast<hsize_t
>(data.size())};
1241 const std::valarray<T>& data) {
1242 std::array<hsize_t, 1> dims = {
static_cast<hsize_t
>(data.size())};
1256namespace isce3 {
namespace io {
1264 const std::string& data) {
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