Beispiel #1
0
//-------------------------------------------------------------------------
// NavigationSyncer constructor using nav file and lev1 file to set up
//-------------------------------------------------------------------------
NavigationSyncer::NavigationSyncer(std::string navfilename, std::string lev1filename)
{
   //Set to NULL here anyway just to be safe - they should all be none-null by the end of this function
   nscans=0;
   time=NULL;
   navfile=NULL;
   hdrsync=0;
   framerate=0;
   NOSYNCINHDR=-999;
   lev1firstscanmaxexpectedsize=30; //30 seconds 

   if(navfilename.compare("NULL")!=0)
   {
      //Create a new Specim nav file object
      navfile=new SpecimFileChooser(navfilename);
      //Read in the nav file to get the time syncs
      navfile->Reader();
   }

   //Need to read in the level1 file hdr info to get nscans
   BinFile bilin(lev1filename);
   //Get the number of scan lines
   nscans=StringToUINT(bilin.FromHeader("lines"));
   DEBUGPRINT("Number of scans: "<<nscans)
   //Get the NavSync timing from the hdr
   try
   {
      hdrsync=StringToUINT(TrimWhitespace(bilin.FromHeader("NavSync Timing",1,"true")))/1000.0; 
   }
   catch(std::string e)
   {
      if(e.compare(0,bilin.MissingHeaderItemError().length(),bilin.MissingHeaderItemError())==0)
      {
         //Set to a value that means "no value in header"
         hdrsync=NOSYNCINHDR;
      }
      else
      {
         throw e;         
      }
   }

   DEBUGPRINT("Sync from header:"<<hdrsync)
   //Get the acquisition date of the data
   acquisitiondate=bilin.FromHeader("acquisition date");
   //Remove the start of the date string 
   acquisitiondate=TrimWhitespace(acquisitiondate.substr(acquisitiondate.find_first_of(':')+1));
   //Get the date format string for leap seconds
   dateformat=bilin.FromHeader("acquisition date");
   size_t startofdateformat=dateformat.find_first_of("DATE(")+5;
   size_t lengthofdateformat=dateformat.find_first_of("):")-startofdateformat;
   dateformat=dateformat.substr(startofdateformat,lengthofdateformat);

   DEBUGPRINT("Date: "<<acquisitiondate)
   //Get the start and stop times from the header to use in case no sync messages 
   //found in the specim nav file
   gpsstarttime=bilin.FromHeader("GPS Start Time");
   gpsstarttime=RemoveAllBut(gpsstarttime,"1234567890.:");
   gpsstarttime=TrimWhitespace(ReplaceAllWith(&gpsstarttime,':',' '));
   gpsstoptime=bilin.FromHeader("GPS Stop Time");
   gpsstoptime=RemoveAllBut(gpsstoptime,"1234567890.:");
   gpsstoptime=TrimWhitespace(ReplaceAllWith(&gpsstoptime,':',' '));
   
   //Get the frame rate from the hdr
   framerate=StringToDouble(bilin.FromHeader("fps"));
   DEBUGPRINT("Frame rate from header:"<<framerate)
   if((framerate <= 0)||(framerate>100000))
   {
      throw "Frame rate (fps) in hdr file seems erroneous - will only process for frame rates >0 and <100000.";
   }

   //Get the Processed_crop_start from the header file - this tells us if 
   //nav for the full line or crop of the line is required
   std::string cropstart=bilin.FromHeader("y start");
   if(cropstart.compare("")==0)
   {
      Logger::Warning("No y start found in level 1 header, if data was cropped in previous stages navigation may be wrongly synced.");
      //Set the time offset to 0
      croptimeoffset=0;
   }
   else
   {
      //Convert to a double
      croptimeoffset=StringToDouble(cropstart);
      //Get the number of dropped scans that occurred in the crop prior to y start (if y start = 0 so will this)
      std::string prevdropscans=bilin.FromHeader("dropped scans before y start");
      if(prevdropscans.compare("")==0)
      {
         Logger::Warning("No 'dropped scans before y start' found in level 1 header, if y start is non-zero navigation may be wrongly synced.");
         //Set the time offset to 0
         prevdropscans="0";
      }
      double previousdroppedscans=StringToDouble(prevdropscans);
      //Convert the sum of the frames (cropstart and prevdropscans) to a time offset to add onto start time
      croptimeoffset=(croptimeoffset + previousdroppedscans)/framerate;
      Logger::Log("Using cropped level-1 data - will add a time offset relating to number of lines cropped (y start + dropped scans values in hdr): "+ToString(croptimeoffset));
   }

   //Close the level 1 file
   bilin.Close();

   //Create the scan time array
   time=new double[nscans];

   //Get the number of leap seconds for the data
   LeapSecond leap;
   leapseconds=leap.GetLeapSeconds(acquisitiondate,dateformat);
   DEBUGPRINT("Using leap seconds of:"<<leapseconds);
}
Beispiel #2
0
double interg(double xlat, double xlon, 
            GRID_HEADER  vec_hdr[50], FILE* vec_ifp[50], int kk) {
/*******************************************************************************
* Interpolates a value  from the kk-th numbered geoid model grid. 
* As the gridded data are all direct-access files,
* only the nearest points (1 thru 9,
* depending on the point's location relative to corners and edges)
* are read into RAM for each point's interpolation.
*
* The size/spacing/etc of the data file's grid
* are defined by the common statement, and the variable kk. 
* Caveats: 
*   1) It is assumed that xlat/xlon fall in the region of the kth grid
*   in - xlat    : latitude  position, decimal degrees, North
*   in - xlon    : longitude position, decimal degrees, West
*   in - vec_hdr : vector of header records, as read from grid files
*   in - vec_ifp : vector of input files, pointing to grid files
*   in - kk      : number (0 offset) of grid file to use
*   out- val     : the interpolated value
*   ret-         : the interpolated value
* 
*******************************************************************************/
    FILE*  infile;
    BUFFER buffer;  // alias for type (*void) for binary grid read

    // Grid header elements for file kk
    double  latMin;
    double  lonMin;
    double  latDelta;
    double  lonDelta;
    long    latRowNum;
    long    lonColNum;
    long    iKind;
    double  latMax;                    // calcd from header data
    double  lonMax;                    // calcd from header data
    double  val;                       // return value

    long   irec;    // binary data file element
    // double xx;
    // double yy;
    double row_counter;
    double col_counter;
    int    irown;
    int    icoln;
    double irown_lat;
    double icoln_lon;
    float  f1;


    // Define some necessary parameters
    // These header data elements are read in the main driver file,
    // are in a common block, and are already checked for endian condition
    latMin    = vec_hdr[kk].lat_min;
    lonMin    = vec_hdr[kk].lon_min;
    latDelta  = vec_hdr[kk].lat_delta;
    lonDelta  = vec_hdr[kk].lon_delta;
    latRowNum = vec_hdr[kk].lat_num;
    lonColNum = vec_hdr[kk].lon_num;
    iKind     = vec_hdr[kk].ikind;
    latMax    = latMin + latDelta * (latRowNum - 1);
    lonMax    = lonMin + lonDelta * (lonColNum - 1);

    infile = vec_ifp[kk];

    // -----------------------------------------------------
    // A little check for safety's sake
    // Verify point is within grid file bounds
    // -----------------------------------------------------
    if (xlat < latMin) {
        fprintf(stderr, "Error: Latitude below minimum bound\n");
        fprintf(stderr, "       Lat = %lf   latMin = %lf\n", xlat, latMin);
        abort();
    }
    if (xlat > (latMin + latDelta * latRowNum) ) {
        fprintf(stderr, "Error: Latitude above maximum bound");
        fprintf(stderr, "       Lat = %lf   latMax = %lf\n", xlat, latMax);
        abort();
    }
    if (xlon < lonMin) {
        fprintf(stderr, "Error: Longitude below minimum bound");
        fprintf(stderr, "       Lon = %lf   lonMin = %lf\n", xlon, lonMin);
        abort();
    }
    if (xlon > (lonMin + lonDelta * lonColNum) ) {
        fprintf(stderr,"Error: Longitude above maximum bound");
        fprintf(stderr, "       Lon = %lf   lonMax = %lf\n", xlon, lonMax);
        abort();
    }


    // --------------------------------------------------------------------
    // Find the row/col of the nearest grid node to the lat/lon point
    // This grid node is southwest from the lat/lon point
    // (row_counter,col_counter) = exact (lat,lon) grid coord location (float)
    // (irown,icoln)             = reference node (to sw) grid coord loc'n (int)
    // --------------------------------------------------------------------
    row_counter = ((xlat-latMin) / latDelta);    // +1 =fortran index corr'n
    col_counter = ((xlon-lonMin) / lonDelta);    // +1 =fortran index corr'n

    irown = (int)floor(row_counter); // reference row, just south from latdd
    icoln = (int)floor(col_counter); // reference col, just west  from londd

    // Find the latitude and longitude of the nearest grid point
    irown_lat = latMin + latDelta*(irown);   // lat just south(up)  from latdd
    icoln_lon = lonMin + lonDelta*(icoln);   // lon just west(left) from londd

    // Find the latitude and longitude of the reference node
    // not needed to find value at a node 
    // yy = (row_counter - row) + 2.0;      //  2 := 4x4 spline window
    // xx = (col_counter - col) + 2.0;


    // -----------------------------------------------------
    // First things first -- 
    // If we're sitting right on or near (0.36 arcsec)
    // a grid node, just assign the value and return
    //   (1.0e-4 * 3600) = 0.36 arcsec
    // 
    //      read(lin(kk),rec=irec)f1
    //      // read big endian values and convert to little endian
    //      if(reverse_bytes(kk)) f1=frev4(f1)
    //      val = f1
    //      return
    // -----------------------------------------------------
    if(fabs(xlat - irown_lat) <= 1.0e-4 
    && fabs(xlon - icoln_lon) <= 1.0e-4) {

        // linear array matrix math: 
        //   44L               gets past the header
        //   irown*lonColNum   gets to the row
        //   icoln             gets the data from the specific column

        irec = 44L + (long)(4*( (irown)*lonColNum + (icoln) ));

        fseek(infile, irec, SEEK_SET);
        fread((char*)&buffer, (sizeof(float)), 1, infile);
        f1 = buffer.ff;

        // Check endian condition
        if (iKind != 1) {
            f1 = flip_endian_f( f1 );
        }
        return( f1 );
    }


    // -----------------------------------------------------
    // Not on a node, so interpolate
    //   1) 6x6 spline grid
    //   2) 4x4 spline grid
    //   3) bilinear
    // -----------------------------------------------------

    if( irown >= 3  &&  irown < (latRowNum - 2) 
    &&  icoln >= 3  &&  icoln < (lonColNum - 2) ) {
        val = spline6(xlat, xlon, vec_ifp, vec_hdr, kk);
    }
    else
    if( irown >= 2  &&  irown < (latRowNum - 1) 
    &&  icoln >= 2  &&  icoln < (lonColNum - 1) ) {
        val = spline4(xlat, xlon, vec_ifp, vec_hdr, kk);
    }
    else {
        val = bilin(  xlat, xlon, vec_ifp, vec_hdr, kk);
    }

    return( val );

}//~interg