Hdf5Utilities.h

Go to the documentation of this file.
00001 /*
00002  * The information in this file is
00003  * Copyright(c) 2007 Ball Aerospace & Technologies Corporation
00004  * and is subject to the terms and conditions of the
00005  * GNU Lesser General Public License Version 2.1
00006  * The license text is available from   
00007  * http://www.gnu.org/licenses/lgpl.html
00008  */
00009 
00010 #ifndef HDF5UTILITIES_H
00011 #define HDF5UTILITIES_H
00012 
00013 #include "HdfUtilities.h"
00014 
00015 #include "AppVerify.h"
00016 #include "DataVariant.h"
00017 #include "Hdf5CustomWriter.h"
00018 #include "Hdf5Dataset.h"
00019 #include "Hdf5Element.h"
00020 #include "Hdf5Group.h"
00021 #include "TypesFile.h"
00022 
00023 #include <hdf5.h>
00024 
00025 #include <memory>
00026 #include <string>
00027 #include <vector>
00028 
00029 /**
00030  * A collection of generic utilities provided to simplify use of the application's HDF API.
00031  */
00032 namespace HdfUtilities
00033 {
00034    /**
00035     * Represents a version of H5T_INTEGER type that the HdfPlugInLib does not know how to parse.
00036     */
00037    static const std::string UNKNOWN_INTEGER_TYPE = "Unknown HDF5 Integer Type";
00038 
00039    /**
00040     * Represents a version of H5T_FLOAT type that the HdfPlugInLib does not know how to parse.
00041     */
00042    static const std::string UNKNOWN_FLOAT_TYPE = "Unknown HDF5 Float Type";
00043 
00044    /**
00045     * Represents the H5T_TIME type.  The HdfPlugInLib will not parse data of this type.
00046     */
00047    static const std::string TIME_TYPE = "HDF5 Time Type";
00048 
00049    /**
00050     * Represents the H5T_ARRAY type.  The HdfPlugInLib will not parse data of this type.
00051     */
00052    static const std::string ARRAY_TYPE = "HDF5 Array Type";
00053 
00054    /**
00055     * Represents the H5T_BITFIELD type.  The HdfPlugInLib will not parse data of this type.
00056     */
00057    static const std::string BITFIELD_TYPE = "HDF5 Bitfield Type";
00058 
00059    /**
00060     * Represents the H5T_OPAQUE type.  The HdfPlugInLib will not parse data of this type.
00061     */
00062    static const std::string OPAQUE_TYPE = "HDF5 Opaque Type";
00063 
00064    /**
00065     * Represents the H5T_COMPOUND type.  The HdfPlugInLib will not parse data of this type.
00066     */
00067    static const std::string COMPOUND_TYPE = "HDF5 Compound Type";
00068 
00069    /**
00070     * Represents the H5T_REFERENCE type.  The HdfPlugInLib will not parse data of this type.
00071     */
00072    static const std::string REFERENCE_TYPE = "HDF5 Reference Type";
00073 
00074    /**
00075     * Represents the H5T_ENUM type.  The HdfPlugInLib will not parse data of this type.
00076     */
00077    static const std::string ENUM_TYPE = "HDF5 ENUM Type";
00078 
00079    /**
00080     * Represents the H5T_VLEN type.  The HdfPlugInLib will not parse data of this type.
00081     */
00082    static const std::string VLEN_TYPE = "HDF5 VLEN Type";
00083 
00084    /**
00085     * Converts an HDF5 data type to a string.  This method simply returns a string
00086     * representation of the type.  It does not take the dataspace into account, ie. the 
00087     * dimensionality.
00088     *
00089     * NOTE: You will need to statically link against the HDF5 libraries.
00090     *
00091     * @param  dataTypeId
00092     *         The value returned from H5Dget_type() or H5Aget_type().
00093     *
00094     * @return A string that represents the HDF5 type.  The return value could be one of 
00095     *         the following:
00096     *           - TypeConverter::toString<char>();
00097     *           - TypeConverter::toString<unsigned char>();
00098     *           - TypeConverter::toString<short>();
00099     *           - TypeConverter::toString<unsigned short>();
00100     *           - TypeConverter::toString<int>();
00101     *           - TypeConverter::toString<unsigned int>();
00102     *           - TypeConverter::toString<float>();
00103     *           - TypeConverter::toString<double>();
00104     *           - TypeConverter::toString<string>();
00105     *           - HdfUtilities::UNKNOWN_INTEGER_TYPE
00106     *           - HdfUtilities::UNKNOWN_FLOAT_TYPE
00107     *           - HdfUtilities::UNKNOWN_TYPE
00108     *           - HdfUtilities::TIME_TYPE
00109     *           - HdfUtilities::ARRAY_TYPE
00110     *           - HdfUtilities::BITFIELD_TYPE
00111     *           - HdfUtilities::OPAQUE_TYPE
00112     *           - HdfUtilities::COMPOUND_TYPE
00113     *           - HdfUtilities::ENUM_TYPE
00114     *           - HdfUtilities::VLEN_TYPE
00115     */
00116    std::string hdf5TypeToTypeString(hid_t dataTypeId);
00117 
00118    /**
00119     *  Given an open HDF5 Attribute identifier retrieves
00120     *  the attribute and places it in a variant.
00121     *
00122     *  @param  attrId
00123     *          A handle to the HDF attribute.
00124     *  @param  var
00125     *          The variant that the attribute data will be placed in.
00126     *
00127     *  @return The number of elements (ie. 5 if a vector of 5 ints) in the attribute.
00128     */
00129    bool readHdf5Attribute(hid_t attrId, DataVariant& var);
00130 
00131    /**
00132     * Given an HDF5 Attribute handle, returns a string representing that attribute.
00133     *
00134     * This method only supports attributes supported by StringUtilities::toString()
00135     * and StringUtilities::fromString() minus the enumerated types in TypesFile.h.
00136     *
00137     * Throws an HdfUtilities::Exception if an error occurs.
00138     *
00139     * @param  attrId
00140     *         The attribute id returned by H5Aopen().
00141     *
00142     * @return A string representing the attribute. For 1-dimensional vector types,
00143     *         this returns the list of values: ie. (val1, val2, val3).
00144     */
00145    std::string hdf5AttributeToString(hid_t attrId);
00146 
00147    /**
00148     * Creates an HDF5 attribute with a given name and value.
00149     *
00150     * @param dataDescriptor
00151     *        A handle to the HDF5 dataset or HDF5 group that this attribute should
00152     *        be attached to.
00153     * @param attributeName
00154     *        The name of the attribute that should be created on the HDF5 dataset
00155     *        or HDF5 group.
00156     * @param attributeValue
00157     *        The value that the created attribute should have.  The value will
00158     *        determine the HDF5 type and HDF5 dataspace of the created attribute.
00159     *        Specifically, the Hdf5CustomWriter created for T will determine both
00160     *        the HDF5 type and HDF5 dataspace.
00161     *
00162     * @return Returns true if the attribute could be created with the given name
00163     *         and value successfully, false otherwise.
00164     */
00165    template<typename T>
00166    bool writeAttribute(hid_t dataDescriptor, const std::string& attributeName, const T& attributeValue)
00167    {
00168       std::auto_ptr<Hdf5CustomWriter> pWriter(createHdf5CustomWriter<T>());
00169       if (pWriter.get() == NULL)
00170       {
00171          return false;
00172       }
00173 
00174       if (!pWriter->setDataToWrite(const_cast<T*>(&attributeValue)))
00175       {
00176          return false;
00177       }
00178       Hdf5DataSpaceResource spaceId = pWriter->createDataSpace();
00179       VERIFY(*spaceId >= 0);
00180       Hdf5TypeResource memTypeId(pWriter->getWriteMemoryType());
00181       Hdf5TypeResource fileTypeId(pWriter->getWriteFileType());
00182       if (*memTypeId < 0 || *fileTypeId < 0)
00183       {
00184          return false;
00185       }
00186       Hdf5AttributeResource attrId(H5Acreate1(dataDescriptor, attributeName.c_str(), *fileTypeId,
00187          *spaceId, H5P_DEFAULT));
00188       if (*attrId < 0)
00189       {
00190          return false;
00191       }
00192 
00193       // now write the attribute
00194       const void* pData = pWriter->getWriteBuffer();
00195       if (pData != NULL)
00196       {
00197          herr_t writeStatus = H5Awrite(*attrId, *memTypeId, pData);
00198          return writeStatus == 0;
00199       }
00200       return false;
00201    }
00202 
00203    /**
00204     * Creates an HDF5 dataset with a given name and value.
00205     *
00206     * @param fileDescriptor
00207     *        A handle to the HDF5 file that this dataset should be created in.
00208     * @param datasetName
00209     *        The full path to where the HDF5 dataset should be created in
00210     *        the HDF5 file. This function assumes that any required groups
00211     *        in the path have already been created.
00212     * @param datasetValue
00213     *        The value that the created dataset should have.  The value will
00214     *        determine the HDF5 type and HDF5 dataspace of the created dataset.
00215     *        Specifically, the Hdf5CustomWriter created for T will determine both
00216     *        the HDF5 type and HDF5 dataspace.
00217     *
00218     * @return Returns true if the dataset could be created at the given location 
00219     *         in the file with the given value successfully, false otherwise.
00220     */
00221    template<typename T>
00222    bool writeDataset(hid_t fileDescriptor, const std::string& datasetName, const T& datasetValue)
00223    {
00224       std::auto_ptr<Hdf5CustomWriter> pWriter(createHdf5CustomWriter<T>());
00225       if (pWriter.get() == NULL)
00226       {
00227          return false;
00228       }
00229       if (!pWriter->setDataToWrite(const_cast<T*>(&datasetValue)))
00230       {
00231          return false;
00232       }
00233       Hdf5DataSpaceResource spaceId = pWriter->createDataSpace();
00234       VERIFY(*spaceId >= 0);
00235 
00236       Hdf5TypeResource memTypeId(pWriter->getWriteMemoryType());
00237       Hdf5TypeResource fileTypeId(pWriter->getWriteFileType());
00238       if (*memTypeId < 0 || *fileTypeId < 0)
00239       {
00240          return false;
00241       }
00242 
00243       Hdf5DataSetResource dataSet(H5Dcreate1(fileDescriptor, datasetName.c_str(),
00244          *fileTypeId, *spaceId, H5P_DEFAULT));
00245       if (*dataSet < 0)
00246       {
00247          return false;
00248       }
00249       const void* pData = pWriter->getWriteBuffer();
00250       if (pData != NULL)
00251       {
00252          herr_t writeStatus = H5Dwrite(*dataSet, *memTypeId, H5S_ALL, *spaceId, H5P_DEFAULT, pData);
00253          return writeStatus == 0;
00254       }
00255       return false;
00256    }
00257 
00258    template<typename T>
00259    Hdf5TypeResource getHdf5Type();
00260 
00261    /**
00262     * Creates one or more HDF5 groups with the given names.
00263     *
00264     * @param hdfPath
00265     *        One or more group names, separated by a '/' character, to be created.
00266     *
00267     * @param fileDescriptor
00268     *        A handle to the HDF5 file that the group(s) should be created in.
00269     *
00270     * @param bLastItemIsGroup
00271     *        True if the last item in the string is a group, false otherwise.
00272     *        If this is false, the text after the final '/' in hdfPath is ignored.
00273     *
00274     * @return Returns true if the group(s) were created (or already existed) at the given location(s), false otherwise.
00275     */
00276    bool createGroups(const std::string& hdfPath, hid_t fileDescriptor, bool bLastItemIsGroup = false);
00277 
00278 }
00279 
00280 #endif

Software Development Kit - Opticks 4.9.0 Build 16218