HighFive  2.2.2
HighFive - Header-only C++ HDF5 interface
H5Easy_misc.hpp
Go to the documentation of this file.
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 
14 namespace H5Easy {
15 
16 namespace detail {
17 
26 inline 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 
44 inline 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).
52 inline 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.getName() << std::endl;
59  return Exception(ss.str());
60 }
61 
62 // Generate specific dump error
63 inline 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
76 template <class T>
77 inline 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.add(Chunking(chunks));
96  if (options.compress()) {
97  props.add(Shuffle());
98  props.add(Deflate(options.getCompressionLevel()));
99  }
100  return file.createDataSet<T>(path, DataSpace(shape), props);
101  }
102  } else if (options.overwrite() && file.getObjectType(path) == ObjectType::Dataset) {
103  DataSet dataset = file.getDataSet(path);
104  if (dataset.getDimensions() != shape) {
105  throw error(file, path, "H5Easy::dump: Inconsistent dimensions");
106  }
107  return dataset;
108  }
109  throw dump_error(file, path);
110 }
111 
112 // get a opened DataSet: scalar
113 template <class T>
114 inline DataSet initScalarDataset(File& file,
115  const std::string& path,
116  const T& data,
117  const DumpOptions& options)
118 {
119  if (!file.exist(path)) {
120  detail::createGroupsToDataSet(file, path);
121  return file.createDataSet<T>(path, DataSpace::From(data));
122  } else if (options.overwrite() && file.getObjectType(path) == ObjectType::Dataset) {
123  DataSet dataset = file.getDataSet(path);
124  if (dataset.getElementCount() != 1) {
125  throw error(file, path, "H5Easy::dump: Existing field not a scalar");
126  }
127  return dataset;
128  }
129  throw dump_error(file, path);
130 }
131 
132 // get a opened Attribute: nd-array
133 template <class T>
134 inline Attribute initAttribute(File& file,
135  const std::string& path,
136  const std::string& key,
137  const std::vector<size_t>& shape,
138  const DumpOptions& options)
139 {
140  if (!file.exist(path)) {
141  throw error(file, path, "H5Easy::dumpAttribute: DataSet does not exist");
142  }
143  if (file.getObjectType(path) != ObjectType::Dataset) {
144  throw error(file, path, "H5Easy::dumpAttribute: path not a DataSet");
145  }
146  DataSet dataset = file.getDataSet(path);
147  if (!dataset.hasAttribute(key)) {
148  return dataset.createAttribute<T>(key, DataSpace(shape));
149  } else if (options.overwrite()) {
150  Attribute attribute = dataset.getAttribute(key);
151  DataSpace dataspace = attribute.getSpace();
152  if (dataspace.getDimensions() != shape) {
153  throw error(file, path, "H5Easy::dumpAttribute: Inconsistent dimensions");
154  }
155  return attribute;
156  }
157  throw error(file, path,
158  "H5Easy: Attribute exists, overwrite with H5Easy::DumpMode::Overwrite.");
159 }
160 
161 // get a opened Attribute: scalar
162 template <class T>
163 inline Attribute initScalarAttribute(File& file,
164  const std::string& path,
165  const std::string& key,
166  const T& data,
167  const DumpOptions& options)
168 {
169  if (!file.exist(path)) {
170  throw error(file, path, "H5Easy::dumpAttribute: DataSet does not exist");
171  }
172  if (file.getObjectType(path) != ObjectType::Dataset) {
173  throw error(file, path, "H5Easy::dumpAttribute: path not a DataSet");
174  }
175  DataSet dataset = file.getDataSet(path);
176  if (!dataset.hasAttribute(key)) {
177  return dataset.createAttribute<T>(key, DataSpace::From(data));
178  } else if (options.overwrite()) {
179  Attribute attribute = dataset.getAttribute(key);
180  DataSpace dataspace = attribute.getSpace();
181  if (dataspace.getElementCount() != 1) {
182  throw error(file, path, "H5Easy::dumpAttribute: Existing field not a scalar");
183  }
184  return attribute;
185  }
186  throw error(file, path,
187  "H5Easy: Attribute exists, overwrite with H5Easy::DumpMode::Overwrite.");
188 }
189 
190 } // namespace detail
191 } // namespace H5Easy
192 
193 #endif // H5EASY_BITS_MISC_HPP
static DataSpace From(const ScalarValue &scalar_value)
Definition: H5Dataspace_misc.hpp:129
Definition: H5Easy.hpp:51
PropertyList< PropertyType::DATASET_CREATE > DataSetCreateProps
Definition: H5PropertyList.hpp:79