diff --git a/src/opera/pge/dswx_hls/templates/OPERA_ISO_metadata_L3_DSWx_HLS_template.xml.jinja2 b/src/opera/pge/dswx_hls/templates/OPERA_ISO_metadata_L3_DSWx_HLS_template.xml.jinja2
index 250b9b7e..4b0258cf 100644
--- a/src/opera/pge/dswx_hls/templates/OPERA_ISO_metadata_L3_DSWx_HLS_template.xml.jinja2
+++ b/src/opera/pge/dswx_hls/templates/OPERA_ISO_metadata_L3_DSWx_HLS_template.xml.jinja2
@@ -593,7 +593,7 @@
HlsDataset
- Identifier for the HLS dataset used to create the DSWx product(s)
+ Name of the input HLS product used to generate the DSWx-HLS product
string
@@ -635,7 +635,7 @@
SensorProductID
- The Landsat product ID or Sentinel L1C granule URI
+ Landsat product IDs, copied from the HLS metadata field LANDSAT_PRODUCT_ID, for Landsat-derived HLS products, or Sentinel granule Uniform Resource Identifier (URI), copied from PRODUCT_URI for Sentinel-derived HLS products
string
@@ -650,13 +650,13 @@
- platformInformation
+ processingInformation
- Accode
+ AerosolClassRemappingEnabled
- The version of Land Surface Reflectance Code (LaSRC) used by HLS for L30 or L30 for atmospheric correction
+ Indicates if the aerosol class remapping is enabled (TRUE) or disabled (FALSE)
string
@@ -664,7 +664,133 @@
- {{ product_output.ACCODE }}{# ISO_OPERA_accode #}
+ {{ product_output.AEROSOL_CLASS_REMAPPING_ENABLED }}{# ISO_OPERA_aerosolClassRemappingEnabled #}
+
+
+
+
+
+
+ processingInformation
+
+
+ AerosolNotWaterToHighConfWaterFMaskValues
+
+
+ HLS Fmask values to convert not-water to high-confidence water in the presence of high aerosol
+
+
+ string
+
+
+
+
+ {{ product_output.AEROSOL_NOT_WATER_TO_HIGH_CONF_WATER_FMASK_VALUES }}{# ISO_OPERA_aerosolNotWaterToHighConfWaterFMaskValues #}
+
+
+
+
+
+
+ processingInformation
+
+
+ AerosolPartialSurfaceAggressiveToHighConfWaterFMaskValues
+
+
+ HLS Fmask values to convert partial surface water aggressive to high-confidence water in the presence of high aerosol
+
+
+ string
+
+
+
+
+ {{ product_output.AEROSOL_PARTIAL_SURFACE_AGGRESSIVE_TO_HIGH_CONF_WATER_FMASK_VALUES }}{# ISO_OPERA_aerosolPartialSurfaceAggressiveToHighConfWaterFMaskValues #}
+
+
+
+
+
+
+ processingInformation
+
+
+ AerosolPartialSurfaceWaterConservativeToHighConfWaterFMaskValues
+
+
+ HLS Fmask values to convert partial surface water conservative to high-confidence water in the presence of high aerosol
+
+
+ string
+
+
+
+
+ {{ product_output.AEROSOL_PARTIAL_SURFACE_WATER_CONSERVATIVE_TO_HIGH_CONF_WATER_FMASK_VALUES }}{# ISO_OPERA_aerosolPartialSurfaceWaterConservativeToHighConfWaterFMaskValues #}
+
+
+
+
+
+
+ processingInformation
+
+
+ AerosolWaterModerateConfToHighConfWaterFMaskValues
+
+
+ HLS Fmask values to convert moderate-confidence water to high-confidence water in the presence of high aerosol
+
+
+ string
+
+
+
+
+ {{ product_output.AEROSOL_PARTIAL_SURFACE_WATER_CONSERVATIVE_TO_HIGH_CONF_WATER_FMASK_VALUES }}{# ISO_OPERA_aerosolPartialSurfaceWaterConservativeToHighConfWaterFMaskValues #}
+
+
+
+
+
+
+ processingInformation
+
+
+ ForestMaskLandcoverClasses
+
+
+ Copernicus CGLS Land Cover 100m forest classes used in additional testing that may mask false water detections from the WTR-2 and WTR layers, due to vegetation-related dark reflectance.
+
+
+ string
+
+
+
+
+ {{ product_output.FOREST_MASK_LANDCOVER_CLASSES }}{# ISO_OPERA_forestMaskLandcoverClasses #}
+
+
+
+
+
+
+ processingInformation
+
+
+ MaskAdjacentToCloudMode
+
+
+ Define how areas adjacent to cloud/cloud-shadow are handled. Three options are available: “mask” - mask out these areas marking them as cloud shadow (default); “ignore” - ignore the adjacent to cloud/cloud shadow classification; and “cover” - cover these areas with a dilation algorithm.
+
+
+ string
+
+
+
+
+ {{ product_output.MASK_ADJACENT_TO_CLOUD_MODE }}{# ISO_OPERA_maskAdjacentToCloudMode #}
@@ -677,7 +803,7 @@
AreaOrPoint
- Indicate that pixel values are assumed to represent an area rather than points
+ Indicates that pixel values are assumed to represent an area rather than points
string
@@ -695,7 +821,7 @@
processingInformation
- ProcessingDatetie
+ ProcessingDatetime
DSWx-HLS product processing date
@@ -877,6 +1003,54 @@
{{ product_output.SPACECRAFT_NAME }}{# ISO_OPERA_spacecraftName #}
+
+
+
+
+ processingInformation
+
+
+ MaxSunLocalIncAngle
+
+
+ Maximum sun local-incidence angle (only applicable for “sun_local_inc_angle” shadow masking algorithm)
+
+
+ Degrees
+
+
+ int
+
+
+
+
+ {{ product_output.MAX_SUN_LOCAL_INC_ANGLE }}{# ISO_OPERA_maxSunLocalIncAngle #}
+
+
+
+
+
+
+ processingInformation
+
+
+ MinSlopeAngle
+
+
+ Minimum slope angle (only applicable for “sun_local_inc_angle” shadow masking algorithm)
+
+
+ Degrees
+
+
+ int
+
+
+
+
+ {{ product_output.MIN_SLOPE_ANGLE }}{# ISO_OPERA_minSlopeAngle #}
+
+
@@ -932,10 +1106,10 @@
geographicIdentifier
- NBAR_SolarZenith
+ MeanViewAzimuthAngle
- The solar zenith angle used in Nadir Bidirectional Reflectance Distribution Function Adjusted Reflectance (NBAR) derivation
+ The mean view azimuth angle
Degrees
@@ -946,7 +1120,7 @@
- {{ product_output.NBAR_SOLAR_ZENITH }}{# ISO_OPERA_nbarSolarZenith #}
+ {{ product_output.MEAN_VIEW_AZIMUTH_ANGLE }}{# ISO_OPERA_meanViewAzimuthAngle #}
@@ -956,10 +1130,10 @@
geographicIdentifier
- MeanViewAzimuthAngle
+ MeanViewZenithAngle
- The mean view azimuth angle
+ The mean view zenith angle
Degrees
@@ -970,7 +1144,7 @@
- {{ product_output.MEAN_VIEW_AZIMUTH_ANGLE }}{# ISO_OPERA_meanViewAzimuthAngle #}
+ {{ product_output.MEAN_VIEW_ZENITH_ANGLE }}{# ISO_OPERA_meanViewZenithAngle #}
@@ -980,10 +1154,10 @@
geographicIdentifier
- MeanViewZenithAngle
+ NBAR_SolarZenith
- The mean view zenith angle
+ The solar zenith angle used in Nadir Bidirectional Reflectance Distribution Function Adjusted Reflectance (NBAR) derivation
Degrees
@@ -994,7 +1168,94 @@
- {{ product_output.MEAN_VIEW_ZENITH_ANGLE }}{# ISO_OPERA_meanViewZenithAngle #}
+ {{ product_output.NBAR_SOLAR_ZENITH }}{# ISO_OPERA_nbarSolarZenith #}
+
+
+
+
+
+
+ platformInformation
+
+
+ Accode
+
+
+ The version of Land Surface Reflectance Code (LaSRC) used by HLS for the Landsat-8 30m (L30) product or the Sentinel-2 30m (S30) product for atmospheric correction
+
+
+ string
+
+
+
+
+ {{ product_output.ACCODE }}{# ISO_OPERA_accode #}
+
+
+
+
+
+
+ processingInformation
+
+
+ OceanMaskingEnabled
+
+
+ Indicates if the ocean masking is enabled (TRUE) or disabled (FALSE)
+
+
+ string
+
+
+
+
+ {{ product_output.OCEAN_MASKING_ENABLED }}{# ISO_OPERA_oceanMaskingEnabled #}
+
+
+
+
+
+
+ processingInformation
+
+
+ OceanMaskingShorelineDistanceKM
+
+
+ Ocean masking distance from shoreline in km (only applicable if the ocean masking is enabled)
+
+
+ Kilometers
+
+
+ string
+
+
+
+
+ {{ product_output.OCEAN_MASKING_SHORELINE_DISTANCE_KM }}{# ISO_OPERA_oceanMaskingShorelineDistanceKM #}
+
+
+
+
+
+
+ processingInformation
+
+
+ ShadowMaskingAlgorithm
+
+
+ Shadow masking algorithm, either “sun_local_inc_angle” (default) or “otsu”
+
+
+ string
+
+
+
+
+ {{ product_output.SHADOW_MASKING_ALGORITHM }}{# ISO_OPERA_shadowMaskingAlgorithm #}
@@ -1007,7 +1268,7 @@
SpatialCoverage
- The area percentage of the tile with data
+ The percentage of the tile area with observational data (as opposed to fill value and ocean masked)
int
@@ -1025,10 +1286,31 @@
qualityInformation
- PercentCloudCover
+ SpatialCoverageExcludingMaskedOcean
+
+
+ The percentage of the tile area with observational data (as opposed to fill value and ocean masked) excluding masked ocean
+
+
+ int
+
+
+
+
+ {{ product_output.SPATIAL_COVERAGE_EXCLUDING_MASKED_OCEAN }}{# ISO_OPERA_spatialCoverageExcludingMaskedOcean #}
+
+
+
+
+
+
+ qualityInformation
+
+
+ CloudCoverage
- The percentage of cloud and cloud shadow in the L3_DSWx_HLS product based on the HLS QA mask
+ The percentage of pixels with observational data (as opposed to fill value and ocean masked) that HLS QA mask marks as cloud, cloud shadow, or adjacent-to-cloud (per MASK_ADJACENT_TO_CLOUD setting)
int
@@ -1039,6 +1321,111 @@
{{ product_output.CLOUD_COVERAGE }}{# ISO_OPERA_cloudCoverage #}
+
+
+
+
+ qualityInformation
+
+
+ InputHlsProductCloudCoverage
+
+
+ The percentage of cloud/cloud shadow over observational data (as opposed to fill value) in the input HLS product derived using the HLS Fmask layer
+
+
+ int
+
+
+
+
+ {{ product_output.INPUT_HLS_PRODUCT_CLOUD_COVERAGE }}{# ISO_OPERA_inputHlsProductCloudCoverage #}
+
+
+
+
+
+
+ qualityInformation
+
+
+ InputHlsProductSpatialCoverage
+
+
+ The percentage of the tile area with observational data (as opposed to fill value) in the input HLS product
+
+
+ int
+
+
+
+
+ {{ product_output.INPUT_HLS_PRODUCT_SPATIAL_COVERAGE }}{# ISO_OPERA_inputHlsProductSpatialCoverage #}
+
+
+
+
+
+
+ qualityInformation
+
+
+ DEMCoverage
+
+
+ Input DEM coverage over the DSWx-HLS product: “FULL” for full coverage, “FULL_WITH_ANTIMERIDIAN_CROSSING” for full coverage with antimeridian crossing, or “NOT_TESTED” if coverage checks are disabled
+
+
+ string
+
+
+
+
+ {{ product_output.DEM_COVERAGE }}{# ISO_OPERA_demCoverage #}
+
+
+
+
+
+
+ qualityInformation
+
+
+ LandcoverCoverage
+
+
+ Input CGLS discrete classification map coverage over the DSWx-HLS product: “FULL” for full coverage, “FULL_WITH_ANTIMERIDIAN_CROSSING” for full coverage with antimeridian crossing, “PARTIAL” if DSWx-HLS product coverage exceeds CGLS map limits (i.e., beyond latitudes -60 or +80 degrees), or “NOT_TESTED” if coverage checks are disabled.
+
+
+ string
+
+
+
+
+ {{ product_output.LANDCOVER_COVERAGE }}{# ISO_OPERA_landcoverCoverage #}
+
+
+
+
+
+
+ qualityInformation
+
+
+ WorldcoverCoverage
+
+
+ Input ESA WorldCover map coverage over the DSWx-HLS product: “FULL” for full coverage, “FULL_WITH_ANTIMERIDIAN_CROSSING” for full coverage with antimeridian crossing, “PARTIAL” if DSWx-HLS product exceeds the WorldCover map limits (i.e.,beyond latitudes -60 or +84 degrees), or “NOT_TESTED” if coverage checks are disabled
+
+
+ string
+
+
+
+
+ {{ product_output.WORLDCOVER_COVERAGE }}{# ISO_OPERA_landcoverCoverage #}
+
+
diff --git a/src/opera/util/img_utils.py b/src/opera/util/img_utils.py
index 12e49bc5..82c03651 100644
--- a/src/opera/util/img_utils.py
+++ b/src/opera/util/img_utils.py
@@ -33,15 +33,28 @@ class MockGdalDataset:
def __init__(self):
self.dummy_metadata = {
- 'ACCODE': 'LaSRC', 'AREA_OR_POINT': 'Area',
- 'CLOUD_COVERAGE': '43', 'DEM_SOURCE': 'dem.tif',
+ 'ACCODE': 'LaSRC', 'AEROSOL_CLASS_REMAPPING_ENABLED': 'TRUE',
+ 'AEROSOL_NOT_WATER_TO_HIGH_CONF_WATER_FMASK_VALUES': '224,160,96',
+ 'AEROSOL_PARTIAL_SURFACE_AGGRESSIVE_TO_HIGH_CONF_WATER_FMASK_VALUES': '224,192,160,128,96',
+ 'AEROSOL_PARTIAL_SURFACE_WATER_CONSERVATIVE_TO_HIGH_CONF_WATER_FMASK_VALUES': '224,192,160,128,96',
+ 'AEROSOL_WATER_MODERATE_CONF_TO_HIGH_CONF_WATER_FMASK_VALUES': '224,160,96',
+ 'AREA_OR_POINT': 'Area', 'CLOUD_COVERAGE': '43',
+ 'DEM_COVERAGE': 'FULL', 'DEM_SOURCE': 'dem.tif',
+ 'FOREST_MASK_LANDCOVER_CLASSES': '20,50,111,113,115,116,121,123,125,126',
'HLS_DATASET': 'HLS.L30.T22VEQ.2021248T143156.v2.0',
- 'LANDCOVER_SOURCE': 'landcover.tif',
+ 'INPUT_HLS_PRODUCT_CLOUD_COVERAGE': '4',
+ 'INPUT_HLS_PRODUCT_SPATIAL_COVERAGE': '84',
+ 'LANDCOVER_COVERAGE': 'FULL', 'LANDCOVER_SOURCE': 'landcover.tif',
+ 'MASK_ADJACENT_TO_CLOUD_MODE': 'mask',
+ 'MAX_SUN_LOCAL_INC_ANGLE': '40',
'MEAN_SUN_AZIMUTH_ANGLE': '145.002203258435',
'MEAN_SUN_ZENITH_ANGLE': '30.7162834439185',
'MEAN_VIEW_AZIMUTH_ANGLE': '100.089770731169',
'MEAN_VIEW_ZENITH_ANGLE': '4.6016561116873',
+ 'MIN_SLOPE_ANGLE': '-5',
'NBAR_SOLAR_ZENITH': '31.7503071022442',
+ 'OCEAN_MASKING_ENABLED': 'FALSE',
+ 'OCEAN_MASKING_SHORELINE_DISTANCE_KM': 'NOT_USED',
'PROCESSING_DATETIME': '2022-01-31T21:54:26',
'PRODUCT_ID': 'dswx_hls', 'PRODUCT_LEVEL': '3',
'PRODUCT_SOURCE': 'HLS', 'PRODUCT_TYPE': 'DSWx-HLS',
@@ -49,8 +62,11 @@ def __init__(self):
'SENSING_TIME': '2021-09-05T14:31:56.9300799Z; 2021-09-05T14:32:20.8126470Z',
'SENSOR': 'MSI',
'SENSOR_PRODUCT_ID': 'S2A_MSIL1C_20210907T163901_N0301_R126_T15SXR_20210907T202434.SAFE',
+ 'SHADOW_MASKING_ALGORITHM': 'SUN_LOCAL_INC_ANGLE',
'SHORELINE_SOURCE': 'shoreline.shp', 'SOFTWARE_VERSION': '0.1',
'SPACECRAFT_NAME': 'Sentinel-2A', 'SPATIAL_COVERAGE': '99',
+ 'SPATIAL_COVERAGE_EXCLUDING_MASKED_OCEAN': '99',
+ 'WORLDCOVER_COVERAGE': 'FULL',
'WORLDCOVER_SOURCE': 'worldcover.tif',
}