Field3D

#include <SparseFieldIO.h>

Inheritance diagram for SparseFieldIO:
FieldIO RefBase

Public Types

typedef SparseFieldIO class_type
 
typedef boost::intrusive_ptr< SparseFieldIOPtr
 
- Public Types inherited from FieldIO
typedef FieldIO class_type
 
typedef boost::intrusive_ptr< FieldIOPtr
 
- Public Types inherited from RefBase
typedef boost::intrusive_ptr< RefBasePtr
 

Public Member Functions

virtual std::string className () const
 Returns the class name. More...
 
const char * classType () const
 
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 SparseField object from it. More...
 
 SparseFieldIO ()
 Ctor. More...
 
virtual bool write (hid_t layerGroup, FieldBase::Ptr field)
 Writes the given field to disk. More...
 
virtual ~SparseFieldIO ()
 Dtor. More...
 
- Public Member Functions inherited from FieldIO
 FieldIO ()
 Ctor. More...
 
virtual ~FieldIO ()
 Dtor. More...
 
- Public Member Functions inherited from RefBase
void ref () const
 Used by boost::intrusive_pointer. More...
 
size_t refcnt ()
 Used by boost::intrusive_pointer. More...
 
void unref () const
 Used by boost::intrusive_pointer. More...
 
 RefBase ()
 
 RefBase (const RefBase &)
 Copy constructor. More...
 
RefBaseoperator= (const RefBase &)
 Assignment operator. More...
 
virtual ~RefBase ()
 Destructor. More...
 
virtual bool checkRTTI (const char *typenameStr)=0
 This function is only implemented by concrete classes and triggers the actual RTTI check through matchRTTI();. More...
 
bool matchRTTI (const char *typenameStr)
 Performs a check to see if the given typename string matches this class' This needs to be implemented in -all- subclasses, even abstract ones. More...
 

Static Public Member Functions

static FieldIO::Ptr create ()
 
- Static Public Member Functions inherited from FieldIO
static const char * classType ()
 
- Static Public Member Functions inherited from RefBase
static const char * classType ()
 

Public Attributes

 DEFINE_FIELD_RTTI_CONCRETE_CLASS
 
- Public Attributes inherited from FieldIO
 DEFINE_FIELD_RTTI_ABSTRACT_CLASS
 

Private Types

typedef FieldIO base
 Convenience typedef for referring to base class. More...
 

Private Member Functions

template<class Data_T >
bool readData (hid_t location, int numBlocks, const std::string &filename, const std::string &layerPath, typename SparseField< Data_T >::Ptr result)
 Reads the data that is dependent on the data type on disk. More...
 
template<class Data_T >
bool writeInternal (hid_t layerGroup, typename SparseField< Data_T >::Ptr field)
 This call writes all the attributes and sets up the data space. More...
 

Static Private Attributes

static const std::string k_bitsPerComponentStr
 
static const std::string k_blockOrderStr
 
static const std::string k_blockResStr
 
static const std::string k_componentsStr
 
static const std::string k_dataStr
 
static const std::string k_dataWindowStr
 
static const std::string k_extentsStr
 
static const std::string k_numBlocksStr
 
static const std::string k_numOccupiedBlocksStr
 
static const std::string k_versionAttrName
 
static const int k_versionNumber
 

Detailed Description

Defines the IO for a SparseField object

Definition at line 79 of file SparseFieldIO.h.

Member Typedef Documentation

◆ Ptr

typedef boost::intrusive_ptr<SparseFieldIO> SparseFieldIO::Ptr

Definition at line 86 of file SparseFieldIO.h.

◆ class_type

Definition at line 90 of file SparseFieldIO.h.

◆ base

typedef FieldIO SparseFieldIO::base
private

Convenience typedef for referring to base class.

Definition at line 163 of file SparseFieldIO.h.

Constructor & Destructor Documentation

◆ SparseFieldIO()

SparseFieldIO::SparseFieldIO ( )
inline

Ctor.

Definition at line 101 of file SparseFieldIO.h.

102  : FieldIO()
103  { }
FieldIO()
Ctor.
Definition: FieldIO.h:105

◆ ~SparseFieldIO()

virtual SparseFieldIO::~SparseFieldIO ( )
inlinevirtual

Dtor.

Definition at line 106 of file SparseFieldIO.h.

107  { /* Empty */ }

Member Function Documentation

◆ classType()

const char* SparseFieldIO::classType ( ) const
inline

Definition at line 93 of file SparseFieldIO.h.

94  {
95  return "SparseFieldIO";
96  }

◆ create()

static FieldIO::Ptr SparseFieldIO::create ( )
inlinestatic

Definition at line 110 of file SparseFieldIO.h.

References read(), and write().

Referenced by initIO().

111  { return Ptr(new SparseFieldIO); }
boost::intrusive_ptr< SparseFieldIO > Ptr
Definition: SparseFieldIO.h:86

◆ read()

FieldBase::Ptr SparseFieldIO::read ( hid_t  layerGroup,
const std::string &  filename,
const std::string &  layerPath,
DataTypeEnum  typeEnum 
)
virtual

Reads the field at the given location and tries to create a SparseField object from it.

Returns
Null if no object was read

Implements FieldIO.

Definition at line 84 of file SparseFieldIO.cpp.

References DataTypeDouble, DataTypeFloat, DataTypeHalf, DataTypeVecDouble, DataTypeVecFloat, DataTypeVecHalf, Msg::print(), Hdf5Util::readAttribute(), SparseField< Data_T >::setBlockOrder(), ResizableField< Data_T >::setSize(), and Msg::SevWarning.

Referenced by create().

87 {
88  Box3i extents, dataW;
89  int components;
90  int blockOrder;
91  int numBlocks;
92  V3i blockRes;
93 
94  if (layerGroup == -1) {
95  Msg::print(Msg::SevWarning, "Bad layerGroup.");
96  return FieldBase::Ptr();
97  }
98 
99  int version;
100  if (!readAttribute(layerGroup, k_versionAttrName, 1, version))
101  throw MissingAttributeException("Couldn't find attribute: " +
103 
104  if (version != k_versionNumber)
105  throw UnsupportedVersionException("SparseField version not supported: " +
106  lexical_cast<std::string>(version));
107 
108  if (!readAttribute(layerGroup, k_extentsStr, 6, extents.min.x))
109  throw MissingAttributeException("Couldn't find attribute: " +
110  k_extentsStr);
111 
112  if (!readAttribute(layerGroup, k_dataWindowStr, 6, dataW.min.x))
113  throw MissingAttributeException("Couldn't find attribute: " +
115 
116  if (!readAttribute(layerGroup, k_componentsStr, 1, components))
117  throw MissingAttributeException("Couldn't find attribute: " +
119 
120  // Read block order
121  if (!readAttribute(layerGroup, k_blockOrderStr, 1, blockOrder))
122  throw MissingAttributeException("Couldn't find attribute: " +
124 
125  // Read number of blocks total
126  if (!readAttribute(layerGroup, k_numBlocksStr, 1, numBlocks))
127  throw MissingAttributeException("Couldn't find attribute: " +
129 
130  // Read block resolution in each dimension
131  if (!readAttribute(layerGroup, k_blockResStr, 3, blockRes.x))
132  throw MissingAttributeException("Couldn't find attribute: " +
133  k_blockResStr);
134 
135  // ... Check that it matches the # reported by summing the active blocks
136 
137  int numCalculatedBlocks = blockRes.x * blockRes.y * blockRes.z;
138  if (numCalculatedBlocks != numBlocks)
139  throw FileIntegrityException("Incorrect block count in SparseFieldIO::read");
140 
141  // Call the appropriate read function based on the data type ---
142 
143  FieldBase::Ptr result;
144 
145  int occupiedBlocks;
146  if (!readAttribute(layerGroup, k_numOccupiedBlocksStr, 1, occupiedBlocks))
147  throw MissingAttributeException("Couldn't find attribute: " +
149 
150  // Check the data type ---
151 
152  int bits;
153  if (!readAttribute(layerGroup, k_bitsPerComponentStr, 1, bits))
154  throw MissingAttributeException("Couldn't find attribute: " +
156 
157  bool isHalf = false;
158  bool isFloat = false;
159  bool isDouble = false;
160 
161  switch (bits) {
162  case 16:
163  isHalf = true;
164  break;
165  case 64:
166  isDouble = true;
167  break;
168  case 32:
169  default:
170  isFloat = true;
171  }
172 
173  // Finally, read the data ---
174 
175  if (components == 1) {
176  if (isHalf && typeEnum == DataTypeHalf) {
178  field->setSize(extents, dataW);
179  field->setBlockOrder(blockOrder);
180  readData<half>(layerGroup, numBlocks, filename, layerPath, field);
181  result = field;
182  } else if (isFloat && typeEnum == DataTypeFloat) {
184  field->setSize(extents, dataW);
185  field->setBlockOrder(blockOrder);
186  readData<float>(layerGroup, numBlocks, filename, layerPath, field);
187  result = field;
188  } else if (isDouble && typeEnum == DataTypeDouble) {
190  field->setSize(extents, dataW);
191  field->setBlockOrder(blockOrder);
192  readData<double>(layerGroup, numBlocks, filename, layerPath, field);
193  result = field;
194  }
195  } else if (components == 3) {
196  if (isHalf && typeEnum == DataTypeVecHalf) {
198  field->setSize(extents, dataW);
199  field->setBlockOrder(blockOrder);
200  readData<V3h>(layerGroup, numBlocks, filename, layerPath, field);
201  result = field;
202  } else if (isFloat && typeEnum == DataTypeVecFloat) {
204  field->setSize(extents, dataW);
205  field->setBlockOrder(blockOrder);
206  readData<V3f>(layerGroup, numBlocks, filename, layerPath, field);
207  result = field;
208  } else if (isDouble && typeEnum == DataTypeVecDouble) {
210  field->setSize(extents, dataW);
211  field->setBlockOrder(blockOrder);
212  readData<V3d>(layerGroup, numBlocks, filename, layerPath, field);
213  result = field;
214  }
215  }
216 
217  return result;
218 }
Imath::Box3i Box3i
Definition: SpiMathLib.h:77
static const std::string k_versionAttrName
static const std::string k_dataWindowStr
boost::intrusive_ptr< FieldBase > Ptr
Definition: Field.h:97
static const std::string k_numOccupiedBlocksStr
static const std::string k_extentsStr
void print(Severity severity, const std::string &message)
Sends the string to the assigned output, prefixing the message with the severity. ...
Definition: Log.cpp:62
boost::intrusive_ptr< SparseField > Ptr
Definition: SparseField.h:167
static const int k_versionNumber
Imath::V3i V3i
Definition: SpiMathLib.h:71
bool readAttribute(hid_t location, const std::string &attrName, std::string &value)
Reads a string attribute.
static const std::string k_blockOrderStr
static const std::string k_numBlocksStr
static const std::string k_componentsStr
static const std::string k_blockResStr
static const std::string k_bitsPerComponentStr
This Field subclass stores voxel data in block-allocated arrays.
Definition: SparseField.h:160

◆ write()

bool SparseFieldIO::write ( hid_t  layerGroup,
FieldBase::Ptr  field 
)
virtual

Writes the given field to disk.

Returns
true if successful, otherwise false

Implements FieldIO.

Definition at line 223 of file SparseFieldIO.cpp.

References FIELD3D_NAMESPACE_SOURCE_CLOSE, field_dynamic_cast(), Msg::print(), Msg::SevWarning, and Hdf5Util::writeAttribute().

Referenced by create().

224 {
225  if (layerGroup == -1) {
226  Msg::print(Msg::SevWarning, "Bad layerGroup.");
227  return false;
228  }
229 
230  // Add version attribute
231  if (!writeAttribute(layerGroup, k_versionAttrName,
232  1, k_versionNumber)) {
233  Msg::print(Msg::SevWarning, "Error adding version attribute.");
234  return false;
235  }
236 
237  SparseField<half>::Ptr halfField =
239  SparseField<float>::Ptr floatField =
241  SparseField<double>::Ptr doubleField =
243  SparseField<V3h>::Ptr vecHalfField =
245  SparseField<V3f>::Ptr vecFloatField =
247  SparseField<V3d>::Ptr vecDoubleField =
249 
250  bool success = true;
251  if (halfField) {
252  success = writeInternal<half>(layerGroup, halfField);
253  } else if (floatField) {
254  success = writeInternal<float>(layerGroup, floatField);
255  } else if (doubleField) {
256  success = writeInternal<double>(layerGroup, doubleField);
257  } else if (vecHalfField) {
258  success = writeInternal<V3h>(layerGroup, vecHalfField);
259  } else if (vecFloatField) {
260  success = writeInternal<V3f>(layerGroup, vecFloatField);
261  } else if (vecDoubleField) {
262  success = writeInternal<V3d>(layerGroup, vecDoubleField);
263  } else {
264  throw WriteLayerException("SparseFieldIO::write does not support the given "
265  "SparseField template parameter");
266  }
267 
268  return success;
269 }
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:224
static const std::string k_versionAttrName
void print(Severity severity, const std::string &message)
Sends the string to the assigned output, prefixing the message with the severity. ...
Definition: Log.cpp:62
boost::intrusive_ptr< SparseField > Ptr
Definition: SparseField.h:167
static const int k_versionNumber
bool writeAttribute(hid_t location, const std::string &attrName, const std::string &value)
Writes a string attribute.
This Field subclass stores voxel data in block-allocated arrays.
Definition: SparseField.h:160

◆ className()

virtual std::string SparseFieldIO::className ( ) const
inlinevirtual

Returns the class name.

Implements FieldIO.

Definition at line 127 of file SparseFieldIO.h.

References readData(), and writeInternal().

128  { return "SparseField"; }

◆ writeInternal()

template<class Data_T >
bool SparseFieldIO::writeInternal ( hid_t  layerGroup,
typename SparseField< Data_T >::Ptr  field 
)
private

This call writes all the attributes and sets up the data space.

Todo:
Tune the chunk size of the gzip call

Definition at line 172 of file SparseFieldIO.h.

References Hdf5Util::checkHdf5Gzip(), FieldTraits< Data_T >::dataDims(), FieldRes::dataWindow(), FieldRes::extents(), DataTypeTraits< T >::h5bits(), DataTypeTraits< T >::h5type(), Hdf5Util::H5Base::id(), k_bitsPerComponentStr, k_blockOrderStr, k_blockResStr, k_componentsStr, k_dataStr, k_dataWindowStr, k_extentsStr, k_numBlocksStr, k_numOccupiedBlocksStr, SparseField< Data_T >::m_blockOrder, SparseField< Data_T >::m_blockRes, SparseField< Data_T >::m_blocks, Msg::print(), Msg::SevWarning, and Hdf5Util::writeAttribute().

Referenced by className().

174 {
175  using namespace std;
176  using namespace Exc;
177  using namespace Hdf5Util;
178  using namespace Sparse;
179 
180  Box3i ext(field->extents()), dw(field->dataWindow());
181 
182  int components = FieldTraits<Data_T>::dataDims();
183 
184  int valuesPerBlock = (1 << (field->m_blockOrder * 3)) * components;
185 
186  int size[3];
187  size[0] = dw.max.x - dw.min.x + 1;
188  size[1] = dw.max.y - dw.min.y + 1;
189  size[2] = dw.max.z - dw.min.z + 1;
190 
191 
192  hsize_t totalSize[1];
193  totalSize[0] = size[0] * size[1] * size[2] * components;
194 
195  // Add extents attribute ---
196 
197  int extents[6] =
198  { ext.min.x, ext.min.y, ext.min.z, ext.max.x, ext.max.y, ext.max.z };
199 
200  if (!writeAttribute(layerGroup, k_extentsStr, 6, extents[0])) {
201  Msg::print(Msg::SevWarning, "Error adding size attribute.");
202  return false;
203  }
204 
205  // Add data window attribute ---
206 
207  int dataWindow[6] =
208  { dw.min.x, dw.min.y, dw.min.z, dw.max.x, dw.max.y, dw.max.z };
209 
210  if (!writeAttribute(layerGroup, k_dataWindowStr, 6, dataWindow[0])) {
211  Msg::print(Msg::SevWarning, "Error adding size attribute.");
212  return false;
213  }
214 
215  // Add components attribute ---
216 
217  if (!writeAttribute(layerGroup, k_componentsStr, 1, components)) {
218  Msg::print(Msg::SevWarning, "Error adding components attribute.");
219  return false;
220  }
221 
222  // Add block order attribute ---
223 
224  int blockOrder = field->m_blockOrder;
225 
226  if (!writeAttribute(layerGroup, k_blockOrderStr, 1, blockOrder)) {
227  Msg::print(Msg::SevWarning, "Error adding block order attribute.");
228  return false;
229  }
230 
231  // Add number of blocks attribute ---
232 
233  V3i &blockRes = field->m_blockRes;
234  int numBlocks = blockRes.x * blockRes.y * blockRes.z;
235 
236  if (!writeAttribute(layerGroup, k_numBlocksStr, 1, numBlocks)) {
237  Msg::print(Msg::SevWarning, "Error adding number of blocks attribute.");
238  return false;
239  }
240 
241  // Add block resolution in each dimension ---
242 
243  if (!writeAttribute(layerGroup, k_blockResStr, 3, blockRes.x)) {
244  Msg::print(Msg::SevWarning, "Error adding block res attribute.");
245  return false;
246  }
247 
248  // Add the bits per component attribute ---
249 
250  int bits = DataTypeTraits<Data_T>::h5bits();
251  if (!writeAttribute(layerGroup, k_bitsPerComponentStr, 1, bits)) {
252  Msg::print(Msg::SevWarning, "Error adding bits per component attribute.");
253  return false;
254  }
255 
256  // Write the block info data sets ---
257 
258  // ... Write the isAllocated array
259  {
260  vector<char> isAllocated(numBlocks);
261  vector<char>::iterator i = isAllocated.begin();
262  typename vector<SparseBlock<Data_T> >::const_iterator b =
263  field->m_blocks.begin();
264  for (; i != isAllocated.end(); ++i, ++b)
265  *i = static_cast<char>(b->isAllocated);
266  writeSimpleData<char>(layerGroup, "block_is_allocated_data", isAllocated);
267  }
268 
269  // ... Write the emptyValue array
270  {
271  vector<Data_T> emptyValue(numBlocks);
272  typename vector<Data_T>::iterator i = emptyValue.begin();
273  typename vector<SparseBlock<Data_T> >::const_iterator b =
274  field->m_blocks.begin();
275  for (; i != emptyValue.end(); ++i, ++b)
276  *i = static_cast<Data_T>(b->emptyValue);
277  writeSimpleData<Data_T>(layerGroup, "block_empty_value_data", emptyValue);
278  }
279 
280  // Count the number of occupied blocks ---
281  int occupiedBlocks = 0;
282  typename vector<SparseBlock<Data_T> >::iterator b =
283  field->m_blocks.begin();
284  for (; b != field->m_blocks.end(); ++b) {
285  if (b->isAllocated)
286  occupiedBlocks++;
287  }
288  if (!writeAttribute(layerGroup, k_numOccupiedBlocksStr, 1, occupiedBlocks)) {
289  throw WriteAttributeException("Couldn't add attribute " +
291  }
292 
293  if (occupiedBlocks > 0) {
294 
295  // Make the memory data space
296  hsize_t memDims[1];
297  memDims[0] = valuesPerBlock;
298  H5ScopedScreate memDataSpace(H5S_SIMPLE);
299  H5Sset_extent_simple(memDataSpace.id(), 1, memDims, NULL);
300 
301  // Make the file data space
302  hsize_t fileDims[2];
303  fileDims[0] = occupiedBlocks;
304  fileDims[1] = valuesPerBlock;
305  H5ScopedScreate fileDataSpace(H5S_SIMPLE);
306  H5Sset_extent_simple(fileDataSpace.id(), 2, fileDims, NULL);
307 
308  // Set up gzip property list
309  bool gzipAvailable = checkHdf5Gzip();
310  hid_t dcpl = H5Pcreate(H5P_DATASET_CREATE);
311  hsize_t chunkSize[2];
312  chunkSize[0] = 1;
313  chunkSize[1] = valuesPerBlock;
314  if (gzipAvailable) {
315  herr_t status = H5Pset_deflate(dcpl, 9);
316  if (status < 0) {
317  return false;
318  }
319  status = H5Pset_chunk(dcpl, 2, chunkSize);
320  if (status < 0) {
321  return false;
322  }
323  }
324 
325  // Add the data set
326  H5ScopedDcreate dataSet(layerGroup, k_dataStr,
328  fileDataSpace.id(),
329  H5P_DEFAULT, dcpl, H5P_DEFAULT);
330  if (dataSet.id() < 0)
331  throw CreateDataSetException("Couldn't create data set in "
332  "SparseFieldIO::writeInternal");
333 
334  // For each allocated block ---
335 
336  int nextBlockIdx = 0;
337  hsize_t offset[2];
338  hsize_t count[2];
339  herr_t status;
340 
341  for (b = field->m_blocks.begin(); b != field->m_blocks.end(); ++b) {
342  if (b->isAllocated) {
343  offset[0] = nextBlockIdx; // Index of next block
344  offset[1] = 0; // Index of first data in block. Always 0
345  count[0] = 1; // Number of columns to read. Always 1
346  count[1] = valuesPerBlock; // Number of values in one column
347  status = H5Sselect_hyperslab(fileDataSpace.id(), H5S_SELECT_SET,
348  offset, NULL, count, NULL);
349  if (status < 0) {
350  throw WriteHyperSlabException(
351  "Couldn't select slab " +
352  boost::lexical_cast<std::string>(nextBlockIdx));
353  }
354  Data_T *data = &b->data[0];
355  status = H5Dwrite(dataSet.id(), DataTypeTraits<Data_T>::h5type(),
356  memDataSpace.id(),
357  fileDataSpace.id(), H5P_DEFAULT, data);
358  if (status < 0) {
359  throw WriteHyperSlabException(
360  "Couldn't write slab " +
361  boost::lexical_cast<std::string>(nextBlockIdx));
362  }
363  // Increment nextBlockIdx
364  nextBlockIdx++;
365  }
366  }
367 
368  } // if occupiedBlocks > 0
369 
370  return true;
371 
372 }
Imath::Box3i Box3i
Definition: SpiMathLib.h:77
Contains utility functions and classes for Hdf5 files.
Definition: Hdf5Util.h:76
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_dataStr
static const std::string k_dataWindowStr
static const std::string k_numOccupiedBlocksStr
static const std::string k_extentsStr
void print(Severity severity, const std::string &message)
Sends the string to the assigned output, prefixing the message with the severity. ...
Definition: Log.cpp:62
Imath::V3i V3i
Definition: SpiMathLib.h:71
bool checkHdf5Gzip()
Checks whether gzip is available in the current hdf5 library.
Definition: Hdf5Util.cpp:680
static const std::string k_blockOrderStr
static hid_t h5type()
Namespace for sparse field specifics.
Definition: SparseField.h:79
static const std::string k_numBlocksStr
static const std::string k_componentsStr
static const std::string k_blockResStr
bool writeAttribute(hid_t location, const std::string &attrName, const std::string &value)
Writes a string attribute.
static int h5bits()
Scoped object - creates a dataspace on creation and closes it on destruction.
Definition: Hdf5Util.h:213
static const std::string k_bitsPerComponentStr
Scoped object - creates a dataset on creation and closes it on destruction.
Definition: Hdf5Util.h:240

◆ readData()

template<class Data_T >
bool SparseFieldIO::readData ( hid_t  location,
int  numBlocks,
const std::string &  filename,
const std::string &  layerPath,
typename SparseField< Data_T >::Ptr  result 
)
private

Reads the data that is dependent on the data type on disk.

Definition at line 377 of file SparseFieldIO.h.

References SparseField< Data_T >::addReference(), FieldTraits< Data_T >::dataDims(), SparseFileManager::doLimitMemUse(), FIELD3D_NAMESPACE_HEADER_CLOSE, k_numOccupiedBlocksStr, SparseField< Data_T >::m_blockOrder, SparseField< Data_T >::m_blocks, Hdf5Util::readAttribute(), SparseDataReader< Data_T >::readBlockList(), SparseField< Data_T >::setupReferenceBlocks(), and SparseFileManager::singleton().

Referenced by className().

382 {
383  using namespace std;
384  using namespace Exc;
385  using namespace Hdf5Util;
386  using namespace Sparse;
387 
388  int occupiedBlocks;
389 
390  bool dynamicLoading = SparseFileManager::singleton().doLimitMemUse();
391 
392  int components = FieldTraits<Data_T>::dataDims();
393  int valuesPerBlock = (1 << (result->m_blockOrder * 3)) * components;
394 
395  // Read the number of occupied blocks ---
396 
397  if (!readAttribute(location, k_numOccupiedBlocksStr, 1, occupiedBlocks))
398  throw MissingAttributeException("Couldn't find attribute: " +
400 
401  // Set up the dynamic read info ---
402 
403  if (dynamicLoading) {
404  // Set up the field reference
405  result->addReference(filename, layerPath,
406  valuesPerBlock,
407  occupiedBlocks);
408  }
409 
410  // Read the block info data sets ---
411 
412  // ... Read the isAllocated array
413 
414  {
415  vector<char> isAllocated(numBlocks);
416  vector<char>::iterator i = isAllocated.begin();
417  readSimpleData<char>(location, "block_is_allocated_data", isAllocated);
418  typename vector<SparseBlock<Data_T> >::iterator b =
419  result->m_blocks.begin();
420  typename vector<SparseBlock<Data_T> >::iterator bend =
421  result->m_blocks.end();
422  // We're assuming there are as many blocks in isAllocated as in the field.
423  for (; b != bend; ++b, ++i) {
424  b->isAllocated = static_cast<bool>(*i);
425  if (*i && !dynamicLoading) {
426  b->data.resize(valuesPerBlock);
427  }
428  }
429  }
430 
431  // ... Read the emptyValue array ---
432 
433  {
434  vector<Data_T> emptyValue(numBlocks);
435  readSimpleData<Data_T>(location, "block_empty_value_data", emptyValue);
436  typename vector<SparseBlock<Data_T> >::iterator b =
437  result->m_blocks.begin();
438  typename vector<SparseBlock<Data_T> >::iterator bend =
439  result->m_blocks.end();
440  typename vector<Data_T>::iterator i = emptyValue.begin();
441  // We're assuming there are as many blocks in isAllocated as in the field.
442  for (; b != bend; ++b, ++i) {
443  b->emptyValue = *i;
444  }
445  }
446 
447  // Read the data ---
448 
449  if (occupiedBlocks > 0) {
450 
451  if (dynamicLoading) {
452 
453  result->setupReferenceBlocks();
454 
455  } else {
456 
457  typename vector<SparseBlock<Data_T> >::iterator b =
458  result->m_blocks.begin();
459  typename vector<SparseBlock<Data_T> >::iterator bend =
460  result->m_blocks.end();
461 
462  SparseDataReader<Data_T> reader(location, valuesPerBlock, occupiedBlocks);
463 
464  // We'll read at most 50meg at a time
465  static const long maxMemPerPass = 50*1024*1024;
466 
467  for (int nextBlockIdx = 0;;) {
468 
469  long mem = 0;
470  std::vector<Data_T*> memoryList;
471 
472  for (; b != bend && mem < maxMemPerPass; ++b) {
473  if (b->isAllocated) {
474  mem += sizeof(Data_T)*valuesPerBlock;
475  memoryList.push_back(&b->data[0]);
476  }
477  }
478 
479  // all done.
480  if (!memoryList.size()) {
481  break;
482  }
483 
484  reader.readBlockList(nextBlockIdx, memoryList);
485  nextBlockIdx += memoryList.size();
486  }
487 
488  }
489 
490  } // if occupiedBlocks > 0
491 
492  return true;
493 
494 }
bool doLimitMemUse() const
Returns whether to limit memory usage and do dynamic loading for sparse fields.
Definition: SparseFile.cpp:80
Contains utility functions and classes for Hdf5 files.
Definition: Hdf5Util.h:76
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_numOccupiedBlocksStr
This class gets used by SparseFieldIO and SparseFileManager to read the block data. On creation it will open the data set and not close it until the object is destroyed.
bool readAttribute(hid_t location, const std::string &attrName, std::string &value)
Reads a string attribute.
Namespace for sparse field specifics.
Definition: SparseField.h:79
static SparseFileManager & singleton()
Returns a reference to the singleton instance.
Definition: SparseFile.cpp:63

Member Data Documentation

◆ DEFINE_FIELD_RTTI_CONCRETE_CLASS

SparseFieldIO::DEFINE_FIELD_RTTI_CONCRETE_CLASS

Definition at line 91 of file SparseFieldIO.h.

◆ k_versionNumber

const int SparseFieldIO::k_versionNumber
staticprivate

Definition at line 148 of file SparseFieldIO.h.

◆ k_versionAttrName

const std::string SparseFieldIO::k_versionAttrName
staticprivate

Definition at line 149 of file SparseFieldIO.h.

◆ k_extentsStr

const std::string SparseFieldIO::k_extentsStr
staticprivate

Definition at line 150 of file SparseFieldIO.h.

Referenced by writeInternal().

◆ k_dataWindowStr

const std::string SparseFieldIO::k_dataWindowStr
staticprivate

Definition at line 151 of file SparseFieldIO.h.

Referenced by writeInternal().

◆ k_componentsStr

const std::string SparseFieldIO::k_componentsStr
staticprivate

Definition at line 152 of file SparseFieldIO.h.

Referenced by writeInternal().

◆ k_blockOrderStr

const std::string SparseFieldIO::k_blockOrderStr
staticprivate

Definition at line 153 of file SparseFieldIO.h.

Referenced by writeInternal().

◆ k_numBlocksStr

const std::string SparseFieldIO::k_numBlocksStr
staticprivate

Definition at line 154 of file SparseFieldIO.h.

Referenced by writeInternal().

◆ k_blockResStr

const std::string SparseFieldIO::k_blockResStr
staticprivate

Definition at line 155 of file SparseFieldIO.h.

Referenced by writeInternal().

◆ k_bitsPerComponentStr

const std::string SparseFieldIO::k_bitsPerComponentStr
staticprivate

Definition at line 156 of file SparseFieldIO.h.

Referenced by writeInternal().

◆ k_numOccupiedBlocksStr

const std::string SparseFieldIO::k_numOccupiedBlocksStr
staticprivate

Definition at line 157 of file SparseFieldIO.h.

Referenced by readData(), and writeInternal().

◆ k_dataStr

const std::string SparseFieldIO::k_dataStr
staticprivate

Definition at line 158 of file SparseFieldIO.h.

Referenced by writeInternal().


The documentation for this class was generated from the following files: