SatPass.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 
40 
41 //------------------------------------------------------------------------------------
42 // system
43 #include <algorithm>
44 #include <ostream>
45 #include <string>
46 #include <vector>
47 // gnsstk
48 #include "RinexObsData.hpp"
49 #include "RinexObsHeader.hpp"
50 #include "RinexObsStream.hpp"
51 #include "RinexUtilities.hpp"
52 #include "SatPass.hpp"
53 #include "Stats.hpp"
54 #include "StringUtils.hpp"
55 #include "logstream.hpp"
56 #include "stl_helpers.hpp"
57 
58 //------------------------------------------------------------------------------------
59 using namespace std;
60 namespace gnsstk
61 {
62  using namespace StringUtils;
63 
64  /* ------------------ configuration --------------------------------
65  note that flag & LL1 = true for all L1 discontinuities
66  flag & LL2 = true for all L2 discontinuities */
67  const unsigned short SatPass::OK = 1; // good data, no discontinuity
68  const unsigned short SatPass::BAD = 0; // used by caller to mark bad data
69  const unsigned short SatPass::LL1 = 2; // discontinuity on L1 only
70  const unsigned short SatPass::LL2 = 4; // discontinuity on L2 only
71  const unsigned short SatPass::LL3 = 6; // discontinuity on L1 and L2
72  double SatPass::maxGap = 1800; // maximum gap (seconds) allowed within pass
73  int SatPass::outRound = 3; // round frac seconds in outFormat
74  string SatPass::outFormat =
75  string("%4F %10.3g"); // GPS week, seconds of week
76  string SatPass::longfmt =
77  string("%04Y/%02m/%02d %02H:%02M:%06.3f = %04F %10.3g");
78 
79  // constructors
80  SatPass::SatPass(const RinexSatID& insat, double indt)
81  {
82  vector<string> defaultObsTypes;
83  defaultObsTypes.push_back("L1");
84  defaultObsTypes.push_back("L2");
85  defaultObsTypes.push_back("P1");
86  defaultObsTypes.push_back("P2");
87 
88  init(insat, indt, defaultObsTypes);
89  }
90 
91  SatPass::SatPass(const RinexSatID& insat, double indt,
92  std::vector<std::string> obstypes)
93  {
94  init(insat, indt, obstypes);
95  }
96 
97  void SatPass::init(const RinexSatID& insat, double indt,
98  std::vector<std::string> obstypes)
99  {
100  sat = insat;
101  dt = indt;
102  // firstTime = CommonTime::BEGINNING_OF_TIME;
103  // lastTime = CommonTime::END_OF_TIME;
104  ngood = 0;
105  Status = 0;
106 
107  for (int i = 0; i < obstypes.size(); i++)
108  {
109  indexForLabel[obstypes[i]] = i;
110  labelForIndex[i] = obstypes[i];
111  }
112  }
113 
114  SatPass& SatPass::operator=(const SatPass& right)
115  {
116  if (&right != this)
117  {
118  Status = right.Status;
119  dt = right.dt;
120  sat = right.sat;
121  indexForLabel = right.indexForLabel;
122  labelForIndex = right.labelForIndex;
123  firstTime = right.firstTime;
124  lastTime = right.lastTime;
125  ngood = right.ngood;
126  spdvector.resize(right.spdvector.size());
127  for (int i = 0; i < right.spdvector.size(); i++)
128  spdvector[i] = right.spdvector[i];
129  }
130 
131  return *this;
132  }
133 
134  int SatPass::addData(const Epoch& tt, std::vector<std::string>& ots,
135  std::vector<double>& data)
136  {
137  vector<unsigned short> lli(data.size(), 0), ssi(data.size(), 0);
138  try
139  {
140  return addData(tt, ots, data, lli, ssi);
141  }
142  catch (Exception& e)
143  {
144  GNSSTK_RETHROW(e);
145  }
146  }
147 
148  // return -2 time tag out of order, data not added
149  // -1 gap is larger than MaxGap, data not added
150  // >=0 (success) index of the added data
151  int SatPass::addData(const Epoch& tt,
152  const std::vector<std::string>& obstypes,
153  const std::vector<double>& data,
154  const std::vector<unsigned short>& lli,
155  const std::vector<unsigned short>& ssi,
156  const unsigned short flag)
157  {
158  // check that data, lli and ssi have the same length - throw
159  if (data.size() != lli.size() || data.size() != ssi.size())
160  {
161  Exception e("Dimensions do not match in addData()" +
162  StringUtils::asString(data.size()) + "," +
163  StringUtils::asString(lli.size()) + "," +
164  StringUtils::asString(ssi.size()));
165  GNSSTK_THROW(e);
166  }
167  if (spdvector.size() > 0 && spdvector[0].data.size() != data.size())
168  {
169  Exception e(
170  "Error - addData passed different dimension that earlier!" +
171  StringUtils::asString(data.size()) +
172  " != " + StringUtils::asString(spdvector[0].data.size()));
173  GNSSTK_THROW(e);
174  }
175 
176  // create a new SatPassData
177  SatPassData spd(data.size());
178  spd.flag = flag;
179  for (int k = 0; k < data.size(); k++)
180  {
181  int i = indexForLabel[obstypes[k]];
182  spd.data[i] = data[k];
183  spd.lli[i] = lli[k];
184  spd.ssi[i] = ssi[k];
185  }
186 
187  // push_back defines count and
188  // returns : >=0 index of added data (ok), -1 gap, -2 tt out of order
189  return pushBack(tt, spd);
190  }
191 
192  /* return -4 robs was not obs data (header info)
193  -3 sat not found, data not added
194  -2 time tag out of order, data not added
195  -1 gap is larger than MaxGap, data not added
196  >=0 (success) index of the added data */
197  int SatPass::addData(const RinexObsData& robs)
198  {
199  if (robs.epochFlag != 0 && robs.epochFlag != 1)
200  {
201  return -4;
202  }
203 
204  RinexObsData::RinexSatMap::const_iterator it;
205  RinexObsData::RinexObsTypeMap::const_iterator jt;
206  map<string, unsigned int>::const_iterator kt;
207  SatPassData spd(indexForLabel.size());
208 
209  // loop over satellites
210  for (it = robs.obs.begin(); it != robs.obs.end(); it++)
211  {
212  if (it->first == sat)
213  { // sat is this->sat
214  spd.flag = OK;
215  // loop over obs
216  for (kt = indexForLabel.begin(); kt != indexForLabel.end(); kt++)
217  {
218  if ((jt = it->second.find(RinexObsHeader::convertObsType(
219  kt->first))) == it->second.end())
220  {
221  spd.data[kt->second] = 0.0;
222  spd.lli[kt->second] = 0;
223  spd.ssi[kt->second] = 0;
224  // spd.flag = BAD;// don't do this b/c spd may have 'empty'
225  // obs types
226  }
227  else
228  {
229  spd.data[kt->second] = jt->second.data;
230  spd.lli[kt->second] = jt->second.lli;
231  spd.ssi[kt->second] = jt->second.ssi;
232  if (jt->second.data == 0.0)
233  {
234  spd.flag = BAD;
235  }
236  }
237  } // end loop over obs
238 
239  return pushBack(robs.time, spd);
240  }
241  }
242  return -3; // sat was not found
243  }
244 
245  /* Truncate all data at and after the given time.
246  return -1 if ttag is at or before the start of this pass,
247  return +1 if ttag is at or after the end of this pass,
248  else return 0 */
249  int SatPass::trimAfter(const Epoch ttag)
250  {
251  try
252  {
253  if (ttag <= firstTime)
254  {
255  return -1;
256  }
257  if (ttag >= lastTime)
258  {
259  return 1;
260  }
261 
262  // find the count for this time limit
263  int count = countForTime(ttag);
264  // if(count == -1) return 1; // 4/16/13
265  if (count < 0)
266  {
267  return -1;
268  }
269 
270  unsigned int i, j, n(0); // count for ngood
271  for (i = 0; i < spdvector.size(); i++)
272  {
273  if (spdvector[i].ndt >= static_cast<unsigned int>(count))
274  {
275  j = i;
276  break;
277  }
278  if (spdvector[i].flag != SatPass::BAD)
279  {
280  n++;
281  }
282  }
283  if (j > -1)
284  {
285  spdvector.resize(j + 1);
286  lastTime = time(j);
287  ngood = n;
288  }
289  else
290  {
291  return 1; // also should never happen ... handled above
292  }
293 
294  return 0;
295  }
296  catch (Exception& e)
297  {
298  GNSSTK_RETHROW(e);
299  }
300  }
301 
302  /* compute the GLO channel
303  start at n, then set n before returning; return false if failure
304  challenge is at low elevation, L1 is slightly better than L2, but need
305  both return true if successful, false if failed; also return string msg,
306  which is FINAL sat n week sow(beg) week sow(end) npts stddev slope sl/std
307  stddev(slope) [??] NB if "??" appears at end of msg, result is
308  questionable (stddev(slope) is high) */
309  bool SatPass::getGLOchannel(int& n, std::string& msg)
310  {
311  try
312  {
313  if (sat.system != SatelliteSystem::Glonass)
314  {
315  return false;
316  }
317 
318  // make sure L1, L2, C1/P1, P2 are present
319  bool useC1 = false;
320  map<string, unsigned int>::const_iterator it;
321  if (indexForLabel.find("L1") == indexForLabel.end() ||
322  indexForLabel.find("L2") == indexForLabel.end() ||
323  (indexForLabel.find("C1") == indexForLabel.end() &&
324  indexForLabel.find("P1") == indexForLabel.end()) ||
325  (indexForLabel.find("P2") == indexForLabel.end() &&
326  indexForLabel.find("C2") == indexForLabel.end()))
327  {
328  Exception e(
329  "Obs types L1 L2 C1/P1 C2/P2 required for GLOchannel()");
330  GNSSTK_THROW(e);
331  }
332  if (indexForLabel.find("P1") == indexForLabel.end())
333  {
334  useC1 = true;
335  }
336 
337  /* transformation matrix
338  PB = D * L - P pure biases = constants for continuous phase
339  RB = D * PB real biases = wavelength * N
340  but DD=1 so **( RB = DDL-DP = L-DP )**
341  dbL = L - RB debiased phase
342  smR = D * dbL smoothed range
343  1 [ a+2 -2 ]
344  D = -- [ ]
345  a [ 2a+2 -(a+2) ] */
346  static const double alpha =
347  ((9. / 7.) * (9. / 7.) - 1.0); // ionospheric constant
348  static const double D11 = (alpha + 2.) / alpha;
349  static const double D12 = -2. / alpha;
350  static const double D21 = (2 * alpha + 2.) / alpha;
351  static const double D22 = -D11;
352 
353  bool first, done, ok;
354  int i, dn, di, sign(0);
355  const int N(spdvector.size());
356  double pP1, pP2, pL1, pL2, pRB1, pRB2;
357  TwoSampleStats<double> dN1, dN2;
358  static const double testStdDev(40.0), testSlope(0.1), testRatio(10.0),
359  testSigma(.25);
360  vector<int> dnSeen;
361 
362  if (n < -7 || n > 7)
363  {
364  n = 0; // just in case
365  }
366  dn = 0;
367  di = (N > 50 ? N / 50 : 1); // want about 50 points total
368 
369  while (1)
370  { // loop over possible choices for n
371  done = ok = true;
372  dN1.Reset();
373  dN2.Reset();
374 
375  // nominal wavelengths
376  double wl1(C_MPS / (1602.0e6 + (n + dn) * 562.5e3));
377  double wl2(C_MPS / (1246.0e6 + (n + dn) * 437.5e3));
378 
379  // compute the slope of dBias vs dL: biases B = L - DP
380  first = true;
381  for (i = 0; i < N; i += di)
382  {
383  if (!(spdvector[i].flag & OK))
384  {
385  continue; // skip bad data
386  }
387 
388  double P1 =
389  spdvector[i].data[indexForLabel[(useC1 ? "C1" : "P1")]];
390  double P2 = spdvector[i].data[indexForLabel["P2"]];
391  double L1 = spdvector[i].data[indexForLabel["L1"]];
392  double L2 = spdvector[i].data[indexForLabel["L2"]];
393  double RB1 = wl1 * L1 - D11 * P1 - D12 * P2;
394  double RB2 = wl2 * L2 - D21 * P1 - D22 * P2;
395 
396  if (!first &&
397  (::fabs(RB1 - pRB1) > 2000. || ::fabs(RB2 - pRB2) > 2000. ||
398  ::fabs(L1 - pL1) / 2848. > 1000. ||
399  ::fabs(L2 - pL2) / 2848. > 1000.))
400  {
401  first = true;
402  continue;
403  }
404 
405  if (!first)
406  {
407  dN1.Add((-L1 + pL1) / 2848., RB1 - pRB1); // X,Y
408  dN2.Add((-L2 + pL2) / 2848., RB2 - pRB2);
409 
410  LOG(DEBUG)
411  << "GLODMP " << sat << " " << setw(2) << n + dn << " "
412  << printTime(time(i), outFormat) << fixed
413  << setprecision(2) << " " << setw(9) << RB1 - pRB1 << " "
414  << setw(9) << -(L1 - pL1) / 2848. << " " << setw(4)
415  << dN1.N() << " " << setw(9) << dN1.StdDevY() << " "
416  << setw(9) << (dN1.N() > 1 ? dN1.Slope() : 0.0) << " "
417  << setw(9) << (dN1.N() > 1 ? dN1.SigmaSlope() : 0.0) << " "
418  << setw(9) << RB2 - pRB2 << " " << setw(9)
419  << -(L2 - pL2) / 2848. << " " << setw(4) << dN2.N() << " "
420  << setw(9) << dN2.StdDevY() << " " << setw(9)
421  << (dN1.N() > 1 ? dN2.Slope() : 0.0) << " " << setw(9)
422  << (dN1.N() > 1 ? dN2.SigmaSlope() : 0.0);
423  }
424  else
425  {
426  first = false;
427  }
428 
429  pL1 = L1;
430  pL2 = L2;
431  pP1 = P1;
432  pP2 = P2;
433  pRB1 = RB1;
434  pRB2 = RB2;
435 
436  } // end for loop over data
437 
438  if (dN1.N() == 0)
439  {
440  return false; // no data
441  }
442 
443  int m(dn); // save for LOG stmt
444 
445  /* ------------------ tests -------------------------------------
446  -slope/Dn is 0.1877 for L1, 0.2413 for L2
447  this fails if SigmaSlope is big >~ 1 //dN1.SigmaSlope() <
448  testSigma && */
449  if (dN1.StdDevY() < testStdDev && ::fabs(dN1.Slope()) < testSlope &&
450  ::fabs(dN1.Slope()) / dN1.SigmaSlope() < testRatio)
451  {
452  done = true; // success
453  }
454  else
455  { // haven't found it yet
456  done = false;
457 
458  // save this dn so its not repeated
459  dnSeen.push_back(dn);
460 
461  // compute a new dn
462  int dm =
463  -int((dN1.Slope() < 0 ? -0.5 : 0.5) + dN1.Slope() / 0.1877);
464  if (::abs(dm) > 5 || n + dn + dm < -7 || n + dn + dm > 7 ||
465  dm == 0 || dN1.SigmaSlope() > testSigma)
466  {
467  if (dN1.Slope() < 0)
468  {
469  ++dn;
470  }
471  else
472  {
473  --dn;
474  }
475  }
476  else
477  {
478  dn += dm;
479  }
480 
481  if (n + dn > 7 || n + dn < -7)
482  { // failure - n+dn too big
483  msg = string("out of range : n+dn=") + asString(n + dn);
484  ok = false;
485  }
486  if (vectorindex(dnSeen, dn) != -1)
487  {
488  msg = string("failed to converge : n+dn=") + asString(n + dn);
489  ok = false;
490  }
491  }
492 
493  LOG(DEBUG) << "GETGLO " << setw(2) << n + m << " PRELIM " << sat
494  << fixed << setprecision(2) << " " << setw(2) << dN1.N()
495  << " " << setw(9) << dN1.StdDevY() << " ("
496  << setprecision(0) << testStdDev << ")"
497  << setprecision(2) << " " << setprecision(3) << setw(10)
498  << dN1.Slope() << " (" << testSlope << ")"
499  << setprecision(2) << " " << setw(9)
500  << dN1.Slope() / dN1.SigmaSlope() << " ("
501  << setprecision(0) << testRatio << ")" << setprecision(2)
502  << " " << setw(9) << dN1.SigmaSlope() << " ("
503  << testSigma
504  << ")"
505  //<< " " << setw(9) << dN2.StdDevY()
506  //<< " " << setw(9) << dN2.Slope()
507  //<< " " << setw(9) << dN2.Slope()/dN1.SigmaSlope()
508  << " " << (done ? "DONE" : "NOPE");
509 
510  if (done || !ok)
511  {
512  break;
513  }
514 
515  } // end while
516 
517  if (!ok)
518  {
519  return false;
520  }
521 
522  ostringstream oss;
523  oss << "FINAL" << fixed << setprecision(6) << " " << sat << " "
524  << setw(2) << n + dn << " "
525  << printTime(getFirstGoodTime(), outFormat) << " "
526  << printTime(getLastGoodTime(), outFormat) << fixed
527  << setprecision(4) << " " << setw(2) << dN1.N() << " " << setw(8)
528  << dN1.StdDevY() << " " << setw(8) << dN1.Slope() << " " << setw(8)
529  << dN1.Slope() / dN1.SigmaSlope() << " " << setw(8)
530  << dN1.SigmaSlope() << " "
531  << (dN1.SigmaSlope() < testSigma ? "" : "??")
532  //<< " " << setw(2) << dN2.N()
533  //<< " " << setw(8) << dN2.StdDevY()
534  //<< " " << setw(8) << dN2.Slope()
535  //<< " " << setw(8) << dN2.Slope()/dN2.SigmaSlope()
536  ;
537 
538  msg = oss.str();
539  n = n + dn;
540 
541  return true;
542  }
543  catch (Exception& e)
544  {
545  GNSSTK_RETHROW(e);
546  }
547  }
548 
549  /* Smooth pseudorange and debias phase; replace the data only if the
550  corresponding input flag is 'true'; use real bias for pseudorange, integer
551  (cycles) for phase. Single frequency version: requires obs types Lf C/Pf
552  Call this ONLY after cycleslips have been removed. */
553  void SatPass::smoothSF(bool smoothPR, bool debiasPH,
554  std::string& msg, const int freq, double wl)
555  {
556  try
557  {
558  if (freq != 1 && freq != 2)
559  {
560  GNSSTK_THROW(Exception("smoothSF requires freq 1 or 2"));
561  }
562 
563  // make sure Lf, Cf/Pf are present
564  ostringstream oss;
565  if (freq == 1 && !hasType("L1"))
566  {
567  oss << " L1";
568  }
569  if (freq == 2 && !hasType("L2"))
570  {
571  oss << " L2";
572  }
573  if (freq == 1 && !hasType("C1") && !hasType("P1"))
574  {
575  oss << " C/P1";
576  }
577  if (freq == 2 && !hasType("C2") && !hasType("P2"))
578  {
579  oss << " C/P2";
580  }
581  if (!oss.str().empty())
582  {
584  string("smoothSF() requires pseudorange and phase:" + oss.str() +
585  string(" are missing."))));
586  }
587 
588  bool first, useC1(hasType("C1")), useC2(hasType("C2"));
589  int i;
590  double RB, dLB0(0.0);
591  long LB, LB0;
592  Stats<double> PB;
593 
594  // get the biases B = L - P
595  for (first = true, i = 0; i < spdvector.size(); i++)
596  {
597  if (!(spdvector[i].flag & OK))
598  {
599  continue; // skip bad data
600  }
601 
602  double P, L;
603  if (freq == 1)
604  {
605  P = spdvector[i].data[indexForLabel[(useC1 ? "C1" : "P1")]];
606  }
607  else
608  {
609  P = spdvector[i].data[indexForLabel[(useC2 ? "C2" : "P2")]];
610  }
611  if (freq == 1)
612  {
613  L = spdvector[i].data[indexForLabel["L1"]];
614  }
615  else
616  {
617  L = spdvector[i].data[indexForLabel["L2"]];
618  }
619 
620  if (first)
621  { // remove the large numerical range
622  LB0 = long(L - P / wl);
623  dLB0 = double(LB0);
624  }
625  L -= dLB0;
626 
627  // Bias = L(m) - P
628  RB = wl * L - P;
629  PB.Add(RB);
630 
631  if (first)
632  {
633  LOG(DEBUG) << "SMTDMP sat week sow RmP L P RB LB0";
634  }
635  LOG(DEBUG) << "SMTDMP " << sat << " " << time(i).printf(outFormat)
636  << fixed << setprecision(3) << " " << setw(13) << RB
637  << " " << setw(13) << L << " " << setw(13) << P << " "
638  << setw(13) << RB << " " << setw(13) << LB0;
639 
640  first = false;
641  } // end loop over data
642 
643  RB = PB.Average() / wl; // real bias in cycles
644  LB = LB0 + long(RB + (RB > 0 ? 0.5 : -0.5)); // integer bias (cycles)
645 
646  oss.str("");
647  oss << "SMT" << fixed << setprecision(2) << " " << sat << " "
648  << getFirstGoodTime().printf(outFormat) << " "
649  << getLastGoodTime().printf(outFormat) << " " << setw(5)
650  << (freq == 1 ? PB.N() : 0) << " " << setw(12)
651  << (freq == 1 ? PB.Average() + dLB0 : 0) << " " << setw(5)
652  << (freq == 1 ? PB.StdDev() : 0) << " " << setw(12)
653  << (freq == 1 ? PB.Minimum() + dLB0 : 0) << " " << setw(12)
654  << (freq == 1 ? PB.Maximum() + dLB0 : 0) << " " << setw(5)
655  << (freq == 1 ? 0 : PB.N()) << " " << setw(12)
656  << (freq == 1 ? 0 : PB.Average() + dLB0) << " " << setw(5)
657  << (freq == 1 ? 0 : PB.StdDev()) << " " << setw(12)
658  << (freq == 1 ? 0 : PB.Minimum() + dLB0) << " " << setw(12)
659  << (freq == 1 ? 0 : PB.Maximum() + dLB0) << " " << setw(13)
660  << (freq == 1 ? RB : 0) << " " << setw(13) << (freq == 1 ? 0 : RB)
661  << " " << setw(10) << (freq == 1 ? LB : 0) << " " << setw(10)
662  << (freq == 1 ? 0 : LB);
663  msg = oss.str();
664 
665  if (!debiasPH && !smoothPR)
666  {
667  return;
668  }
669 
670  for (i = 0; i < spdvector.size(); i++)
671  {
672  if (!(spdvector[i].flag & OK))
673  {
674  continue; // skip bad data
675  }
676 
677  // replace the pseudorange with the smoothed pseudorange
678  if (smoothPR)
679  {
680  // compute the debiased phase, with real bias
681  if (freq == 1)
682  {
683  spdvector[i].data[indexForLabel[(useC1 ? "C1" : "P1")]] =
684  spdvector[i].data[indexForLabel["L1"]] - RB;
685  }
686  else if (freq == 2)
687  {
688  spdvector[i].data[indexForLabel[(useC2 ? "C2" : "P2")]] =
689  spdvector[i].data[indexForLabel["L2"]] - RB;
690  }
691  }
692 
693  // replace the phase with the debiased phase, with integer bias
694  // (cycles)
695  if (debiasPH)
696  {
697  if (freq == 1)
698  {
699  spdvector[i].data[indexForLabel["L1"]] -= LB;
700  }
701  if (freq == 2)
702  {
703  spdvector[i].data[indexForLabel["L2"]] -= LB;
704  }
705  }
706  }
707  }
708  catch (Exception& e)
709  {
710  GNSSTK_RETHROW(e);
711  }
712  }
713 
714  /* Smooth pseudorange and debias phase; replace the data only if the
715  corresponding input flag is 'true'; use real bias for pseudorange, integer
716  (cycles) for phase. Call this ONLY after cycleslips have been removed. */
717  void SatPass::smooth(bool smoothPR, bool debiasPH,
718  std::string& msg, const double& wl1, const double& wl2)
719  {
720  try
721  {
722  ostringstream oss;
723 
724  // make sure L1, L2, C1/P1, C2/P2 are present
725  if (!hasType("L1"))
726  {
727  oss << " L1";
728  }
729  if (!hasType("L2"))
730  {
731  oss << " L2";
732  }
733  if (!hasType("C1") && !hasType("P1"))
734  {
735  oss << " C/P1";
736  }
737  if (!hasType("C2") && !hasType("P2"))
738  {
739  oss << " C/P2";
740  }
741  if (!oss.str().empty())
742  {
744  string("smooth() requires obs types L1 L2 C/P1 C/P2:") +
745  oss.str() + string(" missing.")));
746  }
747 
748  bool useC1(hasType("C1")), useC2(hasType("C2"));
749 
750  /* transformation matrix
751  PB = D * L - P pure biases = constants for continuous phase
752  RB = D * PB real biases = wavelength * N
753  but DD=1 so **( RB = DDL-DP = L-DP )**
754  dbL = L - RB debiased phase
755  smR = D * dbL smoothed range
756  1 [ a+2 -2 ]
757  D = -- [ ]
758  a [ 2a+2 -(a+2) ] */
759  const double alpha =
760  ((wl2 / wl1) * (wl2 / wl1) - 1.0); // ionospheric constant
761  const double D11 = (alpha + 2.) / alpha;
762  const double D12 = -2. / alpha;
763  const double D21 = (2 * alpha + 2.) / alpha;
764  const double D22 = -D11;
765 
766  bool first;
767  int i;
768  double RB1, RB2, dbL1, dbL2, dLB10(0.0), dLB20(0.0);
769  long LB1, LB2, LB10, LB20;
770  Stats<double> PB1, PB2;
771 
772  // get the biases B = L - DP
773  for (first = true, i = 0; i < spdvector.size(); i++)
774  {
775  if (!(spdvector[i].flag & OK))
776  {
777  continue; // skip bad data
778  }
779 
780  double P1 = spdvector[i].data[indexForLabel[(useC1 ? "C1" : "P1")]];
781  double P2 = spdvector[i].data[indexForLabel[(useC2 ? "C2" : "P2")]];
782  double L1 = spdvector[i].data[indexForLabel["L1"]] - dLB10;
783  double L2 = spdvector[i].data[indexForLabel["L2"]] - dLB20;
784 
785  if (first)
786  { // remove the large numerical range
787  LB10 = long(L1 - P1 / wl1);
788  LB20 = long(L2 - P2 / wl2);
789  dLB10 = double(LB10);
790  dLB20 = double(LB20);
791  L1 -= dLB10;
792  L2 -= dLB20;
793  }
794 
795  // Bias = L(m) - D*P
796  RB1 = wl1 * L1 - D11 * P1 - D12 * P2;
797  RB2 = wl2 * L2 - D21 * P1 - D22 * P2;
798 
799  if (first)
800  {
801  dbL1 = RB1;
802  dbL2 = RB2;
803  first = false;
804  }
805 
806  PB1.Add(RB1 - dbL1);
807  PB2.Add(RB2 - dbL2);
808 
809  LOG(DEBUG) << "SMTDMP " << sat << " "
810  << printTime(time(i), outFormat) << fixed
811  << setprecision(3) << " " << setw(13) << RB1 - dbL1
812  << " " << setw(13) << RB2 - dbL2 << " " << setw(13) << L1
813  << " " << setw(13) << L2 << " " << setw(13) << P1 << " "
814  << setw(13) << P2 << " " << setw(13) << RB1 << " "
815  << setw(13) << RB2;
816  }
817 
818  // real biases in cycles
819  RB1 = (dbL1 + PB1.Average()) / wl1;
820  RB2 = (dbL2 + PB2.Average()) / wl2;
821  // integer biases (cycles)
822  LB1 = LB10 + long(RB1 + (RB1 > 0 ? 0.5 : -0.5));
823  LB2 = LB20 + long(RB2 + (RB2 > 0 ? 0.5 : -0.5));
824 
825  oss.str("");
826  oss << "SMT" << fixed << setprecision(2) << " " << sat << " "
827  << printTime(getFirstGoodTime(), outFormat) << " "
828  << printTime(getLastGoodTime(), outFormat) << " " << setw(5)
829  << PB1.N() << " " << setw(12) << PB1.Average() + dbL1 << " "
830  << setw(5) << PB1.StdDev() << " " << setw(12)
831  << PB1.Minimum() + dbL1 << " " << setw(12) << PB1.Maximum() + dbL1
832  << " " << setw(5) << PB2.N() << " " << setw(12)
833  << PB2.Average() + dbL2 << " " << setw(5) << PB2.StdDev() << " "
834  << setw(12) << PB2.Minimum() + dbL2 << " " << setw(12)
835  << PB2.Maximum() + dbL2 << " " << setw(13) << RB1 << " "
836  << setw(13) << RB2 << " " << setw(10) << LB1 << " " << setw(10)
837  << LB2;
838  msg = oss.str();
839 
840  if (!debiasPH && !smoothPR)
841  {
842  return;
843  }
844 
845  for (i = 0; i < spdvector.size(); i++)
846  {
847  if (!(spdvector[i].flag & OK))
848  {
849  continue; // skip bad data
850  }
851 
852  // replace the pseudorange with the smoothed pseudorange
853  if (smoothPR)
854  {
855  // compute the debiased phase, with real bias
856  dbL1 = spdvector[i].data[indexForLabel["L1"]] - RB1;
857  dbL2 = spdvector[i].data[indexForLabel["L2"]] - RB2;
858 
859  spdvector[i].data[indexForLabel[(useC1 ? "C1" : "P1")]] =
860  D11 * wl1 * dbL1 + D12 * wl2 * dbL2;
861  spdvector[i].data[indexForLabel[(useC2 ? "C2" : "P2")]] =
862  D21 * wl1 * dbL1 + D22 * wl2 * dbL2;
863  }
864 
865  // replace the phase with the debiased phase, with integer bias
866  // (cycles)
867  if (debiasPH)
868  {
869  spdvector[i].data[indexForLabel["L1"]] -= LB1;
870  spdvector[i].data[indexForLabel["L2"]] -= LB2;
871  }
872  }
873  }
874  catch (Exception& e)
875  {
876  GNSSTK_RETHROW(e);
877  }
878  }
879 
880  // -------------------------- get and set routines
881  // ---------------------------- NB may be used as rvalue or lvalue
882  double& SatPass::data(unsigned int i, const std::string& type)
883  {
884  if (i >= spdvector.size())
885  {
886  Exception e("Invalid index in data() " + asString(i));
887  GNSSTK_THROW(e);
888  }
889  map<string, unsigned int>::const_iterator it;
890  if ((it = indexForLabel.find(type)) == indexForLabel.end())
891  {
892  Exception e("Invalid obs type in data() " + type);
893  GNSSTK_THROW(e);
894  }
895  return spdvector[i].data[it->second];
896  }
897 
898  double& SatPass::timeoffset(unsigned int i)
899  {
900  if (i >= spdvector.size())
901  {
902  Exception e("Invalid index in timeoffset() " + asString(i));
903  GNSSTK_THROW(e);
904  }
905  return spdvector[i].toffset;
906  }
907 
908  unsigned short& SatPass::LLI(unsigned int i, const std::string& type)
909  {
910  if (i >= spdvector.size())
911  {
912  Exception e("Invalid index in LLI() " + asString(i));
913  GNSSTK_THROW(e);
914  }
915  map<string, unsigned int>::const_iterator it;
916  if ((it = indexForLabel.find(type)) == indexForLabel.end())
917  {
918  Exception e("Invalid obs type in LLI() " + type);
919  GNSSTK_THROW(e);
920  }
921  return spdvector[i].lli[it->second];
922  }
923 
924  unsigned short& SatPass::SSI(unsigned int i, const std::string& type)
925  {
926  if (i >= spdvector.size())
927  {
928  Exception e("Invalid index in SSI() " + asString(i));
929  GNSSTK_THROW(e);
930  }
931  map<string, unsigned int>::const_iterator it;
932  if ((it = indexForLabel.find(type)) == indexForLabel.end())
933  {
934  Exception e("Invalid obs type in SSI() " + type);
935  GNSSTK_THROW(e);
936  }
937  return spdvector[i].ssi[it->second];
938  }
939 
940  // ---------------------------------- set routines
941  // ----------------------------
942  void SatPass::setFlag(unsigned int i, unsigned short f)
943  {
944  if (i >= spdvector.size())
945  {
946  Exception e("Invalid index in setFlag() " + asString(i));
947  GNSSTK_THROW(e);
948  }
949 
950  if (spdvector[i].flag != BAD && f == BAD)
951  {
952  ngood--;
953  }
954  if (spdvector[i].flag == BAD && f != BAD)
955  {
956  ngood++;
957  }
958  spdvector[i].flag = f;
959  }
960 
961  /* set the userflag at one index to inflag;
962  NB SatPass does nothing w/ this member except setUserFlag() and
963  getUserFlag(); */
964  void SatPass::setUserFlag(unsigned int i, unsigned int f)
965  {
966  if (i >= spdvector.size())
967  {
968  Exception e("Invalid index in setUserFlag() " + asString(i));
969  GNSSTK_THROW(e);
970  }
971 
972  spdvector[i].userflag = f;
973  }
974 
975  // ---------------------------------- get routines
976  // ---------------------------- get value of flag at one index
977  unsigned short SatPass::getFlag(unsigned int i) const
978  {
979  if (i >= spdvector.size())
980  {
981  Exception e("Invalid index in getFlag() " + asString(i));
982  GNSSTK_THROW(e);
983  }
984  return spdvector[i].flag;
985  }
986 
987  /* get the userflag at one index
988  NB SatPass does nothing w/ this member except setUserFlag() and
989  getUserFlag(); */
990  unsigned int SatPass::getUserFlag(unsigned int i) const
991  {
992  if (i >= spdvector.size())
993  {
994  Exception e("Invalid index in getUserFlag() " + asString(i));
995  GNSSTK_THROW(e);
996  }
997  return spdvector[i].userflag;
998  }
999 
1000  // get one element of the count array of this SatPass
1001  unsigned int SatPass::getCount(unsigned int i) const
1002  {
1003  if (i >= spdvector.size())
1004  {
1005  Exception e("invalid in getCount() " + asString(i));
1006  GNSSTK_THROW(e);
1007  }
1008  return spdvector[i].ndt;
1009  }
1010 
1011  // @return the earliest time (full, including toffset) in this SatPass data
1012  Epoch SatPass::getFirstTime() const { return time(0); }
1013 
1014  // @return the latest time (full, including toffset) in this SatPass data
1015  Epoch SatPass::getLastTime() const
1016  {
1017  return time(spdvector.size() - 1);
1018  }
1019 
1020  /* these allow you to get e.g. P1 or C1. NB return double not double& as
1021  above: rvalue */
1022  double SatPass::data(unsigned int i, const std::string& type1,
1023  const std::string& type2) const
1024  {
1025  if (i >= spdvector.size())
1026  {
1027  Exception e("Invalid index in data() " + asString(i));
1028  GNSSTK_THROW(e);
1029  }
1030  map<string, unsigned int>::const_iterator it;
1031  if ((it = indexForLabel.find(type1)) != indexForLabel.end())
1032  {
1033  return spdvector[i].data[it->second];
1034  }
1035  else if ((it = indexForLabel.find(type2)) != indexForLabel.end())
1036  {
1037  return spdvector[i].data[it->second];
1038  }
1039  else
1040  {
1041  Exception e("Invalid obs types in data() " + type1 + " " + type2);
1042  GNSSTK_THROW(e);
1043  }
1044  }
1045 
1046  unsigned short SatPass::LLI(unsigned int i, const std::string& type1,
1047  const std::string& type2)
1048  {
1049  if (i >= spdvector.size())
1050  {
1051  Exception e("Invalid index in LLI() " + asString(i));
1052  GNSSTK_THROW(e);
1053  }
1054  map<string, unsigned int>::const_iterator it;
1055  if ((it = indexForLabel.find(type1)) != indexForLabel.end())
1056  {
1057  return spdvector[i].lli[it->second];
1058  }
1059  else if ((it = indexForLabel.find(type2)) != indexForLabel.end())
1060  {
1061  return spdvector[i].lli[it->second];
1062  }
1063  else
1064  {
1065  Exception e("Invalid obs types in LLI() " + type1 + " " + type2);
1066  GNSSTK_THROW(e);
1067  }
1068  }
1069 
1070  unsigned short SatPass::SSI(unsigned int i, const std::string& type1,
1071  const std::string& type2)
1072  {
1073  if (i >= spdvector.size())
1074  {
1075  Exception e("Invalid index in SSI() " + asString(i));
1076  GNSSTK_THROW(e);
1077  }
1078  map<string, unsigned int>::const_iterator it;
1079  if ((it = indexForLabel.find(type1)) == indexForLabel.end())
1080  {
1081  return spdvector[i].ssi[it->second];
1082  }
1083  else if ((it = indexForLabel.find(type2)) == indexForLabel.end())
1084  {
1085  return spdvector[i].ssi[it->second];
1086  }
1087  else
1088  {
1089  Exception e("Invalid obs types in SSI() " + type1 + " " + type2);
1090  GNSSTK_THROW(e);
1091  }
1092  }
1093 
1094  /* ---------------------------------- utils
1095  ----------------------------------- return the time corresponding to the
1096  given index in the data array */
1097  Epoch SatPass::time(unsigned int i) const
1098  {
1099  if (i >= spdvector.size())
1100  {
1101  Exception e("Invalid index in time() " + asString(i));
1102  GNSSTK_THROW(e);
1103  }
1104  // computing toff first is necessary to avoid a rare bug in Epoch..
1105  double toff = spdvector[i].ndt * dt + spdvector[i].toffset;
1106  return (firstTime + toff);
1107  }
1108 
1109  // return true if the input time could lie within the pass
1110  bool SatPass::includesTime(const Epoch& tt) const
1111  {
1112  if (tt < firstTime)
1113  {
1114  if ((firstTime - tt) > maxGap)
1115  {
1116  return false;
1117  }
1118  }
1119  else if (tt > lastTime)
1120  {
1121  if ((tt - lastTime) > maxGap)
1122  {
1123  return false;
1124  }
1125  }
1126  return true;
1127  }
1128 
1129  /* create a new SatPass from the given one, starting at count N.
1130  modify this SatPass to end just before N.
1131  return true if successful. */
1132  bool SatPass::split(int N, SatPass& newSP)
1133  {
1134  try
1135  {
1136  int i, j, n, oldgood, ilast;
1137  Epoch tt;
1138 
1139  newSP = SatPass(sat, dt); // create new SatPass
1140  newSP.Status = Status;
1141  newSP.indexForLabel = indexForLabel;
1142  newSP.labelForIndex = labelForIndex;
1143 
1144  oldgood = ngood;
1145  ngood = ilast = 0;
1146  for (i = 0; i < spdvector.size(); i++)
1147  { // loop over all data
1148  n = spdvector[i].ndt;
1149  tt = time(i);
1150  if (n < N)
1151  { // keep in this SatPass
1152  if (spdvector[i].flag != BAD)
1153  {
1154  ngood++;
1155  }
1156  ilast = i;
1157  }
1158  else
1159  { // copy out data into new SP
1160  if (n == N)
1161  {
1162  newSP.ngood = oldgood - ngood;
1163  newSP.firstTime = newSP.lastTime = tt;
1164  }
1165  j = newSP.countForTime(tt);
1166  spdvector[i].ndt = j;
1167  spdvector[i].toffset = tt - newSP.firstTime - j * dt;
1168  newSP.spdvector.push_back(spdvector[i]);
1169  }
1170  }
1171 
1172  // now trim this SatPass
1173  spdvector.resize(ilast + 1);
1174  lastTime = time(ilast);
1175 
1176  return true;
1177  }
1178  catch (Exception& e)
1179  {
1180  GNSSTK_RETHROW(e);
1181  }
1182  }
1183 
1184  void SatPass::decimate(const int N, Epoch refTime)
1185  {
1186  try
1187  {
1188  if (N <= 1)
1189  {
1190  return;
1191  }
1192  if (spdvector.size() < N)
1193  {
1194  dt = N * dt;
1195  return;
1196  }
1197  if (refTime == CommonTime::BEGINNING_OF_TIME)
1198  {
1199  refTime = firstTime;
1200  }
1201 
1202  // find new firstTime = time(nstart)
1203  int i, j, nstart = int(0.5 + (firstTime - refTime) / dt);
1204  nstart = nstart % N;
1205  while (nstart < 0)
1206  nstart += N;
1207  if (nstart > 0)
1208  {
1209  nstart = N - nstart;
1210  }
1211 
1212  // decimate
1213  ngood = 0;
1214  Epoch newfirstTime, tt;
1215  for (j = 0, i = 0; i < spdvector.size(); i++)
1216  {
1217  if (spdvector[i].ndt % N != nstart)
1218  {
1219  continue;
1220  }
1221  lastTime = time(i);
1222  if (j == 0)
1223  {
1224  newfirstTime = time(i);
1225  spdvector[i].toffset = 0.0;
1226  spdvector[i].ndt = 0;
1227  }
1228  else
1229  {
1230  tt = time(i);
1231  spdvector[i].ndt = int(0.5 + (tt - newfirstTime) / (N * dt));
1232  spdvector[i].toffset =
1233  tt - newfirstTime - spdvector[i].ndt * N * dt;
1234  }
1235  spdvector[j] = spdvector[i];
1236  if (spdvector[j].flag != BAD)
1237  {
1238  ngood++;
1239  }
1240  j++;
1241  }
1242 
1243  dt = N * dt;
1244  firstTime = newfirstTime;
1245  spdvector.resize(j); // trim
1246  }
1247  catch (Exception& e)
1248  {
1249  GNSSTK_RETHROW(e);
1250  }
1251  }
1252 
1253  /*
1254  Determine if there is overlap between data in this SatPass and
1255  another, that is the time limits overlap. If pointers are defined,
1256  return: pdelt: the time in seconds of the overlap, pttb: begin time of
1257  the overlap ptte: end time of the overlap
1258  */
1259  bool SatPass::hasOverlap(const SatPass& that, double *pdelt,
1260  Epoch *pttb, Epoch *ptte)
1261  {
1262  if (lastTime <= that.firstTime) // iiiiii aaaaaaa
1263  {
1264  return false;
1265  }
1266  if (that.lastTime <= firstTime) // aaaaaa iiiiiii
1267  {
1268  return false;
1269  }
1270  if (that.firstTime >= firstTime)
1271  { // iiiiiiii
1272  if (lastTime <= that.lastTime)
1273  { // aaaaaaaaaa
1274  if (pdelt)
1275  {
1276  *pdelt = lastTime - that.firstTime;
1277  }
1278  if (pttb)
1279  {
1280  *pttb = that.firstTime;
1281  }
1282  if (ptte)
1283  {
1284  *ptte = lastTime;
1285  }
1286  }
1287  else
1288  { // iiiiiiiiiiii
1289  if (pdelt) // aaaaa
1290  {
1291  *pdelt = that.lastTime - that.firstTime;
1292  }
1293  if (pttb)
1294  {
1295  *pttb = that.firstTime;
1296  }
1297  if (ptte)
1298  {
1299  *ptte = that.lastTime;
1300  }
1301  }
1302  return true;
1303  }
1304  else
1305  { // if(firstTime > that.firstTime) // iiii
1306  if (that.lastTime >= lastTime)
1307  { // aaaaaaaaa
1308  if (pdelt)
1309  {
1310  *pdelt = lastTime - firstTime;
1311  }
1312  if (pttb)
1313  {
1314  *pttb = firstTime;
1315  }
1316  if (ptte)
1317  {
1318  *ptte = lastTime;
1319  }
1320  }
1321  else
1322  { // iiiiiiiiii
1323  if (pdelt) // aaaaaaaaa
1324  {
1325  *pdelt = that.lastTime - firstTime;
1326  }
1327  if (pttb)
1328  {
1329  *pttb = firstTime;
1330  }
1331  if (ptte)
1332  {
1333  *ptte = that.lastTime;
1334  }
1335  }
1336  return true;
1337  }
1338  return true; // never reached
1339  }
1340 
1341  /* dump all the data in the pass, one line per timetag;
1342  put message msg at beginning of each line. */
1343  void SatPass::dump(ostream& os, const std::string& msg1, const std::string& msg2)
1344  {
1345  int i, j, last;
1346  Epoch tt;
1347  os << '#' << msg1 << " " << *this << " " << msg2 << endl;
1348  os << '#' << msg1 << " n Sat cnt flg time toffset";
1349  for (j = 0; j < indexForLabel.size(); j++)
1350  os << " " << labelForIndex[j] << " L S";
1351  os << " gap(pts)";
1352  os << endl;
1353 
1354  for (i = 0; i < spdvector.size(); i++)
1355  {
1356  tt = time(i);
1357  os << msg1 << " " << setw(3) << i << " " << sat << " " << setw(3)
1358  << spdvector[i].ndt << " " << setw(2) << spdvector[i].flag << " "
1359  << printTime(tt, SatPass::outFormat) << fixed << setprecision(6)
1360  << " " << setw(9) << spdvector[i].toffset << setprecision(3);
1361  for (j = 0; j < indexForLabel.size(); j++)
1362  os << " " << setw(13) << spdvector[i].data[j] << " "
1363  << spdvector[i].lli[j] << " " << spdvector[i].ssi[j];
1364  if (i == 0)
1365  {
1366  last = spdvector[i].ndt;
1367  }
1368  if (spdvector[i].ndt - last > 1)
1369  {
1370  os << " " << spdvector[i].ndt - last;
1371  }
1372  last = spdvector[i].ndt;
1373  os << endl;
1374  }
1375  }
1376 
1377  // output SatPass to ostream
1378  std::ostream& operator<<(std::ostream& os, SatPass& sp)
1379  {
1380  os << setw(4) << sp.spdvector.size() << " " << sp.sat << " " << setw(4)
1381  << sp.ngood << " " << setw(2) << sp.Status << " "
1382  << printTime(sp.firstTime, SatPass::outFormat) << " "
1383  << printTime(sp.lastTime, SatPass::outFormat) << " " << fixed
1384  << setprecision(1) << sp.dt;
1385  for (int i = 0; i < sp.labelForIndex.size(); i++)
1386  os << " " << sp.labelForIndex[i];
1387 
1388  return os;
1389  }
1390 
1391  /* ---------------------------- private SatPassData functions
1392  -------------------- add data to the arrays at timetag tt (private) return
1393  >=0 ok (index of added data), -1 gap, -2 timetag out of order */
1394  int SatPass::pushBack(const Epoch tt, SatPassData& spd)
1395  {
1396  unsigned int n;
1397  // if this is the first point, save first time
1398  if (spdvector.size() == 0)
1399  {
1400  firstTime = lastTime = tt;
1401  n = 0;
1402  }
1403  else
1404  {
1405  if (tt - lastTime < 1.e-8)
1406  {
1407  return -2;
1408  }
1409  // compute count for this point - prev line means n is >= 0
1410  n = countForTime(tt);
1411  // test size of gap
1412  if ((n - spdvector[spdvector.size() - 1].ndt) * dt > maxGap)
1413  {
1414  return -1;
1415  }
1416  lastTime = tt;
1417  }
1418 
1419  /* add it
1420  spd.flag = 1;
1421  ngood is useless unless it's changed whenever any flag is... */
1422  if (spd.flag != SatPass::BAD)
1423  {
1424  ngood++;
1425  }
1426  spd.ndt = n;
1427  spd.toffset = tt - firstTime - n * dt;
1428  spdvector.push_back(spd);
1429  return (spdvector.size() - 1);
1430  }
1431 
1432  // get one element of the data array of this SatPass (private)
1433  struct SatPass::SatPassData SatPass::getData(unsigned int i) const
1434  {
1435  if (i >= spdvector.size())
1436  { // TD ?? keep this - its private
1437  Exception e("invalid in getData() " + asString(i));
1438  GNSSTK_THROW(e);
1439  }
1440  return spdvector[i];
1441  }
1442 
1443 } // end namespace gnsstk
RinexUtilities.hpp
gnsstk::SatPass::labelForIndex
std::map< unsigned int, std::string > labelForIndex
Definition: SatPass.hpp:170
gnsstk::dump
void dump(vector< SatPass > &SatPassList, ostream &os, bool rev, bool dbug)
Definition: SatPassUtilities.cpp:59
SatPass.hpp
gnsstk::SatPass::SatPassData::ndt
unsigned int ndt
time 'count' : time of data = FirstTime + ndt * dt + offset
Definition: SatPass.hpp:97
gnsstk::TwoSampleStats::Add
void Add(const T &x, const T &y)
Definition: Stats.hpp:867
gnsstk::SatPass::ngood
unsigned int ngood
number of timetags with good data in the data arrays.
Definition: SatPass.hpp:182
L1
gnsstk::Matrix< double > L1
Definition: Matrix_LUDecomp_T.cpp:46
gnsstk::SatPass::indexForLabel
std::map< std::string, unsigned int > indexForLabel
Definition: SatPass.hpp:169
gnsstk::BEGINNING_OF_TIME
const Epoch BEGINNING_OF_TIME(CommonTime::BEGINNING_OF_TIME)
Earliest representable Epoch.
const
#define const
Definition: getopt.c:43
StringUtils.hpp
gnsstk::TwoSampleStats::Slope
T Slope(void) const
return slope of best-fit line Y=slope*X + intercept
Definition: Stats.hpp:1060
gnsstk::Stats::Minimum
T Minimum(void) const
return minimum value
Definition: Stats.hpp:321
gnsstk::SatPass::SatPassData::toffset
double toffset
offset of time from integer number * dt since FirstTime.
Definition: SatPass.hpp:100
gnsstk::Stats::StdDev
T StdDev(void) const
return computed standard deviation
Definition: Stats.hpp:347
stl_helpers.hpp
gnsstk::TwoSampleStats::StdDevY
T StdDevY(void) const
return computed Y standard deviation
Definition: Stats.hpp:1057
gnsstk::RinexObsData::obs
RinexSatMap obs
the map of observations
Definition: RinexObsData.hpp:95
RinexObsStream.hpp
logstream.hpp
gnsstk::SatPass::countForTime
int countForTime(const Epoch &tt) const
Definition: SatPass.hpp:906
gnsstk::StringUtils::asString
std::string asString(IonexStoreStrategy e)
Convert a IonexStoreStrategy to a whitespace-free string name.
Definition: IonexStoreStrategy.cpp:46
gnsstk::SatPass
Definition: SatPass.hpp:71
gnsstk
For Sinex::InputHistory.
Definition: BasicFramework.cpp:50
P1
gnsstk::Matrix< double > P1
Definition: Matrix_LUDecomp_T.cpp:49
gnsstk::Stats< double >
gnsstk::StringUtils::split
std::vector< std::string > split(const std::string &str, const char delimiter=' ')
Definition: StringUtils.hpp:2275
gnsstk::SatPass::SatPassData::flag
unsigned short flag
Definition: SatPass.hpp:88
gnsstk::SatPass::dt
double dt
Nominal time spacing of the data; determined on input or by decimate()
Definition: SatPass.hpp:160
Stats.hpp
gnsstk::SatPass::firstTime
Epoch firstTime
Definition: SatPass.hpp:179
gnsstk::Exception
Definition: Exception.hpp:151
gnsstk::RinexObsData::epochFlag
short epochFlag
Definition: RinexObsData.hpp:89
P2
gnsstk::Matrix< double > P2
Definition: Matrix_LUDecomp_T.cpp:49
gnsstk::SatPass::SatPassData::lli
std::vector< unsigned short > lli
Definition: SatPass.hpp:109
gnsstk::C_MPS
const double C_MPS
m/s, speed of light; this value defined by GPS but applies to GAL and GLO.
Definition: GNSSconstants.hpp:74
example4.time
time
Definition: example4.py:103
gnsstk::TwoSampleStats::SigmaSlope
T SigmaSlope(void) const
return uncertainty in slope
Definition: Stats.hpp:1081
gnsstk::Stats::Maximum
T Maximum(void) const
return maximum value
Definition: Stats.hpp:325
gnsstk::GalHealthStatus::OK
@ OK
Signal OK.
wl1
double wl1
Definition: DiscCorr.cpp:656
wl2
double wl2
Definition: DiscCorr.cpp:656
GNSSTK_RETHROW
#define GNSSTK_RETHROW(exc)
Definition: Exception.hpp:369
RinexObsData.hpp
gnsstk::TrackingCode::P
@ P
Legacy GPS precise code.
std::operator<<
std::ostream & operator<<(std::ostream &s, gnsstk::StringUtils::FFLead v)
Definition: FormattedDouble_T.cpp:44
example3.data
data
Definition: example3.py:22
RinexObsHeader.hpp
example6.ssi
ssi
Definition: example6.py:124
gnsstk::SatPass::spdvector
std::vector< SatPassData > spdvector
ALL data in the pass, stored in SatPassData objects, in time order.
Definition: SatPass.hpp:185
LOG
#define LOG(level)
define the macro that is used to write to the log stream
Definition: logstream.hpp:315
gnsstk::printTime
std::string printTime(const CommonTime &t, const std::string &fmt)
Definition: TimeString.cpp:64
gnsstk::RinexSatID
Definition: RinexSatID.hpp:63
gnsstk::SatPass::lastTime
Epoch lastTime
Definition: SatPass.hpp:179
gnsstk::SatPass::SatPassData::ssi
std::vector< unsigned short > ssi
Definition: SatPass.hpp:109
gnsstk::TwoSampleStats::Reset
void Reset(void)
reset, i.e. ignore earlier data and restart sampling
Definition: Stats.hpp:856
std
Definition: Angle.hpp:142
gnsstk::TwoSampleStats::N
unsigned int N(void) const
Definition: Stats.hpp:1037
gnsstk::SatPass::SatPassData::data
std::vector< double > data
data for one epoch of RINEX data
Definition: SatPass.hpp:103
gnsstk::Stats::Average
T Average(void) const
return the average
Definition: Stats.hpp:329
gnsstk::Stats::Add
void Add(const T &x)
Definition: Stats.hpp:158
gnsstk::Epoch
Definition: Epoch.hpp:123
GNSSTK_THROW
#define GNSSTK_THROW(exc)
Definition: Exception.hpp:366
gnsstk::DEBUG
@ DEBUG
Definition: logstream.hpp:57
gnsstk::SatPass::sat
RinexSatID sat
Satellite identifier for this data.
Definition: SatPass.hpp:163
gnsstk::SatPass::Status
int Status
Definition: SatPass.hpp:157
example6.lli
lli
Definition: example6.py:123
gnsstk::RinexObsData
Definition: RinexObsData.hpp:68
L2
gnsstk::Matrix< double > L2
Definition: Matrix_LUDecomp_T.cpp:46
gnsstk::TwoSampleStats< double >
gnsstk::vectorindex
int vectorindex(const std::vector< T > &vec, const T &value)
Definition: stl_helpers.hpp:123
gnsstk::SatPass::SatPassData
Definition: SatPass.hpp:81
gnsstk::RinexObsData::time
gnsstk::CommonTime time
the time corresponding to the observations
Definition: RinexObsData.hpp:77
gnsstk::Stats::N
unsigned int N(void) const
return the sample size
Definition: Stats.hpp:318
sp
double sp
Definition: IERS1996NutationData.hpp:46


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