RinexNavHeader.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 
44 #include "StringUtils.hpp"
45 #include "CommonTime.hpp"
46 #include "CivilTime.hpp"
47 #include "SystemTime.hpp"
48 #include "RinexNavHeader.hpp"
49 #include "RinexNavStream.hpp"
50 
51 #include <iostream>
52 
53 using namespace gnsstk::StringUtils;
54 using namespace std;
55 
56 namespace gnsstk
57 {
58  const string RinexNavHeader::endOfHeader = "END OF HEADER";
59  const string RinexNavHeader::leapSecondsString = "LEAP SECONDS";
60  const string RinexNavHeader::deltaUTCString = "DELTA-UTC: A0,A1,T,W";
61  const string RinexNavHeader::ionBetaString = "ION BETA";
62  const string RinexNavHeader::ionAlphaString = "ION ALPHA";
63  const string RinexNavHeader::commentString = "COMMENT";
64  const string RinexNavHeader::runByString = "PGM / RUN BY / DATE";
65  const string RinexNavHeader::versionString = "RINEX VERSION / TYPE";
66 
68  : valid(0), version(2.1),
69  ionAlpha{FormattedDouble(0., FFLead::Decimal, 4, 2, 12, 'D',
70  FFSign::NegOnly, FFAlign::Right),
71  FormattedDouble(0., FFLead::Decimal, 4, 2, 12, 'D',
72  FFSign::NegOnly, FFAlign::Right),
73  FormattedDouble(0., FFLead::Decimal, 4, 2, 12, 'D',
74  FFSign::NegOnly, FFAlign::Right),
75  FormattedDouble(0., FFLead::Decimal, 4, 2, 12, 'D',
76  FFSign::NegOnly, FFAlign::Right) },
77  ionBeta {FormattedDouble(0., FFLead::Decimal, 4, 2, 12, 'D',
78  FFSign::NegOnly, FFAlign::Right),
79  FormattedDouble(0., FFLead::Decimal, 4, 2, 12, 'D',
80  FFSign::NegOnly, FFAlign::Right),
81  FormattedDouble(0., FFLead::Decimal, 4, 2, 12, 'D',
82  FFSign::NegOnly, FFAlign::Right),
83  FormattedDouble(0., FFLead::Decimal, 4, 2, 12, 'D',
84  FFSign::NegOnly, FFAlign::Right) },
85  A0(0), A1(0), UTCRefTime(0), UTCRefWeek(0), leapSeconds(0)
86  {}
87 
89  {
90  RinexNavStream& strm = dynamic_cast<RinexNavStream&>(ffs);
91 
92  strm.header = (*this);
93 
94  unsigned long allValid;
95  if (version == 2.0) allValid = allValid20;
96  else if (version == 2.1) allValid = allValid21;
97  else if (version == 2.11) allValid = allValid211;
98  else
99  {
100  FFStreamError err("Unknown RINEX version: " + asString(version,3));
101  err.addText("Make sure to set the version correctly.");
102  GNSSTK_THROW(err);
103  }
104 
105  if ((valid & allValid) != allValid)
106  {
107  FFStreamError err("Incomplete or invalid header.");
108  err.addText("Make sure you set all header valid bits for all of the available data.");
109  GNSSTK_THROW(err);
110  }
111 
112  string line;
113 
114  if (valid & versionValid)
115  {
116  line = rightJustify(asString(version,2), 9);
117  line += string(11, ' ');
118  line += string("NAVIGATION"); //leftJustify(fileType, 20);
119  line += string(30, ' ');
120  line += versionString;
121  strm << line << endl;
122  strm.lineNumber++;
123  }
124  if (valid & runByValid)
125  {
126  line = leftJustify(fileProgram,20);
127  line += leftJustify(fileAgency,20);
128  SystemTime dt;
129  string dat = (static_cast<CivilTime>(dt)).printf("%02m/%02d/%04Y %02H:%02M:%02S");
130  line += leftJustify(dat, 20);
131  line += runByString;
132  strm << line << endl;
133  strm.lineNumber++;
134  }
135  if (valid & commentValid)
136  {
137  vector<string>::const_iterator itr = commentList.begin();
138  while (itr != commentList.end())
139  {
140  line = leftJustify((*itr), 60);
141  line += commentString;
142  strm << line << endl;
143  strm.lineNumber++;
144  itr++;
145  }
146  }
147  if (valid & ionAlphaValid)
148  {
149  strm << " ";
150  for (int i = 0; i < 4; i++)
151  {
152  strm << ionAlpha[i];
153  }
154  strm << setw(10) << " " << ionAlphaString << endl;
155  strm.lineNumber++;
156  }
157  if (valid & ionBetaValid)
158  {
159  strm << " ";
160  for (int i = 0; i < 4; i++)
161  {
162  strm << ionBeta[i];
163  }
164  strm << setw(10) << " " << ionBetaString << endl;
165  strm.lineNumber++;
166  }
167  if (valid & deltaUTCValid)
168  {
169  strm << " " << A0 << A1 << setw(9) << right << UTCRefTime
170  << setw(9) << right << UTCRefWeek << " " << deltaUTCString
171  << endl;
172  strm.lineNumber++;
173  }
174  if (valid & leapSecondsValid)
175  {
176  line = rightJustify(asString(leapSeconds), 6);
177  line += string(54, ' ');
178  line += leapSecondsString;
179  strm << line << endl;
180  strm.lineNumber++;
181  }
182  if (valid & endValid)
183  {
184  line = string(60,' ');
185  line += endOfHeader;
186  strm << line << endl;
187  strm.lineNumber++;
188  }
189 
190  }
191 
193  {
194  RinexNavStream& strm = dynamic_cast<RinexNavStream&>(ffs);
195 
196  // if already read, just return
197  if (strm.headerRead == true)
198  return;
199 
200  valid = 0;
201 
202  // clear out anything that was unsuccessfully read the first
203  commentList.clear();
204 
205  while (! (valid & endValid))
206  {
207  string line;
208  strm.formattedGetLine(line);
210 
211  if (line.length()==0) continue;
212  else if (line.length()<60 || line.length()>80)
213  {
214  FFStreamError e("Invalid line length");
215  GNSSTK_THROW(e);
216  }
217 
218  string thisLabel(line, 60, 20);
219 
220  if (thisLabel == versionString)
221  {
222  version = asDouble(line.substr(0,20));
223  fileType = strip(line.substr(20,20));
224  if ( (fileType[0] != 'N') &&
225  (fileType[0] != 'n'))
226  {
227  FFStreamError e("This isn't a Rinex Nav file");
228  GNSSTK_THROW(e);
229  }
230  valid |= versionValid;
231  }
232  else if (thisLabel == runByString)
233  {
234  fileProgram = strip(line.substr(0,20));
235  fileAgency = strip(line.substr(20,20));
236  date = strip(line.substr(40,20));
237  valid |= runByValid;
238  }
239  else if (thisLabel == commentString)
240  {
241  commentList.push_back(strip(line.substr(0,60)));
242  valid |= commentValid;
243  }
244  else if (thisLabel == ionAlphaString)
245  {
246  for(int i = 0; i < 4; i++)
247  ionAlpha[i] = line.substr(2 + 12 * i,12);
248  valid |= ionAlphaValid;
249  }
250  else if (thisLabel == ionBetaString)
251  {
252  for(int i = 0; i < 4; i++)
253  ionBeta[i] = line.substr(2 + 12 * i,12);
254  valid |= ionBetaValid;
255  }
256  else if (thisLabel == deltaUTCString)
257  {
258  A0 = line.substr(3,19);
259  A1 = line.substr(22,19);
260  UTCRefTime = asInt(line.substr(41,9));
261  UTCRefWeek = asInt(line.substr(50,9));
262  valid |= deltaUTCValid;
263  }
264  else if (thisLabel == leapSecondsString)
265  {
266  leapSeconds = asInt(line.substr(0,6));
268  }
269  else if (thisLabel == endOfHeader)
270  {
271  valid |= endValid;
272  }
273  else
274  {
275  FFStreamError exc("Unknown header label at line " +
276  asString<size_t>(strm.lineNumber));
277  GNSSTK_THROW(exc);
278  }
279  }
280 
281  unsigned long allValid;
282  if (version == 2.0) allValid = allValid20;
283  else if (version == 2.1) allValid = allValid21;
284  else if (version == 2.11) allValid = allValid211;
285  else
286  {
287  FFStreamError e("Unknown or unsupported RINEX version " +
288  asString(version));
289  GNSSTK_THROW(e);
290  }
291 
292  if ( (allValid & valid) != allValid)
293  {
294  FFStreamError e("Incomplete or invalid header");
295  GNSSTK_THROW(e);
296  }
297 
298  // we got here, so something must be right...
299  strm.header = *this;
300  strm.headerRead = true;
301  }
302 
303  void RinexNavHeader::dump(ostream& s) const
304  {
305  int i;
306  s << "---------------------------------- REQUIRED ----------------------------------\n";
307  s << "Rinex Version " << fixed << setw(5) << setprecision(2) << version
308  << ", File type " << fileType << ".\n";
309  s << "Prgm: " << fileProgram << ", Run: " << date << ", By: " << fileAgency << endl;
310 
311  s << "(This header is ";
312  if((valid & allValid211) == allValid211) s << "VALID 2.11";
313  else if((valid & allValid21) == allValid21) s << "VALID 2.1";
314  else if((valid & allValid20) == allValid20) s << "VALID 2.0";
315  else s << "NOT VALID";
316  s << " Rinex.)\n";
317 
318  if(!(valid & versionValid)) s << " Version is NOT valid\n";
319  if(!(valid & runByValid)) s << " Run by is NOT valid\n";
320  if(!(valid & endValid)) s << " End is NOT valid\n";
321 
322  s << "---------------------------------- OPTIONAL ----------------------------------\n";
323  if(valid & ionAlphaValid) { s << "Ion alpha:";
324  for(i=0; i<4; i++) s << " " << scientific << setprecision(4) << ionAlpha[i];
325  s << endl; }
326  else s << " Ion alpha is NOT valid\n";
327  if(valid & ionBetaValid) { s << "Ion beta:";
328  for(i=0; i<4; i++) s << " " << scientific << setprecision(4) << ionBeta[i];
329  s << endl; }
330  else s << " Ion beta is NOT valid\n";
331  if(valid & deltaUTCValid) s << "Delta UTC: A0="
332  << scientific << setprecision(12) << A0 << ", A1="
333  << scientific << setprecision(12) << A1 << ", UTC ref = ("
334  << UTCRefWeek << "," << UTCRefTime << ")\n";
335  else s << " Delta UTC is NOT valid\n";
336  if(valid & leapSecondsValid) s << "Leap seconds: " << leapSeconds << endl;
337  else s << " Leap seconds is NOT valid\n";
338  if(commentList.size() > 0) {
339  s << "Comments (" << commentList.size() << ") :\n";
340  for(size_t i=0; i<commentList.size(); i++)
341  s << commentList[i] << endl;
342  }
343  s << "-------------------------------- END OF HEADER -------------------------------\n";
344  }
345 
346 } // namespace
gnsstk::RinexNavHeader::deltaUTCValid
@ deltaUTCValid
Set if the Delta UTC value is valid.
Definition: RinexNavHeader.hpp:89
gnsstk::StringUtils::asInt
long asInt(const std::string &s)
Definition: StringUtils.hpp:713
gnsstk::RinexNavHeader::fileProgram
std::string fileProgram
Definition: RinexNavHeader.hpp:107
gnsstk::RinexNavHeader::leapSecondsValid
@ leapSecondsValid
Set if the Leap Seconds value is valid.
Definition: RinexNavHeader.hpp:90
gnsstk::RinexNavHeader::versionString
static const GNSSTK_EXPORT std::string versionString
Definition: RinexNavHeader.hpp:120
gnsstk::RinexNavHeader::valid
unsigned long valid
Tell me, Am I valid?
Definition: RinexNavHeader.hpp:79
gnsstk::FFStream
Definition: FFStream.hpp:119
gnsstk::RinexNavHeader::UTCRefWeek
long UTCRefWeek
Definition: RinexNavHeader.hpp:116
gnsstk::RinexNavHeader::fileType
std::string fileType
Definition: RinexNavHeader.hpp:106
gnsstk::RinexNavHeader::reallyPutRecord
virtual void reallyPutRecord(FFStream &s) const
Definition: RinexNavHeader.cpp:88
StringUtils.hpp
gnsstk::RinexNavHeader::UTCRefTime
long UTCRefTime
Definition: RinexNavHeader.hpp:115
gnsstk::FFTextStream::formattedGetLine
void formattedGetLine(std::string &line, const bool expectEOF=false)
Definition: FFTextStream.cpp:149
gnsstk::UnixTime::printf
virtual std::string printf(const std::string &fmt) const
Definition: UnixTime.cpp:105
gnsstk::FFTextStream::lineNumber
unsigned int lineNumber
Definition: FFTextStream.hpp:98
gnsstk::RinexNavHeader::deltaUTCString
static const GNSSTK_EXPORT std::string deltaUTCString
Definition: RinexNavHeader.hpp:130
gnsstk::StringUtils::asString
std::string asString(IonexStoreStrategy e)
Convert a IonexStoreStrategy to a whitespace-free string name.
Definition: IonexStoreStrategy.cpp:46
gnsstk::RinexNavHeader::version
double version
RINEX Version.
Definition: RinexNavHeader.hpp:104
RinexNavHeader.hpp
gnsstk::RinexNavHeader::date
std::string date
Definition: RinexNavHeader.hpp:109
gnsstk::RinexNavHeader::ionBetaString
static const GNSSTK_EXPORT std::string ionBetaString
Definition: RinexNavHeader.hpp:128
gnsstk::RinexNavHeader::allValid20
@ allValid20
Definition: RinexNavHeader.hpp:95
gnsstk
For Sinex::InputHistory.
Definition: BasicFramework.cpp:50
gnsstk::RinexNavHeader::leapSecondsString
static const GNSSTK_EXPORT std::string leapSecondsString
Definition: RinexNavHeader.hpp:132
gnsstk::RinexNavHeader::ionAlphaValid
@ ionAlphaValid
Set if the Ion Alpha value is valid.
Definition: RinexNavHeader.hpp:87
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::RinexNavHeader::RinexNavHeader
RinexNavHeader()
Constructor.
Definition: RinexNavHeader.cpp:67
gnsstk::RinexNavHeader::commentList
std::vector< std::string > commentList
Definition: RinexNavHeader.hpp:110
gnsstk::FormattedDouble
Definition: FormattedDouble.hpp:70
gnsstk::RinexNavHeader::ionAlphaString
static const GNSSTK_EXPORT std::string ionAlphaString
Definition: RinexNavHeader.hpp:126
gnsstk::RinexNavHeader::versionValid
@ versionValid
Set if the RINEX version is valid.
Definition: RinexNavHeader.hpp:84
gnsstk::RinexNavHeader::allValid21
@ allValid21
Definition: RinexNavHeader.hpp:98
gnsstk::RinexNavHeader::allValid211
@ allValid211
Definition: RinexNavHeader.hpp:101
SystemTime.hpp
example4.err
err
Definition: example4.py:126
gnsstk::RinexNavHeader::fileAgency
std::string fileAgency
Definition: RinexNavHeader.hpp:108
gnsstk::SystemTime
Definition: SystemTime.hpp:54
version
string version(string("2.4 9/23/15 rev"))
example6.valid
valid
Definition: example6.py:20
CivilTime.hpp
RinexNavStream.hpp
gnsstk::StringUtils::asDouble
double asDouble(const std::string &s)
Definition: StringUtils.hpp:705
gnsstk::RinexNavHeader::endValid
@ endValid
Set if the end value is valid.
Definition: RinexNavHeader.hpp:91
gnsstk::RinexNavHeader::ionBeta
FormattedDouble ionBeta[4]
Definition: RinexNavHeader.hpp:112
gnsstk::RinexNavHeader::commentString
static const GNSSTK_EXPORT std::string commentString
Definition: RinexNavHeader.hpp:124
gnsstk::RinexNavStream
Definition: RinexNavStream.hpp:61
gnsstk::RinexNavHeader::ionBetaValid
@ ionBetaValid
Set if the Ion Beta value is valid.
Definition: RinexNavHeader.hpp:88
gnsstk::RinexNavStream::header
RinexNavHeader header
RINEX NAV header for this file.
Definition: RinexNavStream.hpp:79
gnsstk::CivilTime
Definition: CivilTime.hpp:55
gnsstk::StringUtils
Definition: IonexStoreStrategy.cpp:44
gnsstk::StringUtils::rightJustify
std::string & rightJustify(std::string &s, const std::string::size_type length, const char pad=' ')
Definition: StringUtils.hpp:1557
gnsstk::RinexNavHeader::endOfHeader
static const GNSSTK_EXPORT std::string endOfHeader
Definition: RinexNavHeader.hpp:134
gnsstk::RinexNavStream::headerRead
bool headerRead
Flag showing whether or not the header has been read.
Definition: RinexNavStream.hpp:82
A1
static const int A1
Definition: DiscCorr.cpp:630
CommonTime.hpp
std
Definition: Angle.hpp:142
gnsstk::RinexNavHeader::A0
RNDouble A0
Definition: RinexNavHeader.hpp:113
gnsstk::RinexNavHeader::A1
RNDouble A1
Definition: RinexNavHeader.hpp:114
gnsstk::RinexNavHeader::dump
virtual void dump(std::ostream &s) const
This function dumps the contents of the header.
Definition: RinexNavHeader.cpp:303
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::StringUtils::leftJustify
std::string & leftJustify(std::string &s, const std::string::size_type length, const char pad=' ')
Definition: StringUtils.hpp:1582
GNSSTK_THROW
#define GNSSTK_THROW(exc)
Definition: Exception.hpp:366
gnsstk::RinexNavHeader::ionAlpha
FormattedDouble ionAlpha[4]
Definition: RinexNavHeader.hpp:111
gnsstk::RinexNavHeader::reallyGetRecord
virtual void reallyGetRecord(FFStream &s)
Definition: RinexNavHeader.cpp:192
gnsstk::RinexNavHeader::commentValid
@ commentValid
Set if the comments are valid. Very subjective.
Definition: RinexNavHeader.hpp:86
gnsstk::RinexNavHeader::runByValid
@ runByValid
Set if the Run-by value is valid.
Definition: RinexNavHeader.hpp:85
gnsstk::RinexNavHeader::runByString
static const GNSSTK_EXPORT std::string runByString
Definition: RinexNavHeader.hpp:122
gnsstk::RinexNavHeader::leapSeconds
long leapSeconds
Definition: RinexNavHeader.hpp:117


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