233 #include "NewNavInc.h"
242 #include <gnsstk/Exception.hpp>
243 #include <gnsstk/StringUtils.hpp>
244 #include <gnsstk/GNSSconstants.hpp>
246 #include <gnsstk/singleton.hpp>
247 #include <gnsstk/expandtilde.hpp>
248 #include <gnsstk/logstream.hpp>
249 #include <gnsstk/CommandLine.hpp>
251 #include <gnsstk/CommonTime.hpp>
252 #include <gnsstk/Epoch.hpp>
253 #include <gnsstk/TimeString.hpp>
255 #include <gnsstk/RinexSatID.hpp>
256 #include <gnsstk/RinexObsID.hpp>
257 #include <gnsstk/Rinex3ObsStream.hpp>
258 #include <gnsstk/Rinex3ObsHeader.hpp>
259 #include <gnsstk/Rinex3ObsData.hpp>
264 using namespace StringUtils;
267 string version(
string(
"2.4 9/23/15 rev"));
316 EditCmd(
const string typestr,
const string arg);
322 {
return (type != invalidCT); }
326 string asString(
string msg=
string());
350 int processUserInput(
int argc,
char **argv)
throw();
353 string buildCommandLine(
void)
throw();
357 int extraProcessing(
string& errors,
string& extras)
throw();
360 void parseEditCmds(vector<string>& v,
const string l, ostringstream& os)
throw();
367 defaultstartStr = string(
"[Beginning of dataset]");
368 defaultstopStr = string(
"[End of dataset]");
373 help = verbose = outver2 =
false;
376 messHDdc = messHDda =
false;
408 string messHDp,messHDr,messHDo,messHDa,
messHDx,messHDm,messHDn,messHDt,messHDh,messHDj,messHDk,messHDl,messHDs;
409 vector<string>
messHDc,messDA,messDAm,messDAp,messDO,messDS,messDSp,messDSm,messDD,messDDp,messDDm;
410 vector<string> messSD,
messSS,messSL,messSLp,messSLm,messBD,messBDp,messBDm,messBS,messBL;
451 int main(
int argc,
char **argv)
453 #include "NewNavInit.h"
459 clock_t totaltime(clock());
475 LOG(
ERROR) <<
"------- Input is not valid: ----------\n" << errs
476 <<
"\n------- end errors -----------";
479 if(!errs.empty())
LOG(
INFO) << errs;
490 totaltime = clock()-totaltime;
494 oss << C.
prgmName <<
" timing: processing " << fixed << setprecision(3)
495 << double(totaltime)/double(CLOCKS_PER_SEC) <<
" sec, wallclock: "
496 << setprecision(0) << (wallclkend-wallclkbeg) <<
" sec.";
504 catch(FFStreamError& e) { cerr <<
"FFStreamError: " << e.what(); }
506 catch (...) { cerr <<
"Unknown exception. Abort." << endl; }
525 if(C.
messIF.size() == 0) {
526 ossE <<
"Error : No valid input files have been specified.";
529 if(C.
messOF.size() == 0) {
530 ossE <<
"Error : No valid output files have been specified.";
539 for(j=0, i=0; i<C.
vecCmds.size(); ++i) {
558 if(::fabs(s-sow) > 1.0)
LOG(
WARNING) <<
"Warning : decimation reference time "
559 <<
"(--start) is not an even GPS-seconds-of-week mark.";
562 LOG(
DEBUG) <<
"Decimate, with final decimate ref time "
571 if(!isValid)
return -5;
596 for(nfiles=0,nfile=0; nfile<C.
messIF.size(); nfile++)
601 string filename(C.
messIF[nfile]);
607 istrm.
open(filename.c_str(),ios::in);
610 LOG(
WARNING) <<
"Warning : could not open file " << filename;
615 LOG(
DEBUG) <<
"Opened input file " << filename;
616 istrm.exceptions(ios::failbit);
619 LOG(
INFO) <<
"Reading header...";
627 <<
"\n Header dump follows.";
635 LOG(
DEBUG) <<
"Input header for RINEX file " << filename;
639 map<string,vector<RinexObsID> >::const_iterator kt;
645 <<
" (" << kt->second.size() <<
"):";
646 for(i=0; i<kt->second.size(); i++)
647 oss <<
" " << kt->second[i].asString();
651 vector<EditCmd>::iterator jt;
656 bool mungeData(
false);
657 map<string, map<int,int> > mapSysObsIDTranslate;
660 vector<EditCmd>::iterator it;
663 LOG(
DEBUG) <<
"Killing " << it->asString() <<
" " << it->sat;
669 string sys(
asString(it->sat.systemChar()));
672 Rinex3ObsHeader::RinexObsMap::iterator jt;
675 if (sys !=
string(
"?") && sys != jt->first)
677 RinexObsID obsid(jt->first + it->obs.asString(),
681 Rinex3ObsHeader::RinexObsVec::iterator kt;
682 kt = find(jt->second.begin(), jt->second.end(), obsid);
683 if(kt == jt->second.end())
685 jt->second.erase(kt);
695 if (it->sat.id == -1)
698 Rinex3ObsHeader::PRNNumObsMap::iterator i,j;
702 if (j->first.system == it->sat.system)
705 if (it->sat.system == SatelliteSystem::Glonass)
709 string sys(
asString(it->sat.systemChar()));
715 Rinex3ObsHeader::PRNNumObsMap::iterator jt = RHout.
numObsForSat.find(it->sat);
719 Rinex3ObsHeader::GLOFreqNumMap::iterator kt = RHout.
glonassFreqNo.find(it->sat);
730 map<string, vector<RinexObsID> >::iterator jt;
733 string sys(jt->first);
735 vector<RinexObsID>::iterator kt;
736 for(i=0; i < jt->second.size(); i++)
740 mapSysObsIDTranslate[sys][i]
752 string sys(jt->first);
754 oss <<
"Translation map for sys " << sys;
755 for(i=0; i < jt->second.size(); i++)
756 oss <<
" " << i <<
":" << mapSysObsIDTranslate[sys][i];
767 LOG(
DEBUG) <<
"Header pre prepareVer2Write";
783 LOG(
INFO) <<
"Reading observations...";
786 try { istrm >> Rdata; }
789 LOG(
WARNING) <<
" Warning : Failed to read obs data (Exception "
790 << e.
getText(0) <<
"); dump follows.";
796 catch(std::exception& e) {
797 Exception ge(
string(
"Std excep: ") + e.what());
801 Exception ue(
"Unknown exception while reading RINEX data.");
806 if(!istrm.good() || istrm.eof()) { iret = 0;
break; }
815 <<
" is before begin time.";
820 <<
" is after end time.";
829 LOG(
DEBUG) <<
"Decimate? dt = " << fixed << setprecision(2) << dt;
830 if (::fabs(dt) > 0.25)
832 LOG(
DEBUG) <<
" Decimation rejects RINEX data timetag "
845 Rinex3ObsData::DataMap::const_iterator kt;
846 for (kt=Rdata.
obs.begin(); kt!=Rdata.
obs.end(); ++kt)
850 for (i=0; i<Rdata.
obs[sat].size(); i++)
851 if (mapSysObsIDTranslate[sys][i] > -1)
852 RDout.
obs[sat].push_back(Rdata.
obs[sat][i]);
859 if(iret > 0)
continue;
862 try { C.
ostrm << RDout; }
868 LOG(
DEBUG) <<
"INPUT data ---------------";
870 LOG(
DEBUG) <<
"OUTPUT data ---------------";
882 if(iret >= 0) nfiles++;
887 LOG(
INFO) <<
" Close output file.";
890 if(iret < 0)
return iret;
919 vector<EditCmd>::iterator it, jt;
920 vector<EditCmd> toCurr;
926 if (it->ttag <= now || ::fabs(it->ttag - now) < C.
timetol)
928 LOG(
DEBUG) <<
"Execute vec cmd " << it->asString();
931 if(iret < 0)
return iret;
934 if (iret > 0) toCurr.push_back(*it);
938 if (iret == 0 && it->sign == -1)
941 if (jt->type==it->type && jt->sat==it->sat && jt->obs==it->obs)
945 Exception e(
string(
"Execute failed to find + cmd matching ")+it->asString());
962 LOG(
DEBUG) <<
"Execute current cmd " << it->asString();
974 for (it = toCurr.begin(); it != toCurr.end(); ++it)
994 Rinex3ObsData::DataMap::const_iterator kt;
995 vector<RinexObsID>::iterator jt;
1001 LOG(
DEBUG) <<
" Invalid command " << it->asString();
1012 C.
ostrm.
open(it->field.c_str(),ios::out);
1013 if(!C.
ostrm.is_open())
1015 LOG(
ERROR) <<
"Error : could not open output file " << it->field;
1018 C.
ostrm.exceptions(ios::failbit);
1020 LOG(
INFO) <<
" Opened output file " << it->field <<
" at time "
1045 Rhead.
valid |= Rinex3ObsHeader::validMarkerNumber;
1057 Rhead.
valid ^= Rinex3ObsHeader::validComment;
1061 for(i=0; i<C.
messHDc.size(); i++)
1063 Rhead.
valid |= Rinex3ObsHeader::validComment;
1068 Rhead.
valid |= Rinex3ObsHeader::validInterval;
1073 Rhead.
valid.
clear(Rinex3ObsHeader::validLastTime);
1088 if(it->sign == 0)
return 0;
1106 vector<RinexSatID> sats;
1110 LOG(
DEBUG) <<
" Delete sat " << it->asString();
1114 kt = Rdata.
obs.find(it->sat);
1115 if (kt != Rdata.
obs.end())
1116 sats.push_back(kt->first);
1118 LOG(
DEBUG) <<
" Execute: sat " << it->sat <<
" not found in data";
1123 for (kt=Rdata.
obs.begin(); kt!=Rdata.
obs.end(); ++kt)
1124 if (kt->first.system == it->sat.system)
1125 sats.push_back(kt->first);
1128 LOG(
DEBUG) <<
" sats.size() " << sats.size() <<
" Rdata.obs.size() " << Rdata.
obs.size();
1130 for (j=0; j<sats.size(); j++)
1131 Rdata.
obs.erase(sats[j]);
1143 vector<RinexSatID> sats;
1145 if(it->sign == -1)
return 0;
1147 sys =
asString(it->sat.systemChar());
1154 LOG(
DEBUG) <<
" Execute: obstype " << it->obs <<
" not found in header";
1163 if(Rdata.
obs.find(it->sat)==Rdata.
obs.end())
1165 LOG(
DEBUG) <<
" Execute: sat " << it->sat <<
" not found in data";
1168 sats.push_back(it->sat);
1172 for(kt=Rdata.
obs.begin(); kt!=Rdata.
obs.end(); ++kt)
1174 if(kt->first.system == it->sat.system)
1175 sats.push_back(kt->first);
1179 for(j=0; j<sats.size(); j++)
1185 Rdata.
obs[sats[j]][i].data = 0.0;
1186 Rdata.
obs[sats[j]][i].ssi = 0;
1187 Rdata.
obs[sats[j]][i].lli = 0;
1191 Rdata.
obs[sats[j]][i].data = it->data;
1195 Rdata.
obs[sats[j]][i].ssi = it->idata;
1199 Rdata.
obs[sats[j]][i].lli = it->idata;
1203 if(Rdata.
obs[sats[j]][i].data != 0.0 || C.
messBZ)
1204 Rdata.
obs[sats[j]][i].data += it->data;
1208 Rdata.
obs[sats[j]][i].ssi += it->idata;
1212 Rdata.
obs[sats[j]][i].lli += it->idata;
1234 string PrgmDesc,cmdlineUsage, cmdlineErrors, cmdlineExtras;
1235 vector<string> cmdlineUnrecognized;
1238 opts.DefineUsageString(prgmName +
" [options]");
1239 PrgmDesc = buildCommandLine();
1242 int iret = opts.ProcessCommandLine(argc, argv, PrgmDesc,
1243 cmdlineUsage, cmdlineErrors, cmdlineUnrecognized);
1246 if(iret == -2)
return iret;
1247 if(iret == -3)
return iret;
1250 if(opts.hasHelp()) {
1256 iret = extraProcessing(cmdlineErrors, cmdlineExtras);
1257 if(iret == -4)
return iret;
1260 if(cmdlineUnrecognized.size() > 0) {
1261 LOG(
WARNING) <<
"Warning - unrecognized arguments:";
1262 for(
size_t i=0; i<cmdlineUnrecognized.size(); i++)
1263 LOG(
WARNING) <<
" " << cmdlineUnrecognized[i];
1264 LOG(
WARNING) <<
"End of unrecognized arguments";
1267 if(!cmdlineExtras.empty()) {
1273 if(!cmdlineErrors.empty()) {
1276 LOG(
ERROR) <<
"Errors found on command line:\n " << cmdlineErrors
1277 <<
"\nEnd of command line errors.";
1284 oss <<
"------ Summary of " << prgmName
1285 <<
" command line configuration ------\n";
1286 opts.DumpConfiguration(oss);
1287 if(!cmdlineExtras.empty()) oss <<
"# Extra Processing:\n" << cmdlineExtras;
1288 oss <<
"\n------ End configuration summary ------";
1300 string PrgmDesc =
" Program " + prgmName +
1301 " will open and read RINEX observation files(s), apply editing\n"
1302 " commands, and write out the modified RINEX data to RINEX file(s).\n"
1303 " Input is on the command line, or of the same form in a file (--file).\n"
1304 " NB. Minimum required input is one input file (--IF) and one output file (--OF).\n"
1305 " Usage: " + prgmName +
" [options] [editing commands]\n"
1311 opts.Add(0,
"IF",
"fn",
true,
false, &messIF,
1312 "# RINEX input and output files",
1313 "Input RINEX observation file name");
1314 opts.Add(0,
"ID",
"p",
false,
false, &InObspath,
"",
1315 "Path of input RINEX observation file(s)");
1316 opts.Add(0,
"OF",
"fn",
true,
false, &messOF,
"",
1317 "Output RINEX obs files [also see --OF <f,t> below]");
1318 opts.Add(0,
"OD",
"p",
false,
false, &OutObspath,
"",
1319 "Path of output RINEX observation file(s)");
1321 opts.Add(
'f',
"file",
"fn",
true,
false, &cfgfile,
"# Other file I/O",
1322 "Name of file containing more options [#->EOL = comment]");
1323 opts.Add(
'l',
"log",
"fn",
false,
false, &logfile,
"",
1324 "Output log file name");
1325 opts.Add(0,
"ver2",
"",
false,
false, &outver2,
"",
1326 "Write out RINEX version 2");
1328 opts.Add(0,
"verbose",
"",
false,
false, &verbose,
"# Help",
1329 "Print extra output information");
1330 opts.Add(0,
"debug",
"",
false,
false, &
debug,
"",
1331 "Print debug output at level 0 [debug<n> for level n=1-7]");
1332 opts.Add(0,
"help",
"",
false,
false, &
help,
"",
1333 "Print this syntax page, and quit");
1335 opts.Add(0,
"HDp",
"p",
false,
false, &messHDp,
"# ------ Editing commands ------\n"
1336 "# RINEX header modifications (arguments with whitespace must be quoted)",
1337 "Set header 'PROGRAM' field to <p>");
1338 opts.Add(0,
"HDr",
"rb",
false,
false, &messHDr,
"",
1339 "Set header 'RUN BY' field to <rb>");
1340 opts.Add(0,
"HDo",
"obs",
false,
false, &messHDo,
"",
1341 "Set header 'OBSERVER' field to <obs>");
1342 opts.Add(0,
"HDa",
"a",
false,
false, &messHDa,
"",
1343 "Set header 'AGENCY' field to <a>");
1344 opts.Add(0,
"HDx",
"x,y,z",
false,
false, &messHDx,
"",
1345 "Set header 'POSITION' field to <x,y,z> (ECEF, m)");
1346 opts.Add(0,
"HDm",
"m",
false,
false, &messHDm,
"",
1347 "Set header 'MARKER NAME' field to <m>");
1348 opts.Add(0,
"HDn",
"n",
false,
false, &messHDn,
"",
1349 "Set header 'MARKER NUMBER' field to <n>");
1350 opts.Add(0,
"HDj",
"n",
false,
false, &messHDj,
"",
1351 "Set header 'REC #' field to <n>");
1352 opts.Add(0,
"HDk",
"t",
false,
false, &messHDk,
"",
1353 "Set header 'REC TYPE' field to <t>");
1354 opts.Add(0,
"HDl",
"v",
false,
false, &messHDl,
"",
1355 "Set header 'REC VERS' field to <v>");
1356 opts.Add(0,
"HDs",
"n",
false,
false, &messHDs,
"",
1357 "Set header 'ANT #' field to <n>");
1358 opts.Add(0,
"HDt",
"t",
false,
false, &messHDt,
"",
1359 "Set header 'ANT TYPE' field to <t>");
1360 opts.Add(0,
"HDh",
"h,e,n",
false,
false, &messHDh,
"",
1361 "Set header 'ANTENNA OFFSET' field to <h,e,n> (Ht,East,North)");
1362 opts.Add(0,
"HDc",
"c",
true,
false, &messHDc,
"",
1363 "Add 'COMMENT' <c> to the output header");
1364 opts.Add(0,
"HDdc",
"",
false,
false, &messHDdc,
"",
1365 "Delete all comments [not --HDc] from input header");
1366 opts.Add(0,
"HDda",
"",
false,
false, &messHDda,
"",
1367 "Delete all auxiliary header data");
1369 startStr = defaultstartStr;
1370 stopStr = defaultstopStr;
1371 opts.Add(0,
"TB",
"t[:f]",
false,
false, &startStr,
1372 "# Time related [t,f are strings, time t conforms to format f;"
1373 " cf. gnsstk::Epoch.]\n# Default t(f) is 'week,sec-of-week'(%F,%g)"
1374 " OR 'y,m,d,h,m,s'(%Y,%m,%d,%H,%M,%S)\n"
1375 " --OF <f,t> At RINEX time <t>, close output file and open "
1376 "another named <f> ()",
1377 "Start time: Reject data before this time");
1378 opts.Add(0,
"TE",
"t[:f]",
false,
false, &stopStr,
"",
1379 "Stop time: Reject data after this time");
1380 opts.Add(0,
"TT",
"dt",
false,
false, &timetol,
"",
1381 "Tolerance in comparing times, in seconds");
1382 opts.Add(0,
"TN",
"dt",
false,
false, &decimate,
"",
1383 "If dt>0, decimate data to times = TB + N*dt [sec, w/in tol]");
1385 opts.Add(0,
"DA",
"t",
true,
false, &messDA,
1386 "# In the following <SV> is a RINEX satellite identifier, "
1387 "e.g. G17 R7 E22 R etc.\n"
1388 "# and <OT> is a 3- or 4-char RINEX observation code "
1389 "e.g. C1C GL2X S2N\n"
1390 "# Delete cmds; for start(stop) cmds. stop(start) time defaults "
1391 "to end(begin) of data\n"
1392 "# and 'deleting' data for a single OT means it is set to zero "
1393 "- as RINEX requires.",
1394 "Delete all data at a single time <t>");
1395 opts.Add(0,
"DA+",
"t",
true,
false, &messDAp,
"",
1396 "Delete all data beginning at time <t>");
1397 opts.Add(0,
"DA-",
"t",
true,
false, &messDAm,
"",
1398 "Stop deleting at time <t>");
1400 opts.Add(0,
"DO",
"OT",
true,
false, &messDO,
"",
1401 "Delete RINEX obs type <OT> entirely (incl. header)");
1403 opts.Add(0,
"DS",
"SV,t",
true,
false, &messDS,
1404 " --DS <SV> Delete all data for satellite <SV> [SV may be char]",
1405 "Delete all data for satellite <SV> at single time <t>");
1406 opts.Add(0,
"DS+",
"SV,t",
true,
false, &messDSp,
"",
1407 "Delete data for satellite <SV> beginning at time <t>");
1408 opts.Add(0,
"DS-",
"SV,t",
true,
false, &messDSm,
"",
1409 "Stop deleting data for sat <SV> beginning at time <t>");
1411 opts.Add(0,
"DD",
"SV,OT,t",
true,
false, &messDD,
"",
1412 "Delete a single RINEX datum(SV,OT) at time <t>");
1413 opts.Add(0,
"DD+",
"SV,OT,t",
true,
false, &messDDp,
"",
1414 "Delete all RINEX data(SV,OT) starting at time <t>");
1415 opts.Add(0,
"DD-",
"SV,OT,t",
true,
false, &messDDm,
"",
1416 "Stop deleting RINEX data(SV,OT) at time <t>");
1418 opts.Add(0,
"SD",
"SV,OT,t,d",
true,
false, &messSD,
"",
1419 "Set data(SV,OT) to value <d> at single time <t>");
1420 opts.Add(0,
"SS",
"SV,OT,t,s",
true,
false, &messSS,
"",
1421 "Set SSI(SV,OT) to value <s> at single time <t>");
1422 opts.Add(0,
"SL",
"SV,OT,t,l",
true,
false, &messSL,
"",
1423 "Set LLI(SV,OT) to value <l> at single time <t>");
1424 opts.Add(0,
"SL+",
"SV,OT,t,l",
true,
false, &messSLp,
"",
1425 "Set all LLI(SV,OT) to value <l> starting at time <t>");
1426 opts.Add(0,
"SL-",
"SV,OT,t,l",
true,
false, &messSLm,
"",
1427 "Stop setting LLI(SV,OT) to value <l> at time <t>");
1429 opts.Add(0,
"BZ",
"",
false,
false, &messBZ,
1430 "# Bias cmds: (BD cmds apply only when data is non-zero, unless --BZ)",
1431 "Apply BD command even when data is zero (i.e. 'missing')");
1432 opts.Add(0,
"BS",
"SV,OT,t,s",
true,
false, &messBS,
"",
1433 "Add the value <s> to SSI(SV,OT) at single time <t>");
1434 opts.Add(0,
"BL",
"SV,OT,t,l",
true,
false, &messBL,
"",
1435 "Add the value <l> to LLI(SV,OT) at single time <t>");
1436 opts.Add(0,
"BD",
"SV,OT,t,d",
true,
false, &messBD,
"",
1437 "Add the value <d> to data(SV,OT) at single time <t>");
1438 opts.Add(0,
"BD+",
"SV,OT,t,d",
true,
false, &messBDp,
"",
1439 "Add the value <d> to data(SV,OT) beginning at time <t>");
1440 opts.Add(0,
"BD-",
"SV,OT,t,d",
true,
false, &messBDm,
"",
1441 "Stop adding the value <d> to data(SV,OT) at time <t>");
1444 opts.noExpansion(
"HDc");
1445 opts.noExpansion(
"OF");
1446 opts.noExpansion(
"DA");
1447 opts.noExpansion(
"DA-");
1448 opts.noExpansion(
"DA+");
1449 opts.noExpansion(
"DO");
1450 opts.noExpansion(
"DS");
1451 opts.noExpansion(
"DS+");
1452 opts.noExpansion(
"DS-");
1453 opts.noExpansion(
"DD");
1454 opts.noExpansion(
"DD+");
1455 opts.noExpansion(
"DD-");
1456 opts.noExpansion(
"SD");
1457 opts.noExpansion(
"SS");
1458 opts.noExpansion(
"SL");
1459 opts.noExpansion(
"SL+");
1460 opts.noExpansion(
"SL-");
1461 opts.noExpansion(
"BD");
1462 opts.noExpansion(
"BD+");
1463 opts.noExpansion(
"BD-");
1464 opts.noExpansion(
"BS");
1465 opts.noExpansion(
"BL");
1480 ostringstream oss,ossx;
1483 for(i=0; i<2; i++) {
1484 static const string fmtGPS(
"%F,%g"),fmtCAL(
"%Y,%m,%d,%H,%M,%S");
1485 msg = (i==0 ? startStr : stopStr);
1486 if(msg == (i==0 ? defaultstartStr : defaultstopStr))
continue;
1489 bool hasfmt(msg.find(
'%') != string::npos);
1492 fld =
split(msg,
':');
1493 if(fld.size() != 2) { ok =
false; }
1498 ep.
scanf(fld[0],fld[1]);
1499 (i==0 ? beginTime : endTime) =
static_cast<CommonTime>(ep);
1503 else if(n == 2 || n == 6) {
1506 ep.
scanf(msg,(n==2 ? fmtGPS : fmtCAL));
1507 (i==0 ? beginTime : endTime) =
static_cast<CommonTime>(ep);
1513 msg =
printTime((i==0 ? beginTime : endTime),fmtGPS+
" = "+fmtCAL);
1514 if(msg.find(
"Error") != string::npos) ok =
false;
1518 oss <<
"Error : invalid time or format in --" << (i==0 ?
"start" :
"stop")
1519 <<
" " << (i==0 ? startStr : stopStr) << endl;
1521 ossx << (i==0 ?
" Begin time --begin" :
" End time --end") <<
" is "
1522 <<
printTime((i==0 ? beginTime : endTime), fmtGPS+
" = "+fmtCAL+
"\n");
1526 parseEditCmds(messOF,
"OF", oss);
1527 parseEditCmds(messDA,
"DA", oss);
1528 parseEditCmds(messDAp,
"DA+", oss);
1529 parseEditCmds(messDAm,
"DA-", oss);
1530 parseEditCmds(messDO,
"DO", oss);
1531 parseEditCmds(messDS,
"DS", oss);
1532 parseEditCmds(messDSp,
"DS+", oss);
1533 parseEditCmds(messDSm,
"DS-", oss);
1534 parseEditCmds(messDD,
"DD", oss);
1535 parseEditCmds(messDDp,
"DD+", oss);
1536 parseEditCmds(messDDm,
"DD-", oss);
1537 parseEditCmds(messSD,
"SD", oss);
1538 parseEditCmds(messSS,
"SS", oss);
1539 parseEditCmds(messSL,
"SL", oss);
1540 parseEditCmds(messSLp,
"SL+", oss);
1541 parseEditCmds(messSLm,
"SL-", oss);
1542 parseEditCmds(messBD,
"BD", oss);
1543 parseEditCmds(messBDp,
"BD+", oss);
1544 parseEditCmds(messBDm,
"BD-", oss);
1545 parseEditCmds(messBS,
"BS", oss);
1546 parseEditCmds(messBL,
"BL", oss);
1558 for(i=0; i<vecCmds.size(); i++)
1559 ossx << vecCmds[i].
asString(
" Edit cmd:") << endl;
1562 if(!logfile.empty()) {
1563 logstrm.open(logfile.c_str(), ios::out);
1565 LOG(
ERROR) <<
"Error : Failed to open log file " << logfile;
1568 LOG(
INFO) <<
"Output redirected to log file " << logfile;
1575 if(!msg.empty()) errors += msg;
1577 if(!msg.empty()) extras += msg;
1586 ostringstream& os)
throw()
1588 for(
size_t i=0; i<vec.size(); i++) {
1590 if(ec.
isValid()) vecCmds.push_back(ec);
1591 else os <<
"Error: invalid argument in " << lab <<
" cmd: >" << vec[i] <<
"<\n";
1602 vector<string> flds;
1609 if(tag.size() == 2) sign = 0;
1610 else if(tag[2] ==
'+') sign = 1;
1611 else if(tag[2] ==
'-') sign = -1;
1613 tag = tag.substr(0,2);
1616 const size_t n(flds.size());
1619 if(n != 1 && n != 3 && n != 7)
return;
1623 if(!parseTime(
arg,ttag))
return;
1627 else if(tag ==
"DA") {
1628 if(!parseTime(
arg,ttag))
return;
1631 else if(tag ==
"DO") {
1632 if(sign != 0)
return;
1648 else if(tag ==
"DS") {
1649 if(n != 1 && n != 3 && n != 7)
return;
1653 if(!parseTime(
arg,ttag))
return;
1655 if(sign == 0 && n == 1) sign = 1;
1666 dat = flds[flds.size()-1];
1669 if(!parseTime(
arg,ttag))
return;
1675 if(flds[1].size() == 3 && sat.
systemChar() !=
'?')
1676 flds[1] = string(1,sat.
systemChar()) + flds[1];
1683 obs =
RinexObsID(flds[1], Rinex3ObsBase::currentVersion);
1688 if(tag ==
"DD") { type = ddCT;
return; }
1690 if(n != 5 && n != 9)
return;
1692 if(tag ==
"SD" || tag ==
"BD") {
1700 if(tag ==
"SD") type = sdCT;
1701 else if(tag ==
"SS") type = ssCT;
1702 else if(tag ==
"SL") type = slCT;
1703 else if(tag ==
"BS") type = bsCT;
1704 else if(tag ==
"BL") type = blCT;
1705 else if(tag ==
"BD") type = bdCT;
1714 static const string fmtGPS(
"%F,%g"),fmtCAL(
"%Y,%m,%d,%H,%M,%S");
1717 if(n == 2 || n == 6) {
1719 try { ep.
scanf(
arg, (n==2 ? fmtGPS : fmtCAL)); }
1720 catch(StringException) {
return false; }
1734 static map<CmdType,string> typeLabel;
1735 if(typeLabel.size() == 0) {
1736 typeLabel[invalidCT] = string(
"--invalidCT-- ");
1737 typeLabel[ofCT] = string(
"OF_Output_File");
1738 typeLabel[daCT] = string(
"DA_Delete_All ");
1739 typeLabel[doCT] = string(
"DO_Delete_Obs ");
1740 typeLabel[dsCT] = string(
"DS_Delete_Sat ");
1741 typeLabel[ddCT] = string(
"DD_Delete_Data");
1742 typeLabel[sdCT] = string(
"SD_Set_Data ");
1743 typeLabel[ssCT] = string(
"SS_Set_SSI ");
1744 typeLabel[slCT] = string(
"SL_Set_LLI ");
1745 typeLabel[bdCT] = string(
"BD_Bias_Data ");
1746 typeLabel[bsCT] = string(
"BS_Bias_SSI ");
1747 typeLabel[blCT] = string(
"BL_Bias_LLI ");
1752 if(msg.size()) os << msg;
1753 os <<
" " << typeLabel[type]
1754 <<
" " << (sign==0 ?
"0" : (sign<0 ?
"-":
"+"))
1757 <<
" d:" << fixed << setprecision(4) <<
data
1761 <<
" >" << field <<
"<";
1766 catch(std::exception& e) {
1767 Exception E(
string(
"std::except: ") + e.what());
1776 vector<EditCmd>::iterator it, jt;
1777 vector<EditCmd> newCmds;
1786 bool havePair(
false);
1790 if(jt->type == it->type &&
1791 jt->sat == it->sat &&
1794 if(jt->sign == 1) havePair=
true;
1795 else if(jt->sign == -1) {
1796 LOG(
ERROR) << it->asString(
"Error: repeat '-'");
1802 if(jt == C.
vecCmds.begin())
break;
1810 newCmds.push_back(ec);
1816 if(newCmds.size() > 0) {
1817 for(it = newCmds.begin(); it != newCmds.end(); ++it )
1825 while(it != C.
vecCmds.end()) {