Newer
Older
#include "MantidDataHandling/H5Util.h"
#include <boost/numeric/conversion/cast.hpp>
using namespace H5;
namespace Mantid {
namespace DataHandling {
namespace H5Util {
/// static logger object
Mantid::Kernel::Logger g_log("H5Util");
H5::DataSet writeScalarStrDataSet(Group &group, const std::string &name,
const std::string &value) {
StrType dataType(0, value.length() + 1);
DataSpace dataSpace = getDataSpace(1);
H5::DataSet data = group.createDataSet(name, dataType, dataSpace);
data.write(value, dataType);
return data;
}
// -------------------------------------------------------------------
// convert primitives to HDF5 enum
// -------------------------------------------------------------------
template <typename NumT> DataType getType() { throw DataTypeIException(); }
template <> MANTID_DATAHANDLING_DLL DataType getType<float>() {
template <> MANTID_DATAHANDLING_DLL DataType getType<double>() {
template <> MANTID_DATAHANDLING_DLL DataType getType<int32_t>() {
template <> MANTID_DATAHANDLING_DLL DataType getType<uint32_t>() {
template <> MANTID_DATAHANDLING_DLL DataType getType<int64_t>() {
template <> MANTID_DATAHANDLING_DLL DataType getType<uint64_t>() {
// -------------------------------------------------------------------
// write methods
// -------------------------------------------------------------------
Group createGroupNXS(H5File &file, const std::string &name,
const std::string &nxtype) {
auto group = file.createGroup(name);
writeStrAttribute(group, NX_ATTR_CLASS, nxtype);
return group;
}
Group createGroupNXS(Group &group, const std::string &name,
const std::string &nxtype) {
auto outGroup = group.createGroup(name);
writeStrAttribute(outGroup, NX_ATTR_CLASS, nxtype);
return outGroup;
}
DataSpace getDataSpace(const size_t length) {
hsize_t dims[] = {length};
return DataSpace(1, dims);
}
template <typename NumT> DataSpace getDataSpace(const std::vector<NumT> &data) {
return H5Util::getDataSpace(data.size());
}
DSetCreatPropList setCompressionAttributes(const std::size_t length,
const int deflateLevel) {
DSetCreatPropList propList;
hsize_t chunk_dims[1] = {length};
propList.setChunk(1, chunk_dims);
propList.setDeflate(deflateLevel);
return propList;
}
void writeStrAttribute(LocationType &location, const std::string &name,
const std::string &value) {
StrType attrType(0, H5T_VARIABLE);
DataSpace attrSpace(H5S_SCALAR);
auto attribute = location.createAttribute(name, attrType, attrSpace);
attribute.write(attrType, value);
void write(Group &group, const std::string &name, const std::string &value) {
writeScalarStrDataSet(group, name, value);
}
void writeWithStrAttributes(
H5::Group &group, const std::string &name, const std::string &value,
const std::map<std::string, std::string> &attributes) {
auto data = writeScalarStrDataSet(group, name, value);
for (const auto &attribute : attributes) {
writeStrAttribute(data, attribute.first, attribute.second);
}
void writeArray1D(Group &group, const std::string &name,
DataSpace dataSpace = getDataSpace(values);
DSetCreatPropList propList = setCompressionAttributes(values.size());
auto data = group.createDataSet(name, dataType, dataSpace, propList);
data.write(values.data(), dataType);
// -------------------------------------------------------------------
// read methods
// -------------------------------------------------------------------
std::string readString(H5::H5File &file, const std::string &path) {
try {
auto data = file.openDataSet(path);
return readString(data);
} catch (H5::FileIException &e) {
UNUSED_ARG(e);
return "";
} catch (H5::GroupIException &e) {
UNUSED_ARG(e);
return "";
}
}
std::string readString(H5::Group &group, const std::string &name) {
try {
auto data = group.openDataSet(name);
return readString(data);
} catch (H5::GroupIException &e) {
UNUSED_ARG(e);
return "";
}
}
std::string readString(H5::DataSet &dataset) {
std::string value;
dataset.read(value, dataset.getDataType(), dataset.getSpace());
return value;
}
template <typename LocationType>
std::string readAttributeAsString(LocationType &location,
const std::string &attributeName) {
auto attribute = location.openAttribute(attributeName);
std::string value;
attribute.read(attribute.getDataType(), value);
return value;
}
template <typename NumT>
std::vector<NumT> readArray1DCoerce(H5::Group &group, const std::string &name) {
std::vector<NumT> result;
DataSet dataset = group.openDataSet(name);
result = readArray1DCoerce<NumT>(dataset);
} catch (H5::GroupIException &e) {
UNUSED_ARG(e);
g_log.information() << "Failed to open dataset \"" << name << "\"\n";
} catch (H5::DataTypeIException &e) {
UNUSED_ARG(e);
g_log.information() << "DataSet \"" << name << "\" should be double"
<< "\n";
namespace {
template <typename InputNumT, typename OutputNumT>
std::vector<OutputNumT> convertingingRead(DataSet &dataset,
DataSpace dataSpace = dataset.getSpace();
std::vector<InputNumT> temp(dataSpace.getSelectNpoints());
dataset.read(temp.data(), dataType, dataSpace);
std::vector<OutputNumT> result;
result.resize(temp.size());
std::transform(temp.begin(), temp.end(), result.begin(),
[](const InputNumT a) { // lambda
return boost::numeric_cast<OutputNumT>(a);
});
return result;
}
template <typename NumT> std::vector<NumT> readArray1DCoerce(DataSet &dataset) {
DataType dataType = dataset.getDataType();
if (getType<NumT>() == dataType) { // no conversion necessary
std::vector<NumT> result;
DataSpace dataSpace = dataset.getSpace();
result.resize(dataSpace.getSelectNpoints());
dataset.read(result.data(), dataType, dataSpace);
}
if (PredType::NATIVE_INT32 == dataType) {
return convertingingRead<int32_t, NumT>(dataset, dataType);
} else if (PredType::NATIVE_UINT32 == dataType) {
return convertingingRead<uint32_t, NumT>(dataset, dataType);
} else if (PredType::NATIVE_INT64 == dataType) {
return convertingingRead<int64_t, NumT>(dataset, dataType);
} else if (PredType::NATIVE_UINT64 == dataType) {
return convertingingRead<uint64_t, NumT>(dataset, dataType);
} else if (PredType::NATIVE_FLOAT == dataType) {
return convertingingRead<float, NumT>(dataset, dataType);
} else if (PredType::NATIVE_DOUBLE == dataType) {
return convertingingRead<double, NumT>(dataset, dataType);
// not a supported type
throw DataTypeIException();
// -------------------------------------------------------------------
// instantiations for writeStrAttribute
// -------------------------------------------------------------------
template MANTID_DATAHANDLING_DLL void
writeStrAttribute(H5::Group &location, const std::string &name,
const std::string &value);
template MANTID_DATAHANDLING_DLL void
writeStrAttribute(H5::DataSet &location, const std::string &name,
const std::string &value);
// -------------------------------------------------------------------
// instantiations for readAttributeAsString
// -------------------------------------------------------------------
template MANTID_DATAHANDLING_DLL std::string
readAttributeAsString(H5::Group &location, const std::string &attributeName);
template MANTID_DATAHANDLING_DLL std::string
readAttributeAsString(H5::DataSet &location, const std::string &attributeName);
// -------------------------------------------------------------------
// instantiations for writeArray1D
// -------------------------------------------------------------------
template MANTID_DATAHANDLING_DLL void
writeArray1D(H5::Group &group, const std::string &name,
const std::vector<float> &values);
template MANTID_DATAHANDLING_DLL void
writeArray1D(H5::Group &group, const std::string &name,
const std::vector<double> &values);
template MANTID_DATAHANDLING_DLL void
writeArray1D(H5::Group &group, const std::string &name,
const std::vector<int32_t> &values);
template MANTID_DATAHANDLING_DLL void
writeArray1D(H5::Group &group, const std::string &name,
const std::vector<uint32_t> &values);
template MANTID_DATAHANDLING_DLL void
writeArray1D(H5::Group &group, const std::string &name,
const std::vector<int64_t> &values);
template MANTID_DATAHANDLING_DLL void
writeArray1D(H5::Group &group, const std::string &name,
const std::vector<uint64_t> &values);
// -------------------------------------------------------------------
// instantiations for getDataSpace
// -------------------------------------------------------------------
template MANTID_DATAHANDLING_DLL DataSpace
getDataSpace(const std::vector<float> &data);
template MANTID_DATAHANDLING_DLL DataSpace
getDataSpace(const std::vector<double> &data);
template MANTID_DATAHANDLING_DLL DataSpace
getDataSpace(const std::vector<int32_t> &data);
template MANTID_DATAHANDLING_DLL DataSpace
getDataSpace(const std::vector<uint32_t> &data);
template MANTID_DATAHANDLING_DLL DataSpace
getDataSpace(const std::vector<int64_t> &data);
template MANTID_DATAHANDLING_DLL DataSpace
getDataSpace(const std::vector<uint64_t> &data);
// -------------------------------------------------------------------
// instantiations for readArray1DCoerce
// -------------------------------------------------------------------
readArray1DCoerce(H5::Group &group, const std::string &name);
template MANTID_DATAHANDLING_DLL std::vector<double>
readArray1DCoerce(H5::Group &group, const std::string &name);
template MANTID_DATAHANDLING_DLL std::vector<int32_t>
readArray1DCoerce(H5::Group &group, const std::string &name);
template MANTID_DATAHANDLING_DLL std::vector<uint32_t>
readArray1DCoerce(H5::Group &group, const std::string &name);
template MANTID_DATAHANDLING_DLL std::vector<int64_t>
readArray1DCoerce(H5::Group &group, const std::string &name);
template MANTID_DATAHANDLING_DLL std::vector<uint64_t>
readArray1DCoerce(H5::Group &group, const std::string &name);
template MANTID_DATAHANDLING_DLL std::vector<float>
readArray1DCoerce<float>(DataSet &dataset);
readArray1DCoerce<int32_t>(DataSet &dataset);
readArray1DCoerce<uint32_t>(DataSet &dataset);
readArray1DCoerce<int64_t>(DataSet &dataset);
readArray1DCoerce<uint64_t>(DataSet &dataset);
} // namespace H5Util
} // namespace DataHandling
} // namespace Mantid