PolarODIM.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 POLAR_ODIM_STRUCT
32 #define POLAR_ODIM_STRUCT
33 
34 #include <drain/util/Geo.h>
35 #include <drain/Type.h>
36 
37 #include "ODIM.h"
38 
39 namespace rack {
40 
42 
45 class PolarODIM : public ODIM {
46 
47 
48 public:
49 
50  PolarODIM(group_t initialize = ODIMPathElem::ALL_LEVELS) : ODIM(initialize), rscale(resolution.x){
51  init(initialize);
52  };
53 
54  PolarODIM(const PolarODIM & odim) : ODIM(ODIMPathElem::ALL_LEVELS), rscale(resolution.x), highprf(0.0) {
55  initFromMap(odim);
56  getNyquist();
57  }
58 
59  template <class T>
60  PolarODIM(const std::map<std::string,T> & m) : ODIM(ODIMPathElem::ALL_LEVELS), rscale(resolution.x), highprf(0.0) {
61  initFromMap(m);
62  getNyquist();
63  }
64 
65  PolarODIM(const drain::image::Image & img, const std::string & quantity="") : ODIM(ODIMPathElem::ALL_LEVELS), rscale(resolution.x), highprf(0.0) {
66  initFromImage(img, quantity);
67  }
68 
69  inline
70  rack::PolarODIM & operator=(const rack::PolarODIM & odim){
71  updateFromMap(odim);
72  // updateFromCastableMap(odim);
73  return *this;
74  }
75 
77  double & rscale;
78 
80  double lon = 0.0;
82  double lat = 0.0;
84  double height = 0.0;
85 
87  double elangle = 0.0;
89  double rstart = 0.0;
91  long a1gate = 0.0;
92 
93 
94  double startaz = 0.0;
95  double stopaz = 0.0;
96 
97  //double NI; // Maximum Nyquist
98  double highprf = 0.0; //
99  double lowprf = 0.0; //
100  double wavelength = 0.0;
101 
103  double freeze = 0.0;
104 
105 
107  virtual inline
109  using namespace drain::image;
110  static const CoordinatePolicy polarLeft(EdgePolicy::POLAR, EdgePolicy::WRAP, EdgePolicy::LIMIT, EdgePolicy::WRAP);
111  return polarLeft;
112  }
113 
115  /*
116  inline
117  void setGeometry(size_t cols, size_t rows){
118  nbins = cols;
119  nrays = rows;
120  }
121  */
122 
124 
127  virtual
128  void updateLenient(const PolarODIM & odim);
129 
130 
132 
135  inline
136  bool optimiseVRAD(){
137  if (quantity.find("VRAD") == 0){
138  getNyquist();
139  setRange(-NI, NI);
140  return true;
141  }
142  else
143  return false;
144  }
145 
146  // Sets how:NI from lowprf if needed. If that fails, tries to derive it from scaling (gain, offset).
150  double getNyquist(int errorThreshold = LOG_NOTICE) const;
151 
152 
154  inline
155  double getBeamWidth() const {
156  return 2.0*M_PI/static_cast<double>(area.height);
157  };
158 
159  bool deriveDifference(double v1, double v2, double & dOmega) const;
160 
162 
169  signed char checkAliasing(double v1, double v2, double NI_threshold) const;
170 
172  inline
173  double getElangleR() const {
174  return elangle * drain::DEG2RAD;
175  }
176 
178  // CF ? Returns the distance in metres to the start of the measurement volume (i.e. the end nearer to radar).
179  inline
180  double getBinDistance(size_t i) const {
181  return rstart + (static_cast<double>(i)+0.5)*rscale;
182  }
183 
185  inline
186  double getBinSpan(size_t i) const {
187  return (static_cast<double>(i))*rscale;
188  }
189 
191  inline
192  int getBinIndex(double d) const {
193  return static_cast<int>((d - rstart) / rscale) ;
194  }
195 
197  inline
198  int getRayIndex(double d) const {
199  return static_cast<int>(d * static_cast<double>(area.height)/(2.0 * M_PI)) ;
200  }
201 
203  inline
204  int getDRayIndex(double d) const {
205  return static_cast<int>(d * static_cast<double>(area.height) / 360.0) ;
206  }
207 
209  template <class T>
210  inline
211  double getAzimuth(T j) const {
212  return static_cast<double>(j)*2.0*M_PI / static_cast<double>(area.height);
213  }
214 
216 
219  inline
220  int getAzimuthalBins(double degree) const {
221  return static_cast<int>(degree * static_cast<double>(area.height)/360.0 + 0.5) ;
222  }
223 
225  /*
226  * Returns the number of bins corresponding to a given distance range (in meters).
227  * \see getAzimuthalBins()
228  */
229  inline
230  int getBeamBins(double spanM) const {
231  return static_cast<int>(spanM/rscale + 0.5) ;
232  }
233 
235  //inline
236  double getMaxRange(bool warn = false) const;
237 
238  double getGroundAngle(size_t i) const {
239  return (static_cast<double>(i)+0.5) * rscale / EARTH_RADIUS_43;
240  }
241 
243  inline
244  void mapDopplerSpeed(double d, double &x, double &y) const {
245  d = scaleForward(d) * M_PI/NI;
246  //std::cerr << d << '\n';
247  x = cos(d);
248  y = sin(d);
249  }
250 
251 
252  // defaultRange
253  static int defaultRange;
254 
255 private:
256 
257  virtual // must
258  void init(group_t initialize =ODIMPathElem::ALL_LEVELS);
259 
260 
261 };
262 
263 
264 
265 
266 
267 } // namespace rack
268 
269 namespace drain {
270  DRAIN_TYPENAME(rack::PolarODIM);
271 }
272 
273 
274 #endif
275 
276 // Rack
void updateFromMap(const std::map< std::string, T2 > &m)
Assign values from a map. Updates existing entries only.
Definition: SmartMap.h:294
Policies for coordinate underflows and overflows.
Definition: CoordinatePolicy.h:106
Class for multi-channel digital images. Supports dynamic typing with base types (char,...
Definition: Image.h:184
double scaleForward(double x) const
Converts a quantity from storage scale: y = offset + gain*y .
Definition: EncodingODIM.h:225
static const group_t ALL_LEVELS
Abbreviation for linking (referencing) attributes at different levels (tree depths).
Definition: ODIMPath.h:118
ODIM metadata (quantity, gain, offset, undetect, nodata, date, time)
Definition: ODIM.h:79
drain::Point2D< double > resolution
Spatial resolution in metres.
Definition: ODIM.h:156
std::string quantity
dataX/what (obligatory)
Definition: ODIM.h:181
Metadata structure for single-radar data (polar scans, volumes and products).
Definition: PolarODIM.h:45
virtual void updateLenient(const PolarODIM &odim)
Sets number of bins (geometry.width) and number of rays (geometry.height)
Definition: PolarODIM.cpp:75
double freeze
Freezing level.
Definition: PolarODIM.h:103
signed char checkAliasing(double v1, double v2, double NI_threshold) const
Detect Doppler speed aliasing (wrapping)
Definition: PolarODIM.cpp:213
int getBinIndex(double d) const
Returns the index of bin at given (bin center) distance along the beam.
Definition: PolarODIM.h:192
virtual const drain::image::CoordinatePolicy & getCoordinatePolicy() const
Returns recommended coordinate policy (Polar coords, origin at left)
Definition: PolarODIM.h:108
double getMaxRange(bool warn=false) const
Returns the range in metres (i.e. distance to the end of the last measurement volume).
Definition: PolarODIM.cpp:104
int getAzimuthalBins(double degree) const
Returns the span of bins for the given azimuthal span.
Definition: PolarODIM.h:220
long a1gate
Index of the first azimuth gate radiated in the scan.
Definition: PolarODIM.h:91
double getAzimuth(T j) const
Returns the azimuth in radians of the bin with vertical index j.
Definition: PolarODIM.h:211
double getBinSpan(size_t i) const
Returns the radial distance covered by i consecutive bins.
Definition: PolarODIM.h:186
double lat
Latitude position of the radar antenna (degrees), normalized to the WGS-84 reference ellipsoid and da...
Definition: PolarODIM.h:82
double & rscale
Beam-directional bin length [m].
Definition: PolarODIM.h:77
void mapDopplerSpeed(double d, double &x, double &y) const
Converts Doppler speed [-NI,NI] to unit circle.
Definition: PolarODIM.h:244
double getBeamWidth() const
Azimuthal resolution in radians.
Definition: PolarODIM.h:155
double height
Height of the centre of the antenna in meters above sea level.
Definition: PolarODIM.h:84
double getNyquist(int errorThreshold=LOG_NOTICE) const
Definition: PolarODIM.cpp:135
double lon
Longitude position of the radar antenna (degrees), normalized to the WGS-84 reference ellipsoid and d...
Definition: PolarODIM.h:80
double getBinDistance(size_t i) const
Returns the distance along the beam to the center of the i'th bin.
Definition: PolarODIM.h:180
double getElangleR() const
Returns elevation angle in radians.
Definition: PolarODIM.h:173
int getDRayIndex(double d) const
Returns the index of a ray at a given azimuth [degrees].
Definition: PolarODIM.h:204
double elangle
Antenna elevation angle (degrees) above the horizon.
Definition: PolarODIM.h:87
bool deriveDifference(double v1, double v2, double &dOmega) const
Given two Doppler speeds (m/s), computes their difference (m/s).
Definition: PolarODIM.cpp:190
int getBeamBins(double spanM) const
Returns the span of bins for the given distance range in meters.
Definition: PolarODIM.h:230
bool optimiseVRAD()
For VRAD, set encoding range to cover [-NI,NI].
Definition: PolarODIM.h:136
int getRayIndex(double d) const
Returns the index of a ray at a given azimuth [radians].
Definition: PolarODIM.h:198
double rstart
The range (km) of the start of the first range bin.
Definition: PolarODIM.h:89
Namespace for images and image processing tools.
Definition: AccumulationArray.cpp:45
Definition: DataSelector.cpp:1277
Definition: DataSelector.cpp:44
const double EARTH_RADIUS_43
The standard 4/3 radius applied in radar to compensate the decreasing density of the atmosphere.
Definition: Constants.h:53