From d1c4d7f93fe3f9ec11bf11e32259ea02b21a0dcd Mon Sep 17 00:00:00 2001 From: "Gustavo H. X. Shiroma" Date: Thu, 3 Jul 2025 11:30:42 -0700 Subject: [PATCH 1/5] disable polarimetric symmetrization by default --- share/nisar/defaults/gcov.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/share/nisar/defaults/gcov.yaml b/share/nisar/defaults/gcov.yaml index db0c71352..3b9da8a89 100644 --- a/share/nisar/defaults/gcov.yaml +++ b/share/nisar/defaults/gcov.yaml @@ -177,7 +177,7 @@ runconfig: # HV and VH), otherwise, the flag is ignored. # If enabled, the output product's "HV" dataset will contain symmetrized # HV/VH data and the "VH" dataset will be omitted from the output. - symmetrize_cross_pol_channels: True + symmetrize_cross_pol_channels: False # TODO OPTIONAL - Only checked when internet access is available dem_download: From 2ac26942f19a6ff2e3145a96ca52044d09f867ea Mon Sep 17 00:00:00 2001 From: "Gustavo H. X. Shiroma" Date: Tue, 22 Jul 2025 13:58:03 -0700 Subject: [PATCH 2/5] revert changes to `symmetrize_cross_pol_channels` --- share/nisar/defaults/gcov.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/share/nisar/defaults/gcov.yaml b/share/nisar/defaults/gcov.yaml index 3b9da8a89..db0c71352 100644 --- a/share/nisar/defaults/gcov.yaml +++ b/share/nisar/defaults/gcov.yaml @@ -177,7 +177,7 @@ runconfig: # HV and VH), otherwise, the flag is ignored. # If enabled, the output product's "HV" dataset will contain symmetrized # HV/VH data and the "VH" dataset will be omitted from the output. - symmetrize_cross_pol_channels: False + symmetrize_cross_pol_channels: True # TODO OPTIONAL - Only checked when internet access is available dem_download: From 05d7fda0ff21704541179bfc5b0fb5415ebae1b6 Mon Sep 17 00:00:00 2001 From: "Gustavo H. X. Shiroma" Date: Tue, 22 Jul 2025 16:01:58 -0700 Subject: [PATCH 3/5] Update GCOV and GSLC specification XMLs --- .../nisar/products/XML/L2/nisar_L2_GCOV.xml | 291 ++++++++++------ .../nisar/products/XML/L2/nisar_L2_GSLC.xml | 321 +++++++++++------- 2 files changed, 371 insertions(+), 241 deletions(-) diff --git a/python/packages/nisar/products/XML/L2/nisar_L2_GCOV.xml b/python/packages/nisar/products/XML/L2/nisar_L2_GCOV.xml index 021b48b6a..a9e931bdb 100644 --- a/python/packages/nisar/products/XML/L2/nisar_L2_GCOV.xml +++ b/python/packages/nisar/products/XML/L2/nisar_L2_GCOV.xml @@ -105,7 +105,7 @@ + shape="numberOfObservations"> List of planned datatakes included in the product @@ -127,13 +127,19 @@ List of frequency layers available in the product - + List of each input raw dataset's observation mode + + - Indicates if the radar operation mode is a diagnostic mode (1-2) or DBFed science (0): 0, 1, or 2 - + Indicates if the radar operation mode is a diagnostic mode (1-2) or DBFed science (0): 0, 1, or 2 + @@ -182,7 +188,7 @@ name="/science/LSAR/identification/processingType" shape="scalar"> Nominal (or) Urgent (or) Custom (or) Undefined + lang="en">Processing pipeline used to generate this granule. "Nominal": standard production system; "Urgent": time-sensitive processing in response to urgent response events; "Custom": user-initiated processing outside the nominal production system X coordinates in specified projection Y coordinates in specified projection @@ -329,7 +337,7 @@ valid_min="0" _FillValue="nan" grid_mapping="projection" - units="1">Radiometric terrain correction factor to normalize GCOV terms from gamma0 to sigma0 + units="1">Radiometric terrain correction (RTC) scaling factor to normalize backscatter coefficients from gamma0 to sigma0, accounting for local terrain Mask indicating the subswath number associated with valid GCOV samples. A GCOV sample is only considered valid if it is generated from fully-focused radar samples. If at least one radar sample in the averaging set is partially focused or invalid, the corresponding mask pixel will contain the value `0`. GCOV pixels outside of the radar acquisition extent are filled with the value `255` + grid_mapping="projection">Mask indicating the subswath number associated with valid GCOV samples. A GCOV sample is only considered valid if it is generated from fully-focused radar samples. If at least one radar sample in the averaging set is partially focused or invalid, the corresponding mask pixel will contain the value 0. GCOV pixels outside of the radar acquisition extent are filled with the value 255 X coordinates in specified projection Y coordinates in specified projection @@ -706,7 +716,7 @@ valid_min="0" _FillValue="nan" grid_mapping="projection" - units="1">Radiometric terrain correction factor to normalize GCOV terms from gamma0 to sigma0 + units="1">Radiometric terrain correction (RTC) scaling factor to normalize backscatter coefficients from gamma0 to sigma0, accounting for local terrain Mask indicating the subswath number associated with valid GCOV samples. A GCOV sample is only considered valid if it is generated from fully-focused radar samples. If at least one radar sample in the averaging set is partially focused or invalid, the corresponding mask pixel will contain the value `0`. GCOV pixels outside of the radar acquisition extent are filled with the value `255` + grid_mapping="projection">Mask indicating the subswath number associated with valid GCOV samples. A GCOV sample is only considered valid if it is generated from fully-focused radar samples. If at least one radar sample in the averaging set is partially focused or invalid, the corresponding mask pixel will contain the value 0. GCOV pixels outside of the radar acquisition extent are filled with the value 255 East component of unit vector of LOS from target to sensor + units="1">East component of the line-of-sight (LOS) unit vector, defined from the target to the sensor, expressed in the east-north-up (ENU) coordinate system with its origin at the target location North component of unit vector of LOS from target to sensor + units="1">North component of the line-of-sight (LOS) unit vector, defined from the target to the sensor, expressed in the east-north-up (ENU) coordinate system with its origin at the target location East component of unit vector along ground track + units="1">East component of the along-track unit vector at the target location, expressed in the east-north-up (ENU) coordinate system and projected onto the horizontal plane (i.e., excluding the up component) North component of unit vector along ground track + units="1">North component of the along-track unit vector at the target location, expressed in the east-north-up (ENU) coordinate system and projected onto the horizontal plane (i.e., excluding the up component) X coordinates in specified projection X coordinates in specified projection - - + + Product map grid projection: EPSG code, with additional projection information as HDF5 Attributes + + + Y coordinates in specified projection + + + X coordinates in specified projection + Crosstalk in H-transmit channel expressed as ratio txV / txH Crosstalk in V-transmit channel expressed as ratio txH / txV Crosstalk in H-receive channel expressed as ratio rxV / rxH Crosstalk in V-receive channel expressed as ratio rxH / rxV + + @@ -2437,14 +2519,14 @@ Reference Terrain Height as a function of map coordinates + units="meters">Reference terrain height as a function of map coordinates scalar values - - - number of datatakes in product - - - number of observations in product + lang="en">Number of observations in product @@ -3372,28 +3445,22 @@ Shape of calibration LUTs + lang="en">Shape of real-valued calibration LUTs - Shape of antenna pattern datasets + lang="en">Shape of complex-valued calibration LUTs - - Shape of crosstalk datasets - - + shape="numberOfObservations"> List of planned datatakes included in the product @@ -127,13 +127,19 @@ List of frequency layers available in the product - + List of each input raw dataset's observation mode + + - Indicates if the radar operation mode is a diagnostic mode (1-2) or DBFed science (0): 0, 1, or 2 - + Indicates if the radar operation mode is a diagnostic mode (1-2) or DBFed science (0): 0, 1, or 2 + @@ -182,7 +188,7 @@ name="/science/LSAR/identification/processingType" shape="scalar"> Nominal (or) Urgent (or) Custom (or) Undefined + lang="en">Processing pipeline used to generate this granule. "Nominal": standard production system; "Urgent": time-sensitive processing in response to urgent response events; "Custom": user-initiated processing outside the nominal production system Mask indicating the subswath number representing valid GSLC samples. Each GSLC pixel is assumed valid if all the pixels in the interpolation window are fully focused in the input RSLC. A value of `0` indicates that at least one RSLC pixel in the interpolation window is partially focused or invalid. Pixels outside of the radar acquisition extent are filled with the value `255`. + _FillValue="255">Mask indicating the subswath number representing valid GSLC samples. Each GSLC pixel is assumed valid if all the pixels in the interpolation window are fully focused in the input RSLC. A value of 0 indicates that at least one RSLC pixel in the interpolation window is partially focused or invalid. Pixels outside of the radar acquisition extent are filled with the value 255. Focused SLC image (HH) @@ -373,7 +379,7 @@ mean_real_value="Arithmetic average of the real part of the numeric data points" sample_stddev_real="Standard deviation of the real part of the numeric data points" long_name="Geocoded single-look complex image HV" - grid_mapping='projection' + grid_mapping="projection" DIMENSION_LIST="HDF5 internal attribute" _FillValue="(nan+nan*j)" units="1">Focused SLC image (HV) @@ -393,7 +399,7 @@ mean_real_value="Arithmetic average of the real part of the numeric data points" sample_stddev_real="Standard deviation of the real part of the numeric data points" long_name="Geocoded single-look complex image VH" - grid_mapping='projection' + grid_mapping="projection" DIMENSION_LIST="HDF5 internal attribute" _FillValue="(nan+nan*j)" units="1">Focused SLC image (VH) @@ -413,7 +419,7 @@ mean_real_value="Arithmetic average of the real part of the numeric data points" sample_stddev_real="Standard deviation of the real part of the numeric data points" long_name="Geocoded single-look complex image VV" - grid_mapping='projection' + grid_mapping="projection" DIMENSION_LIST="HDF5 internal attribute" _FillValue="(nan+nan*j)" units="1">Focused SLC image (VV) @@ -433,7 +439,7 @@ mean_real_value="Arithmetic average of the real part of the numeric data points" sample_stddev_real="Standard deviation of the real part of the numeric data points" long_name="Geocoded single-look complex image RH" - grid_mapping='projection' + grid_mapping="projection" DIMENSION_LIST="HDF5 internal attribute" _FillValue="(nan+nan*j)" units="1">Focused SLC image (RH) @@ -453,7 +459,7 @@ mean_real_value="Arithmetic average of the real part of the numeric data points" sample_stddev_real="Standard deviation of the real part of the numeric data points" long_name="Geocoded single-look complex image RV" - grid_mapping='projection' + grid_mapping="projection" DIMENSION_LIST="HDF5 internal attribute" _FillValue="(nan+nan*j)" units="1">Focused SLC image (RV) @@ -538,14 +544,14 @@ Mask indicating the subswath number representing valid GSLC samples. Each GSLC pixel is assumed valid if all the pixels in the interpolation window are fully focused in the input RSLC. A value of `0` indicates that at least one RSLC pixel in the interpolation window is partially focused or invalid. Pixels outside of the radar acquisition extent are filled with the value `255`. + _FillValue="255">Mask indicating the subswath number representing valid GSLC samples. Each GSLC pixel is assumed valid if all the pixels in the interpolation window are fully focused in the input RSLC. A value of 0 indicates that at least one RSLC pixel in the interpolation window is partially focused or invalid. Pixels outside of the radar acquisition extent are filled with the value 255. Focused SLC image (HH) @@ -626,7 +632,7 @@ mean_real_value="Arithmetic average of the real part of the numeric data points" sample_stddev_real="Standard deviation of the real part of the numeric data points" long_name="Geocoded single-look complex image HV" - grid_mapping='projection' + grid_mapping="projection" DIMENSION_LIST="HDF5 internal attribute" _FillValue="(nan+nan*j)" units="1">Focused SLC image (HV) @@ -646,7 +652,7 @@ mean_real_value="Arithmetic average of the real part of the numeric data points" sample_stddev_real="Standard deviation of the real part of the numeric data points" long_name="Geocoded single-look complex image VH" - grid_mapping='projection' + grid_mapping="projection" DIMENSION_LIST="HDF5 internal attribute" _FillValue="(nan+nan*j)" units="1">Focused SLC image (VH) @@ -666,7 +672,7 @@ mean_real_value="Arithmetic average of the real part of the numeric data points" sample_stddev_real="Standard deviation of the real part of the numeric data points" long_name="Geocoded single-look complex image VV" - grid_mapping='projection' + grid_mapping="projection" DIMENSION_LIST="HDF5 internal attribute" _FillValue="(nan+nan*j)" units="1">Focused SLC image (VV) @@ -686,7 +692,7 @@ mean_real_value="Arithmetic average of the real part of the numeric data points" sample_stddev_real="Standard deviation of the real part of the numeric data points" long_name="Geocoded single-look complex image RH" - grid_mapping='projection' + grid_mapping="projection" DIMENSION_LIST="HDF5 internal attribute" _FillValue="(nan+nan*j)" units="1">Focused SLC image (RH) @@ -706,7 +712,7 @@ mean_real_value="Arithmetic average of the real part of the numeric data points" sample_stddev_real="Standard deviation of the real part of the numeric data points" long_name="Geocoded single-look complex image RVH" - grid_mapping='projection' + grid_mapping="projection" DIMENSION_LIST="HDF5 internal attribute" _FillValue="(nan+nan*j)" units="1">Focused SLC image (RV) @@ -832,7 +838,7 @@ _FillValue="nan" grid_mapping="projection" long_name="LOS unit vector X" - units="1">East component of unit vector of LOS from target to sensor + units="1">East component of the line-of-sight (LOS) unit vector, defined from the target to the sensor, expressed in the east-north-up (ENU) coordinate system with its origin at the target location North component of unit vector of LOS from target to sensor + units="1">North component of the line-of-sight (LOS) unit vector, defined from the target to the sensor, expressed in the east-north-up (ENU) coordinate system with its origin at the target location East component of unit vector along ground track + units="1">East component of the along-track unit vector at the target location, expressed in the east-north-up (ENU) coordinate system and projected onto the horizontal plane (i.e., excluding the up component) North component of unit vector along ground track + units="1">North component of the along-track unit vector at the target location, expressed in the east-north-up (ENU) coordinate system and projected onto the horizontal plane (i.e., excluding the up component) X coordinates in specified projection X coordinates in specified projection - - + + Product map grid projection: EPSG code, with additional projection information as HDF5 Attributes + + + Y coordinates in specified projection + + + X coordinates in specified projection + Crosstalk in H-transmit channel expressed as ratio txV / txH Crosstalk in V-transmit channel expressed as ratio txH / txV Crosstalk in H-receive channel expressed as ratio rxV / rxH Crosstalk in V-receive channel expressed as ratio rxH / rxV + + @@ -2096,7 +2174,7 @@ lang="en" _FillValue="nan" grid_mapping="projection" - units="meters">Reference Terrain Height as a function of geographical location + units="meters">Reference terrain height as a function of map coordinates scalar values - - - number of datatakes in product - - - number of observations in product + lang="en">Number of observations in product @@ -3116,28 +3185,22 @@ Shape of calibration LUTs + lang="en">Shape of real-valued calibration LUTs - Shape of antenna pattern datasets + lang="en">Shape of complex-valued calibration LUTs - - Shape of crosstalk datasets - - Number of input L1 SLC granules + name="numberOfInputL1Files"/> From 749058db5115479f727ca055d828370ecd1ec07e Mon Sep 17 00:00:00 2001 From: "Gustavo H. X. Shiroma" Date: Wed, 23 Jul 2025 11:45:11 -0700 Subject: [PATCH 4/5] Revert changes to the GCOV and GSLC specification XMLs --- .../nisar/products/XML/L2/nisar_L2_GCOV.xml | 291 ++++++---------- .../nisar/products/XML/L2/nisar_L2_GSLC.xml | 321 +++++++----------- 2 files changed, 241 insertions(+), 371 deletions(-) diff --git a/python/packages/nisar/products/XML/L2/nisar_L2_GCOV.xml b/python/packages/nisar/products/XML/L2/nisar_L2_GCOV.xml index a9e931bdb..021b48b6a 100644 --- a/python/packages/nisar/products/XML/L2/nisar_L2_GCOV.xml +++ b/python/packages/nisar/products/XML/L2/nisar_L2_GCOV.xml @@ -105,7 +105,7 @@ + shape="numberOfDatatakes"> List of planned datatakes included in the product @@ -127,19 +127,13 @@ List of frequency layers available in the product - - List of each input raw dataset's observation mode - - - Indicates if the radar operation mode is a diagnostic mode (1-2) or DBFed science (0): 0, 1, or 2 - + Indicates if the radar operation mode is a diagnostic mode (1-2) or DBFed science (0): 0, 1, or 2 + @@ -188,7 +182,7 @@ name="/science/LSAR/identification/processingType" shape="scalar"> Processing pipeline used to generate this granule. "Nominal": standard production system; "Urgent": time-sensitive processing in response to urgent response events; "Custom": user-initiated processing outside the nominal production system + lang="en">Nominal (or) Urgent (or) Custom (or) Undefined X coordinates in specified projection Y coordinates in specified projection @@ -337,7 +329,7 @@ valid_min="0" _FillValue="nan" grid_mapping="projection" - units="1">Radiometric terrain correction (RTC) scaling factor to normalize backscatter coefficients from gamma0 to sigma0, accounting for local terrain + units="1">Radiometric terrain correction factor to normalize GCOV terms from gamma0 to sigma0 Mask indicating the subswath number associated with valid GCOV samples. A GCOV sample is only considered valid if it is generated from fully-focused radar samples. If at least one radar sample in the averaging set is partially focused or invalid, the corresponding mask pixel will contain the value 0. GCOV pixels outside of the radar acquisition extent are filled with the value 255 + grid_mapping="projection">Mask indicating the subswath number associated with valid GCOV samples. A GCOV sample is only considered valid if it is generated from fully-focused radar samples. If at least one radar sample in the averaging set is partially focused or invalid, the corresponding mask pixel will contain the value `0`. GCOV pixels outside of the radar acquisition extent are filled with the value `255` X coordinates in specified projection Y coordinates in specified projection @@ -716,7 +706,7 @@ valid_min="0" _FillValue="nan" grid_mapping="projection" - units="1">Radiometric terrain correction (RTC) scaling factor to normalize backscatter coefficients from gamma0 to sigma0, accounting for local terrain + units="1">Radiometric terrain correction factor to normalize GCOV terms from gamma0 to sigma0 Mask indicating the subswath number associated with valid GCOV samples. A GCOV sample is only considered valid if it is generated from fully-focused radar samples. If at least one radar sample in the averaging set is partially focused or invalid, the corresponding mask pixel will contain the value 0. GCOV pixels outside of the radar acquisition extent are filled with the value 255 + grid_mapping="projection">Mask indicating the subswath number associated with valid GCOV samples. A GCOV sample is only considered valid if it is generated from fully-focused radar samples. If at least one radar sample in the averaging set is partially focused or invalid, the corresponding mask pixel will contain the value `0`. GCOV pixels outside of the radar acquisition extent are filled with the value `255` East component of the line-of-sight (LOS) unit vector, defined from the target to the sensor, expressed in the east-north-up (ENU) coordinate system with its origin at the target location + units="1">East component of unit vector of LOS from target to sensor North component of the line-of-sight (LOS) unit vector, defined from the target to the sensor, expressed in the east-north-up (ENU) coordinate system with its origin at the target location + units="1">North component of unit vector of LOS from target to sensor East component of the along-track unit vector at the target location, expressed in the east-north-up (ENU) coordinate system and projected onto the horizontal plane (i.e., excluding the up component) + units="1">East component of unit vector along ground track North component of the along-track unit vector at the target location, expressed in the east-north-up (ENU) coordinate system and projected onto the horizontal plane (i.e., excluding the up component) + units="1">North component of unit vector along ground track X coordinates in specified projection X coordinates in specified projection + + - - Product map grid projection: EPSG code, with additional projection information as HDF5 Attributes - - - Y coordinates in specified projection - - - X coordinates in specified projection - Crosstalk in H-transmit channel expressed as ratio txV / txH Crosstalk in V-transmit channel expressed as ratio txH / txV Crosstalk in H-receive channel expressed as ratio rxV / rxH Crosstalk in V-receive channel expressed as ratio rxH / rxV - - @@ -2519,14 +2437,14 @@ Reference terrain height as a function of map coordinates + units="meters">Reference Terrain Height as a function of map coordinates scalar values + + + number of datatakes in product + + + Number of observations in product + lang="en">number of observations in product @@ -3445,22 +3372,28 @@ Shape of real-valued calibration LUTs + lang="en">Shape of calibration LUTs - Shape of complex-valued calibration LUTs + lang="en">Shape of antenna pattern datasets + + Shape of crosstalk datasets + + + shape="numberOfDatatakes"> List of planned datatakes included in the product @@ -127,19 +127,13 @@ List of frequency layers available in the product - - List of each input raw dataset's observation mode - - - Indicates if the radar operation mode is a diagnostic mode (1-2) or DBFed science (0): 0, 1, or 2 - + Indicates if the radar operation mode is a diagnostic mode (1-2) or DBFed science (0): 0, 1, or 2 + @@ -188,7 +182,7 @@ name="/science/LSAR/identification/processingType" shape="scalar"> Processing pipeline used to generate this granule. "Nominal": standard production system; "Urgent": time-sensitive processing in response to urgent response events; "Custom": user-initiated processing outside the nominal production system + lang="en">Nominal (or) Urgent (or) Custom (or) Undefined Mask indicating the subswath number representing valid GSLC samples. Each GSLC pixel is assumed valid if all the pixels in the interpolation window are fully focused in the input RSLC. A value of 0 indicates that at least one RSLC pixel in the interpolation window is partially focused or invalid. Pixels outside of the radar acquisition extent are filled with the value 255. + _FillValue="255">Mask indicating the subswath number representing valid GSLC samples. Each GSLC pixel is assumed valid if all the pixels in the interpolation window are fully focused in the input RSLC. A value of `0` indicates that at least one RSLC pixel in the interpolation window is partially focused or invalid. Pixels outside of the radar acquisition extent are filled with the value `255`. Focused SLC image (HH) @@ -379,7 +373,7 @@ mean_real_value="Arithmetic average of the real part of the numeric data points" sample_stddev_real="Standard deviation of the real part of the numeric data points" long_name="Geocoded single-look complex image HV" - grid_mapping="projection" + grid_mapping='projection' DIMENSION_LIST="HDF5 internal attribute" _FillValue="(nan+nan*j)" units="1">Focused SLC image (HV) @@ -399,7 +393,7 @@ mean_real_value="Arithmetic average of the real part of the numeric data points" sample_stddev_real="Standard deviation of the real part of the numeric data points" long_name="Geocoded single-look complex image VH" - grid_mapping="projection" + grid_mapping='projection' DIMENSION_LIST="HDF5 internal attribute" _FillValue="(nan+nan*j)" units="1">Focused SLC image (VH) @@ -419,7 +413,7 @@ mean_real_value="Arithmetic average of the real part of the numeric data points" sample_stddev_real="Standard deviation of the real part of the numeric data points" long_name="Geocoded single-look complex image VV" - grid_mapping="projection" + grid_mapping='projection' DIMENSION_LIST="HDF5 internal attribute" _FillValue="(nan+nan*j)" units="1">Focused SLC image (VV) @@ -439,7 +433,7 @@ mean_real_value="Arithmetic average of the real part of the numeric data points" sample_stddev_real="Standard deviation of the real part of the numeric data points" long_name="Geocoded single-look complex image RH" - grid_mapping="projection" + grid_mapping='projection' DIMENSION_LIST="HDF5 internal attribute" _FillValue="(nan+nan*j)" units="1">Focused SLC image (RH) @@ -459,7 +453,7 @@ mean_real_value="Arithmetic average of the real part of the numeric data points" sample_stddev_real="Standard deviation of the real part of the numeric data points" long_name="Geocoded single-look complex image RV" - grid_mapping="projection" + grid_mapping='projection' DIMENSION_LIST="HDF5 internal attribute" _FillValue="(nan+nan*j)" units="1">Focused SLC image (RV) @@ -544,14 +538,14 @@ Mask indicating the subswath number representing valid GSLC samples. Each GSLC pixel is assumed valid if all the pixels in the interpolation window are fully focused in the input RSLC. A value of 0 indicates that at least one RSLC pixel in the interpolation window is partially focused or invalid. Pixels outside of the radar acquisition extent are filled with the value 255. + _FillValue="255">Mask indicating the subswath number representing valid GSLC samples. Each GSLC pixel is assumed valid if all the pixels in the interpolation window are fully focused in the input RSLC. A value of `0` indicates that at least one RSLC pixel in the interpolation window is partially focused or invalid. Pixels outside of the radar acquisition extent are filled with the value `255`. Focused SLC image (HH) @@ -632,7 +626,7 @@ mean_real_value="Arithmetic average of the real part of the numeric data points" sample_stddev_real="Standard deviation of the real part of the numeric data points" long_name="Geocoded single-look complex image HV" - grid_mapping="projection" + grid_mapping='projection' DIMENSION_LIST="HDF5 internal attribute" _FillValue="(nan+nan*j)" units="1">Focused SLC image (HV) @@ -652,7 +646,7 @@ mean_real_value="Arithmetic average of the real part of the numeric data points" sample_stddev_real="Standard deviation of the real part of the numeric data points" long_name="Geocoded single-look complex image VH" - grid_mapping="projection" + grid_mapping='projection' DIMENSION_LIST="HDF5 internal attribute" _FillValue="(nan+nan*j)" units="1">Focused SLC image (VH) @@ -672,7 +666,7 @@ mean_real_value="Arithmetic average of the real part of the numeric data points" sample_stddev_real="Standard deviation of the real part of the numeric data points" long_name="Geocoded single-look complex image VV" - grid_mapping="projection" + grid_mapping='projection' DIMENSION_LIST="HDF5 internal attribute" _FillValue="(nan+nan*j)" units="1">Focused SLC image (VV) @@ -692,7 +686,7 @@ mean_real_value="Arithmetic average of the real part of the numeric data points" sample_stddev_real="Standard deviation of the real part of the numeric data points" long_name="Geocoded single-look complex image RH" - grid_mapping="projection" + grid_mapping='projection' DIMENSION_LIST="HDF5 internal attribute" _FillValue="(nan+nan*j)" units="1">Focused SLC image (RH) @@ -712,7 +706,7 @@ mean_real_value="Arithmetic average of the real part of the numeric data points" sample_stddev_real="Standard deviation of the real part of the numeric data points" long_name="Geocoded single-look complex image RVH" - grid_mapping="projection" + grid_mapping='projection' DIMENSION_LIST="HDF5 internal attribute" _FillValue="(nan+nan*j)" units="1">Focused SLC image (RV) @@ -838,7 +832,7 @@ _FillValue="nan" grid_mapping="projection" long_name="LOS unit vector X" - units="1">East component of the line-of-sight (LOS) unit vector, defined from the target to the sensor, expressed in the east-north-up (ENU) coordinate system with its origin at the target location + units="1">East component of unit vector of LOS from target to sensor North component of the line-of-sight (LOS) unit vector, defined from the target to the sensor, expressed in the east-north-up (ENU) coordinate system with its origin at the target location + units="1">North component of unit vector of LOS from target to sensor East component of the along-track unit vector at the target location, expressed in the east-north-up (ENU) coordinate system and projected onto the horizontal plane (i.e., excluding the up component) + units="1">East component of unit vector along ground track North component of the along-track unit vector at the target location, expressed in the east-north-up (ENU) coordinate system and projected onto the horizontal plane (i.e., excluding the up component) + units="1">North component of unit vector along ground track X coordinates in specified projection X coordinates in specified projection + + - - Product map grid projection: EPSG code, with additional projection information as HDF5 Attributes - - - Y coordinates in specified projection - - - X coordinates in specified projection - Crosstalk in H-transmit channel expressed as ratio txV / txH Crosstalk in V-transmit channel expressed as ratio txH / txV Crosstalk in H-receive channel expressed as ratio rxV / rxH Crosstalk in V-receive channel expressed as ratio rxH / rxV - - @@ -2174,7 +2096,7 @@ lang="en" _FillValue="nan" grid_mapping="projection" - units="meters">Reference terrain height as a function of map coordinates + units="meters">Reference Terrain Height as a function of geographical location scalar values + + + number of datatakes in product + + + Number of observations in product + lang="en">number of observations in product @@ -3185,22 +3116,28 @@ Shape of real-valued calibration LUTs + lang="en">Shape of calibration LUTs - Shape of complex-valued calibration LUTs + lang="en">Shape of antenna pattern datasets + + Shape of crosstalk datasets + + Number of input L1 SLC granules + name="numberOfInputL0BFiles"/> From 0497910de33368bf7834ae48f38b760c2b804ba8 Mon Sep 17 00:00:00 2001 From: "Gustavo H. X. Shiroma" Date: Tue, 26 May 2026 10:59:12 -0700 Subject: [PATCH 5/5] Update DEM bounding box selection --- cxx/isce3/geometry/RTC.cpp | 2 +- cxx/isce3/geometry/loadDem.cpp | 162 ++++++------------ cxx/isce3/geometry/loadDem.h | 28 ++- .../pybind_isce3/geometry/DEMInterpolator.cpp | 32 ++-- 4 files changed, 87 insertions(+), 137 deletions(-) diff --git a/cxx/isce3/geometry/RTC.cpp b/cxx/isce3/geometry/RTC.cpp index 80db426f1..5a65e7e9e 100644 --- a/cxx/isce3/geometry/RTC.cpp +++ b/cxx/isce3/geometry/RTC.cpp @@ -1174,7 +1174,7 @@ void _RunBlock(const int jmax, const int block_size, the bounding-box corners. */ int dem_margin_x_in_pixels = 100; - int dem_margin_y_in_pixels = 200; + int dem_margin_y_in_pixels = 100; auto error_code = loadDemFromProj( dem_raster, minX, maxX, minY, maxY, &dem_interp_block, proj, dem_margin_x_in_pixels, dem_margin_y_in_pixels); diff --git a/cxx/isce3/geometry/loadDem.cpp b/cxx/isce3/geometry/loadDem.cpp index 4ad801508..44eb57001 100644 --- a/cxx/isce3/geometry/loadDem.cpp +++ b/cxx/isce3/geometry/loadDem.cpp @@ -132,14 +132,13 @@ DEMInterpolator DEMRasterToInterpolator( return demInterp; } - isce3::error::ErrorCode loadDemFromProj( isce3::io::Raster& dem_raster, const double x0, const double xf, const double minY, const double maxY, DEMInterpolator* dem_interp, isce3::core::ProjectionBase* proj, const int dem_margin_x_in_pixels, - const int dem_margin_y_in_pixels, const int dem_raster_band) { - + const int dem_margin_y_in_pixels, const int dem_raster_band, + const int n_edge_samples){ double min_x, max_x, min_y, max_y; if (proj == nullptr || proj->code() == dem_raster.getEPSG()) { @@ -152,110 +151,62 @@ isce3::error::ErrorCode loadDemFromProj( } else { std::unique_ptr dem_proj( isce3::core::createProj(dem_raster.getEPSG())); - auto p_west_1_llh = proj->inverse({x0, minY, 0}); - auto p_west_2_llh = proj->inverse({x0, maxY, 0}); - auto p_east_1_llh = proj->inverse({xf, minY, 0}); - auto p_east_2_llh = proj->inverse({xf, maxY, 0}); - - auto p_west_1_xy = dem_proj->forward(p_west_1_llh); - auto p_west_2_xy = dem_proj->forward(p_west_2_llh); - auto p_east_1_xy = dem_proj->forward(p_east_1_llh); - auto p_east_2_xy = dem_proj->forward(p_east_2_llh); - - min_y = std::min(std::min(p_west_1_xy[1], p_west_2_xy[1]), - std::min(p_east_1_xy[1], p_east_2_xy[1])); - max_y = std::max(std::max(p_west_1_xy[1], p_west_2_xy[1]), - std::max(p_east_1_xy[1], p_east_2_xy[1])); - - /* We address two cases in this if statement below: - 1. If the DEM projection is NOT geographic: - No antimeridian crossing, compute `min_x` and `max_x` - directly - 2. The user projection is in polar stereographic AND - the DEM projection is geographic: - In this case we need to check for antimeridian crossing. - */ - if (dem_raster.getEPSG() != 4326 or proj->code() == 3031 or - proj->code() == 3413) { - - // Compute X min/max directly - min_x = std::min(std::min(p_west_1_xy[0], p_west_2_xy[0]), - std::min(p_east_1_xy[0], p_east_2_xy[0])); - max_x = std::max(std::max(p_west_1_xy[0], p_west_2_xy[0]), - std::max(p_east_1_xy[0], p_east_2_xy[0])); - - if (dem_raster.getEPSG() == 4326 and - max_x - min_x > 180 and - (proj->code() == 3031 or proj->code() == 3413)) { - - /* - If (DEM is in geographic (EPSG: 4326) and - the difference between max and min longitudes is greater - than 180 and the map grid is in polar stereo (i.e., proj - epsg == 3031 or 3413), we cannot assume that `x0` is at - the western side of `xf`. - In that case, we also compute the (min/max using longitudes in - the [0, 360] range */ - - /* The conversion of longitude values from the [-180, 180] - domain to the [0, 360] domain is done by adding 360 to - negative longitude values. */ - const double p1_0_360 = \ - p_west_1_xy[0] < 0 ? p_west_1_xy[0] + 360 : p_west_1_xy[0]; - const double p2_0_360 = \ - p_west_2_xy[0] < 0 ? p_west_2_xy[0] + 360 : p_west_2_xy[0]; - const double p3_0_360 = \ - p_east_1_xy[0] < 0 ? p_east_1_xy[0] + 360 : p_east_1_xy[0]; - const double p4_0_360 = \ - p_east_2_xy[0] < 0 ? p_east_2_xy[0] + 360 : p_east_2_xy[0]; - - // Compute min/max longitudes in the [0, 360] domain - min_x = std::min(std::min(p1_0_360, p2_0_360), - std::min(p3_0_360, p4_0_360)); - max_x = std::max(std::max(p1_0_360, p2_0_360), - std::max(p3_0_360, p4_0_360)); - } - - } else { - /* - X-coordinates may be wrapped due to the antimeridian - crossing. In this case, we compute western and eastern boundaries - separately. - We just need to make sure that there's no antimeridian crossing - in between the western and eastern edges - */ - - // Western edge - if (std::abs(p_west_1_xy[0] - p_west_2_xy[0]) < 180) { - - // Normal case - min_x = std::min(p_west_1_xy[0], p_west_2_xy[0]); - } - else { - - // Antimeridian crossing - const double p1_0_360 = \ - p_west_1_xy[0] < 0 ? p_west_1_xy[0] + 360 : p_west_1_xy[0]; - const double p2_0_360 = \ - p_west_2_xy[0] < 0 ? p_west_2_xy[0] + 360 : p_west_2_xy[0]; - min_x = std::min(p1_0_360, p2_0_360); - } - // Eastern edge - if (std::abs(p_east_1_xy[0] - p_east_2_xy[0]) < 180) { - - // Normal case - max_x = std::max(p_east_1_xy[0], p_east_2_xy[0]); - } - - else { + const int N = std::max(n_edge_samples, 2); + + // Densely sample all four edges of the input bounding box + // to capture curvature introduced by reprojection + // (e.g. UTM -> geographic). + std::vector all_x, all_y; + all_x.reserve(4 * N); + all_y.reserve(4 * N); + + for (int i = 0; i < N; ++i) { + double t = static_cast(i) / (N - 1); + double xMid = x0 + t * (xf - x0); + double yMid = minY + t * (maxY - minY); + + // West edge (x = x0, y varies) + auto west_llh = proj->inverse({x0, yMid, 0}); + auto west_xy = dem_proj->forward(west_llh); + all_x.push_back(west_xy[0]); + all_y.push_back(west_xy[1]); + + // East edge (x = xf, y varies) + auto east_llh = proj->inverse({xf, yMid, 0}); + auto east_xy = dem_proj->forward(east_llh); + all_x.push_back(east_xy[0]); + all_y.push_back(east_xy[1]); + + // South edge (y = minY, x varies) + auto south_llh = proj->inverse({xMid, minY, 0}); + auto south_xy = dem_proj->forward(south_llh); + all_x.push_back(south_xy[0]); + all_y.push_back(south_xy[1]); + + // North edge (y = maxY, x varies) + auto north_llh = proj->inverse({xMid, maxY, 0}); + auto north_xy = dem_proj->forward(north_llh); + all_x.push_back(north_xy[0]); + all_y.push_back(north_xy[1]); + } - // Antimeridian crossing - const double p3_0_360 = \ - p_east_1_xy[0] < 0 ? p_east_1_xy[0] + 360 : p_east_1_xy[0]; - const double p4_0_360 = \ - p_east_2_xy[0] < 0 ? p_east_2_xy[0] + 360 : p_east_2_xy[0]; - max_x = std::max(p3_0_360, p4_0_360); + min_y = *std::min_element(all_y.begin(), all_y.end()); + max_y = *std::max_element(all_y.begin(), all_y.end()); + + min_x = *std::min_element(all_x.begin(), all_x.end()); + max_x = *std::max_element(all_x.begin(), all_x.end()); + + // If the DEM is in geographic coordinates and the X range + // exceeds 180 degrees, an antimeridian crossing is likely. + // Retry in [0, 360] domain. + if (dem_raster.getEPSG() == 4326 && max_x - min_x > 180.0) { + min_x = std::numeric_limits::max(); + max_x = std::numeric_limits::lowest(); + for (double lon : all_x) { + double lon_360 = lon < 0 ? lon + 360.0 : lon; + min_x = std::min(min_x, lon_360); + max_x = std::max(max_x, lon_360); } } } @@ -264,7 +215,6 @@ isce3::error::ErrorCode loadDemFromProj( min_y -= margin_y; max_y += margin_y; - float margin_x = dem_margin_x_in_pixels * dem_raster.dx(); min_x -= margin_x; max_x += margin_x; diff --git a/cxx/isce3/geometry/loadDem.h b/cxx/isce3/geometry/loadDem.h index eb35139c8..ce95d1809 100644 --- a/cxx/isce3/geometry/loadDem.h +++ b/cxx/isce3/geometry/loadDem.h @@ -47,26 +47,23 @@ isce3::geometry::DEMInterpolator DEMRasterToInterpolator( * in the same or different coordinate system as the DEM raster * * @param[in] dem_raster DEM raster -* @param[in] x0 Easting/longitude of western edge of bounding box, -* If the DEM is in geographic coordinates and the `x0` coordinate is not -* from the polar stereo system EPSG 3031 or EPSG 3413, this point represents -* the minimum X coordinate value. In this case, the maximum -* longitude span that this function can handle is 180 degrees -* (when the DEM is in geographic coordinates and `proj` is in polar stereo) -* @param[in] xf Easting/longitude of eastern edge of bounding box -* If the DEM is in geographic coordinates and the `xf` coordinate is not -* from the polar stereo system EPSG 3031 or EPSG 3413, this point represents -* the maximum X coordinate value. In this case, the maximum -* longitude span that this function can handle is 180 degrees -* (when the DEM is in geographic coordinates and `proj` is in polar stereo) -* @param[in] minY Minimum Y/northing position -* @param[in] maxY Maximum Y/northing position +* @param[in] x0 Minimum X/easting position of the input +# bounding box in the coordinate system of `proj` +* @param[in] xf Maximum X/easting position of the input +# bounding box in the coordinate system of `proj` +* @param[in] minY Minimum Y/northing position of the input +# bounding box in the coordinate system of `proj` +* @param[in] maxY Maximum Y/northing position of the input +# bounding box in the coordinate system of `proj` * @param[out] dem_interp DEM interpolation object * @param[in] proj Projection object (nullptr to use same * DEM projection) * @param[in] dem_margin_x_in_pixels DEM X/easting margin in pixels * @param[in] dem_margin_y_in_pixels DEM Y/northing margin in pixels * @param[in] dem_raster_band DEM raster band (starting from 1) +* @param[in] n_edge_samples Number of points sampled along each edge +* of the bounding box when reprojecting. Must be >= 2 to include corners; +* values below 2 are clamped to 2. Default: 11. */ isce3::error::ErrorCode loadDemFromProj( isce3::io::Raster& dem_raster, @@ -75,7 +72,8 @@ isce3::error::ErrorCode loadDemFromProj( isce3::core::ProjectionBase* proj = nullptr, const int dem_margin_x_in_pixels = 100, const int dem_margin_y_in_pixels = 100, - const int dem_raster_band = 1); + const int dem_raster_band = 1, + const int n_edge_samples = 11); /* Interpolate DEM at position (x, y) considering that input_proj and diff --git a/python/extensions/pybind_isce3/geometry/DEMInterpolator.cpp b/python/extensions/pybind_isce3/geometry/DEMInterpolator.cpp index 47167b30f..b58c8988e 100644 --- a/python/extensions/pybind_isce3/geometry/DEMInterpolator.cpp +++ b/python/extensions/pybind_isce3/geometry/DEMInterpolator.cpp @@ -232,7 +232,8 @@ void addbinding_load_dem_from_proj(py::module& m) isce3::core::ProjectionBase* proj, const int dem_margin_x_in_pixels, const int dem_margin_y_in_pixels, - const int dem_raster_band) { + const int dem_raster_band, + const int n_edge_samples) { DEMInterp dem_interp(0, dem_interp_method); @@ -245,7 +246,8 @@ void addbinding_load_dem_from_proj(py::module& m) proj, dem_margin_x_in_pixels, dem_margin_y_in_pixels, - dem_raster_band); + dem_raster_band, + n_edge_samples); return dem_interp; }, @@ -259,6 +261,7 @@ void addbinding_load_dem_from_proj(py::module& m) py::arg("dem_margin_x_in_pixels") = 100, py::arg("dem_margin_y_in_pixels") = 200, py::arg("dem_raster_band") = 1, + py::arg("n_edge_samples") = 1, R"( Load DEM raster into a DEMInterpolator object around a given bounding box in the same or different coordinate system as the DEM raster @@ -268,22 +271,17 @@ void addbinding_load_dem_from_proj(py::module& m) dem_raster: isce3.io.Raster Raster of the DEM x0: double - If the DEM is in geographic coordinates and the `x0` coordinate is not - from the polar stereo system EPSG 3031 or EPSG 3413, this point represents - the minimum X coordinate value. In this case, the maximum - longitude span that this function can handle is 180 degrees - (when the DEM is in geographic coordinates and `proj` is in polar stereo + Minimum X/easting position of the input bounding box in the coordinate + system of `proj` xf: double - Easting/longitude of eastern edge of bounding box - If the DEM is in geographic coordinates and the `xf` coordinate is not - from the polar stereo system EPSG 3031 or EPSG 3413, this point represents - the maximum X coordinate value. In this case, the maximum - longitude span that this function can handle is 180 degrees - (when the DEM is in geographic coordinates and `proj` is in polar stereo) + Maximum X/easting position of the input bounding box in the coordinate + system of `proj` min_y: double - Minimum Y/northing position + Minimum Y/northing position of the input bounding box in the coordinate + system of `proj` max_y: double - Maximum Y/northing position + Maximum Y/northing position of the input bounding box in the coordinate + system of `proj` dem_interp_method: isce3.core.DataInterpMethod DEM interpolation method proj: @@ -294,6 +292,10 @@ void addbinding_load_dem_from_proj(py::module& m) DEM Y/northing margin in pixels dem_raster_band: int DEM raster band (starting from 1) + n_edge_samples: int + Number of points sampled along each edge of the bounding box when + reprojecting. Must be >= 2 to include corners. Values below 2 + are clamped to 2. Default: 11. Returns -------