Field3D
MACFieldIO.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 
00042 //----------------------------------------------------------------------------//
00043 
00044 #ifndef _INCLUDED_Field3D_MACFieldIO_H_
00045 #define _INCLUDED_Field3D_MACFieldIO_H_
00046 
00047 //----------------------------------------------------------------------------//
00048 
00049 #include <string>
00050 
00051 #include <boost/intrusive_ptr.hpp>
00052 
00053 #include <hdf5.h>
00054 
00055 #include "Exception.h"
00056 #include "Field3DFile.h"
00057 #include "FieldIO.h"
00058 #include "Hdf5Util.h"
00059 #include "MACField.h"
00060 
00061 //----------------------------------------------------------------------------//
00062 
00063 #include "ns.h"
00064 
00065 FIELD3D_NAMESPACE_OPEN
00066 
00067 //----------------------------------------------------------------------------//
00068 // MACFieldIO
00069 //----------------------------------------------------------------------------//
00070 
00076 //----------------------------------------------------------------------------//
00077 
00078 class MACFieldIO : public FieldIO 
00079 {
00080 
00081 public:
00082   
00083   // Typedefs ------------------------------------------------------------------
00084   
00085   typedef boost::intrusive_ptr<MACFieldIO> Ptr;
00086 
00087   // RTTI replacement ----------------------------------------------------------
00088 
00089   typedef MACFieldIO class_type;
00090   DEFINE_FIELD_RTTI_CONCRETE_CLASS;
00091 
00092   static const char *classType()
00093   {
00094     return "MACFieldIO";
00095   }
00096     
00097   // Constructors --------------------------------------------------------------
00098 
00100   MACFieldIO() 
00101    : FieldIO()
00102   { }
00103 
00105   virtual ~MACFieldIO() 
00106   { /* Empty */ }
00107 
00108   static FieldIO::Ptr create()
00109   { return Ptr(new MACFieldIO); }
00110 
00111   // From FieldIO --------------------------------------------------------------
00112 
00116   virtual FieldBase::Ptr read(hid_t layerGroup, const std::string &filename, 
00117                               const std::string &layerPath,
00118                               DataTypeEnum typeEnum);
00119 
00122   virtual bool write(hid_t layerGroup, FieldBase::Ptr field);
00123 
00125   virtual std::string className() const
00126   { return "MACField"; }
00127 
00128 private:
00129 
00130   // Internal methods ----------------------------------------------------------
00131 
00133   template <class Data_T>
00134   bool writeInternal(hid_t layerGroup, typename MACField<Data_T>::Ptr field);
00135   
00137   template <class Data_T>
00138   bool writeData(hid_t layerGroup, typename MACField<Data_T>::Ptr field,
00139                  MACComponent comp);
00140 
00142   template <class Data_T>
00143   bool readData(hid_t location, typename MACField<Data_T>::Ptr result);
00144 
00145   // Strings -------------------------------------------------------------------
00146 
00147   static const int         k_versionNumber;
00148   static const std::string k_versionAttrName;
00149   static const std::string k_extentsStr;
00150   static const std::string k_dataWindowStr;
00151   static const std::string k_componentsStr;
00152   static const std::string k_bitsPerComponentStr;
00153   static const std::string k_uDataStr;
00154   static const std::string k_vDataStr;
00155   static const std::string k_wDataStr;
00156 
00157   // Typedefs ------------------------------------------------------------------
00158 
00160   typedef FieldIO base;    
00161 };
00162  
00163 //----------------------------------------------------------------------------//
00164 // Template methods
00165 //----------------------------------------------------------------------------//
00166 
00168 template <class Data_T>
00169 bool MACFieldIO::writeInternal(hid_t layerGroup, 
00170                                  typename MACField<Data_T>::Ptr field)
00171 {
00172   using namespace Exc;
00173   using namespace Hdf5Util;
00174 
00175   int components = FieldTraits<Data_T>::dataDims();
00176   V3i compSize = field->getComponentSize();
00177   int size[3];
00178   size[0] = compSize.x;
00179   size[1] = compSize.y;
00180   size[2] = compSize.z;
00181 
00182   Box3i ext(field->extents()), dw(field->dataWindow());
00183 
00184   // Add extents attribute ---
00185 
00186   int extents[6] = 
00187     { ext.min.x, ext.min.y, ext.min.z, ext.max.x, ext.max.y, ext.max.z };
00188 
00189   if (!writeAttribute(layerGroup, k_extentsStr, 6, extents[0]))
00190     throw WriteAttributeException("Couldn't write attribute " + k_extentsStr);
00191 
00192   // Add data window attribute ---
00193 
00194   int dataWindow[6] = 
00195     { dw.min.x, dw.min.y, dw.min.z, dw.max.x, dw.max.y, dw.max.z };
00196 
00197   if (!writeAttribute(layerGroup, k_dataWindowStr, 6, dataWindow[0])) 
00198     throw WriteAttributeException("Couldn't write attribute " + k_dataWindowStr);
00199 
00200   // Add components attribute ---
00201 
00202   if (!writeAttribute(layerGroup, k_componentsStr, 1, components)) 
00203     throw WriteAttributeException("Couldn't write attribute " + k_componentsStr);
00204 
00205   // Add the bits per component attribute ---
00206 
00207   int bits = DataTypeTraits<Data_T>::h5bits();
00208   if (!writeAttribute(layerGroup, k_bitsPerComponentStr, 1, bits)) {
00209     throw WriteAttributeException("Couldn't write attribute " + k_bitsPerComponentStr);
00210     return false;    
00211   }
00212 
00213   // Add data to file ---
00214   if (!writeData<Data_T>(layerGroup, field, MACCompU)) {
00215     throw WriteMACFieldDataException("Error writing u_data");
00216     return false;
00217   }    
00218   if (!writeData<Data_T>(layerGroup, field, MACCompV)) {
00219     throw WriteMACFieldDataException("Error writing v_data");
00220     return false;
00221   }    
00222   if (!writeData<Data_T>(layerGroup, field, MACCompW)) {
00223     throw WriteMACFieldDataException("Error writing w_data");
00224     return false;
00225   }    
00226 
00227   return true; 
00228 }
00229 
00230 //----------------------------------------------------------------------------//
00231 
00232 template <class Data_T>
00233 bool MACFieldIO::writeData(hid_t layerGroup, 
00234                            typename MACField<Data_T>::Ptr field,
00235                            MACComponent comp)
00236 {
00237   using namespace Exc;
00238   using namespace Hdf5Util;
00239 
00240   const V3i &compSize = field->getComponentSize();
00241 
00242   hsize_t totalSize[1];
00243   std::string compStr;
00244 
00245   switch (comp) {
00246     case MACCompU:
00247       totalSize[0] = compSize.x;
00248       compStr = k_uDataStr;
00249         break;
00250     case MACCompV:
00251       totalSize[0] = compSize.y;
00252       compStr = k_vDataStr;
00253         break;
00254     case MACCompW:
00255       totalSize[0] = compSize.z;
00256       compStr = k_wDataStr;
00257         break;
00258     default:
00259       break;
00260   }    
00261 
00262   // Make sure chunk size isn't too big.
00263   hsize_t preferredChunkSize = 4096 * 16;
00264   const hsize_t chunkSize = std::min(preferredChunkSize, totalSize[0] / 2);
00265 
00266   H5ScopedScreate dataSpace(H5S_SIMPLE);
00267 
00268   if (dataSpace.id() < 0) 
00269     throw CreateDataSpaceException("Couldn't create data space in "
00270                                    "MACFieldIO::writeData");
00271 
00272   // Create a "simple" data structure ---
00273 
00274   H5Sset_extent_simple(dataSpace.id(), 1, totalSize, NULL);
00275 
00276   // Set up gzip property list
00277   bool gzipAvailable = checkHdf5Gzip();
00278   hid_t dcpl = H5Pcreate(H5P_DATASET_CREATE);
00279   if (gzipAvailable) {
00280     herr_t status = H5Pset_deflate(dcpl, 9);
00281     if (status < 0) {
00282       return false;
00283     }
00284     status = H5Pset_chunk(dcpl, 1, &chunkSize);
00285     if (status < 0) {
00286       return false;
00287     }    
00288   }
00289   
00290   H5ScopedDcreate dataSet(layerGroup, compStr, 
00291                           DataTypeTraits<Data_T>::h5type(), 
00292                           dataSpace.id(), 
00293                           H5P_DEFAULT, dcpl, H5P_DEFAULT);
00294 
00295   if (dataSet.id() < 0) 
00296     throw CreateDataSetException("Couldn't create data set in "
00297                                  "MACFieldIO::writeData");
00298 
00299   hid_t err = H5Dwrite(dataSet, 
00300                        DataTypeTraits<Data_T>::h5type(), 
00301                        H5S_ALL, H5S_ALL, 
00302                        H5P_DEFAULT, &(*field->cbegin_comp(comp)));
00303   if (err < 0) 
00304     throw Exc::WriteLayerException("Error writing layer in "
00305                                    "MACFieldIO::writeData");
00306 
00307 
00308   return true;
00309 }
00310 
00311 //----------------------------------------------------------------------------//
00312 
00313 template <class Data_T>
00314 bool MACFieldIO::readData(hid_t layerGroup,
00315                           typename MACField<Data_T>::Ptr field)
00316 {
00317   using namespace std;
00318   using namespace Exc;
00319   using namespace Hdf5Util;
00320 
00321   hsize_t dims[1];
00322 
00323   // read u_data
00324   {
00325 
00326     H5ScopedDopen dataSet(layerGroup, k_uDataStr, H5P_DEFAULT);
00327     if (dataSet.id() < 0) 
00328       throw OpenDataSetException("Couldn't open data set: " + k_uDataStr);
00329 
00330     H5ScopedDget_space dataSpace(dataSet.id());
00331     H5ScopedDget_type dataType(dataSet.id());
00332     H5Sget_simple_extent_dims(dataSpace.id(), dims, NULL);
00333 
00334     if (dataSpace.id() < 0) 
00335       throw GetDataSpaceException("Couldn't get data space");
00336 
00337     if (dataType.id() < 0)
00338       throw GetDataTypeException("Couldn't get data type");
00339 
00340     if (H5Dread(dataSet, DataTypeTraits<Data_T>::h5type(), 
00341                 H5S_ALL, H5S_ALL, H5P_DEFAULT, &(*field->begin_comp(MACCompU))) < 0) 
00342       {
00343         std::string typeName = "MACField<" + 
00344           DataTypeTraits<Data_T>::name() + ">";
00345         throw Exc::Hdf5DataReadException("Couldn't read " + typeName + " data");
00346       } 
00347 
00348   }
00349 
00350   // read v_data
00351   {
00352 
00353     H5ScopedDopen dataSet(layerGroup, k_vDataStr, H5P_DEFAULT);
00354     if (dataSet.id() < 0) 
00355       throw OpenDataSetException("Couldn't open data set: " + k_vDataStr);
00356 
00357     H5ScopedDget_space dataSpace(dataSet.id());
00358     H5ScopedDget_type dataType(dataSet.id());
00359     H5Sget_simple_extent_dims(dataSpace.id(), dims, NULL);
00360 
00361     if (dataSpace.id() < 0) 
00362       throw GetDataSpaceException("Couldn't get data space");
00363 
00364     if (dataType.id() < 0)
00365       throw GetDataTypeException("Couldn't get data type");
00366 
00367 
00368     if (H5Dread(dataSet, DataTypeTraits<Data_T>::h5type(), 
00369                 H5S_ALL, H5S_ALL, H5P_DEFAULT, &(*field->begin_comp(MACCompV))) < 0) 
00370       {
00371         std::string typeName = "MACField<" + 
00372           DataTypeTraits<Data_T>::name() + ">";
00373         throw Exc::Hdf5DataReadException("Couldn't read " + typeName + " data");
00374       } 
00375 
00376   }
00377 
00378   // read w_data
00379   {
00380 
00381     H5ScopedDopen dataSet(layerGroup, k_wDataStr, H5P_DEFAULT);
00382     if (dataSet.id() < 0) 
00383       throw OpenDataSetException("Couldn't open data set: " + k_wDataStr);
00384 
00385     H5ScopedDget_space dataSpace(dataSet.id());
00386     H5ScopedDget_type dataType(dataSet.id());
00387     H5Sget_simple_extent_dims(dataSpace.id(), dims, NULL);
00388 
00389     if (dataSpace.id() < 0) 
00390       throw GetDataSpaceException("Couldn't get data space");
00391 
00392     if (dataType.id() < 0)
00393       throw GetDataTypeException("Couldn't get data type");
00394 
00395 
00396     if (H5Dread(dataSet, DataTypeTraits<Data_T>::h5type(), 
00397                 H5S_ALL, H5S_ALL, H5P_DEFAULT, &(*field->begin_comp(MACCompW))) < 0) 
00398       {
00399         std::string typeName = "MACField<" + 
00400           DataTypeTraits<Data_T>::name() + ">";
00401         throw Exc::Hdf5DataReadException("Couldn't read " + typeName + " data");
00402       } 
00403 
00404   }
00405 
00406   return true;
00407 }
00408 
00409 //----------------------------------------------------------------------------//
00410 
00411 FIELD3D_NAMESPACE_HEADER_CLOSE
00412 
00413 //----------------------------------------------------------------------------//
00414 
00415 #endif // Include guard