SatPassIterator.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 #include "SatPassIterator.hpp"
42 #include "logstream.hpp"
43 
44 using namespace std;
45 using namespace gnsstk::StringUtils;
46 
47 namespace gnsstk
48 {
49 
50  // -----------------------------------------------------------------------------
51  // only constructor
52  SatPassIterator::SatPassIterator(std::vector<SatPass>& splist, bool rev,
53  bool dbug)
54  : SPList(splist), timeReverse(rev), debug(dbug)
55  {
56  if (SPList.size() == 0)
57  {
58  Exception e("Empty list");
59  GNSSTK_THROW(e);
60  }
61 
62  int i, j;
63 
64  // ensure time order
65  std::sort(SPList.begin(), SPList.end());
66 
67  // copy the list of obs types, and check that each is registered
68  vector<string> otlist;
69  for (i = 0; i < SPList[0].labelForIndex.size(); i++)
70  {
71  otlist.push_back(SPList[0].labelForIndex[i]);
72  // if(RinexObsHeader::convertObsType(SPList[0].labelForIndex[i])
73  // == RinexObsHeader::UN)
74  //{
75  // Exception e("Unregistered observation type :
76  // "+SPList[0].labelForIndex[i]); GNSSTK_THROW(e);
77  //}
78  }
79 
80  /* copy the data from the first SatPass in the list, for comparison with
81  the rest */
82  DT = SPList[0].dt;
83  FirstTime = SPList[0].getFirstTime();
84  LastTime = SPList[0].getLastTime();
85 
86  // loop over the list
87  for (i = 0; i < SPList.size(); i++)
88  {
89  // check for consistency of dt
90  if (SPList[i].dt != DT)
91  {
92  Exception e("Inconsistent time intervals: " +
93  asString(SPList[i].dt) + " != " + asString(DT));
94  GNSSTK_THROW(e);
95  }
96 
97  // find the earliest and latest time
98  if (SPList[i].getFirstTime() < FirstTime)
99  {
100  FirstTime = SPList[i].getFirstTime();
101  }
102  if (SPList[i].getLastTime() > LastTime)
103  {
104  LastTime = SPList[i].getLastTime();
105  }
106 
107  } // end loop over the list
108 
110  }
111 
112  // -----------------------------------------------------------------------------
113  // restart the iteration
114  void SatPassIterator::reset(bool rev, bool dbug)
115  {
116  timeReverse = rev;
117  debug = dbug;
118  // clear out the old
119  currentN = 0;
120  listIndex.clear();
121  dataIndex.clear();
122  countOffset.clear();
123  indexStatus = vector<int>(SPList.size(), -1);
124  // loop over the list
125  int i = (timeReverse ? SPList.size() - 1 : 0);
126  while ((timeReverse && i >= 0) || (!timeReverse && i < SPList.size()))
127  {
128 
129  for (;;)
130  {
131  // ignore passes with negative Status
132  if (SPList[i].Status < 0)
133  {
134  break;
135  }
136 
137  // define latest epoch when time reversed
138  if (timeReverse && currentN == 0)
139  {
140  currentN = int((SPList[i].firstTime - FirstTime) / DT + 0.5) +
141  SPList[i].spdvector[SPList[i].size() - 1].ndt;
142  }
143 
144  // (re)build the maps
145  if (listIndex.find(SPList[i].sat) == listIndex.end())
146  {
147  indexStatus[i] = 0;
148  listIndex[SPList[i].sat] = i;
149  dataIndex[SPList[i].sat] =
150  (timeReverse ? SPList[i].size() - 1 : 0);
151  countOffset[SPList[i].sat] =
152  int((SPList[i].firstTime - FirstTime) / DT + 0.5);
153  LOG(DEBUG4) << "reset - define map " << i << " for sat "
154  << SPList[i].sat << " at time "
155  << SPList[i].firstTime.printf("%4F %10.3g")
156  << " offset " << countOffset[SPList[i].sat];
157  }
158  else
159  {
160  indexStatus[i] = -1;
161  LOG(DEBUG4) << "reset - turn off pass " << i << " for sat "
162  << SPList[i].sat << " at time "
163  << SPList[i].firstTime.printf("%4F %10.3g");
164  }
165 
166  break; // mandatory
167  }
168 
169  if (timeReverse)
170  {
171  i--;
172  }
173  else
174  {
175  i++;
176  }
177  } // end loop over the list
178  }
179 
180  /* -----------------------------------------------------------------------------
181  return 1 for success, 0 at end of data
182  Access (all of) the data for the next epoch. As long as this function
183  returns non-zero, there is more data to be accessed. Ignore passes with
184  Status less than zero.
185  @param indexMap map<unsigned int, unsigned int> defined so that all the
186  data in the current iteration is found at
187  SatPassList[i].data(j) where indexMap[i] = j.
188  @return 1 for success, 0 at the end of the dataset.
189  @throw if time tags are out of order. */
190  int SatPassIterator::next(std::map<unsigned int, unsigned int>& indexMap)
191  {
192  int i, j, k, numsvs;
193  RinexSatID sat;
194 
195  numsvs = 0;
196  indexMap.clear();
197  nextIndexMap.clear();
198 
199  if (debug)
200  {
201  LOG(INFO) << "SPIterator::next(map) - time "
202  << (FirstTime + currentN * DT).printf("%4F %10.3g")
203  << " size of listIndex " << listIndex.size();
204  }
205 
206  while (numsvs == 0)
207  {
208  if (listIndex.size() == 0)
209  {
210  if (debug)
211  {
212  LOG(INFO) << "Return 0 from next()";
213  }
214  return 0;
215  }
216 
217  // loop over active SatPass's
218  map<RinexSatID, int>::iterator kt;
219 
220  // debugging - dump the listIndex
221 
222  if (debug)
223  {
224  for (kt = listIndex.begin(); kt != listIndex.end(); kt++)
225  LOG(INFO) << " listIndex: " << kt->first << " " << kt->second;
226  }
227 
228  kt = listIndex.begin();
229  while (kt != listIndex.end())
230  {
231  sat = kt->first;
232  i = kt->second;
233  j = dataIndex[sat];
234  if (debug)
235  {
236  LOG(INFO) << "Loop over listIndex: " << sat << " " << i << " "
237  << j;
238  }
239 
240  if (SPList[i].Status < 0)
241  {
242  listIndex.erase(
243  kt++); // erasing a map - do exactly this and no more
244  if (debug)
245  {
246  LOG(INFO)
247  << " Erase this pass for bad status: index " << i
248  << " sat " << sat << " size is now " << listIndex.size();
249  }
250  continue;
251  }
252 
253  if (countOffset[sat] + SPList[i].spdvector[j].ndt == currentN)
254  {
255  // found active sat at this count - add to map
256  nextIndexMap[i] = j;
257  numsvs++;
258  if (debug)
259  {
260  LOG(INFO) << "SPIterator::next(map) found sat " << sat
261  << " at index " << i;
262  }
263 
264  // increment data index
265  if ((timeReverse && --j < 0) ||
266  (!timeReverse && ++j == SPList[i].spdvector.size()))
267  {
268  if (debug)
269  {
270  LOG(INFO)
271  << " This pass for sat " << sat << " is done ...";
272  }
273  indexStatus[i] = 1;
274 
275  // find the next pass for this sat
276  k = i + (timeReverse ? -1 : 1);
277  while ((timeReverse && k >= 0) ||
278  (!timeReverse && k < SPList.size()))
279  // for(k=i+1; k<SPList.size(); k++)
280  {
281  if (debug)
282  {
283  LOG(INFO) << " ... consider next pass " << k << " "
284  << SPList[k].sat << " "
285  << SPList[k].firstTime.printf("%4F %10.3g");
286  }
287  bool found(false);
288  for (;;)
289  {
290  if (SPList[k].Status < 0) // bad pass
291  {
292  break;
293  }
294  if (SPList[k].sat != sat) // wrong sat
295  {
296  break;
297  }
298  if (indexStatus[k] > 0) // already done
299  {
300  break;
301  }
302 
303  // take this one
304  indexStatus[k] = 0;
305  i = listIndex[sat] = k;
306  dataIndex[sat] =
307  (timeReverse ? SPList[i].size() - 1 : 0);
308  countOffset[sat] =
309  int((SPList[i].firstTime - FirstTime) / DT + 0.5);
310  found = true;
311  break; // mandatory
312  }
313  if (found)
314  {
315  break;
316  }
317  if (timeReverse)
318  {
319  k--;
320  }
321  else
322  {
323  k++;
324  }
325  } // end while loop over next passes
326 
327  if (indexStatus[i] == 0)
328  {
329  if (debug)
330  {
331  LOG(INFO) << " ... new pass for sat " << SPList[i].sat
332  << " at index " << i << " and time "
333  << SPList[i].firstTime.printf("%4F %10.3g");
334  }
335  }
336  }
337  else
338  {
339  dataIndex[sat] = j;
340  }
341 
342  } // end if found active sat at this count
343 
344  // increment the iterator
345  if (indexStatus[i] > 0)
346  { // a new one was not found
347  listIndex.erase(
348  kt++); // erasing a map - do exactly this and no more
349  if (debug)
350  {
351  LOG(INFO) << " Erase this pass: index " << i << " sat " << sat
352  << " size is now " << listIndex.size();
353  }
354  }
355  else
356  {
357  kt++;
358  }
359 
360  } // end while loop over active SatPass's
361  if (debug)
362  {
363  LOG(INFO) << "End while loop over active SatPasses";
364  }
365 
366  // if(robs.numSvs == 0) cout << "Gap at " << currentN << endl;
367  if (timeReverse)
368  {
369  currentN--;
370  }
371  else
372  {
373  currentN++;
374  }
375 
376  } // end while robs.numSvs==0
377 
378  indexMap = nextIndexMap;
379  if (debug)
380  {
381  LOG(INFO) << "Return 1 from next()";
382  }
383 
384  return 1;
385  }
386 
387  /* -----------------------------------------------------------------------------
388  return 1 for success, 0 at end of data
389  NB This assumes all the passes have the same obstypes in the same order,
390  AND
391  it knows nothing of the obstypes in the header....
392  TD perhaps better design is to pass this (SatPassIterator) a vector of
393  obstypes
394  from the header and have it fill the robs parallel to that, inserting 0
395  as nec. */
397  {
398  if (listIndex.size() == 0)
399  {
400  return 0;
401  }
402 
403  map<unsigned int, unsigned int> indexMap;
404  map<unsigned int, unsigned int>::const_iterator kt;
405  int iret = next(indexMap);
406  if (iret == 0)
407  {
408  return iret;
409  }
410 
411  robs.obs.clear();
412  robs.epochFlag = 0;
413  robs.clockOffset = 0.0;
414  robs.numSvs = 0;
415 
416  /* get the time tag.
417  NB there is an assumption here, that all that SatPass'es in indexMap
418  are consistent w.r.t. time tag - clearly ok if SPList was created in
419  the usual ways. */
420  kt = indexMap.begin();
421  robs.time = SPList[kt->first].time(kt->second);
422 
423  // loop over the map
424  for (kt = indexMap.begin(); kt != indexMap.end(); kt++)
425  {
426  int i = kt->first;
427  int j = kt->second;
428  RinexSatID sat = SPList[i].getSat();
429  // LOG(DEBUG2) << "SPIterator::next(robs) found sat " << sat
430  // << " at index " << i << " and time " << SPList[i].time(j);
431 
432  bool found = false;
433  bool flag = (SPList[i].spdvector[j].flag != SatPass::BAD);
434  for (int k = 0; k < SPList[i].labelForIndex.size(); k++)
435  {
436  RinexObsType ot;
437  ot = RinexObsHeader::convertObsType(SPList[i].labelForIndex[k]);
438  if (ot == RinexObsHeader::UN)
439  {
440  ; // LOG(DEBUG1) << " Error - this sat has UN obstype"; // TD
441  // warn?
442  }
443  else
444  {
445  found = true;
446  /* NO some obs may be zero b/c they are not collected (e.g. C2)
447  -> bad
448  robs.obs[sat][ot].data = flag ? SPList[i].spdvector[j].data[k]
449  : 0.; robs.obs[sat][ot].lli = flag ?
450  SPList[i].spdvector[j].lli[k] : 0; robs.obs[sat][ot].ssi =
451  flag ? SPList[i].spdvector[j].ssi[k] : 0; */
452  robs.obs[sat][ot].data = SPList[i].spdvector[j].data[k];
453  robs.obs[sat][ot].lli = SPList[i].spdvector[j].lli[k];
454  robs.obs[sat][ot].ssi = SPList[i].spdvector[j].ssi[k];
455  }
456  }
457  if (found)
458  {
459  robs.numSvs++;
460  }
461  }
462 
463  return 1;
464  }
465 
466 } // namespace gnsstk
467 
468 // -------------------------------------------------------------------------------
469 // -------------------------------------------------------------------------------
gnsstk::SatPassIterator::DT
double DT
Definition: SatPassIterator.hpp:166
gnsstk::SatPassIterator::listIndex
std::map< RinexSatID, int > listIndex
index of the current object in the list for this satellite
Definition: SatPassIterator.hpp:176
gnsstk::SatPassIterator::currentN
int currentN
count of the current epoch, = 0,1,...
Definition: SatPassIterator.hpp:160
gnsstk::RinexObsData::obs
RinexSatMap obs
the map of observations
Definition: RinexObsData.hpp:95
logstream.hpp
gnsstk::StringUtils::asString
std::string asString(IonexStoreStrategy e)
Convert a IonexStoreStrategy to a whitespace-free string name.
Definition: IonexStoreStrategy.cpp:46
gnsstk::SatPass::BAD
static const GNSSTK_EXPORT unsigned short BAD
flag indicating bad data
Definition: SatPass.hpp:854
gnsstk::DEBUG4
@ DEBUG4
Definition: logstream.hpp:58
gnsstk
For Sinex::InputHistory.
Definition: BasicFramework.cpp:50
gnsstk::SatPassIterator::nextIndexMap
std::map< unsigned int, unsigned int > nextIndexMap
Definition: SatPassIterator.hpp:201
gnsstk::RinexObsData::numSvs
short numSvs
Definition: RinexObsData.hpp:93
gnsstk::Exception
Definition: Exception.hpp:151
gnsstk::RinexObsData::epochFlag
short epochFlag
Definition: RinexObsData.hpp:89
gnsstk::SatPassIterator::LastTime
Epoch LastTime
Definition: SatPassIterator.hpp:173
gnsstk::SatPassIterator::countOffset
std::map< RinexSatID, int > countOffset
offset in count of the current object in the list for this satellite
Definition: SatPassIterator.hpp:185
gnsstk::SatPassIterator::indexStatus
std::vector< int > indexStatus
Definition: SatPassIterator.hpp:192
debug
#define debug
Definition: Rinex3ClockHeader.cpp:51
gnsstk::RinexObsType
RINEX Observation Types.
Definition: RinexObsHeader.hpp:67
gnsstk::SatPassIterator::getFirstTime
Epoch getFirstTime()
Get the first (earliest) time found in the SatPass list.
Definition: SatPassIterator.hpp:106
gnsstk::RinexObsData::clockOffset
double clockOffset
optional clock offset
Definition: RinexObsData.hpp:94
gnsstk::RinexObsHeader::convertObsType
static RinexObsType convertObsType(const std::string &oneObs)
Definition: RinexObsHeader.cpp:830
gnsstk::SatPassIterator::FirstTime
Epoch FirstTime
Definition: SatPassIterator.hpp:173
gnsstk::SatPassIterator::next
int next(std::map< unsigned int, unsigned int > &indexMap)
Definition: SatPassIterator.cpp:190
gnsstk::StringUtils
Definition: IonexStoreStrategy.cpp:44
LOG
#define LOG(level)
define the macro that is used to write to the log stream
Definition: logstream.hpp:315
gnsstk::RinexSatID
Definition: RinexSatID.hpp:63
gnsstk::SatPassIterator::SPList
std::vector< SatPass > & SPList
reference to the vector of passes being processed
Definition: SatPassIterator.hpp:195
std
Definition: Angle.hpp:142
gnsstk::SatPassIterator::getLastTime
Epoch getLastTime()
Get the last (latest) time found in the SatPass list.
Definition: SatPassIterator.hpp:109
gnsstk::SatPassIterator::debug
bool debug
if true, print debug info in nex()
Definition: SatPassIterator.hpp:154
gnsstk::INFO
@ INFO
Definition: logstream.hpp:57
gnsstk::SatPassIterator::timeReverse
bool timeReverse
if true, iterate in reverse time order
Definition: SatPassIterator.hpp:157
GNSSTK_THROW
#define GNSSTK_THROW(exc)
Definition: Exception.hpp:366
gnsstk::RinexObsData
Definition: RinexObsData.hpp:68
gnsstk::RinexObsHeader::UN
static const GNSSTK_EXPORT RinexObsType UN
Definition: RinexObsHeader.hpp:212
SatPassIterator.hpp
gnsstk::SatPassIterator::dataIndex
std::map< RinexSatID, int > dataIndex
Definition: SatPassIterator.hpp:182
gnsstk::SatPassIterator::reset
void reset(bool rev=false, bool dbug=false)
Restart the iteration, i.e. return to the initial time.
Definition: SatPassIterator.cpp:114
gnsstk::RinexObsData::time
gnsstk::CommonTime time
the time corresponding to the observations
Definition: RinexObsData.hpp:77


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