8#ifndef THEORETICA_IO_HDF5_H
9#define THEORETICA_IO_HDF5_H
15#include <unordered_map>
22#include "../core/constants.h"
23#include "../algebra/vec.h"
24#include "../algebra/mat.h"
68 std::unordered_map<std::string, hdf5_node>
children;
148 if (
this != &
other) {
168 namespace _internal {
173 template<
typename Type>
174 inline hid_t hdf5_type() {
187 inline void suppress_errors() {
195 inline void remove_link(
const hdf5_handle&
id,
const std::string& path) {
216 inline void load_attributes(
hid_t obj_id, std::vector<std::string>& attributes) {
222 template<
typename Type>
233 inline void read_attribute(
hid_t attr_id, std::string& value) {
238 value = std::string();
251 value = std::string();
255 value =
buf ? std::string(
buf) : std::string();
262 std::vector<char>
buf (size + 1,
'\0');
268 value = std::string();
272 value = std::string(
buf.data());
276 value = std::string();
283 template<
typename Type>
284 inline void write_attribute(
hid_t obj_id,
const std::string& name,
const Type& value) {
300 inline void write_attribute(
hid_t obj_id,
const std::string& name,
const std::string& value) {
320 inline void write_attribute(
hid_t obj_id,
const std::string& name,
const char*
str) {
321 write_attribute(
obj_id, name, std::string(
str));
334 child.path =
"/" + std::string(name);
336 child.path =
parent->path +
"/" + std::string(name);
367 std::vector<hsize_t>
dims (
static_cast<size_t>(
ndims));
388 inline void build_tree(
389 std::ostringstream&
oss,
const hdf5_node&
node,
400 if (
node.is_dataset()) {
403 for (
size_t i = 0; i <
node.dimensions.size(); ++i) {
405 if (i + 1 <
node.dimensions.size())
413 if (!
node.attributes.empty()) {
414 oss <<
" (@" <<
node.attributes.size() <<
" attrs)";
419 if (
node.children.empty())
449 std::ostringstream
oss;
450 _internal::build_tree(
oss,
node,
"",
true,
true);
474 _internal::suppress_errors();
523 _internal::suppress_errors();
529 root.dimensions.clear();
530 root.attributes.clear();
531 root.children.clear();
533 _internal::load_attributes(
id,
root.attributes);
546 _internal::suppress_errors();
568 _internal::suppress_errors();
589 template<
typename Type>
592 _internal::suppress_errors();
609 _internal::read_attribute(
attr_id, value);
621 _internal::suppress_errors();
646 template<
typename Type>
649 _internal::suppress_errors();
673 template<
typename Vector = vec<real>>
676 using Type = vector_element_t<Vector>;
678 _internal::suppress_errors();
698 if (v.size() !=
dims[0]) {
718 template<
typename Vector = vec<real>>
731 template<
typename Vector>
734 using Type = vector_element_t<Vector>;
735 _internal::remove_link(
id, path);
759 _internal::suppress_errors();
775 template<
typename Matrix = mat<real>>
778 using Type = matrix_element_t<Matrix>;
779 _internal::suppress_errors();
798 if (
m.rows() !=
dims[0] ||
m.cols() !=
dims[1]) {
818 template<
typename Matrix = mat<real>>
831 template<
typename Matrix>
834 using Type = matrix_element_t<Matrix>;
835 _internal::remove_link(
id, path);
859 std::string m_filename;
897 m_root.
name = m_filename;
958 const std::string path = (
parent.path ==
"/")
988 template<
typename Vector = vec<real>>
1000 template<
typename Vector = vec<real>>
1011 template<
typename Vector>
1021 template<
typename Vector>
1034 template<
typename Matrix = mat<real>>
1045 template<
typename Matrix = mat<real>>
1056 template<
typename Matrix>
1067 template<
typename Matrix>
1097 template<
typename Type>
1109 template<
typename Type>
1121 template<
typename Type>
1133 template<
typename Type>
1162 return io::to_string(m_root);
1172 return os <<
file.to_string();
High-level interface for managing an HDF5 file, its structure, and operations.
Definition hdf5.h:855
hid_t id() const
Get the raw ID of the HDF5 file handle for direct API access.
Definition hdf5.h:927
Matrix read_mat(const std::string &path) const
Read a 2D dataset array into a matrix from the given path.
Definition hdf5.h:1035
void write_vec(const std::string &path, const Vector &v)
Writes a 1D vector to an HDF5 dataset at the given path, overwriting if it exists.
Definition hdf5.h:1012
Type read_attribute(const hdf5_node &node, const std::string &attr_name) const
Read metadata (attribute) attached to a specific node by reference.
Definition hdf5.h:1110
void write_mat(const hdf5_node &node, const Matrix &m)
Write a 2D matrix to an HDF5 dataset at the given node, overwriting if it exists.
Definition hdf5.h:1068
void delete_attribute(const std::string &path, const std::string &attr_name)
Delete an attribute attached to a specific node by path, if it exists.
Definition hdf5.h:1143
void delete_group(const hdf5_node &node)
Delete a group referenced by a node.
Definition hdf5.h:975
const hdf5_node & root() const
Get the base node containing the entire loaded file structure.
Definition hdf5.h:920
void delete_dataset(const std::string &path)
Delete a dataset at the given path if it exists.
Definition hdf5.h:1076
void create_group(const std::string &path)
Create a new group inside the file.
Definition hdf5.h:948
void create_group(const hdf5_node &parent, const std::string &child_name)
Create a new group using a parent node and a child name.
Definition hdf5.h:956
void write_attribute(const std::string &path, const std::string &attr_name, const Type &value)
Write or overwrite metadata (attribute) attached to a specific node by path.
Definition hdf5.h:1122
void write_attribute(const hdf5_node &node, const std::string &attr_name, const Type &value)
Write or overwrite metadata (attribute) attached to a specific node by reference.
Definition hdf5.h:1134
void write_mat(const std::string &path, const Matrix &m)
Write a 2D matrix to an HDF5 dataset at the given path, overwriting if it exists.
Definition hdf5.h:1057
void delete_dataset(const hdf5_node &node)
Delete a dataset at the given node if it exists.
Definition hdf5.h:1084
void delete_group(const std::string &path)
Delete a group inside the file.
Definition hdf5.h:968
void close()
Close the HDF5 file immediately.
Definition hdf5.h:902
Vector read_vec(const hdf5_node &node) const
Loads a 1D dataset array into a vector from the given node inside the HDF5 file.
Definition hdf5.h:1001
hdf5_file(const std::string &filename, bool write=false)
Open the file persistently.
Definition hdf5.h:873
void write_vec(const hdf5_node &node, const Vector &v)
Writes a 1D vector to the HDF5 dataset represented by the given node, overwriting if it exists.
Definition hdf5.h:1022
Matrix read_mat(const hdf5_node &node) const
Read a 2D dataset array into a matrix from the given node.
Definition hdf5.h:1046
hdf5_node & operator[](const std::string &child_name)
Access children of the root node by reference using dictionary-like syntax.
Definition hdf5.h:934
void refresh()
Refresh the cached tree structure from disk.
Definition hdf5.h:882
Type read_attribute(const std::string &path, const std::string &attr_name) const
Read metadata (attribute) attached to a specific node by path.
Definition hdf5.h:1098
const std::string & filename() const
Get the name of the file.
Definition hdf5.h:913
Vector read_vec(const std::string &path) const
Loads a 1D dataset array into a vector from the given path inside the HDF5 file.
Definition hdf5.h:989
std::string to_string() const
Converts an entire HDF5 file structure into a formatted tree string.
Definition hdf5.h:1161
friend std::ostream & operator<<(std::ostream &os, const hdf5_file &file)
Print the HDF5 file structure to a stream in a formatted tree representation.
Definition hdf5.h:1171
const hdf5_node & operator[](const std::string &child_name) const
Access children of the root node by const reference using dictionary-like syntax.
Definition hdf5.h:941
void delete_attribute(const hdf5_node &node, const std::string &attr_name)
Delete an attribute attached to a specific node by path, if it exists.
Definition hdf5.h:1152
Error handling for IO operations.
Matrix & mat_error(Matrix &m)
Overwrite the given matrix with the error matrix with NaN values on the diagonal and zeroes everywher...
Definition algebra.h:40
Vector & vec_error(Vector &v)
Overwrite the given vector with the error vector with NaN values.
Definition algebra.h:58
hdf5_node hdf5_load(const hdf5_handle &id)
Recursively loads the structure of an active HDF5 group or file.
Definition hdf5.h:521
void hdf5_create_group(const hdf5_handle &id, const std::string &path)
Create a new group at the given path under an already open HDF5 location.
Definition hdf5.h:544
void hdf5_delete_dataset(const hdf5_handle &id, const std::string &path)
Deletes a dataset at the given path if it exists.
Definition hdf5.h:757
void hdf5_delete_group(const hdf5_handle &id, const std::string &path)
Delete a group (link) at the given path under an already open HDF5 location.
Definition hdf5.h:566
std::ostream & operator<<(std::ostream &os, const hdf5_node &node)
Prints the HDF5 file tree to a stream.
Definition hdf5.h:460
bool hdf5_is_valid(const hdf5_handle &handle)
Check whether a given HDF5 handle is valid.
Definition hdf5.h:512
Matrix hdf5_read_mat(const hdf5_handle &id, const std::string &path, Matrix &m)
Loads a 2D dataset array into a matrix.
Definition hdf5.h:776
@ FileNotFound
File or directory not found.
@ WriteError
Error occurred while writing to the file or stream.
@ FormatError
The file format is invalid or the data is corrupted.
@ ReadError
Error occurred while reading from the file or stream.
Type hdf5_read_attribute(const hdf5_handle &id, const std::string &path, const std::string &attr_name)
Reads an attribute attached to a specific node.
Definition hdf5.h:590
void hdf5_write_vec(const hdf5_handle &id, const std::string &path, const Vector &v)
Writes a 1D vector to an HDF5 dataset, overwriting if it exists.
Definition hdf5.h:732
void hdf5_delete_attribute(const hdf5_handle &id, const std::string &path, const std::string &attr_name)
Deletes an attribute attached to a specific node, if it exists.
Definition hdf5.h:619
Vector & hdf5_read_vec(const hdf5_handle &id, const std::string &path, Vector &v)
Loads a 1D dataset array into a vector.
Definition hdf5.h:674
HDF5NodeType
Type of node inside an HDF5 file.
Definition hdf5.h:34
@ DATASET
A node containing multi-dimensional array data.
@ UNKNOWN
An unsupported node type.
@ GROUP
A structural grouping containing other groups or datasets.
void hdf5_write_mat(const hdf5_handle &id, const std::string &path, const Matrix &m)
Writes a 2D matrix to an HDF5 dataset, overwriting if it exists.
Definition hdf5.h:832
void hdf5_write_attribute(const hdf5_handle &id, const std::string &path, const std::string &attr_name, const Type &value)
Writes or overwrites an attribute attached to a specific node.
Definition hdf5.h:647
hdf5_handle hdf5_open(const std::string &filename, bool write=false)
Open an HDF5 file with the given filename, returning a file handle.
Definition hdf5.h:472
Main namespace of the library which contains all functions and objects.
Definition algebra.h:27
TH_CONSTEXPR Type make_error()
Create a number representing an error state, constructed from a NaN value.
Definition real_analysis.h:1322
TH_CONSTEXPR real nan()
Return a quiet NaN number in floating point representation.
Definition error.h:78
std::string to_string(MathError err)
Convert a MathError class enum to a string description.
Definition error.h:72
real root(real x, int n)
Compute the n-th root of x.
Definition real_analysis.h:812
RAII wrapper for managing HDF5 C-style handles, allowing direct API usage.
Definition hdf5.h:104
hid_t id
Underlying ID obtained by opening a file or group.
Definition hdf5.h:108
hdf5_handle(const hdf5_handle &)=delete
Prevent copying.
hdf5_handle(hdf5_handle &&other) noexcept
Move constructor.
Definition hdf5.h:140
hdf5_handle & operator=(hdf5_handle &&other) noexcept
Move assignment.
Definition hdf5.h:146
~hdf5_handle()
Safely decrements reference count and closes the handle if valid.
Definition hdf5.h:118
hdf5_handle(hid_t id=H5I_INVALID_HID)
Initialize the handle with a given HDF5 ID, for example obtained by opening a file or group,...
Definition hdf5.h:114
Represents a single node (group or dataset) in the HDF5 file hierarchy.
Definition hdf5.h:49
std::unordered_map< std::string, hdf5_node > children
For groups, the child nodes indexed by their local name.
Definition hdf5.h:68
std::vector< std::string > attributes
List of metadata attribute names attached to the node.
Definition hdf5.h:65
bool is_group() const noexcept
Check whether the node is a group.
Definition hdf5.h:72
std::vector< size_t > dimensions
For datasets, the dimensions of the array.
Definition hdf5.h:62
bool is_dataset() const noexcept
Check whether the node is a dataset.
Definition hdf5.h:78
HDF5NodeType type
The type of the node.
Definition hdf5.h:59
const hdf5_node & operator[](const std::string &child_name) const
Read-only dictionary-like access to child nodes by name.
Definition hdf5.h:96
std::string name
The local name of the node (e.g. "my_dataset")
Definition hdf5.h:52
hdf5_node & operator[](const std::string &child_name)
Dictionary-like access to child nodes by name.
Definition hdf5.h:87
std::string path
The absolute internal path to the node (e.g.
Definition hdf5.h:56