Doppler.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 RACK_ANALYSIS_DOPPLER_H
32 #define RACK_ANALYSIS_DOPPLER_H
33 
34 #include <drain/Log.h>
35 #include <math.h>
36 
37 #include "drain/util/Fuzzy.h"
38 
39 //#include "drain/image/FuzzyOp.h"
40 
41 #include "drain/util/Functor.h"
42 #include "drain/util/FunctorBank.h"
43 
44 #include "drain/image/Window.h"
45 #include "drain/image/SlidingWindow.h"
46 //#include "drain/image/SequentialImageOp.h"
47 
48 
49 #include "RadarWindows.h"
50 
51 //#include "Analysis.h"
52 
53 
54 
55 using namespace drain::image;
56 
57 namespace rack {
58 
59 
60 
64 class DopplerWindow : public SlidingRadarWindow<RadarWindowConfig> {
65 public:
66 
67 
68  DopplerWindow(const RadarWindowConfig & conf) :
69  SlidingRadarWindow<RadarWindowConfig>(conf), radialSpeedConv(0.0) , radialSpeedConvInv(1.0),
70  sumI(0.0), sumI2(0.0), sumJ(0.0), sumJ2(0.0), count(0){}; //, countMin(0) {};
71 
72  virtual
73  inline
74  ~DopplerWindow(){};
75 
76 protected:
77 
78 
80 
85 
87 
90 
91 
92  // cumulants
93  double sumI;
94  double sumI2;
95  double sumJ;
96  double sumJ2;
97  int count;
98 
99  virtual inline
100  void initialize(){
101 
102  drain::Logger mout("RadarWindowDopplerDev", __FUNCTION__);
103 
104  this->setImageLimits();
105  this->setLoopLimits();
106  this->setRangeNorm();
107 
108 
109  this->NI = this->odimSrc.getNyquist(LOG_WARNING); // warn if guessed from scaling
110  if (this->NI == 0.0){
111  mout.warn(odimSrc );
112  mout.error("Could not derive Nyquist velocity (NI) from metadata." );
113  radialSpeedConv = 1.0;
114  radialSpeedConvInv = 1.0;
115  }
116  else {
117  radialSpeedConv = M_PI / this->NI;
118  radialSpeedConvInv = this->NI / M_PI; // M_1_PI * this->NI;
119  }
120 
121  reset();
122 
123  };
124 
125 
126  virtual inline
127  void clear(){
128  sumI = 0.0;
129  sumI2 = 0.0;
130  sumJ = 0.0;
131  sumJ2 = 0.0;
132  count = 0;
133  };
134 
135 
136  virtual
137  inline
138  void removeTrailingValue(double x){
139  x *= radialSpeedConv;
140  double t;
141  t = cos(x);
142  sumI -= t;
143  sumI2 -= t*t;
144  t = sin(x);
145  sumJ -= t;
146  sumJ2 -= t*t;
147  --count;
148  };
149 
150  virtual inline
151  void addLeadingValue(double x){
152  x *= radialSpeedConv;
153  double t;
154  t = cos(x);
155  sumI += t;
156  sumI2 += t*t;
157  t = sin(x);
158  sumJ += t;
159  sumJ2 += t*t;
160  ++count;
161  //if ((this->p.x == this->p.y) && (x > -15.0))
162  // std::cerr << "handleLeadingPixel" << this->p << ':' << x << '\t' << count << ':' << sum << std::endl;
163  };
164 
166  virtual inline
167  double averageR(){
168  return atan2(sumJ, sumI);
169  }
170 
172 
175  virtual inline
176  double stdDevR(){
177  double c = 1.0/static_cast<double>(count);
178  return ::sqrt((sumI2+sumJ2 - (sumI*sumI+sumJ*sumJ)*c)*c);
179  }
180 
182 
188  virtual inline
189  double eccentricity(){
190  return ::sqrt(sumI*sumI + sumJ*sumJ) / static_cast<double>(count);
191  }
192 
193 };
194 
195 
197 
198 public:
199 
201 
202  }
203 
205 
206 protected:
207 
208  virtual
209  inline
210  void write(){
211  //if ((this->location.x == this->location.y) && (this->location.x%15 == 0))
212  // std::cerr << "write" << this->location << ':' << '\t' << count << ':' << (this->conf.contributionThreshold * this->samplingArea) << std::endl;
213 
214  if (count > countMin){ // TODO threshold 0.5?
215 
216  if (this->conf.relativeScale)
217  this->dst.putScaled(this->location.x, this->location.y, averageR() * M_1_PI); // todo ftor?
218  else
219  this->dst.putScaled(this->location.x, this->location.y, averageR() * this->radialSpeedConvInv);
220  /*
221  if (this->debugDiag()){
222  std::cerr << "write: " << this->location.x << ":\t"
223  << atan2(sumJ, sumI) << "~\t"
224  << ((this->conf.relativeScale?M_1_PI:this->radialSpeedConvInv) * atan2(sumJ, sumI)) << ":\t"
225  << this->dst.getScaled(this->location.x, this->location.y) << '\t'
226  << this->dst.get<double>(this->location.x, this->location.y) << '\n';
227  }
228  */
229  }
230  else
231  this->dst.put(this->location, this->odimSrc.undetect); // NOTE: may be wrong (C/S), add odimDst?
232 
233  };
234 
235 };
236 
239 
240 public:
241 
243 
244  }
245 
246  typedef DopplerAverageWindow2 unweighted; // ????
247 
248 protected:
249 
250  virtual inline
251  void write(){
252 
253  //if ((this->location.x == this->location.y) && (this->location.x%15 == 0))
254  // std::cerr << "write" << this->location << ':' << '\t' << count << ':' << (this->conf.contributionThreshold * this->samplingArea) << std::endl;
255 
256  double confidence = this->myFunctor(this->eccentricity());
257 
258  if (count > countMin){ // TODO threshold 0.5?
259 
260  if (this->conf.relativeScale)
261  this->dst.putScaled(this->location.x, this->location.y, averageR() * M_1_PI); //
262  else
263  this->dst.putScaled(this->location.x, this->location.y, averageR() * this->radialSpeedConvInv);
264 
265  this->dstWeight.putScaled(this->location.x, this->location.y, confidence);
266  //this->dstWeight.putScaled(this->location.x, this->location.y, this->conf.ftor(this->NI*stdDevR()));
267  //this->dstWeight.putScaled(this->location.x, this->location.y, this->eccentricity());
268 
269  }
270  else {
271  this->dst.put(this->location, this->odimSrc.undetect); // NOTE: may be wrong (C/S), add odimDst?
272  this->dstWeight.put(this->location, 0.0); // NOTE: may be wrong (C/S), add odimDst?
273  }
274 
275  };
276 
277 };
278 
279 
281 
282 public:
283 
284  DopplerDevWindow(const RadarWindowConfig & conf) : DopplerWindow(conf){
285  }
286 
288 
289 protected:
290 
291 
292  virtual inline
293  void write(){
294 
295  if (count > countMin){ // TODO threshold 0.5?
296 
297  if (this->conf.relativeScale)
298  this->dst.putScaled(this->location.x, this->location.y, this->myFunctor(stdDevR()));
299  else
300  //this->dst.putScaled(this->location.x, this->location.y, this->conf.ftor(c));
301  // NOTE: possibly odimSrc != odimDst, (C/S), add odimDst?
302  this->dst.putScaled(this->location.x, this->location.y, this->myFunctor(NI * stdDevR()) );
303  /*
304  if (this->debugDiag()){
305  std::cerr << "write: " << this->location.x << ":\t" << (int) this->conf.relativeScale << '\t'
306  << c << ">\t"
307  << (this->conf.relativeScale ? c : c*this->odimSrc.NI ) << ":\t"
308  << this->dst.getScaled(this->location.x, this->location.y) << '\t'
309  << this->dst.get<double>(this->location.x, this->location.y) << '\n';
310  }
311  */
312 
313  }
314  // else this->dst.put(this->location, 0); LEAVE undetect
315 
316  };
317 
318 };
319 
320 
323 
324 public:
325 
327 
328  }
329 
330  typedef DopplerEccentricityWindow unweighted; // ????
331 
332 protected:
333 
334  virtual inline
335  void write(){
336 
337  //if ((this->location.x == this->location.y) && (this->location.x%15 == 0))
338  // std::cerr << "write" << this->location << ':' << '\t' << count << ':' << (this->conf.contributionThreshold * this->samplingArea) << std::endl;
339 
340  //double confidence = this->conf.ftor(this->eccentricity());
341 
342  if (count > countMin){ // TODO threshold 0.5?
343  this->dst.putScaled(this->location.x, this->location.y, this->myFunctor(this->eccentricity()));
344  }
345  else {
346  this->dst.put(this->location, this->odimSrc.undetect); // NOTE: may be wrong (C/S), add odimDst?
347  }
348 
349  };
350 
351 };
352 
353 
354 } // rack::
355 
356 
357 
358 
359 #endif
360 
361 // Rack
LogSourc e is the means for a function or any program segment to "connect" to a Log.
Definition: Log.h:308
Logger & error(const TT &... args)
Echoes.
Definition: Log.h:412
Logger & warn(const TT &... args)
Possible error, but execution can continue.
Definition: Log.h:426
Smoothens Doppler field, providing quality computed as eccentricity.
Definition: Doppler.h:238
virtual void write()
Write the result in the target image.
Definition: Doppler.h:251
Definition: Doppler.h:196
virtual void write()
Write the result in the target image.
Definition: Doppler.h:210
Definition: Doppler.h:280
virtual void write()
Write the result in the target image.
Definition: Doppler.h:293
Computes eccentrity of Doppler speeds mapped on a Nyquist-normalized unit window.
Definition: Doppler.h:322
virtual void write()
Write the result in the target image.
Definition: Doppler.h:335
Definition: Doppler.h:64
double radialSpeedConv
Speed scaled to radians [-M_PI, M_PI]: radialSpeedConv = M_PI/this->conf.odimSrc.NI.
Definition: Doppler.h:74
virtual double stdDevR()
Returns the radial speed variance [rad] defined as the variance of the cloud of velocity points on un...
Definition: Doppler.h:176
virtual void initialize()
Sets class-specific initial values. Does not change general window state (e.g. location)....
Definition: Doppler.h:100
virtual void removeTrailingValue(double x)
Handles the converted (natural-scaled) value.
Definition: Doppler.h:138
virtual void addLeadingValue(double x)
Handles the converted (natural-scaled) value.
Definition: Doppler.h:151
virtual double averageR()
Returns direction [rad] of the dominant speed.
Definition: Doppler.h:167
double radialSpeedConvInv
Inverse of radialSpeedConv.
Definition: Doppler.h:89
virtual void clear()
Clears the applied statistics. Redefined in derived classes.
Definition: Doppler.h:127
virtual double eccentricity()
Returns the eccentricity of the velocity points on unit circle.
Definition: Doppler.h:189
Definition: RadarWindows.h:112
bool relativeScale
If true, use speed up to -1.0...+1.0 instead of -Vnyq...+Vnyq.
Definition: RadarWindows.h:123
Definition: RadarWindows.h:311
Namespace for images and image processing tools.
Definition: AccumulationArray.cpp:45
Definition: DataSelector.cpp:44