HOPS
HOPS class reference
MHO_ContainerHDF5Converter.hh
Go to the documentation of this file.
1 #ifndef MHO_ContainerHDF5Converter_HH__
2 #define MHO_ContainerHDF5Converter_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 // #include "MHO_HDF5Datasets.hh"
26 
27 namespace hops
28 {
29 
40 {
41  public:
43  virtual ~MHO_HDF5Converter(){};
44 
45  virtual void SetObjectToConvert(MHO_Serializable* ) = 0;
46  virtual void SetObjectMetaData(const mho_json& mdata){fMetaData = mdata;}
47  virtual void WriteToHDF5File(hid_t /*file_id*/, std::string /*group_prefix*/) = 0;
48 
49  protected:
50 
52 
53 };
54 
55 template< typename XContainerType > class MHO_ContainerHDF5Converter: public MHO_HDF5Converter
56 {
57  public:
58  MHO_ContainerHDF5Converter(): MHO_HDF5Converter() { fContainer = nullptr; }
59 
61  {
62  fContainer = dynamic_cast< XContainerType* >(element);
63  }
64 
66 
67  virtual void SetObjectToConvert(MHO_Serializable* obj) { fContainer = dynamic_cast< XContainerType* >(obj); };
68 
69  virtual void WriteToHDF5File(hid_t file_id, std::string group_prefix)
70  {
71  if(fContainer != nullptr)
72  {
73  ConstructHDF5(file_id, group_prefix, fContainer);
74  }
75  }
76 
77  private:
78  XContainerType* fContainer;
79 
80  protected:
81 
82  //unspecialized template doesn't do much
83  template< typename XCheckType > void ConstructHDF5(hid_t /*file_id*/, std::string /*group_prefix*/, const XCheckType* obj)
84  {
85  std::string class_name = MHO_ClassIdentity::ClassName< XCheckType >();
86  std::string class_uuid = MHO_ClassIdentity::GetUUIDFromClass< XCheckType >().as_string();
87  };
88 
89  //use SFINAE to generate specialization for the rest of the container types
90  //that we actually care about
91 
92  //scalar specialization
93  template< typename XCheckType = XContainerType >
94  typename std::enable_if< std::is_base_of< MHO_ScalarContainerBase, XCheckType >::value, void >::type
95  ConstructHDF5(hid_t file_id, std::string group_prefix, const XContainerType* obj)
96  {
97  std::string class_name = MHO_ClassIdentity::ClassName< XContainerType >();
98  std::string class_uuid = MHO_ClassIdentity::GetUUIDFromClass< XContainerType >().as_string();
99  std::string object_uuid = obj->GetObjectUUID().as_string();
100  msg_debug("hdf5interface", "creating scalar type for object with uuid: "<< object_uuid << eom);
101  std::string item_group = group_prefix + "/" + object_uuid;
102 
103  if (H5Lexists(file_id, item_group.c_str(), H5P_DEFAULT) == 0)
104  {
105  hid_t group_id = H5Gcreate(file_id, item_group.c_str(), H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
106  if(group_id < 0)
107  {
108  msg_error("hdf5interface", "failed to create HDF5 group: "<< item_group << eom);
109  }
110  else
111  {
112  std::string name = item_group + "/data";
113  //write the data
114  hid_t dataset_id = -1;
115  herr_t status =
116  make_scalar_dataset< typename XContainerType::value_type >(file_id, dataset_id, name, fContainer->GetValue() );//fMetaData);
117  H5Gclose(group_id);
118  }
119  }
120  };
121 
122  //vector specialization (but not an axis!)
123  template< typename XCheckType = XContainerType >
124  typename std::enable_if< (std::is_base_of< MHO_VectorContainerBase, XCheckType >::value &&
125  !std::is_base_of< MHO_AxisBase, XCheckType >::value),
126  void >::type
127  ConstructHDF5(hid_t file_id, std::string group_prefix, const XContainerType* obj)
128  {
129  std::string class_name = MHO_ClassIdentity::ClassName< XContainerType >();
130  std::string class_uuid = MHO_ClassIdentity::GetUUIDFromClass< XContainerType >().as_string();
131  std::string object_uuid = obj->GetObjectUUID().as_string();
132  msg_debug("hdf5interface", "creating vector type for object with uuid: "<< object_uuid << eom);
133 
134  //grab the rank and dimensions
135  hsize_t rank = 1;
136  hsize_t dims[1];
137  auto dim_array = fContainer->GetDimensionArray();
138  for(std::size_t i=0; i<rank; i++){dims[i] = dim_array[i];}
139  std::string item_group = group_prefix + "/" + object_uuid;
140 
141  if (H5Lexists(file_id, item_group.c_str(), H5P_DEFAULT) == 0)
142  {
143  hid_t group_id = H5Gcreate(file_id, item_group.c_str(), H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
144  if(group_id < 0)
145  {
146  msg_error("hdf5interface", "failed to create HDF5 group: "<< item_group << eom);
147  }
148  else
149  {
150  std::string name = item_group + "/data";
151  //write the data
152  hid_t dataset_id = -1;
153  herr_t status =
154  make_dataset< typename XContainerType::value_type >(file_id, dataset_id, name, rank, dims, fContainer->GetData(), fMetaData);
155 
156  H5Gclose(group_id);
157  }
158  }
159  };
160 
161  //axis specialization
162  template< typename XCheckType = XContainerType >
163  typename std::enable_if< std::is_base_of< MHO_AxisBase, XCheckType >::value, void >::type
164  ConstructHDF5(hid_t file_id, std::string group_prefix, const XContainerType* obj)
165  {
166  std::string class_name = MHO_ClassIdentity::ClassName< XContainerType >();
167  std::string class_uuid = MHO_ClassIdentity::GetUUIDFromClass< XContainerType >().as_string();
168  std::string object_uuid = obj->GetObjectUUID().as_string();
169  msg_debug("hdf5interface", "creating axis type for object with uuid: "<< object_uuid << eom);
170 
171  //grab the rank and dimensions
172  hsize_t rank = 1;
173  hsize_t dims[1];
174  auto dim_array = fContainer->GetDimensionArray();
175  for(std::size_t i=0; i<rank; i++){dims[i] = dim_array[i];}
176  std::string item_group = group_prefix + "/" + object_uuid;
177 
178  if (H5Lexists(file_id, item_group.c_str(), H5P_DEFAULT) == 0)
179  {
180  hid_t group_id = H5Gcreate(file_id, item_group.c_str(), H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
181  if(group_id < 0)
182  {
183  msg_error("hdf5interface", "failed to create HDF5 group: "<< item_group << eom);
184  }
185  else
186  {
187  std::string name = item_group + "/data";
188  //write the data
189  hid_t dataset_id = -1;
190  herr_t status =
191  make_dataset< typename XContainerType::value_type >(file_id, dataset_id, name, rank, dims, fContainer->GetData(), fMetaData);
192 
193  H5Gclose(group_id);
194  }
195  }
196  };
197 
198  //table specialization
199  template< typename XCheckType = XContainerType >
200  typename std::enable_if< std::is_base_of< MHO_TableContainerBase, XCheckType >::value, void >::type
201  ConstructHDF5(hid_t file_id, std::string group_prefix, const XContainerType* obj)
202  {
203  std::string class_name = MHO_ClassIdentity::ClassName< XContainerType >();
204  std::string class_uuid = MHO_ClassIdentity::GetUUIDFromClass< XContainerType >().as_string();
205  std::string object_uuid = obj->GetObjectUUID().as_string();
206  msg_debug("hdf5interface", "creating table type for object with uuid: "<< object_uuid << eom);
207 
208  //grab the rank and dimensions
209  hsize_t rank = XContainerType::rank::value;
210  hsize_t dims[XContainerType::rank::value];
211  auto dim_array = obj->GetDimensionArray();
212  for(std::size_t i=0; i<rank; i++){dims[i] = dim_array[i];}
213 
214  std::string item_group = group_prefix + "/" + object_uuid;
215 
216  if (H5Lexists(file_id, item_group.c_str(), H5P_DEFAULT) == 0)
217  {
218  hid_t group_id = H5Gcreate(file_id, item_group.c_str(), H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
219  if(group_id < 0)
220  {
221  msg_error("hdf5interface", "failed to create HDF5 group: "<< item_group << eom);
222  }
223  else
224  {
225  std::string name = item_group + "/data";
226  //write the data
227  hid_t dataset_id = -1;
228  herr_t status =
229  make_dataset< typename XContainerType::value_type >(file_id, dataset_id, name, rank, dims, fContainer->GetData(), fMetaData);
230  // make_dataset< typename XContainerType::value_type >(file_id, dataset_id, name, rank, dims, fContainer->GetData(), fMetaData["tags"]);
231 
232  //now attach the table axes
233  name = item_group;
234  AxisDumper axis_dumper(file_id, dataset_id, name, fMetaData);
235  for(std::size_t idx = 0; idx < obj->GetRank(); idx++)
236  {
237  axis_dumper.SetIndex(idx);
238  apply_at< typename XContainerType::axis_pack_tuple_type, AxisDumper >(*obj, idx, axis_dumper);
239  }
240 
241  H5Gclose(group_id);
242  }
243  }
244 
245  };
246 
248  {
249  public:
250  AxisDumper(hid_t file_id, hid_t ds_id, const std::string& parent, const mho_json& pmetadata):
251  fFileID(file_id),
252  fDataSetID(ds_id),
253  fParentName(parent),
254  fParentMetadata(pmetadata)
255  {};
256 
257  AxisDumper(): fFileID(-1), fDataSetID(-1), fParentName(""){};
259 
260  void SetIndex(std::size_t idx) { fIndex = idx; }
261  void SetFileID(hid_t file_id){ fFileID = file_id; }
262  void SetDataSetID(hid_t ds_id){ fDataSetID = ds_id; }
263 
264  template< typename XAxisType > void operator()(const XAxisType& axis)
265  {
266  mho_json j;
267  std::string class_name = MHO_ClassIdentity::ClassName< XAxisType >();
268  std::string class_uuid = MHO_ClassIdentity::GetUUIDFromClass< XAxisType >().as_string();
269 
270  std::stringstream ssn;
271  ssn << "axis_" << fIndex;
272  std::string ax_name = ssn.str();
273 
274  std::stringstream ss;
275  ss << fParentName << "/axis_";
276  ss << fIndex;
277  std::string item_group = ss.str();
278 
279  if (H5Lexists(fFileID, item_group.c_str(), H5P_DEFAULT) == 0)
280  {
281  hid_t group_id = H5Gcreate(fFileID, item_group.c_str(), H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
282  if(group_id < 0)
283  {
284  msg_error("hdf5interface", "failed to create HDF5 group: "<< item_group << eom);
285  }
286  else
287  {
288  std::string name = item_group + "/data";
289 
290  mho_json mdata;
291  if(fParentMetadata.contains(ax_name))
292  {
293  mdata = fParentMetadata[ax_name];
294  }
295  msg_debug("hdf5interface", "creating an axis object with name: " << name<< eom);
296 
297  //copy the data into a temporary vector (needed to deal with string axes)
298  std::size_t n = axis.GetSize();
299  std::vector< typename XAxisType::value_type > axis_data;
300  for(std::size_t i=0; i<n; i++){axis_data.push_back( axis.at(i) ); }
301 
302  hsize_t dims[1];
303  dims[0] = n;
304  hid_t dataset_id = -1;
305  herr_t status =
306  make_scale< typename XAxisType::value_type >(fFileID, fDataSetID, fIndex, item_group, name, &axis_data, mdata);
307 
308  H5Gclose(group_id);
309  }
310  }
311  };
312 
313  private:
314 
315  hid_t fFileID;
316  hid_t fDataSetID;
317  std::string fParentName;
318  std::size_t fIndex;
319  const mho_json& fParentMetadata;
320 
321  };
322 };
323 
324 
325 
326 
327 
328 
329 
330 
332 {
333  public:
334  MHO_ContainerHDF5Converter(): MHO_HDF5Converter() { fContainer = nullptr; }
335 
337  {
338  fContainer = dynamic_cast< MHO_ObjectTags* >(element);
339  }
340 
342 
343  virtual void SetObjectToConvert(MHO_Serializable* obj) { fContainer = dynamic_cast< MHO_ObjectTags* >(obj); };
344 
345  virtual void WriteToHDF5File(hid_t file_id, std::string group_prefix)
346  {
347  if(fContainer != nullptr)
348  {
349  ConstructHDF5(file_id, group_prefix, fContainer);
350  }
351  }
352 
353  private:
354 
355  void ConstructHDF5(hid_t file_id, std::string group_prefix, const MHO_ObjectTags* obj)
356  {
357  std::string class_name = MHO_ClassIdentity::ClassName< MHO_ObjectTags >();
358  std::string class_uuid = MHO_ClassIdentity::GetUUIDFromClass< MHO_ObjectTags >().as_string();
359  std::string object_uuid = obj->GetObjectUUID().as_string();
360  msg_debug("hdf5interface", "creating tag type for object with uuid: "<< object_uuid << eom);
361 
362  std::string item_group = group_prefix + "/" + object_uuid;
363 
364  if (H5Lexists(file_id, item_group.c_str(), H5P_DEFAULT) == 0)
365  {
366  hid_t group_id = H5Gcreate(file_id, item_group.c_str(), H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
367  if(group_id < 0)
368  {
369  msg_error("hdf5interface", "failed to create HDF5 group: "<< item_group << eom);
370  }
371  else
372  {
373  std::string name = item_group + "/uuid_set";
374  //the data we want to store is a vector of the object UUIDs that we are tagging
375  std::vector< MHO_UUID > uvec = obj->GetAllObjectUUIDs();
376  //now convert these to a vector of strings
377  std::vector< std::string > uuid_vec;
378  for(std::size_t i=0; i<uvec.size(); i++){uuid_vec.push_back( uvec[i].as_string() );}
379  mho_json mdata = obj->GetMetaDataAsJSON();
380 
381  mdata["class_name"] = class_name;
382  mdata["class_uuid"] = class_uuid;
383  hid_t dataset_id = -1;
384  herr_t status =
385  make_string_vector_dataset(file_id, dataset_id, name, &uuid_vec, mdata);
386 
387  //store plot data as a separate object
388  if(mdata.contains("plot_data"))
389  {
390  std::string plot_group = item_group + "/" + "plot_data";
391  hid_t plot_group_id = H5Gcreate(file_id, plot_group.c_str(), H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
392  json_to_hdf5_attributes(mdata["plot_data"], plot_group_id);
393  H5Gclose(plot_group_id);
394  // hid_t pd_dset_id = -1;
395  // std::string plot_data_name = item_group + "/plot_data";
396  // std::string plot_data = mdata["plot_data"].dump();
397  // make_scalar_dataset(file_id, pd_dset_id, plot_data_name, plot_data);
398  }
399 
400  //store paramters as a separate object
401  if(mdata.contains("parameters"))
402  {
403  std::string param_group = item_group + "/" + "parameters";
404  hid_t param_group_id = H5Gcreate(file_id, param_group.c_str(), H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
405  json_to_hdf5_attributes(mdata["parameters"], param_group_id);
406  H5Gclose(param_group_id);
407 
408  // hid_t pm_dset_id = -1;
409  // std::string param_data_name = item_group + "/parameters";
410  // std::string param_data = mdata["parameters"].dump();
411  // make_scalar_dataset(file_id, pm_dset_id, param_data_name, param_data);
412  }
413 
414  H5Gclose(group_id);
415  }
416  }
417  };
418 
419  MHO_ObjectTags* fContainer;
420 };
421 
422 } // namespace hops
423 
424 #endif
nlohmann::json mho_json
Definition: MHO_JSONHeaderWrapper.hh:5
#define msg_debug(xKEY, xCONTENT)
Definition: MHO_Message.hh:297
#define msg_error(xKEY, xCONTENT)
Definition: MHO_Message.hh:244
int axis(char *y_axis, char *x_axis)
Definition: axis.c:22
Definition: MHO_ContainerHDF5Converter.hh:248
void SetFileID(hid_t file_id)
Definition: MHO_ContainerHDF5Converter.hh:261
~AxisDumper()
Definition: MHO_ContainerHDF5Converter.hh:258
AxisDumper(hid_t file_id, hid_t ds_id, const std::string &parent, const mho_json &pmetadata)
Definition: MHO_ContainerHDF5Converter.hh:250
void operator()(const XAxisType &axis)
Definition: MHO_ContainerHDF5Converter.hh:264
AxisDumper()
Definition: MHO_ContainerHDF5Converter.hh:257
void SetIndex(std::size_t idx)
Definition: MHO_ContainerHDF5Converter.hh:260
void SetDataSetID(hid_t ds_id)
Definition: MHO_ContainerHDF5Converter.hh:262
MHO_ContainerHDF5Converter()
Definition: MHO_ContainerHDF5Converter.hh:334
virtual void SetObjectToConvert(MHO_Serializable *obj)
Definition: MHO_ContainerHDF5Converter.hh:343
virtual ~MHO_ContainerHDF5Converter()
Definition: MHO_ContainerHDF5Converter.hh:341
MHO_ContainerHDF5Converter(MHO_ExtensibleElement *element)
Definition: MHO_ContainerHDF5Converter.hh:336
virtual void WriteToHDF5File(hid_t file_id, std::string group_prefix)
Definition: MHO_ContainerHDF5Converter.hh:345
Converts a given ndarray-based container into a HDF5 representation - export only for now.
Definition: MHO_ContainerHDF5Converter.hh:56
MHO_ContainerHDF5Converter()
Definition: MHO_ContainerHDF5Converter.hh:58
std::enable_if< std::is_base_of< MHO_ScalarContainerBase, XCheckType >::value, void >::type ConstructHDF5(hid_t file_id, std::string group_prefix, const XContainerType *obj)
Definition: MHO_ContainerHDF5Converter.hh:95
virtual ~MHO_ContainerHDF5Converter()
Definition: MHO_ContainerHDF5Converter.hh:65
virtual void WriteToHDF5File(hid_t file_id, std::string group_prefix)
Definition: MHO_ContainerHDF5Converter.hh:69
MHO_ContainerHDF5Converter(MHO_ExtensibleElement *element)
Definition: MHO_ContainerHDF5Converter.hh:60
std::enable_if< std::is_base_of< MHO_AxisBase, XCheckType >::value, void >::type ConstructHDF5(hid_t file_id, std::string group_prefix, const XContainerType *obj)
Definition: MHO_ContainerHDF5Converter.hh:164
void ConstructHDF5(hid_t, std::string, const XCheckType *obj)
Definition: MHO_ContainerHDF5Converter.hh:83
virtual void SetObjectToConvert(MHO_Serializable *obj)
Definition: MHO_ContainerHDF5Converter.hh:67
std::enable_if<(std::is_base_of< MHO_VectorContainerBase, XCheckType >::value &&!std::is_base_of< MHO_AxisBase, XCheckType >::value), void >::type ConstructHDF5(hid_t file_id, std::string group_prefix, const XContainerType *obj)
Definition: MHO_ContainerHDF5Converter.hh:127
std::enable_if< std::is_base_of< MHO_TableContainerBase, XCheckType >::value, void >::type ConstructHDF5(hid_t file_id, std::string group_prefix, const XContainerType *obj)
Definition: MHO_ContainerHDF5Converter.hh:201
Class MHO_ExtensibleElement.
Definition: MHO_ExtensibleElement.hh:60
Definition: MHO_ContainerHDF5Converter.hh:40
virtual void SetObjectMetaData(const mho_json &mdata)
Definition: MHO_ContainerHDF5Converter.hh:46
virtual void SetObjectToConvert(MHO_Serializable *)=0
mho_json fMetaData
Definition: MHO_ContainerHDF5Converter.hh:51
virtual ~MHO_HDF5Converter()
Definition: MHO_ContainerHDF5Converter.hh:43
virtual void WriteToHDF5File(hid_t, std::string)=0
MHO_HDF5Converter()
Definition: MHO_ContainerHDF5Converter.hh:42
Class MHO_ObjectTags.
Definition: MHO_ObjectTags.hh:28
std::vector< MHO_UUID > GetAllObjectUUIDs() const
Getter for all object uuids at once.
Definition: MHO_ObjectTags.hh:84
Class MHO_Serializable.
Definition: MHO_Serializable.hh:26
MHO_UUID GetObjectUUID() const
Getter for object uuid.
Definition: MHO_Serializable.hh:61
mho_json GetMetaDataAsJSON() const
Getter for all meta data stored in this object as a json object.
Definition: MHO_Taggable.hh:95
std::string as_string() const
Definition: MHO_UUID.hh:125
struct type_status status
Definition: fourfit3.c:53
Definition: MHO_ChannelLabeler.hh:17
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
void json_to_hdf5_attributes(const mho_json &j, hid_t parent_group)
Definition: MHO_HDF5ConversionHelpers.hh:39