39 #ifndef GNSSTK_WINDOWFILTER_HPP
40 #define GNSSTK_WINDOWFILTER_HPP
136 virtual void Reset() = 0;
139 virtual unsigned int N()
const = 0;
142 virtual void Add(
const T& x,
const T&
y) = 0;
145 virtual void Subtract(
const T& x,
const T&
y) = 0;
148 virtual T
StdDev()
const = 0;
163 virtual T
Slope()
const = 0;
172 virtual std::string
asString()
const = 0;
187 inline unsigned int N()
const {
return S.N(); }
190 void Add(
const T& x,
const T&
y) {
S.Add(
y); }
214 inline T
Slope()
const {
return T(); }
241 inline unsigned int N()
const {
return TSS.N(); }
244 void Add(
const T& x,
const T&
y) {
TSS.Add(x,
y); }
254 return TSS.StdDevY();
256 return TSS.SigmaYX();
264 return TSS.VarianceY();
266 return TSS.VarianceYX();
344 const std::vector<int>& f)
429 int filter(
const size_t index = 0,
int npts = -1);
444 void dump(std::ostream& s, std::string tag = std::string());
477 const std::vector<int>
511 dsize =
data.size() - i0 - buffsize;
515 const int ilimit(dsize + i0);
525 while (i < ilimit && n < 2 * width + buffsize)
538 else if (dsize <
int(2 * width + buffsize))
544 if (twoSample && noxdata)
550 if (!noxdata && xdata.size() - i0 - buffsize < dsize)
554 if (!noflags && flags.size() - i0 - buffsize < dsize)
576 std::deque<int> buff;
632 #define dvec(i) (data[i])
634 #define xvec(i) (noxdata ? T(i) : xdata[i])
636 #define inc(i) i++; if(!noflags) while(i<ilimit && flags[i]) i++
642 while (i < ilimit && flags[i])
653 int iplus, iminus(i), isecond;
656 T xprev(
xvec(i)), xmid;
662 while (buff.size() < buffsize)
671 while (ptrPast->
N() < width)
682 while (ptrFuture->
N() < width)
714 while (ptrFuture->
N() < width)
728 for (i = 0; i < 3; i++)
740 for (i = isecond; i < limm2;)
749 A.
fN = ptrFuture->
N();
751 xmid = xprev + 0.5 * (
xvec(i) - xprev);
812 if (A.
psig <= T(0) && A.
fsig <= T(0))
816 else if (A.
psig <= T(0))
820 else if (A.
fsig <= T(0))
840 std::cout <<
"WF:FIL" << std::fixed << std::setprecision(osp) <<
" "
841 << std::setw(osw) <<
xvec(i) <<
" " << std::setw(osw)
842 <<
dvec(i) <<
" " << std::setw(osw) << A.
step <<
" "
843 << std::setw(osw) << A.
sigma <<
" " << std::setw(3)
844 << A.
pN <<
" " << std::setw(osw) << A.
pave <<
" "
845 << std::setw(osw) << A.
psig <<
" " << std::setw(3) << A.
fN
846 <<
" " << std::setw(osw) << A.
fave <<
" "
847 << std::setw(osw) << A.
fsig <<
" " << std::setw(osw)
848 << ::fabs(A.
step / A.
sigma) << std::endl;
852 analvec.push_back(A);
871 if (fullwindows && iplus >= i0 + dsize - 1)
877 if (balanced && iplus == i0 + dsize)
889 else if (balanced && ptrPast->
N() < width + 1)
905 if (balanced || iplus < i0 + dsize - 1)
912 if (balanced || ptrPast->
N() > width)
929 return analvec.size();
951 fe.
index = analvec[0].index;
954 results.push_back(fe);
962 std::deque<double> rat, rat1d, sig, sig1d, fminusp;
964 std::string ratmsg, sigmsg, fmpmsg, wtmsg;
967 std::cout <<
"WF:ANL size is " << analvec.size() << std::endl;
969 for (i = 0; i < analvec.size(); i++)
975 for (j = 0; j < halfwidth; j++)
979 fminusp.push_back(0.0);
981 for (j = 0; (j <= halfwidth && j < analvec.size()); j++)
984 ::fabs(analvec[j].step / analvec[j].sigma));
985 sig.push_back(analvec[j].sigma);
986 fminusp.push_back(analvec[j].fsig -
989 for (j = 0; j < 2 * halfwidth; j++)
991 rat1d.push_back(0.0);
992 sig1d.push_back(0.0);
997 else if (i + halfwidth < analvec.size())
1001 rat.push_back(::fabs(analvec[i + halfwidth].step /
1002 analvec[i + halfwidth].sigma));
1003 rat1d.push_back(rat.back() - tmp);
1005 sig.push_back(analvec[i + halfwidth].sigma);
1006 sig1d.push_back(sig.back() - tmp);
1008 fminusp.push_back(analvec[i + halfwidth].fsig -
1009 analvec[i + halfwidth].psig);
1013 while (rat.size() > 2 * halfwidth + 1)
1017 fminusp.pop_front();
1020 while (rat1d.size() > 2 * halfwidth)
1027 bool rmax =
true, smin =
true, fmp =
true;
1028 int fmpcount(2 * halfwidth);
1029 double fmp0(fminusp[halfwidth]);
1030 double rat0(::fabs(rat[halfwidth]));
1031 for (j = 0; j < halfwidth; j++)
1035 if (j == halfwidth - 1)
1041 if (rat1d[j + halfwidth] > 0.0)
1048 if (rat1d[j] < -rat0 / 10.0)
1052 if (rat1d[j + halfwidth] > rat0 / 10.0)
1061 if (fminusp[j] - fmp0 < 0.0)
1066 if (fminusp[j + halfwidth + 1] - fmp0 > 0.0)
1078 double slim(0.04 * analvec[i].sigma);
1082 if (-sig1d[halfwidth - 1] / slim < 2.0)
1086 else if (sig1d[halfwidth] / slim < 2.0)
1092 for (j = 0; j < halfwidth - 1; j++)
1094 if (::fabs(sig1d[j] / sig1d[halfwidth - 1]) > 0.5)
1098 if (::fabs(sig1d[halfwidth + 1 + j] / sig1d[halfwidth]) > 0.5)
1107 for (j = 0; j < halfwidth; j++)
1111 if (sig1d[j] > slim)
1115 if (sig1d[j + halfwidth] < -slim)
1123 if (2 * halfwidth - fmpcount <= halfwidth / 3)
1130 double weight = (rmax ? 0.25 : 0) + (smin ? 0.25 : 0) +
1131 0.5 * fmpcount / double(2 * halfwidth);
1136 std::ostringstream oss;
1137 oss <<
" F-P" << std::fixed << std::setprecision(3);
1138 for (j = 0; j < fminusp.size(); j++)
1139 oss <<
"," << fminusp[j] - fmp0;
1140 oss <<
",cnt=" << fmpcount <<
"/" << 2 * halfwidth;
1143 oss <<
" RAT1d" << std::fixed << std::setprecision(3);
1144 for (j = 0; j < rat1d.size(); j++)
1145 oss <<
"," << rat1d[j];
1148 oss <<
" SIG1d" << std::scientific << std::setprecision(1);
1149 for (j = 0; j < sig1d.size(); j++)
1150 oss <<
"," << sig1d[j];
1151 oss <<
",(" << slim <<
")";
1158 oss <<
" changeF-P " << std::scientific
1159 << std::setprecision(2) << tmp;
1161 oss <<
" wt=" << std::fixed << std::setprecision(3) << weight;
1167 results[curr].ngood++;
1172 std::cout <<
"WF:ANL"
1173 <<
" " << std::setw(3) << i <<
" " << std::setw(3)
1174 << analvec[i].index << std::fixed
1175 << std::setprecision(osp) << std::setw(osw) <<
" "
1176 << (noxdata ? T(analvec[i].index)
1177 : xdata[analvec[i].index])
1178 <<
" " << std::setw(osw) <<
data[analvec[i].index] <<
" "
1179 << std::setw(osw) << analvec[i].step <<
" "
1180 << std::setw(osw) << analvec[i].sigma <<
" "
1181 << std::setw(3) << analvec[i].pN <<
" " << std::setw(osw)
1182 << analvec[i].pave <<
" " << std::setw(osw)
1183 << analvec[i].psig <<
" " << std::setw(3) << analvec[i].fN
1184 <<
" " << std::setw(osw) << analvec[i].fave <<
" "
1185 << std::setw(osw) << analvec[i].fsig <<
" "
1187 << ::fabs(analvec[i].step / analvec[i].sigma) << ratmsg
1188 << sigmsg << fmpmsg << wtmsg << std::flush;
1193 if (::fabs(analvec[i].step / analvec[i].sigma) <= minratio)
1197 std::cout <<
" small ratio" << std::flush;
1199 analvec[i].score = -3;
1200 analvec[i].msg =
" small_ratio";
1204 else if (::fabs(analvec[i].step) < minstep)
1208 std::cout <<
" small step" << std::flush;
1210 analvec[i].score = -2;
1211 analvec[i].msg =
" small_step";
1220 std::cout <<
" begin" << std::flush;
1222 analvec[i].score = -1;
1223 analvec[i].msg =
" i=0_no_tests";
1227 else if (i == analvec.size() - 1)
1231 std::cout <<
" end" << std::flush;
1233 analvec[i].score = -1;
1234 analvec[i].msg =
" i=end_no_tests";
1238 else if (::fabs(analvec[i].step / analvec[i].sigma) / minratio +
1239 ::fabs(analvec[i].step) / minstep - 2. <
1244 std::cout <<
" marginal" << std::flush;
1246 analvec[i].score = -4;
1247 analvec[i].msg =
" marginal_step+ratio";
1253 else if (!rmax || !smin || !fmp)
1258 msg =
"; no-ratio-max";
1259 analvec[i].msg += msg + ratmsg;
1267 msg =
"; no-sig-min";
1268 analvec[i].msg += msg + sigmsg;
1277 analvec[i].msg += msg + fmpmsg;
1283 analvec[i].score = int(100. * weight + 0.5);
1284 analvec[i].msg += wtmsg;
1287 std::cout << std::flush;
1293 analvec[i].msg =
";" + ratmsg +
";" + sigmsg +
";" + fmpmsg + wtmsg;
1294 analvec[i].score = int(100. * weight + 0.5);
1295 results[curr].ngood--;
1296 results[curr].npts = analvec[i].index - results[curr].index;
1299 fe.
index = analvec[i].index;
1302 fe.
step = analvec[i].step;
1303 fe.
sigma = analvec[i].sigma;
1304 fe.
score = analvec[i].score;
1305 fe.
msg = analvec[i].msg;
1306 results.push_back(fe);
1326 std::cout <<
" " << analvec[i].msg << std::endl;
1332 results[curr].npts =
1333 analvec[analvec.size() - 1].index - results[curr].index + 1;
1335 return (results.size());
1344 std::string msg(tag), slip, res;
1347 os <<
"#" << msg <<
" WindowFilter::dump() with "
1348 << (twoSample ?
"two" :
"one") <<
"-sample stats, minStep "
1349 << std::fixed << std::setprecision(osp) << getMinStep() <<
" minRatio "
1350 << getMinRatio() <<
" width " << width <<
" btwn-buff " << buffsize
1351 << (noxdata ?
" (xdata is index)" :
"") << std::endl;
1356 <<
" i xdata data step sigma pN pave psig fN fave fsig ratio ("
1357 << (balanced ?
"" :
"not ") <<
"balanced, "
1358 << (twoSample ?
"two" :
"one") <<
"-sample stats)" << std::endl;
1361 for (i = 0, j = 0, k = 0; i <
data.size(); i++)
1363 if (j >= analvec.size() || i != analvec[j].index)
1367 os << msg << std::fixed << std::setprecision(osp) <<
" "
1368 << std::setw(3) << i <<
" " << std::setw(osw)
1369 << (noxdata ? T(i) : xdata[i])
1371 <<
" " << std::setw(osw) <<
data[i] <<
" " << std::setw(osw)
1373 <<
" " << std::setw(osw) <<
"--"
1374 <<
" " << std::setw(3) << 0 <<
" " << std::setw(osw) <<
"--"
1375 <<
" " << std::setw(osw) <<
"--"
1376 <<
" " << std::setw(3) << 0 <<
" " << std::setw(osw) <<
"--"
1377 <<
" " << std::setw(osw) <<
"--"
1378 <<
" " << std::setw(osw) <<
"--";
1381 os <<
" no analysis";
1389 if (analvec[j].score > 0)
1391 if (analvec[j].score == 100)
1401 std::stringstream ss;
1402 ss <<
" score:" << analvec[j].score;
1407 if (k < results.size() && i == results[k].index)
1409 res =
" " + (results[k].haveStats ? results[k].asStatsString(osp)
1410 : results[k].asString());
1414 os << msg << std::fixed << std::setprecision(osp) <<
" "
1415 << std::setw(3) << i <<
" " << std::setw(osw)
1416 << (noxdata ? T(i) : xdata[i])
1418 <<
" " << std::setw(osw) <<
data[i] <<
" " << std::setw(osw)
1419 << analvec[j].step <<
" " << std::setw(osw) << analvec[j].sigma
1420 <<
" " << std::setw(3) << analvec[j].pN
1421 <<
" " << std::setw(osw) << analvec[j].pave <<
" "
1422 << std::setw(osw) << analvec[j].psig <<
" " << std::setw(3)
1424 <<
" " << std::setw(osw) << analvec[j].fave <<
" "
1428 <<
" " << std::setw(osw)
1429 << ::fabs(analvec[j].step / analvec[j].sigma)
1432 << res << slip << (dumpAmsg ? analvec[j].msg :
"") << std::endl;
1456 bool notfound(
true);
1457 for (i = 0; i < analvec.size(); i++)
1459 if (analvec[i].index == sg.
index)
1476 for (i = 0; i < sg.
ngood; i++)
1484 if (i > sg.
npts - width)
1489 sd = analvec[j + i].sigma;
1515 gnsstk::Robust::MedianAbsoluteDeviation<T>(&sdv[0], i, sg.
med,
false);
1524 #endif // GNSSTK_WINDOWFILTER_HPP