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