use of org.esa.snap.core.datamodel.MetadataElement in project snap-novasar-reader by bcdev.
the class NovaSARProductDirectory method addSRGRCoefficients.
// End of addVector()
// =============================================================================================================
// Function to extract the Ground Range to Slant Range coefficients from the metadata and load them into SNAP
// =============================================================================================================
private static void addSRGRCoefficients(final MetadataElement absRoot, final MetadataElement imageGenerationParameters, final double sampledPixelSpacing) {
final MetadataElement srgrCoefficientsElem = absRoot.getElement(AbstractMetadata.srgr_coefficients);
int listCnt = 1;
final String zdtfl = imageGenerationParameters.getAttributeString("ZeroDopplerTimeFirstLine");
ProductData.UTC zdtfl_utc = AbstractMetadata.parseUTC(zdtfl, standardDateFormat);
// ProductData.UTC zdtfl_utc = ReaderUtils.getTime(zdtfl_elem, "Value", standardDateFormat);
final MetadataElement srgrListElem = new MetadataElement(AbstractMetadata.srgr_coef_list + '.' + listCnt);
srgrCoefficientsElem.addElement(srgrListElem);
++listCnt;
srgrListElem.setAttributeUTC(AbstractMetadata.srgr_coef_time, zdtfl_utc);
// final MetadataElement srgrListElem = new MetadataElement(AbstractMetadata.srgr_coef_list + '.' + listCnt);
// srgrCoefficientsElem.addElement(srgrListElem);
// elem.getElement("groundRangeOrigin").getAttributeDouble("groundRangeOrigin", 0); // No parameter in NovaSAR metadata file for this. Must always be zero for NovaSAR.
final double grOrigin = 0.0;
AbstractMetadata.addAbstractedAttribute(srgrListElem, AbstractMetadata.ground_range_origin, ProductData.TYPE_FLOAT64, "m", "Ground Range Origin");
AbstractMetadata.setAttribute(srgrListElem, AbstractMetadata.ground_range_origin, grOrigin);
final String gtosrcoeffsString = imageGenerationParameters.getAttributeString("GroundToSlantRangeCoefficients");
if (!gtosrcoeffsString.isEmpty()) {
LOG.info("Sample pixel spacing: " + sampledPixelSpacing + "m");
LOG.info("Re-scaling NovaSAR metadata SRGR coefficients (by dividing each by (sample pixel spacing)^n where (n = 0 to 5))");
LOG.info("to ensure that slant-range is calculated correctly using ground-range in metres");
LOG.info("Note: NovaSAR SRGR coefficients are for ground-range in pixels; SNAP expects ground-range in metres");
StringBuilder originalCoeffsSb = new StringBuilder();
StringBuilder rescaledCoeffsSb = new StringBuilder();
StringTokenizer st = new StringTokenizer(gtosrcoeffsString);
int cnt = 1;
while (st.hasMoreTokens()) {
final double coefValue = Double.parseDouble(st.nextToken());
originalCoeffsSb.append(coefValue + " ");
// Rescale the SRGR coefficients (used in the polynomial to convert ground range to slant range)
// as they are for cross-track distance specified in pixels, whereas the SNAP code expects the cross-track
// distance to be specified in metres. Rescaling the SRGR coefficients in this way corrects the issue
final double rescaledCoefValue = coefValue / Math.pow(sampledPixelSpacing, cnt - 1);
rescaledCoeffsSb.append(rescaledCoefValue + " ");
final MetadataElement coefElem = new MetadataElement(AbstractMetadata.coefficient + '.' + cnt);
srgrListElem.addElement(coefElem);
++cnt;
AbstractMetadata.addAbstractedAttribute(coefElem, AbstractMetadata.srgr_coef, ProductData.TYPE_FLOAT64, "", "SRGR Coefficient");
AbstractMetadata.setAttribute(coefElem, AbstractMetadata.srgr_coef, rescaledCoefValue);
}
LOG.info("Original SRGR coefficients: " + originalCoeffsSb.toString());
LOG.info("Rescaled SRGR coefficients: " + rescaledCoeffsSb.toString());
}
}
use of org.esa.snap.core.datamodel.MetadataElement in project snap-novasar-reader by bcdev.
the class NovaSARProductDirectory method setLatLongMetadata.
// End of addGeoCoding()
// ====================================================================================================================
// Function to set image corner tiepoint longitudes and latitudes in the SNAP structures
//
// - called by addGeoCoding()
// ====================================================================================================================
private static void setLatLongMetadata(Product product, TiePointGrid latGrid, TiePointGrid lonGrid) {
final MetadataElement absRoot = AbstractMetadata.getAbstractedMetadata(product);
final int w = product.getSceneRasterWidth();
final int h = product.getSceneRasterHeight();
AbstractMetadata.setAttribute(absRoot, AbstractMetadata.first_near_lat, latGrid.getPixelDouble(0, 0));
AbstractMetadata.setAttribute(absRoot, AbstractMetadata.first_near_long, lonGrid.getPixelDouble(0, 0));
AbstractMetadata.setAttribute(absRoot, AbstractMetadata.first_far_lat, latGrid.getPixelDouble(w - 1, 0));
AbstractMetadata.setAttribute(absRoot, AbstractMetadata.first_far_long, lonGrid.getPixelDouble(w - 1, 0));
AbstractMetadata.setAttribute(absRoot, AbstractMetadata.last_near_lat, latGrid.getPixelDouble(0, h - 1));
AbstractMetadata.setAttribute(absRoot, AbstractMetadata.last_near_long, lonGrid.getPixelDouble(0, h - 1));
AbstractMetadata.setAttribute(absRoot, AbstractMetadata.last_far_lat, latGrid.getPixelDouble(w - 1, h - 1));
AbstractMetadata.setAttribute(absRoot, AbstractMetadata.last_far_long, lonGrid.getPixelDouble(w - 1, h - 1));
}
use of org.esa.snap.core.datamodel.MetadataElement in project snap-novasar-reader by bcdev.
the class NovaSARProductDirectory method addTiePointGrids.
// ========================================================================================================================================================================================
// Function to
// ========================================================================================================================================================================================
@Override
protected void addTiePointGrids(final Product product) {
final int sourceImageWidth = product.getSceneRasterWidth();
final int sourceImageHeight = product.getSceneRasterHeight();
final int gridWidth = 11;
final int gridHeight = 11;
final int subSamplingX = (int) ((float) sourceImageWidth / (float) (gridWidth - 1));
final int subSamplingY = (int) ((float) sourceImageHeight / (float) (gridHeight - 1));
// WGS 84: equatorial Earth radius in m
double a = Constants.semiMajorAxis;
// WGS 84: polar Earth radius in m
double b = Constants.semiMinorAxis;
// Get slant range to first pixel and pixel spacing
final MetadataElement absRoot = AbstractMetadata.getAbstractedMetadata(product);
// in m
final double slantRangeToFirstPixel = absRoot.getAttributeDouble(AbstractMetadata.slant_range_to_first_pixel, 0);
// in m
final double rangeSpacing = absRoot.getAttributeDouble(AbstractMetadata.range_spacing, 0);
final boolean srgrFlag = absRoot.getAttributeInt(AbstractMetadata.srgr_flag) != 0;
final boolean isDescending = absRoot.getAttributeString(AbstractMetadata.PASS).equals("DESCENDING");
final boolean isAntennaPointingRight = absRoot.getAttributeString(AbstractMetadata.antenna_pointing).equals("right");
// Get scene center latitude
final GeoPos sceneCenterPos = product.getSceneGeoCoding().getGeoPos(new PixelPos(sourceImageWidth / 2.0f, sourceImageHeight / 2.0f), null);
// in deg
double sceneCenterLatitude = sceneCenterPos.lat;
// Get near range incidence angle
final MetadataElement origProdRoot = AbstractMetadata.getOriginalProductMetadata(product);
final MetadataElement origMetaData = origProdRoot.getElement("metadata");
final MetadataElement imageGenerationParameters = origMetaData.getElement("Image_Generation_Parameters");
// Get the Incidence Angle Coefficients string
final String incAngleCoeffs = imageGenerationParameters.getAttributeString("IncAngleCoeffs", defStr);
// Convert it to a tokeniser
StringTokenizer st = new StringTokenizer(incAngleCoeffs);
// Extract the first token substring (which is the near edge incidence angle) as a double
final double nearRangeIncidenceAngle = Double.parseDouble(st.nextToken());
final double alpha1 = nearRangeIncidenceAngle * Constants.DTOR;
final double lambda = sceneCenterLatitude * Constants.DTOR;
final double cos2 = FastMath.cos(lambda) * FastMath.cos(lambda);
final double sin2 = FastMath.sin(lambda) * FastMath.sin(lambda);
final double e2 = (b * b) / (a * a);
final double rt = a * Math.sqrt((cos2 + e2 * e2 * sin2) / (cos2 + e2 * sin2));
final double rt2 = rt * rt;
double groundRangeSpacing;
if (srgrFlag) {
// ground range - so use as is
groundRangeSpacing = rangeSpacing;
} else {
// slant range - so convert to ground range
groundRangeSpacing = rangeSpacing / FastMath.sin(alpha1);
}
// in radians
double deltaPsi = groundRangeSpacing / rt;
final double r1 = slantRangeToFirstPixel;
final double rtPlusH = Math.sqrt(rt2 + r1 * r1 + 2.0 * rt * r1 * FastMath.cos(alpha1));
final double rtPlusH2 = rtPlusH * rtPlusH;
final double theta1 = FastMath.acos((r1 + rt * FastMath.cos(alpha1)) / rtPlusH);
final double psi1 = alpha1 - theta1;
double psi = psi1;
float[] incidenceAngles = new float[gridWidth];
final int n = gridWidth * subSamplingX;
int k = 0;
for (int i = 0; i < n; i++) {
final double ri = Math.sqrt(rt2 + rtPlusH2 - 2.0 * rt * rtPlusH * FastMath.cos(psi));
final double alpha = FastMath.acos((rtPlusH2 - ri * ri - rt2) / (2.0 * ri * rt));
if (i % subSamplingX == 0) {
int index = k++;
incidenceAngles[index] = (float) (alpha * Constants.RTOD);
}
if (!srgrFlag) {
// complex
groundRangeSpacing = rangeSpacing / FastMath.sin(alpha);
deltaPsi = groundRangeSpacing / rt;
}
psi = psi + deltaPsi;
}
float[] incidenceAngleList = new float[gridWidth * gridHeight];
for (int j = 0; j < gridHeight; j++) {
System.arraycopy(incidenceAngles, 0, incidenceAngleList, j * gridWidth, gridWidth);
}
final TiePointGrid incidentAngleGrid = new TiePointGrid(OperatorUtils.TPG_INCIDENT_ANGLE, gridWidth, gridHeight, 0, 0, subSamplingX, subSamplingY, incidenceAngleList);
incidentAngleGrid.setUnit(Unit.DEGREES);
product.addTiePointGrid(incidentAngleGrid);
// addSlantRangeTime(product, imageGenerationParameters);
}
use of org.esa.snap.core.datamodel.MetadataElement in project snap-novasar-reader by bcdev.
the class NovaSARProductDirectory method addVector.
// End of addOrbitStateVectors()
// ========================================================================================================
// Function to extract the parameters of an orbit State Vector from the metadata and load them into SNAP
// ========================================================================================================
private static void addVector(String name, MetadataElement orbitVectorListElem, MetadataElement srcElem, int num) {
final MetadataElement orbitVectorElem = new MetadataElement(name + num);
orbitVectorElem.setAttributeUTC(AbstractMetadata.orbit_vector_time, ReaderUtils.getTime(srcElem, "Time", standardDateFormat));
final MetadataElement xpos = srcElem.getElement("xPosition");
orbitVectorElem.setAttributeDouble(AbstractMetadata.orbit_vector_x_pos, xpos.getAttributeDouble("xPosition", 0));
final MetadataElement ypos = srcElem.getElement("yPosition");
orbitVectorElem.setAttributeDouble(AbstractMetadata.orbit_vector_y_pos, ypos.getAttributeDouble("yPosition", 0));
final MetadataElement zpos = srcElem.getElement("zPosition");
orbitVectorElem.setAttributeDouble(AbstractMetadata.orbit_vector_z_pos, zpos.getAttributeDouble("zPosition", 0));
final MetadataElement xvel = srcElem.getElement("xVelocity");
orbitVectorElem.setAttributeDouble(AbstractMetadata.orbit_vector_x_vel, xvel.getAttributeDouble("xVelocity", 0));
final MetadataElement yvel = srcElem.getElement("yVelocity");
orbitVectorElem.setAttributeDouble(AbstractMetadata.orbit_vector_y_vel, yvel.getAttributeDouble("yVelocity", 0));
final MetadataElement zvel = srcElem.getElement("zVelocity");
orbitVectorElem.setAttributeDouble(AbstractMetadata.orbit_vector_z_vel, zvel.getAttributeDouble("zVelocity", 0));
orbitVectorListElem.addElement(orbitVectorElem);
}
use of org.esa.snap.core.datamodel.MetadataElement in project snap-novasar-reader by bcdev.
the class NovaSARProductDirectory method addOrbitStateVectors.
// End of getPolarizations()
// ==========================================================================================================================================
// Function to analyse the dataType metadata element and return its contents as either "COMPLEX" or "DETECTED"
// ==========================================================================================================================================
// private static String getDataType(final MetadataElement rasterAttributes)
// {
//
// final String dataType = rasterAttributes.getAttributeString("dataType", AbstractMetadata.NO_METADATA_STRING).toUpperCase();
// if (dataType.contains("COMPLEX")) return "COMPLEX";
// return "DETECTED";
//
// } // End of getDataType()
// ==========================================================================================================================================
// Function to read in all the orbit state vectors from the metadata file and load them into the SNAP structures using calls to addVector()
// ==========================================================================================================================================
private static void addOrbitStateVectors(final MetadataElement absRoot, final MetadataElement orbitData) {
final MetadataElement orbitVectorListElem = absRoot.getElement(AbstractMetadata.orbit_state_vectors);
final int numVectors = orbitData.getAttributeInt("NumberOfStateVectorSets");
final MetadataElement[] stateVectorElems = orbitData.getElements();
for (int i = 1; i <= numVectors; i++) {
addVector(AbstractMetadata.orbit_vector, orbitVectorListElem, stateVectorElems[i - 1], i);
}
// set state vector time
if (absRoot.getAttributeUTC(AbstractMetadata.STATE_VECTOR_TIME, AbstractMetadata.NO_METADATA_UTC).equalElems(AbstractMetadata.NO_METADATA_UTC)) {
AbstractMetadata.setAttribute(absRoot, AbstractMetadata.STATE_VECTOR_TIME, ReaderUtils.getTime(stateVectorElems[0], "Time", standardDateFormat));
}
}
Aggregations