00001 #pragma ident "$Id: DiscCorr.cpp 3153 2012-06-21 15:18:18Z snelsen $"
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00034
00035 #include <string>
00036 #include <iostream>
00037 #include <sstream>
00038 #include <vector>
00039 #include <deque>
00040 #include <list>
00041 #include <algorithm>
00042
00043 #include "StringUtils.hpp"
00044 #include "Stats.hpp"
00045 #include "PolyFit.hpp"
00046 #include "GNSSconstants.hpp"
00047 #include "RobustStats.hpp"
00048 #include "SystemTime.hpp"
00049 #include "CivilTime.hpp"
00050
00051 #include "DiscCorr.hpp"
00052
00053 using namespace std;
00054 using namespace gpstk;
00055 using namespace StringUtils;
00056
00057
00058
00059
00060
00061 string GDCconfiguration::GDCVersion = string("5.3 7/14/2008");
00062
00063
00064
00065
00066
00067 void GDCconfiguration::setParameter(string cmd) throw(Exception)
00068 {
00069 try {
00070 if(cmd.empty()) return;
00071
00072 while(cmd[0] == '-') cmd.erase(0,1);
00073 if(cmd.substr(0,2) == "DC") cmd.erase(0,2);
00074
00075 string label, value;
00076 string::size_type pos=cmd.find_first_of(",=:");
00077 if(pos == string::npos) {
00078 label = cmd;
00079 }
00080 else {
00081 label = cmd.substr(0,pos);
00082 value = cmd;
00083 value.erase(0,pos+1);
00084 }
00085
00086 setParameter(label, asDouble(value));
00087 }
00088 catch(Exception& e) { GPSTK_RETHROW(e); }
00089 catch(exception& e) { Exception E("std except: "+string(e.what())); GPSTK_THROW(E); }
00090 catch(...) { Exception e("Unknown exception"); GPSTK_THROW(e); }
00091 }
00092
00093
00094
00095
00096 void GDCconfiguration::setParameter(string label, double value) throw(Exception)
00097 {
00098 try {
00099 if(CFG.find(label) == CFG.end())
00100 ;
00101 else {
00102
00103 if(CFG["Debug"] > 0) *(p_oflog) << "GDCconfiguration::setParameter sets "
00104 << label << " to " << value << endl;
00105 CFG[label] = value;
00106 }
00107 }
00108 catch(Exception& e) { GPSTK_RETHROW(e); }
00109 catch(exception& e) { Exception E("std except: "+string(e.what())); GPSTK_THROW(E); }
00110 catch(...) { Exception e("Unknown exception"); GPSTK_THROW(e); }
00111 }
00112
00113
00114
00115
00116 void GDCconfiguration::DisplayParameterUsage(ostream& os, bool advanced)
00117 throw(Exception)
00118 {
00119 try {
00120 os << "GPSTk Discontinuity Corrector (GDC) v." << GDCVersion
00121 << " configuration:"
00122
00123
00124 << endl;
00125
00126 map<string,double>::const_iterator it;
00127 for(it=CFG.begin(); it != CFG.end(); it++) {
00128 if(CFGdescription[it->first][0] == '*')
00129 continue;
00130 ostringstream stst;
00131 stst << it->first
00132 << "=" << it->second;
00133 os << " " << leftJustify(stst.str(),18)
00134 << " : " << CFGdescription[it->first]
00135 << endl;
00136 }
00137 if(advanced) {
00138 os << " Advanced options:" << endl;
00139 for(it=CFG.begin(); it != CFG.end(); it++) {
00140 if(CFGdescription[it->first][0] != '*')
00141 continue;
00142 ostringstream stst;
00143 stst << it->first
00144 << "=" << it->second;
00145 os << " " << leftJustify(stst.str(),25)
00146 << " : " << CFGdescription[it->first].substr(2)
00147 << endl;
00148 }
00149 }
00150 }
00151 catch(Exception& e) { GPSTK_RETHROW(e); }
00152 catch(exception& e) { Exception E("std except: "+string(e.what())); GPSTK_THROW(E); }
00153 catch(...) { Exception e("Unknown exception"); GPSTK_THROW(e); }
00154 }
00155
00156
00157
00158 #define setcfg(a,b,c) { CFG[#a]=b; CFGdescription[#a]=c; }
00159
00160 void GDCconfiguration::initialize(void)
00161 {
00162 try {
00163 p_oflog = &cout;
00164
00165
00166 setcfg(DT, -1, "nominal timestep of data (seconds) [required - no default!]");
00167 setcfg(Debug, 0, "level of diagnostic output to log, from none(0) to extreme(7)");
00168 setcfg(useCA, 0, "use C/A code pseudorange (C1) ()");
00169 setcfg(MaxGap, 180, "maximum allowed time gap within a segment (seconds)");
00170 setcfg(MinPts, 13, "minimum number of good points in phase segment ()");
00171 setcfg(WLSigma, 1.5, "expected WL sigma (WL cycle) [NB = ~0.83*p-range noise(m)]");
00172 setcfg(GFVariation, 16,
00173 "expected maximum variation in GF phase in time DT (meters)");
00174
00175 setcfg(OutputGPSTime, 0,
00176 "if 0: Y,M,D,H,M,S else: W,SoW (GPS) in editing commands");
00177 setcfg(OutputDeletes, 1,
00178 "if non-zero, include delete commands in the output cmd list");
00179
00180
00181
00182 setcfg(RawBiasLimit, 100, "* change in raw R-Ph that triggers bias reset (m)");
00183
00184 setcfg(WLNSigmaDelete, 2, "* delete segments with sig(WL) > this * WLSigma ()");
00185
00186
00187 setcfg(WLWindowWidth, 50, "* sliding window width for WL slip detection = 10+this/dt) (points)");
00188 setcfg(WLNWindows, 2.5,
00189 "* minimum segment size for WL small slip search (WLWindowWidth)");
00190 setcfg(WLobviousLimit, 3,
00191 "* minimum delta(WL) that produces an obvious slip (WLSigma)");
00192 setcfg(WLNSigmaStrip, 3.5, "* delete points with WL > this * computed sigma ()");
00193 setcfg(WLNptsOutlierStats, 200,
00194 "* maximum segment size to use robust outlier detection (pts)");
00195 setcfg(WLRobustWeightLimit, 0.35,
00196 "* minimum good weight in robust outlier detection (0<wt<=1)");
00197
00198 setcfg(WLSlipEdge, 3,
00199 "* minimum separating WL slips and end of segment, else edit (pts)");
00200
00201 setcfg(WLSlipSize, 1.0, "* minimum WL slip size (WL wavelengths)");
00202 setcfg(WLSlipExcess, 0.1,
00203 "* minimum amount WL slip must exceed noise (WL wavelengths)");
00204
00205 setcfg(WLSlipSeparation, 2.5, "* minimum excess/noise ratio of WL slip ()");
00206
00207 setcfg(GFSlipWidth, 5,
00208 "* minimum segment length for GF small slip detection (pts)");
00209 setcfg(GFSlipEdge, 3,
00210 "* minimum separating GF slips and end of segment, else edit (pts)");
00211 setcfg(GFobviousLimit, 1,
00212 "* minimum delta(GF) that produces an obvious slip (GFVariation)");
00213 setcfg(GFSlipOutlier, 5, "* minimum GF outlier magnitude/noise ratio ()");
00214 setcfg(GFSlipSize, 0.8, "* minimum GF slip size (5.4cm wavelengths)");
00215 setcfg(GFSlipStepToNoise, 2, "* maximum GF slip step/noise ratio ()");
00216 setcfg(GFSlipToStep, 3, "* minimum GF slip magnitude/step ratio ()");
00217 setcfg(GFSlipToNoise, 3, "* minimum GF slip magnitude/noise ratio ()");
00218
00219 setcfg(GFFixNpts, 15,
00220 "* maximum number of points on each side to fix GF slips ()");
00221 setcfg(GFFixDegree, 3, "* degree of polynomial used to fix GF slips ()");
00222 setcfg(GFFixMaxRMS, 100,
00223 "* limit on RMS fit residuals to fix GF slips, else delete (5.4cm)");
00224
00225 }
00226 catch(Exception& e) { GPSTK_RETHROW(e); }
00227 catch(exception& e) { Exception E("std except: "+string(e.what())); GPSTK_THROW(E); }
00228 catch(...) { Exception e("Unknown exception"); GPSTK_THROW(e); }
00229 }
00230
00231
00232
00233
00234
00235
00236
00237 class Segment {
00238 public:
00239
00240 int nbeg,nend;
00241
00242 int npts;
00243 int nseg;
00244 double bias1;
00245 Stats<double> WLStats;
00246 double bias2;
00247 PolyFit<double> PF;
00248 double RMSROF;
00249 bool WLsweep;
00250
00251
00252 Segment(void) : nbeg(0),nend(0),npts(0),nseg(0),bias1(0.0),bias2(0.0)
00253 { WLStats.Reset(); WLsweep=false; }
00254 Segment(const Segment& s)
00255 { *this = s; }
00256 ~Segment(void) { }
00257 Segment& operator=(const Segment& s) {
00258 if(this==&s) return *this;
00259 nbeg = s.nbeg; nend = s.nend; npts = s.npts; nseg = s.nseg;
00260 bias1 = s.bias1; bias2 = s.bias2;
00261 WLStats = s.WLStats; PF = s.PF; RMSROF = s.RMSROF; WLsweep = s.WLsweep;
00262 return *this;
00263 }
00264 };
00265
00266
00267
00268
00269 class Slip {
00270 public:
00271 int index;
00272 long NWL,N1;
00273 string msg;
00274 explicit Slip(int in) : index(in),NWL(0),N1(0) { }
00275 bool operator<(const Slip &rhs) const { return index < rhs.index; }
00276 };
00277
00278
00279
00280
00281
00282 class GDCPass : public SatPass, public GDCconfiguration
00283 {
00284 public:
00285 static const unsigned short DETECT;
00286 static const unsigned short FIX;
00287 static const unsigned short WLDETECT;
00288 static const unsigned short WLFIX;
00289 static const unsigned short GFDETECT;
00290 static const unsigned short GFFIX;
00291
00292 explicit GDCPass(SatPass& sp, const GDCconfiguration& gdc);
00293
00294
00295
00297 int preprocess(void) throw(Exception);
00298
00302 int linearCombinations(void) throw(Exception);
00303
00305 int detectWLslips(void) throw(Exception);
00306
00310 int detectObviousSlips(string which) throw(Exception);
00311
00315 int firstDifferences(string which) throw(Exception);
00316
00319 void WLcomputeStats(list<Segment>::iterator& it) throw(Exception);
00320
00323 void WLsigmaStrip(list<Segment>::iterator& it) throw(Exception);
00324
00328 int WLstatSweep(list<Segment>::iterator& it, int width) throw(Exception);
00329
00334 int detectWLsmallSlips(void) throw(Exception);
00335
00345 bool foundWLsmallSlip(list<Segment>::iterator& it, int i) throw(Exception);
00346
00349 int fixAllSlips(string which) throw(Exception);
00350
00353 void fixOneSlip(list<Segment>::iterator& kt, string which) throw(Exception);
00354
00356 void WLslipFix(list<Segment>::iterator& left,
00357 list<Segment>::iterator& right)
00358 throw(Exception);
00359
00363 int prepareGFdata(void) throw(Exception);
00364
00366 int detectGFslips(void) throw(Exception);
00367
00370 int GFphaseResiduals(list<Segment>::iterator& it) throw(Exception);
00371
00375 int detectGFsmallSlips(void) throw(Exception);
00376
00383 bool foundGFoutlier(int i,int inew,Stats<double>& pastSt,Stats<double>& futureSt)
00384 throw(Exception);
00385
00396 bool foundGFsmallSlip(int i, int nseg, int iend, int ibeg,
00397 deque<int>& pastIn, deque<int>& futureIn,
00398 Stats<double>& pastSt, Stats<double>& futureSt)
00399 throw(Exception);
00400
00402 void GFslipFix(list<Segment>::iterator& left,
00403 list<Segment>::iterator& right)
00404 throw(Exception);
00405
00409 long EstimateGFslipFix(list<Segment>::iterator& left,
00410 list<Segment>::iterator& right,
00411 int nb, int ne, long n1)
00412 throw(Exception);
00413
00415 int WLconsistencyCheck(void) throw(Exception);
00416
00419 string finish(int iret, SatPass& svp, vector<string>& editCmds) throw(Exception);
00420
00424 list<Segment>::iterator createSegment(list<Segment>::iterator sit,
00425 int ibeg,
00426 string msg=string())
00427 throw(Exception);
00428
00434 string dumpSegments(string msg, int level=2, bool extra=false)
00435 throw(Exception);
00436
00439 void deleteSegment(list<Segment>::iterator& it, string msg=string())
00440 throw(Exception);
00441
00442 private:
00443
00446 double cfg_func(string a) throw(Exception)
00447 {
00448 if(CFGdescription[a] == string()) {
00449 Exception e("cfg(UNKNOWN LABEL) : " + a);
00450 GPSTK_THROW(e);
00451 }
00452 return CFG[a];
00453 }
00454
00457 list<Segment> SegList;
00458
00460 list<Slip> SlipList;
00461
00463
00464
00466 Stats<double> WLPassStats;
00467
00469 Stats<double> GFPassStats;
00470
00472 PolyFit<double> GFPassFit;
00473
00475 map<string,int> learn;
00476
00477 };
00478
00479
00480
00481
00482
00483 int GDCUnique=0;
00484 int GDCUniqueFix;
00485
00486
00487 #define log *(p_oflog)
00488 #define cfg(a) cfg_func(#a)
00489
00490 enum obstypeenum { L1=0, L2=1, P1=2, P2=3, A1=4, A2=5 };
00491 vector<string> DCobstypes;
00492
00493
00494 const double CFF=C_MPS/OSC_FREQ_GPS;
00495 const double F1=L1_MULT_GPS;
00496 const double F2=L2_MULT_GPS;
00497
00498 const double wl1=CFF/F1;
00499 const double wl2=CFF/F2;
00500 const double wlwl=CFF/(F1-F2);
00501 const double wl21=CFF*(1.0/F2 - 1.0/F1);
00502
00503 const double wl1r=F1/(F1+F2);
00504 const double wl2r=F2/(F1+F2);
00505 const double wl1p=wl1*F1/(F1-F2);
00506 const double wl2p=-wl2*F2/(F1-F2);
00507
00508 const double gf1r=-1;
00509 const double gf2r=1;
00510 const double gf1p=wl1;
00511 const double gf2p=-wl2;
00512
00513
00514
00515 const int BadInput=-5;
00516 const int NoData=-4;
00517 const int FatalProblem=-3;
00518
00519 const int Singular=-1;
00520 const int ReturnOK=0;
00521
00522
00523
00524
00525
00526
00527
00528
00529
00530
00531
00532
00533
00534
00535
00536
00537
00538
00539
00540
00541
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552
00553
00554
00555
00556
00557
00558
00559
00560
00561
00562
00563
00564
00565
00566
00567
00568
00569 const unsigned short GDCPass::WLDETECT = 2;
00570 const unsigned short GDCPass::GFDETECT = 4;
00571 const unsigned short GDCPass::DETECT = 6;
00572 const unsigned short GDCPass::WLFIX = 8;
00573 const unsigned short GDCPass::GFFIX = 16;
00574 const unsigned short GDCPass::FIX = 24;
00575
00576
00577
00578
00579
00580
00581
00582
00583
00584
00585
00586
00587
00588
00589
00590
00591
00592
00593
00594
00595 int gpstk::DiscontinuityCorrector(SatPass& svp,
00596 GDCconfiguration& gdc,
00597 vector<string>& editCmds,
00598 string& retMessage)
00599 throw(Exception)
00600 {
00601 try {
00602 int i,j,iret;
00603 GDCUnique++;
00604
00605
00606
00607 DCobstypes.clear();
00608 DCobstypes.push_back("L1");
00609 DCobstypes.push_back("L2");
00610 DCobstypes.push_back((int(gdc.getParameter("useCA"))) == 0 ? "P1" : "C1");
00611 DCobstypes.push_back("P2");
00612 DCobstypes.push_back("A1");
00613 DCobstypes.push_back("A2");
00614
00615
00616
00617 vector<double> newdata(6);
00618 try {
00619 newdata[L1] = svp.data(0,DCobstypes[L1]);
00620 newdata[L2] = svp.data(0,DCobstypes[L2]);
00621 newdata[P1] = svp.data(0,DCobstypes[P1]);
00622 newdata[P2] = svp.data(0,DCobstypes[P2]);
00623 }
00624 catch (Exception& e) {
00625 return BadInput;
00626 }
00627
00628
00629
00630 SatPass nsvp(svp.getSat(), svp.getDT(), DCobstypes);
00631
00632
00633 nsvp.status() = svp.status();
00634 vector<unsigned short> lli(6),ssi(6);
00635 for(i=0; i<svp.size(); i++) {
00636 for(j=0; j<6; j++) {
00637 newdata[j] = j < 4 ? svp.data(i,DCobstypes[j]) : 0.0;
00638 lli[j] = j < 4 ? svp.LLI(i,DCobstypes[j]) : 0;
00639 ssi[j] = j < 4 ? svp.SSI(i,DCobstypes[j]) : 0;
00640 }
00641
00642 nsvp.addData(svp.time(i), DCobstypes, newdata, lli, ssi, svp.getFlag(i));
00643 }
00644
00645
00646
00647 GDCPass gp(nsvp,gdc);
00648
00649
00650
00651
00652
00653
00654 for(;;) {
00655
00656 if( (iret = gp.preprocess() )) break;
00657 if( (iret = gp.linearCombinations() )) break;
00658
00659
00660 if( (iret = gp.detectWLslips() )) break;
00661 if( (iret = gp.fixAllSlips("WL") )) break;
00662
00663
00664 if( (iret = gp.prepareGFdata() )) break;
00665 if( (iret = gp.detectGFslips() )) break;
00666 if( (iret = gp.WLconsistencyCheck() )) break;
00667 if( (iret = gp.fixAllSlips("GF") )) break;
00668
00669 break;
00670 }
00671
00672
00673
00674
00675
00676 retMessage = gp.finish(iret, svp, editCmds);
00677
00678 return iret;
00679 }
00680 catch(Exception& e) { GPSTK_RETHROW(e); }
00681 catch(exception& e) { Exception E("std except: "+string(e.what())); GPSTK_THROW(E); }
00682 catch(...) { Exception e("Unknown exception"); GPSTK_THROW(e); }
00683 }
00684
00685
00686
00687
00688
00689 GDCPass::GDCPass(SatPass& sp, const GDCconfiguration& gdc)
00690 : SatPass(sp.getSat(), sp.getDT(), sp.getObsTypes())
00691 {
00692 int i,j;
00693 Status = sp.status();
00694 dt = sp.getDT();
00695 sat = sp.getSat();
00696 vector<string> ot = sp.getObsTypes();
00697 for(i=0; i<ot.size(); i++) {
00698 labelForIndex[i] = ot[i];
00699 indexForLabel[labelForIndex[i]] = i;
00700 }
00701
00702 vector<double> vdata;
00703 vector<unsigned short> lli,ssi;
00704 for(i=0; i<sp.size(); i++) {
00705 vdata.clear();
00706 lli.clear();
00707 ssi.clear();
00708 for(j=0; j<ot.size(); j++) {
00709 vdata.push_back(sp.data(i,ot[j]));
00710 lli.push_back(sp.LLI(i,ot[j]));
00711 ssi.push_back(sp.SSI(i,ot[j]));
00712 }
00713 addData(sp.time(i),ot,vdata,lli,ssi,sp.getFlag(i));
00714 }
00715
00716 *((GDCconfiguration*)this) = gdc;
00717
00718 learn.clear();
00719 }
00720
00721
00722 int GDCPass::preprocess(void) throw(Exception)
00723 {
00724 try {
00725 int i,ilast,Ngood;
00726 double biasL1,biasL2,dbias;
00727 list<Segment>::iterator it;
00728
00729 if(cfg(Debug) >= 2) {
00730 log << "======== Beg GPSTK Discontinuity Corrector " << GDCUnique
00731 << " ================================================" << endl;
00732 log << "GPSTK Discontinuity Corrector Ver. " << GDCVersion << " Run "
00733 << CivilTime(SystemTime()) << endl;
00734 }
00735
00736
00737 if(cfg(DT) <= 0) {
00738 log << "Error: data time interval is not set...Abort" << endl;
00739 return FatalProblem;
00740 }
00741
00742
00743 CFG["WLWindowWidth"] = 10 + int(0.5+CFG["WLWindowWidth"]/CFG["DT"]);
00744
00745
00746
00747 SegList.clear();
00748 {
00749 Segment s;
00750 s.nseg = 1;
00751 SegList.push_back(s);
00752 }
00753 it = SegList.begin();
00754
00755
00756
00757 for(ilast=-1,i=0; i<size(); i++) {
00758
00759
00760 if(!(spdvector[i].flag & OK)) continue;
00761
00762
00763 spdvector[i].flag = OK;
00764
00765
00766
00767
00768
00769
00770
00771
00772
00773
00774
00775
00776
00777
00778
00779
00780
00781
00782 if(ilast == -1) ilast = it->nbeg = i;
00783
00784
00785
00786
00787 if(cfg(DT)*(i-ilast) > cfg(MaxGap))
00788 it = createSegment(it,i,"initial gap");
00789
00790
00791 it->npts++;
00792 ilast = i;
00793 }
00794
00795
00796 if(ilast == -1) ilast = it->nbeg;
00797 it->nend = ilast;
00798
00799
00800
00801
00802 for(Ngood=0,it=SegList.begin(); it != SegList.end(); it++) {
00803 biasL1 = biasL2 = 0.0;
00804
00805
00806 for(i=it->nbeg; i<=it->nend; i++) {
00807 if(!(spdvector[i].flag & OK)) continue;
00808
00809 dbias = fabs(spdvector[i].data[P1]-wl1*spdvector[i].data[L1]-biasL1);
00810 if(dbias > cfg(RawBiasLimit)) {
00811 if(cfg(Debug) >= 2) log << "BEFresetL1 " << GDCUnique
00812 << " " << sat << " " << printTime(time(i),outFormat)
00813 << " " << fixed << setprecision(3) << biasL1
00814 << " " << spdvector[i].data[P1] - wl1 * spdvector[i].data[L1] << endl;
00815 biasL1 = spdvector[i].data[P1] - wl1 * spdvector[i].data[L1];
00816 }
00817
00818 dbias = fabs(spdvector[i].data[P2]-wl2*spdvector[i].data[L2]-biasL2);
00819 if(dbias > cfg(RawBiasLimit)) {
00820 if(cfg(Debug) >= 2) log << "BEFresetL2 " << GDCUnique
00821 << " " << sat << " " << printTime(time(i),outFormat)
00822 << " " << fixed << setprecision(3) << biasL2
00823 << " " << spdvector[i].data[P2] - wl2 * spdvector[i].data[L2] << endl;
00824 biasL2 = spdvector[i].data[P2] - wl2 * spdvector[i].data[L2];
00825 }
00826
00827 spdvector[i].data[A1] =
00828 spdvector[i].data[P1] - wl1 * spdvector[i].data[L1] - biasL1;
00829 spdvector[i].data[A2] =
00830 spdvector[i].data[P2] - wl2 * spdvector[i].data[L2] - biasL2;
00831
00832 }
00833
00834
00835 if(it->npts < int(cfg(MinPts)))
00836 deleteSegment(it,"insufficient data in segment");
00837 else
00838 Ngood++;
00839 }
00840
00841 if(cfg(Debug) >= 2) dumpSegments("BEF",2,true);
00842
00843 if(Ngood == 0) return NoData;
00844 return ReturnOK;
00845 }
00846 catch(Exception& e) { GPSTK_RETHROW(e); }
00847 catch(exception& e) { Exception E("std except: "+string(e.what())); GPSTK_THROW(E); }
00848 catch(...) { Exception e("Unknown exception"); GPSTK_THROW(e); }
00849 }
00850
00851
00852
00853 int GDCPass::linearCombinations(void) throw(Exception)
00854 {
00855 try {
00856 int i;
00857 double wlr,wlp,wlbias,gfr,gfp;
00858 list<Segment>::iterator it;
00859
00860
00861 for(it=SegList.begin(); it != SegList.end(); it++) {
00862 it->npts = 0;
00863
00864
00865 for(i=it->nbeg; i<=it->nend; i++) {
00866 if(!(spdvector[i].flag & OK)) continue;
00867
00868
00869 wlr = wl1r * spdvector[i].data[P1] + wl2r * spdvector[i].data[P2];
00870
00871 wlp = wl1p * spdvector[i].data[L1] + wl2p * spdvector[i].data[L2];
00872
00873 gfr = spdvector[i].data[P1] - spdvector[i].data[P2];
00874
00875 gfp = gf1p * spdvector[i].data[L1] + gf2p * spdvector[i].data[L2];
00876
00877 wlbias = (wlp-wlr)/wlwl;
00878
00879
00880 if(it->npts == 0) {
00881 it->bias1 = wlbias;
00882 it->bias2 = gfp;
00883 }
00884
00885
00886 spdvector[i].data[L1] = gfp + gfr;
00887 spdvector[i].data[L2] = gfp;
00888 spdvector[i].data[P1] = wlbias;
00889 spdvector[i].data[P2] = - gfr;
00890
00891 it->npts++;
00892 }
00893 }
00894
00895 if(cfg(Debug) >= 2) dumpSegments("LCD");
00896
00897 return ReturnOK;
00898 }
00899 catch(Exception& e) { GPSTK_RETHROW(e); }
00900 catch(exception& e) { Exception E("std except: "+string(e.what())); GPSTK_THROW(E); }
00901 catch(...) { Exception e("Unknown exception"); GPSTK_THROW(e); }
00902 }
00903
00904
00905
00906
00907 int GDCPass::detectWLslips(void) throw(Exception)
00908 {
00909 try {
00910 int iret;
00911 list<Segment>::iterator it;
00912
00913
00914 if( (iret = detectObviousSlips("WL"))) return iret;
00915
00916 for(it=SegList.begin(); it != SegList.end(); it++) {
00917
00918
00919 WLcomputeStats(it);
00920
00921
00922 if(it->npts > 0) WLsigmaStrip(it);
00923
00924
00925 if(cfg(Debug) >= 1 && it->npts >= int(cfg(MinPts)))
00926 log << "WLSIG " << GDCUnique << " " << sat
00927 << " " << it->nseg
00928 << " " << printTime(time(it->nbeg),outFormat)
00929 << fixed << setprecision(3)
00930 << " " << it->WLStats.StdDev()
00931 << " " << it->WLStats.Average()
00932 << " " << it->WLStats.Minimum()
00933 << " " << it->WLStats.Maximum()
00934 << " " << it->npts
00935 << " " << it->nbeg << " - " << it->nend
00936 << " " << it->bias1
00937 << " " << it->bias2
00938 << endl;
00939
00940
00941 if(it->WLStats.StdDev() > cfg(WLNSigmaDelete)*cfg(WLSigma))
00942 deleteSegment(it,"WL sigma too big");
00943
00944
00945
00946
00947
00948 if(double(it->npts) >= cfg(WLNWindows) * int(cfg(WLWindowWidth))) {
00949 iret = WLstatSweep(it,int(cfg(WLWindowWidth)));
00950 if(iret) return iret;
00951 }
00952
00953 }
00954
00955
00956
00957 if( (iret = detectWLsmallSlips())) return iret;
00958
00959
00960 for(it=SegList.begin(); it != SegList.end(); it++) {
00961 if(it->npts < int(cfg(MinPts)))
00962 deleteSegment(it,"insufficient data in segment");
00963 }
00964
00965 if(cfg(Debug) >= 4) dumpSegments("WLD");
00966
00967 return ReturnOK;
00968 }
00969 catch(Exception& e) { GPSTK_RETHROW(e); }
00970 catch(exception& e) { Exception E("std except: "+string(e.what())); GPSTK_THROW(E); }
00971 catch(...) { Exception e("Unknown exception"); GPSTK_THROW(e); }
00972 }
00973
00974
00975
00976
00977
00978 int GDCPass::detectObviousSlips(string which) throw(Exception)
00979 {
00980 try {
00981
00982 const double WLobviousNwlLimit=cfg(WLobviousLimit)*cfg(WLSigma);
00983 const double GFobviousNwlLimit=cfg(GFobviousLimit)*cfg(GFVariation)/wl21;
00984 bool outlier;
00985 int i,j,iret,ibad=0,igood,nok;
00986 double limit,wlbias;
00987 list<Segment>::iterator it;
00988
00989
00990 iret = firstDifferences(which);
00991 if(iret) return iret;
00992
00993 if(cfg(Debug) >= 5) dumpSegments(string("D")+which,2,true);
00994
00995
00996
00997 limit = (which == string("WL") ? WLobviousNwlLimit : GFobviousNwlLimit);
00998 it = SegList.begin();
00999 nok = 0;
01000 igood = -1;
01001 outlier = false;
01002 for(i=0; i<size(); i++) {
01003 if(i < it->nbeg) {
01004 outlier = false;
01005 continue;
01006 }
01007 if(i > it->nend) {
01008 if(outlier) {
01009 if(spdvector[ibad].flag & OK) nok--;
01010 spdvector[ibad].flag = BAD;
01011 learn[string("points deleted: ") + which + string(" slip outlier")]++;
01012 outlier = false;
01013 }
01014 it->npts = nok;
01015
01016 while(it->nbeg < it->nend
01017 && it->nbeg < size()
01018 && !(spdvector[it->nbeg].flag & OK) ) it->nbeg++;
01019 while(it->nend > it->nbeg
01020 && it->nend > 0
01021 && !(spdvector[it->nend].flag & OK) ) it->nend--;
01022 it++;
01023 if(it == SegList.end())
01024 return ReturnOK;
01025 nok = 0;
01026 }
01027
01028 if(!(spdvector[i].flag & OK))
01029 continue;
01030 nok++;
01031
01032 if(igood == -1) igood = i;
01033
01034 if(fabs(spdvector[i].data[A1]) > limit) {
01035 outlier = true;
01036 ibad = i;
01037 }
01038 else if(outlier) {
01039 for(j=igood+1; j<ibad; j++) {
01040 if(spdvector[j].flag & OK)
01041 nok--;
01042 if(spdvector[j].flag & DETECT)
01043 log << "Warning - found an obvious slip, "
01044 << "but marking BAD a point already marked with slip "
01045 << GDCUnique << " " << sat
01046 << " " << printTime(time(j),outFormat) << " " << j << endl;
01047 spdvector[j].flag = BAD;
01048 learn[string("points deleted: ") + which + string(" slip outlier")]++;
01049 }
01050
01051
01052 it->npts = nok-2;
01053
01054 it = createSegment(it,ibad,which+string(" slip gross"));
01055
01056
01057 spdvector[ibad].flag |= (which == string("WL") ? WLDETECT : GFDETECT);
01058
01059
01060 if(which == "WL") {
01061 wlbias = spdvector[ibad].data[P1];
01062 it->bias1 = long(wlbias+(wlbias > 0 ? 0.5 : -0.5));
01063 }
01064 if(which == "GF")
01065 it->bias2 = spdvector[ibad].data[L2];
01066
01067
01068 nok = 2;
01069 outlier = false;
01070 igood = ibad;
01071 }
01072 else
01073 igood = i;
01074 }
01075 it->npts = nok;
01076
01077 return ReturnOK;
01078 }
01079 catch(Exception& e) { GPSTK_RETHROW(e); }
01080 catch(exception& e) { Exception E("std except: "+string(e.what())); GPSTK_THROW(E); }
01081 catch(...) { Exception e("Unknown exception"); GPSTK_THROW(e); }
01082 }
01083
01084
01085
01086
01087
01088 int GDCPass::firstDifferences(string which) throw(Exception)
01089 {
01090 try {
01091
01092
01093 int i,iprev=-1;
01094
01095 for(i=0; i<size(); i++) {
01096
01097 if(!(spdvector[i].flag & OK)) {
01098 spdvector[i].data[A1] = spdvector[i].data[A2] = 0.0;
01099 continue;
01100 }
01101
01102
01103 if(which == string("WL")) {
01104 if(iprev == -1)
01105 spdvector[i].data[A1] = 0.0;
01106 else
01107 spdvector[i].data[A1] =
01108 (spdvector[i].data[P1] - spdvector[iprev].data[P1]) /
01109 (spdvector[i].ndt-spdvector[iprev].ndt);
01110 }
01111 else if(which == string("GF")) {
01112 if(iprev == -1)
01113 spdvector[i].data[A1] = spdvector[i].data[A2] = 0.0;
01114 else {
01115
01116 spdvector[i].data[A1] =
01117 (spdvector[i].data[L1] - spdvector[iprev].data[L1]);
01118
01119
01120
01121 spdvector[i].data[A2] =
01122 (spdvector[i].data[L2] - spdvector[iprev].data[L2]);
01123
01124
01125 }
01126 }
01127
01128
01129 iprev = i;
01130 }
01131
01132 return ReturnOK;
01133 }
01134 catch(Exception& e) { GPSTK_RETHROW(e); }
01135 catch(exception& e) { Exception E("std except: "+string(e.what())); GPSTK_THROW(E); }
01136 catch(...) { Exception e("Unknown exception"); GPSTK_THROW(e); }
01137 }
01138
01139
01140
01141
01142 void GDCPass::WLcomputeStats(list<Segment>::iterator& it) throw(Exception)
01143 {
01144 try {
01145
01146 it->WLStats.Reset();
01147 it->npts = 0;
01148
01149
01150 for(int i=it->nbeg; i<=it->nend; i++) {
01151 if(!(spdvector[i].flag & OK)) continue;
01152 it->WLStats.Add(spdvector[i].data[P1] - it->bias1);
01153 it->npts++;
01154 }
01155
01156
01157 if(it->npts < int(cfg(MinPts)))
01158 deleteSegment(it,"insufficient data in segment");
01159 }
01160 catch(Exception& e) { GPSTK_RETHROW(e); }
01161 catch(exception& e) { Exception E("std except: "+string(e.what())); GPSTK_THROW(E); }
01162 catch(...) { Exception e("Unknown exception"); GPSTK_THROW(e); }
01163 }
01164
01165
01166
01167
01168 void GDCPass::WLsigmaStrip(list<Segment>::iterator& it) throw(Exception)
01169 {
01170 try {
01171 bool outlier,haveslip;
01172 unsigned short slip;
01173 int i,slipindex;
01174 double wlbias,nsigma,ave;
01175
01176
01177
01178 if(it->npts < cfg(WLNptsOutlierStats)) {
01179
01180
01181
01182 int j,k;
01183 double median,mad;
01184 vector<double> vecA1,vecA2;
01185
01186
01187 for(j=i=it->nbeg; i<=it->nend; i++) {
01188 if(!(spdvector[i].flag & OK)) continue;
01189 wlbias = spdvector[i].data[P1] - it->bias1;
01190 vecA1.push_back(wlbias);
01191 vecA2.push_back(0.0);
01192 j++;
01193 }
01194
01195 mad = Robust::MAD(&(vecA1[0]),j-it->nbeg,median,true);
01196 nsigma = cfg(WLNSigmaStrip) * mad;
01197 ave = Robust::MEstimate(&(vecA1[0]),j-it->nbeg,median,mad,&(vecA2[0]));
01198
01199
01200
01201 for(k=0,i=it->nbeg; i<j; k++,i++) {
01202 spdvector[i].data[A1] = vecA1[k];
01203 spdvector[i].data[A2] = vecA2[k];
01204 }
01205
01206 haveslip = false;
01207 for(j=i=it->nbeg; i<=it->nend; i++) {
01208 if(!(spdvector[i].flag & OK)) continue;
01209
01210 wlbias = spdvector[i].data[P1] - it->bias1;
01211
01212
01213
01214 if(fabs(wlbias-ave) > nsigma ||
01215 spdvector[j].data[A2] < cfg(WLRobustWeightLimit))
01216 outlier = true;
01217 else
01218 outlier = false;
01219
01220
01221 if(outlier) {
01222 if(spdvector[i].flag & DETECT || i == it->nbeg) {
01223 haveslip = true;
01224 slipindex = i;
01225 slip = spdvector[i].flag;
01226
01227
01228
01229 }
01230 spdvector[i].flag = BAD;
01231 learn["points deleted: WL sigma stripping"]++;
01232 it->npts--;
01233 it->WLStats.Subtract(wlbias);
01234 }
01235 else if(haveslip) {
01236 spdvector[i].flag = slip;
01237 haveslip = false;
01238 }
01239
01240 if(cfg(Debug) >= 6) {
01241 log << "DSCWLR " << GDCUnique << " " << sat
01242 << " " << it->nseg
01243 << " " << printTime(time(i),outFormat)
01244 << fixed << setprecision(3)
01245 << " " << setw(3) << spdvector[i].flag
01246 << " " << setw(13) << spdvector[j].data[A1]
01247 << " " << setw(13) << fabs(wlbias-ave)
01248 << " " << setw(5) << spdvector[j].data[A2]
01249 << " " << setw(3) << i
01250 << (outlier ? " outlier" : "");
01251 if(i == it->nbeg) log
01252 << " " << setw(13) << it->bias1
01253 << " " << setw(13) << it->bias2;
01254 log << endl;
01255 }
01256
01257 j++;
01258 }
01259
01260 }
01261 else {
01262
01263
01264 nsigma = cfg(WLNSigmaStrip) * it->WLStats.StdDev();
01265
01266 haveslip = false;
01267 ave = it->WLStats.Average();
01268 for(i=it->nbeg; i<=it->nend; i++) {
01269 if(!(spdvector[i].flag & OK)) continue;
01270
01271 wlbias = spdvector[i].data[P1] - it->bias1;
01272
01273
01274 if(fabs(wlbias-ave) > nsigma) {
01275 if(spdvector[i].flag & DETECT) {
01276 haveslip = true;
01277 slipindex = i;
01278 slip = spdvector[i].flag;
01279
01280
01281
01282 }
01283 spdvector[i].flag = BAD;
01284 learn["points deleted: WL sigma stripping"]++;
01285 it->npts--;
01286 it->WLStats.Subtract(wlbias);
01287 }
01288 else if(haveslip) {
01289 spdvector[i].flag = slip;
01290 haveslip = false;
01291 }
01292
01293 }
01294 }
01295
01296
01297 if(haveslip) {
01298 it->nbeg = slipindex;
01299
01300
01301 }
01302
01303
01304 if(it->npts < int(cfg(MinPts)))
01305 deleteSegment(it,"WL sigma stripping");
01306 else {
01307
01308 while(it->nbeg < it->nend && !(spdvector[it->nbeg].flag & OK)) it->nbeg++;
01309 while(it->nend > it->nbeg && !(spdvector[it->nend].flag & OK)) it->nend--;
01310 }
01311
01312 }
01313 catch(Exception& e) { GPSTK_RETHROW(e); }
01314 catch(exception& e) { Exception E("std except: "+string(e.what())); GPSTK_THROW(E); }
01315 catch(...) { Exception e("Unknown exception"); GPSTK_THROW(e); }
01316 }
01317
01318
01319
01320
01321
01322 int GDCPass::WLstatSweep(list<Segment>::iterator& it, int width) throw(Exception)
01323 {
01324 try {
01325 int iminus,i,iplus;
01326 double wlbias,test,limit;
01327 Stats<double> pastStats, futureStats;
01328
01329
01330 if(it->npts == 0) return ReturnOK;
01331 it->WLsweep = true;
01332
01333
01334
01335
01336
01337
01338
01339
01340
01341 iminus = i = iplus = it->nbeg;
01342
01343
01344 while(futureStats.N() < width && iplus <= it->nend) {
01345 if(spdvector[iplus].flag & OK) {
01346 futureStats.Add(spdvector[iplus].data[P1] - it->bias1);
01347 }
01348 iplus++;
01349 }
01350
01351
01352 for(i=it->nbeg; i<= it->nend; i++) {
01353 if(!(spdvector[i].flag & OK))
01354 continue;
01355
01356
01357 test = 0;
01358 if(pastStats.N() > 0 && futureStats.N() > 0)
01359 test = fabs(futureStats.Average()-pastStats.Average());
01360 limit = ::sqrt(futureStats.Variance() + pastStats.Variance());
01361
01362 spdvector[i].data[A1] = test;
01363 spdvector[i].data[A2] = limit;
01364
01365 wlbias = spdvector[i].data[P1] - it->bias1;
01366
01367
01368 if(cfg(Debug) >= 6) log << "WLS " << GDCUnique
01369 << " " << sat << " " << it->nseg
01370 << " " << printTime(time(i),outFormat)
01371 << fixed << setprecision(3)
01372 << " " << setw(3) << pastStats.N()
01373 << " " << setw(7) << pastStats.Average()
01374 << " " << setw(7) << pastStats.StdDev()
01375 << " " << setw(3) << futureStats.N()
01376 << " " << setw(7) << futureStats.Average()
01377 << " " << setw(7) << futureStats.StdDev()
01378 << " " << setw(9) << spdvector[i].data[A1]
01379 << " " << setw(9) << spdvector[i].data[A2]
01380 << " " << setw(9) << wlbias
01381 << " " << setw(3) << i
01382 << endl;
01383
01384
01385
01386 futureStats.Subtract(wlbias);
01387 pastStats.Add(wlbias);
01388
01389 while(futureStats.N() < width && iplus <= it->nend) {
01390 if(spdvector[iplus].flag & OK) {
01391 futureStats.Add(spdvector[iplus].data[P1] - it->bias1);
01392 }
01393 iplus++;
01394 }
01395
01396 while(pastStats.N() > width && iminus <= it->nend) {
01397 if(spdvector[iminus].flag & OK) {
01398 pastStats.Subtract(spdvector[iminus].data[P1] - it->bias1);
01399 }
01400 iminus++;
01401 }
01402
01403 }
01404
01405 return ReturnOK;
01406 }
01407 catch(Exception& e) { GPSTK_RETHROW(e); }
01408 catch(exception& e) { Exception E("std except: "+string(e.what())); GPSTK_THROW(E); }
01409 catch(...) { Exception e("Unknown exception"); GPSTK_THROW(e); }
01410 }
01411
01412
01413
01414
01415
01416 int GDCPass::detectWLsmallSlips(void) throw(Exception)
01417 {
01418 try {
01419 int i,k,nok;
01420 double wlbias;
01421 list<Segment>::iterator it;
01422
01423
01424 it = SegList.begin();
01425 while(!it->WLsweep) {
01426 it++;
01427 if(it == SegList.end()) return ReturnOK;
01428 }
01429 it->WLStats.Reset();
01430
01431
01432 i = it->nbeg;
01433 nok = 0;
01434 int halfwidth = int(cfg(WLSlipEdge));
01435 while(i < size())
01436 {
01437
01438 while(i > it->nend || !it->WLsweep) {
01439 if(i > it->nend) {
01440 it->npts = nok;
01441 nok = 0;
01442 }
01443 it++;
01444 if(it == SegList.end()) return ReturnOK;
01445 i = it->nbeg;
01446 if(it->WLsweep) {
01447 it->WLStats.Reset();
01448 }
01449 }
01450
01451 if(spdvector[i].flag & OK) {
01452 nok++;
01453
01454 if(nok == 1) {
01455 wlbias = spdvector[i].data[P1];
01456 it->bias1 = long(wlbias+(wlbias > 0 ? 0.5 : -0.5));
01457 }
01458
01459
01460 if(nok < halfwidth || (it->npts - nok) < halfwidth ) {
01461
01462
01463
01464 if(cfg(Debug) >= 6) log << "too near end " << GDCUnique
01465 << " " << i << " " << nok << " " << it->npts-nok
01466 << " " << printTime(time(i),outFormat)
01467 << " " << spdvector[i].data[A1] << " " << spdvector[i].data[A2]
01468 << endl;
01469 }
01470 else if(foundWLsmallSlip(it,i)) {
01471
01472
01473 k = it->npts;
01474 it->npts = nok;
01475
01476 it = createSegment(it,i,"WL slip small");
01477
01478
01479 spdvector[i].flag |= WLDETECT;
01480
01481
01482
01483 it->npts = k - nok;
01484 nok = 0;
01485 it->WLStats.Reset();
01486 wlbias = spdvector[i].data[P1];
01487 it->bias1 = long(wlbias+(wlbias > 0 ? 0.5 : -0.5));
01488 }
01489
01490 it->WLStats.Add(spdvector[i].data[P1] - it->bias1);
01491
01492 }
01493
01494 i++;
01495
01496 }
01497 it->npts = nok;
01498
01499 return ReturnOK;
01500 }
01501 catch(Exception& e) { GPSTK_RETHROW(e); }
01502 catch(exception& e) { Exception E("std except: "+string(e.what())); GPSTK_THROW(E); }
01503 catch(...) { Exception e("Unknown exception"); GPSTK_THROW(e); }
01504 }
01505
01506
01507
01508
01509
01510
01511
01512
01513
01514
01515
01516
01517
01518 bool GDCPass::foundWLsmallSlip(list<Segment>::iterator& it, int i)
01519 throw(Exception)
01520 {
01521 try {
01522 const int minMaxWidth=int(cfg(WLSlipEdge));
01523 int j,jp,jm,pass4,pass5,Pass;
01524
01525
01526
01527
01528 double test = spdvector[i].data[A1];
01529 double lim = spdvector[i].data[A2];
01530
01531
01532 bool isSlip=false;
01533 ostringstream oss;
01534 for(;;) {
01535
01536
01537 if(cfg(Debug) >= 6) oss << "WLslip " << GDCUnique
01538 << " " << sat << " " << setw(2) << it->nseg
01539 << " " << setw(3) << i
01540 << " " << printTime(time(i),outFormat)
01541
01542 << fixed << setprecision(2)
01543 << " test=" << test << " lim=" << lim
01544 << " (1)" << spdvector[i].data[A1]
01545 << (spdvector[i].data[A1] > cfg(WLSlipSize) ? ">" : "<=")
01546 << cfg(WLSlipSize)
01547 << " (2)" << spdvector[i].data[A1]-spdvector[i].data[A2]
01548 << (spdvector[i].data[A1]-spdvector[i].data[A2]>cfg(WLSlipExcess)?">":"<=")
01549 << cfg(WLSlipExcess);
01550
01551
01552 if(test <= cfg(WLSlipSize) || test-lim <= cfg(WLSlipExcess)) break;
01553
01554
01555
01556
01557
01558
01559
01560
01561
01562
01563
01564 double slope=(test-lim)/(8.0*minMaxWidth);
01565 j = pass4 = pass5 = Pass = 0;
01566 jp = jm = i;
01567 do {
01568
01569 do { jp++; } while(jp < it->nend && !(spdvector[jp].flag & OK));
01570 if(jp >= it->nend) break;
01571
01572 if(spdvector[i].data[A1]-spdvector[jp].data[A1] > j*slope) pass4++;
01573
01574 if(spdvector[i].data[A2]-spdvector[jp].data[A2] < -j*slope) pass5++;
01575
01576
01577 do { jm--; } while(jm > it->nbeg && !(spdvector[jm].flag & OK));
01578 if(jm <= it->nbeg) break;
01579
01580 if(spdvector[i].data[A1]-spdvector[jm].data[A1] > j*slope) pass4++;
01581
01582 if(spdvector[i].data[A2]-spdvector[jm].data[A2] < -j*slope) pass5++;
01583
01584 } while(++j < minMaxWidth);
01585
01586
01587 if(pass4 >= 2*minMaxWidth-1) Pass++;
01588 if(cfg(Debug) >= 6) oss << " (4)" << pass4
01589 << (pass4 >= 2*minMaxWidth-1 ? ">" : "<=") << 2*minMaxWidth-2;
01590 if(pass5 >= 2*minMaxWidth-1) Pass++;
01591 if(cfg(Debug) >= 6) oss << " (5)" << pass5
01592 << (pass5 >= 2*minMaxWidth-1 ? ">" : "<=") << 2*minMaxWidth-2;
01593
01594
01595 double ratio=(test-lim)/lim;
01596 if(cfg(Debug) >= 6) oss << " (6)" << ratio
01597 << (ratio > cfg(WLSlipSeparation) ? ">" : "<=") << cfg(WLSlipSeparation);
01598 if(ratio > cfg(WLSlipSeparation) ) Pass++;
01599
01600 if(Pass == 3) {
01601 if(cfg(Debug) >= 6) oss << " possible WL slip";
01602 isSlip = true;
01603 }
01604
01605 break;
01606 }
01607
01608 if(cfg(Debug) >= 6) log << oss.str() << endl;
01609 return isSlip;
01610 }
01611 catch(Exception& e) { GPSTK_RETHROW(e); }
01612 catch(exception& e) { Exception E("std except: "+string(e.what())); GPSTK_THROW(E); }
01613 catch(...) { Exception e("Unknown exception"); GPSTK_THROW(e); }
01614 }
01615
01616
01617
01618
01619
01620 int GDCPass::fixAllSlips(string which) throw(Exception)
01621 {
01622 try {
01623
01624
01625 int i,nmax,ifirst;
01626 list<Segment>::iterator it, kt;
01627
01628
01629 it = SegList.begin();
01630 while(it != SegList.end()) {
01631 if(it->npts == 0)
01632 it = SegList.erase(it);
01633 else
01634 it++;
01635 }
01636
01637 if(SegList.empty())
01638 return NoData;
01639
01640
01641 for(kt=SegList.end(),nmax=0,it=SegList.begin(); it != SegList.end(); it++) {
01642 if(it->npts > nmax) {
01643 nmax = it->npts;
01644 kt = it;
01645 }
01646 }
01647
01648
01649
01650 GDCUniqueFix = 0;
01651 while(kt != SegList.end()) {
01652 fixOneSlip(kt,which);
01653 }
01654
01655
01656
01657
01658 kt = SegList.begin();
01659 if(which == string("WL")) {
01660 WLPassStats.Reset();
01661 for(i=kt->nbeg; i <= kt->nend; i++) {
01662 if(!(spdvector[i].flag & OK)) continue;
01663 WLPassStats.Add(spdvector[i].data[P1] - kt->bias1);
01664 }
01665
01666
01667
01668
01669
01670
01671 }
01672
01673 else {
01674
01675 for(ifirst=-1,i=kt->nbeg; i <= kt->nend; i++) {
01676 if(!(spdvector[i].flag & OK)) continue;
01677 if(ifirst == -1) {
01678 ifirst = i;
01679 kt->bias2 = spdvector[ifirst].data[L2] + spdvector[ifirst].data[P2];
01680 kt->bias1 = spdvector[ifirst].data[P1];
01681 }
01682
01683 spdvector[i].data[L1] = spdvector[i].data[L2] + spdvector[i].data[P2];
01684 }
01685 }
01686
01687 if(cfg(Debug) >= 3) dumpSegments(which + string("F"),2,true);
01688
01689 return ReturnOK;
01690 }
01691 catch(Exception& e) { GPSTK_RETHROW(e); }
01692 catch(exception& e) { Exception E("std except: "+string(e.what())); GPSTK_THROW(E); }
01693 catch(...) { Exception e("Unknown exception"); GPSTK_THROW(e); }
01694 }
01695
01696
01697
01698
01699 void GDCPass::fixOneSlip(list<Segment>::iterator& kt, string which) throw(Exception)
01700 {
01701 try {
01702 if(kt->npts == 0) { kt++; return; }
01703
01704 list<Segment>::iterator left,right,it;
01705
01706
01707
01708
01709 right = left = kt;
01710
01711
01712 right++;
01713
01714
01715 if(kt != SegList.begin())
01716 left--;
01717 else
01718 left = SegList.end();
01719
01720
01721 if(left == SegList.end() && right == SegList.end()) {
01722 kt++;
01723 return;
01724 }
01725
01726
01727 if(left == SegList.end()) {
01728 left = kt;
01729 }
01730 else if(right == SegList.end()
01731 || left->npts >= right->npts) {
01732 right = kt;
01733 kt = left;
01734 }
01735 else {
01736 left = kt;
01737 }
01738
01739
01740 if(which == string("WL"))
01741 WLslipFix(left,right);
01742 else
01743 GFslipFix(left,right);
01744
01745 left->npts += right->npts;
01746 left->nend = right->nend;
01747
01748
01749
01750 SegList.erase(right);
01751
01752 return;
01753 }
01754 catch(Exception& e) { GPSTK_RETHROW(e); }
01755 catch(exception& e) { Exception E("std except: "+string(e.what())); GPSTK_THROW(E); }
01756 catch(...) { Exception e("Unknown exception"); GPSTK_THROW(e); }
01757 }
01758
01759
01760
01761 void GDCPass::WLslipFix(list<Segment>::iterator& left,
01762 list<Segment>::iterator& right)
01763 throw(Exception)
01764 {
01765 try {
01766 int i;
01767
01768 GDCUniqueFix++;
01769
01770
01771 double dwl = right->bias1 + right->WLStats.Average()
01772 - (left->bias1 + left->WLStats.Average());
01773 long nwl = long(dwl + (dwl > 0 ? 0.5 : -0.5));
01774
01775
01776
01777
01778
01779
01780
01781
01782
01783
01784
01785
01786
01787
01788
01789
01790 if(cfg(Debug) >= 6) log << "Fix " << GDCUnique << " " << sat << " " << GDCUniqueFix
01791 << " WL " << printTime(time(right->nbeg),outFormat)
01792 << " " << nwl
01793 << " " << left->nseg << "-" << right->nseg
01794 << fixed << setprecision(2)
01795 << " right: " << right->bias1 << " + " << right->WLStats.Average()
01796 << " - left: " << left->bias1 << " + " << left->WLStats.Average()
01797 << " = " << dwl << " " << nwl
01798 << endl;
01799
01800
01801 for(i=right->nbeg; i<=right->nend; i++) {
01802
01803 spdvector[i].data[P1] -= nwl;
01804 spdvector[i].data[L2] -= nwl * wl2;
01805
01806
01807
01808 }
01809
01810
01811
01812
01813
01814 list<Segment>::iterator it = right;
01815 for(it++; it != SegList.end(); it++) {
01816
01817
01818 it->bias1 -= dwl;
01819 for(i=it->nbeg; i<=it->nend; i++) {
01820
01821 spdvector[i].data[P1] -= nwl;
01822 spdvector[i].data[L2] -= nwl * wl2;
01823 }
01824 }
01825
01826
01827 Slip newSlip(right->nbeg);
01828 newSlip.NWL = nwl;
01829 newSlip.msg = "WL";
01830 SlipList.push_back(newSlip);
01831
01832
01833 spdvector[right->nbeg].flag |= WLFIX;
01834
01835 return;
01836 }
01837 catch(Exception& e) { GPSTK_RETHROW(e); }
01838 catch(exception& e) { Exception E("std except: "+string(e.what())); GPSTK_THROW(E); }
01839 catch(...) { Exception e("Unknown exception"); GPSTK_THROW(e); }
01840 }
01841
01842
01843
01844
01845 void GDCPass::GFslipFix(list<Segment>::iterator& left,
01846 list<Segment>::iterator& right) throw(Exception)
01847 {
01848 try {
01849
01850 const int Npts=int(cfg(GFFixNpts));
01851 int i,nb,ne,nl,nr,ilast;
01852 long n1,nadj;
01853 double dn1,dnGFR;
01854 Stats<double> Lstats,Rstats;
01855
01856 GDCUniqueFix++;
01857
01858
01859
01860
01861
01862 nb = left->nend;
01863 i = 1;
01864 nl = 0;
01865 ilast = -1;
01866 while(nb > left->nbeg && i < Npts) {
01867 if(spdvector[nb].flag & OK) {
01868 if(ilast == -1) ilast = nb;
01869 i++; nl++;
01870 Lstats.Add(spdvector[nb].data[L1] - left->bias2);
01871
01872 }
01873 nb--;
01874 }
01875 ne = right->nbeg;
01876 i = 1;
01877 nr = 0;
01878 while(ne < right->nend && i < Npts) {
01879 if(spdvector[ne].flag & OK) {
01880 i++; nr++;
01881 Rstats.Add(spdvector[ne].data[L1] - right->bias2);
01882
01883 }
01884 ne++;
01885 }
01886
01887
01888
01889
01890
01891
01892
01893
01894 dn1 = spdvector[right->nbeg].data[L2] - right->bias2
01895 - (spdvector[ilast].data[L2] - left->bias2);
01896
01897
01898 n1 = long(dn1 + (dn1 > 0 ? 0.5 : -0.5));
01899
01900
01901
01902
01903 nadj = EstimateGFslipFix(left,right,nb,ne,n1);
01904
01905
01906
01907
01908
01909
01910 dnGFR = Rstats.Average() - Lstats.Average();
01911
01912 if(fabs(n1+nadj-dnGFR) > 10.*(Rstats.StdDev()+Lstats.StdDev())) {
01913 if(cfg(Debug) >= 6)
01914 log << "GFRadjust " << GDCUnique << " " << sat << " " << GDCUniqueFix
01915 << " GF " << printTime(time(right->nbeg),outFormat)
01916 << fixed << setprecision(2)
01917 << " dbias(GFR): " << dnGFR
01918 << " n1+nadj: " << n1+nadj;
01919
01920 nadj = long(dnGFR+(dnGFR > 0 ? 0.5 : -0.5)) - n1;
01921
01922 if(cfg(Debug) >= 6)
01923 log << " new n1+nadj: " << n1+nadj << endl;
01924 }
01925
01926
01927 if(cfg(Debug) >= 6) {
01928 log << "Fix " << GDCUnique << " " << sat << " " << GDCUniqueFix
01929 << " GF " << printTime(time(right->nbeg),outFormat)
01930 << " " << nadj
01931 << fixed << setprecision(2)
01932 << " dbias: " << right->bias2 - left->bias2
01933 << ", dn1: " << dn1 << ", n1: " << n1 << ", adj: " << nadj
01934 << " indexes " << nb << " " << ne << " " << nl << " " << nr
01935 << " segs " << left->nseg << " " << right->nseg
01936 << " GFR-GFP:L: "
01937 << Lstats.N() << " " << Lstats.Average() << " " << Lstats.StdDev()
01938 << " R: "
01939 << Rstats.N() << " " << Rstats.Average() << " " << Rstats.StdDev()
01940 << " tests " << n1+nadj-dnGFR << " " << Rstats.StdDev()+Lstats.StdDev()
01941 << endl;
01942 }
01943
01944
01945 dn1 += right->bias2 - left->bias2;
01946 n1 = long(dn1 + (dn1 > 0 ? 0.5 : -0.5));
01947 n1 += nadj;
01948
01949
01950
01951 for(i=right->nbeg; i<size(); i++) {
01952
01953
01954 spdvector[i].data[L2] -= n1;
01955 spdvector[i].data[L1] -= n1;
01956 }
01957
01958
01959 list<Segment>::iterator kt;
01960 for(kt=right; kt != SegList.end(); kt++)
01961 kt->bias2 -= n1;
01962
01963
01964 list<Slip>::iterator jt;
01965 for(jt=SlipList.begin(); jt != SlipList.end(); jt++)
01966 if(jt->index == right->nbeg) break;
01967
01968 if(jt == SlipList.end()) {
01969 Slip newSlip(right->nbeg);
01970 newSlip.N1 = -n1;
01971 newSlip.msg = "GF only";
01972 SlipList.push_back(newSlip);
01973 }
01974 else {
01975 jt->N1 = -n1;
01976 jt->msg += string(" GF");
01977 }
01978
01979
01980 spdvector[right->nbeg].flag |= GFFIX;
01981
01982 return;
01983 }
01984 catch(Exception& e) { GPSTK_RETHROW(e); }
01985 catch(exception& e) { Exception E("std except: "+string(e.what())); GPSTK_THROW(E); }
01986 catch(...) { Exception e("Unknown exception"); GPSTK_THROW(e); }
01987 }
01988
01989
01990
01991
01992 long GDCPass::EstimateGFslipFix(list<Segment>::iterator& left,
01993 list<Segment>::iterator& right,
01994 int nb, int ne, long n1)
01995 throw(Exception)
01996 {
01997 try {
01998 bool quit;
01999 int i,k,in[3];
02000 double rof,rmsrof[3];
02001 PolyFit<double> PF[3];
02002
02003
02004 long nadj = 0;
02005
02006
02007 for(k=0; k<3; k++) {
02008 in[k]=k;
02009 PF[in[k]].Reset(int(cfg(GFFixDegree)));
02010 }
02011
02012 while(1) {
02013
02014
02015 for(k=0; k<3; k++) {
02016 if(PF[in[k]].N() > 0) continue;
02017
02018
02019 for(i=nb; i<=ne; i++) {
02020 if(!(spdvector[i].flag & OK)) continue;
02021 PF[in[k]].Add(
02022
02023 spdvector[i].data[L2]
02024
02025 - (i < right->nbeg ? left->bias2-n1-(nadj+k-1) : right->bias2),
02026
02027 spdvector[i].ndt - spdvector[nb].ndt
02028 );
02029 }
02030
02031
02032
02033
02034 rmsrof[in[k]] = 0.0;
02035 for(i=nb; i<=ne; i++) {
02036 if(!(spdvector[i].flag & OK)) continue;
02037 rof =
02038 spdvector[i].data[L2]
02039 - (i < right->nbeg ? left->bias2-n1-(nadj+k-1) : right->bias2)
02040 - PF[in[k]].Evaluate(spdvector[i].ndt - spdvector[nb].ndt);
02041 rmsrof[in[k]] += rof*rof;
02042 }
02043 rmsrof[in[k]] = ::sqrt(rmsrof[in[k]]);
02044
02045 }
02046
02047
02048
02049 for(quit=false,k=0; k<3; k++) if(rmsrof[in[k]] > cfg(GFFixMaxRMS)) {
02050 log << "Warning - large RMS ROF in GF slip fix at in,k = "
02051 << in[k] << " " << k << " " << rmsrof[in[k]] << " abort." << endl;
02052 quit = true;
02053 }
02054 if(quit) break;
02055
02056
02057
02058
02059
02060
02061
02062
02063
02064
02065
02066
02067 if(rmsrof[in[0]] > rmsrof[in[1]]) {
02068 if(rmsrof[in[1]] < rmsrof[in[2]]) {
02069
02070 break;
02071 }
02072 else {
02073 k = in[0];
02074 in[0] = in[1];
02075 in[1] = in[2];
02076 in[2] = k;
02077 PF[in[2]].Reset();
02078 nadj += 1;
02079
02080 }
02081 }
02082 else {
02083 if(rmsrof[in[1]] < rmsrof[in[2]]) {
02084 k = in[2];
02085 in[2] = in[1];
02086 in[1] = in[0];
02087 in[0] = k;
02088 PF[in[0]].Reset();
02089 nadj -= 1;
02090
02091 }
02092 else {
02093 log << "Warning - local maximum in RMS residuals in EstimateGFslipFix"
02094 << endl;
02095
02096 break;
02097 }
02098 }
02099
02100 }
02101
02102
02103 if(cfg(Debug) >= 4) for(i=nb; i<=ne; i++) {
02104 if(!(spdvector[i].flag & OK)) continue;
02105 log << "GFE " << GDCUnique << " " << sat
02106 << " " << GDCUniqueFix
02107 << " " << printTime(time(i),outFormat)
02108 << " " << setw(2) << spdvector[i].flag << fixed << setprecision(3);
02109 for(k=0; k<3; k++) log << " " << spdvector[i].data[L2]
02110 - (i < right->nbeg ? left->bias2-n1-(nadj+k-1) : right->bias2)
02111 << " " << PF[in[k]].Evaluate(spdvector[i].ndt - spdvector[nb].ndt);
02112 log << " " << setw(3) << spdvector[i].ndt << endl;
02113 }
02114
02115 return nadj;
02116 }
02117 catch(Exception& e) { GPSTK_RETHROW(e); }
02118 catch(exception& e) { Exception E("std except: "+string(e.what())); GPSTK_THROW(E); }
02119 catch(...) { Exception e("Unknown exception"); GPSTK_THROW(e); }
02120 }
02121
02122
02123
02124
02125
02126 int GDCPass::prepareGFdata(void) throw(Exception)
02127 {
02128 try {
02129 bool first;
02130 int i,nbeg,nend;
02131 unsigned ndeg;
02132
02133
02134 nbeg = SegList.begin()->nbeg;
02135 nend = SegList.begin()->nend;
02136 ndeg = 2 + int(0.5 + (nend-nbeg+1)*cfg(DT)/3000.0);
02137 if(ndeg > 6) ndeg = 6;
02138
02139 if(ndeg < 2) ndeg = 2;
02140
02141
02142 GFPassFit.Reset(ndeg);
02143
02144 for(first=true,i=nbeg; i <= nend; i++) {
02145 if(!(spdvector[i].flag & OK)) continue;
02146
02147
02148
02149 if(first) {
02150
02151
02152
02153
02154 SegList.begin()->bias2 /= wl21;
02155 first = false;
02156 }
02157
02158
02159
02160 spdvector[i].data[P2] /= wl21;
02161 spdvector[i].data[L2] /= wl21;
02162
02163
02164 GFPassFit.Add(spdvector[i].data[P2],spdvector[i].ndt);
02165
02166
02167
02168
02169
02170
02171 spdvector[i].data[L1] = spdvector[i].data[L2] - spdvector[i].data[P2];
02172
02173 }
02174
02175 if(GFPassFit.isSingular()) {
02176 log << "Polynomial fit to GF range is singular! .. abort." << endl;
02177 return Singular;
02178 }
02179
02180 return ReturnOK;
02181 }
02182 catch(Exception& e) { GPSTK_RETHROW(e); }
02183 catch(exception& e) { Exception E("std except: "+string(e.what())); GPSTK_THROW(E); }
02184 catch(...) { Exception e("Unknown exception"); GPSTK_THROW(e); }
02185 }
02186
02187
02188
02189
02190 int GDCPass::detectGFslips(void) throw(Exception)
02191 {
02192 try {
02193 int i,iret;
02194
02195 list<Segment>::iterator it;
02196
02197
02198 if( (iret = detectObviousSlips("GF"))) return iret;
02199
02200 GFPassStats.Reset();
02201
02202 for(it=SegList.begin(); it != SegList.end(); it++) {
02203
02204
02205
02206
02207
02208 for(i=it->nbeg; i <= it->nend; i++) {
02209 if(!(spdvector[i].flag & OK)) continue;
02210
02211
02212
02213 if(i > it->nbeg) GFPassStats.Add(spdvector[i].data[A1]*wl21);
02214
02215
02216
02217
02218
02219 }
02220
02221
02222
02223
02224 if(it->npts < int(cfg(MinPts))) {
02225 deleteSegment(it,"insufficient data in segment");
02226 continue;
02227 }
02228
02229
02230
02231
02232 if( (iret = GFphaseResiduals(it))) {
02233
02234 deleteSegment(it,"polynomial fit to GF residual failed");
02235 continue;
02236 }
02237 }
02238
02239
02240
02241
02242
02243
02244
02245
02246
02247
02248 if( (iret = detectGFsmallSlips())) return iret;
02249
02250
02251 for(it=SegList.begin(); it != SegList.end(); it++) {
02252 if(it->npts < int(cfg(MinPts)))
02253 deleteSegment(it,"insufficient data in segment");
02254 }
02255
02256 if(cfg(Debug) >= 4) dumpSegments("GFD",2,true);
02257
02258 return ReturnOK;
02259 }
02260 catch(Exception& e) { GPSTK_RETHROW(e); }
02261 catch(exception& e) { Exception E("std except: "+string(e.what())); GPSTK_THROW(E); }
02262 catch(...) { Exception e("Unknown exception"); GPSTK_THROW(e); }
02263 }
02264
02265
02266
02267
02268 int GDCPass::GFphaseResiduals(list<Segment>::iterator& it) throw(Exception)
02269 {
02270 try {
02271 int i,j,ndeg,nprev;
02272 double fit,rbias,prev,tmp;
02273 Stats<double> rofStats;
02274
02275
02276 ndeg = 2 + int(0.5 + (it->nend-it->nbeg+1)*cfg(DT)/3000.0);
02277
02278 if(ndeg > 6) ndeg = 6;
02279 if(ndeg < 2) ndeg = 2;
02280
02281 it->PF.Reset(ndeg);
02282
02283 for(i=it->nbeg; i <= it->nend; i++) {
02284 if(!(spdvector[i].flag & OK)) continue;
02285 it->PF.Add(spdvector[i].data[P2],spdvector[i].ndt);
02286 }
02287
02288 if(it->PF.isSingular()) {
02289 log << "Polynomial fit to GF range is singular in segment " << it->nseg
02290 << "! .. abort." << endl;
02291 return Singular;
02292 }
02293
02294
02295 rbias = prev = 0.0;
02296 rofStats.Reset();
02297 for(i=it->nbeg; i <= it->nend; i++) {
02298
02299 if(!(spdvector[i].flag & OK)) continue;
02300
02301
02302
02303 fit = it->PF.Evaluate(spdvector[i].ndt);
02304
02305
02306
02307
02308
02309
02310 spdvector[i].data[A1] = spdvector[i].data[L2] - it->bias2 - fit;
02311 if(rbias == 0.0) {
02312 rbias = spdvector[i].data[A1];
02313 nprev = spdvector[i].ndt - 1;
02314 }
02315 spdvector[i].data[A1] -= rbias;
02316
02317
02318 rofStats.Add(spdvector[i].data[A1]);
02319
02320 if(1) {
02321 tmp = spdvector[i].data[A1];
02322 spdvector[i].data[A1] -= prev;
02323
02324
02325 prev = tmp;
02326 nprev = spdvector[i].ndt;
02327 }
02328
02329
02330
02331
02332
02333
02334 }
02335
02336
02337
02338
02339
02340
02341
02342
02343
02344
02345 return ReturnOK;
02346 }
02347 catch(Exception& e) { GPSTK_RETHROW(e); }
02348 catch(exception& e) { Exception E("std except: "+string(e.what())); GPSTK_THROW(E); }
02349 catch(...) { Exception e("Unknown exception"); GPSTK_THROW(e); }
02350 }
02351
02352
02353
02354
02355 int GDCPass::detectGFsmallSlips(void) throw(Exception)
02356 {
02357 try {
02358 const int width=int(cfg(GFSlipWidth));
02359 int i,j,iplus,inew,ifirst,nok;
02360 list<Segment>::iterator it;
02361 Stats<double> pastStats,futureStats;
02362
02363
02364 for(it=SegList.begin(); it != SegList.end(); it++) {
02365
02366 if(it->npts < 2*width+1) continue;
02367
02368
02369
02370
02371
02372
02373
02374
02375
02376 deque<int> pastIndex, futureIndex;
02377 pastStats.Reset();
02378 futureStats.Reset();
02379 i = inew = ifirst = -1;
02380 nok = 0;
02381
02382
02383 for(iplus=it->nbeg; iplus<=it->nend+width; iplus++) {
02384
02385
02386 if(iplus <= it->nend && !(spdvector[iplus].flag & OK)) continue;
02387 if(ifirst == -1) ifirst = iplus;
02388
02389
02390 if(futureIndex.size() == width || iplus > it->nend) {
02391 inew = futureIndex.front();
02392 futureIndex.pop_front();
02393 futureStats.Subtract(spdvector[inew].data[A1]);
02394 nok++;
02395 }
02396
02397
02398 if(iplus <= it->nend) {
02399 futureIndex.push_back(iplus);
02400 futureStats.Add(spdvector[iplus].data[A1]);
02401 }
02402 else
02403 futureIndex.push_back(-1);
02404
02405
02406
02407
02408
02409
02410
02411
02412
02413 if(foundGFoutlier(i,inew,pastStats,futureStats)) {
02414
02415
02416 if(spdvector[i].flag & DETECT) {
02417
02418
02419
02420 spdvector[inew].flag = spdvector[i].flag;
02421 it->nbeg = inew;
02422 }
02423 spdvector[i].flag = BAD;
02424 spdvector[inew].data[A1] += spdvector[i].data[A1];
02425 learn["points deleted: GF outlier"]++;
02426 i = inew;
02427 nok--;
02428 }
02429
02430
02431 if(pastIndex.size() == width) {
02432 j = pastIndex.front();
02433 pastIndex.pop_front();
02434 pastStats.Subtract(spdvector[j].data[A1]);
02435 }
02436
02437
02438 if(i > -1) {
02439 pastIndex.push_back(i);
02440 pastStats.Add(spdvector[i].data[A1]);
02441 }
02442
02443
02444 i = inew;
02445
02446
02447 if(foundGFsmallSlip(i,it->nseg,it->nend,it->nbeg,
02448 pastIndex,futureIndex,pastStats,futureStats)) {
02449
02450
02451 it->npts = nok-1;
02452 it = createSegment(it,i,"GF slip small");
02453 nok = 1;
02454
02455
02456 spdvector[i].flag |= GFDETECT;
02457
02458
02459 }
02460
02461 }
02462 it->npts = nok;
02463
02464 }
02465
02466 return ReturnOK;
02467 }
02468 catch(Exception& e) { GPSTK_RETHROW(e); }
02469 catch(exception& e) { Exception E("std except: "+string(e.what())); GPSTK_THROW(E); }
02470 catch(...) { Exception e("Unknown exception"); GPSTK_THROW(e); }
02471 }
02472
02473
02474 bool GDCPass::foundGFoutlier(int i, int inew,
02475 Stats<double>& pastSt, Stats<double>& futureSt)
02476 throw(Exception)
02477 {
02478 try {
02479 if(i < 0 || inew < 0) return false;
02480 bool ok;
02481 double pmag = spdvector[i].data[A1];
02482 double fmag = spdvector[inew].data[A1];
02483 double var = ::sqrt(pastSt.Variance() + futureSt.Variance());
02484
02485 ostringstream oss;
02486 if(cfg(Debug) >= 6) oss << "GFoutlier " << GDCUnique
02487 << " " << sat << " " << setw(3) << inew
02488 << " " << printTime(time(inew),outFormat)
02489 << fixed << setprecision(3)
02490 << " p,fave=" << fabs(pmag) << "," << fabs(fmag)
02491 << " snr=" << fabs(pmag)/var <<","<< fabs(fmag)/var;
02492
02493 bool isOut=true;
02494 for(;;) {
02495
02496
02497 if(pmag * fmag >= 0) isOut=false;
02498 if(cfg(Debug) >= 6) oss << " (1)" << (isOut?"ok":"no");
02499 if(!isOut) break;
02500
02501
02502
02503
02504
02505 double noise=cfg(GFSlipOutlier)*var;
02506 if(fabs(pmag) < noise || fabs(fmag) < noise) isOut=false;
02507 if(cfg(Debug) >= 6) oss << " (2)" << fabs(pmag)/var << "or" << fabs(fmag)/var
02508 << (isOut?">=":"<") << cfg(GFSlipOutlier);
02509 if(!isOut) break;
02510
02511 if(cfg(Debug) >= 6) oss << " possible GF outlier";
02512
02513 break;
02514 }
02515
02516 if(cfg(Debug) >= 6) log << oss.str() << endl;
02517
02518 return isOut;
02519 }
02520 catch(Exception& e) { GPSTK_RETHROW(e); }
02521 catch(exception& e) { Exception E("std except: "+string(e.what())); GPSTK_THROW(E); }
02522 catch(...) { Exception e("Unknown exception"); GPSTK_THROW(e); }
02523 }
02524
02525
02526
02527
02528 bool GDCPass::foundGFsmallSlip(int i,int nseg,int iend,int ibeg,
02529 deque<int>& pastIn,deque<int>& futureIn,
02530 Stats<double>& pastSt, Stats<double>& futureSt)
02531 throw(Exception)
02532 {
02533 try {
02534 if(i < 0) return false;
02535
02536 int j,k;
02537 double mag,pmag,fmag,pvar,fvar;
02538
02539 pmag = fmag = pvar = fvar = 0.0;
02540
02541
02542 if(pastSt.N() > 0) pmag = spdvector[i].data[A1]-pastSt.Average();
02543 if(futureSt.N() > 0) fmag = spdvector[i].data[A1]-futureSt.Average();
02544 if(pastSt.N() > 1) pvar = pastSt.Variance();
02545 if(futureSt.N() > 1) fvar = futureSt.Variance();
02546 mag = (pmag + fmag) / 2.0;
02547
02548 if(cfg(Debug) >= 6) log << "GFS " << GDCUnique
02549 << " " << sat << " " << nseg
02550 << " " << printTime(time(i),outFormat)
02551
02552
02553
02554
02555
02556
02557
02558
02559
02560
02561
02562 << fixed << setprecision(3)
02563 << " " << setw(3) << pastSt.N()
02564 << " " << setw(7) << pastSt.Average()
02565 << " " << setw(7) << pastSt.StdDev()
02566 << " " << setw(3) << futureSt.N()
02567 << " " << setw(7) << futureSt.Average()
02568 << " " << setw(7) << futureSt.StdDev()
02569 << " " << setw(7) << mag
02570 << " " << setw(7) << ::sqrt(pvar+fvar)
02571 << " " << setw(9) << spdvector[i].data[A1]
02572 << " " << setw(7) << pmag
02573 << " " << setw(7) << pvar
02574 << " " << setw(7) << fmag
02575 << " " << setw(7) << fvar
02576 << " " << setw(3) << i
02577 << endl;
02578
02579
02580
02581
02582
02583 const double minMag=cfg(GFSlipSize);
02584 const double STN=cfg(GFSlipStepToNoise);
02585 const double MTS=cfg(GFSlipToStep);
02586 const double MTN=cfg(GFSlipToNoise);
02587 const int Edge=int(cfg(GFSlipEdge));
02588 const double RangeCheckLimit = 2*cfg(WLSigma)/(0.83*wl21);
02589
02590 const double snr=fabs(pmag-fmag)/::sqrt(pvar+fvar);
02591
02592
02593 bool isSlip=true;
02594 ostringstream oss;
02595
02596 for(;;) {
02597
02598 if(cfg(Debug) >= 6) oss << "GFslip " << GDCUnique
02599 << " " << sat << " " << nseg
02600 << " " << setw(3) << i
02601 << " " << printTime(time(i),outFormat) << fixed << setprecision(3)
02602 << " mag=" << mag << " snr=" << snr;
02603
02604
02605
02606
02607 if(fabs(mag) <= minMag) isSlip=false;
02608 if(cfg(Debug) >= 6) oss << " (1)" << fabs(mag) << (isSlip?">":"<=") << minMag;
02609 if(!isSlip) break;
02610
02611
02612 if(snr <= STN) isSlip=false;
02613 if(cfg(Debug) >= 6) oss << " (2)" << snr << (isSlip?">":"<=") << STN;
02614 if(!isSlip) break;
02615
02616
02617 if(fabs(mag) <= MTS*fabs(pmag-fmag)) isSlip=false;
02618 if(cfg(Debug) >= 6) oss << " (3)" << fabs(mag/(pmag-fmag))
02619 << (isSlip?">":"<=") << MTS;
02620 if(!isSlip) break;
02621
02622
02623 if(fabs(mag) <= MTN*::sqrt(pvar+fvar)) isSlip=false;
02624 if(cfg(Debug) >= 6) oss << " (4)" << fabs(mag)/::sqrt(pvar+fvar)
02625 << (isSlip?">":"<=") << MTN;
02626 if(!isSlip) break;
02627
02628
02629 if(pastSt.N() < Edge || futureSt.N() < Edge+1) isSlip=false;
02630 if(cfg(Debug) >= 6) oss << " (5)" << pastSt.N() << "," << futureSt.N()
02631 << (isSlip?">":"<") << Edge;
02632 if(!isSlip) break;
02633
02634
02635
02636
02637 if(fabs(mag) > RangeCheckLimit) {
02638 double magGFR,mtnGFR;
02639 Stats<double> pGFRmPh,fGFRmPh;
02640 for(j=0; j<pastIn.size(); j++) {
02641 if(pastIn[j] > -1) pGFRmPh.Add(spdvector[pastIn[j]].data[L1]);
02642 if(futureIn[j] > -1) fGFRmPh.Add(spdvector[futureIn[j]].data[L1]);
02643 }
02644 magGFR = spdvector[i].data[L1] - (pGFRmPh.Average()+fGFRmPh.Average())/2.0;
02645 mtnGFR = fabs(magGFR)/::sqrt(pGFRmPh.Variance()+fGFRmPh.Variance());
02646
02647 if(cfg(Debug) >= 6)
02648 oss << "; GFR-GFP has mag: " << magGFR
02649 << ", |dmag|: " << fabs(mag-magGFR)
02650 << " and mag/noise " << mtnGFR;
02651
02652
02653
02654 if(fabs(mag-magGFR) > fabs(magGFR)) isSlip=false;
02655 if(cfg(Debug) >= 6) oss << " (6a)" << fabs(mag-magGFR)
02656 << (isSlip?"<=":">") << fabs(magGFR);
02657 if(!isSlip) break;
02658
02659 if(mtnGFR < 3) isSlip=false;
02660 if(cfg(Debug) >= 6) oss << " (6b)"
02661 << mtnGFR << "><3:can" << (isSlip?"":"not") << "_see_in_GFR";
02662 if(!isSlip) break;
02663 }
02664
02665
02666
02667 else {
02668 double magFD;
02669 Stats<double> fdStats;
02670 j = i-1; k=0;
02671 while(j >= ibeg && k < 15) {
02672 if(spdvector[j].flag & OK) { fdStats.Add(spdvector[j].data[A2]); k++; }
02673 j--;
02674 }
02675 j = i+1; k=0;
02676 while(j <= iend && k < 15) {
02677 if(spdvector[j].flag & OK) { fdStats.Add(spdvector[j].data[A2]); k++; }
02678 j++;
02679 }
02680 magFD = spdvector[i].data[A2] - fdStats.Average();
02681
02682 if(cfg(Debug) >= 6)
02683 oss << " (7)1stD(GFP)mag=" << magFD
02684 << ",noise=" << fdStats.StdDev()
02685 << ",snr=" << fabs(magFD)/fdStats.StdDev()
02686 << ",maxima=" << fdStats.Minimum() << "," << fdStats.Maximum();
02687 }
02688
02689 break;
02690 }
02691
02692 if(isSlip) oss << " possible GF slip";
02693 if(cfg(Debug) >= 6) log << oss.str() << endl;
02694
02695 return isSlip;
02696 }
02697 catch(Exception& e) { GPSTK_RETHROW(e); }
02698 catch(exception& e) { Exception E("std except: "+string(e.what())); GPSTK_THROW(E); }
02699 catch(...) { Exception e("Unknown exception"); GPSTK_THROW(e); }
02700 }
02701
02702
02703
02704
02705 int GDCPass::WLconsistencyCheck(void) throw(Exception)
02706 {
02707 try {
02708 int i,k;
02709 const int N=2*int(cfg(WLWindowWidth));
02710 double mag,absmag,factor=wl2/wl21;
02711
02712
02713 for(i=0; i<size(); i++) {
02714
02715 if(!(spdvector[i].flag & OK)) continue;
02716 if(!(spdvector[i].flag & DETECT)) continue;
02717 if(spdvector[i].flag & WLDETECT) continue;
02718
02719
02720 Stats<double> futureStats,pastStats;
02721 k = i;
02722
02723 while(k < size() && futureStats.N() < N) {
02724 if(spdvector[k].flag & OK)
02725 futureStats.Add(spdvector[k].data[P1]);
02726 k++;
02727 }
02728
02729 k = i-1;
02730 while(k >= 0 && pastStats.N() < N) {
02731 if(spdvector[k].flag & OK)
02732 pastStats.Add(spdvector[k].data[P1]);
02733 k--;
02734 }
02735
02736
02737
02738
02739
02740 mag = futureStats.Average()-pastStats.Average();
02741 absmag = fabs(mag);
02742
02743 if(absmag > cfg(WLSlipSize) &&
02744 absmag > pastStats.StdDev() &&
02745 absmag > futureStats.StdDev()) {
02746
02747 long nwl;
02748 nwl = long(mag + (mag > 0 ? 0.5 : -0.5));
02749
02750 if(nwl == 0) continue;
02751
02752
02753 for(k=i; k<size(); k++) {
02754
02755 spdvector[k].data[P1] -= nwl;
02756 spdvector[k].data[L2] -= nwl * factor;
02757 }
02758
02759
02760 Slip newSlip(i);
02761 newSlip.NWL = nwl;
02762 newSlip.msg = "WL";
02763 SlipList.push_back(newSlip);
02764
02765
02766 spdvector[i].flag |= (WLDETECT + WLFIX);
02767
02768 if(cfg(Debug) >= 7) log << "CHECK " << GDCUnique << " " << sat
02769 << " " << i
02770 << " " << printTime(time(i),outFormat)
02771 << fixed << setprecision(3)
02772 << " " << pastStats.N()
02773
02774 << " " << pastStats.StdDev()
02775 << " " << futureStats.N()
02776
02777 << " " << futureStats.StdDev()
02778 << " " << futureStats.Average() - pastStats.Average()
02779 << " " << nwl
02780 << endl;
02781
02782 }
02783 }
02784
02785 return ReturnOK;
02786 }
02787 catch(Exception& e) { GPSTK_RETHROW(e); }
02788 catch(exception& e) { Exception E("std except: "+string(e.what())); GPSTK_THROW(E); }
02789 catch(...) { Exception e("Unknown exception"); GPSTK_THROW(e); }
02790 }
02791
02792
02793
02794
02795
02796
02797
02798 string GDCPass::finish(int iret, SatPass& svp, vector<string>& editCmds)
02799 throw(Exception)
02800 {
02801 try {
02802 bool ok;
02803 int i,ifirst,ilast,npts;
02804 long N1,N2,prevN1,prevN2;
02805 double slipL1,slipL2,WLbias,GFbias;
02806
02807 list<Slip>::iterator jt;
02808 string retMessage;
02809
02810
02811
02812 SlipList.sort();
02813
02814
02815
02816
02817
02818
02819 npts = 0;
02820 ilast = -1;
02821 ifirst = -1;
02822 WLbias = GFbias = slipL1 = slipL2 = 0.0;
02823 prevN1 = prevN2 = 0L;
02824 jt = SlipList.begin();
02825 for(i=0; i<size(); i++) {
02826
02827
02828 if(!(spdvector[i].flag & OK)) {
02829 ok = false;
02830 if(i == size() - 1) {
02831 i++;
02832 ok = true;
02833 }
02834 }
02835 else ok = true;
02836
02837 if(ok) {
02838 if(ifirst == -1) ifirst = i;
02839
02840
02841 if(i-ilast > 2 && cfg(OutputDeletes) != 0) {
02842
02843
02844 ostringstream stst1;
02845 stst1 << "-DS";
02846 if(i-ilast > 3) stst1 << "+";
02847 stst1 << sat << ",";
02848 if(cfg(OutputGPSTime))
02849 stst1 << printTime(time(ilast+1),"%F,%.3g");
02850 else
02851 stst1 << printTime(time(ilast+1),"%Y,%m,%d,%H,%M,%f");
02852 if(i-ilast > 3) stst1 << " # begin delete of "
02853 << asString(i+1-ilast) << " points";
02854 editCmds.push_back(stst1.str());
02855
02856
02857 ostringstream stst2;
02858 stst2 << "-DS";
02859 if(i-ilast > 3) stst2 << "-";
02860 stst2 << sat << ",";
02861 if(cfg(OutputGPSTime))
02862 stst2 << printTime(time(i-1),"%F,%.3g");
02863 else
02864 stst2 << printTime(time(i-1),"%Y,%m,%d,%H,%M,%f");
02865 if(i-ilast > 3) stst2 << " # end delete of "
02866 << asString(i+1-ilast) << " points";
02867 editCmds.push_back(stst2.str());
02868 }
02869 else if(i-ilast > 1 && cfg(OutputDeletes) != 0) {
02870
02871 ostringstream stst;
02872 stst << "-DS" << sat << ",";
02873 if(cfg(OutputGPSTime))
02874 stst << printTime(time(i-1),"%F,%.3g");
02875 else
02876 stst << printTime(time(i-1),"%Y,%m,%d,%H,%M,%f");
02877 editCmds.push_back(stst.str());
02878 }
02879
02880 ilast = i;
02881 npts++;
02882 }
02883
02884
02885 if(jt != SlipList.end() && i == jt->index) {
02886
02887 N1 = jt->N1;
02888 N2 = jt->N1 - jt->NWL;
02889 slipL1 += double(N1);
02890 slipL2 += double(N2);
02891
02892
02893 {
02894 ostringstream stst;
02895 stst << "-BD+" << sat << ",L1,";
02896 if(cfg(OutputGPSTime))
02897 stst << printTime(time(jt->index),"%F,%.3g");
02898 else
02899 stst << printTime(time(jt->index),"%Y,%m,%d,%H,%M,%f");
02900 stst << "," << N1-prevN1;
02901 if(!jt->msg.empty()) stst << " # " << jt->msg;
02902
02903 editCmds.push_back(stst.str());
02904 }
02905 {
02906 ostringstream stst;
02907 stst << "-BD+" << sat << ",L2,";
02908 if(cfg(OutputGPSTime))
02909 stst << printTime(time(jt->index),"%F,%.3g");
02910 else
02911 stst << printTime(time(jt->index),"%Y,%m,%d,%H,%M,%f");
02912 stst << "," << N2-prevN2;
02913 if(!jt->msg.empty()) stst << " # " << jt->msg;
02914 editCmds.push_back(stst.str());
02915 }
02916
02917 prevN1 = N1;
02918 prevN2 = N2;
02919 jt++;
02920 }
02921
02922 if(i >= size()) break;
02923
02924
02925 spdvector[i].data[L1] = svp.data(i,DCobstypes[L1]) - slipL1;
02926 spdvector[i].data[L2] = svp.data(i,DCobstypes[L2]) - slipL2;
02927 spdvector[i].data[P1] = svp.data(i,DCobstypes[P1]);
02928 spdvector[i].data[P2] = svp.data(i,DCobstypes[P2]);
02929
02930
02931
02932
02933
02934
02935 double wlr = wl1r * spdvector[i].data[P1] + wl2r * spdvector[i].data[P2];
02936
02937 double wlp = wl1p * spdvector[i].data[L1] + wl2p * spdvector[i].data[L2];
02938
02939 double gfr = gf1r * spdvector[i].data[P1] + gf2r * spdvector[i].data[P2];
02940
02941 double gfp = gf1p * spdvector[i].data[L1] + gf2p * spdvector[i].data[L2];
02942 if(i == ifirst) {
02943 WLbias = (wlp-wlr)/wlwl;
02944 GFbias = gfp;
02945 }
02946 spdvector[i].data[A1] = (wlp-wlr)/wlwl - WLbias;
02947 spdvector[i].data[A2] = gfp - GFbias;
02948
02949
02950 }
02951
02952
02953 if(SegList.begin() != SegList.end()) {
02954 SegList.begin()->bias1 = SegList.begin()->bias2 = 0;
02955 SegList.begin()->nbeg = 0;
02956 SegList.begin()->nend = size()-1;
02957 SegList.begin()->npts = npts;
02958 }
02959
02960 if(cfg(Debug) >= 2) dumpSegments("AFT",2,true);
02961
02962
02963 for(i=0; i<editCmds.size(); i++)
02964 if(cfg(Debug) >= 2)
02965 log << "EditCmd: " << GDCUnique << " " << editCmds[i] << endl;
02966
02967
02968
02969 for(i=0; i<size(); i++) {
02970 svp.data(i,DCobstypes[L1]) = spdvector[i].data[L1];
02971 svp.data(i,DCobstypes[L2]) = spdvector[i].data[L2];
02972 svp.data(i,DCobstypes[P1]) = spdvector[i].data[P1];
02973 svp.data(i,DCobstypes[P2]) = spdvector[i].data[P2];
02974
02975
02976
02977
02978
02979
02980
02981
02982
02983 if(spdvector[i].flag & OK) {
02984
02985 if(((spdvector[i].flag & DETECT)==0 && (spdvector[i].flag & FIX)!=0)
02986 || i == ifirst)
02987 spdvector[i].flag = LL3 + OK;
02988 else
02989 spdvector[i].flag = OK;
02990 }
02991 else
02992 spdvector[i].flag = BAD;
02993
02994 svp.LLI(i,DCobstypes[L1]) = (spdvector[i].flag & LL1) ? 1 : 0;
02995 svp.LLI(i,DCobstypes[L2]) = (spdvector[i].flag & LL2) ? 1 : 0;
02996 svp.setFlag(i,spdvector[i].flag);
02997 }
02998
02999
03000
03001 if(cfg(Debug) >= 1) retMessage = dumpSegments("GDC",1);
03002
03003 ostringstream oss;
03004
03005 if(cfg(Debug) > 0 && WLPassStats.N() > 2) {
03006 oss << "GDC " << GDCUnique << " " << sat
03007 << " " << fixed << setprecision(3) << WLPassStats.StdDev()
03008 << " WL sigma in cycles"
03009 << " N=" << WLPassStats.N()
03010 << " Min=" << WLPassStats.Minimum()
03011 << " Max=" << WLPassStats.Maximum()
03012 << " Ave=" << WLPassStats.Average();
03013 if(WLPassStats.StdDev() > cfg(WLSigma))
03014 oss << " Warning - WL sigma > input (" << cfg(WLSigma) << ")";
03015 oss << endl;
03016 }
03017
03018 if(cfg(Debug) > 0 && GFPassStats.N() > 2) {
03019 oss << "GDC " << GDCUnique << " " << sat
03020 << " " << fixed << setprecision(3) << GFPassStats.StdDev()
03021 << " sigma GF variation in meters per DT"
03022 << " N=" << GFPassStats.N()
03023 << " Min=" << GFPassStats.Minimum()
03024 << " Max=" << GFPassStats.Maximum()
03025 << " Ave=" << GFPassStats.Average()
03026 << endl;
03027 oss << "GDC " << GDCUnique << " " << sat
03028 << " " << fixed << setprecision(3)
03029 << (fabs(GFPassStats.Minimum()) > fabs(GFPassStats.Maximum()) ?
03030 fabs(GFPassStats.Minimum()) : fabs(GFPassStats.Maximum()))
03031 << " maximum GF variation in meters per DT"
03032 << " N=" << GFPassStats.N()
03033 << " Ave=" << GFPassStats.Average()
03034 << " Std=" << GFPassStats.StdDev()
03035 << endl;
03036 }
03037
03038
03039 if(cfg(Debug) > 0) {
03040 map<string,int>::const_iterator kt;
03041 for(kt=learn.begin(); kt != learn.end(); kt++)
03042 oss << "GDC " << GDCUnique << " " << sat
03043 << " " << setw(3) << kt->second << " " << kt->first << endl;
03044
03045 int n = int((lastTime-firstTime)/cfg(DT)) + 1;
03046 double percent = 100.0*double(ngood)/n;
03047 if(cfg(Debug) > 0) oss << "GDC# " << setw(2) << GDCUnique << ", SAT " << sat
03048 << ", Pts: " << setw(4) << n << " total " << setw(4) << ngood
03049 << " good " << fixed << setprecision(1) << setw(5) << percent << "%"
03050 << ", start " << printTime(firstTime,outFormat)
03051 << endl;
03052 }
03053
03054 if(iret) {
03055 oss << "GDC " << setw(3) << GDCUnique << " " << sat
03056 << " " << printTime(firstTime,outFormat)
03057 << " is returning with error code: "
03058 << (iret == NoData ? "insufficient data" :
03059 (iret == Singular ? "singularity" :
03060 (iret == FatalProblem ? "fatal problem" : "unknown problem")
03061
03062 ))
03063 << endl;
03064 }
03065
03066 retMessage += oss.str();
03067 if(oss.str().size() > 0) log << oss.str();
03068
03069 if(cfg(Debug) >= 2) log << "======== End GPSTK Discontinuity Corrector "
03070 << GDCUnique << " ================================================" << endl;
03071
03072 return retMessage;
03073 }
03074 catch(Exception& e) { GPSTK_RETHROW(e); }
03075 catch(exception& e) { Exception E("std except: "+string(e.what())); GPSTK_THROW(E); }
03076 catch(...) { Exception e("Unknown exception"); GPSTK_THROW(e); }
03077 }
03078
03079
03080
03081
03082
03083
03084
03085 list<Segment>::iterator GDCPass::createSegment(list<Segment>::iterator sit,
03086 int ibeg, string msg) throw(Exception)
03087 {
03088 try {
03089 Segment s;
03090 s = *sit;
03091 s.nbeg = ibeg;
03092 s.nend = sit->nend;
03093 sit->nend = ibeg-1;
03094
03095
03096 while(s.nend > s.nbeg && !(spdvector[s.nend].flag & OK)) s.nend--;
03097 while(sit->nend > sit->nbeg && !(spdvector[sit->nend].flag & OK)) sit->nend--;
03098
03099
03100 s.nseg++;
03101 list<Segment>::iterator skt=sit;
03102 for(skt++; skt != SegList.end(); skt++) skt->nseg++;
03103
03104 if(cfg(Debug) >= 6)
03105 log << "SEG " << GDCUnique << " " << sat
03106 << " " << msg
03107 << " " << printTime(time(ibeg),outFormat)
03108 << " " << s.nbeg << " - " << s.nend
03109 << " biases " << fixed << setprecision(3) << s.bias1 << " " << s.bias2
03110 << endl;
03111
03112 learn["breaks found: " + msg]++;
03113
03114 return SegList.insert(++sit,s);
03115 }
03116 catch(Exception& e) { GPSTK_RETHROW(e); }
03117 catch(exception& e) { Exception E("std except: "+string(e.what())); GPSTK_THROW(E); }
03118 catch(...) { Exception e("Unknown exception"); GPSTK_THROW(e); }
03119 }
03120
03121
03122
03123
03124
03125
03126
03127 string GDCPass::dumpSegments(string label, int level, bool extra) throw(Exception)
03128 {
03129 try {
03130 int i,ifirst,ilast;
03131 list<Segment>::iterator it;
03132 string msg;
03133 ostringstream oss;
03134
03135
03136 oss << label << " " << GDCUnique
03137 << " list of Segments (" << SegList.size() << "):"
03138 << endl;
03139
03140 if(level < 1) { msg = oss.str(); log << msg; return msg; }
03141
03142
03143 ilast = -1;
03144 for(it=SegList.begin(); it != SegList.end(); it++) {
03145
03146
03147
03148
03149
03150
03151 i = (it->nend - it->nbeg + 1);
03152
03153 oss << label << " " << GDCUnique << " " << sat
03154 << " #" << setw(2) << it->nseg << ": "
03155 << setw(4) << it->npts << "/" << setw(4) << i << " pts, # "
03156 << setw(4) << it->nbeg << "-" << setw(4) << it->nend
03157 << " (" << printTime(time(it->nbeg),outFormat)
03158 << " - " << printTime(time(it->nend),outFormat)
03159 << ")";
03160
03161 if(it->npts > 0) {
03162 oss << fixed << setprecision(3)
03163 << " bias(wl)=" << setw(13) << it->bias1
03164 << " bias(gf)=" << setw(13) << it->bias2;
03165 if(ilast > -1) {
03166 ifirst = it->nbeg;
03167 while(ifirst <= it->nend && !(spdvector[ifirst].flag & OK)) ifirst++;
03168 i = spdvector[ifirst].ndt - spdvector[ilast].ndt;
03169 oss << " Gap " << setprecision(1) << setw(5)
03170 << cfg(DT)*i << " s = " << i << " pts.";
03171 }
03172 ilast = it->nend;
03173 while(ilast >= it->nbeg && !(spdvector[ilast].flag & OK)) ilast--;
03174 }
03175
03176 oss << endl;
03177 }
03178
03179 msg = oss.str();
03180 log << msg;
03181 if(level < 2) return msg;
03182
03183
03184 for(it=SegList.begin(); it != SegList.end(); it++) {
03185 for(i=it->nbeg; i<=it->nend; i++) {
03186
03187
03188 log << "DSC" << label << " " << GDCUnique << " " << sat << " " << it->nseg
03189 << " " << printTime(time(i),outFormat)
03190 << " " << setw(3) << spdvector[i].flag
03191 << fixed << setprecision(3)
03192 << " " << setw(13) << spdvector[i].data[L1] - it->bias2
03193 << " " << setw(13) << spdvector[i].data[L2] - it->bias2
03194 << " " << setw(13) << spdvector[i].data[P1] - it->bias1
03195 << " " << setw(13) << spdvector[i].data[P2];
03196 if(extra) log
03197 << " " << setw(13) << spdvector[i].data[A1]
03198 << " " << setw(13) << spdvector[i].data[A2];
03199 log << " " << setw(4) << i;
03200 if(i == it->nbeg) log
03201 << " " << setw(13) << it->bias1
03202 << " " << setw(13) << it->bias2;
03203 log << endl;
03204 }
03205 }
03206 return msg;
03207 }
03208 catch(Exception& e) { GPSTK_RETHROW(e); }
03209 catch(exception& e) { Exception E("std except: "+string(e.what())); GPSTK_THROW(E); }
03210 catch(...) { Exception e("Unknown exception"); GPSTK_THROW(e); }
03211 }
03212
03213
03214 void GDCPass::deleteSegment(list<Segment>::iterator& it, string msg) throw(Exception)
03215 {
03216 try {
03217 int i;
03218
03219 if(cfg(Debug) >= 6) log << "Delete segment "
03220 << GDCUnique << " " << sat << " " << it->nseg
03221 << " pts " << it->npts
03222 << " indexes " << it->nbeg << " - " << it->nend
03223 << " start " << printTime(firstTime,outFormat)
03224 << " : " << msg
03225 << endl;
03226
03227 it->npts = 0;
03228 for(i=it->nbeg; i<=it->nend; i++) if(spdvector[i].flag & OK) {
03229
03230 learn["points deleted: " + msg]++;
03231 spdvector[i].flag = BAD;
03232 }
03233
03234 learn["segments deleted: " + msg]++;
03235 }
03236 catch(Exception& e) { GPSTK_RETHROW(e); }
03237 catch(exception& e) { Exception E("std except: "+string(e.what())); GPSTK_THROW(E); }
03238 catch(...) { Exception e("Unknown exception"); GPSTK_THROW(e); }
03239 }
03240
03241
03242