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