Example #1
0
/**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;
}