MOPSTropModel.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 "MOPSTropModel.hpp"
42 
43 #define THROW_IF_INVALID_DETAILED() {if (!valid) { \
44  InvalidTropModel e; \
45  if(!validLat) e.addText("Invalid trop model: validLat"); \
46  if(!validHeight) e.addText("Invalid trop model: validHeight"); \
47  if(!validTime) e.addText("Invalid trop model: day of year"); \
48  GNSSTK_THROW(e);}}
49 
50 namespace gnsstk
51 {
52  // Some specific constants
53  static const double MOPSg=9.80665;
54  static const double MOPSgm=9.784;
55  static const double MOPSk1=77.604;
56  static const double MOPSk2=382000.0;
57  static const double MOPSRd=287.054;
58 
59 
61  {
62  validHeight = false;
63  validLat = false;
64  validTime = false;
65  valid = false;
66  }
67 
68 
69  MOPSTropModel::MOPSTropModel( const double& ht,
70  const double& lat,
71  const int& doy )
72  {
75  setDayOfYear(doy);
76  }
77 
78 
80  {
84  }
85 
86 
87  double MOPSTropModel::correction(double elevation) const
88  {
90 
91  if(elevation < 5.0) return 0.0;
92 
93  double map = MOPSTropModel::mapping_function(elevation);
94 
95  // Compute tropospheric delay
96  double tropDelay = ( MOPSTropModel::dry_zenith_delay() +
98 
99  return tropDelay;
100 
101  }
102 
103 
105  const Position& SV )
106  {
107  try
108  {
111  setWeather();
112  }
113  catch(GeometryException& e)
114  {
115  valid = false;
116  }
117 
118  if(!valid) throw InvalidTropModel("Invalid model");
119 
120  double c;
121  try
122  {
124  }
125  catch(InvalidTropModel& e)
126  {
127  GNSSTK_RETHROW(e);
128  }
129 
130  return c;
131 
132  }
133 
134 
136  const Position& SV,
137  const CommonTime& tt )
138  {
139  setDayOfYear(tt);
140 
141  return MOPSTropModel::correction(RX,SV);
142  }
143 
144 
146  const Position& SV,
147  const int& doy )
148  {
149  setDayOfYear(doy);
150 
151  return MOPSTropModel::correction(RX,SV);
152  }
153 
154 
155  double MOPSTropModel::correction( const Xvt& RX,
156  const Xvt& SV )
157  {
158  Position R(RX),S(SV);
159 
160  return MOPSTropModel::correction(R,S);
161  }
162 
163 
164  double MOPSTropModel::correction( const Xvt& RX,
165  const Xvt& SV,
166  const CommonTime& tt )
167  {
168  setDayOfYear(tt);
169  Position R(RX),S(SV);
170 
171  return MOPSTropModel::correction(R,S);
172  }
173 
174 
175  double MOPSTropModel::correction( const Xvt& RX,
176  const Xvt& SV,
177  const int& doy )
178  {
179  setDayOfYear(doy);
180  Position R(RX),S(SV);
181 
182  return MOPSTropModel::correction(R,S);
183  }
184 
185 
187  {
189 
190  double ddry, zh_dry, exponent;
191 
192  // Set the extra parameters
193  double P = MOPSParameters(0);
194  double T = MOPSParameters(1);
195  double beta = MOPSParameters(3);
196 
197  // Zero-altitude dry zenith delay:
198  zh_dry = 0.000001*(MOPSk1*MOPSRd)*P/MOPSgm;
199 
200  /* Zenith delay terms at MOPSHeight meters of height above mean sea
201  * level
202  */
203  exponent = MOPSg/MOPSRd/beta;
204  ddry = zh_dry * std::pow( (1.0 - beta*MOPSHeight/T), exponent );
205 
206  return ddry;
207 
208  }
209 
210 
212  {
214 
215  double dwet, zh_wet, exponent;
216 
217  // Set the extra parameters
218  double T = MOPSParameters(1);
219  double e = MOPSParameters(2);
220  double beta = MOPSParameters(3);
221  double lambda = MOPSParameters(4);
222 
223  // Zero-altitude wet zenith delay:
224  zh_wet = (0.000001*MOPSk2)*MOPSRd/(MOPSgm*(lambda+1.0)-beta*MOPSRd)*e/T;
225 
226  /* Zenith delay terms at MOPSHeight meters of height above mean sea
227  * level
228  */
229  exponent = ( (lambda+1.0)*MOPSg/MOPSRd/beta)-1.0;
230  dwet= zh_wet * std::pow( (1.0 - beta*MOPSHeight/T), exponent );
231 
232  return dwet;
233 
234  } // end MOPSTropModel::wet_zenith_delay()
235 
236 
238  {
239  if(!validLat)
240  {
241  valid = false;
242  InvalidTropModel e(
243  "MOPSTropModel must have Rx latitude before computing weather");
244  GNSSTK_THROW(e);
245  }
246 
247  if(!validTime)
248  {
249  valid = false;
250  InvalidTropModel e(
251  "MOPSTropModel must have day of year before computing weather");
252  GNSSTK_THROW(e);
253  }
254 
255  /* In order to compute tropospheric delay we need to compute some
256  * extra parameters
257  */
258  try
259  {
261  }
262  catch(InvalidTropModel& e)
263  {
264  GNSSTK_RETHROW(e);
265  }
266 
268  }
269 
270 
271  void MOPSTropModel::setReceiverHeight(const double& ht)
272  {
273  MOPSHeight = ht;
274  validHeight = true;
275 
276  // Change the value of field "valid" if everything is already set
278 
279  // If model is valid, set the appropriate parameters
280  if (valid) setWeather();
281  }
282 
283 
284  void MOPSTropModel::setReceiverLatitude(const double& lat)
285  {
286  MOPSLat = lat;
287  validLat = true;
288 
289  // Change the value of field "valid" if everything is already set
291 
292  // If model is valid, set the appropriate parameters
293  if (valid) setWeather();
294  }
295 
296 
297  void MOPSTropModel::setDayOfYear(const int& doy)
298  {
299 
300  if ( (doy>=1) && (doy<=366))
301  {
302  validTime = true;
303  }
304  else
305  {
306  validTime = false;
307  }
308 
309  MOPSTime = doy;
310 
311  // Change the value of field "valid" if everything is already set
313 
314  // If model is valid, set the appropriate parameters
315  if (valid) setWeather();
316  }
317 
318 
320  {
321  MOPSTime = (int)(static_cast<YDSTime>(time)).doy;
322  validTime = true;
323 
324  // Change the value of field "valid" if everything is already set
326 
327  // If model is valid, set the appropriate parameters
328  if (valid) setWeather();
329  }
330 
331 
333  const Position& rxPos )
334  {
335  MOPSTime = (int)(static_cast<YDSTime>(time)).doy;
336  validTime = true;
337  MOPSLat = rxPos.getGeodeticLatitude();
338  validLat = true;
339  MOPSHeight = rxPos.getHeight();
340  validHeight = true;
341 
342  // Change the value of field "valid" if everything is already set
344 
345  // If model is valid, set the appropriate parameters
346  if (valid) setWeather();
347  }
348 
349 
350  double MOPSTropModel::MOPSsigma2(double elevation)
351  {
352  double map_f;
353 
354  /* If elevation is below bounds, fail in a sensible way returning a
355  * very big sigma value
356  */
357  if(elevation < 5.0)
358  {
359  return 9.9e9;
360  }
361  else
362  {
363  map_f = MOPSTropModel::mapping_function(elevation);
364  }
365 
366  // Compute residual error for tropospheric delay
367  double MOPSsigma2trop = (0.12*map_f)*(0.12*map_f);
368 
369  return MOPSsigma2trop;
370  }
371 
372 
374  {
376 
377  try
378  {
379  // We need to read some data
380  prepareTables();
381 
382  // Declare some variables
383  int idmin, j, index;
384  double fact, axfi;
385  Vector<double> avr0(5);
386  Vector<double> svr0(5);
387 
388  // Resize MOPSParameters as appropriate
390 
391  if (MOPSLat >= 0.0)
392  {
393  idmin = 28;
394  }
395  else
396  {
397  idmin = 211;
398  }
399 
400  // Fraction of the year in radians
401  fact = 2.0*PI*((double)(MOPSTime-idmin))/365.25;
402 
403  axfi = ABS(MOPSLat);
404 
405  if ( axfi <= 15.0 ) index=0;
406  if ( (axfi > 15.0) && (axfi <= 30.0) ) index=1;
407  if ( (axfi > 30.0) && (axfi <= 45.0) ) index=2;
408  if ( (axfi > 45.0) && (axfi <= 60.0) ) index=3;
409  if ( (axfi > 60.0) && (axfi < 75.0) ) index=4;
410  if ( axfi >= 75.0 ) index=5;
411 
412  for (j=0; j<5; j++)
413  {
414  if (index == 0) {
415  avr0(j)=avr(index,j);
416  svr0(j)=svr(index,j);
417  }
418  else
419  {
420  if (index < 5)
421  {
422  avr0(j) = avr(index-1,j) + (avr(index,j)-avr(index-1,j)) *
423  (axfi-fi0(index-1))/(fi0( index)-fi0(index-1));
424 
425  svr0(j) = svr(index-1,j) + (svr(index,j)-svr(index-1,j)) *
426  (axfi-fi0(index-1))/(fi0( index)-fi0(index-1));
427  }
428  else
429  {
430  avr0(j) = avr(index-1,j);
431  svr0(j) = svr(index-1,j);
432  }
433  }
434 
435  MOPSParameters(j) = avr0(j)-svr0(j)*std::cos(fact);
436  }
437 
438  } // end try
439  catch (...)
440  {
441  InvalidTropModel e("Problem computing extra MOPS parameters.");
442  GNSSTK_RETHROW(e);
443  }
444  }
445 
446 
448  {
449  avr.resize(5,5);
450  svr.resize(5,5);
451  fi0.resize(5);
452 
453 
454  // Table avr (Average):
455 
456  avr(0,0) = 1013.25; avr(0,1) = 299.65; avr(0,2) = 26.31;
457  avr(0,3) = 0.0063; avr(0,4) = 2.77;
458 
459  avr(1,0) = 1017.25; avr(1,1) = 294.15; avr(1,2) = 21.79;
460  avr(1,3) = 0.00605; avr(1,4) = 3.15;
461 
462  avr(2,0) = 1015.75; avr(2,1) = 283.15; avr(2,2) = 11.66;
463  avr(2,3) = 0.00558; avr(2,4) = 2.57;
464 
465  avr(3,0) = 1011.75; avr(3,1) = 272.15; avr(3,2) = 6.78;
466  avr(3,3) = 0.00539; avr(3,4) = 1.81;
467 
468  avr(4,0) = 1013.00; avr(4,1) = 263.65; avr(4,2) = 4.11;
469  avr(4,3) = 0.00453; avr(4,4) = 1.55;
470 
471 
472  // Table svr (Seasonal Variation):
473 
474  svr(0,0) = 0.00; svr(0,1) = 0.00; svr(0,2) = 0.00;
475  svr(0,3) = 0.00000; svr(0,4) = 0.00;
476 
477  svr(1,0) = -3.75; svr(1,1) = 7.00; svr(1,2) = 8.85;
478  svr(1,3) = 0.00025; svr(1,4) = 0.33;
479 
480  svr(2,0) = -2.25; svr(2,1) = 11.00; svr(2,2) = 7.24;
481  svr(2,3) = 0.00032; svr(2,4) = 0.46;
482 
483  svr(3,0) = -1.75; svr(3,1) = 15.00; svr(3,2) = 5.36;
484  svr(3,3) = 0.00081; svr(3,4) = 0.74;
485 
486  svr(4,0) = -0.50; svr(4,1) = 14.50; svr(4,2) = 3.39;
487  svr(4,3) = 0.00062; svr(4,4) = 0.30;
488 
489 
490  // Table fi0 (Latitude bands):
491 
492  fi0(0) = 15.0; fi0(1) = 30.0; fi0(2) = 45.0;
493  fi0(3) = 60.0; fi0(4) = 75.0;
494  }
495 }
gnsstk::MOPSTropModel::MOPSParameters
Vector< double > MOPSParameters
Definition: MOPSTropModel.hpp:298
YDSTime.hpp
gnsstk::MOPSTropModel::validHeight
bool validHeight
Definition: MOPSTropModel.hpp:292
gnsstk::Matrix::resize
Matrix & resize(size_t rows, size_t cols)
Definition: MatrixImplementation.hpp:135
gnsstk::MOPSTropModel::correction
virtual double correction(double elevation) const
Definition: MOPSTropModel.cpp:87
gnsstk::MOPSTropModel::MOPSsigma2
double MOPSsigma2(double elevation)
Definition: MOPSTropModel.cpp:350
THROW_IF_INVALID_DETAILED
#define THROW_IF_INVALID_DETAILED()
Definition: MOPSTropModel.cpp:43
gnsstk::YDSTime
Definition: YDSTime.hpp:58
gnsstk::MOPSTropModel::svr
Matrix< double > svr
Definition: MOPSTropModel.hpp:296
gnsstk::MOPSRd
static const double MOPSRd
Definition: MOPSTropModel.cpp:57
gnsstk::GCATTropModel::mapping_function
virtual double mapping_function(double elevation) const
Definition: GCATTropModel.cpp:113
gnsstk::MOPSk2
static const double MOPSk2
Definition: MOPSTropModel.cpp:56
gnsstk::MOPSTropModel::MOPSTime
int MOPSTime
Definition: MOPSTropModel.hpp:291
gnsstk::Position::getAltitude
double getAltitude() const noexcept
return height above ellipsoid (meters)
Definition: Position.hpp:469
gnsstk::MOPSTropModel::setDayOfYear
virtual void setDayOfYear(const int &doy)
Definition: MOPSTropModel.cpp:297
THROW_IF_INVALID
#define THROW_IF_INVALID()
Definition: TropModel.hpp:57
gnsstk::PI
const double PI
GPS value of PI; also specified by GAL.
Definition: GNSSconstants.hpp:62
gnsstk::MOPSTropModel::setReceiverHeight
virtual void setReceiverHeight(const double &ht)
Definition: MOPSTropModel.cpp:271
gnsstk
For Sinex::InputHistory.
Definition: BasicFramework.cpp:50
gnsstk::Vector::resize
Vector & resize(const size_t index)
Definition: Vector.hpp:262
gnsstk::Position::getHeight
double getHeight() const noexcept
return height above ellipsoid (meters)
Definition: Position.hpp:474
gnsstk::MOPSk1
static const double MOPSk1
Definition: MOPSTropModel.cpp:55
gnsstk::MOPSTropModel::prepareParameters
virtual void prepareParameters()
Definition: MOPSTropModel.cpp:373
MOPSTropModel.hpp
example4.time
time
Definition: example4.py:103
gnsstk::MOPSTropModel::setReceiverLatitude
virtual void setReceiverLatitude(const double &lat)
Definition: MOPSTropModel.cpp:284
gnsstk::Position::getGeodeticLatitude
double getGeodeticLatitude() const noexcept
return geodetic latitude (deg N)
Definition: Position.hpp:454
gnsstk::MOPSTropModel::dry_zenith_delay
virtual double dry_zenith_delay() const
Definition: MOPSTropModel.cpp:186
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::MOPSTropModel::avr
Matrix< double > avr
Definition: MOPSTropModel.hpp:295
std::cos
double cos(gnsstk::Angle x)
Definition: Angle.hpp:146
gnsstk::beta
double beta(double x, double y)
Definition: SpecialFuncs.cpp:204
gnsstk::MOPSgm
static const double MOPSgm
Definition: MOPSTropModel.cpp:54
GNSSTK_RETHROW
#define GNSSTK_RETHROW(exc)
Definition: Exception.hpp:369
gnsstk::Vector< double >
gnsstk::TrackingCode::P
@ P
Legacy GPS precise code.
ABS
#define ABS(x)
Definition: MathBase.hpp:73
gnsstk::MOPSTropModel::MOPSLat
double MOPSLat
Definition: MOPSTropModel.hpp:290
gnsstk::MOPSTropModel::MOPSTropModel
MOPSTropModel()
Empty constructor.
Definition: MOPSTropModel.cpp:60
gnsstk::MOPSTropModel::fi0
Vector< double > fi0
Definition: MOPSTropModel.hpp:297
gnsstk::MOPSTropModel::setWeather
void setWeather()
Definition: MOPSTropModel.cpp:237
gnsstk::Position
Definition: Position.hpp:136
GNSSTK_THROW
#define GNSSTK_THROW(exc)
Definition: Exception.hpp:366
gnsstk::MOPSTropModel::wet_zenith_delay
virtual double wet_zenith_delay() const
Definition: MOPSTropModel.cpp:211
gnsstk::MOPSg
static const double MOPSg
Definition: MOPSTropModel.cpp:53
gnsstk::Position::elevationGeodetic
double elevationGeodetic(const Position &Target) const
Definition: Position.cpp:1331
gnsstk::MOPSTropModel::prepareTables
virtual void prepareTables()
Definition: MOPSTropModel.cpp:447
gnsstk::MOPSTropModel::MOPSHeight
double MOPSHeight
Definition: MOPSTropModel.hpp:289
gnsstk::MOPSTropModel::validLat
bool validLat
Definition: MOPSTropModel.hpp:293
gnsstk::MOPSTropModel::validTime
bool validTime
Definition: MOPSTropModel.hpp:294
gnsstk::MOPSTropModel::setAllParameters
virtual void setAllParameters(const CommonTime &time, const Position &rxPos)
Definition: MOPSTropModel.cpp:332


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