PyNE C++
h5wrap.h
Go to the documentation of this file.
1 
6 #ifndef PYNE_MRNAFG5GNZDNPCRPX3UCBZ5MFE
7 #define PYNE_MRNAFG5GNZDNPCRPX3UCBZ5MFE
8 
9 #include <iostream>
10 #include <fstream>
11 #include <string>
12 #include <map>
13 #include <vector>
14 #include <set>
15 #include <stdio.h>
16 #include <stdlib.h>
17 #include <exception>
18 
19 #include "hdf5.h"
20 
21 #ifndef PYNE_IS_AMALGAMATED
22 #include "extra_types.h"
23 #endif
24 
26 namespace h5wrap
27 {
29  class HDF5BoundsError: public std::exception
30  {
32  virtual const char* what() const throw()
33  {
34  return "Index of point is out of bounds. Cannot handle in HDF5 file.";
35  };
36  };
37 
38 
40  class FileNotHDF5: public std::exception
41  {
42  public:
43 
46 
48  ~FileNotHDF5() throw () {};
49 
51  FileNotHDF5(std::string fname)
52  {
53  filename = fname;
54  };
55 
57  virtual const char* what() const throw()
58  {
59  std::string FNH5str ("Not a valid HDF5 file: ");
60  if (!filename.empty())
61  FNH5str += filename;
62 
63  const char* FNH5str_rtn = FNH5str.c_str();
64  return FNH5str_rtn;
65  };
66 
67  private:
68  std::string filename;
69  };
70 
71 
73  class GroupNotFound: public std::exception
74  {
75  public:
76 
79 
81  ~GroupNotFound() throw () {};
82 
84  GroupNotFound(std::string fname, std::string gname)
85  {
86  filename = fname;
87  };
88 
90  virtual const char* what() const throw()
91  {
92  std::string msg ("the group ");
93  msg += groupname;
94  msg += " not found in the file ";
95  msg += filename;
96  const char* msg_rtn = msg.c_str();
97  return msg_rtn;
98  };
99 
100  private:
101  std::string filename;
102  std::string groupname;
103  };
104 
106  class PathNotFound: public std::exception
107  {
108  public:
109 
112 
114  ~PathNotFound() throw () {};
115 
117  PathNotFound(std::string fname, std::string pname)
118  {
119  filename = fname;
120  path = pname;
121  };
122 
124  virtual const char* what() const throw()
125  {
126  std::string msg ("the path ");
127  msg += path;
128  msg += " was not found in the HDF5 file ";
129  msg += filename;
130  const char* msg_rtn = msg.c_str();
131  return msg_rtn;
132  };
133 
134  private:
135  std::string filename;
136  std::string path;
137  };
138 
139 
140 
141  // Read-in Functions
142 
145  template <typename T>
146  T get_array_index(hid_t dset, int n, hid_t dtype=H5T_NATIVE_DOUBLE)
147  {
148  hsize_t count [1] = {1};
149  hsize_t offset [1] = {static_cast<hsize_t>(n)};
150 
151  hid_t dspace = H5Dget_space(dset);
152  hsize_t npoints = H5Sget_simple_extent_npoints(dspace);
153 
154  //Handle negative indices
155  if (n < 0)
156  offset[0] = offset[0] + npoints;
157 
158  //If still out of range we have a problem
159  if (npoints <= offset[0])
160  throw HDF5BoundsError();
161 
162  H5Sselect_hyperslab(dspace, H5S_SELECT_SET, offset, NULL, count, NULL);
163 
164  //Set memmory hyperspace
165  hsize_t dimsm[1] = {1};
166  hid_t memspace = H5Screate_simple(1, dimsm, NULL);
167 
168  hsize_t count_out [1] = {1};
169  hsize_t offset_out [1] = {0};
170 
171  H5Sselect_hyperslab(memspace, H5S_SELECT_SET, offset_out, NULL,
172  count_out, NULL);
173 
174  T data_out [1];
175  H5Dread(dset, dtype, memspace, dspace, H5P_DEFAULT, data_out);
176 
177  return data_out[0];
178  }
179 
180 
181  // Conversion functions
182 
189  template <typename T>
190  std::set<T> h5_array_to_cpp_set(hid_t h5file, std::string data_path, hid_t dtype=H5T_NATIVE_DOUBLE)
191  {
192  std::set<T> cpp_set = std::set<T>();
193  hsize_t arr_len[1];
194  hid_t dset = H5Dopen2(h5file, data_path.c_str(), H5P_DEFAULT);
195 
196  // Initilize to dataspace, to find the indices we are looping over
197  hid_t arr_space = H5Dget_space(dset);
198  int arr_dim = H5Sget_simple_extent_dims(arr_space, arr_len, NULL);
199 
200  // Read in data from file to memory
201  T * mem_arr = new T [arr_len[0]];
202  H5Dread(dset, dtype, H5S_ALL, H5S_ALL, H5P_DEFAULT, mem_arr);
203 
204  // Load new values into the set
205  cpp_set.insert(&mem_arr[0], &mem_arr[arr_len[0]]);
206 
207  H5Dclose(dset);
208 
209  delete[] mem_arr;
210  return cpp_set;
211  }
212 
213 
220  template <typename T>
221  std::vector<T> h5_array_to_cpp_vector_1d(hid_t h5file, std::string data_path,
222  hid_t dtype=H5T_NATIVE_DOUBLE)
223  {
224  std::vector<T> cpp_vec;
225  hsize_t arr_dims [1];
226  hid_t dset = H5Dopen2(h5file, data_path.c_str(), H5P_DEFAULT);
227 
228  // Initilize to dataspace, to find the indices we are looping over
229  hid_t arr_space = H5Dget_space(dset);
230  int arr_ndim = H5Sget_simple_extent_dims(arr_space, arr_dims, NULL);
231 
232  // Read in data from file to memory
233  T mem_arr [arr_dims[0]];
234  H5Dread(dset, dtype, H5S_ALL, H5S_ALL, H5P_DEFAULT, mem_arr);
235 
236  // Load new values into the vector
237  cpp_vec.assign(mem_arr, mem_arr+arr_dims[0]);
238 
239  H5Dclose(dset);
240  return cpp_vec;
241  }
242 
243 
250  template <typename T>
251  std::vector< std::vector<T> > h5_array_to_cpp_vector_2d(hid_t h5file, std::string data_path,
252  hid_t dtype=H5T_NATIVE_DOUBLE)
253  {
254  hsize_t arr_dims [2];
255  hid_t dset = H5Dopen2(h5file, data_path.c_str(), H5P_DEFAULT);
256 
257  // Initilize to dataspace, to find the indices we are looping over
258  hid_t arr_space = H5Dget_space(dset);
259  int arr_ndim = H5Sget_simple_extent_dims(arr_space, arr_dims, NULL);
260 
261  // Read in data from file to memory
262  // Have to read in as 1D array to get HDF5 and new keyword
263  // to play nice with each other
264  T mem_arr [arr_dims[0] * arr_dims[1]];
265  H5Dread(dset, dtype, H5S_ALL, H5S_ALL, H5P_DEFAULT, mem_arr);
266 
267  // Load new values into the vector of vectors, using some indexing tricks
268  std::vector< std::vector<T> > cpp_vec (arr_dims[0], std::vector<T>(arr_dims[1]));
269  for(int i = 0; i < arr_dims[0]; i++)
270  {
271  cpp_vec[i].assign(mem_arr+(i*arr_dims[1]), mem_arr+((i+1)*arr_dims[1]));
272  };
273 
274  H5Dclose(dset);
275  return cpp_vec;
276  }
277 
278 
285  template <typename T>
286  std::vector< std::vector< std::vector<T> > > h5_array_to_cpp_vector_3d(hid_t h5file,
287  std::string data_path,
288  hid_t dtype=H5T_NATIVE_DOUBLE)
289  {
290  hsize_t arr_dims [3];
291  hid_t dset = H5Dopen2(h5file, data_path.c_str(), H5P_DEFAULT);
292 
293  // Initilize to dataspace, to find the indices we are looping over
294  hid_t arr_space = H5Dget_space(dset);
295  int arr_ndim = H5Sget_simple_extent_dims(arr_space, arr_dims, NULL);
296 
297  // Read in data from file to memory
298  // Have to read in as 1D array to get HDF5 and new keyword
299  // to play nice with each other
300  T mem_arr [arr_dims[0] * arr_dims[1] * arr_dims[2]];
301  H5Dread(dset, dtype, H5S_ALL, H5S_ALL, H5P_DEFAULT, mem_arr);
302 
303  // Load new values into the vector of vectors of vectors, using some indexing tricks
304  std::vector< std::vector< std::vector<T> > > cpp_vec (arr_dims[0], std::vector< std::vector<T> >(arr_dims[1], std::vector<T>(arr_dims[2])));
305  for(int i = 0; i < arr_dims[0]; i++)
306  {
307  for(int j = 0; j < arr_dims[1]; j++)
308  {
309  cpp_vec[i][j].assign(mem_arr+((i*arr_dims[1]*arr_dims[2]) + (j*arr_dims[2])), mem_arr+((i*arr_dims[1]*arr_dims[2]) + ((j+1)*arr_dims[2])));
310  };
311  };
312 
313  H5Dclose(dset);
314  return cpp_vec;
315  }
316 
317 
318 
319  // Classes
322  template <typename T>
324  {
325  public:
326 
329 
332 
338  HomogenousTypeTable(hid_t h5file, std::string data_path, hid_t dtype=H5T_NATIVE_DOUBLE)
339  {
340  hid_t h5_set = H5Dopen2(h5file, data_path.c_str(), H5P_DEFAULT);
341  hid_t h5_space = H5Dget_space(h5_set);
342  hid_t h5_type = H5Dget_type(h5_set);
343 
344  // set path
345  path = data_path;
346 
347  // set shape
348  shape[0] = H5Sget_simple_extent_npoints(h5_space);
349  shape[1] = H5Tget_nmembers(h5_type);
350 
351  // set cols
352  std::string * cols_buf = new std::string [shape[1]];
353  for(int n = 0; n < shape[1]; n++)
354  cols_buf[n] = H5Tget_member_name(h5_type, n);
355  cols.assign(cols_buf, cols_buf+shape[1]);
356 
357  // set data
358  hid_t col_type;
359  T * col_buf = new T [shape[0]];
360 
361  data.clear();
362  for(int n = 0; n < shape[1]; n++)
363  {
364  // Make a compound data type of just this column
365  col_type = H5Tcreate(H5T_COMPOUND, sizeof(T));
366  H5Tinsert(col_type, cols[n].c_str(), 0, dtype);
367 
368  // Read in this column
369  H5Dread(h5_set, col_type, H5S_ALL, H5S_ALL, H5P_DEFAULT, col_buf);
370 
371  // save this column as a vector in out data map
372  data[cols[n]] = std::vector<T>(col_buf, col_buf+shape[0]);
373  };
374  delete[] col_buf;
375  };
376 
377  // Metadata attributes
378  std::string path;
379  int shape [2];
380  std::vector<std::string> cols;
381  std::map<std::string, std::vector<T> > data;
383 
384  //
385  // operator overloads
386  //
388  std::vector<T> operator[] (std::string col_name)
389  {
390  return data[col_name];
391  };
392 
394  std::map<std::string, T> operator[] (int m)
395  {
396  std::map<std::string, T> row = std::map<std::string, T>();
397 
398  for(int n = 0; n < shape[1]; n++)
399  row[cols[n]] = data[cols[n]][m];
400 
401  return row;
402  };
403  };
404 
405 
409  {
410  hid_t ct = H5Tcreate(H5T_COMPOUND, sizeof(xd_complex_t));
411  H5Tinsert(ct, "r", HOFFSET(xd_complex_t, re), H5T_NATIVE_DOUBLE);
412  H5Tinsert(ct, "i", HOFFSET(xd_complex_t, im), H5T_NATIVE_DOUBLE);
413  return ct;
414  }
415 
417  static hid_t PYTABLES_COMPLEX128 = _get_PYTABLES_COMPLEX128();
418 
419 
424  inline bool path_exists(hid_t h5file, std::string path)
425  {
426  bool rtn = false;
427  hid_t ds = H5Dopen2(h5file, path.c_str(), H5P_DEFAULT);
428  if (0 <= ds)
429  {
430  rtn = true;
431  H5Dclose(ds);
432  }
433  else
434  {
435  hid_t grp = H5Gopen2(h5file, path.c_str(), H5P_DEFAULT);
436  if (0 <= grp)
437  {
438  rtn = true;
439  H5Gclose(grp);
440  }
441  }
442  return rtn;
443  }
444 
445 
446 // End namespace h5wrap
447 }
448 
449 
450 
451 #endif
std::vector< std::string > cols
Definition: h5wrap.h:380
~PathNotFound()
default destructor
Definition: h5wrap.h:114
FileNotHDF5(std::string fname)
constructor with the filename
Definition: h5wrap.h:51
PathNotFound()
default constructor
Definition: h5wrap.h:111
complex type struct, matching PyTables definition
Definition: extra_types.h:56
std::string path
path in file to the data
Definition: h5wrap.h:375
std::set< T > h5_array_to_cpp_set(hid_t h5file, std::string data_path, hid_t dtype=H5T_NATIVE_DOUBLE)
Definition: h5wrap.h:190
HomogenousTypeTable(hid_t h5file, std::string data_path, hid_t dtype=H5T_NATIVE_DOUBLE)
Definition: h5wrap.h:338
Custom exception for when a path is not found in an HDF5 file.
Definition: h5wrap.h:106
~GroupNotFound()
default destructor
Definition: h5wrap.h:81
GroupNotFound()
default constructor
Definition: h5wrap.h:78
virtual const char * what() const
helpful error message that includes the filename and the groupname
Definition: h5wrap.h:90
~HomogenousTypeTable()
default destructor
Definition: h5wrap.h:331
std::vector< T > h5_array_to_cpp_vector_1d(hid_t h5file, std::string data_path, hid_t dtype=H5T_NATIVE_DOUBLE)
Definition: h5wrap.h:221
PathNotFound(std::string fname, std::string pname)
constructor with the filename and the pathname
Definition: h5wrap.h:117
std::vector< std::vector< T > > h5_array_to_cpp_vector_2d(hid_t h5file, std::string data_path, hid_t dtype=H5T_NATIVE_DOUBLE)
Definition: h5wrap.h:251
FileNotHDF5()
default constructor
Definition: h5wrap.h:45
Custom exception for when an existing file is not in a valid HDF5 format.
Definition: h5wrap.h:40
HomogenousTypeTable()
default constructor
Definition: h5wrap.h:328
Custom exception for when a group cannot be found in an HDF5 file.
Definition: h5wrap.h:73
virtual const char * what() const
helpful error message that includes the filename and the pathname
Definition: h5wrap.h:124
std::vector< std::vector< std::vector< T > > > h5_array_to_cpp_vector_3d(hid_t h5file, std::string data_path, hid_t dtype=H5T_NATIVE_DOUBLE)
Definition: h5wrap.h:286
~FileNotHDF5()
default destructor
Definition: h5wrap.h:48
Wrapper for standard HDF5 operations.
Definition: h5wrap.h:26
hid_t _get_PYTABLES_COMPLEX128()
Definition: h5wrap.h:408
Custom exception for HDF5 indexing errors.
Definition: h5wrap.h:29
GroupNotFound(std::string fname, std::string gname)
constructor with the filename and the groupname
Definition: h5wrap.h:84
virtual const char * what() const
helpful error message that includes the filename
Definition: h5wrap.h:57
Definition: h5wrap.h:323
T get_array_index(hid_t dset, int n, hid_t dtype=H5T_NATIVE_DOUBLE)
Definition: h5wrap.h:146
bool path_exists(hid_t h5file, std::string path)
Definition: h5wrap.h:424