Rinex3ObsData.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 
43 #include <algorithm>
44 #include "StringUtils.hpp"
45 #include "CivilTime.hpp"
46 #include "TimeString.hpp"
47 #include "RinexObsID.hpp"
48 #include "Rinex3ObsStream.hpp"
49 #include "Rinex3ObsData.hpp"
50 
51 using namespace gnsstk::StringUtils;
52 using namespace std;
53 
54 namespace gnsstk
55 {
57  const Rinex3ObsData& rod )
58  {
59  // is there anything to write?
60  if( (rod.epochFlag==0 || rod.epochFlag==1 || rod.epochFlag==6)
61  && (rod.numSVs==0 || rod.obs.empty()) ) return;
62 
63  if( rod.epochFlag>=2
64  && rod.epochFlag<=5
65  && rod.auxHeader.numberHeaderRecordsToBeWritten()==0 ) return;
66 
67  // first the epoch line to 'line'
68  //line = writeTime(rod.time); // (ver 2 RinexObsData::writeTime)
69  string line;
71  line = string(26, ' ');
72  else
73  {
74  CivilTime civTime(rod.time);
75  line = string(1, ' ');
76  line += rightJustify(asString<short>(civTime.year),2);
77  line += string(1, ' ');
78  line += rightJustify(asString<short>(civTime.month),2);
79  line += string(1, ' ');
80  line += rightJustify(asString<short>(civTime.day),2);
81  line += string(1, ' ');
82  line += rightJustify(asString<short>(civTime.hour),2);
83  line += string(1, ' ');
84  line += rightJustify(asString<short>(civTime.minute),2);
85  line += rightJustify(asString(civTime.second, 7),11);
86  line += string(2, ' ');
87  line += rightJustify(asString<short>(rod.epochFlag), 1);
88  line += rightJustify(asString<short>(rod.numSVs), 3);
89  }
90 
91  // write satellite ids to 'line'
92  const size_t maxPrnsPerLine = 12;
93  size_t satsWritten = 0;
94 
95  Rinex3ObsData::DataMap::const_iterator itr(rod.obs.begin());
96 
97  if( rod.epochFlag==0 || rod.epochFlag==1 || rod.epochFlag==6 )
98  {
99  while( itr != rod.obs.end() && satsWritten < maxPrnsPerLine )
100  {
101  line += itr->first.toString();
102  satsWritten++;
103  itr++;
104  }
105 
106  // add clock offset
107  if( rod.clockOffset != 0.0 )
108  {
109  line += string(68 - line.size(), ' ');
110  line += rightJustify( asString(rod.clockOffset, 9), 12 );
111  }
112 
113  // continuation lines
114  while( satsWritten != rod.obs.size() )
115  {
116  if((satsWritten % maxPrnsPerLine) == 0)
117  {
118  strm << line << endl;
119  strm.lineNumber++;
120  line = string(32, ' ');
121  }
122  line += itr->first.toString();
123  satsWritten++;
124  itr++;
125  }
126 
127  } // End of 'if( rod.epochFlag==0 || rod.epochFlag==1 || ...'
128 
129  // write the epoch line
130  strm << line << endl;
131  strm.lineNumber++;
132  // write the auxiliary header records, if any
133  if( rod.epochFlag >= 2 && rod.epochFlag <= 5 )
134  {
135  try
136  {
137  rod.auxHeader.writeHeaderRecords(strm);
138  }
139  catch(FFStreamError& e)
140  {
141  GNSSTK_RETHROW(e);
142  }
143  catch(StringException& e)
144  {
145  GNSSTK_RETHROW(e);
146  }
147  } // write out data
148  else if( rod.epochFlag == 0 || rod.epochFlag == 1 || rod.epochFlag == 6 )
149  {
150  size_t i;
151  const int maxObsPerLine(5);
152 
153  // loop over satellites in R3 obs data
154  for( itr = rod.obs.begin(); itr != rod.obs.end(); ++itr )
155  {
156 
157  RinexSatID sat(itr->first); // current satellite
158  string sys(string(1,sat.systemChar())); // system
159  int obsWritten(0);
160  line = string("");
161 
162  // loop over R2 obstypes
163  for( i=0; i<strm.header.R2ObsTypes.size(); i++ )
164  {
165 
166  // get the R3 obs ID from the map
167  RinexObsID obsid;
168  obsid =
169  strm.header.mapSysR2toR3ObsID[sys][strm.header.R2ObsTypes[i]];
170 
171  // now find index of that data from R3 header
172  const vector<RinexObsID>& vecData(strm.header.mapObsTypes[sys]);
173 
174  vector<RinexObsID>::const_iterator jt;
175  jt = find(vecData.begin(), vecData.end(), obsid);
176 
177  // index into vecData
178  int ind(-1);
179 
180  if( jt != vecData.end() )
181  ind = jt-vecData.begin();
182 
183  // need a continuation line?
184  if( obsWritten != 0 && (obsWritten % maxObsPerLine) == 0 )
185  {
186  strm << line << endl;
187  strm.lineNumber++;
188  line = string("");
189  }
190 
191  // write the line
192  if (ind == -1)
193  {
194  RinexDatum empty;
195  line += empty.asString();
196  }
197  else
198  {
199  line += itr->second[ind].asString();
200  }
201  obsWritten++;
202 
203  } // End of 'for( i=0; i<strm.header.R2ObsTypes.size(); i++ )'
204 
205  strm << line << endl;
206  strm.lineNumber++;
207 
208  } // End of 'for( itr = rod.obs.begin(); itr != rod.obs.end();...'
209 
210  } // Ebf of 'else if( rod.epochFlag == 0 || rod.epochFlag == 1 || ...'
211 
212  } // End of function 'reallyPutRecordVer2()'
213 
214 
217  epochFlag(-1),
218  numSVs(-1),
219  clockOffset(0.L),
220  xmitAnt(XmitAnt::Standard)
221  {}
222 
223 
224  RinexDatum Rinex3ObsData::getObs(const RinexSatID& svID, size_t index ) const
225  {
226  DataMap::const_iterator i = obs.find(svID);
227  if (i == obs.end())
228  {
229  InvalidRequest ir( svID.toString() + " is not available.");
230  GNSSTK_THROW(ir);
231  }
232  if (index >= i->second.size())
233  {
234  InvalidRequest ir( svID.toString() + " index " + StringUtils::asString(index) + " is not available.");
235  GNSSTK_THROW(ir);
236  }
237 
238  return i->second[index];
239  }
240 
241 
243  const std::string& type,
244  const Rinex3ObsHeader& hdr ) const
245  {
246  string obsID;
247  // Add GNSS code if needed
248  if( type.size() == 3 )
249  obsID = svID.systemChar() + type;
250  else
251  obsID = type;
252 
253  return getObs(svID, hdr.getObsIndex(obsID));
254  }
255 
256 
258  const RinexObsID& obsID,
259  const Rinex3ObsHeader& hdr ) const
260  {
261  string sys(1,svID.systemChar());
262  return getObs(svID, hdr.getObsIndex(sys, obsID));
263  }
264 
265 
267  const RinexSatID& svID,
268  const RinexObsID& obsID,
269  const Rinex3ObsHeader& hdr )
270  {
271  size_t index = hdr.getObsIndex(string(1,svID.systemChar()), obsID);
272  if (obs[svID].size() <= index)
273  obs[svID].resize(index+1);
274  if (obsID.type == ObservationType::Channel)
275  {
276  // double, because everything is floating point in RINEX...
277  double channel = data.data;
278  if (channel == 0)
279  {
280  // substitute 99 for 0 so we always have something
281  // (unless someone sets the channel to a negative
282  // number).
283  channel = 99;
284  }
289  // also checking for channel being < 1, which is not allowed
290  // per RINEX 3.04
291  if ((obs[svID][index].data < 100000000) &&
292  (channel >= 1))
293  {
294  obs[svID][index].data *= 100;
295  // We assume the channel number is in the supplied
296  // RinexDatum, but we need to keep it under 100
297  // according to RINEX 3.04. This is a kludge.
298  obs[svID][index].data += fmod(channel, 100);
299  obs[svID][index].lliBlank = obs[svID][index].ssiBlank = true;
300  }
301  }
302  else
303  {
304  obs[svID][index] = data;
305  }
306  }
307 
308 
310  {
311  // is there anything to write?
312  if( (epochFlag == 0 || epochFlag == 1 || epochFlag == 6)
313  && (numSVs==0 || obs.empty())){
314  return;
315  }
316 
317  Rinex3ObsStream& strm = dynamic_cast<Rinex3ObsStream&>(ffs);
318 
319  // call the version for RINEX ver 2
320  if(strm.header.version < 3)
321  {
322  try
323  {
324  reallyPutRecordVer2(strm, *this);
325  }
326  catch(Exception& e)
327  {
328  GNSSTK_RETHROW(e);
329  }
330  return;
331  }
332 
333  string line;
334 
335  // first the epoch line
336  line = ">";
337  line += writeTime(time);
338  line += string(2, ' ');
339  line += rightJustify(asString<short>(epochFlag), 1);
340  line += rightJustify(asString<short>(numSVs ), 3);
341  line += string(6, ' ');
342  if(clockOffset != 0.0) // optional data; need to test for its existence
343  line += rightJustify(asString(clockOffset, 12), 15);
344 
345  strm << line << endl;
346  strm.lineNumber++;
347  line.erase();
348 
349  if(epochFlag == 0 || epochFlag == 1 || epochFlag == 6)
350  {
351  DataMap::const_iterator itr = obs.begin();
352 
353  while(itr != obs.end())
354  {
355  line = itr->first.toString();
356 
357  for(size_t i=0; i < itr->second.size(); i++)
358  {
359  line += itr->second[i].asString();
360  }
361  // write the data line out
362  strm << line << endl;
363  strm.lineNumber++;
364  line.erase();
365 
366  itr++;
367  } // end loop over sats and data
368  }
369 
370  // write the auxiliary header records, if any
371  else if(epochFlag >= 2 && epochFlag <= 5)
372  {
373  try
374  {
376  }
377  catch(FFStreamError& e)
378  {
379  GNSSTK_RETHROW(e);
380  }
381  catch(StringException& e)
382  {
383  GNSSTK_RETHROW(e);
384  }
385  }
386 
387  } // end Rinex3ObsData::reallyPutRecord
388 
389 
391  {
392  static CommonTime previousTime(CommonTime::BEGINNING_OF_TIME);
393 
394  // get the epoch line and check
395  string line;
396  while(line.empty()) // ignore blank lines in place of epoch lines
397  strm.formattedGetLine(line, true);
399 
400  if(line.size()>80 || line[0] != ' ' || line[3] != ' ' || line[6] != ' ')
401  {
402  FFStreamError e("Bad epoch line: >" + line + "<");
403  GNSSTK_THROW(e);
404  }
405 
406  // process the epoch line, including SV list and clock bias
407  rod.epochFlag = asInt(line.substr(28,1));
408  if((rod.epochFlag < 0) || (rod.epochFlag > 6))
409  {
410  FFStreamError e("Invalid epoch flag: " + asString(rod.epochFlag));
411  GNSSTK_THROW(e);
412  }
413 
414  // Not all epoch flags are required to have a time.
415  // Specifically, 0,1,5,6 must have an epoch time; it is
416  // optional for 2,3,4. If there is and epoch time, parse it
417  // and load it in the member "time".
418  // If epoch flag=0, 1, 5, or 6 and there is NO epoch time, then throw.
419  // If epoch flag=2, 3, or 4 and there is no epoch time,
420  // use the time of the previous record.
421  bool noEpochTime = (line.substr(0,26) == string(26, ' '));
422  if(noEpochTime && (rod.epochFlag==0 || rod.epochFlag==1 ||
423  rod.epochFlag==5 || rod.epochFlag==6 ))
424  {
425  FFStreamError e("Required epoch time missing: " + line);
426  GNSSTK_THROW(e);
427  }
428  else if(noEpochTime)
429  rod.time = previousTime;
430  else
431  {
432  try
433  {
434  // check if the spaces are in the right place - an easy
435  // way to check if there's corruption in the file
436  if((line[0] != ' ') || (line[3] != ' ') || (line[6] != ' ') ||
437  (line[9] != ' ') || (line[12] != ' ') || (line[15] != ' '))
438  {
439  FFStreamError e("Invalid time format");
440  GNSSTK_THROW(e);
441  }
442 
443  // if there's no time, just use a bad time
444  if(line.substr(0,26) == string(26, ' '))
446  //rod.time = previousTime; ??
447  else
448  {
449  int year, month, day, hour, min;
450  double sec;
451  int yy = (static_cast<CivilTime>(strm.header.firstObs)).year/100;
452  yy *= 100;
453 
454  year = asInt( line.substr(1, 2 ));
455  month = asInt( line.substr(4, 2 ));
456  day = asInt( line.substr(7, 2 ));
457  hour = asInt( line.substr(10, 2 ));
458  min = asInt( line.substr(13, 2 ));
459  sec = asDouble(line.substr(15, 11));
460 
461  // Real Rinex has epochs 'yy mm dd hr 59 60.0'
462  // surprisingly often....
463  double ds(0);
464  if(sec >= 60.)
465  {
466  ds=sec;
467  sec=0.0;
468  }
469  CivilTime rv(yy+year, month, day, hour, min, sec,
471  if(ds != 0) rv.second += ds;
472 
473  rod.time = rv.convertToCommonTime();
474  }
475  }
476  // string exceptions for substr are caught here
477  catch(std::exception &e)
478  {
479  FFStreamError err("std::exception: " + string(e.what()));
480  GNSSTK_THROW(err);
481  }
482  catch(Exception& e)
483  {
484  FFStreamError err(e);
485  GNSSTK_THROW(err);
486  }
487  // end rod.time = parseTime(line, strm.header);
488 
489  // save for next call
490  previousTime = rod.time;
491  }
492 
493  // number of satellites
494  rod.numSVs = asInt(line.substr(29,3));
495 
496  // clock offset
497  if(line.size() > 68 )
498  rod.clockOffset = asDouble(line.substr(68, 12));
499  else
500  rod.clockOffset = 0.0;
501 
502  // Read the observations ...
503  if(rod.epochFlag==0 || rod.epochFlag==1 || rod.epochFlag==6)
504  {
505  // first read the SatIDs off the epoch line
506  int isv, ndx, line_ndx;
507  string satsys;
508  RinexSatID sat;
509  vector<RinexSatID> satIndex(rod.numSVs);
510  for(isv=1, ndx=0; ndx<rod.numSVs; isv++, ndx++)
511  {
512  if(!(isv % 13))
513  { // get a new continuation line
514  strm.formattedGetLine(line);
516  isv = 1;
517  if(line.size() > 80)
518  {
519  FFStreamError err("Invalid line size:" +
520  asString(line.size()));
521  GNSSTK_THROW(err);
522  }
523  }
524 
525  // read the sat id
526  try
527  {
528  sat = RinexSatID(line.substr(30+isv*3-1, 3));
529  satIndex[ndx] = sat;
530  }
531  catch (Exception& e)
532  {
533  FFStreamError ffse(e);
534  GNSSTK_THROW(ffse);
535  }
536  } // end loop over numSVs
537 
538  // number of R2 OTs in header
539  int numObs(strm.header.R2ObsTypes.size());
540  rod.obs.clear();
541  // loop over all sats, reading obs data
542  for(isv=0; isv < rod.numSVs; isv++)
543  {
544  sat = satIndex[isv]; // sat for this data
545  satsys = asString(sat.systemChar()); // system for this sat
546  vector<RinexDatum> data;
547  // loop over data in the line
548  for(ndx=0, line_ndx=0; ndx < numObs; ndx++, line_ndx++)
549  {
550  if(! (line_ndx % 5))
551  { // get a new line
552  strm.formattedGetLine(line);
554  line.resize(80, ' '); // pad just in case
555  line_ndx = 0;
556  if(line.size() > 80)
557  {
558  FFStreamError err("Invalid line size:" +
559  asString(line.size()));
560  GNSSTK_THROW(err);
561  }
562  }
563 
564  // does this R2 OT map into a valid R3 ObsID?
565  string R2ot(strm.header.R2ObsTypes[ndx]);
566  string R3ot(strm.header.mapSysR2toR3ObsID[satsys][R2ot].asString());
567  if(R3ot != string(" "))
568  {
569  RinexDatum tempData(line.substr(line_ndx*16, 16));
570  data.push_back(tempData);
571  }
572  }
573  rod.obs[sat] = data;
574 
575  } // end loop over sats to read obs data
576  }
577 
578  // ... or the auxiliary header information
579  else if(rod.numSVs > 0)
580  {
581  rod.auxHeader.clear();
582  for(int i=0; i<rod.numSVs; i++)
583  {
584  strm.formattedGetLine(line);
586  try
587  {
588  rod.auxHeader.parseHeaderRecord(line);
589  }
590  catch(FFStreamError& e)
591  {
592  GNSSTK_RETHROW(e);
593  }
594  catch(StringException& e)
595  {
596  GNSSTK_RETHROW(e);
597  }
598  }
599  }
600  rod.xmitAnt = strm.header.xmitAnt;
601  } // end void reallyGetRecordVer2(Rinex3ObsStream& strm, Rinex3ObsData& rod)
602 
603 
605  {
606  Rinex3ObsStream& strm = dynamic_cast<Rinex3ObsStream&>(ffs);
607 
608  // If the header hasn't been read, read it.
609  if(!strm.headerRead) strm >> strm.header;
610 
611  Rinex3ObsData rod;
612 
613  // clear out this ObsData
614  *this = rod;
615 
616  // call the version for RINEX ver 2
617  if(strm.header.version < 3)
618  {
619  try
620  {
621  reallyGetRecordVer2(strm, *this);
622  }
623  catch(Exception& e)
624  {
625  GNSSTK_RETHROW(e);
626  }
627  return;
628  }
629 
630  string line;
631 
632  // read the first (epoch) line
633  strm.formattedGetLine(line, true);
634  StringUtils::stripTrailing(line, " ");
635 
636  // Check and parse the epoch line -----------------------------------
637  // Check for epoch marker ('>') and following space.
638  if(line[0] != '>' || line[1] != ' ')
639  {
640  FFStreamError e("Bad epoch line: >" + line + "<");
641  GNSSTK_THROW(e);
642  }
643 
644  epochFlag = asInt(line.substr(31,1));
645  if(epochFlag < 0 || epochFlag > 6)
646  {
647  FFStreamError e("Invalid epoch flag: " + asString(epochFlag));
648  GNSSTK_THROW(e);
649  }
650 
651  time = parseTime(line, strm.header, strm.timesystem);
652 
653  numSVs = asInt(line.substr(32,3));
654 
655  if(line.size() > 41)
656  clockOffset = asDouble(line.substr(41,15));
657  else
658  clockOffset = 0.0;
659 
660  // Read the observations: SV ID and data ----------------------------
661  if(epochFlag == 0 || epochFlag == 1 || epochFlag == 6)
662  {
663  vector<RinexSatID> satIndex(numSVs);
664  map<RinexSatID, vector<RinexDatum> > tempDataMap;
665 
666  for(int isv = 0; isv < numSVs; isv++)
667  {
668  strm.formattedGetLine(line);
669  StringUtils::stripTrailing(line, " ");
670 
671  // get the SV ID
672  try
673  {
674  satIndex[isv] = RinexSatID(line.substr(0,3));
675  }
676  catch (Exception& e)
677  {
678  FFStreamError ffse(e);
679  GNSSTK_THROW(ffse);
680  }
681 
682  // get the # data items (# entries in ObsType map of
683  // maps from header)
684  string gnss = asString(satIndex[isv].systemChar());
685  int size = strm.header.mapObsTypes[gnss].size();
686 
687  // Some receivers leave blanks for missing Obs (which
688  // is OK by RINEX 3). If the last Obs are the ones
689  // missing, it won't necessarily be padded with spaces,
690  // so the parser will break. This adds the padding to
691  // let the parser do its job and interpret spaces as
692  // zeroes.
693  size_t minSize = 3 + 16*size;
694  if(line.size() < minSize)
695  line += string(minSize-line.size(), ' ');
696 
697  // get the data (# entries in ObsType map of maps from header)
698  vector<RinexDatum> data;
699  for(int i = 0; i < size; i++)
700  {
701  size_t pos = 3 + 16*i;
702  RinexDatum tempData(line.substr(pos,16));
703  data.push_back(tempData);
704  }
705  obs[satIndex[isv]] = data;
706  }
707  }
708 
709  // ... or the auxiliary header information
710  else if(numSVs > 0)
711  {
712  auxHeader.clear();
713  for(int i = 0; i < numSVs; i++)
714  {
715  strm.formattedGetLine(line);
717  try
718  {
720  }
721  catch(FFStreamError& e)
722  {
723  GNSSTK_RETHROW(e);
724  }
725  catch(StringException& e)
726  {
727  GNSSTK_RETHROW(e);
728  }
729  catch (Exception& e)
730  {
731  GNSSTK_RETHROW(e);
732  }
733  }
734  }
735 
736  xmitAnt = strm.header.xmitAnt;
737  return;
738 
739  } // end of reallyGetRecord()
740 
741 
743  const Rinex3ObsHeader& hdr,
744  const TimeSystem& ts) const
745  {
746  try
747  {
748  // check if the spaces are in the right place - an easy
749  // way to check if there's corruption in the file
750  if( (line[ 1] != ' ') || (line[ 6] != ' ') || (line[ 9] != ' ') ||
751  (line[12] != ' ') || (line[15] != ' ') || (line[18] != ' ') ||
752  (line[29] != ' ') || (line[30] != ' '))
753  {
754  FFStreamError e("Invalid time format");
755  GNSSTK_THROW(e);
756  }
757 
758  // if there's no time, just return a bad time
759  if(line.substr(2,27) == string(27, ' '))
761 
762  int year, month, day, hour, min;
763  double sec;
764 
765  year = asInt( line.substr( 2, 4));
766  month = asInt( line.substr( 7, 2));
767  day = asInt( line.substr(10, 2));
768  hour = asInt( line.substr(13, 2));
769  min = asInt( line.substr(16, 2));
770  sec = asDouble(line.substr(19, 11));
771 
772  // Real Rinex has epochs 'yy mm dd hr 59 60.0' surprisingly often.
773  double ds = 0;
774  if(sec >= 60.)
775  {
776  ds = sec;
777  sec = 0.0;
778  }
779 
781  if(ds != 0) rv += ds;
782 
783  rv.setTimeSystem(ts);
784 
785  return rv;
786  }
787  // string exceptions for substr are caught here
788  catch (std::exception &e)
789  {
790  FFStreamError err("std::exception: " + string(e.what()));
791  GNSSTK_THROW(err);
792  }
793  catch (gnsstk::Exception& e)
794  {
795  FFStreamError err(e);
796  GNSSTK_THROW(err);
797  }
798  } // end parseTime
799 
800  string Rinex3ObsData::writeTime(const CommonTime& ct) const
801  {
803  return string(26, ' ');
804 
805  CivilTime civtime(ct);
806  string line;
807 
808  line = string(1, ' ');
809  line += rightJustify(asString<short>(civtime.year ), 4);
810  line += string(1, ' ');
811  line += rightJustify(asString<short>(civtime.month ), 2, '0');
812  line += string(1, ' ');
813  line += rightJustify(asString<short>(civtime.day ), 2, '0');
814  line += string(1, ' ');
815  line += rightJustify(asString<short>(civtime.hour ), 2, '0');
816  line += string(1, ' ');
817  line += rightJustify(asString<short>(civtime.minute ), 2, '0');
818  line += rightJustify(asString (civtime.second,7),11);
819 
820  return line;
821  } // end writeTime
822 
824  {
825  return writeTime(time);
826  }
827 
828  void Rinex3ObsData::dump(std::ostream& s) const
829  {
830  if(obs.empty())
831  return;
832 
833  s << "Dump of Rinex3ObsData - time: " << writeTime(time)
834  << " epochFlag: " << " " << epochFlag
835  << " numSVs: " << numSVs
836  << fixed << setprecision(9) << " clk offset: " << clockOffset << endl;
837 
838  if(epochFlag == 0 || epochFlag == 1)
839  {
840  DataMap::const_iterator jt;
841  for(jt = obs.begin(); jt != obs.end(); jt++)
842  {
843  s << " " << (jt->first).toString() << ":" << fixed
844  << setprecision(3);
845  for(size_t i = 0; i < jt->second.size(); i++)
846  {
847  s << " " << setw(12) << jt->second[i].data
848  << "/" << jt->second[i].lli << "/" << jt->second[i].ssi;
849  }
850  s << endl;
851  }
852  }
853  else
854  {
855  s << "aux. header info:\n";
856  auxHeader.dump(s);
857  }
858  } // end dump
859 
860 
861  void Rinex3ObsData::dump(std::ostream& os, Rinex3ObsHeader& head) const
862  {
863  os << "Dump of Rinex3ObsData: "
864  << printTime(time,"%4F/%w/%10.3g = %04Y/%02m/%02d %02H:%02M:%02S")
865  << " flag " << epochFlag << " NSVs " << numSVs
866  << fixed << setprecision(6) << " clk " << clockOffset;
867 
868  if(obs.empty())
869  {
870  os << " : EMPTY" << endl;
871  return;
872  }
873  else os << endl;
874 
875  if(epochFlag >= 2)
876  {
877  os << "Auxiliary header:\n";
878  auxHeader.dump(os);
879  return;
880  }
881 
882  for(DataMap::const_iterator jt=obs.begin(); jt != obs.end(); jt++)
883  {
884  RinexSatID sat(jt->first);
885  const vector<RinexObsID>
886  types(head.mapObsTypes[sat.toString().substr(0,1)]);
887  os << " " << sat.toString() << fixed << setprecision(3);
888  for(size_t i=0; i<jt->second.size(); i++)
889  os << " " << setw(13) << jt->second[i].data
890  << "/" << jt->second[i].lli
891  << "/" << jt->second[i].ssi
892  << "/" << types[i].asString()
893  ;
894  os << endl;
895  }
896 
897  }
898 
899 }
gnsstk::StringUtils::asInt
long asInt(const std::string &s)
Definition: StringUtils.hpp:713
gnsstk::Rinex3ObsHeader::numberHeaderRecordsToBeWritten
int numberHeaderRecordsToBeWritten(void) const noexcept
Definition: Rinex3ObsHeader.cpp:293
gnsstk::reallyPutRecordVer2
void reallyPutRecordVer2(Rinex3ObsStream &strm, const Rinex3ObsData &rod)
Definition: Rinex3ObsData.cpp:56
gnsstk::Rinex3ObsData::reallyPutRecord
virtual void reallyPutRecord(FFStream &s) const
Definition: Rinex3ObsData.cpp:309
gnsstk::Rinex3ObsData::dump
virtual void dump(std::ostream &s) const
Definition: Rinex3ObsData.cpp:828
gnsstk::RinexDatum
Storage for single RINEX OBS data measurements.
Definition: RinexDatum.hpp:55
example6.day
day
Definition: example6.py:66
gnsstk::CivilTime::year
int year
Definition: CivilTime.hpp:198
gnsstk::FFStream
Definition: FFStream.hpp:119
gnsstk::BEGINNING_OF_TIME
const Epoch BEGINNING_OF_TIME(CommonTime::BEGINNING_OF_TIME)
Earliest representable Epoch.
StringUtils.hpp
example6.year
year
Definition: example6.py:64
gnsstk::Rinex3ObsData::timeString
std::string timeString() const
Definition: Rinex3ObsData.cpp:823
gnsstk::Rinex3ObsHeader
Definition: Rinex3ObsHeader.hpp:155
gnsstk::FFTextStream::formattedGetLine
void formattedGetLine(std::string &line, const bool expectEOF=false)
Definition: FFTextStream.cpp:149
gnsstk::Rinex3ObsData::obs
DataMap obs
the map of observations
Definition: Rinex3ObsData.hpp:114
gnsstk::Rinex3ObsStream::headerRead
bool headerRead
Whether or not the Rinex3ObsHeader has been read.
Definition: Rinex3ObsStream.hpp:107
gnsstk::Rinex3ObsHeader::writeHeaderRecords
void writeHeaderRecords(FFStream &s) const
Definition: Rinex3ObsHeader.cpp:345
gnsstk::Rinex3ObsHeader::getObsIndex
virtual std::size_t getObsIndex(const std::string &type) const
Definition: Rinex3ObsHeader.cpp:2502
gnsstk::FFTextStream::lineNumber
unsigned int lineNumber
Definition: FFTextStream.hpp:98
example6.hour
hour
Definition: example6.py:67
gnsstk::ObservationType::Channel
@ Channel
Channel number.
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::Rinex3ObsData::numSVs
short numSVs
Definition: Rinex3ObsData.hpp:109
gnsstk::CommonTime::setTimeSystem
CommonTime & setTimeSystem(TimeSystem timeSystem)
Definition: CommonTime.hpp:195
gnsstk::CommonTime::BEGINNING_OF_TIME
static const GNSSTK_EXPORT CommonTime BEGINNING_OF_TIME
earliest representable CommonTime
Definition: CommonTime.hpp:102
gnsstk::Rinex3ObsHeader::dump
virtual void dump(std::ostream &s) const
Definition: Rinex3ObsHeader.hpp:568
gnsstk::Rinex3ObsHeader::xmitAnt
XmitAnt xmitAnt
Non-standard, transmitter ID.
Definition: Rinex3ObsHeader.hpp:537
gnsstk::Rinex3ObsData::getObs
virtual RinexDatum getObs(const RinexSatID &svID, size_t index) const
Definition: Rinex3ObsData.cpp:224
gnsstk
For Sinex::InputHistory.
Definition: BasicFramework.cpp:50
gnsstk::reallyGetRecordVer2
void reallyGetRecordVer2(Rinex3ObsStream &strm, Rinex3ObsData &rod)
Definition: Rinex3ObsData.cpp:390
gnsstk::Rinex3ObsData::epochFlag
short epochFlag
Definition: Rinex3ObsData.hpp:104
gnsstk::TrackingCode::Standard
@ Standard
Legacy Glonass civil signal.
gnsstk::Rinex3ObsHeader::mapObsTypes
RinexObsMap mapObsTypes
SYS / # / OBS TYPES.
Definition: Rinex3ObsHeader.hpp:519
gnsstk::Exception
Definition: Exception.hpp:151
gnsstk::Rinex3ObsStream::header
Rinex3ObsHeader header
The header for this file.
Definition: Rinex3ObsStream.hpp:110
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::Rinex3ObsData::setObs
virtual void setObs(const RinexDatum &data, const RinexSatID &svID, const RinexObsID &obsID, const Rinex3ObsHeader &hdr)
Definition: Rinex3ObsData.cpp:266
gnsstk::Rinex3ObsData::time
CommonTime time
Time corresponding to the observations.
Definition: Rinex3ObsData.hpp:91
gnsstk::CivilTime::convertToCommonTime
virtual CommonTime convertToCommonTime() const
Definition: CivilTime.cpp:75
gnsstk::Rinex3ObsData::reallyGetRecord
virtual void reallyGetRecord(FFStream &s)
Definition: Rinex3ObsData.cpp:604
gnsstk::Rinex3ObsHeader::version
double version
RINEX 3 version/type.
Definition: Rinex3ObsHeader.hpp:481
example4.time
time
Definition: example4.py:103
example4.err
err
Definition: example4.py:126
RinexObsID.hpp
gnsstk::CommonTime
Definition: CommonTime.hpp:84
gnsstk::Rinex3ObsData
Definition: Rinex3ObsData.hpp:75
example6.clockOffset
clockOffset
Definition: example6.py:110
gnsstk::min
T min(const SparseMatrix< T > &SM)
Maximum element - return 0 if empty.
Definition: SparseMatrix.hpp:858
gnsstk::TimeSystem
TimeSystem
Definition of various time systems.
Definition: TimeSystem.hpp:51
gnsstk::Rinex3ObsData::xmitAnt
XmitAnt xmitAnt
Non-standard, transmitter ID.
Definition: Rinex3ObsData.hpp:118
gnsstk::Rinex3ObsHeader::mapSysR2toR3ObsID
VersionObsMap mapSysR2toR3ObsID
Definition: Rinex3ObsHeader.hpp:475
CivilTime.hpp
gnsstk::RinexObsID
Definition: RinexObsID.hpp:102
gnsstk::StringUtils::asDouble
double asDouble(const std::string &s)
Definition: StringUtils.hpp:705
Rinex3ObsData.hpp
gnsstk::XmitAnt
XmitAnt
Definition: XmitAnt.hpp:53
GNSSTK_RETHROW
#define GNSSTK_RETHROW(exc)
Definition: Exception.hpp:369
example4.pos
pos
Definition: example4.py:125
gnsstk::Rinex3ObsData::parseTime
CommonTime parseTime(const std::string &line, const Rinex3ObsHeader &hdr, const TimeSystem &ts) const
Definition: Rinex3ObsData.cpp:742
gnsstk::CivilTime::minute
int minute
Definition: CivilTime.hpp:202
gnsstk::Rinex3ObsHeader::R2ObsTypes
StringVec R2ObsTypes
Definition: Rinex3ObsHeader.hpp:471
gnsstk::Rinex3ObsStream
Definition: Rinex3ObsStream.hpp:65
example3.data
data
Definition: example3.py:22
gnsstk::Rinex3ObsData::clockOffset
double clockOffset
optional clock offset in seconds
Definition: Rinex3ObsData.hpp:112
gnsstk::CivilTime
Definition: CivilTime.hpp:55
gnsstk::StringUtils
Definition: IonexStoreStrategy.cpp:44
Rinex3ObsStream.hpp
gnsstk::StringUtils::rightJustify
std::string & rightJustify(std::string &s, const std::string::size_type length, const char pad=' ')
Definition: StringUtils.hpp:1557
gnsstk::RinexDatum::asString
std::string asString() const
Turn this datum into a RINEX OBS formatted string.
Definition: RinexDatum.cpp:107
gnsstk::RinexSatID::toString
std::string toString() const noexcept
Definition: RinexSatID.cpp:204
gnsstk::printTime
std::string printTime(const CommonTime &t, const std::string &fmt)
Definition: TimeString.cpp:64
gnsstk::ObsID::type
ObservationType type
Definition: ObsID.hpp:199
gnsstk::RinexSatID
Definition: RinexSatID.hpp:63
gnsstk::TimeSystem::GPS
@ GPS
GPS system time.
std
Definition: Angle.hpp:142
gnsstk::CivilTime::month
int month
Definition: CivilTime.hpp:199
gnsstk::Rinex3ObsHeader::clear
void clear()
Definition: Rinex3ObsHeader.cpp:180
gnsstk::CivilTime::second
double second
Definition: CivilTime.hpp:203
GNSSTK_THROW
#define GNSSTK_THROW(exc)
Definition: Exception.hpp:366
example6.month
month
Definition: example6.py:65
gnsstk::Rinex3ObsData::Rinex3ObsData
Rinex3ObsData()
Constructor.
Definition: Rinex3ObsData.cpp:215
gnsstk::Rinex3ObsData::writeTime
std::string writeTime(const CommonTime &dt) const
Definition: Rinex3ObsData.cpp:800
gnsstk::Rinex3ObsHeader::parseHeaderRecord
void parseHeaderRecord(std::string &line)
Definition: Rinex3ObsHeader.cpp:1066
example6.numSVs
numSVs
Definition: example6.py:112
TimeString.hpp
gnsstk::Rinex3ObsStream::timesystem
TimeSystem timesystem
Time system for epochs in this file.
Definition: Rinex3ObsStream.hpp:113
gnsstk::Rinex3ObsData::auxHeader
Rinex3ObsHeader auxHeader
auxiliary header records (epochFlag 2-5)
Definition: Rinex3ObsData.hpp:116
example6.epochFlag
epochFlag
Definition: example6.py:111
gnsstk::RinexSatID::systemChar
char systemChar() const noexcept
Definition: RinexSatID.cpp:62
gnsstk::CivilTime::hour
int hour
Definition: CivilTime.hpp:201
gnsstk::Rinex3ObsHeader::firstObs
CivilTime firstObs
TIME OF FIRST OBS.
Definition: Rinex3ObsHeader.hpp:524


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