Hdf5Util.cpp
Go to the documentation of this file.
//----------------------------------------------------------------------------//
/*
* Copyright (c) 2009 Sony Pictures Imageworks Inc
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the
* distribution. Neither the name of Sony Pictures Imageworks nor the
* names of its contributors may be used to endorse or promote
* products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
//----------------------------------------------------------------------------//
//----------------------------------------------------------------------------//
#include "Hdf5Util.h"
#include <iostream>
#include <vector>
#include <boost/scoped_array.hpp>
//----------------------------------------------------------------------------//
using namespace std;
//----------------------------------------------------------------------------//
FIELD3D_NAMESPACE_OPEN
using namespace Exc;
//----------------------------------------------------------------------------//
// Implementations
//----------------------------------------------------------------------------//
boost::recursive_mutex g_hdf5Mutex;
//----------------------------------------------------------------------------//
namespace Hdf5Util {
//----------------------------------------------------------------------------//
// Implementations
//----------------------------------------------------------------------------//
bool
readAttribute(hid_t location, const string& attrName, string& value)
{
GlobalLock lock(g_hdf5Mutex);
H5T_class_t typeClass;
H5A_info_t attrInfo;
hsize_t strLen;
if (H5Aexists(location, attrName.c_str()) < 1)
throw MissingAttributeException("Couldn't find attribute " + attrName);
H5ScopedAopen attr(location, attrName.c_str(), H5P_DEFAULT);
H5ScopedAget_space attrSpace(attr);
H5ScopedAget_type attrType(attr);
if (H5Aget_info(attr, &attrInfo) < 0) {
throw MissingAttributeException("Couldn't get attribute info " + attrName);
} else {
strLen = attrInfo.data_size;
}
typeClass = H5Tget_class(attrType);
if (typeClass != H5T_STRING)
throw MissingAttributeException("Bad attribute type class for " + attrName);
H5ScopedTget_native_type nativeType(attrType, H5T_DIR_ASCEND);
std::vector<char> tempString(strLen + 1);
if (H5Aread(attr, nativeType, &tempString[0]) < 0)
throw MissingAttributeException("Couldn't read attribute " + attrName);
value = string(&tempString[0]);
return true;
}
//----------------------------------------------------------------------------//
bool
readAttribute(hid_t location, const string& attrName,
unsigned int attrSize, int &value)
{
GlobalLock lock(g_hdf5Mutex);
H5T_class_t typeClass;
if (H5Aexists(location, attrName.c_str()) < 1)
throw MissingAttributeException("Couldn't find attribute " + attrName);
H5ScopedAopen attr(location, attrName.c_str(), H5P_DEFAULT);
H5ScopedAget_space attrSpace(attr);
H5ScopedAget_type attrType(attr);
if (H5Sget_simple_extent_ndims(attrSpace) != 1)
throw MissingAttributeException("Bad attribute rank for attribute " +
attrName);
hsize_t dims[1];
H5Sget_simple_extent_dims(attrSpace, dims, NULL);
if (dims[0] != attrSize)
throw MissingAttributeException("Invalid attribute size for attribute " +
attrName);
typeClass = H5Tget_class(attrType);
if (typeClass != H5T_INTEGER)
throw MissingAttributeException("Bad attribute type class for " +
attrName);
H5ScopedTget_native_type nativeType(attrType, H5T_DIR_ASCEND);
if (H5Aread(attr, nativeType, &value) < 0)
throw MissingAttributeException("Couldn't read attribute " + attrName);
return true;
}
//----------------------------------------------------------------------------//
bool
readAttribute(hid_t location, const string& attrName,
unsigned int attrSize, float &value)
{
GlobalLock lock(g_hdf5Mutex);
H5T_class_t typeClass;
if (H5Aexists(location, attrName.c_str()) < 1)
throw MissingAttributeException("Couldn't find attribute " + attrName);
H5ScopedAopen attr(location, attrName.c_str(), H5P_DEFAULT);
H5ScopedAget_space attrSpace(attr);
H5ScopedAget_type attrType(attr);
if (H5Sget_simple_extent_ndims(attrSpace) != 1)
throw MissingAttributeException("Bad attribute rank for attribute " +
attrName);
hsize_t dims[1];
H5Sget_simple_extent_dims(attrSpace, dims, NULL);
if (dims[0] != attrSize)
throw MissingAttributeException("Invalid attribute size for attribute " +
attrName);
typeClass = H5Tget_class(attrType);
if (typeClass != H5T_FLOAT)
throw MissingAttributeException("Bad attribute type class for " +
attrName);
H5ScopedTget_native_type nativeType(attrType, H5T_DIR_ASCEND);
if (H5Aread(attr, nativeType, &value) < 0)
throw MissingAttributeException("Couldn't read attribute " + attrName);
return true;
}
//----------------------------------------------------------------------------//
bool
readAttribute(hid_t location, const string& attrName,
unsigned int attrSize, double &value)
{
GlobalLock lock(g_hdf5Mutex);
H5T_class_t typeClass;
if (H5Aexists(location, attrName.c_str()) < 0)
throw MissingAttributeException("Couldn't find attribute " + attrName);
H5ScopedAopen attr(location, attrName.c_str(), H5P_DEFAULT);
H5ScopedAget_space attrSpace(attr);
H5ScopedAget_type attrType(attr);
if (H5Sget_simple_extent_ndims(attrSpace) != 1)
throw MissingAttributeException("Bad attribute rank for attribute " +
attrName);
hsize_t dims[1];
H5Sget_simple_extent_dims(attrSpace, dims, NULL);
if (dims[0] != attrSize)
throw MissingAttributeException("Invalid attribute size for attribute " +
attrName);
typeClass = H5Tget_class(attrType);
if (typeClass != H5T_FLOAT)
throw MissingAttributeException("Bad attribute type class for " +
attrName);
H5ScopedTget_native_type nativeType(attrType, H5T_DIR_ASCEND);
if (H5Aread(attr, nativeType, &value) < 0)
throw MissingAttributeException("Couldn't read attribute " + attrName);
return true;
}
//----------------------------------------------------------------------------//
bool
readAttribute(hid_t location, const string& attrName,
std::vector<unsigned int> &attrSize, int &value)
{
GlobalLock lock(g_hdf5Mutex);
H5T_class_t typeClass;
size_t rank = attrSize.size();
if (H5Aexists(location, attrName.c_str()) < 0)
throw MissingAttributeException("Couldn't find attribute " + attrName);
H5ScopedAopen attr(location, attrName.c_str(), H5P_DEFAULT);
H5ScopedAget_space attrSpace(attr);
H5ScopedAget_type attrType(attr);
if (H5Sget_simple_extent_ndims(attrSpace) != (int) rank)
throw MissingAttributeException("Bad attribute rank for attribute " +
attrName);
boost::scoped_array<hsize_t> dims(new hsize_t[rank]);
H5Sget_simple_extent_dims(attrSpace, dims.get(), NULL);
for (size_t i=0; i < rank; i++) {
if (dims[i] != attrSize[i])
throw MissingAttributeException("Invalid attribute size for attribute " +
attrName);
}
typeClass = H5Tget_class(attrType);
if (typeClass != H5T_INTEGER)
throw MissingAttributeException("Bad attribute type class for " +
attrName);
H5ScopedTget_native_type nativeType(attrType, H5T_DIR_ASCEND);
if (H5Aread(attr, nativeType, &value) < 0)
throw MissingAttributeException("Couldn't read attribute " + attrName);
return true;
}
//----------------------------------------------------------------------------//
bool
readAttribute(hid_t location, const string& attrName,
std::vector<unsigned int> &attrSize, float &value)
{
GlobalLock lock(g_hdf5Mutex);
H5T_class_t typeClass;
size_t rank = attrSize.size();
if (H5Aexists(location, attrName.c_str()) < 0)
throw MissingAttributeException("Couldn't find attribute " + attrName);
H5ScopedAopen attr(location, attrName.c_str(), H5P_DEFAULT);
H5ScopedAget_space attrSpace(attr);
H5ScopedAget_type attrType(attr);
if (H5Sget_simple_extent_ndims(attrSpace) != (int) rank)
throw MissingAttributeException("Bad attribute rank for attribute " +
attrName);
boost::scoped_array<hsize_t> dims(new hsize_t[rank]);
H5Sget_simple_extent_dims(attrSpace, dims.get(), NULL);
for (size_t i=0; i < rank; i++) {
if (dims[i] != attrSize[i])
throw MissingAttributeException("Invalid attribute size for attribute " +
attrName);
}
typeClass = H5Tget_class(attrType);
if (typeClass != H5T_FLOAT)
throw MissingAttributeException("Bad attribute type class for " +
attrName);
H5ScopedTget_native_type nativeType(attrType, H5T_DIR_ASCEND);
if (H5Aread(attr, nativeType, &value) < 0)
throw MissingAttributeException("Couldn't read attribute " + attrName);
return true;
}
//----------------------------------------------------------------------------//
bool
readAttribute(hid_t location, const string& attrName,
std::vector<unsigned int> &attrSize, double &value)
{
GlobalLock lock(g_hdf5Mutex);
H5T_class_t typeClass;
size_t rank = attrSize.size();
if (H5Aexists(location, attrName.c_str()) < 0)
throw MissingAttributeException("Couldn't find attribute " + attrName);
H5ScopedAopen attr(location, attrName.c_str(), H5P_DEFAULT);
H5ScopedAget_space attrSpace(attr);
H5ScopedAget_type attrType(attr);
if (H5Sget_simple_extent_ndims(attrSpace) != (int) rank)
throw MissingAttributeException("Bad attribute rank for attribute " +
attrName);
boost::scoped_array<hsize_t> dims(new hsize_t[rank]);
H5Sget_simple_extent_dims(attrSpace, dims.get(), NULL);
for (size_t i=0; i < rank; i++) {
if (dims[i] != attrSize[i])
throw MissingAttributeException("Invalid attribute size for attribute " +
attrName);
}
typeClass = H5Tget_class(attrType);
if (typeClass != H5T_FLOAT)
throw MissingAttributeException("Bad attribute type class for " +
attrName);
H5ScopedTget_native_type nativeType(attrType, H5T_DIR_ASCEND);
if (H5Aread(attr, nativeType, &value) < 0)
throw MissingAttributeException("Couldn't read attribute " + attrName);
return true;
}
//----------------------------------------------------------------------------//
bool
writeAttribute(hid_t location, const string& attrName, const string &value)
{
GlobalLock lock(g_hdf5Mutex);
hid_t attr = -1;
hid_t attrSpace;
hid_t attrType;
bool success = true;
attrSpace = H5Screate(H5S_SCALAR);
if (attrSpace == -1)
success = false;
attrType = H5Tcopy(H5T_C_S1);
if (attrType == -1)
success = false;
if (value.size()) {
// if the string is null the following will return error
// which we don't want.
if (success && H5Tset_size(attrType, value.size()) == -1){
success = false;
}
}
if (success) {
H5Tset_strpad(attrType, H5T_STR_NULLTERM);
attr = H5Acreate(location, attrName.c_str(), attrType, attrSpace,
H5P_DEFAULT, H5P_DEFAULT);
}
if (attr == -1) {
Msg::print(Msg::SevWarning, "Error creating attribute: " + attrName);
success = false;
}
if (success && H5Awrite(attr, attrType, value.c_str()) == -1) {
Msg::print(Msg::SevWarning, "Error writing attribute: " + attrName);
success = false;
}
H5Aclose(attr);
H5Tclose(attrType);
H5Sclose(attrSpace);
return success;
}
//----------------------------------------------------------------------------//
bool
writeAttribute(hid_t location, const string &attrName,
unsigned int attrSize, const int &value)
{
GlobalLock lock(g_hdf5Mutex);
hid_t attr;
hid_t attrSpace;
hsize_t dims[1];
dims[0] = attrSize;
attrSpace = H5Screate(H5S_SIMPLE);
if (attrSpace < 0)
return false;
if (H5Sset_extent_simple(attrSpace, 1, dims, NULL) < 0)
return false;
attr = H5Acreate(location, attrName.c_str(), H5T_NATIVE_INT,
attrSpace, H5P_DEFAULT, H5P_DEFAULT);
if (attr < 0) {
Msg::print(Msg::SevWarning, "Error creating attribute: " + attrName);
H5Aclose(attr);
H5Sclose(attrSpace);
return false;
}
if (H5Awrite(attr, H5T_NATIVE_INT, &value) < 0) {
Msg::print(Msg::SevWarning, "Error writing attribute: " + attrName);
H5Aclose(attr);
H5Sclose(attrSpace);
return false;
}
H5Aclose(attr);
H5Sclose(attrSpace);
return true;
}
//----------------------------------------------------------------------------//
bool
writeAttribute(hid_t location, const string& attrName,
unsigned int attrSize, const float &value)
{
GlobalLock lock(g_hdf5Mutex);
hid_t attr;
hid_t attrSpace;
hsize_t dims[1];
dims[0] = attrSize;
attrSpace = H5Screate(H5S_SIMPLE);
if (attrSpace < 0)
return false;
if (H5Sset_extent_simple(attrSpace, 1, dims, NULL) < 0)
return false;
attr = H5Acreate(location, attrName.c_str(), H5T_NATIVE_FLOAT,
attrSpace, H5P_DEFAULT, H5P_DEFAULT);
if (attr < 0) {
Msg::print(Msg::SevWarning, "Error creating attribute: " + attrName);
H5Aclose(attr);
H5Sclose(attrSpace);
return false;
}
if (H5Awrite(attr, H5T_NATIVE_FLOAT, &value) < 0) {
Msg::print(Msg::SevWarning, "Error writing attribute: " + attrName);
H5Aclose(attr);
H5Sclose(attrSpace);
return false;
}
H5Aclose(attr);
H5Sclose(attrSpace);
return true;
}
//----------------------------------------------------------------------------//
bool
writeAttribute(hid_t location, const string& attrName,
unsigned int attrSize, const double &value)
{
GlobalLock lock(g_hdf5Mutex);
hid_t attr;
hid_t attrSpace;
hsize_t dims[1];
dims[0] = attrSize;
attrSpace = H5Screate(H5S_SIMPLE);
if (attrSpace < 0)
return false;
if (H5Sset_extent_simple(attrSpace, 1, dims, NULL) < 0)
return false;
attr = H5Acreate(location, attrName.c_str(), H5T_NATIVE_DOUBLE,
attrSpace, H5P_DEFAULT, H5P_DEFAULT);
if (attr < 0) {
Msg::print(Msg::SevWarning, "Error creating attribute: " + attrName);
H5Aclose(attr);
H5Sclose(attrSpace);
return false;
}
if (H5Awrite(attr, H5T_NATIVE_DOUBLE, &value) < 0) {
Msg::print(Msg::SevWarning, "Error writing attribute: " + attrName);
H5Aclose(attr);
H5Sclose(attrSpace);
return false;
}
H5Aclose(attr);
H5Sclose(attrSpace);
return true;
}
//----------------------------------------------------------------------------//
bool
writeAttribute(hid_t location, const string& attrName,
std::vector<unsigned int> &attrSize, const int &value)
{
GlobalLock lock(g_hdf5Mutex);
hid_t attr;
hid_t attrSpace;
size_t rank = attrSize.size();
boost::scoped_array<hsize_t> current_dims(new hsize_t[rank]);
boost::scoped_array<hsize_t> max_dims(new hsize_t[rank]);
for (size_t i=0; i < rank; i++)
current_dims[i] = attrSize[i];
for (size_t i=0; i < rank; i++)
max_dims[i] = H5S_UNLIMITED;
attrSpace = H5Screate(H5S_SIMPLE);
if (attrSpace < 0)
return false;
if (H5Sset_extent_simple(attrSpace, (int)rank,
current_dims.get(), max_dims.get()) < 0) {
return false;
}
attr = H5Acreate(location, attrName.c_str(), H5T_NATIVE_INT,
attrSpace, H5P_DEFAULT, H5P_DEFAULT);
if (attr < 0) {
Msg::print(Msg::SevWarning, "Error creating attribute: " + attrName);
H5Aclose(attr);
H5Sclose(attrSpace);
return false;
}
if (H5Awrite(attr, H5T_NATIVE_INT, &value) < 0) {
Msg::print(Msg::SevWarning, "Error writing attribute: " + attrName);
H5Aclose(attr);
H5Sclose(attrSpace);
return false;
}
H5Aclose(attr);
H5Sclose(attrSpace);
return true;
}
//----------------------------------------------------------------------------//
bool
writeAttribute(hid_t location, const string& attrName,
std::vector<unsigned int> &attrSize, const float &value)
{
GlobalLock lock(g_hdf5Mutex);
hid_t attr;
hid_t attrSpace;
size_t rank = attrSize.size();
boost::scoped_array<hsize_t> current_dims(new hsize_t[rank]);
boost::scoped_array<hsize_t> max_dims(new hsize_t[rank]);
for (size_t i=0; i < rank; i++)
current_dims[i] = attrSize[i];
for (size_t i=0; i < rank; i++)
max_dims[i] = H5S_UNLIMITED;
attrSpace = H5Screate(H5S_SIMPLE);
if (attrSpace < 0)
return false;
if (H5Sset_extent_simple(attrSpace, (int)rank,
current_dims.get(), max_dims.get()) < 0) {
return false;
}
attr = H5Acreate(location, attrName.c_str(), H5T_NATIVE_FLOAT,
attrSpace, H5P_DEFAULT, H5P_DEFAULT);
if (attr < 0) {
Msg::print(Msg::SevWarning, "Error creating attribute: " + attrName);
H5Aclose(attr);
H5Sclose(attrSpace);
return false;
}
if (H5Awrite(attr, H5T_NATIVE_FLOAT, &value) < 0) {
Msg::print(Msg::SevWarning, "Error writing attribute: " + attrName);
H5Aclose(attr);
H5Sclose(attrSpace);
return false;
}
H5Aclose(attr);
H5Sclose(attrSpace);
return true;
}
//----------------------------------------------------------------------------//
bool
writeAttribute(hid_t location, const string& attrName,
std::vector<unsigned int> &attrSize, const double &value)
{
GlobalLock lock(g_hdf5Mutex);
hid_t attr;
hid_t attrSpace;
size_t rank = attrSize.size();
boost::scoped_array<hsize_t> current_dims(new hsize_t[rank]);
boost::scoped_array<hsize_t> max_dims(new hsize_t[rank]);
for (size_t i=0; i < rank; i++)
current_dims[i] = attrSize[i];
for (size_t i=0; i < rank; i++)
max_dims[i] = H5S_UNLIMITED;
attrSpace = H5Screate(H5S_SIMPLE);
if (attrSpace < 0)
return false;
if (H5Sset_extent_simple(attrSpace, (int)rank,
current_dims.get(), max_dims.get()) < 0) {
return false;
}
attr = H5Acreate(location, attrName.c_str(), H5T_NATIVE_DOUBLE,
attrSpace, H5P_DEFAULT, H5P_DEFAULT);
if (attr < 0) {
Msg::print(Msg::SevWarning, "Error creating attribute: " + attrName);
H5Aclose(attr);
H5Sclose(attrSpace);
return false;
}
if (H5Awrite(attr, H5T_NATIVE_DOUBLE, &value) < 0) {
Msg::print(Msg::SevWarning, "Error writing attribute: " + attrName);
H5Aclose(attr);
H5Sclose(attrSpace);
return false;
}
H5Aclose(attr);
H5Sclose(attrSpace);
return true;
}
//----------------------------------------------------------------------------//
bool checkHdf5Gzip()
{
GlobalLock lock(g_hdf5Mutex);
htri_t avail = H5Zfilter_avail(H5Z_FILTER_DEFLATE);
if (!avail)
return false;
unsigned int filter_info;
herr_t status = H5Zget_filter_info (H5Z_FILTER_DEFLATE, &filter_info);
if (status < 0)
return false;
if (!(filter_info & H5Z_FILTER_CONFIG_ENCODE_ENABLED) ||
!(filter_info & H5Z_FILTER_CONFIG_DECODE_ENABLED)) {
return false;
}
return true;
}
//----------------------------------------------------------------------------//
} // namespace Hdf5Util
//----------------------------------------------------------------------------//
FIELD3D_NAMESPACE_SOURCE_CLOSE
//----------------------------------------------------------------------------//
Hdf5Util.h
Contains various utility functions for Hdf5.
g_hdf5Mutex
FIELD3D_NAMESPACE_OPEN FIELD3D_API boost::recursive_mutex g_hdf5Mutex
Definition Hdf5Util.cpp:67
GlobalLock
boost::recursive_mutex::scoped_lock GlobalLock
Definition Hdf5Util.h:78
Hdf5Util::H5ScopedAget_space
Scoped object - opens an attribute data space on creation and closes it on destruction.
Definition Hdf5Util.h:288
Hdf5Util::H5ScopedAget_type
Scoped object - opens an attribute data type on creation and closes it on destruction.
Definition Hdf5Util.h:311
Hdf5Util::H5ScopedAopen
Scoped object - Opens attribute by name and closes it on destruction.
Definition Hdf5Util.h:114
Hdf5Util::H5ScopedTget_native_type
Scoped object - opens an native type id on creation and closes it on destruction.
Definition Hdf5Util.h:334
Hdf5Util::readAttribute
FIELD3D_API bool readAttribute(hid_t location, const std::string &attrName, std::string &value)
Reads a string attribute.
Hdf5Util::writeAttribute
FIELD3D_API bool writeAttribute(hid_t location, const std::string &attrName, const std::string &value)
Writes a string attribute.
Hdf5Util::checkHdf5Gzip
FIELD3D_API bool checkHdf5Gzip()
Checks whether gzip is available in the current hdf5 library.
Definition Hdf5Util.cpp:722
Exc
Namespace for Exception objects.
Definition Exception.h:57
FIELD3D_NAMESPACE_OPEN
Definition FieldMapping.cpp:74
Hdf5Util
Contains utility functions and classes for Hdf5 files.
Definition Hdf5Util.h:86
Msg::SevWarning
@ SevWarning
Definition Log.h:68
Msg::print
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:70
FIELD3D_NAMESPACE_SOURCE_CLOSE
#define FIELD3D_NAMESPACE_SOURCE_CLOSE
Definition ns.h:60