Field3D
MIPFieldIO.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 
42 //----------------------------------------------------------------------------//
43 
44 #ifndef _INCLUDED_Field3D_MIPFieldIO_H_
45 #define _INCLUDED_Field3D_MIPFieldIO_H_
46 
47 //----------------------------------------------------------------------------//
48 
49 #include <string>
50 
51 #include <boost/intrusive_ptr.hpp>
52 #include <boost/thread/mutex.hpp>
53 
54 #include <hdf5.h>
55 
56 #include "MIPField.h"
57 #include "Exception.h"
58 #include "Field3DFile.h"
59 #include "Hdf5Util.h"
60 
61 //----------------------------------------------------------------------------//
62 
63 #include "ns.h"
64 
66 
67 //----------------------------------------------------------------------------//
68 // MIPFieldIO
69 //----------------------------------------------------------------------------//
70 
76 //----------------------------------------------------------------------------//
77 
78 class MIPFieldIO : public FieldIO
79 {
80 
81 public:
82 
83  // Typedefs ------------------------------------------------------------------
84 
85  typedef boost::intrusive_ptr<MIPFieldIO> Ptr;
86 
87  // RTTI replacement ----------------------------------------------------------
88 
91 
92  static const char* staticClassType()
93  {
94  return "MIPFieldIO";
95  }
96 
97  // Constructors --------------------------------------------------------------
98 
101  : FieldIO()
102  { }
103 
105  virtual ~MIPFieldIO()
106  { /* Empty */ }
107 
109  { return Ptr(new MIPFieldIO); }
110 
111  // From FieldIO --------------------------------------------------------------
112 
116  virtual FieldBase::Ptr read(hid_t layerGroup,
117  const std::string &filename,
118  const std::string &layerPath,
119  DataTypeEnum typeEnum);
120 
124  virtual bool write(hid_t layerGroup, FieldBase::Ptr field);
125 
127  virtual std::string className() const
128  { return "MIPField"; }
129 
130 private:
131 
132  // Internal methods ----------------------------------------------------------
133 
135  template <template <typename X> class Field_T, class Data_T>
136  bool writeInternal(hid_t layerGroup,
137  typename MIPField<Field_T<Data_T> >::Ptr field);
138 
139  template <template <typename X> class Field_T, class Data_T>
141  readInternal(hid_t layerGroup, const std::string &filename,
142  const std::string &layerPath, DataTypeEnum typeEnum);
143 
144  // Strings -------------------------------------------------------------------
145 
146  static const int k_versionNumber;
147  static const std::string k_versionAttrName;
148  static const std::string k_extentsStr;
149  static const std::string k_dataWindowStr;
150  static const std::string k_componentsStr;
151  static const std::string k_bitsPerComponentStr;
152  static const std::string k_mipGroupStr;
153  static const std::string k_levelGroupStr;
154  static const std::string k_levelsStr;
155  static const std::string k_baseTypeStr;
156 
157  // Typedefs ------------------------------------------------------------------
158 
160  typedef FieldIO base;
161 
162 };
163 
164 //----------------------------------------------------------------------------//
165 // Implementation details
166 //----------------------------------------------------------------------------//
167 
168 namespace detail {
169 
172  template <typename Field_T>
173  struct MIPInstance;
174 
176  template <typename Data_T>
177  struct MIPInstance<SparseField<Data_T> >
178  {
180  };
181 
182  // Specialization for dense field
183  template <typename Data_T>
184  struct MIPInstance<DenseField<Data_T> >
185  {
187  };
188 
189 }
190 
191 //----------------------------------------------------------------------------//
192 // GenericLazyLoadAction
193 //----------------------------------------------------------------------------//
194 
195 template <class Field_T>
197  : public LazyLoadAction<Field_T>
198 {
199 public:
200 
201  // Typedefs ------------------------------------------------------------------
202 
203  typedef boost::shared_ptr<GenericLazyLoadAction<Field_T> > Ptr;
204  typedef std::vector<Ptr> Vec;
205 
206  // Constructor ---------------------------------------------------------------
207 
208  GenericLazyLoadAction(const std::string &filename,
209  const std::string &path,
210  const DataTypeEnum &typeEnum)
211  : LazyLoadAction<Field_T>(),
212  m_filename(filename), m_path(path), m_typeEnum(typeEnum)
213  {
214  // Empty
215  }
216 
218  { }
219 
220  // From LazyLoadAction -------------------------------------------------------
221 
222  virtual typename Field_T::Ptr load() const
223  {
224  using namespace Hdf5Util;
225 
226  hid_t file;
227  boost::shared_ptr<H5ScopedGopen> levelGroup;
228 
229  {
230  // Hold lock while calling H5Fopen
231  GlobalLock lock(g_hdf5Mutex);
232 
233  // Open the HDF5 file
234  file = H5Fopen(m_filename.c_str(), H5F_ACC_RDONLY, H5P_DEFAULT);
235  if (file < 0) {
236  throw Exc::NoSuchFileException(m_filename);
237  }
238  levelGroup.reset(new H5ScopedGopen(file, m_path));
239  }
240 
241  // Instantiate I/O
242  FieldIO::Ptr io =
243  ClassFactory::singleton().createFieldIO(Field_T::staticClassName());
244  // Read the data
245  FieldBase::Ptr field = io->read(*levelGroup, m_filename,
246  m_path, m_typeEnum);
247 
248  {
249  // Hold lock again
250  GlobalLock lock(g_hdf5Mutex);
251  // Close the file
252  if (H5Fclose(file) < 0) {
253  Msg::print("Error closing file: " + m_filename);
254  }
255  }
256  // Done
257  return field_dynamic_cast<Field_T>(field);
258  }
259 
260 private:
261 
262  // Data members --------------------------------------------------------------
263 
265  const std::string m_filename;
267  const std::string m_path;
270 
272  static boost::mutex ms_hdf5Mutex;
273 
274 };
275 
276 //----------------------------------------------------------------------------//
277 // Templated methods
278 //----------------------------------------------------------------------------//
279 
280 template <template <typename X> class Field_T, class Data_T>
281 bool MIPFieldIO::writeInternal(hid_t layerGroup,
282  typename MIPField<Field_T<Data_T> >::Ptr field)
283 {
284  using namespace Exc;
285  using namespace Hdf5Util;
286 
287  Box3i ext(field->extents()), dw(field->dataWindow());
288 
289  // Add extents attribute ---
290 
291  int extents[6] =
292  { ext.min.x, ext.min.y, ext.min.z, ext.max.x, ext.max.y, ext.max.z };
293 
294  if (!writeAttribute(layerGroup, k_extentsStr, 6, extents[0])) {
295  throw WriteAttributeException("Couldn't write attribute " + k_extentsStr);
296  }
297 
298  // Add data window attribute ---
299 
300  int dataWindow[6] =
301  { dw.min.x, dw.min.y, dw.min.z, dw.max.x, dw.max.y, dw.max.z };
302 
303  if (!writeAttribute(layerGroup, k_dataWindowStr, 6, dataWindow[0])) {
304  throw WriteAttributeException("Couldn't write attribute " + k_dataWindowStr);
305  }
306 
307  // Add components attribute ---
308 
309  int components = FieldTraits<Data_T>::dataDims();
310 
311  if (!writeAttribute(layerGroup, k_componentsStr, 1, components)) {
312  throw WriteAttributeException("Couldn't write attribute " + k_componentsStr);
313  }
314 
315  // Add the bits per component attribute ---
316 
317  int bits = DataTypeTraits<Data_T>::h5bits();
318  if (!writeAttribute(layerGroup, k_bitsPerComponentStr, 1, bits)) {
319  Msg::print(Msg::SevWarning, "Error adding bits per component attribute.");
320  return false;
321  }
322 
323  // Add the base type attribute ---
324 
325  std::string baseType = Field_T<Data_T>::staticClassName();
326  if (!writeAttribute(layerGroup, k_baseTypeStr, baseType)) {
327  throw WriteAttributeException("Couldn't write attribute " + k_baseTypeStr);
328  }
329 
330  // Add the mip fields group
331 
332  H5ScopedGcreate mipGroup(layerGroup, k_mipGroupStr);
333 
334  // Write number of layers
335  int numLevels = field->numLevels();
336  if (!writeAttribute(mipGroup, k_levelsStr, 1, numLevels)) {
337  throw WriteAttributeException("Couldn't write attribute " + k_levelsStr);
338  }
339 
340  // For each level ---
341 
342  for (size_t i = 0; i < field->numLevels(); i++) {
343 
344  // Add a named group
345  H5ScopedGcreate levelGroup(mipGroup, k_levelGroupStr + "." +
346  boost::lexical_cast<std::string>(i));
347 
348  // Add the field to the group
349  std::string className = Field_T<Data_T>::staticClassName();
350  FieldIO::Ptr io =
352  io->write(levelGroup, field->mipLevel(i));
353 
354  }
355 
356  return true;
357 }
358 
359 //----------------------------------------------------------------------------//
360 
361 template <template <typename X> class Field_T, class Data_T>
363 MIPFieldIO::readInternal(hid_t layerGroup,
364  const std::string &filename,
365  const std::string &layerPath,
366  DataTypeEnum typeEnum)
367 {
368  using namespace detail;
369  using namespace Exc;
370  using namespace Hdf5Util;
371 
372  typedef MIPField<Field_T<Data_T> > MIPType;
373  typedef GenericLazyLoadAction<Field_T<Data_T> > Action;
374 
375  // Read extents
376  Box3i extents;
377  if (!readAttribute(layerGroup, k_extentsStr, 6, extents.min.x))
378  throw MissingAttributeException("Couldn't find attribute " +
379  k_extentsStr);
380 
381  // Read data window
382  Box3i dataW;
383  if (!readAttribute(layerGroup, k_dataWindowStr, 6, dataW.min.x))
384  throw MissingAttributeException("Couldn't find attribute " +
386 
387  // Read components
388  int components;
389  if (!readAttribute(layerGroup, k_componentsStr, 1, components))
390  throw MissingAttributeException("Couldn't find attribute " +
392 
393  // Construct the resulting MIP field
394  typename MIPType::Ptr result(new typename MIPInstance<Field_T<Data_T> >::type);
395 
396  // Open the MIP field group
397  H5ScopedGopen mipGroup(layerGroup, k_mipGroupStr);
398 
399  // Read num levels
400  int numLevels;
401  if (!readAttribute(mipGroup, k_levelsStr, 1, numLevels))
402  throw MissingAttributeException("Couldn't find attribute " + k_levelsStr);
403 
404  // Read each level ---
405 
406  std::vector<typename EmptyField<Data_T>::Ptr> proxies;
407  typename LazyLoadAction<Field_T<Data_T> >::Vec actions;
408 
409  for (int i = 0; i < numLevels; i++) {
410  // Open level group
411  std::string levelGroupStr =
412  k_levelGroupStr + "." + boost::lexical_cast<std::string>(i);
413  H5ScopedGopen levelGroup(mipGroup, levelGroupStr);
414  // Read the proxy
415  typename EmptyField<Data_T>::Ptr proxy(new EmptyField<Data_T>);
416  // Read extents
417  if (!readAttribute(levelGroup, k_extentsStr, 6, extents.min.x))
418  throw MissingAttributeException("Couldn't find attribute " +
419  k_extentsStr);
420  // Read data window
421  if (!readAttribute(levelGroup, k_dataWindowStr, 6, dataW.min.x))
422  throw MissingAttributeException("Couldn't find attribute " +
424  // Configure proxy with resolution
425  proxy->setSize(extents, dataW);
426  proxies.push_back(proxy);
427  // Make the lazy load action
428  std::string fullPath =
429  layerPath + "/" + k_mipGroupStr + "/" + levelGroupStr;
430  typename Action::Ptr action(new Action(filename, fullPath, typeEnum));
431  actions.push_back(action);
432  }
433 
434  result->setupLazyLoad(proxies, actions);
435 
436  return result;
437 }
438 
439 //----------------------------------------------------------------------------//
440 // Template instantiations
441 //----------------------------------------------------------------------------//
442 
443 template <typename Field_T>
445 
446 //----------------------------------------------------------------------------//
447 
449 
450 //----------------------------------------------------------------------------//
451 
452 #endif // Include guard
This subclass of Field stores data in a contiguous std::vector.
Definition: DenseField.h:85
virtual std::string className() const
Returns the class name.
Definition: MIPFieldIO.h:127
const std::string m_path
Path in file.
Definition: MIPFieldIO.h:267
#define FIELD3D_NAMESPACE_HEADER_CLOSE
Definition: ns.h:58
Field_T::Ptr field_dynamic_cast(RefBase::Ptr field)
Dynamic cast that uses string-comparison in order to be safe even after an object crosses a shared li...
Definition: RefCount.h:256
Imath::Box3i Box3i
Definition: SpiMathLib.h:77
Contains utility functions and classes for Hdf5 files.
Definition: Hdf5Util.h:86
FIELD3D_API bool writeAttribute(hid_t location, const std::string &attrName, const std::string &value)
Writes a string attribute.
Contains the Field3DFile classesOSS sanitized.
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
static const std::string k_dataWindowStr
Definition: MIPFieldIO.h:149
static boost::mutex ms_hdf5Mutex
HDF5 access mutex.
Definition: MIPFieldIO.h:272
FIELD3D_API bool readAttribute(hid_t location, const std::string &attrName, std::string &value)
Reads a string attribute.
boost::intrusive_ptr< FieldBase > Ptr
Definition: Field.h:97
virtual Field_T::Ptr load() const
Performs the loading of the pre-determined field and returns a pointer to it.
Definition: MIPFieldIO.h:222
static ClassFactory & singleton()
}
static const std::string k_levelsStr
Definition: MIPFieldIO.h:154
boost::recursive_mutex::scoped_lock GlobalLock
Definition: Hdf5Util.h:78
static const std::string k_baseTypeStr
Definition: MIPFieldIO.h:155
FIELD3D_API void print(Severity severity, const std::string &message)
Sends the string to the assigned output, prefixing the message with the severity. ...
Definition: Log.cpp:66
std::vector< Ptr > Vec
Definition: MIPFieldIO.h:204
This subclass stores a MIP representation of a Field_T field.
Definition: MIPField.h:109
boost::intrusive_ptr< MIPFieldIO > Ptr
Definition: MIPFieldIO.h:85
Contains various utility functions for Hdf5.
Scoped object - creates a group on creation and closes it on destruction.
Definition: Hdf5Util.h:165
GenericLazyLoadAction(const std::string &filename, const std::string &path, const DataTypeEnum &typeEnum)
Definition: MIPFieldIO.h:208
boost::shared_ptr< GenericLazyLoadAction< Field_T > > Ptr
Definition: MIPFieldIO.h:203
static const std::string k_levelGroupStr
Definition: MIPFieldIO.h:153
static const std::string k_mipGroupStr
Definition: MIPFieldIO.h:152
void setSize(const V3i &size)
Resizes the object.
Definition: Field.h:918
static const std::string k_extentsStr
Definition: MIPFieldIO.h:148
static const std::string k_versionAttrName
Definition: MIPFieldIO.h:147
static FieldIO::Ptr create()
Definition: MIPFieldIO.h:108
MIPFieldIO()
Ctor.
Definition: MIPFieldIO.h:100
static const char * staticClassType()
Definition: MIPFieldIO.h:92
virtual ~MIPFieldIO()
Dtor.
Definition: MIPFieldIO.h:105
This subclass of Field does not store any data.
Definition: EmptyField.h:86
We need to instantiate MIPSparseField rather than MIPField<SparseField>. This traits class does that...
Definition: MIPFieldIO.h:173
MIPField< Field_T< Data_T > >::Ptr readInternal(hid_t layerGroup, const std::string &filename, const std::string &layerPath, DataTypeEnum typeEnum)
Definition: MIPFieldIO.h:363
boost::intrusive_ptr< EmptyField > Ptr
Definition: EmptyField.h:93
virtual FieldBase::Ptr read(hid_t layerGroup, const std::string &filename, const std::string &layerPath, DataTypeEnum typeEnum)
Reads the field at the given location and tries to create a MIPField object from it. Calls out to readData() for template-specific work.
Definition: MIPFieldIO.cpp:82
static int h5bits()
MIPFieldIO class_type
Definition: MIPFieldIO.h:89
FIELD3D_NAMESPACE_OPEN FIELD3D_API boost::recursive_mutex g_hdf5Mutex
Definition: Hdf5Util.cpp:67
const std::string m_filename
Filename.
Definition: MIPFieldIO.h:265
static const std::string k_componentsStr
Definition: MIPFieldIO.h:150
const DataTypeEnum m_typeEnum
Data type enum.
Definition: MIPFieldIO.h:269
FieldIO::Ptr createFieldIO(const std::string &className) const
Instances an IO object by name.
bool writeInternal(hid_t layerGroup, typename MIPField< Field_T< Data_T > >::Ptr field)
This call writes all the attributes and sets up the data space.
Definition: MIPFieldIO.h:281
boost::intrusive_ptr< FieldIO > Ptr
Definition: FieldIO.h:90
static const std::string k_bitsPerComponentStr
Definition: MIPFieldIO.h:151
This Field subclass stores voxel data in block-allocated arrays.
Definition: SparseField.h:350
DataTypeEnum
Definition: Traits.h:66
Scoped object - opens a group on creation and closes it on destruction.
Definition: Hdf5Util.h:194
Contains Exception base class.
DEFINE_FIELD_RTTI_CONCRETE_CLASS
Definition: MIPFieldIO.h:90
virtual bool write(hid_t layerGroup, FieldBase::Ptr field)
Writes the given field to disk. This function calls out to writeInternal once the template type has b...
Definition: MIPFieldIO.cpp:190
Contains the MIPField class.
static const int k_versionNumber
Definition: MIPFieldIO.h:146
FieldIO base
Convenience typedef for referring to base class.
Definition: MIPFieldIO.h:160