12#ifndef BELFEM_HDF5_TOOLS_HPP
13#define BELFEM_HDF5_TOOLS_HPP
40 hid_t mDataSet = H5I_INVALID_HID ;
41 hid_t mDataType = H5I_INVALID_HID ;
42 hid_t mDataSpace = H5I_INVALID_HID ;
44 DatasetHandles() = default ;
47 DatasetHandles(
const DatasetHandles & ) = delete ;
48 DatasetHandles & operator=(
const DatasetHandles & ) = delete ;
49 DatasetHandles( DatasetHandles && ) = delete ;
50 DatasetHandles & operator=( DatasetHandles && ) = delete ;
56 H5Sclose( mDataSpace );
60 H5Tclose( mDataType );
81 return H5Lexists( aLoc, aLabel.c_str(), tDataSet );
98 return H5Lexists( aLoc, aLabel.c_str(), tGroup );
119#if ! H5_VERSION_GE( 1, 12, 0 )
120#error "BELFEM requires HDF5 1.12 or newer ( hdf5_tools.hpp uses H5Literate2 and H5Oget_info_by_name3 )."
127 const H5L_info2_t * aInfo,
130 auto * tLabels =
static_cast<std::vector<std::string> *
>( aData );
138 if( aInfo !=
nullptr && aInfo->type != H5L_TYPE_HARD )
150 if( H5Oget_info_by_name3( aLoc, aLabel, & tInfo,
151 H5O_INFO_BASIC, H5P_DEFAULT ) < 0 )
158 if( tInfo.type != H5O_TYPE_GROUP )
163 tLabels->emplace_back( aLabel );
173 inline Cell< std::string >
185 const herr_t tStatus = H5Literate2(
198 "H5Literate2 failed while listing the groups of an HDF5 location." );
213 template <
typename T >
218 return H5Tget_size(
datatype<T>() ) ==
sizeof( T );
246 template <
typename T >
252 "datatype class mismatch reading '%s': the file holds class %i, but %s is class %i.\n"
253 "HDF5 can convert between widths, not between classes - this file does not hold what the reader expects.",
255 (
int ) H5Tget_class( aFileType ),
272 template <
typename T >
276 const std::string & aLabel,
283 "Dataset %s of type %s does already exist.",
288 "Error in datatype size of type %s.",
298 = H5Screate_simple( 1, tDims,
nullptr );
300 hid_t tDataSet = H5Dcreate(
317 H5Sclose( tDataSpace );
318 H5Tclose( tDataType );
319 H5Dclose( tDataSet );
322 "Something went wrong while trying to store scalar %s of type %s",
329 template <
typename T >
333 const std::string & aLabel,
340 "Dataset %s of type %s does not exist.",
345 "Error in datatype size of type %s.",
348 DatasetHandles tHandles ;
350 tHandles.mDataSet = H5Dopen1( aLoc, aLabel.c_str() );
352 tHandles.mDataType = H5Dget_type( tHandles.mDataSet );
358 tHandles.mDataSpace = H5Dget_space( tHandles.mDataSet );
369 "Something went wrong while trying to load scalar %s of type %s",
381 const std::string & aLabel,
390 const std::string & aLabel,
399 const std::string & aLabel,
400 const std::string & aValue,
408 const std::string & aLabel,
409 std::string & aValue,
413 template <
typename T >
417 const std::string & aLabel,
424 "Dataset %s of type Vector<%s> does already exist.",
429 "Error in datatype size of type %s.",
437 tDims[ 0 ] = aLength;
440 = H5Screate_simple( 1, tDims,
nullptr );
442 hid_t tDataSet = H5Dcreate(
462 H5Sclose( tDataSpace );
463 H5Tclose( tDataType );
464 H5Dclose( tDataSet );
467 "Something went wrong while trying to store vector %s of type %s",
478 const std::string & aLabel );
482 template <
typename T >
486 const std::string & aLabel,
494 "Dataset %s of type Vector<%s> does not exist.",
499 "Error in datatype size of type %s.",
502 DatasetHandles tHandles ;
504 tHandles.mDataSet = H5Dopen1( aLoc, aLabel.c_str() );
506 tHandles.mDataType = H5Dget_type( tHandles.mDataSet );
512 tHandles.mDataSpace = H5Dget_space( tHandles.mDataSet );
518 const int tRank = H5Sget_simple_extent_ndims( tHandles.mDataSpace );
520 BELFEM_ERROR( tRank == 1,
"Dataset %s is not a 1-D array (rank %i)",
521 aLabel.c_str(), tRank );
523 aStatus = H5Sget_simple_extent_dims( tHandles.mDataSpace, tDims,
nullptr );
525 BELFEM_ERROR( tDims[ 0 ] == aLength,
"Lengths do not match: is %lu, expect %lu.",
526 (
long unsigned int ) tDims[ 0 ], (
long unsigned int ) aLength );
544 "Something went wrong while trying to load vector %s of type %s",
551 template <
typename T >
555 const std::string & aLabel,
562 "Dataset %s of type Vector<%s> does already exist.",
567 "Error in datatype size of type %s.",
577 tDims[ 0 ] = tLength;
580 = H5Screate_simple( 1, tDims,
nullptr );
582 tDataSet = H5Dcreate(
593 T* tData = ( T* ) malloc( tLength *
sizeof( T ) );
598 tLength *
sizeof( T ) );
611 H5Sclose( tDataSpace );
612 H5Tclose( tDataType );
613 H5Dclose( tDataSet );
616 "Something went wrong while trying to store vector %s of type %s",
624 template <
typename T >
628 const std::string & aLabel,
634 "Dataset %s of type Vector<%s> does not exist.",
639 "Error in datatype size of type %s.",
642 DatasetHandles tHandles ;
644 tHandles.mDataSet = H5Dopen1( aLoc, aLabel.c_str() );
646 tHandles.mDataType = H5Dget_type( tHandles.mDataSet );
652 tHandles.mDataSpace = H5Dget_space( tHandles.mDataSet );
658 const int tRank = H5Sget_simple_extent_ndims( tHandles.mDataSpace );
660 BELFEM_ERROR( tRank == 1,
"Dataset %s is not a 1-D array (rank %i)",
661 aLabel.c_str(), tRank );
663 aStatus = H5Sget_simple_extent_dims( tHandles.mDataSpace, tDims,
nullptr );
671 T* tData = ( T* ) malloc( tLength *
sizeof( T ) );
684 tLength *
sizeof( T ) );
694 "Something went wrong while trying to load vector %s of type %s",
701 template <
typename T >
705 const std::string & aLabel,
708 const bool aTranspose =
false )
712 "Dataset %s of type Matrix<%s> does already exist.",
717 "Error in datatype size of type %s.",
729 tDims[ 0 ] = aMatrix.
n_cols();
730 tDims[ 1 ] = aMatrix.
n_rows();
735 tDims[ 0 ] = aMatrix.
n_rows();
736 tDims[ 1 ] = aMatrix.
n_cols();
740 = H5Screate_simple( 2, tDims,
nullptr );
742 tDataSet = H5Dcreate(
751 if( tDims[ 0 ]*tDims[ 1 ] > 0 )
753 T** tData = ( T** ) malloc( tDims[ 0 ] *
sizeof( T * ) );
754 tData[ 0 ] = ( T* ) malloc( tDims[ 0 ]*tDims[ 1 ] *
sizeof( T ) );
756 for(
hsize_t i=0; i<tDims[ 0 ]; ++i )
758 tData[ i ] = tData[ 0 ]+ i*tDims[ 1 ];
763 for (
hsize_t i = 0; i < tDims[ 0 ]; ++i )
765 for (
hsize_t j = 0; j < tDims[ 1 ]; ++j )
767 tData[ i ][ j ] = aMatrix( j, i );
773 for (
hsize_t i = 0; i < tDims[ 0 ]; ++i )
775 for (
hsize_t j = 0; j < tDims[ 1 ]; ++j )
777 tData[ i ][ j ] = aMatrix( i, j );
793 H5Sclose( tDataSpace );
794 H5Tclose( tDataType );
795 H5Dclose( tDataSet );
798 "Something went wrong while trying to store matrix %s of type %s",
806 template <
typename T >
810 const std::string & aLabel,
813 const bool aTranspose =
false )
818 "Dataset %s of type Matrix<%s> does not exist.",
823 "Error in datatype size of type %s.",
826 DatasetHandles tHandles ;
828 tHandles.mDataSet = H5Dopen1( aLoc, aLabel.c_str() );
830 tHandles.mDataType = H5Dget_type( tHandles.mDataSet );
836 tHandles.mDataSpace = H5Dget_space( tHandles.mDataSet );
840 aStatus = H5Sget_simple_extent_dims( tHandles.mDataSpace, tDims,
nullptr );
845 aMatrix.
set_size( tDims[ 1 ], tDims[ 0 ] );
849 aMatrix.
set_size( tDims[ 0 ], tDims[ 1 ] );
852 if( tDims[ 0 ]*tDims[ 1 ] > 0 )
855 malloc( tDims[ 0 ]*
sizeof( T* ) );
858 malloc( tDims[ 0 ]* tDims[ 1 ] *
sizeof( T ) );
860 for(
hsize_t i=1; i<tDims[ 0 ]; ++i )
862 tData[ i ] = tData[ 0 ]+ i*tDims[ 1 ];
876 for (
hsize_t i = 0; i < tDims[ 0 ]; ++i )
878 for (
hsize_t j = 0; j < tDims[ 1 ]; ++j )
880 aMatrix( j, i ) = tData[ i ][ j ];
886 for (
hsize_t j = 0; j < tDims[ 1 ]; ++j )
888 for (
hsize_t i = 0; i < tDims[ 0 ]; ++i )
890 aMatrix( i, j ) = tData[ i ][ j ];
897 else if( aStatus == 2 )
903 "Something went wrong while trying to load matrix %s of type %s",
911 const std::string & aLabel,
917 DatasetHandles tHandles ;
920 hsize_t tDim[ 1 ] = { tNumStrings };
921 tHandles.mDataSpace = H5Screate_simple( 1, tDim, NULL );
923 tHandles.mDataType = H5Tcopy( H5T_C_S1 );
924 H5Tset_size( tHandles.mDataType, H5T_VARIABLE );
926 tHandles.mDataSet = H5Dcreate2(
935 BELFEM_ERROR( tHandles.mDataSet > -1,
"Error creating dataset" );
938 for (
hsize_t i=0; i<tNumStrings; ++i )
940 tBuffer( i ) = aCell( i ).c_str();
957 const std::string & aLabel,
965 "Dataset %s does not exist at expected location.", aLabel.c_str() );
967 DatasetHandles tHandles ;
969 tHandles.mDataSet = H5Dopen1( aLoc, aLabel.c_str() );
971 tHandles.mDataSpace = H5Dget_space( tHandles.mDataSet );
977 const int tRank = H5Sget_simple_extent_ndims( tHandles.mDataSpace );
979 BELFEM_ERROR( tRank == 1,
"Dataset %s is not a 1-D array (rank %i)",
980 aLabel.c_str(), tRank );
982 BELFEM_ERROR( H5Sget_simple_extent_dims( tHandles.mDataSpace, tDim,
nullptr ) > -1 ,
983 "Error getting dataspace dimensions" );
985 hsize_t tNumStrings = tDim[ 0 ];
994 tHandles.mDataType = H5Tcopy( H5T_C_S1 );
995 H5Tset_size( tHandles.mDataType, H5T_VARIABLE );
997 hid_t tFileType = H5Dget_type( tHandles.mDataSet );
998 H5Tset_cset( tHandles.mDataType, H5Tget_cset( tFileType ) );
999 H5Tclose( tFileType );
1009 const herr_t tReadStatus = H5Dread( tHandles.mDataSet, tHandles.mDataType,
1010 H5S_ALL, H5S_ALL, H5P_DEFAULT, tBuffer.
data() );
1012 if( tReadStatus == 0 )
1016 for (
hsize_t i=0; i<tNumStrings; ++i )
1018 aCell( i ) = std::string( tBuffer( i ) );
1022 if( tNumStrings > 0 )
1024 H5Dvlen_reclaim( tHandles.mDataType, tHandles.mDataSpace, H5P_DEFAULT, tBuffer.
data() );
1027 BELFEM_ERROR( tReadStatus == 0,
"Failed to read strings from file." );
1047 "Group %s does not exist.",
1063 return H5Gclose( aGroup );
#define BELFEM_ERROR(aCheck,...)
Definition assert.hpp:264
#define BELFEM_ASSERT(aCheck,...)
Definition assert.hpp:244
A bounds-checked wrapper around std::vector.
Definition cl_Cell.hpp:45
void set_size(const size_t aSize)
New elements are value-initialized ( zero for arithmetic T, nullptr for pointers ).
Definition cl_Cell.hpp:199
size_t size() const
Definition cl_Cell.hpp:189
void clear()
Empties the Cell.
Definition cl_Cell.hpp:249
std::vector< T > & vector_data()
The underlying vector.
Definition cl_Cell.hpp:146
T * data()
Returns a borrowed pointer into contiguous storage, possibly nullptr when the Cell is empty ( test si...
Definition cl_Cell.hpp:129
Dense column-major matrix.
Definition cl_BZ_Matrix.hpp:28
void set_size(const size_t aNumRows, const size_t aNumCols)
Definition cl_AR_Matrix.hpp:164
size_t n_rows() const
Definition cl_AR_Matrix.hpp:183
size_t n_cols() const
Definition cl_AR_Matrix.hpp:191
Column vector.
Definition cl_BZ_Vector.hpp:41
T * data()
Returns a borrowed raw buffer under the layout contract stated in cl_Vector.hpp; may be nullptr when ...
Definition cl_AR_Vector.hpp:163
void set_size(const size_t aNumRows)
change the size of the vector
Definition cl_AR_Vector.hpp:215
size_t length() const
get the length of the vector
Definition cl_AR_Vector.hpp:235
Definition cl_HDF5_Dataset.hpp:21
void save_vector_to_file(hid_t &aLoc, const std::string &aLabel, const Vector< T > &aVector, herr_t &aStatus)
Definition hdf5_tools.hpp:553
bool group_exists(hid_t aLoc, const std::string &aLabel)
test if a group exists ( tests for a link of that name; the link type is not checked )
Definition hdf5_tools.hpp:94
void save_string_to_file(hid_t &aFileID, const std::string &aLabel, const std::string &aValue, herr_t &aStatus)
Definition hdf5_tools.cpp:121
void load_scalar_from_file(hid_t &aLoc, const std::string &aLabel, T &aValue, herr_t &aStatus)
Definition hdf5_tools.hpp:331
void save_array_to_file(hid_t &aLoc, const std::string &aLabel, const T *aData, const hsize_t &aLength, herr_t &aStatus)
Definition hdf5_tools.hpp:415
void load_bool_from_file(hid_t &aFileID, const std::string &aLabel, bool &aValue, herr_t &aStatus)
Definition hdf5_tools.cpp:75
void save_strings_to_file(hid_t &aLoc, const std::string &aLabel, const Cell< string > &aCell, herr_t &aStatus)
Definition hdf5_tools.hpp:910
void save_scalar_to_file(hid_t &aLoc, const std::string &aLabel, const T &aValue, herr_t &aStatus)
saves a scalar value to a file file must be open
Definition hdf5_tools.hpp:274
hid_t open_group(const std::string &aLabel, hid_t aParent)
Definition hdf5_tools.hpp:1033
void load_strings_from_file(hid_t &aLoc, const std::string &aLabel, Cell< string > &aCell, herr_t &aStatus)
Definition hdf5_tools.hpp:956
void load_matrix_from_file(hid_t &aLoc, const std::string &aLabel, Matrix< T > &aMatrix, herr_t &aStatus, const bool aTranspose=false)
Definition hdf5_tools.hpp:808
void save_matrix_to_file(hid_t &aLoc, const std::string &aLabel, const Matrix< T > &aMatrix, herr_t &aStatus, const bool aTranspose=false)
Definition hdf5_tools.hpp:703
bool check_datatye_size()
this function returns true of both the HDF5 datatype and the passed datatype have the same size
Definition hdf5_tools.hpp:215
hid_t datatype()
Definition hdf5_types.hpp:36
Cell< std::string > get_groups(hid_t aLoc)
list groups that exist in location
Definition hdf5_tools.hpp:174
hid_t filetype()
Definition hdf5_types.hpp:56
hsize_t get_array_size(hid_t &aFileID, const std::string &aLabel)
Definition hdf5_tools.cpp:223
bool dataset_exists(hid_t aLoc, const std::string &aLabel)
test if a dataset exists ( tests for a link of that name; the link type is not checked )
Definition hdf5_tools.hpp:77
string create_tree(const Cell< string > &aTree, const string &aLabel)
Definition hdf5_tools.cpp:258
void load_vector_from_file(hid_t &aLoc, const std::string &aLabel, Vector< T > &aVector, herr_t &aStatus)
Definition hdf5_tools.hpp:626
void check_read_datatype(const hid_t aFileType, const std::string &aLabel)
Guard for every read: the FILE datatype must be convertible into T.
Definition hdf5_tools.hpp:248
void load_string_from_file(hid_t &aFileID, const std::string &aLabel, std::string &aValue, herr_t &aStatus)
Definition hdf5_tools.cpp:178
void load_array_from_file(hid_t &aLoc, const std::string &aLabel, T *aData, const hsize_t aLength, herr_t &aStatus)
Definition hdf5_tools.hpp:484
void save_bool_to_file(hid_t &aFileID, const std::string &aLabel, const bool &aValue, herr_t &aStatus)
Definition hdf5_tools.cpp:21
herr_t close_group(hid_t aGroup)
Definition hdf5_tools.hpp:1060
USER GUIDES:
Definition cl_Capacitor.cpp:16
std::string datatype_string()
Definition stringtools.hpp:64
int hsize_t
Definition hdf5_types.hpp:22
int hid_t
Definition hdf5_types.hpp:20
int herr_t
Definition hdf5_types.hpp:21