Field3D
Hdf5Util.h
Go to the documentation of this file.
00001 //----------------------------------------------------------------------------//
00002 
00003 /*
00004  * Copyright (c) 2009 Sony Pictures Imageworks Inc
00005  *
00006  * All rights reserved.
00007  *
00008  * Redistribution and use in source and binary forms, with or without
00009  * modification, are permitted provided that the following conditions
00010  * are met:
00011  *
00012  * Redistributions of source code must retain the above copyright
00013  * notice, this list of conditions and the following disclaimer.
00014  * Redistributions in binary form must reproduce the above copyright
00015  * notice, this list of conditions and the following disclaimer in the
00016  * documentation and/or other materials provided with the
00017  * distribution.  Neither the name of Sony Pictures Imageworks nor the
00018  * names of its contributors may be used to endorse or promote
00019  * products derived from this software without specific prior written
00020  * permission.
00021  *
00022  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00023  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00024  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00025  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
00026  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00027  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00028  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
00029  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00030  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
00031  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00032  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
00033  * OF THE POSSIBILITY OF SUCH DAMAGE.
00034  */
00035 
00036 //----------------------------------------------------------------------------//
00037 
00045 //----------------------------------------------------------------------------//
00046 
00047 #ifndef _INCLUDED_Field3D_Hdf5Util_H_
00048 #define _INCLUDED_Field3D_Hdf5Util_H_
00049 
00050 //----------------------------------------------------------------------------//
00051 
00052 #include <string>
00053 #include <exception>
00054 #include <vector>
00055 
00056 #include <boost/lexical_cast.hpp>
00057 
00058 #include <hdf5.h>
00059 
00060 #include "Exception.h"
00061 #include "Traits.h"
00062 #include "Field.h"
00063 
00064 //----------------------------------------------------------------------------//
00065 
00066 #include "ns.h"
00067 
00068 FIELD3D_NAMESPACE_OPEN
00069 
00070 //----------------------------------------------------------------------------//
00071 // Hdf5Util classes
00072 //----------------------------------------------------------------------------//
00073 
00076 namespace Hdf5Util {
00077 
00078 //----------------------------------------------------------------------------//
00079 
00082 class H5Base
00083 {
00084 public:
00085   // Constructor
00086   H5Base()
00087     : m_id(-1)
00088   { /* Empty */ }
00090   hid_t id() const
00091   { return m_id; }
00093   operator hid_t ()
00094   { return m_id; }
00095 protected:
00096   hid_t m_id;
00097 };
00098 
00099 //----------------------------------------------------------------------------//
00100 
00103 class H5ScopedAopen : public H5Base
00104 {
00105 public:
00106   H5ScopedAopen(hid_t location, const std::string &name)
00107   {
00108     m_id = H5Aopen(location, name.c_str(), H5P_DEFAULT);
00109     if (m_id < 0)
00110       throw Exc::MissingAttributeException("Couldn't open attribute " + name);
00111   }
00112   H5ScopedAopen(hid_t location, const std::string &name, hid_t aapl_id)
00113   {
00114     m_id = H5Aopen(location, name.c_str(), aapl_id);
00115     if (m_id < 0)
00116       throw Exc::MissingAttributeException("Couldn't open attribute " + name);
00117   }
00118   ~H5ScopedAopen()
00119   {
00120     if (m_id >= 0)
00121       H5Aclose(m_id);
00122   }
00123 };
00124 
00125 //----------------------------------------------------------------------------//
00126 
00129 class H5ScopedAopenIdx : public H5Base
00130 {
00131 public:
00132   H5ScopedAopenIdx(hid_t location, unsigned idx)
00133   {
00134     m_id = H5Aopen_idx(location, idx);
00135     if (m_id < 0)
00136       throw Exc::MissingAttributeException("Couldn't open attribute at index: " +
00137                                            boost::lexical_cast<std::string>(idx));
00138   }
00139   ~H5ScopedAopenIdx()
00140   {
00141     if (m_id >= 0)
00142       H5Aclose(m_id);
00143   }
00144 };
00145 
00146 //----------------------------------------------------------------------------//
00147 
00150 class H5ScopedGcreate : public H5Base
00151 {
00152 public:
00153   H5ScopedGcreate(hid_t parentLocation, const std::string &name)
00154   {
00155     m_id = H5Gcreate(parentLocation, name.c_str(), 
00156                      H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
00157   }
00158   H5ScopedGcreate(hid_t parentLocation, const std::string &name,              
00159                   hid_t lcpl_id, hid_t gcpl_id, hid_t gapl_id)
00160   {
00161     m_id = H5Gcreate(parentLocation, name.c_str(), 
00162                           lcpl_id, gcpl_id, gapl_id);
00163   }
00164 
00165   ~H5ScopedGcreate()
00166   {
00167     if (m_id >= 0)
00168       H5Gclose(m_id);
00169   }
00170 };
00171 
00172 //----------------------------------------------------------------------------//
00173 
00176 class H5ScopedGopen : public H5Base
00177 {
00178 public:
00179   H5ScopedGopen()
00180     : H5Base()
00181   {
00182     // Empty
00183   }
00184   H5ScopedGopen(hid_t parentLocation, const std::string &name)
00185   {
00186     open(parentLocation, name);
00187   }
00188   H5ScopedGopen(hid_t parentLocation, const std::string &name, hid_t gapl_id)
00189   {
00190     open(parentLocation, name, gapl_id);
00191   }
00192   void open(hid_t parentLocation, const std::string &name)
00193   {
00194     m_id = H5Gopen(parentLocation, name.c_str(), H5P_DEFAULT);
00195   }
00196   void open(hid_t parentLocation, const std::string &name, hid_t gapl_id)
00197   {
00198     m_id = H5Gopen(parentLocation, name.c_str(), gapl_id);
00199   }
00200 
00201   ~H5ScopedGopen()
00202   {
00203     if (m_id >= 0)
00204       H5Gclose(m_id);
00205   }
00206 };
00207 
00208 //----------------------------------------------------------------------------//
00209 
00213 class H5ScopedScreate : public H5Base
00214 {
00215 public:
00216   H5ScopedScreate()
00217     : H5Base()
00218   {
00219     // Empty
00220   }
00221   H5ScopedScreate(H5S_class_t type)
00222   {
00223     create(type);
00224   }
00225   void create(H5S_class_t type)
00226   {
00227     m_id = H5Screate(type);
00228   }
00229   ~H5ScopedScreate()
00230   {
00231     if (m_id >= 0)
00232       H5Sclose(m_id);
00233   }
00234 };
00235 
00236 //----------------------------------------------------------------------------//
00237 
00240 class H5ScopedDcreate : public H5Base
00241 {
00242 public:
00243   H5ScopedDcreate(hid_t parentLocation, const std::string &name,
00244                   hid_t dtype_id, hid_t space_id, hid_t lcpl_id, 
00245                   hid_t dcpl_id, hid_t dapl_id)
00246   {
00247     m_id = H5Dcreate(parentLocation, name.c_str(), dtype_id, space_id,
00248                      lcpl_id, dcpl_id, dapl_id);
00249   }
00250   ~H5ScopedDcreate()
00251   {
00252     if (m_id >= 0)
00253       H5Dclose(m_id);
00254   }
00255 };
00256 
00257 //----------------------------------------------------------------------------//
00258 
00262 class H5ScopedAget_space : public H5Base
00263 {
00264 public:
00265   H5ScopedAget_space(hid_t dataset_id)
00266   {
00267     m_id = H5Aget_space(dataset_id);
00268     if (m_id < 0)
00269       throw Exc::AttrGetSpaceException("Couldn't get attribute space");
00270   }
00271   ~H5ScopedAget_space()
00272   {
00273     if (m_id >= 0)
00274       H5Sclose(m_id);
00275   }
00276 };
00277 
00278 //----------------------------------------------------------------------------//
00279 
00283 class H5ScopedAget_type : public H5Base
00284 {
00285 public:
00286   H5ScopedAget_type(hid_t dataset_id)
00287   {
00288     m_id = H5Aget_type(dataset_id);
00289     if (m_id < 0)
00290       throw Exc::AttrGetTypeException("Couldn't get attribute type");
00291   }
00292   ~H5ScopedAget_type()
00293   {
00294     if (m_id >= 0)
00295       H5Tclose(m_id);
00296   }
00297 };
00298 
00299 //----------------------------------------------------------------------------//
00300 
00304 class H5ScopedTget_native_type : public H5Base
00305 {
00306 public:
00307   H5ScopedTget_native_type(hid_t dataset_id, H5T_direction_t direction)
00308   {
00309     m_id = H5Tget_native_type(dataset_id, direction);
00310     if (m_id < 0)
00311       throw Exc::AttrGetNativeTypeException("Couldn't get native attribute type");
00312   }
00313   ~H5ScopedTget_native_type()
00314   {
00315     if (m_id >= 0)
00316       H5Tclose(m_id);
00317   }
00318 };
00319 
00320 //----------------------------------------------------------------------------//
00321 
00325 class H5ScopedDopen : public H5Base
00326 {
00327 public:
00328   H5ScopedDopen()
00329     : H5Base()
00330   {
00331     // Empty
00332   }
00333   H5ScopedDopen(hid_t parentLocation, const std::string &name, hid_t dapl_id)
00334   {
00335     open(parentLocation, name, dapl_id);
00336   }
00337   void open(hid_t parentLocation, const std::string &name, hid_t dapl_id)
00338   {
00339     m_id = H5Dopen(parentLocation, name.c_str(), dapl_id);
00340   }
00341   ~H5ScopedDopen()
00342   {
00343     if (m_id >= 0) {
00344       H5Dclose(m_id);
00345     }
00346   }
00347 };
00348 
00349 //----------------------------------------------------------------------------//
00350 
00353 class H5ScopedDget_space : public H5Base
00354 {
00355 public:
00356   H5ScopedDget_space()
00357     : H5Base()
00358   {
00359     // Empty
00360   }
00361   H5ScopedDget_space(hid_t dataset_id)
00362   {
00363     open(dataset_id);
00364   }
00365   void open(hid_t dataset_id)
00366   {
00367     m_id = H5Dget_space(dataset_id);
00368   }
00369   ~H5ScopedDget_space()
00370   {
00371     if (m_id >= 0)
00372       H5Sclose(m_id);
00373   }
00374 };
00375 
00376 //----------------------------------------------------------------------------//
00377 
00381 class H5ScopedDget_type : public H5Base
00382 {
00383 public:
00384   H5ScopedDget_type()
00385     : H5Base()
00386   {
00387     // Empty
00388   }
00389   H5ScopedDget_type(hid_t dataset_id)
00390   {
00391     open(dataset_id);
00392   }
00393   void open(hid_t dataset_id)
00394   {
00395     m_id = H5Dget_type(dataset_id);
00396   }
00397   ~H5ScopedDget_type()
00398   {
00399     if (m_id >= 0)
00400       H5Tclose(m_id);
00401   }
00402 };
00403 
00404 //----------------------------------------------------------------------------//
00405 // Hdf5Util functions
00406 //----------------------------------------------------------------------------//
00407 
00412 
00413 
00414 template <typename T>
00415 void writeSimpleData(hid_t location, const std::string &name,
00416                      const std::vector<T> &data);
00417 
00420 template <typename T>
00421 void readSimpleData(hid_t location, const std::string &name,
00422                     std::vector<T> &data);
00423 
00425 
00426 //----------------------------------------------------------------------------//
00427 
00432 
00433 
00434 bool readAttribute(hid_t location, const std::string& attrName, 
00435                   std::string& value); 
00436 
00439 bool readAttribute(hid_t location, const std::string& attrName, 
00440                   unsigned int attrSize, int &value); 
00441 
00444 bool readAttribute(hid_t location, const std::string& attrName, 
00445                   unsigned int attrSize, float &value); 
00446 
00449 bool readAttribute(hid_t location, const std::string& attrName, 
00450                   unsigned int attrSize, double &value); 
00451 
00454 bool readAttribute(hid_t location, const std::string& attrName, 
00455                    std::vector<unsigned int> &attrSize, int &value); 
00456 
00459 bool readAttribute(hid_t location, const std::string& attrName, 
00460                    std::vector<unsigned int> &attrSize, float &value); 
00461 
00464 bool readAttribute(hid_t location, const std::string& attrName, 
00465                    std::vector<unsigned int> &attrSize, double &value); 
00466 
00467 
00469 
00470 //----------------------------------------------------------------------------//
00471 
00476 
00477 
00478 bool writeAttribute(hid_t location, const std::string& attrName, 
00479                   const std::string& value); 
00480 
00483 bool writeAttribute(hid_t location, const std::string& attrName, 
00484                   unsigned int attrSize, const int &value); 
00485 
00488 bool writeAttribute(hid_t location, const std::string& attrName, 
00489                   unsigned int attrSize, const float &value); 
00490 
00493 bool writeAttribute(hid_t location, const std::string& attrName, 
00494                   unsigned int attrSize, const double &value); 
00495 
00498 bool writeAttribute(hid_t location, const std::string& attrName, 
00499                     std::vector<unsigned int> &attrSize, const int &value); 
00500 
00501 
00504 bool writeAttribute(hid_t location, const std::string& attrName, 
00505                     std::vector<unsigned int> &attrSize, const int &value); 
00506 
00509 bool writeAttribute(hid_t location, const std::string& attrName, 
00510                     std::vector<unsigned int> &attrSize, const float &value); 
00511 
00514 bool writeAttribute(hid_t location, const std::string& attrName, 
00515                     std::vector<unsigned int> &attrSize, const double &value); 
00516 
00518 
00519 //----------------------------------------------------------------------------//
00520 
00523 bool checkHdf5Gzip();
00524 
00525 //----------------------------------------------------------------------------//
00526 // Templated functions and classes
00527 //----------------------------------------------------------------------------//
00528 
00529 template <typename T>
00530 void writeSimpleData(hid_t location, const std::string &name,
00531                      const std::vector<T> &data)
00532 {
00533   using namespace Exc;
00534 
00535   // Calculate the total number of entries. This factors in that
00536   // V3f uses 3 components per value, etc.
00537   hsize_t totalSize[1];
00538   int components = FieldTraits<T>::dataDims();
00539   totalSize[0] = data.size() * components;
00540 
00541   // Get the internal data type
00542   hid_t type = DataTypeTraits<T>::h5type();
00543 
00544   H5ScopedScreate dataSpace(H5S_SIMPLE);
00545 
00546   if (dataSpace.id() < 0)
00547     throw WriteSimpleDataException("Couldn't create data space");
00548   
00549   H5Sset_extent_simple(dataSpace.id(), 1, totalSize, NULL);
00550 
00551   H5ScopedDcreate dataSet(location, name.c_str(), type, dataSpace.id(), 
00552                           H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
00553 
00554   if (dataSet.id() < 0) 
00555     throw WriteSimpleDataException("Couldn't create data set");
00556     
00557   hid_t err = H5Dwrite(dataSet.id(), type, H5S_ALL, H5S_ALL, 
00558                        H5P_DEFAULT, &data[0]);
00559 
00560   if (err < 0) 
00561     throw WriteSimpleDataException("Couldn't write data");
00562 }
00563 
00564 //----------------------------------------------------------------------------//
00565 
00566 template <typename T>
00567 void readSimpleData(hid_t location, const std::string &name,
00568                      std::vector<T> &data)
00569 {
00570   using namespace Exc;
00571 
00572   int components = FieldTraits<T>::dataDims();
00573   hsize_t dims[1];
00574 
00575   H5ScopedDopen dataSet(location, name.c_str(), H5P_DEFAULT);
00576 
00577   if (dataSet.id() < 0) 
00578     throw OpenDataSetException("Couldn't open data set: " + name);
00579   
00580   H5ScopedDget_space dataSpace(dataSet.id());
00581   H5ScopedDget_type dataType(dataSet.id());
00582   H5Sget_simple_extent_dims(dataSpace.id(), dims, NULL);
00583 
00584   if (dataSpace.id() < 0) 
00585     throw GetDataSpaceException("Couldn't get data space");
00586 
00587   if (dataType.id() < 0)
00588     throw GetDataTypeException("Couldn't get data type");
00589 
00590   int reportedSize = dims[0] / components;
00591 
00592   // Resize target
00593   data.clear();
00594   data.resize(reportedSize);
00595   
00596   // Get the internal data type
00597   hid_t type = DataTypeTraits<T>::h5type();
00598 
00599   if (H5Dread(dataSet.id(), type, H5S_ALL, H5S_ALL, 
00600               H5P_DEFAULT, &data[0]) < 0) {
00601     throw Hdf5DataReadException("Couldn't read simple data");
00602   }
00603 }
00604 
00605 //----------------------------------------------------------------------------//
00606 
00607 } // namespace Hdf5Util
00608 
00609 //----------------------------------------------------------------------------//
00610 
00611 FIELD3D_NAMESPACE_HEADER_CLOSE
00612 
00613 //----------------------------------------------------------------------------//
00614 
00615 #endif