Line data Source code
1 1 : // Distributed under the MIT License.
2 : // See LICENSE.txt for details.
3 :
4 : /// \file
5 : /// Defines functions for h5 manipulations
6 :
7 : #pragma once
8 :
9 : #include <array>
10 : #include <cstddef>
11 : #include <hdf5.h>
12 : #include <string>
13 : #include <vector>
14 :
15 : #include "DataStructures/Index.hpp"
16 :
17 : /// \cond
18 : class DataVector;
19 : class Matrix;
20 : /// \endcond
21 :
22 : namespace h5 {
23 : /*!
24 : * \ingroup HDF5Group
25 : * \brief Check if `dtype1` and `dtype2` are the same HDF5 data type.
26 : */
27 1 : bool types_equal(hid_t dtype1, hid_t dtype2);
28 :
29 : /*!
30 : * \ingroup HDF5Group
31 : * \brief Write a std::vector named `name` to the group `group_id`
32 : */
33 : template <typename T>
34 1 : void write_data(hid_t group_id, const std::vector<T>& data,
35 : const std::vector<size_t>& extents,
36 : const std::string& name = "scalar",
37 : const bool overwrite_existing = false);
38 :
39 : /*!
40 : * \ingroup HDF5Group
41 : * \brief Write a DataVector named `name` to the group `group_id`
42 : */
43 1 : void write_data(hid_t group_id, const DataVector& data, const std::string& name,
44 : const bool overwrite_existing = false);
45 :
46 : /*!
47 : * \ingroup HDF5Group
48 : * \brief Write the extents as an attribute named `name` to the group
49 : * `group_id`.
50 : */
51 : template <size_t Dim>
52 1 : void write_extents(hid_t group_id, const Index<Dim>& extents,
53 : const std::string& name = "Extents");
54 :
55 : /*!
56 : * \ingroup HDF5Group
57 : * \brief Write a value of type `Type` to an HDF5 attribute named `name`
58 : */
59 : template <typename Type>
60 1 : void write_to_attribute(hid_t location_id, const std::string& name,
61 : const Type& value);
62 :
63 : /*!
64 : * \ingroup HDF5Group
65 : * \brief Write the vector `data` to the attribute `attribute_name` in the group
66 : * `group_id`.
67 : */
68 : template <typename T>
69 1 : void write_to_attribute(hid_t group_id, const std::string& name,
70 : const std::vector<T>& data);
71 :
72 : /*!
73 : * \ingroup HDF5Group
74 : * \brief Write the `vector<array<fundamental, size>>` `data` to the attribute
75 : * `name` in the group `group_id`.
76 : */
77 : template <typename T, size_t Size>
78 1 : void write_to_attribute(hid_t group_id, const std::string& name,
79 : const std::vector<std::array<T, Size>>& data);
80 :
81 : /*!
82 : * \ingroup HDF5Group
83 : * \brief Read a value of type `Type` from an HDF5 attribute named `name`
84 : */
85 : template <typename Type>
86 1 : Type read_value_attribute(hid_t location_id, const std::string& name);
87 :
88 : /*!
89 : * \ingroup HDF5Group
90 : * \brief Read rank-1 of type `Type` from an HDF5 attribute named `name`
91 : */
92 : template <typename Type>
93 1 : std::vector<Type> read_rank1_attribute(hid_t group_id, const std::string& name);
94 :
95 : /*!
96 : * \ingroup HDF5Group
97 : * \brief Read the `vector<array<fundamental, size>>` from the attribute
98 : * `name` in the group `group_id`.
99 : */
100 : template <typename T, size_t Size>
101 1 : std::vector<std::array<T, Size>> read_rank1_array_attribute(
102 : hid_t group_id, const std::string& name);
103 :
104 : /*!
105 : * \ingroup HDF5Group
106 : * \brief Get the names of all the attributes in a group
107 : */
108 1 : std::vector<std::string> get_attribute_names(hid_t file_id,
109 : const std::string& group_name);
110 :
111 : /*!
112 : * \ingroup HDF5Group
113 : * \brief Write the connectivity into the group in the H5 file
114 : */
115 1 : void write_connectivity(hid_t group_id, const std::vector<int>& connectivity);
116 :
117 : /*!
118 : * \ingroup HDF5Group
119 : * \brief Delete the connectivity from the group in the H5 file
120 : */
121 1 : void delete_connectivity(hid_t group_id);
122 :
123 : /*!
124 : * \ingroup HDF5Group
125 : * \brief Append rows to an existing dataset
126 : *
127 : * \return std::array<hsize_t, 2> New size of the data in the file
128 : */
129 1 : std::array<hsize_t, 2> append_to_dataset(
130 : hid_t file_id, const std::string& name, const std::vector<double>& data,
131 : hsize_t number_of_rows, const std::array<hsize_t, 2>& current_file_size);
132 :
133 : /// @{
134 : /*!
135 : * \ingroup HDF5Group
136 : * \brief Convert the data in a dataset to a Matrix or a
137 : * std::vector<std::vector<double>>
138 : */
139 : template <typename T>
140 1 : T retrieve_dataset(hid_t file_id, const std::array<hsize_t, 2>& file_size);
141 :
142 : template <typename T>
143 1 : T retrieve_dataset_subset(hid_t file_id,
144 : const std::vector<size_t>& these_columns,
145 : size_t first_row, size_t num_rows,
146 : const std::array<hsize_t, 2>& file_size);
147 : /// @}
148 :
149 : /*!
150 : * \ingroup HDF5Group
151 : * \brief Get the names of all the groups and datasets in a group
152 : */
153 1 : std::vector<std::string> get_group_names(hid_t file_id,
154 : const std::string& group_name);
155 :
156 : /*!
157 : * \ingroup HDF5Group
158 : * \brief Check if `name` is a dataset or group in the subgroup `group_name` of
159 : * `id`.
160 : *
161 : * \note To check the current id for `name`, pass `""` as `group_name`.
162 : */
163 1 : bool contains_dataset_or_group(hid_t id, const std::string& group_name,
164 : const std::string& dataset_name);
165 :
166 : /*!
167 : * \ingroup HDF5Group
168 : * \brief Check if an attribute is in a group
169 : */
170 1 : bool contains_attribute(hid_t file_id, const std::string& group_name,
171 : const std::string& attribute_name);
172 :
173 : /*!
174 : * \ingroup HDF5Group
175 : * \brief Open an HDF5 dataset
176 : */
177 1 : hid_t open_dataset(hid_t group_id, const std::string& dataset_name);
178 :
179 : /*!
180 : * \ingroup HDF5Group
181 : * \brief Close an HDF5 dataset
182 : */
183 1 : void close_dataset(hid_t dataset_id);
184 :
185 : /*!
186 : * \ingroup HDF5Group
187 : * \brief Open an HDF5 dataspace
188 : */
189 1 : hid_t open_dataspace(hid_t dataset_id);
190 :
191 : /*!
192 : * \ingroup HDF5Group
193 : * \brief Close an HDF5 dataspace
194 : */
195 1 : void close_dataspace(hid_t dataspace_id);
196 :
197 : /*!
198 : * \ingroup HDF5Group
199 : * \brief Read an array of rank 0-3 into an object.
200 : *
201 : * For each rank, the data can be read into objects of the following types:
202 : * rank 0: double or int
203 : * rank 1: std::vector or DataVector
204 : * rank 2: boost::multiarray or DataVector
205 : * rank 3: boost::multiarray or DataVector
206 : */
207 : template <size_t Rank, typename T>
208 1 : T read_data(hid_t group_id, const std::string& dataset_name);
209 :
210 : /*!
211 : * \ingroup HDF5Group
212 : * \brief Read the HDF5 attribute representing extents from a group
213 : */
214 : template <size_t Dim>
215 1 : Index<Dim> read_extents(hid_t group_id,
216 : const std::string& extents_name = "Extents");
217 : } // namespace h5
218 :
219 : namespace h5 {
220 : namespace detail {
221 : /*!
222 : * \ingroup HDF5Group
223 : * \brief Create a dataset that can be extended/appended to
224 : *
225 : * \requires group_id is an open group, each element of `initial_size` is less
226 : * than the respective element in `max_size`, and each element in `max_size` is
227 : * a positive integer or `H5S_UNLIMITED`
228 : * \effects creates a potentially extensible dataset of dimension Dim inside the
229 : * group `group_id`
230 : * \returns the HDF5 id to the created dataset
231 : *
232 : * See the tutorial at https://support.hdfgroup.org/HDF5/Tutor/extend.html
233 : * for details on the implementation choice.
234 : */
235 : template <size_t Dims>
236 : hid_t create_extensible_dataset(hid_t group_id, const std::string& name,
237 : const std::array<hsize_t, Dims>& initial_size,
238 : const std::array<hsize_t, Dims>& chunk_size,
239 : const std::array<hsize_t, Dims>& max_size);
240 : } // namespace detail
241 : } // namespace h5
|