1 //==============================================================================
2 //
3 //  This file is part of GPSTk, the GPS Toolkit.
4 //
5 //  The GPSTk 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 GPSTk 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 GPSTk; 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-2020, 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 #ifndef SAAS_TROP_MODEL_HPP
41 #define SAAS_TROP_MODEL_HPP
42 
43 #include "TropModel.hpp"
44 
45 namespace gpstk
46 {
47       /** Saastamoinen tropospheric model based on Saastamoinen, J.,
48        * 'Atmospheric Correction for the Troposphere and Stratosphere
49        * in Radio Ranging of Satellites,' Geophysical Monograph 15,
50        * American Geophysical Union, 1972, and Ch 9 of McCarthy, D and
51        * Petit, G, IERS Conventions (2003), IERS Technical Note 32,
52        * IERS, 2004. The mapping functions are from Neill, A.E., 1996,
53        * 'Global Mapping Functions for the Atmosphere Delay of Radio
54        * Wavelengths,' J. Geophys. Res., 101, pp. 3227-3246 (also see
55        * IERS TN 32).
56        *
57        * This model includes a wet and dry component, and requires
58        * input of the geodetic latitude, day of year and height above
59        * the ellipsoid of the receiver.
60        *
61        * Usually, the caller will set the latitude and day of year at the same
62        * time the weather is set
63        *   SaasTropModel stm;
64        *   stm.setReceiverLatitude(lat);
65        *   stm.setDayOfYear(doy);
66        *   stm.setWeather(T,P,H);
67        * Then, when the correction (and/or delay and map) is computed,
68        * receiver height should be set before the call to
69        * correction(elevation):
70        *   stm.setReceiverHeight(height);
71        *   trop_corr = stm.correction(elevation);
72        *
73        * @note in this model, units of 'temp' are degrees Celsius and
74        * humid actually stores water vapor partial pressure in mbars
75        */
76    class SaasTropModel : public TropModel
77    {
78    public:
79          /// Empty constructor
80       SaasTropModel(void);
81 
82          /** Create a trop model using the minimum information:
83           * latitude and doy.
84           * @param lat Latitude of the receiver in degrees.
85           * @param day Day of year.
86           */
87       SaasTropModel(const double& lat,
88                     const int& day);
89 
90          /** Create a trop model with weather.
91           * @param lat Latitude of the receiver in degrees.
92           * @param day Day of year.
93           * @param wx the weather to use for this correction.
94           * @throw InvalidParameter
95           */
96       SaasTropModel(const double& lat,
97                     const int& day,
98                     const WxObservation& wx);
99 
100          /** Create a tropospheric model from explicit weather data
101           * @param lat Latitude of the receiver in degrees.
102           * @param day Day of year.
103           * @param T temperature in degrees Celsius
104           * @param P atmospheric pressure in millibars
105           * @param H relative humidity in percent
106           * @throw InvalidParameter
107           */
108       SaasTropModel(const double& lat,
109                     const int& day,
110                     const double& T,
111                     const double& P,
112                     const double& H);
113 
114          /// Return the name of the model
name(void)115       virtual std::string name(void)
116       { return std::string("Saas"); }
117 
118          /** Compute and return the full tropospheric delay
119           * @param elevation Elevation of satellite as seen at
120           *   receiver, in degrees
121           * @throw InvalidTropModel
122           */
123       virtual double correction(double elevation) const;
124 
125          /**
126           * Compute and return the full tropospheric delay, given the
127           * positions of receiver and satellite and the time tag. This
128           * version is most useful within positioning algorithms,
129           * where the receiver position and timetag may vary; it
130           * computes the elevation (and other receiver location
131           * information) and passes them to appropriate set...()
132           * routines and the correction(elevation) routine.
133           * @param RX  Receiver position
134           * @param SV  Satellite position
135           * @param tt  Time tag of the signal
136           * @throw InvalidTropModel
137           */
138       virtual double correction(const Position& RX,
139                                 const Position& SV,
140                                 const CommonTime& tt);
141 
142          /** \deprecated
143           * Compute and return the full tropospheric delay, given the
144           * positions of receiver and satellite and the time tag. This
145           * version is most useful within positioning algorithms,
146           * where the receiver position and timetag may vary; it
147           * computes the elevation (and other receiver location
148           * information) and passes them to appropriate set...()
149           * routines and the correction(elevation) routine.
150           * @param RX  Receiver position in ECEF cartesian coordinates (meters)
151           * @param SV  Satellite position in ECEF cartesian coordinates (meters)
152           * @param tt  Time tag of the signal
153           * @throw InvalidTropModel
154           */
155       virtual double correction(const Xvt& RX,
156                                 const Xvt& SV,
157                                 const CommonTime& tt);
158 
159          /** Compute and return the zenith delay for dry component
160           * of the troposphere
161           * @throw InvalidTropModel
162           */
163       virtual double dry_zenith_delay(void) const;
164 
165          /** Compute and return the zenith delay for wet component
166           * of the troposphere
167           * @throw InvalidTropModel
168           */
169       virtual double wet_zenith_delay(void) const;
170 
171          /** Compute and return the mapping function for dry component of
172           * the troposphere.
173           * @note this function will return infinity at zero elevation.
174           * @param elevation Elevation of satellite as seen at
175           *   receiver, in degrees
176           * @throw InvalidTropModel
177           */
178       virtual double dry_mapping_function(double elevation) const;
179 
180          /** Compute and return the mapping function for wet component of
181           * the troposphere.
182           * @param elevation Elevation of satellite as seen at
183           *   receiver, in degrees
184           * @throw InvalidTropModel
185           */
186       virtual double wet_mapping_function(double elevation) const;
187 
188          /** Re-define the tropospheric model with explicit weather data.
189           * Typically called just before correction().
190           * @param wx the weather to use for this correction
191           * @throw InvalidParameter
192           */
193       virtual void setWeather(const WxObservation& wx);
194 
195          /** Define the weather data; typically called just before correction().
196           * @param T temperature in degrees Celsius
197           * @param P atmospheric pressure in millibars
198           * @param H relative humidity in percent
199           * @throw InvalidParameter
200           */
201       virtual void setWeather(const double& T,
202                               const double& P,
203                               const double& H);
204 
205          /** Define the receiver height; this required before calling
206           * correction() or any of the zenith_delay or
207           * mapping_function routines.
208           * @param ht Height of the receiver in meters.
209           */
210       void setReceiverHeight(const double& ht);
211 
212          /** Define the latitude of the receiver; this is required
213           * before calling correction() or any of the zenith_delay or
214           * mapping_function routines.
215           * @param lat Latitude of the receiver in degrees.
216           */
217       void setReceiverLatitude(const double& lat);
218 
219          /** Define the day of year; this is required before calling
220           * correction() or any of the zenith_delay or
221           * mapping_function routines.
222           * @param d Day of year.
223           */
224       void setDayOfYear(const int& d);
225 
226    private:
227       double height;             ///< height (m) of the receiver above the geoid
228       double latitude;           ///< latitude (deg) of receiver
229       int doy;                   ///< day of year
230       bool validWeather;
231       bool validRxLatitude;
232       bool validRxHeight;
233       bool validDOY;
234    };
235 
236 }
237 #endif
238