Field3D
|
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