Field3D
DenseFieldIO.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_DenseFieldIO_H_
45 #define _INCLUDED_Field3D_DenseFieldIO_H_
46 
47 //----------------------------------------------------------------------------//
48 
49 #include <string>
50 
51 #include <boost/intrusive_ptr.hpp>
52 
53 #include <hdf5.h>
54 
55 #include "DenseField.h"
56 #include "Exception.h"
57 #include "FieldIO.h"
58 #include "Field3DFile.h"
59 #include "Hdf5Util.h"
60 
61 //----------------------------------------------------------------------------//
62 
63 #include "ns.h"
64 
66 
67 //----------------------------------------------------------------------------//
68 // DenseFieldIO
69 //----------------------------------------------------------------------------//
70 
76 //----------------------------------------------------------------------------//
77 
78 class DenseFieldIO : public FieldIO
79 {
80 
81 public:
82 
83  // Typedefs ------------------------------------------------------------------
84 
85  typedef boost::intrusive_ptr<DenseFieldIO> Ptr;
86 
87  // RTTI replacement ----------------------------------------------------------
88 
91 
92  static const char* staticClassType()
93  {
94  return "DenseFieldIO";
95  }
96 
97  // Constructors --------------------------------------------------------------
98 
101  : FieldIO()
102  { }
103 
105  virtual ~DenseFieldIO()
106  { /* Empty */ }
107 
109  { return Ptr(new DenseFieldIO); }
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 
123  virtual bool write(hid_t layerGroup, FieldBase::Ptr field);
124 
126  virtual std::string className() const
127  { return "DenseField"; }
128 
129 private:
130 
131  // Internal methods ----------------------------------------------------------
132 
134  template <class Data_T>
135  bool writeInternal(hid_t layerGroup,
136  typename DenseField<Data_T>::Ptr field);
137 
139  template <class Data_T>
140  bool writeData(hid_t dataSet, typename DenseField<Data_T>::Ptr field,
141  Data_T dummy);
142 
144  template <class Data_T>
145  typename DenseField<Data_T>::Ptr readData(hid_t dataSet, const Box3i &extents,
146  const Box3i &dataW);
147 
148  // Strings -------------------------------------------------------------------
149 
150  static const int k_versionNumber;
151  static const std::string k_versionAttrName;
152  static const std::string k_extentsStr;
153  static const std::string k_dataWindowStr;
154  static const std::string k_componentsStr;
155  static const std::string k_bitsPerComponentStr;
156  static const std::string k_dataStr;
157 
158  // Typedefs ------------------------------------------------------------------
159 
161  typedef FieldIO base;
162 
163 };
164 
165 //----------------------------------------------------------------------------//
166 // Templated methods
167 //----------------------------------------------------------------------------//
168 
170 template <class Data_T>
171 bool DenseFieldIO::writeInternal(hid_t layerGroup,
172  typename DenseField<Data_T>::Ptr field)
173 {
174  using namespace Exc;
175  using namespace Hdf5Util;
176 
177  const V3i& memSize = field->internalMemSize();
178  int size[3];
179  size[0] = memSize.x;
180  size[1] = memSize.y;
181  size[2] = memSize.z;
182 
183  int components = FieldTraits<Data_T>::dataDims();
184 
185  hsize_t totalSize[1];
186  totalSize[0] = size[0] * size[1] * size[2] * components;
187 
188  // Make sure chunk size isn't too big.
189  hsize_t preferredChunkSize = 4096 * 16;
190  const hsize_t chunkSize = std::min(preferredChunkSize, totalSize[0] / 2);
191 
192  Box3i ext(field->extents()), dw(field->dataWindow());
193 
194  // Add extents attribute ---
195 
196  int extents[6] =
197  { ext.min.x, ext.min.y, ext.min.z, ext.max.x, ext.max.y, ext.max.z };
198 
199  if (!writeAttribute(layerGroup, k_extentsStr, 6, extents[0])) {
200  throw WriteAttributeException("Couldn't write attribute " + k_extentsStr);
201  }
202 
203  // Add data window attribute ---
204 
205  int dataWindow[6] =
206  { dw.min.x, dw.min.y, dw.min.z, dw.max.x, dw.max.y, dw.max.z };
207 
208  if (!writeAttribute(layerGroup, k_dataWindowStr, 6, dataWindow[0])) {
209  throw WriteAttributeException("Couldn't write attribute " + k_dataWindowStr);
210  }
211 
212  // Add components attribute ---
213 
214  if (!writeAttribute(layerGroup, k_componentsStr, 1, components)) {
215  throw WriteAttributeException("Couldn't write attribute " + k_componentsStr);
216  }
217 
218  // Add the bits per component attribute ---
219 
220  int bits = DataTypeTraits<Data_T>::h5bits();
221  if (!writeAttribute(layerGroup, k_bitsPerComponentStr, 1, bits)) {
222  Msg::print(Msg::SevWarning, "Error adding bits per component attribute.");
223  return false;
224  }
225 
226  // Add data to file ---
227 
228  H5ScopedScreate dataSpace(H5S_SIMPLE);
229 
230  if (dataSpace.id() < 0) {
231  throw CreateDataSpaceException("Couldn't create data space in "
232  "DenseFieldIO::writeInternal");
233  }
234 
235  // Create a "simple" data structure ---
236 
237  H5Sset_extent_simple(dataSpace.id(), 1, totalSize, NULL);
238 
239  // Set up gzip property list
240  bool gzipAvailable = checkHdf5Gzip();
241  hid_t dcpl = H5Pcreate(H5P_DATASET_CREATE);
242  if (gzipAvailable) {
243  herr_t status = H5Pset_deflate(dcpl, 9);
244  if (status < 0) {
245  return false;
246  }
247  status = H5Pset_chunk(dcpl, 1, &chunkSize);
248  if (status < 0) {
249  return false;
250  }
251  }
252 
253  H5ScopedDcreate dataSet(layerGroup, k_dataStr,
255  dataSpace.id(),
256  H5P_DEFAULT, dcpl, H5P_DEFAULT);
257 
258  if (dataSet.id() < 0) {
259  throw CreateDataSetException("Couldn't create data set in "
260  "DenseFieldIO::writeInternal");
261  }
262 
263  // Call out to the templated function, it will figure out how to get
264  // the data into the file in the appropriate fashion.
265  if (!writeData<Data_T>(dataSet.id(), field, Data_T(0.0f))) {
266  throw WriteLayerException("Error writing layer");
267  }
268 
269  return true;
270 }
271 
272 //----------------------------------------------------------------------------//
273 
274 template <class Data_T>
275 bool DenseFieldIO::writeData(hid_t dataSet,
276  typename DenseField<Data_T>::Ptr field,
277  Data_T /* dummy */)
278 {
279  using namespace Hdf5Util;
280 
281  hid_t err = H5Dwrite(dataSet,
283  H5S_ALL, H5S_ALL,
284  H5P_DEFAULT, &(*field->begin()));
285 
286  if (err < 0) {
287  throw Exc::WriteLayerException("Error writing layer in "
288  "DenseFieldIO::writeData");
289  }
290 
291  return true;
292 }
293 
294 //----------------------------------------------------------------------------//
295 
296 template <class Data_T>
297 typename DenseField<Data_T>::Ptr
298 DenseFieldIO::readData(hid_t dataSet, const Box3i &extents, const Box3i &dataW)
299 {
300  typename DenseField<Data_T>::Ptr field(new DenseField<Data_T>);
301  field->setSize(extents, dataW);
302 
303  if (H5Dread(dataSet, DataTypeTraits<Data_T>::h5type(),
304  H5S_ALL, H5S_ALL, H5P_DEFAULT, &(*field->begin())) < 0)
305  {
306  std::string typeName = "DenseField<" +
308  throw Exc::Hdf5DataReadException("Couldn't read " + typeName + " data");
309  }
310 
311  return field;
312 }
313 
314 //----------------------------------------------------------------------------//
315 
317 
318 //----------------------------------------------------------------------------//
319 
320 #endif // Include guard
This subclass of Field stores data in a contiguous std::vector.
Definition: DenseField.h:85
#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_versionAttrName
Definition: DenseFieldIO.h:151
const Box3i & extents() const
Returns the extents of the data. This signifies the relevant area that the data exists over...
Definition: Field.h:254
DenseField< Data_T >::Ptr readData(hid_t dataSet, const Box3i &extents, const Box3i &dataW)
This call performs the actual reading of data from disk.
Definition: DenseFieldIO.h:298
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 DenseField class.
DEFINE_FIELD_RTTI_CONCRETE_CLASS
Definition: DenseFieldIO.h:90
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: DenseFieldIO.h:153
iterator begin()
Iterator to first element.
Definition: DenseField.h:602
DenseFieldIO()
Ctor.
Definition: DenseFieldIO.h:100
static const int k_versionNumber
Definition: DenseFieldIO.h:150
boost::intrusive_ptr< FieldBase > Ptr
Definition: Field.h:97
static std::string name()
Definition: Traits.h:101
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
Contains various utility functions for Hdf5.
static const std::string k_extentsStr
Definition: DenseFieldIO.h:152
Imath::V3i V3i
Definition: SpiMathLib.h:71
DenseFieldIO class_type
Definition: DenseFieldIO.h:89
static FieldIO::Ptr create()
Definition: DenseFieldIO.h:108
const FIELD3D_VEC3_T< size_t > & internalMemSize() const
Returns the internal memory size in each dimension. This is used for example in LinearInterpolator, where it optimizes random access to voxels.
Definition: DenseField.h:196
void setSize(const V3i &size)
Resizes the object.
Definition: Field.h:918
bool writeData(hid_t dataSet, typename DenseField< Data_T >::Ptr field, Data_T dummy)
This call performs the actual writing of data to disk.
Definition: DenseFieldIO.h:275
static const std::string k_bitsPerComponentStr
Definition: DenseFieldIO.h:155
static const std::string k_dataStr
Definition: DenseFieldIO.h:156
static const char * staticClassType()
Definition: DenseFieldIO.h:92
FIELD3D_API bool checkHdf5Gzip()
Checks whether gzip is available in the current hdf5 library.
Definition: Hdf5Util.cpp:722
boost::intrusive_ptr< DenseFieldIO > Ptr
Definition: DenseFieldIO.h:85
static const std::string k_componentsStr
Definition: DenseFieldIO.h:154
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 DenseField object from it...
FieldIO base
Convenience typedef for referring to base class.
Definition: DenseFieldIO.h:161
static int h5bits()
Scoped object - creates a dataspace on creation and closes it on destruction.
Definition: Hdf5Util.h:234
virtual std::string className() const
Returns the class name.
Definition: DenseFieldIO.h:126
boost::intrusive_ptr< DenseField > Ptr
Definition: DenseField.h:92
bool writeInternal(hid_t layerGroup, typename DenseField< Data_T >::Ptr field)
This call writes all the attributes and sets up the data space.
Definition: DenseFieldIO.h:171
Scoped object - creates a dataset on creation and closes it on destruction.
Definition: Hdf5Util.h:263
boost::intrusive_ptr< FieldIO > Ptr
Definition: FieldIO.h:90
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
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...
virtual ~DenseFieldIO()
Dtor.
Definition: DenseFieldIO.h:105
Contains Exception base class.
Contains FieldIO class.
hid_t id() const
Query the hid_t value.
Definition: Hdf5Util.h:100