[cig-commits] r13585 - cs/cigma/trunk/src
luis at geodynamics.org
luis at geodynamics.org
Tue Dec 9 18:15:10 PST 2008
Author: luis
Date: 2008-12-09 18:15:10 -0800 (Tue, 09 Dec 2008)
New Revision: 13585
Added:
cs/cigma/trunk/src/io_hdf5.cpp
cs/cigma/trunk/src/io_hdf5.h
Log:
Refactored how we are using the C++ HDF5 API
Added: cs/cigma/trunk/src/io_hdf5.cpp
===================================================================
--- cs/cigma/trunk/src/io_hdf5.cpp (rev 0)
+++ cs/cigma/trunk/src/io_hdf5.cpp 2008-12-10 02:15:10 UTC (rev 13585)
@@ -0,0 +1,218 @@
+#include "io_hdf5.h"
+
+/* predtypes */
+/*
+template <> H5::PredType predtype_from<int>() { return H5::PredType::NATIVE_INT; }
+template <> H5::PredType predtype_from<long>() { return H5::PredType::NATIVE_LONG; }
+template <> H5::PredType predtype_from<float>() { return H5::PredType::NATIVE_FLOAT; }
+template <> H5::PredType predtype_from<double>(){ return H5::PredType::NATIVE_DOUBLE; }
+// */
+
+/* datatypes */
+template <> H5::DataType h5_datatype_from<int>() { return H5::PredType::NATIVE_INT; }
+template <> H5::DataType h5_datatype_from<long>() { return H5::PredType::NATIVE_LONG; }
+template <> H5::DataType h5_datatype_from<float>() { return H5::PredType::NATIVE_FLOAT; }
+template <> H5::DataType h5_datatype_from<double>() { return H5::PredType::NATIVE_DOUBLE; }
+template <> H5::DataType h5_datatype_from<std::string>(){ return H5::StrType(0, H5T_VARIABLE); }
+
+/* typeclasses */
+template <> H5T_class_t h5_typeclass_from<int>() { return H5T_INTEGER; }
+template <> H5T_class_t h5_typeclass_from<long>() { return H5T_INTEGER; }
+template <> H5T_class_t h5_typeclass_from<float>() { return H5T_FLOAT; }
+template <> H5T_class_t h5_typeclass_from<double>() { return H5T_FLOAT; }
+template <> H5T_class_t h5_typeclass_from<std::string>(){ return H5T_STRING; }
+
+
+/* specialize read_scalar_attribute for T=std::string */
+/*
+template <>
+int read_scalar_attribute<std::string>(H5::H5File *file, const char *loc, const char *attr_name, std::string& val)
+{
+ H5::H5Object* obj = 0;
+ H5::Attribute* attr = 0;
+
+ if (file)
+ {
+ try
+ {
+ obj = load_h5obj(file, loc);
+ if (obj == 0) { return -2; }
+
+ if (obj == 0)
+ {
+ return -2;
+ }
+
+ attr = new H5::Attribute(obj->openAttribute(attr_name));
+ attr->read(predtype_from<T>(), val);
+ }
+ catch (H5::Exception error)
+ {
+ if (obj) { delete obj; }
+ if (attr) { delete attr; }
+ return -1;
+ }
+
+ if (obj) { delete obj; }
+ if (attr) { delete attr; }
+ }
+
+ return 0;
+}
+// */
+
+
+/* specialize write_scalar_attribute for T=std::string */
+/*
+template <>
+int write_scalar_attribute<std::string>(H5::H5File *file, const char *loc, const char *attr_name, const std::string& val)
+{
+ return 0;
+}
+// */
+
+
+
+/* open hdf5 file */
+H5::H5File* h5_open_file(const char *filename, const char *mode)
+{
+ std::string m(mode);
+ H5::H5File *file = 0;
+
+ try
+ {
+ H5::Exception::dontPrint();
+
+ if (m == "a")
+ {
+ try
+ {
+ // open existing file in read/write mode
+ file = new H5::H5File(filename, H5F_ACC_RDWR);
+ }
+ catch (H5::FileIException e)
+ {
+ }
+
+ if (file == 0)
+ {
+ // previous attempt failed: force creation of new file
+ file = new H5::H5File(filename, H5F_ACC_TRUNC);
+ }
+ }
+ else if (m == "rw")
+ {
+ // open existing file in read/write mode (fail otherwise)
+ file = new H5::H5File(filename, H5F_ACC_RDWR);
+ }
+ else if (m == "r")
+ {
+ // opens existing file in read-only mode (fail otherwise)
+ file = new H5::H5File(filename, H5F_ACC_RDONLY);
+ }
+ else if (m == "w")
+ {
+ // creates new file
+ file = new H5::H5File(filename, H5F_ACC_TRUNC);
+ }
+ else if (m == "x")
+ {
+ // creates file, but fails if it already exists
+ file = new H5::H5File(filename, H5F_ACC_EXCL);
+ }
+ else
+ {
+ std::cerr << "Error: Unknown file mode '" << mode << "'" << std::endl;
+ }
+ }
+ catch (H5::FileIException error)
+ {
+ error.printError();
+ }
+
+ return file;
+}
+
+
+/* open hdf5 group */
+H5::Group* h5_open_group(H5::H5File *file, const char *loc)
+{
+ H5::Group* group = 0;
+
+ if (file)
+ {
+ H5::Exception::dontPrint();
+
+ try
+ {
+ group = new H5::Group(file->openGroup(loc));
+ }
+ catch (H5::Exception error)
+ {
+ }
+ }
+
+ return group;
+}
+
+
+/* open hdf5 dataset */
+H5::DataSet* h5_open_dataset(H5::H5File *file, const char *loc)
+{
+ H5::DataSet* dataset = 0;
+
+ if (file)
+ {
+ H5::Exception::dontPrint();
+
+ try
+ {
+ dataset = new H5::DataSet(file->openDataSet(loc));
+ }
+ catch (H5::Exception error)
+ {
+ }
+ }
+
+ return dataset;
+}
+
+
+/* open object in hdf5 file */
+H5::H5Object* h5_open_object(H5::H5File *file, const char *loc)
+{
+ H5::H5Object* obj = 0;
+
+ if (file)
+ {
+ obj = h5_open_group(file, loc);
+
+ if (obj == 0)
+ {
+ obj = h5_open_dataset(file, loc);
+ }
+ }
+
+ return obj;
+}
+
+
+/* open attribute on hdf5 object */
+H5::Attribute* h5_open_attribute(H5::H5Object *obj, const char *attr_name)
+{
+ H5::Attribute *attribute = 0;
+
+ if (obj)
+ {
+ try
+ {
+ attribute = new H5::Attribute(obj->openAttribute(attr_name));
+ }
+ catch (H5::Exception error)
+ {
+ }
+ }
+
+ return attribute;
+}
+
Added: cs/cigma/trunk/src/io_hdf5.h
===================================================================
--- cs/cigma/trunk/src/io_hdf5.h (rev 0)
+++ cs/cigma/trunk/src/io_hdf5.h 2008-12-10 02:15:10 UTC (rev 13585)
@@ -0,0 +1,296 @@
+#ifndef __CIGMA_IO_HDF5_H__
+#define __CIGMA_IO_HDF5_H__
+
+#include "H5Cpp.h"
+#include "Exception.h"
+#include <iostream>
+#include <string>
+
+/**
+ * Function template returns an H5::DataType from given C++ type.
+ * See io_hdf5.cpp for specializations.
+ * @param T C++ type
+ */
+template <typename T>
+H5::DataType h5_datatype_from()
+{
+ throw cigma::Exception("h5_datatype_from", "no mapping available for this datatype");
+ return H5::DataType();
+}
+
+
+/**
+ * Function template returns an H5T_class_t from given C++ type.
+ * See io_hdf5.cpp for specializations.
+ * @param T C++ type
+ */
+template <typename T>
+H5T_class_t h5_typeclass_from()
+{
+ throw cigma::Exception("h5_typeclass_from", "no mapping available for this h5_typeclass");
+ return H5T_NO_CLASS;
+}
+
+
+/**
+ * Load H5File from filename.
+ */
+H5::H5File* h5_open_file(const char *filename, const char *mode);
+
+
+/**
+ * Load group from location
+ */
+H5::Group* h5_open_group(H5::H5File *file, const char *loc);
+
+
+/**
+ * Load dataset from location.
+ */
+H5::DataSet* h5_open_dataset(H5::H5File *file, const char *loc);
+
+
+/**
+ * Load object from location, whether it is a group or dataset.
+ */
+H5::H5Object* h5_open_object(H5::H5File *file, const char *loc);
+
+
+/**
+ * Load attribute from object
+ */
+H5::Attribute* h5_open_attribute(H5::H5Object *obj, const char *attr_name);
+
+
+/**
+ * Read entire dataset into memory.
+ * @param MT C++ memory type of data array
+ */
+template <typename MT>
+int get_full_dataset(H5::H5File *file, const char *loc, MT **data, int *nrows, int *ncols)
+{
+ if (file == 0)
+ {
+ return -1;
+ }
+
+ try
+ {
+ H5::DataSet dataset = file->openDataSet(loc);
+
+ H5T_class_t type_class = dataset.getTypeClass();
+ if (type_class != h5_typeclass_from<MT>())
+ {
+ std::cerr << "Dataset type mismatch in read operation." << std::endl;
+ return -2;
+ }
+
+ H5::DataSpace dataspace = dataset.getSpace();
+
+ int rank = dataspace.getSimpleExtentNdims();
+ if ((rank != 1) && (rank != 2))
+ {
+ std::cerr << "Dataset rank must be 1 or 2." << std::endl;
+ return -3;
+ }
+
+ hsize_t dims[2];
+ int ndims = dataspace.getSimpleExtentDims(dims, NULL);
+ int size = dataspace.getSimpleExtentNpoints();
+ MT *array = 0;
+
+ try
+ {
+ array = new MT[size];
+ dataset.read(array, h5_datatype_from<MT>());
+ }
+ catch (H5::DataSetIException error)
+ {
+ std::cerr << "Dataset '" << loc << "' could not be read." << std::endl;
+ delete array;
+ array = 0;
+ }
+
+ if (array == 0)
+ {
+ return -1;
+ }
+
+ *nrows = dims[0];
+ *ncols = dims[1];
+ *data = array;
+ }
+ catch (H5::DataSetIException error)
+ {
+ error.printError();
+ return -1;
+ }
+ catch (H5::DataSpaceIException error)
+ {
+ error.printError();
+ return -1;
+ }
+ catch (H5::Exception error)
+ {
+ //error.printError();
+ return -1;
+ }
+ return 0;
+}
+
+
+/**
+ * Write dataset to location.
+ * @param MT memory type of data
+ * @param FT file type of data (what gets written to disk)
+ */
+template <typename MT, typename FT>
+int write_full_dataset(H5::H5File *file, const char *loc, const MT *data, int nrows, int ncols)
+{
+ if (file == 0)
+ {
+ return -1;
+ }
+
+ try
+ {
+ hsize_t dims[2] = {nrows, ncols};
+ H5::DataSpace dataspace(2, dims);
+ H5::DataType filetype = h5_datatype_from<FT>();
+ H5::DataType memtype = h5_datatype_from<MT>();
+ H5::DataSet dataset = file->createDataSet(loc, filetype, dataspace);
+ dataset.write(data, memtype);
+ }
+ catch (H5::DataSpaceIException error)
+ {
+ error.printError();
+ return -1;
+ }
+ catch (H5::DataSetIException error)
+ {
+ error.printError();
+ return -1;
+ }
+ catch (H5::Exception error)
+ {
+ //error.printError();
+ return -1;
+ }
+
+ return 0;
+}
+
+
+/**
+ * Read scalar attribute from location.
+ * @param T C++ type
+ */
+template <typename T>
+int read_scalar_attribute(H5::H5File *file, const char *loc, const char *attr_name, T& val)
+{
+ H5::H5Object* obj = 0;
+ H5::Attribute* attr = 0;
+
+ if (file == 0)
+ {
+ return -1;
+ }
+
+ try
+ {
+ obj = h5_open_object(file, loc);
+
+ if (obj == 0)
+ {
+ return -2;
+ }
+
+ attr = new H5::Attribute(obj->openAttribute(attr_name));
+
+ attr->read(h5_datatype_from<T>(), &val);
+ }
+ catch (H5::Exception error)
+ {
+ if (obj) { delete obj; }
+ if (attr) { delete attr; }
+ return -1;
+ }
+
+ if (attr) { delete attr; }
+ if (obj) { delete obj; }
+
+ return 0;
+}
+
+
+/**
+ * Write scalar attribute to location.
+ * @param T C++ type
+ */
+template <typename T>
+int write_scalar_attribute(H5::H5File *file, const char *loc, const char *attr_name, const T& val)
+{
+ H5::H5Object* obj = 0;
+ H5::Attribute* attr = 0;
+
+ if (file == 0)
+ {
+ return -1;
+ }
+
+ obj = h5_open_object(file, loc);
+
+ if (obj == 0)
+ {
+ return -3;
+ }
+
+ attr = h5_open_attribute(obj, attr_name);
+
+ if (attr == 0)
+ {
+ if (obj) { delete obj; }
+ return -4;
+ }
+
+ const bool overwrite_mode = true;
+ if (overwrite_mode)
+ {
+ try
+ {
+ delete attr;
+ attr = 0;
+ obj->removeAttr(attr_name);
+ }
+ catch (H5::AttributeIException e)
+ {
+ }
+ }
+ else
+ {
+ std::cerr << "Error: Overwriting existing attribute '" << attr_name << "' is not allowed" << std::endl;
+ return -5;
+ }
+
+ try
+ {
+ H5::DataSpace dataspace(H5S_SCALAR);
+ H5::DataType datatype = h5_datatype_from<T>();
+ attr = new H5::Attribute(obj->createAttribute(attr_name, datatype, dataspace));
+ attr->write(datatype, &val);
+ }
+ catch (H5::Exception error)
+ {
+ std::cerr << "Error: Could not set attribute '" << attr_name << "'" << std::endl;
+ error.printError();
+ return -2;
+ }
+
+ if (attr) { delete attr; }
+ if (obj) { delete obj; }
+
+ return 0;
+}
+
+
+#endif
More information about the CIG-COMMITS
mailing list