hdf_file.h
Go to the documentation of this file.
1 /*
2  -------------------------------------------------------------------
3 
4  Copyright (C) 2006-2017, Andrew W. Steiner
5 
6  This file is part of O2scl.
7 
8  O2scl is free software; you can redistribute it and/or modify
9  it under the terms of the GNU General Public License as published by
10  the Free Software Foundation; either version 3 of the License, or
11  (at your option) any later version.
12 
13  O2scl is distributed in the hope that it will be useful,
14  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  GNU General Public License for more details.
17 
18  You should have received a copy of the GNU General Public License
19  along with O2scl. If not, see <http://www.gnu.org/licenses/>.
20 
21  -------------------------------------------------------------------
22 */
23 #ifndef O2SCL_HDF_FILE_H
24 #define O2SCL_HDF_FILE_H
25 
26 /** \file hdf_file.h
27  \brief File defining \ref o2scl_hdf::hdf_file
28 */
29 #include <limits>
30 
31 #include <hdf5.h>
32 
33 #include <boost/numeric/ublas/vector.hpp>
34 #include <boost/numeric/ublas/matrix.hpp>
35 
36 #include <o2scl/vector.h>
37 #include <o2scl/tensor.h>
38 #include <o2scl/format_float.h>
39 
40 /** \brief The \o2 namespace for I/O with HDF
41  */
42 namespace o2scl_hdf {
43 
44  /** \brief Store data in an \o2 compatible HDF5 file
45 
46  See also the \ref hdf_section section of the \o2
47  User's guide.
48 
49  The member functions which write or get data from an HDF file
50  begin with either <tt>get</tt> or <tt>set</tt>. Where
51  appropriate, the next character is either \c c for character, \c
52  d for double, \c f for float, or \c i for int.
53 
54  By default, vectors and matrices are written to HDF files in a
55  chunked format, so their length can be changed later as
56  necessary. The chunk size is chosen in \ref def_chunk() to be
57  the closest power of 10 to the current vector size.
58 
59  All files not closed by the user are closed in the destructor,
60  but the destructor does not automatically close groups.
61 
62  \note Currently, HDF I/O functions write data to HDF files
63  assuming that \c int and \c float have 4 bytes, while \c size_t
64  and \c double are 8 bytes. All output is done in little endian
65  format. While <tt>get</tt> functions can read data with
66  different sizes or in big endian format, the <tt>set</tt>
67  functions cannot currently write data this way.
68 
69  \note It does make sense to write a zero-length vector to an HDF
70  file if the vector does not have a fixed size in order to create
71  a placeholder for future output. Thus the <tt>set_vec()</tt> and
72  allow zero-length vectors and the <tt>set_arr()</tt> functions
73  allow the <tt>size_t</tt> parameter to be zero, in which case
74  the pointer parameter is ignored. The <tt>set_vec_fixed()</tt>
75  and <tt>set_arr_fixed()</tt> functions do not allow this, and
76  will throw an exception if sent a zero-length vector.
77 
78  \warning This class is still in development. Because of this,
79  hdf5 files generated by this class may not be easily read by
80  future versions. Later versions of \o2 will have stronger
81  guarantees on backwards compatibility.
82 
83  \future This class opens all files in R/W mode, which may
84  cause I/O problems in file systems. This needs to be
85  fixed by allowing the user to open a read-only file.
86  \future The \o2 HDF functions do not always consistently choose
87  between throwing \o2 exceptions and throwing HDF5 exceptions.
88  Check and/or fix this.
89  \future Automatically close groups, e.g. by storing hid_t's in a
90  stack?
91  \future Rewrite the _arr_alloc() functions so that they
92  return a shared_ptr.
93  \future Move the code from the 'filelist' acol command here
94  into hdf_file.
95  */
96  class hdf_file {
97 
98  public:
99 
104 
105 #ifndef DOXYGEN_INTERNAL
106 
107  protected:
108 
109  /// File ID
110  hid_t file;
111 
112  /// True if a file has been opened
113  bool file_open;
114 
115  /// Current file or group location
116  hid_t current;
117 
118  /** \brief Default chunk size
119 
120  Choose the closest power of 10 which is greater than or equal
121  to 10 and less than or equal to \f$ 10^6 \f$.
122  */
123  virtual hsize_t def_chunk(size_t n) {
124  size_t ch=(size_t)((1.0+1.0e-12)*
125  pow(10.0,floor(log10(((double)n))+0.5)));
126  if (ch<10) ch=10;
127  if (ch>1000000) ch=1000000;
128  return ch;
129  }
130 
131  /// If true, then the file has read and write access
133 
134 #endif
135 
136  public:
137 
138  hdf_file();
139 
140  virtual ~hdf_file();
141 
142  /// If true, then the file has read and write access
144  return write_access;
145  }
146 
147  /// Compression type (not yet supported)
149 
150  /// \name Open and close files
151  //@{
152  /** \brief Open a file named \c fname
153 
154  If \c err_on_fail is \c true, this calls the error handler if
155  opening the file fails (e.g. because the file does not exist).
156  If \c err_on_fail is \c false and opening the file fails,
157  nothing is done and the function returns the value \ref
158  o2scl::exc_efilenotfound. If the open succeeds, this function
159  returns \ref o2scl::success.
160  */
161  int open(std::string fname, bool write_access=false,
162  bool err_on_fail=true);
163 
164  /// Open a file named \c fname or create if it doesn't already exist
165  void open_or_create(std::string fname);
166 
167  /// Close the file
168  void close();
169  //@}
170 
171  /// \name Manipulate ids
172  //@{
173  /// Get the current file id
174  hid_t get_file_id();
175 
176  /// Set the current working id
177  void set_current_id(hid_t cur);
178 
179  /// Retrieve the current working id
180  hid_t get_current_id();
181  //@}
182 
183  /** \name Simple get functions
184 
185  If the specified object is not found, the \o2 error handler
186  will be called.
187  */
188  //@{
189  /// Get a character named \c name
190  int getc(std::string name, char &c);
191 
192  /// Get a double named \c name
193  int getd(std::string name, double &d);
194 
195  /// Get a float named \c name
196  int getf(std::string name, float &f);
197 
198  /// Get a integer named \c name
199  int geti(std::string name, int &i);
200 
201  /// Get an unsigned integer named \c name
202  int get_szt(std::string name, size_t &u);
203 
204  /** \brief Get a string named \c name
205 
206  \note Strings are stored as character arrays and thus
207  retrieving a string from a file requires loading the
208  information from the file into a character array, and then
209  copying it to the string. This will be slow for very long
210  strings.
211  */
212  int gets(std::string name, std::string &s);
213 
214  /** \brief Get a fixed-length string named \c name
215  */
216  int gets_fixed(std::string name, std::string &s);
217 
218  /** \brief Get a fixed-length string named \c name with default
219  value \c s
220  */
221  int gets_def_fixed(std::string name, std::string def, std::string &s);
222  //@}
223 
224  /// \name Simple set functions
225  //@{
226  /// Set a character named \c name to value \c c
227  void setc(std::string name, char c);
228 
229  /// Set a double named \c name to value \c d
230  void setd(std::string name, double d);
231 
232  /// Set a float named \c name to value \c f
233  void setf(std::string name, float f);
234 
235  /// Set an integer named \c name to value \c i
236  void seti(std::string name, int i);
237 
238  /// Set an unsigned integer named \c name to value \c u
239  void set_szt(std::string name, size_t u);
240 
241  /** \brief Set a string named \c name to value \c s
242 
243  The string is stored in the HDF file as an extensible
244  character array rather than a string.
245  */
246  void sets(std::string name, std::string s);
247 
248  /** \brief Set a fixed-length string named \c name to value \c s
249 
250  This function stores <tt>s</tt> as a fixed-length string
251  in the HDF file. If a dataset named \c name is already
252  present, then \c s must not be longer than the string
253  length already specified in the HDF file.
254  */
255  void sets_fixed(std::string name, std::string s);
256  //@}
257 
258  /// \name Group manipulation
259  //@{
260  /** \brief Open a group relative to the location specified in
261  \c init_id
262 
263  \note In order to ensure that future objects are written to the
264  newly-created group, the user must use set_current_id()
265  using the newly-created group ID for the argument.
266  */
267  hid_t open_group(hid_t init_id, std::string path);
268 
269  /** \brief Open a group relative to the current location
270 
271  \note In order to ensure that future objects are written to the
272  newly-created group, the user must use set_current_id()
273  using the newly-created group ID for the argument.
274  */
275  hid_t open_group(std::string path);
276 
277  /// Close a previously created group
278  int close_group(hid_t group) {
279  return H5Gclose(group);
280  }
281  //@}
282 
283  /** \name Vector get functions
284 
285  These functions automatically free any previously allocated
286  memory in <tt>v</tt> and then allocate the proper space
287  required to read the information from the HDF file.
288  */
289  //@{
290  /// Get vector dataset and place data in \c v
291  int getd_vec(std::string name, std::vector<double> &v);
292 
293  /** \brief Get vector dataset and place data in \c v
294 
295  This works with any vector class which has a
296  <tt>resize()</tt> method.
297 
298  \future This currently requires a copy, but there may
299  be a way to write a new version which does not.
300  \comment
301  AWS 12/10/13: I don't think the ublas library guarantees
302  that the vector occupies a continuous chunk of memory
303  like std::vector<> now does.
304  \endcomment
305  */
306  template<class vec_t>
307  int getd_vec_copy(std::string name, vec_t &v) {
308  std::vector<double> v2;
309  int ret=getd_vec(name,v2);
310  v.resize(v2.size());
311  o2scl::vector_copy(v2.size(),v2,v);
312  return ret;
313  }
314 
315  /// Get vector dataset and place data in \c v
316  int geti_vec(std::string name, std::vector<int> &v);
317  /** \brief Get vector dataset and place data in \c v
318 
319  \future This currently requires a copy, but there may
320  be a way to write a new version which does not.
321  */
322  template<class vec_int_t>
323  int geti_vec_copy(std::string name, vec_int_t &v) {
324  std::vector<int> v2;
325  int ret=geti_vec(name,v2);
326  v.resize(v2.size());
327  for(size_t i=0;i<v2.size();i++) v[i]=v2[i];
328  return ret;
329  }
330  /// Get vector dataset and place data in \c v
331  int get_szt_vec(std::string name, std::vector<size_t> &v);
332  /** \brief Get vector dataset and place data in \c v
333 
334  \future This currently requires a copy, but there may
335  be a way to write a new version which does not.
336  */
337  template<class vec_size_t>
338  int get_szt_vec_copy(std::string name, vec_size_t &v) {
339  std::vector<int> v2;
340  int ret=geti_vec(name,v2);
341  v.resize(v2.size());
342  for(size_t i=0;i<v2.size();i++) v[i]=v2[i];
343  return ret;
344  }
345  /** \brief Get a vector of strings named \c name and store it in \c s
346  */
347  int gets_vec(std::string name, std::vector<std::string> &s);
348  //@}
349 
350  /** \name Vector set functions
351 
352  These functions automatically write all of the vector elements
353  to the HDF file, if necessary extending the data that is
354  already present.
355  */
356  //@{
357  /// Set vector dataset named \c name with \c v
358  int setd_vec(std::string name, const std::vector<double> &v);
359 
360  /** \brief Set vector dataset named \c name with \c v
361 
362  This requires a copy before the vector is written to
363  the file.
364  */
365  template<class vec_t>
366  int setd_vec_copy(std::string name, const vec_t &v) {
367  if (v.size()==0) {
368  return setd_arr(name,0,0);
369  }
370 
371  // We have to copy to an std::vector first
372  std::vector<double> v2(v.size());
373  o2scl::vector_copy(v.size(),v,v2);
374 
375  return setd_arr(name,v2.size(),&v2[0]);
376  }
377 
378  /// Set vector dataset named \c name with \c v
379  int seti_vec(std::string name, const std::vector<int> &v);
380  /** \brief Set vector dataset named \c name with \c v
381 
382  This requires a copy before the vector is written to
383  the file.
384  */
385  template<class vec_int_t>
386  int seti_vec_copy(std::string name, vec_int_t &v) {
387  if (v.size()==0) {
388  return seti_arr(name,0,0);
389  }
390 
391  // We have to copy to an std::vector first
392  std::vector<int> v2(v.size());
393  vector_copy(v.size(),v,v2);
394 
395  return seti_arr(name,v2.size(),&v2[0]);
396  }
397  /// Set vector dataset named \c name with \c v
398  int set_szt_vec(std::string name, const std::vector<size_t> &v);
399  /** \brief Set vector dataset named \c name with \c v
400 
401  This requires a copy before the vector is written to
402  the file.
403  */
404  template<class vec_size_t>
405  int set_szt_vec_copy(std::string name, vec_size_t &v) {
406  if (v.size()==0) {
407  return set_szt_arr(name,0,0);
408  }
409 
410  // We have to copy to an std::vector first
411  std::vector<size_t> v2(v.size());
412  vector_copy(v.size(),v,v2);
413 
414  return set_szt_arr(name,v2.size(),&v2[0]);
415  }
416 
417  /** \brief Set a vector of strings named \c name
418 
419  \devnote
420  String vectors are reformatted as a single character array, in
421  order to allow each string to have different length and to
422  make each string extensible. The size of the vector \c s is
423  stored as an integer named <tt>nw</tt>.
424  */
425  int sets_vec(std::string name, std::vector<std::string> &s);
426  //@}
427 
428  /** \name Matrix get functions
429 
430  These functions automatically free any previously allocated
431  memory in <tt>m</tt> and then allocate the proper space
432  required to read the information from the HDF file.
433  */
434  //@{
435  /// Get matrix dataset and place data in \c m
436  int getd_mat_copy(std::string name, ubmatrix &m);
437  /// Get matrix dataset and place data in \c m
438  int geti_mat_copy(std::string name, ubmatrix_int &m);
439  //@}
440 
441  /** \name Matrix set functions
442 
443  These functions automatically write all of the vector elements
444  to the HDF file, if necessary extending the data that is
445  already present.
446  */
447  //@{
448  /** \brief Set matrix dataset named \c name with \c m
449  */
450  int setd_mat_copy(std::string name, const ubmatrix &m);
451 
452  /** \brief Set matrix dataset named \c name with \c m
453  */
454  int seti_mat_copy(std::string name, const ubmatrix_int &m);
455 
456  /** \brief Set a two-dimensional array dataset named \c name with \c m
457  */
458  template<class arr2d_t>
459  int setd_arr2d_copy(std::string name, size_t r,
460  size_t c, const arr2d_t &a2d) {
461 
462  if (write_access==false) {
463  O2SCL_ERR2("File not opened with write access ",
464  "in hdf_file::setd_arr2d_copy().",o2scl::exc_efailed);
465  }
466 
467  // Copy to a C-style array
468  double *d=new double[r*c];
469  for(size_t i=0;i<r;i++) {
470  for(size_t j=0;j<c;j++) {
471  d[i*c+j]=a2d[i][j];
472  }
473  }
474 
475  hid_t dset, space, dcpl=0;
476  bool chunk_alloc=false;
477 
478  H5E_BEGIN_TRY
479  {
480  // See if the dataspace already exists first
481  dset=H5Dopen(current,name.c_str(),H5P_DEFAULT);
482  }
483  H5E_END_TRY
484 #ifdef O2SCL_NEVER_DEFINED
485  {
486  }
487 #endif
488 
489  // If it doesn't exist, create it
490  if (dset<0) {
491 
492  // Create the dataspace
493  hsize_t dims[2]={r,c};
494  hsize_t max[2]={H5S_UNLIMITED,H5S_UNLIMITED};
495  space=H5Screate_simple(2,dims,max);
496 
497  // Set chunk with size determined by def_chunk()
498  dcpl=H5Pcreate(H5P_DATASET_CREATE);
499  hsize_t chunk[2]={def_chunk(r),def_chunk(c)};
500  int status2=H5Pset_chunk(dcpl,2,chunk);
501 
502 #ifdef O2SCL_HDF5_COMP
503  // Compression part
504  if (compr_type==1) {
505  int status3=H5Pset_deflate(dcpl,6);
506  } else if (compr_type==2) {
507  int status3=H5Pset_szip(dcpl,H5_SZIP_NN_OPTION_MASK,16);
508  } else if (compr_type!=0) {
509  O2SCL_ERR2("Invalid compression type in ",
510  "hdf_file::setd_arr2d_copy().",o2scl::exc_einval);
511  }
512 #endif
513 
514  // Create the dataset
515  dset=H5Dcreate(current,name.c_str(),H5T_IEEE_F64LE,space,H5P_DEFAULT,
516  dcpl,H5P_DEFAULT);
517  chunk_alloc=true;
518 
519  } else {
520 
521  // Get current dimensions
522  space=H5Dget_space(dset);
523  hsize_t dims[2];
524  int ndims=H5Sget_simple_extent_dims(space,dims,0);
525 
526  // Set error if this dataset is more than 1-dimensional
527  if (ndims!=2) {
528  O2SCL_ERR2("Tried to set a non-matrix dataset with a ",
529  "matrix in hdf_file::setd_arr2d_copy().",
531  }
532 
533  // If necessary, extend the dataset
534  if (r!=dims[0] || c!=dims[1]) {
535  hsize_t new_dims[2]={r,c};
536  int status3=H5Dset_extent(dset,new_dims);
537  }
538 
539  }
540 
541  // Write the data
542  int status;
543  status=H5Dwrite(dset,H5T_NATIVE_DOUBLE,H5S_ALL,
544  H5S_ALL,H5P_DEFAULT,d);
545 
546  status=H5Dclose(dset);
547  status=H5Sclose(space);
548  if (chunk_alloc) {
549  status=H5Pclose(dcpl);
550  }
551 
552  // Free the C-style array
553  delete[] d;
554 
555  return 0;
556  }
557 
558  /** \brief Set a two-dimensional array dataset named \c name with \c m
559  */
560  template<class arr2d_t>
561  int seti_arr2d_copy(std::string name, size_t r,
562  size_t c, const arr2d_t &a2d) {
563 
564  if (write_access==false) {
565  O2SCL_ERR2("File not opened with write access ",
566  "in hdf_file::seti_arr2d_copy().",o2scl::exc_efailed);
567  }
568 
569  // Copy to a C-style array
570  int *d=new int[r*c];
571  for(size_t i=0;i<r;i++) {
572  for(size_t j=0;j<c;j++) {
573  d[i*c+j]=a2d[i][j];
574  }
575  }
576 
577  hid_t dset, space, dcpl=0;
578  bool chunk_alloc=false;
579 
580  H5E_BEGIN_TRY
581  {
582  // See if the dataspace already exists first
583  dset=H5Dopen(current,name.c_str(),H5P_DEFAULT);
584  }
585  H5E_END_TRY
586 #ifdef O2SCL_NEVER_DEFINED
587  {
588  }
589 #endif
590 
591  // If it doesn't exist, create it
592  if (dset<0) {
593 
594  // Create the dataspace
595  hsize_t dims[2]={r,c};
596  hsize_t max[2]={H5S_UNLIMITED,H5S_UNLIMITED};
597  space=H5Screate_simple(2,dims,max);
598 
599  // Set chunk with size determined by def_chunk()
600  dcpl=H5Pcreate(H5P_DATASET_CREATE);
601  hsize_t chunk[2]={def_chunk(r),def_chunk(c)};
602  int status2=H5Pset_chunk(dcpl,2,chunk);
603 
604 #ifdef O2SCL_HDF5_COMP
605  // Compression part
606  if (compr_type==1) {
607  int status3=H5Pset_deflate(dcpl,6);
608  } else if (compr_type==2) {
609  int status3=H5Pset_szip(dcpl,H5_SZIP_NN_OPTION_MASK,16);
610  } else if (compr_type!=0) {
611  O2SCL_ERR2("Invalid compression type in ",
612  "hdf_file::seti_arr2d_copy().",o2scl::exc_einval);
613  }
614 #endif
615 
616  // Create the dataset
617  dset=H5Dcreate(current,name.c_str(),H5T_STD_I32LE,space,H5P_DEFAULT,
618  dcpl,H5P_DEFAULT);
619  chunk_alloc=true;
620 
621  } else {
622 
623  // Get current dimensions
624  space=H5Dget_space(dset);
625  hsize_t dims[2];
626  int ndims=H5Sget_simple_extent_dims(space,dims,0);
627 
628  // Set error if this dataset is more than 1-dimensional
629  if (ndims!=2) {
630  O2SCL_ERR2("Tried to set a non-matrix dataset with a ",
631  "matrix in hdf_file::seti_arr2d_copy().",
633  }
634 
635  // If necessary, extend the dataset
636  if (r!=dims[0] || c!=dims[1]) {
637  hsize_t new_dims[2]={r,c};
638  int status3=H5Dset_extent(dset,new_dims);
639  }
640 
641  }
642 
643  // Write the data
644  int status;
645  status=H5Dwrite(dset,H5T_NATIVE_INT,H5S_ALL,
646  H5S_ALL,H5P_DEFAULT,d);
647 
648  status=H5Dclose(dset);
649  status=H5Sclose(space);
650  if (chunk_alloc) {
651  status=H5Pclose(dcpl);
652  }
653 
654  // Free the C-style array
655  delete[] d;
656 
657  return 0;
658  }
659 
660  /** \brief Set a two-dimensional array dataset named \c name with \c m
661  */
662  template<class arr2d_t>
663  int set_szt_arr2d_copy(std::string name, size_t r,
664  size_t c, const arr2d_t &a2d) {
665 
666  if (write_access==false) {
667  O2SCL_ERR2("File not opened with write access ",
668  "in hdf_file::set_szt_arr2d_copy().",o2scl::exc_efailed);
669  }
670 
671  // Copy to a C-style array
672  size_t *d=new size_t[r*c];
673  for(size_t i=0;i<r;i++) {
674  for(size_t j=0;j<c;j++) {
675  d[i*c+j]=a2d[i][j];
676  }
677  }
678 
679  hid_t dset, space, dcpl=0;
680  bool chunk_alloc=false;
681 
682  H5E_BEGIN_TRY
683  {
684  // See if the dataspace already exists first
685  dset=H5Dopen(current,name.c_str(),H5P_DEFAULT);
686  }
687  H5E_END_TRY
688 #ifdef O2SCL_NEVER_DEFINED
689  {
690  }
691 #endif
692 
693  // If it doesn't exist, create it
694  if (dset<0) {
695 
696  // Create the dataspace
697  hsize_t dims[2]={r,c};
698  hsize_t max[2]={H5S_UNLIMITED,H5S_UNLIMITED};
699  space=H5Screate_simple(2,dims,max);
700 
701  // Set chunk with size determined by def_chunk()
702  dcpl=H5Pcreate(H5P_DATASET_CREATE);
703  hsize_t chunk[2]={def_chunk(r),def_chunk(c)};
704  int status2=H5Pset_chunk(dcpl,2,chunk);
705 
706 #ifdef O2SCL_HDF5_COMP
707  // Compression part
708  if (compr_type==1) {
709  int status3=H5Pset_deflate(dcpl,6);
710  } else if (compr_type==2) {
711  int status3=H5Pset_szip(dcpl,H5_SZIP_NN_OPTION_MASK,16);
712  } else if (compr_type!=0) {
713  O2SCL_ERR2("Invalid compression type in ",
714  "hdf_file::set_szt_arr2d_copy().",o2scl::exc_einval);
715  }
716 #endif
717 
718  // Create the dataset
719  dset=H5Dcreate(current,name.c_str(),H5T_STD_U64LE,space,H5P_DEFAULT,
720  dcpl,H5P_DEFAULT);
721  chunk_alloc=true;
722 
723  } else {
724 
725  // Get current dimensions
726  space=H5Dget_space(dset);
727  hsize_t dims[2];
728  int ndims=H5Sget_simple_extent_dims(space,dims,0);
729 
730  // Set error if this dataset is more than 1-dimensional
731  if (ndims!=2) {
732  O2SCL_ERR2("Tried to set a non-matrix dataset with a ",
733  "matrix in hdf_file::set_szt_arr2d_copy().",
735  }
736 
737  // If necessary, extend the dataset
738  if (r!=dims[0] || c!=dims[1]) {
739  hsize_t new_dims[2]={r,c};
740  int status3=H5Dset_extent(dset,new_dims);
741  }
742 
743  }
744 
745  // Write the data
746  int status;
747  status=H5Dwrite(dset,H5T_NATIVE_HSIZE,H5S_ALL,
748  H5S_ALL,H5P_DEFAULT,d);
749 
750  status=H5Dclose(dset);
751  status=H5Sclose(space);
752  if (chunk_alloc) {
753  status=H5Pclose(dcpl);
754  }
755 
756  // Free the C-style array
757  delete[] d;
758 
759  return 0;
760  }
761  //@}
762 
763  /// \name Tensor I/O functions
764  //@{
765  /** \brief Get a tensor from an HDF file
766 
767  This version does not require a full copy of the tensor.
768  */
769  int getd_ten(std::string name,
770  o2scl::tensor<std::vector<double>,std::vector<size_t> > &t);
771 
772  /** \brief Get a tensor from an HDF file
773 
774  This version requires a full copy of the tensor from the
775  HDF5 file into the \ref o2scl::tensor object.
776  */
777  template<class vec_t, class vec_size_t>
778  int getd_ten_copy(std::string name, o2scl::tensor<vec_t,vec_size_t> &t) {
779  o2scl::tensor<std::vector<double>,std::vector<size_t> > t2;
780  int ret=getd_ten(name,t2);
781  t=t2;
782  return ret;
783  }
784 
785  /** \brief Write a tensor to an HDF file
786 
787  You may overwrite a tensor already present in the
788  HDF file only if it has the same rank. This version
789  does not require a full copy of the tensor.
790  */
791  int setd_ten(std::string name,
792  const o2scl::tensor<std::vector<double>,
793  std::vector<size_t> > &t);
794 
795  /** \brief Write a tensor to an HDF file
796 
797  You may overwrite a tensor already present in the
798  HDF file only if it has the same rank. This version
799  requires a full copy of the tensor from the \ref o2scl::tensor
800  object into the HDF5 file.
801  */
802  template<class vec_t, class vec_size_t>
803  int setd_ten_copy(std::string name,
804  const o2scl::tensor<std::vector<double>,
805  std::vector<size_t> > &t) {
806  o2scl::tensor<std::vector<double>,std::vector<size_t> > t2;
807  t2=t;
808  int ret=getd_ten(name,t2);
809  return ret;
810  }
811  //@}
812 
813  /** \name Array get functions
814 
815  All of these functions assume that the
816  pointer allocated beforehand, and matches the size of the
817  array in the HDF file. If the specified object is not found,
818  the \o2 error handler will be called.
819  */
820  //@{
821  /** \brief Get a character array named \c name of size \c n
822 
823  \note The pointer \c c must be allocated beforehand to
824  hold \c n entries, and \c n must match the size of the
825  array in the HDF file.
826  */
827  int getc_arr(std::string name, size_t n, char *c);
828 
829  /** \brief Get a double array named \c name of size \c n
830 
831  \note The pointer \c d must be allocated beforehand to
832  hold \c n entries, and \c n must match the size of the
833  array in the HDF file.
834  */
835  int getd_arr(std::string name, size_t n, double *d);
836 
837  /** \brief Get a float array named \c name of size \c n
838 
839  \note The pointer \c f must be allocated beforehand to
840  hold \c n entries, and \c n must match the size of the
841  array in the HDF file.
842  */
843  int getf_arr(std::string name, size_t n, float *f);
844 
845  /** \brief Get an integer array named \c name of size \c n
846 
847  \note The pointer \c i must be allocated beforehand to
848  hold \c n entries, and \c n must match the size of the
849  array in the HDF file.
850  */
851  int geti_arr(std::string name, size_t n, int *i);
852  //@}
853 
854  /** \name Array get functions with memory allocation
855 
856  These functions allocate memory with \c new, which
857  should be freed by the user with \c delete .
858  */
859  //@{
860  /// Get a character array named \c name of size \c n
861  int getc_arr_alloc(std::string name, size_t &n, char *c);
862 
863  /// Get a double array named \c name of size \c n
864  int getd_arr_alloc(std::string name, size_t &n, double *d);
865 
866  /// Get a float array named \c name of size \c n
867  int getf_arr_alloc(std::string name, size_t &n, float *f);
868 
869  /// Get an integer array named \c name of size \c n
870  int geti_arr_alloc(std::string name, size_t &n, int *i);
871  //@}
872 
873  /** \name Array set functions
874  */
875  //@{
876  /// Set a character array named \c name of size \c n to value \c c
877  int setc_arr(std::string name, size_t n, const char *c);
878 
879  /// Set a double array named \c name of size \c n to value \c d
880  int setd_arr(std::string name, size_t n, const double *d);
881 
882  // Set a double array with compression
883  //int setd_arr_comp(std::string name, size_t n, const double *d);
884 
885  /// Set a float array named \c name of size \c n to value \c f
886  int setf_arr(std::string name, size_t n, const float *f);
887 
888  /// Set a integer array named \c name of size \c n to value \c i
889  int seti_arr(std::string name, size_t n, const int *i);
890 
891  /// Set a integer array named \c name of size \c n to value \c i
892  int set_szt_arr(std::string name, size_t n, const size_t *u);
893  //@}
894 
895  /** \name Fixed-length array set functions
896 
897  If a dataset named \c name is already present, then the
898  user-specified array must not be longer than the array already
899  present in the HDF file.
900  */
901  //@{
902  /// Set a character array named \c name of size \c n to value \c c
903  int setc_arr_fixed(std::string name, size_t n, const char *c);
904 
905  /// Set a double array named \c name of size \c n to value \c d
906  int setd_arr_fixed(std::string name, size_t n, const double *c);
907 
908  /// Set a float array named \c name of size \c n to value \c f
909  int setf_arr_fixed(std::string name, size_t n, const float *f);
910 
911  /// Set an integer array named \c name of size \c n to value \c i
912  int seti_arr_fixed(std::string name, size_t n, const int *i);
913  //@}
914 
915  /** \name Get functions with default values
916 
917  If the requested dataset is not found in the HDF file,
918  the object is set to the specified default value
919  and the error handler is not called.
920  */
921  //@{
922  /// Get a character named \c name
923  int getc_def(std::string name, char def, char &c);
924 
925  /// Get a double named \c name
926  int getd_def(std::string name, double def, double &d);
927 
928  /// Get a float named \c name
929  int getf_def(std::string name, float def, float &f);
930 
931  /// Get a integer named \c name
932  int geti_def(std::string name, int def, int &i);
933 
934  /// Get a size_t named \c name
935  int get_szt_def(std::string name, size_t def, size_t &i);
936 
937  /// Get a string named \c name
938  int gets_def(std::string name, std::string def, std::string &s);
939  //@}
940 
941  /** \name Get functions with pre-allocated pointer
942  */
943  //@{
944  /// Get a double array \c d pre-allocated to have size \c n
945  int getd_vec_prealloc(std::string name, size_t n, double *d);
946 
947  /// Get an integer array \c i pre-allocated to have size \c n
948  int geti_vec_prealloc(std::string name, size_t n, int *i);
949 
950  /// Get a double matrix \c d pre-allocated to have size <tt>(n,m)</tt>
951  int getd_mat_prealloc(std::string name, size_t n, size_t m, double *d);
952 
953  /// Get an integer matrix \c i pre-allocated to have size <tt>(n,m)</tt>
954  int geti_mat_prealloc(std::string name, size_t n, size_t m, int *i);
955  //@}
956 
957  /// \name Find a group
958  //@{
959  /** \brief Look in hdf_file \c hf for an \o2 object of type \c
960  type and if found, set \c group_name to the associated object
961  name
962 
963  This function returns 0 if an object of type \c type is found
964  and \ref o2scl::exc_enoprog if it fails.
965  */
966  int find_group_by_type(std::string type,
967  std::string &group_name, int verbose=0);
968 
969  /** \brief Look in hdf_file \c hf for an \o2 object with name
970  \c name and if found, set \c type to the associated type
971 
972  This function returns 0 if an object with name \c name is
973  found and \ref o2scl::exc_enoprog if it fails.
974  */
975  int find_group_by_name(std::string name,
976  std::string &type, int verbose=0);
977  //@}
978 
979 #ifndef DOXYGEN_INTERNAL
980 
981  private:
982 
983  /*
984  In principle, one might be able to copy the IDs, but then we'd
985  have to worry about the possibility that the file would be
986  closed twice.
987  */
988  hdf_file(const hdf_file &);
989  hdf_file& operator=(const hdf_file&);
990 
991 #endif
992 
993  };
994 
995  /// \name Helper functions
996  //@{
997  /** \brief An internal structure to pass information to and
998  from \ref iterate_match_type() and \ref iterate_match_name()
999  */
1000  typedef struct {
1001  hdf_file *hf;
1002  std::string type;
1003  std::string group_name;
1004  bool found;
1005  int verbose;
1006  } iterate_parms;
1007 
1008  /** \brief Look at location \c loc in an HDF file for an \o2 object
1009  of a specified type
1010 
1011  This is used by \ref hdf_file::find_group_by_type() where \c
1012  op_data is a pointer to an object of type \ref iterate_parms to
1013  look for \o2 objects of a specified type without knowing the
1014  group name.
1015  */
1016  int iterate_match_type(hid_t loc, const char *name,
1017  const H5L_info_t *inf, void *op_data);
1018 
1019  /** \brief Look at location \c loc in an HDF file for an \o2 object
1020  with a specified name
1021 
1022  This is used by \ref hdf_file::find_group_by_name() where \c
1023  op_data is a pointer to an object of type \ref iterate_parms to
1024  look for \o2 objects with a specified name without knowing the
1025  type.
1026  */
1027  int iterate_match_name(hid_t loc, const char *name,
1028  const H5L_info_t *inf, void *op_data);
1029  //@}
1030 
1031 }
1032 
1033 #endif
int getf_arr_alloc(std::string name, size_t &n, float *f)
Get a float array named name of size n.
int seti_vec_copy(std::string name, vec_int_t &v)
Set vector dataset named name with v.
Definition: hdf_file.h:386
int getd_ten_copy(std::string name, o2scl::tensor< vec_t, vec_size_t > &t)
Get a tensor from an HDF file.
Definition: hdf_file.h:778
int seti_mat_copy(std::string name, const ubmatrix_int &m)
Set matrix dataset named name with m.
hid_t current
Current file or group location.
Definition: hdf_file.h:116
int getd_vec(std::string name, std::vector< double > &v)
Get vector dataset and place data in v.
int setd_mat_copy(std::string name, const ubmatrix &m)
Set matrix dataset named name with m.
int setd_vec_copy(std::string name, const vec_t &v)
Set vector dataset named name with v.
Definition: hdf_file.h:366
int setd_vec(std::string name, const std::vector< double > &v)
Set vector dataset named name with v.
int setd_arr(std::string name, size_t n, const double *d)
Set a double array named name of size n to value d.
int geti(std::string name, int &i)
Get a integer named name.
int getd_arr(std::string name, size_t n, double *d)
Get a double array named name of size n.
int set_szt_vec(std::string name, const std::vector< size_t > &v)
Set vector dataset named name with v.
int get_szt_def(std::string name, size_t def, size_t &i)
Get a size_t named name.
int find_group_by_name(std::string name, std::string &type, int verbose=0)
Look in hdf_file hf for an O<span style=&#39;position: relative; top: 0.3em; font-size: 0...
int find_group_by_type(std::string type, std::string &group_name, int verbose=0)
Look in hdf_file hf for an O<span style=&#39;position: relative; top: 0.3em; font-size: 0...
int getf_arr(std::string name, size_t n, float *f)
Get a float array named name of size n.
void close()
Close the file.
void set_szt(std::string name, size_t u)
Set an unsigned integer named name to value u.
int getd(std::string name, double &d)
Get a double named name.
void setd(std::string name, double d)
Set a double named name to value d.
int gets_def(std::string name, std::string def, std::string &s)
Get a string named name.
bool file_open
True if a file has been opened.
Definition: hdf_file.h:113
int setf_arr(std::string name, size_t n, const float *f)
Set a float array named name of size n to value f.
int iterate_match_name(hid_t loc, const char *name, const H5L_info_t *inf, void *op_data)
Look at location loc in an HDF file for an O<span style=&#39;position: relative; top: 0...
int set_szt_arr(std::string name, size_t n, const size_t *u)
Set a integer array named name of size n to value i.
invalid argument supplied by user
Definition: err_hnd.h:59
int getd_ten(std::string name, o2scl::tensor< std::vector< double >, std::vector< size_t > > &t)
Get a tensor from an HDF file.
int getc_arr(std::string name, size_t n, char *c)
Get a character array named name of size n.
int getc_arr_alloc(std::string name, size_t &n, char *c)
Get a character array named name of size n.
void seti(std::string name, int i)
Set an integer named name to value i.
int setd_arr_fixed(std::string name, size_t n, const double *c)
Set a double array named name of size n to value d.
void sets_fixed(std::string name, std::string s)
Set a fixed-length string named name to value s.
int geti_vec_copy(std::string name, vec_int_t &v)
Get vector dataset and place data in v.
Definition: hdf_file.h:323
int geti_arr_alloc(std::string name, size_t &n, int *i)
Get an integer array named name of size n.
int geti_arr(std::string name, size_t n, int *i)
Get an integer array named name of size n.
int iterate_match_type(hid_t loc, const char *name, const H5L_info_t *inf, void *op_data)
Look at location loc in an HDF file for an O<span style=&#39;position: relative; top: 0...
int get_szt(std::string name, size_t &u)
Get an unsigned integer named name.
hid_t get_current_id()
Retrieve the current working id.
int getf_def(std::string name, float def, float &f)
Get a float named name.
generic failure
Definition: err_hnd.h:61
An internal structure to pass information to and from iterate_match_type() and iterate_match_name() ...
Definition: hdf_file.h:1000
int getd_vec_prealloc(std::string name, size_t n, double *d)
Get a double array d pre-allocated to have size n.
int geti_vec(std::string name, std::vector< int > &v)
Get vector dataset and place data in v.
void sets(std::string name, std::string s)
Set a string named name to value s.
int setd_ten_copy(std::string name, const o2scl::tensor< std::vector< double >, std::vector< size_t > > &t)
Write a tensor to an HDF file.
Definition: hdf_file.h:803
int close_group(hid_t group)
Close a previously created group.
Definition: hdf_file.h:278
int getf(std::string name, float &f)
Get a float named name.
int gets_fixed(std::string name, std::string &s)
Get a fixed-length string named name.
int setc_arr(std::string name, size_t n, const char *c)
Set a character array named name of size n to value c.
int geti_def(std::string name, int def, int &i)
Get a integer named name.
void vector_copy(const vec_t &src, vec2_t &dest)
Simple vector copy.
Definition: vector.h:127
void open_or_create(std::string fname)
Open a file named fname or create if it doesn&#39;t already exist.
int getd_mat_copy(std::string name, ubmatrix &m)
Get matrix dataset and place data in m.
int seti_vec(std::string name, const std::vector< int > &v)
Set vector dataset named name with v.
int set_szt_vec_copy(std::string name, vec_size_t &v)
Set vector dataset named name with v.
Definition: hdf_file.h:405
int setd_ten(std::string name, const o2scl::tensor< std::vector< double >, std::vector< size_t > > &t)
Write a tensor to an HDF file.
#define O2SCL_ERR2(d, d2, n)
Set an error, two-string version.
Definition: err_hnd.h:281
The O<span style=&#39;position: relative; top: 0.3em; font-size: 0.8em&#39;>2</span>scl O$_2$scl namespace ...
Definition: table.h:53
bool has_write_access()
If true, then the file has read and write access.
Definition: hdf_file.h:143
void set_current_id(hid_t cur)
Set the current working id.
int set_szt_arr2d_copy(std::string name, size_t r, size_t c, const arr2d_t &a2d)
Set a two-dimensional array dataset named name with m.
Definition: hdf_file.h:663
int geti_vec_prealloc(std::string name, size_t n, int *i)
Get an integer array i pre-allocated to have size n.
int getd_def(std::string name, double def, double &d)
Get a double named name.
int setf_arr_fixed(std::string name, size_t n, const float *f)
Set a float array named name of size n to value f.
int compr_type
Compression type (not yet supported)
Definition: hdf_file.h:148
int geti_mat_prealloc(std::string name, size_t n, size_t m, int *i)
Get an integer matrix i pre-allocated to have size (n,m)
int geti_mat_copy(std::string name, ubmatrix_int &m)
Get matrix dataset and place data in m.
int setd_arr2d_copy(std::string name, size_t r, size_t c, const arr2d_t &a2d)
Set a two-dimensional array dataset named name with m.
Definition: hdf_file.h:459
int getd_mat_prealloc(std::string name, size_t n, size_t m, double *d)
Get a double matrix d pre-allocated to have size (n,m)
hid_t file
File ID.
Definition: hdf_file.h:110
virtual hsize_t def_chunk(size_t n)
Default chunk size.
Definition: hdf_file.h:123
hid_t get_file_id()
Get the current file id.
Store data in an O<span style=&#39;position: relative; top: 0.3em; font-size: 0.8em&#39;>2</span>scl O$_2$sc...
Definition: hdf_file.h:96
int sets_vec(std::string name, std::vector< std::string > &s)
Set a vector of strings named name.
int getc(std::string name, char &c)
Get a character named name.
int gets_vec(std::string name, std::vector< std::string > &s)
Get a vector of strings named name and store it in s.
int setc_arr_fixed(std::string name, size_t n, const char *c)
Set a character array named name of size n to value c.
void setc(std::string name, char c)
Set a character named name to value c.
int gets(std::string name, std::string &s)
Get a string named name.
int seti_arr_fixed(std::string name, size_t n, const int *i)
Set an integer array named name of size n to value i.
int getd_vec_copy(std::string name, vec_t &v)
Get vector dataset and place data in v.
Definition: hdf_file.h:307
int open(std::string fname, bool write_access=false, bool err_on_fail=true)
Open a file named fname.
int get_szt_vec_copy(std::string name, vec_size_t &v)
Get vector dataset and place data in v.
Definition: hdf_file.h:338
void setf(std::string name, float f)
Set a float named name to value f.
int gets_def_fixed(std::string name, std::string def, std::string &s)
Get a fixed-length string named name with default value s.
int seti_arr2d_copy(std::string name, size_t r, size_t c, const arr2d_t &a2d)
Set a two-dimensional array dataset named name with m.
Definition: hdf_file.h:561
bool write_access
If true, then the file has read and write access.
Definition: hdf_file.h:132
int get_szt_vec(std::string name, std::vector< size_t > &v)
Get vector dataset and place data in v.
int getd_arr_alloc(std::string name, size_t &n, double *d)
Get a double array named name of size n.
int seti_arr(std::string name, size_t n, const int *i)
Set a integer array named name of size n to value i.
Tensor class with arbitrary dimensions.
Definition: tensor.h:120
hid_t open_group(hid_t init_id, std::string path)
Open a group relative to the location specified in init_id.
int getc_def(std::string name, char def, char &c)
Get a character named name.

Documentation generated with Doxygen. Provided under the GNU Free Documentation License (see License Information).