Field3D
Hdf5Util.h
Go to the documentation of this file.
1 //----------------------------------------------------------------------------//
2 
3 /*
4  * Copyright (c) 2009 Sony Pictures Imageworks Inc
5  *
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  *
12  * Redistributions of source code must retain the above copyright
13  * notice, this list of conditions and the following disclaimer.
14  * Redistributions in binary form must reproduce the above copyright
15  * notice, this list of conditions and the following disclaimer in the
16  * documentation and/or other materials provided with the
17  * distribution. Neither the name of Sony Pictures Imageworks nor the
18  * names of its contributors may be used to endorse or promote
19  * products derived from this software without specific prior written
20  * permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
25  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
26  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
27  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
28  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
29  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
31  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
32  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
33  * OF THE POSSIBILITY OF SUCH DAMAGE.
34  */
35 
36 //----------------------------------------------------------------------------//
37 
45 //----------------------------------------------------------------------------//
46 
47 #ifndef _INCLUDED_Field3D_Hdf5Util_H_
48 #define _INCLUDED_Field3D_Hdf5Util_H_
49 
50 //----------------------------------------------------------------------------//
51 
52 #include <string>
53 #include <exception>
54 #include <vector>
55 
56 #include <boost/lexical_cast.hpp>
57 #include <boost/thread/mutex.hpp>
58 #include <boost/thread/recursive_mutex.hpp>
59 
60 #include <hdf5.h>
61 
62 #include "Exception.h"
63 #include "Traits.h"
64 #include "Field.h"
65 
66 //----------------------------------------------------------------------------//
67 
68 #include "ns.h"
69 
71 
72 //----------------------------------------------------------------------------//
73 // Global HDF5 Mutex
74 //----------------------------------------------------------------------------//
75 
76 FIELD3D_API extern boost::recursive_mutex g_hdf5Mutex;
77 
78 typedef boost::recursive_mutex::scoped_lock GlobalLock;
79 
80 //----------------------------------------------------------------------------//
81 // Hdf5Util classes
82 //----------------------------------------------------------------------------//
83 
86 namespace Hdf5Util {
87 
88 //----------------------------------------------------------------------------//
89 
92 class H5Base
93 {
94 public:
95  // Constructor
97  : m_id(-1)
98  { /* Empty */ }
100  hid_t id() const
101  { return m_id; }
103  operator hid_t ()
104  { return m_id; }
105 protected:
106  hid_t m_id;
107 };
108 
109 //----------------------------------------------------------------------------//
110 
113 class H5ScopedAopen : public H5Base
114 {
115 public:
116  H5ScopedAopen(hid_t location, const std::string &name)
117  {
118  GlobalLock lock(g_hdf5Mutex);
119  m_id = H5Aopen(location, name.c_str(), H5P_DEFAULT);
120  if (m_id < 0)
121  throw Exc::MissingAttributeException("Couldn't open attribute " + name);
122  }
123  H5ScopedAopen(hid_t location, const std::string &name, hid_t aapl_id)
124  {
125  GlobalLock lock(g_hdf5Mutex);
126  m_id = H5Aopen(location, name.c_str(), aapl_id);
127  if (m_id < 0)
128  throw Exc::MissingAttributeException("Couldn't open attribute " + name);
129  }
131  {
132  GlobalLock lock(g_hdf5Mutex);
133  if (m_id >= 0)
134  H5Aclose(m_id);
135  }
136 };
137 
138 //----------------------------------------------------------------------------//
139 
142 class H5ScopedAopenIdx : public H5Base
143 {
144 public:
145  H5ScopedAopenIdx(hid_t location, unsigned idx)
146  {
147  GlobalLock lock(g_hdf5Mutex);
148  m_id = H5Aopen_idx(location, idx);
149  if (m_id < 0)
150  throw Exc::MissingAttributeException("Couldn't open attribute at index: " +
151  boost::lexical_cast<std::string>(idx));
152  }
154  {
155  GlobalLock lock(g_hdf5Mutex);
156  if (m_id >= 0)
157  H5Aclose(m_id);
158  }
159 };
160 
161 //----------------------------------------------------------------------------//
162 
165 class H5ScopedGcreate : public H5Base
166 {
167 public:
168  H5ScopedGcreate(hid_t parentLocation, const std::string &name)
169  {
170  GlobalLock lock(g_hdf5Mutex);
171  m_id = H5Gcreate(parentLocation, name.c_str(),
172  H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
173  }
174  H5ScopedGcreate(hid_t parentLocation, const std::string &name,
175  hid_t lcpl_id, hid_t gcpl_id, hid_t gapl_id)
176  {
177  GlobalLock lock(g_hdf5Mutex);
178  m_id = H5Gcreate(parentLocation, name.c_str(),
179  lcpl_id, gcpl_id, gapl_id);
180  }
181 
183  {
184  GlobalLock lock(g_hdf5Mutex);
185  if (m_id >= 0)
186  H5Gclose(m_id);
187  }
188 };
189 
190 //----------------------------------------------------------------------------//
191 
194 class H5ScopedGopen : public H5Base
195 {
196 public:
198  : H5Base()
199  {
200  // Empty
201  }
202  H5ScopedGopen(hid_t parentLocation, const std::string &name)
203  {
204  open(parentLocation, name);
205  }
206  H5ScopedGopen(hid_t parentLocation, const std::string &name, hid_t gapl_id)
207  {
208  open(parentLocation, name, gapl_id);
209  }
210  void open(hid_t parentLocation, const std::string &name)
211  {
212  GlobalLock lock(g_hdf5Mutex);
213  m_id = H5Gopen(parentLocation, name.c_str(), H5P_DEFAULT);
214  }
215  void open(hid_t parentLocation, const std::string &name, hid_t gapl_id)
216  {
217  GlobalLock lock(g_hdf5Mutex);
218  m_id = H5Gopen(parentLocation, name.c_str(), gapl_id);
219  }
220 
222  {
223  GlobalLock lock(g_hdf5Mutex);
224  if (m_id >= 0)
225  H5Gclose(m_id);
226  }
227 };
228 
229 //----------------------------------------------------------------------------//
230 
234 class H5ScopedScreate : public H5Base
235 {
236 public:
238  : H5Base()
239  {
240  // Empty
241  }
242  H5ScopedScreate(H5S_class_t type)
243  {
244  create(type);
245  }
246  void create(H5S_class_t type)
247  {
248  GlobalLock lock(g_hdf5Mutex);
249  m_id = H5Screate(type);
250  }
252  {
253  GlobalLock lock(g_hdf5Mutex);
254  if (m_id >= 0)
255  H5Sclose(m_id);
256  }
257 };
258 
259 //----------------------------------------------------------------------------//
260 
263 class H5ScopedDcreate : public H5Base
264 {
265 public:
266  H5ScopedDcreate(hid_t parentLocation, const std::string &name,
267  hid_t dtype_id, hid_t space_id, hid_t lcpl_id,
268  hid_t dcpl_id, hid_t dapl_id)
269  {
270  GlobalLock lock(g_hdf5Mutex);
271  m_id = H5Dcreate(parentLocation, name.c_str(), dtype_id, space_id,
272  lcpl_id, dcpl_id, dapl_id);
273  }
275  {
276  GlobalLock lock(g_hdf5Mutex);
277  if (m_id >= 0)
278  H5Dclose(m_id);
279  }
280 };
281 
282 //----------------------------------------------------------------------------//
283 
288 {
289 public:
290  H5ScopedAget_space(hid_t dataset_id)
291  {
292  GlobalLock lock(g_hdf5Mutex);
293  m_id = H5Aget_space(dataset_id);
294  if (m_id < 0)
295  throw Exc::AttrGetSpaceException("Couldn't get attribute space");
296  }
298  {
299  GlobalLock lock(g_hdf5Mutex);
300  if (m_id >= 0)
301  H5Sclose(m_id);
302  }
303 };
304 
305 //----------------------------------------------------------------------------//
306 
310 class H5ScopedAget_type : public H5Base
311 {
312 public:
313  H5ScopedAget_type(hid_t dataset_id)
314  {
315  GlobalLock lock(g_hdf5Mutex);
316  m_id = H5Aget_type(dataset_id);
317  if (m_id < 0)
318  throw Exc::AttrGetTypeException("Couldn't get attribute type");
319  }
321  {
322  GlobalLock lock(g_hdf5Mutex);
323  if (m_id >= 0)
324  H5Tclose(m_id);
325  }
326 };
327 
328 //----------------------------------------------------------------------------//
329 
334 {
335 public:
336  H5ScopedTget_native_type(hid_t dataset_id, H5T_direction_t direction)
337  {
338  GlobalLock lock(g_hdf5Mutex);
339  m_id = H5Tget_native_type(dataset_id, direction);
340  if (m_id < 0)
341  throw Exc::AttrGetNativeTypeException("Couldn't get native attribute type");
342  }
344  {
345  GlobalLock lock(g_hdf5Mutex);
346  if (m_id >= 0)
347  H5Tclose(m_id);
348  }
349 };
350 
351 //----------------------------------------------------------------------------//
352 
356 class H5ScopedDopen : public H5Base
357 {
358 public:
360  : H5Base()
361  {
362  // Empty
363  }
364  H5ScopedDopen(hid_t parentLocation, const std::string &name, hid_t dapl_id)
365  {
366  open(parentLocation, name, dapl_id);
367  }
368  void open(hid_t parentLocation, const std::string &name, hid_t dapl_id)
369  {
370  GlobalLock lock(g_hdf5Mutex);
371  m_id = H5Dopen(parentLocation, name.c_str(), dapl_id);
372  }
374  {
375  GlobalLock lock(g_hdf5Mutex);
376  if (m_id >= 0) {
377  H5Dclose(m_id);
378  }
379  }
380 };
381 
382 //----------------------------------------------------------------------------//
383 
387 {
388 public:
390  : H5Base()
391  {
392  // Empty
393  }
394  H5ScopedDget_space(hid_t dataset_id)
395  {
396  open(dataset_id);
397  }
398  void open(hid_t dataset_id)
399  {
400  GlobalLock lock(g_hdf5Mutex);
401  m_id = H5Dget_space(dataset_id);
402  }
404  {
405  GlobalLock lock(g_hdf5Mutex);
406  if (m_id >= 0)
407  H5Sclose(m_id);
408  }
409 };
410 
411 //----------------------------------------------------------------------------//
412 
416 class H5ScopedDget_type : public H5Base
417 {
418 public:
420  : H5Base()
421  {
422  // Empty
423  }
424  H5ScopedDget_type(hid_t dataset_id)
425  {
426  open(dataset_id);
427  }
428  void open(hid_t dataset_id)
429  {
430  GlobalLock lock(g_hdf5Mutex);
431  m_id = H5Dget_type(dataset_id);
432  }
434  {
435  GlobalLock lock(g_hdf5Mutex);
436  if (m_id >= 0)
437  H5Tclose(m_id);
438  }
439 };
440 
441 //----------------------------------------------------------------------------//
442 // Hdf5Util functions
443 //----------------------------------------------------------------------------//
444 
449 template <typename T>
452 void writeSimpleData(hid_t location, const std::string &name,
453  const std::vector<T> &data);
454 
457 template <typename T>
458 void readSimpleData(hid_t location, const std::string &name,
459  std::vector<T> &data);
460 
462 
463 //----------------------------------------------------------------------------//
464 
469 FIELD3D_API bool readAttribute(hid_t location, const std::string& attrName,
472  std::string& value);
473 
476 FIELD3D_API bool readAttribute(hid_t location, const std::string& attrName,
477  unsigned int attrSize, int &value);
478 
481 FIELD3D_API bool readAttribute(hid_t location, const std::string& attrName,
482  unsigned int attrSize, float &value);
483 
486 FIELD3D_API bool readAttribute(hid_t location, const std::string& attrName,
487  unsigned int attrSize, double &value);
488 
491 FIELD3D_API bool readAttribute(hid_t location, const std::string& attrName,
492  std::vector<unsigned int> &attrSize,
493  int &value);
494 
497 FIELD3D_API bool readAttribute(hid_t location, const std::string& attrName,
498  std::vector<unsigned int> &attrSize,
499  float &value);
500 
503 FIELD3D_API bool readAttribute(hid_t location, const std::string& attrName,
504  std::vector<unsigned int> &attrSize,
505  double &value);
506 
508 
509 //----------------------------------------------------------------------------//
510 
515 FIELD3D_API bool writeAttribute(hid_t location, const std::string& attrName,
518  const std::string& value);
519 
522 FIELD3D_API bool writeAttribute(hid_t location, const std::string& attrName,
523  unsigned int attrSize, const int &value);
524 
527 FIELD3D_API bool writeAttribute(hid_t location, const std::string& attrName,
528  unsigned int attrSize, const float &value);
529 
532 FIELD3D_API bool writeAttribute(hid_t location, const std::string& attrName,
533  unsigned int attrSize, const double &value);
534 
537 FIELD3D_API bool writeAttribute(hid_t location, const std::string& attrName,
538  std::vector<unsigned int> &attrSize,
539  const int &value);
540 
543 FIELD3D_API bool writeAttribute(hid_t location, const std::string& attrName,
544  std::vector<unsigned int> &attrSize,
545  const int &value);
546 
549 FIELD3D_API bool writeAttribute(hid_t location, const std::string& attrName,
550  std::vector<unsigned int> &attrSize,
551  const float &value);
552 
555 FIELD3D_API bool writeAttribute(hid_t location, const std::string& attrName,
556  std::vector<unsigned int> &attrSize,
557  const double &value);
558 
560 
561 //----------------------------------------------------------------------------//
562 
566 
567 //----------------------------------------------------------------------------//
568 // Templated functions and classes
569 //----------------------------------------------------------------------------//
570 
571 template <typename T>
572 void writeSimpleData(hid_t location, const std::string &name,
573  const std::vector<T> &data)
574 {
575  using namespace Exc;
576 
577  GlobalLock lock(g_hdf5Mutex);
578 
579  // Calculate the total number of entries. This factors in that
580  // V3f uses 3 components per value, etc.
581  hsize_t totalSize[1];
582  int components = FieldTraits<T>::dataDims();
583  totalSize[0] = data.size() * components;
584 
585  // Get the internal data type
586  hid_t type = DataTypeTraits<T>::h5type();
587 
588  H5ScopedScreate dataSpace(H5S_SIMPLE);
589 
590  if (dataSpace.id() < 0)
591  throw WriteSimpleDataException("Couldn't create data space");
592 
593  H5Sset_extent_simple(dataSpace.id(), 1, totalSize, NULL);
594 
595  H5ScopedDcreate dataSet(location, name.c_str(), type, dataSpace.id(),
596  H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
597 
598  if (dataSet.id() < 0)
599  throw WriteSimpleDataException("Couldn't create data set");
600 
601  hid_t err = H5Dwrite(dataSet.id(), type, H5S_ALL, H5S_ALL,
602  H5P_DEFAULT, &data[0]);
603 
604  if (err < 0)
605  throw WriteSimpleDataException("Couldn't write data");
606 }
607 
608 //----------------------------------------------------------------------------//
609 
610 template <typename T>
611 void readSimpleData(hid_t location, const std::string &name,
612  std::vector<T> &data)
613 {
614  using namespace Exc;
615 
616  GlobalLock lock(g_hdf5Mutex);
617 
618  int components = FieldTraits<T>::dataDims();
619  hsize_t dims[1];
620 
621  H5ScopedDopen dataSet(location, name.c_str(), H5P_DEFAULT);
622 
623  if (dataSet.id() < 0)
624  throw OpenDataSetException("Couldn't open data set: " + name);
625 
626  H5ScopedDget_space dataSpace(dataSet.id());
627  H5ScopedDget_type dataType(dataSet.id());
628  H5Sget_simple_extent_dims(dataSpace.id(), dims, NULL);
629 
630  if (dataSpace.id() < 0)
631  throw GetDataSpaceException("Couldn't get data space");
632 
633  if (dataType.id() < 0)
634  throw GetDataTypeException("Couldn't get data type");
635 
636  int reportedSize = dims[0] / components;
637 
638  // Resize target
639  data.clear();
640  data.resize(reportedSize);
641 
642  // Get the internal data type
643  hid_t type = DataTypeTraits<T>::h5type();
644 
645  if (H5Dread(dataSet.id(), type, H5S_ALL, H5S_ALL,
646  H5P_DEFAULT, &data[0]) < 0) {
647  throw Hdf5DataReadException("Couldn't read simple data");
648  }
649 }
650 
651 //----------------------------------------------------------------------------//
652 
653 } // namespace Hdf5Util
654 
655 //----------------------------------------------------------------------------//
656 
658 
659 //----------------------------------------------------------------------------//
660 
661 #endif
void open(hid_t dataset_id)
Definition: Hdf5Util.h:398
#define FIELD3D_NAMESPACE_HEADER_CLOSE
Definition: ns.h:58
Scoped object - opens an attribute data type on creation and closes it on destruction.
Definition: Hdf5Util.h:310
Contains utility functions and classes for Hdf5 files.
Definition: Hdf5Util.h:86
Scoped object - opens a dataset on creation and closes it on destruction.
Definition: Hdf5Util.h:416
FIELD3D_API bool writeAttribute(hid_t location, const std::string &attrName, const std::string &value)
Writes a string attribute.
H5ScopedGcreate(hid_t parentLocation, const std::string &name)
Definition: Hdf5Util.h:168
Scoped object - opens an native type id on creation and closes it on destruction. ...
Definition: Hdf5Util.h:333
static int dataDims()
Dimensions of the given data type. i.e. 3 for V3f, 1 for float.
Namespace for Exception objects.
Definition: Exception.h:57
Scoped object - opens a dataset on creation and closes it on destruction.
Definition: Hdf5Util.h:356
FIELD3D_API bool readAttribute(hid_t location, const std::string &attrName, std::string &value)
Reads a string attribute.
boost::recursive_mutex::scoped_lock GlobalLock
Definition: Hdf5Util.h:78
H5ScopedAopen(hid_t location, const std::string &name)
Definition: Hdf5Util.h:116
H5ScopedScreate(H5S_class_t type)
Definition: Hdf5Util.h:242
H5ScopedTget_native_type(hid_t dataset_id, H5T_direction_t direction)
Definition: Hdf5Util.h:336
Scoped object - creates a group on creation and closes it on destruction.
Definition: Hdf5Util.h:165
H5ScopedGopen(hid_t parentLocation, const std::string &name)
Definition: Hdf5Util.h:202
H5ScopedAget_type(hid_t dataset_id)
Definition: Hdf5Util.h:313
void open(hid_t dataset_id)
Definition: Hdf5Util.h:428
Scoped object - Opens attribute by name and closes it on destruction.
Definition: Hdf5Util.h:113
Scoped object - Opens attribute by index and closes it on destruction.
Definition: Hdf5Util.h:142
FIELD3D_API bool checkHdf5Gzip()
Checks whether gzip is available in the current hdf5 library.
Definition: Hdf5Util.cpp:722
H5ScopedAopenIdx(hid_t location, unsigned idx)
Definition: Hdf5Util.h:145
void open(hid_t parentLocation, const std::string &name, hid_t dapl_id)
Definition: Hdf5Util.h:368
void readSimpleData(hid_t location, const std::string &name, std::vector< T > &data)
Reads a simple linear data set from the given location.
Definition: Hdf5Util.h:611
static hid_t h5type()
H5ScopedGopen(hid_t parentLocation, const std::string &name, hid_t gapl_id)
Definition: Hdf5Util.h:206
void open(hid_t parentLocation, const std::string &name, hid_t gapl_id)
Definition: Hdf5Util.h:215
#define FIELD3D_API
Definition: ns.h:77
Scoped object - opens an attribute data space on creation and closes it on destruction.
Definition: Hdf5Util.h:287
H5ScopedAopen(hid_t location, const std::string &name, hid_t aapl_id)
Definition: Hdf5Util.h:123
Scoped object - creates a dataspace on creation and closes it on destruction.
Definition: Hdf5Util.h:234
FIELD3D_NAMESPACE_OPEN FIELD3D_API boost::recursive_mutex g_hdf5Mutex
Definition: Hdf5Util.cpp:67
Base class for all scoped Hdf5 util classes.
Definition: Hdf5Util.h:92
Contains Field, WritableField and ResizableField classes.
H5ScopedGcreate(hid_t parentLocation, const std::string &name, hid_t lcpl_id, hid_t gcpl_id, hid_t gapl_id)
Definition: Hdf5Util.h:174
H5ScopedDget_space(hid_t dataset_id)
Definition: Hdf5Util.h:394
Scoped object - creates a dataset on creation and closes it on destruction.
Definition: Hdf5Util.h:263
H5ScopedAget_space(hid_t dataset_id)
Definition: Hdf5Util.h:290
Scoped object - opens a group on creation and closes it on destruction.
Definition: Hdf5Util.h:194
Contains Exception base class.
void create(H5S_class_t type)
Definition: Hdf5Util.h:246
H5ScopedDget_type(hid_t dataset_id)
Definition: Hdf5Util.h:424
void open(hid_t parentLocation, const std::string &name)
Definition: Hdf5Util.h:210
Scoped object - opens a dataset on creation and closes it on destruction.
Definition: Hdf5Util.h:386
void writeSimpleData(hid_t location, const std::string &name, const std::vector< T > &data)
Writes a simple linear data set to the given location.
Definition: Hdf5Util.h:572
H5ScopedDopen(hid_t parentLocation, const std::string &name, hid_t dapl_id)
Definition: Hdf5Util.h:364
H5ScopedDcreate(hid_t parentLocation, const std::string &name, hid_t dtype_id, hid_t space_id, hid_t lcpl_id, hid_t dcpl_id, hid_t dapl_id)
Definition: Hdf5Util.h:266
hid_t id() const
Query the hid_t value.
Definition: Hdf5Util.h:100