/home/runner/work/DiFfRG_current/DiFfRG_current/DiFfRG/include/hdf5lib/group.hh Source File#

DiFfRG: /home/runner/work/DiFfRG_current/DiFfRG_current/DiFfRG/include/hdf5lib/group.hh Source File
DiFfRG
group.hh
Go to the documentation of this file.
1#pragma once
2
3#include <hdf5lib/dataset.hh>
5#include <hdf5lib/datatype.hh>
7#include <hdf5lib/handle.hh>
8
9#include <string>
10#include <type_traits>
11#include <vector>
12
13namespace DiFfRG::hdf5
14{
15 class Group
16 {
17 public:
18 Group() = default;
19 explicit Group(hid_t id) : h_(id) {}
20 static Group take(hid_t id) { return Group(Handle::take(id)); }
21
22 hid_t id() const noexcept { return h_.get(); }
23 bool valid() const noexcept { return h_.valid(); }
24
25 // ----------------- subgroups -----------------
26
27 Group create_group(const std::string &name)
28 {
29 hid_t g = H5Gcreate2(h_.get(), name.c_str(), H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
30 throw_if_negative(g, "H5Gcreate2 failed");
31 return Group::take(g);
32 }
33
34 Group open_group(const std::string &name)
35 {
36 hid_t g = H5Gopen2(h_.get(), name.c_str(), H5P_DEFAULT);
37 throw_if_negative(g, "H5Gopen2 failed");
38 return Group::take(g);
39 }
40
41 bool has_group(const std::string &name) const { return child_kind(name) == H5O_TYPE_GROUP; }
42 bool has_dataset(const std::string &name) const { return child_kind(name) == H5O_TYPE_DATASET; }
43
44 // ----------------- datasets -----------------
45
46 Dataset create_dataset(const std::string &name, const Datatype &type, const Dataspace &space)
47 {
48 hid_t d = H5Dcreate2(h_.get(), name.c_str(), type.id(), space.id(), H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
49 throw_if_negative(d, "H5Dcreate2 failed");
50 return Dataset::take(d);
51 }
52
55 Dataset create_chunked_dataset(const std::string &name, const Datatype &type, const Dataspace &space,
56 const Dims &chunk)
57 {
58 hid_t dcpl = H5Pcreate(H5P_DATASET_CREATE);
59 throw_if_negative(dcpl, "H5Pcreate(H5P_DATASET_CREATE) failed");
60 herr_t e = H5Pset_chunk(dcpl, static_cast<int>(chunk.size()), chunk.data());
61 if (e < 0) {
62 H5Pclose(dcpl);
63 throw std::runtime_error("hdf5lib: H5Pset_chunk failed");
64 }
65 hid_t d = H5Dcreate2(h_.get(), name.c_str(), type.id(), space.id(), H5P_DEFAULT, dcpl, H5P_DEFAULT);
66 H5Pclose(dcpl);
67 throw_if_negative(d, "H5Dcreate2 (chunked) failed");
68 return Dataset::take(d);
69 }
70
71 Dataset open_dataset(const std::string &name)
72 {
73 hid_t d = H5Dopen2(h_.get(), name.c_str(), H5P_DEFAULT);
74 throw_if_negative(d, "H5Dopen2 failed");
75 return Dataset::take(d);
76 }
77
78 // ----------------- soft link -----------------
79
80 void create_soft_link(const std::string &name, const std::string &target_path)
81 {
83 H5Lcreate_soft(target_path.c_str(), h_.get(), name.c_str(), H5P_DEFAULT, H5P_DEFAULT),
84 "H5Lcreate_soft failed");
85 }
86
87 // ----------------- attributes -----------------
88
89 template <class T>
90 requires(!std::is_same_v<std::decay_t<T>, std::string>)
91 void write_attribute(const std::string &name, const T &value)
92 {
93 auto type = type_of<std::decay_t<T>>();
94 auto space = Dataspace::scalar();
95 hid_t a = H5Acreate2(h_.get(), name.c_str(), type.id(), space.id(), H5P_DEFAULT, H5P_DEFAULT);
96 throw_if_negative(a, "H5Acreate2 failed");
97 herr_t e = H5Awrite(a, type.id(), &value);
98 H5Aclose(a);
99 throw_if_negative(e, "H5Awrite failed");
100 }
101
102 void write_attribute(const std::string &name, const std::string &value)
103 {
104 auto type = type_of<std::string>();
105 auto space = Dataspace::scalar();
106 hid_t a = H5Acreate2(h_.get(), name.c_str(), type.id(), space.id(), H5P_DEFAULT, H5P_DEFAULT);
107 throw_if_negative(a, "H5Acreate2 (string) failed");
108 const char *cstr = value.c_str();
109 herr_t e = H5Awrite(a, type.id(), &cstr);
110 H5Aclose(a);
111 throw_if_negative(e, "H5Awrite (string) failed");
112 }
113
114 void write_attribute(const std::string &name, const char *value)
115 {
116 write_attribute(name, std::string(value));
117 }
118
119 template <class T>
120 requires(!std::is_same_v<std::decay_t<T>, std::string>)
121 T read_attribute(const std::string &name) const
122 {
123 hid_t a = H5Aopen(h_.get(), name.c_str(), H5P_DEFAULT);
124 throw_if_negative(a, "H5Aopen failed");
125 auto type = type_of<std::decay_t<T>>();
126 T value{};
127 herr_t e = H5Aread(a, type.id(), &value);
128 H5Aclose(a);
129 throw_if_negative(e, "H5Aread failed");
130 return value;
131 }
132
133 template <class T>
134 requires(std::is_same_v<std::decay_t<T>, std::string>)
135 std::string read_attribute(const std::string &name) const
136 {
137 hid_t a = H5Aopen(h_.get(), name.c_str(), H5P_DEFAULT);
138 throw_if_negative(a, "H5Aopen (string) failed");
139 auto type = type_of<std::string>();
140 char *raw = nullptr;
141 herr_t e = H5Aread(a, type.id(), &raw);
142 if (e < 0) {
143 H5Aclose(a);
144 throw std::runtime_error("hdf5lib: H5Aread (string) failed");
145 }
146 std::string out = raw != nullptr ? std::string(raw) : std::string();
147 // Reclaim the per-element allocation for the variable-length string.
148 hid_t scalar = H5Screate(H5S_SCALAR);
149 H5Treclaim(type.id(), scalar, H5P_DEFAULT, &raw);
150 H5Sclose(scalar);
151 H5Aclose(a);
152 return out;
153 }
154
155 // ----------------- iteration -----------------
156
158 std::vector<std::string> child_names() const
159 {
160 std::vector<std::string> out;
161 auto cb = [](hid_t /*loc*/, const char *name, const H5L_info2_t * /*info*/, void *op_data) -> herr_t {
162 auto &vec = *static_cast<std::vector<std::string> *>(op_data);
163 vec.emplace_back(name);
164 return 0;
165 };
166 hsize_t idx = 0;
167 throw_if_negative(H5Literate2(h_.get(), H5_INDEX_NAME, H5_ITER_NATIVE, &idx, cb, &out),
168 "H5Literate2 failed");
169 return out;
170 }
171
172 bool child_is_group(const std::string &name) const { return child_kind(name) == H5O_TYPE_GROUP; }
173 bool child_is_dataset(const std::string &name) const { return child_kind(name) == H5O_TYPE_DATASET; }
174
175 private:
176 explicit Group(Handle h) : h_(std::move(h)) {}
178
180 H5O_type_t child_kind(const std::string &name) const
181 {
182 if (H5Lexists(h_.get(), name.c_str(), H5P_DEFAULT) <= 0) return H5O_TYPE_UNKNOWN;
183 H5O_info2_t info;
184 if (H5Oget_info_by_name3(h_.get(), name.c_str(), &info, H5O_INFO_BASIC, H5P_DEFAULT) < 0)
185 return H5O_TYPE_UNKNOWN;
186 return info.type;
187 }
188 };
189} // namespace DiFfRG::hdf5
Definition dataset.hh:15
static Dataset take(hid_t id)
Definition dataset.hh:19
Definition dataspace.hh:12
static Dataspace scalar()
Definition dataspace.hh:49
hid_t id() const noexcept
Definition dataspace.hh:18
Definition datatype.hh:12
hid_t id() const noexcept
Definition datatype.hh:18
Definition group.hh:16
T read_attribute(const std::string &name) const
Definition group.hh:121
bool child_is_group(const std::string &name) const
Definition group.hh:172
void write_attribute(const std::string &name, const std::string &value)
Definition group.hh:102
static Group take(hid_t id)
Definition group.hh:20
void write_attribute(const std::string &name, const char *value)
Definition group.hh:114
Dataset open_dataset(const std::string &name)
Definition group.hh:71
hid_t id() const noexcept
Definition group.hh:22
bool has_dataset(const std::string &name) const
Definition group.hh:42
Group create_group(const std::string &name)
Definition group.hh:27
Dataset create_chunked_dataset(const std::string &name, const Datatype &type, const Dataspace &space, const Dims &chunk)
Definition group.hh:55
void write_attribute(const std::string &name, const T &value)
Definition group.hh:91
void create_soft_link(const std::string &name, const std::string &target_path)
Definition group.hh:80
Group(hid_t id)
Definition group.hh:19
H5O_type_t child_kind(const std::string &name) const
H5O_TYPE_UNKNOWN if the child does not exist (or is not an object).
Definition group.hh:180
Dataset create_dataset(const std::string &name, const Datatype &type, const Dataspace &space)
Definition group.hh:46
Handle h_
Definition group.hh:177
std::vector< std::string > child_names() const
Names of all immediate children, in link-name order.
Definition group.hh:158
bool valid() const noexcept
Definition group.hh:23
std::string read_attribute(const std::string &name) const
Definition group.hh:135
bool has_group(const std::string &name) const
Definition group.hh:41
Group open_group(const std::string &name)
Definition group.hh:34
Group(Handle h)
Definition group.hh:176
bool child_is_dataset(const std::string &name) const
Definition group.hh:173
Definition handle.hh:25
bool valid() const noexcept
Definition handle.hh:80
hid_t get() const noexcept
Definition handle.hh:79
static Handle take(hid_t id)
Definition handle.hh:37
Definition hdf5.hh:12
std::vector< hsize_t > Dims
Definition dataspace.hh:9
Datatype type_of()
Convenience factory — type_of<T>() returns the HDF5 datatype for T.
Definition datatype.hh:56
void throw_if_negative(hid_t id, const char *what)
Definition handle.hh:11