HOPS
HOPS class reference
MHO_HDF5Datasets.hh
Go to the documentation of this file.
1 #ifndef MHO_HDF5Datasets_HH__
2 #define MHO_HDF5Datasets_HH__
3 
4 #include "MHO_ClassIdentity.hh"
7 
8 #include "MHO_Axis.hh"
9 #include "MHO_AxisPack.hh"
10 #include "MHO_ObjectTags.hh"
11 #include "MHO_ScalarContainer.hh"
12 #include "MHO_TableContainer.hh"
13 #include "MHO_Taggable.hh"
14 #include "MHO_VectorContainer.hh"
15 
16 #include <sstream>
17 
18 #include "hdf5.h"
19 #include "hdf5_hl.h"
20 
21 #include "MHO_NumpyTypeCode.hh"
22 #include "MHO_HDF5TypeCode.hh"
23 #include "MHO_HDF5Attributes.hh"
24 
25 namespace hops
26 {
27 
38 template < typename XValueType >
39 inline void make_scalar_dataset(hid_t group_id, hid_t& dataset_id, const std::string& name, const XValueType& value)
40 {
41  hid_t TYPE_CODE = MHO_HDF5TypeCode<XValueType>();
42  hid_t space_id = H5Screate(H5S_SCALAR);
43  dataset_id = H5Dcreate(group_id, name.c_str(), TYPE_CODE, space_id, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
44  H5Dwrite(dataset_id, TYPE_CODE, H5S_ALL, H5S_ALL, H5P_DEFAULT, &value);
45  H5Dclose(dataset_id);
46  H5Sclose(space_id);
47 }
48 
49 template<>
50 inline void make_scalar_dataset< std::string >(hid_t group_id, hid_t& dataset_id, const std::string& name, const std::string& value)
51 {
52  hid_t TYPE_CODE = H5Tcopy(H5T_C_S1);
53  H5Tset_size(TYPE_CODE, value.size());
54  H5Tset_strpad(TYPE_CODE, H5T_STR_NULLTERM);
55  hid_t space_id = H5Screate(H5S_SCALAR);
56  dataset_id = H5Dcreate(group_id, name.c_str(), TYPE_CODE, space_id, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
57  H5Dwrite(dataset_id, TYPE_CODE, H5S_ALL, H5S_ALL, H5P_DEFAULT, value.c_str());
58  H5Dclose(dataset_id);
59  H5Sclose(space_id);
60  H5Tclose(TYPE_CODE);
61 }
62 
63 
64 //template function for writing a dimension scale (coordinate axis)
65 template< typename XDataType >
66 herr_t
67 inline make_scale(hid_t group_id, hid_t dataset_id, std::size_t axis_idx,
68  const std::string& parent_name,
69  const std::string& name,
70  const std::vector< XDataType >* data,
71  const mho_json& metadata)
72 {
73  herr_t status;
74  hsize_t dims[1];
75  dims[0] = data->size();
76  hid_t dataspace_id = H5Screate_simple(1, dims, NULL);
77 
78  //get the type code
79  hid_t TYPE_CODE = MHO_HDF5TypeCode<XDataType>();
80  //create axis dataset
81  hid_t axis_dset_id = H5Dcreate(group_id, name.c_str(), TYPE_CODE, dataspace_id, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
82  //write the data
83  status = H5Dwrite(axis_dset_id, TYPE_CODE, H5S_ALL, H5S_ALL, H5P_DEFAULT, data->data() );
84 
85  H5DSset_scale(axis_dset_id, name.c_str());
86  H5DSattach_scale(dataset_id, axis_dset_id, axis_idx); // attach to appropriate index
87 
88  //attach meta data in 'tags'
89  if( metadata.contains("tags"))
90  {
91  for(auto it = metadata["tags"].begin(); it != metadata["tags"].end(); ++it)
92  {
93  const std::string& key = it.key();
94  const mho_json& value = it.value();
95  if(key == "index_labels")
96  {
97  hid_t tmp_dset_id = -1;
98  std::string tmp_key = parent_name + "/" + key;
99  std::string sval = value.dump();
100  make_scalar_dataset(group_id, tmp_dset_id, tmp_key, sval);
101  }
102  else if( key == "interval_labels")
103  {
104  hid_t tmp_dset_id;
105  std::string tmp_key = parent_name + "/" + key;
106  std::string sval = value.dump();
107  make_scalar_dataset(group_id, tmp_dset_id, tmp_key, sval);
108  }
109  else
110  {
111  make_attribute(key, value, axis_dset_id);
112  }
113  }
114  }
115  //attach class name and uuid if they exist
116  if( metadata.contains("class_uuid"))
117  {
118  std::string key = "class_uuid";
119  mho_json value = metadata[key];
120  make_attribute(key, value, axis_dset_id);
121  }
122  if( metadata.contains("class_name"))
123  {
124  std::string key = "class_name";
125  mho_json value = metadata[key];
126  make_attribute(key, value, axis_dset_id);
127  }
128 
129  return status;
130 }
131 
133 template<>
134 herr_t
135 inline make_scale< std::string>(hid_t group_id, hid_t dataset_id, std::size_t axis_idx,
136  const std::string& parent_name,
137  const std::string& name,
138  const std::vector< std::string >* data,
139  const mho_json& metadata)
140 {
141  herr_t status;
142  hsize_t dims[1];
143  dims[0] = data->size();
144  hid_t TYPE_CODE = H5Tcopy(H5T_C_S1);
145  H5Tset_size(TYPE_CODE, H5T_VARIABLE);
146 
147  //convert to const chars
148  std::vector<const char*> cstrs;
149  for(const auto& s : *data)
150  {
151  cstrs.push_back(s.c_str());
152  }
153 
154  hid_t dataspace_id = H5Screate_simple(1, dims, NULL);
155 
156  //create axis dataset
157  hid_t axis_dset_id = H5Dcreate(group_id, name.c_str(), TYPE_CODE, dataspace_id, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
158  status = H5Dwrite(axis_dset_id, TYPE_CODE, H5S_ALL, H5S_ALL, H5P_DEFAULT, cstrs.data() );
159 
160  H5DSset_scale(axis_dset_id, name.c_str());
161  H5DSattach_scale(dataset_id, axis_dset_id, axis_idx); // attach to appropriate index
162 
163  //attach meta data
164  if( metadata.contains("tags"))
165  {
166  for(auto it = metadata["tags"].begin(); it != metadata["tags"].end(); ++it)
167  {
168  const std::string& key = it.key();
169  const mho_json& value = it.value();
170  if(key == "index_labels")
171  {
172  hid_t tmp_dset_id = -1;
173  std::string tmp_key = parent_name + "/" + key;
174  std::string sval = value.dump();
175  make_scalar_dataset(group_id, tmp_dset_id, tmp_key, sval);
176  }
177  else if( key == "interval_labels")
178  {
179  hid_t tmp_dset_id = -1;
180  std::string tmp_key = parent_name + "/" + key;
181  std::string sval = value.dump();
182  make_scalar_dataset(group_id, tmp_dset_id, tmp_key, sval);
183  }
184  else
185  {
186  make_attribute(key, value, axis_dset_id);
187  }
188  }
189  }
190  //attach class name and uuid if they exist
191  if( metadata.contains("class_uuid"))
192  {
193  std::string key = "class_uuid";
194  mho_json value = metadata[key];
195  make_attribute(key, value, axis_dset_id);
196  }
197  if( metadata.contains("class_name"))
198  {
199  std::string key = "class_name";
200  mho_json value = metadata[key];
201  make_attribute(key, value, axis_dset_id);
202  }
203 
204  return status;
205 }
206 
207 
208 //write an ND-array data object
209 template< typename XDataType >
210 herr_t
211 inline make_dataset(hid_t group_id, hid_t& dataset_id,
212  const std::string& name, hsize_t rank, hsize_t* dims,
213  const XDataType* data, const mho_json& metadata)
214 {
215  herr_t status;
216  hid_t dataspace_id = -1;
217  //return the dataset_id in reference so we can attach attributes later
218  dataset_id = -1;
219  //create dataspace
220  dataspace_id = H5Screate_simple(rank, dims, NULL);
221  if (dataspace_id < 0)
222  {
223  msg_error("main", "could not create dataspace" << eom);
224  return -1;
225  }
226  //get the type code
227  hid_t TYPE_CODE = MHO_HDF5TypeCode<XDataType>();
228  //create dataset
229  dataset_id = H5Dcreate(group_id, name.c_str(), TYPE_CODE, dataspace_id, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
230  if (dataset_id < 0)
231  {
232  msg_error("main", "could not create data set" << eom);
233  H5Sclose(dataspace_id);
234  return -1;
235  }
236 
237  //write data
238  status = H5Dwrite(dataset_id, TYPE_CODE, H5S_ALL, H5S_ALL, H5P_DEFAULT, data);
239 
240  //attach meta data in 'tags'
241  if( metadata.contains("tags"))
242  {
243  for(auto it = metadata["tags"].begin(); it != metadata["tags"].end(); ++it)
244  {
245  const std::string& key = it.key();
246  const mho_json& value = it.value();
247  make_attribute(key, value, dataset_id);
248  }
249  }
250  //attach class name and uuid if they exist
251  if( metadata.contains("class_uuid"))
252  {
253  std::string key = "class_uuid";
254  mho_json value = metadata[key];
255  make_attribute(key, value, dataset_id);
256  }
257  if( metadata.contains("class_name"))
258  {
259  std::string key = "class_name";
260  mho_json value = metadata[key];
261  make_attribute(key, value, dataset_id);
262  }
263 
264  //clean up
265  H5Dclose(dataset_id);
266  H5Sclose(dataspace_id);
267 
268  return status;
269 }
270 
271 
272 //1-D string dataset
273 herr_t
274 inline make_string_vector_dataset(hid_t group_id, hid_t dataset_id,
275  const std::string& name,
276  const std::vector< std::string >* data,
277  const mho_json& metadata)
278 {
279  herr_t status;
280  hsize_t dims[1];
281  dims[0] = data->size();
282  hid_t TYPE_CODE = H5Tcopy(H5T_C_S1);
283  H5Tset_size(TYPE_CODE, H5T_VARIABLE);
284 
285  //convert to const chars
286  std::vector<const char*> cstrs;
287  for(const auto& s : *data)
288  {
289  cstrs.push_back(s.c_str());
290  }
291 
292  hid_t dataspace_id = H5Screate_simple(1, dims, NULL);
293  //create axis dataset
294  dataset_id = H5Dcreate(group_id, name.c_str(), TYPE_CODE, dataspace_id, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
295  status = H5Dwrite(dataset_id, TYPE_CODE, H5S_ALL, H5S_ALL, H5P_DEFAULT, cstrs.data() );
296 
297  //attache the metadata
298  for(auto it = metadata.begin(); it != metadata.end(); ++it)
299  {
300  const std::string& key = it.key();
301  //exclude plot_data and parameters from attributes -- these are large objects
302  if(key != "plot_data" && key != "parameters")
303  {
304  const mho_json& value = it.value();
305  make_attribute(key, value, dataset_id);
306  }
307  }
308 
309  //clean up
310  H5Dclose(dataset_id);
311  H5Sclose(dataspace_id);
312 
313  return status;
314 }
315 
316 
317 } // namespace hops
318 
319 #endif
nlohmann::json mho_json
Definition: MHO_JSONHeaderWrapper.hh:5
#define msg_error(xKEY, xCONTENT)
Definition: MHO_Message.hh:244
struct type_status status
Definition: fourfit3.c:53
Definition: MHO_ChannelLabeler.hh:17
void make_scalar_dataset< std::string >(hid_t group_id, hid_t &dataset_id, const std::string &name, const std::string &value)
Definition: MHO_HDF5Datasets.hh:50
herr_t make_scale(hid_t group_id, hid_t dataset_id, std::size_t axis_idx, const std::string &parent_name, const std::string &name, const std::vector< XDataType > *data, const mho_json &metadata)
Definition: MHO_HDF5Datasets.hh:67
void make_attribute(const std::string &key, XValueType value, hid_t parent_dataset_id)
Definition: MHO_HDF5Attributes.hh:38
void make_scalar_dataset(hid_t group_id, hid_t &dataset_id, const std::string &name, const XValueType &value)
Definition: MHO_HDF5Datasets.hh:39
herr_t make_string_vector_dataset(hid_t group_id, hid_t dataset_id, const std::string &name, const std::vector< std::string > *data, const mho_json &metadata)
Definition: MHO_HDF5Datasets.hh:274
herr_t make_dataset(hid_t group_id, hid_t &dataset_id, const std::string &name, hsize_t rank, hsize_t *dims, const XDataType *data, const mho_json &metadata)
Definition: MHO_HDF5Datasets.hh:211
Definition: vex.h:175