00001 #pragma once
00002 #ifndef MARRAY_HDF5_HXX
00003 #define MARRAY_HDF5_HXX
00004
00005
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
00025
00026
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
00042
00043
00044
00045 const char reverseShapeAttributeName[14] = "reverse-shape";
00046
00047
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
00082
00083
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
00158
00159
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
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
00188 for(size_t j=0; j<dimension; ++j) {
00189 shape[j] = hsize_t(*begin);
00190 ++begin;
00191 }
00192 }
00193 else {
00194
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
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
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
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
00272 hid_t datatype = H5Tcopy(hdf5Type<T>());
00273 Vector<hsize_t> shape(in.dimension());
00274 if(in.coordinateOrder() == FirstMajorOrder) {
00275
00276 for(size_t j=0; j<in.dimension(); ++j) {
00277 shape[j] = hsize_t(in.shape(j));
00278 }
00279 }
00280 else {
00281
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
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
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
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
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
00435 out = Marray<T>(SkipInitialization, newShape.rbegin(),
00436 newShape.rend(), LastMajorOrder);
00437 }
00438 else {
00439
00440 out = Marray<T>(SkipInitialization, newShape.begin(),
00441 newShape.end(), FirstMajorOrder);
00442 }
00443
00444
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
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
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
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
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
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
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
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
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
00597 hid_t memspace = H5Screate_simple(int(size), &marrayShape[0], NULL);
00598 Vector<hsize_t> offsetOut(size, 0);
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
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
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
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
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
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
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
00708 hid_t memspace = H5Screate_simple(int(in.dimension()), &memoryShape[0], NULL);
00709 Vector<hsize_t> memoryOffset(int(in.dimension()), 0);
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
00721 status = H5Dwrite(dataset, datatype, memspace, dataspace, H5P_DEFAULT, &(in(0)));
00722
00723
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 }
00876 }
00877
00878 #endif // #ifndef MARRAY_HDF5_HXX
00879