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  * @file IonexStore.hpp
41  * Read and store Ionosphere maps. It computes TEC and RMS values with respect
42  * to time and receiver position. Based on extracted TEC values, it calculates
43  * the ionospheric delay.
44  */
45 
46 #ifndef GPSTK_IONEXSTORE_HPP
47 #define GPSTK_IONEXSTORE_HPP
48 
49 #include <map>
50 
51 #include "FileStore.hpp"
52 #include "IonexData.hpp"
53 
54 #include "GNSSconstants.hpp"                   // DEG_TO_RAD
55 #include "GNSSconstants.hpp"          // LX_FREQ, with X = 1,2,5,6,7,8
56 #include "Triple.hpp"
57 
58 namespace gpstk
59 {
60 
61       /// @ingroup IonosphereMaps
62       //@{
63 
64       /** This class reads and stores Ionosphere maps.
65        *
66        * It computes TEC and RMS values with respect to time and receiver
67        * position. Based on extracted TEC values, it calculates the ionospheric
68        * delay.
69        *
70        * @sa test ionex store.cpp for an example
71        *
72        *
73        * @warning The first IONEX map refers to 00:00 UT, the last map
74        *          to 24:00 UT. The time spacing of the maps (snapshots) is 2
75        *          hours. When two consecutive files are loaded the previuous
76        *          map for 24:00 UT is overwritten by the new 00:00 UT. This
77        *          might affect the interpolation strategy.
78        */
79    class IonexStore : public FileStore<IonexHeader>
80    {
81    public:
82 
83 
84          /// Default constructor.
IonexStore()85       IonexStore()
86          throw()
87          : initialTime(CommonTime::END_OF_TIME),
88            finalTime(CommonTime::BEGINNING_OF_TIME)
89       {};
90 
91 
92          /// destructor
~IonexStore()93       virtual ~IonexStore() {};
94 
95 
96          /** Load the given IONEX file
97           * @throw FileMissingException
98           */
99       virtual void loadFile(const std::string& filename);
100 
101 
102          /// Insert a new IonexData object into the store
103       void addMap(const IonexData& iod)
104          throw();
105 
106 
107          /** Dump the store to the provided std::ostream (std::cout by default).
108           *
109           * @param s       std::ostream object to dump the data to.
110           * @param detail  Determines how much detail to include in the output:
111           *                0 list of filenames with their start and stop times.
112           *                1 list of filenames with their start, stop times,
113           *                  type of data and for how many epochs.
114           */
115       void dump( std::ostream& s = std::cout,
116                  short detail = 0 ) const
117          throw();
118 
119 
120          /// Remove all data
121       void clear() throw();
122 
123 
124          /** Get IONEX TEC, RMS and ionosphere height values as a function of
125           *  epoch and receiver's position.
126           *
127           * Four interpolation strategies are suported  (see also Ionex manual:
128           * http://igscb.jpl.nasa.gov/igscb/data/format/ionex1.pdf )
129           *
130           * A simple 4-point formula is applied to interpolate between the grid
131           * points. See more at IonexData::getValue()
132           *
133           * @param t          Time tag of signal (CommonTime object)
134           * @param RX         Receiver position in ECEF cartesian coordinates
135           *                   (meters).
136           * @param strategy   Interpolation strategy
137           *                   (1) take neareast map,
138           *                   (2) interpolate between two consecutive maps,
139           *                   (3) interpolate between two consecutive rotated
140           *                       maps or,
141           *                   (4) take neareast rotated map.
142           *
143           * @return values    TEC, RMS and ionosphere height values
144           *                   (Triple object with: TEC and RMS in TECU and
145           *                   the ionosphere height in meters)
146           * @throw InvalidRequest
147           */
148       Triple getIonexValue( const CommonTime& t,
149                             const Position& RX,
150                             int strategy = 3 ) const;
151 
152 
153 
154       /** Get slant total electron content (STEC) in TECU
155        *
156        * @param elevation     Time tag of signal (CommonTime object)
157        * @param tecval        TEC value as derived from IONEX file (TECU)
158        * @param ionoMapType   Type of ionosphere mapping function (string)
159        *                      @sa IonexStore::iono_mapping_function
160        *
161        * @return              slant total electron content (TECU)
162        * @throw InvalidParameter
163        */
164    double getSTEC( const double& elevation,
165                    const double& tecval,
166                    const std::string& ionoMapType ) const;
167 
168 
169 
170          /** Get ionospheric slant delay for a given frequency
171           *
172           * @param elevation     Time tag of signal (CommonTime object)
173           * @param tecval        TEC value as derived from IONEX file (TECU)
174           * @param freq          Frequency value, in Hz
175           * @param ionoMapType   Type of ionosphere mapping function (string)
176           *                      @sa IonexStore::iono_mapping_function
177           *
178           * @return              Ionosphere slant delay (meters)
179           * @throw InvalidParameter
180           */
181       double getIono( const double& elevation,
182                       const double& tecval,
183                       const double& freq,
184                       const std::string& ionoMapType ) const;
185 
186 
187          // The next 6 functions define the interface for calculating
188          // the ionospheric slant delay for a specific frequency
189 
190          /** Get ionospheric slant delay for L1 frequency
191           *
192           * @param elevation     Time tag of signal (CommonTime object)
193           * @param tecval        TEC value as derived from IONEX file (TECU)
194           * @param ionoMapType   Type of ionosphere mapping function (string)
195           *                      @sa IonexStore::iono_mapping_function
196           *
197           * @return              Ionosphere slant delay (meters)
198           * @throw InvalidParameter
199           */
getIonoL1(const double & elevation,const double & tecval,const std::string & ionoMapType) const200       double getIonoL1( const double& elevation,
201                         const double& tecval,
202                         const std::string& ionoMapType ) const
203       { return getIono(elevation, tecval, L1_FREQ_GPS, ionoMapType); };
204 
205 
206          /** Get ionospheric slant delay for L2 frequency
207           *
208           * @param elevation     Time tag of signal (CommonTime object)
209           * @param tecval        TEC value as derived from IONEX file (TECU)
210           * @param ionoMapType   Type of ionosphere mapping function (string)
211           *                      @sa IonexStore::iono_mapping_function
212           *
213           * @return              Ionosphere slant delay (meters)
214           * @throw InvalidParameter
215           */
getIonoL2(const double & elevation,const double & tecval,const std::string & ionoMapType) const216       double getIonoL2( const double& elevation,
217                         const double& tecval,
218                         const std::string& ionoMapType ) const
219       { return getIono(elevation, tecval, L2_FREQ_GPS, ionoMapType); };
220 
221 
222          /** Get ionospheric slant delay for L5 frequency
223           *
224           * @param elevation     Time tag of signal (CommonTime object)
225           * @param tecval        TEC value as derived from IONEX file (TECU)
226           * @param ionoMapType   Type of ionosphere mapping function (string)
227           *                      @sa IonexStore::iono_mapping_function
228           *
229           * @return              Ionosphere slant delay (meters)
230           * @throw InvalidParameter
231           */
getIonoL5(const double & elevation,const double & tecval,const std::string & ionoMapType) const232       double getIonoL5( const double& elevation,
233                         const double& tecval,
234                         const std::string& ionoMapType ) const
235       { return getIono(elevation, tecval, L5_FREQ_GPS, ionoMapType); };
236 
237 
238          /** Get ionospheric slant delay for L6 frequency
239           *
240           * @param elevation     Time tag of signal (CommonTime object)
241           * @param tecval        TEC value as derived from IONEX file (TECU)
242           * @param ionoMapType   Type of ionosphere mapping function (string)
243           *                      @sa IonexStore::iono_mapping_function
244           *
245           * @return              Ionosphere slant delay (meters)
246           * @throw InvalidParameter
247           */
getIonoL6(const double & elevation,const double & tecval,const std::string & ionoMapType) const248       double getIonoL6( const double& elevation,
249                         const double& tecval,
250                         const std::string& ionoMapType ) const
251       { return getIono(elevation, tecval, L6_FREQ_GAL, ionoMapType); };
252 
253 
254          /** Get ionospheric slant delay for L7 frequency
255           *
256           * @param elevation     Time tag of signal (CommonTime object)
257           * @param tecval        TEC value as derived from IONEX file (TECU)
258           * @param ionoMapType   Type of ionosphere mapping function (string)
259           *                      @sa IonexStore::iono_mapping_function
260           *
261           * @return              Ionosphere slant delay (meters)
262           * @throw InvalidParameter
263           */
getIonoL7(const double & elevation,const double & tecval,const std::string & ionoMapType) const264       double getIonoL7( const double& elevation,
265                         const double& tecval,
266                         const std::string& ionoMapType ) const
267       { return getIono(elevation, tecval, L7_FREQ_GAL, ionoMapType); };
268 
269 
270          /** Get ionospheric slant delay for L8 frequency
271           *
272           * @param elevation     Time tag of signal (CommonTime object)
273           * @param tecval        TEC value as derived from IONEX file (TECU)
274           * @param ionoMapType   Type of ionosphere mapping function (string)
275           *                      @sa IonexStore::iono_mapping_function
276           *
277           * @return              Ionosphere slant delay (meters)
278           * @throw InvalidParameter
279           */
getIonoL8(const double & elevation,const double & tecval,const std::string & ionoMapType) const280       double getIonoL8( const double& elevation,
281                         const double& tecval,
282                         const std::string& ionoMapType ) const
283       { return getIono(elevation, tecval, L8_FREQ_GAL, ionoMapType); };
284 
285 
286          /** Ionosphere mapping function
287           *
288           * @param elevation     Elevation of satellite as seen at receiver
289           *                      (degrees).
290           * @param ionoMapType   Type of ionosphere mapping function (string)
291           *                      (0) NONE no mapping function is applied
292           *                      (1) SLM  Single Layer Model (IGS)
293           *                      (2) MSLM Modified Single Layer Model (CODE)
294           *                      (3) ESM  Extended Slab Model (JLP)
295           *
296           * Details at: http://aiuws.unibe.ch/ionosphere/mslm.pdf
297           *
298           * @warning No implementation for JPL's mapping function.
299           */
300       double iono_mapping_function( const double& elevation,
301                                     const std::string& ionoMapType ) const;
302 
303 
304          /** Determine the earliest time for which this object can
305           *  successfully determine the TEC values, and implicitly, the
306           *  ionospheric delay for any object.
307           *
308           * @return     Initial time.
309           *
310           * @throw      InvalidRequest This is thrown if the object has no data.
311           */
getInitialTime() const312       CommonTime getInitialTime() const
313       { return initialTime; }
314 
315 
316          /** Determine the latest time for which this object can successfully
317           *  determine the TEC values, and implicitly, the ionospheric delay
318           *  for any object.
319           *
320           * @return     Final time.
321           *
322           * @throw      InvalidRequest This is thrown if the object has no data.
323           */
getFinalTime() const324       CommonTime getFinalTime() const
325       { return finalTime; }
326 
327 
328          /** Find a DCB value
329           *
330           * @param sat     SatID of satellite of interest
331           * @param t       Time to search for DCB
332           *
333           * @return        DCB value found (nanoseconds).
334           *
335           * @throw InvalidRequest object thrown when no DCB value is found
336           */
337       double findDCB( const SatID sat,
338                       const CommonTime& time ) const;
339 
340 
341    private:
342 
343 
344          /** These fields set the overall span of time for which this object
345           *  contains data.
346           *
347           * @warning There may be gaps in the data, i.e. the data may not be
348           *          continuous.
349           */
350       CommonTime initialTime, finalTime;
351 
352 
353          /// The key to this map is IonexValType
354       typedef std::map<IonexData::IonexValType, IonexData> IonexValTypeMap;
355 
356 
357          /// The key to this map is the time
358       typedef std::map<CommonTime, IonexValTypeMap> IonexMap;
359 
360 
361          /// Map of IONEX maps
362       IonexMap inxMaps;
363 
364 
365          /// The key of this map is the time (first epoch as in IonexHeader)
366       typedef std::map<CommonTime, IonexHeader::SatDCBMap> IonexDCBMap;
367 
368 
369          /// Map of DCB values (IonexHeader.firstEpoch, IonexHeader.svsmap)
370       IonexDCBMap inxDCBMap;
371 
372 
373    }; // End of class 'IonexStore'
374 
375       //@}
376 
377 }  // End of namespace gpstk
378 #endif   // GPSTK_IONEXSTORE_HPP
379