[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