h5gt 0.2.0
C++ wrapper for HDF5 library (based on HighFive project)
Loading...
Searching...
No Matches
H5Easy_misc.hpp
1/*
2 * Copyright (c), 2017, Adrien Devresse <adrien.devresse@epfl.ch>
3 *
4 * Distributed under the Boost Software License, Version 1.0.
5 * (See accompanying file LICENSE_1_0.txt or copy at
6 * http://www.boost.org/LICENSE_1_0.txt)
7 *
8 */
9#ifndef H5EASY_BITS_MISC_HPP
10#define H5EASY_BITS_MISC_HPP
11
12#include "../H5Easy.hpp"
13
14namespace H5Easy {
15
16namespace detail {
17
26inline std::string getParentName(const std::string& path) {
27 std::size_t idx = path.find_last_of("/\\");
28 if (idx == std::string::npos) {
29 return "/";
30 } else if (idx == 0) {
31 return "/";
32 } else {
33 return path.substr(0, idx);
34 }
35}
36
44inline void createGroupsToDataSet(File& file, const std::string& path) {
45 std::string group_name = getParentName(path);
46 if (!file.exist(group_name)) {
47 file.createGroup(group_name);
48 }
49}
50
51// Generate error-stream and return "Exception" (not yet thrown).
52inline Exception error(const File& file,
53 const std::string& path,
54 const std::string& message) {
55 std::ostringstream ss;
56 ss << message << std::endl
57 << "Path: " << path << std::endl
58 << "Filename: " << file.getFileName() << std::endl;
59 return Exception(ss.str());
60}
61
62// Generate specific dump error
63inline Exception dump_error(File& file, const std::string& path)
64{
65 if (file.getObjectType(path) == ObjectType::Dataset) {
66 return error(file, path,
67 "H5Easy: Dataset already exists, dump with H5Easy::DumpMode::Overwrite "
68 "to overwrite (with an array of the same shape).");
69 } else {
70 return error(file, path,
71 "H5Easy: path exists, but does not correspond to a Dataset. Dump not possible.");
72 }
73}
74
75// get a opened DataSet: nd-array
76template <class T>
77inline DataSet initDataset(File& file,
78 const std::string& path,
79 const std::vector<size_t>& shape,
80 const DumpOptions& options)
81{
82 if (!file.exist(path)) {
83 detail::createGroupsToDataSet(file, path);
84 if (!options.compress() && !options.isChunked()) {
85 return file.createDataSet<T>(path, DataSpace(shape));
86 } else {
87 std::vector<hsize_t> chunks(shape.begin(), shape.end());
88 if (options.isChunked()) {
89 chunks = options.getChunkSize();
90 if (chunks.size() != shape.size()) {
91 throw error(file, path, "H5Easy::dump: Incorrect rank ChunkSize");
92 }
93 }
94 DataSetCreateProps props;
95 props.setChunk(chunks);
96 if (options.compress()) {
97 props.setShuffle();
98 props.setDeflate(options.getCompressionLevel());
99 }
100 return file.createDataSet<T>(
101 path, DataSpace(shape), LinkCreateProps(),
102 props);
103 }
104 } else if (options.overwrite() && file.getObjectType(path) == ObjectType::Dataset) {
105 DataSet dataset = file.getDataSet(path);
106 if (dataset.getDimensions() != shape) {
107 throw error(file, path, "H5Easy::dump: Inconsistent dimensions");
108 }
109 return dataset;
110 }
111 throw dump_error(file, path);
112}
113
114// get a opened DataSet: scalar
115template <class T>
116inline DataSet initScalarDataset(File& file,
117 const std::string& path,
118 const T& data,
119 const DumpOptions& options)
120{
121 if (!file.exist(path)) {
122 detail::createGroupsToDataSet(file, path);
123 return file.createDataSet<T>(path, DataSpace::From(data));
124 } else if (options.overwrite() && file.getObjectType(path) == ObjectType::Dataset) {
125 DataSet dataset = file.getDataSet(path);
126 if (dataset.getElementCount() != 1) {
127 throw error(file, path, "H5Easy::dump: Existing field not a scalar");
128 }
129 return dataset;
130 }
131 throw dump_error(file, path);
132}
133
134// get a opened Attribute: nd-array
135template <class T>
136inline Attribute initAttribute(File& file,
137 const std::string& path,
138 const std::string& key,
139 const std::vector<size_t>& shape,
140 const DumpOptions& options)
141{
142 if (!file.exist(path)) {
143 throw error(file, path, "H5Easy::dumpAttribute: DataSet does not exist");
144 }
145 if (file.getObjectType(path) != ObjectType::Dataset) {
146 throw error(file, path, "H5Easy::dumpAttribute: path not a DataSet");
147 }
148 DataSet dataset = file.getDataSet(path);
149 if (!dataset.hasAttribute(key)) {
150 return dataset.createAttribute<T>(key, DataSpace(shape));
151 } else if (options.overwrite()) {
152 Attribute attribute = dataset.getAttribute(key);
153 DataSpace dataspace = attribute.getSpace();
154 if (dataspace.getDimensions() != shape) {
155 throw error(file, path, "H5Easy::dumpAttribute: Inconsistent dimensions");
156 }
157 return attribute;
158 }
159 throw error(file, path,
160 "H5Easy: Attribute exists, overwrite with H5Easy::DumpMode::Overwrite.");
161}
162
163// get a opened Attribute: scalar
164template <class T>
165inline Attribute initScalarAttribute(File& file,
166 const std::string& path,
167 const std::string& key,
168 const T& data,
169 const DumpOptions& options)
170{
171 if (!file.exist(path)) {
172 throw error(file, path, "H5Easy::dumpAttribute: DataSet does not exist");
173 }
174 if (file.getObjectType(path) != ObjectType::Dataset) {
175 throw error(file, path, "H5Easy::dumpAttribute: path not a DataSet");
176 }
177 DataSet dataset = file.getDataSet(path);
178 if (!dataset.hasAttribute(key)) {
179 return dataset.createAttribute<T>(key, DataSpace::From(data));
180 } else if (options.overwrite()) {
181 Attribute attribute = dataset.getAttribute(key);
182 DataSpace dataspace = attribute.getSpace();
183 if (dataspace.getElementCount() != 1) {
184 throw error(file, path, "H5Easy::dumpAttribute: Existing field not a scalar");
185 }
186 return attribute;
187 }
188 throw error(file, path,
189 "H5Easy: Attribute exists, overwrite with H5Easy::DumpMode::Overwrite.");
190}
191
192} // namespace detail
193} // namespace H5Easy
194
195#endif // H5EASY_BITS_MISC_HPP
static DataSpace From(const T &value)
Create a dataspace matching a type accepted by details::inspector.
Definition H5Dataspace_misc.hpp:137