EncodingODIM.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 #ifndef ENC_ODIM_STRUCT
32 #define ENC_ODIM_STRUCT
33 
34 #include <ostream>
35 #include <cmath>
36 #include <string>
37 #include <set>
38 #include <algorithm>
39 //#include <drain/util/Options.h>
40 #include <drain/util/ReferenceMap.h>
41 #include <drain/util/Rectangle.h>
42 #include <drain/util/Time.h>
43 #include <drain/util/ValueScaling.h>
44 
45 #include "hi5/Hi5.h"
46 #include "radar/Constants.h"
47 #include "ODIMPath.h"
48 
49 namespace rack {
50 
52 
75 class EncodingODIM : public drain::ReferenceMap { // public ODIMPathElem,
76 
77 public:
78 
80  typedef ODIMPathElem::group_t group_t;
81 
82  drain::ValueScaling & scaling;
83  const drain::ValueScaling & scalingConst;
84 
85  drain::ValueScaling ownScaling;
86 
87  typedef enum {NONE=0, SCALING=1, RANGE=2} ExplicitSetting;
88 
89  static
90  const drain::FlagResolver::dict_t settingDict;
91 
92  //typedef drain::EnumFlagger<drain::SingleFlagger<TiffCompliance> > tiffComplianceFlagger;
93  //typedef drain::EnumFlagger<drain::MultiFlagger<Adaption> > AdaptionFlagger;
94 
95  int explicitSettings;
96 
98  inline
99  EncodingODIM(group_t initialize = ODIMPathElem::ALL_LEVELS) : scaling(ownScaling), scalingConst(ownScaling), explicitSettings(NONE){
100  init(initialize);
101  };
102 
104  EncodingODIM(const EncodingODIM & odim);
105 
107  EncodingODIM(char type, double scale=1.0, double offset=0.0, double nodata = NAN, double undetect = NAN, const drain::Range<double> & range = {0,0});
108 
110  EncodingODIM(char type, const drain::Range<double> & range, double scale=0.0, double offset=0.0, double nodata = NAN, double undetect = NAN);
111 
112 
113  inline
114  EncodingODIM(const drain::image::Image & image) : scaling(ownScaling), scalingConst(image.getScaling()), explicitSettings(NONE) {
115  initFromImage(image);
116  };
117 
118  inline
119  EncodingODIM(drain::image::Image & image) : scaling(image.getScaling()), scalingConst(image.getScaling()), explicitSettings(NONE) {
120  initFromImage(image);
121  };
122 
123 
124  inline
125  EncodingODIM & operator=(const EncodingODIM & odim) {
126  // std::cerr << "EncodingODIM & operator=" << std::endl;
127  updateFromMap(odim);
128  explicitSettings = odim.explicitSettings;
129  return *this;
130  }
131 
132  // In case of const image this is not "true" ? But for const EncodingODIM, never called?
133  operator drain::ValueScaling & (){
134  return scaling;
135  }
136 
137  operator const drain::ValueScaling & () const {
138  return scalingConst;
139  }
140 
141 
143 
146  std::string type;
147 
149  //double scale;
150  //double offset;
151  double nodata;
152  double undetect;
153 
154  EncodingODIM & setScaling(double gain, double offset = NAN);
155 
156  EncodingODIM & setScaling(double gain, double offset, double undetect, double nodata);
157 
158  inline
159  bool isSet() const {
160  return ((scaling.scale != 0.0) && (!type.empty()) && (type.at(0) != '*'));
161  }
162 
164  // todo: bool operator==(const EncodingODIM & odim);
165  static
166  inline
167  bool haveSimilarEncoding(const EncodingODIM & odim1, const EncodingODIM & odim2){
168  return (odim1.type == odim2.type) &&
169  (odim1.scaling.scale == odim2.scaling.scale) &&
170  (odim1.scaling.offset == odim2.scaling.offset) &&
171  (odim1.undetect == odim2.undetect) &&
172  (odim1.nodata == odim2.nodata)
173  ;
174  };
175 
176  void setRange(double min, double max);
177 
179  template <class T>
180  inline
181  void setTypeDefaults(const T & type, const std::string & values = ""){
182 
183  drain::Logger mout("EncodingODIM", __FUNCTION__);
184 
185  drain::Type t(type);
186  const char typechar = drain::Type::getTypeChar(t);
187  if (this->type.empty())
188  this->type = typechar;
189  else {
190  if (this->type.at(0) != typechar)
191  mout.warn("different types: " , this->type , '/' , typechar );
192  }
193 
194  scaling.set(1.0, 0.0);
195  // scale = 1.0;
196  // offset = 0.0;
197 
198  //if (!type.empty()){ // ?
199  if (typechar != '*'){
200  undetect = drain::Type::call<drain::typeMin, double>(t); //drain::Type::getMin<double>(t);
201  nodata = drain::Type::call<drain::typeMax, double>(t); // drain::Type::call<drain::typeMax,double>(t);
202  }
203  else {
204  undetect = drain::Type::call<drain::typeMin, double>(this->type); //drain::Type::getMin<double>(this->type);
205  nodata = drain::Type::call<drain::typeMax, double>(this->type); //drain::Type::call<drain::typeMax,double>(this->type);
206  }
207 
208  setValues(values);
209 
210  }
211 
212  inline
213  void setTypeDefaults(){
214  setTypeDefaults(this->type);
215  }
216 
218  inline
219  bool isValue(double x) const {
220  return (x != undetect) && (x != nodata);
221  }
222 
224  inline
225  double scaleForward(double x) const {
226  return scaling.offset + scaling.scale*x; // TODO: direct
227  }
228 
230  inline
231  double scaleInverse(double y) const {
232  return (y-scaling.offset)/scaling.scale; // TODO: direct
233  }
234 
236  double getMin() const;
237 
239  double getMax() const;
240 
242  inline
243  double operator()(double y) const {
244  return (y-scaling.offset)/scaling.scale;
245  }
246 
247 
249  // ?virtual?
251  void clear();
252 
253 
255  /*
256  inline
257  void getShortKeys(std::map<std::string,std::string> & m){
258  for (ReferenceMap::iterator it = begin(); it != end(); ++it){
259  const std::string & longKey = it->first;
260  const std::string shortKey = longKey.substr(0,longKey.find(':'));
261  m[shortKey] = longKey;
262  std::cerr << shortKey << '#' << longKey << '\n';
263  }
264  }
265  */
266 
267 
269  virtual
270  void updateLenient(const EncodingODIM & odim);
271 
272 
274  /*
275  * Does not change the values of the map.
276  *
277  * The object itself can be given as an argument, \see addShortKeys().
278  */
280 
282  /*
283  * Does not change the values of the map.
284  */
285  inline
286  void addShortKeys(){
287  grantShortKeys(*this);
288  }
289 
291 
294  void copyFrom(const drain::image::Image & data);
295 
297 
300  static
301  inline
302  void checkType(Hi5Tree & dst){
303  EncodingODIM odim;
304  checkType(dst, odim);
305  } // Temp for thread-safety.
306 
307 
309 
320  static
321  const ODIMPathElemSeq & attributeGroups;
322 
323  //bool RANGE_DRIVEN;
324 
325 protected:
326 
327 
328 
329  static
330  void checkType(Hi5Tree & dst, EncodingODIM & odim); // SEE ABOVE?
331 
332 
333  static
334  const ODIMPathElemSeq & getAttributeGroups();
335 
336 
337 private:
338 
339  virtual // must
340  void init(group_t initialize = ODIMPathElem::ALL_LEVELS);
341 
342  void initFromImage(const drain::image::Image & img);
343 
344 };
345 
346 
347 
348 } // namespace rack
349 
350 
351 #endif
352 
353 // Rack
LogSourc e is the means for a function or any program segment to "connect" to a Log.
Definition: Log.h:308
Logger & warn(const TT &... args)
Possible error, but execution can continue.
Definition: Log.h:426
Definition: ReferenceMap.h:207
void setValues(const std::string &entries, char assignmentSymbol='=', char separatorSymbol=0)
Sets values. If strictness==STRICTLY_CLOSED, throws exception if tries to assign a non-existing entry...
Definition: SmartMap.h:311
void updateFromMap(const std::map< std::string, T2 > &m)
Assign values from a map. Updates existing entries only.
Definition: SmartMap.h:294
Utilities related to std::type_info.
Definition: Type.h:51
Linear scaling and physical range for image intensities.
Definition: ValueScaling.h:64
double & scale
Multiplicative coefficient \i a in: y = ax + b.
Definition: ValueScaling.h:68
double & offset
Additive coefficient \i b in: y = ax + b.
Definition: ValueScaling.h:71
Class for multi-channel digital images. Supports dynamic typing with base types (char,...
Definition: Image.h:184
Structure for data storage type, scaling and marker codes. Does not contain quantity.
Definition: EncodingODIM.h:75
double operator()(double y) const
Functor (why inverse?)
Definition: EncodingODIM.h:243
EncodingODIM(group_t initialize=ODIMPathElem::ALL_LEVELS)
Default constructor.
Definition: EncodingODIM.h:99
static bool haveSimilarEncoding(const EncodingODIM &odim1, const EncodingODIM &odim2)
Checks if data encoding is similar (storage type, gain, offset, undetect and nodata are the same).
Definition: EncodingODIM.h:167
double scaleInverse(double y) const
Converts a quantity to storage scale: x = (y-offset)/gain .
Definition: EncodingODIM.h:231
void addShortKeys()
Creates a short alias (attrib) for each (group):(attrib). Example: "gain" => "what:gain".
Definition: EncodingODIM.h:286
static const ODIMPathElemSeq & attributeGroups
Copies contents of this to a h5 group.
Definition: EncodingODIM.h:321
std::string type
This is non-standard (not in ODIM), but a practical means of handling storage type of datasets.
Definition: EncodingODIM.h:146
double scaleForward(double x) const
Converts a quantity from storage scale: y = offset + gain*y .
Definition: EncodingODIM.h:225
static void checkType(Hi5Tree &dst)
Traverses recursively subtrees and checks the types of PolarODIM variables.
Definition: EncodingODIM.h:302
virtual void updateLenient(const EncodingODIM &odim)
Todo: keep the function, but move implementation to (future single-exec) register ?
Definition: EncodingODIM.cpp:217
double getMin() const
Returns the minimum physical value that can be returned using current storage type,...
Definition: EncodingODIM.cpp:375
void copyFrom(const drain::image::Image &data)
Copies image attributes and type . Experimental.
Definition: EncodingODIM.cpp:250
bool isValue(double x) const
Returns true for a valid measurement value, false for undetect and nodata marker values.
Definition: EncodingODIM.h:219
void clear()
Resets the values.
Definition: EncodingODIM.cpp:171
void setTypeDefaults(const T &type, const std::string &values="")
Sets gain=1, offset=0, undetect=type_min, nodata=type_max. Note: sets type only if unset.
Definition: EncodingODIM.h:181
double nodata
data[n]/what (obligatory)
Definition: EncodingODIM.h:151
double getMax() const
Returns the minimum physical value that can be returned using current storage type,...
Definition: EncodingODIM.cpp:399
void grantShortKeys(drain::ReferenceMap &ref)
Creates a short alias (attrib) for each (group):(attrib). Example: "gain" => "what:gain".
Definition: EncodingODIM.cpp:233
static const group_t ALL_LEVELS
Abbreviation for linking (referencing) attributes at different levels (tree depths).
Definition: ODIMPath.h:118
drain::Flagger::ivalue_t group_t
In H5, "groups" correspond to "directories" or "folders" in Unix and Windows.
Definition: ODIMPath.h:91
Definition: DataSelector.cpp:44