/**main * gets the command line arguments, set parameters accordingly and triggers the data acquisition to generate CSV files. * Input data are contained in a RINEX observation or navigation file containing header and epoch data. * The output is a CSV (Comma Separated Values) text data file. This type of files can be used to import data to some available * application (like MS Excel). * A detailed definition of the RINEX format can be found in the document "RINEX: The Receiver Independent Exchange * Format Version 2.10" from Werner Gurtner; Astronomical Institute; University of Berne. An updated document exists * also for Version 3.01. * *@param argc the number of arguments passed from the command line *@param argv the array of arguments passed from the command line *@return the exit status according to the following values and meaning:: * - (0) no errors have been detected * - (1) an error has been detected in arguments * - (2) error when opening the input file * - (3) error when reading, setting or printing header data * - (4) error in data filtering parameters * - (5) there were format errors in epoch data or no epoch data exist * - (6) error when creating output file * - (7) inconsistent data in RINEX VERSION header record */ int main(int argc, char* argv[]) { int anInt; //a general purpose int variable string aStr; //a general purpose string variable string fileName; double aDouble; //a general purpose double variable /**The main process sequence follows:*/ /// 1- Defines and sets the error logger object Logger log("LogFile.txt", string(), string(argv[0]) + MYVER + string(" START")); /// 2- Setups the valid options in the command line. They will be used by the argument/option parser TOT = parser.addOption("-t", "--totime=TOT", "TOT", "Select epochs before the given date and time (comma separated yyyy,mm,dd,hh,mm,sec", ""); SELSAT = parser.addOption("-s", "--selsat", "SELSAT", "Select system-satellite from input (comma separated list of sys-prn, like G01,G02)", ""); SELOBS2 = parser.addOption("-p", "--selobs2", "SELOBS2", "Select system-observable (ver.2.10 notation) from input (comma separated list, like C1,L1,L2)", ""); SELOBS3 = parser.addOption("-o", "--selobs", "SELOBS3", "Select system-observable (ver.3.01 notation) from input (comma separated list, like GC1C,GL1C)", ""); LOGLEVEL = parser.addOption("-l", "--llevel", "LOGLEVEL", "Maximum level to log (SEVERE, WARNING, INFO, CONFIG, FINE, FINER, FINEST)", "INFO"); HELP = parser.addOption("-h", "--help", "HELP", "Show usage data and stops", false); FROMT = parser.addOption("-f", "--fromtime=FROMT", "FROMT", "Select epochs from the given date and time (comma separated yyyy,mm,dd,hh,mm,sec", ""); /// 3- Setups the default values for operators in the command line INRINEX = parser.addOperator("RINEX.DAT"); /// 4- Parses arguments in the command line extracting options and operators try { parser.parseArgs(argc, argv); } catch (string error) { parser.usage("Argument error: " + error, CMDLINE); log.severe(error); return 1; } log.info(parser.showOptValues()); log.info(parser.showOpeValues()); if (parser.getBoolOpt(HELP)) { //help info has been requested parser.usage("Parses and read the given observation RINEX file generating a CSV ot TXT file with the requested characteristics", CMDLINE); return 0; } /// 5- Sets logging level stated in option. Default level is INFO log.setLevel(parser.getStrOpt(LOGLEVEL)); /// 7 - Set 1st and last epoch time tags (if selected from / to epochs time) TimeIntervalParams timeInterval; int week, year, month, day, hour, minute; double tow, second; aStr = parser.getStrOpt(FROMT); if (!aStr.empty()) { if (sscanf(aStr.c_str(), "%d,%d,%d,%d,%d,%lf", &year, &month, &day, &hour, &minute, &second) != 6) { log.severe("Cannot state 'from time' for the time interval"); return 1; } setWeekTow (year, month, day, hour, minute, second, week, tow); timeInterval.fromTimeTag = getSecsGPSEphe(week, tow); timeInterval.fromTime = true; } else timeInterval.fromTime = false; aStr = parser.getStrOpt(TOT); if (!aStr.empty()) { if (sscanf(aStr.c_str(), "%d,%d,%d,%d,%d,%lf", &year, &month, &day, &hour, &minute, &second) != 6) { log.severe("Cannot state 'to time' for the time interval"); return 1; } setWeekTow (year, month, day, hour, minute, second, week, tow); timeInterval.toTimeTag = getSecsGPSEphe(week, tow); timeInterval.toTime = true; } else timeInterval.toTime = false; /// 7- Opens the RINEX input file passed as operator FILE* inFile; fileName = parser.getOperator(INRINEX); if ((inFile = fopen(fileName.c_str(), "r")) == NULL) { log.severe("Cannot open file " + fileName); return 2; } /// 8- Create a RINEX object and extract header data from the RINEX input file RinexData rinex(RinexData::VTBD, &log); char fileType = ' '; char sysId = ' '; try { rinex.readRinexHeader(inFile); if (!rinex.getHdLnData(RinexData::INFILEVER, aDouble, fileType, sysId)) { log.severe("This RINEX input file version cannot be processed"); fclose(inFile); return 3; } } catch (string error) { log.severe(error); fclose(inFile); return 3; } /// 9 - Set filtering parameters passed in options, if any //convert obsV2Tokens to V3 and append them to obsTokens vector<string> obsV2Tokens = getTokens(parser.getStrOpt(SELOBS2), ','); vector<string> obsTokens = getTokens(parser.getStrOpt(SELOBS3), ','); for (vector<string>::iterator it = obsV2Tokens.begin(); it != obsV2Tokens.end(); it++) { aStr = rinex.obsV2toV3((*it).substr(1)); if (aStr.empty()) log.warning("Filtering data: ignored unknown V2 observable " + aStr); else obsTokens.push_back((*it).substr(0,1) + aStr); } //verify coherence of SELSAT w.r.t. fileType and system identifier vector<string> selsat = getTokens(parser.getStrOpt(SELSAT), ','); if (fileType == 'N' && sysId == 'M') { if (selsat.empty()) { log.severe("File is Navigation type 'M', and no sytem was selected."); return 4; } else { //state sysId as per the 1st satellite selected sysId = selsat[0].at(0); } } if (!rinex.setFilter(selsat, obsTokens)) log.warning("Ignored inconsistent data filtering parameters for observation files."); /// 10 - Create output file for header data (suffix name _HDR.CSV), print them, and close output file FILE* outFile; while ((anInt = fileName.find('.')) != string::npos) fileName.replace(anInt, 1, "_"); //replace . by _ in fileName aStr = fileName + "_HDR.CSV"; if ((outFile = fopen(aStr.c_str(), "w")) == NULL) { log.severe("Cannot create file " + aStr); return 6; } generateHeaderCSV(outFile, rinex, &log); fclose(outFile); rinex.clearHeaderData(); /// 11 - Create output file for observation or navigation data switch (fileType) { case 'O': /// 11.1- If observation file, create output file (suffix name _OBS.CSV), and epoch by epoch read its data and print them. Close output file aStr = fileName + "_OBS.CSV"; if ((outFile = fopen(aStr.c_str(), "w")) == NULL) { log.severe("Cannot create file " + aStr); return 6; } anInt = generateObsCSV(inFile, outFile, rinex, timeInterval, &log); fclose(outFile); break; case 'N': /// 11.2 - If navigation file, create output file (suffix name _xxxNAV.CSV), and epoch by epoch read its data and print them. Close output file switch (sysId) { case 'G': aStr = fileName + "_GPSNAV.CSV"; if ((outFile = fopen(aStr.c_str(), "w")) == NULL) { log.severe("Cannot create file " + aStr); return 6; } anInt = generateGPSNavCSV(inFile, outFile, rinex, timeInterval, &log); fclose(outFile); break; case 'E': aStr = fileName + "_GALNAV.CSV"; if ((outFile = fopen(aStr.c_str(), "w")) == NULL) { log.severe("Cannot create file " + aStr); return 6; } anInt = generateGalNavCSV(inFile, outFile, rinex, timeInterval, &log); fclose(outFile); break; case 'R': aStr = fileName + "_GLONAV.CSV"; if ((outFile = fopen(aStr.c_str(), "w")) == NULL) { log.severe("Cannot create file " + aStr); return 6; } anInt = generateGloNavCSV(inFile, outFile, rinex, timeInterval, &log); fclose(outFile); break; case 'S': aStr = fileName + "_SBASNAV.CSV"; if ((outFile = fopen(aStr.c_str(), "w")) == NULL) { log.severe("Cannot create file " + aStr); return 6; } anInt = generateSBASNavCSV(inFile, outFile, rinex, timeInterval, &log); fclose(outFile); break; default: //should not happen log.severe("Unexpected system type for navigation file"); return 7; } break; default: log.severe("Unexpected file type, different from Observation or Navigation"); return 7; } fclose(inFile); return anInt>0? 0:5; }