00001 #pragma ident "$Id: SatPass.cpp 3140 2012-06-18 15:03:02Z susancummins $"
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00030
00031
00032 #include <ostream>
00033 #include <string>
00034 #include <vector>
00035 #include <algorithm>
00036
00037 #include "SatPass.hpp"
00038 #include "GNSSconstants.hpp"
00039 #include "Stats.hpp"
00040 #include "StringUtils.hpp"
00041 #include "RinexObsHeader.hpp"
00042 #include "RinexObsData.hpp"
00043 #include "RinexObsStream.hpp"
00044 #include "RinexUtilities.hpp"
00045 #include "logstream.hpp"
00046
00047 using namespace std;
00048 using namespace gpstk::StringUtils;
00049
00050
00051 namespace gpstk {
00052
00053
00054
00055
00056 const unsigned short SatPass::OK = 1;
00057 const unsigned short SatPass::BAD = 0;
00058 const unsigned short SatPass::LL1 = 2;
00059 const unsigned short SatPass::LL2 = 4;
00060 const unsigned short SatPass::LL3 = 6;
00061 double SatPass::maxGap = 1800;
00062 string SatPass::outFormat = string("%4F %10.3g");
00063
00064
00065 SatPass::SatPass(GSatID insat, double indt) throw()
00066 {
00067 vector<string> defaultObsTypes;
00068 defaultObsTypes.push_back("L1");
00069 defaultObsTypes.push_back("L2");
00070 defaultObsTypes.push_back("P1");
00071 defaultObsTypes.push_back("P2");
00072
00073 init(insat, indt, defaultObsTypes);
00074 }
00075
00076 SatPass::SatPass(GSatID insat, double indt, vector<string> obstypes) throw()
00077 {
00078 init(insat, indt, obstypes);
00079 }
00080
00081 void SatPass::init(GSatID insat, double indt, vector<string> obstypes) throw()
00082 {
00083 sat = insat;
00084 dt = indt;
00085
00086
00087 ngood = 0;
00088 Status = 0;
00089
00090 for(int i=0; i<obstypes.size(); i++) {
00091 indexForLabel[obstypes[i]] = i;
00092 labelForIndex[i] = obstypes[i];
00093 }
00094 }
00095
00096 SatPass& SatPass::operator=(const SatPass& right) throw()
00097 {
00098 if(&right != this) {
00099 Status = right.Status;
00100 dt = right.dt;
00101 sat = right.sat;
00102 indexForLabel = right.indexForLabel;
00103 labelForIndex = right.labelForIndex;
00104 firstTime = right.firstTime;
00105 lastTime = right.lastTime;
00106 ngood = right.ngood;
00107 spdvector.resize(right.spdvector.size());
00108 for(int i=0; i<right.spdvector.size(); i++)
00109 spdvector[i] = right.spdvector[i];
00110 }
00111
00112 return *this;
00113 }
00114
00115 int SatPass::addData(const CommonTime tt, vector<string>& ots, vector<double>& data)
00116 throw(Exception)
00117 {
00118 vector<unsigned short> lli(data.size(),0),ssi(data.size(),0);
00119 try { return addData(tt, ots, data, lli, ssi); }
00120 catch(Exception& e) { GPSTK_RETHROW(e); }
00121 }
00122
00123
00124
00125
00126 int SatPass::addData(const CommonTime tt,
00127 vector<string>& obstypes,
00128 vector<double>& data,
00129 vector<unsigned short>& lli,
00130 vector<unsigned short>& ssi,
00131 unsigned short flag) throw(Exception)
00132 {
00133
00134 if(data.size() != lli.size() || data.size() != ssi.size()) {
00135 Exception e("Dimensions do not match in addData()"
00136 + StringUtils::asString(data.size()) + ","
00137 + StringUtils::asString(lli.size()) + ","
00138 + StringUtils::asString(ssi.size()));
00139 GPSTK_THROW(e);
00140 }
00141 if(spdvector.size() > 0 && spdvector[0].data.size() != data.size()) {
00142 Exception e("Error - addData passed different dimension that earlier!"
00143 + StringUtils::asString(data.size()) + " != "
00144 + StringUtils::asString(spdvector[0].data.size()));
00145 GPSTK_THROW(e);
00146 }
00147
00148
00149 SatPassData spd(data.size());
00150 spd.flag = flag;
00151 for(int k=0; k<data.size(); k++) {
00152 int i = indexForLabel[obstypes[k]];
00153 spd.data[i] = data[k];
00154 spd.lli[i] = lli[k];
00155 spd.ssi[i] = ssi[k];
00156 }
00157
00158
00159
00160 return push_back(tt, spd);
00161 }
00162
00163
00164
00165
00166
00167 int SatPass::addData(const RinexObsData& robs) throw()
00168 {
00169 if(robs.epochFlag != 0 && robs.epochFlag != 1) return false;
00170 RinexObsData::RinexSatMap::const_iterator it;
00171 RinexObsData::RinexObsTypeMap::const_iterator jt;
00172 map<string,unsigned int>::const_iterator kt;
00173 SatPassData spd(indexForLabel.size());
00174
00175
00176 for(it=robs.obs.begin(); it != robs.obs.end(); it++) {
00177 if(it->first == sat) {
00178
00179 for(kt=indexForLabel.begin(); kt != indexForLabel.end(); kt++) {
00180 if((jt=it->second.find(RinexObsHeader::convertObsType(kt->first)))
00181 == it->second.end()) {
00182 spd.data[kt->second] = 0.0;
00183 spd.lli[kt->second] = 0;
00184 spd.ssi[kt->second] = 0;
00185 }
00186 else {
00187 spd.data[kt->second] = jt->second.data;
00188 spd.lli[kt->second] = jt->second.lli;
00189 spd.ssi[kt->second] = jt->second.ssi;
00190 }
00191 }
00192
00193 spd.flag = OK;
00194
00195 return push_back(robs.time,spd);
00196 }
00197 }
00198 return -3;
00199 }
00200
00201
00202
00203
00204 void SatPass::smooth(bool smoothPR, bool debiasPH, string& msg) throw(Exception)
00205 {
00206
00207 bool useC1=false;
00208 map<string, unsigned int>::const_iterator it;
00209 if(indexForLabel.find("L1") == indexForLabel.end() ||
00210 indexForLabel.find("L2") == indexForLabel.end() ||
00211 (indexForLabel.find("C1") == indexForLabel.end() &&
00212 indexForLabel.find("P1") == indexForLabel.end()) ||
00213 indexForLabel.find("P2") == indexForLabel.end()) {
00214 Exception e("Obs types L1 L2 C1/P1 P2 required for smooth()");
00215 GPSTK_THROW(e);
00216 }
00217 if(indexForLabel.find("P1") == indexForLabel.end()) useC1=true;
00218
00219
00220 static const double F1=L1_MULT_GPS;
00221 static const double F2=L2_MULT_GPS;
00222
00223 static const double wl1=L1_WAVELENGTH_GPS;
00224 static const double wl2=L2_WAVELENGTH_GPS;
00225
00226 static const double alpha = ((F1/F2)*(F1/F2) - 1.0);
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237 static const double D11 = (alpha+2.)/alpha;
00238 static const double D12 = -2./alpha;
00239 static const double D21 = (2*alpha+2.)/alpha;
00240 static const double D22 = -D11;
00241
00242 bool first;
00243 int i;
00244 double RB1,RB2,dbL1,dbL2;
00245 Stats<double> PB1,PB2;
00246
00247
00248 for(first=true,i=0; i<spdvector.size(); i++) {
00249 if(!(spdvector[i].flag & OK)) continue;
00250 double P1 = spdvector[i].data[indexForLabel[(useC1 ? "C1" : "P1")]];
00251 double P2 = spdvector[i].data[indexForLabel["P2"]];
00252 RB1 = wl1*spdvector[i].data[indexForLabel["L1"]] - D11*P1 - D12*P2;
00253 RB2 = wl2*spdvector[i].data[indexForLabel["L2"]] - D21*P1 - D22*P2;
00254 if(first) { dbL1 = RB1; dbL2 = RB2; first = false; }
00255 PB1.Add(RB1-dbL1);
00256 PB2.Add(RB2-dbL2);
00257 }
00258
00259 RB1 = (dbL1 + PB1.Average())/wl1;
00260 RB2 = (dbL2 + PB2.Average())/wl2;
00261
00262 ostringstream oss;
00263 oss << "SMT" << fixed << setprecision(2)
00264 << " " << sat
00265 << " " << printTime(getFirstGoodTime(),outFormat)
00266 << " " << printTime(getLastGoodTime(),outFormat)
00267 << " " << setw(5) << PB1.N()
00268 << " " << setw(12) << PB1.Average()+dbL1
00269 << " " << setw(5) << PB1.StdDev()
00270 << " " << setw(12) << PB1.Minimum()+dbL1
00271 << " " << setw(12) << PB1.Maximum()+dbL1
00272 << " " << setw(5) << PB2.N()
00273 << " " << setw(12) << PB2.Average()+dbL2
00274 << " " << setw(5) << PB2.StdDev()
00275 << " " << setw(12) << PB2.Minimum()+dbL2
00276 << " " << setw(12) << PB2.Maximum()+dbL2
00277 << " " << setw(13) << RB1
00278 << " " << setw(13) << RB2;
00279 msg = oss.str();
00280
00281 if(!debiasPH && !smoothPR) return;
00282
00283 for(i=0; i<spdvector.size(); i++) {
00284 if(!(spdvector[i].flag & OK)) continue;
00285
00286
00287 dbL1 = spdvector[i].data[indexForLabel["L1"]] - RB1;
00288 dbL2 = spdvector[i].data[indexForLabel["L2"]] - RB2;
00289
00290
00291 if(debiasPH) {
00292 spdvector[i].data[indexForLabel["L1"]] = dbL1;
00293 spdvector[i].data[indexForLabel["L2"]] = dbL2;
00294 }
00295
00296 if(smoothPR) {
00297 spdvector[i].data[indexForLabel[(useC1 ? "C1" : "P1")]]
00298 = D11*wl1*dbL1 + D12*wl2*dbL2;
00299 spdvector[i].data[indexForLabel["P2"]] = D21*wl1*dbL1 + D22*wl2*dbL2;
00300 }
00301 }
00302 }
00303
00304
00305 double& SatPass::data(unsigned int i, std::string type) throw(Exception)
00306 {
00307 if(i >= spdvector.size()) {
00308 Exception e("Invalid index in data() " + asString(i));
00309 GPSTK_THROW(e);
00310 }
00311 map<string, unsigned int>::const_iterator it;
00312 if((it = indexForLabel.find(type)) == indexForLabel.end()) {
00313 Exception e("Invalid obs type in data() " + type);
00314 GPSTK_THROW(e);
00315 }
00316 return spdvector[i].data[it->second];
00317 }
00318
00319 double& SatPass::timeoffset(unsigned int i) throw(Exception)
00320 {
00321 if(i >= spdvector.size()) {
00322 Exception e("Invalid index in timeoffset() " + asString(i));
00323 GPSTK_THROW(e);
00324 }
00325 return spdvector[i].toffset;
00326 }
00327
00328 unsigned short& SatPass::LLI(unsigned int i, std::string type) throw(Exception)
00329 {
00330 if(i >= spdvector.size()) {
00331 Exception e("Invalid index in LLI() " + asString(i));
00332 GPSTK_THROW(e);
00333 }
00334 map<string, unsigned int>::const_iterator it;
00335 if((it = indexForLabel.find(type)) == indexForLabel.end()) {
00336 Exception e("Invalid obs type in LLI() " + type);
00337 GPSTK_THROW(e);
00338 }
00339 return spdvector[i].lli[it->second];
00340 }
00341
00342 unsigned short& SatPass::SSI(unsigned int i, std::string type) throw(Exception)
00343 {
00344 if(i >= spdvector.size()) {
00345 Exception e("Invalid index in SSI() " + asString(i));
00346 GPSTK_THROW(e);
00347 }
00348 map<string, unsigned int>::const_iterator it;
00349 if((it = indexForLabel.find(type)) == indexForLabel.end()) {
00350 Exception e("Invalid obs type in SSI() " + type);
00351 GPSTK_THROW(e);
00352 }
00353 return spdvector[i].ssi[it->second];
00354 }
00355
00356
00357 void SatPass::setFlag(unsigned int i, unsigned short f) throw(Exception)
00358 {
00359 if(i >= spdvector.size()) {
00360 Exception e("Invalid index in setFlag() " + asString(i));
00361 GPSTK_THROW(e);
00362 }
00363
00364 if(spdvector[i].flag != BAD && f == BAD) ngood--;
00365 if(spdvector[i].flag == BAD && f != BAD) ngood++;
00366 spdvector[i].flag = f;
00367 }
00368
00369
00370
00371 unsigned short SatPass::getFlag(unsigned int i) throw(Exception)
00372 {
00373 if(i >= spdvector.size()) {
00374 Exception e("Invalid index in getFlag() " + asString(i));
00375 GPSTK_THROW(e);
00376 }
00377 return spdvector[i].flag;
00378 }
00379
00380
00381 unsigned int SatPass::getCount(unsigned int i) const throw(Exception)
00382 {
00383 if(i >= spdvector.size()) {
00384 Exception e("invalid in getCount() " + asString(i));
00385 GPSTK_THROW(e);
00386 }
00387 return spdvector[i].ndt;
00388 }
00389
00390
00391
00392 CommonTime SatPass::time(unsigned int i) const throw(Exception)
00393 {
00394 if(i > spdvector.size()) {
00395 Exception e("invalid in time() " + asString(i));
00396 GPSTK_THROW(e);
00397 }
00398
00399 double toff = spdvector[i].ndt * dt + spdvector[i].toffset;
00400 return (firstTime + toff);
00401 }
00402
00403
00404 bool SatPass::includesTime(const CommonTime& tt) const throw()
00405 {
00406 if(tt < firstTime) {
00407 if((firstTime-tt) > maxGap) return false;
00408 }
00409 else if(tt > lastTime) {
00410 if((tt-lastTime) > maxGap) return false;
00411 }
00412 return true;
00413 }
00414
00415
00416
00417
00418 bool SatPass::split(int N, SatPass &newSP) {
00419 try {
00420 int i,j,n,oldgood,ilast;
00421 CommonTime tt;
00422
00423 newSP = SatPass(sat, dt);
00424 newSP.Status = Status;
00425 newSP.indexForLabel = indexForLabel;
00426 newSP.labelForIndex = labelForIndex;
00427
00428 oldgood = ngood;
00429 ngood = ilast = 0;
00430 for(i=0; i<spdvector.size(); i++) {
00431 n = spdvector[i].ndt;
00432 tt = time(i);
00433 if(n < N) {
00434 if(spdvector[i].flag != BAD) ngood++;
00435 ilast = i;
00436 }
00437 else {
00438 if(n == N) {
00439 newSP.ngood = oldgood-ngood;
00440 newSP.firstTime = newSP.lastTime = tt;
00441 }
00442 j = newSP.countForTime(tt);
00443 spdvector[i].ndt = j;
00444 spdvector[i].toffset = tt - newSP.firstTime - j*dt;
00445 newSP.spdvector.push_back(spdvector[i]);
00446 }
00447 }
00448
00449
00450 spdvector.resize(ilast+1);
00451 lastTime = time(ilast);
00452
00453 return true;
00454 }
00455 catch(Exception& e) { GPSTK_RETHROW(e); }
00456 }
00457
00458 void SatPass::decimate(const int N, CommonTime refTime) throw(Exception)
00459 {
00460 try {
00461 if(N <= 1) return;
00462 if(spdvector.size() < N) { dt = N*dt; return; }
00463 if(refTime == CommonTime::BEGINNING_OF_TIME) refTime = firstTime;
00464
00465
00466 int i,j,nstart=int(0.5+(firstTime-refTime)/dt);
00467 nstart = nstart % N;
00468 while(nstart < 0) nstart += N;
00469 if(nstart > 0) nstart = N-nstart;
00470
00471
00472 ngood = 0;
00473 CommonTime newfirstTime, tt;
00474 for(j=0,i=0; i<spdvector.size(); i++) {
00475 if(spdvector[i].ndt % N != nstart) continue;
00476 lastTime = time(i);
00477 if(j==0) {
00478 newfirstTime = time(i);
00479 spdvector[i].toffset = 0.0;
00480 spdvector[i].ndt = 0;
00481 }
00482 else {
00483 tt = time(i);
00484 spdvector[i].ndt = int(0.5+(tt-newfirstTime)/(N*dt));
00485 spdvector[i].toffset = tt - newfirstTime - spdvector[i].ndt * N * dt;
00486 }
00487 spdvector[j] = spdvector[i];
00488 if(spdvector[j].flag != BAD) ngood++;
00489 j++;
00490 }
00491
00492 dt = N*dt;
00493 firstTime = newfirstTime;
00494 spdvector.resize(j);
00495 }
00496 catch(Exception& e) { GPSTK_RETHROW(e); }
00497 }
00498
00499
00500
00501 void SatPass::dump(ostream& os, string msg1, string msg2) throw()
00502 {
00503 int i,j,last;
00504 CommonTime tt;
00505 os << '#' << msg1 << " " << *this << " " << msg2 << endl;
00506 os << '#' << msg1 << " n Sat cnt flg time ";
00507 for(j=0; j<indexForLabel.size(); j++)
00508 os << " " << labelForIndex[j] << " L S";
00509 os << " gap(pts)";
00510 os << endl;
00511
00512 for(i=0; i<spdvector.size(); i++) {
00513 tt = time(i);
00514 os << msg1
00515 << " " << setw(3) << i
00516 << " " << sat
00517 << " " << setw(3) << spdvector[i].ndt
00518 << " " << setw(2) << spdvector[i].flag
00519 << " " << printTime(tt,SatPass::outFormat)
00520 << fixed << setprecision(6)
00521 << " " << setw(9) << spdvector[i].toffset
00522 << setprecision(3);
00523 for(j=0; j<indexForLabel.size(); j++)
00524 os << " " << setw(13) << spdvector[i].data[j]
00525 << " " << spdvector[i].lli[j]
00526 << " " << spdvector[i].ssi[j];
00527 if(i==0) last = spdvector[i].ndt;
00528 if(spdvector[i].ndt - last > 1) os << " " << spdvector[i].ndt-last;
00529 last = spdvector[i].ndt;
00530 os << endl;
00531 }
00532 }
00533
00534
00535 ostream& operator<<(ostream& os, SatPass& sp )
00536 {
00537 os << setw(4) << sp.spdvector.size()
00538 << " " << sp.sat
00539 << " " << setw(4) << sp.ngood
00540 << " " << setw(2) << sp.Status
00541 << " " << printTime(sp.firstTime,SatPass::outFormat)
00542 << " " << printTime(sp.lastTime,SatPass::outFormat)
00543 << " " << fixed << setprecision(1) << sp.dt;
00544 for(int i=0; i<sp.labelForIndex.size(); i++) os << " " << sp.labelForIndex[i];
00545
00546 return os;
00547 }
00548
00549
00550
00551
00552 int SatPass::push_back(const CommonTime tt, SatPassData& spd) throw()
00553 {
00554 unsigned int n;
00555
00556 if(spdvector.size() == 0) {
00557 firstTime = lastTime = tt;
00558 n = 0;
00559 }
00560 else {
00561 if(tt - lastTime < 1.e-8) return -2;
00562
00563 n = countForTime(tt);
00564
00565 if( (n - spdvector[spdvector.size()-1].ndt) * dt > maxGap)
00566 return -1;
00567 lastTime = tt;
00568 }
00569
00570
00571
00572 ngood++;
00573 spd.ndt = n;
00574 spd.toffset = tt - firstTime - n*dt;
00575 spdvector.push_back(spd);
00576 return (spdvector.size()-1);
00577 }
00578
00579
00580 struct SatPass::SatPassData SatPass::getData(unsigned int i) const
00581 throw(Exception)
00582 {
00583 if(i >= spdvector.size()) {
00584 Exception e("invalid in getData() " + asString(i));
00585 GPSTK_THROW(e);
00586 }
00587 return spdvector[i];
00588 }
00589
00590
00591
00592
00593 SatPassIterator::SatPassIterator(vector<SatPass>& splist)
00594 throw(Exception) : SPList(splist)
00595 {
00596 if(SPList.size() == 0) {
00597 Exception e("Empty list");
00598 GPSTK_THROW(e);
00599 }
00600
00601
00602 sort(SPList);
00603
00604 int i,j;
00605 vector<string> otlist;
00606
00607
00608 DT = SPList[0].dt;
00609 FirstTime = SPList[0].firstTime;
00610 LastTime = SPList[0].lastTime;
00611
00612 for(i=0; i<SPList[0].labelForIndex.size(); i++) {
00613 otlist.push_back(SPList[0].labelForIndex[i]);
00614 if(RinexObsHeader::convertObsType(SPList[0].labelForIndex[i])
00615 == RinexObsHeader::UN) {
00616 Exception e("Unregistered observation type : " + SPList[0].labelForIndex[i]);
00617 GPSTK_THROW(e);
00618 }
00619 }
00620
00621
00622 for(i=0; i<SPList.size(); i++) {
00623
00624 if(SPList[i].dt != DT) {
00625 Exception e("Inconsistent time intervals: " + asString(SPList[i].dt)
00626 + " != " + asString(DT));
00627 GPSTK_THROW(e);
00628 }
00629
00630 for(j=0; j<otlist.size(); j++) {
00631 if(SPList[i].indexForLabel.find(otlist[j]) ==
00632 SPList[i].indexForLabel.end()) {
00633 Exception e("Inconsistent observation types");
00634 GPSTK_THROW(e);
00635 }
00636 }
00637
00638
00639
00640 if(SPList[i].firstTime < FirstTime) FirstTime = SPList[i].firstTime;
00641 if(SPList[i].lastTime > LastTime) LastTime = SPList[i].lastTime;
00642
00643 }
00644
00645 reset();
00646 }
00647
00648
00649
00650
00651
00652
00653
00654
00655
00656 int SatPassIterator::next(map<unsigned int, unsigned int>& indexMap) throw(Exception)
00657 {
00658 int i,j,k,numsvs;
00659 GSatID sat;
00660
00661 numsvs = 0;
00662 indexMap.clear();
00663 nextIndexMap.clear();
00664
00665 while(numsvs == 0) {
00666 if(listIndex.size() == 0) return 0;
00667
00668
00669 map<GSatID,int>::iterator kt = listIndex.begin();
00670
00671 kt = listIndex.begin();
00672 while(kt != listIndex.end()) {
00673 sat = kt->first;
00674 i = kt->second;
00675 j = dataIndex[sat];
00676
00677 if(SPList[i].Status < 0) continue;
00678
00679 if(countOffset[sat] + SPList[i].spdvector[j].ndt == currentN) {
00680
00681 nextIndexMap[i] = j;
00682 numsvs++;
00683
00684
00685 j++;
00686 if(j == SPList[i].spdvector.size()) {
00687 indexStatus[i] = 1;
00688
00689
00690 for(k=i+1; k<SPList.size(); k++) {
00691 if(SPList[k].Status < 0)
00692 continue;
00693 if(SPList[k].sat != sat)
00694 continue;
00695 if(indexStatus[k] > 0)
00696 continue;
00697
00698
00699 indexStatus[k] = 0;
00700 i = listIndex[sat] = k;
00701 dataIndex[sat] = 0;
00702 countOffset[sat]
00703 = int((SPList[i].firstTime - FirstTime)/DT + 0.5);
00704 break;
00705 }
00706 }
00707 else {
00708 dataIndex[sat] = j;
00709 }
00710
00711 }
00712
00713
00714 if(indexStatus[i] > 0) {
00715 listIndex.erase(kt++);
00716 }
00717 else kt++;
00718
00719 }
00720
00721 currentN++;
00722
00723 }
00724
00725 indexMap = nextIndexMap;
00726
00727 return 1;
00728 }
00729
00730
00731 int SatPassIterator::next(RinexObsData& robs) throw(Exception)
00732 {
00733 if(listIndex.size() == 0) return 0;
00734
00735 map<unsigned int, unsigned int> indexMap;
00736 int iret = next(indexMap);
00737 if(iret == 0) return iret;
00738
00739 robs.obs.clear();
00740 robs.epochFlag = 0;
00741 robs.time = FirstTime + (currentN-1) * DT;
00742 robs.clockOffset = 0.0;
00743 robs.numSvs = 0;
00744
00745
00746 map<unsigned int, unsigned int>::const_iterator kt;
00747 for(kt = indexMap.begin(); kt != indexMap.end(); kt++) {
00748 int i = kt->first;
00749 int j = kt->second;
00750 GSatID sat = SPList[i].getSat();
00751
00752 bool found = false;
00753 bool flag = (SPList[i].spdvector[j].flag != SatPass::BAD);
00754 for(int k=0; k<SPList[i].labelForIndex.size(); k++) {
00755 RinexObsHeader::RinexObsType ot;
00756 ot = RinexObsHeader::convertObsType(SPList[i].labelForIndex[k]);
00757 if(ot == RinexObsHeader::UN) {
00758 }
00759 else {
00760 found = true;
00761 robs.obs[sat][ot].data = flag ? SPList[i].spdvector[j].data[k] : 0.;
00762 robs.obs[sat][ot].lli = flag ? SPList[i].spdvector[j].lli[k] : 0;
00763 robs.obs[sat][ot].ssi = flag ? SPList[i].spdvector[j].ssi[k] : 0;
00764 }
00765 }
00766 if(found) robs.numSvs++;
00767 }
00768
00769 return 1;
00770 }
00771
00772
00773 void SatPassIterator::reset(void) throw()
00774 {
00775
00776 currentN = 0;
00777 listIndex.clear();
00778 dataIndex.clear();
00779 countOffset.clear();
00780 indexStatus = vector<int>(SPList.size(),-1);
00781
00782
00783 for(int i=0; i<SPList.size(); i++) {
00784
00785 if(SPList[i].Status < 0) continue;
00786
00787
00788 if(listIndex.find(SPList[i].sat) == listIndex.end()) {
00789 indexStatus[i] = 0;
00790 listIndex[SPList[i].sat] = i;
00791 dataIndex[SPList[i].sat] = 0;
00792 countOffset[SPList[i].sat]
00793 = int((SPList[i].firstTime - FirstTime)/DT + 0.5);
00794 }
00795 else {
00796 indexStatus[i] = -1;
00797 }
00798 }
00799 }
00800
00801
00802
00803
00804 void sort(vector<SatPass>& SPList) throw()
00805 {
00806 std::sort(SPList.begin(), SPList.end());
00807 }
00808
00809 int SatPassFromRinexFiles(vector<string>& filenames,
00810 vector<string>& obstypes,
00811 double dt,
00812 vector<SatPass>& SPList,
00813 CommonTime beginTime,
00814 CommonTime endTime)
00815 throw(Exception)
00816 {
00817 if(filenames.size() == 0) return -1;
00818
00819
00820 if(filenames.size() > 1) sortRinexObsFiles(filenames);
00821
00822 int i,j,nfiles = 0;
00823 vector<double> data(obstypes.size(),0.0);
00824 vector<unsigned short> ssi(obstypes.size(),0);
00825 vector<unsigned short> lli(obstypes.size(),0);
00826 map<GSatID,int> indexForSat;
00827 map<GSatID,int>::const_iterator satit;
00828 RinexObsHeader header;
00829 RinexObsData obsdata;
00830
00831
00832 sort(SPList);
00833
00834
00835
00836 for(i=0; i<SPList.size(); i++)
00837 indexForSat[SPList[i].sat] = i;
00838
00839 for(int nfile=0; nfile<filenames.size(); nfile++) {
00840 string filename = filenames[nfile];
00841
00842
00843 RinexObsStream RinFile(filename.c_str());
00844 if(filename.empty() || !RinFile) {
00845
00846 continue;
00847 }
00848 RinFile.exceptions(fstream::failbit);
00849
00850
00851 try { RinFile >> header; }
00852 catch(Exception& e) {
00853
00854 continue;
00855 }
00856
00857
00858 nfiles++;
00859
00860
00861 if(obstypes.size() == 0) {
00862 for(j=0; j<header.obsTypeList.size(); j++) {
00863 obstypes.push_back(RinexObsHeader::convertObsType(header.obsTypeList[j]));
00864 }
00865 data = vector<double>(obstypes.size(),0.0);
00866 ssi = vector<unsigned short>(obstypes.size(),0);
00867 lli = vector<unsigned short>(obstypes.size(),0);
00868 }
00869
00870
00871 while(RinFile >> obsdata) {
00872 RinexObsData::RinexSatMap::const_iterator it;
00873 RinexObsData::RinexObsTypeMap::const_iterator jt;
00874
00875
00876 if(obsdata.time < beginTime) continue;
00877 if(obsdata.time > endTime) break;
00878
00879
00880 if(obsdata.epochFlag != 0 && obsdata.epochFlag != 1) continue;
00881
00882
00883 for(it=obsdata.obs.begin(); it != obsdata.obs.end(); ++it) {
00884 GSatID sat = it->first;
00885
00886
00887 for(j=0; j<obstypes.size(); j++) {
00888 if((jt=it->second.find(RinexObsHeader::convertObsType(obstypes[j])))
00889 == it->second.end()) {
00890 data[j] = 0.0;
00891 lli[j] = ssi[j] = 0;
00892 }
00893 else {
00894 data[j] = jt->second.data;
00895 lli[j] = jt->second.lli;
00896 ssi[j] = jt->second.ssi;
00897 }
00898 }
00899
00900
00901 satit = indexForSat.find(sat);
00902
00903
00904 if(satit == indexForSat.end()) {
00905 SatPass newSP(sat,dt,obstypes);
00906 SPList.push_back(newSP);
00907 indexForSat[sat] = SPList.size()-1;
00908 satit = indexForSat.find(sat);
00909 }
00910
00911
00912 do {
00913 i = SPList[satit->second].addData(obsdata.time,obstypes,data,lli,ssi);
00914 if(i < 0) {
00915 if(i == -1) {
00916 SatPass newSP(sat,dt,obstypes);
00917 SPList.push_back(newSP);
00918 indexForSat[sat] = SPList.size()-1;
00919 satit = indexForSat.find(sat);
00920 }
00921 else if(i == -2) {
00922 Exception e("Time tags out of order in the RINEX file "
00923 + filename);
00924
00925 GPSTK_THROW(e);
00926 }
00927
00928
00929 }
00930 } while(i < 0);
00931
00932 }
00933
00934 }
00935
00936 RinFile.close();
00937 }
00938
00939 return nfiles;
00940 }
00941
00942 int SatPassToRinexFile(string filename,
00943 RinexObsHeader& header,
00944 vector<SatPass>& SPList) throw(Exception)
00945 {
00946 try {
00947
00948 SatPassIterator spit(SPList);
00949
00950
00951 RinexObsStream rstrm(filename.c_str(), ios::out);
00952 if(!rstrm) return -1;
00953 rstrm.exceptions(fstream::failbit);
00954
00955
00956 header.obsTypeList.clear();
00957 for(int i=0; i<SPList[0].labelForIndex.size(); i++)
00958 header.obsTypeList.push_back(
00959 RinexObsHeader::convertObsType(SPList[0].labelForIndex[i]));
00960 header.firstObs = spit.getFirstTime();
00961 header.lastObs = spit.getLastTime();
00962 header.interval = spit.getDT();
00963 header.valid |= RinexObsHeader::firstTimeValid;
00964 header.valid |= RinexObsHeader::lastTimeValid;
00965 header.valid |= RinexObsHeader::intervalValid;
00966
00967 rstrm << header;
00968
00969 RinexObsData robs;
00970 RinexObsData::RinexSatMap::const_iterator it;
00971 RinexObsData::RinexObsTypeMap::const_iterator jt;
00972
00973 while(spit.next(robs)) {
00974 if(robs.epochFlag != 0 || robs.obs.size() == 0) {
00975 continue;
00976 }
00977
00978 rstrm << robs;
00979 }
00980
00981 rstrm.close();
00982 }
00983 catch(Exception& e) { GPSTK_RETHROW(e); }
00984
00985 return 0;
00986 }
00987
00988 }