Repository navigation
Expand file tree
/
Copy pathh5stream.hpp
More file actions
236 lines (223 loc) · 8.1 KB
/
Copy pathh5stream.hpp
File metadata and controls
236 lines (223 loc) · 8.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
/*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include "H5Cpp.h"
#include <iostream>
#include <string>
#include <vector>
//#include <vector>
// Maps C++ type to HDF5 type
template <typename T> inline const H5::PredType &get_datatype_for_hdf5();
// Reference:
// https://www.hdfgroup.org/HDF5/doc/cpplus_RM/class_h5_1_1_pred_type.html
template <> inline const H5::PredType &get_datatype_for_hdf5<char>() {
return H5::PredType::NATIVE_CHAR;
}
template <> inline const H5::PredType &get_datatype_for_hdf5<unsigned char>() {
return H5::PredType::NATIVE_UCHAR;
}
template <> inline const H5::PredType &get_datatype_for_hdf5<short>() {
return H5::PredType::NATIVE_SHORT;
}
template <> inline const H5::PredType &get_datatype_for_hdf5<unsigned short>() {
return H5::PredType::NATIVE_USHORT;
}
template <> inline const H5::PredType &get_datatype_for_hdf5<int>() {
return H5::PredType::NATIVE_INT;
}
template <> inline const H5::PredType &get_datatype_for_hdf5<unsigned int>() {
return H5::PredType::NATIVE_UINT;
}
template <> inline const H5::PredType &get_datatype_for_hdf5<long>() {
return H5::PredType::NATIVE_LONG;
}
template <> inline const H5::PredType &get_datatype_for_hdf5<unsigned long>() {
return H5::PredType::NATIVE_ULONG;
}
template <> inline const H5::PredType &get_datatype_for_hdf5<long long>() {
return H5::PredType::NATIVE_LLONG;
}
template <>
inline const H5::PredType &get_datatype_for_hdf5<unsigned long long>() {
return H5::PredType::NATIVE_ULLONG;
}
template <> inline const H5::PredType &get_datatype_for_hdf5<float>() {
return H5::PredType::NATIVE_FLOAT;
}
template <> inline const H5::PredType &get_datatype_for_hdf5<double>() {
return H5::PredType::NATIVE_DOUBLE;
}
template <> inline const H5::PredType &get_datatype_for_hdf5<long double>() {
return H5::PredType::NATIVE_LDOUBLE;
}
//---------------------------------------------------------
namespace h5stream {
template <typename T> struct h5str1 {
std::string keyName;
T *data;
const unsigned dataSize;
};
} // namespace h5stream
//
namespace h5stream {
class dspace {
public:
H5::DataSet dataset;
explicit dspace(H5::DataSet datasetx) : dataset(datasetx){};
template <typename T>
void write_atr(const T data, const H5std_string &dataname) {
auto type = get_datatype_for_hdf5<T>();
H5::DataSpace attr_dataspace = H5::DataSpace(H5S_SCALAR);
H5::Attribute attribute =
dataset.createAttribute(dataname, type, attr_dataspace);
attribute.write(type, &data);
}
template <typename T> void read_atr(T &data, const H5std_string &dataname) {
// auto type = get_datatype_for_hdf5<T>();
H5::Attribute attribute = dataset.openAttribute(dataname);
H5::DataType type = attribute.getDataType();
attribute.read(type, &data);
}
//----------------------
};
} // namespace h5stream
//******************************************************************
// namespace h5stream
//----------------------------------------------------------
namespace h5stream {
class h5stream {
public:
H5std_string hdf5FileName;
H5::H5File hdf5File;
h5stream(){};
h5stream(const std::string &fileName,
const std::string &rw = std::string("tr")) {
setFileName(fileName, rw);
}
void setFileName(const H5std_string &fileName,
const std::string &rw = std::string("tr")) {
hdf5FileName = fileName;
try {
H5::Exception::dontPrint();
if (rw.compare("r") == 0)
hdf5File = H5::H5File(fileName, H5F_ACC_RDONLY);
if (rw == "rw")
hdf5File = H5::H5File(fileName, H5F_ACC_RDWR);
if (rw == "x")
hdf5File = H5::H5File(fileName, H5F_ACC_EXCL);
if (rw == "tr")
hdf5File = H5::H5File(fileName, H5F_ACC_TRUNC);
} catch (...) {
std::cout << " Error :: Unable to setFileName! " << fileName
<< std::endl;
}
}
template <typename T = double, template <typename...> class vec = std::vector>
void write(const vec<T> &data, const H5std_string &datasetName) {
write(datasetName, data.data(), data.size());
}
template <typename T = double, template <typename...> class vec = std::vector>
void write(const H5std_string &datasetName, const vec<T> &data) {
write(datasetName, data.data(), data.size());
}
// Write raw pointer
template <typename T = double>
void write(const H5std_string &datasetName, const T *data,
unsigned data_size) {
try {
H5::Exception::dontPrint();
const int RANK = 1;
auto type = get_datatype_for_hdf5<T>();
hsize_t dimsf[1]; // dataset dimensions
dimsf[0] = data_size; //
H5::DataSpace dataspace(RANK, dimsf);
H5::DataSet dataset =
hdf5File.createDataSet(datasetName, type, dataspace);
dataset.write(data, type);
} catch (...) {
std::cout << "Error! :: Unable to write datasetName" << datasetName
<< " from the file " << hdf5FileName << std::endl;
// error.printErrorStack();
std::cout << " Error ::FileIException! (Write )" << std::endl;
}
}
// Read file
template <typename T = double, template <typename...> class vec = std::vector>
vec<T> read(const H5std_string &datasetName) {
vec<T> data;
try {
H5::Exception::dontPrint();
auto type = get_datatype_for_hdf5<T>();
H5::DataSet dataset = hdf5File.openDataSet(datasetName);
H5::DataSpace dataspace = dataset.getSpace();
hsize_t dim[1];
dataspace.getSimpleExtentDims(dim, NULL);
data.resize(dim[0]);
dataset.read(data.data(), type, dataspace, dataspace);
} catch (...) {
// H5::FileIException::printErrorStack();
std::cout << "Error! :: Unable to read datasetName" << datasetName
<< " from the file " << hdf5FileName << std::endl;
}
return data;
}
template <typename T = double, template <typename...> class vec = std::vector>
void read(vec<T> &data, const H5std_string &datasetName) {
data = read<T, vec>(datasetName);
}
template <typename T = double>
void read(const H5std_string &datasetName, const T *data,
const unsigned data_size) {
try {
H5::Exception::dontPrint();
auto type = get_datatype_for_hdf5<T>();
H5::DataSet dataset = hdf5File.openDataSet(datasetName);
H5::DataSpace dataspace = dataset.getSpace();
hsize_t dim[1];
dataspace.getSimpleExtentDims(dim, NULL);
// data.resize(dim[0]);
if (dim[0] != data_size) {
std::cout << "Error: data from the file dont have the currect size"
<< std::endl;
}
dataset.read(data, type, dataspace, dataspace);
} catch (...) {
// H5::FileIException::printErrorStack();
std::cout << "Error! :: Unable to read datasetName" << datasetName
<< " from the file " << hdf5FileName << std::endl;
}
}
void close() { hdf5File.close(); }
double file_size() { return hdf5File.getFileSize() / (1024 * 1024.); }
dspace get_dataspace(const H5std_string &dataset_name) {
return dspace(hdf5File.openDataSet(dataset_name));
}
H5::Group create_group(const H5std_string &group_name) {
return hdf5File.createGroup(group_name);
}
//*************************************************
// overload << and >>
template <typename T>
friend h5stream &operator<<(h5stream &out, const h5str1<T> struct1) {
out.write<T>(struct1.keyName, struct1.data, struct1.dataSize);
return out;
}
template <typename T>
friend h5stream &operator>>(h5stream &out, const h5str1<T> struct1) {
out.read<T>(struct1.keyName, struct1.data, struct1.dataSize);
return out;
}
//-------------------------------------------------
};
} // namespace h5stream