9#ifndef THEORETICA_IO_HDF5_H
10#define THEORETICA_IO_HDF5_H
16#include <unordered_map>
23#include "../core/constants.h"
24#include "../algebra/vec.h"
25#include "../algebra/mat.h"
69 std::unordered_map<std::string, hdf5_node>
children;
149 if (
this != &
other) {
169 namespace _internal {
174 template<
typename Type>
217 inline void load_attributes(
hid_t obj_id, std::vector<std::string>& attributes) {
223 template<
typename Type>
234 inline void read_attribute(
hid_t attr_id, std::string& value) {
239 value = std::string();
252 value = std::string();
256 value =
buf ? std::string(
buf) : std::string();
263 std::vector<char>
buf (size + 1,
'\0');
269 value = std::string();
273 value = std::string(
buf.data());
277 value = std::string();
284 template<
typename Type>
285 inline void write_attribute(
hid_t obj_id,
const std::string& name,
const Type& value) {
301 inline void write_attribute(
hid_t obj_id,
const std::string& name,
const std::string& value) {
321 inline void write_attribute(
hid_t obj_id,
const std::string& name,
const char*
str) {
322 write_attribute(
obj_id, name, std::string(
str));
335 child.path =
"/" + std::string(name);
337 child.path =
parent->path +
"/" + std::string(name);
368 std::vector<hsize_t>
dims (
static_cast<size_t>(
ndims));
389 inline void build_tree(
390 std::ostringstream&
oss,
const hdf5_node&
node,
401 if (
node.is_dataset()) {
404 for (
size_t i = 0; i <
node.dimensions.size(); ++i) {
406 if (i + 1 <
node.dimensions.size())
414 if (!
node.attributes.empty()) {
415 oss <<
" (@" <<
node.attributes.size() <<
" attrs)";
420 if (
node.children.empty())
450 std::ostringstream
oss;
451 _internal::build_tree(
oss,
node,
"",
true,
true);
475 _internal::suppress_errors();
524 _internal::suppress_errors();
530 root.dimensions.clear();
531 root.attributes.clear();
532 root.children.clear();
534 _internal::load_attributes(
id,
root.attributes);
547 _internal::suppress_errors();
569 _internal::suppress_errors();
590 template<
typename Type>
593 _internal::suppress_errors();
610 _internal::read_attribute(
attr_id, value);
622 _internal::suppress_errors();
647 template<
typename Type>
650 _internal::suppress_errors();
674 template<
typename Vector = vec<real>>
677 using Type = vector_element_t<Vector>;
679 _internal::suppress_errors();
699 if (v.size() !=
dims[0]) {
719 template<
typename Vector = vec<real>>
732 template<
typename Vector>
735 using Type = vector_element_t<Vector>;
736 _internal::remove_link(
id, path);
760 _internal::suppress_errors();
776 template<
typename Matrix = mat<real>>
779 using Type = matrix_element_t<Matrix>;
780 _internal::suppress_errors();
799 if (
m.rows() !=
dims[0] ||
m.cols() !=
dims[1]) {
819 template<
typename Matrix = mat<real>>
832 template<
typename Matrix>
835 using Type = matrix_element_t<Matrix>;
836 _internal::remove_link(
id, path);
860 std::string m_filename;
898 m_root.
name = m_filename;
959 const std::string path = (
parent.path ==
"/")
989 template<
typename Vector = vec<real>>
1001 template<
typename Vector = vec<real>>
1012 template<
typename Vector>
1022 template<
typename Vector>
1035 template<
typename Matrix = mat<real>>
1046 template<
typename Matrix = mat<real>>
1057 template<
typename Matrix>
1068 template<
typename Matrix>
1098 template<
typename Type>
1110 template<
typename Type>
1122 template<
typename Type>
1134 template<
typename Type>
1163 return io::to_string(m_root);
1173 return os <<
file.to_string();
High-level interface for managing an HDF5 file, its structure, and operations.
Definition hdf5.h:856
hid_t id() const
Get the raw ID of the HDF5 file handle for direct API access.
Definition hdf5.h:928
Matrix read_mat(const std::string &path) const
Read a 2D dataset array into a matrix from the given path.
Definition hdf5.h:1036
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:1013
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:1111
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:1069
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:1144
void delete_group(const hdf5_node &node)
Delete a group referenced by a node.
Definition hdf5.h:976
const hdf5_node & root() const
Get the base node containing the entire loaded file structure.
Definition hdf5.h:921
void delete_dataset(const std::string &path)
Delete a dataset at the given path if it exists.
Definition hdf5.h:1077
void create_group(const std::string &path)
Create a new group inside the file.
Definition hdf5.h:949
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:957
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:1123
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:1135
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:1058
void delete_dataset(const hdf5_node &node)
Delete a dataset at the given node if it exists.
Definition hdf5.h:1085
void delete_group(const std::string &path)
Delete a group inside the file.
Definition hdf5.h:969
void close()
Close the HDF5 file immediately.
Definition hdf5.h:903
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:1002
hdf5_file(const std::string &filename, bool write=false)
Open the file persistently.
Definition hdf5.h:874
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:1023
Matrix read_mat(const hdf5_node &node) const
Read a 2D dataset array into a matrix from the given node.
Definition hdf5.h:1047
hdf5_node & operator[](const std::string &child_name)
Access children of the root node by reference using dictionary-like syntax.
Definition hdf5.h:935
void refresh()
Refresh the cached tree structure from disk.
Definition hdf5.h:883
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:1099
const std::string & filename() const
Get the name of the file.
Definition hdf5.h:914
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:990
std::string to_string() const
Converts an entire HDF5 file structure into a formatted tree string.
Definition hdf5.h:1162
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:1172
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:942
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:1153
void remove_link(const hdf5_handle &id, const std::string &path)
Removes a link (dataset or group) if it exists at the given path.
Definition hdf5.h:196
void suppress_errors()
Suppress HDF5 error messages by setting a custom dummy error handler.
Definition hdf5.h:188
hid_t hdf5_type()
Helper template to map C++ types to HDF5 Native Types.
Definition hdf5.h:175
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:522
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:545
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:758
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:567
std::ostream & operator<<(std::ostream &os, const hdf5_node &node)
Prints the HDF5 file tree to a stream.
Definition hdf5.h:461
bool hdf5_is_valid(const hdf5_handle &handle)
Check whether a given HDF5 handle is valid.
Definition hdf5.h:513
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:777
@ 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:591
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:733
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:620
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:675
HDF5NodeType
Type of node inside an HDF5 file.
Definition hdf5.h:35
@ 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:833
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:648
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:473
Main namespace of the library which contains all functions and objects.
Definition algebra.h:27
Vector make_error()
Create a vector representing an error state, with all NaN values.
Definition algebra.h:103
TH_CONSTEXPR real nan()
Return a quiet NaN number in floating point representation.
Definition error.h:74
std::string to_string(MathError err)
Convert a MathError class enum to a string description.
Definition error.h:68
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:105
hid_t id
Underlying ID obtained by opening a file or group.
Definition hdf5.h:109
hdf5_handle(const hdf5_handle &)=delete
Prevent copying.
hdf5_handle(hdf5_handle &&other) noexcept
Move constructor.
Definition hdf5.h:141
hdf5_handle & operator=(hdf5_handle &&other) noexcept
Move assignment.
Definition hdf5.h:147
~hdf5_handle()
Safely decrements reference count and closes the handle if valid.
Definition hdf5.h:119
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:115
Represents a single node (group or dataset) in the HDF5 file hierarchy.
Definition hdf5.h:50
std::unordered_map< std::string, hdf5_node > children
For groups, the child nodes indexed by their local name.
Definition hdf5.h:69
std::vector< std::string > attributes
List of metadata attribute names attached to the node.
Definition hdf5.h:66
bool is_group() const noexcept
Check whether the node is a group.
Definition hdf5.h:73
std::vector< size_t > dimensions
For datasets, the dimensions of the array.
Definition hdf5.h:63
bool is_dataset() const noexcept
Check whether the node is a dataset.
Definition hdf5.h:79
HDF5NodeType type
The type of the node.
Definition hdf5.h:60
const hdf5_node & operator[](const std::string &child_name) const
Read-only dictionary-like access to child nodes by name.
Definition hdf5.h:97
std::string name
The local name of the node (e.g. "my_dataset")
Definition hdf5.h:53
hdf5_node & operator[](const std::string &child_name)
Dictionary-like access to child nodes by name.
Definition hdf5.h:88
std::string path
The absolute internal path to the node (e.g.
Definition hdf5.h:57