-
Notifications
You must be signed in to change notification settings - Fork 160
/
H5Easy_misc.hpp
153 lines (143 loc) · 5.73 KB
/
H5Easy_misc.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
/*
* Copyright (c), 2017, Adrien Devresse <adrien.devresse@epfl.ch>
*
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
*/
#pragma once
#include "../H5Easy.hpp"
namespace H5Easy {
namespace detail {
// Generate error-stream and return "Exception" (not yet thrown).
inline Exception error(const File& file, const std::string& path, const std::string& message) {
std::ostringstream ss;
ss << message << std::endl
<< "Path: " << path << std::endl
<< "Filename: " << file.getName() << std::endl;
return Exception(ss.str());
}
// Generate specific dump error
inline Exception dump_error(File& file, const std::string& path) {
if (file.getObjectType(path) == ObjectType::Dataset) {
return error(file,
path,
"H5Easy: Dataset already exists, dump with H5Easy::DumpMode::Overwrite "
"to overwrite (with an array of the same shape).");
} else {
return error(
file,
path,
"H5Easy: path exists, but does not correspond to a Dataset. Dump not possible.");
}
}
// get a opened DataSet: nd-array
template <class T>
inline DataSet initDataset(File& file,
const std::string& path,
const std::vector<size_t>& shape,
const DumpOptions& options) {
if (!file.exist(path)) {
if (!options.compress() && !options.isChunked()) {
return file.createDataSet<T>(path, DataSpace(shape), {}, {}, true);
} else {
std::vector<hsize_t> chunks(shape.begin(), shape.end());
if (options.isChunked()) {
chunks = options.getChunkSize();
if (chunks.size() != shape.size()) {
throw error(file, path, "H5Easy::dump: Incorrect rank ChunkSize");
}
}
DataSetCreateProps props;
props.add(Chunking(chunks));
if (options.compress()) {
props.add(Shuffle());
props.add(Deflate(options.getCompressionLevel()));
}
return file.createDataSet<T>(path, DataSpace(shape), props, {}, true);
}
} else if (options.overwrite() && file.getObjectType(path) == ObjectType::Dataset) {
DataSet dataset = file.getDataSet(path);
if (dataset.getDimensions() != shape) {
throw error(file, path, "H5Easy::dump: Inconsistent dimensions");
}
return dataset;
}
throw dump_error(file, path);
}
// get a opened DataSet: scalar
template <class T>
inline DataSet initScalarDataset(File& file,
const std::string& path,
const T& data,
const DumpOptions& options) {
if (!file.exist(path)) {
return file.createDataSet<T>(path, DataSpace::From(data), {}, {}, true);
} else if (options.overwrite() && file.getObjectType(path) == ObjectType::Dataset) {
DataSet dataset = file.getDataSet(path);
if (dataset.getElementCount() != 1) {
throw error(file, path, "H5Easy::dump: Existing field not a scalar");
}
return dataset;
}
throw dump_error(file, path);
}
// get a opened Attribute: nd-array
template <class T>
inline Attribute initAttribute(File& file,
const std::string& path,
const std::string& key,
const std::vector<size_t>& shape,
const DumpOptions& options) {
if (!file.exist(path)) {
throw error(file, path, "H5Easy::dumpAttribute: DataSet does not exist");
}
if (file.getObjectType(path) != ObjectType::Dataset) {
throw error(file, path, "H5Easy::dumpAttribute: path not a DataSet");
}
DataSet dataset = file.getDataSet(path);
if (!dataset.hasAttribute(key)) {
return dataset.createAttribute<T>(key, DataSpace(shape));
} else if (options.overwrite()) {
Attribute attribute = dataset.getAttribute(key);
DataSpace dataspace = attribute.getSpace();
if (dataspace.getDimensions() != shape) {
throw error(file, path, "H5Easy::dumpAttribute: Inconsistent dimensions");
}
return attribute;
}
throw error(file,
path,
"H5Easy: Attribute exists, overwrite with H5Easy::DumpMode::Overwrite.");
}
// get a opened Attribute: scalar
template <class T>
inline Attribute initScalarAttribute(File& file,
const std::string& path,
const std::string& key,
const T& data,
const DumpOptions& options) {
if (!file.exist(path)) {
throw error(file, path, "H5Easy::dumpAttribute: DataSet does not exist");
}
if (file.getObjectType(path) != ObjectType::Dataset) {
throw error(file, path, "H5Easy::dumpAttribute: path not a DataSet");
}
DataSet dataset = file.getDataSet(path);
if (!dataset.hasAttribute(key)) {
return dataset.createAttribute<T>(key, DataSpace::From(data));
} else if (options.overwrite()) {
Attribute attribute = dataset.getAttribute(key);
DataSpace dataspace = attribute.getSpace();
if (dataspace.getElementCount() != 1) {
throw error(file, path, "H5Easy::dumpAttribute: Existing field not a scalar");
}
return attribute;
}
throw error(file,
path,
"H5Easy: Attribute exists, overwrite with H5Easy::DumpMode::Overwrite.");
}
} // namespace detail
} // namespace H5Easy