Example #1
0
int main(int argc, char* argv[])
{
try
{
   // if no options are given on command line, print syntax and quit
  if (argc < 2 || string(argv[1]) == "-h" || string(argv[1]) == "--help")
   {
      cout << "Program CalcDOPs reads an FIC, FICA or a Rinex Nav file" << endl
           << "Usage:  CalcDOPs -i  <inputfile>     input file for day to be calculated (required)" << endl
           << "                 -p  <inputfile>     input file for previous day (optional, ephemeris mode only)" << endl
           << "                 -o  <outputfile>    grid  output file [DOPs.out]" << endl
           << "                 -sf <outputfile>    stats output file [DOPs.stat]" << endl
           << "                 -tf <outputfile>    time steps output file [DOPs.times]" << endl
           << "                 -l  <outputfile>    log   output file [DOPs.log]" << endl
           << "                 -rs                 read from stats file" << endl
           << "                 -a                  work in almanac mode [ephemeris mode is default]" << endl
           << "                 -w <week> -s <sow>  starting time tag" << endl
           << "                 -x <prn>            exclude satellite PRN" << endl
           << "                 -t <dt>             time spacing" << endl
           << "                 -na                 do North America only" << endl
           << "                 -d                  dump grid results at each time step (time-intensive)" << endl
           << "                 -h, --help          output options info and exit" << endl
           << "                 -v                  print version info and exit" << endl
           << endl;
      return 0;
   }

  int i, j, ii;

   // parse command line
   i = 1;
   while (i < argc)
   {
          if (string(argv[i]) == "-i" ) inputfile = string(argv[++i]);
     else if (string(argv[i]) == "-p" ) previnputfile = string(argv[++i]);
     else if (string(argv[i]) == "-o" ) outputfile = string(argv[++i]);
     else if (string(argv[i]) == "-l" ) logfile = string(argv[++i]);
     else if (string(argv[i]) == "-tf") timesfile = string(argv[++i]);
     else if (string(argv[i]) == "-a" ) ephmode = false;
     else if (string(argv[i]) == "-w" ) week = atoi(argv[++i]);
     else if (string(argv[i]) == "-s" ) sow = atof(argv[++i]);
     else if (string(argv[i]) == "-x" ) ExPRN.push_back(atoi(argv[++i]));
     else if (string(argv[i]) == "-t" ) dt = atof(argv[++i]);
     else if (string(argv[i]) == "-sf") statsfile = string(argv[++i]);
     else if (string(argv[i]) == "-rs") readStats = true;
     else if (string(argv[i]) == "-na") NAonly = true;
     else if (string(argv[i]) == "-d" ) dumpeach = true;
     else if (string(argv[i]) == "-v" )
     {
       cout << "CalcDOPs version " << fixed << setprecision(1) << setw(3) << version << endl;
       return 0;
     }
     else cout << "Unrecognized option: " << argv[i] << endl;
     i++;
   }

   lofs.open(logfile.c_str(),ios_base::out);
   if (!lofs) return -8;

   tofs.open(timesfile.c_str(),ios_base::out);
   if (!tofs) return -8;

   // reassurance print
   lofs << "Program visible with:" << endl << "current-day input file " << inputfile << endl;
   if ( previnputfile != "" ) lofs << "and previous-day input file " << previnputfile << endl;
   lofs << "and output file " << outputfile << endl;
   if (week > 0) lofs << " Input time tag: " << week << " " << sow << endl;
   if (ExPRN.size() > 0)
   {
      lofs << " Exclude satellite PRNs";
      for(i=0; i<ExPRN.size(); i++) lofs << " " << ExPRN[i];
      lofs << "." << endl;
   }

   // compute the number of time steps from the time spacing
   nt = int(86400.0/dt); // 86400 = 60*60*24 = sec/day

   // open and read the previous day's input data file first, if specified and in Eph mode
   if ( previnputfile != "" && ephmode )
   {
     lofs << "Reading in previous-day input file..." << endl;
     i = ReadDataFile(previnputfile);
     if (i)
     {
       if (i == -1) lofs << "Previous-day input file does not exist. Abort." << endl;
       if (i == -2) lofs << "Cannot identify previous-day file type. Abort." << endl;
       return i;
     }
   }

   // open and read the current day's input data file
   lofs << "Reading in current-day input file..." << endl;
   i = ReadDataFile(inputfile);
   if (i)
   {
     if (i == -1) lofs << "Current-day input file does not exist. Abort." << endl;
     if (i == -2) lofs << "Cannot identify current-day file type. Abort." << endl;
     return i;
   }

   // build the spatial grid, and store it in vector<GridData> Grid;
   BuildGrid();

   // get a list of the available satellite PRNs and the initial timetag
   bool ok;
   DayTime tt, starttime;
   bool initialTimeSet = false;
   if ( ephmode ) // ephemeris mode
   {
     try
     {
       DayTime earliest = ges.getInitialTime();
       DayTime latest = ges.getFinalTime();
//       DayTime start = latest - gpstk::DayTime::SEC_DAY/2; /* make sure you're in the right day */
       DayTime start = latest - 6*3600.0; /* go back 6 h: covers any 4 h ephemeris going into the next day */
       tt = DayTime( start.year(), start.month(), start.day(), 0, 0, 0.0 );
       starttime = tt;
       lofs << " Initial time tag is " << tt.printf("%4F %8.1g") << endl;
       initialTimeSet = true;
     }
     catch(InvalidRequest)
     {
       i = -100;
       lofs << "Initial Time or Final Time missing. Abort." << endl;
       return i;
     }
     for (i=1; i<33; i++)
     {
       for (ok=true,j=0; j<ExPRN.size(); j++)
       {
         if (ExPRN[j] == i) { ok=false; break; }
       }
       if (!ok) continue;                     // skip this satellite
       Sats.push_back(i);                     // save this satellite
     }
   }
   else           // almanac mode (original version)
   {
     DayTime start(DayTime::BEGINNING_OF_TIME); // Declare and initialize to something guaranteed to be early.
     for (i=1; i<33; i++) // # of SVs hard-wired to 32
     {
       if (aomap.find(i) == aomap.end()) continue; // satellite not found in almanac
       for (ok=true,j=0; j<ExPRN.size(); j++)
       {
         if (ExPRN[j] == i) { ok=false; break; }
       }
       if (!ok) continue;                     // skip this satellite if not ok

       Sats.push_back(i);                     // save this satellite otherwise

       // store latest transmit time tag of the set.
       if (aomap[i].getTransmitTime()>start) start = aomap[i].getTransmitTime();
     }
     // Set starting time to beginning of day in which majority of almanac was collected.
     tt = DayTime( start.year(), start.month(), start.day(), 0, 0, 0.0 );
     starttime = tt;
     lofs << " Initial time tag is " << tt.printf("%4F %8.1g") << endl;
     initialTimeSet = true;
   }
   if (Sats.size() < 4)
   {
     lofs << "Fewer than 4 satellite almanacs are available - abort." << endl;
     return -3;
   }

   // allocate Stats objects for each grid point's DOPs
   GGridStats = new Stats<double>[Grid.size()];    
   PGridStats = new Stats<double>[Grid.size()];
   HGridStats = new Stats<double>[Grid.size()];
   VGridStats = new Stats<double>[Grid.size()];
   TGridStats = new Stats<double>[Grid.size()];
   NGridStats = new Stats<double>[Grid.size()];
   BadPDOP = (double*)calloc(Grid.size(),sizeof(double));
   if (!GGridStats || !PGridStats || !HGridStats ||
       !VGridStats || !TGridStats || !NGridStats   )
   {
      lofs << "Failed to allocate GridStats" << endl;
      return -4;
   }

   // initialize storage of 'worsts' and 'peaks'
   IworstN = IworstG = IworstP = IworstH = IworstV = IworstT = -1; // indexes of worst Number and worst DOPs
   NtrofN  = NpeakG  = NpeakP  = NpeakH  = NpeakV  = NpeakT  =  0; // number of cells with DOP > 10, # with < 5 sats

   // if reading a stats file (-rs), initialize stats using data from a file
   if (readStats)
   {
      i = ReadStatsFile(statsfile);
      if (i)
      {
         lofs << "Could not open stats file for input. Abort." << endl;
         return i;
      }
   }

   // compute away
   dlon = 360.0/double(MaxNLon);

   for (j=0; j<nt; j++)             // LOOP OVER TIMES
   {
      SVs.clear();                  // clear SV position array

      for (i=0; i<Sats.size(); i++) // LOOP OVER SVs -- get positions at each time step
      {
        if (ephmode)  // ephemeris mode
        {
          SatID sid(Sats[i],SatID::systemGPS);
          try
          {
            if (ges.getSatHealth(sid,tt)!=0) continue;
            SVPVT = ges.getXvt(sid,tt);
          }
          catch(InvalidRequest& e)
          {
            continue;
          }
          SV.setECEF(SVPVT.x[0],SVPVT.x[1],SVPVT.x[2]); // get SV position
          SVs.push_back(SV);                            // add to the vector
        }
        else          // almanac mode
        {
          SVPVT = aomap[Sats[i]].svXvt(tt);
          SV.setECEF(SVPVT.x[0],SVPVT.x[1],SVPVT.x[2]); // get SV position
          SVs.push_back(SV);                            // add to the vector
        }
      }

      // zero worst-site DOPs (worst #SVs to large #) for this time step

      StepWorstG = StepWorstP = StepWorstH = StepWorstV = StepWorstT = 0.;
      StepWorstN = 10000.;

      for (i=0; i<Grid.size(); i++) // LOOP OVER GRID POSITIONS
      {
        if ( j == 0 ) // set up grid position vector only on first time step
        {
          // transform XYZT to UENT: R*Vector(XYZT) = Vector(UENT)
          double ca,sa,co,so;
          Position Rx(Grid[i].lat,Grid[i].lon,0.0,Position::Geodetic); // grid position
          ca = cos(Rx.geodeticLatitude()*DEG_TO_RAD);
          sa = sin(Rx.geodeticLatitude()*DEG_TO_RAD);
          co = cos(Rx.longitude()*DEG_TO_RAD);
          so = sin(Rx.longitude()*DEG_TO_RAD);
          M4 Rtemp;
          Rtemp(0,0) = ca*co ; Rtemp(0,1) = ca*so ; Rtemp(0,2) = sa ; Rtemp(0,3) = 0.0;
          Rtemp(1,0) = -so   ; Rtemp(1,1) = co    ; Rtemp(1,2) = 0.0; Rtemp(1,3) = 0.0;
          Rtemp(2,0) = -sa*co; Rtemp(2,1) = -sa*so; Rtemp(2,2) = ca ; Rtemp(2,3) = 0.0;
          Rtemp(3,0) = 0.0   ; Rtemp(3,1) = 0.0   ; Rtemp(3,2) = 0.0; Rtemp(3,3) = 1.0;
          Rmat.push_back(Rtemp); // add this grid point's R matrix to the stack
        }

        ComputeDOPs(tt,Grid[i],SVs,Rmat[i]); // compute DOPs

        BadPDOP[i] = BadPDOP[i] + Grid[i].bdop; // adds up each grid pt.'s BDOP over all times
                                                // BDOP for a single pt. is 0 or 1 for PDOP <= v. > 6

        // add to stats -- each GridStats object ends up holding all times for a grid point

        GGridStats[i].Add(Grid[i].gdop);
        PGridStats[i].Add(Grid[i].pdop);
        HGridStats[i].Add(Grid[i].hdop);
        VGridStats[i].Add(Grid[i].vdop);
        TGridStats[i].Add(Grid[i].tdop);
        NGridStats[i].Add(Grid[i].nsvs);

        // save the worst and the peaks

        if (Grid[i].gdop > StepWorstG)
        {
          StepWorstG = Grid[i].gdop;
        }

        if (Grid[i].pdop > StepWorstP)
        {
          StepWorstP = Grid[i].pdop;
        }

        if (Grid[i].hdop > StepWorstH)
        {
          StepWorstH = Grid[i].hdop;
        }

        if (Grid[i].vdop > StepWorstV)
        {
          StepWorstV = Grid[i].vdop;
        }

        if (Grid[i].tdop > StepWorstT)
        {
          StepWorstT = Grid[i].tdop;
        }

        if (Grid[i].nsvs < StepWorstN)
        {
          StepWorstN = Grid[i].nsvs;
        }

        if (IworstG == -1 || Grid[i].gdop > WorstG)
        {
          IworstG = i;
          WorstG  = Grid[i].gdop;
          TworstG = tt;
        }

        if (IworstP == -1 || Grid[i].pdop > WorstP)
        {
          IworstP = i;
          WorstP  = Grid[i].pdop;
          TworstP = tt;
        }

        if (IworstH == -1 || Grid[i].hdop > WorstH)
        {
          IworstH = i;
          WorstH  = Grid[i].hdop;
          TworstH = tt;
        }

        if (IworstV == -1 || Grid[i].vdop > WorstV)
        {
          IworstV = i;
          WorstV  = Grid[i].vdop;
          TworstV = tt;
        }

        if (IworstT == -1 || Grid[i].tdop > WorstT)
        {
          IworstT = i;
          WorstT  = Grid[i].tdop;
          TworstT = tt;
        }

        if (IworstN == -1 || Grid[i].nsvs < WorstN)
        {
          IworstN = i;
          WorstN  = Grid[i].nsvs;
          TworstN = tt;
        }

        if (Grid[i].nsvs < 5) NtrofN++;

        if (Grid[i].pdop > 10.)
        {
          NpeakP++;
          lofs << "PDS " << NpeakP
               << " " << setw(4) << j+1              // time
               << fixed << setprecision(2)
               << " " << setw(7) << Grid[i].lon
               << " " << setw(7) << Grid[i].lat
               << endl;
        }

        if (Grid[i].hdop > 10.)
        {
          NpeakH++;
          lofs << "HDS " << NpeakH
               << " " << setw(4) << j+1              // time
               << fixed << setprecision(2)
               << " " << setw(7) << Grid[i].lon
               << " " << setw(7) << Grid[i].lat
               << endl;
        }

      } // end loop over grid

      // write timestep results to timesfile

      tofs << " "
           << tt.printf("%4F %8.1g") << "  "
           << " " << setw(7) << StepWorstG
           << " " << setw(7) << StepWorstP
           << " " << setw(7) << StepWorstH
           << " " << setw(7) << StepWorstV
           << " " << setw(7) << StepWorstT
           << " " << setw(6) << StepWorstN
           << endl;

      // dump grid results to file for each time step if enabled

      if (dumpeach)
      {
        stringstream ss;
        ss << j;
        dumpfile = outputfile + ".t-" + ss.str();
        cout << dumpfile << endl;
        ii = DumpGrid(tt, dumpfile);
        if (ii)
        {
          lofs << "Could not dump grid file for writing. Abort." << endl;
          return i;
        }
      }

      // record worst-site DOPs at each time step

      WGTimeStats.push_back(StepWorstG);
      WPTimeStats.push_back(StepWorstP);
      WHTimeStats.push_back(StepWorstH);
      WVTimeStats.push_back(StepWorstV);
      WTTimeStats.push_back(StepWorstT);
      WNTimeStats.push_back(StepWorstN);

      tt += dt;      // increment time tag
   } // end loop over times

   // get day's average of worst-site (grid) DOPs

   for (i=0; i<nt; i++)
   {
     AvgWorstSiteDOP.wgdop += WGTimeStats[i];
     AvgWorstSiteDOP.wpdop += WPTimeStats[i];
     AvgWorstSiteDOP.whdop += WHTimeStats[i];
     AvgWorstSiteDOP.wvdop += WVTimeStats[i];
     AvgWorstSiteDOP.wtdop += WTTimeStats[i];
     AvgWorstSiteDOP.wnsvs += WNTimeStats[i];
   }
   AvgWorstSiteDOP.wgdop /= nt;
   AvgWorstSiteDOP.wpdop /= nt;
   AvgWorstSiteDOP.whdop /= nt;
   AvgWorstSiteDOP.wvdop /= nt;
   AvgWorstSiteDOP.wtdop /= nt;
   AvgWorstSiteDOP.wnsvs /= nt;

   // output the grid itself and the stats - for use later

   i = OutputGrid(outputfile); // output average and worst-site DOP results over the grid
   if (i)
   {
      lofs << "Could not output file for writing. Abort." << endl;
      return i;
   }

   i = WriteStatsFile(statsfile);
   if (i)
   {
      lofs << "Could not open stats file for output. Abort." << endl;
      return i;
   }

   // clean up

   delete[] GGridStats;
   delete[] PGridStats;
   delete[] HGridStats;
   delete[] VGridStats;
   delete[] TGridStats;
   delete[] NGridStats;

   lofs.close();
}
catch(Exception& e) {
   lofs << "Caught an exception" << endl << e << endl;
}
   return 0;
}