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 *classType()
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  V3i compSize = field->getComponentSize();
177  int size[3];
178  size[0] = compSize.x;
179  size[1] = compSize.y;
180  size[2] = compSize.z;
181 
182  Box3i ext(field->extents()), dw(field->dataWindow());
183 
184  // Add extents attribute ---
185 
186  int extents[6] =
187  { ext.min.x, ext.min.y, ext.min.z, ext.max.x, ext.max.y, ext.max.z };
188 
189  if (!writeAttribute(layerGroup, k_extentsStr, 6, extents[0]))
190  throw WriteAttributeException("Couldn't write attribute " + k_extentsStr);
191 
192  // Add data window attribute ---
193 
194  int dataWindow[6] =
195  { dw.min.x, dw.min.y, dw.min.z, dw.max.x, dw.max.y, dw.max.z };
196 
197  if (!writeAttribute(layerGroup, k_dataWindowStr, 6, dataWindow[0]))
198  throw WriteAttributeException("Couldn't write attribute " + k_dataWindowStr);
199 
200  // Add components attribute ---
201 
202  if (!writeAttribute(layerGroup, k_componentsStr, 1, components))
203  throw WriteAttributeException("Couldn't write attribute " + k_componentsStr);
204 
205  // Add the bits per component attribute ---
206 
207  int bits = DataTypeTraits<Data_T>::h5bits();
208  if (!writeAttribute(layerGroup, k_bitsPerComponentStr, 1, bits)) {
209  throw WriteAttributeException("Couldn't write attribute " + k_bitsPerComponentStr);
210  return false;
211  }
212 
213  // Add data to file ---
214  if (!writeData<Data_T>(layerGroup, field, MACCompU)) {
215  throw WriteMACFieldDataException("Error writing u_data");
216  return false;
217  }
218  if (!writeData<Data_T>(layerGroup, field, MACCompV)) {
219  throw WriteMACFieldDataException("Error writing v_data");
220  return false;
221  }
222  if (!writeData<Data_T>(layerGroup, field, MACCompW)) {
223  throw WriteMACFieldDataException("Error writing w_data");
224  return false;
225  }
226 
227  return true;
228 }
229 
230 //----------------------------------------------------------------------------//
231 
232 template <class Data_T>
233 bool MACFieldIO::writeData(hid_t layerGroup,
234  typename MACField<Data_T>::Ptr field,
235  MACComponent comp)
236 {
237  using namespace Exc;
238  using namespace Hdf5Util;
239 
240  const V3i &compSize = field->getComponentSize();
241 
242  hsize_t totalSize[1];
243  std::string compStr;
244 
245  switch (comp) {
246  case MACCompU:
247  totalSize[0] = compSize.x;
248  compStr = k_uDataStr;
249  break;
250  case MACCompV:
251  totalSize[0] = compSize.y;
252  compStr = k_vDataStr;
253  break;
254  case MACCompW:
255  totalSize[0] = compSize.z;
256  compStr = k_wDataStr;
257  break;
258  default:
259  break;
260  }
261 
262  // Make sure chunk size isn't too big.
263  hsize_t preferredChunkSize = 4096 * 16;
264  const hsize_t chunkSize = std::min(preferredChunkSize, totalSize[0] / 2);
265 
266  H5ScopedScreate dataSpace(H5S_SIMPLE);
267 
268  if (dataSpace.id() < 0)
269  throw CreateDataSpaceException("Couldn't create data space in "
270  "MACFieldIO::writeData");
271 
272  // Create a "simple" data structure ---
273 
274  H5Sset_extent_simple(dataSpace.id(), 1, totalSize, NULL);
275 
276  // Set up gzip property list
277  bool gzipAvailable = checkHdf5Gzip();
278  hid_t dcpl = H5Pcreate(H5P_DATASET_CREATE);
279  if (gzipAvailable) {
280  herr_t status = H5Pset_deflate(dcpl, 9);
281  if (status < 0) {
282  return false;
283  }
284  status = H5Pset_chunk(dcpl, 1, &chunkSize);
285  if (status < 0) {
286  return false;
287  }
288  }
289 
290  H5ScopedDcreate dataSet(layerGroup, compStr,
292  dataSpace.id(),
293  H5P_DEFAULT, dcpl, H5P_DEFAULT);
294 
295  if (dataSet.id() < 0)
296  throw CreateDataSetException("Couldn't create data set in "
297  "MACFieldIO::writeData");
298 
299  hid_t err = H5Dwrite(dataSet,
301  H5S_ALL, H5S_ALL,
302  H5P_DEFAULT, &(*field->cbegin_comp(comp)));
303  if (err < 0)
304  throw Exc::WriteLayerException("Error writing layer in "
305  "MACFieldIO::writeData");
306 
307 
308  return true;
309 }
310 
311 //----------------------------------------------------------------------------//
312 
313 template <class Data_T>
314 bool MACFieldIO::readData(hid_t layerGroup,
315  typename MACField<Data_T>::Ptr field)
316 {
317  using namespace std;
318  using namespace Exc;
319  using namespace Hdf5Util;
320 
321  hsize_t dims[1];
322 
323  // read u_data
324  {
325 
326  H5ScopedDopen dataSet(layerGroup, k_uDataStr, H5P_DEFAULT);
327  if (dataSet.id() < 0)
328  throw OpenDataSetException("Couldn't open data set: " + k_uDataStr);
329 
330  H5ScopedDget_space dataSpace(dataSet.id());
331  H5ScopedDget_type dataType(dataSet.id());
332  H5Sget_simple_extent_dims(dataSpace.id(), dims, NULL);
333 
334  if (dataSpace.id() < 0)
335  throw GetDataSpaceException("Couldn't get data space");
336 
337  if (dataType.id() < 0)
338  throw GetDataTypeException("Couldn't get data type");
339 
340  if (H5Dread(dataSet, DataTypeTraits<Data_T>::h5type(),
341  H5S_ALL, H5S_ALL, H5P_DEFAULT, &(*field->begin_comp(MACCompU))) < 0)
342  {
343  std::string typeName = "MACField<" +
345  throw Exc::Hdf5DataReadException("Couldn't read " + typeName + " data");
346  }
347 
348  }
349 
350  // read v_data
351  {
352 
353  H5ScopedDopen dataSet(layerGroup, k_vDataStr, H5P_DEFAULT);
354  if (dataSet.id() < 0)
355  throw OpenDataSetException("Couldn't open data set: " + k_vDataStr);
356 
357  H5ScopedDget_space dataSpace(dataSet.id());
358  H5ScopedDget_type dataType(dataSet.id());
359  H5Sget_simple_extent_dims(dataSpace.id(), dims, NULL);
360 
361  if (dataSpace.id() < 0)
362  throw GetDataSpaceException("Couldn't get data space");
363 
364  if (dataType.id() < 0)
365  throw GetDataTypeException("Couldn't get data type");
366 
367 
368  if (H5Dread(dataSet, DataTypeTraits<Data_T>::h5type(),
369  H5S_ALL, H5S_ALL, H5P_DEFAULT, &(*field->begin_comp(MACCompV))) < 0)
370  {
371  std::string typeName = "MACField<" +
373  throw Exc::Hdf5DataReadException("Couldn't read " + typeName + " data");
374  }
375 
376  }
377 
378  // read w_data
379  {
380 
381  H5ScopedDopen dataSet(layerGroup, k_wDataStr, H5P_DEFAULT);
382  if (dataSet.id() < 0)
383  throw OpenDataSetException("Couldn't open data set: " + k_wDataStr);
384 
385  H5ScopedDget_space dataSpace(dataSet.id());
386  H5ScopedDget_type dataType(dataSet.id());
387  H5Sget_simple_extent_dims(dataSpace.id(), dims, NULL);
388 
389  if (dataSpace.id() < 0)
390  throw GetDataSpaceException("Couldn't get data space");
391 
392  if (dataType.id() < 0)
393  throw GetDataTypeException("Couldn't get data type");
394 
395 
396  if (H5Dread(dataSet, DataTypeTraits<Data_T>::h5type(),
397  H5S_ALL, H5S_ALL, H5P_DEFAULT, &(*field->begin_comp(MACCompW))) < 0)
398  {
399  std::string typeName = "MACField<" +
401  throw Exc::Hdf5DataReadException("Couldn't read " + typeName + " data");
402  }
403 
404  }
405 
406  return true;
407 }
408 
409 //----------------------------------------------------------------------------//
410 
412 
413 //----------------------------------------------------------------------------//
414 
415 #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:76
const_mac_comp_iterator cbegin_comp(MACComponent comp) const
Const iterator to first element. "cbegin" matches the tr1 c++ standard.
Definition: MACField.h:801
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:381
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
const Box3i & extents() const
Returns the extents of the data. This signifies the relevant area that the data exists over...
Definition: Field.h:251
mac_comp_iterator begin_comp(MACComponent comp)
Iterator to first element.
Definition: MACField.h:857
Scoped object - opens a dataset on creation and closes it on destruction.
Definition: Hdf5Util.h:325
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
virtual std::string className() const
Returns the class name.
Definition: MACFieldIO.h:125
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
V3i getComponentSize() const
Returns the size of U,V,W components.
Definition: MACField.h:261
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:255
boost::intrusive_ptr< MACField > Ptr
Definition: MACField.h:101
static const std::string k_wDataStr
Definition: MACFieldIO.h:155
bool checkHdf5Gzip()
Checks whether gzip is available in the current hdf5 library.
Definition: Hdf5Util.cpp:680
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 char * classType()
Definition: MACFieldIO.h:92
bool writeAttribute(hid_t location, const std::string &attrName, const std::string &value)
Writes a string attribute.
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:213
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:233
DEFINE_FIELD_RTTI_CONCRETE_CLASS
Definition: MACFieldIO.h:90
Scoped object - creates a dataset on creation and closes it on destruction.
Definition: Hdf5Util.h:240
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
hid_t id() const
Query the hid_t value.
Definition: Hdf5Util.h:90
DataTypeEnum
Definition: Traits.h:66
Contains Exception base class.
MACFieldIO()
Ctor.
Definition: MACFieldIO.h:100
Contains FieldIO class.
Scoped object - opens a dataset on creation and closes it on destruction.
Definition: Hdf5Util.h:353
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:314