Loading...
Searching...
No Matches
Sampler.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#ifndef DRAIN_SAMPLER_H_
32#define DRAIN_SAMPLER_H_
33
34
35#include <vector>
36#include <iostream>
37#include <sstream>
38#include <string>
39
40#include <drain/FlexibleVariable.h>
41
42
43#include "drain/util/BeanLike.h"
44#include "drain/util/IosFormat.h"
45#include "drain/util/Range.h"
46#include "drain/util/ReferenceMap.h"
47#include "drain/util/StringMapper.h"
48#include "drain/image/Image.h"
49
50namespace drain
51{
52
53namespace image
54{
55
57
62
66 inline
67 //SamplePicker(ReferenceMap & variableMap) : variableMap(variableMap) {
69 infoMap["width"].link(width = 0);
70 infoMap["height"].link(height = 0);
71 }
72
73 virtual inline
74 ~SamplePicker(){};
75
76 void setSize(int w, int h){
77 width = w;
78 height = h;
79 }
80
82 virtual
83 inline
84 void setPosition(int i, int j) const {
85 current_i = i;
86 current_j = j;
87 current_j2 = height-1 - j;
88 }
89
90 // TODO: min/max coord control, like CoordHandler for checking min and max.
91 //bool checkPosition()
92
94 //virtual
95 //void writeHeader(char commentPrefix, std::ostream & ostr) const {};
96
97
99 mutable int current_i = 0;
100
102 mutable int current_j = 0;
103
105 mutable int current_j2 = 0;
106
107 int width = 0;
108 int height = 0;
109
112
116
117};
118
120
123class ImageReader : public SamplePicker {
124
125public:
126
127 inline
128 ImageReader(ReferenceMap2<> & ref) : SamplePicker(ref) {//static int dummy;
129 variableMap.link("i", current_i = 0);
130 variableMap.link("j", current_j = 0);
131 variableMap.link("j2", current_j2 = 0);
132 }
133
134 inline
135 bool getValue(const ImageFrame & image, double & value) const {
136 //value = image.get<double>(current_i, current_j);
137 // if (mode==SCALED ?
138 value = image.getScaled(current_i, current_j);
139 //value = image.get<double>(current_i, current_j);
140 //std::cerr << current_i << ',' << current_j << '\t' << value << '\n';
141 return true;
142 }
143
144
145};
146
148
152class Sampler : public BeanLike {
153
154public:
155
156 Sampler();
157
158 inline
159 Sampler(const Sampler &sampler) : BeanLike(sampler){
160 parameters.copyStruct(sampler.getParameters(), sampler, *this);
161 };
162
163 // Named conf, to separate ImageMod::parameters (BeanLike)
164 //ReferenceMap conf;
165
166 int iStep = 10;
167 int jStep = 0;
168
169 drain::Range<int> iRange = {-1,1};
170 drain::Range<int> jRange = {-1,1};
171
173 std::string commentPrefix = "#";
174
175
176 // was already DEPRECATING...
178 bool skipVoid = false ;
179 //std::string skipVoid = "false";
180 std::string voidComment = "void";
181
182 // NEW
183 std::string handleVoid = "null"; // "false","skip"
184
185
187 mutable
189
191 char getCommentChar() const;
192
194 std::string getFormat(const std::string & formatStr) const;
195
196
198
209 template <class D, class P>
210 void sample(const std::map<std::string, D> & images, const P & picker, const std::string & formatStr, std::ostream & ostr = std::cout) const { // std::string format copy ok
211
212 drain::Logger mout(getImgLog(), __FUNCTION__, getName());
213
214 if (images.empty()){
215 mout.error("no image data (channels) provided: " );
216 return;
217 }
218
219 const bool SKIP_VOID = (handleVoid == "skip") || (skipVoid == true);
220
221 const bool MARK_VOID = (handleVoid != "skip");
222
223 double voidMarker = NAN;
224 if (handleVoid != "null"){
225 StringTools::convert(handleVoid, voidMarker);
226 }
227
228 // Save initial formatting data
229
230 //mout.special("fieldWidth: " , fieldWidth , ", fillChar=" , fillChar );
231 mout.attention("variables (initially): " , variableMap.getKeys() );
232
234 // Note: supports leading minus sign
235 drain::StringMapper formatter("-?[a-zA-Z0-9_]+"); // WAS: "-?[a-zA-Z0-9_]+" with odd "-?"
236 // format = drain::StringTools::replace(format, "\\n", "\n");
237 // format = drain::StringTools::replace(format, "\\t", "\t");
238 std::string format = getFormat(formatStr);
239 formatter.parse(format, true); // convert escaped, eg. "\\n" -> "\n"
240 formatter.iosFormat.copyFrom(ostr);
241 mout.special("iosFormat: ", formatter.iosFormat);
242
243 // std::string format = getFormat(formatStr);
244
245 // Service: associate file keys with data
246 // mout.debug("check minus" );
247 std::map<std::string, double> values;
248 static const std::string minusStr("-");
249 for (typename std::map<std::string, D>::const_iterator it = images.begin(); it != images.end(); ++it){
250 const std::string & key = it->first;
251 mout.debug2("referencing: " , key , ',' , minusStr , key );
252 variableMap.link(key, values[key]=0);
253 variableMap.link(minusStr+key, values[minusStr+key]=0);
254 }
255 mout.debug("variables: " , variableMap );
256
257
258
259 const int iStep = this->iStep;
260 const int jStep = (this->jStep > 0) ? this->jStep : iStep;
261
262 const char commentChar = getCommentChar();
263 if (commentChar){
265
266 // ostr << commentChar << " TEST\n";
267 // picker.writeHeader(commentChar, ostr);
268 // ostr << commentChar << " size='" << picker.width << 'x' << picker.height << "'\n";
269
270 ostr << commentChar << commentChar << " input properties " << '\n';
271
272 for (const auto & entry: picker.infoMap){
273 ostr << commentChar << ' ' << entry.first << '=';
274 //it->second.valueToJSON(ostr);
275 Sprinter::toStream(ostr, entry.second, Sprinter::jsonLayout);
276 ostr << '\n';
277 }
278
279 ostr << commentChar << commentChar << " sampling parameters " << '\n';
280
281 for (const auto & entry: parameters){
282 ostr << commentChar << ' ' << entry.first << '=';
283 // it->second.valueToJSON(ostr);
284 Sprinter::toStream(ostr, entry.second, Sprinter::jsonLayout);
285 ostr << '\n';
286 }
287 if (!formatStr.empty())
288 ostr << commentChar << " format='" << formatStr << "'\n"; // formatStr instead of format, to save double slash \\n \\t
289 else
290 ostr << commentChar << " format='" << format << "'\n";
291
292 ostr << commentChar << commentChar << " resulting geometry " << '\n';
293 const int iN = picker.width/iStep;
294 const int jN = picker.height/jStep;
295 ostr << commentChar << " rows=" << iN << "\n";
296 ostr << commentChar << " rols=" << jN << "\n";
297 ostr << commentChar << " samples=" << (iN*jN) << "\n";
298
299
300 }
301
302
303 int iStart = this->iRange.min; // this->iStart;
304 if (iStart < 0)
305 iStart = iStep/2;
306
307 int jStart = this->jRange.min; //jStart;
308 if (jStart < 0)
309 jStart = jStep/2;
310
311 int iEnd = this->iRange.max; // iEnd;
312 if (iEnd < iStart)
313 iEnd = picker.width-1;
314
315 int jEnd = this->jRange.max; // jEnd;
316 if (jEnd < jStart)
317 jEnd = picker.height-1;
318
319 mout.attention(DRAIN_LOG_VAR(iStart));
320 mout.attention(DRAIN_LOG_VAR(iStep));
321 mout.attention(DRAIN_LOG_VAR(iEnd));
322 mout.attention(DRAIN_LOG_VAR(jStart));
323 mout.attention(DRAIN_LOG_VAR(jStep));
324 mout.attention(DRAIN_LOG_VAR(jEnd));
325
326 // Main loop: traverse image area with (i,j)
327 // SamplePicker has set variableMap references (ie. geographical coords j2=(height-1-j) ).
328 double x;
329 bool dataOk;
330 for (int j = jStart; j<=jEnd; j+=jStep){
331 for (int i = iStart; i<=iEnd; i+=iStep){
332
333 picker.setPosition(i, j);
334
335 // SLOW, but works... // TODO speedup with iterator
336 dataOk = true;
337 for (typename std::map<std::string, D>::const_iterator it = images.begin(); it != images.end(); ++it){
338 const std::string & quantity = it->first;
339 const D & data = it->second;
340 if (!picker.getValue(data, x)){
341 dataOk = false;
342 if (MARK_VOID){
343 x = voidMarker;
344 }
345 }
346 //else if (x != 0) std::cerr << x << '\t';
347
348 values[quantity] = x;
349 values[minusStr+quantity] = -x;
350 }
351
352 if (dataOk || !SKIP_VOID){
353 //if (dataOk || (skipVoid==0)){
354 //formatter.toStream(ostr, variableMap, true);
355 formatter.toStream(ostr, variableMap, -1); // leaves ${variable} ?
356 if ((!dataOk) && (commentChar))
357 ostr << ' ' << commentChar << voidComment;
358 ostr << '\n';
359 }
360 }
361 // formatter.expand(map, true);
362 }
363 mout.warn("last values: " , variableMap );
364 //mout.warn("formatter " , formatter );
365
366 }
367
368
369};
370
371
372
373}
374}
375
376
377#endif /*POINT_H_*/
378
379// Drain
Something which has a name, a description and possibly some parameters of varying type.
Definition BeanLike.h:60
virtual const std::string & getName() const
Return the name of an instance.
Definition BeanLike.h:82
A map of FlexVariable:s.
Definition VariableMap.h:138
LogSourc e is the means for a function or any program segment to "connect" to a Log.
Definition Log.h:312
Logger & warn(const TT &... args)
Possible error, but execution can continue.
Definition Log.h:430
Logger & debug(const TT &... args)
Debug information.
Definition Log.h:666
Logger & special(const TT &... args)
Other useful information.
Definition Log.h:531
Logger & attention(const TT &... args)
Possible error, but execution can continue. Special type of Logger::warn().
Definition Log.h:476
Logger & error(const TT &... args)
Echoes.
Definition Log.h:416
Logger & debug2(const TT &... args)
Debug information.
Definition Log.h:676
Definition Range.h:52
A map of references to base type scalars, arrays or std::string; changing values in either are equiva...
Definition ReferenceMap.h:69
ref_t & link(const std::string &key, F &x)
Associates a map entry with a variable.
Definition ReferenceMap.h:84
void copyStruct(const ReferenceMap &m, const T &src, T &dst, extLinkPolicy policy=RESERVE)
Experimental. Copies references and values of a structure to another.
Definition ReferenceMap.h:399
static std::ostream & toStream(std::ostream &ostr, const std::initializer_list< T > &x, const SprinterLayout &layout=defaultLayout)
New (experimental)
Definition Sprinter.h:420
static const SprinterLayout jsonLayout
Resembles JSON structure: {"a":1,"b":22,"c":3}.
Definition Sprinter.h:221
A tool for expanding variables embedded in a std::string to literals.
Definition StringMapper.h:275
StringMapper & parse(const std::string &s, bool convertEscaped=false)
Converts a std::string containing variables like in "Hello, ${NAME}!" to a list of StringLet's.
Definition StringMapper.cpp:53
std::ostream & toStream(std::ostream &ostr) const
Output a concatenated chain of stringlets: literals as such and variables surrounded with "${" and "}...
Definition StringMapper.h:364
static void convert(const std::string &s, T &dst)
Conversion from std::string to basic types, including std::string.
Definition String.h:522
Image with static geometry.
Definition ImageFrame.h:67
double getScaled(size_t i, size_t j) const
Get intensity in original physical scale.
Definition ImageFrame.h:287
Reads image channels, returning scaled (physical) values.
Definition Sampler.h:123
Utility for sampling images (2D data), outputting formatted text data.
Definition Sampler.h:152
char getCommentChar() const
Returns character, also supporting numeric ASCII values between 32 and 128.
Definition Sampler.cpp:58
std::string commentPrefix
Escape std::string for prefixing text no to be handled as data values.
Definition Sampler.h:173
ReferenceMap2 variableMap
Interface that links coordinates and image data.
Definition Sampler.h:188
std::string getFormat(const std::string &formatStr) const
Use given format or generate default "${var},${var2}, ...".
Definition Sampler.cpp:90
bool skipVoid
Skip lines, if contain missing values.
Definition Sampler.h:178
void sample(const std::map< std::string, D > &images, const P &picker, const std::string &formatStr, std::ostream &ostr=std::cout) const
Main function.
Definition Sampler.h:210
Definition DataSelector.cpp:1277
Interprets data values for Sampler.
Definition Sampler.h:61
int current_j2
Vertical inversed coordinate.
Definition Sampler.h:105
ReferenceMap2 & variableMap
Definition Sampler.h:115
int current_i
Optional utility. Called prior to writing the actual data to output stream.
Definition Sampler.h:99
SamplePicker(ReferenceMap2<> &variableMap)
Definition Sampler.h:68
FlexVariableMap infoMap
Information to be should in output file header.
Definition Sampler.h:111
int current_j
Vertical coordinate.
Definition Sampler.h:102
virtual void setPosition(int i, int j) const
Sets current position in image coordinates. To be redefined to compute also geographical projections,...
Definition Sampler.h:84