Beispiel #1
0
int read_hdrfile(char *infile)
{
  SEASAT_header_ext *hdr;
  FILE *fp = fopen(infile,"r");
  
  int val, i, end_line;
  double dtmp, t, t1;
  
  int clock_drift_hist[MAX_CLOCK_DRIFT];
  int clock_drift_median;
  double clock_shift;
  
  if (fp==NULL) {printf("ERROR: can't open %s header file\n",infile); return(1); }
  hdr = (SEASAT_header_ext *) malloc(sizeof(SEASAT_header_ext));

  for (i=0; i<start_line; i++) {
    val = get_values(fp, hdr);
    if (val!=20) {printf("ERROR: unable to read to specified start line in header file\n"); exit(1);}
  }

  station_code = hdr->station_code;

  start_year = 1970 + hdr->lsd_year;
  start_date = hdr->day_of_year;
  start_sec  = (double) hdr->msec / 1000.0;
  
  s_date.year = 1970 + hdr->lsd_year;
  s_date.jd   = hdr->day_of_year;
  dtmp = (double) hdr->msec / 1000.0;
  date_sec2hms(dtmp,&s_time);

  if (USE_CLOCK_DRIFT==1) {
    for (i=0; i<MAX_CLOCK_DRIFT; i++) clock_drift_hist[i] = 0;
    end_line = start_line + npatches*patch_size;
    for (i = start_line; i<end_line; i++) {
      val = get_values(fp, hdr);
      if (val!=20) {printf("ERROR: unable to read to specified end line in header file\n"); exit(1);}
      clock_drift_hist[hdr->clock_drift]++;
    }
    
    printf("APPLYING CLOCK DRIFT TO IMAGE TIMING.\n");
    clock_drift_median = get_median(clock_drift_hist,MAX_CLOCK_DRIFT);
    printf("\tclock_drift_median     = %li \n",clock_drift_median);
    
    clock_shift = (double) clock_drift_median / 1000.0;
    start_sec += clock_shift;
    if (start_sec > 86400.0) {start_sec -= 86400.0; start_date += 1;}

    dtmp = date_hms2sec(&s_time)+clock_shift;
    if (dtmp > 86400.0) { s_date.jd+=1; dtmp-=86400.0;}
    date_sec2hms(dtmp,&s_time);
  }

  printf("Found start time: %i %i %lf\n",start_year, start_date, start_sec);
  fclose(fp);

}
/***************************************************************
 * Get_timeDelta:
 * Return the time difference, in seconds, between the start
 * of the state vectors (in the PPDR) and the start of the image
 * (as described in the DSSR).  Write this time to the given
 * meta_parameters->state_vectors structure.*/
double get_timeDelta(ceos_description *ceos,struct pos_data_rec *ppdr,meta_parameters *meta)
{
    ymd_date imgDate;
    julian_date imgJD,stJD;
    hms_time imgTime,stTime;
    double imgSec,stSec;/*Seconds since 1900 for start of image and start of state vectors*/

/*Read time of *start* of state vectors*/
    stJD.year = (int) ppdr->year;
    stJD.jd = (int) ppdr->gmt_day;
    date_sec2hms(ppdr->gmt_sec,&stTime);
    stSec=date2sec(&stJD,&stTime);

/*Compute the *scene* start time from the CEOS DSSR: */
    /* begin with scene center time */
    if (ceos->facility == BEIJING)
      date_dssr2time(ceos->dssr.inp_sctim,&imgDate,&imgTime);
    else
      date_dssr2date(ceos->dssr.inp_sctim,&imgDate,&imgTime);
    date_ymd2jd(&imgDate,&imgJD);
    imgSec=date2sec(&imgJD,&imgTime);

    if (ceos->processor==FOCUS && ceos->product==CCSD) {
        /* do nothing-- dssr "inp_sctim" already gives scene start time */
    }
    else if (0!=strcmp(ceos->dssr.az_time_first,""))
    { /* e.g., ESA data.  "az_time_first" field gives start of image */
        date_dssr2time(ceos->dssr.az_time_first,&imgDate,&imgTime);
        imgSec=date2sec(&imgJD,&imgTime);
    }
    else if (ceos->facility==EOC)
    {
        imgSec-=ceos->dssr.sc_lin*fabs(meta->sar->azimuth_time_per_pixel);
    }
    else {/*Convert scene center time to scene *start* time, by
       subtracting off the center line # * the time/line */
        imgSec-=ceos->dssr.sc_lin*fabs(meta->sar->azimuth_time_per_pixel);
    }
    /*
    // Complex ALOS data have an additional 1 sec shift
    // Still under investigation: Need word from DQ on this
    if (ceos->facility==EOC && ceos->product==SLC)
      imgSec -= 1.0;
    */

    /*Convert scene center # of seconds back to date/time*/
    sec2date(imgSec,&imgJD,&imgTime);

/*Write image time to meta->state_vectors structure*/
    meta->state_vectors->year   = (int) imgJD.year;
    meta->state_vectors->julDay = (int) imgJD.jd;
    meta->state_vectors->second = date_hms2sec(&imgTime);

/*Return the time between state vector start and image start*/
    return stSec-imgSec;
}
Beispiel #3
0
/*Compute the date corresponding to this number of seconds
since midnight, Jan 1, 1900.
This is sub-millisecond accurate; but ignores leap seconds.
*/
void sec2date(double secs,julian_date *date,hms_time *time)
{
    int year=1900;
    while (secs>=date_getDaysInYear(year)*DAY2SEC)
        secs-=date_getDaysInYear(year++)*DAY2SEC;
    date->year=year;
    date->jd=1+(int)(secs/DAY2SEC);
    secs-=(date->jd-1)*DAY2SEC;
    date_sec2hms(secs,time);
}
Beispiel #4
0
// Compute date corresponding to seconds since midnight, Jan 1, 1985.
void seconds2date(double seconds, ymd_date *date, hms_time *time)
{
  julian_date jd;
  int year = 1985;
  double secs = seconds;
  while (secs >= date_getDaysInYear(year)*DAY2SEC)
    secs -= date_getDaysInYear(year++)*DAY2SEC;
  jd.year = year;
  jd.jd = 1 + (int)(secs/DAY2SEC);
  secs -= (jd.jd - 1)*DAY2SEC;
  date_sec2hms(secs, time);
  date_jd2ymd(&jd, date);
}
static void rgps2iso_date(int year, double day, char *isoStr)
{
  julian_date jd;
  hms_time time;
  ymd_date date;
  
  jd.year = year;
  jd.jd = (int) day;
  date_jd2ymd(&jd, &date);
  double sec = 86400 * (day - jd.jd);
  date_sec2hms(sec, &time);
  sprintf(isoStr, "%4d-%02d-%02dT%02d:%02d:%09.6lfZ",
        date.year, date.month, date.day, time.hour, time.min, time.sec);
}
Beispiel #6
0
static void dateTimeStamp(meta_parameters *meta, int line, 
			  iso_dateTime *dateTime)
{
  julian_date jd;
  hms_time hms;
  ymd_date ymd;
  jd.year = meta->state_vectors->year;
  jd.jd = meta->state_vectors->julDay;
  date_sec2hms(meta->state_vectors->second, &hms);
  date_jd2ymd(&jd, &ymd);
  double imgSec = line*meta->sar->azimuth_time_per_pixel;
  add_time(imgSec, &ymd, &hms);
  dateTime->year = ymd.year;
  dateTime->month = ymd.month;
  dateTime->day = ymd.day;
  dateTime->hour = hms.hour;
  dateTime->min = hms.min;
  dateTime->second = hms.sec;
}
Beispiel #7
0
/*******************************************************
 * meta_get_dop:
 * Converts a line, sample pair to the doppler value at
 * that location. Returns Hz. Only works for SR & GR. */
double meta_get_dop(meta_parameters *meta,double yLine, double xSample)
{
  assert (meta->sar); // && (meta->sar->image_type == 'S'
         //   || meta->sar->image_type == 'G'));

  yLine += meta->general->start_line;
  xSample += meta->general->start_sample;
  
  if (meta->doppler && meta->doppler->tsx) {
    int ii;
    julian_date imgStartDate, imgDopplerDate;
    hms_time imgStartTime, imgDopplerTime;
    double time, refTime, *coeff;
    imgStartDate.year = meta->state_vectors->year;
    imgStartDate.jd = meta->state_vectors->julDay;
    date_sec2hms(meta->state_vectors->second, &imgStartTime);
    imgDopplerDate.year = meta->doppler->tsx->year;
    imgDopplerDate.jd = meta->doppler->tsx->julDay;
    date_sec2hms(meta->doppler->tsx->second, &imgDopplerTime);
    double imgAzimuthTime = date2sec(&imgStartDate, &imgStartTime) +
      yLine * meta->sar->range_time_per_pixel;
    double dopAzimuthStart = date2sec(&imgDopplerDate, &imgDopplerTime);
    for (ii=0; ii<meta->doppler->tsx->doppler_count; ii++) {
      time = dopAzimuthStart + meta->doppler->tsx->dop[ii].time;
      if (time > imgAzimuthTime)
	break;
    }
    int max = ii;
    int min = ii - 1;
    double dopAzimuthMin = dopAzimuthStart + meta->doppler->tsx->dop[min].time;
    double dopRangeTimeMin = meta->doppler->tsx->dop[min].first_range_time + 
      xSample * meta->sar->azimuth_time_per_pixel;
    refTime = meta->doppler->tsx->dop[min].reference_time;
    coeff = (double *) MALLOC(sizeof(double)*
			      meta->doppler->tsx->dop[min].poly_degree);
    double dopplerMin = 0.0;
    for (ii=0; ii<=meta->doppler->tsx->dop[min].poly_degree; ii++) {
      coeff[ii] = meta->doppler->tsx->dop[min].coefficient[ii];
      dopplerMin += coeff[ii] * pow(dopRangeTimeMin - refTime, ii);
    }
    FREE(coeff);
    double dopAzimuthMax = dopAzimuthStart + meta->doppler->tsx->dop[max].time;
    refTime = meta->doppler->tsx->dop[min].reference_time;
    coeff = (double *) MALLOC(sizeof(double)*
			      meta->doppler->tsx->dop[max].poly_degree);
    double dopplerMax = 0.0;
    for (ii=0; ii<=meta->doppler->tsx->dop[max].poly_degree; ii++) {
      coeff[ii] = meta->doppler->tsx->dop[max].coefficient[ii];
      dopplerMax += coeff[ii] * pow(dopRangeTimeMin - refTime, ii);
    }
    FREE(coeff);
    return dopplerMin + (dopplerMax - dopplerMin) / 
      (dopAzimuthMax - dopAzimuthMin) * (imgAzimuthTime - dopAzimuthMin);
  }
  else if (meta->doppler && meta->doppler->r2) {
    int ii;
    double doppler = 0.0;
    radarsat2_doppler_params *r2 = meta->doppler->r2;
    double slant_time = 
      r2->time_first_sample + xSample * meta->sar->range_time_per_pixel;
    for (ii=0; ii<r2->doppler_count; ++ii)
      doppler += 
	r2->centroid[ii] * pow((slant_time - r2->ref_time_centroid), ii);

    return doppler;
  }
  else
    return meta->sar->range_doppler_coefficients[0]+
      meta->sar->range_doppler_coefficients[1]*xSample+
      meta->sar->range_doppler_coefficients[2]*xSample*xSample+
      meta->sar->azimuth_doppler_coefficients[1]*yLine+
      meta->sar->azimuth_doppler_coefficients[2]*yLine*yLine;
}
Beispiel #8
0
meta_parameters* airsar2meta(airsar_header *header,
			     airsar_param_header *params,
			     airsar_dem_header *dem)
{
  meta_parameters *meta;
  hms_time hms;

  // Allocate memory for metadata structure
  meta = raw_init();

  // General block
  sprintf(meta->general->basename, "%s", params->site_name);
  sprintf(meta->general->sensor, "AIRSAR");
  strcpy(meta->general->sensor_name, "SAR");
  if (strlen(header->processor)>0) {
    header->processor[4] = '\0';
    strcpy(meta->general->processor, "JPL version ");
    strcat(meta->general->processor, header->processor);
  } else {
    strcpy(meta->general->processor, MAGIC_UNSET_STRING);
  }
  // FIXME: various data types - InSAR vs. polarimetric
  date_sec2hms(params->acquisition_seconds, &hms);
  sprintf(meta->general->acquisition_date, "%s %d:%d:%.3lf",
      params->acquisition_date, hms.hour, hms.min, hms.sec);
  meta->general->orbit = params->cct_id; // close enough
  // no frame number
  // FIXME: decide how to separate interferometric/polarimetric data
  meta->general->band_count = 1;
  meta->general->line_count = header->line_count;
    //header->line_count - header->first_data_offset / header->sample_count;
  meta->general->sample_count = header->sample_count;
  meta->general->start_line = 0;
  meta->general->start_sample = 0;
  meta->general->x_pixel_size = header->x_pixel_size;
  meta->general->y_pixel_size = header->y_pixel_size;
  meta->general->center_latitude = params->center_lat;
  meta->general->center_longitude = params->center_lon;
  meta->general->re_major = 6378137.0; // WGS84
  meta->general->re_minor = 6356752.314; // WGS84
  // no information on bit error rate, missing lines and no data

  // SAR block
  meta->sar = meta_sar_init();
  // The CCT type 'CM' stands for 'Compressed Stokes Matrix' which implies
  // that you have fully polarimetric data
  if (strncmp_case(params->cct_type, "CM", 2) == 0) {
    meta->general->image_data_type = POLARIMETRIC_IMAGE;
    meta->general->radiometry = r_SIGMA;
    strcpy(meta->sar->polarization, "QUAD-POL");
    meta->general->band_count = 8;
  }
  if (strncmp_case(header->range_projection, "GROUND", 6) == 0)
    meta->sar->image_type = 'G';
  // no information on look direction
  if (params->deskewed == 1)
    meta->sar->deskewed = 1;
  else if (params->deskewed == 2)
    meta->sar->deskewed = 0;
  meta->sar->original_line_count = header->line_count;
  meta->sar->original_sample_count = header->sample_count;
  meta->sar->line_increment = 1;
  meta->sar->sample_increment = 1;
  // no information on azimuth and range time per pixel
  // no information on slant and time shift
  meta->sar->slant_range_first_pixel = params->near_slant_range;
  meta->sar->wavelength = params->wavelength;
  meta->sar->prf = params->prf;
  // no information on earth radius and satellite height
  // no time information
  // no Doppler information
  meta->sar->azimuth_processing_bandwidth = params->chirp_bandwidth;
  // no chirp rate information
  meta->sar->pulse_duration = params->pulse_length;
  meta->sar->range_sampling_rate = params->range_sampling_rate;
  // FIXME: check polarizations for interferometric/polarimetric data
  // FIXME: multilook flag depends on data type
  
  // AirSAR block
  meta->airsar = meta_airsar_init();
  meta->airsar->scale_factor = 1.0; // Bruce Chapman said so.
  meta->airsar->gps_altitude = params->gps_altitude;
  if (dem) {
    meta->airsar->lat_peg_point = dem->lat_peg_point;
    meta->airsar->lon_peg_point = dem->lon_peg_point;
    meta->airsar->head_peg_point = dem->head_peg_point;
    meta->airsar->along_track_offset = dem->along_track_offset;
    meta->airsar->cross_track_offset = dem->cross_track_offset;
  }
  else {
    meta->airsar->lat_peg_point = params->lat_peg_point;
    meta->airsar->lon_peg_point = params->lon_peg_point;
    meta->airsar->head_peg_point = params->head_peg_point;
    meta->airsar->along_track_offset = params->along_track_offset;
    meta->airsar->cross_track_offset = params->cross_track_offset;
  }
  // The DEM header of Rick's prime test data did not have a valid peg point.
  // Without that the other numbers (along-track and cross-track offsets
  // as well as corner coordinates) don't make sense.
  // Will take the numbers out of the parameter header. Seems to work fine
  // with the prime test data set. Extract only elevation offset and increment
  // out of the DEM header
  if (dem) {
    meta->airsar->elevation_increment = dem->elevation_increment;
    meta->airsar->elevation_offset = dem->elevation_offset;
  }

  // Location block
  meta->location = meta_location_init();
  if (dem) {
    meta->location->lat_start_near_range = dem->corner1_lat;
    meta->location->lon_start_near_range = dem->corner1_lon;
    meta->location->lat_start_far_range = dem->corner2_lat;
    meta->location->lon_start_far_range = dem->corner2_lon;
    meta->location->lat_end_near_range = dem->corner4_lat;
    meta->location->lon_end_near_range = dem->corner4_lon;
    meta->location->lat_end_far_range = dem->corner3_lat;
    meta->location->lon_end_far_range = dem->corner3_lon;
  }
    
  return meta;
}
/***************************************************************
 * Ceos_init_stVec:
 * Reads state vectors from given CEOS file, writing them in the
 * appropriate format to SAR parameters structure.*/
void ceos_init_stVec(const char *fName, ceos_description *ceos,
             meta_parameters *meta)
{
  struct pos_data_rec ppdr;

  /*Fetch platform position data record.*/
  get_ppdr(fName,&ppdr);

  // Read the state vectors from the leader data file, adjust coordinate system, etc.
  // and write them to the SAR parameters structures
  ceos_read_stVecs(fName, ceos, meta);

  // For ALOS Palsar orbits only
  // Don't propagate but select nine state vectors around the center for the
  // higher order interpolation scheme
  if (ceos->processor == ALOS_PROC) {

    // Determine closest state vector
    int ii, min;
    double diff = 99999999;
    for (ii=0; ii<meta->state_vectors->vector_count; ii++) {
      if (fabs(meta->state_vectors->vecs[ii].time) < diff) {
        diff = fabs(meta->state_vectors->vecs[ii].time);
        min = ii;
      }
    }

    // Populate a new state vector 
    ymd_date img_ymd;
    julian_date img_jd;
    hms_time img_time;
    img_jd.year = meta->state_vectors->year;
    img_jd.jd   = meta->state_vectors->julDay;
    date_sec2hms(meta->state_vectors->second,&img_time);
    date_jd2ymd(&img_jd, &img_ymd);
    add_time((min-4)*60, &img_ymd, &img_time);
    date_ymd2jd(&img_ymd, &img_jd);
    meta_state_vectors *new_st = meta_state_vectors_init(9);
    new_st->year   = img_jd.year;
    new_st->julDay = img_jd.jd;
    new_st->second = date_hms2sec(&img_time);
    for (ii=0; ii<9; ii++)
      new_st->vecs[ii] = meta->state_vectors->vecs[ii+min-4];
    FREE(meta->state_vectors);
    meta->state_vectors = new_st;
    // Time shift should definitely set in the code that is calling this function
    // meta->sar->time_shift = 0.0;
  }
  // Propagate three state vectors for regular frames
  else if (ceos->processor != PREC && ceos->processor != unknownProcessor) {
      int vector_count=3;
      double data_int = meta->sar->original_line_count / 2
                  * fabs(meta->sar->azimuth_time_per_pixel);
      meta->state_vectors->vecs[0].time = get_timeDelta(ceos, &ppdr, meta);
      if (ceos->processor != PREC && data_int < 360.0) {
          while (fabs(data_int) > 15.0) {
              data_int /= 2;
              vector_count = vector_count*2-1;
          }
      // propagate three state vectors: start, center, end
          propagate_state(meta, vector_count, data_int);
      }
  }
}