Field3D
DenseFieldIO Class Reference

#include <DenseFieldIO.h>

Inheritance diagram for DenseFieldIO:
FieldIO RefBase

Public Types

typedef DenseFieldIO class_type
 
typedef boost::intrusive_ptr
< DenseFieldIO
Ptr
 
- Public Types inherited from FieldIO
typedef FieldIO class_type
 
typedef boost::intrusive_ptr
< FieldIO
Ptr
 
- Public Types inherited from RefBase
typedef boost::intrusive_ptr
< RefBase
Ptr
 

Public Member Functions

virtual std::string className () const
 Returns the class name.
 
 DenseFieldIO ()
 Ctor.
 
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. Calls out to readData() for template-specific work.
 
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 been determined.
 
virtual ~DenseFieldIO ()
 Dtor.
 
- Public Member Functions inherited from FieldIO
 FieldIO ()
 Ctor.
 
virtual ~FieldIO ()
 Dtor.
 
- Public Member Functions inherited from RefBase
void ref () const
 Used by boost::intrusive_pointer.
 
size_t refcnt ()
 Used by boost::intrusive_pointer.
 
void unref () const
 Used by boost::intrusive_pointer.
 
 RefBase ()
 
 RefBase (const RefBase &)
 Copy constructor.
 
RefBaseoperator= (const RefBase &)
 Assignment operator.
 
virtual ~RefBase ()
 Destructor.
 
virtual bool checkRTTI (const char *typenameStr)=0
 This function is only implemented by concrete classes and triggers the actual RTTI check through matchRTTI();.
 
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.
 

Static Public Member Functions

static const char * classType ()
 
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.
 

Private Member Functions

template<class Data_T >
DenseField< Data_T >::Ptr readData (hid_t dataSet, const Box3i &extents, const Box3i &dataW)
 This call performs the actual reading of data from disk.
 
template<class Data_T >
bool writeData (hid_t dataSet, typename DenseField< Data_T >::Ptr field, Data_T dummy)
 This call performs the actual writing of data to disk.
 
template<class Data_T >
bool writeInternal (hid_t layerGroup, typename DenseField< Data_T >::Ptr field)
 This call writes all the attributes and sets up the data space.
 

Static Private Attributes

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_versionAttrName
 
static const int k_versionNumber
 

Detailed Description

Handles IO for a DenseField object

Definition at line 78 of file DenseFieldIO.h.

Member Typedef Documentation

typedef boost::intrusive_ptr<DenseFieldIO> DenseFieldIO::Ptr

Definition at line 85 of file DenseFieldIO.h.

Definition at line 89 of file DenseFieldIO.h.

typedef FieldIO DenseFieldIO::base
private

Convenience typedef for referring to base class.

Definition at line 160 of file DenseFieldIO.h.

Constructor & Destructor Documentation

DenseFieldIO::DenseFieldIO ( )
inline

Ctor.

Definition at line 100 of file DenseFieldIO.h.

: FieldIO()
{ }
virtual DenseFieldIO::~DenseFieldIO ( )
inlinevirtual

Dtor.

Definition at line 105 of file DenseFieldIO.h.

{ /* Empty */ }

Member Function Documentation

static const char* DenseFieldIO::classType ( )
inlinestatic

Definition at line 92 of file DenseFieldIO.h.

{
return "DenseFieldIO";
}
static FieldIO::Ptr DenseFieldIO::create ( )
inlinestatic

Definition at line 108 of file DenseFieldIO.h.

Referenced by initIO().

{ return Ptr(new DenseFieldIO); }
FieldBase::Ptr DenseFieldIO::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 DenseField object from it. Calls out to readData() for template-specific work.

Returns
Null if no object was read

Implements FieldIO.

Definition at line 76 of file DenseFieldIO.cpp.

References DataTypeDouble, DataTypeFloat, DataTypeHalf, DataTypeVecDouble, DataTypeVecFloat, DataTypeVecHalf, Hdf5Util::H5Base::id(), and Hdf5Util::readAttribute().

{
Box3i extents, dataW;
int components;
hsize_t dims[1];
if (layerGroup == -1)
throw BadHdf5IdException("Bad layer group in DenseFieldIO::read");
int version;
if (!readAttribute(layerGroup, k_versionAttrName, 1, version))
throw MissingAttributeException("Couldn't find attribute " +
if (version != k_versionNumber)
throw UnsupportedVersionException("DenseField version not supported: " +
lexical_cast<std::string>(version));
if (!readAttribute(layerGroup, k_extentsStr, 6, extents.min.x))
throw MissingAttributeException("Couldn't find attribute " +
if (!readAttribute(layerGroup, k_dataWindowStr, 6, dataW.min.x))
throw MissingAttributeException("Couldn't find attribute " +
if (!readAttribute(layerGroup, k_componentsStr, 1, components))
throw MissingAttributeException("Couldn't find attribute " +
H5ScopedDopen dataSet(layerGroup, k_dataStr, H5P_DEFAULT);
if (dataSet.id() < 0)
throw OpenDataSetException("Couldn't open data set: " + k_dataStr);
H5ScopedDget_space dataSpace(dataSet.id());
H5ScopedDget_type dataType(dataSet.id());
H5Sget_simple_extent_dims(dataSpace.id(), dims, NULL);
if (dataSpace.id() < 0)
throw GetDataSpaceException("Couldn't get data space");
if (dataType.id() < 0)
throw GetDataTypeException("Couldn't get data type");
// Double-check that the sizes match ---
V3i size(dataW.size() + V3i(1));
int calculatedTotal = size.x * size.y * size.z;
int reportedSize = dims[0] / components;
if (calculatedTotal != reportedSize)
throw FileIntegrityException("Data size doesn't match number of voxels");
// Build a DenseField to store everything in
// Read the data ---
bool isHalf, isFloat, isDouble;
isHalf = H5Tequal(dataType, H5T_NATIVE_SHORT);
isFloat = H5Tequal(dataType, H5T_NATIVE_FLOAT);
isDouble = H5Tequal(dataType, H5T_NATIVE_DOUBLE);
if (isHalf && components == 1 && typeEnum == DataTypeHalf)
result = readData<half>(dataSet.id(), extents, dataW);
if (isFloat && components == 1 && typeEnum == DataTypeFloat)
result = readData<float>(dataSet.id(), extents, dataW);
if (isDouble && components == 1 && typeEnum == DataTypeDouble)
result = readData<double>(dataSet.id(), extents, dataW);
if (isHalf && components == 3 && typeEnum == DataTypeVecHalf)
result = readData<V3h>(dataSet.id(), extents, dataW);
if (isFloat && components == 3 && typeEnum == DataTypeVecFloat)
result = readData<V3f>(dataSet.id(), extents, dataW);
if (isDouble && components == 3 && typeEnum == DataTypeVecDouble)
result = readData<V3d>(dataSet.id(), extents, dataW);
return result;
}
bool DenseFieldIO::write ( hid_t  layerGroup,
FieldBase::Ptr  field 
)
virtual

Writes the given field to disk. This function calls out to writeInternal once the template type has been determined.

Returns
true if successful, otherwise false

Implements FieldIO.

Definition at line 161 of file DenseFieldIO.cpp.

References field_dynamic_cast(), and Hdf5Util::writeAttribute().

{
if (layerGroup == -1)
throw BadHdf5IdException("Bad layer group in DenseFieldIO::write");
// Add version attribute
if (!writeAttribute(layerGroup, k_versionAttrName,
throw WriteAttributeException("Couldn't write attribute " +
DenseField<half>::Ptr halfField =
DenseField<float>::Ptr floatField =
DenseField<double>::Ptr doubleField =
DenseField<V3h>::Ptr vecHalfField =
DenseField<V3f>::Ptr vecFloatField =
DenseField<V3d>::Ptr vecDoubleField =
bool success = true;
if (floatField) {
success = writeInternal<float>(layerGroup, floatField);
}
else if (halfField) {
success = writeInternal<half>(layerGroup, halfField);
}
else if (doubleField) {
success = writeInternal<double>(layerGroup, doubleField);
}
else if (vecFloatField) {
success = writeInternal<V3f>(layerGroup, vecFloatField);
}
else if (vecHalfField) {
success = writeInternal<V3h>(layerGroup, vecHalfField);
}
else if (vecDoubleField) {
success = writeInternal<V3d>(layerGroup, vecDoubleField);
}
else {
throw WriteLayerException("DenseFieldIO does not support the given "
"DenseField template parameter");
}
return success;
}
virtual std::string DenseFieldIO::className ( ) const
inlinevirtual

Returns the class name.

Implements FieldIO.

Definition at line 126 of file DenseFieldIO.h.

{ return "DenseField"; }
template<class Data_T >
bool DenseFieldIO::writeInternal ( hid_t  layerGroup,
typename DenseField< 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 170 of file DenseFieldIO.h.

References Hdf5Util::checkHdf5Gzip(), FieldTraits< Data_T >::dataDims(), FieldRes::dataWindow(), FieldRes::extents(), Hdf5Util::H5Base::id(), DenseField< Data_T >::internalMemSize(), k_componentsStr, k_dataStr, k_dataWindowStr, k_extentsStr, and Hdf5Util::writeAttribute().

{
using namespace Exc;
using namespace Hdf5Util;
const V3i& memSize = field->internalMemSize();
int size[3];
size[0] = memSize.x;
size[1] = memSize.y;
size[2] = memSize.z;
int components = FieldTraits<Data_T>::dataDims();
hsize_t totalSize[1];
totalSize[0] = size[0] * size[1] * size[2] * components;
// Make sure chunk size isn't too big.
hsize_t preferredChunkSize = 4096 * 16;
const hsize_t chunkSize = std::min(preferredChunkSize, totalSize[0] / 2);
Box3i ext(field->extents()), dw(field->dataWindow());
// Add extents attribute ---
int extents[6] =
{ ext.min.x, ext.min.y, ext.min.z, ext.max.x, ext.max.y, ext.max.z };
if (!writeAttribute(layerGroup, k_extentsStr, 6, extents[0])) {
throw WriteAttributeException("Couldn't write attribute " + k_extentsStr);
}
// Add data window attribute ---
int dataWindow[6] =
{ dw.min.x, dw.min.y, dw.min.z, dw.max.x, dw.max.y, dw.max.z };
if (!writeAttribute(layerGroup, k_dataWindowStr, 6, dataWindow[0])) {
throw WriteAttributeException("Couldn't write attribute " + k_dataWindowStr);
}
// Add components attribute ---
if (!writeAttribute(layerGroup, k_componentsStr, 1, components)) {
throw WriteAttributeException("Couldn't write attribute " + k_componentsStr);
}
// Add data to file ---
H5ScopedScreate dataSpace(H5S_SIMPLE);
if (dataSpace.id() < 0) {
throw CreateDataSpaceException("Couldn't create data space in "
"DenseFieldIO::writeInternal");
}
// Create a "simple" data structure ---
H5Sset_extent_simple(dataSpace.id(), 1, totalSize, NULL);
// Set up gzip property list
bool gzipAvailable = checkHdf5Gzip();
hid_t dcpl = H5Pcreate(H5P_DATASET_CREATE);
if (gzipAvailable) {
herr_t status = H5Pset_deflate(dcpl, 9);
if (status < 0) {
return false;
}
status = H5Pset_chunk(dcpl, 1, &chunkSize);
if (status < 0) {
return false;
}
}
H5ScopedDcreate dataSet(layerGroup, k_dataStr,
dataSpace.id(),
H5P_DEFAULT, dcpl, H5P_DEFAULT);
if (dataSet.id() < 0) {
throw CreateDataSetException("Couldn't create data set in "
"DenseFieldIO::writeInternal");
}
// Call out to the templated function, it will figure out how to get
// the data into the file in the appropriate fashion.
if (!writeData<Data_T>(dataSet.id(), field, Data_T(0.0f))) {
throw WriteLayerException("Error writing layer");
}
return true;
}
template<class Data_T >
bool DenseFieldIO::writeData ( hid_t  dataSet,
typename DenseField< Data_T >::Ptr  field,
Data_T  dummy 
)
private

This call performs the actual writing of data to disk.

Definition at line 266 of file DenseFieldIO.h.

References DenseField< Data_T >::begin().

{
using namespace Hdf5Util;
hid_t err = H5Dwrite(dataSet,
H5S_ALL, H5S_ALL,
H5P_DEFAULT, &(*field->begin()));
if (err < 0) {
throw Exc::WriteLayerException("Error writing layer in "
"DenseFieldIO::writeData");
}
return true;
}
template<class Data_T >
DenseField< Data_T >::Ptr DenseFieldIO::readData ( hid_t  dataSet,
const Box3i extents,
const Box3i dataW 
)
private

This call performs the actual reading of data from disk.

Definition at line 289 of file DenseFieldIO.h.

References DenseField< Data_T >::begin(), DataTypeTraits< T >::name(), and ResizableField< Data_T >::setSize().

{
field->setSize(extents, dataW);
if (H5Dread(dataSet, DataTypeTraits<Data_T>::h5type(),
H5S_ALL, H5S_ALL, H5P_DEFAULT, &(*field->begin())) < 0)
{
std::string typeName = "DenseField<" +
throw Exc::Hdf5DataReadException("Couldn't read " + typeName + " data");
}
return field;
}

Member Data Documentation

DenseFieldIO::DEFINE_FIELD_RTTI_CONCRETE_CLASS

Definition at line 90 of file DenseFieldIO.h.

const int DenseFieldIO::k_versionNumber
staticprivate

Definition at line 150 of file DenseFieldIO.h.

const std::string DenseFieldIO::k_versionAttrName
staticprivate

Definition at line 151 of file DenseFieldIO.h.

const std::string DenseFieldIO::k_extentsStr
staticprivate

Definition at line 152 of file DenseFieldIO.h.

Referenced by writeInternal().

const std::string DenseFieldIO::k_dataWindowStr
staticprivate

Definition at line 153 of file DenseFieldIO.h.

Referenced by writeInternal().

const std::string DenseFieldIO::k_componentsStr
staticprivate

Definition at line 154 of file DenseFieldIO.h.

Referenced by writeInternal().

const std::string DenseFieldIO::k_dataStr
staticprivate

Definition at line 155 of file DenseFieldIO.h.

Referenced by writeInternal().


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