8 #ifndef UTOPIA_DATAIO_HDFATTRIBUTE_HH
9 #define UTOPIA_DATAIO_HDFATTRIBUTE_HH
79 template <
typename result_type >
83 this->
_log->debug(
"Creating attribute {}",
_path);
105 template <
typename Type >
109 this->
_log->debug(
"Writing container data to attribute {} ...",
_path);
110 using value_type_1 =
typename Type::value_type;
115 if constexpr (std::is_same_v< Type, std::vector< value_type_1 > > and
116 not Utils::is_container_v< value_type_1 > and
117 not Utils::is_string_v< value_type_1 >)
119 this->
_log->debug(
"... of simple vector type");
124 __create_attribute__< base_type >(0);
134 this->
_log->debug(
"... of non-trivial container type");
137 if constexpr (Utils::is_array_like_v< value_type_1 >)
139 this->
_log->debug(
"... of fixed size array type");
140 constexpr std::size_t s =
145 __create_attribute__< base_type >(s);
151 [](
auto& value) -> value_type_1& {
return value; });
157 this->
_log->debug(
"... of variable length type");
160 __create_attribute__< base_type >();
166 [](
auto& value) -> value_type_1& {
return value; });
174 template <
typename Type >
179 this->
_log->debug(
"Writing string data to attribute {} ...",
_path);
185 const char* buffer =
nullptr;
187 if constexpr (std::is_pointer_v< Type >)
190 len = std::strlen(attribute_data);
191 buffer = attribute_data;
195 len = attribute_data.size();
196 buffer = attribute_data.c_str();
202 __create_attribute__< const char* >(len);
211 template <
typename Type >
215 this->
_log->debug(
"Writing pointer data to attribute {} ...",
_path);
222 __create_attribute__< basetype >();
229 template <
typename Type >
233 this->
_log->debug(
"Writing scalar data to attribute {} ...",
_path);
239 __create_attribute__< std::decay_t< Type > >();
250 template <
typename Type >
255 this->
_log->debug(
"Reading container data from attribute {} ...",
266 if constexpr (Utils::is_container_v< value_type_1 >)
274 if constexpr (Utils::is_container_v< value_type_2 >)
276 throw std::runtime_error(
277 "Cannot read data into nested containers with depth > 3 "
279 _path +
" into vector containers!");
289 if constexpr (Utils::is_array_like_v< value_type_1 >)
291 this->
_log->debug(
"... of fixed size array type");
296 this->
_log->debug(
"... of variable size type");
298 std::vector< hvl_t > temp_buffer(buffer.size());
306 this->
_log->debug(
"... turning read data into desired type");
308 for (std::size_t i = 0; i < buffer.size(); ++i)
310 buffer[i].resize(temp_buffer[i].len);
311 for (std::size_t j = 0; j < temp_buffer[i].len; ++j)
314 static_cast< value_type_2*
>(temp_buffer[i].p)[j];
318 #if H5_VERSION_GE(1, 12 , 0)
332 throw std::runtime_error(
"Error, something went wrong while reading in " +
_path +
" while reclaiming vlen memory");
341 if constexpr (!std::is_same_v< std::vector< value_type_1 >, Type >)
343 throw std::runtime_error(
"Can only read data from " +
_path +
344 " into vector containers!");
351 if constexpr (Utils::is_string_v< value_type_1 >)
353 this->
_log->debug(
"... of string type");
355 std::vector< char* > temp_buffer(buffer.size());
357 herr_t err = H5Aread(
361 for (std::size_t i = 0; i < buffer.size(); ++i)
363 buffer[i] = temp_buffer[i];
368 for (
auto&& c: temp_buffer)
377 this->
_log->debug(
"... of scalar type");
388 template <
typename Type >
393 this->
_log->debug(
"Reading string type from attribute {}",
_path);
404 template <
typename Type >
408 this->
_log->debug(
"Reading pointer type from attribute {}",
_path);
414 template <
typename Type >
418 this->
_log->debug(
"Reading scalar type from attribute {}",
_path);
440 swap(
static_cast< Base&
>(*
this),
static_cast< Base&
>(other));
509 _shape.assign(shape.begin(), shape.end());
520 template < HDFCategory cat >
525 "Opening attribute named {} in object {}", name, parent.
get_path());
549 this->
_log->debug(
"... attribute exists already, opening");
568 this->
_log->debug(
"... attribute does not yet exist, have to "
569 "wait for incoming data to build it");
576 throw std::invalid_argument(
577 "Parent object of attribute '" +
_path +
578 "' is invalid! Has it been closed already or not been opened "
607 template <
typename Type >
611 this->
_log->debug(
"Reading attribute {}",
_path);
613 if (_shape.size() == 0)
621 std::size_t size = 1;
622 for (
auto& value :
_shape)
629 if constexpr (Utils::is_container_v< Type >)
635 throw std::runtime_error(
"Error in reading data from " +
_path +
636 " into container types");
639 return std::make_tuple(
_shape, buffer);
641 else if constexpr (Utils::is_string_v< Type >)
651 throw std::runtime_error(
"Error in reading data from " +
_path +
655 return std::make_tuple(
_shape, buffer);
657 else if constexpr (std::is_pointer_v< Type > &&
658 !Utils::is_string_v< Type >)
660 std::shared_ptr< Utils::remove_qualifier_t<Type> > buffer(
666 throw std::runtime_error(
"Error in reading data from " +
_path +
667 " into pointertype");
669 return std::make_tuple(
_shape, buffer);
677 throw std::runtime_error(
"Error in reading data from " +
_path +
680 return std::make_tuple(
_shape, buffer);
693 template <
typename Type >
697 this->
_log->debug(
"Reading attribute {} into given buffer",
_path);
699 if (_shape.size() == 0)
706 if constexpr (Utils::is_container_v< Type >)
710 std::size_t size = 1;
711 for (
auto& value :
_shape)
716 if (buffer.size() != size)
724 throw std::runtime_error(
"Error in reading data from " +
_path +
725 " into container types");
728 else if constexpr (Utils::is_string_v< Type >)
737 throw std::runtime_error(
"Error in reading data from " +
_path +
741 else if constexpr (std::is_pointer_v< Type > &&
742 !Utils::is_string_v< Type >)
748 throw std::runtime_error(
"Error in reading data from " +
_path +
749 " into pointertype");
757 throw std::runtime_error(
"Error in reading data from " +
_path +
778 template <
typename Type >
780 write(Type attribute_data, std::vector< hsize_t > shape = {})
782 this->
_log->debug(
"Writing data to attribute {}",
_path);
787 if constexpr (Utils::is_container_v< Type >)
794 _shape = { attribute_data.size() };
804 throw std::runtime_error(
805 "An error occurred while writing a containertype to "
813 else if constexpr (Utils::is_string_v< Type >)
821 throw std::runtime_error(
822 "An error occurred while writing a stringtype to "
830 else if constexpr (std::is_pointer_v< Type > &&
831 !Utils::is_string_v< Type >)
833 if (shape.size() == 0)
835 throw std::runtime_error(
836 "Attribute: " +
_path +
838 "The shape parameter has to be given for pointers "
840 "it cannot be determined automatically");
851 throw std::runtime_error(
852 "An error occurred while writing a pointertype/plain array "
866 throw std::runtime_error(
867 "An error occurred while writing a scalar "
887 template <
typename Iter,
typename Adaptor >
892 Adaptor adaptor = [](
auto& value) {
return value; },
893 [[maybe_unused]] std::vector< hsize_t > shape = {})
895 this->
_log->debug(
"Writing data from iterator range to attribute {}",
901 if constexpr (std::is_same< Type, typename Iter::value_type >::value)
908 std::vector< Type > buff(std::distance(
begin,
end));
909 std::generate(buff.begin(), buff.end(), [&
begin, &adaptor]() {
910 return adaptor(*(begin++));
971 template < HDFCategory cat >
Class for hdf5 attribute, which can be attached to groups and datasets.
Definition: hdfattribute.hh:46
virtual ~HDFAttribute()
Destructor.
Definition: hdfattribute.hh:959
void close()
closes the attribute
Definition: hdfattribute.hh:483
HDFType _type
type done in the HDFAttribute
Definition: hdfattribute.hh:68
auto __read_pointertype__(Type buffer)
Definition: hdfattribute.hh:406
herr_t __read_container__(Type &buffer)
Definition: hdfattribute.hh:252
HDFAttribute(const HDFObject< cat > &object, std::string name)
Constructor for attribute.
Definition: hdfattribute.hh:972
auto __read_scalartype__(Type &buffer)
Definition: hdfattribute.hh:416
HDFIdentifier get_parent_id()
Get the hdf5 identifier to which the attribute belongs.
Definition: hdfattribute.hh:474
void __create_attribute__(hsize_t typesize=0)
private helper function for creation of attribute
Definition: hdfattribute.hh:81
herr_t __write_stringtype__(Type attribute_data)
Definition: hdfattribute.hh:176
auto read()
Reads data from attribute, and returns the data and its shape in the form of a hsize_t vector.
Definition: hdfattribute.hh:609
void open(const HDFObject< cat > &parent, std::string name)
Open a new attribute on HDFObject 'parent' with name 'name'.
Definition: hdfattribute.hh:522
HDFAttribute & operator=(HDFAttribute &&other)=default
Attribute move assignment operator.
void open(const HDFIdentifier &parent, std::string name)
Open a new attribute on HDFObject 'parent' with name 'name'.
Definition: hdfattribute.hh:536
HDFDataspace get_filespace()
Get the file-dataspace object.
Definition: hdfattribute.hh:452
HDFAttribute(const HDFAttribute &other)=default
Copy constructor.
auto get_shape()
Get the shape object.
Definition: hdfattribute.hh:504
void write(Iter begin, Iter end, Adaptor adaptor=[](auto &value) { return value;}, [[maybe_unused]] std::vector< hsize_t > shape={})
Function for writing data to the attribute.
Definition: hdfattribute.hh:889
auto __read_stringtype__(Type &buffer)
Definition: hdfattribute.hh:390
HDFAttribute & operator=(const HDFAttribute &other)=default
Copy assignment operator.
void swap(HDFAttribute &other)
Exchange states between caller and argument.
Definition: hdfattribute.hh:436
void write(Type attribute_data, std::vector< hsize_t > shape={})
Function for writing data to the attribute.
Definition: hdfattribute.hh:780
HDFAttribute(HDFAttribute &&other)=default
Move constructor.
std::vector< hsize_t > _shape
size of the attributes dataspace
Definition: hdfattribute.hh:51
herr_t __write_pointertype__(Type attribute_data)
Definition: hdfattribute.hh:213
HDFIdentifier _parent_identifier
Identifier of the parent object.
Definition: hdfattribute.hh:56
herr_t __write_container__(Type attribute_data)
Function for writing containers as attribute.
Definition: hdfattribute.hh:107
herr_t __write_scalartype__(Type attribute_data)
Definition: hdfattribute.hh:231
void read(Type &buffer)
Reads data from attribute into a predefined buffer, and returns the data and its shape in the form of...
Definition: hdfattribute.hh:695
HDFDataspace _dataspace
Dataspace object that manages topology of data written and read.
Definition: hdfattribute.hh:62
auto get_type()
Get the type object.
Definition: hdfattribute.hh:463
HDFAttribute()=default
Default constructor, deleted because of reference member.
static auto buffer(Iter begin, Iter end, Adaptor &&adaptor)
static function for turning an iterator range with arbitrarty datatypes into a vector of data as retu...
Definition: hdfbufferfactory.hh:96
Class that wraps an HDF5 dataspace and takes care of managing its resources.
Definition: hdfdataspace.hh:37
Wrapper class around an hdf5 identifier, used to manage reference counts of the object this identifie...
Definition: hdfidentifier.hh:29
void close()
Close the identifier and render the C-Level id held invalid.
Definition: hdfidentifier.hh:134
hid_t get_id() const
Get the HDF5 id held by this object.
Definition: hdfidentifier.hh:53
bool is_valid() const
Check if thi ID refers to a valid object.
Definition: hdfidentifier.hh:77
Common base class for all HDF5 classes in the DATAIO Module i.e., for all classes that wrap HDF5-C-Li...
Definition: hdfobject.hh:37
auto get_id_object() const
Get the id object.
Definition: hdfobject.hh:99
std::string _path
Name of the object.
Definition: hdfobject.hh:50
std::string get_path() const
Get the name or path object.
Definition: hdfobject.hh:88
void close()
Close function which takes care of correctly closing the object and managing the reference counter.
Definition: hdfobject.hh:161
virtual bool is_valid() const
Check if the object is still valid.
Definition: hdfobject.hh:143
std::shared_ptr< spdlog::logger > _log
pointer to the logger for dataio
Definition: hdfobject.hh:56
HDFIdentifier _id
Identifier object that binds an instance of this class to an HDF5 object.
Definition: hdfobject.hh:44
hid_t get_C_id() const
Get the C id object.
Definition: hdfobject.hh:120
void bind_to(hid_t id, std::function< herr_t(hid_t) > closing_func, std::string path={})
Open the object and bind it to a HDF5 object identified by 'id' with name 'path'. Object should be cr...
Definition: hdfobject.hh:186
Class which handles the conversion of C-types into hdf5types.
Definition: hdftype.hh:136
void open(T &&object)
Open the HDF5 type associated with an HDFObject, i.e., a dataset or an attribute.
Definition: hdftype.hh:224
void close()
Construct close from the given arguments.
Definition: hdftype.hh:322
std::size_t size() const
Size of the type held in bytes.
Definition: hdftype.hh:210
void swap(WriteTask< BGB, DW, DB, AWG, AWD > &lhs, WriteTask< BGB, DW, DB, AWG, AWD > &rhs)
Swaps the state of lhs and rhs.
Definition: write_task.hh:240
arma::Row< hsize_t > size()
Get the current size of the dataspace in each dimension.
Definition: hdfdataspace.hh:94
void swap(HDFAttribute &lhs, HDFAttribute &rhs)
Swaps the states of Attributes rhs and lhs.
Definition: hdfattribute.hh:988
void open()
Open the dataspace - set it to be equivalent to any data that later will be used to write or read.
Definition: hdfdataspace.hh:117
In this file, a class for automatically creating intermediate buffer data structures between the user...
This file provides a class which is responsible for the automatic conversion between C/C++ types and ...
typename remove_qualifier< T >::type remove_qualifier_t
Shorthand for 'typename remove_qualifier::value'.
Definition: type_traits.hh:97
Definition: parallel.hh:235
Return the size of a Type T containing other types at compile time. If no object for which an overloa...
Definition: type_traits.hh:438