36 #ifndef VIGRA_HDF5IMPEX_HXX
37 #define VIGRA_HDF5IMPEX_HXX
41 #define H5Gcreate_vers 2
42 #define H5Gopen_vers 2
43 #define H5Dopen_vers 2
44 #define H5Dcreate_vers 2
45 #define H5Acreate_vers 2
49 #if (H5_VERS_MAJOR == 1 && H5_VERS_MINOR <= 6)
51 # define H5Gopen(a, b, c) H5Gopen(a, b)
54 # define H5Gcreate(a, b, c, d, e) H5Gcreate(a, b, 1)
57 # define H5Dopen(a, b, c) H5Dopen(a, b)
60 # define H5Dcreate(a, b, c, d, e, f, g) H5Dcreate(a, b, c, d, f)
63 # define H5Acreate(a, b, c, d, e, f) H5Acreate(a, b, c, d, e)
65 # ifndef H5Pset_obj_track_times
66 # define H5Pset_obj_track_times(a, b) do {} while (0)
74 #include "multi_array.hxx"
75 #include "multi_impex.hxx"
76 #include "utilities.hxx"
117 typedef herr_t (*Destructor)(hid_t);
121 Destructor destructor_;
152 HDF5Handle(hid_t h, Destructor destructor,
const char * error_message)
154 destructor_(destructor)
157 vigra_fail(error_message);
164 : handle_( h.handle_ ),
165 destructor_(h.destructor_)
176 if(h.handle_ != handle_)
180 destructor_ = h.destructor_;
200 if(handle_ && destructor_)
201 res = (*destructor_)(handle_);
221 operator hid_t()
const
230 return handle_ == h.handle_;
244 return handle_ != h.handle_;
274 enum PixelType { UINT8, UINT16, UINT32, UINT64,
275 INT8, INT16, INT32, INT64,
288 VIGRA_EXPORT
HDF5ImportInfo(
const char* filePath,
const char* pathInFile );
290 VIGRA_EXPORT ~HDF5ImportInfo();
294 VIGRA_EXPORT
const std::string&
getFilePath()
const;
355 VIGRA_EXPORT PixelType
pixelType()
const;
359 std::string m_filename, m_path, m_pixeltype;
360 hssize_t m_dimensions;
368 inline hid_t getH5DataType()
370 std::runtime_error(
"getH5DataType(): invalid type");
374 #define VIGRA_H5_DATATYPE(type, h5type) \
376 inline hid_t getH5DataType<type>() \
379 VIGRA_H5_DATATYPE(
char, H5T_NATIVE_CHAR)
380 VIGRA_H5_DATATYPE(
float, H5T_NATIVE_FLOAT)
381 VIGRA_H5_DATATYPE(
double, H5T_NATIVE_DOUBLE)
382 VIGRA_H5_DATATYPE(
long double, H5T_NATIVE_LDOUBLE)
386 inline hid_t getH5DataType<
char*>()
388 hid_t stringtype = H5Tcopy (H5T_C_S1);
389 H5Tset_size(stringtype, H5T_VARIABLE);
393 inline hid_t getH5DataType<const char*>()
395 hid_t stringtype = H5Tcopy (H5T_C_S1);
396 H5Tset_size(stringtype, H5T_VARIABLE);
399 #undef VIGRA_H5_DATATYPE
401 #define VIGRA_H5_SIGNED_DATATYPE(type) \
403 inline hid_t getH5DataType<type>() \
404 { static hid_t types[] = {0, H5T_NATIVE_INT8, H5T_NATIVE_INT16, 0, H5T_NATIVE_INT32, 0,0,0,H5T_NATIVE_INT64}; \
405 return types[sizeof(type)];}
407 VIGRA_H5_SIGNED_DATATYPE(
signed char)
408 VIGRA_H5_SIGNED_DATATYPE(
signed short)
409 VIGRA_H5_SIGNED_DATATYPE(
signed int)
410 VIGRA_H5_SIGNED_DATATYPE(
signed long)
411 VIGRA_H5_SIGNED_DATATYPE(
signed long long)
413 #undef VIGRA_H5_SIGNED_DATATYPE
415 #define VIGRA_H5_UNSIGNED_DATATYPE(type) \
417 inline hid_t getH5DataType<type>() \
418 { static hid_t types[] = {0, H5T_NATIVE_UINT8, H5T_NATIVE_UINT16, 0, H5T_NATIVE_UINT32, 0,0,0,H5T_NATIVE_UINT64}; \
419 return types[sizeof(type)];}
421 VIGRA_H5_UNSIGNED_DATATYPE(
unsigned char)
422 VIGRA_H5_UNSIGNED_DATATYPE(
unsigned short)
423 VIGRA_H5_UNSIGNED_DATATYPE(
unsigned int)
424 VIGRA_H5_UNSIGNED_DATATYPE(
unsigned long)
425 VIGRA_H5_UNSIGNED_DATATYPE(
unsigned long long)
427 #undef VIGRA_H5_UNSIGNED_DATATYPE
431 inline hid_t getH5DataType<FFTWComplex<float> >()
433 hid_t complex_id = H5Tcreate (H5T_COMPOUND,
sizeof (FFTWComplex<float>));
434 H5Tinsert (complex_id,
"real", 0, H5T_NATIVE_FLOAT);
435 H5Tinsert (complex_id,
"imaginary",
sizeof(
float), H5T_NATIVE_FLOAT);
440 inline hid_t getH5DataType<FFTWComplex<double> >()
442 hid_t complex_id = H5Tcreate (H5T_COMPOUND,
sizeof (FFTWComplex<double>));
443 H5Tinsert (complex_id,
"real", 0, H5T_NATIVE_DOUBLE);
444 H5Tinsert (complex_id,
"imaginary",
sizeof(
double), H5T_NATIVE_DOUBLE);
453 void HDF5_ls_insert(
void*,
const std::string &);
458 VIGRA_EXPORT H5O_type_t HDF5_get_type(hid_t,
const char*);
459 extern "C" VIGRA_EXPORT herr_t HDF5_ls_inserter_callback(hid_t,
const char*,
const H5L_info_t*,
void*);
508 virtual void insert(
const std::string &) = 0;
509 virtual ~ls_closure() {}
512 struct lsOpData :
public ls_closure
514 std::vector<std::string> & objects;
515 lsOpData(std::vector<std::string> & o) : objects(o) {}
516 void insert(
const std::string & x)
518 objects.push_back(x);
522 template<
class Container>
523 struct ls_container_data :
public ls_closure
526 ls_container_data(Container & o) : objects(o) {}
527 void insert(
const std::string & x)
529 objects.insert(std::string(x));
536 friend void HDF5_ls_insert(
void*,
const std::string &);
558 : track_time(track_creation_times)
560 std::string errorMessage =
"HDF5File: Could not create file '" + filename +
"'.";
561 fileHandle_ =
HDF5Handle(createFile_(filename, mode), &H5Fclose, errorMessage.c_str());
562 cGroupHandle_ =
HDF5Handle(openCreateGroup_(
"/"), &H5Gclose,
"HDF5File(): Failed to open root group.");
573 H5Fflush(fileHandle_, H5F_SCOPE_GLOBAL);
583 std::string message =
"HDF5File::root(): Could not open group '/'.";
584 cGroupHandle_ =
HDF5Handle(H5Gopen(fileHandle_,
"/", H5P_DEFAULT),&H5Gclose,message.c_str());
593 inline void cd(std::string groupName)
595 std::string message =
"HDF5File::cd(): Could not open group '" + groupName +
"'.\n";
600 if(groupName ==
"/"){
601 cGroupHandle_ =
HDF5Handle(openCreateGroup_(
"/"),&H5Gclose,message.c_str());
605 if (H5Lexists(fileHandle_, groupName.c_str(), H5P_DEFAULT) == 0)
607 std::cerr << message;
610 cGroupHandle_ =
HDF5Handle(openCreateGroup_(groupName),&H5Gclose,message.c_str());
622 std::string groupName = currentGroupName_();
625 if(groupName ==
"/"){
629 size_t lastSlash = groupName.find_last_of(
'/');
631 std::string parentGroup (groupName.begin(), groupName.begin()+lastSlash+1);
637 inline void cd_up(
int levels)
639 for(
int i = 0; i<levels; i++)
650 inline void mkdir(std::string groupName)
655 hid_t handle = openCreateGroup_(groupName.c_str());
656 if (handle != cGroupHandle_){
668 inline void cd_mk(std::string groupName)
673 std::string message =
"HDF5File::cd_mk(): Could not create group '" + groupName +
"'.";
674 cGroupHandle_ =
HDF5Handle(openCreateGroup_(groupName.c_str()),&H5Gclose,message.c_str());
678 void ls_H5Literate(ls_closure & data)
680 H5Literate(cGroupHandle_, H5_INDEX_NAME, H5_ITER_NATIVE, NULL,
681 HDF5_ls_inserter_callback, static_cast<void*>(&data));
692 inline std::vector<std::string>
ls()
694 std::vector<std::string> list;
712 template<
class Container>
713 void ls(Container & cont)
715 ls_container_data<Container> data(cont);
724 return currentGroupName_();
746 std::string errorMessage =
"HDF5File::getDatasetDimensions(): Unable to open dataset '" + datasetName +
"'.";
747 HDF5Handle datasetHandle =
HDF5Handle(getDatasetHandle_(datasetName), &H5Dclose, errorMessage.c_str());
749 errorMessage =
"HDF5File::getDatasetDimensions(): Unable to access dataspace.";
750 HDF5Handle dataspaceHandle(H5Dget_space(datasetHandle), &H5Sclose, errorMessage.c_str());
753 return H5Sget_simple_extent_ndims(dataspaceHandle);
771 std::string errorMessage =
"HDF5File::getDatasetShape(): Unable to open dataset '" + datasetName +
"'.";
772 HDF5Handle datasetHandle =
HDF5Handle(getDatasetHandle_(datasetName), &H5Dclose, errorMessage.c_str());
774 errorMessage =
"HDF5File::getDatasetShape(): Unable to access dataspace.";
775 HDF5Handle dataspaceHandle(H5Dget_space(datasetHandle), &H5Sclose, errorMessage.c_str());
782 H5Sget_simple_extent_dims(dataspaceHandle, shape.
data(), maxdims.
data());
787 shape_inv[i] = shape[dimensions-1-i];
800 return getDatasetHandle_(dataset_name);
814 vigra_precondition((H5Lexists(fileHandle_, group_name.c_str(), H5P_DEFAULT) == 1),
"Error: Group '" + group_name +
"' does not exist.");
817 return openCreateGroup_( group_name);
827 HDF5Handle dset (getDatasetHandle_(dataset_name),&H5Dclose,std::string(
"Error: Dataset '"+dataset_name+
"' not found.").c_str());
829 return H5Aopen(dset, attribute_name.c_str(),H5P_DEFAULT);
840 template<
unsigned int N,
class T>
846 write_attribute_(object_name, attribute_name, array, detail::getH5DataType<T>(), 1);
851 template<
unsigned int N,
class T,
int SIZE>
857 write_attribute_(datasetName, attributeName, array, detail::getH5DataType<T>(), SIZE);
862 template<
unsigned int N,
class T>
863 inline void writeAttribute(std::string datasetName, std::string attributeName,
const MultiArrayView<N, RGBValue<T>, UnstridedArrayTag> & array)
868 write_attribute_(datasetName, attributeName, array, detail::getH5DataType<T>(), 3);
877 inline void writeAttribute(std::string object_name, std::string attribute_name,
char data)
878 { writeAtomicAttribute(object_name,attribute_name,data); }
879 inline void writeAttribute(std::string datasetName, std::string attributeName,
signed char data)
880 { writeAtomicAttribute(datasetName,attributeName,data); }
881 inline void writeAttribute(std::string datasetName, std::string attributeName,
signed short data)
882 { writeAtomicAttribute(datasetName,attributeName,data); }
883 inline void writeAttribute(std::string datasetName, std::string attributeName,
signed int data)
884 { writeAtomicAttribute(datasetName,attributeName,data); }
885 inline void writeAttribute(std::string datasetName, std::string attributeName,
signed long data)
886 { writeAtomicAttribute(datasetName,attributeName,data); }
887 inline void writeAttribute(std::string datasetName, std::string attributeName,
signed long long data)
888 { writeAtomicAttribute(datasetName,attributeName,data); }
889 inline void writeAttribute(std::string datasetName, std::string attributeName,
unsigned char data)
890 { writeAtomicAttribute(datasetName,attributeName,data); }
891 inline void writeAttribute(std::string datasetName, std::string attributeName,
unsigned short data)
892 { writeAtomicAttribute(datasetName,attributeName,data); }
893 inline void writeAttribute(std::string datasetName, std::string attributeName,
unsigned int data)
894 { writeAtomicAttribute(datasetName,attributeName,data); }
895 inline void writeAttribute(std::string datasetName, std::string attributeName,
unsigned long data)
896 { writeAtomicAttribute(datasetName,attributeName,data); }
897 inline void writeAttribute(std::string datasetName, std::string attributeName,
unsigned long long data)
898 { writeAtomicAttribute(datasetName,attributeName,data); }
899 inline void writeAttribute(std::string datasetName, std::string attributeName,
float data)
900 { writeAtomicAttribute(datasetName,attributeName,data); }
901 inline void writeAttribute(std::string datasetName, std::string attributeName,
double data)
902 { writeAtomicAttribute(datasetName,attributeName,data); }
903 inline void writeAttribute(std::string datasetName, std::string attributeName,
long double data)
904 { writeAtomicAttribute(datasetName,attributeName,data); }
905 inline void writeAttribute(std::string datasetName, std::string attributeName,
const char* data)
906 { writeAtomicAttribute(datasetName,attributeName,data); }
907 inline void writeAttribute(std::string datasetName, std::string attributeName, std::string
const & data)
908 { writeAtomicAttribute(datasetName,attributeName,data.c_str()); }
916 htri_t exists = H5Aexists_by_name(fileHandle_, obj_path.c_str(),
917 attribute_name.c_str(), H5P_DEFAULT);
918 vigra_precondition(exists >= 0,
"HDF5File::existsAttribute(): "
919 "object \"" + object_name +
"\" "
929 template<
unsigned int N,
class T>
935 read_attribute_(object_name, attribute_name, array, detail::getH5DataType<T>(), 1);
940 template<
unsigned int N,
class T,
int SIZE>
946 read_attribute_(datasetName, attributeName, array, detail::getH5DataType<T>(), SIZE);
951 template<
unsigned int N,
class T>
952 inline void readAttribute(std::string datasetName, std::string attributeName,
const MultiArrayView<N, RGBValue<T>, UnstridedArrayTag> & array)
957 read_attribute_(datasetName, attributeName, array, detail::getH5DataType<T>(), 3);
966 inline void readAttribute(std::string object_name, std::string attribute_name,
char &data)
967 { readAtomicAttribute(object_name,attribute_name,data); }
968 inline void readAttribute(std::string datasetName, std::string attributeName,
signed char &data)
969 { readAtomicAttribute(datasetName,attributeName,data); }
970 inline void readAttribute(std::string datasetName, std::string attributeName,
signed short &data)
971 { readAtomicAttribute(datasetName,attributeName,data); }
972 inline void readAttribute(std::string datasetName, std::string attributeName,
signed int &data)
973 { readAtomicAttribute(datasetName,attributeName,data); }
974 inline void readAttribute(std::string datasetName, std::string attributeName,
signed long &data)
975 { readAtomicAttribute(datasetName,attributeName,data); }
976 inline void readAttribute(std::string datasetName, std::string attributeName,
signed long long &data)
977 { readAtomicAttribute(datasetName,attributeName,data); }
978 inline void readAttribute(std::string datasetName, std::string attributeName,
unsigned char &data)
979 { readAtomicAttribute(datasetName,attributeName,data); }
980 inline void readAttribute(std::string datasetName, std::string attributeName,
unsigned short &data)
981 { readAtomicAttribute(datasetName,attributeName,data); }
982 inline void readAttribute(std::string datasetName, std::string attributeName,
unsigned int &data)
983 { readAtomicAttribute(datasetName,attributeName,data); }
984 inline void readAttribute(std::string datasetName, std::string attributeName,
unsigned long &data)
985 { readAtomicAttribute(datasetName,attributeName,data); }
986 inline void readAttribute(std::string datasetName, std::string attributeName,
unsigned long long &data)
987 { readAtomicAttribute(datasetName,attributeName,data); }
988 inline void readAttribute(std::string datasetName, std::string attributeName,
float &data)
989 { readAtomicAttribute(datasetName,attributeName,data); }
990 inline void readAttribute(std::string datasetName, std::string attributeName,
double &data)
991 { readAtomicAttribute(datasetName,attributeName,data); }
992 inline void readAttribute(std::string datasetName, std::string attributeName,
long double &data)
993 { readAtomicAttribute(datasetName,attributeName,data); }
994 inline void readAttribute(std::string datasetName, std::string attributeName, std::string &data)
995 { readAtomicAttribute(datasetName,attributeName,data); }
1017 template<
unsigned int N,
class T>
1024 for(
int i = 0; i < N; i++){
1025 chunkSize[i] = iChunkSize;
1027 write_(datasetName, array, detail::getH5DataType<T>(), 1, chunkSize, compression);
1044 template<
unsigned int N,
class T>
1050 write_(datasetName, array, detail::getH5DataType<T>(), 1, chunkSize, compression);
1069 template<
unsigned int N,
class T>
1075 writeBlock_(datasetName, blockOffset, array, detail::getH5DataType<T>(), 1);
1082 template<
unsigned int N,
class T,
int SIZE>
1089 for(
int i = 0; i < N; i++){
1090 chunkSize[i] = iChunkSize;
1092 write_(datasetName, array, detail::getH5DataType<T>(), SIZE, chunkSize, compression);
1097 template<
unsigned int N,
class T,
int SIZE>
1098 inline void write(std::string datasetName,
const MultiArrayView<N, TinyVector<T, SIZE>, UnstridedArrayTag> & array,
typename MultiArrayShape<N>::type chunkSize,
int compression = 0)
1103 write_(datasetName, array, detail::getH5DataType<T>(), SIZE, chunkSize, compression);
1118 void write(
const std::string & datasetName,
1120 int compression = 0)
1125 write(datasetName, m_array, compression);
1129 template<
unsigned int N,
class T,
int SIZE>
1135 writeBlock_(datasetName, blockOffset, array, detail::getH5DataType<T>(), SIZE);
1142 template<
unsigned int N,
class T>
1143 inline void write(std::string datasetName,
const MultiArrayView<N, RGBValue<T>, UnstridedArrayTag> & array,
int iChunkSize = 0,
int compression = 0)
1148 typename MultiArrayShape<N>::type chunkSize;
1149 for(
int i = 0; i < N; i++){
1150 chunkSize[i] = iChunkSize;
1152 write_(datasetName, array, detail::getH5DataType<T>(), 3, chunkSize, compression);
1157 template<
unsigned int N,
class T>
1158 inline void write(std::string datasetName,
const MultiArrayView<N, RGBValue<T>, UnstridedArrayTag> & array,
typename MultiArrayShape<N>::type chunkSize,
int compression = 0)
1163 write_(datasetName, array, detail::getH5DataType<T>(), 3, chunkSize, compression);
1168 template<
unsigned int N,
class T>
1169 inline void writeBlock(std::string datasetName,
typename MultiArrayShape<N>::type blockOffset,
const MultiArrayView<N, RGBValue<T>, UnstridedArrayTag> & array)
1174 writeBlock_(datasetName, blockOffset, array, detail::getH5DataType<T>(), 3);
1183 inline void write(std::string datasetName,
char data) { writeAtomic(datasetName,data); }
1184 inline void write(std::string datasetName,
signed char data) { writeAtomic(datasetName,data); }
1185 inline void write(std::string datasetName,
signed short data) { writeAtomic(datasetName,data); }
1186 inline void write(std::string datasetName,
signed int data) { writeAtomic(datasetName,data); }
1187 inline void write(std::string datasetName,
signed long data) { writeAtomic(datasetName,data); }
1188 inline void write(std::string datasetName,
signed long long data) { writeAtomic(datasetName,data); }
1189 inline void write(std::string datasetName,
unsigned char data) { writeAtomic(datasetName,data); }
1190 inline void write(std::string datasetName,
unsigned short data) { writeAtomic(datasetName,data); }
1191 inline void write(std::string datasetName,
unsigned int data) { writeAtomic(datasetName,data); }
1192 inline void write(std::string datasetName,
unsigned long data) { writeAtomic(datasetName,data); }
1193 inline void write(std::string datasetName,
unsigned long long data) { writeAtomic(datasetName,data); }
1194 inline void write(std::string datasetName,
float data) { writeAtomic(datasetName,data); }
1195 inline void write(std::string datasetName,
double data) { writeAtomic(datasetName,data); }
1196 inline void write(std::string datasetName,
long double data) { writeAtomic(datasetName,data); }
1197 inline void write(std::string datasetName,
const char* data) { writeAtomic(datasetName,data); }
1198 inline void write(std::string datasetName, std::string
const & data) { writeAtomic(datasetName,data.c_str()); }
1210 template<
unsigned int N,
class T>
1216 read_(datasetName, array, detail::getH5DataType<T>(), 1);
1225 template<
unsigned int N,
class T>
1237 "HDF5File::readAndResize(): Array dimension disagrees with dataset dimension.");
1247 read_(datasetName, array, detail::getH5DataType<T>(), 1);
1260 read(datasetName, m_array);
1280 "HDF5File::readAndResize(): Array dimension disagrees with Dataset dimension must equal one for vigra::ArrayVector.");
1287 read_(datasetName, m_array, detail::getH5DataType<T>(), 1);
1300 template<
unsigned int N,
class T>
1306 readBlock_(datasetName, blockOffset, blockShape, array, detail::getH5DataType<T>(), 1);
1313 template<
unsigned int N,
class T,
int SIZE>
1319 read_(datasetName, array, detail::getH5DataType<T>(), SIZE);
1325 template<
unsigned int N,
class T,
int SIZE>
1326 inline void readAndResize(std::string datasetName, MultiArray<N, TinyVector<T, SIZE> > & array)
1337 "HDF5File::readAndResize(): Array dimension disagrees with dataset dimension.");
1338 typename MultiArrayShape<N>::type shape;
1345 array.reshape(shape);
1347 read_(datasetName, array, detail::getH5DataType<T>(), SIZE);
1352 template<
unsigned int N,
class T,
int SIZE>
1353 inline void readBlock(std::string datasetName,
typename MultiArrayShape<N>::type blockOffset,
typename MultiArrayShape<N>::type blockShape, MultiArrayView<N, TinyVector<T, SIZE>, UnstridedArrayTag> & array)
1358 readBlock_(datasetName, blockOffset, blockShape, array, detail::getH5DataType<T>(), SIZE);
1365 template<
unsigned int N,
class T>
1366 inline void read(std::string datasetName, MultiArrayView<N, RGBValue<T>, UnstridedArrayTag> & array)
1371 read_(datasetName, array, detail::getH5DataType<T>(), 3);
1377 template<
unsigned int N,
class T>
1378 inline void readAndResize(std::string datasetName, MultiArray<N, RGBValue<T> > & array)
1389 "HDF5File::readAndResize(): Array dimension disagrees with dataset dimension.");
1390 typename MultiArrayShape<N>::type shape;
1397 array.reshape(shape);
1399 read_(datasetName, array, detail::getH5DataType<T>(), 3);
1404 template<
unsigned int N,
class T>
1405 inline void readBlock(std::string datasetName,
typename MultiArrayShape<N>::type blockOffset,
typename MultiArrayShape<N>::type blockShape, MultiArrayView<N, RGBValue<T>, UnstridedArrayTag> & array)
1410 readBlock_(datasetName, blockOffset, blockShape, array, detail::getH5DataType<T>(), 3);
1419 inline void read(std::string datasetName,
char &data) { readAtomic(datasetName,data); }
1420 inline void read(std::string datasetName,
signed char &data) { readAtomic(datasetName,data); }
1421 inline void read(std::string datasetName,
signed short &data) { readAtomic(datasetName,data); }
1422 inline void read(std::string datasetName,
signed int &data) { readAtomic(datasetName,data); }
1423 inline void read(std::string datasetName,
signed long &data) { readAtomic(datasetName,data); }
1424 inline void read(std::string datasetName,
signed long long &data) { readAtomic(datasetName,data); }
1425 inline void read(std::string datasetName,
unsigned char &data) { readAtomic(datasetName,data); }
1426 inline void read(std::string datasetName,
unsigned short &data) { readAtomic(datasetName,data); }
1427 inline void read(std::string datasetName,
unsigned int &data) { readAtomic(datasetName,data); }
1428 inline void read(std::string datasetName,
unsigned long &data) { readAtomic(datasetName,data); }
1429 inline void read(std::string datasetName,
unsigned long long &data) { readAtomic(datasetName,data); }
1430 inline void read(std::string datasetName,
float &data) { readAtomic(datasetName,data); }
1431 inline void read(std::string datasetName,
double &data) { readAtomic(datasetName,data); }
1432 inline void read(std::string datasetName,
long double &data) { readAtomic(datasetName,data); }
1433 inline void read(std::string datasetName, std::string &data) { readAtomic(datasetName,data); }
1458 template<
unsigned int N,
class T>
1465 for(
int i = 0; i < N; i++){
1466 chunkSize[i] = iChunkSize;
1468 createDataset<N,T>(datasetName, shape, init, chunkSize, compressionParameter);
1473 template<
unsigned int N,
class T>
1479 std::string groupname = SplitString(datasetName).first();
1480 std::string setname = SplitString(datasetName).last();
1482 hid_t parent = openCreateGroup_(groupname);
1485 deleteDataset_(parent, setname);
1492 hsize_t shape_inv[N];
1493 for(
unsigned int k=0; k<N; ++k)
1494 shape_inv[N-1-k] = shape[k];
1497 dataspaceHandle =
HDF5Handle(H5Screate_simple(N, shape_inv, NULL),
1498 &H5Sclose,
"HDF5File::createDataset(): unable to create dataspace for scalar data.");
1501 HDF5Handle plist ( H5Pcreate(H5P_DATASET_CREATE), &H5Pclose,
"HDF5File::createDataset(): unable to create property list." );
1502 H5Pset_fill_value(plist,detail::getH5DataType<T>(), &init);
1505 H5Pset_obj_track_times(plist, track_time);
1508 if(chunkSize[0] > 0)
1511 for(
int i = 0; i<N; i++)
1513 cSize[i] = chunkSize[N-1-i];
1515 H5Pset_chunk (plist, N, cSize);
1519 if(compressionParameter > 0)
1521 H5Pset_deflate(plist, compressionParameter);
1525 HDF5Handle datasetHandle ( H5Dcreate(parent, setname.c_str(), detail::getH5DataType<T>(), dataspaceHandle, H5P_DEFAULT, plist, H5P_DEFAULT),
1526 &H5Dclose,
"HDF5File::createDataset(): unable to create dataset.");
1527 if(parent != cGroupHandle_)
1538 H5Fflush(fileHandle_, H5F_SCOPE_GLOBAL);
1552 class SplitString:
public std::string {
1554 SplitString(std::string &sstring): std::string(sstring) {};
1557 std::string first(
char delimiter =
'/')
1559 size_t last = find_last_of(delimiter);
1560 if(last == std::string::npos)
1563 return std::string(begin(), begin()+last+1);
1567 std::string last(
char delimiter =
'/')
1569 size_t last = find_last_of(delimiter);
1570 if(last == std::string::npos)
1571 return std::string(*
this);
1572 return std::string(begin()+last+1, end());
1586 if(path.length() == 0 || path ==
"."){
1587 return currentGroupName_();
1592 if(relativePath_(path)){
1593 std::string cname = currentGroupName_();
1595 str = currentGroupName_()+path;
1597 str = currentGroupName_()+
"/"+path;
1603 std::string::size_type startpos = 0;
1604 while(str.find(std::string(
"./"), startpos) != std::string::npos){
1605 std::string::size_type pos = str.find(std::string(
"./"), startpos);
1608 if(str.substr(pos-1,3) !=
"../"){
1610 str = str.substr(0,pos) + str.substr(pos+2,str.length()-pos-2);
1616 while(str.find(std::string(
"..")) != std::string::npos){
1617 std::string::size_type pos = str.find(std::string(
".."));
1620 std::string::size_type end = str.find(
"/",pos);
1621 if(end != std::string::npos){
1631 std::string::size_type prev_slash = str.rfind(
"/",pos);
1633 vigra_invariant(prev_slash != 0 && prev_slash != std::string::npos,
1634 "Error parsing path: "+str);
1636 std::string::size_type begin = str.rfind(
"/",prev_slash-1);
1639 str = str.substr(0,begin+1) + str.substr(end,str.length()-end);
1649 inline bool relativePath_(std::string & path)
1651 std::string::size_type pos = path.find(
'/') ;
1663 inline std::string currentGroupName_()
1665 int len = H5Iget_name(cGroupHandle_,NULL,1000);
1666 ArrayVector<char> name (len+1,0);
1667 H5Iget_name(cGroupHandle_,name.begin(),len+1);
1669 return std::string(name.begin());
1677 inline std::string fileName_()
1679 int len = H5Fget_name(fileHandle_,NULL,1000);
1680 ArrayVector<char> name (len+1,0);
1681 H5Fget_name(fileHandle_,name.begin(),len+1);
1683 return std::string(name.begin());
1691 inline hid_t createFile_(std::string filePath,
OpenMode mode = Open)
1695 pFile = fopen ( filePath.c_str(),
"r" );
1699 if ( pFile == NULL )
1701 fileId = H5Fcreate(filePath.c_str(), H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
1703 else if(mode == Open)
1706 fileId = H5Fopen(filePath.c_str(), H5F_ACC_RDWR, H5P_DEFAULT);
1711 std::remove(filePath.c_str());
1712 fileId = H5Fcreate(filePath.c_str(), H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
1722 inline hid_t openCreateGroup_(std::string groupName)
1728 hid_t parent = H5Gopen(fileHandle_,
"/", H5P_DEFAULT);
1729 if(groupName ==
"/")
1735 groupName = std::string(groupName.begin()+1, groupName.end());
1738 if( groupName.size() != 0 && *groupName.rbegin() !=
'/')
1740 groupName = groupName +
'/';
1744 std::string::size_type begin = 0, end = groupName.find(
'/');
1746 while (end != std::string::npos)
1748 std::string group(groupName.begin()+begin, groupName.begin()+end);
1749 hid_t prevParent = parent;
1751 if(H5LTfind_dataset(parent, group.c_str()) == 0)
1753 parent = H5Gcreate(prevParent, group.c_str(), H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
1755 parent = H5Gopen(prevParent, group.c_str(), H5P_DEFAULT);
1760 H5Gclose(prevParent);
1768 end = groupName.find(
'/', begin);
1780 inline void deleteDataset_(hid_t parent, std::string datasetName)
1783 if(H5LTfind_dataset(parent, datasetName.c_str()))
1786 #if (H5_VERS_MAJOR == 1 && H5_VERS_MINOR <= 6)
1787 if(H5Gunlink(parent, datasetName.c_str()) < 0)
1789 vigra_postcondition(
false,
"HDF5File::deleteDataset_(): Unable to delete existing data.");
1792 if(H5Ldelete(parent, datasetName.c_str(), H5P_DEFAULT ) < 0)
1794 vigra_postcondition(
false,
"HDF5File::deleteDataset_(): Unable to delete existing data.");
1805 inline hid_t getDatasetHandle_(std::string datasetName)
1810 std::string groupname = SplitString(datasetName).first();
1811 std::string setname = SplitString(datasetName).last();
1813 if (H5Lexists(fileHandle_, datasetName.c_str(), H5P_DEFAULT) <= 0)
1815 std::cerr <<
"HDF5File::getDatasetHandle_(): Dataset '" << datasetName <<
"' does not exist.\n";
1820 hid_t groupHandle = openCreateGroup_(groupname);
1822 hid_t datasetHandle = H5Dopen(groupHandle, setname.c_str(), H5P_DEFAULT);
1824 if(groupHandle != cGroupHandle_)
1826 H5Gclose(groupHandle);
1830 return datasetHandle;
1837 H5O_type_t get_object_type_(std::string name)
1840 std::string group_name = SplitString(name).first();
1841 std::string object_name = SplitString(name).last();
1842 if (!object_name.size())
1843 return H5O_TYPE_GROUP;
1845 htri_t exists = H5Lexists(fileHandle_, name.c_str(), H5P_DEFAULT);
1846 vigra_precondition(exists > 0,
"HDF5File::get_object_type_(): "
1847 "object \"" + name +
"\" "
1850 hid_t group_handle = openCreateGroup_(group_name);
1851 H5O_type_t h5_type = HDF5_get_type(group_handle, name.c_str());
1852 if (group_handle != cGroupHandle_)
1854 H5Gclose(group_handle);
1861 template<
unsigned int N,
class T>
1862 void write_attribute_(std::string name,
const std::string & attribute_name,
1863 const MultiArrayView<N, T, UnstridedArrayTag> & array,
1864 const hid_t datatype,
const int numBandsOfType)
1868 ArrayVector<hsize_t> shape(N + (numBandsOfType > 1),0);
1869 for(
unsigned int i = 0; i < N; i++){
1870 shape[N-1-i] = array.shape(i);
1873 if(numBandsOfType > 1)
1874 shape[N] = numBandsOfType;
1876 HDF5Handle dataspace(H5Screate_simple(N + (numBandsOfType > 1),
1877 shape.
begin(), NULL),
1878 &H5Sclose,
"HDF5File::writeAttribute(): Can not"
1879 " create dataspace.");
1881 std::string errorMessage (
"HDF5File::writeAttribute(): can not find "
1882 "object '" + name +
"'.");
1884 H5O_type_t h5_type = get_object_type_(name);
1885 bool is_group = h5_type == H5O_TYPE_GROUP;
1886 if (!is_group && h5_type != H5O_TYPE_DATASET)
1887 vigra_precondition(0,
"HDF5File::writeAttribute(): object \""
1888 + name +
"\" is neither a group nor a "
1891 HDF5Handle object_handle(is_group
1892 ? openCreateGroup_(name)
1893 : getDatasetHandle_(name),
1897 errorMessage.c_str());
1900 HDF5Handle attributeHandle(exists
1901 ? H5Aopen(object_handle,
1902 attribute_name.c_str(),
1904 : H5Acreate(object_handle,
1905 attribute_name.c_str(), datatype,
1906 dataspace, H5P_DEFAULT,
1909 "HDF5File::writeAttribute(): Can not create"
1913 H5Awrite(attributeHandle, datatype, array.data());
1925 inline void writeAtomicAttribute(std::string datasetName, std::string attributeName,
const T data)
1930 typename MultiArrayShape<1>::type chunkSize;
1932 MultiArray<1,T> array(MultiArrayShape<1>::type(1));
1934 write_attribute_(datasetName, attributeName, array, detail::getH5DataType<T>(), 1);
1942 template<
unsigned int N,
class T>
1943 inline void read_attribute_(std::string datasetName, std::string attributeName, MultiArrayView<N, T, UnstridedArrayTag> array,
const hid_t datatype,
const int numBandsOfType)
1947 std::string message =
"Error: could not get handle for attribute '"+attributeName+
"'' of object '"+dataset_path+
"'.";
1948 HDF5Handle attr_handle (H5Aopen_by_name(fileHandle_,dataset_path.c_str(),attributeName.c_str(),H5P_DEFAULT,H5P_DEFAULT),&H5Aclose, message.c_str());
1951 message =
"Error: could not get dataspace for attribute '"+attributeName+
"'' of object '"+dataset_path+
"'.";
1952 HDF5Handle attr_dataspace_handle (H5Aget_space(attr_handle),&H5Sclose,message.c_str());
1955 int dims = H5Sget_simple_extent_ndims(attr_dataspace_handle);
1956 ArrayVector<hsize_t> shape_inv(dims);
1957 H5Sget_simple_extent_dims(attr_dataspace_handle, shape_inv.data(), NULL);
1960 ArrayVector<hsize_t> dimshape(dims);
1961 for(ArrayVector<hsize_t>::size_type i=0; i<shape_inv.size(); i++) {
1962 dimshape[i] = shape_inv[dims-1-i];
1965 int offset = (numBandsOfType > 1);
1966 message =
"Error: Array dimension disagrees with dataset dimension.";
1968 vigra_precondition( ( (N + offset ) ==
MultiArrayIndex(dims)), message);
1970 typename MultiArrayShape<N>::type shape;
1975 message =
"Error: Array shape disagrees with dataset shape";
1976 vigra_precondition(shape == array.shape(),message);
1979 H5Aread( attr_handle, datatype, array.data());
1991 inline void readAtomicAttribute(std::string datasetName, std::string attributeName, T & data)
1996 MultiArray<1,T> array(MultiArrayShape<1>::type(1));
1997 read_attribute_(datasetName, attributeName, array, detail::getH5DataType<T>(), 1);
2003 inline void readAtomicAttribute(std::string datasetName, std::string attributeName, std::string & data)
2008 MultiArray<1,const char *> array(MultiArrayShape<1>::type(1));
2009 read_attribute_(datasetName, attributeName, array, detail::getH5DataType<const char *>(), 1);
2010 data = std::string(array[0]);
2018 template<
unsigned int N,
class T>
2019 inline void write_(std::string &datasetName,
const MultiArrayView<N, T, UnstridedArrayTag> & array,
const hid_t datatype,
const int numBandsOfType,
typename MultiArrayShape<N>::type &chunkSize,
int compressionParameter = 0)
2021 std::string groupname = SplitString(datasetName).first();
2022 std::string setname = SplitString(datasetName).last();
2025 ArrayVector<hsize_t> shape(N + (numBandsOfType > 1),0);
2026 for(
unsigned int i = 0; i < N; i++){
2027 shape[N-1-i] = array.shape(i);
2030 if(numBandsOfType > 1)
2031 shape[N] = numBandsOfType;
2033 HDF5Handle dataspace ( H5Screate_simple(N + (numBandsOfType > 1), shape.begin(), NULL), &H5Sclose,
"HDF5File::write(): Can not create dataspace.");
2036 std::string errorMessage (
"HDF5File::write(): can not create group '" + groupname +
"'.");
2037 hid_t groupHandle = openCreateGroup_(groupname);
2038 if(groupHandle <= 0)
2040 std::cerr << errorMessage <<
"\n";
2044 deleteDataset_(groupHandle, setname.c_str());
2047 HDF5Handle plist ( H5Pcreate(H5P_DATASET_CREATE), &H5Pclose,
"HDF5File::write(): unable to create property list." );
2050 H5Pset_obj_track_times(plist, track_time);
2053 if(chunkSize[0] > 0)
2055 ArrayVector<hsize_t> cSize(N + (numBandsOfType > 1),0);
2056 for(
unsigned int i = 0; i<N; i++)
2058 cSize[i] = chunkSize[N-1-i];
2060 if(numBandsOfType > 1)
2061 cSize[N] = numBandsOfType;
2063 H5Pset_chunk (plist, N + (numBandsOfType > 1), cSize.begin());
2067 if(compressionParameter > 0)
2069 H5Pset_deflate(plist, compressionParameter);
2073 HDF5Handle datasetHandle (H5Dcreate(groupHandle, setname.c_str(), datatype, dataspace,H5P_DEFAULT, plist, H5P_DEFAULT), &H5Dclose,
"HDF5File::write(): Can not create dataset.");
2076 herr_t write_status = H5Dwrite(datasetHandle, datatype, H5S_ALL,
2077 H5S_ALL, H5P_DEFAULT, array.data());
2078 vigra_precondition(write_status >= 0,
"HDF5File::write_(): write to "
2079 "dataset \"" + datasetName +
"\" "
2082 if(groupHandle != cGroupHandle_)
2084 H5Gclose(groupHandle);
2100 inline void writeAtomic(std::string datasetName,
const T data)
2105 typename MultiArrayShape<1>::type chunkSize;
2107 MultiArray<1,T> array(MultiArrayShape<1>::type(1));
2109 write_(datasetName, array, detail::getH5DataType<T>(), 1, chunkSize,0);
2117 template<
unsigned int N,
class T>
2118 inline void read_(std::string datasetName, MultiArrayView<N, T, UnstridedArrayTag> array,
const hid_t datatype,
const int numBandsOfType)
2124 std::string errorMessage (
"HDF5File::read(): Unable to open dataset '" + datasetName +
"'.");
2125 HDF5Handle datasetHandle (getDatasetHandle_(datasetName), &H5Dclose, errorMessage.c_str());
2127 int offset = (numBandsOfType > 1);
2130 "HDF5File::read(): Array dimension disagrees with dataset dimension.");
2132 typename MultiArrayShape<N>::type shape;
2137 vigra_precondition(shape == array.shape(),
2138 "HDF5File::read(): Array shape disagrees with dataset shape.");
2141 H5Dread( datasetHandle, datatype, H5S_ALL, H5S_ALL, H5P_DEFAULT, array.data() );
2156 inline void readAtomic(std::string datasetName, T & data)
2161 MultiArray<1,T> array(MultiArrayShape<1>::type(1));
2162 read_(datasetName, array, detail::getH5DataType<T>(), 1);
2165 inline void readAtomic(std::string datasetName, std::string & data)
2170 MultiArray<1,const char *> array(MultiArrayShape<1>::type(1));
2171 read_(datasetName, array, detail::getH5DataType<const char *>(), 1);
2172 data = std::string(array[0]);
2180 template<
unsigned int N,
class T>
2181 inline void writeBlock_(std::string datasetName,
typename MultiArrayShape<N>::type &blockOffset,
const MultiArrayView<N, T, UnstridedArrayTag> & array,
const hid_t datatype,
const int numBandsOfType)
2184 std::string errorMessage =
"HDF5File::writeBlock(): Error opening dataset '" + datasetName +
"'.";
2185 HDF5Handle datasetHandle (getDatasetHandle_(datasetName), &H5Dclose, errorMessage.c_str());
2189 hsize_t boffset [N];
2193 for(
int i = 0; i < N; i++){
2194 boffset[i] = blockOffset[N-1-i];
2195 bshape[i] = array.size(N-1-i);
2200 HDF5Handle memspace_handle (H5Screate_simple(N,bshape,NULL),&H5Sclose,
"Unable to get origin dataspace");
2203 HDF5Handle dataspaceHandle (H5Dget_space(datasetHandle),&H5Sclose,
"Unable to create target dataspace");
2204 H5Sselect_hyperslab(dataspaceHandle, H5S_SELECT_SET, boffset, bones, bones, bshape);
2207 H5Dwrite( datasetHandle, datatype, memspace_handle, dataspaceHandle, H5P_DEFAULT, array.data());
2215 template<
unsigned int N,
class T>
2216 inline void readBlock_(std::string datasetName,
typename MultiArrayShape<N>::type &blockOffset,
typename MultiArrayShape<N>::type &blockShape, MultiArrayView<N, T, UnstridedArrayTag> &array,
const hid_t datatype,
const int numBandsOfType)
2222 std::string errorMessage (
"HDF5File::readBlock(): Unable to open dataset '" + datasetName +
"'.");
2223 HDF5Handle datasetHandle (getDatasetHandle_(datasetName), &H5Dclose, errorMessage.c_str());
2226 int offset = (numBandsOfType > 1);
2229 "readHDF5_block(): Array dimension disagrees with data dimension.");
2231 vigra_precondition(blockShape == array.shape(),
2232 "readHDF5_block(): Array shape disagrees with block size.");
2235 hsize_t boffset [N];
2239 for(
int i = 0; i < N; i++){
2241 boffset[i] = blockOffset[N-1-i];
2243 bshape[i] = blockShape[N-1-i];
2249 HDF5Handle memspace_handle (H5Screate_simple(N,bshape,NULL),&H5Sclose,
"Unable to create target dataspace");
2252 HDF5Handle dataspaceHandle (H5Dget_space(datasetHandle),&H5Sclose,
"Unable to get dataspace");
2253 H5Sselect_hyperslab(dataspaceHandle, H5S_SELECT_SET, boffset, bones, bones, bshape);
2256 H5Dread( datasetHandle, datatype, memspace_handle, dataspaceHandle, H5P_DEFAULT, array.data() );
2263 template <
class Shape>
2265 selectHyperslabs(HDF5Handle & mid1, HDF5Handle & mid2, Shape
const & shape,
int & counter,
const int elements,
const int numBandsOfType)
2268 hsize_t shapeHDF5[2];
2270 shapeHDF5[1] = elements;
2271 hsize_t startHDF5[2];
2273 startHDF5[1] = counter * numBandsOfType * shape[0];
2274 hsize_t strideHDF5[2];
2277 hsize_t countHDF5[2];
2279 countHDF5[1] = numBandsOfType * shape[0];
2280 hsize_t blockHDF5[2];
2283 mid1 = HDF5Handle(H5Screate_simple(2, shapeHDF5, NULL),
2284 &H5Sclose,
"unable to create hyperslabs.");
2285 H5Sselect_hyperslab(mid1, H5S_SELECT_SET, startHDF5, strideHDF5, countHDF5, blockHDF5);
2287 hsize_t shapeData[2];
2289 shapeData[1] = numBandsOfType * shape[0];
2290 hsize_t startData[2];
2293 hsize_t strideData[2];
2296 hsize_t countData[2];
2298 countData[1] = numBandsOfType * shape[0];
2299 hsize_t blockData[2];
2302 mid2 = HDF5Handle(H5Screate_simple(2, shapeData, NULL),
2303 &H5Sclose,
"unable to create hyperslabs.");
2304 H5Sselect_hyperslab(mid2, H5S_SELECT_SET, startData, strideData, countData, blockData);
2307 template <
class DestIterator,
class Shape,
class T>
2309 readHDF5Impl(DestIterator d, Shape
const & shape,
const hid_t dataset_id,
const hid_t datatype, ArrayVector<T> & buffer,
int & counter,
const int elements,
const int numBandsOfType, MetaInt<0>)
2311 HDF5Handle mid1, mid2;
2314 selectHyperslabs(mid1, mid2, shape, counter, elements, numBandsOfType);
2317 herr_t read_status = H5Dread(dataset_id, datatype, mid2, mid1, H5P_DEFAULT, buffer.data());
2318 vigra_precondition(read_status >= 0,
"readHDF5Impl(): read from dataset failed.");
2324 DestIterator dend = d + shape[0];
2326 for(; d < dend; ++d, k++)
2334 template <
class DestIterator,
class Shape,
class T,
int N>
2336 readHDF5Impl(DestIterator d, Shape
const & shape,
const hid_t dataset_id,
const hid_t datatype, ArrayVector<T> & buffer,
int & counter,
const int elements,
const int numBandsOfType, MetaInt<N>)
2338 DestIterator dend = d + shape[N];
2339 for(; d < dend; ++d)
2341 readHDF5Impl(d.begin(), shape, dataset_id, datatype, buffer, counter, elements, numBandsOfType, MetaInt<N-1>());
2382 doxygen_overloaded_function(template <...>
void readHDF5)
2385 template<
unsigned int N,
class T>
2386 inline void readHDF5(
const HDF5ImportInfo &info, MultiArrayView<N, T, UnstridedArrayTag> array)
2388 readHDF5(info, array, detail::getH5DataType<T>(), 1);
2392 template<
unsigned int N,
class T,
int SIZE>
2393 inline void readHDF5(
const HDF5ImportInfo &info, MultiArrayView<N, TinyVector<T, SIZE>, UnstridedArrayTag> array)
2395 readHDF5(info, array, detail::getH5DataType<T>(), SIZE);
2399 template<
unsigned int N,
class T>
2400 inline void readHDF5(
const HDF5ImportInfo &info, MultiArrayView<N, RGBValue<T>, UnstridedArrayTag> array)
2402 readHDF5(info, array, detail::getH5DataType<T>(), 3);
2406 template<
unsigned int N,
class T>
2407 void readHDF5(
const HDF5ImportInfo &info, MultiArrayView<N, T, UnstridedArrayTag> array,
const hid_t datatype,
const int numBandsOfType)
2409 int offset = (numBandsOfType > 1);
2412 vigra_precondition(( (N + offset ) == info.numDimensions()),
2413 "readHDF5(): Array dimension disagrees with HDF5ImportInfo.numDimensions().");
2415 typename MultiArrayShape<N>::type shape;
2416 for(
int k=offset; k<info.numDimensions(); ++k) {
2417 shape[k-offset] = info.shapeOfDimension(k);
2420 vigra_precondition(shape == array.shape(),
2421 "readHDF5(): Array shape disagrees with HDF5ImportInfo.");
2424 H5Dread( info.getDatasetHandle(), datatype, H5S_ALL, H5S_ALL, H5P_DEFAULT, array.data() );
2428 template<
unsigned int N,
class T>
2429 inline void readHDF5(
const HDF5ImportInfo &info, MultiArrayView<N, T, StridedArrayTag> array)
2431 readHDF5(info, array, detail::getH5DataType<T>(), 1);
2435 template<
unsigned int N,
class T,
int SIZE>
2436 inline void readHDF5(
const HDF5ImportInfo &info, MultiArrayView<N, TinyVector<T, SIZE>, StridedArrayTag> array)
2438 readHDF5(info, array, detail::getH5DataType<T>(), SIZE);
2442 template<
unsigned int N,
class T>
2443 inline void readHDF5(
const HDF5ImportInfo &info, MultiArrayView<N, RGBValue<T>, StridedArrayTag> array)
2445 readHDF5(info, array, detail::getH5DataType<T>(), 3);
2449 template<
unsigned int N,
class T>
2450 void readHDF5(
const HDF5ImportInfo &info, MultiArrayView<N, T, StridedArrayTag> array,
const hid_t datatype,
const int numBandsOfType)
2452 int offset = (numBandsOfType > 1);
2455 vigra_precondition(( (N + offset ) == info.numDimensions()),
2456 "readHDF5(): Array dimension disagrees with HDF5ImportInfo.numDimensions().");
2458 typename MultiArrayShape<N>::type shape;
2459 for(
int k=offset; k<info.numDimensions(); ++k) {
2460 shape[k-offset] = info.shapeOfDimension(k);
2463 vigra_precondition(shape == array.shape(),
2464 "readHDF5(): Array shape disagrees with HDF5ImportInfo.");
2468 int elements = numBandsOfType;
2469 for(
unsigned int i=0;i<N;++i)
2470 elements *= shape[i];
2471 ArrayVector<T> buffer(shape[0]);
2472 detail::readHDF5Impl(array.traverser_begin(), shape, info.getDatasetHandle(), datatype, buffer, counter, elements, numBandsOfType, vigra::MetaInt<N-1>());
2475 inline hid_t openGroup(hid_t parent, std::string group_name)
2478 size_t last_slash = group_name.find_last_of(
'/');
2479 if (last_slash == std::string::npos || last_slash != group_name.size() - 1)
2480 group_name = group_name +
'/';
2481 std::string::size_type begin = 0, end = group_name.find(
'/');
2483 while (end != std::string::npos)
2485 std::string group(group_name.begin()+begin, group_name.begin()+end);
2486 hid_t prev_parent = parent;
2487 parent = H5Gopen(prev_parent, group.c_str(), H5P_DEFAULT);
2489 if(ii != 0) H5Gclose(prev_parent);
2490 if(parent < 0)
return parent;
2493 end = group_name.find(
'/', begin);
2498 inline hid_t createGroup(hid_t parent, std::string group_name)
2500 if(group_name.size() == 0 ||*group_name.rbegin() !=
'/')
2501 group_name = group_name +
'/';
2502 if(group_name ==
"/")
2503 return H5Gopen(parent, group_name.c_str(), H5P_DEFAULT);
2505 std::string::size_type begin = 0, end = group_name.find(
'/');
2507 while (end != std::string::npos)
2509 std::string group(group_name.begin()+begin, group_name.begin()+end);
2510 hid_t prev_parent = parent;
2512 if(H5LTfind_dataset(parent, group.c_str()) == 0)
2514 parent = H5Gcreate(prev_parent, group.c_str(), H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
2516 parent = H5Gopen(prev_parent, group.c_str(), H5P_DEFAULT);
2519 if(ii != 0) H5Gclose(prev_parent);
2520 if(parent < 0)
return parent;
2523 end = group_name.find(
'/', begin);
2528 inline void deleteDataset(hid_t parent, std::string dataset_name)
2531 if(H5LTfind_dataset(parent, dataset_name.c_str()))
2534 #if (H5_VERS_MAJOR == 1 && H5_VERS_MINOR <= 6)
2535 if(H5Gunlink(parent, dataset_name.c_str()) < 0)
2537 vigra_postcondition(
false,
"writeToHDF5File(): Unable to delete existing data.");
2540 if(H5Ldelete(parent, dataset_name.c_str(), H5P_DEFAULT ) < 0)
2542 vigra_postcondition(
false,
"createDataset(): Unable to delete existing data.");
2548 inline hid_t createFile(std::string filePath,
bool append_ =
true)
2551 pFile = fopen ( filePath.c_str(),
"r" );
2553 if ( pFile == NULL )
2555 file_id = H5Fcreate(filePath.c_str(), H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
2560 file_id = H5Fopen(filePath.c_str(), H5F_ACC_RDWR, H5P_DEFAULT);
2565 std::remove(filePath.c_str());
2566 file_id = H5Fcreate(filePath.c_str(), H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
2571 template<
unsigned int N,
class T,
class Tag>
2572 void createDataset(
const char* filePath,
const char* pathInFile,
const MultiArrayView<N, T, Tag> & array,
const hid_t datatype,
const int numBandsOfType, HDF5Handle & file_handle, HDF5Handle & dataset_handle)
2574 std::string path_name(pathInFile), group_name, data_set_name, message;
2575 std::string::size_type delimiter = path_name.rfind(
'/');
2578 file_handle = HDF5Handle(createFile(filePath), &H5Fclose,
2579 "createDataset(): unable to open output file.");
2582 if(delimiter == std::string::npos)
2585 data_set_name = path_name;
2589 group_name = std::string(path_name.begin(), path_name.begin()+delimiter);
2590 data_set_name = std::string(path_name.begin()+delimiter+1, path_name.end());
2594 HDF5Handle group(createGroup(file_handle, group_name), &H5Gclose,
2595 "createDataset(): Unable to create and open group. generic v");
2598 deleteDataset(group, data_set_name);
2602 HDF5Handle dataspace_handle;
2603 if(numBandsOfType > 1) {
2605 hsize_t shape_inv[N+1];
2606 for(
unsigned int k=0; k<N; ++k) {
2607 shape_inv[N-1-k] = array.shape(k);
2610 shape_inv[N] = numBandsOfType;
2613 dataspace_handle = HDF5Handle(H5Screate_simple(N+1, shape_inv, NULL),
2614 &H5Sclose,
"createDataset(): unable to create dataspace for non-scalar data.");
2617 hsize_t shape_inv[N];
2618 for(
unsigned int k=0; k<N; ++k)
2619 shape_inv[N-1-k] = array.shape(k);
2622 dataspace_handle = HDF5Handle(H5Screate_simple(N, shape_inv, NULL),
2623 &H5Sclose,
"createDataset(): unable to create dataspace for scalar data.");
2627 dataset_handle = HDF5Handle(H5Dcreate(group,
2628 data_set_name.c_str(),
2631 H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT),
2632 &H5Dclose,
"createDataset(): unable to create dataset.");
2639 template <
class DestIterator,
class Shape,
class T>
2641 writeHDF5Impl(DestIterator d, Shape
const & shape,
const hid_t dataset_id,
const hid_t datatype, ArrayVector<T> & buffer,
int & counter,
const int elements,
const int numBandsOfType, MetaInt<0>)
2643 DestIterator dend = d + (
typename DestIterator::difference_type)shape[0];
2646 for(; d < dend; ++d, k++)
2652 HDF5Handle mid1, mid2;
2655 selectHyperslabs(mid1, mid2, shape, counter, elements, numBandsOfType);
2658 H5Dwrite(dataset_id, datatype, mid2, mid1, H5P_DEFAULT, buffer.data());
2663 template <
class DestIterator,
class Shape,
class T,
int N>
2665 writeHDF5Impl(DestIterator d, Shape
const & shape,
const hid_t dataset_id,
const hid_t datatype, ArrayVector<T> & buffer,
int & counter,
const int elements,
const int numBandsOfType, MetaInt<N>)
2667 DestIterator dend = d + (
typename DestIterator::difference_type)shape[N];
2668 for(; d < dend; ++d)
2670 writeHDF5Impl(d.begin(), shape, dataset_id, datatype, buffer, counter, elements, numBandsOfType, MetaInt<N-1>());
2710 doxygen_overloaded_function(template <...>
void writeHDF5)
2713 template<
unsigned int N,
class T>
2714 inline void writeHDF5(
const char* filePath,
const char* pathInFile,
const MultiArrayView<N, T, UnstridedArrayTag> & array)
2716 writeHDF5(filePath, pathInFile, array, detail::getH5DataType<T>(), 1);
2720 template<
unsigned int N,
class T,
int SIZE>
2721 inline void writeHDF5(
const char* filePath,
const char* pathInFile,
const MultiArrayView<N, TinyVector<T, SIZE>, UnstridedArrayTag> & array)
2723 writeHDF5(filePath, pathInFile, array, detail::getH5DataType<T>(), SIZE);
2727 template<
unsigned int N,
class T>
2728 inline void writeHDF5(
const char* filePath,
const char* pathInFile,
const MultiArrayView<N, RGBValue<T>, UnstridedArrayTag> & array)
2730 writeHDF5(filePath, pathInFile, array, detail::getH5DataType<T>(), 3);
2734 template<
unsigned int N,
class T>
2735 inline void writeHDF5(
const char* filePath,
const char* pathInFile,
const MultiArrayView<N, FFTWComplex<T>, UnstridedArrayTag> & array)
2737 writeHDF5(filePath, pathInFile, array, detail::getH5DataType<T>(), 2);
2741 template<
unsigned int N,
class T>
2742 void writeHDF5(
const char* filePath,
const char* pathInFile,
const MultiArrayView<N, T, UnstridedArrayTag> & array,
const hid_t datatype,
const int numBandsOfType)
2744 HDF5Handle file_handle;
2745 HDF5Handle dataset_handle;
2746 createDataset(filePath, pathInFile, array, datatype, numBandsOfType, file_handle, dataset_handle);
2749 H5Dwrite( dataset_handle, datatype, H5S_ALL, H5S_ALL, H5P_DEFAULT, array.data());
2751 H5Fflush(file_handle, H5F_SCOPE_GLOBAL);
2756 template<
unsigned int N,
class T>
2757 inline void writeHDF5(
const char* filePath,
const char* pathInFile,
const MultiArrayView<N, T, StridedArrayTag> & array)
2759 writeHDF5(filePath, pathInFile, array, detail::getH5DataType<T>(), 1);
2763 template<
unsigned int N,
class T,
int SIZE>
2764 inline void writeHDF5(
const char* filePath,
const char* pathInFile,
const MultiArrayView<N, TinyVector<T, SIZE>, StridedArrayTag> & array)
2766 writeHDF5(filePath, pathInFile, array, detail::getH5DataType<T>(), SIZE);
2770 template<
unsigned int N,
class T>
2771 inline void writeHDF5(
const char* filePath,
const char* pathInFile,
const MultiArrayView<N, RGBValue<T>, StridedArrayTag> & array)
2773 writeHDF5(filePath, pathInFile, array, detail::getH5DataType<T>(), 3);
2777 template<
unsigned int N,
class T>
2778 inline void writeHDF5(
const char* filePath,
const char* pathInFile,
const MultiArrayView<N, FFTWComplex<T>, StridedArrayTag> & array)
2780 writeHDF5(filePath, pathInFile, array, detail::getH5DataType<T>(), 2);
2784 template<
unsigned int N,
class T>
2785 void writeHDF5(
const char* filePath,
const char* pathInFile,
const MultiArrayView<N, T, StridedArrayTag> & array,
const hid_t datatype,
const int numBandsOfType)
2787 HDF5Handle file_handle;
2788 HDF5Handle dataset_handle;
2789 createDataset(filePath, pathInFile, array, datatype, numBandsOfType, file_handle, dataset_handle);
2793 int elements = numBandsOfType;
2794 for(
unsigned int k=0; k<N; ++k)
2796 shape[k] = array.shape(k);
2797 stride[k] = array.stride(k);
2798 elements *= (int)shape[k];
2802 ArrayVector<T> buffer((
int)array.shape(0));
2803 detail::writeHDF5Impl(array.traverser_begin(), shape, dataset_handle, datatype, buffer, counter, elements, numBandsOfType, vigra::MetaInt<N-1>());
2805 H5Fflush(file_handle, H5F_SCOPE_GLOBAL);
2819 void operator()(std::string
const & in)
2821 size = in.size() > size ?
2829 #if (H5_VERS_MAJOR == 1 && H5_VERS_MINOR == 8) || DOXYGEN
2836 template<
size_t N,
class T,
class C>
2841 if(H5Aexists(loc, name) > 0)
2842 H5Adelete(loc, name);
2845 array.
shape().end());
2847 dataspace_handle(H5Screate_simple(N, shape.data(), NULL),
2849 "writeToHDF5File(): unable to create dataspace.");
2853 detail::getH5DataType<T>(),
2855 H5P_DEFAULT ,H5P_DEFAULT ),
2857 "writeHDF5Attr: unable to create Attribute");
2861 for(
int ii = 0; ii < array.
size(); ++ii)
2862 buffer.push_back(array[ii]);
2863 H5Awrite(attr, detail::getH5DataType<T>(), buffer.
data());
2872 template<
size_t N,
class C>
2877 if(H5Aexists(loc, name) > 0)
2878 H5Adelete(loc, name);
2881 array.
shape().end());
2883 dataspace_handle(H5Screate_simple(N, shape.data(), NULL),
2885 "writeToHDF5File(): unable to create dataspace.");
2889 "writeToHDF5File(): unable to create type.");
2891 detail::MaxSizeFnc max_size;
2892 max_size = std::for_each(array.
data(),array.
data()+ array.
size(), max_size);
2893 H5Tset_size (atype, max_size.size);
2899 H5P_DEFAULT ,H5P_DEFAULT ),
2901 "writeHDF5Attr: unable to create Attribute");
2903 std::string buf =
"";
2904 for(
int ii = 0; ii < array.
size(); ++ii)
2906 buf = buf + array[ii]
2907 + std::string(max_size.size - array[ii].
size(),
' ');
2909 H5Awrite(attr, atype, buf.c_str());
2937 std::string pathInFile,
2940 std::string path_name(pathInFile), group_name, data_set_name, message, attr_name;
2941 std::string::size_type delimiter = path_name.rfind(
'/');
2944 HDF5Handle file_id(createFile(filePath), &H5Fclose,
2945 "writeToHDF5File(): unable to open output file.");
2948 if(delimiter == std::string::npos)
2951 data_set_name = path_name;
2956 group_name = std::string(path_name.begin(), path_name.begin()+delimiter);
2957 data_set_name = std::string(path_name.begin()+delimiter+1, path_name.end());
2959 delimiter = data_set_name.rfind(
'.');
2960 if(delimiter == std::string::npos)
2962 attr_name = path_name;
2963 data_set_name =
"/";
2967 attr_name = std::string(data_set_name.begin()+delimiter+1, data_set_name.end());
2968 data_set_name = std::string(data_set_name.begin(), data_set_name.begin()+delimiter);
2971 HDF5Handle group(openGroup(file_id, group_name), &H5Gclose,
2972 "writeToHDF5File(): Unable to create and open group. attr ver");
2974 if(data_set_name !=
"/")
2976 HDF5Handle dset(H5Dopen(group, data_set_name.c_str(), H5P_DEFAULT), &H5Dclose,
2977 "writeHDF5Attr():unable to open dataset");
2992 #endif // VIGRA_HDF5IMPEX_HXX