void ceos_init_alos_stVec(const char *fName, ceos_description *ceos, meta_parameters *meta) { struct pos_data_rec ppdr; // Read platform position record get_ppdr(fName,&ppdr); // Initialize state vector int vector_count=3; double data_int = meta->sar->original_line_count / 2 * fabs(meta->sar->azimuth_time_per_pixel); while (fabs(data_int) > 15.0) { data_int /= 2; vector_count = vector_count*2-1; } meta->state_vectors = meta_state_vectors_init(vector_count); meta->state_vectors->vector_count = vector_count; // Determine image start time ymd_date imgDate; julian_date imgJD; hms_time imgTime; date_dssr2date(ceos->dssr.inp_sctim, &imgDate, &imgTime); date_ymd2jd(&imgDate, &imgJD); double imgSec = date2sec(&imgJD, &imgTime); imgSec -= ceos->dssr.sc_lin*fabs(meta->sar->azimuth_time_per_pixel); sec2date(imgSec, &imgJD, &imgTime); meta->state_vectors->year = (int) imgJD.year; meta->state_vectors->julDay = (int) imgJD.jd; meta->state_vectors->second = date_hms2sec(&imgTime); // Assign position and velocity for center of image int n = (vector_count - 1)/2; double timeStart = get_timeDelta(ceos, &ppdr, meta); double time = timeStart + n*data_int; stateVector st; st.pos.x = ppdr.orbit_ele[0]; st.pos.y = ppdr.orbit_ele[1]; st.pos.z = ppdr.orbit_ele[2]; st.vel.x = ppdr.orbit_ele[3]; st.vel.y = ppdr.orbit_ele[4]; st.vel.z = ppdr.orbit_ele[5]; meta->state_vectors->vecs[n].vec = st; meta->state_vectors->vecs[n].time = time - timeStart; int ii; double newTime; for (ii=0; ii<n; ii++) { newTime = time - (n - ii)*data_int; meta->state_vectors->vecs[ii].time = newTime - timeStart; meta->state_vectors->vecs[ii].vec = propagate(st, time, newTime); } for (ii=n+1; ii<vector_count; ii++) { newTime = time + (vector_count - n - 1)*data_int; meta->state_vectors->vecs[ii].time = newTime - timeStart; meta->state_vectors->vecs[ii].vec = propagate(st, time, newTime); } }
terrasar_meta *read_terrasar_meta(const char *dataFile) { int ii, kk, numStateVectors, numDopplerEstimates; ymd_date imgStartDate, imgDopplerDate, date; hms_time imgStartTime, imgDopplerTime, time; julian_date julianDate; char timeStr[30], str[50]; tsx_doppler_params *tsx; terrasar_meta *terrasar = terrasar_meta_init(); if (!fileExists(dataFile)) asfPrintError("Metadata file (%s) does not exist!\n", dataFile); xmlDoc *doc = xmlReadFile(dataFile, NULL, 0); if (!doc) asfPrintError("Could not parse file %s\n", dataFile); strcpy(terrasar->filename, xml_get_string_value(doc, "level1Product.productComponents.annotation.file.location.filename")); strcpy(terrasar->mission, xml_get_string_value(doc, "level1Product.productInfo.missionInfo.mission")); strcpy(terrasar->sensor, xml_get_string_value(doc, "level1Product.productInfo.acquisitionInfo.sensor")); strcpy(terrasar->imagingMode, xml_get_string_value(doc, "level1Product.productInfo.acquisitionInfo.imagingMode")); strcpy(terrasar->elevationBeamConfiguration, xml_get_string_value(doc, "level1Product.productInfo.acquisitionInfo.elevationBeamConfiguration")); strcpy(terrasar->imageDataType, xml_get_string_value(doc, "level1Product.productInfo.imageDataInfo.imageDataType")); terrasar->imageDataDepth = xml_get_int_value(doc, "level1Product.productInfo.imageDataInfo.imageDataDepth"); strcpy(terrasar->imageDataFormat, xml_get_string_value(doc, "level1Product.productInfo.imageDataInfo.imageDataFormat")); strcpy(terrasar->azimuthTimeUTC, xml_get_string_value(doc, "level1Product.productInfo.sceneInfo.sceneCenterCoord.azimuthTimeUTC")); terrasar->absOrbit = xml_get_int_value(doc, "level1Product.productInfo.missionInfo.absOrbit"); strcpy(terrasar->orbitDirection, xml_get_string_value(doc, "level1Product.productInfo.missionInfo.orbitDirection")); terrasar->numberOfLayers = xml_get_int_value(doc, "level1Product.productInfo.imageDataInfo.numberOfLayers"); strcpy(terrasar->polarisationMode, xml_get_string_value(doc, "level1Product.productInfo.acquisitionInfo.polarisationMode")); if (strcmp_case(terrasar->polarisationMode, "SINGLE") == 0) strcpy(terrasar->bands, xml_get_string_value(doc, "level1Product.productInfo.acquisitionInfo.polarisationList.polLayer[0]")); else if (strcmp_case(terrasar->polarisationMode, "DUAL") == 0) { strcpy(terrasar->bands, xml_get_string_value(doc, "level1Product.productInfo.acquisitionInfo.polarisationList.polLayer[0]")); strcat(terrasar->bands, ","); strcat(terrasar->bands, xml_get_string_value(doc, "level1Product.productInfo.acquisitionInfo.polarisationList.polLayer[1]")); } else if (strcmp_case(terrasar->polarisationMode, "TWIN") == 0) { strcpy(terrasar->bands, xml_get_string_value(doc, "level1Product.productInfo.acquisitionInfo.polarisationList.polLayer[0]")); strcat(terrasar->bands, ","); strcat(terrasar->bands, xml_get_string_value(doc, "level1Product.productInfo.acquisitionInfo.polarisationList.polLayer[1]")); } else if (strcmp_case(terrasar->polarisationMode, "QUAD") == 0) { strcpy(terrasar->bands, xml_get_string_value(doc, "level1Product.productInfo.acquisitionInfo.polarisationList.polLayer[0]")); strcat(terrasar->bands, ","); strcat(terrasar->bands, xml_get_string_value(doc, "level1Product.productInfo.acquisitionInfo.polarisationList.polLayer[1]")); strcat(terrasar->bands, ","); strcat(terrasar->bands, xml_get_string_value(doc, "level1Product.productInfo.acquisitionInfo.polarisationList.polLayer[2]")); strcat(terrasar->bands, ","); strcat(terrasar->bands, xml_get_string_value(doc, "level1Product.productInfo.acquisitionInfo.polarisationList.polLayer[3]")); } terrasar->numberOfRows = xml_get_int_value(doc, "level1Product.productInfo.imageDataInfo.imageRaster.numberOfRows"); terrasar->numberOfColumns = xml_get_int_value(doc, "level1Product.productInfo.imageDataInfo.imageRaster.numberOfColumns"); strcpy(terrasar->projection, xml_get_string_value(doc, "level1Product.productInfo.productVariantInfo.projection")); if (strcmp_case(terrasar->projection, "GROUNDRANGE") == 0) terrasar->rangeResolution = xml_get_double_value(doc, "level1Product.productInfo.imageDataInfo.imageRaster." "groundRangeResolution"); if (strcmp_case(terrasar->projection, "SLANTRANGE") == 0) terrasar->rangeResolution = xml_get_double_value(doc, "level1Product.productSpecific.complexImageInfo.projectedSpacingRange." "slantRange"); // FIXME: cover MAP case terrasar->azimuthResolution = xml_get_double_value(doc, "level1Product.productInfo.imageDataInfo.imageRaster.azimuthResolution"); terrasar->sceneCenterCoordLat = xml_get_double_value(doc, "level1Product.productInfo.sceneInfo.sceneCenterCoord.lat"); terrasar->sceneCenterCoordLon = xml_get_double_value(doc, "level1Product.productInfo.sceneInfo.sceneCenterCoord.lon"); strcpy(terrasar->lookDirection, xml_get_string_value(doc, "level1Product.productInfo.acquisitionInfo.lookDirection")); terrasar->azimuthLooks = xml_get_int_value(doc, "level1Product.productInfo.imageDataInfo.imageRaster.azimuthLooks"); terrasar->rangeLooks = xml_get_int_value(doc, "level1Product.productInfo.imageDataInfo.imageRaster.rangeLooks"); strcpy(terrasar->imageCoordinateType, xml_get_string_value(doc, "level1Product.productSpecific.complexImageInfo.imageCoordinateType")); terrasar->rowSpacing = xml_get_double_value(doc, "level1Product.productInfo.imageDataInfo.imageRaster.rowSpacing"); terrasar->columnSpacing = xml_get_double_value(doc, "level1Product.productInfo.imageDataInfo.imageRaster.columnSpacing"); terrasar->rangeTimeFirst = xml_get_double_value(doc, "level1Product.productInfo.sceneInfo.rangeTime.firstPixel"); terrasar->rangeTimeLast = xml_get_double_value(doc, "level1Product.productInfo.sceneInfo.rangeTime.lastPixel"); terrasar->centerFrequency = xml_get_double_value(doc, "level1Product.instrument.radarParameters.centerFrequency"); terrasar->prf = xml_get_double_value(doc, "level1Product.instrument.settings.settingRecord.PRF"); terrasar->totalProcessedAzimuthBandwidth = xml_get_double_value(doc, "level1Product.processing.processingParameter." "totalProcessedAzimuthBandwidth"); // chirp rate ??? terrasar->pulseLength = xml_get_double_value(doc, "level1Product.processing.processingParameter.rangeCompression.chirps." "referenceChirp.pulseLength"); terrasar->rsf = xml_get_double_value(doc, "level1Product.instrument.settings.RSF"); // pitch, roll, yaw ??? // read Doppler values terrasar->doppler = meta_doppler_init(); terrasar->doppler->type = tsx_doppler; numDopplerEstimates = xml_get_int_value(doc, "level1Product.processing.doppler.dopplerCentroid[0]." "numberOfDopplerRecords"); tsx = tsx_doppler_init(numDopplerEstimates); terrasar->doppler->tsx = tsx; strcpy(str, xml_get_string_value(doc, "level1Product.processing.doppler.dopplerCentroid[0].dopplerEstimate[0]." "timeUTC")); date_terrasar2date(str, &imgDopplerDate, &imgDopplerTime); tsx->year = imgDopplerDate.year; date_ymd2jd(&imgDopplerDate, &julianDate); tsx->julDay = julianDate.jd; tsx->second = date_hms2sec(&imgDopplerTime); for (ii=0; ii<numDopplerEstimates; ii++) { strcpy(timeStr, xml_get_string_value(doc, "level1Product.processing.doppler.dopplerCentroid[0]." "dopplerEstimate[%d].timeUTC", ii)); date_terrasar2date(timeStr, &date, &time); tsx->dop[ii].time = time_difference(&date, &time, &imgDopplerDate, &imgDopplerTime); tsx->dop[ii].first_range_time = xml_get_double_value(doc, "level1Product.processing.doppler.dopplerCentroid[0]." "dopplerEstimate[%d].combinedDoppler.validityRangeMin", ii); tsx->dop[ii].reference_time = xml_get_double_value(doc, "level1Product.processing.doppler.dopplerCentroid[0]." "dopplerEstimate[%d].combinedDoppler.referencePoint", ii); tsx->dop[ii].poly_degree = xml_get_double_value(doc, "level1Product.processing.doppler.dopplerCentroid[0]." "dopplerEstimate[%d].combinedDoppler.polynomialDegree", ii); tsx->dop[ii].coefficient = (double *) MALLOC(sizeof(double) * (tsx->dop[ii].poly_degree+1)); for (kk=0; kk<=tsx->dop[ii].poly_degree; kk++) tsx->dop[ii].coefficient[kk] = xml_get_double_value(doc, "level1Product.processing.doppler.dopplerCentroid[0]." "dopplerEstimate[%d].combinedDoppler.coefficient[%d]", ii, kk); } // read state vectors strcpy(terrasar->sceneStart, xml_get_string_value(doc, "level1Product.productInfo.sceneInfo.start.timeUTC")); date_terrasar2date(terrasar->sceneStart, &imgStartDate, &imgStartTime); strcpy(terrasar->sceneStop, xml_get_string_value(doc, "level1Product.productInfo.sceneInfo.stop.timeUTC")); numStateVectors = xml_get_int_value(doc, "level1Product.platform.orbit.orbitHeader.numStateVectors"); terrasar->state_vectors = meta_state_vectors_init(numStateVectors); terrasar->state_vectors->year = imgStartDate.year; date_ymd2jd(&imgStartDate, &julianDate); terrasar->state_vectors->julDay = julianDate.jd; terrasar->state_vectors->second = date_hms2sec(&imgStartTime); for (ii=0; ii<numStateVectors; ii++) { sprintf(str, "level1Product.platform.orbit.stateVec[%d].timeUTC", ii); strcpy(timeStr, xml_get_string_value(doc, str)); date_terrasar2date(timeStr, &date, &time); terrasar->state_vectors->vecs[ii].time = time_difference(&date, &time, &imgStartDate, &imgStartTime); sprintf(str, "level1Product.platform.orbit.stateVec[%d].posX", ii); terrasar->state_vectors->vecs[ii].vec.pos.x = xml_get_double_value(doc, str); sprintf(str, "level1Product.platform.orbit.stateVec[%d].posY", ii); terrasar->state_vectors->vecs[ii].vec.pos.y = xml_get_double_value(doc, str); sprintf(str, "level1Product.platform.orbit.stateVec[%d].posZ", ii); terrasar->state_vectors->vecs[ii].vec.pos.z = xml_get_double_value(doc, str); sprintf(str, "level1Product.platform.orbit.stateVec[%d].velX", ii); terrasar->state_vectors->vecs[ii].vec.vel.x = xml_get_double_value(doc, str); sprintf(str, "level1Product.platform.orbit.stateVec[%d].velY", ii); terrasar->state_vectors->vecs[ii].vec.vel.y = xml_get_double_value(doc, str); sprintf(str, "level1Product.platform.orbit.stateVec[%d].velZ", ii); terrasar->state_vectors->vecs[ii].vec.vel.z = xml_get_double_value(doc, str); } // read location information terrasar->sceneCornerCoord1Lat = xml_get_double_value(doc, "level1Product.productInfo.sceneInfo.sceneCornerCoord[0].lat"); terrasar->sceneCornerCoord1Lon = xml_get_double_value(doc, "level1Product.productInfo.sceneInfo.sceneCornerCoord[0].lon"); terrasar->sceneCornerCoord2Lat = xml_get_double_value(doc, "level1Product.productInfo.sceneInfo.sceneCornerCoord[1].lat"); terrasar->sceneCornerCoord2Lon = xml_get_double_value(doc, "level1Product.productInfo.sceneInfo.sceneCornerCoord[1].lon"); terrasar->sceneCornerCoord3Lat = xml_get_double_value(doc, "level1Product.productInfo.sceneInfo.sceneCornerCoord[2].lat"); terrasar->sceneCornerCoord3Lon = xml_get_double_value(doc, "level1Product.productInfo.sceneInfo.sceneCornerCoord[2].lon"); terrasar->sceneCornerCoord4Lat = xml_get_double_value(doc, "level1Product.productInfo.sceneInfo.sceneCornerCoord[3].lat"); terrasar->sceneCornerCoord4Lon = xml_get_double_value(doc, "level1Product.productInfo.sceneInfo.sceneCornerCoord[3].lon"); // read calibration information char calFlag[15]; strcpy(calFlag, xml_get_string_value(doc, "level1Product.productInfo.productVariantInfo.radiometricCorrection")); if (strcmp_case(calFlag, "CALIBRATED") == 0) terrasar->cal_factor = xml_get_double_value(doc, "level1Product.calibration.calibrationConstant.calFactor"); xmlFreeDoc(doc); xmlCleanupParser(); return terrasar; }
int update_state_vectors(char *outBaseName, char *file) { int ret = FALSE; char *odrFile = NULL; meta_parameters *meta = meta_read(outBaseName); const char *sensor = meta->general->sensor; if (strcmp_case(sensor, "E1") == 0 || strcmp_case(sensor, "ERS1") == 0) { sensor = "ERS-1"; } if (strcmp_case(sensor, "E2") == 0 || strcmp_case(sensor, "ERS2") == 0) { sensor = "ERS-2"; } if (strcmp_case(sensor, "ERS-1") != 0 && strcmp_case(sensor, "ERS-2") != 0) { // not ERS data meta_free(meta); return ret; } asfPrintStatus("\nChecking for %s precision state vectors...\n", sensor); if (!file || strlen(file) == 0) { file = get_arclist_from_settings(sensor); } if (!file || strlen(file) == 0) { return ret; } if (is_dir(file)) { char *arclist = MALLOC(sizeof(char)*(strlen(file) + 128)); if (file[strlen(file)-1] == DIR_SEPARATOR) sprintf(arclist, "%sarclist", file); else sprintf(arclist, "%s%carclist", file, DIR_SEPARATOR); if (isArcList(sensor, arclist)) odrFile = findInArcList(meta->general->acquisition_date, arclist); else asfPrintError("No arclist file found in %s\n", file); FREE(arclist); } else if (isArcList(sensor, file)) odrFile = findInArcList(meta->general->acquisition_date, file); else if (!fileExists(file)) asfPrintError("Not found: %s\n", file); else // assume file is just a regular ODR file odrFile = STRDUP(file); if (!odrFile || !fileExists(odrFile)) asfPrintError("Precision state vector file (%s) does not exist!\n", odrFile ? odrFile : "null"); asfPrintStatus("Refining %s orbits using ODR file: %s\n", sensor, odrFile); FILE *fpIn = FOPEN(odrFile, "rb"); // Check for new version of ODR file: xODR char spec[5]; FREAD(&spec, 1, 4, fpIn); spec[4] = '\0'; if (strcmp_case(spec, "xODR") != 0) asfPrintError("Unsupported precision state vector file (%s) type\n", odrFile); // Determine image center time for reference julian_date jd; jd.year = meta->state_vectors->year; jd.jd = meta->state_vectors->julDay; double ref_secs = meta->state_vectors->second; double ref_time = date2seconds(&jd, ref_secs); int stVec_count = meta->state_vectors->vector_count; ref_time += meta->state_vectors->vecs[stVec_count/2].time; // Initialize structure for updated state vector structure meta_state_vectors *prcVec = meta_state_vectors_init(9); int year = meta->state_vectors->year; prcVec->year = year; int julDay = meta->state_vectors->julDay; prcVec->julDay = julDay; double second = meta->state_vectors->second; prcVec->second = second; prcVec->vector_count = 9; // Read header information char satellite[9]; int begin, repeat_cycle, arc, nRecords, version; FREAD(&satellite, 1, 8, fpIn); satellite[8] = '\0'; FREAD(&begin, 1, 4, fpIn); ieee_big32(begin); FREAD(&repeat_cycle, 1, 4, fpIn); ieee_big32(repeat_cycle); FREAD(&arc, 1, 4, fpIn); ieee_big32(arc); FREAD(&nRecords, 1, 4, fpIn); ieee_big32(nRecords); FREAD(&version, 1, 4, fpIn); ieee_big32(version); // Read state vectors doris_prc_polar *stVec = (doris_prc_polar *) MALLOC(sizeof(doris_prc_polar)*nRecords); int ii, kk, closest = 0, time, nLat, nLon, nHeight; double diff = DAY2SEC*100; for (ii=0; ii<nRecords; ii++) { FREAD(&time, 1, 4, fpIn); ieee_big32(time); FREAD(&nLat, 1, 4, fpIn); ieee_big32(nLat); FREAD(&nLon, 1, 4, fpIn); ieee_big32(nLon); FREAD(&nHeight, 1, 4, fpIn); ieee_big32(nHeight); stVec[ii].time = time; stVec[ii].lat = (double)nLat/10000000.0; stVec[ii].lon = (double)nLon/10000000.0; stVec[ii].height = (double)nHeight/1000.0; if (fabs((double)time - ref_time) < diff) { closest = ii; diff = fabs(time - ref_time); } } FCLOSE(fpIn); if (closest > 0) { asfPrintStatus("Updating orbit information with precision state vectors.\n\n"); ret = TRUE; // Generating state vectors in earth-fixed coordinates doris_prc_polar polarVec; doris_prc_cartesian cartVec, velOne, velTwo; ref_time = date2seconds(&jd, ref_secs); for (ii=closest-4; ii<=closest+4; ii++) { geocentric_latlon(stVec[ii], &polarVec); polar2cartesian(polarVec, &cartVec); // Approximate state vector velocity according to getorb FAQs // (http://www.deos.tudelft.nl/ers/precorbs/faq.shtml#004001): // XYZvel(t) = XYZpos(t + 0.5sec) - XYZpos(t - 0.5sec) // Approximating velocities is fine since we will use an interpolation // scheme later that does not require these. interpolate_prc_vectors(stVec, cartVec.time-0.5, closest-4, closest+4, &velOne); interpolate_prc_vectors(stVec, cartVec.time+0.5, closest-4, closest+4, &velTwo); // Fill in the orbit information into metadata state vector structure kk = ii - closest + 4; prcVec->vecs[kk].time = cartVec.time - ref_time; prcVec->vecs[kk].vec.pos.x = cartVec.x; prcVec->vecs[kk].vec.pos.y = cartVec.y; prcVec->vecs[kk].vec.pos.z = cartVec.z; prcVec->vecs[kk].vec.vel.x = velTwo.x - velOne.x; prcVec->vecs[kk].vec.vel.y = velTwo.y - velOne.y; prcVec->vecs[kk].vec.vel.z = velTwo.z - velOne.z; } FREE(meta->state_vectors); meta->state_vectors = prcVec; meta_write(meta, outBaseName); meta_free(meta); FREE(stVec); } else asfPrintStatus("\nCould not update orbit information with precision state" " vectors\nOrbit information not available in orbit file " "(%s).\n\n", odrFile); return ret; }
radarsat2_meta *read_radarsat2_meta_ext(const char *dataFile, int cal) { int ii, numStateVectors, numDopplerEstimates; ymd_date imgStartDate, date; hms_time imgStartTime, time; julian_date julianDate; char timeStr[30], str[150]; radarsat2_doppler_params *r2_doppler; radarsat2_meta *radarsat2 = radarsat2_meta_init(); if (!fileExists(dataFile)) asfPrintError("Metadata file (%s) does not exist!\n", dataFile); char *path = (char *) MALLOC(sizeof(char)*512); char *file = (char *) MALLOC(sizeof(char)*128); split_dir_and_file(dataFile, path, file); xmlDoc *doc = xmlReadFile(dataFile, NULL, 0); if (!doc) asfPrintError("Could not parse file %s\n", dataFile); strcpy(radarsat2->satellite, xml_get_string_value(doc, "product.sourceAttributes.satellite")); strcpy(radarsat2->sensor, xml_get_string_value(doc, "product.sourceAttributes.sensor")); strcpy(radarsat2->beamModeMnemonic, xml_get_string_value(doc, "product.sourceAttributes.beamModeMnemonic")); strcpy(radarsat2->acquisitionType, xml_get_string_value(doc, "product.sourceAttributes.radarParameters.acquisitionType")); strcpy(radarsat2->productType, xml_get_string_value(doc, "product.imageGenerationParameters.generalProcessingInformation." "productType")); strcpy(radarsat2->dataType, xml_get_string_value(doc, "product.imageAttributes.rasterAttributes.dataType")); strcpy(radarsat2->processingFacility, xml_get_string_value(doc, "product.imageGenerationParameters.generalProcessingInformation." "processingFacility")); strcpy(radarsat2->zeroDopplerAzimuthTime, xml_get_string_value(doc, "product.imageGenerationParameters.slantRangeToGroundRange." "zeroDopplerAzimuthTime")); strcpy(radarsat2->softwareVersion, xml_get_string_value(doc, "product.imageGenerationParameters.generalProcessingInformation." "softwareVersion")); radarsat2->bitsPerSample = xml_get_int_value(doc, "product.productInfo.imageDataInfo.imageDataDepth"); //radarsat2->absOrbit = //xml_get_int_value(doc, "product.productInfo.missionInfo.absOrbit"); strcpy(radarsat2->passDirection, xml_get_string_value(doc, "product.sourceAttributes.orbitAndAttitude.orbitInformation." "passDirection")); // Number of bands needs to be derived from polarizations string int band_count = 0; char *attribute = (char *) MALLOC(sizeof(char)*128); char *fileName = (char *) MALLOC(sizeof(char)*512); strcpy(radarsat2->polarizations, xml_get_string_value(doc, "product.sourceAttributes.radarParameters.polarizations")); for (ii=0; ii<strlen(radarsat2->polarizations)-1; ii++) if (radarsat2->polarizations[ii] == ' ') radarsat2->polarizations[ii] = ','; if (strstr(radarsat2->polarizations, "HH")) band_count++; if (strstr(radarsat2->polarizations, "VV")) band_count++; if (strstr(radarsat2->polarizations, "HV")) band_count++; if (strstr(radarsat2->polarizations, "VH")) band_count++; radarsat2->band_count = band_count; strcpy(radarsat2->filename, ""); strcpy(radarsat2->bands, ""); // Park the filenames in the basename field of the metadata and replace // it with the directory name once we are done with importing the data for (ii=0; ii<band_count; ii++) { sprintf(str, "product.imageAttributes.fullResolutionImageData[%d].pole", ii); strcpy(attribute, xml_get_string_attribute(doc, str)); sprintf(str, "product.imageAttributes.fullResolutionImageData[%d]", ii); strcpy(fileName, xml_get_string_value(doc, str)); if (ii == 0) { sprintf(radarsat2->filename, "%s", fileName); sprintf(radarsat2->bands, "AMP-%s,PHASE-%s", uc(attribute), uc(attribute)); } else { strcat(radarsat2->filename, ","); strcat(radarsat2->filename, fileName); strcat(radarsat2->bands, ","); sprintf(str, "AMP-%s,PHASE-%s", uc(attribute), uc(attribute)); strcat(radarsat2->bands, str); } } FREE(fileName); FREE(attribute); radarsat2->numberOfLines = xml_get_int_value(doc, "product.imageAttributes.rasterAttributes.numberOfLines"); radarsat2->numberOfSamplesPerLine = xml_get_int_value(doc, "product.imageAttributes.rasterAttributes.numberOfSamplesPerLine"); radarsat2->sampledPixelSpacing = xml_get_double_value(doc, "product.imageAttributes.rasterAttributes.sampledPixelSpacing"); radarsat2->sampledLineSpacing = xml_get_double_value(doc, "product.imageAttributes.rasterAttributes.sampledLineSpacing"); radarsat2->semiMajorAxis = xml_get_double_value(doc, "product.imageAttributes.geographicInformation." "referenceEllipsoidParameters.semiMajorAxis"); radarsat2->semiMinorAxis = xml_get_double_value(doc, "product.imageAttributes.geographicInformation." "referenceEllipsoidParameters.semiMinorAxis"); strcpy(radarsat2->lineTimeOrdering, xml_get_string_value(doc, "product.imageAttributes.rasterAttributes.lineTimeOrdering")); strcpy(radarsat2->pixelTimeOrdering, xml_get_string_value(doc, "product.imageAttributes.rasterAttributes.pixelTimeOrdering")); strcpy(radarsat2->antennaPointing, xml_get_string_value(doc, "product.sourceAttributes.radarParameters.antennaPointing")); radarsat2->numberOfAzimuthLooks = xml_get_int_value(doc, "product.imageGenerationParameters.sarProcessingInformation." "numberOfAzimuthLooks"); radarsat2->numberOfRangeLooks = xml_get_int_value(doc, "product.imageGenerationParameters.sarProcessingInformation." "numberOfRangeLooks"); radarsat2->slantRangeNearEdge = xml_get_double_value(doc, "product.imageGenerationParameters.sarProcessingInformation." "slantRangeNearEdge"); radarsat2->radarCenterFrequency = xml_get_double_value(doc, "product.sourceAttributes.radarParameters.radarCenterFrequency"); radarsat2->pulseRepetitionFrequency = xml_get_double_value(doc, "product.sourceAttributes.radarParameters.pulseRepetitionFrequency"); radarsat2->satelliteHeight = xml_get_double_value(doc, "product.imageGenerationParameters.sarProcessingInformation." "satelliteHeight"); radarsat2->totalProcessedAzimuthBandwidth = xml_get_double_value(doc, "product.imageGenerationParameters.sarProcessingInformation." "totalProcessedAzimuthBandwidth"); // chirp rate ??? radarsat2->pulseLength = xml_get_double_value(doc, "product.sourceAttributes.radarParameters.pulseLength"); radarsat2->adcSamplingRate = xml_get_double_value(doc, "product.sourceAttributes.radarParameters.adcSamplingRate"); // pitch, roll, yaw ??? // read Doppler values radarsat2->doppler = meta_doppler_init(); radarsat2->doppler->type = radarsat2_doppler; char *dopplerCentroidStr; dopplerCentroidStr = (char *) MALLOC(sizeof(char)*512); strcpy(dopplerCentroidStr, xml_get_string_value(doc, "product.imageGenerationParameters.dopplerCentroid." "dopplerCentroidCoefficients")); numDopplerEstimates = getNumParamsInString(dopplerCentroidStr); r2_doppler = radarsat2_doppler_init(numDopplerEstimates); radarsat2->doppler->r2 = r2_doppler; r2_doppler->ref_time_centroid = xml_get_double_value(doc, "product.imageGenerationParameters.dopplerCentroid." "dopplerCentroidReferenceTime"); r2_doppler->ref_time_rate = xml_get_double_value(doc, "product.imageGenerationParameters.dopplerRateValues." "dopplerRateReferenceTime"); char *dopplerRateStr; dopplerRateStr = (char *) MALLOC(sizeof(char)*512); strcpy(dopplerRateStr, xml_get_string_value(doc, "product.imageGenerationParameters.dopplerRateValues." "dopplerRateValuesCoefficients")); r2_doppler->time_first_sample = xml_get_double_value(doc, "product.imageGenerationParameters.slantRangeToGroundRange." "slantRangeTimeToFirstRangeSample"); char *p, *q; p = dopplerCentroidStr; for (ii=0; ii<numDopplerEstimates; ii++) { if (ii == 0) q = p; else { if (strchr(p, ' ')) { q = strchr(p, ' '); q++; } } sscanf(q, "%lf", &r2_doppler->centroid[ii]); p = q; } FREE(dopplerCentroidStr); p = dopplerRateStr; for (ii=0; ii<numDopplerEstimates; ii++) { if (ii == 0) q = p; else { if (strchr(p, ' ')) { q = strchr(p, ' '); q++; } } sscanf(q, "%lf", &r2_doppler->rate[ii]); p = q; } FREE(dopplerRateStr); // read state vectors strcpy(radarsat2->zeroDopplerTimeFirstLine, xml_get_string_value(doc, "product.imageGenerationParameters.sarProcessingInformation." "zeroDopplerTimeFirstLine")); date_terrasar2date(radarsat2->zeroDopplerTimeFirstLine, &imgStartDate, &imgStartTime); strcpy(radarsat2->zeroDopplerTimeLastLine, xml_get_string_value(doc, "product.imageGenerationParameters.sarProcessingInformation." "zeroDopplerTimeLastLine")); // Accommodate data stored in reverse time if (strcmp_case(radarsat2->lineTimeOrdering, "DECREASING") == 0) date_terrasar2date(radarsat2->zeroDopplerTimeLastLine, &imgStartDate, &imgStartTime); // FIXME: determine numStateVector from data - count the entries //numStateVectors = xml_get_int_value(doc, // "product.platform.orbit.orbitHeader.numStateVectors"); numStateVectors = 5; radarsat2->state_vectors = meta_state_vectors_init(numStateVectors); radarsat2->state_vectors->year = imgStartDate.year; date_ymd2jd(&imgStartDate, &julianDate); radarsat2->state_vectors->julDay = julianDate.jd; radarsat2->state_vectors->second = date_hms2sec(&imgStartTime); for (ii=0; ii<numStateVectors; ii++) { sprintf(str, "product.sourceAttributes.orbitAndAttitude.orbitInformation." "stateVector[%d].timeStamp", ii); strcpy(timeStr, xml_get_string_value(doc, str)); date_terrasar2date(timeStr, &date, &time); radarsat2->state_vectors->vecs[ii].time = time_difference(&date, &time, &imgStartDate, &imgStartTime); sprintf(str, "product.sourceAttributes.orbitAndAttitude.orbitInformation." "stateVector[%d].xPosition", ii); radarsat2->state_vectors->vecs[ii].vec.pos.x = xml_get_double_value(doc, str); sprintf(str, "product.sourceAttributes.orbitAndAttitude.orbitInformation." "stateVector[%d].yPosition", ii); radarsat2->state_vectors->vecs[ii].vec.pos.y = xml_get_double_value(doc, str); sprintf(str, "product.sourceAttributes.orbitAndAttitude.orbitInformation." "stateVector[%d].zPosition", ii); radarsat2->state_vectors->vecs[ii].vec.pos.z = xml_get_double_value(doc, str); sprintf(str, "product.sourceAttributes.orbitAndAttitude.orbitInformation." "stateVector[%d].xVelocity", ii); radarsat2->state_vectors->vecs[ii].vec.vel.x = xml_get_double_value(doc, str); sprintf(str, "product.sourceAttributes.orbitAndAttitude.orbitInformation." "stateVector[%d].yVelocity", ii); radarsat2->state_vectors->vecs[ii].vec.vel.y = xml_get_double_value(doc, str); sprintf(str, "product.sourceAttributes.orbitAndAttitude.orbitInformation." "stateVector[%d].zVelocity", ii); radarsat2->state_vectors->vecs[ii].vec.vel.z = xml_get_double_value(doc, str); } // read location information from the tie points ii = 0; int line=-99, pixel=-99, found=TRUE; while (found) { sprintf(str, "product.imageAttributes.geographicInformation." "geolocationGrid.imageTiePoint[%d].imageCoordinate.line", ii); line = (int) xml_get_double_value(doc, str); sprintf(str, "product.imageAttributes.geographicInformation." "geolocationGrid.imageTiePoint[%d].imageCoordinate.pixel", ii); pixel = (int) xml_get_double_value(doc, str); if (line < 0 || pixel < 0) found = FALSE; if (found) { if (line == 0 && pixel == 0) { sprintf(str, "product.imageAttributes.geographicInformation." "geolocationGrid.imageTiePoint[%d].geodeticCoordinate." "latitude", ii); radarsat2->sceneCornerCoord1Lat = xml_get_double_value(doc, str); sprintf(str, "product.imageAttributes.geographicInformation." "geolocationGrid.imageTiePoint[%d].geodeticCoordinate." "longitude", ii); radarsat2->sceneCornerCoord1Lon = xml_get_double_value(doc, str); } if (line == 0 && pixel == radarsat2->numberOfSamplesPerLine-1) { sprintf(str, "product.imageAttributes.geographicInformation." "geolocationGrid.imageTiePoint[%d].geodeticCoordinate." "latitude", ii); radarsat2->sceneCornerCoord2Lat = xml_get_double_value(doc, str); sprintf(str, "product.imageAttributes.geographicInformation." "geolocationGrid.imageTiePoint[%d].geodeticCoordinate." "longitude", ii); radarsat2->sceneCornerCoord2Lon = xml_get_double_value(doc, str); } if (line == radarsat2->numberOfLines-1 && pixel == 0) { sprintf(str, "product.imageAttributes.geographicInformation." "geolocationGrid.imageTiePoint[%d].geodeticCoordinate." "latitude", ii); radarsat2->sceneCornerCoord3Lat = xml_get_double_value(doc, str); sprintf(str, "product.imageAttributes.geographicInformation." "geolocationGrid.imageTiePoint[%d].geodeticCoordinate." "longitude", ii); radarsat2->sceneCornerCoord3Lon = xml_get_double_value(doc, str); } if (line == radarsat2->numberOfLines-1 && pixel == radarsat2->numberOfSamplesPerLine-1) { sprintf(str, "product.imageAttributes.geographicInformation." "geolocationGrid.imageTiePoint[%d].geodeticCoordinate." "latitude", ii); radarsat2->sceneCornerCoord4Lat = xml_get_double_value(doc, str); sprintf(str, "product.imageAttributes.geographicInformation." "geolocationGrid.imageTiePoint[%d].geodeticCoordinate." "longitude", ii); radarsat2->sceneCornerCoord4Lon = xml_get_double_value(doc, str); } } ii++; } // Read calibration information if (cal) { double sample_count = radarsat2->numberOfSamplesPerLine; attribute = (char *) MALLOC(sizeof(char)*128); fileName = (char *) MALLOC(sizeof(char)*512); for (ii=0; ii<3; ii++) { sprintf(str, "product.imageAttributes.lookupTable[%d].incidenceAngleCorrection", ii); strcpy(attribute, xml_get_string_attribute(doc, str)); sprintf(str, "product.imageAttributes.lookupTable[%d]", ii); if (strlen(path) > 0) sprintf(fileName, "%s%s", path, xml_get_string_value(doc, str)); else strcpy(fileName, xml_get_string_value(doc, str)); if (strcmp_case(attribute, "Beta Nought") == 0) radarsat2->gains_beta = read_radarsat2_lut(fileName, sample_count); else if (strcmp_case(attribute, "Sigma Nought") == 0) radarsat2->gains_sigma = read_radarsat2_lut(fileName, sample_count); else if (strcmp_case(attribute, "Gamma") == 0) radarsat2->gains_gamma = read_radarsat2_lut(fileName, sample_count); } FREE(attribute); FREE(fileName); } xmlFreeDoc(doc); xmlCleanupParser(); return radarsat2; }
/*************************************************************** * meta_read_old: * Reads in old style meta file and fills new style meta struct * Note that the appropriate extension is appended to the given * base name automagically. */ void meta_read_old(meta_parameters *meta, char *fileName) { char *ddrName = appendExt(fileName,".ddr"); struct DDR ddr; char *metaName = appendExt(fileName,".meta"); meta_general *general = meta->general; meta_sar *sar = meta->sar; coniStruct *coni = coniOpen(metaName, asciiIn); /* Fields that cannot be filled from the old structures */ general->frame = 0; general->band_count = 1; general->center_latitude = MAGIC_UNSET_DOUBLE; general->center_longitude = MAGIC_UNSET_DOUBLE; general->missing_lines = -999999999; /* Read old style meta file */ coniIO_double(coni,"","meta_version:",&meta->meta_version,"ASF Metadata File.\n"); /*Geolocation parameters.*/ coniIO_structOpen(coni,"geo {","begin parameters used in geolocating the image."); coniIO_char(coni,"geo.","type:",&sar->image_type,"Image type: [S=slant range; G=ground range; P=map projected]"); if (sar->image_type=='P') { /*Projection Parameters.*/ char projection_type[256]; meta_projection *projection = meta->projection = meta_projection_init(); coniIO_structOpen(coni,"proj {","Map Projection parameters"); coniIO_str (coni,"geo.proj.","type:", projection_type, "Projection Type: [U=utm; P=ps; L=Lambert; A=at/ct]"); if ( !strcmp(projection_type, "UNIVERSAL_TRANSVERSE_MERCATOR") ) projection->type = UNIVERSAL_TRANSVERSE_MERCATOR; else if ( !strcmp(projection_type, "POLAR_STEREOGRAPHIC") ) projection->type = POLAR_STEREOGRAPHIC; else if ( !strcmp(projection_type, "ALBERS_EQUAL_AREA") ) projection->type = ALBERS_EQUAL_AREA; else if ( !strcmp(projection_type, "LAMBERT_CONFORMAL_CONIC") ) projection->type = LAMBERT_CONFORMAL_CONIC; else if ( !strcmp(projection_type, "LAMBERT_AZIMUTHAL_EQUAL_AREA") ) projection->type = LAMBERT_AZIMUTHAL_EQUAL_AREA; else if ( !strcmp(projection_type, "STATE_PLANE") ) projection->type = STATE_PLANE; else if ( !strcmp(projection_type, "SCANSAR_PROJECTION") ) projection->type = SCANSAR_PROJECTION; else if ( !strcmp(projection_type, "U") ) projection->type = UNIVERSAL_TRANSVERSE_MERCATOR; else if ( !strcmp(projection_type, "P") ) projection->type = POLAR_STEREOGRAPHIC; else if ( !strcmp(projection_type, "L") ) projection->type = LAMBERT_CONFORMAL_CONIC; else if ( !strcmp(projection_type, "A") ) projection->type = SCANSAR_PROJECTION; else if ( !strcmp(projection_type, "G") ) projection->type = LAT_LONG_PSEUDO_PROJECTION; else projection->type = -1; coniIO_double(coni,"geo.proj.","startX:",&projection->startX,"Projection Coordinate at top-left, X direction"); coniIO_double(coni,"geo.proj.","startY:",&projection->startY,"Projection Coordinate at top-left, Y direction"); coniIO_double(coni,"geo.proj.","perX:", &projection->perX, "Projection Coordinate per pixel, X direction"); coniIO_double(coni,"geo.proj.","perY:", &projection->perY, "Projection Coordinate per pixel, Y direction"); coniIO_char (coni,"geo.proj.","hem:", &projection->hem, "Hemisphere: [N=northern hemisphere; S=southern hemisphere]"); if (meta->meta_version>0.8) { /*Read geoid from file*/ coniIO_double(coni,"geo.proj.","re_major:",&projection->re_major,"Major (equator) Axis of earth (meters)"); coniIO_double(coni,"geo.proj.","re_minor:",&projection->re_minor,"Minor (polar) Axis of earth (meters)"); } else { /*Default: use the GEM-06 (Goddard Earth Model 6) Ellipsoid*/ projection->re_major=6378144.0; projection->re_minor=6356754.9; } switch(projection->type) { case SCANSAR_PROJECTION: coniIO_double(coni,"geo.proj.","rlocal:", &projection->param.atct.rlocal,"Local earth radius [m]"); coniIO_double(coni,"geo.proj.","atct_alpha1:",&projection->param.atct.alpha1,"at/ct projection parameter"); coniIO_double(coni,"geo.proj.","atct_alpha2:",&projection->param.atct.alpha2,"at/ct projection parameter"); coniIO_double(coni,"geo.proj.","atct_alpha3:",&projection->param.atct.alpha3,"at/ct projection parameter"); break; case LAMBERT_CONFORMAL_CONIC: coniIO_double(coni,"geo.proj.","lam_plat1:",&projection->param.lamcc.plat1,"Lambert first standard parallel"); coniIO_double(coni,"geo.proj.","lam_plat2:",&projection->param.lamcc.plat2,"Lambert second standard parallel"); coniIO_double(coni,"geo.proj.","lam_lat:", &projection->param.lamcc.lat0, "Lambert original latitude"); coniIO_double(coni,"geo.proj.","lam_lon:", &projection->param.lamcc.lon0, "Lambert original longitude"); break; case POLAR_STEREOGRAPHIC: coniIO_double(coni,"geo.proj.","ps_lat:",&projection->param.ps.slat,"Polar Stereographic reference Latitude"); coniIO_double(coni,"geo.proj.","ps_lon:",&projection->param.ps.slon,"Polar Stereographic reference Longitude"); break; case UNIVERSAL_TRANSVERSE_MERCATOR: coniIO_int(coni,"geo.proj.","utm_zone:",&projection->param.utm.zone,"UTM Zone Code"); break; case LAT_LONG_PSEUDO_PROJECTION: break; // The following several cases get rid of compiler warnings case ALBERS_EQUAL_AREA: case LAMBERT_AZIMUTHAL_EQUAL_AREA: case STATE_PLANE: case UNKNOWN_PROJECTION: default: break; /* default: printf("ERROR! Unrecognized map projection code '%c!'\n",projection->type); exit(1); */ } coniIO_structClose(coni,"end proj"); } coniIO_char(coni,"geo.","lookDir:", &sar->look_direction, "SAR Satellite look direction (normally R) [R=right; L=left]"); coniIO_int(coni,"geo.","deskew:", &sar->deskewed, "Image moved to zero doppler? [1=yes; 0=no]"); coniIO_double(coni,"geo.","xPix:", &general->x_pixel_size, "Pixel size in X direction [m]"); coniIO_double(coni,"geo.","yPix:", &general->y_pixel_size, "Pixel size in Y direction [m]"); coniIO_double(coni,"geo.","rngPixTime:", &sar->range_time_per_pixel, "Time/pixel, range (xPix/(c/2.0), or 1/fs) [s]"); coniIO_double(coni,"geo.","azPixTime:", &sar->azimuth_time_per_pixel, "Time/pixel, azimuth (yPix/swathVel, or 1/prf) [s]"); coniIO_double(coni,"geo.","slantShift:", &sar->slant_shift, "Error correction factor, in slant range [m]"); coniIO_double(coni,"geo.","timeShift:", &sar->time_shift, "Error correction factor, in time [s]"); coniIO_double(coni,"geo.","slantFirst:", &sar->slant_range_first_pixel,"Slant range to first image pixel [m]"); coniIO_double(coni,"geo.","wavelength:", &sar->wavelength, "SAR Carrier Wavelength [m]"); coniIO_double(coni,"geo.","dopRangeCen:", &sar->range_doppler_coefficients[0], "Doppler centroid [Hz]"); coniIO_double(coni,"geo.","dopRangeLin:", &sar->range_doppler_coefficients[1], "Doppler per range pixel [Hz/pixel]"); coniIO_double(coni,"geo.","dopRangeQuad:",&sar->range_doppler_coefficients[2], "Doppler per range pixel sq. [Hz/(pixel^2)]"); coniIO_double(coni,"geo.","dopAzCen:", &sar->azimuth_doppler_coefficients[0],"Doppler centroid [Hz]"); coniIO_double(coni,"geo.","dopAzLin:", &sar->azimuth_doppler_coefficients[1],"Doppler per azimuth pixel [Hz/pixel]"); coniIO_double(coni,"geo.","dopAzQuad:", &sar->azimuth_doppler_coefficients[2],"Doppler per azimuth pixel sq. [Hz/(pixel^2)]"); coniIO_structClose(coni,"end geo\n"); /*Interferometry parameters:*/ coniIO_structOpen(coni,"ifm {","begin interferometry-related parameters"); coniIO_double(coni,"ifm.","er:",&sar->earth_radius,"Local earth radius [m]"); coniIO_double(coni,"ifm.","ht:",&sar->satellite_height,"Satellite height, from center of earth [m]"); if (meta->meta_version>0.6) coniIO_int(coni,"ifm.","nLooks:",&sar->azimuth_look_count, "Number of looks to take from SLC"); coniIO_int(coni,"ifm.","orig_lines:", &sar->original_line_count, "Number of lines in original image"); coniIO_int(coni,"ifm.","orig_samples:", &sar->original_sample_count,"Number of samples in original image"); coniIO_structClose(coni,"end ifm\n"); /*State Vectors:*/ { /*Check to see if the state vectors even exist.*/ int err,nVec; nVec=coniInt(coni,"state.number:",&err); coniReopen(coni);/*Seek back to beginning of file.*/ if (err==CONI_OK && nVec!=0) { /*We have state vectors!*/ meta->state_vectors = meta_state_vectors_init(nVec); /*Allocate state vectors.*/ meta_io_state(coni, meta->state_vectors); /*And initialize them.*/ } } /*Extra Info:*/ { /* Check to see if extra info exists.*/ int err; coniStr(coni,"extra.sensor:",&err); coniReopen(coni);/*Seek back to beginning of file.*/ if (err==CONI_OK) { coniIO_str (coni,"extra.","sensor:", general->sensor, "Imaging sensor"); if (meta->meta_version>0.7) coniIO_str (coni,"extra.","mode:", general->mode, "Imaging mode"); if (meta->meta_version>0.6) coniIO_str (coni,"extra.","processor:", general->processor, "Name & Version of SAR Processor"); if (meta->meta_version>0.7) { coniIO_int (coni,"extra.","orbit:", &general->orbit, "Orbit Number for this datatake"); coniIO_double(coni,"extra.","bitErrorRate:",&general->bit_error_rate, "Bit Error Rate"); coniIO_str (coni,"extra.","satBinTime:", sar->satellite_binary_time,"Satellite Binary Time"); coniIO_str (coni,"extra.","satClkTime:", sar->satellite_clock_time, "Satellite Clock Time (UTC)"); coniIO_double(coni,"extra.","prf:", &sar->prf, "Pulse Repetition Frequency"); } } } /* Info from ddr (if its there) */ if (fileExists(ddrName)) { c_getddr(ddrName, &ddr); general->line_count = ddr.nl; general->sample_count = ddr.ns; general->start_line = ddr.master_line - 1; general->start_sample = ddr.master_sample - 1; sar->line_increment = ddr.line_inc; sar->sample_increment = ddr.sample_inc; if (sar->image_type=='P') {strcpy(meta->projection->units, ddr.proj_units);} switch ( ddr.dtype ) { case 0: /* BYTE */ case DTYPE_BYTE: general->data_type = ASF_BYTE; break; case DTYPE_SHORT: general->data_type = INTEGER16; break; case DTYPE_LONG: general->data_type = INTEGER32; break; case DTYPE_FLOAT: general->data_type = REAL32; break; case DTYPE_DOUBLE: general->data_type = REAL64; break; case DTYPE_COMPLEX: general->data_type = COMPLEX_REAL32; break; default: printf("ERROR in meta_read_old(): Unrecognized DDR data type: (code %d)... Exit program.\n",ddr.dtype); exit(EXIT_FAILURE); } } /* else { printf("\n" "WARNING: * Failed to get DDR file while reading old style metadata.\n" " * Some meta fields will not be correctly initialized.\n"); }*/ /* Fields not yet filled */ general->orbit_direction = MAGIC_UNSET_CHAR; if (meta->state_vectors) { if (meta->state_vectors->vecs[0].vec.vel.z > 0) general->orbit_direction = 'A'; else if (meta->state_vectors->vecs[0].vec.vel.z < 0) general->orbit_direction = 'D'; } general->re_major = (meta->projection) ? meta->projection->re_major : 6378144.0; general->re_minor = (meta->projection) ? meta->projection->re_minor : 6356754.9; /* Close coni structure */ coniClose(coni); } /* End pre-1.1 version read */
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; }
void ceos_read_stVecs(const char *fName, ceos_description *ceos, meta_parameters *meta) { int i; double timeStart=0.0;/*Time of first state vector, relative to image start.*/ int areInertial=1;/*Flag: are state vectors in non-rotating frame?*/ int areInertialVelocity=0;/*Flag: have state vectors not been corrected for non-rotating frame?*/ int areFixedVelocity=0;/*Flag: were state vectors in fixed-earth velocity; but inertial coordinates?*/ meta_state_vectors *s; struct pos_data_rec ppdr; /*Fetch platform position data record.*/ get_ppdr(fName,&ppdr); /*Allocate output record.*/ meta->state_vectors = meta_state_vectors_init(ppdr.ndata); meta->state_vectors->vector_count = ppdr.ndata; s = meta->state_vectors; /*Determine State Vector Format.*/ if (0==strncmp(ppdr.ref_coord,"INERTIAL",9)) areInertial=1;/*Listed as Inertial-- believe it.*/ if (0==strncmp(ppdr.ref_coord,"EARTH CENTERED ROT",18)) areInertial=0;/*Listed as rotating-- believe it.*/ else if (0==strncmp(ppdr.ref_coord,"Earth Centred Rot",17)) areInertial = 0; else if (0 == strncmp(ppdr.ref_coord, "ECR", 3)) { areInertial = 0; //areInertialVelocity = 1; } else if (0 == strncmp(ppdr.ref_coord, "EARTH FIXED REFERENCE SYSTEM",28)) areInertial = 0; if (ppdr.hr_angle<=-99.0) areInertial=0;/*Bogus GHA-- must be fixed-earth*/ if (ceos->facility==ASF && ceos->processor==SP2 && ceos->version <=2.50) /*The SCANSAR processor made very odd state vectors before 2.51*/ areInertial=0,areInertialVelocity=1; /*Fill output record with inital time.*/ if (ceos->facility==ASF && ceos->processor!=LZP) {/* ASF's state vectors start at the same time as the images themselves.*/ timeStart = 0.0; s->year = (int) ppdr.year; s->julDay = (int) ppdr.gmt_day; s->second = ppdr.gmt_sec; } else {/*Most facility's state vectors don't necessarily start at the same time as the image.*/ timeStart=get_timeDelta(ceos,&ppdr,meta); s->year = (int) ppdr.year; s->julDay = (int) ppdr.gmt_day; s->second = ppdr.gmt_sec; } /*Fill ouput record with state vectors.*/ for (i=0; i<s->vector_count; i++) { /*Read a state vector from the record, fixing the units.*/ stateVector st; st.pos.x = ppdr.pos_vec[i][0]; st.pos.y = ppdr.pos_vec[i][1]; st.pos.z = ppdr.pos_vec[i][2]; vecScale(&st.pos,get_units(vecMagnitude(st.pos),EXPECTED_POS)); st.vel.x = ppdr.pos_vec[i][3]; st.vel.y = ppdr.pos_vec[i][4]; st.vel.z = ppdr.pos_vec[i][5]; vecScale(&st.vel,get_units(vecMagnitude(st.vel),EXPECTED_VEL)); /*Correct for non-rotating frame.*/ if (areInertial) gei2fixed(&st,ppdr2gha(&ppdr,ceos,i*ppdr.data_int)); /*Perform velocity fixes.*/ if (areInertialVelocity) gei2fixed(&st,0.0); else if (areFixedVelocity) fixed2gei(&st,0.0); /*Write out resulting state vectors.*/ s->vecs[i].vec = st; s->vecs[i].time = timeStart+i*ppdr.data_int; } }
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; }
/*************************************************************** * Ceos_init_stVec: * Reads state vectors from given CEOS file, writing them in the * appropriate format to SAR parameters structure.*/ void ceos_init_stVec(const char *fName, ceos_description *ceos, meta_parameters *meta) { struct pos_data_rec ppdr; /*Fetch platform position data record.*/ get_ppdr(fName,&ppdr); // Read the state vectors from the leader data file, adjust coordinate system, etc. // and write them to the SAR parameters structures ceos_read_stVecs(fName, ceos, meta); // For ALOS Palsar orbits only // Don't propagate but select nine state vectors around the center for the // higher order interpolation scheme if (ceos->processor == ALOS_PROC) { // Determine closest state vector int ii, min; double diff = 99999999; for (ii=0; ii<meta->state_vectors->vector_count; ii++) { if (fabs(meta->state_vectors->vecs[ii].time) < diff) { diff = fabs(meta->state_vectors->vecs[ii].time); min = ii; } } // Populate a new state vector ymd_date img_ymd; julian_date img_jd; hms_time img_time; img_jd.year = meta->state_vectors->year; img_jd.jd = meta->state_vectors->julDay; date_sec2hms(meta->state_vectors->second,&img_time); date_jd2ymd(&img_jd, &img_ymd); add_time((min-4)*60, &img_ymd, &img_time); date_ymd2jd(&img_ymd, &img_jd); meta_state_vectors *new_st = meta_state_vectors_init(9); new_st->year = img_jd.year; new_st->julDay = img_jd.jd; new_st->second = date_hms2sec(&img_time); for (ii=0; ii<9; ii++) new_st->vecs[ii] = meta->state_vectors->vecs[ii+min-4]; FREE(meta->state_vectors); meta->state_vectors = new_st; // Time shift should definitely set in the code that is calling this function // meta->sar->time_shift = 0.0; } // Propagate three state vectors for regular frames else if (ceos->processor != PREC && ceos->processor != unknownProcessor) { int vector_count=3; double data_int = meta->sar->original_line_count / 2 * fabs(meta->sar->azimuth_time_per_pixel); meta->state_vectors->vecs[0].time = get_timeDelta(ceos, &ppdr, meta); if (ceos->processor != PREC && data_int < 360.0) { while (fabs(data_int) > 15.0) { data_int /= 2; vector_count = vector_count*2-1; } // propagate three state vectors: start, center, end propagate_state(meta, vector_count, data_int); } } }
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; }
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); }