NeillTropModel.cpp
Go to the documentation of this file.
1 //==============================================================================
2 //
3 // This file is part of GNSSTk, the ARL:UT GNSS Toolkit.
4 //
5 // The GNSSTk is free software; you can redistribute it and/or modify
6 // it under the terms of the GNU Lesser General Public License as published
7 // by the Free Software Foundation; either version 3.0 of the License, or
8 // any later version.
9 //
10 // The GNSSTk is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU Lesser General Public License for more details.
14 //
15 // You should have received a copy of the GNU Lesser General Public
16 // License along with GNSSTk; if not, write to the Free Software Foundation,
17 // Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
18 //
19 // This software was developed by Applied Research Laboratories at the
20 // University of Texas at Austin.
21 // Copyright 2004-2022, The Board of Regents of The University of Texas System
22 //
23 //==============================================================================
24 
25 //==============================================================================
26 //
27 // This software was developed by Applied Research Laboratories at the
28 // University of Texas at Austin, under contract to an agency or agencies
29 // within the U.S. Department of Defense. The U.S. Government retains all
30 // rights to use, duplicate, distribute, disclose, or release this software.
31 //
32 // Pursuant to DoD Directive 523024
33 //
34 // DISTRIBUTION STATEMENT A: This software has been approved for public
35 // release, distribution is unlimited.
36 //
37 //==============================================================================
38 
39 
40 #include "YDSTime.hpp"
41 #include "NeillTropModel.hpp"
42 
43 #define THROW_IF_INVALID_DETAILED() {if (!valid) { \
44  InvalidTropModel e; \
45  if(!validHeight) e.addText("Invalid trop model: Rx Height"); \
46  if(!validLat) e.addText("Invalid trop model: Rx Latitude"); \
47  if(!validDOY) e.addText("Invalid trop model: day of year"); \
48  GNSSTK_THROW(e);}}
49 
50 namespace gnsstk
51 {
53  const CommonTime& time )
54  {
58  }
59 
60 
61 
62  /* Parameters borrowed from Saastamoinen tropospheric model
63  * Constants for wet mapping function
64  */
65  static const double NeillWetA[5] =
66  { 0.00058021897, 0.00056794847, 0.00058118019,
67  0.00059727542, 0.00061641693 };
68  static const double NeillWetB[5] =
69  { 0.0014275268, 0.0015138625, 0.0014572752,
70  0.0015007428, 0.0017599082 };
71  static const double NeillWetC[5] =
72  { 0.043472961, 0.046729510, 0.043908931,
73  0.044626982, 0.054736038 };
74 
75  // constants for dry mapping function
76  static const double NeillDryA[5] =
77  { 0.0012769934, 0.0012683230, 0.0012465397,
78  0.0012196049, 0.0012045996 };
79  static const double NeillDryB[5] =
80  { 0.0029153695, 0.0029152299, 0.0029288445,
81  0.0029022565, 0.0029024912 };
82  static const double NeillDryC[5] =
83  { 0.062610505, 0.062837393, 0.063721774,
84  0.063824265, 0.064258455 };
85 
86  static const double NeillDryA1[5] =
87  { 0.0, 0.000012709626, 0.000026523662,
88  0.000034000452, 0.000041202191 };
89  static const double NeillDryB1[5] =
90  { 0.0, 0.000021414979, 0.000030160779,
91  0.000072562722, 0.00011723375 };
92  static const double NeillDryC1[5] =
93  { 0.0, 0.000090128400, 0.000043497037,
94  0.00084795348, 0.0017037206 };
95 
96 
97  double NeillTropModel::correction(double elevation) const
98  {
100 
101  // Neill mapping functions work down to 3 degrees of elevation
102  if(elevation < 3.0)
103  {
104  return 0.0;
105  }
106 
107  double map_dry(NeillTropModel::dry_mapping_function(elevation));
108 
109  double map_wet(NeillTropModel::wet_mapping_function(elevation));
110 
111  // Compute tropospheric delay
112  double tropDelay( (NeillTropModel::dry_zenith_delay() * map_dry) +
113  (NeillTropModel::wet_zenith_delay() * map_wet) );
114 
115  return tropDelay;
116  }
117 
118 
120  const Position& SV )
121  {
122 
123  try
124  {
127  setWeather();
128  }
129  catch(GeometryException& e)
130  {
131  valid = false;
132  }
133 
134  if(!valid)
135  {
136  throw InvalidTropModel("Invalid model");
137  }
138 
139  double c;
140  try
141  {
143  }
144  catch(InvalidTropModel& e)
145  {
146  GNSSTK_RETHROW(e);
147  }
148 
149  return c;
150  }
151 
152 
154  const Position& SV,
155  const CommonTime& tt )
156  {
157  setDayOfYear(tt);
158 
159  return NeillTropModel::correction(RX,SV);
160  }
161 
162 
164  const Position& SV,
165  const int& doy )
166  {
167  setDayOfYear(doy);
168 
169  return NeillTropModel::correction(RX,SV);
170  }
171 
172 
173  double NeillTropModel::correction( const Xvt& RX,
174  const Xvt& SV )
175  {
176  Position R(RX),S(SV);
177  return NeillTropModel::correction(R,S);
178  }
179 
180 
181  double NeillTropModel::correction( const Xvt& RX,
182  const Xvt& SV,
183  const CommonTime& tt )
184  {
185  setDayOfYear(tt);
186  Position R(RX),S(SV);
187 
188  return NeillTropModel::correction(R,S);
189  }
190 
191 
192  double NeillTropModel::correction( const Xvt& RX,
193  const Xvt& SV,
194  const int& doy )
195  {
196  setDayOfYear(doy);
197  Position R(RX),S(SV);
198 
199  return NeillTropModel::correction(R,S);
200  }
201 
202 
204  {
206 
207  // Note: 1.013*2.27 = 2.29951
208  double ddry( 2.29951*std::exp( (-0.000116 * NeillHeight) ) );
209 
210  /* where does above come from? Not Neill 1996
211  * probably ought to use SaasDryDelay
212  */
213  //return SaasDryDelay(press,NeillLat,NeillHeight);
214 
215  return ddry;
216  }
217 
218 
219  double NeillTropModel::dry_mapping_function(double elevation) const
220  {
222 
223  if(elevation < 3.0)
224  {
225  return 0.0;
226  }
227 
228  double lat, t, ct;
229  lat = fabs(NeillLat); // degrees
230  t = static_cast<double>(NeillDOY) - 28.0; // mid-winter
231 
232  if(NeillLat < 0.0) // southern hemisphere
233  {
234  t += 365.25/2.;
235  }
236 
237  t *= 360.0/365.25; // convert to degrees
238  ct = ::cos(t*DEG_TO_RAD);
239 
240  double a, b, c;
241  if(lat < 15.0)
242  {
243  a = NeillDryA[0];
244  b = NeillDryB[0];
245  c = NeillDryC[0];
246  }
247  else if(lat < 75.) // coefficients are for 15,30,45,60,75 deg
248  {
249  int i=int(lat/15.0)-1;
250  double frac=(lat-15.*(i+1))/15.;
251  a = NeillDryA[i] + frac*(NeillDryA[i+1]-NeillDryA[i]);
252  b = NeillDryB[i] + frac*(NeillDryB[i+1]-NeillDryB[i]);
253  c = NeillDryC[i] + frac*(NeillDryC[i+1]-NeillDryC[i]);
254 
255  a -= ct * (NeillDryA1[i] + frac*(NeillDryA1[i+1]-NeillDryA1[i]));
256  b -= ct * (NeillDryB1[i] + frac*(NeillDryB1[i+1]-NeillDryB1[i]));
257  c -= ct * (NeillDryC1[i] + frac*(NeillDryC1[i+1]-NeillDryC1[i]));
258  }
259  else
260  {
261  a = NeillDryA[4] - ct * NeillDryA1[4];
262  b = NeillDryB[4] - ct * NeillDryB1[4];
263  c = NeillDryC[4] - ct * NeillDryC1[4];
264  }
265 
266  double se = ::sin(elevation*DEG_TO_RAD);
267  double map = (1.+a/(1.+b/(1.+c)))/(se+a/(se+b/(se+c)));
268 
269  a = 0.0000253;
270  b = 0.00549;
271  c = 0.00114;
272  map += ( NeillHeight/1000.0 ) *
273  ( 1./se - ( (1.+a/(1.+b/(1.+c))) / (se+a/(se+b/(se+c))) ) );
274 
275  return map;
276  }
277 
278 
279  double NeillTropModel::wet_mapping_function(double elevation) const
280  {
282 
283  if(elevation < 3.0)
284  {
285  return 0.0;
286  }
287 
288  double a,b,c,lat;
289  lat = fabs(NeillLat); // degrees
290  if(lat < 15.0)
291  {
292  a = NeillWetA[0];
293  b = NeillWetB[0];
294  c = NeillWetC[0];
295  }
296  else if(lat < 75.) // coefficients are for 15,30,45,60,75 deg
297  {
298  int i=int(lat/15.0)-1;
299  double frac=(lat-15.*(i+1))/15.;
300  a = NeillWetA[i] + frac*(NeillWetA[i+1]-NeillWetA[i]);
301  b = NeillWetB[i] + frac*(NeillWetB[i+1]-NeillWetB[i]);
302  c = NeillWetC[i] + frac*(NeillWetC[i+1]-NeillWetC[i]);
303  }
304  else
305  {
306  a = NeillWetA[4];
307  b = NeillWetB[4];
308  c = NeillWetC[4];
309  }
310 
311  double se = ::sin(elevation*DEG_TO_RAD);
312  double map = ( 1.+ a/ (1.+ b/(1.+c) ) ) / (se + a/(se + b/(se+c) ) );
313 
314  return map;
315 
316  } // end NeillTropModel::wet_mapping_function()
317 
318 
320  {
321 
322  if(!validLat)
323  {
324  valid = false;
325  InvalidTropModel e(
326  "NeillTropModel must have Rx latitude before computing weather");
327  GNSSTK_THROW(e);
328  }
329  if(!validDOY)
330  {
331  valid = false;
332  InvalidTropModel e(
333  "NeillTropModel must have day of year before computing weather");
334  GNSSTK_THROW(e);
335  }
336 
338 
339  }
340 
341 
342  void NeillTropModel::setReceiverHeight(const double& ht)
343  {
344  NeillHeight = ht;
345  validHeight = true;
346 
347  // Change the value of field "valid" if everything is already set
349 
350  // If model is valid, set the appropriate parameters
351  if (valid) setWeather();
352  }
353 
354 
355  void NeillTropModel::setReceiverLatitude(const double& lat)
356  {
357  NeillLat = lat;
358  validLat = true;
359 
360  // Change the value of field "valid" if everything is already set
362 
363  // If model is valid, set the appropriate parameters
364  if (valid) setWeather();
365  }
366 
367 
368  void NeillTropModel::setDayOfYear(const int& doy)
369  {
370  if( (doy>=1) && (doy<=366) )
371  {
372  validDOY = true;
373  }
374  else
375  {
376  validDOY = false;
377  }
378 
379  NeillDOY = doy;
380 
381  // Change the value of field "valid" if everything is already set
383 
384  // If model is valid, set the appropriate parameters
385  if (valid) setWeather();
386  }
387 
388 
390  {
391 
392  NeillDOY = static_cast<int>((static_cast<YDSTime>(time)).doy);
393  validDOY = true;
394 
395  // Change the value of field "valid" if everything is already set
397 
398  // If model is valid, set the appropriate parameters
399  if (valid) setWeather();
400  }
401 
402 
404  const Position& rxPos )
405  {
406  YDSTime ydst = static_cast<YDSTime>(time);
407  NeillDOY = static_cast<int>(ydst.doy);
408  validDOY = true;
409  NeillLat = rxPos.getGeodeticLatitude();
410  validLat = true;
411  NeillHeight = rxPos.getHeight();
412  validHeight = true;
413 
414  // Change the value of field "valid" if everything is already set
416 
417  // If model is valid, set the appropriate parameters
418  if (valid) setWeather();
419  }
420 
421 }
gnsstk::NeillDryA1
static const double NeillDryA1[5]
Definition: NeillTropModel.cpp:86
gnsstk::NeillWetA
static const double NeillWetA[5]
Definition: NeillTropModel.cpp:65
YDSTime.hpp
se
double se
obliquity cos, T*cos, sin coefficients
Definition: IERS2003NutationData.hpp:48
gnsstk::NeillDryC1
static const double NeillDryC1[5]
Definition: NeillTropModel.cpp:92
gnsstk::NeillTropModel::wet_zenith_delay
virtual double wet_zenith_delay() const
Definition: NeillTropModel.hpp:234
gnsstk::NeillTropModel::setReceiverLatitude
virtual void setReceiverLatitude(const double &lat)
Definition: NeillTropModel.cpp:355
gnsstk::NeillTropModel::validLat
bool validLat
Definition: NeillTropModel.hpp:306
gnsstk::YDSTime
Definition: YDSTime.hpp:58
gnsstk::NeillTropModel::validHeight
bool validHeight
Definition: NeillTropModel.hpp:305
gnsstk::NeillTropModel::dry_zenith_delay
virtual double dry_zenith_delay() const
Definition: NeillTropModel.cpp:203
gnsstk::NeillTropModel::validDOY
bool validDOY
Definition: NeillTropModel.hpp:307
gnsstk::NeillTropModel::setWeather
void setWeather()
Definition: NeillTropModel.cpp:319
gnsstk::NeillTropModel::dry_mapping_function
virtual double dry_mapping_function(double elevation) const
Definition: NeillTropModel.cpp:219
gnsstk::Position::getAltitude
double getAltitude() const noexcept
return height above ellipsoid (meters)
Definition: Position.hpp:469
THROW_IF_INVALID_DETAILED
#define THROW_IF_INVALID_DETAILED()
Definition: NeillTropModel.cpp:43
gnsstk::NeillTropModel::NeillHeight
double NeillHeight
Definition: NeillTropModel.hpp:302
THROW_IF_INVALID
#define THROW_IF_INVALID()
Definition: TropModel.hpp:57
gnsstk::NeillTropModel::NeillTropModel
NeillTropModel()
Default constructor.
Definition: NeillTropModel.hpp:90
gnsstk
For Sinex::InputHistory.
Definition: BasicFramework.cpp:50
gnsstk::NeillDryC
static const double NeillDryC[5]
Definition: NeillTropModel.cpp:82
std::sin
double sin(gnsstk::Angle x)
Definition: Angle.hpp:144
gnsstk::Position::getHeight
double getHeight() const noexcept
return height above ellipsoid (meters)
Definition: Position.hpp:474
gnsstk::YDSTime::doy
int doy
Definition: YDSTime.hpp:185
gnsstk::NeillTropModel::setDayOfYear
virtual void setDayOfYear(const int &doy)
Definition: NeillTropModel.cpp:368
gnsstk::NeillWetC
static const double NeillWetC[5]
Definition: NeillTropModel.cpp:71
example4.time
time
Definition: example4.py:103
gnsstk::NeillDryA
static const double NeillDryA[5]
Definition: NeillTropModel.cpp:76
gnsstk::NeillDryB1
static const double NeillDryB1[5]
Definition: NeillTropModel.cpp:89
gnsstk::Position::getGeodeticLatitude
double getGeodeticLatitude() const noexcept
return geodetic latitude (deg N)
Definition: Position.hpp:454
gnsstk::CommonTime
Definition: CommonTime.hpp:84
gnsstk::Xvt
Definition: Xvt.hpp:60
gnsstk::TropModel::valid
bool valid
true only if current model parameters are valid
Definition: TropModel.hpp:279
gnsstk::NeillTropModel::wet_mapping_function
virtual double wet_mapping_function(double elevation) const
Definition: NeillTropModel.cpp:279
std::cos
double cos(gnsstk::Angle x)
Definition: Angle.hpp:146
gnsstk::NeillWetB
static const double NeillWetB[5]
Definition: NeillTropModel.cpp:68
GNSSTK_RETHROW
#define GNSSTK_RETHROW(exc)
Definition: Exception.hpp:369
gnsstk::NeillTropModel::correction
virtual double correction(double elevation) const
Definition: NeillTropModel.cpp:97
gnsstk::NeillTropModel::setAllParameters
virtual void setAllParameters(const CommonTime &time, const Position &rxPos)
Definition: NeillTropModel.cpp:403
gnsstk::NeillDryB
static const double NeillDryB[5]
Definition: NeillTropModel.cpp:79
NeillTropModel.hpp
gnsstk::NeillTropModel::setReceiverHeight
virtual void setReceiverHeight(const double &ht)
Definition: NeillTropModel.cpp:342
gnsstk::NeillTropModel::NeillDOY
int NeillDOY
Definition: NeillTropModel.hpp:304
gnsstk::Position
Definition: Position.hpp:136
GNSSTK_THROW
#define GNSSTK_THROW(exc)
Definition: Exception.hpp:366
gnsstk::NeillTropModel::NeillLat
double NeillLat
Definition: NeillTropModel.hpp:303
gnsstk::Position::elevationGeodetic
double elevationGeodetic(const Position &Target) const
Definition: Position.cpp:1331
gnsstk::DEG_TO_RAD
static const double DEG_TO_RAD
Conversion Factor from degrees to radians (units: degrees^-1)
Definition: GNSSconstants.hpp:76


gnsstk
Author(s):
autogenerated on Wed Oct 25 2023 02:40:40