Hi5.h
1 /*
2 
3 MIT License
4 
5 Copyright (c) 2017 FMI Open Development / Markus Peura, first.last@fmi.fi
6 
7 Permission is hereby granted, free of charge, to any person obtaining a copy
8 of this software and associated documentation files (the "Software"), to deal
9 in the Software without restriction, including without limitation the rights
10 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 copies of the Software, and to permit persons to whom the Software is
12 furnished to do so, subject to the following conditions:
13 
14 The above copyright notice and this permission notice shall be included in all
15 copies or substantial portions of the Software.
16 
17 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23 SOFTWARE.
24 
25 */
26 /*
27 Part of Rack development has been done in the BALTRAD projects part-financed
28 by the European Union (European Regional Development Fund and European
29 Neighbourhood Partnership Instrument, Baltic Sea Region Programme 2007-2013)
30 */
31 
32 // #define H5_USE_16_API_DEFAULT 1
33 #define H5_USE_18_API_DEFAULT 1
34 //#define H5_USE_110_API_DEFAULT 1
35 
36 #ifndef HI5_BASE
37 #define HI5_BASE
38 
39 
40 
41 #include <hdf5.h>
42 
43 #include <string>
44 #include <list>
45 
46 #include <drain/Log.h>
47 // #include <drain/VariableAssign.h>
48 // #include "drain/Variable.h"
49 #include <drain/image/Image.h>
50 #include <drain/util/FileInfo.h>
51 #include <drain/util/TreeOrdered.h>
52 
53 #include "data/ODIMPath.h"
54 
55 
56 namespace hi5 {
57 
58 extern
59 drain::Log & getLogH5();
60 
61 
62 extern
63 const drain::FileInfo fileInfo;
64 
66 
74 struct NodeHi5 {
75 
77 
78  drain::image::Image image;
79 
80  // Required, but not much needed.
81  bool empty() const {
82  return (image.isEmpty() && attributes.empty());
83  }
84 
85  drain::VariableMap attributes;
86 
87  NodeHi5() : exclude(false) {};
88 
89  inline
90  NodeHi5(const NodeHi5 & n) : exclude(n.exclude) {
91  attributes.importMap(n.attributes);
92  };
93 
94  inline
95  NodeHi5 & operator=(const hi5::NodeHi5 & node){
96  if (&node != this){
97  attributes.importMap(node.attributes);
98  }
99  return *this;
100  };
101 
102  //void writeText(std::ostream & ostr = std::cout, const std::string & prefix = "") const;
103  void writeText(std::ostream & ostr = std::cout, const rack::ODIMPath & prefix = rack::ODIMPath()) const;
104 
106  bool exclude; // OK!
107 
108 };
109 
110 }
111 
112 
114 typedef drain::OrderedTree<hi5::NodeHi5, false, rack::ODIMPath> Hi5Tree;
115 
116 namespace drain {
117 
118 /*
119 template <>
120 template <typename K> // for K (path elem arg)
121 const Hi5Tree::key_t & Hi5Tree::getKey(const K & key){
122  static const rack::ODIMPathElem elem(key); // dangerous
123  return elem;
124 }
125 */
126 
127 /*
128 template <>
129 template <> // for K (path elem arg)
130 inline
131 const Hi5Tree::key_t & Hi5Tree::getKey(const rack::ODIMPathElem::group_t & key){
132  static const rack::ODIMPathElem elem(key); // dangerous
133  return elem;
134 }
135 
136 template <> // for T (Tree class)
137 template <> // for K (path elem arg)
138 inline
139 const Hi5Tree & Hi5Tree::operator[](const std::string & s) const {
140  return (*this)[rack::ODIMPathElem(s)];
141  //return (*this)[EnumDict<rack::RackSVG::TitleClass>::dict.getKey(x, false)];
142 }
143 
144 template <> // for T (Tree class)
145 template <> // for K (path elem arg)
146 inline
147 Hi5Tree & Hi5Tree::operator[](const std::string & s) {
148  return (*this)[rack::ODIMPathElem(s)];
149  //return (*this)[EnumDict<rack::RackSVG::TitleClass>::dict.getKey(x, false)];
150 }
151 */
152 
153 }
154 
155 namespace hi5 {
156 
157 
159 class Hi5Base {
160 
161 public:
162 
163  static
164  void handleStatus(herr_t status, const std::string & message, drain::Logger &mout, int lineNo=0);
165 
166  template <int L, class T>
167  static inline
168  // void handleStatus(drain::Logger &mout, herr_t status, const std::string & message, const drain::Path<> & path, int lineNo=0);
169  void handleStatus(drain::Logger &mout, herr_t status, const std::string & message, const T & arg, int lineNo=0){
170 
171  if (status >= 0)
172  return;
173 
174  mout.start<L>() << message << ": " << arg;
175  if (lineNo)
176  mout << ", line=" << lineNo;
177  mout << ", status=" << status << mout.endl;
178 
179  }
180 
182  static
183  hid_t getH5StandardType(const std::type_info &type);
184 
186  static
187  hid_t getH5NativeDataType(const std::type_info &t);
188 
190  template <class T>
191  static
193  return getH5NativeDataType(typeid(T));
194  }
195 
196  static
197  hid_t getH5StringVariableLength();
198 
199 
201  static
202  //Hi5Tree & getPalette(Hi5Tree & dst);
203  drain::image::Image & getPalette(Hi5Tree & dst);
204 
206  static
207  void linkPalette(const Hi5Tree & palette, Hi5Tree & dst);
208 
209 
211  static
212  void writeText(const Hi5Tree &src, const std::list<typename Hi5Tree::path_t> & paths, std::ostream & ostr = std::cout);
213 
215  static
216  void writeText(const Hi5Tree &src, std::ostream & ostr = std::cout){
217  std::list<typename Hi5Tree::path_t> paths;
218  drain::TreeUtils::getPaths(src, paths);
219  writeText(src, paths, ostr);
220  };
221 
222 
224 
227  static
228  void readText(Hi5Tree &src, std::istream & istr = std::cin);
229 
230 
232  // consider ValueReader, TextReader instead (skipping attrType)
244  static
245  void parsePath(const std::string & line, Hi5Tree::path_t & path, std::string & attrKey, std::string & attrValue);
246 
247 
249 
253  static
254  void readTextLine(Hi5Tree &src, const std::string & line);
255 
256  static
257  //void readTextLine(Hi5Tree & dst, const Hi5Tree::path_t & path, const std::string & assignment);
258  void assignAttribute(Hi5Tree & dst, const std::string & assignment);
259 
260  // static void readTextLine(Hi5Tree & dst, const Hi5Tree::path_t & path, const std::string & key, const std::string & value);
261 
263  /*
264  static
265  void markExcluded(Hi5Tree &src, bool exclude=true);
266  */
267 
268 
269 
271  static
272  void deleteExcluded(Hi5Tree &src);
273 
274 
275 };
276 
277 
279 std::ostream & operator<<(std::ostream &ostr, const hi5::NodeHi5 &n);
280 
282 std::ostream & operator<<(std::ostream &ostr, const Hi5Tree & tree);
283 
284 
285 /*
286 struct lessAlphaNum {
287 
288  enum comparison {LESS=-1, EQUAL=0, GREATER=+1};
289 
290  inline
291  static
292  bool isNumeric(char c) {
293  return ((c >= '0') && (c <= '9'));
294  };
295 
296  inline
297  static
298  comparison compareAlphaBetical(std::string::const_iterator & c1, std::string::const_iterator end1,
299  std::string::const_iterator & c2, std::string::const_iterator end2){
300 
301 
302  while (c1 != end1){
303 
304  if (c2 == end2){
305  return GREATER; // str1 longer
306  }
307 
308  // Stop if both are numeric
309  if (isNumeric(*c1) && isNumeric(*c2)){
310  return EQUAL; // that is, equal as to the alpha part.
311  }
312 
313  if (*c1 < *c2)
314  return LESS;
315  else if (*c1 > *c2)
316  return GREATER;
317 
318  // *c1 == *c2 : strs are equal, non-numeric this far.
319 
320  ++c1;
321  ++c2;
322 
323  }
324 
325  if (c2 != end2) // str2 is longer
326  return LESS;
327  else
328  return EQUAL;
329 
330  }
331 
332  inline
333  static
334  comparison compareNumeric(std::string::const_iterator & c1, std::string::const_iterator end1,
335  std::string::const_iterator & c2, std::string::const_iterator end2){
336 
337  const std::string::const_iterator n1 = c1;
338  const std::string::const_iterator n2 = c2;
339  size_t length1 = 0;
340  size_t length2 = 0;
341 
342  // scan to end of numeric segment
343  while ((c1 != end1) && isNumeric(*c1)){
344  ++c1;
345  // todo: if undetectValue padding?
346  ++length1;
347  }
348 
349  // scan to end of numeric segment
350  while ((c2 != end2) && isNumeric(*c2)){
351  ++c2;
352  // todo: if undetectValue padding?
353  ++length2;
354  }
355 
356 
357 
358  if (length1 < length2)
359  return LESS;
360  else if (length1 > length2)
361  return GREATER;
362  else {
363  // std::cout << "Equal lengths. Compare element by element\n";
364  // end points of numsegs
365  const std::string::const_iterator ne1 = c1;
366  const std::string::const_iterator ne2 = c2;
367  // rescan from start
368  c1 = n1;
369  c2 = n2;
370  while ((c1 != ne1) && (c2 != ne2)){ //
371 
372  if (*c1 < *c2)
373  return LESS;
374  else if (*c1 > *c2)
375  return GREATER;
376  ++c1;
377  ++c2;
378  }
379 
380  return EQUAL;
381 
382  }
383 
384  }
385 
386  // Main function
387  bool operator()(const std::string & s1, const std::string & s2) const {
388 
389  const std::string::const_iterator end1 = s1.end();
390  const std::string::const_iterator end2 = s2.end();
391  std::string::const_iterator c1 = s1.begin();
392  std::string::const_iterator c2 = s2.begin();
393 
394  comparison result;
395 
396  // debugging
397  std::string d1, d2;
398 
399  //while ((c1 != end1) && (c2 != end2)){
400  //int n = 10;
401  //while (n > 0){
402  //--n;
403  while (true){
404 
405  //std::cout << "Alphabetic check\n";
406  //std::cout << d1.assign(c1, end1) << " vs. " << d2.assign(c2, end2) << '\n';
407 
408  result = compareAlphaBetical(c1, end1, c2, end2);
409 
410  if (result == LESS)
411  return true;
412  if (result == GREATER)
413  return false;
414 
415  //if (c1 == end1) // s1 ends, so s2 same this far (ie. same or longer)
416  if (c2 == end2) // s2 gives up, so s1 same this far (ie. same or longer)
417  return false;
418 
419  // std::cout << "Numeric part check\n";
420  //std::cout << d1.assign(c1, end1) << " vs. " << d2.assign(c2, end2) << '\n';
421 
422 
423  result = compareNumeric(c1, end1, c2, end2);
424 
425  if (result == LESS)
426  return true;
427  if (result == GREATER)
428  return false;
429 
430  //if (c1 == end1) // s1 ends, so s2 same this far (ie. same or longer)
431  if (c2 == end2) // s2 gives up, so s1 same this far (ie. same or longer)
432  return false;
433 
434  // std::cout << "Equal, continuing \n";
435  }
436 
437 
438 
439 
440  } // end operator()
441 
442 }; // end class
443 */
444 
445 
446 } // ::hi5
447 
448 
449 #endif
Definition: FileInfo.h:48
Handler for notifications sent by a Logger.
Definition: Log.h:147
LogSourc e is the means for a function or any program segment to "connect" to a Log.
Definition: Log.h:310
Logger & start(const TT &... args)
General.
Definition: Log.h:366
Definition: Path.h:112
void importMap(const std::map< std::string, S > &m)
Assign values from a map, overriding existing entries.
Definition: SmartMap.h:252
static void getPaths(const TR &tree, S &container)
Retrieve all the paths.
Definition: TreeUtils.h:68
A map of Variables.
Definition: VariableMap.h:61
Class for multi-channel digital images. Supports dynamic typing with base types (char,...
Definition: Image.h:184
Base class for Reader and Writer, essentially just wrapping some utilities.
Definition: Hi5.h:159
static void writeText(const Hi5Tree &src, const std::list< typename Hi5Tree::path_t > &paths, std::ostream &ostr=std::cout)
Dumps the H5 structure, attributes and data properties.
Definition: Hi5.cpp:302
static hid_t getH5StandardType(const std::type_info &type)
Give a native C++ type, returns a standard(?) HDF5 data type.
Definition: Hi5.cpp:128
static drain::image::Image & getPalette(Hi5Tree &dst)
Creates a 256-element RGB palette to be referenced with linkPalette().
Definition: Hi5.cpp:259
static void deleteExcluded(Hi5Tree &src)
Traverse subtree setting exclude=true .
Definition: Hi5.cpp:448
static void parsePath(const std::string &line, Hi5Tree::path_t &path, std::string &attrKey, std::string &attrValue)
Split full path string to path object and attribute key.
Definition: Hi5.cpp:433
static hid_t getH5NativeDataType()
Given a native C++ type, returns a native HDF5 data type.
Definition: Hi5.h:192
static void writeText(const Hi5Tree &src, std::ostream &ostr=std::cout)
Dumps the H5 structure, attributes and data properties. (Calls writeText(src, src....
Definition: Hi5.h:216
static void assignAttribute(Hi5Tree &dst, const std::string &assignment)
Definition: Hi5.cpp:353
static void linkPalette(const Hi5Tree &palette, Hi5Tree &dst)
Links the palette that has been (or will be) created with createPalette().
Definition: Hi5.cpp:294
static void readText(Hi5Tree &src, std::istream &istr=std::cin)
Constructs a tree from formatted text. See writeText().
Definition: Hi5.cpp:311
static void readTextLine(Hi5Tree &src, const std::string &line)
Assign a value with optional type specification.
Definition: Hi5.cpp:332
Definition: DataSelector.cpp:1277
Rack's hi5 structure that uses Rack classes (Tree, Data, Image).
Definition: Hi5.h:74
bool exclude
Experimental.
Definition: Hi5.h:106
void writeText(std::ostream &ostr=std::cout, const rack::ODIMPath &prefix=rack::ODIMPath()) const
Definition: Hi5.cpp:58