Loading...
Searching...
No Matches
Hi5Write.h
1/*
2
3MIT License
4
5Copyright (c) 2017 FMI Open Development / Markus Peura, first.last@fmi.fi
6
7Permission is hereby granted, free of charge, to any person obtaining a copy
8of this software and associated documentation files (the "Software"), to deal
9in the Software without restriction, including without limitation the rights
10to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11copies of the Software, and to permit persons to whom the Software is
12furnished to do so, subject to the following conditions:
13
14The above copyright notice and this permission notice shall be included in all
15copies or substantial portions of the Software.
16
17THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23SOFTWARE.
24
25*/
26/*
27Part of Rack development has been done in the BALTRAD projects part-financed
28by the European Union (European Regional Development Fund and European
29Neighbourhood Partnership Instrument, Baltic Sea Region Programme 2007-2013)
30*/
31
32#include "Hi5.h" // to define H5_USE_*_API_DEFAULT
33
34#ifndef Hi5WRITE
35#define Hi5WRITE
36
37// TODO rename class to H52Tree
38
39#include <hdf5.h>
40
41#include <string>
42#include <list>
43
44#include <drain/util/TreeOrdered.h>
45#include <drain/TypeUtils.h> // debugging
46#include <drain/image/Image.h>
47
48/*
49 *
50 * TODO:
51 * - classify (hide methods)
52 *
53 */
54
55
56namespace hi5 {
57
59
63class Writer : public Hi5Base {
64
65public:
66
68 static
69 void writeFile(const std::string &filename, const Hi5Tree &tree);
70
72 //static
73 //void writeText(std::ostream & ostr, const Hi5Tree &tree);
74
75
77
82 static
83 void treeToH5File(const Hi5Tree &tree, hid_t fid, const Hi5Tree::path_t & path);
84
86 static
87 void dataToH5Attribute(const drain::Variable &d, hid_t fid, const Hi5Tree::path_t &path, const std::string &attribute);
88
90 /* template <class T>
91 static
92 void dataToH5AttributeT(const drain::Variable &d, hid_t fid, const std::string &path, const std::string &attribute);
93 */
94
96 static // ,const std::string &path
97 void dataToH5AttributeString(const drain::Variable &d, hid_t fid, const Hi5Tree::path_t &path, const std::string &attribute);
98
100 static
101 hid_t imageToH5DataSet(const drain::image::Image &image, hid_t fid, const Hi5Tree::path_t & path);
102
103
104 // Under constr
105
107
119 template <class K, class V>
120 static
121 void vectorToH5Compound(const std::vector<std::pair<K,V> > & v, hid_t fid, const Hi5Tree::path_t & path, const char *labelFirst="key", const char *labelSecond="value");
122
124 // template <class T> static void vectorToH5Compound(const std::vector<T> ... )
125
127
131 template <class K, class V>
132 static
133 void mapToH5Compound(const std::map<K,V> & m, hid_t fid, const Hi5Tree::path_t & path, const char *labelFirst="key", const char *labelSecond="value");
134
135
137 // static void dataToH5Compound(const drain::VariableMap & m, hid_t fid, const std::string &path);
138
139
141 static
142 void linkToH5Attribute(hid_t lid, hid_t fid, const std::string &path, const std::string &attribute);
143
144 // deprecated (exclude from save marker)
145 //static char tempPathSuffix;
146
147 static
148 unsigned short compressionLevel;
149
151
154 static
156
157
158protected:
159
161
166 static
167 hsize_t deriveDimensions(const drain::image::Geometry & g, std::vector<hsize_t> & dims, std::vector<hsize_t> & chunkDims);
168
169 template <class T>
171
172 public:
173
174 typedef T conv_t;
175
176 static inline
177 const conv_t & conv(const T & x){
178 return x;
179 }
180
181 };
182
183
184};
185
186template <class K, class V>
187void Writer::vectorToH5Compound(const std::vector<std::pair<K,V> > & v, hid_t fid, const Hi5Tree::path_t & path, const char *labelFirst, const char *labelSecond){
188
189 drain::Logger mout(__FILE__, __FUNCTION__);
190
191 typedef std::vector<std::pair<K,V> > vect_t;
192 typedef typename vect_t::value_type pair_t;
193 typedef typename pair_t::first_type first_type;
194 typedef typename pair_t::second_type second_type;
196 // drain::Type::call<drain::simpleName>(second_type));
197
198
199 // General return code checking
200 herr_t status;
201
202 const hsize_t size = sizeof(pair_t);
203 mout.special(path, ": ", v.size(), " elements x ", size, "b");
204
205 const hid_t first_h5t = Hi5Base::getH5NativeDataType(typeid(first_type));
206 const hid_t second_h5t = Hi5Base::getH5NativeDataType(typeid(second_type));
207 mout.debug("datatypes: ", first_h5t, ", ", second_h5t);
208
209 // Create the compound datatype for memory.
210 hid_t memtype = H5Tcreate (H5T_COMPOUND, size);
211 mout.debug("H5Tcreate, memtype=", memtype);
212
213
214 // HOFFSET(pair_t, first)
215 status = H5Tinsert (memtype, labelFirst, 0, first_h5t); // Hi5Base::getH5NativeDataType(typeid(int));
216 handleStatus(status, "H5Tinsert failed", mout, __LINE__);
217 //if (status < 0) mout.error() << "H5Tinsert failed for pair.first type, path=" << path << mout.endl;
218
219 status = H5Tinsert (memtype, labelSecond, sizeof(first_type), second_h5t); // Hi5Base::getH5NativeDataType(typeid(int));
220 handleStatus(status, "H5Tinsert failed", mout, __LINE__);
221 //if (status < 0) mout.error() << "H5Tinsert failed for pair.second type, path=" << path << mout.endl;
222
223
224 const hid_t std_t1 = Hi5Base::getH5StandardType(typeid(first_type));
225 const hid_t std_t2 = Hi5Base::getH5StandardType(typeid(second_type));
226 mout.debug("h5 (file) types: ", std_t1, ", ", std_t2);
227
228 const hsize_t s1 = H5Tget_size(std_t1);
229 const hsize_t s2 = H5Tget_size(std_t2);
230 mout.debug("h5 element sizes [bytes]: ", s1, ", ", s2);
231
232 hid_t filetype = H5Tcreate (H5T_COMPOUND, s1+s2); // size wrong if hvt_t ?
233 H5Tinsert(filetype, labelFirst, 0, std_t1);
234 H5Tinsert(filetype, labelSecond, s1, std_t2); // TODO? Hi5Base::getH5StandardType(typeid(int));
235
236 // Create dataspace. Setting maximum size to NULL sets the maximum size to be the current size.
237 hsize_t dims[1]; // 1-dimensional = list
238 dims[0] = v.size();
239 hid_t space = H5Screate_simple (1, dims, NULL);
240
241 const std::string pathStr(path);
242 mout.debug("experimental: creating compound at ", pathStr);
243
244 if (H5Lexists(fid, pathStr.c_str(), H5P_DEFAULT)){
245 mout.warn("compound object exists already (combining is not supported) : ", pathStr);
246 }
247 else {
248 // mout.debug3() << "does not exist, creating " << pathStr << mout.endl;
249 hid_t dset = H5Dcreate(fid, pathStr.c_str(), filetype, space, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
250 handleStatus(dset, "H5Dcreate failed", mout, __LINE__);
251 if (dset >= 0){
252 // Create the dataset and write the compound data to it.
253 status = H5Dwrite (dset, memtype, H5S_ALL, H5S_ALL, H5P_DEFAULT, &v.at(0));
254 handleStatus(dset, "H5Dwrite failed", mout, __LINE__);
255 //H5Dclose();
256 status = H5Dclose(dset);
257 handleStatus(status, "H5Dclose failed", mout, __LINE__);
258 }
259 }
260
261 status = H5Sclose(space);
262 handleStatus(status, "H5Sclose failed", mout, __LINE__);
263
264}
265
267template <>
269
270public:
271
272 typedef long int conv_t;
273
274 static inline
275 conv_t conv(int x){
276 return static_cast<conv_t>(x);
277 }
278
279};
280
281
282template <>
283class Writer::CompoundConv<std::string> {
284
285public:
286
287 typedef const char * conv_t;
288
289 static inline
290 conv_t conv(const std::string & x){
291 return x.c_str();
292 }
293
294};
295
296template <class K, class V>
297void Writer::mapToH5Compound(const std::map<K,V> & m, hid_t fid, const Hi5Tree::path_t & path, const char *labelFirst, const char *labelSecond){
298
299 drain::Logger mout(__FILE__, __FUNCTION__);
300
301 typedef typename CompoundConv<K>::conv_t key_t;
302 typedef typename CompoundConv<V>::conv_t val_t;
303
304 typedef std::vector<std::pair<key_t,val_t> > vect_t;
305 vect_t v(m.size());
306 //v.resize(m.size());
307
308 typename vect_t::iterator vit = v.begin();
309 for (typename std::map<K,V>::const_iterator it = m.begin(); it != m.end(); ++it) {
310 vit->first = CompoundConv<K>::conv(it->first);
311 vit->second = CompoundConv<V>::conv(it->second);
312 mout.debug2() << vit->first << ':' << vit->second << mout.endl;
313 ++vit;
314 }
315
316 Writer::vectorToH5Compound(v, fid, path, labelFirst, labelSecond);
317
318}
319
320
321
322
323/*
324template <>
325inline
326void Writer::dataToH5AttributeT<std::string>(const drain::Variable & data, hid_t fid, const std::string & path, const std::string & attribute){
327 dataToH5AttributeString(d, fid, path, attribute);
328}
329*/
330
331/*
332 *
333
334template <class T>
335void Writer::dataToH5AttributeT(const drain::Variable &d, hid_t fid, const std::string &path, const std::string &attribute){
336
337 drain::Logger mout(hi5::hi5monitor, "Hi5Write", __FUNCTION__);
338
339 if (d.isCharArrayString() || (d.getType() == typeid(std::string))){
340 dataToH5AttributeString(d, fid, path, attribute);
341 return;
342 }
343
344
345 int status = 0;
346
347 const hid_t tid = getH5NativeDataType(typeid(T));
348
349 // New
350 const hsize_t elements = d.getElementCount();
351 const bool isArray = (elements > 1); // && false;
352
353 //const hid_t sid = isArray ? H5Screate_simple(1, &elements, NULL) : H5Screate(H5S_SCALAR);
354 const hid_t sid = isArray ? H5Screate_simple(1, &elements, &elements) : H5Screate(H5S_SCALAR);
355 if (sid < 0){
356 mout.error() << ": H5Screate failed for attribute, path=" << path;
357 mout << ", size=" << elements << mout.endl;
358 }
359 //H5Sc
360
361*/
362 // NEW
363 /*
364 if (isArray){
365 mout.debug() << ": creating array of size " << elements;
366 mout << ", path=" << path << mout.endl;
367 status = H5Sset_extent_simple(sid, 1, &elements, &elements); //NULL);
368 if (status < 0)
369 mout.error() << ": H5Screate failed for ARRAY, path=" << path << mout.endl;
370 return;
371 }
372 */
373/*
374 const hid_t oid = H5Oopen(fid, path.c_str(), H5P_DEFAULT);
375 if (oid < 0)
376 mout.error() << "H5Oopen failed, path=" << path << mout.endl;
377 //const hid_t gid = H5Gopen2(fid,path.c_str(),H5P_DEFAULT);
378 //if (gid < 0)
379 // mout.error() << ": H5Gopen failed, path=" << path << mout.endl;
380
381 const hid_t aid = H5Acreate2(oid, attribute.c_str(), tid, sid, H5P_DEFAULT, H5P_DEFAULT);
382 if (aid < 0)
383 mout.error() << "H5Acreate failed, path=" << path << mout.endl;
384
385 // OLD const T x = d;
386 // status = H5Awrite(aid,tid,&x);
387 // New
388 status = H5Awrite(aid, tid, d.getPtr());
389 if (status < 0)
390 mout.error() << "H5Awrite failed, path=" << path << mout.endl;
391
392
393 status = H5Aclose(aid);
394 if (status < 0)
395 mout.error() << ": H5 close failed, path=" << path << mout.endl;
396
397 //status = H5Gclose(gid);
398 status = H5Oclose(oid);
399 if (status < 0)
400 mout.error() << ": H5 close failed, path=" << path << mout.endl;
401
402 status = H5Sclose(sid);
403 if (status < 0)
404 mout.error() << ": H5 close failed, path=" << path << mout.endl;
405
406}
407*/
408
409
410
411
412
413} // ::hi5
414
415#endif
416
417// Rack
LogSourc e is the means for a function or any program segment to "connect" to a Log.
Definition Log.h:326
Logger & warn(const TT &... args)
Possible error, but execution can continue.
Definition Log.h:440
Logger & debug(const TT &... args)
Debug information.
Definition Log.h:676
Logger & special(const TT &... args)
Other useful information.
Definition Log.h:541
Logger & debug2(const TT &... args)
Debug information.
Definition Log.h:686
Tuple of N elements of type T.
Definition UniTuple.h:65
Definition Geometry.h:143
Class for multi-channel digital images. Supports dynamic typing with base types (char,...
Definition Image.h:183
Base class for Reader and Writer, essentially just wrapping some utilities.
Definition Hi5.h:169
static hid_t getH5StandardType(const std::type_info &type)
Give a native C++ type, returns a standard(?) HDF5 data type.
Definition Hi5.cpp:218
static hid_t getH5NativeDataType()
Given a native C++ type, returns a native HDF5 data type.
Definition Hi5.h:202
Definition Hi5Write.h:170
Converts Rack's h5 structure to native h5 structure applied for file output.
Definition Hi5Write.h:63
static void dataToH5Attribute(const drain::Variable &d, hid_t fid, const Hi5Tree::path_t &path, const std::string &attribute)
Converts drain::Variable to an HDF5 attribute of a group or dataset.
Definition Hi5Write.cpp:443
static void writeFile(const std::string &filename, const Hi5Tree &tree)
Writes Rack's hi5 object to an HDF5 file.
Definition Hi5Write.cpp:57
static hid_t imageToH5DataSet(const drain::image::Image &image, hid_t fid, const Hi5Tree::path_t &path)
Converts drain::image::Image to an HDF5 dataset.
Definition Hi5Write.cpp:351
static drain::UniTuple< size_t, 2 > chunkSize
chunk dimensions: width, height (channels always as actual number)
Definition Hi5Write.h:155
static void vectorToH5Compound(const std::vector< std::pair< K, V > > &v, hid_t fid, const Hi5Tree::path_t &path, const char *labelFirst="key", const char *labelSecond="value")
Write a vector of paired values.
Definition Hi5Write.h:187
static hsize_t deriveDimensions(const drain::image::Geometry &g, std::vector< hsize_t > &dims, std::vector< hsize_t > &chunkDims)
Definition Hi5Write.cpp:276
static void dataToH5AttributeString(const drain::Variable &d, hid_t fid, const Hi5Tree::path_t &path, const std::string &attribute)
Creates and writes scalar (non-std::string) attributes to group.
Definition Hi5Write.cpp:530
static void linkToH5Attribute(hid_t lid, hid_t fid, const std::string &path, const std::string &attribute)
Under constr.
static void mapToH5Compound(const std::map< K, V > &m, hid_t fid, const Hi5Tree::path_t &path, const char *labelFirst="key", const char *labelSecond="value")
TODO:
Definition Hi5Write.h:297
static void treeToH5File(const Hi5Tree &tree, hid_t fid, const Hi5Tree::path_t &path)
Writes Rack's hi5 object to an HDF5 file.
Definition Hi5Write.cpp:112
DRAIN_VARIABLE Variable
Value container supporting dynamic type.
Definition Variable.h:63
Default implementation.
Definition TypeName.h:54