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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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 }
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); }