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 IonexHeader.hpp
41  * This class encapsulates the header of Ionex file, including I/O
42  */
43 
44 #ifndef GPSTK_IONEXHEADER_HPP
45 #define GPSTK_IONEXHEADER_HPP
46 
47 #include <string>
48 #include <vector>
49 #include <map>
50 
51 #include "CommonTime.hpp"
52 #include "SatID.hpp"
53 #include "IonexBase.hpp"
54 
55 namespace gpstk
56 {
57 
58 
59       /// @ingroup IonosphereMaps
60       //@{
61 
62 
63       /**
64        * This class models the header for a IONEX file
65        *
66        * @sa gpstk::IonexData and IonexStream
67        * @sa main_ionex_test.cpp for an example
68        */
69    class IonexHeader : public IonexBase
70    {
71    public:
72 
73          /// Default constructor
IonexHeader()74       IonexHeader() : version(1.0), exponent(-1), valid(false) {}
75 
76 
77          /// Clear (empty out) header
78       void clear(void);
79 
80 
81          /**
82           * @name IonexHeaderFormatStrings
83           * IONEX Header Formatting Strings
84           */
85          //@{
86       static const std::string versionString;            ///< "IONEXVERSION / TYPE"
87       static const std::string runByString;              ///< "PGM / RUN BY / DATE"
88       static const std::string descriptionString;        ///< "DESCRIPTION"
89       static const std::string commentString;            ///< "COMMENT"
90       static const std::string firstTimeString;          ///< "EPOCH OF FIRST MAP"
91       static const std::string lastTimeString;           ///< "EPOCH OF LAST MAP"
92       static const std::string intervalString;           ///< "INTERVAL"
93       static const std::string numMapsString;            ///< "# OF MAPS IN FILE"
94       static const std::string mappingFunctionString;    ///< "MAPPING FUNCTION"
95       static const std::string elevationString;          ///< "ELEVATION CUTOFF"
96       static const std::string observablesUsedString;    ///< "OBSERVABLES USED"
97       static const std::string numStationsString;        ///< "# OF STATIONS"
98       static const std::string numSatsString;            ///< "# OF SATELLITES"
99       static const std::string baseRadiusString;         ///< "BASE RADIUS"
100       static const std::string mapDimensionString;       ///< "MAP DIMENSION"
101       static const std::string hgtGridString;            ///< "HGT1 / HGT2 / DHGT"
102       static const std::string latGridString;            ///< "LAT1 / LAT2 / DLAT"
103       static const std::string lonGridString;            ///< "LON1 / LON2 / DLON"
104       static const std::string exponentString;           ///< "EXPONENT"
105       static const std::string startAuxDataString;       ///< "START OF AUX DATA"
106       static const std::string endAuxDataString;         ///< "END OF AUX DATA"
107       static const std::string endOfHeader;              ///< "END OF HEADER"
108          //@}
109 
110          // Differential Code Bias structure
111       struct DCB
112       {
113 
114          char system;   ///< one char indicating the system for this satellite
115                         ///< (i.e., 'U' for unknown, 'G' or blank for GPS and
116                         ///< 'R' for GLONASS)
117          int prn;       ///< 2-digit satellite identifier (pseudo random number)
118          double bias;   ///< differential (L1-L2) code bias in nanoseconds
119          double rms;    ///< RMS error of DCB in nanoseconds
120 
121 
122             /// Default constructor. Defines and invalid structure.
DCBgpstk::IonexHeader::DCB123          DCB() : system('U'), prn(-1), bias(0), rms(0.0) {};
124 
125 
126             /** Common constructor
127              *
128              * @param s    System type. ('U' for unknown, 'G' or blank for
129              *             GPS, and 'R' for GLONASS).
130              * @param p    Satellite PRN (2-digit integer).
131              * @param b    Differential (L1-L2) code bias.
132              * @param r    RMS error of DCB, in nanoseconds.
133              */
DCBgpstk::IonexHeader::DCB134          DCB(char s, int p, double b, double r)
135             : system(s), prn(p), bias(b), rms(r)
136          {};
137 
138 
139             /**
140              * @name DCBformatStrings
141              * Differential Code Bias Formatting Strings
142              */
143             //@{
144          static const std::string svsAuxDataString;   ///< "PRN / BIAS / RMS"
145          static const std::string stationsAuxDataString;///< "STATION/BIAS/RMS";
146             //@}
147 
148             /// convert DCB structure to a string
toStringgpstk::IonexHeader::DCB149          std::string toString() const throw()
150          {
151             std::string line(3, ' ');
152             line += std::string(3, '0');
153 
154                // update with the system char
155             line[3] = system;
156 
157                // convert the prn into 2-digit string
158             std::string s = StringUtils::asString(prn);
159             if (prn < 10)
160             {
161                line[5] = s[0];
162             }
163             else
164             {
165                line[4] = s[0];
166                line[5] = s[1];
167             }
168 
169                // append bias and rms
170             line += StringUtils::rightJustify(
171                                  StringUtils::asString(bias,3), 10 );
172             line += StringUtils::rightJustify(
173                                  StringUtils::asString(rms, 3), 10 );
174 
175             return line;
176 
177          }  // End of method 'DCB::toString()'
178 
179       }; // End of 'DCB' data structure
180 
181 
182          /**
183           * @name IonexHeaderValues
184           */
185          //@{
186       double version;            ///< IONEX version
187 
188       std::string fileType;      ///< IONEX filetype ('I' for Ionoshere Maps)
189       std::string system;        ///< Satellite system or theoretical model
190       std::string fileProgram;   ///< Name of program creating this file
191       std::string fileAgency;    ///< Name of agency creating this file
192       std::string date;          ///< Date and time of file creation
193 
194       std::vector<std::string> descriptionList;///< Descriptions in header (opt)
195       std::vector<std::string> commentList;    ///< Comments in header(optional)
196 
197       CommonTime firstEpoch;           ///< Epoch of first map
198       CommonTime lastEpoch;            ///< Epoch of last map
199 
200       int interval;                 ///< Time interval between maps (seconds)
201       size_t numMaps;               ///< Total number of TEC/RMS/HGT maps
202       std::string mappingFunction;  ///< Mapping function adopted
203       double elevation;             ///< Minimum elevation angle, in degrees
204       std::string observablesUsed;  ///< One-line specification of used obs.
205 
206       size_t numStations;       ///< Number of contributing stations (optional)
207       size_t numSVs;            ///< Number of contributing satellites (opt)
208 
209       double baseRadius;  ///< Mean earth radius, or bottom of height grid (km)
210       size_t mapDims;     ///< Dimension of maps (2 or 3)
211 
212       double hgt[3];    ///< Definition of an equidistand grid in height
213                         /// 'hgt[0]' to 'hgt[1]' with increment 'hgt[2]' in km
214                         /// For 2-dimensional maps hgt[0]=hgt[1] and hgt[2]=0.
215       double lat[3];    ///< Definition of the grid in latitude
216                         /// 'lat[0]' to 'lat[1]' with increment 'hgt[2]' in deg
217       double lon[3];    ///< Definition of the grid in longitude
218                         /// 'lon[0]' to 'lon[1]' with increment 'hon[2]' in deg
219 
220       int exponent;    ///< Exponent defining the unit of the values (optional)
221       std::string auxData;          ///< Type of auxiliar data (optional)
222 
223          /// The key to this map is the svid of the satellite (usually the prn)
224       typedef std::map<SatID,DCB> SatDCBMap;
225 
226       SatDCBMap svsmap;    ///< Map of satellites' DCBs (in nanoseconds)
227       bool auxDataFlag;    ///< Flag to monitor the sequence of auxiliar data
228 
229          /// return code, Am I valid?
230       bool valid;
231          //@}
232 
233          /// Destructor
~IonexHeader()234       virtual ~IonexHeader() {};
235 
236 
237          // IonexHeader is a "header" so this function always returns true.
isHeader() const238       virtual bool isHeader() const
239       { return true; };
240 
241 
242          /** Simple debug output function.
243           *
244           * It simply outputs the version, name and number of maps contained
245           * in this Ionex header.
246           */
247       virtual void dump(std::ostream& s = std::cout) const;
248 
249 
250          /**
251           * Parse a single auxiliary header record that contains "Differential
252           * code biases".
253           * @throw FFStreamError
254           */
255       void ParseDcbRecord(std::string &line);
256 
257 
258          /** Parse a single header record, and modify 'valid' accordingly.
259           *
260           * Used by reallyGetRecord for both IonexHeader and IonexData.
261           * @throw FFStreamError
262           */
263       void ParseHeaderRecord(std::string& line);
264 
265 
266          /**
267           * Write all valid header records to the given stream.
268           * Used by reallyPutRecord for both IonexHeader and IonexData.
269           * @throw FFStreamError
270           * @throw StringUtils::StringException
271           */
272       void WriteHeaderRecords(FFStream& s) const;
273 
274 
275 
276    protected:
277 
278 
279          /** Writes the record formatted to the FFStream \a s.
280           *
281           * @throw std::exception
282           * @throw FFStreamError
283           * @throw StringException when a StringUtils function fails
284           */
285       virtual void reallyPutRecord(FFStream& s) const;
286 
287 
288          /** This function retrieves the IONEX header from the given FFStream.
289           *
290           * If an stream error is encountered, the stream is reset to its
291           * original position and its fail-bit is set.
292           *
293           * @throw std::exception
294           * @throw StringException when a StringUtilis function fails
295           * @throw FFStreamError when exceptions (failbit) is set and
296           *  a read or formatting error occurs. This also resets the stream
297           *  to its pre-read position.
298           */
299       virtual void reallyGetRecord(FFStream& s);
300 
301 
302          // Not sure how it helps (seen in SP3Header and RinexObsHeader)
303       friend class IonexData;
304 
305 
306 
307    private:
308          /** Converts the CommonTime \a dt into a Ionex Obs time
309           * string for the header
310           */
311       std::string writeTime(const CommonTime& dt) const;
312 
313 
314          /** This function sets the time for this header.
315           *
316           * It looks at \a line to obtain the needed information.
317           */
318       CommonTime parseTime(const std::string& line) const;
319 
320 
321 
322    }; // End of class 'IonexHeader'
323 
324 
325       //@}
326 
327 
328 }  // End of namespace gpstk
329 #endif   // GPSTK_IONEXHEADER_HPP
330