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', }