예제 #1
0
meta_parameters* radarsat2meta(radarsat2_meta *radarsat2)
{

    ymd_date date, imgStartDate, imgStopDate;
    hms_time time, imgStartTime, imgStopTime;
    meta_parameters *meta;
    char *mon[13]= {"","Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep",
                    "Oct","Nov","Dec"
                   };
    double lat, lon, height, re, rp;

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

    // General block
    strcpy(meta->general->basename, radarsat2->filename);
    strcpy(meta->general->sensor, radarsat2->satellite);
    strcpy(meta->general->sensor_name, radarsat2->sensor);
    strcpy(meta->general->mode, radarsat2->beamModeMnemonic);
    sprintf(meta->general->processor, "%s %s",
            radarsat2->processingFacility, radarsat2->softwareVersion);
    meta->general->data_type = REAL32;
    if (strcmp_case(radarsat2->dataType, "COMPLEX") == 0)
        meta->general->image_data_type = COMPLEX_IMAGE;
    //else if (strcmp_case(radarsat2->dataType, "DETECTED") == 0)
    //  meta->general->image_data_type = AMPLITUDE_IMAGE;
    meta->general->radiometry = r_AMP;
    date_terrasar2date(radarsat2->zeroDopplerAzimuthTime, &date, &time);
    sprintf(meta->general->acquisition_date, "%02d-%s-%4d %02d:%02d:%02.0f",
            date.day, mon[date.month], date.year, time.hour, time.min, time.sec);
    //meta->general->orbit = radarsat2->absOrbit;
    if (strcmp_case(radarsat2->passDirection, "ASCENDING") == 0)
        meta->general->orbit_direction = 'A';
    else if (strcmp_case(radarsat2->passDirection, "DESCENDING") == 0)
        meta->general->orbit_direction = 'D';
    if (strcmp_case(radarsat2->dataType, "COMPLEX") == 0)
        meta->general->band_count = radarsat2->band_count * 2;
    else
        meta->general->band_count = radarsat2->band_count;
    strcpy(meta->general->bands, radarsat2->bands);
    meta->general->line_count = radarsat2->numberOfLines;
    meta->general->sample_count = radarsat2->numberOfSamplesPerLine;
    meta->general->start_line = 0;
    meta->general->start_sample = 0;
    meta->general->x_pixel_size = radarsat2->sampledPixelSpacing;
    meta->general->y_pixel_size = radarsat2->sampledLineSpacing;
    //meta->general->center_latitude = radarsat2->sceneCenterCoordLat;
    //meta->general->center_longitude = radarsat2->sceneCenterCoordLon;
    meta->general->re_major = radarsat2->semiMajorAxis;
    meta->general->re_minor = radarsat2->semiMinorAxis;

    // SAR block
    meta->sar = meta_sar_init();
    if (strcmp_case(radarsat2->productType, "SLC") == 0)
        meta->sar->image_type = 'S';
    if (strcmp_case(radarsat2->antennaPointing, "LEFT") == 0)
        meta->sar->look_direction = 'L';
    else if (strcmp_case(radarsat2->antennaPointing, "RIGHT") == 0)
        meta->sar->look_direction = 'R';
    meta->sar->azimuth_look_count = radarsat2->numberOfAzimuthLooks;
    meta->sar->range_look_count = radarsat2->numberOfRangeLooks;
    meta->sar->deskewed = 1;
    meta->sar->original_line_count = meta->general->line_count;
    meta->sar->original_sample_count = meta->general->sample_count;
    meta->sar->line_increment = 1;
    meta->sar->sample_increment = 1;
    date_terrasar2date(radarsat2->zeroDopplerTimeFirstLine,
                       &imgStartDate, &imgStartTime);
    date_terrasar2date(radarsat2->zeroDopplerTimeLastLine,
                       &imgStopDate, &imgStopTime);
    meta->sar->azimuth_time_per_pixel =
        date_difference(&imgStopDate, &imgStopTime,
                        &imgStartDate, &imgStartTime) / meta->general->line_count;
    meta->sar->range_time_per_pixel =
        meta->general->x_pixel_size * 2.0 / speedOfLight;
    meta->sar->slant_range_first_pixel = radarsat2->slantRangeNearEdge;
    meta->sar->slant_shift = 0.0;
    meta->sar->time_shift = 0.0;
    meta->sar->wavelength = SPD_LIGHT / radarsat2->radarCenterFrequency;
    meta->sar->prf = radarsat2->pulseRepetitionFrequency;
    meta->sar->satellite_height = radarsat2->satelliteHeight;
    meta->sar->azimuth_processing_bandwidth =
        radarsat2->totalProcessedAzimuthBandwidth;
    // FIXME: chirp_rate ???
    meta->sar->pulse_duration = radarsat2->pulseLength;
    meta->sar->range_sampling_rate = radarsat2->adcSamplingRate;
    if (strcmp_case(radarsat2->polarizations, "HH,VV,HV,VH") == 0) {
        meta->general->image_data_type = POLARIMETRIC_IMAGE;
        strcpy(meta->sar->polarization, "quad-pol");
    }
    else
        strcpy(meta->sar->polarization, radarsat2->polarizations);
    if (strcmp_case(radarsat2->dataType, "COMPLEX") == 0)
        meta->sar->multilook = FALSE;
    // FIXME: pitch, roll, yaw ???

    // Doppler block
    meta->doppler = radarsat2->doppler;

    // State vectors
    meta->state_vectors = radarsat2->state_vectors;

    // Propagate the state vectors to start, center, end
    int vector_count = 3;
    double data_int = date_difference(&imgStopDate, &imgStopTime,
                                      &imgStartDate, &imgStartTime) / 2.0;
    while (fabs(data_int) > 10.0) {
        data_int /= 2;
        vector_count = vector_count*2-1;
    }
    propagate_state(meta, vector_count, data_int);

    // Location block
    meta->location = meta_location_init();
    meta->location->lat_start_near_range = radarsat2->sceneCornerCoord1Lat;
    meta->location->lon_start_near_range = radarsat2->sceneCornerCoord1Lon;
    meta->location->lat_start_far_range = radarsat2->sceneCornerCoord2Lat;
    meta->location->lon_start_far_range = radarsat2->sceneCornerCoord2Lon;
    meta->location->lat_end_near_range = radarsat2->sceneCornerCoord3Lat;
    meta->location->lon_end_near_range = radarsat2->sceneCornerCoord3Lon;
    meta->location->lat_end_far_range = radarsat2->sceneCornerCoord4Lat;
    meta->location->lon_end_far_range = radarsat2->sceneCornerCoord4Lon;

    // Still need to determine center location, really only needed to get
    // the earth radius straight
    meta->general->center_longitude = (radarsat2->sceneCornerCoord1Lon +
                                       radarsat2->sceneCornerCoord2Lon +
                                       radarsat2->sceneCornerCoord3Lon +
                                       radarsat2->sceneCornerCoord4Lon) / 4.0;
    location_to_latlon(meta, meta->general->sample_count/2,
                       meta->general->line_count/2, 0.0, &lat, &lon, &height);
    meta->general->center_latitude = lat;
    meta->general->center_longitude = lon;
    lat = meta->general->center_latitude * D2R;
    re = meta->general->re_major;
    rp = meta->general->re_minor;
    meta->sar->earth_radius =
        (re*rp) / sqrt(rp*rp*cos(lat)*cos(lat)+re*re*sin(lat)*sin(lat));
    meta->sar->satellite_height += meta->sar->earth_radius;

    return meta;
}
예제 #2
0
meta_parameters* terrasar2meta(terrasar_meta *terrasar)
{
  ymd_date date, imgStartDate, imgStopDate;
  hms_time time, imgStartTime, imgStopTime;
  meta_parameters *meta;
  char *mon[13]={"","Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep",
     "Oct","Nov","Dec"};
  double lat, re, rp;

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

  // General block
  strcpy(meta->general->basename, terrasar->filename);
  strcpy(meta->general->sensor, terrasar->mission);
  strcpy(meta->general->sensor_name, terrasar->sensor);
  strcpy(meta->general->mode, terrasar->elevationBeamConfiguration);
  strcpy(meta->general->processor, "");
  // terrsar->imagingMode determines stripMap, scanSAR and spotLight modes
  // not using the information yet
  meta->general->data_type = REAL32;
  if (strcmp_case(terrasar->imageDataType, "COMPLEX") == 0)
    meta->general->image_data_type = COMPLEX_IMAGE;
  else if (strcmp_case(terrasar->imageDataType, "DETECTED") == 0)
    meta->general->image_data_type = AMPLITUDE_IMAGE;
  meta->general->radiometry = r_AMP;
  date_terrasar2date(terrasar->azimuthTimeUTC, &date, &time);
  sprintf(meta->general->acquisition_date, "%02d-%s-%4d %02d:%02d:%02.0f",
	  date.day, mon[date.month], date.year, time.hour, time.min, time.sec);
  meta->general->orbit = terrasar->absOrbit;
  if (strcmp_case(terrasar->orbitDirection, "ASCENDING") == 0)
    meta->general->orbit_direction = 'A';
  else if (strcmp_case(terrasar->orbitDirection, "DESCENDING") == 0)
    meta->general->orbit_direction = 'D';
  meta->general->band_count = terrasar->numberOfLayers;
  meta->general->line_count = terrasar->numberOfRows;
  meta->general->sample_count = terrasar->numberOfColumns;
  meta->general->start_line = 0;
  meta->general->start_sample = 0;
  meta->general->x_pixel_size = terrasar->rangeResolution;
  meta->general->y_pixel_size = terrasar->azimuthResolution;
  meta->general->center_latitude = terrasar->sceneCenterCoordLat;
  meta->general->center_longitude = terrasar->sceneCenterCoordLon;
  meta->general->re_major = 6378137.000; // WGS84
  meta->general->re_minor = 6356752.314; // WGS84

  // SAR block
  meta->sar = meta_sar_init();
  if (strcmp_case(terrasar->projection, "SLANTRANGE") == 0)
    meta->sar->image_type = 'S';
  else if (strcmp_case(terrasar->projection, "GROUNDRANGE") == 0)
    meta->sar->image_type = 'G';
  // FIXME: MAP case not covered yet
  if (strcmp_case(terrasar->lookDirection, "LEFT") == 0)
    meta->sar->look_direction = 'L';
  else if (strcmp_case(terrasar->lookDirection, "RIGHT") == 0)
    meta->sar->look_direction = 'R';
  meta->sar->azimuth_look_count = terrasar->azimuthLooks;
  meta->sar->range_look_count = terrasar->rangeLooks;
  if (strcmp_case(terrasar->imageCoordinateType, "ZERODOPPLER") == 0)
    meta->sar->deskewed = 1;
  meta->sar->original_line_count = meta->general->line_count;
  meta->sar->original_sample_count = meta->general->sample_count;
  meta->sar->line_increment = 1;
  meta->sar->sample_increment = 1;
  if (meta->sar->image_type == 'S') {
    meta->sar->range_time_per_pixel = terrasar->rowSpacing;
    meta->sar->azimuth_time_per_pixel = terrasar->columnSpacing;
  }
  else if (meta->sar->image_type == 'G') {
    meta->sar->range_time_per_pixel = 
      (terrasar->rangeTimeLast - terrasar->rangeTimeFirst) /
      terrasar->numberOfColumns;
    meta->general->x_pixel_size = terrasar->columnSpacing;
    meta->general->y_pixel_size = terrasar->rowSpacing;
  }
  meta->sar->slant_range_first_pixel = 
    terrasar->rangeTimeFirst * SPD_LIGHT / 2.0;
  meta->sar->slant_shift = 0.0;
  meta->sar->time_shift = 0.0;
  meta->sar->wavelength = SPD_LIGHT / terrasar->centerFrequency;
  meta->sar->prf = terrasar->prf;
  lat = meta->general->center_latitude * D2R;
  re = meta->general->re_major;
  rp = meta->general->re_minor;
  meta->sar->earth_radius = 
    (re*rp) / sqrt(rp*rp*cos(lat)*cos(lat)+re*re*sin(lat)*sin(lat));
  // FIXME: Doppler values need to be filled in
  meta->sar->azimuth_processing_bandwidth = 
    terrasar->totalProcessedAzimuthBandwidth;
  // FIXME: chirp_rate ???
  meta->sar->pulse_duration = terrasar->pulseLength;
  meta->sar->range_sampling_rate = terrasar->rsf;
  strcpy(meta->sar->polarization, terrasar->polarisationMode);
  if (strcmp_case(terrasar->imageDataType, "COMPLEX") == 0)
    meta->sar->multilook = FALSE;
  else if (strcmp_case(terrasar->imageDataType, "DETECTED") == 0)
    meta->sar->multilook = TRUE;
  // FIXME: pitch, roll, yaw ???

  // Doppler block
  meta->doppler = terrasar->doppler;

  // State vectors
  meta->state_vectors = terrasar->state_vectors;

  // Propagate the state vectors to start, center, end
  date_terrasar2date(terrasar->sceneStart, &imgStartDate, &imgStartTime);
  date_terrasar2date(terrasar->sceneStop, &imgStopDate, &imgStopTime);
  int vector_count = 3;
  double data_int = date_difference(&imgStopDate, &imgStopTime, 
				    &imgStartDate, &imgStartTime) / 2.0;
  while (fabs(data_int) > 10.0) {
    data_int /= 2;
    vector_count = vector_count*2-1;
  }
  propagate_state(meta, vector_count, data_int);

  data_int = date_difference(&imgStopDate, &imgStopTime, 
			     &imgStartDate, &imgStartTime);
  if (meta->sar->image_type == 'G')
    meta->sar->azimuth_time_per_pixel = data_int / meta->general->line_count;
  if (meta->general->orbit_direction == 'A') {
    meta->sar->time_shift = data_int;
    meta->sar->azimuth_time_per_pixel *= -1.0;
  }
  data_int /= 2.0;
  stateVector stVec = meta_get_stVec(meta, data_int);
  meta->sar->satellite_height = sqrt(stVec.pos.x * stVec.pos.x +
				     stVec.pos.y * stVec.pos.y +
				     stVec.pos.z * stVec.pos.z);

  // Location block
  meta->location = meta_location_init();
  meta->location->lat_start_near_range = terrasar->sceneCornerCoord1Lat;
  meta->location->lon_start_near_range = terrasar->sceneCornerCoord1Lon;
  meta->location->lat_start_far_range = terrasar->sceneCornerCoord2Lat;
  meta->location->lon_start_far_range = terrasar->sceneCornerCoord2Lon;
  meta->location->lat_end_near_range = terrasar->sceneCornerCoord3Lat;
  meta->location->lon_end_near_range = terrasar->sceneCornerCoord3Lon;
  meta->location->lat_end_far_range = terrasar->sceneCornerCoord4Lat;
  meta->location->lon_end_far_range = terrasar->sceneCornerCoord4Lon;

  return meta;
}
예제 #3
0
meta_parameters* uavsar_insar2meta(uavsar_insar *params)
{
  meta_parameters *meta;

  // Allocate memory for metadata structure
  meta = raw_init();
  
  // General block
  sprintf(meta->general->basename, "%s", params->site);
  sprintf(meta->general->sensor, "UAVSAR");
  strcpy(meta->general->sensor_name, "InSAR");
  strcpy(meta->general->processor, "JPL version ");
  strcat(meta->general->processor, params->processor);
  if (params->type == INSAR_AMP || params->type == INSAR_AMP_GRD) {
    if (params->type == INSAR_AMP) 
      strcpy(meta->general->mode, "AMP");
    else if (params->type == INSAR_AMP_GRD) 
      strcpy(meta->general->mode, "AMP_GRD");
    meta->general->image_data_type = AMPLITUDE_IMAGE;
  }
  else if (params->type == INSAR_INT || params->type == INSAR_INT_GRD) {
    if (params->type == INSAR_INT)
      strcpy(meta->general->mode, "INT");
    else if (params->type == INSAR_INT_GRD)
      strcpy(meta->general->mode, "INT_GRD");
    meta->general->image_data_type = INTERFEROGRAM;
  }
  else if (params->type == INSAR_UNW || params->type == INSAR_UNW_GRD) {
    if (params->type == INSAR_UNW)
      strcpy(meta->general->mode, "UNW");
    else if (params->type == INSAR_UNW_GRD)
      strcpy(meta->general->mode, "UNW_GRD");
    meta->general->image_data_type = UNWRAPPED_PHASE;
  }
  else if (params->type == INSAR_COR || params->type == INSAR_COR_GRD) {
    if (params->type == INSAR_COR)
      strcpy(meta->general->mode, "COR");
    else if (params->type == INSAR_COR_GRD)
      strcpy(meta->general->mode, "COR_GRD");
    meta->general->image_data_type = COHERENCE_IMAGE;
  }
  else if (params->type == INSAR_HGT_GRD) {
    strcpy(meta->general->mode, "HGT_GRD");
    meta->general->image_data_type = DEM;
  }
  else
    strcpy(meta->general->mode, "unknown");
  meta->general->data_type = REAL32;
  strcpy(meta->general->acquisition_date, params->acquisition_date);
  meta->general->band_count = 1;
  meta->general->line_count = params->row_count;
  meta->general->sample_count = params->column_count;
  meta->general->start_line = 0;
  meta->general->start_sample = 0;
  meta->general->x_pixel_size = params->range_pixel_spacing;
  meta->general->y_pixel_size = fabs(params->azimuth_pixel_spacing);
  meta->general->re_major = params->semi_major;
  double a = params->semi_major;
  double ecc2 = params->eccentricity;
  meta->general->re_minor = sqrt((1-ecc2)*a*a);
  // no information on bit error rate, missing lines and no data
  
  // SAR block
  meta->sar = meta_sar_init();
  strcpy(meta->sar->polarization, params->polarization);
  if (strcmp_case(params->projection, "SCX") == 0)
    meta->sar->image_type = 'S';
  else if (strcmp_case(params->projection, "EQA") == 0)
    meta->sar->image_type = 'P';
  if (strcmp_case(params->look_direction, "Left") == 0)
    meta->sar->look_direction = 'L';
  else if (strcmp_case(params->look_direction, "Right") == 0)
    meta->sar->look_direction = 'R';
  meta->sar->azimuth_look_count = params->azimuth_look_count;
  meta->sar->range_look_count = params->range_look_count;
  meta->sar->multilook = 1;
  meta->sar->deskewed = 1;
  meta->sar->original_line_count = params->row_count;
  meta->sar->original_sample_count = params->column_count;
  meta->sar->line_increment = 1;
  meta->sar->sample_increment = 1;
  // no information on azimuth and range time per pixel
  meta->sar->time_shift = 0.0;
  meta->sar->slant_shift = 0.0;
  meta->sar->slant_range_first_pixel = params->slant_range_first_pixel * 1000.0;
  meta->sar->wavelength = params->wavelength / 100.0;
  // no information on pulse repetition frequency
  // no information on earth radius and satellite height
  // no time information
  // no Doppler information
  meta->sar->yaw = params->yaw;
  meta->sar->pitch = params->pitch;
  meta->sar->roll = params->roll;
  meta->sar->azimuth_processing_bandwidth = params->bandwidth;
  // no chirp rate information
  meta->sar->pulse_duration = params->pulse_length / 1000.0;
  // no information on range sampling rate
  // FIXME: check polarizations for interferometric/polarimetric data
  // FIXME: multilook flag depends on data type
  
  // UAVSAR block
  meta->uavsar = meta_uavsar_init();
  strcpy(meta->uavsar->id, params->id);
  meta->uavsar->scale_factor = 1.0;
  meta->uavsar->gps_altitude = params->altitude;
  meta->uavsar->lat_peg_point = params->lat_peg_point;
  meta->uavsar->lon_peg_point = params->lon_peg_point;
  meta->uavsar->head_peg_point = params->head_peg_point;
  meta->uavsar->along_track_offset = params->along_track_offset;
  meta->uavsar->cross_track_offset = params->cross_track_offset;

  // Projection block
  if (params->type >= INSAR_AMP_GRD && params->type <= INSAR_HGT_GRD) {
    meta->projection = meta_projection_init();
    meta->projection->type = LAT_LONG_PSEUDO_PROJECTION;
    strcpy (meta->projection->units, "degrees");
    if (params->along_track_offset >= 0.0)
      meta->projection->hem = 'N';
    else
      meta->projection->hem = 'S';
    meta->projection->re_major = meta->general->re_major;
    meta->projection->re_minor = meta->general->re_minor;
    meta->projection->height = 0.0;
    meta->projection->spheroid = WGS84_SPHEROID;
    meta->projection->datum = WGS84_DATUM;

    // FIXME: Check that the following is correct - needs some data
    // Coordinate reference: Point
    // UAVSAR lat/lon projected data is calculated from center
    // pixel.  Thus we have to add in a half-pixel shift.
    meta->projection->startX = 
      params->cross_track_offset - params->range_pixel_spacing / 2.0;
    meta->projection->startY = 
      params->along_track_offset - params->azimuth_pixel_spacing / 2.0;
    meta->projection->perX = params->range_pixel_spacing;
    meta->projection->perY = params->azimuth_pixel_spacing;

    meta->general->center_latitude = params->along_track_offset + 
      params->azimuth_pixel_spacing * params->row_count / 2.0;
    meta->general->center_longitude = params->cross_track_offset +
      params->range_pixel_spacing * params->column_count / 2.0;
  }

  // Location block
  meta->location = meta_location_init();
  meta->location->lat_start_near_range = params->lat_upper_left;
  meta->location->lon_start_near_range = params->lon_upper_left;
  meta->location->lat_start_far_range = params->lat_upper_right;
  meta->location->lon_start_far_range = params->lon_upper_right;
  meta->location->lat_end_near_range = params->lat_lower_left;
  meta->location->lon_end_near_range = params->lon_lower_left;
  meta->location->lat_end_far_range = params->lat_lower_right;
  meta->location->lon_end_far_range = params->lon_lower_right;

  return meta;
}
예제 #4
0
meta_parameters *iso2meta(iso_meta *iso)
{
  int ii;
  meta_parameters *meta = raw_init();
  char str[30];

  // Convenience pointers
  iso_generalHeader *header = iso->generalHeader;
  iso_productComponents *comps = iso->productComponents;
  iso_productInfo *info = iso->productInfo;
  iso_productSpecific *spec = iso->productSpecific;
  iso_setup *setup = iso->setup;
  iso_processing *proc = iso->processing;
  iso_instrument *inst = iso->instrument;
  iso_platform *platform = iso->platform;
  iso_productQuality *quality = iso->productQuality;

  meta->meta_version = 3.5;

  // General block
  for (ii=0; ii<comps->numAnnotations; ii++)
    if (comps->annotation[ii].type == MAIN_TYPE)
      strncpy(meta->general->basename, comps->annotation[ii].file.name, 256);
  strcpy(meta->general->sensor, header->mission);
  strcpy(meta->general->sensor_name, info->sensor);
  strcpy(meta->general->mode, info->elevationBeamConfiguration);
  strcpy(meta->general->receiving_station, info->receivingStation);
  strcpy(meta->general->processor, header->generationSystem);
  if (info->imageDataType == DETECTED_DATA_TYPE &&
      info->imageDataDepth == 8)
    meta->general->data_type = ASF_BYTE;
  else if (info->imageDataType == DETECTED_DATA_TYPE &&
	   info->imageDataDepth == 16)
    meta->general->data_type = INTEGER16;
  else if (info->imageDataType == DETECTED_DATA_TYPE &&
	   info->imageDataDepth == 32)
    // assumption here is that we are not dealing with INTERGER32
    meta->general->data_type = REAL32;
  else if (info->imageDataType == DETECTED_DATA_TYPE &&
	   info->imageDataDepth == 64)
    meta->general->data_type = REAL64;
  else if (info->imageDataType == COMPLEX_DATA_TYPE &&
	   info->imageDataDepth == 8)
    meta->general->data_type = COMPLEX_BYTE;
  else if (info->imageDataType == COMPLEX_DATA_TYPE &&
	   info->imageDataDepth == 16)
    meta->general->data_type = COMPLEX_INTEGER16;
  else if (info->imageDataType == COMPLEX_DATA_TYPE &&
	   info->imageDataDepth == 32)
    // assumption here is that we are not dealing with COMPLEX_INTEGER32
    meta->general->data_type = COMPLEX_REAL32;
  else if (info->imageDataType == COMPLEX_DATA_TYPE &&
	   info->imageDataDepth == 64)
    meta->general->data_type = COMPLEX_REAL64;
  if (info->imageDataType == RAW_DATA_TYPE)
    meta->general->image_data_type = RAW_IMAGE;
  else if (info->imageDataType == COMPLEX_DATA_TYPE)
    meta->general->image_data_type = COMPLEX_IMAGE;
  else if (info->imageDataType == DETECTED_DATA_TYPE)
    meta->general->image_data_type = AMPLITUDE_IMAGE;
  // more detailed mapping of imageDataType will probably need pixelValueID 
  // context
  if (strcmp_case(info->pixelValueID, "RADAR BRIGHTNESS") == 0)
    meta->general->radiometry = r_AMP;
  // dealing with any form of calibration not implemented yet
  dateTime2str(info->sceneCenterCoord.azimuthTimeUTC,
	       meta->general->acquisition_date);
  meta->general->orbit = info->absOrbit;
  if (info->orbitDirection == ASCENDING)  
    meta->general->orbit_direction = 'A';
  else if (info->orbitDirection == DESCENDING)
    meta->general->orbit_direction = 'D';
  meta->general->frame = setup->frameID;
  meta->general->band_count = comps->numLayers;
  strcpy(meta->general->bands, polLayer2str(comps->imageData[0].polLayer));
  for (ii=1; ii<comps->numLayers; ii++) {
    sprintf(str, ", %s", polLayer2str(comps->imageData[ii].polLayer));
    strcat(meta->general->bands, str);
  }
  meta->general->line_count = info->numberOfRows;
  meta->general->sample_count = info->numberOfColumns;
  meta->general->start_line = info->startRow;
  meta->general->start_sample = info->startColumn;
  meta->general->x_pixel_size = info->groundRangeResolution;
  meta->general->y_pixel_size = info->azimuthResolution;
  meta->general->center_latitude = info->sceneCenterCoord.lat;
  meta->general->center_longitude = info->sceneCenterCoord.lon;
  spheroid_type_t spheroid = WGS84_SPHEROID; // FIXME: needs to know reference
  spheroid_axes_lengths(spheroid,
			&meta->general->re_major, &meta->general->re_minor);
  meta->general->bit_error_rate = quality->imageDataQuality[0].bitErrorRate;
  meta->general->missing_lines = quality->imageDataQuality[0].missingLines;
  meta->general->no_data = (float) quality->imageDataQuality[0].noData;

  // SAR block
  meta->sar = meta_sar_init();
  if (info->projection == SLANTRANGE_PROJ)
    meta->sar->image_type = 'S';
  else if (info->projection == GROUNDRANGE_PROJ)
    meta->sar->image_type = 'G';
  else if (info->projection == MAP_PROJ)
    meta->sar->image_type = 'P';
  if (setup->lookDirection == RIGHT_LOOK)
    meta->sar->look_direction = 'R';
  else if (setup->lookDirection == LEFT_LOOK)
    meta->sar->look_direction = 'L';
  meta->sar->azimuth_look_count = info->azimuthLooks;
  meta->sar->range_look_count = info->rangeLooks;
  if (spec->imageCoordinateType == RAW_COORD)
    meta->sar->deskewed = FALSE;
  else if (spec->imageCoordinateType == ZERODOPPLER)
    meta->sar->deskewed = TRUE;
  meta->general->line_scaling = info->rowScaling;  
  meta->general->sample_scaling = info->columnScaling;
  meta->sar->range_time_per_pixel = info->columnSpacing;
  meta->sar->azimuth_time_per_pixel = info->rowSpacing;
  meta->sar->slant_shift = spec->slantRangeShift;
  //meta->sar->slant_range_first_pixel = info->rangeTimeFirstPixel * SPD_LIGHT;
  meta->sar->slant_range_first_pixel = spec->projectedSpacingSlantRange;
  meta->sar->wavelength = SPD_LIGHT / inst->centerFrequency;
  meta->sar->prf = spec->commonPRF;
  meta->sar->earth_radius = info->earthRadius;
  meta->sar->satellite_height = info->satelliteHeight;
  // meta->sar->satellite_binary_time;
  // meta->sar->satellite_clock_time;
  for (ii=0; ii<=proc->doppler[0].polynomialDegree; ii++)
    meta->sar->range_doppler_coefficients[ii] = 
      proc->doppler[0].coefficient[ii];
  meta->sar->azimuth_doppler_coefficients[0] = proc->doppler[0].coefficient[0];
  // meta->sar->chirp_rate
  // meta->sar->pulse_duration
  meta->sar->range_sampling_rate = spec->commonRSF;
  if (info->polarizationMode == SINGLE_POL)
    strcpy(meta->sar->polarization, "SINGLE");
  else if (info->polarizationMode == DUAL_POL)
    strcpy(meta->sar->polarization, "DUAL");
  else if (info->polarizationMode == QUAD_POL)
    strcpy(meta->sar->polarization, "QUAD");
  meta->sar->multilook = proc->multiLookedFlag;
  meta->sar->pitch = info->pitch;
  meta->sar->roll = info->roll;
  meta->sar->yaw = info->yaw;
  meta->sar->incid_a[0] = info->sceneCenterCoord.incidenceAngle;
  meta->sar->heading_angle = info->headingAngle;
  meta->sar->chirp_rate = proc->processingParameter[0].chirpRate;
  meta->sar->pulse_duration = proc->processingParameter[0].pulseDuration;

  // meta->projection
  // meta->transform
  // meta->airsar
  // meta->uavsar
  // meta->statistics

  int numVectors = platform->numStateVectors;
  meta->state_vectors = meta_state_vectors_init(numVectors);
  meta->state_vectors->vector_count = numVectors;
  ymd_date ymdStart, ymdSV;
  julian_date jd;
  hms_time hmsStart, hmsSV;
  ymdStart.year = info->startTimeUTC.year;
  ymdStart.month = info->startTimeUTC.month;
  ymdStart.day = info->startTimeUTC.day;
  hmsStart.hour = info->startTimeUTC.hour;
  hmsStart.min = info->startTimeUTC.min;
  hmsStart.sec = info->startTimeUTC.second;
  meta->state_vectors->year = info->startTimeUTC.year;
  date_ymd2jd(&ymdStart, &jd);
  meta->state_vectors->julDay = jd.jd;
  meta->state_vectors->second = date_hms2sec(&hmsStart);
  for (ii=0; ii<numVectors; ii++) {
    ymdSV.year = platform->stateVec[ii].timeUTC.year;
    ymdSV.month = platform->stateVec[ii].timeUTC.month;
    ymdSV.day = platform->stateVec[ii].timeUTC.day;
    hmsSV.hour = platform->stateVec[ii].timeUTC.hour;
    hmsSV.min = platform->stateVec[ii].timeUTC.min;
    hmsSV.sec = platform->stateVec[ii].timeUTC.second;
    meta->state_vectors->vecs[ii].time = 
      time_difference(&ymdSV, &hmsSV, &ymdStart, &hmsStart);
    meta->state_vectors->vecs[ii].vec.pos.x = platform->stateVec[ii].posX;
    meta->state_vectors->vecs[ii].vec.pos.y = platform->stateVec[ii].posY;
    meta->state_vectors->vecs[ii].vec.pos.z = platform->stateVec[ii].posZ;
    meta->state_vectors->vecs[ii].vec.vel.x = platform->stateVec[ii].velX;
    meta->state_vectors->vecs[ii].vec.vel.y = platform->stateVec[ii].velY;
    meta->state_vectors->vecs[ii].vec.vel.z = platform->stateVec[ii].velZ;
  }
  if (meta->sar->azimuth_time_per_pixel > 0)
    meta->sar->time_shift = 0.0;
  else
    meta->sar->time_shift = meta->state_vectors->vecs[numVectors-1].time;

  if (meta->sar->yaw == 0 ||
      !meta_is_valid_double(meta->sar->yaw))
  {
    meta->sar->yaw = meta_yaw(meta, meta->general->line_count/2.0,
                                    meta->general->sample_count/2.0);
  }
  /*
  // few calculations need state vectors
  meta->sar->earth_radius = 
    meta_get_earth_radius(meta, line_count/2, sample_count/2);
  // meta->sar->earth_radius_pp
  meta->sar->satellite_height =
    meta_get_sat_height(meta, meta->general->line_count/2,
			meta->general->sample_count/2);
  meta->sar->incid_a[0] = meta_incid(meta, line_count/2, sample_count/2)*R2D;
  */

  // Location block
  meta_get_corner_coords(meta);
/*
  meta->location = meta_location_init();
  for (ii=0; ii<4; ii++) {
    if (info->sceneCornerCoord[ii].refRow == 0 &&
	info->sceneCornerCoord[ii].refColumn == 0) {
      meta->location->lat_start_near_range = info->sceneCornerCoord[ii].lat;
      meta->location->lon_start_near_range = info->sceneCornerCoord[ii].lon;
    }
    else if (info->sceneCornerCoord[ii].refRow == 0 &&
	     info->sceneCornerCoord[ii].refColumn == sample_count) {
      meta->location->lat_start_far_range = info->sceneCornerCoord[ii].lat;
      meta->location->lon_start_far_range = info->sceneCornerCoord[ii].lon;
    }
    else if (info->sceneCornerCoord[ii].refRow == line_count &&
	     info->sceneCornerCoord[ii].refColumn == 0) {
      meta->location->lat_end_near_range = info->sceneCornerCoord[ii].lat;
      meta->location->lon_end_near_range = info->sceneCornerCoord[ii].lon;
    }
    else if (info->sceneCornerCoord[ii].refRow == line_count &&
	     info->sceneCornerCoord[ii].refColumn == sample_count) {
      meta->location->lat_end_far_range = info->sceneCornerCoord[ii].lat;
      meta->location->lon_end_far_range = info->sceneCornerCoord[ii].lon;
    }
  }
*/
  return meta;
}
예제 #5
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;
}
예제 #6
0
meta_parameters* uavsar_polsar2meta(uavsar_polsar *params)
{
  meta_parameters *meta;

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

  // General block
  sprintf(meta->general->basename, "%s", params->site);
  sprintf(meta->general->sensor, "UAVSAR");
  strcpy(meta->general->sensor_name, "PolSAR");
  strcpy(meta->general->processor, "JPL version ");
  strcat(meta->general->processor, params->processor);
  if (params->type == POLSAR_SLC) {
    strcpy(meta->general->mode, "SLC");
    meta->general->image_data_type = POLARIMETRIC_S2_MATRIX;
  }
  else if (params->type == POLSAR_MLC) {
    strcpy(meta->general->mode, "MLC");
    meta->general->image_data_type = POLARIMETRIC_C3_MATRIX;
  }
  else if (params->type == POLSAR_DAT) {
    strcpy(meta->general->mode, "DAT");
    meta->general->image_data_type = POLARIMETRIC_STOKES_MATRIX;
  }
  else if (params->type == POLSAR_GRD) {
    strcpy(meta->general->mode, "GRD");
    meta->general->image_data_type = POLARIMETRIC_C3_MATRIX;
    meta->general->no_data = 0;
  }
  else if (params->type == POLSAR_HGT) {
    strcpy(meta->general->mode, "HGT");
    meta->general->image_data_type = DEM;
  }
  else
    strcpy(meta->general->mode, "unknown");
  meta->general->radiometry = r_GAMMA;
  meta->general->data_type = REAL32;
  strcpy(meta->general->acquisition_date, params->acquisition_date);
  meta->general->band_count = 1;
  meta->general->line_count = params->row_count;
  meta->general->sample_count = params->column_count;
  meta->general->start_line = 0;
  meta->general->start_sample = 0;
  meta->general->x_pixel_size = params->range_pixel_spacing;
  meta->general->y_pixel_size = fabs(params->azimuth_pixel_spacing);
  meta->general->re_major = params->semi_major;
  double re = params->semi_major;
  double ecc2 = params->eccentricity;
  double rp = sqrt((1-ecc2)*re*re);
  meta->general->re_minor = rp;
  // no information on bit error rate, missing lines and no data

  // SAR block
  meta->sar = meta_sar_init();
  strcpy(meta->sar->polarization, "QUAD-POL");
  if (strcmp_case(params->projection, "SCX") == 0)
    meta->sar->image_type = 'S';
  else if (strcmp_case(params->projection, "EQA") == 0)
    meta->sar->image_type = 'P';
  if (strcmp_case(params->look_direction, "Left") == 0)
    meta->sar->look_direction = 'L';
  else if (strcmp_case(params->look_direction, "Right") == 0)
    meta->sar->look_direction = 'R';
  if (params->type == POLSAR_SLC) {
    meta->sar->azimuth_look_count = 1;
    meta->sar->range_look_count = 1;
    meta->sar->multilook = 0;
  }
  else {
    // FIXME: Update once range look count is introduced to metadata structure
    meta->sar->azimuth_look_count = params->azimuth_look_count;
    meta->sar->range_look_count = params->range_look_count;
    meta->sar->multilook = 1;
  }
  meta->sar->deskewed = 1;
  meta->sar->original_line_count = params->row_count;
  meta->sar->original_sample_count = params->column_count;
  meta->sar->line_increment = 1;
  meta->sar->sample_increment = 1;
  // no information on azimuth and range time per pixel
  meta->sar->time_shift = 0.0;
  meta->sar->slant_shift = 0.0;
  meta->sar->slant_range_first_pixel = params->slant_range_first_pixel * 1000.0;
  meta->sar->wavelength = params->wavelength / 100.0;
  // no information on pulse repetition frequency
  double tan_lat = params->lat_peg_point*D2R;
  meta->sar->earth_radius = rp*sqrt(1 + tan_lat*tan_lat) /
    sqrt(rp*rp/(re*re) + tan_lat*tan_lat);
  // no information on satellite height
  // no time information
  // no Doppler information
  meta->sar->yaw = params->yaw;
  meta->sar->pitch = params->pitch;
  meta->sar->roll = params->roll;
  meta->sar->azimuth_processing_bandwidth = params->bandwidth;
  // no chirp rate information
  meta->sar->pulse_duration = params->pulse_length / 1000.0;
  // no information on range sampling rate
  // FIXME: check polarizations for interferometric/polarimetric data
  // FIXME: multilook flag depends on data type
  
  // UAVSAR block
  meta->uavsar = meta_uavsar_init();
  strcpy(meta->uavsar->id, params->id);
  meta->uavsar->scale_factor = 1.0;
  meta->uavsar->gps_altitude = params->altitude;
  meta->uavsar->lat_peg_point = params->lat_peg_point;
  meta->uavsar->lon_peg_point = params->lon_peg_point;
  meta->uavsar->head_peg_point = params->head_peg_point;
  meta->uavsar->along_track_offset = params->along_track_offset;
  meta->uavsar->cross_track_offset = params->cross_track_offset;

  // Location block
  meta->location = meta_location_init();
  meta->location->lat_start_near_range = params->lat_upper_left;
  meta->location->lon_start_near_range = params->lon_upper_left;
  meta->location->lat_start_far_range = params->lat_upper_right;
  meta->location->lon_start_far_range = params->lon_upper_right;
  meta->location->lat_end_near_range = params->lat_lower_left;
  meta->location->lon_end_near_range = params->lon_lower_left;
  meta->location->lat_end_far_range = params->lat_lower_right;
  meta->location->lon_end_far_range = params->lon_lower_right;

  // Projection block
  if (params->type == POLSAR_GRD || params->type == POLSAR_HGT) {
    meta->projection = meta_projection_init();
    meta->projection->type = LAT_LONG_PSEUDO_PROJECTION;
    strcpy (meta->projection->units, "degrees");
    if (params->along_track_offset >= 0.0)
      meta->projection->hem = 'N';
    else
      meta->projection->hem = 'S';
    meta->projection->re_major = meta->general->re_major;
    meta->projection->re_minor = meta->general->re_minor;
    meta->projection->height = 0.0;
    meta->projection->spheroid = WGS84_SPHEROID;
    meta->projection->datum = WGS84_DATUM;

    // Coordinate reference: Point
    // UAVSAR lat/lon projected data is calculated from center
    // pixel.  Thus we have to add in a half-pixel shift.
    meta->projection->startX = 
      params->cross_track_offset - params->range_pixel_spacing / 2.0;
    meta->projection->startY = 
      params->along_track_offset - params->azimuth_pixel_spacing / 2.0;
    meta->projection->perX = params->range_pixel_spacing;
    meta->projection->perY = params->azimuth_pixel_spacing;

    meta->general->center_latitude = params->along_track_offset + 
      params->azimuth_pixel_spacing * params->row_count / 2.0;
    meta->general->center_longitude = params->cross_track_offset +
      params->range_pixel_spacing * params->column_count / 2.0;
  }
  else {
    meta_get_latLon(meta, meta->general->line_count/2, meta->general->sample_count/2, 0,
                    &meta->general->center_latitude, &meta->general->center_longitude);
  }

  return meta;
}
예제 #7
0
meta_parameters* gamma_isp2meta(gamma_isp *gamma)
{
  meta_parameters *meta;
  char *mon[13]={"","Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep",
     "Oct","Nov","Dec"};

  // Initialize the meta structure
  meta = raw_init();

  // Fill general block
  strcpy(meta->general->basename, gamma->title);
  strcpy(meta->general->sensor, gamma->sensor);
  strcpy(meta->general->sensor_name, MAGIC_UNSET_STRING); // Sensor name not available in ISP metadata
  strcpy(meta->general->mode, MAGIC_UNSET_STRING); // Mode not available in ISP metadata
  strcpy(meta->general->processor, "GAMMA ISP");
  if (strncmp_case(gamma->image_format, "FCOMPLEX", 8) == 0)
    meta->general->data_type = COMPLEX_REAL32;
  else if (strncmp_case(gamma->image_format, "SCOMPLEX", 8) == 0)
    meta->general->data_type = COMPLEX_INTEGER16;
  else if (strncmp_case(gamma->image_format, "FLOAT", 8) == 0)
    meta->general->data_type = REAL32;
  else if (strncmp_case(gamma->image_format, "SHORT", 8) == 0)
    meta->general->data_type = INTEGER16;
  else if (strncmp_case(gamma->image_format, "BYTE", 8) == 0)
    meta->general->data_type = ASF_BYTE;
  if (strcmp(gamma->image_data_type, "UNKNOWN") == 0) {
    switch(meta->general->data_type) 
      {
      case COMPLEX_REAL32:
      case COMPLEX_INTEGER16:
	meta->general->image_data_type = COMPLEX_IMAGE;
	break;
      default:
	meta->general->image_data_type = IMAGE;
	break;
      }
  }
  else {
    if (strncmp_case(gamma->image_data_type, "RAW_IMAGE", 9) == 0)
      meta->general->image_data_type = RAW_IMAGE;
    if (strncmp_case(gamma->image_data_type, "COMPLEX_IMAGE", 13) == 0)
      meta->general->image_data_type = COMPLEX_IMAGE;
    if (strncmp_case(gamma->image_data_type, "AMPLITUDE_IMAGE", 15) == 0)
      meta->general->image_data_type = AMPLITUDE_IMAGE;
    if (strncmp_case(gamma->image_data_type, "PHASE_IMAGE", 11) == 0)
      meta->general->image_data_type = PHASE_IMAGE;
    if (strncmp_case(gamma->image_data_type, "COHERENCE_IMAGE", 15) == 0)
      meta->general->image_data_type = COHERENCE_IMAGE;
    if (strncmp_case(gamma->image_data_type, "POLARIMETRIC_IMAGE", 18) == 0)
      meta->general->image_data_type = POLARIMETRIC_IMAGE;
    if (strncmp_case(gamma->image_data_type, "POLARIMETRIC_SEGMENTATION", 25) == 0)
      meta->general->image_data_type = POLARIMETRIC_SEGMENTATION;
    if (strncmp_case(gamma->image_data_type, "POLARIMETRIC_DECOMPOSITION", 26) == 0)
      meta->general->image_data_type = POLARIMETRIC_DECOMPOSITION;
    if (strncmp_case(gamma->image_data_type, "POLARIMETRIC_PARAMETER", 22) == 0)
      meta->general->image_data_type = POLARIMETRIC_PARAMETER;
    if (strncmp_case(gamma->image_data_type, "POLARIMETRIC_C2_MATRIX", 22) == 0)
      meta->general->image_data_type = POLARIMETRIC_C2_MATRIX;
    if (strncmp_case(gamma->image_data_type, "POLARIMETRIC_C3_MATRIX", 22) == 0)
      meta->general->image_data_type = POLARIMETRIC_C3_MATRIX;
    if (strncmp_case(gamma->image_data_type, "POLARIMETRIC_C4_MATRIX", 22) == 0)
      meta->general->image_data_type = POLARIMETRIC_C4_MATRIX;
    if (strncmp_case(gamma->image_data_type, "POLARIMETRIC_T3_MATRIX", 22) == 0)
      meta->general->image_data_type = POLARIMETRIC_T3_MATRIX;
    if (strncmp_case(gamma->image_data_type, "POLARIMETRIC_T4_MATRIX", 22) == 0)
      meta->general->image_data_type = POLARIMETRIC_T4_MATRIX;
    if (strncmp_case(gamma->image_data_type, 
		     "POLARIMETRIC_STOKES_MATRIX", 26) == 0)
      meta->general->image_data_type = POLARIMETRIC_STOKES_MATRIX;
    if (strncmp_case(gamma->image_data_type, "LUT_IMAGE", 9) == 0)
      meta->general->image_data_type = LUT_IMAGE;
    if (strncmp_case(gamma->image_data_type, "ELEVATION", 9) == 0)
      meta->general->image_data_type = ELEVATION;
    if (strncmp_case(gamma->image_data_type, "DEM", 3) == 0)
      meta->general->image_data_type = DEM;
    if (strncmp_case(gamma->image_data_type, "IMAGE", 5) == 0)
      meta->general->image_data_type = IMAGE;
    if (strncmp_case(gamma->image_data_type, "MASK", 4) == 0)
      meta->general->image_data_type = MASK;
    if (strncmp_case(gamma->image_data_type, "IMAGE_LAYER_STACK", 17) == 0)
      meta->general->image_data_type = IMAGE_LAYER_STACK;
    if (strncmp_case(gamma->image_data_type, "INSAR_STACK", 11) == 0)
      meta->general->image_data_type = INSAR_STACK;
  }
  sprintf(meta->general->acquisition_date, "%2d-%s-%4d",
    gamma->acquisition.day, mon[gamma->acquisition.month],
    gamma->acquisition.year);
  meta->general->orbit = gamma->orbit;
  if (gamma->heading > 90.0 && gamma->heading < 270.0)
    meta->general->orbit_direction = 'D';
  else
    meta->general->orbit_direction = 'A';
  meta->general->frame = MAGIC_UNSET_INT;
  meta->general->band_count = 1;
  strcpy(meta->general->bands, MAGIC_UNSET_STRING);
  meta->general->line_count = gamma->azimuth_lines;
  meta->general->sample_count = gamma->range_samples;
  meta->general->start_line = 0;
  meta->general->start_sample = 0;
  meta->general->x_pixel_size = gamma->range_pixel_spacing;
  meta->general->y_pixel_size = gamma->azimuth_pixel_spacing;
  meta->general->center_latitude = gamma->center_latitude;
  meta->general->center_longitude = gamma->center_longitude;
  meta->general->re_major = gamma->earth_semi_major_axis;
  meta->general->re_minor = gamma->earth_semi_minor_axis;
  meta->general->bit_error_rate = MAGIC_UNSET_DOUBLE;
  meta->general->missing_lines = 0;
  meta->general->no_data = MAGIC_UNSET_DOUBLE;

  // Fill SAR block
  meta->sar = meta_sar_init();
  if (strncmp(uc(gamma->image_geometry), "SLANT_RANGE", 11) == 0)
    meta->sar->image_type = 'S';
  else if (strncmp(uc(gamma->image_geometry), "GROUND_RANGE", 11) == 0)
    meta->sar->image_type = 'G';
  else
    meta->sar->image_type = MAGIC_UNSET_CHAR;
  if (gamma->azimuth_angle >= 0.0)
    meta->sar->look_direction = 'R';
  else
    meta->sar->look_direction = 'L';
  meta->sar->azimuth_look_count = gamma->azimuth_looks;
  meta->sar->range_look_count = gamma->range_looks;
  if (gamma->azimuth_looks > 1 || gamma->range_looks > 1)
    meta->sar->multilook = 1;
  else
    meta->sar->multilook = 0;
  meta->sar->deskewed = gamma->azimuth_deskew;
  meta->sar->original_line_count = meta->general->line_count;
  meta->sar->original_sample_count = meta->general->sample_count;
  meta->sar->line_increment = 1;
  meta->sar->sample_increment = 1;
  meta->sar->range_time_per_pixel = fabs((2.0 * gamma->range_pixel_spacing) / 
					 gamma->range_looks /
					 SPD_LIGHT);
  meta->sar->azimuth_time_per_pixel = gamma->azimuth_line_time;
  meta->sar->slant_range_first_pixel = gamma->near_range_slc;
  meta->sar->slant_shift = 0.0;
  meta->sar->time_shift = 0.0;
  /* Under testing - does not seem to apply to the test data set.
  if (meta->general->orbit_direction == 'D')
    meta->sar->time_shift = 0.0;
  else if (meta->general->orbit_direction == 'A')
    meta->sar->time_shift = fabs(meta->sar->original_line_count * meta->sar->azimuth_time_per_pixel);
  else
    meta->sar->time_shift = MAGIC_UNSET_DOUBLE;
  */
  meta->sar->wavelength = SPD_LIGHT / gamma->radar_frequency;
  meta->sar->prf = gamma->prf;
  meta->sar->earth_radius = gamma->earth_radius_below_sensor;
  meta->sar->earth_radius_pp = meta->sar->earth_radius; // KLUDGE: This value is actually unknown in ISP metadata
  meta->sar->satellite_height = gamma->sar_to_earth_center;
  strcpy(meta->sar->satellite_binary_time, MAGIC_UNSET_STRING);
  strcpy(meta->sar->satellite_clock_time, MAGIC_UNSET_STRING);
  int i;
  if (gamma->doppler_polynomial[3] > 0.0001) {
    // FIXME: If this error ever fires, then we should insert a function that does a
    // quadratic fit to the cubic function.  Then we can derive close 'nuf quadratic
    // values from a set of points generated by the cubic and use those.
    asfPrintError("GAMMA doppler polynomial has a large cubic term\n"
        "(%f versus limit of 0.0001) and is not well modeled by a\nquadratic.",
        gamma->doppler_polynomial[3]);
  }
  for (i=0; i<3; i++) {
    meta->sar->range_doppler_coefficients[i] = gamma->doppler_polynomial[i]; 
    meta->sar->azimuth_doppler_coefficients[i] = 0.0;
  }
  // Adjust for difference in units [Hz/m] -> [Hz/pixel]
  meta->sar->range_doppler_coefficients[1] /= gamma->range_pixel_spacing;
  meta->sar->range_doppler_coefficients[2] /= 
    gamma->range_pixel_spacing * gamma->range_pixel_spacing;

  meta->sar->azimuth_doppler_coefficients[0] = gamma->doppler_polynomial[0];
  meta->sar->azimuth_processing_bandwidth = gamma->azimuth_proc_bandwidth;
  meta->sar->chirp_rate = gamma->chirp_bandwidth;
  meta->sar->pulse_duration = MAGIC_UNSET_DOUBLE;
  meta->sar->range_sampling_rate = gamma->adc_sampling_rate;
  strcpy(meta->sar->polarization, MAGIC_UNSET_STRING);

  // Fill state vector structure
  meta->state_vectors = meta_state_vectors_init(3);
  meta->state_vectors = gamma->stVec;

  // Propagate the state vectors to start, center, end
  int vector_count = 3;
  double data_int = gamma->center_time - gamma->start_time;
  while (fabs(data_int) > 15.0) {
    data_int /= 2;
    vector_count = vector_count*2-1;
  }
  propagate_state(meta, vector_count, data_int);
  
  // Generate location block
  meta_get_corner_coords(meta);

  return meta;
}
예제 #8
0
meta_parameters* gamma_msp2meta(gamma_msp *gamma)
{
  meta_parameters *meta;
  char *mon[13]={"","Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep",
    "Oct","Nov","Dec"};

  // Initialize the meta structure
  meta = raw_init();

  // Fill general block
  strcpy(meta->general->basename, gamma->title);
  strcpy(meta->general->sensor, MAGIC_UNSET_STRING); // Sensor not available in MSP metadata
  strcpy(meta->general->sensor_name, MAGIC_UNSET_STRING); // Sensor name not available in MSP metadata
  strcpy(meta->general->mode, MAGIC_UNSET_STRING); // Mode not available in MSP metadata
  strcpy(meta->general->processor, "GAMMA MSP");
  if (strncmp(uc(gamma->image_format), "FCOMPLEX", 8) == 0)
    meta->general->data_type = COMPLEX_REAL32;
  else if (strncmp(uc(gamma->image_format), "SCOMPLEX", 8) == 0)
    meta->general->data_type = COMPLEX_INTEGER16;
  else if (strncmp(uc(gamma->image_format), "FLOAT", 8) == 0)
    meta->general->data_type = REAL32;
  else if (strncmp(uc(gamma->image_format), "SHORT", 8) == 0)
    meta->general->data_type = INTEGER16;
  else if (strncmp(uc(gamma->image_format), "BYTE", 8) == 0)
    meta->general->data_type = ASF_BYTE;
  if (strcmp(gamma->image_data_type, "UNKNOWN") == 0) {
    switch(meta->general->data_type) 
      {
      case COMPLEX_REAL32:
      case COMPLEX_INTEGER16:
	meta->general->image_data_type = COMPLEX_IMAGE;
	break;
      default:
	meta->general->image_data_type = IMAGE;
	break;
      }
  }
  else {
    if (strncmp(uc(gamma->image_data_type), "RAW_IMAGE", 9) == 0)
      meta->general->image_data_type = RAW_IMAGE;
    if (strncmp(uc(gamma->image_data_type), "COMPLEX_IMAGE", 13) == 0)
      meta->general->image_data_type = COMPLEX_IMAGE;
    if (strncmp(uc(gamma->image_data_type), "AMPLITUDE_IMAGE", 15) == 0)
      meta->general->image_data_type = AMPLITUDE_IMAGE;
    if (strncmp(uc(gamma->image_data_type), "PHASE_IMAGE", 11) == 0)
      meta->general->image_data_type = PHASE_IMAGE;
    if (strncmp(uc(gamma->image_data_type), "COHERENCE_IMAGE", 15) == 0)
      meta->general->image_data_type = COHERENCE_IMAGE;
    if (strncmp(uc(gamma->image_data_type), "POLARIMETRIC_IMAGE", 18) == 0)
      meta->general->image_data_type = POLARIMETRIC_IMAGE;
    if (strncmp_case(gamma->image_data_type, "POLARIMETRIC_SEGMENTATION", 25) == 0)
      meta->general->image_data_type = POLARIMETRIC_SEGMENTATION;
    if (strncmp_case(gamma->image_data_type, "POLARIMETRIC_DECOMPOSITION", 26) == 0)
      meta->general->image_data_type = POLARIMETRIC_DECOMPOSITION;
    if (strncmp_case(gamma->image_data_type, "POLARIMETRIC_PARAMETER", 22) == 0)
      meta->general->image_data_type = POLARIMETRIC_PARAMETER;
    if (strncmp_case(gamma->image_data_type, "POLARIMETRIC_C2_MATRIX", 22) == 0)
      meta->general->image_data_type = POLARIMETRIC_C2_MATRIX;
    if (strncmp_case(gamma->image_data_type, "POLARIMETRIC_C3_MATRIX", 22) == 0)
      meta->general->image_data_type = POLARIMETRIC_C3_MATRIX;
    if (strncmp_case(gamma->image_data_type, "POLARIMETRIC_C4_MATRIX", 19) == 0)
      meta->general->image_data_type = POLARIMETRIC_C4_MATRIX;
    if (strncmp_case(gamma->image_data_type, "POLARIMETRIC_T3_MATRIX", 19) == 0)
      meta->general->image_data_type = POLARIMETRIC_T3_MATRIX;
    if (strncmp_case(gamma->image_data_type, "POLARIMETRIC_T4_MATRIX", 19) == 0)
      meta->general->image_data_type = POLARIMETRIC_T4_MATRIX;
    if (strncmp_case(gamma->image_data_type, 
		     "POLARIMETRIC_STOKES_MATRIX", 26) == 0)
      meta->general->image_data_type = POLARIMETRIC_STOKES_MATRIX;
    if (strncmp(uc(gamma->image_data_type), "LUT_IMAGE", 9) == 0)
      meta->general->image_data_type = LUT_IMAGE;
    if (strncmp(uc(gamma->image_data_type), "ELEVATION", 9) == 0)
      meta->general->image_data_type = ELEVATION;
    if (strncmp(uc(gamma->image_data_type), "DEM", 3) == 0)
      meta->general->image_data_type = DEM;
    if (strncmp(uc(gamma->image_data_type), "IMAGE", 5) == 0)
      meta->general->image_data_type = IMAGE;
    if (strncmp(uc(gamma->image_data_type), "MASK", 4) == 0)
      meta->general->image_data_type = MASK;
  }
  sprintf(meta->general->acquisition_date, "%2d-%s-%4d",
          gamma->acquisition.day, mon[gamma->acquisition.month],
          gamma->acquisition.year);
  meta->general->orbit = gamma->orbit;
  if (gamma->track_angle < -90.0)
    meta->general->orbit_direction = 'D';
  else
    meta->general->orbit_direction = 'A';
  meta->general->frame = MAGIC_UNSET_INT;
  meta->general->band_count = 1;
  strcpy(meta->general->bands, gamma->band);
  meta->general->line_count = gamma->azimuth_pixels;
  meta->general->sample_count = gamma->range_pixels;
  meta->general->start_line = 0;
  meta->general->start_sample = 0;
  meta->general->x_pixel_size = gamma->range_pixel_spacing;
  meta->general->y_pixel_size = gamma->azimuth_pixel_spacing;
  meta->general->center_latitude = gamma->scene_center_latitude;
  meta->general->center_longitude = gamma->scene_center_longitude;
  meta->general->re_major = gamma->earth_semi_major_axis;
  meta->general->re_minor = gamma->earth_semi_minor_axis;
  meta->general->bit_error_rate = MAGIC_UNSET_DOUBLE;
  meta->general->missing_lines = 0;
  meta->general->no_data = MAGIC_UNSET_DOUBLE;
  // Fill SAR block
  meta->sar = meta_sar_init();
  meta->sar->image_type = MAGIC_UNSET_CHAR;
  meta->sar->look_direction = MAGIC_UNSET_CHAR;
  meta->sar->azimuth_look_count = gamma->azimuth_looks;
  meta->sar->range_look_count = gamma->range_looks;
  meta->sar->deskewed = gamma->azimuth_deskew;
  meta->sar->original_line_count = gamma->offset_to_first_echo_to_process + gamma->echoes_to_process;
  meta->sar->original_sample_count = gamma->range_offset + gamma->raw_range_samples;
  meta->sar->line_increment = 1;
  meta->sar->sample_increment = 1;
  meta->sar->range_time_per_pixel = fabs((2.0 * gamma->range_pixel_spacing) / SPD_LIGHT);
  meta->sar->azimuth_time_per_pixel = get_gamma_msp_azimuth_time_per_pixel(gamma);
  meta->sar->slant_range_first_pixel = gamma->near_range_slc;
  meta->sar->slant_shift = 0.0;
  if (meta->general->orbit_direction == 'D')
    meta->sar->time_shift = 0.0;
  else if (meta->general->orbit_direction == 'A')
    meta->sar->time_shift = fabs(meta->sar->original_line_count * meta->sar->azimuth_time_per_pixel);
  else
    meta->sar->time_shift = MAGIC_UNSET_DOUBLE;
  meta->sar->wavelength = MAGIC_UNSET_DOUBLE;
  meta->sar->prf = gamma->prf;
  meta->sar->earth_radius = get_gamma_msp_earth_radius_below_sensor(gamma);
  meta->sar->earth_radius_pp = meta->sar->earth_radius; // KLUDGE: This value is actually unknown in MSP metadata
  meta->sar->satellite_height = sqrt(gamma->sensor_position_vector.x*gamma->sensor_position_vector.x +
      gamma->sensor_position_vector.y*gamma->sensor_position_vector.y +
      gamma->sensor_position_vector.z*gamma->sensor_position_vector.z);
  strcpy(meta->sar->satellite_binary_time, MAGIC_UNSET_STRING);
  strcpy(meta->sar->satellite_clock_time, MAGIC_UNSET_STRING);
  int i;
  if (gamma->doppler_polynomial[3] > 0.0001) {
    // FIXME: If this error ever fires, then we should insert a function that does a
    // quadratic fit to the cubic function.  Then we can derive close 'nuf quadratic
    // values from a set of points generated by the cubic and use those.
    asfPrintError("GAMMA doppler polynomial has a large cubic term\n"
           "(%f versus limit of 0.0001) and is not well modeled by a\nquadratic.",
       gamma->doppler_polynomial[3]);
  }
  for (i=0; i<3; i++) {
    meta->sar->range_doppler_coefficients[i] = gamma->doppler_polynomial[i];
    meta->sar->azimuth_doppler_coefficients[i] = 0.0; // FIXME: We have gamma->radar_frequency and state vectors ...we should estimate the azimuth doppler stuff
  }
  meta->sar->azimuth_processing_bandwidth = MAGIC_UNSET_DOUBLE;
  meta->sar->chirp_rate = MAGIC_UNSET_DOUBLE;
  meta->sar->pulse_duration = MAGIC_UNSET_DOUBLE;
  meta->sar->range_sampling_rate = MAGIC_UNSET_DOUBLE;
  strcpy(meta->sar->polarization, MAGIC_UNSET_STRING);
  meta->sar->multilook = 0;

  // Fill state vector structure
  meta->state_vectors = meta_state_vectors_init(3);
  meta->state_vectors = gamma->stVec;

  // Fill location block
  meta->location = meta_location_init();
  if (meta->general->orbit_direction == 'D') {
    // See comments in gamma.h for map coordinate identification
    meta->location->lat_start_near_range = gamma->map_coordinate_2.lat;
    meta->location->lon_start_near_range = gamma->map_coordinate_2.lon;
    meta->location->lat_start_far_range = gamma->map_coordinate_1.lat;
    meta->location->lon_start_far_range = gamma->map_coordinate_1.lon;
    meta->location->lat_end_near_range = gamma->map_coordinate_4.lat;
    meta->location->lon_end_near_range = gamma->map_coordinate_4.lon;
    meta->location->lat_end_far_range = gamma->map_coordinate_3.lat;
    meta->location->lon_end_far_range = gamma->map_coordinate_3.lon;
  }
  else {
    meta->location->lat_start_near_range = gamma->map_coordinate_3.lat;
    meta->location->lon_start_near_range = gamma->map_coordinate_3.lon;
    meta->location->lat_start_far_range = gamma->map_coordinate_4.lat;
    meta->location->lon_start_far_range = gamma->map_coordinate_4.lon;
    meta->location->lat_end_near_range = gamma->map_coordinate_1.lat;
    meta->location->lon_end_near_range = gamma->map_coordinate_1.lon;
    meta->location->lat_end_far_range = gamma->map_coordinate_2.lat;
    meta->location->lon_end_far_range = gamma->map_coordinate_2.lon;
  }

  return meta;
}
예제 #9
0
meta_parameters* vp2meta(vexcel_plain *vp)
{
  vp_doppler_centroid_parameters doppler_params;
  meta_parameters *meta;
  char *mon[13]={"","Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep",
     "Oct","Nov","Dec"};
  ymd_date ymd, ref_date;
  hms_time time, ref_time;
  julian_date jd;
  int i, nStVec;

  // Initialize the meta structure
  meta = raw_init();

  // Fill general block
  strcpy(meta->general->basename, vp->gli_product.image_desc.title);
  strcpy(meta->general->sensor, vp->sensor.instrument_name);
  strcpy(meta->general->sensor_name, vp->sensor.sensor_name);
  // FIXME: need to handle multibeam data
  strcpy(meta->general->mode, vp->sensor.beam[0].beam_name);
  strcpy(meta->general->processor, vp->gli_product.processor_name);
  if (vp->gli_product.image_desc.bytes_per_pixel == 1)
    meta->general->data_type = ASF_BYTE;
  else if (vp->gli_product.image_desc.bytes_per_pixel == 2)
    meta->general->data_type = INTEGER16;
  else if (vp->gli_product.image_desc.bytes_per_pixel == 4)
    meta->general->data_type = REAL32;
  meta->general->image_data_type = AMPLITUDE_IMAGE;
  meta->general->radiometry = r_AMP;
  date_dssr2date(vp->gli_product.orbit_nr_date, &ymd, &time);
  sprintf(meta->general->acquisition_date, "%2d-%s-%4d", 
	  ymd.day, mon[ymd.month], ymd.year);
  meta->general->orbit = vp->gli_product.orbit_nr;
  if (strncmp(vp->flight_path_direction, "ASCENDING", 9) == 0)
    meta->general->orbit_direction = 'A';
  else
    meta->general->orbit_direction = 'D';
  meta->general->frame = MAGIC_UNSET_INT;
  meta->general->band_count = vp->sensor.nr_beams;
  strcpy(meta->general->bands, "AMP");
  meta->general->line_count = vp->gli_product.image_desc.nr_lines;;
  meta->general->sample_count = vp->gli_product.image_desc.nr_pixels;
  meta->general->start_line = 0;
  meta->general->start_sample = 0;
  meta->general->x_pixel_size = vp->gli_product.image_desc.line_spacing;
  meta->general->y_pixel_size = vp->gli_product.image_desc.pixel_spacing;
  meta->general->center_latitude = 
    vp->gli_product.image_desc.coord.center_line_center_pixel.lat;
  meta->general->center_longitude = 
    vp->gli_product.image_desc.coord.center_line_center_pixel.lon;;
  meta->general->re_major = 
    vp->gli_product.image_desc.coord.earth_model.major;
  meta->general->re_minor = 
    vp->gli_product.image_desc.coord.earth_model.minor;
  meta->general->bit_error_rate = MAGIC_UNSET_DOUBLE;
  meta->general->missing_lines = 0;
  meta->general->no_data = MAGIC_UNSET_DOUBLE;

  // Fill SAR block
  meta->sar = meta_sar_init();
  // working with assumptions here
  meta->sar->image_type = 'G';
  if (vp->sensor.clock_angle >= 0.0)
    meta->sar->look_direction = 'R';
  else
    meta->sar->look_direction = 'L';
  meta->sar->azimuth_look_count = vp->gli_product.azimuth_looks;
  meta->sar->range_look_count = vp->gli_product.range_looks;
  meta->sar->deskewed = vp->gli_product.skew_flag;
  meta->sar->original_line_count = meta->general->line_count;
  meta->sar->original_sample_count = meta->general->sample_count;
  meta->sar->line_increment = 1;
  meta->sar->sample_increment = 1;
  meta->sar->range_time_per_pixel = 
    fabs((2.0 * vp->gli_product.image_desc.pixel_spacing) / SPD_LIGHT);
  meta->sar->azimuth_time_per_pixel = vp->gli_product.time_per_line;
  meta->sar->slant_range_first_pixel = vp->gli_product.near_range;
  meta->sar->slant_shift = 0.0;
  if (meta->general->orbit_direction == 'D')
    meta->sar->time_shift = 0.0;
  else if (meta->general->orbit_direction == 'A')
    meta->sar->time_shift = 
      fabs(meta->sar->original_line_count * meta->sar->azimuth_time_per_pixel);
  else
    meta->sar->time_shift = MAGIC_UNSET_DOUBLE;
  meta->sar->wavelength = SPD_LIGHT / vp->sensor.beam[0].carrier_freq;
  meta->sar->prf = vp->sensor.beam[0].prf;
  meta->sar->earth_radius_pp = MAGIC_UNSET_DOUBLE;
  strcpy(meta->sar->satellite_binary_time, MAGIC_UNSET_STRING);
  strcpy(meta->sar->satellite_clock_time, MAGIC_UNSET_STRING);
  doppler_params = vp->sensor.beam[0].doppler_centroid_parameters;
  // FIXME: Check units for higher coefficients
  meta->sar->range_doppler_coefficients[0] =
    doppler_params.doppler_centroid_coefficients.a[0];
  meta->sar->range_doppler_coefficients[1] =
    doppler_params.doppler_centroid_coefficients.a[1];
  meta->sar->range_doppler_coefficients[2] =
    doppler_params.doppler_centroid_coefficients.a[2];

  for (i=0; i<3; i++)
    meta->sar->azimuth_doppler_coefficients[i] = 0.0;
  meta->sar->azimuth_processing_bandwidth = 
    vp->gli_product.processor_bandwidth;
  meta->sar->chirp_rate = vp->sensor.beam[0].chirp_rate;
  meta->sar->pulse_duration = vp->sensor.beam[0].pulse_length;
  meta->sar->range_sampling_rate = vp->sensor.beam[0].sampling_freq;
  strcpy(meta->sar->polarization,
	 vp->sensor.beam[0].polarization_block.polarization[0].polarization);
  meta->sar->multilook = 1;
  meta->sar->pitch = vp->sensor.ephemeris.attitude.pitch;
  meta->sar->roll = vp->sensor.ephemeris.attitude.roll;
  meta->sar->yaw = vp->sensor.ephemeris.attitude.yaw;

  // Fill state vector structure
  nStVec = vp->sensor.ephemeris.sv_block.nr_sv;
  meta->state_vectors = meta_state_vectors_init(nStVec);
  date_dssr2date(vp->sensor.ephemeris.sv_block.state_vector[0].date, 
		 &ref_date, &ref_time);
  meta->state_vectors->year = ref_date.year;
  date_ymd2jd(&ref_date, &jd);
  meta->state_vectors->julDay = jd.jd;
  meta->state_vectors->second = date_hms2sec(&ref_time);
  meta->state_vectors->vector_count = nStVec;
  for (i=0; i<nStVec; i++) {
    date_dssr2date(vp->sensor.ephemeris.sv_block.state_vector[i].date, 
		   &ymd, &time);
    meta->state_vectors->vecs[i].time = 
      date_difference(&ref_date, &ref_time, &ymd, &time);
    meta->state_vectors->vecs[i].vec.pos.x = 
      vp->sensor.ephemeris.sv_block.state_vector[i].x;
    meta->state_vectors->vecs[i].vec.pos.y =
      vp->sensor.ephemeris.sv_block.state_vector[i].y;
    meta->state_vectors->vecs[i].vec.pos.z =
      vp->sensor.ephemeris.sv_block.state_vector[i].z;
    meta->state_vectors->vecs[i].vec.vel.x = 
      vp->sensor.ephemeris.sv_block.state_vector[i].xv;
    meta->state_vectors->vecs[i].vec.vel.y =
      vp->sensor.ephemeris.sv_block.state_vector[i].yv;
    meta->state_vectors->vecs[i].vec.vel.z =
      vp->sensor.ephemeris.sv_block.state_vector[i].zv;
  }
  date_dssr2date(vp->gli_product.first_line, &ymd, &time);
  double shift = date_difference(&ref_date, &ref_time, &ymd, &time);
  int sign;
  if (compare_time(&ymd, &time, &ref_date, &ref_time) > 0)
    sign = -1;
  else
    sign = 1;
  for (i=0; i<nStVec; i++)
    meta->state_vectors->vecs[i].time += sign * shift;
  meta->state_vectors->second = date_hms2sec(&time);
  double interval = 
    meta->general->line_count * meta->sar->azimuth_time_per_pixel / 2;
  propagate_state(meta, 3, interval);
  meta->sar->earth_radius = 
    meta_get_earth_radius(meta, meta->general->line_count/2, 
			  meta->general->sample_count/2);
  meta->sar->satellite_height = 
    meta_get_sat_height(meta, meta->general->line_count/2,
			meta->general->sample_count/2);  

  // Fill location block
  meta->location = meta_location_init();
  meta->location->lat_start_near_range =
    vp->gli_product.image_desc.coord.first_line_first_pixel.lat;
  meta->location->lon_start_near_range =
    vp->gli_product.image_desc.coord.first_line_first_pixel.lon;
  meta->location->lat_start_far_range =
    vp->gli_product.image_desc.coord.first_line_last_pixel.lat;
  meta->location->lon_start_far_range =
    vp->gli_product.image_desc.coord.first_line_last_pixel.lon;
  meta->location->lat_end_near_range =
    vp->gli_product.image_desc.coord.last_line_first_pixel.lat;
  meta->location->lon_end_near_range =
    vp->gli_product.image_desc.coord.last_line_first_pixel.lon;
  meta->location->lat_end_far_range =
    vp->gli_product.image_desc.coord.last_line_last_pixel.lat;
  meta->location->lon_end_far_range =
    vp->gli_product.image_desc.coord.last_line_last_pixel.lon;

  return meta;
}
예제 #10
0
static int
proj_to_sr(const char *infile, const char *outfile, double pixel_size)
{
    int ii, jj, kk;
    const float_image_sample_method_t sampling_method =
        FLOAT_IMAGE_SAMPLE_METHOD_BILINEAR;

    // overall algorithm:
    // 1. find extents in time/slant space
    // 2. for each pixel in output, resample in input space

    meta_parameters *inMeta = meta_read(infile);
    int nl = inMeta->general->line_count;
    int ns = inMeta->general->sample_count;

    if (!inMeta->projection && !inMeta->transform)
        asfPrintError("Expected a projection/transform block!\n");
    if (!inMeta->state_vectors)
        asfPrintError("Input data does not have state vectors!\n");

    //asfPrintStatus("Converting %s to slant range...\n", infile);

    // first, find extents in time/slant space
    // do this by projecting image corners to time/slant
    int tl_x=0,    tl_y=0;
    int tr_x=ns-1, tr_y=0;
    int bl_x=0,    bl_y=nl-1;
    int br_x=ns-1, br_y=nl-1;

    // we have to find the "real" corners of the image
    // do this using the first band of the input image as a reference
    if (inMeta->general->band_count == 1)
        asfPrintStatus("Tiling the input image...\n");
    else
        asfPrintStatus("Tiling the reference band of the input image...\n");

    FloatImage *in = float_image_new_from_metadata(inMeta, infile);

    // find top left pixel -- TOP-most non-no-data pixel in the image
    for (ii=0; ii<nl; ++ii)
        for (jj=0; jj<ns; ++jj) {
            double val = float_image_get_pixel(in, jj, ii);
            if (val != inMeta->general->no_data && val != 0.0) {
                tl_x = jj; tl_y = ii;
                goto found_tl;
            }
        }

    asfPrintError("Couldn't find top-left pixel! Entire image no data?\n");

  found_tl:

    // find top right pixel -- RIGHT-most non-no-data pixel in the image
    for (jj=ns-1; jj>=0; --jj)
        for (ii=0; ii<nl; ++ii) {
            double val = float_image_get_pixel(in, jj, ii);
            if (val != inMeta->general->no_data && val != 0.0) {
                tr_x = jj; tr_y = ii;
                goto found_tr;
            }
        }

    asfPrintError("Couldn't find top-right pixel! Entire image no data?\n");

  found_tr:

    // find bottom left pixel -- LEFT-most non-no-data pixel in the image
    for (jj=0; jj<ns; ++jj)
        for (ii=nl-1; ii>=0; --ii) {
            double val = float_image_get_pixel(in, jj, ii);
            if (val != inMeta->general->no_data && val != 0.0) {
                bl_x = jj; bl_y = ii;
                goto found_bl;
            }
        }

    asfPrintError("Couldn't find bottom-left pixel! Entire image no data?\n");

  found_bl:

    // find bottom right pixel -- BOTTOM-most non-no-data pixel in the image
    for (ii=nl-1; ii>=0; --ii)
        for (jj=ns-1; jj>=0; --jj) {
            double val = float_image_get_pixel(in, jj, ii);
            if (val != inMeta->general->no_data && val != 0.0) {
                br_x = jj; br_y = ii;
                goto found_br;
            }
        }

    asfPrintError("Couldn't find bottom-right pixel! Entire image no data?\n");

  found_br:

    asfPrintStatus("Determining image extents in time/slant coordinates.\n");
    //asfPrintStatus("Corners are at: TL (%d,%d)\n", tl_y, tl_x);
    //asfPrintStatus(" (line,sample)  TR (%d,%d)\n", tr_y, tr_x);
    //asfPrintStatus("                BL (%d,%d)\n", bl_y, bl_x);
    //asfPrintStatus("                BR (%d,%d)\n", br_y, br_x);

    double tl_time, tl_slant;
    double tr_time, tr_slant;
    double bl_time, bl_slant;
    double br_time, br_slant;

    meta_get_timeSlantDop(inMeta, tl_y, tl_x, &tl_time, &tl_slant, NULL);
    meta_get_timeSlantDop(inMeta, tr_y, tr_x, &tr_time, &tr_slant, NULL);
    meta_get_timeSlantDop(inMeta, bl_y, bl_x, &bl_time, &bl_slant, NULL);
    meta_get_timeSlantDop(inMeta, br_y, br_x, &br_time, &br_slant, NULL);

    //asfPrintStatus("Corners are at: TL (%f,%f)\n", tl_time, tl_slant);
    //asfPrintStatus(" (time,slant)   TR (%f,%f)\n", tr_time, tr_slant);
    //asfPrintStatus("                BL (%f,%f)\n", bl_time, bl_slant);
    //asfPrintStatus("                BR (%f,%f)\n", br_time, br_slant);

    double slant_start = min4(tl_slant, tr_slant, bl_slant, br_slant);
    double slant_end = max4(tl_slant, tr_slant, bl_slant, br_slant);

    double time_min = min4(tl_time, tr_time, bl_time, br_time);
    double time_max = max4(tl_time, tr_time, bl_time, br_time);

    double slant_incr;
    double time_start, time_end, time_incr;
    int onl, ons;

    if (pixel_size > 0) {
        slant_incr = pixel_size;
        ons = (slant_end - slant_start) / slant_incr;

        if (inMeta->sar) {
            // in this case, the original data has a SAR block, we will use the
            // same azimuth time per pixel.
            time_incr = inMeta->sar->azimuth_time_per_pixel;

            // we always want to be DECREASING in time
            // latest time is on top (line 1), earliest on bottom (line ONL)
            if (time_incr > 0) {
                time_incr = -time_incr;
                inMeta->sar->azimuth_time_per_pixel =
                    -inMeta->sar->azimuth_time_per_pixel;
            }

            time_start = time_max;
            time_end = time_min;

            onl = (time_end - time_start) / time_incr;
        }
        else {
            // here, no sar block in the original data, just make a square
            // image with decreasing time
            onl = ons;
            time_incr = (time_min - time_max) / (double)onl;
            time_start = time_max;
            time_end = time_min;
        }
    }
    else {
        // not provided a slant range pixel size, we'll figure something out

        if (inMeta->sar) {
            // use the same azimuth time per pixel.
            time_incr = inMeta->sar->azimuth_time_per_pixel;

            // we always want to be DECREASING in time
            // latest time is on top (line 1), earliest on bottom (line ONL)
            if (time_incr > 0) {
                time_incr = -time_incr;
                inMeta->sar->azimuth_time_per_pixel =
                    -inMeta->sar->azimuth_time_per_pixel;
            }

            time_start = time_max;
            time_end = time_min;

            onl = (time_end - time_start) / time_incr;
        }
        else {
            // no info... determine azimuth time per pixel by keeping
            // the height the same as in the original image
            onl = nl;
            time_incr = (time_min - time_max) / (double)onl;
            time_start = time_max;
            time_end = time_min;
        }

        // make it square, to get the slant range pixel size
        ons = onl;
        pixel_size = slant_incr = (slant_end - slant_start) / (double)ons;
    }

    asfRequire(onl > 0, "Internal Error: Invalid output line count: %d\n", onl);
    asfRequire(ons > 0, "Internal Error: Invalid output sample count: %d\n", ons);

    asfPrintStatus("  Slant range values: %f -> %f\n", slant_start, slant_end);
    asfPrintStatus("  Slant range pixel size: %f\n", pixel_size);
    asfPrintStatus("  Time values: %f -> %f\n", time_start, time_end);
    asfPrintStatus("  Output Image will be %5d x %5d LxS\n", onl, ons);
    asfPrintStatus("      (Input Image was %5d x %5d LxS)\n", nl, ns);

    // generate a grid over the image, to generate our splines
    // this grid size seems to work pretty well...
    int n = 120;

    asfPrintStatus("Creating %dx%d mapping grid...\n", n, n);
 
    // changed how these are calculated, so that the spline will cover
    // the entire value range
    double time_grid_incr = fabs(time_end - time_start) / (double)(n-1);
    if (time_incr < 0) time_grid_incr = -time_grid_incr;
    double slant_grid_incr = fabs(slant_end - slant_start) / (double)(n-1);
    if (slant_incr < 0) slant_grid_incr = -slant_grid_incr;    

    // allocating memory for the splines, and the arrays to generate them
    gsl_interp_accel **samp_accels = MALLOC(sizeof(gsl_interp_accel *) * n);
    gsl_spline **samp_splines = MALLOC(sizeof(gsl_spline *) * n);

    gsl_interp_accel **line_accels = MALLOC(sizeof(gsl_interp_accel *) * n);
    gsl_spline **line_splines = MALLOC(sizeof(gsl_spline *) * n);

    double *slant_in = MALLOC(sizeof(double)*n);
    double *line_out = MALLOC(sizeof(double)*n);
    double *samp_out = MALLOC(sizeof(double)*n);

    // an alias -- use the same array (to save memory -- these are not used
    // at the same time), but create an alias for it, so it is not so confusing
    double *time_in = slant_in;
    //double max_err = 0;

    // set up the vertical splines
    for (jj=0; jj<n; ++jj) {
        double slant = slant_start + jj*slant_grid_incr;

        for (ii=0; ii<n; ++ii) {
            // splines need strictly increasing range variables
            if (time_grid_incr > 0)
                time_in[ii] = time_start + ii*time_grid_incr;
            else
                time_in[ii] = time_end - ii*time_grid_incr;

            ts2ls(inMeta, time_in[ii], slant, &line_out[ii], &samp_out[ii]);
            //printf("time: %f, slant: %f ==> line: %f, samp %f\n",
            //       time_in[ii], slant, line_out[ii], samp_out[ii]);
        }

        samp_accels[jj] = gsl_interp_accel_alloc();
        samp_splines[jj] = gsl_spline_alloc(gsl_interp_cspline, n);
        gsl_spline_init(samp_splines[jj], time_in, samp_out, n);

        line_accels[jj] = gsl_interp_accel_alloc();
        line_splines[jj] = gsl_spline_alloc(gsl_interp_cspline, n);
        gsl_spline_init(line_splines[jj], time_in, line_out, n);
    }

    // now, we're on to the resampling stage.. loop through output pixels
    asfPrintStatus("Generating slant range image...\n");

    double no_data_value = meta_is_valid_double(inMeta->general->no_data) ?
        inMeta->general->no_data : 0;

    // keep track of error sizes
    double max_error = 0;
    double avg_error = 0;
    int count = 0;

    // these stride values allow us to track when we're in between grid points
    int ii_n = onl/n;
    int jj_n = ons/n;
    int ii_n2 = ii_n/2;
    int jj_n2 = jj_n/2;

    // set up output metadata
    meta_parameters *outMeta = meta_read(infile);

    if (outMeta->transform) {
        FREE(outMeta->transform);
        outMeta->transform = NULL;
    }

    if (outMeta->projection) {
        FREE(outMeta->projection);
        outMeta->projection = NULL;
    }

    outMeta->general->line_count = onl;
    outMeta->general->sample_count = ons;

    if (!outMeta->sar)
        outMeta->sar = meta_sar_init();

    outMeta->sar->image_type = 'S';

    outMeta->sar->azimuth_time_per_pixel = time_incr;
    assert(outMeta->sar->azimuth_time_per_pixel < 0);

    outMeta->sar->time_shift = time_start;

    outMeta->general->y_pixel_size = inMeta->sar->azimuth_time_per_pixel / 
                                     time_incr * inMeta->general->y_pixel_size;
    assert(outMeta->general->y_pixel_size > 0);

    outMeta->sar->slant_range_first_pixel = slant_start;
    outMeta->general->x_pixel_size = slant_incr;

    outMeta->sar->line_increment = outMeta->sar->sample_increment = 1;
    outMeta->general->start_sample = outMeta->general->start_line = 0;

    outMeta->general->no_data = no_data_value;

    char **band_name = extract_band_names(inMeta->general->bands,
                                          inMeta->general->band_count);

    // now generate output image
    char *img_file = appendExt(outfile, ".img");
    float *out = MALLOC(sizeof(float) * ons);

    for (kk=0; kk<inMeta->general->band_count; ++kk) {
        if (inMeta->general->band_count != 1)
            asfPrintStatus("Working on band: %s\n", band_name[kk]);

        // for the 2nd and higher bands, free the band from the previous iteration,
        // and read in the next band from the input image
        if (kk>0) {
            float_image_free(in);
            asfPrintStatus("Loading input...\n");
            in = float_image_band_new_from_metadata(inMeta, kk, infile);
        }

        FILE *ofp = FOPEN(img_file, kk==0 ? "wb" : "ab");
        asfPrintStatus("Generating output...\n");
        for (ii=0; ii<onl; ++ii) {
            asfLineMeter(ii,onl);
            double time = time_start + ii * time_incr;

            // set up horizontal splines for this row
            gsl_interp_accel *samp_accel = gsl_interp_accel_alloc();
            gsl_spline *samp_spline = gsl_spline_alloc(gsl_interp_cspline, n);

            gsl_interp_accel *line_accel = gsl_interp_accel_alloc();
            gsl_spline *line_spline = gsl_spline_alloc(gsl_interp_cspline, n);

            //printf("time: %f slant: %f\n", time, slant_start);
            for (jj=0; jj<n; ++jj) {
                slant_in[jj] = slant_start + jj * slant_grid_incr;
                //printf("time: %f slant: %f\n", time, slant_in[jj]);
                samp_out[jj] = gsl_spline_eval_check(samp_splines[jj], time,
                                               samp_accels[jj]);
                line_out[jj] = gsl_spline_eval_check(line_splines[jj], time,
                                               line_accels[jj]);
                //printf("samp_out: %f line_out: %f\n", samp_out[jj], line_out[jj]);
            }

            gsl_spline_init(samp_spline, slant_in, samp_out, n);
            gsl_spline_init(line_spline, slant_in, line_out, n);

            // use the splines to produce output pixels
            for (jj=0; jj<ons; ++jj) {
                double slant = slant_start + jj * slant_incr;
                double samp = gsl_spline_eval_check(samp_spline, slant, samp_accel);
                double line = gsl_spline_eval_check(line_spline, slant, line_accel);

                // check the spline every so often (halfway between grid points)
                // only do this on band #1 (the reference band)
                if (kk==0 && ii%ii_n2==0 && 
                    ii%ii_n!=0 && jj%jj_n2==0 && jj%jj_n!=0)
                {
                    double samp_real, line_real;
                    ts2ls(inMeta, time, slant, &line_real, &samp_real);

                    double err = (line-line_real)*(line-line_real) +
                                 (samp-samp_real)*(samp-samp_real);

                    //printf("(%d,%d) -- Actual: (%f,%f) Splined: (%f,%f)\n",
                    //       ii, jj, line_real, samp_real, line, samp);

                    if (err > max_error) max_error = err;
                    avg_error += err;
                    ++count;
                }

                // now interpolate within the original image
                // if we are outside, use "no_data" from metadata
                double val = no_data_value;
                if (line > 0 && line < nl-1 && samp > 0 && samp < ns-1)
                    val = float_image_sample(in, samp, line, sampling_method);

                out[jj] = (float)val;
            }

            gsl_interp_accel_free(samp_accel);
            gsl_spline_free(samp_spline);

            gsl_interp_accel_free(line_accel);
            gsl_spline_free(line_spline);

            put_float_line(ofp, outMeta, ii, out);
        }

        fclose(ofp);
    }

    // free the last band of the input
    float_image_free(in);

    FREE(slant_in);
    FREE(line_out);
    FREE(samp_out);

    for (ii=0; ii<n; ++ii) {
        gsl_interp_accel_free(samp_accels[ii]);
        gsl_spline_free(samp_splines[ii]);
        gsl_interp_accel_free(line_accels[ii]);
        gsl_spline_free(line_splines[ii]);
    }

    FREE(samp_accels);
    FREE(samp_splines);
    FREE(line_accels);
    FREE(line_splines);

    FREE(out);

    for (kk=0; kk<inMeta->general->band_count; ++kk)
        FREE(band_name[kk]);
    FREE(band_name);

    // see how bad our errors were
    avg_error /= (double)count;
    asfPrintStatus("Model max error: %f, avg: %f\n",
                   max_error, avg_error);

    double thresh = 0.1;
    if (max_error > 100*thresh)
        asfPrintError("Maximum error exceeded threshold: %f > %f\n",
                      max_error, 100*thresh);
    else if (avg_error > 10*thresh)
        asfPrintError("Average error exceeded threshold: %f > %f\n",
                      avg_error, 10*thresh);
    if (max_error > 10*thresh)
        asfPrintWarning("Maximum error exceeds threshold: %f > %f\n",
                        max_error, 10*thresh);
    if (avg_error > thresh)
        asfPrintWarning("Average error exceeds threshold: %f > %f\n",
                        avg_error, thresh);

    char *meta_file = appendExt(outfile, ".meta");
    asfPrintStatus("Writing %s\n", meta_file);
    meta_write(outMeta, meta_file);
    free(meta_file);
    free(img_file);

    meta_free(outMeta);
    meta_free(inMeta);

    return 0; //success
}
예제 #11
0
main(int argc, char *argv[]) 
{
  FILE *fpin, *fpout;
  
  float ibuff[CPX_PIX*2*LD];
  float **obuff;
  float b[CPX_PIX];
  float c[CPX_PIX/LA];

  int cla,nl;
  int i,j,k,line;
  int olines, osamps;
  int oline, osamp;
  double t;
  char basefile[256], infile[256], outbasefile[256], outfile[256], roifile[256];
  char *hdrfile;
  
  ymd_date date;
  hms_time time;
  meta_parameters *meta;

  char *mon[13]={"","Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep",
     "Oct","Nov","Dec"};
  
  char	 dir;			// orbit direction - A or D
  double x, y, z;		// state vector positions at start of segment
  double xdot, ydot, zdot;	// state vector veloctiy at start of segment
  int    META_ONLY = 0;		// only create meta file, no img file
  int	 SEPARATE_ROI_FILE = 0; // CLA roi file given?
  int    USE_TLES = 1;		// TLE/state vector switch
  int    ESA_FRAME = 0;		// switch to control output file names
  int    node = 0;
   
  asfSplashScreen(argc, argv); 

  if (argc<2 || argc>9) { give_usage(argc,argv); exit(1); }

  while ((cla=getopt(argc,argv,"mvcE:r:")) != -1)
    switch(cla) {
      case 'm':
        META_ONLY = 1;
	printf("Using meta only option\n");
	break;
      case 'r':
	strcpy(roifile,optarg);
	SEPARATE_ROI_FILE = 1;
	break;
      case 'E':
        ESA_FRAME = 1;
	node = atoi(optarg);
	break;
      case 'v':
        USE_TLES = 0;
	break;
      case 'c':
        USE_CLOCK_DRIFT = 1;
	break;
      case '?':
        give_usage(argc,argv);
        printf("Unknown option %s\n",optarg);
	exit(1);
      default:
        give_usage(argc,argv);
	exit(1);
    } 

  strcpy(basefile,argv[optind]);
  strcpy(infile,basefile);
  strcat(infile,".slc");

  /* if no separate roi.in file is specified, use the main name */
  if (SEPARATE_ROI_FILE == 0) {
    strcpy(roifile,basefile);
    strcat(roifile,".roi.in");
  }

  /* Read parameters from the ROI.in file */
  read_roi_infile(roifile);
  nl = npatches * patch_size;
  hdrfile = get_basename(datfilename);
  strcat(hdrfile,".hdr");
  
  /* Read the start time for this image from the hdr file */
  read_hdrfile(hdrfile);
  
  if (USE_TLES == 0) 
   {
    int cnt;
    int year, month, day, hour, min;
    double sec, thisSec;
    FILE *fpvec, *fpo;
    char tmp[256];
  
    sprintf(tmp,"/home/talogan/Seasat_State_Vectors/%3i.ebf",start_date);
    fpvec = fopen(tmp,"r");
    if (fpvec == NULL) {
      printf("Unable to open state vector file for day %i\n",start_date); 
      printf("Defaulting to using TLEs instead\n");
      USE_TLES = 1;
    } else {
      cnt = fscanf(fpvec,"%i %i %i %i %i %lf %lf %lf %lf %lf %lf %lf",&year,&month,&day,&hour,&min,&sec,&x,&y,&z,&xdot,&ydot,&zdot);
      thisSec = (double) ((hour*60+min)*60)+sec;

      /* seek to the correct second of the day for the START of this file 
      -----------------------------------------------------------------*/
      while (cnt == 12 && start_sec > (thisSec+1.0)) {
        cnt = fscanf(fpvec,"%i %i %i %i %i %lf %lf %lf %lf %lf %lf %lf",&year,&month,&day,&hour,&min,&sec,&x,&y,&z,&xdot,&ydot,&zdot);
        thisSec = (double) ((hour*60+min)*60)+sec;
      }
      printf("Found closest second %lf\n",thisSec);
  
      /* need to create a state vector file the start of this image
      ------------------------------------------------------------*/
      stateVector vec, last_vec;
      last_vec.pos.x = x; last_vec.pos.y = y; last_vec.pos.z = z;
      last_vec.vel.x = xdot; last_vec.vel.y = ydot; last_vec.vel.z = zdot;
      vec = propagate(last_vec,thisSec,start_sec);
      x = vec.pos.x; y = vec.pos.y; z = vec.pos.z;
      xdot = vec.vel.x; ydot = vec.vel.y; zdot = vec.vel.z;
    }
   }
  
  if (USE_TLES == 1) {
    /* get the correct state vector */
    printf("Propagating state vectors to requested time...\n");
    create_input_tle_file(s_date,s_time,"tle1.txt");
    propagate_state_vector("tle1.txt"); 
    printf("\n\nConverting state vectors from ECI to ECEF\n");
    fix_state_vectors(s_date.year,s_date.jd,s_time.hour,s_time.min,s_time.sec);
    remove("tle1.txt");
    remove("propagated_state_vector.txt");

    printf("Reading first state vector\n");
    FILE *fpvec = fopen("fixed_state_vector.txt","r");
    if (fscanf(fpvec,"%lf %lf %lf %lf %lf %lf %lf\n",&t,&x,&y,&z,&xdot,&ydot,&zdot)!=7) 
      { printf("ERROR: Unable to find state vector in fixed_state_vector.txt file\n"); exit(1); }
    fclose(fpvec);
    remove("fixed_state_vector.txt");
  }
  if (zdot > 0.0) dir = 'A'; else dir = 'D';

  /* set up output image parameters */
  olines = nl / LD;
  osamps = ns / LA;

  /* Create the meta file */
  printf("Initializing the meta structure\n");
  meta = raw_init();

  /* Propagate the state vectors */  
  printf("Creating state vectors\n");
  stateVector stVec;/*Source state vector*/

  stVec.pos.x = x;
  stVec.pos.y = y;
  stVec.pos.z = z;
  stVec.vel.x = xdot;
  stVec.vel.y = ydot;
  stVec.vel.z = zdot;

  date_jd2ymd(&s_date,&date);

  meta->state_vectors = meta_state_vectors_init(1);
  meta->state_vectors->vecs[0].vec = stVec;
  meta->state_vectors->year = date.year;
  meta->state_vectors->julDay = s_date.jd;
  meta->state_vectors->second = date_hms2sec(&s_time);
  meta->state_vectors->vecs[0].time = 0;
  int num_vecs = 2 + (int)(nl*PRI)/30.0;
  propagate_state(meta, num_vecs+1, (nl*PRI)/num_vecs);

  printf("Calculating scene geometry parameters\n");

  double RE = r_awgs84;
  double RP = r_awgs84 * sqrt(1-r_e2wgs84);
  
  double imgSec=date2sec(&s_date,&s_time);					// time at start of image
  int num = meta->state_vectors->num / 2;					// closest state vector to center of image
  double sourceSec = imgSec+meta->state_vectors->vecs[num].time;		// time at closest state vector
  double destSec = imgSec+meta->state_vectors->vecs[meta->state_vectors->num-1].time/2;	// time at center of image

  printf("Finding center state vector\n");
  stateVector midVec = propagate(meta->state_vectors->vecs[num].vec,sourceSec,destSec);	// state vector at middle time of image
      
  x = midVec.pos.x;
  y = midVec.pos.y;
  z = midVec.pos.z;
  xdot = midVec.vel.x;
  ydot = midVec.vel.y;
  zdot = midVec.vel.z;
  
  double geocentric_lat_nadir = asin(z / sqrt (x*x+y*y+z*z));
  double lon_nadir = atan2(x,y)*180/M_PI;
  double RE_nadir = (RE * RP) / sqrt((RP*cos(geocentric_lat_nadir)*RP*cos(geocentric_lat_nadir)) +
  				     (RE*sin(geocentric_lat_nadir)*RE*sin(geocentric_lat_nadir)));
  double Rsc = sqrt(x*x+y*y+z*z);
  double geodetic_lat_nadir = atan(tan(geocentric_lat_nadir)/(1-r_e2wgs84));
  double lat_nadir = geodetic_lat_nadir*180/M_PI;
  double gamma = geodetic_lat_nadir - geocentric_lat_nadir;
    
  printf("Filling in meta->general parameters\n");
  
  strcpy(meta->general->sensor,"SEASAT");
  strcpy(meta->general->sensor_name,"SAR");
  strcpy(meta->general->mode,"STD");
  strcpy(meta->general->processor,"ASPS-v" ASPS_VERSION_STRING);
  meta->general->data_type = REAL32;
  meta->general->image_data_type = AMPLITUDE_IMAGE;
  meta->general->radiometry = r_AMP;
  sprintf(meta->general->acquisition_date, "%02d-%s-%4d %02d:%02d:%02.0f",
          date.day, mon[date.month], date.year, s_time.hour, s_time.min, s_time.sec);
  meta->general->orbit = time2rev(s_date,s_time);
  meta->general->orbit_direction = dir;
  if (ESA_FRAME == 1) meta->general->frame = node;
  meta->general->band_count = 1;
  strcpy(meta->general->bands,"HH");
  meta->general->line_count = nl/LD;
  meta->general->sample_count = ns/LA;
  meta->general->start_line = 0; 
  meta->general->start_sample = 0;
  meta->general->line_scaling = 1;
  meta->general->sample_scaling = 1;
  meta->general->x_pixel_size = (C / (2.0 * fs)) * LA;
 
  switch (station_code) {
    case 5:
      strcpy(meta->general->receiving_station, "ULA");
      break;
    case 6:
      strcpy(meta->general->receiving_station, "GDS");
      break;
    case 7:
      strcpy(meta->general->receiving_station, "MIL");
      break;
    case 9:
      strcpy(meta->general->receiving_station, "UKO");
      break;
    case 10:
      strcpy(meta->general->receiving_station, "SNF");
      break;
  }
 
  double orbit_vel = sqrt(9.81*RE_nadir*RE_nadir / Rsc);
  double swath_vel = orbit_vel * RE_nadir / Rsc;
  
  meta->general->y_pixel_size = (swath_vel * PRI) * LD;    // TAL - Check the sc_vel...
  meta->general->re_major = r_awgs84;
  meta->general->re_minor = r_awgs84 * sqrt(1-r_e2wgs84);
  
//  meta->general->bit_error_rate = ???
//  meta->general->missing_lines = ???  
//  meta->general->no_data = ???

      
  /*Create the SAR metadata block*/
  
  printf("Creating the meta->sar block\n");
  if (!meta->sar) meta->sar = meta_sar_init();

  meta->sar->image_type = 'S';
  meta->sar->look_direction = 'R';
  meta->sar->azimuth_look_count = LD;
  meta->sar->range_look_count = LA;
  meta->sar->deskewed = 0;
  meta->sar->original_line_count = nl;
  meta->sar->original_sample_count = ns;
  meta->sar->line_increment = 1;
  meta->sar->sample_increment = 1;
  meta->sar->range_time_per_pixel = 1/(2*fs);
  
  // Should be this, right???    meta->sar->azimuth_time_per_pixel = PRI;
  // Second try is this one	 meta->sar->azimuth_time_per_pixel = (destSec - imgSec) / (meta->sar->original_line_count/2);
  
  meta->sar->azimuth_time_per_pixel = meta->general->y_pixel_size / swath_vel;
  meta->sar->azimuth_time_per_pixel *= -1;
  meta->sar->time_shift = fabs(meta->general->line_count*meta->sar->azimuth_time_per_pixel);
  
//  meta->sar->slant_shift = -1080;			// emperical value from a single delta scene
//  meta->sar->time_shift = 0.18;			// emperical value from a single delta scene

  if (USE_CLOCK_DRIFT ==1) meta->sar->slant_shift = SEASAT_SLANT_SHIFT; // -1000.0;
  else meta->sar->slant_shift = 0.0;

  meta->sar->slant_range_first_pixel = srf;
  meta->sar->wavelength = wavelength;
  meta->sar->prf = prf;
  meta->sar->earth_radius = meta_get_earth_radius(meta,	meta->general->line_count/2.0, meta->general->sample_count/2.0);
  meta->sar->satellite_height = Rsc;
  meta->sar->range_doppler_coefficients[0] = dop1*prf;
  meta->sar->range_doppler_coefficients[1] = dop2*prf;
  meta->sar->range_doppler_coefficients[2] = dop3*prf;
  meta->sar->azimuth_doppler_coefficients[0] = dop1*prf;
  meta->sar->azimuth_doppler_coefficients[1] = 0;
  meta->sar->azimuth_doppler_coefficients[2] = 0;
  
///  meta->sar->azimuth_processing_bandwidth = ????
  
  meta->sar->chirp_rate = chirp_slope;
  meta->sar->pulse_duration = pulse_duration;
  meta->sar->range_sampling_rate = fs;
  strcpy(meta->sar->polarization,"HH");
  meta->sar->multilook = 1;
  meta->sar->pitch = 0;
  meta->sar->roll = 0;
  meta->sar->yaw = 0;
///  meta->sar->incid_a[0-5] = ???

  printf("Creating the meta->location block\n");
  if (!meta->location) meta->location = meta_location_init();
  meta_get_corner_coords(meta);
  meta_get_latLon(meta,meta->general->line_count/2,meta->general->sample_count/2,0,
  		  &meta->general->center_latitude, &meta->general->center_longitude);

  if (ESA_FRAME==0) {
    strcpy(outbasefile,basefile);
  } else {
    sprintf(outbasefile,"SS_%.5i_SLANT_F%.4i",meta->general->orbit,meta->general->frame);
  }

  strcpy(outfile,outbasefile);
  strcat(outfile,".img");
  strcpy(meta->general->basename,outbasefile);

  if (META_ONLY==0) { 
    obuff = (float **) malloc (sizeof(float *)*olines);
    for (i=0; i<olines; i++) obuff[i] = (float *) malloc (sizeof(float)*osamps);
  
    /* Open the input slc file and output img file*/
    fpin = fopen(infile,"rb");
    if (fpin==NULL) {printf("ERROR: Unable to open input file %s\n",infile); exit(1);}
    fpout = fopen(outfile,"wb");

    /* Take the complex looks from the slc file to create the img file */
    printf("Taking complex looks from file %s to create %s\n",infile,outfile);
    oline = 0;
    for (line=0; line < nl; line+=LD) {
      if (line%2560==0) printf("\t%i\n",line);
      fread(ibuff,sizeof(float),ns*2*LD,fpin);

      /* take looks down */
      for (j=0; j<ns; j++) {
        b[j] = 0;
        for (i=0; i<LD; i++)
          b[j] = b[j] + (ibuff[(2*j)+(i*ns*2)]*ibuff[2*j+(i*ns*2)]) 
  		      + (ibuff[(2*j+1)+(i*ns*2)]*ibuff[(2*j+1)+(i*ns*2)]);    
      }
    
      /* take looks across */
      for (j=0; j<ns/LA; j++) {
        c[j] = 0;
        for (k=0;k<LA;k++)
          c[j] = c[j] + b[j*LA+k];
        c[j] = sqrt(c[j]);
      }
      byteswap(c,ns/LA);
      for (j=0; j<osamps; j++) obuff[oline][j] = c[j];
      oline++;
    }

    /* write out image in reverse order */
    for (j=0; j<olines; j++) fwrite(obuff[olines-j-1],sizeof(float),osamps,fpout); 
 
    fclose(fpout);
    fclose(fpin);
    free(obuff);
    
  }  /* END IF META_ONLY */   

  printf("Writing out the meta file\n");
  meta_write(meta, outbasefile);

  if (META_ONLY == 0) {
    char grfilename[256];
    float grPixSiz = 12.5;
    int err = 0;
    if (ESA_FRAME == 1) {
      char tmpstr[256];
      char cropfile[256];
      char tmpfile[256];
      
      /* create the ground range image */
      sprintf(grfilename,"temp_%.5i_STD_F%.4i",meta->general->orbit,meta->general->frame);
      sr2gr_pixsiz(outbasefile, grfilename, grPixSiz);
      
      /* crop the image to exact size */
      sprintf(cropfile,"SS_%.5i_STD_F%.4i",meta->general->orbit,meta->general->frame);
      trim(grfilename,cropfile,(long long)0,(long long)0,(long long)8000,(long long)8000);
      
      /* remove the non-cropped ground range image */
      strcat(strcpy(tmpstr,grfilename),".img");
      remove(tmpstr);
      strcat(strcpy(tmpstr,grfilename),".meta");
      remove(tmpstr);

      /* geocode and export to geotiff */
      sprintf(tmpstr,"asf_geocode -p utm %s %s_utm\n",cropfile,cropfile);
      err = system(tmpstr);
      if (err) {printf("Error returned from asf_geocode\n"); exit(1);}

      sprintf(tmpstr,"asf_export -format geotiff %s_utm %s\n",cropfile,cropfile);
      err = system(tmpstr);
      if (err) {printf("Error returned from asf_export to geotiff\n"); exit(1);}
 
      /* remove the utm projected internal format image */
      strcat(strcpy(tmpstr,cropfile),"_utm.img");
      remove(tmpstr);
      strcat(strcpy(tmpstr,cropfile),"_utm.meta");
      remove(tmpstr);
 
      /* this changes the basename in the metadata from blah_SLANT to blah_STD  */
      meta_parameters *crop_meta = meta_read(cropfile);
      strcpy(crop_meta->general->basename, cropfile);
      meta_write(crop_meta, cropfile);
      meta_free(crop_meta);
 
      /* create the dowsized QC image */
      sprintf(tmpstr,"resample -scale 0.125 %s %s_small\n",cropfile,cropfile);
      err = system(tmpstr);
      if (err) {printf("Error returned from resample\n"); exit(1);}
      
      sprintf(tmpfile,"%s_QCFULL",cropfile);
      sprintf(tmpstr,"asf_export -format jpeg %s_small %s\n",cropfile,tmpfile);
      err = system(tmpstr);
      if (err) {printf("Error returned from asf_export to jpeg\n"); exit(1);}
      
      /* remove the small .img file */
      strcat(strcpy(tmpstr,cropfile),"_small.img");
      remove(tmpstr);
      strcat(strcpy(tmpstr,cropfile),"_small.meta");
      remove(tmpstr);

      /* create the subsampled QC image */
      sprintf(tmpfile,"%s_QCSUB",cropfile);
      trim(cropfile,tmpfile,(long long)3500,(long long)3500,(long long)1000,(long long)1000);

      sprintf(tmpstr,"asf_export -format jpeg %s %s\n",tmpfile,tmpfile);
      err = system(tmpstr);
      if (err) {printf("Error returned from asf_export\n"); exit(1);}

      /* run make_seasat_h5 */
      sprintf(tmpstr,"make_seasat_h5 -gap %s.dis %s %s",basefile,cropfile,cropfile);
      err = system(tmpstr);
      if (err) {printf("Error returned from make_seasat_h5\n"); exit(1);}

      /* remove the subsampled QC .img file */
      strcat(strcpy(tmpstr,tmpfile),".img");
      remove(tmpstr);
      strcat(strcpy(tmpstr,tmpfile),".meta");
      remove(tmpstr);

      /* rename the ROI.in file to match the new file name */
      sprintf(tmpfile,"%s.roi.in",cropfile);
      rename(roifile,tmpfile);

    } else {
      strcpy(grfilename,basefile);
      strcat(grfilename,"G12");
      sr2gr_pixsiz(basefile, grfilename, grPixSiz);
    } 
  }

  exit(0);
}