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  return (const char *) FNH5str.c_str();
64  };
65 
66  private:
67  std::string filename;
68  };
69 
70 
72  class GroupNotFound: public std::exception
73  {
74  public:
75 
78 
80  ~GroupNotFound() throw () {};
81 
83  GroupNotFound(std::string fname, std::string gname)
84  {
85  filename = fname;
86  };
87 
89  virtual const char* what() const throw()
90  {
91  std::string msg ("the group ");
92  msg += groupname;
93  msg += " not found in the file ";
94  msg += filename;
95  return (const char *) msg.c_str();
96  };
97 
98  private:
99  std::string filename;
100  std::string groupname;
101  };
102 
104  class PathNotFound: public std::exception
105  {
106  public:
107 
110 
112  ~PathNotFound() throw () {};
113 
115  PathNotFound(std::string fname, std::string pname)
116  {
117  filename = fname;
118  path = pname;
119  };
120 
122  virtual const char* what() const throw()
123  {
124  std::string msg ("the path ");
125  msg += path;
126  msg += " was not found in the HDF5 file ";
127  msg += filename;
128  return (const char *) msg.c_str();
129  };
130 
131  private:
132  std::string filename;
133  std::string path;
134  };
135 
136 
137 
138  // Read-in Functions
139 
142  template <typename T>
143  T get_array_index(hid_t dset, int n, hid_t dtype=H5T_NATIVE_DOUBLE)
144  {
145  hsize_t count [1] = {1};
146  hsize_t offset [1] = {static_cast<hsize_t>(n)};
147 
148  hid_t dspace = H5Dget_space(dset);
149  hsize_t npoints = H5Sget_simple_extent_npoints(dspace);
150 
151  //Handle negative indices
152  if (n < 0)
153  offset[0] = offset[0] + npoints;
154 
155  //If still out of range we have a problem
156  if (npoints <= offset[0])
157  throw HDF5BoundsError();
158 
159  H5Sselect_hyperslab(dspace, H5S_SELECT_SET, offset, NULL, count, NULL);
160 
161  //Set memmory hyperspace
162  hsize_t dimsm[1] = {1};
163  hid_t memspace = H5Screate_simple(1, dimsm, NULL);
164 
165  hsize_t count_out [1] = {1};
166  hsize_t offset_out [1] = {0};
167 
168  H5Sselect_hyperslab(memspace, H5S_SELECT_SET, offset_out, NULL,
169  count_out, NULL);
170 
171  T data_out [1];
172  H5Dread(dset, dtype, memspace, dspace, H5P_DEFAULT, data_out);
173 
174  return data_out[0];
175  }
176 
177 
178  // Conversion functions
179 
186  template <typename T>
187  std::set<T> h5_array_to_cpp_set(hid_t h5file, std::string data_path, hid_t dtype=H5T_NATIVE_DOUBLE)
188  {
189  std::set<T> cpp_set = std::set<T>();
190  hsize_t arr_len[1];
191  hid_t dset = H5Dopen2(h5file, data_path.c_str(), H5P_DEFAULT);
192 
193  // Initilize to dataspace, to find the indices we are looping over
194  hid_t arr_space = H5Dget_space(dset);
195  int arr_dim = H5Sget_simple_extent_dims(arr_space, arr_len, NULL);
196 
197  // Read in data from file to memory
198  T * mem_arr = new T [arr_len[0]];
199  H5Dread(dset, dtype, H5S_ALL, H5S_ALL, H5P_DEFAULT, mem_arr);
200 
201  // Load new values into the set
202  cpp_set.insert(&mem_arr[0], &mem_arr[arr_len[0]]);
203 
204  H5Dclose(dset);
205 
206  delete[] mem_arr;
207  return cpp_set;
208  }
209 
210 
217  template <typename T>
218  std::vector<T> h5_array_to_cpp_vector_1d(hid_t h5file, std::string data_path,
219  hid_t dtype=H5T_NATIVE_DOUBLE)
220  {
221  std::vector<T> cpp_vec;
222  hsize_t arr_dims [1];
223  hid_t dset = H5Dopen2(h5file, data_path.c_str(), H5P_DEFAULT);
224 
225  // Initilize to dataspace, to find the indices we are looping over
226  hid_t arr_space = H5Dget_space(dset);
227  int arr_ndim = H5Sget_simple_extent_dims(arr_space, arr_dims, NULL);
228 
229  // Read in data from file to memory
230  T mem_arr [arr_dims[0]];
231  H5Dread(dset, dtype, H5S_ALL, H5S_ALL, H5P_DEFAULT, mem_arr);
232 
233  // Load new values into the vector
234  cpp_vec.assign(mem_arr, mem_arr+arr_dims[0]);
235 
236  H5Dclose(dset);
237  return cpp_vec;
238  }
239 
240 
247  template <typename T>
248  std::vector< std::vector<T> > h5_array_to_cpp_vector_2d(hid_t h5file, std::string data_path,
249  hid_t dtype=H5T_NATIVE_DOUBLE)
250  {
251  hsize_t arr_dims [2];
252  hid_t dset = H5Dopen2(h5file, data_path.c_str(), H5P_DEFAULT);
253 
254  // Initilize to dataspace, to find the indices we are looping over
255  hid_t arr_space = H5Dget_space(dset);
256  int arr_ndim = H5Sget_simple_extent_dims(arr_space, arr_dims, NULL);
257 
258  // Read in data from file to memory
259  // Have to read in as 1D array to get HDF5 and new keyword
260  // to play nice with each other
261  T mem_arr [arr_dims[0] * arr_dims[1]];
262  H5Dread(dset, dtype, H5S_ALL, H5S_ALL, H5P_DEFAULT, mem_arr);
263 
264  // Load new values into the vector of vectors, using some indexing tricks
265  std::vector< std::vector<T> > cpp_vec (arr_dims[0], std::vector<T>(arr_dims[1]));
266  for(int i = 0; i < arr_dims[0]; i++)
267  {
268  cpp_vec[i].assign(mem_arr+(i*arr_dims[1]), mem_arr+((i+1)*arr_dims[1]));
269  };
270 
271  H5Dclose(dset);
272  return cpp_vec;
273  }
274 
275 
282  template <typename T>
283  std::vector< std::vector< std::vector<T> > > h5_array_to_cpp_vector_3d(hid_t h5file,
284  std::string data_path,
285  hid_t dtype=H5T_NATIVE_DOUBLE)
286  {
287  hsize_t arr_dims [3];
288  hid_t dset = H5Dopen2(h5file, data_path.c_str(), H5P_DEFAULT);
289 
290  // Initilize to dataspace, to find the indices we are looping over
291  hid_t arr_space = H5Dget_space(dset);
292  int arr_ndim = H5Sget_simple_extent_dims(arr_space, arr_dims, NULL);
293 
294  // Read in data from file to memory
295  // Have to read in as 1D array to get HDF5 and new keyword
296  // to play nice with each other
297  T mem_arr [arr_dims[0] * arr_dims[1] * arr_dims[2]];
298  H5Dread(dset, dtype, H5S_ALL, H5S_ALL, H5P_DEFAULT, mem_arr);
299 
300  // Load new values into the vector of vectors of vectors, using some indexing tricks
301  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])));
302  for(int i = 0; i < arr_dims[0]; i++)
303  {
304  for(int j = 0; j < arr_dims[1]; j++)
305  {
306  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])));
307  };
308  };
309 
310  H5Dclose(dset);
311  return cpp_vec;
312  }
313 
314 
315 
316  // Classes
319  template <typename T>
321  {
322  public:
323 
326 
329 
335  HomogenousTypeTable(hid_t h5file, std::string data_path, hid_t dtype=H5T_NATIVE_DOUBLE)
336  {
337  hid_t h5_set = H5Dopen2(h5file, data_path.c_str(), H5P_DEFAULT);
338  hid_t h5_space = H5Dget_space(h5_set);
339  hid_t h5_type = H5Dget_type(h5_set);
340 
341  // set path
342  path = data_path;
343 
344  // set shape
345  shape[0] = H5Sget_simple_extent_npoints(h5_space);
346  shape[1] = H5Tget_nmembers(h5_type);
347 
348  // set cols
349  std::string * cols_buf = new std::string [shape[1]];
350  for(int n = 0; n < shape[1]; n++)
351  cols_buf[n] = H5Tget_member_name(h5_type, n);
352  cols.assign(cols_buf, cols_buf+shape[1]);
353 
354  // set data
355  hid_t col_type;
356  T * col_buf = new T [shape[0]];
357 
358  data.clear();
359  for(int n = 0; n < shape[1]; n++)
360  {
361  // Make a compound data type of just this column
362  col_type = H5Tcreate(H5T_COMPOUND, sizeof(T));
363  H5Tinsert(col_type, cols[n].c_str(), 0, dtype);
364 
365  // Read in this column
366  H5Dread(h5_set, col_type, H5S_ALL, H5S_ALL, H5P_DEFAULT, col_buf);
367 
368  // save this column as a vector in out data map
369  data[cols[n]] = std::vector<T>(col_buf, col_buf+shape[0]);
370  };
371  delete[] col_buf;
372  };
373 
374  // Metadata attributes
375  std::string path;
376  int shape [2];
377  std::vector<std::string> cols;
378  std::map<std::string, std::vector<T> > data;
380 
381  //
382  // operator overloads
383  //
385  std::vector<T> operator[] (std::string col_name)
386  {
387  return data[col_name];
388  };
389 
391  std::map<std::string, T> operator[] (int m)
392  {
393  std::map<std::string, T> row = std::map<std::string, T>();
394 
395  for(int n = 0; n < shape[1]; n++)
396  row[cols[n]] = data[cols[n]][m];
397 
398  return row;
399  };
400  };
401 
402 
406  {
407  hid_t ct = H5Tcreate(H5T_COMPOUND, sizeof(xd_complex_t));
408  H5Tinsert(ct, "r", HOFFSET(xd_complex_t, re), H5T_NATIVE_DOUBLE);
409  H5Tinsert(ct, "i", HOFFSET(xd_complex_t, im), H5T_NATIVE_DOUBLE);
410  return ct;
411  }
412 
414  static hid_t PYTABLES_COMPLEX128 = _get_PYTABLES_COMPLEX128();
415 
416 
421  inline bool path_exists(hid_t h5file, std::string path)
422  {
423  bool rtn = false;
424  hid_t ds = H5Dopen2(h5file, path.c_str(), H5P_DEFAULT);
425  if (0 <= ds)
426  {
427  rtn = true;
428  H5Dclose(ds);
429  }
430  else
431  {
432  hid_t grp = H5Gopen2(h5file, path.c_str(), H5P_DEFAULT);
433  if (0 <= grp)
434  {
435  rtn = true;
436  H5Gclose(grp);
437  }
438  }
439  return rtn;
440  }
441 
442 
443 // End namespace h5wrap
444 }
445 
446 
447 
448 #endif
std::vector< std::string > cols
Definition: h5wrap.h:377
~PathNotFound()
default destructor
Definition: h5wrap.h:112
FileNotHDF5(std::string fname)
constructor with the filename
Definition: h5wrap.h:51
PathNotFound()
default constructor
Definition: h5wrap.h:109
virtual const char * what() const
helpful error message that includes the filename and the groupname
Definition: h5wrap.h:89
complex type struct, matching PyTables definition
Definition: extra_types.h:56
std::string path
path in file to the data
Definition: h5wrap.h:372
std::set< T > h5_array_to_cpp_set(hid_t h5file, std::string data_path, hid_t dtype=H5T_NATIVE_DOUBLE)
Definition: h5wrap.h:187
HomogenousTypeTable(hid_t h5file, std::string data_path, hid_t dtype=H5T_NATIVE_DOUBLE)
Definition: h5wrap.h:335
Custom exception for when a path is not found in an HDF5 file.
Definition: h5wrap.h:104
~GroupNotFound()
default destructor
Definition: h5wrap.h:80
GroupNotFound()
default constructor
Definition: h5wrap.h:77
~HomogenousTypeTable()
default destructor
Definition: h5wrap.h:328
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:218
PathNotFound(std::string fname, std::string pname)
constructor with the filename and the pathname
Definition: h5wrap.h:115
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:248
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:325
Custom exception for when a group cannot be found in an HDF5 file.
Definition: h5wrap.h:72
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:283
~FileNotHDF5()
default destructor
Definition: h5wrap.h:48
Wrapper for standard HDF5 operations.
Definition: h5wrap.h:26
virtual const char * what() const
helpful error message that includes the filename
Definition: h5wrap.h:57
hid_t _get_PYTABLES_COMPLEX128()
Definition: h5wrap.h:405
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:83
Definition: h5wrap.h:320
T get_array_index(hid_t dset, int n, hid_t dtype=H5T_NATIVE_DOUBLE)
Definition: h5wrap.h:143
virtual const char * what() const
helpful error message that includes the filename and the pathname
Definition: h5wrap.h:122
bool path_exists(hid_t h5file, std::string path)
Definition: h5wrap.h:421