marray_hdf5.hxx

Go to the documentation of this file.
00001 #pragma once
00002 #ifndef MARRAY_HDF5_HXX
00003 #define MARRAY_HDF5_HXX
00004 
00005 // compat fix for buggy hdf5 1.8 versions
00006 #include <H5version.h>
00007 #if (H5_VERS_MAJOR == 1 && H5_VERS_MINOR >= 8 && defined(H5_USE_16_API_DEFAULT))
00008 #define H5Gcreate_vers 2
00009 #define H5Gopen_vers 2
00010 #define H5Dopen_vers 2
00011 #define H5Dcreate_vers 2
00012 #define H5Acreate_vers 2
00013 #endif
00014 
00015 #include <cstring>
00016 
00017 #include "marray.hxx"
00018 #include "hdf5.h"
00019 
00020 namespace marray {
00022 namespace hdf5 {
00023 
00024 // assertion testing
00025 
00026 // \cond suppress doxygen
00027 template<bool B> class HandleCheck;
00028 template<> class HandleCheck<false> {
00029 public:
00030     HandleCheck()
00031         { counter_ = H5Fget_obj_count(H5F_OBJ_ALL, H5F_OBJ_ALL); }
00032     void check()
00033         { marray_detail::Assert( counter_ == H5Fget_obj_count(H5F_OBJ_ALL, H5F_OBJ_ALL)); }
00034 private:
00035     ssize_t counter_;
00036 };
00037 template<> class HandleCheck<true> {
00038 public:
00039     void check() {}
00040 };
00041 // \endcond
00042 
00043 // namespace variables
00044 
00045 const char reverseShapeAttributeName[14] = "reverse-shape";
00046 
00047 // prototypes
00048 
00049 enum FileAccessMode {READ_ONLY, READ_WRITE};
00050 enum HDF5Version {DEFAULT_HDF5_VERSION, LATEST_HDF5_VERSION};
00051 
00052 inline hid_t createFile(const std::string&, HDF5Version = DEFAULT_HDF5_VERSION);
00053 inline hid_t openFile(const std::string&, FileAccessMode = READ_ONLY, HDF5Version = DEFAULT_HDF5_VERSION);
00054 inline void closeFile(const hid_t&);
00055 
00056 inline hid_t createGroup(const hid_t&, const std::string&);
00057 inline hid_t openGroup(const hid_t&, const std::string&);
00058 inline void closeGroup(const hid_t&);
00059 
00060 template<class T>
00061     void save(const hid_t&, const std::string&, const Marray<T>&);
00062 template<class T, bool isConst>
00063     void save(const hid_t&, const std::string&, const View<T, isConst>&);
00064 template<class T>
00065     void save(const hid_t&, const std::string&, const std::vector<T>&);
00066 template<class T, class BaseIterator, class ShapeIterator>
00067     void saveHyperslab(const hid_t&, const std::string&,
00068         BaseIterator, BaseIterator, ShapeIterator, const Marray<T>&);
00069 template<class T, class ShapeIterator>
00070     void create(const hid_t&, const std::string&, ShapeIterator,
00071         ShapeIterator, CoordinateOrder);
00072 
00073 template<class T>
00074     void load(const hid_t&, const std::string&, Marray<T>&);
00075 template<class T>
00076     void loadShape(const hid_t&, const std::string&, Vector<T>&);
00077 template<class T, class BaseIterator, class ShapeIterator>
00078     void loadHyperslab(const hid_t&, const std::string&,
00079         BaseIterator, BaseIterator, ShapeIterator, Marray<T>&);
00080 
00081 // type conversion from C++ to HDF5
00082 
00083 // \cond suppress doxygen
00084 template<class T>
00085 inline hid_t uintTypeHelper() {
00086    switch(sizeof(T)) {
00087        case 1:
00088            return H5T_STD_U8LE;
00089        case 2:
00090            return H5T_STD_U16LE;
00091        case 4:
00092            return H5T_STD_U32LE;
00093        case 8:
00094            return H5T_STD_U64LE;
00095        default:
00096            throw std::runtime_error("No matching HDF5 type.");
00097    }
00098 }
00099 
00100 template<class T>
00101 inline hid_t intTypeHelper() {
00102    switch(sizeof(T)) {
00103        case 1:
00104            return H5T_STD_I8LE;
00105        case 2:
00106            return H5T_STD_I16LE;
00107        case 4:
00108            return H5T_STD_I32LE;
00109        case 8:
00110            return H5T_STD_I64LE;
00111        default:
00112            throw std::runtime_error("No matching HDF5 type.");
00113    }
00114 }
00115 
00116 template<class T>
00117 inline hid_t floatingTypeHelper() {
00118    switch(sizeof(T)) {
00119        case 4:
00120            return H5T_IEEE_F32LE;
00121        case 8:
00122            return H5T_IEEE_F64LE;
00123        default:
00124            throw std::runtime_error("No matching HDF5 type.");
00125    }
00126 }
00127 
00128 template<class T>
00129 inline hid_t hdf5Type();
00130 
00131 template<> inline hid_t hdf5Type<unsigned char>()
00132     { return uintTypeHelper<unsigned char>(); }
00133 template<> inline hid_t hdf5Type<unsigned short>()
00134     { return uintTypeHelper<unsigned short>(); }
00135 template<> inline hid_t hdf5Type<unsigned int>()
00136     { return uintTypeHelper<unsigned int>(); }
00137 template<> inline hid_t hdf5Type<unsigned long>()
00138     { return uintTypeHelper<unsigned long>(); }
00139 template<> inline hid_t hdf5Type<unsigned long long>()
00140     { return uintTypeHelper<unsigned long long>(); }
00141 
00142 template<> inline hid_t hdf5Type<char>()
00143     { return uintTypeHelper<char>(); }
00144 template<> inline hid_t hdf5Type<short>()
00145     { return intTypeHelper<short>(); }
00146 template<> inline hid_t hdf5Type<int>()
00147     { return intTypeHelper<int>(); }
00148 template<> inline hid_t hdf5Type<long>()
00149     { return intTypeHelper<long>(); }
00150 template<> inline hid_t hdf5Type<long long>()
00151     { return intTypeHelper<long long>(); }
00152 
00153 template<> inline hid_t hdf5Type<float>()
00154     { return floatingTypeHelper<float>(); }
00155 template<> inline hid_t hdf5Type<double>()
00156     { return floatingTypeHelper<double>(); }
00157 // \endcond
00158 
00159 // implementation
00160 
00171 template<class T, class ShapeIterator>
00172 void create(
00173     const hid_t& groupHandle,
00174     const std::string& datasetName,
00175     ShapeIterator begin,
00176     ShapeIterator end,
00177     CoordinateOrder coordinateOrder
00178 ) {
00179     marray_detail::Assert(MARRAY_NO_ARG_TEST || groupHandle >= 0);
00180     HandleCheck<MARRAY_NO_DEBUG> handleCheck;
00181 
00182     // build dataspace
00183     hid_t datatype = H5Tcopy(hdf5Type<T>());
00184     size_t dimension = std::distance(begin, end);
00185     Vector<hsize_t> shape((size_t)(dimension));
00186     if(coordinateOrder == FirstMajorOrder) {
00187         // copy shape as is
00188         for(size_t j=0; j<dimension; ++j) {
00189             shape[j] = hsize_t(*begin);
00190             ++begin;
00191         }
00192     }
00193     else {
00194         // reverse shape
00195         for(size_t j=0; j<dimension; ++j) {
00196             shape[dimension-j-1] = hsize_t(*begin);
00197             ++begin;
00198         }
00199     }
00200     hid_t dataspace = H5Screate_simple(dimension, &shape[0], NULL);
00201     if(dataspace < 0) {
00202         H5Tclose(datatype);
00203         throw std::runtime_error("Marray cannot create dataspace.");
00204     }
00205 
00206 
00207     // create new dataset
00208     hid_t dataset = H5Dcreate(groupHandle, datasetName.c_str(), datatype,
00209         dataspace, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
00210     if(dataset < 0) {
00211         H5Sclose(dataspace);
00212         H5Tclose(datatype);
00213         throw std::runtime_error("Marray cannot create dataset.");
00214     }
00215 
00216     // write attribute to indicate whether shape is reversed
00217     if(coordinateOrder == LastMajorOrder) {
00218         hsize_t attributeShape[1] = {1};
00219         hid_t attributeDataspace = H5Screate_simple(1, attributeShape, NULL);
00220         if(attributeDataspace < 0) {
00221             H5Dclose(dataset);
00222             H5Sclose(dataspace);
00223             H5Tclose(datatype);
00224             throw std::runtime_error("Marray cannot create dataspace.");
00225         }
00226         hid_t attribute = H5Acreate(dataset, reverseShapeAttributeName,
00227             H5T_STD_U8LE, attributeDataspace, H5P_DEFAULT, H5P_DEFAULT);
00228         if(attribute < 0) {
00229             H5Sclose(attributeDataspace);
00230             H5Dclose(dataset);
00231             H5Sclose(dataspace);
00232             H5Tclose(datatype);
00233             throw std::runtime_error("Marray cannot create attribute.");
00234         }
00235         unsigned int data = 1;
00236         herr_t err = H5Awrite(attribute, H5T_STD_U8LE, &data);
00237         H5Aclose(attribute);
00238         H5Sclose(attributeDataspace);
00239         if(err < 0) {
00240             H5Dclose(dataset);
00241             H5Sclose(dataspace);
00242             H5Tclose(datatype);
00243             throw std::runtime_error("Marray cannot create write to attribute.");
00244         }
00245     }
00246 
00247     // clean up
00248     H5Dclose(dataset);
00249     H5Sclose(dataspace);
00250     H5Tclose(datatype);
00251     handleCheck.check();
00252 }
00253 
00262 template<class T>
00263 void save(
00264     const hid_t& groupHandle,
00265     const std::string& datasetName,
00266     const Marray<T>& in
00267 ) {
00268     marray_detail::Assert(MARRAY_NO_ARG_TEST || groupHandle >= 0);
00269     HandleCheck<MARRAY_NO_DEBUG> handleCheck;
00270 
00271     // build dataspace
00272     hid_t datatype = H5Tcopy(hdf5Type<T>());
00273     Vector<hsize_t> shape(in.dimension());
00274     if(in.coordinateOrder() == FirstMajorOrder) {
00275         // copy shape as is
00276         for(size_t j=0; j<in.dimension(); ++j) {
00277             shape[j] = hsize_t(in.shape(j));
00278         }
00279     }
00280     else {
00281         // reverse shape
00282         for(size_t j=0; j<in.dimension(); ++j) {
00283             shape[size_t(in.dimension()-j-1)] = hsize_t(in.shape(j));
00284         }
00285     }
00286     hid_t dataspace = H5Screate_simple(in.dimension(), &shape[0], NULL);
00287     if(dataspace < 0) {
00288         H5Tclose(datatype);
00289         throw std::runtime_error("Marray cannot create dataspace.");
00290     }
00291 
00292     // create new dataset
00293     hid_t dataset = H5Dcreate(groupHandle, datasetName.c_str(), datatype,
00294         dataspace, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
00295     if(dataset < 0) {
00296         H5Sclose(dataspace);
00297         H5Tclose(datatype);
00298         throw std::runtime_error("Marray cannot create dataset.");
00299     }
00300 
00301     // write attribute to indicate whether shape is reversed
00302     if(in.coordinateOrder() == LastMajorOrder) {
00303         hsize_t attributeShape[1] = {1};
00304         hid_t attributeDataspace = H5Screate_simple(1, attributeShape, NULL);
00305         if(attributeDataspace < 0) {
00306             H5Dclose(dataset);
00307             H5Sclose(dataspace);
00308             H5Tclose(datatype);
00309             throw std::runtime_error("Marray cannot create dataspace.");
00310         }
00311         hid_t attribute = H5Acreate(dataset, reverseShapeAttributeName,
00312             H5T_STD_U8LE, attributeDataspace, H5P_DEFAULT, H5P_DEFAULT);
00313         if(attribute < 0) {
00314             H5Sclose(attributeDataspace);
00315             H5Dclose(dataset);
00316             H5Sclose(dataspace);
00317             H5Tclose(datatype);
00318             throw std::runtime_error("Marray cannot create attribute.");
00319         }
00320         unsigned int data = 1;
00321         herr_t err = H5Awrite(attribute, H5T_STD_U8LE, &data);
00322         H5Aclose(attribute);
00323         H5Sclose(attributeDataspace);
00324         if(err < 0) {
00325             H5Dclose(dataset);
00326             H5Sclose(dataspace);
00327             H5Tclose(datatype);
00328             throw std::runtime_error("Marray cannot create write to attribute.");
00329         }
00330     }
00331 
00332     // write
00333     herr_t status = H5Dwrite(dataset, datatype, H5S_ALL, H5S_ALL,
00334         H5P_DEFAULT, &in(0));
00335     H5Dclose(dataset);
00336     H5Sclose(dataspace);
00337     H5Tclose(datatype);
00338     if(status < 0) {
00339         throw std::runtime_error("Marray cannot write to dataset.");
00340     }
00341 
00342     handleCheck.check();
00343 }
00344 
00353 template<class T, bool isConst>
00354 inline void save(
00355     const hid_t& groupHandle,
00356     const std::string& datasetName,
00357     const View<T, isConst>& in
00358 ) {
00359     Marray<T> m = in;
00360     save(groupHandle, datasetName, m);
00361 }
00362 
00371 template<class T>
00372 void save(
00373     const hid_t& groupHandle,
00374     const std::string& datasetName,
00375     const std::vector<T>& in
00376 )
00377 {
00378     marray::Vector<T> v(in.size());
00379     for(size_t j=0; j<in.size(); ++j) {
00380         v[j] = in[j];
00381     }
00382     save(groupHandle, datasetName, v);
00383 }
00384 
00393 template<class T>
00394 void load(
00395     const hid_t& groupHandle,
00396     const std::string& datasetName,
00397     Marray<T>& out
00398 ) {
00399     marray_detail::Assert(MARRAY_NO_ARG_TEST || groupHandle >= 0);
00400     HandleCheck<MARRAY_NO_DEBUG> handleCheck;
00401 
00402     hid_t dataset = H5Dopen(groupHandle, datasetName.c_str(), H5P_DEFAULT);
00403     if(dataset < 0) {
00404         throw std::runtime_error("Marray cannot open dataset.");
00405     }
00406     hid_t filespace = H5Dget_space(dataset);
00407     hid_t type = H5Dget_type(dataset);
00408     hid_t nativeType = H5Tget_native_type(type, H5T_DIR_DESCEND);
00409     if(!H5Tequal(nativeType, hdf5Type<T>())) {
00410         H5Dclose(dataset);
00411         H5Tclose(nativeType);
00412         H5Tclose(type);
00413         H5Sclose(filespace);
00414         throw std::runtime_error("Data types not equal error.");
00415     }
00416     int dimension = H5Sget_simple_extent_ndims(filespace);
00417     Vector<hsize_t> shape(dimension);
00418     herr_t status = H5Sget_simple_extent_dims(filespace, &shape[0], NULL);
00419     if(status < 0) {
00420         H5Dclose(dataset);
00421         H5Tclose(nativeType);
00422         H5Tclose(type);
00423         H5Sclose(filespace);
00424         throw std::runtime_error("H5Sget_simple_extent_dims error.");
00425     }
00426     hid_t memspace = H5Screate_simple(dimension, &shape[0], NULL);
00427 
00428     // resize marray
00429     marray::Vector<size_t> newShape((size_t)(dimension));
00430     for(size_t j=0; j<newShape.size(); ++j) {
00431         newShape(j) = (size_t)(shape[j]);
00432     }
00433     if(H5Aexists(dataset, reverseShapeAttributeName) > 0) {
00434         // reverse shape
00435         out = Marray<T>(SkipInitialization, newShape.rbegin(), 
00436             newShape.rend(), LastMajorOrder);
00437     }
00438     else {
00439         // don't reverse shape
00440         out = Marray<T>(SkipInitialization, newShape.begin(),
00441             newShape.end(), FirstMajorOrder);
00442     }
00443 
00444     // read
00445     status = H5Dread(dataset, nativeType, memspace, filespace,
00446         H5P_DEFAULT, &out(0));
00447     H5Dclose(dataset);
00448     H5Tclose(nativeType);
00449     H5Tclose(type);
00450     H5Sclose(memspace);
00451     H5Sclose(filespace);
00452     if(status < 0) {
00453         throw std::runtime_error("Marray cannot read from dataset.");
00454     }
00455 
00456     handleCheck.check();
00457 }
00458 
00467 template<class T>
00468 void loadShape(
00469    const hid_t& groupHandle,
00470    const std::string& datasetName,
00471    Vector<T>& out
00472 ) {
00473     marray_detail::Assert(MARRAY_NO_ARG_TEST || groupHandle >= 0);
00474     HandleCheck<MARRAY_NO_DEBUG> handleCheck;
00475 
00476     // load shape from HDF5 file
00477     hid_t dataset = H5Dopen(groupHandle, datasetName.c_str(), H5P_DEFAULT);
00478     if(dataset < 0) {
00479         throw std::runtime_error("Marray cannot open dataset.");
00480     }
00481     hid_t filespace = H5Dget_space(dataset);
00482     hsize_t dimension = H5Sget_simple_extent_ndims(filespace);
00483     hsize_t* shape = new hsize_t[(size_t)(dimension)];
00484     herr_t status = H5Sget_simple_extent_dims(filespace, shape, NULL);
00485     if(status < 0) {
00486         H5Dclose(dataset);
00487         H5Sclose(filespace);
00488         delete[] shape;
00489         throw std::runtime_error("Marray cannot get extension of dataset.");
00490     }
00491 
00492     // write shape to out
00493     out = Vector<T>((size_t)(dimension));
00494     if(H5Aexists(dataset, reverseShapeAttributeName) > 0) {
00495         for(size_t j=0; j<out.size(); ++j) {
00496            out[out.size()-j-1] = T(shape[j]);
00497         }
00498     }
00499     else {
00500         for(size_t j=0; j<out.size(); ++j) {
00501             out[j] = T(shape[j]);
00502         }
00503     }
00504 
00505     // clean up
00506     delete[] shape;
00507     H5Dclose(dataset);
00508     H5Sclose(filespace);
00509     handleCheck.check();
00510 }
00511 
00523 template<class T, class BaseIterator, class ShapeIterator>
00524 void loadHyperslab(
00525     const hid_t& groupHandle,
00526     const std::string& datasetName,
00527     BaseIterator baseBegin,
00528     BaseIterator baseEnd,
00529     ShapeIterator shapeBegin,
00530     Marray<T>& out
00531 ) {
00532     marray_detail::Assert(MARRAY_NO_ARG_TEST || groupHandle >= 0);
00533     HandleCheck<MARRAY_NO_DEBUG> handleCheck;
00534 
00535     // open dataset
00536     hid_t dataset = H5Dopen(groupHandle, datasetName.c_str(), H5P_DEFAULT);
00537     if(dataset < 0) {
00538         throw std::runtime_error("Marray cannot open dataset.");
00539     }
00540 
00541     // determine shape of hyperslab and array
00542     size_t size = std::distance(baseBegin, baseEnd);
00543     Vector<hsize_t> offset(size);
00544     Vector<hsize_t> slabShape(size);
00545     Vector<hsize_t> marrayShape(size);
00546     CoordinateOrder coordinateOrder;
00547     if(H5Aexists(dataset, reverseShapeAttributeName) > 0) {
00548         // reverse base and shape
00549         coordinateOrder = LastMajorOrder;
00550         size_t j = size-1;
00551         size_t k = 0;
00552         for(;;) {
00553             offset[j] = hsize_t(*baseBegin);
00554             slabShape[j] = hsize_t(*shapeBegin);
00555             marrayShape[k] = slabShape[j];
00556             if(j == 0) {
00557                 break;
00558             }
00559             else {
00560                 ++baseBegin;
00561                 ++shapeBegin;
00562                 ++k;
00563                 --j;
00564             }
00565         }
00566     } 
00567     else {
00568         // don't reverse base and shape
00569         coordinateOrder = FirstMajorOrder;
00570         for(size_t j=0; j<size; ++j) {
00571             offset[j] = hsize_t(*baseBegin);
00572             slabShape[j] = hsize_t(*shapeBegin);
00573             marrayShape[j] = slabShape[j];
00574             ++baseBegin;
00575             ++shapeBegin;
00576         }
00577     }
00578     
00579     // select dataspace hyperslab
00580     hid_t datatype = H5Dget_type(dataset);
00581     
00582     if(!H5Tequal(datatype, hdf5Type<T>())) {
00583         throw std::runtime_error("data type of stored hdf5 dataset and passed array do not match in loadHyperslab");
00584     }
00585     
00586     hid_t dataspace = H5Dget_space(dataset);
00587     herr_t status = H5Sselect_hyperslab(dataspace, H5S_SELECT_SET, 
00588         &offset[0], NULL, &slabShape[0], NULL);
00589     if(status < 0) {
00590         H5Tclose(datatype);
00591         H5Sclose(dataspace);
00592         H5Dclose(dataset);
00593         throw std::runtime_error("Marray cannot select hyperslab. Check offset and shape!");
00594     }
00595 
00596     // select memspace hyperslab
00597     hid_t memspace = H5Screate_simple(int(size), &marrayShape[0], NULL);
00598     Vector<hsize_t> offsetOut(size, 0); // no offset
00599     status = H5Sselect_hyperslab(memspace, H5S_SELECT_SET, &offsetOut[0],
00600         NULL, &marrayShape[0], NULL);
00601     if(status < 0) {
00602         H5Sclose(memspace); 
00603         H5Tclose(datatype);
00604         H5Sclose(dataspace);
00605         H5Dclose(dataset);
00606         throw std::runtime_error("Marray cannot select hyperslab. Check offset and shape!");
00607     }
00608 
00609     // read from dataspace into memspace
00610     out = Marray<T>(SkipInitialization, &marrayShape[0], 
00611         (&marrayShape[0])+size, coordinateOrder);
00612     status = H5Dread(dataset, datatype, memspace, dataspace,
00613         H5P_DEFAULT, &(out(0)));
00614 
00615     // clean up
00616     H5Sclose(memspace); 
00617     H5Tclose(datatype);
00618     H5Sclose(dataspace);
00619     H5Dclose(dataset);
00620     if(status < 0) {
00621         throw std::runtime_error("Marray cannot read from dataset.");
00622     }
00623     handleCheck.check();
00624 }
00625 
00637 template<class T, class BaseIterator, class ShapeIterator>
00638 void 
00639 saveHyperslab(
00640     const hid_t& groupHandle,
00641     const std::string& datasetName,
00642     BaseIterator baseBegin,
00643     BaseIterator baseEnd,
00644     ShapeIterator shapeBegin,
00645     const Marray<T>& in
00646 ) {
00647     marray_detail::Assert(MARRAY_NO_ARG_TEST || groupHandle >= 0);
00648     HandleCheck<MARRAY_NO_DEBUG> handleCheck;
00649 
00650     // open dataset
00651     hid_t dataset = H5Dopen(groupHandle, datasetName.c_str(), H5P_DEFAULT);
00652     if(dataset < 0) {
00653         throw std::runtime_error("Marray cannot open dataset.");
00654     }
00655 
00656     // determine hyperslab shape
00657     Vector<hsize_t> memoryShape(in.dimension());
00658     for(size_t j=0; j<in.dimension(); ++j) {
00659         memoryShape[j] = in.shape(j);
00660     }
00661     size_t size = std::distance(baseBegin, baseEnd);
00662     Vector<hsize_t> offset(size);
00663     Vector<hsize_t> slabShape(size);
00664     bool reverseShapeAttribute = 
00665         (H5Aexists(dataset, reverseShapeAttributeName) > 0);
00666     if(reverseShapeAttribute && in.coordinateOrder() == LastMajorOrder) {
00667         // reverse base and shape
00668         size_t j = size-1;
00669         for(;;) {
00670             offset[j] = hsize_t(*baseBegin);
00671             slabShape[j] = hsize_t(*shapeBegin);
00672             if(j == 0) {
00673                 break;
00674             }
00675             else {
00676                 ++baseBegin;
00677                 ++shapeBegin;
00678                 --j;
00679             }
00680         }
00681     }
00682     else if(!reverseShapeAttribute && in.coordinateOrder() == FirstMajorOrder) {
00683         for(size_t j=0; j<size; ++j) {
00684             offset[j] = hsize_t(*baseBegin);
00685             slabShape[j] = hsize_t(*shapeBegin);
00686             ++baseBegin;
00687             ++shapeBegin;
00688         }
00689     }
00690     else {
00691         H5Dclose(dataset);
00692         throw std::runtime_error("Marray cannot write to HDF5 file. A different order was used when the file was created.");
00693     }
00694 
00695     // select dataspace hyperslab
00696     hid_t datatype = H5Dget_type(dataset);
00697     hid_t dataspace = H5Dget_space(dataset);
00698     herr_t status = H5Sselect_hyperslab(dataspace, H5S_SELECT_SET, 
00699         &offset[0], NULL, &slabShape[0], NULL);
00700     if(status < 0) {
00701         H5Tclose(datatype);
00702         H5Sclose(dataspace);
00703         H5Dclose(dataset);
00704         throw std::runtime_error("Marray cannot select hyperslab. Check offset and shape!");
00705     }
00706 
00707     // select memspace hyperslab
00708     hid_t memspace = H5Screate_simple(int(in.dimension()), &memoryShape[0], NULL);
00709     Vector<hsize_t> memoryOffset(int(in.dimension()), 0); // no offset
00710     status = H5Sselect_hyperslab(memspace, H5S_SELECT_SET, &memoryOffset[0], NULL,
00711         &memoryShape[0], NULL);
00712     if(status < 0) {
00713         H5Sclose(memspace); 
00714         H5Tclose(datatype);
00715         H5Sclose(dataspace);
00716         H5Dclose(dataset);
00717         throw std::runtime_error("Marray cannot select hyperslab. Check offset and shape!");
00718     }
00719 
00720     // write from memspace to dataspace
00721     status = H5Dwrite(dataset, datatype, memspace, dataspace, H5P_DEFAULT, &(in(0)));
00722 
00723     // clean up
00724     H5Sclose(memspace); 
00725     H5Tclose(datatype);
00726     H5Sclose(dataspace);
00727     H5Dclose(dataset);
00728     if(status < 0) {
00729         throw std::runtime_error("Marray cannot write to dataset.");
00730     }
00731     handleCheck.check();
00732 }
00733 
00743 inline hid_t
00744 createFile
00745 (
00746     const std::string& filename,
00747     HDF5Version hdf5version
00748 )
00749 {
00750     hid_t version = H5P_DEFAULT;
00751     if(hdf5version == LATEST_HDF5_VERSION) {
00752         version = H5Pcreate(H5P_FILE_ACCESS);
00753         H5Pset_libver_bounds(version, H5F_LIBVER_LATEST, H5F_LIBVER_LATEST);
00754     }
00755 
00756     hid_t fileHandle = H5Fcreate(filename.c_str(), H5F_ACC_TRUNC, H5P_DEFAULT, version);
00757     if(fileHandle < 0) {
00758         throw std::runtime_error("Could not create HDF5 file: " + filename);
00759     }
00760 
00761     return fileHandle;
00762 }
00763 
00774 inline hid_t
00775 openFile
00776 (
00777     const std::string& filename,
00778     FileAccessMode fileAccessMode,
00779     HDF5Version hdf5version
00780 )
00781 {
00782     hid_t access = H5F_ACC_RDONLY;
00783     if(fileAccessMode == READ_WRITE) {
00784         access = H5F_ACC_RDWR;
00785     }
00786 
00787     hid_t version = H5P_DEFAULT;
00788     if(hdf5version == LATEST_HDF5_VERSION) {
00789         version = H5Pcreate(H5P_FILE_ACCESS);
00790         H5Pset_libver_bounds(version, H5F_LIBVER_LATEST, H5F_LIBVER_LATEST);
00791     }
00792 
00793     hid_t fileHandle = H5Fopen(filename.c_str(), access, version);
00794     if(fileHandle < 0) {
00795         throw std::runtime_error("Could not open HDF5 file: " + filename);
00796     }
00797 
00798     return fileHandle;
00799 }
00800 
00807 inline void closeFile
00808 (
00809     const hid_t& handle
00810 )
00811 {
00812     H5Fclose(handle);
00813 }
00814 
00823 inline hid_t 
00824 createGroup
00825 (
00826     const hid_t& parentHandle,
00827     const std::string& groupName
00828 )
00829 { 
00830     hid_t groupHandle = H5Gcreate(parentHandle, groupName.c_str(), 
00831         H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
00832     if(groupHandle < 0) {
00833         throw std::runtime_error("Could not create HDF5 group.");
00834     }
00835     return groupHandle;
00836 }
00837 
00846 inline hid_t 
00847 openGroup
00848 (
00849     const hid_t& parentHandle,
00850     const std::string& groupName
00851 )
00852 { 
00853     hid_t groupHandle = H5Gopen(parentHandle, groupName.c_str(), H5P_DEFAULT);
00854     if(groupHandle < 0) {
00855         throw std::runtime_error("Could not open HDF5 group.");
00856     }
00857     return groupHandle;
00858 }
00859 
00866 inline void 
00867 closeGroup
00868 (
00869     const hid_t& handle
00870 )
00871 {
00872     H5Gclose(handle);
00873 }
00874 
00875 } // namespace hdf5
00876 } // namespace marray
00877 
00878 #endif // #ifndef MARRAY_HDF5_HXX
00879 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
Generated on Mon Jun 17 16:31:04 2013 for OpenGM by  doxygen 1.6.3