Loading...
Searching...
No Matches
RadarWindows.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 RACK_RADAR_WINDOWS_H
32#define RACK_RADAR_WINDOWS_H
33
34#include <math.h>
35
36#include <drain/Log.h>
37#include <drain/TypeUtils.h>
38#include <drain/util/Fuzzy.h>
39#include <drain/util/Functor.h>
40#include <drain/util/FunctorBank.h>
41#include <drain/image/Window.h>
42#include <drain/image/SegmentProber.h>
43#include <drain/image/SlidingWindow.h>
44#include <drain/image/GaussianWindow.h>
45#include <drain/imageops/FunctorOp.h>
46#include <drain/imageops/GaussianAverageOp.h>
47//#include <drain/image/SequentialImageOp.h>
48
49#include "data/ODIM.h"
50#include "data/PolarODIM.h"
51#include "data/Quantity.h"
52
53using namespace drain::image;
54
55// file RadarFunctorOp?
56
57namespace rack {
58
59
61
65class RadarWindowGeom : public drain::UniTuple<double,2> {
66
67public:
68
69 RadarWindowGeom() : widthM(this->next()), heightD(this->next()) {
70 }
71
72 RadarWindowGeom(const RadarWindowGeom & geom) : widthM(next()), heightD(next()) {
73 assignSequence(geom.tuple());
74 }
75
76 // Beam-directional window width in metres
77 double & widthM; // = 1500.0;
78
79 // Azimuthal window height in degrees
80 double & heightD; // = 3.0;
81
82};
83
85
86public:
87
89 double contributionThreshold = 0.5; //
90
92 bool invertPolar = false;
93
95 bool relativeScale = false; //
96
102 RadarWindowConfig(int widthM=1500, double heightD=3.0, double contributionThreshold = 0.5, bool invertPolar=false, bool relativeScale=false) :
103 drain::image::WindowConfig(1, 1), // drain::image::WindowConfig(width, height),
104 // widthM(widthM), heightD(heightD),
106 this->widthM = widthM;
107 this->heightD = heightD;
108 }
109
111 RadarWindowGeom(conf),
112 drain::image::WindowConfig(conf),
113 //widthM(conf.widthM),
114 //heightD(conf.heightD),
118
119 }
120
129 //RadarWindowConfig(drain::UnaryFunctor & ftor, int width=3, int height=3, double contributionThreshold = 0.5) :
130 template <class FT>
131 RadarWindowConfig(const FT & ftor, int widthM=1500, double heightD=3.0,
132 double contributionThreshold = 0.5, bool invertPolar=false, bool relativeScale=false) :
133 drain::image::WindowConfig(0, 0, ftor), //drain::image::WindowConfig(ftor, width, height),
134 //widthM(widthM), heightD(heightD),
136 // invertPolar(false), contributionThreshold(contributionThreshold) {
137 this->widthM = widthM;
138 this->heightD = heightD;
139 }
140
141 // Perhaphs deprecating.
143 void setPixelConf(RadarWindowConfig & conf, const PolarODIM & inputODIM) const;
144
145 // NEW, "Inverted" setPixelConf
147 void adjustMyConf(const RadarWindowConfig & conf, const PolarODIM & inputODIM);
148
149
150 void updatePixelSize(const PolarODIM & inputODIM);
151
152};
153
154
155
157
158
159public:
160
162
165 }
166
167 PolarODIM odimSrc;
168
171 mutable double NI;
172
173};
174
175
177
183template <class C, class R=RadarWindowCore>
185public:
186
187 SlidingRadarWindowBase(int width=0, int height=0) : drain::image::SlidingWindow<C,R>(width,height), rangeNorm(1), rangeNormEnd(2), countMin(0) {
188 this->resetAtEdges = true;
189 };
190
191 SlidingRadarWindowBase(const C & conf) : drain::image::SlidingWindow<C,R>(conf), rangeNorm(1), rangeNormEnd(2), countMin(0) {
192 this->resetAtEdges = conf.invertPolar;
193 //this->resetAtEdges = true; //conf.invertPolar;
194 };
195
196 virtual
198
200 // Redefines Window<C,R>::setSrcFrame(ImageFrame)
205
206 drain::Logger mout("SlidingRadarWindow", __FUNCTION__);
207 //mout.debug("src Scaling0: " , src.getScaling() );
208 mout.debug2("src props for odim: " , src.getProperties() );
209
210 this->odimSrc.updateFromMap(src.getProperties());
211 mout.info("NI=" , this->odimSrc.getNyquist(LOG_WARNING) );
212 mout.info("copied odim: " , EncodingODIM(this->odimSrc) );
213
215 // direct should be:
216 // R::setSrcFrame(src);
217 mout.debug2("src Scaling: " , src.getScaling() );
218 }
219
220 /*
221 void setDst(drain::image::ImageFrame & dst){
222 drain::Logger mout("SlidingRadarWindow", __FUNCTION__);
223 //this->odimSrc.updateFromMap(src.getProperties());
224 //mout.debug("copied odim: " , this->odimSrc );
225 SlidingWindow<C, RadarWindowCore>::setDst(dst);
226 }
227 */
228
229protected:
230
231 virtual
232 void initialize() override {
234 setRangeNorm(); // interplay setLoopLimits(), with reset() and
235 //if (drain::Type::call<drain::typeIsSmallInt>(this->src.getType()) && drain::Type::call<drain::drain::typeIsSmallInt>(this->dst.getType())){
236 if (drain::Type::call<drain::typeIsSmallInt>(this->dst.getType())){
237 drain::Logger mout("SlidingRadarWindow", __FUNCTION__);
238 //this->conf.ftor.setScale(1.0);
239 mout.info("(not implemented: functor scaling for small int dst)" ); // << this->odimSrc
240 }
241 // what about reset(); ?
242 reset();
243 };
244
245
246 inline
247 void setImageLimits() const {
248 this->coordinateHandler.set(this->src.getGeometry(), this->src.getCoordinatePolicy());
249 // this->src.adjustCoordinateHandler(this->coordinateHandler);
250 }
251
254
255 drain::Logger mout("SlidingRadarWindow", __FUNCTION__);
256
257 if (this->odimSrc.area.height == 0)
258 mout.error("src odim.area.height==0" );
259
261 const double r = static_cast<double>(this->odimSrc.area.height) / (2.0*M_PI);
262 const int max = static_cast<int>(this->odimSrc.area.width);
263
264 rangeNorm = static_cast<int>(r);
266 rangeNormEnd = static_cast<int>(r * static_cast<double>(this->conf.frame.height));
267 if ((rangeNorm <= 0) || (rangeNormEnd >= max)){
268 mout.note(rangeNorm , '-' , rangeNormEnd );
269 }
270 //
271 }
272
273 int rangeNorm;
274 int rangeNormEnd;
275 int countMin; // raise
276
277
279 virtual inline
280 bool reset(){
281
282 if (this->location.x <= rangeNorm){
283 this->setLoopLimits(this->conf.frame.width, this->conf.frame.height);
284 }
285 else if (this->location.x < rangeNormEnd){ // from 'height' down to 1
286 this->setLoopLimits(this->conf.frame.width, (rangeNorm * this->conf.frame.height)/(this->location.x+1) );
287 //std::cerr << "loop limits " << this->jMax << std::endl;
288 }
289 else {
290 this->setLoopLimits(this->conf.frame.width, 1);
291 }
292 //drain::Logger mout("SlidingRadarWindow", __FUNCTION__);
293 //mout.warn(this->iMax , ',' , this->jMax , '\t' , this->getSamplingArea( ));
294 countMin = this->conf.contributionThreshold * this->getSamplingArea();
295
297 };
298
299};
300
301
302template <class C, class R=RadarWindowCore>
303class SlidingRadarWindow : public SlidingRadarWindowBase<C,R> { // drain::image::WeightedWindowCore
304public:
305
306 inline
307 SlidingRadarWindow(int width=0, int height=0) : SlidingRadarWindowBase<C,R>(width, height) {
308 };
309
310 inline
311 SlidingRadarWindow(const C & conf) : SlidingRadarWindowBase<C,R>(conf) {
312 };
313
314
315 virtual inline
317 if (this->coordinateHandler.validate(p)){
318 double x = this->src.template get<double>(p);
319 if ((x != this->odimSrc.nodata) && (x != this->odimSrc.undetect))
320 removeTrailingValue(this->odimSrc.scaleForward(x));
321 }
322 };
323
324 virtual inline
326 if (this->coordinateHandler.validate(p)){
327 double x = this->src.template get<double>(p);
328 if ((x != this->odimSrc.nodata) && (x != this->odimSrc.undetect))
329 addLeadingValue(this->odimSrc.scaleForward(x));
330 }
331 };
332
334 virtual inline
335 void removeTrailingValue(double x){}; // = 0;
336
338 virtual inline
339 void addLeadingValue(double x){}; // = 0;
340
341
342
343};
344
349template <class C>
351public:
352
353 //drain::UnaryFunctor & myFunctor;
354
355 RadarWindowAvg(int width=0, int height=0) :
356 SlidingRadarWindow<C>(width,height),
357 //myFunctor(this->conf.getFunctor()),
358 sum(0.0),
359 count(0) {
360 };
361
362 RadarWindowAvg(const RadarWindowAvg & window) :
363 SlidingRadarWindow<C>(window),
364 //myFunctor(this->conf.getFunctor(window.conf.getFunctorName())), // kludge
365 sum(0.0),
366 count(0) {
367 };
368
369 RadarWindowAvg(const C & conf) :
371 // myFunctor(this->conf.getFunctor(conf.getFunctorName())),
372 sum(0.0),
373 count(0) {
374 };
375
376
377
378
379 virtual
380 inline
381 ~RadarWindowAvg(){};
382
384
385protected:
386
387 double sum;
388 int count;
389
390 virtual
391 inline
392 void clear(){
393 sum = 0.0;
394 count = 0;
395 };
396
397 virtual inline
398 void removeTrailingValue(double x){
399 sum -= x;
400 --count;
401 };
402
403 virtual inline
404 void addLeadingValue(double x){
405 sum += x;
406 ++count;
407 };
408
409 virtual inline
410 void write(){
411 if (count > 0){
412 //if (this->location.x == this->location.y)
413 // std::cerr << sum << '\t' << count << '\n';
414 this->dst.putScaled(this->location.x, this->location.y, this->myFunctor(sum/static_cast<double>(count)));
415 }
416 else
417 this->dst.put(this->location, this->odimSrc.undetect); // ?
418 };
419
420
421};
422
427template <class C>
429public:
430
431
432 // Consider metres & degrees?
433 RadarWindowWeightedAvg(int width=0, int height=0) : SlidingRadarWindow<C>(width,height) {
434 };
435
437 };
438
439 RadarWindowWeightedAvg(const C & conf) : SlidingRadarWindow<C>(conf) {
440 };
441
442 virtual inline
444
445protected:
446
447 int count = 0;
448
449 // Copied from SlidingStripeAverage
450 typedef float sum_t;
451 sum_t w = 0.0;
452 sum_t sum = 0.0;
453 sum_t sumW = 0.0;
454
455 virtual inline
456 void clear() final {
457 this->sum = 0.0;
458 this->sumW = 0.0;
459 this->count = 0;
460 };
461
462
463 virtual inline
465 if (this->coordinateHandler.validate(p)){
466 double x = this->src.template get<double>(p);
467 if (this->odimSrc.isValue(x)){
468 this->w = this->srcWeight.template get<sum_t>(p);
469 this->sum += w*this->odimSrc.scaling.fwd(x);
470 this->sumW += w;
471 ++this->count;
472 }
473 }
474 };
475
476 virtual inline
478 if (this->coordinateHandler.validate(p)){
479 double x = this->src.template get<double>(p);
480 if (this->odimSrc.isValue(x)){
481 this->w = this->srcWeight.template get<sum_t>(p);
482 this->sum -= w*this->odimSrc.scaling.fwd(x);
483 this->sumW -= w;
484 --this->count;
485 }
486 }
487 };
488
489 virtual inline
490 void write() final {
491 if (sumW > 0.0){ // then also count>0
492 this->dst.put(this->location, this->odimSrc.scaling.inv(this->sum/sumW));
493 //this->dstWeight.put(this->location, this->scalingW.inv(sumW/static_cast<sum_t>(this->count)));
494 this->dstWeight.put(this->location, sumW/static_cast<sum_t>(this->count)); // "uses" original scaling
495 }
496 else {
497 this->dst.put(this->location, this->odimSrc.undetect); // change
498 this->dstWeight.put(this->location, 0);
499 }
500
501 }
502
503 /*
504 virtual inline
505 void removeTrailingValue(double x) final {
506 sum -= x;
507 --count;
508 };
509
510 virtual inline
511 void addLeadingValue(double x) final {
512 sum += x;
513 ++count;
514 };
515
516 virtual inline
517 void write(){
518 if (count > 0){
519 //if (this->location.x == this->location.y)
520 // std::cerr << sum << '\t' << count << '\n';
521 this->dst.putScaled(this->location.x, this->location.y, this->myFunctor(sum/static_cast<double>(count)));
522 }
523 else
524 this->dst.put(this->location, this->odimSrc.undetect); // ?
525 };
526 */
527
528
529};
530
531
535template <class C>
537public:
538
539 RadarWindowSoftMax(int width=0, int height=0, double coeff=1.0) : SlidingRadarWindow<C>(width,height), coeff(1.0), coeffInv(1.0/coeff), sum(0.0), count(0) {};
540
541
542 virtual inline
544
545 void setCoeff(double c){
546 if (c==0.0)
547 throw std::runtime_error("RadarWindowSoftMax: zero coeff");
548 coeff = c;
549 coeffInv = 1.0/c;
550 };
551
552protected:
553
554 double coeff;
555 double coeffInv;
556
557 double sum;
558 int count;
559
560 virtual inline
561 void clear(){
562 sum = 0.0;
563 count = 0;
564 };
565
566 virtual inline
567 void removeTrailingValue(double x){
568 sum -= ::exp(coeff * x);
569 --count;
570 };
571
572 virtual inline
573 void addLeadingValue(double x){
574 sum += ::exp(coeff * x);
575 ++count;
576 //if ((p.x == p.y) && (x > -15.0))
577 // std::cerr << "handleLeadingPixel" << p << ':' << x << '\t' << count << ':' << sum << std::endl;
578 };
579
580 virtual inline
581 void write(){
582 if (count > 0)
583 this->dst.put(this->location, this->fuzzifier(coeffInv*::log(sum/static_cast<double>(count))));
584 //this->dst.put(this->location, this->functor(sum/static_cast<double>(count)));
585 };
586
587
588};
589
591
596template <class F>
598public:
599
600 RadarWindowStdDev(int width=0, int height=0) : SlidingRadarWindow<F>(width,height), sum(0.0), sum2(0.0), count(0) {};
601
602
603 virtual inline
605
606protected:
607
608 double sum;
609 double sum2;
610 int count;
611
612 virtual inline
613 void clear(){
614 sum = 0.0;
615 sum2 = 0.0;
616 count = 0;
617 };
618
619 virtual
620 inline
621 void removeTrailingValue(double x){
622 sum -= x;
623 sum2 -= x*x;
624 --count;
625 };
626
627 virtual
628 inline
629 void addLeadingValue(double x){
630 sum += x;
631 sum2 += x*x;
632 ++count;
633 //if ((this->p.x == this->p.y) && (x > -15.0))
634 // std::cerr << "handleLeadingPixel" << this->p << ':' << x << '\t' << count << ':' << sum << std::endl;
635 };
636
637 virtual
638 inline
639 void write(){
640
641 if (count > 0){
642 double countD = static_cast<double>(count);
643 this->dst.put(this->location, this->fuzzifier( ::sqrt(sum2/countD - sum*sum/(countD*countD)) ));
644 /*
645 countD = sum2/countD - sum*sum/(countD*countD);
646 if ((this->p.x == this->p.y) && (count > 5))
647 std::cerr << __FUNCTION__ << this->p << ':' << countD << std::endl;
648 */
649 }
650 else
651 this->dst.put(this->location, 0);
652
653 };
654
655
656};
657
658
659
660
661
662
663
664} // rack::
665
666
667
668
669#endif
670
671// Rack
LogSourc e is the means for a function or any program segment to "connect" to a Log.
Definition Log.h:312
Logger & note(const TT &... args)
For top-level information.
Definition Log.h:489
Logger & error(const TT &... args)
Echoes.
Definition Log.h:416
Logger & debug2(const TT &... args)
Debug information.
Definition Log.h:676
tuplebase_t & assignSequence(T &sequence, bool LENIENT=false)
Proposed for tuples only; derived classes should not shadow this.
Definition TupleBase.h:287
Tuple of N elements of type T.
Definition UniTuple.h:65
bool validate(Point2D< int > &p) const
Handles the coordinate, returning true if the position is reversible.
Definition CoordinateHandler.h:238
Image with static geometry.
Definition ImageFrame.h:67
void put(size_t i, T x)
Sets the intensity in location i to x. See \address.
Definition ImageFrame.h:192
void putScaled(size_t i, size_t j, double x)
Put intensity using original physical value.
Definition ImageFrame.h:241
const std::type_info & getType() const
Get the storage type.
Definition ImageLike.h:100
Window implementation that uses incremental update of state.
Definition SlidingWindow.h:50
virtual bool reset()
Returns false, if traversal should be ended.
Definition SlidingWindow.h:212
Definition Window.h:268
Base class for configurations applied in image processing windows, e.g. for operators of type WindowO...
Definition Window.h:56
bool resetAtEdges
To avoid accumulated numerical errors esp. with floats, reset the statistics at row/cols ends....
Definition Window.h:529
Point2D< int > location
Current location of this window.
Definition Window.h:523
size_t getSamplingArea()
Returns the area which has eventually been scaled (in a non-linear coordinate system)
Definition Window.h:492
void setLoopLimits()
Sets the actual traversal range inside the window. Sometimes applied dynamically by reset().
Definition Window.h:608
Structure for data storage type, scaling and marker codes. Does not contain quantity.
Definition EncodingODIM.h:75
Metadata structure for single-radar data (polar scans, volumes and products).
Definition PolarODIM.h:45
Definition RadarWindows.h:350
virtual void write()
Write the result in the target image.
Definition RadarWindows.h:410
virtual void removeTrailingValue(double x)
Handles the converted (natural-scaled) value.
Definition RadarWindows.h:398
virtual void addLeadingValue(double x)
Handles the converted (natural-scaled) value.
Definition RadarWindows.h:404
virtual void clear()
Clears the applied statistics. Redefined in derived classes.
Definition RadarWindows.h:392
Definition RadarWindows.h:84
RadarWindowConfig(int widthM=1500, double heightD=3.0, double contributionThreshold=0.5, bool invertPolar=false, bool relativeScale=false)
Definition RadarWindows.h:102
RadarWindowConfig(const FT &ftor, int widthM=1500, double heightD=3.0, double contributionThreshold=0.5, bool invertPolar=false, bool relativeScale=false)
Definition RadarWindows.h:131
void adjustMyConf(const RadarWindowConfig &conf, const PolarODIM &inputODIM)
Copies configuration from conf and update pixel frame (width x height).
Definition RadarWindows.cpp:54
void setPixelConf(RadarWindowConfig &conf, const PolarODIM &inputODIM) const
Copies configuration to conf and update its pixel frame (width x height).
Definition RadarWindows.cpp:37
bool invertPolar
Compensate the polar coordinate system to correspond the Cartesian one in computations.
Definition RadarWindows.h:92
bool relativeScale
If true, use speed up to -1.0...+1.0 instead of -Vnyq...+Vnyq.
Definition RadarWindows.h:95
double contributionThreshold
Minimum percentage of detected values in a window (not undetect and nodata)
Definition RadarWindows.h:89
Definition RadarWindows.h:156
double NI
Definition RadarWindows.h:171
RadarWindowCore()
Will act as base class: Window<RadarWindowCore> : public RadarWindowCore {...}, init currently not su...
Definition RadarWindows.h:164
Like pixel window, but width is metres and height is degrees.
Definition RadarWindows.h:65
Definition RadarWindows.h:536
virtual void write()
Write the result in the target image.
Definition RadarWindows.h:581
virtual void removeTrailingValue(double x)
Handles the converted (natural-scaled) value.
Definition RadarWindows.h:567
virtual void addLeadingValue(double x)
Handles the converted (natural-scaled) value.
Definition RadarWindows.h:573
virtual void clear()
Clears the applied statistics. Redefined in derived classes.
Definition RadarWindows.h:561
Sliding window for computing standard deviation of scalar quantities.
Definition RadarWindows.h:597
virtual void write()
Write the result in the target image.
Definition RadarWindows.h:639
virtual void removeTrailingValue(double x)
Handles the converted (natural-scaled) value.
Definition RadarWindows.h:621
virtual void addLeadingValue(double x)
Handles the converted (natural-scaled) value.
Definition RadarWindows.h:629
virtual void clear()
Clears the applied statistics. Redefined in derived classes.
Definition RadarWindows.h:613
Definition RadarWindows.h:428
virtual void addPixel(drain::Point2D< int > &p) final
Adds a pixel to window statistics. Unvalidated location.
Definition RadarWindows.h:464
virtual void removePixel(drain::Point2D< int > &p) final
Removes a pixel from window statistics. Unvalidated location.
Definition RadarWindows.h:477
virtual void write() final
Write the result in the target image.
Definition RadarWindows.h:490
virtual void clear() final
Clears the applied statistics. Redefined in derived classes.
Definition RadarWindows.h:456
A two-dimensional image processing window that handles the special ODIM codes and scales the result....
Definition RadarWindows.h:184
void setImageLimits() const
Sets internal limits corresponding to image geometries. Typically using coordHandler.
Definition RadarWindows.h:247
void setSrcFrame(const drain::image::ImageFrame &src)
Sets input image and retrieves ODIM metadata from image Properties.
Definition RadarWindows.h:204
virtual void initialize() override
Sets class-specific initial values. Does not change general window state (e.g. location)....
Definition RadarWindows.h:232
virtual bool reset()
Returns false, if traversal should be ended.
Definition RadarWindows.h:280
void setRangeNorm()
To compensate polar geometry, set applicable range for pixel area scaling.
Definition RadarWindows.h:253
Definition RadarWindows.h:303
virtual void addPixel(drain::Point2D< int > &p)
Adds a pixel to window statistics. Unvalidated location.
Definition RadarWindows.h:325
virtual void removePixel(drain::Point2D< int > &p)
Removes a pixel from window statistics. Unvalidated location.
Definition RadarWindows.h:316
virtual void removeTrailingValue(double x)
Handles the converted (natural-scaled) value.
Definition RadarWindows.h:335
virtual void addLeadingValue(double x)
Handles the converted (natural-scaled) value.
Definition RadarWindows.h:339
Namespace for images and image processing tools.
Definition AccumulationArray.cpp:45
Definition DataSelector.cpp:1277
Definition DataSelector.cpp:44
Definition Point.h:48