Field3D
MACFieldIO.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_MACFieldIO_H_
45 #define _INCLUDED_Field3D_MACFieldIO_H_
46 
47 //----------------------------------------------------------------------------//
48 
49 #include <string>
50 
51 #include <boost/intrusive_ptr.hpp>
52 
53 #include <hdf5.h>
54 
55 #include "Exception.h"
56 #include "Field3DFile.h"
57 #include "FieldIO.h"
58 #include "Hdf5Util.h"
59 #include "MACField.h"
60 
61 //----------------------------------------------------------------------------//
62 
63 #include "ns.h"
64 
66 
67 //----------------------------------------------------------------------------//
68 // MACFieldIO
69 //----------------------------------------------------------------------------//
70 
76 //----------------------------------------------------------------------------//
77 
78 class MACFieldIO : public FieldIO
79 {
80 
81 public:
82 
83  // Typedefs ------------------------------------------------------------------
84 
85  typedef boost::intrusive_ptr<MACFieldIO> Ptr;
86 
87  // RTTI replacement ----------------------------------------------------------
88 
91 
92  static const char *staticClassType()
93  {
94  return "MACFieldIO";
95  }
96 
97  // Constructors --------------------------------------------------------------
98 
101  : FieldIO()
102  { }
103 
105  virtual ~MACFieldIO()
106  { /* Empty */ }
107 
109  { return Ptr(new MACFieldIO); }
110 
111  // From FieldIO --------------------------------------------------------------
112 
116  virtual FieldBase::Ptr read(hid_t layerGroup, const std::string &filename,
117  const std::string &layerPath,
118  DataTypeEnum typeEnum);
119 
122  virtual bool write(hid_t layerGroup, FieldBase::Ptr field);
123 
125  virtual std::string className() const
126  { return "MACField"; }
127 
128 private:
129 
130  // Internal methods ----------------------------------------------------------
131 
133  template <class Data_T>
134  bool writeInternal(hid_t layerGroup, typename MACField<Data_T>::Ptr field);
135 
137  template <class Data_T>
138  bool writeData(hid_t layerGroup, typename MACField<Data_T>::Ptr field,
139  MACComponent comp);
140 
142  template <class Data_T>
143  bool readData(hid_t location, typename MACField<Data_T>::Ptr result);
144 
145  // Strings -------------------------------------------------------------------
146 
147  static const int k_versionNumber;
148  static const std::string k_versionAttrName;
149  static const std::string k_extentsStr;
150  static const std::string k_dataWindowStr;
151  static const std::string k_componentsStr;
152  static const std::string k_bitsPerComponentStr;
153  static const std::string k_uDataStr;
154  static const std::string k_vDataStr;
155  static const std::string k_wDataStr;
156 
157  // Typedefs ------------------------------------------------------------------
158 
160  typedef FieldIO base;
161 };
162 
163 //----------------------------------------------------------------------------//
164 // Template methods
165 //----------------------------------------------------------------------------//
166 
168 template <class Data_T>
169 bool MACFieldIO::writeInternal(hid_t layerGroup,
170  typename MACField<Data_T>::Ptr field)
171 {
172  using namespace Exc;
173  using namespace Hdf5Util;
174 
175  int components = FieldTraits<Data_T>::dataDims();
176 
177  Box3i ext(field->extents()), dw(field->dataWindow());
178 
179  // Add extents attribute ---
180 
181  int extents[6] =
182  { ext.min.x, ext.min.y, ext.min.z, ext.max.x, ext.max.y, ext.max.z };
183 
184  if (!writeAttribute(layerGroup, k_extentsStr, 6, extents[0]))
185  throw WriteAttributeException("Couldn't write attribute " + k_extentsStr);
186 
187  // Add data window attribute ---
188 
189  int dataWindow[6] =
190  { dw.min.x, dw.min.y, dw.min.z, dw.max.x, dw.max.y, dw.max.z };
191 
192  if (!writeAttribute(layerGroup, k_dataWindowStr, 6, dataWindow[0]))
193  throw WriteAttributeException("Couldn't write attribute " + k_dataWindowStr);
194 
195  // Add components attribute ---
196 
197  if (!writeAttribute(layerGroup, k_componentsStr, 1, components))
198  throw WriteAttributeException("Couldn't write attribute " + k_componentsStr);
199 
200  // Add the bits per component attribute ---
201 
202  int bits = DataTypeTraits<Data_T>::h5bits();
203  if (!writeAttribute(layerGroup, k_bitsPerComponentStr, 1, bits)) {
204  throw WriteAttributeException("Couldn't write attribute " + k_bitsPerComponentStr);
205  return false;
206  }
207 
208  // Add data to file ---
209  if (!writeData<Data_T>(layerGroup, field, MACCompU)) {
210  throw WriteMACFieldDataException("Error writing u_data");
211  return false;
212  }
213  if (!writeData<Data_T>(layerGroup, field, MACCompV)) {
214  throw WriteMACFieldDataException("Error writing v_data");
215  return false;
216  }
217  if (!writeData<Data_T>(layerGroup, field, MACCompW)) {
218  throw WriteMACFieldDataException("Error writing w_data");
219  return false;
220  }
221 
222  return true;
223 }
224 
225 //----------------------------------------------------------------------------//
226 
227 template <class Data_T>
228 bool MACFieldIO::writeData(hid_t layerGroup,
229  typename MACField<Data_T>::Ptr field,
230  MACComponent comp)
231 {
232  using namespace Exc;
233  using namespace Hdf5Util;
234 
235  const V3i &compSize = field->getComponentSize();
236 
237  hsize_t totalSize[1];
238  std::string compStr;
239 
240  switch (comp) {
241  case MACCompU:
242  totalSize[0] = compSize.x;
243  compStr = k_uDataStr;
244  break;
245  case MACCompV:
246  totalSize[0] = compSize.y;
247  compStr = k_vDataStr;
248  break;
249  case MACCompW:
250  totalSize[0] = compSize.z;
251  compStr = k_wDataStr;
252  break;
253  default:
254  break;
255  }
256 
257  // Make sure chunk size isn't too big.
258  hsize_t preferredChunkSize = 4096 * 16;
259  const hsize_t chunkSize = std::min(preferredChunkSize, totalSize[0] / 2);
260 
261  H5ScopedScreate dataSpace(H5S_SIMPLE);
262 
263  if (dataSpace.id() < 0)
264  throw CreateDataSpaceException("Couldn't create data space in "
265  "MACFieldIO::writeData");
266 
267  // Create a "simple" data structure ---
268 
269  H5Sset_extent_simple(dataSpace.id(), 1, totalSize, NULL);
270 
271  // Set up gzip property list
272  bool gzipAvailable = checkHdf5Gzip();
273  hid_t dcpl = H5Pcreate(H5P_DATASET_CREATE);
274  if (gzipAvailable) {
275  herr_t status = H5Pset_deflate(dcpl, 9);
276  if (status < 0) {
277  return false;
278  }
279  status = H5Pset_chunk(dcpl, 1, &chunkSize);
280  if (status < 0) {
281  return false;
282  }
283  }
284 
285  H5ScopedDcreate dataSet(layerGroup, compStr,
287  dataSpace.id(),
288  H5P_DEFAULT, dcpl, H5P_DEFAULT);
289 
290  if (dataSet.id() < 0)
291  throw CreateDataSetException("Couldn't create data set in "
292  "MACFieldIO::writeData");
293 
294  hid_t err = H5Dwrite(dataSet,
296  H5S_ALL, H5S_ALL,
297  H5P_DEFAULT, &(*field->cbegin_comp(comp)));
298  if (err < 0)
299  throw Exc::WriteLayerException("Error writing layer in "
300  "MACFieldIO::writeData");
301 
302 
303  return true;
304 }
305 
306 //----------------------------------------------------------------------------//
307 
308 template <class Data_T>
309 bool MACFieldIO::readData(hid_t layerGroup,
310  typename MACField<Data_T>::Ptr field)
311 {
312  using namespace std;
313  using namespace Exc;
314  using namespace Hdf5Util;
315 
316  hsize_t dims[1];
317 
318  // read u_data
319  {
320 
321  H5ScopedDopen dataSet(layerGroup, k_uDataStr, H5P_DEFAULT);
322  if (dataSet.id() < 0)
323  throw OpenDataSetException("Couldn't open data set: " + k_uDataStr);
324 
325  H5ScopedDget_space dataSpace(dataSet.id());
326  H5ScopedDget_type dataType(dataSet.id());
327  H5Sget_simple_extent_dims(dataSpace.id(), dims, NULL);
328 
329  if (dataSpace.id() < 0)
330  throw GetDataSpaceException("Couldn't get data space");
331 
332  if (dataType.id() < 0)
333  throw GetDataTypeException("Couldn't get data type");
334 
335  if (H5Dread(dataSet, DataTypeTraits<Data_T>::h5type(),
336  H5S_ALL, H5S_ALL, H5P_DEFAULT, &(*field->begin_comp(MACCompU))) < 0)
337  {
338  std::string typeName = "MACField<" +
340  throw Exc::Hdf5DataReadException("Couldn't read " + typeName + " data");
341  }
342 
343  }
344 
345  // read v_data
346  {
347 
348  H5ScopedDopen dataSet(layerGroup, k_vDataStr, H5P_DEFAULT);
349  if (dataSet.id() < 0)
350  throw OpenDataSetException("Couldn't open data set: " + k_vDataStr);
351 
352  H5ScopedDget_space dataSpace(dataSet.id());
353  H5ScopedDget_type dataType(dataSet.id());
354  H5Sget_simple_extent_dims(dataSpace.id(), dims, NULL);
355 
356  if (dataSpace.id() < 0)
357  throw GetDataSpaceException("Couldn't get data space");
358 
359  if (dataType.id() < 0)
360  throw GetDataTypeException("Couldn't get data type");
361 
362 
363  if (H5Dread(dataSet, DataTypeTraits<Data_T>::h5type(),
364  H5S_ALL, H5S_ALL, H5P_DEFAULT, &(*field->begin_comp(MACCompV))) < 0)
365  {
366  std::string typeName = "MACField<" +
368  throw Exc::Hdf5DataReadException("Couldn't read " + typeName + " data");
369  }
370 
371  }
372 
373  // read w_data
374  {
375 
376  H5ScopedDopen dataSet(layerGroup, k_wDataStr, H5P_DEFAULT);
377  if (dataSet.id() < 0)
378  throw OpenDataSetException("Couldn't open data set: " + k_wDataStr);
379 
380  H5ScopedDget_space dataSpace(dataSet.id());
381  H5ScopedDget_type dataType(dataSet.id());
382  H5Sget_simple_extent_dims(dataSpace.id(), dims, NULL);
383 
384  if (dataSpace.id() < 0)
385  throw GetDataSpaceException("Couldn't get data space");
386 
387  if (dataType.id() < 0)
388  throw GetDataTypeException("Couldn't get data type");
389 
390 
391  if (H5Dread(dataSet, DataTypeTraits<Data_T>::h5type(),
392  H5S_ALL, H5S_ALL, H5P_DEFAULT, &(*field->begin_comp(MACCompW))) < 0)
393  {
394  std::string typeName = "MACField<" +
396  throw Exc::Hdf5DataReadException("Couldn't read " + typeName + " data");
397  }
398 
399  }
400 
401  return true;
402 }
403 
404 //----------------------------------------------------------------------------//
405 
407 
408 //----------------------------------------------------------------------------//
409 
410 #endif // Include guard
#define FIELD3D_NAMESPACE_HEADER_CLOSE
Definition: ns.h:58
Imath::Box3i Box3i
Definition: SpiMathLib.h:77
Contains utility functions and classes for Hdf5 files.
Definition: Hdf5Util.h:86
static const std::string k_vDataStr
Definition: MACFieldIO.h:154
Scoped object - opens a dataset on creation and closes it on destruction.
Definition: Hdf5Util.h:416
const Box3i & extents() const
Returns the extents of the data. This signifies the relevant area that the data exists over...
Definition: Field.h:254
FIELD3D_API bool writeAttribute(hid_t location, const std::string &attrName, const std::string &value)
Writes a string attribute.
Contains the Field3DFile classesOSS sanitized.
Contains the MACField class.
virtual ~MACFieldIO()
Dtor.
Definition: MACFieldIO.h:105
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
mac_comp_iterator begin_comp(MACComponent comp)
Iterator to first element.
Definition: MACField.h:868
virtual std::string className() const
Returns the class name.
Definition: MACFieldIO.h:125
V3i getComponentSize() const
Returns the size of U,V,W components.
Definition: MACField.h:261
Scoped object - opens a dataset on creation and closes it on destruction.
Definition: Hdf5Util.h:356
boost::intrusive_ptr< FieldBase > Ptr
Definition: Field.h:97
boost::intrusive_ptr< MACFieldIO > Ptr
Definition: MACFieldIO.h:85
static const std::string k_componentsStr
Definition: MACFieldIO.h:151
static std::string name()
Definition: Traits.h:101
MACComponent
Definition: MACField.h:71
static const std::string k_uDataStr
Definition: MACFieldIO.h:153
Contains various utility functions for Hdf5.
static const int k_versionNumber
Definition: MACFieldIO.h:147
Imath::V3i V3i
Definition: SpiMathLib.h:71
static FieldIO::Ptr create()
Definition: MACFieldIO.h:108
boost::intrusive_ptr< MACField > Ptr
Definition: MACField.h:101
static const std::string k_wDataStr
Definition: MACFieldIO.h:155
FIELD3D_API bool checkHdf5Gzip()
Checks whether gzip is available in the current hdf5 library.
Definition: Hdf5Util.cpp:722
static const std::string k_extentsStr
Definition: MACFieldIO.h:149
MACFieldIO class_type
Definition: MACFieldIO.h:89
bool writeInternal(hid_t layerGroup, typename MACField< Data_T >::Ptr field)
This call writes all the attributes and sets up the data space.
Definition: MACFieldIO.h:169
static const std::string k_versionAttrName
Definition: MACFieldIO.h:148
static int h5bits()
FieldIO base
Convenience typedef for referring to base class.
Definition: MACFieldIO.h:160
static const std::string k_dataWindowStr
Definition: MACFieldIO.h:150
static const std::string k_bitsPerComponentStr
Definition: MACFieldIO.h:152
Scoped object - creates a dataspace on creation and closes it on destruction.
Definition: Hdf5Util.h:234
virtual bool write(hid_t layerGroup, FieldBase::Ptr field)
Writes the given field to disk.
Definition: MACFieldIO.cpp:158
bool writeData(hid_t layerGroup, typename MACField< Data_T >::Ptr field, MACComponent comp)
This call writes out the u,v,w data.
Definition: MACFieldIO.h:228
DEFINE_FIELD_RTTI_CONCRETE_CLASS
Definition: MACFieldIO.h:90
Scoped object - creates a dataset on creation and closes it on destruction.
Definition: Hdf5Util.h:263
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 MACField object from it.
Definition: MACFieldIO.cpp:79
boost::intrusive_ptr< FieldIO > Ptr
Definition: FieldIO.h:90
const_mac_comp_iterator cbegin_comp(MACComponent comp) const
Const iterator to first element. "cbegin" matches the tr1 c++ standard.
Definition: MACField.h:812
DataTypeEnum
Definition: Traits.h:66
const Box3i & dataWindow() const
Returns the data window. Any coordinate inside this window is safe to pass to value() in the Field su...
Definition: Field.h:258
Contains Exception base class.
static const char * staticClassType()
Definition: MACFieldIO.h:92
MACFieldIO()
Ctor.
Definition: MACFieldIO.h:100
Contains FieldIO class.
Scoped object - opens a dataset on creation and closes it on destruction.
Definition: Hdf5Util.h:386
hid_t id() const
Query the hid_t value.
Definition: Hdf5Util.h:100
bool readData(hid_t location, typename MACField< Data_T >::Ptr result)
Reads the data that is dependent on the data type on disk.
Definition: MACFieldIO.h:309