Rinex3NavHeader.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 
45 #include "StringUtils.hpp"
46 #include "GNSSconstants.hpp"
47 #include "SystemTime.hpp"
48 #include "CivilTime.hpp"
49 #include "GPSWeekSecond.hpp"
50 #include "GALWeekSecond.hpp"
51 #include "BDSWeekSecond.hpp"
52 #include "TimeString.hpp"
53 #include "Rinex3NavHeader.hpp"
54 #include "Rinex3NavStream.hpp"
55 
56 #include <iostream>
57 #include <set>
58 #include <cmath>
59 
60 using namespace gnsstk::StringUtils;
61 using namespace std;
62 
63 namespace gnsstk
64 {
65  const string Rinex3NavHeader::stringVersion = "RINEX VERSION / TYPE";
66  const string Rinex3NavHeader::stringRunBy = "PGM / RUN BY / DATE";
67  const string Rinex3NavHeader::stringComment = "COMMENT";
68  const string Rinex3NavHeader::stringIonoCorr = "IONOSPHERIC CORR";
69  const string Rinex3NavHeader::stringTimeSysCorr = "TIME SYSTEM CORR";
70  const string Rinex3NavHeader::stringLeapSeconds = "LEAP SECONDS";
71  //R2.10GLO
72  const string Rinex3NavHeader::stringCorrSysTime = "CORR TO SYSTEM TIME";
73  //R2.11GPS
74  const string Rinex3NavHeader::stringDeltaUTC = "DELTA-UTC: A0,A1,T,W";
75  //R2.11GEO
76  const string Rinex3NavHeader::stringDUTC = "D-UTC A0,A1,T,W,S,U";
77  //R2.11
78  const string Rinex3NavHeader::stringIonAlpha = "ION ALPHA";
79  //R2.11
80  const string Rinex3NavHeader::stringIonBeta = "ION BETA";
81  const string Rinex3NavHeader::stringEoH = "END OF HEADER";
82 
83 
86  : type(Unknown),
99  {
100  }
101 
102 
104  IonoCorr(std::string str)
105  : type(Unknown), // just in case someone breaks fromString
106  param{ FormattedDouble(0, StringUtils::FFLead::Decimal, 4, 2, 12,
118  {
119  this->fromString(str);
120  }
121 
122 
123  std::string IonoCorr ::
124  asString() const noexcept
125  {
126  switch(type)
127  {
128  case GAL: return std::string("GAL");
129  case GPSA: return std::string("GPSA");
130  case GPSB: return std::string("GPSB");
131  case Unknown:
132  break;
133  }
134  return std::string("ERROR");
135  }
136 
137 
138  void IonoCorr ::
139  fromString(const std::string str)
140  {
141  std::string STR(gnsstk::StringUtils::upperCase(str));
142  if (STR == std::string("GAL"))
143  type = GAL;
144  else if (STR == std::string("GPSA"))
145  type = GPSA;
146  else if (STR == std::string("GPSB"))
147  type = GPSB;
148  else
149  {
150  Exception e("Unknown IonoCorr type: " + str);
151  GNSSTK_THROW(e);
152  }
153  }
154 
155 
156  bool IonoCorr ::
157  operator==(const IonoCorr& right)
158  const
159  {
160  // Epsilon is chosen based on data format in RINEX which is
161  // %12.4f. Rounding errors can be expected up to .0001
162  return ((type == right.type) &&
163  (fabs(param[0] - right.param[0]) < 0.0001) &&
164  (fabs(param[1] - right.param[1]) < 0.0001) &&
165  (fabs(param[2] - right.param[2]) < 0.0001) &&
166  (fabs(param[3] - right.param[3]) < 0.0001));
167  }
168 
169 
170  bool IonoCorr ::
171  operator<(const IonoCorr& right)
172  const
173  {
174  if (type < right.type) return true;
175  if (type > right.type) return false;
176  if (param[0] < right.param[0]) return true;
177  if (param[0] > right.param[0]) return false;
178  if (param[1] < right.param[1]) return true;
179  if (param[1] > right.param[1]) return false;
180  if (param[2] < right.param[2]) return true;
181  if (param[2] > right.param[2]) return false;
182  if (param[3] < right.param[3]) return true;
183  return false;
184  }
185 
186 
188  {
189  Rinex3NavStream& strm = dynamic_cast<Rinex3NavStream&>(ffs);
190 
191  // if already read, just return
192  if(strm.headerRead == true) return;
193 
194  int i;
195  valid = 0;
196 
197  // clear out anything that was unsuccessfully read first
198  commentList.clear();
199 
200  while (!(valid & validEoH))
201  {
202  string line;
203  strm.formattedGetLine(line);
204  stripTrailing(line);
205  if(line.length() == 0) continue;
206  else if(line.length() < 60 || line.length() > 80)
207  {
208  FFStreamError e("Invalid line length");
209  GNSSTK_THROW(e);
210  }
211 
212  string thisLabel(line, 60, 20);
213 
214  // following is huge if else else ... endif for each record type
215  if(thisLabel == stringVersion)
216  {
217  // "RINEX VERSION / TYPE"
218  version = asDouble(line.substr( 0,20));
219 
220  fileType = strip(line.substr(20,20));
221  if(version >= 3)
222  { // ver 3
223  if(fileType[0] != 'N' && fileType[0] != 'n')
224  {
225  FFStreamError e("File type is not NAVIGATION: " + fileType);
226  GNSSTK_THROW(e);
227  }
228  fileSys = strip(line.substr(40,20)); // not in ver 2
230  fileType = "N: GNSS NAV DATA";
231  }
232  else
233  { // ver 2
234  if(fileType[0] == 'N' || fileType[0] == 'n')
235  setFileSystem("G");
236  else if(fileType[0] == 'G' || fileType[0] == 'g')
237  setFileSystem("R");
238  else if(fileType[0] == 'H' || fileType[0] == 'h')
239  setFileSystem("S");
240  else
241  {
242  FFStreamError e("Version 2 file type is invalid: " +
243  fileType);
244  GNSSTK_THROW(e);
245  }
246  fileType = "N: GPS NAV DATA";
247  }
248  valid |= validVersion;
249  }
250  else if(thisLabel == stringRunBy)
251  {
252  // "PGM / RUN BY / DATE"
253  fileProgram = strip(line.substr( 0,20));
254  fileAgency = strip(line.substr(20,20));
255  // R2 may not have 'UTC' at end
256  date = strip(line.substr(40,20));
257  valid |= validRunBy;
258  }
259  else if(thisLabel == stringComment)
260  {
261  // "COMMENT"
262  commentList.push_back(stripTrailing(line.substr(0,60)));
263  valid |= validComment;
264  }
265  else if(thisLabel == stringIonAlpha)
266  {
267  // GPS alpha "ION ALPHA" R2.11
268  IonoCorr ic("GPSA");
269  for(i=0; i < 4; i++)
270  ic.param[i] = line.substr(2 + 12*i, 12);
271  mapIonoCorr[ic.asString()] = ic;
272  if(mapIonoCorr.find("GPSB") != mapIonoCorr.end())
274  }
275  else if(thisLabel == stringIonBeta)
276  {
277  // GPS beta "ION BETA" R2.11
278  IonoCorr ic("GPSB");
279  for(i=0; i < 4; i++)
280  ic.param[i] = line.substr(2 + 12*i, 12);
281  mapIonoCorr[ic.asString()] = ic;
282  if(mapIonoCorr.find("GPSA") != mapIonoCorr.end())
284  }
285  else if(thisLabel == stringIonoCorr)
286  {
287  // "IONOSPHERIC CORR"
288  IonoCorr ic;
289  try
290  {
291  ic.fromString(strip(line.substr(0,4)));
292  }
293  catch(Exception& e)
294  {
295  FFStreamError fse(e.what());
296  GNSSTK_THROW(e);
297  }
298  for(i=0; i < 4; i++)
299  ic.param[i] = line.substr(5 + 12*i, 12);
300 
301  if(ic.type == IonoCorr::GAL)
302  {
304  }
305  else if(ic.type == IonoCorr::GPSA)
306  {
307  if(mapIonoCorr.find("GPSB") != mapIonoCorr.end())
309  }
310  else if(ic.type == IonoCorr::GPSB)
311  {
312  if(mapIonoCorr.find("GPSA") != mapIonoCorr.end())
314  }
315  //else
316  mapIonoCorr[ic.asString()] = ic;
317  }
318  else if(thisLabel == stringDeltaUTC)
319  {
320  // "DELTA-UTC: A0,A1,T,W" R2.11 GPS
321  TimeSystemCorrection tc("GPUT");
322  tc.A0 = RNDouble(line.substr(3,19));
323  tc.A1 = RNDouble(line.substr(22,19));
324  tc.refTime = GPSWeekSecond(asInt(line.substr(50,9)),
325  asDouble(line.substr(41,9)),
327  tc.geoProvider = string(" ");
328  tc.geoUTCid = 0;
329 
330  mapTimeCorr[tc.asString4()] = tc;
332  }
333  // R2.11 but Javad uses it in 3.01
334  else if(thisLabel == stringCorrSysTime)
335  {
336  // "CORR TO SYSTEM TIME" R2.10 GLO
337  TimeSystemCorrection tc("GLUT");
338  tc.refTime = CivilTime(asInt(line.substr(0,6)),
339  asInt(line.substr(6,6)),
340  asInt(line.substr(12,6)), 0, 0, 0.0,
342  tc.A0 = -RNDouble(line.substr(21,19)); // -TauC
343  tc.A1 = 0.0;
344  tc.geoProvider = string(" ");
345  tc.geoUTCid = 3; // UTC(SU)
346 
347  mapTimeCorr[tc.asString4()] = tc;
349  }
350  else if(thisLabel == stringDUTC)
351  {
352  // "D-UTC A0,A1,T,W,S,U" // R2.11 GEO
353  TimeSystemCorrection tc("SBUT");
354  tc.A0 = RNDouble(line.substr(0,19));
355  tc.A1 = RNDouble(line.substr(19,19));
356  tc.refTime = GPSWeekSecond(asInt(line.substr(45,5)),
357  asDouble(line.substr(38,7)),
359  tc.geoProvider = line.substr(51,5);
360  tc.geoUTCid = asInt(line.substr(57,2));
361 
362  mapTimeCorr[tc.asString4()] = tc;
364  }
365  else if(thisLabel == stringTimeSysCorr)
366  {
367  // R3 only // "TIME SYSTEM CORR"
369  try
370  {
371  tc.fromString(strip(line.substr(0,4)));
372  }
373  catch(Exception& e)
374  {
375  FFStreamError fse(e.what());
376  GNSSTK_THROW(e);
377  }
378 
379  tc.A0 = RNDouble(line.substr(5,17));
380  tc.A1 = RNDouble(line.substr(22,16));
381  if ((tc.type == TimeSystemCorrection::BDUT) ||
383  {
384  // BDT time stamps are actually referenced to BDT week epoch
385  tc.refTime = BDSWeekSecond(asInt(line.substr(45,5)),
386  asDouble(line.substr(38,7)));
387  }
388  else
389  {
390  // Everything else (including Galileo, oddly) is
391  // referenced to the GPS epoch.
392  tc.refTime = GPSWeekSecond(asInt(line.substr(45,5)),
393  asDouble(line.substr(38,7)));
394  }
395  tc.geoProvider = strip(line.substr(51,6));
396  tc.geoUTCid = asInt(line.substr(57,2));
397  tc.fixTimeSystem();
398 
399  mapTimeCorr[tc.asString4()] = tc;
401  }
402  else if(thisLabel == stringLeapSeconds)
403  {
404  // "LEAP SECONDS"
405  leapSeconds = asInt(line.substr(0,6));
406  leapDelta = asInt(line.substr(6,6)); // R3 only
407  leapWeek = asInt(line.substr(12,6)); // R3 only
408  leapDay = asInt(line.substr(18,6)); // R3 only
410  }
411  else if(thisLabel == stringEoH)
412  {
413  // "END OF HEADER"
414  valid |= validEoH;
415  }
416  else
417  {
418  GNSSTK_THROW(FFStreamError("Unknown header label >" + thisLabel +
419  "< at line " +
420  asString<size_t>(strm.lineNumber)));
421  }
422  }
423 
424  unsigned long allValid;
425  if(version >= 3.0)
426  allValid = allValid3;
427  else if(version >= 2 && version < 3)
428  allValid = allValid2;
429  else
430  {
431  FFStreamError e("Unknown or unsupported RINEX version "+
432  asString(version,2));
433  GNSSTK_THROW(e);
434  }
435 
436  if((allValid & valid) != allValid)
437  {
438  FFStreamError e("Incomplete or invalid header");
439  GNSSTK_THROW(e);
440  }
441 
442  strm.header = *this;
443  strm.headerRead = true;
444 
445  } // end of reallyGetRecord
446 
447  //-----------------------------------------------------------------------
449  {
450  Rinex3NavStream& strm = dynamic_cast<Rinex3NavStream&>(ffs);
451 
452  strm.header = (*this);
453 
454  int j;
455  unsigned long allValid;
456  if(version >= 3.0)
457  allValid = allValid3;
458  else if(version >= 2 && version < 3)
459  allValid = allValid2;
460  else
461  {
462  FFStreamError err("Unknown RINEX version: " + asString(version,4));
463  GNSSTK_THROW(err);
464  }
465 
466  if((valid & allValid) != allValid)
467  {
468  FFStreamError err("Incomplete or invalid header.");
469  GNSSTK_THROW(err);
470  }
471 
472  if(valid & validVersion)
473  {
474  // "RINEX VERSION / TYPE"
475  ffs << right << setw(10) << setprecision(2) << fixed << version
476  << setw(10) << ' ' << left << setw(20) << fileType;
477 
478  if (version >= 3)
479  ffs << left << setw(20) << fileSys;
480  else
481  ffs << setw(20) << ' ';
482  ffs << stringVersion << endlpp;
483  }
484 
485  if(valid & validRunBy)
486  {
487  // "PGM / RUN BY / DATE"
488  strm << left << setw(20) << fileProgram
489  << left << setw(20) << fileAgency;
490  SystemTime sysTime;
491  if(version < 3)
492  {
493  strm << left << setw(20)
494  << printTime(sysTime,"%02m/%02d/%04Y %02H:%02M:%02S");
495  }
496  else
497  {
498  strm << left << setw(20)
499  << printTime(sysTime,"%04Y%02m%02d %02H%02M%02S UTC");
500  }
501  strm << stringRunBy << endlpp;
502  }
503 
504  if(valid & validComment)
505  {
506  // "COMMENT"
507  for (unsigned i = 0; i < commentList.size(); i++)
508  {
509  strm << left << setw(60) << commentList[i] << stringComment
510  << endlpp;
511  }
512  }
513 
515  {
516  // "IONOSPHERIC CORR"
517  map<string,IonoCorr>::const_iterator it;
518  for(it=mapIonoCorr.begin(); it != mapIonoCorr.end(); ++it)
519  {
520  switch(it->second.type)
521  {
522  case IonoCorr::GAL:
523  strm << "GAL ";
524  for(j=0; j<3; j++)
525  {
526  strm << it->second.param[j];
527  }
528  strm << " " << setw(7) << ' ' << stringIonoCorr;
529  break;
530  case IonoCorr::GPSA:
531  if(version >= 3)
532  {
533  strm << "GPSA ";
534  for(j=0; j<4; j++)
535  {
536  strm << it->second.param[j];
537  }
538  strm << setw(7) << ' ' << stringIonoCorr;
539  }
540  else
541  {
542  // "ION ALPHA" // R2.11
543  strm << " ";
544  for(j=0; j<4; j++)
545  {
546  strm << it->second.param[j];
547  }
548  strm << setw(10) << ' ' << stringIonAlpha;
549  }
550  break;
551  case IonoCorr::GPSB:
552  if(version >= 3)
553  {
554  strm << "GPSB ";
555  for(j=0; j<4; j++)
556  strm << it->second.param[j];
557  strm << setw(7) << ' ' << stringIonoCorr;
558  }
559  else
560  {
561  // "ION BETA" // R2.11
562  strm << " ";
563  for(j=0; j<4; j++)
564  strm << it->second.param[j];
565  strm << setw(10) << ' ' << stringIonBeta;
566  }
567  break;
568  case IonoCorr::Unknown:
569  default:
570  FFStreamError err("Unknown IonoCorr type " +
571  asString(it->second.type));
572  GNSSTK_THROW(err);
573  break;
574  }
575  strm << endlpp;
576  }
577  }
578 
579  if(valid & validTimeSysCorr)
580  {
581  // "TIME SYSTEM CORR"
582  map<string,TimeSystemCorrection>::const_iterator it;
583  for(it=mapTimeCorr.begin(); it != mapTimeCorr.end(); ++it)
584  {
585  const TimeSystemCorrection& tc(it->second);
586  if(version >= 3)
587  {
588  strm << tc.asString4() << " "
590  2, 17, 'D', StringUtils::FFSign::NegOnly,
593  2, 16, 'D', StringUtils::FFSign::NegOnly,
595  if ((tc.type == TimeSystemCorrection::BDUT) ||
597  {
598  // BDT time stamps are actually referenced to BDT
599  // week epoch
600  BDSWeekSecond ws(tc.refTime);
601  strm << right << setw(7) << (unsigned)ws.sow
602  << right << setw(5) << ws.week;
603  }
604  else
605  {
606  // Everything else (including Galileo, oddly) is
607  // referenced to the GPS epoch.
608  GPSWeekSecond ws(tc.refTime);
609  strm << right << setw(7) << (unsigned)ws.sow
610  << right << setw(5) << ws.week;
611  }
612  // For SBAS this should be one of the three
613  // providers (EGNOS, WAAS or MSAS). For others it
614  // should be system and number Snn of GNSS satellite
615  // broadcasting the time system difference.
616  if (!tc.geoProvider.empty())
617  {
618  strm << ' ' << right << setw(5) << tc.geoProvider << ' ';
619  }
620  else
621  {
622  strm << setw(7) << ' ';
623  }
624  strm << right << setw(2) << tc.geoUTCid << ' '
626  }
627  else
628  {
629  if(tc.asString4() == "GPUT")
630  {
631  // "DELTA-UTC: A0,A1,T,W" R2.11 GPS
632  GPSWeekSecond ws(tc.refTime);
633  strm << " " << RNDouble(tc.A0) << RNDouble(tc.A1)
634  << right << setw(9) << (unsigned)ws.sow
635  << right << setw(9) << ws.week << " "
636  << stringDeltaUTC;
637  }
638  else if(tc.asString4() == "GLGP")
639  {
640  // "CORR TO SYSTEM TIME" R2.10 GLO
641  CivilTime civ(tc.refTime);
642  strm << right << setw(6) << civ.year
643  << right << setw(6) << civ.month
644  << right << setw(6) << civ.day
645  << RNDouble(tc.A0) << setw(23) << ' '
647  }
648  else if(tc.asString4() == "SBUT")
649  {
650  // "D-UTC A0,A1,T,W,S,U" R2.11 GEO
651  GPSWeekSecond ws(tc.refTime);
652  strm << RNDouble(tc.A0) << RNDouble(tc.A1)
653  << right << setw(7) << (unsigned)ws.sow
654  << right << setw(5) << ws.week
655  << right << setw(6) << tc.geoProvider << " "
656  << right << setw(2) << tc.geoUTCid << " "
657  << stringDUTC;
658  }
659  }
660 
661  strm << endlpp;
662  }
663  }
664 
665  if(valid & validLeapSeconds)
666  {
667  // "LEAP SECONDS"
668  strm << right << setw(6) << leapSeconds;
669  if(version >= 3)
670  { // ver 3
671  strm << right << setw(6) << leapDelta
672  << right << setw(6) << leapWeek
673  << right << setw(6) << leapDay
674  << setw(36) << ' ';
675  }
676  else // ver 2
677  {
678  strm << setw(54) << ' ';
679  }
680  strm << stringLeapSeconds << endlpp;
681  }
682 
683  if(valid & validEoH)
684  {
685  // "END OF HEADER"
686  strm << setw(60) << ' ' << stringEoH << endlpp;
687  }
688 
689  } // end of reallyPutRecord
690 
691  //-----------------------------------------------------------------------
692 
693  void Rinex3NavHeader::dump(ostream& s) const
694  {
695 
696  s << "---------------------------------- REQUIRED "
697  << "----------------------------------\n";
698 
699  s << "Rinex Version " << fixed << setw(5) << setprecision(2) << version
700  << ", File type " << fileType << ", System " << fileSys << ".\n";
701  s << "Prgm: " << fileProgram << ", Run: " << date << ", By: "
702  << fileAgency << endl;
703 
704  s << "(This header is ";
705  if(version >= 3 && (valid & allValid3) == allValid3)
706  s << "VALID RINEX version 3";
707  else if(version < 3 && (valid & allValid2) == allValid2)
708  s << "VALID RINEX version 2";
709  else s << "NOT VALID RINEX";
710  s << ")." << endl;
711 
712  if(!(valid & validVersion)) s << " Version is NOT valid\n";
713  if(!(valid & validRunBy )) s << " Run by is NOT valid\n";
714  if(!(valid & validEoH )) s << " End of Header is NOT valid\n";
715 
716  s << "---------------------------------- OPTIONAL "
717  << "----------------------------------\n";
718 
719  for(map<string,TimeSystemCorrection>::const_iterator tcit
720  = mapTimeCorr.begin(); tcit != mapTimeCorr.end(); ++tcit)
721 
722  {
723  tcit->second.dump(s);
724  s << endl;
725  }
726 
727  map<string,IonoCorr>::const_iterator icit;
728  for(icit=mapIonoCorr.begin(); icit != mapIonoCorr.end(); ++icit)
729  {
730  s << "Iono correction for " << icit->second.asString() << " : "
731  << scientific << setprecision(4);
732  switch(icit->second.type)
733  {
734  case IonoCorr::GAL:
735  s << "ai0 = " << icit->second.param[0]
736  << ", ai1 = " << icit->second.param[1]
737  << ", ai2 = " << icit->second.param[2];
738  break;
739  case IonoCorr::GPSA:
740  s << "alpha " << icit->second.param[0]
741  << " " << icit->second.param[1]
742  << " " << icit->second.param[2]
743  << " " << icit->second.param[3];
744  break;
745  case IonoCorr::GPSB:
746  s << "beta " << icit->second.param[0]
747  << " " << icit->second.param[1]
748  << " " << icit->second.param[2]
749  << " " << icit->second.param[3];
750  break;
751  case IonoCorr::Unknown:
752  default:
753  FFStreamError err("Unknown IonoCorr type " +
754  asString(icit->second.type));
755  GNSSTK_THROW(err);
756  break;
757  }
758  s << endl;
759  }
760 
761  if(valid & validLeapSeconds)
762  {
763  s << "Leap seconds: " << leapSeconds;
764  if(leapDelta != 0)
765  s << ", change " << leapDelta << " at week " << leapWeek
766  << ", day " << leapDay;
767  s << endl;
768  }
769  else s << " Leap seconds is NOT valid\n";
770 
771  if(commentList.size() > 0)
772  {
773  s << "Comments (" << commentList.size() << ") :\n";
774  for(size_t i = 0; i < commentList.size(); i++)
775  s << commentList[i] << endl;
776  }
777 
778  s << "-------------------------------- END OF HEADER "
779  << "-------------------------------\n";
780 
781  } // end of dump
782 
783 
784  void Rinex3NavHeader::setFileSystem(const std::string& str)
785  {
786  try
787  {
788  if(str[0] == 'M' || str[0] == 'm')
789  {
790  if(version < 3)
791  {
792  Exception e("RINEX version 2 'Mixed' Nav files do not exist");
793  GNSSTK_THROW(e);
794  }
795  fileType = "N: GNSS NAV DATA";
796  fileSys = "MIXED";
798  }
799  else
800  {
801  RinexSatID sat(std::string(1,str[0]));
802  fileSysSat = SatID(sat);
804  + ": (" + sat.systemString3()+")";
805  if(version >= 3)
806  {
807  fileType = "N: GNSS NAV DATA";
808  }
809  else
810  {
811  // RINEX 2
812  if(sat.system == SatelliteSystem::GPS)
813  fileType = "N: GPS NAV DATA";
814  else if(sat.system == SatelliteSystem::Glonass)
815  fileType = "G: GLO NAV DATA)";
816  else if(sat.system == SatelliteSystem::Geosync)
817  fileType = "H: GEO NAV DATA";
818  else
819  {
820  Exception e( std::string("RINEX version 2 ") +
821  sat.systemString3() +
822  std::string(" Nav files do not exist") );
823  GNSSTK_THROW(e);
824  }
825  }
826  }
827  }
828  catch(Exception& e)
829  {
830  GNSSTK_RETHROW(e);
831  }
832  }
833 
834 
836  std::vector<std::string>& diffs,
837  const std::vector<std::string>& inclExclList,
838  bool incl)
839  {
840  // map header token to comparison result
841  std::map<std::string,bool> lineMap;
842  std::map<std::string,bool>::const_iterator lmi;
843  // Put the comments in a sorted set, we don't really care
844  // about the ordering.
845  std::set<std::string>
846  lcomments(commentList.begin(), commentList.end()),
847  rcomments(right.commentList.begin(), right.commentList.end());
848  // Compare everything first...
849  // deliberately ignoring valid flags
850 
851  // only comparing first character of file type because that's
852  // all that matters according to RINEX
853  lineMap[stringVersion] =
854  ((version == right.version) &&
855  (fileType[0] == right.fileType[0]) &&
856  (fileSysSat.system == right.fileSysSat.system));
857  lineMap[stringRunBy] =
858  ((fileProgram == right.fileProgram) &&
859  (fileAgency == right.fileAgency) &&
860  (date == right.date));
861  lineMap[stringComment] = (lcomments == rcomments);
862  lineMap[stringIonoCorr] = (mapIonoCorr == right.mapIonoCorr);
863  lineMap[stringTimeSysCorr] = (mapTimeCorr == right.mapTimeCorr);
864  lineMap[stringLeapSeconds] =
865  ((leapSeconds == right.leapSeconds) &&
866  (leapDelta == right.leapDelta) &&
867  (leapWeek == right.leapWeek) &&
868  (leapDay == right.leapDay));
869  std::map<std::string,TimeSystemCorrection>::const_iterator ltci, rtci;
870  std::map<std::string,IonoCorr>::const_iterator lici, rici;
871  if (((ltci = mapTimeCorr.find("GPUT")) != mapTimeCorr.end()) &&
872  ((rtci = right.mapTimeCorr.find("GPUT")) != right.mapTimeCorr.end()))
873 
874  {
875  lineMap[stringDeltaUTC] = ltci->second == rtci->second;
876  }
877  else
878  {
879  lineMap[stringDeltaUTC] = true;
880  }
885  if (((ltci = mapTimeCorr.find("SBUT")) != mapTimeCorr.end()) &&
886  ((rtci = right.mapTimeCorr.find("SBUT")) != right.mapTimeCorr.end()))
887 
888  {
889  lineMap[stringDUTC] = ltci->second == rtci->second;
890  }
891  else
892  {
893  lineMap[stringDUTC] = true;
894  }
895  if (((lici = mapIonoCorr.find("GPSA")) != mapIonoCorr.end()) &&
896  ((rici = right.mapIonoCorr.find("GPSA")) != right.mapIonoCorr.end()))
897 
898  {
899 // lineMap[stringIonAlpha] = lici->second == rici->second;
900  }
901  else
902  {
903  lineMap[stringIonAlpha] = true;
904  }
905  if (((lici = mapIonoCorr.find("GPSB")) != mapIonoCorr.end()) &&
906  ((rici = right.mapIonoCorr.find("GPSB")) != right.mapIonoCorr.end()))
907 
908  {
909 // lineMap[stringIonBeta] = lici->second == rici->second;
910  }
911  else
912  {
913  lineMap[stringIonBeta] = true;
914  }
915  // ...then filter by inclExclList later
916  if (incl)
917  {
918  std::map<std::string,bool> oldLineMap(lineMap);
919  std::map<std::string,bool>::const_iterator olmi;
920  lineMap.clear();
921  for (unsigned i = 0; i < inclExclList.size(); i++)
922 
923  {
924  if ((olmi = oldLineMap.find(inclExclList[i])) != oldLineMap.end())
925 
926  {
927  lineMap[olmi->first] = olmi->second;
928  }
929  }
930  }
931  else
932  {
933  // exclude, remove items in inclExclList
934  for (unsigned i = 0; i < inclExclList.size(); i++)
935 
936  {
937  lineMap.erase(inclExclList[i]);
938  }
939  }
940  // check the equality of the final remaining set of header lines
941  bool rv = true;
942  for (lmi = lineMap.begin(); lmi != lineMap.end(); lmi++)
943  {
944  if (!lmi->second)
945  {
946  diffs.push_back(lmi->first);
947  rv = false;
948  }
949  }
950  return rv;
951  } // bool Rinex3NavHeader::compare
952 
953 } // namespace
gnsstk::RNDouble
Definition: RNDouble.hpp:50
gnsstk::Rinex3NavHeader::validLeapSeconds
@ validLeapSeconds
Set if the Leap Seconds value is valid.
Definition: Rinex3NavHeader.hpp:164
gnsstk::Rinex3NavHeader::fileSysSat
SatID fileSysSat
File system as a SatID.
Definition: Rinex3NavHeader.hpp:181
gnsstk::IonoCorr::operator==
bool operator==(const IonoCorr &ic) const
Equality test.
Definition: Rinex3NavHeader.cpp:157
gnsstk::StringUtils::upperCase
std::string & upperCase(std::string &s)
Definition: StringUtils.hpp:2117
gnsstk::StringUtils::asInt
long asInt(const std::string &s)
Definition: StringUtils.hpp:713
gnsstk::Rinex3NavHeader::stringIonAlpha
static const GNSSTK_EXPORT std::string stringIonAlpha
Definition: Rinex3NavHeader.hpp:215
Rinex3NavHeader.hpp
gnsstk::Rinex3NavHeader::compare
bool compare(const Rinex3NavHeader &right, std::vector< std::string > &diffs, const std::vector< std::string > &inclExclList, bool incl=false)
Definition: Rinex3NavHeader.cpp:835
gnsstk::TimeSystemCorrection
Definition: TimeSystemCorr.hpp:60
gnsstk::IonoCorr::IonoCorr
IonoCorr()
Set data members to default values.
Definition: Rinex3NavHeader.cpp:85
gnsstk::Rinex3NavHeader::version
double version
RINEX Version.
Definition: Rinex3NavHeader.hpp:178
gnsstk::Rinex3NavHeader::leapWeek
long leapWeek
Week number of ref time.
Definition: Rinex3NavHeader.hpp:192
gnsstk::Rinex3NavStream
Definition: Rinex3NavStream.hpp:62
gnsstk::Rinex3NavHeader::fileType
std::string fileType
File type "N....".
Definition: Rinex3NavHeader.hpp:179
gnsstk::Rinex3NavHeader::valid
unsigned long valid
Definition: Rinex3NavHeader.hpp:153
gnsstk::Rinex3NavHeader::stringVersion
static const GNSSTK_EXPORT std::string stringVersion
Definition: Rinex3NavHeader.hpp:196
gnsstk::CivilTime::year
int year
Definition: CivilTime.hpp:198
gnsstk::FFStream
Definition: FFStream.hpp:119
const
#define const
Definition: getopt.c:43
StringUtils.hpp
gnsstk::Rinex3NavHeader::validIonoCorrGPS
@ validIonoCorrGPS
Set if GPS Iono Correction data is valid.
Definition: Rinex3NavHeader.hpp:161
gnsstk::Rinex3NavHeader::stringEoH
static const GNSSTK_EXPORT std::string stringEoH
Definition: Rinex3NavHeader.hpp:219
gnsstk::Rinex3NavHeader::commentList
std::vector< std::string > commentList
Definition: Rinex3NavHeader.hpp:185
gnsstk::RinexSatID::systemString3
std::string systemString3() const noexcept
Definition: RinexSatID.cpp:102
gnsstk::TimeSystemCorrection::type
CorrType type
Definition: TimeSystemCorr.hpp:164
gnsstk::TimeSystemCorrection::A1
double A1
Definition: TimeSystemCorr.hpp:166
gnsstk::FFTextStream::formattedGetLine
void formattedGetLine(std::string &line, const bool expectEOF=false)
Definition: FFTextStream.cpp:149
gnsstk::Rinex3NavHeader::stringTimeSysCorr
static const GNSSTK_EXPORT std::string stringTimeSysCorr
Definition: Rinex3NavHeader.hpp:205
gnsstk::TimeSystemCorrection::refTime
CommonTime refTime
reference time for polynominal
Definition: TimeSystemCorr.hpp:167
gnsstk::Exception::what
std::string what() const
Dump to a string.
Definition: Exception.cpp:193
gnsstk::Rinex3NavStream::header
Rinex3NavHeader header
RINEX NAV header for this file.
Definition: Rinex3NavStream.hpp:80
gnsstk::FFTextStream::lineNumber
unsigned int lineNumber
Definition: FFTextStream.hpp:98
gnsstk::Rinex3NavHeader::stringIonBeta
static const GNSSTK_EXPORT std::string stringIonBeta
Definition: Rinex3NavHeader.hpp:217
gnsstk::TimeSystemCorrection::A0
double A0
Definition: TimeSystemCorr.hpp:166
gnsstk::SatID
Definition: SatID.hpp:89
gnsstk::StringUtils::asString
std::string asString(IonexStoreStrategy e)
Convert a IonexStoreStrategy to a whitespace-free string name.
Definition: IonexStoreStrategy.cpp:46
gnsstk::CivilTime::day
int day
Definition: CivilTime.hpp:200
gnsstk::Rinex3NavHeader::dump
virtual void dump(std::ostream &s) const
This function dumps the contents of the header.
Definition: Rinex3NavHeader.cpp:693
gnsstk::Rinex3NavHeader::mapIonoCorr
std::map< std::string, IonoCorr > mapIonoCorr
map of label : GAL, GPSA or GPSB, and IONO CORRs
Definition: Rinex3NavHeader.hpp:189
gnsstk::Rinex3NavHeader::stringIonoCorr
static const GNSSTK_EXPORT std::string stringIonoCorr
Definition: Rinex3NavHeader.hpp:203
gnsstk::SatelliteSystem::Geosync
@ Geosync
gnsstk::IonoCorr
Ionospheric Corrections.
Definition: Rinex3NavHeader.hpp:66
gnsstk::IonoCorr::asString
std::string asString() const noexcept
Return string version of CorrType.
Definition: Rinex3NavHeader.cpp:124
gnsstk::Rinex3NavHeader::validEoH
@ validEoH
Set if the End of Header is valid.
Definition: Rinex3NavHeader.hpp:165
gnsstk::Rinex3NavHeader::stringRunBy
static const GNSSTK_EXPORT std::string stringRunBy
Definition: Rinex3NavHeader.hpp:198
gnsstk::IonoCorr::GAL
@ GAL
Galileo.
Definition: Rinex3NavHeader.hpp:73
GNSSconstants.hpp
gnsstk::TimeSystemCorrection::fromString
void fromString(const std::string &str)
Definition: TimeSystemCorr.cpp:71
gnsstk::Rinex3NavHeader::validTimeSysCorr
@ validTimeSysCorr
Set if Time System Correction is valid.
Definition: Rinex3NavHeader.hpp:163
gnsstk
For Sinex::InputHistory.
Definition: BasicFramework.cpp:50
Rinex3NavStream.hpp
gnsstk::IonexStoreStrategy::Unknown
@ Unknown
Unknown or uninitialized stategy value.
gnsstk::StringUtils::FFAlign::Right
@ Right
Formatted output will be right-aligned.
gnsstk::GPSWeekSecond
Definition: GPSWeekSecond.hpp:56
gnsstk::Rinex3NavStream::headerRead
bool headerRead
Flag showing whether or not the header has been read.
Definition: Rinex3NavStream.hpp:83
gnsstk::Exception
Definition: Exception.hpp:151
gnsstk::SatelliteSystem::GPS
@ GPS
gnsstk::StringUtils::stripTrailing
std::string & stripTrailing(std::string &s, const std::string &aString, std::string::size_type num=std::string::npos)
Definition: StringUtils.hpp:1453
gnsstk::TimeSystemCorrection::asString4
std::string asString4() const
Return 4-char string version of CorrType.
Definition: TimeSystemCorr.cpp:270
gnsstk::Rinex3NavHeader::allValid2
@ allValid2
Definition: Rinex3NavHeader.hpp:173
gnsstk::Rinex3NavHeader
Definition: Rinex3NavHeader.hpp:107
gnsstk::TimeSystemCorrection::geoUTCid
int geoUTCid
Definition: TimeSystemCorr.hpp:169
gnsstk::FormattedDouble
Definition: FormattedDouble.hpp:70
gnsstk::StringUtils::FFSign::NegOnly
@ NegOnly
Prefix output with a minus sign (neg) or nothing (pos)
gnsstk::Rinex3NavHeader::stringComment
static const GNSSTK_EXPORT std::string stringComment
Definition: Rinex3NavHeader.hpp:200
gnsstk::Rinex3NavHeader::reallyPutRecord
virtual void reallyPutRecord(FFStream &s) const
Definition: Rinex3NavHeader.cpp:448
gnsstk::IonoCorr::operator<
bool operator<(const IonoCorr &ic) const
Ordering operator.
Definition: Rinex3NavHeader.cpp:171
gnsstk::Rinex3NavHeader::stringCorrSysTime
static const GNSSTK_EXPORT std::string stringCorrSysTime
Definition: Rinex3NavHeader.hpp:211
SystemTime.hpp
gnsstk::IonoCorr::GPSB
@ GPSB
Definition: Rinex3NavHeader.hpp:75
gnsstk::Rinex3NavHeader::reallyGetRecord
virtual void reallyGetRecord(FFStream &s)
Definition: Rinex3NavHeader.cpp:187
gnsstk::Rinex3NavHeader::validVersion
@ validVersion
Set if RINEX version is valid.
Definition: Rinex3NavHeader.hpp:158
example4.err
err
Definition: example4.py:126
gnsstk::StringUtils::FFLead::Decimal
@ Decimal
Start with decimal, e.g. .12345.
gnsstk::IonoCorr::Unknown
@ Unknown
A default value.
Definition: Rinex3NavHeader.hpp:72
gnsstk::SystemTime
Definition: SystemTime.hpp:54
gnsstk::Rinex3NavHeader::leapDelta
long leapDelta
Change in Leap seconds at ref time.
Definition: Rinex3NavHeader.hpp:191
gnsstk::WeekSecond::sow
double sow
Definition: WeekSecond.hpp:155
CivilTime.hpp
gnsstk::Rinex3NavHeader::validRunBy
@ validRunBy
Set if Run-by value is valid.
Definition: Rinex3NavHeader.hpp:159
gnsstk::IonoCorr::type
CorrType type
type of correction - enum CorrType
Definition: Rinex3NavHeader.hpp:101
gnsstk::Week::week
int week
Full week number.
Definition: Week.hpp:267
gnsstk::StringUtils::asDouble
double asDouble(const std::string &s)
Definition: StringUtils.hpp:705
gnsstk::Rinex3NavHeader::validComment
@ validComment
Set if Comments are valid.
Definition: Rinex3NavHeader.hpp:160
GNSSTK_RETHROW
#define GNSSTK_RETHROW(exc)
Definition: Exception.hpp:369
gnsstk::TimeSystem::GLO
@ GLO
GLONASS system time (aka UTC(SU))
gnsstk::Rinex3NavHeader::setFileSystem
void setFileSystem(const std::string &str)
Definition: Rinex3NavHeader.cpp:784
gnsstk::Rinex3NavHeader::allValid3
@ allValid3
Definition: Rinex3NavHeader.hpp:170
gnsstk::SatID::system
SatelliteSystem system
System for this satellite.
Definition: SatID.hpp:156
gnsstk::Rinex3NavHeader::date
std::string date
Date string; includes "UTC" at the end.
Definition: Rinex3NavHeader.hpp:184
gnsstk::Rinex3NavHeader::stringDUTC
static const GNSSTK_EXPORT std::string stringDUTC
Definition: Rinex3NavHeader.hpp:213
gnsstk::Rinex3NavHeader::leapSeconds
long leapSeconds
Leap seconds.
Definition: Rinex3NavHeader.hpp:190
gnsstk::CivilTime
Definition: CivilTime.hpp:55
gnsstk::StringUtils
Definition: IonexStoreStrategy.cpp:44
gnsstk::Rinex3NavHeader::stringLeapSeconds
static const GNSSTK_EXPORT std::string stringLeapSeconds
Definition: Rinex3NavHeader.hpp:207
GPSWeekSecond.hpp
gnsstk::IonoCorr::param
FormattedDouble param[4]
parameters ai0-ai2,0(GAL), alpha0-3 or beta0-3(GPS)
Definition: Rinex3NavHeader.hpp:102
gnsstk::Rinex3NavHeader::fileAgency
std::string fileAgency
Agency string.
Definition: Rinex3NavHeader.hpp:183
gnsstk::printTime
std::string printTime(const CommonTime &t, const std::string &fmt)
Definition: TimeString.cpp:64
gnsstk::RinexSatID
Definition: RinexSatID.hpp:63
gnsstk::TimeSystem::GPS
@ GPS
GPS system time.
std
Definition: Angle.hpp:142
gnsstk::SatelliteSystem::Mixed
@ Mixed
gnsstk::CivilTime::month
int month
Definition: CivilTime.hpp:199
BDSWeekSecond.hpp
gnsstk::StringUtils::strip
std::string & strip(std::string &s, const std::string &aString, std::string::size_type num=std::string::npos)
Definition: StringUtils.hpp:1482
gnsstk::Rinex3NavHeader::stringDeltaUTC
static const GNSSTK_EXPORT std::string stringDeltaUTC
Definition: Rinex3NavHeader.hpp:209
gnsstk::IonoCorr::GPSA
@ GPSA
GPS alpha.
Definition: Rinex3NavHeader.hpp:74
gnsstk::TimeSystemCorrection::BDGP
@ BDGP
BDT to GPS using A0, A1 !! not in RINEX.
Definition: TimeSystemCorr.hpp:77
GNSSTK_THROW
#define GNSSTK_THROW(exc)
Definition: Exception.hpp:366
endlpp
std::ostream & endlpp(std::ostream &os)
Definition: FFTextStream.hpp:147
gnsstk::SatelliteSystem::Glonass
@ Glonass
gnsstk::Rinex3NavHeader::fileSys
std::string fileSys
File system string.
Definition: Rinex3NavHeader.hpp:180
gnsstk::BDSWeekSecond
Definition: BDSWeekSecond.hpp:56
gnsstk::IonoCorr::fromString
void fromString(const std::string str)
Definition: Rinex3NavHeader.cpp:139
gnsstk::Rinex3NavHeader::fileProgram
std::string fileProgram
Program string.
Definition: Rinex3NavHeader.hpp:182
gnsstk::TimeSystemCorrection::BDUT
@ BDUT
BDT to UTC using A0, A1.
Definition: TimeSystemCorr.hpp:76
gnsstk::TimeSystemCorrection::geoProvider
std::string geoProvider
string 'EGNOS' 'WAAS' or 'MSAS'
Definition: TimeSystemCorr.hpp:168
gnsstk::Rinex3NavHeader::mapTimeCorr
std::map< std::string, TimeSystemCorrection > mapTimeCorr
map of label: GAUT, GPUT, etc, and TimeCorr
Definition: Rinex3NavHeader.hpp:187
GALWeekSecond.hpp
gnsstk::Rinex3NavHeader::validIonoCorrGal
@ validIonoCorrGal
Set if Gal Iono Correction data is valid.
Definition: Rinex3NavHeader.hpp:162
gnsstk::TimeSystemCorrection::fixTimeSystem
void fixTimeSystem()
Definition: TimeSystemCorr.cpp:580
TimeString.hpp
gnsstk::RinexSatID::systemChar
char systemChar() const noexcept
Definition: RinexSatID.cpp:62
gnsstk::Rinex3NavHeader::leapDay
long leapDay
Day of week of ref time.
Definition: Rinex3NavHeader.hpp:193


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