//--------------------------------------------------------------------------- #include #include #include #include #include #include #include #include #include // Program CF2PS // A program which uses GMT to create a postscript plot file // from a TEQC Compact Format plot file. // Author: Steve Hilla, National Geodetic Survey, NOAA // Note: This source code must be compiled using a compiler // that supports ANSI/ISO C++ . This code was originally // compiled using Borland C++ Builder Professional, Version 5.0, // (Build 12.34), Update Pack 1. // c::0206.25, sah, created program cf2ps (compact format to postscript) // c::0207.22, sah, added command-line arguments. // c::0208.22, sah, test for cases where only one satellite is left to plot. // c::0603.23, sah, changed outString.str(" \0"); to outString.str(""); #pragma hdrstop // used for C++Builder 5, comment out for UNIX //--------------------------------------------------------------------------- #pragma argsused // used for C++Builder 5, comment out for UNIX using namespace std; const int MAXPRNID = 36; const string VERDAT = "0603.23"; int optind = 1; int opterr = 1; int optopt; char* optarg; void writeUsageDescription( ofstream &outputStream ); void writeUsageDescriptionToScreen( ); int getopt_sh(int argc, char* argv[], char opts[]); void ymdhms_to_mjd(long year, long month, long mday, long hour, long minute, double second, long *mjd, double *fmjd); int main(int argc, char* argv[]) { char myopts[] = "i:o:p:x:y:b:e:s:d:"; int JMJ, ch, prnid; ostringstream outString; istringstream inString; istringstream prnList; string filename = "XX"; string psfile = "XX"; string plotTitle = "XX"; string xtitle = "XX"; string ytitle = "XX"; string startTime = "XX"; string stopTime = "XX"; string svlist = "XX"; string deleteList = "XX"; bool userStart,userStop,userSVS,userOmitSVS; string temp, temp2; string buf; int i, j, k, fileNumPrns, currNumPrns, itemp, prnIDs[MAXPRNID] = { 0 }; int userPRNs[MAXPRNID] = { 0 }; int userOmitPRNs[MAXPRNID] = { 0 }; int currPRNs[MAXPRNID] = { 0 }; bool prnHasData[MAXPRNID] = { false }; int lineNum, firstGoodPRN, lastGoodPRN, numGoodPRNs; long year, month, day, hour, minute, mjd; double dtemp, sampleRate, startMJD, currMJD, currHour, myExp; double userStartMJD = 15385.0, userStopMJD = 87704.0; double startDay, hourTick, valueTick, second, fmjd, epochNum = 0.0; double minValue = 1.0E300; double maxValue = -1.0E300; double minHour = 1.0E300; double maxHour = -1.0E300; string mySymbols[36] = {"@","A","B","C","D","E","F","G","H","I","J","K","L", "M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z", "7","8","9","@O","1","2","3","4","5"}; userStart = userStop = userSVS = userOmitSVS = true; if( argc < 2 ) { writeUsageDescriptionToScreen(); return -1; } ofstream sum("cf2ps.sum"); if( !sum ) { cerr << "Error! Cannot open cf2ps.sum!" << endl << "Now terminating Program CF2PS." << endl << endl; return -1; } sum << "Program CF2PS Version: " << VERDAT << endl; sum << endl << "The command-line, as interpreted by the program:" << endl; for( i = 0; i < argc; i++ ) sum << argv[i] << " "; sum << endl << endl; sum << endl << "Input Data entered by the user:" << endl; sum << "===============================" << endl; while((ch = getopt_sh(argc, argv, myopts)) != EOF ) { switch (ch) { case 'i': // input filename filename = optarg; sum << "Input filename (compact format plot file from teqc): " << filename << endl; break; case 'o': // Output filename psfile = optarg; sum << "Output filename (postscript file): " << psfile << endl; break; case 'p': // Plot Title plotTitle = optarg; sum << "Plot Title: " << plotTitle << endl; break; case 'x': // X-axis Title xtitle = optarg; sum << "X-axis Title: " << xtitle << endl; break; case 'y': // Y-axis Title ytitle = optarg; sum << "Y-axis Title: " << ytitle << endl; break; case 'b': // start time year = month = day = hour = minute = 0; startTime = optarg; inString.clear(); inString.str( startTime ); inString >> year >> month >> day >> hour >> minute >> second; if( year < 1980 || year > 2099 || month < 1 || month > 12 || day < 1 || day > 31 || hour < 0 || hour > 24 || minute < 0 || minute > 60 || second < 0.0 || second > 60.0 ) { sum << endl << "Error reading start time. Start time must be in" << endl << "\"year month day hour minute second\" format." << endl << "Please try again. Terminating program." << endl; writeUsageDescription( sum ); cerr << endl << "Error reading start time. Start time must be in" << endl << "\"year month day hour minute second\" format." << endl << "Please try again. Terminating program." << endl; writeUsageDescriptionToScreen( ); exit(1); } else { ymdhms_to_mjd(year,month,day,hour,minute,second, &mjd,&fmjd); userStartMJD = static_cast< double >( mjd ) + fmjd; sum << "Start Time: " << startTime << endl; } break; case 'e': // stop time year = month = day = hour = minute = 0; stopTime = optarg; inString.clear(); inString.str( stopTime ); inString >> year >> month >> day >> hour >> minute >> second; if( year < 1980 || year > 2099 || month < 1 || month > 12 || day < 1 || day > 31 || hour < 0 || hour > 24 || minute < 0 || minute > 60 || second < 0.0 || second > 60.0 ) { sum << endl << "Error reading stop time. Stop time must be in" << endl << "\"year month day hour minute second\" format." << endl << "Please try again. Terminating program." << endl; writeUsageDescription( sum ); cerr << endl << "Error reading stop time. Stop time must be in" << endl << "\"year month day hour minute second\" format." << endl << "Please try again. Terminating program." << endl; writeUsageDescriptionToScreen( ); exit(1); } else { ymdhms_to_mjd(year,month,day,hour,minute,second, &mjd,&fmjd); userStopMJD = static_cast< double >( mjd ) + fmjd; sum << "Stop Time: " << stopTime << endl; } break; case 's': // list of satellites to plot svlist = optarg; sum << "List of Satellite to plot: " << svlist << endl; inString.clear(); inString.str( svlist ); while( inString.good() ) { inString >> prnid; if( prnid < MAXPRNID ) userPRNs[prnid] = 1; } break; case 'd': // list of satellites to delete deleteList = optarg; sum << "List of Satellites to omit: " << deleteList << endl; inString.clear(); inString.str( deleteList ); while( inString.good() ) { inString >> prnid; if( prnid < MAXPRNID ) userOmitPRNs[prnid] = 1; } break; case '?': // "?" is an error code returned by getopt_sh() sum << "Error. Unknown option or missing/invalid argument. \n"; sum << "Terminating program CF2PS." << endl << endl; sum << "Please check the command-line options." << endl; writeUsageDescription( sum ); cerr << "Error. Unknown option or missing/invalid argument. \n"; cerr << "Terminating program CF2PS." << endl << endl; cerr << "Please check the command-line options." << endl; writeUsageDescriptionToScreen(); exit(1); break; default: // the program should never get here sum << "Error reading character returned by getopt_sh(): " << ch << endl; cerr << "Error reading character returned by getopt_sh(): " << ch << endl; exit(1); break; } } // end of while loop to read all command-line arguments. if( filename == "XX" ) { sum << "Error. You must enter an input filename." << endl; cerr << "Error. You must enter an input filename." << endl; writeUsageDescription( sum ); writeUsageDescriptionToScreen( ); exit(1); } if( psfile == "XX" ) { psfile = filename; psfile.append( ".ps" ); } if( plotTitle == "XX" ) plotTitle = filename; if( xtitle == "XX" ) xtitle = "Time (hours)"; if( ytitle == "XX" ) { if( filename.find( ".azi" ) != string::npos ) ytitle = "azimuth (degrees)"; else if ( filename.find( ".ele" ) != string::npos ) ytitle = "elevation (degrees)"; else if ( filename.find( ".iod" ) != string::npos ) ytitle = "derivative of ion-delay"; else if ( filename.find( ".ion" ) != string::npos ) ytitle = "ion-delay (meters)"; else if ( filename.find( ".mp1" ) != string::npos ) ytitle = "L1 pseudorange multipath (meters)"; else if ( filename.find( ".mp2" ) != string::npos ) ytitle = "L2 pseudorange multipath (meters)"; else if ( filename.find( ".sn1" ) != string::npos ) ytitle = "L1 signal-to-noise ratio"; else if ( filename.find( ".sn2" ) != string::npos ) ytitle = "L2 signal-to-noise ratio"; else ytitle = "y-axis (?) "; } if( startTime == "XX" ) userStart = false; if( stopTime == "XX" ) userStop = false; if( svlist == "XX" ) userSVS = false; if( deleteList == "XX" ) userOmitSVS = false; sum << endl << endl << "Input Data to be used for this run:" << endl; sum << "===================================" << endl; sum << "input filename: " << filename << endl; sum << "output filename: " << psfile << endl; sum << "Plot Title: " << plotTitle << endl; sum << "X-axis Title: " << xtitle << endl; sum << "Y-axis Title: " << ytitle << endl; if( userStart) sum << "User Start Time: " << startTime << endl; else sum << "(The user did not specify a start time)" << endl; if( userStop) sum << "User Stop Time: " << stopTime << endl; else sum << "(The user did not specify a stop time)" << endl; if( userSVS) sum << "User list of satellites to plot: " << svlist << endl; else { // If user did not specify any SVs, then make ALL SVs acceptable for plotting for( i = 0; i < MAXPRNID; i++ ) userPRNs[i] = 1; sum << "(The user did not specify a list of satellites to plot)" << endl; } if( userOmitSVS) { // if the user wants to omit certain SVs, then turn these off in userPRNs[] for( i = 0; i < MAXPRNID; i++ ) if( userOmitPRNs[i] == 1 ) userPRNs[i] = 0; sum << "User list of satellites to omit: " << deleteList << endl; } else sum << "(The user did not specify a list of satellites to omit)" << endl; cout << endl << "Now reading the input TEQC plot file: " << filename << endl << endl; sum << endl << "Now reading the input TEQC plot file: " << filename << endl << endl; ifstream cfplt( filename.c_str() ); if( !cfplt ) { sum << "Error! Cannot open file: " << filename.c_str() << endl << "Now terminating Program CF2PS." << endl << endl; cerr << "Error! Cannot open file: " << filename.c_str() << endl << "Now terminating Program CF2PS." << endl << endl; return -1; } getline( cfplt, buf ); // **** read the first line temp = buf.substr( 0, 7 ); if( temp != "COMPACT" ) { cerr << "WARNING! First Line in teqc plot file is not the word COMPACT!" << endl; sum << "WARNING! First Line in teqc plot file is not the word COMPACT!" << endl; } getline( cfplt, buf ); // **** read the second line temp = buf.substr( 0, 3 ); if( temp != "SVS" ) { cerr << "WARNING! Second Line in teqc plot file does not start with SVS!" << endl; sum << "WARNING! Second Line in teqc plot file does not start with SVS!" << endl; } fileNumPrns = (buf.length() - 5 )/6; for( i = 0; i < fileNumPrns; i++ ) { temp = buf.substr( 6+(6*i), 2 ); prnIDs[i] = atoi(temp.c_str()); temp = buf.substr( 6+(6*i)+3, 2 ); itemp = atoi(temp.c_str()); if( itemp != prnIDs[i] ) { cerr << "Warning! unequal satellite IDs found in header for file: " << filename << endl << endl; sum << "Warning! unequal satellite IDs found in header for file: " << filename << endl << endl; } } getline( cfplt, buf ); // **** read the third line temp = buf.substr( 0, 6 ); if( temp != "T_SAMP" ) { cerr << "WARNING! Third Line in teqc plot file does not start with T_SAMP!" << endl; sum << "WARNING! Third Line in teqc plot file does not start with T_SAMP!" << endl; } temp = buf.substr( 6, 10); sampleRate = atof(temp.c_str()); getline( cfplt, buf ); // **** read the fourth line temp = buf.substr( 0, 14 ); if( temp != "START_TIME_MJL" ) { cerr << "WARNING! 4th Line in teqc plot file does not start with START_TIME_MJL!" << endl << "Terminating program." << endl << endl; sum << "WARNING! 4th Line in teqc plot file does not start with START_TIME_MJL!" << endl << "Terminating program." << endl << endl; sum.close(); cfplt.close(); exit(1); } temp = buf.substr( 14, 20); startMJD = atof(temp.c_str()); startDay = floor(startMJD); if( userStop && (userStopMJD < startMJD) ) { sum << "Error. User's Stop Time is before the file starts ! " << endl << "User Stop Time (MJD): " << userStopMJD << " File Start Time (MJD): " << startMJD << endl << "Terminating program." << endl << endl; cerr << "Error. User's Stop Time is before the file starts ! " << endl << "User Stop Time (MJD): " << userStopMJD << " File Start Time (MJD): " << startMJD << endl << "Terminating program." << endl << endl; sum.close(); cfplt.close(); exit(1); } j = system("del *.xy"); // delete any older, leftover *.xy files if( j != 0 ) { cerr << "Cannot execute: delete *.xy ! " << endl; sum << "Cannot execute: delete *.xy ! " << endl; } cout << endl << "Now deleting any old *.xy files..." << endl << endl; sum << endl << "Now deleting any old *.xy files..." << endl << endl; sum << endl << "Sampling Rate from TEQC plot file: " << sampleRate << endl; sum << "Modified Julian Date of Start Time from TEQC plot file: " << startMJD << endl << endl; cout << endl << "Now reading the TEQC plot file..." << endl << endl; sum << endl << "Now reading the TEQC plot file..." << endl << endl; lineNum = 4; while( getline( cfplt, buf ) ) // **** loop to read two lines for each epoch { //debug cout << buf << endl; temp = buf.substr( 0, 2); // The first integer is the # of PRNs lineNum++; epochNum = epochNum + 1.0; currMJD = startMJD + (((epochNum - 1.0) * sampleRate)/86400.0); currHour = (currMJD - startDay)*24.0; itemp = atoi( temp.c_str() ); if( itemp == 0 ) { // zero means there is data for zero satellites at this epoch } else if( itemp == -1 ) // when itemp == -1, use previous list of PRNs { getline( cfplt, buf ); lineNum++; inString.clear(); inString.str( buf ); for( i = 0; i < currNumPrns; i++ ) { inString >> dtemp; if( userPRNs[currPRNs[i]] == 1 && (currMJD > userStartMJD || fabs(currMJD - userStartMJD) < 0.0000001) && (currMJD < userStopMJD || fabs(currMJD - userStopMJD) < 0.0000001) ) { outString.str(""); outString << "prn" << setw(2) << setfill('0') << currPRNs[i] << ".xy"; ofstream xy(outString.str().c_str(),ios::app); if( !xy ) { cerr << "Error! Cannot open file: " << outString.str() << endl; sum << "Error! Cannot open file: " << outString.str() << endl << "Error occured while reading PRN: " << currPRNs[i] << endl << "On line: " << buf << endl << endl; continue; } xy << fixed << showpoint << setw(15) << setprecision(10) << currHour << " " << setw(12) << setprecision(4) << dtemp << endl; xy.close(); if( dtemp > maxValue ) maxValue = dtemp; if( dtemp < minValue ) minValue = dtemp; prnHasData[ currPRNs[i] ] = true; if( currHour > maxHour ) maxHour = currHour; if( currHour < minHour ) minHour = currHour; } } } else if( itemp >= 1 ) // when itemp >= 1, read in new list of PRNs { currNumPrns = itemp; prnList.clear(); temp = buf.substr(2, buf.length()); prnList.str( temp ); for( i = 0; i < currNumPrns; i++ ) prnList >> currPRNs[i]; getline( cfplt, buf ); lineNum++; inString.clear(); inString.str( buf ); for( i = 0; i < currNumPrns; i++ ) { inString >> dtemp; if( userPRNs[currPRNs[i]] == 1 && (currMJD > userStartMJD || fabs(currMJD - userStartMJD) < 0.0000001) && (currMJD < userStopMJD || fabs(currMJD - userStopMJD) < 0.0000001) ) { outString.str(""); outString << "prn" << setw(2) << setfill('0') << currPRNs[i] << ".xy"; ofstream xy(outString.str().c_str(),ios::app); if( !xy ) { cerr << "Error! Cannot open file: " << outString.str() << endl; sum << "Error! Cannot open file: " << outString.str() << endl << "Error occured while reading PRN: " << currPRNs[i] << endl << "On line: " << buf << endl << endl; continue; } xy << fixed << showpoint << setw(15) << setprecision(10) << currHour << " " << setw(12) << setprecision(4) << dtemp << endl; xy.close(); if( dtemp > maxValue ) maxValue = dtemp; if( dtemp < minValue ) minValue = dtemp; prnHasData[ currPRNs[i] ] = true; if( currHour > maxHour ) maxHour = currHour; if( currHour < minHour ) minHour = currHour; } } } else { cerr << "Number of satellites incorrect on line number: " << lineNum << endl << buf << endl << endl; cerr << "Now terminating Program CF2PS." << endl << endl; sum << "Number of satellites incorrect on line number: " << lineNum << endl << buf << endl << endl; sum << "Now terminating Program CF2PS." << endl << endl; return -1; } } // end of while-loop over all epochs cfplt.close(); // check that the file stop time agrees with the user's start time if( userStart && (currMJD < userStartMJD) ) { sum << "Error. File Stop Time is before the User's Start Time! " << endl << "File Stop Time (MJD): " << currMJD << " User Start Time (MJD): " << userStartMJD << endl << "Terminating program." << endl << endl; cerr << "Error. File Stop Time is before the User's Start Time! " << endl << "File Stop Time (MJD): " << currMJD << " User Start Time (MJD): " << userStartMJD << endl << "Terminating program." << endl << endl; sum.close(); exit(1); } // Now create the *.ps file using GMT numGoodPRNs = 0; for( i = 0; i < MAXPRNID; i++ ) // count the number of SVs with data if( prnHasData[i] ) { numGoodPRNs++; } if( numGoodPRNs < 1 ) { cerr << "Error! No satellites left to plot !" << endl << "Now terminating Program CF2PS." << endl << endl; sum << "Error! No satellites left to plot !" << endl << "Now terminating Program CF2PS." << endl << endl; return -1; } cout << "Now creating the makePS.bat file ..." << endl << endl; sum << "Now creating the makePS.bat file ..." << endl << endl; ofstream bat("makePS.bat"); if( !bat ) { cerr << "Error! Cannot open file: " << "makePS.bat" << endl << "Now terminating Program CF2PS." << endl << endl; sum << "Error! Cannot open file: " << "makePS.bat" << endl << "Now terminating Program CF2PS." << endl << endl; return -1; } for( i = 0; i < MAXPRNID; i++ ) // find the first sv with data if( prnHasData[i] ) { firstGoodPRN = i; break; } // Create the legend.txt file cout << "Now creating the legend.txt file ..." << endl << endl; sum << "Now creating the legend.txt file ..." << endl << endl; k = 0; ofstream txt("legend.txt"); if( !txt ) { cerr << "Error! Cannot open file: " << "legend.txt" << endl << "Now terminating Program CF2PS." << endl << endl; sum << "Error! Cannot open file: " << "legend.txt" << endl << "Now terminating Program CF2PS." << endl << endl; return -1; } txt.setf( ios::fixed, ios::floatfield ); txt << "9.75 7.0 10 0 4 BL PRN SYM" << endl; for( i = 0; i < MAXPRNID; i++ ) // find the last sv with data if( prnHasData[i] ) { k++; lastGoodPRN = i; dtemp = 7.0 - (0.2 * static_cast< double >(k)); txt.setf( ios::fixed, ios::floatfield ); txt << "9.85 " << setw(3) << setprecision(1) << dtemp << " 10 0 1 BL " << setw(2) << setfill('0') << i << " " << mySymbols[i] << endl; } txt.close(); // find the tick mark interval for the X-axis (hours) outString.clear(); outString.str(""); outString << scientific << (maxHour - minHour); temp = outString.str(); temp2 = temp.substr( temp.size() - 3, 3); myExp = atof(temp2.c_str()); hourTick = pow(10.0,myExp); // sum << "span of x-axis: " << temp << " Exponent: " << temp2 // << " hour Tick spacing: " << hourTick << endl; // find the tick mark interval for the Y-axis (for the values) outString.clear(); outString.str(""); if( maxValue > 0.0 && minValue < 0.0 ) { if( fabs(maxValue) > fabs(minValue) ) outString << scientific << fabs(maxValue); else outString << scientific << fabs(minValue); } else outString << scientific << (maxValue - minValue); temp = outString.str(); temp2 = temp.substr( temp.size() - 3, 3); myExp = atof(temp2.c_str()); valueTick = pow(10.0,myExp); // sum << "span of y-axis: " << temp << " Exponent: " << temp2 // << " Y-value Tick spacing: " << valueTick << endl; bat << "gmtset DEGREE_FORMAT 4 BASEMAP_TYPE FANCY" << endl; bat << "gmtset HEADER_FONT_SIZE 16 LABEL_FONT_SIZE 12 LABEL_FONT 0 " << "ANOT_FONT_SIZE 12 ANOT_FONT 0 TICK_LENGTH -0.075i" << endl << endl; bat << "pstext legend.txt -JX11.0/8.5 -R0/11.0/0/8.5 -U -K -N -X0 -Y0 > " << psfile << endl << endl; bat << "psxy prn" << setw(2) << setfill('0') << firstGoodPRN << ".xy " << "-JX8.0/6.0 -R" << fixed << showpoint << setprecision(4) << minHour - ((maxHour - minHour)/20.0) << "/" << setprecision(4) << maxHour + ((maxHour - minHour)/20.0) << "/" << setprecision(4) << minValue - ((maxValue - minValue)/20.0) << "/" << setprecision(4) << maxValue + ((maxValue - minValue)/20.0) << " -B" << setprecision(4) << hourTick << ":\"" << xtitle << "\":/" << setprecision(4) << valueTick << "g" << setprecision(4) << valueTick << ":\"" << ytitle << "\"::.\"" << plotTitle << "\":WeSn -V -X1.5 -Y1 -O -K >> " << psfile << endl; if( numGoodPRNs == 1 ) { bat << "psxy prn" << setw(2) << setfill('0') << firstGoodPRN << ".xy " << "-JX -R -Sl0.2/" << mySymbols[ firstGoodPRN ] << " -G0/0/0 -W0.5p -O >> " << psfile << endl << endl; } else { bat << "psxy prn" << setw(2) << setfill('0') << firstGoodPRN << ".xy " << "-JX -R -Sl0.2/" << mySymbols[ firstGoodPRN ] << " -G0/0/0 -W0.5p -O -K >> " << psfile << endl << endl; } prnHasData[ firstGoodPRN ] = false; // do not plot the first PRN ever again // loop over all remaining satellites for( i = 0; i < MAXPRNID; i++ ) { if( prnHasData[i] ) { if( i == lastGoodPRN ) { bat << "psxy prn" << setw(2) << setfill('0') << i << ".xy " << "-JX -R -O -K >> " << psfile << endl; bat << "psxy prn" << setw(2) << setfill('0') << i << ".xy -JX -R " << "-Sl0.2/" << mySymbols[i] << " -G0/0/0 -W0.5p -O >> " << psfile << endl << endl; } else { bat << "psxy prn" << setw(2) << setfill('0') << i << ".xy " << "-JX -R -O -K >> " << psfile << endl; bat << "psxy prn" << setw(2) << setfill('0') << i << ".xy -JX -R " << "-Sl0.2/" << mySymbols[i] << " -G0/0/0 -W0.5p -O -K >> " << psfile << endl << endl; } } } bat.close(); cout << endl << "Now running the makePS.bat program ... " << endl << endl; sum << endl << "Now running the makePS.bat program ... " << endl << endl; // system("chmod 777 makePS.bat"); // this line needed for UNIX system("makePS.bat"); cout << endl << "Normal Termination for Program CF2PS" << endl; sum << endl << "Normal Termination for Program CF2PS" << endl; sum.close(); return 0; } //--------------------------------------------------------------------------- void writeUsageDescription( ofstream &outputStream ) { outputStream << endl << endl << "usage: cf2ps -iwbrd1560.mp1 -owbrd1560.mp1.ps " << "-p\"Station WBRD, Day-Of-Year 156\" " << "-x\"Time (hours)\" -y\"L1 Pseudorange Multipath (meters)\" " << "-b\"2002 06 05 00 00 00.0000\" -e\"2002 06 05 23 59 59.9999\" " << "-s\"02 03 05 14 18 25 30 31\" -d\"04 29\" " << endl << endl << "where option -i is followed by the input filename (required)," << endl << "-o is followed by the output filename," << endl << "-p is followed by the Plot Title," << endl << "-x is followed by the title for the X-axis," << endl << "-y is followed by the title for the Y-axis," << endl << "-b is the GPS Start Time of the plot in YMDHMS," << endl << "-e is the GPS Stop Time of the plot in YMDHMS," << endl << "-s means limit the plot to only these satellites," << endl << "-d means do not use these satellites even if they are present in the data." << endl << "(Note: Only -iInputFile is required each time the program is run." << endl << " Each and every option requires its own argument. Use double quotes" << endl << " whenever an argument contains imbedded blank spaces.)" << endl << endl << endl; } //--------------------------------------------------------------------------- void writeUsageDescriptionToScreen( ) { cout << endl << endl << "usage: cf2ps -iwbrd1560.mp1 -owbrd1560.mp1.ps " << "-p\"Station WBRD, Day-Of-Year 156\" " << "-x\"Time (hours)\" -y\"L1 Pseudorange Multipath (meters)\" " << "-b\"2002 06 05 00 00 00.0000\" -e\"2002 06 05 23 59 59.9999\" " << "-s\"02 03 05 14 18 25 30 31\" -d\"04 29\" " << endl << endl << "where option -i is followed by the input filename (required)," << endl << "-o is followed by the output filename," << endl << "-p is followed by the Plot Title," << endl << "-x is followed by the title for the X-axis," << endl << "-y is followed by the title for the Y-axis," << endl << "-b is the GPS Start Time of the plot in YMDHMS," << endl << "-e is the GPS Stop Time of the plot in YMDHMS," << endl << "-s means limit the plot to only these satellites," << endl << "-d means do not use these satellites even if they are present in the data." << endl << "(Note: Only -iInputFile is required each time the program is run." << endl << " Each and every option requires its own argument. Use double quotes" << endl << " whenever an argument contains imbedded blank spaces.)" << endl << endl << endl; } //--------------------------------------------------------------------------- /* * Modified from: * Hansen, Augie 1987, (Proficient C, Redmond, WA USA * Microsoft Press, pg 127.) */ #define ERR(s, c) if(opterr){\ cerr << endl << "Error: " << s << static_cast< char >( c ) << endl;} int getopt_sh(int argc, char* argv[], char opts[]) { static int sp= 1; int c; char *cp; if(sp == 1) if(optind >= argc || argv[optind][0] != '-' || argv[optind][1] == '\0') return(EOF); else if(strcmp(argv[optind],"--") == NULL) { optind++; return(EOF); } optopt= c= argv[optind][sp]; if(c == ':' || (cp=strchr(opts,c)) == NULL) { ERR("Illegal option found: ",c); if(argv[optind][++sp] == '\0') { optind++; sp= 1; } return('?'); } if(*++cp == ':') { if(argv[optind][sp+1] != '\0') { optarg= &argv[optind++][sp+1]; } else if(++optind >= argc) { ERR("Following option requires an argument: ", c); sp= 1; return('?'); } else optarg= argv[optind++]; sp= 1; } else { if(argv[optind][++sp] == '\0') { sp= 1; optind++; } optarg= NULL; } return(c); } /*------------------------------------------------------------------------ * ymdhms_to_mjd * * * * Input: year, month, mday, hour, minute, second * * * * Output: mjd, fmjd * * * * Author: Benjamin W. Remondi Date: November 1999 * *-----------------------------------------------------------------------*/ void ymdhms_to_mjd(long year, long month, long mday, long hour, long minute, double second, long *mjd, double *fmjd) { const long JAN11901 = 15385; const long month_day[2][12] = { {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334}, {0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335} }; long yday, leap; leap = (year%4 == 0); yday = (month_day[leap][month-1] + mday); *mjd = ((year - 1901)/4)*1461 + ((year - 1901)%4)*365 + yday - 1 + JAN11901; *fmjd = ((second/60.0 + minute)/60.0 + hour)/24.0; }