Object-oriented Scientific Computing Library: Version 0.910
hdf_file.h
00001 /*
00002   -------------------------------------------------------------------
00003 
00004   Copyright (C) 2006-2012, Andrew W. Steiner
00005 
00006   This file is part of O2scl.
00007   
00008   O2scl is free software; you can redistribute it and/or modify
00009   it under the terms of the GNU General Public License as published by
00010   the Free Software Foundation; either version 3 of the License, or
00011   (at your option) any later version.
00012   
00013   O2scl is distributed in the hope that it will be useful,
00014   but WITHOUT ANY WARRANTY; without even the implied warranty of
00015   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016   GNU General Public License for more details.
00017   
00018   You should have received a copy of the GNU General Public License
00019   along with O2scl. If not, see <http://www.gnu.org/licenses/>.
00020 
00021   -------------------------------------------------------------------
00022 */
00023 #ifndef O2SCL_HDF_FILE_H
00024 #define O2SCL_HDF_FILE_H
00025 
00026 #include <hdf5.h>
00027 
00028 #include <o2scl/ovector_tlate.h>
00029 #include <o2scl/uvector_tlate.h>
00030 #include <o2scl/omatrix_tlate.h>
00031 #include <o2scl/umatrix_tlate.h>
00032 #include <o2scl/tensor.h>
00033 
00034 #ifndef DOXYGENP
00035 namespace o2scl_hdf {
00036 #endif
00037 
00038   /** \brief Store data in an HDF5 file
00039 
00040       The member functions which write or get data from an HDF file
00041       begin with either <tt>get</tt> or <tt>set</tt>.  Where
00042       appropriate, the next character is either \c c for character, \c
00043       d for double, \c f for float, or \c i for int. 
00044       
00045       The get functions are:
00046       - getc() - get a single character
00047       - getc_def() - get a character or set to a default value
00048       - getc_arr() - get an array
00049       - getc_arr_alloc() - allocate memory with \c new and get an array
00050 
00051       The set functions are:
00052       - setc() - set a single character
00053       - setc_arr() - set an extensible array
00054       - setc_arr_fixed() - set a fixed array
00055 
00056       The string I/O functions:
00057       - gets() - get a string
00058       - gets_def() - get a string or set to a default value
00059       - gets_arr() - Get an extensible string
00060       - gets_fixed() - get a fixed-length string
00061       - sets() - set a string
00062       - sets_fixed() - set a fixed-length string
00063       - sets_arr() - set an extensible array of strings
00064 
00065       The vector I/O functions:
00066       - setd_vec() and seti_vec() - set a vector
00067       - getd_vec() and geti_vec() - get a vector
00068       - getd_vec_prealloc() and geti_vec_prealloc - 
00069       get a pre-allocated vector
00070 
00071       The matrix I/O functions:
00072       - setd_mat() and seti_mat() - set a matrix
00073       - getd_mat() and geti_mat() - get a matrix
00074       
00075       By default, vectors and matrices are written to HDF files in a
00076       chunked format, so their length can be changed later as
00077       necessary. The chunk size is chosen in \ref def_chunk() to be
00078       the closest power of 10 to the current vector size. 
00079 
00080       All files not closed by the user are closed in the destructor,
00081       but the destructor does not automatically close groups.
00082 
00083       \warning This class is still in development. Because of this,
00084       hdf5 files generated by this class may not be easily read by
00085       future versions. Later versions of \o2 will have stronger
00086       guarantees on backwards compatibility.
00087 
00088       \todo Error handling with HDF functions is a particular concern.
00089       Modify to throw \o2 exceptions when appropriate.
00090 
00091       \future Automatically close groups, e.g. by storing hid_t's in a
00092       stack?
00093   */
00094   class hdf_file {
00095     
00096 #ifndef DOXYGEN_INTERNAL
00097 
00098   protected:
00099 
00100     /// File ID
00101     hid_t file;
00102 
00103     /// True if a file has been opened
00104     bool file_open;
00105     
00106     /// Current file or group location
00107     hid_t current;
00108     
00109     /** \brief Default chunk size
00110 
00111         Choose the closest power of 10 which is greater than or equal
00112         to 10 and less than or equal to \f$ 10^6 \f$.
00113     */
00114     virtual hsize_t def_chunk(size_t n) {
00115       size_t ch=(size_t)((1.0+1.0e-12)*
00116                          pow(10.0,floor(log10(((double)n))+0.5)));
00117       if (ch<10) ch=10;
00118       if (ch>1000000) ch=1000000;
00119       return ch;
00120     }
00121     
00122 #endif
00123     
00124   public:
00125 
00126     hdf_file();
00127 
00128     virtual ~hdf_file();
00129 
00130     /// \name Open and close files
00131     //@{
00132     /// Open a file named \c fname
00133     int open(std::string fname);
00134 
00135     /// Close the file
00136     int close();
00137     //@}
00138     
00139     /// \name Manipulate ids
00140     //@{
00141     /// Get the current file id
00142     hid_t get_file_id();
00143 
00144     /// Set the current working id
00145     int set_current_id(hid_t cur);
00146 
00147     /// Retrieve the current working it
00148     hid_t get_current_id();
00149     //@}
00150 
00151     /// \name Set functions
00152     //@{
00153     /// Set a character named \c name to value \c d
00154     int setc(std::string name, char c);
00155 
00156     /// Set a double named \c name to value \c d
00157     int setd(std::string name, double d);
00158     
00159     /// Set a float named \c name to value \c d
00160     int setf(std::string name, float f);
00161     
00162     /// Set an integer named \c name to value \c d
00163     int seti(std::string name, int i);
00164 
00165     /** \brief Set a string named \c name to value \c s
00166         
00167         The string is stored in the HDF file as an extensible
00168         character array rather than a string.
00169     */
00170     int sets(std::string name, std::string s);
00171 
00172     /** \brief Set a string named \c name to value \c s
00173         
00174         This function stores <tt>s</tt> as a fixed-length string
00175         in the HDF file. If a dataset named \c name is already
00176         present, then \c s must not be longer than the string
00177         length already specified in the HDF file.
00178     */
00179     int sets_fixed(std::string name, std::string s);
00180     //@}
00181 
00182     /// \name Group manipulation
00183     //@{
00184     /** \brief Open a group relative to the location specified in 
00185         \c init_id
00186 
00187         \note In order to ensure that future objects are written to the
00188         newly-created group, the user must use set_current_id()
00189         using the newly-created group ID for the argument. 
00190     */
00191     hid_t open_group(hid_t init_id, std::string path);
00192     
00193     /** \brief Open a group relative to the current location
00194 
00195         \note In order to ensure that future objects are written to the
00196         newly-created group, the user must use set_current_id()
00197         using the newly-created group ID for the argument. 
00198      */
00199     hid_t open_group(std::string path); 
00200 
00201     /// Close a previously created group
00202     int close_group(hid_t group) {
00203       return H5Gclose(group);
00204     }
00205     //@}
00206 
00207     /** \name Vector set functions
00208 
00209         These functions automatically write all of the vector elements
00210         to the HDF file, if necessary extending the data that is
00211         already present.
00212     */
00213     //@{
00214     /// Set vector dataset named \c name with \c v
00215     int setd_vec(std::string name, const std::vector<double> &v);
00216     /** \brief Set vector dataset named \c name with \c v
00217 
00218         \note In the case that the stride of the vector \c v is not
00219         unity, this function requires copying the data twice: once from
00220         the vector to a pointer, and once from the pointer to the file.
00221         Keep this in mind when performing I/O with larger data sets.
00222     */
00223     int setd_vec(std::string name, const o2scl::ovector_const_view &v);
00224     /// Set vector dataset named \c name with \c v
00225     int setd_vec(std::string name, const o2scl::uvector_const_view &v);
00226     /// Set vector dataset named \c name with \c v
00227     int seti_vec(std::string name, const std::vector<int> &v);
00228     /** \brief Set vector dataset named \c name with \c v
00229 
00230         \note In the case that the stride of the vector \c v is not
00231         unity, this function requires copying the data twice: once from
00232         the vector to a pointer, and once from the pointer to the file.
00233         Keep this in mind when performing I/O with larger data sets.
00234     */
00235     int seti_vec(std::string name, const o2scl::ovector_int_const_view &v);
00236     /// Set vector dataset named \c name with \c v
00237     int seti_vec(std::string name, const o2scl::uvector_int_const_view &v);
00238     //@}
00239 
00240     /** \name Vector get functions
00241 
00242         These functions automatically free any previously allocated
00243         memory in <tt>v</tt> and then allocate the proper space
00244         required to read the information from the HDF file.
00245     */
00246     //@{
00247     /// Get vector dataset and place data in \c v
00248     int getd_vec(std::string name, std::vector<double> &v);
00249     /// Get vector dataset and place data in \c v
00250     int getd_vec(std::string name, o2scl::ovector &v);
00251     /// Get vector dataset and place data in \c v
00252     int getd_vec(std::string name, o2scl::uvector &v);
00253     /// Get vector dataset and place data in \c v
00254     int geti_vec(std::string name, std::vector<int> &v);
00255     /// Get vector dataset and place data in \c v
00256     int geti_vec(std::string name, o2scl::ovector_int &v);
00257     /// Get vector dataset and place data in \c v
00258     int geti_vec(std::string name, o2scl::uvector_int &v);
00259     //@}
00260 
00261     /** \name Matrix set functions
00262 
00263         These functions automatically write all of the vector elements
00264         to the HDF file, if necessary extending the data that is
00265         already present.
00266     */
00267     //@{
00268     /** \brief Set matrix dataset named \c name with \c m
00269 
00270         \note In the case that the trailing dimension (as reported by
00271         \ref omatrix_const_view_tlate::tda() ) of the matrix \c m is
00272         greater than the number of columns, this function requires
00273         copying the data twice: once from the matrix to a pointer, and
00274         once from the pointer to the file. Keep this in mind when
00275         performing I/O with larger data sets.
00276     */
00277     int setd_mat(std::string name, const o2scl::omatrix_const_view &m);
00278     /** \brief Set matrix dataset named \c name with \c m
00279     */
00280     int setd_mat(std::string name, const o2scl::umatrix_const_view &m);
00281     /** \brief Set matrix dataset named \c name with \c m
00282 
00283         \note In the case that the trailing dimension (as reported by
00284         \ref omatrix_const_view_tlate::tda() ) of the matrix \c m is
00285         greater than the number of columns, this function requires
00286         copying the data twice: once from the matrix to a pointer, and
00287         once from the pointer to the file. Keep this in mind when
00288         performing I/O with larger data sets.
00289     */
00290     int seti_mat(std::string name, const o2scl::omatrix_int_const_view &m);
00291     /** \brief Set matrix dataset named \c name with \c m
00292     */
00293     int seti_mat(std::string name, const o2scl::umatrix_int_const_view &m);
00294     //@}
00295 
00296     /** \name Matrix get functions
00297 
00298         These functions automatically free any previously allocated
00299         memory in <tt>m</tt> and then allocate the proper space
00300         required to read the information from the HDF file.
00301     */
00302     //@{
00303     /// Get matrix dataset and place data in \c m
00304     int getd_mat(std::string name, o2scl::omatrix &m);
00305     /// Get matrix dataset and place data in \c m
00306     int getd_mat(std::string name, o2scl::umatrix &m);
00307     /// Get matrix dataset and place data in \c m
00308     int geti_mat(std::string name, o2scl::omatrix_int &m);
00309     /// Get matrix dataset and place data in \c m
00310     int geti_mat(std::string name, o2scl::umatrix_int &m);
00311     //@}
00312 
00313     /// Desc
00314     int getd_ten3(std::string name, o2scl::tensor3 &t3);
00315 
00316     /// \name Array set functions
00317     //@{
00318     /// Set a character array named \c name of size \c n to value \c c
00319     int setc_arr(std::string name, size_t n, const char *c);
00320     
00321     /// Set a double array named \c name of size \c n to value \c d
00322     int setd_arr(std::string name, size_t n, const double *d);
00323     
00324     /// Set a float array named \c name of size \c n to value \c f
00325     int setf_arr(std::string name, size_t n, const float *f);
00326 
00327     /// Set a integer array named \c name of size \c n to value \c i
00328     int seti_arr(std::string name, size_t n, const int *i);
00329 
00330     /** \brief Set a vector of strings named \c name
00331 
00332         \devnote 
00333         String vectors are reformatted as a single character array, in
00334         order to allow each string to have different length and to
00335         make each string extensible. The size of the vector \c s is
00336         stored as an integer named <tt>nw</tt>.
00337     */
00338     int sets_arr(std::string name, std::vector<std::string> &s);
00339     //@}
00340 
00341     /** \name Fixed-length array set functions
00342         
00343         If a dataset named \c name is already present, then the
00344         user-specified array must not be longer than the array already
00345         present in the HDF file.
00346     */
00347     //@{
00348     /// Set a character array named \c name of size \c n to value \c c
00349     int setc_arr_fixed(std::string name, size_t n, const char *c);
00350 
00351     /// Set a double array named \c name of size \c n to value \c d
00352     int setd_arr_fixed(std::string name, size_t n, const double *c);
00353 
00354     /// Set a float array named \c name of size \c n to value \c f
00355     int setf_arr_fixed(std::string name, size_t n, const float *f);
00356     
00357     /// Set an integer array named \c name of size \c n to value \c i
00358     int seti_arr_fixed(std::string name, size_t n, const int *i);
00359     //@}
00360         
00361     /** \name Get functions
00362 
00363         If the specified object is not found, the \o2 error handler
00364         will be called.
00365      */
00366     //@{
00367     /// Get a character named \c name
00368     int getc(std::string name, char &c);
00369     
00370     /// Get a double named \c name
00371     int getd(std::string name, double &d);
00372     
00373     /// Get a float named \c name
00374     int getf(std::string name, float &f);
00375 
00376     /// Get a integer named \c name
00377     int geti(std::string name, int &i);
00378 
00379     /** \brief Get a string named \c name
00380 
00381         \note Strings are stored as character arrays and thus
00382         retrieving a string from a file requires loading the
00383         information from the file into a character array, and then
00384         copying it to the string. This will be slow for very long
00385         strings.
00386     */
00387     int gets(std::string name, std::string &s);
00388     
00389     /** \brief Get a string named \c name
00390      */
00391     int gets_fixed(std::string name, std::string &s);
00392 
00393     /** \brief Get a string named \c name
00394      */
00395     int gets_def_fixed(std::string name, std::string def, std::string &s);
00396     //@}
00397 
00398     /** \name Array get functions
00399 
00400         All of these functions (except gets_arr()) assume that the
00401         pointer allocated beforehand, and matches the size of the
00402         array in the HDF file. If the specified object is not found,
00403         the \o2 error handler will be called.
00404      */
00405     //@{
00406     /** \brief Get a character array named \c name of size \c n
00407 
00408         \note The pointer \c c must be allocated beforehand to 
00409         hold \c n entries, and \c n must match the size of the
00410         array in the HDF file.
00411      */
00412     int getc_arr(std::string name, size_t n, char *c);
00413 
00414     /** \brief Get a double array named \c name of size \c n 
00415 
00416         \note The pointer \c d must be allocated beforehand to 
00417         hold \c n entries, and \c n must match the size of the
00418         array in the HDF file.
00419      */
00420     int getd_arr(std::string name, size_t n, double *d);
00421     
00422     /** \brief Get a float array named \c name of size \c n 
00423 
00424         \note The pointer \c f must be allocated beforehand to 
00425         hold \c n entries, and \c n must match the size of the
00426         array in the HDF file.
00427      */
00428     int getf_arr(std::string name, size_t n, float *f);
00429     
00430     /** \brief Get an integer array named \c name of size \c n
00431 
00432         \note The pointer \c i must be allocated beforehand to 
00433         hold \c n entries, and \c n must match the size of the
00434         array in the HDF file.
00435      */
00436     int geti_arr(std::string name, size_t n, int *i);
00437     
00438     /** \brief Get a string array named \c name and store it in \c s
00439      */
00440     int gets_arr(std::string name, std::vector<std::string> &s);
00441     //@}
00442     
00443     /** \name Array get functions with memory allocation
00444 
00445         These functions allocate memory with \c new, which
00446         should be freed by the user with \c delete .
00447     */
00448     //@{
00449     /// Get a character array named \c name of size \c n
00450     int getc_arr_alloc(std::string name, size_t &n, char *c);
00451 
00452     /// Get a double array named \c name of size \c n 
00453     int getd_arr_alloc(std::string name, size_t &n, double *d);
00454     
00455     /// Get a float array named \c name of size \c n 
00456     int getf_arr_alloc(std::string name, size_t &n, float *f);
00457     
00458     /// Get an integer array named \c name of size \c n
00459     int geti_arr_alloc(std::string name, size_t &n, int *i);
00460     //@}
00461     
00462     /** \name Get functions with default values
00463 
00464         If the requested dataset is not found in the HDF file,
00465         the object is set to the specified default value
00466         and the error handler is not called.
00467      */
00468     //@{
00469     /// Get a character named \c name
00470     int getc_def(std::string name, char def, char &c);
00471     
00472     /// Get a double named \c name
00473     int getd_def(std::string name, double def, double &d);
00474     
00475     /// Get a float named \c name
00476     int getf_def(std::string name, float def, float &f);
00477 
00478     /// Get a integer named \c name
00479     int geti_def(std::string name, int def, int &i);
00480 
00481     /// Get a string named \c name
00482     int gets_def(std::string name, std::string def, std::string &s);
00483     //@}
00484 
00485     /** \name Get functions with pre-allocated pointer
00486      */
00487     //@{
00488     /// Get a double array \c d pre-allocated to have size \c n
00489     int getd_vec_prealloc(std::string name, size_t n, double *d);
00490 
00491     /// Get an integer array \c i pre-allocated to have size \c n
00492     int geti_vec_prealloc(std::string name, size_t n, int *i);
00493 
00494     /// Get a double matrix \c d pre-allocated to have size <tt>(n,m)</tt>
00495     int getd_mat_prealloc(std::string name, size_t n, size_t m, double *d);
00496 
00497     /// Get an integer matrix \c i pre-allocated to have size <tt>(n,m)</tt>
00498     int geti_mat_prealloc(std::string name, size_t n, size_t m, int *i);
00499     //@}
00500     
00501   };
00502 
00503 #ifndef DOXYGENP
00504 }
00505 #endif
00506 
00507 #endif
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

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

Get Object-oriented Scientific Computing
Lib at SourceForge.net. Fast, secure and Free Open Source software
downloads.