QuantityMap.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 ODIM_QUANTITY_MAP
32 #define ODIM_QUANTITY_MAP
33 
34 #include <drain/Log.h>
35 #include <drain/Type.h>
36 #include <ostream>
37 //#include <set>
38 
39 #include <stdexcept>
40 
41 #include <drain/util/ReferenceMap.h>
42 
43 #include "Data.h"
44 #include "Quantity.h"
45 
46 
47 namespace rack {
48 
49 
50 class QuantityMap : public std::map<std::string, Quantity> {
51 
52 public:
53 
54  typedef std::map<std::string, Quantity> map_t;
55 
56  inline
57  QuantityMap(){
58  initialize();
59  }
60 
61  inline
62  QuantityMap(const QuantityMap & m) : map_t(m){
63  drain::Logger mout(__FILE__, __FUNCTION__);
64  mout.attention("? copy const <QuantityMap>");
65  }
66 
67  inline
68  QuantityMap(const map_t & m) : map_t(m){
69  drain::Logger mout(__FILE__, __FUNCTION__);
70  mout.attention("? copy const <map>");
71  }
72 
73 
74  void initialize();
75 
77  //void set(const std::string & key, char type, double gain, double offset, double undetect, double nodata);
78  //Quantity & set(const std::string & key);
79 
81  /*
82  * If offset not given, for unsigned storage types the lowest mapped value
83  * will be 0.0, encoded with byte value 1. Byte value 0 set for \c undetect.
84  *
85  */
86  //void set(const std::string & key, char type='C', double gain=1.0, double offset=NAN);
87  inline // EncodingODIM
88  Quantity & add(const std::string & key){ // char typecode = 'C'
89  Quantity & q = (*this)[key];
90  q.set('C');
91  return q;
92  }
93 
94  inline // EncodingODIM
95  EncodingODIM & set(const std::string & key, char typecode){ // char typecode = 'C'
96  Quantity & q = (*this)[key];
97  return q.set(typecode);
98  }
99 
100  /*
101  inline
102  EncodingODIM & set(const std::string & key, const EncodingODIM & src){
103  Quantity & q = (*this)[key];
104  char typecode = src.type.empty() ? 'C' : src.type.at(0);
105  return q.set(typecode);
106  }
107  */
108  //void set(const std::string & key, const Quantity & q);
109 
110  inline
111  Quantity & copy(const std::string & key, const Quantity & dst){
112  Quantity & q = (*this)[key];
113  //char typecode = src.type.empty() ? 'C' : src.type.at(0);
114  q = dst;
115  return q;
116  }
117 
118 
119  inline
120  bool hasQuantity(const std::string & key) const {
121  return find(key) != end();
122  }
123 
124 
125  inline
126  const Quantity & get(const std::string & key) const {
127 
128  const const_iterator it = find(key);
129 
130  if (it != end()){ // null ok
131  return it->second;
132  }
133  else {
134  //drain::Logger mout("Quantity", __FUNCTION__);
135  //mout.warn("undefined quantity=" , key );
136  static Quantity empty;
137  return empty;
138  }
139 
140  }
141 
142  inline
143  Quantity & get(const std::string & key) {
144 
145  const iterator it = find(key);
146 
147  if (it != end()){ // null ok
148  return it->second;
149  }
150  else {
151  // Warning: if this is declared (modified), further instances will override and hence confuse
152 
153  static Quantity empty;
154  return empty;
155  }
156 
157  }
158 
160 
166  bool setQuantityDefaults(EncodingODIM & dst, const std::string & quantity, const std::string & values = "") const;
167 
168  inline
169  bool setQuantityDefaults(ODIM & dst) const {
170  return setQuantityDefaults(dst, dst.quantity);
171  }
172 
174 
183  template <class D>
184  bool setQuantityDefaults(PlainData<D> & dstData, const std::string & quantity = "", const std::string & values = "") const {
185 
186  drain::Logger mout("QuantityMap", __FUNCTION__);
187 
188  const std::string & q = !quantity.empty() ? quantity : dstData.odim.quantity;
189 
190  const bool typeSet = setQuantityDefaults(dstData.odim, q, values);
191 
192  if (dstData.odim.quantity.empty()){
193  if (!q.empty()){
194  dstData.odim.quantity = q;
195  }
196  else {
197  mout.warn("quantity neither given nor set already" );
198  }
199  }
200 
201  if (!typeSet){
202  mout.warn("conf for " , quantity , "[" , dstData.odim.type , "] not found" );
203  }
204  // Redesign all this...
205  dstData.data.setType(dstData.odim.type);
206  //dstData.data.scaling.set(dstData.odim.scaling);
207  //dstData.data.setScaling(dstData.odim.scaling.scale, dstData.odim.scaling.offset);
208  dstData.data.setScaling(dstData.odim.scaling); // needed?
209 
210  //if ((dstData.odim.quantity == "QIND") || (dstData.odim.quantity == "PROB")){
211  if ((q == "QIND") || (q == "PROB")){
212  //dstData.data.setOptimalScale(0.0, 1.0);
213  //dstData.data.setPhysicalRange(0.0, 1.0, true);
214  dstData.data.getScaling().setPhysicalRange(0.0, 1.0); // note: does not change scaling
215  }
216  else if (q == "CLASS"){
217  //dstData.data.setOptimalScale(0.0, 1.0);
218  drain::image::Image & img = dstData.data;
219  img.setPhysicalRange(0.0, img.getConf().getTypeMax<double>());
220  //dstData.data.getScaling().setPhysicalRange(0.0, 1.0); // note: does not change scaling
221  }
222 
223 
224  if (dstData.data.getName().empty())
225  dstData.data.setName(dstData.odim.quantity);
226 
227  mout.debug2("final scaling for " , dstData.odim.quantity , '[' , quantity , ']' , dstData.data.getScaling() );
228 
229  return typeSet;
230  }
231 
233  template <class M>
234  inline
235  bool isNormalized(const M odim) const {
236  const Quantity & q = get(odim.quantity);
237  if (!q.defaultType){
238  drain::Logger mout("QuantityMap", __FUNCTION__);
239  mout.warn("no default type for quantity:" , odim.quantity );
240  return false;
241  }
243  }
244 
245 
246 
247  inline
248  std::ostream & toOstr(std::ostream & ostr) const {
249  for (const_iterator it = begin(); it != end(); ++it){
250  ostr << it->first << '\n' << it->second; // << '\n';
251  }
252  return ostr;
253  }
254 
255 
256 
257 };
258 
259 inline
260 std::ostream & operator<<(std::ostream & ostr, const QuantityMap & map){
261  return map.toOstr(ostr);
262 }
263 
264 QuantityMap & getQuantityMap();
265 
266 
267 
268 } // namespace rack
269 
270 
271 #endif
272 
273 // Rack
LogSourc e is the means for a function or any program segment to "connect" to a Log.
Definition: Log.h:308
Logger & attention(const TT &... args)
Possible error, but execution can continue. Special type of Logger::warn().
Definition: Log.h:472
Logger & warn(const TT &... args)
Possible error, but execution can continue.
Definition: Log.h:426
Logger & debug2(const TT &... args)
Debug information.
Definition: Log.h:686
T getTypeMax() const
Returns the maximum value supported by the current storage type.
Definition: ImageConf.h:281
void setPhysicalRange(const Range< double > &range, bool rescale=false)
Sets the supported range for physical values and optionally adjusts the scaling for maximal resolutio...
Definition: ImageFrame.h:106
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
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
Essential class for storing radar data.
Definition: Data.h:302
Definition: QuantityMap.h:50
bool setQuantityDefaults(PlainData< D > &dstData, const std::string &quantity="", const std::string &values="") const
Definition: QuantityMap.h:184
bool setQuantityDefaults(EncodingODIM &dst, const std::string &quantity, const std::string &values="") const
Sets default values of given quantity - but not the quantity itself. Optionally overrides with user v...
Definition: QuantityMap.cpp:398
bool isNormalized(const M odim) const
Checks if data.
Definition: QuantityMap.h:235
Quantity & add(const std::string &key)
Sets quantity encoding. If gain=0.0, default values for the given type will be set as defined in drai...
Definition: QuantityMap.h:88
Structure for defining.
Definition: Quantity.h:53
const EncodingODIM & get(char typecode='\0') const
Retrieve the scaling for a given storage type.
Definition: Quantity.h:108
char defaultType
Default storage type.
Definition: Quantity.h:63
EncodingODIM & set(char typecode)
Declare encoding (a storage type and scaling) for this quantity.
Definition: Quantity.cpp:87
Definition: DataSelector.cpp:44