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 //----------------------------------------------------------------------------// 00127 00130 class H5ScopedAopenIdx : public H5Base 00131 { 00132 public: 00133 H5ScopedAopenIdx(hid_t location, unsigned idx) 00134 { 00135 m_id = H5Aopen_idx(location, idx); 00136 if (m_id < 0) 00137 throw Exc::MissingAttributeException("Couldn't open attribute at index: "+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 00453 00454 //----------------------------------------------------------------------------// 00455 00460 00461 00462 bool writeAttribute(hid_t location, const std::string& attrName, 00463 const std::string& value); 00464 00467 bool writeAttribute(hid_t location, const std::string& attrName, 00468 unsigned int attrSize, const int &value); 00469 00472 bool writeAttribute(hid_t location, const std::string& attrName, 00473 unsigned int attrSize, const float &value); 00474 00477 bool writeAttribute(hid_t location, const std::string& attrName, 00478 unsigned int attrSize, const double &value); 00479 00481 00482 //----------------------------------------------------------------------------// 00483 00486 bool checkHdf5Gzip(); 00487 00488 //----------------------------------------------------------------------------// 00489 // Templated functions and classes 00490 //----------------------------------------------------------------------------// 00491 00492 template <typename T> 00493 void writeSimpleData(hid_t location, const std::string &name, 00494 const std::vector<T> &data) 00495 { 00496 using namespace Exc; 00497 00498 // Calculate the total number of entries. This factors in that 00499 // V3f uses 3 components per value, etc. 00500 hsize_t totalSize[1]; 00501 int components = FieldTraits<T>::dataDims(); 00502 totalSize[0] = data.size() * components; 00503 00504 // Get the internal data type 00505 hid_t type = DataTypeTraits<T>::h5type(); 00506 00507 H5ScopedScreate dataSpace(H5S_SIMPLE); 00508 00509 if (dataSpace.id() < 0) 00510 throw WriteSimpleDataException("Couldn't create data space"); 00511 00512 H5Sset_extent_simple(dataSpace.id(), 1, totalSize, NULL); 00513 00514 H5ScopedDcreate dataSet(location, name.c_str(), type, dataSpace.id(), 00515 H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); 00516 00517 if (dataSet.id() < 0) 00518 throw WriteSimpleDataException("Couldn't create data set"); 00519 00520 hid_t err = H5Dwrite(dataSet.id(), type, H5S_ALL, H5S_ALL, 00521 H5P_DEFAULT, &data[0]); 00522 00523 if (err < 0) 00524 throw WriteSimpleDataException("Couldn't write data"); 00525 } 00526 00527 //----------------------------------------------------------------------------// 00528 00529 template <typename T> 00530 void readSimpleData(hid_t location, const std::string &name, 00531 std::vector<T> &data) 00532 { 00533 using namespace Exc; 00534 00535 int components = FieldTraits<T>::dataDims(); 00536 hsize_t dims[1]; 00537 00538 H5ScopedDopen dataSet(location, name.c_str(), H5P_DEFAULT); 00539 00540 if (dataSet.id() < 0) 00541 throw OpenDataSetException("Couldn't open data set: " + name); 00542 00543 H5ScopedDget_space dataSpace(dataSet.id()); 00544 H5ScopedDget_type dataType(dataSet.id()); 00545 H5Sget_simple_extent_dims(dataSpace.id(), dims, NULL); 00546 00547 if (dataSpace.id() < 0) 00548 throw GetDataSpaceException("Couldn't get data space"); 00549 00550 if (dataType.id() < 0) 00551 throw GetDataTypeException("Couldn't get data type"); 00552 00553 int reportedSize = dims[0] / components; 00554 00555 // Resize target 00556 data.clear(); 00557 data.resize(reportedSize); 00558 00559 // Get the internal data type 00560 hid_t type = DataTypeTraits<T>::h5type(); 00561 00562 if (H5Dread(dataSet.id(), type, H5S_ALL, H5S_ALL, 00563 H5P_DEFAULT, &data[0]) < 0) { 00564 throw Hdf5DataReadException("Couldn't read simple data"); 00565 } 00566 } 00567 00568 //----------------------------------------------------------------------------// 00569 00570 } // namespace Hdf5Util 00571 00572 //----------------------------------------------------------------------------// 00573 00574 FIELD3D_NAMESPACE_HEADER_CLOSE 00575 00576 //----------------------------------------------------------------------------// 00577 00578 #endif