Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,11 @@ number as needed.

### Fixed

- Support the OLCI Collection 4 (v4.01) level 2 water processing baseline:
data objects absent from a manifest (such as the OC4Me chlorophyll product
`chlOc4meData`, removed in Collection 4) are skipped instead of raising a
`RuntimeError`, and the new `chlor_a`, `fluorescence`, and `iop_lsd`
products are turned into assets when present
- Use correct EO Extension attribute names and units ([#13](https://github.com/stactools-packages/sentinel3/pull/15))
- Use un-stripped `instance_id` to check for strip granules and apply geometry
fix ([#19](https://github.com/stactools-packages/sentinel3/pull/19))
Expand Down
59 changes: 59 additions & 0 deletions src/stactools/sentinel3/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -730,6 +730,65 @@
"wqsfData",
]

# Additional data objects introduced by the OLCI Collection 4 (v4.01)
# processing baseline for level 2 water products. The OC4Me chlorophyll
# product (chl_oc4me.nc / chlOc4meData) was replaced by chlor_a.nc, and the
# fluorescence (fluorescence.nc) and inherent optical properties (iop_lsd.nc)
# products were added. See:
# https://user.eumetsat.int/news-events/news/update-to-sentinel-3-olci-level-2-water-processing
OLCI_L2_WATER_ASSET_KEYS_C4 = [
"chlor_aData",
"fluoData",
"iopLsdData",
]

# Maps each OLCI L2 water data object ID to the OLCI bands it is derived from.
# Data objects without an entry here (annotation files, and the Collection 4
# chlor_a/fluorescence/iop_lsd products) carry no eo:bands.
OLCI_L2_WATER_BAND_KEYS = {
"chlNnData": [
"Oa01",
"Oa02",
"Oa03",
"Oa04",
"Oa05",
"Oa06",
"Oa07",
"Oa08",
"Oa09",
"Oa10",
"Oa11",
"Oa12",
"Oa16",
"Oa17",
"Oa18",
"Oa21",
],
"tsmNnData": [
"Oa01",
"Oa02",
"Oa03",
"Oa04",
"Oa05",
"Oa06",
"Oa07",
"Oa08",
"Oa09",
"Oa10",
"Oa11",
"Oa12",
"Oa16",
"Oa17",
"Oa18",
"Oa21",
],
"chlOc4meData": ["Oa03", "Oa04", "Oa05", "Oa06"],
"iopNnData": ["Oa01", "Oa12", "Oa16", "Oa17", "Oa21"],
"iwvData": ["Oa18", "Oa19"],
"trspData": ["Oa04", "Oa06"],
"wAerData": ["Oa05", "Oa06", "Oa17"],
}

SLSTR_L1_ASSET_KEYS = [
"SLSTR_S1_RAD_AN_Data",
"SLSTR_S2_RAD_AN_Data",
Expand Down
68 changes: 21 additions & 47 deletions src/stactools/sentinel3/metadata_links.py
Original file line number Diff line number Diff line change
Expand Up @@ -559,55 +559,25 @@ def strip_prefix(prefix: str, content: str) -> str:
asset_identifier_list.append(asset_key)
asset_list.append(asset_obj)
elif "_WFR_" in product_type:
asset_key_list = constants.OLCI_L2_WATER_ASSET_KEYS
for asset_key in asset_key_list:
if asset_key == "chlNnData" or asset_key == "tsmNnData":
band_key_list = [
"Oa01",
"Oa02",
"Oa03",
"Oa04",
"Oa05",
"Oa06",
"Oa07",
"Oa08",
"Oa09",
"Oa10",
"Oa11",
"Oa12",
"Oa16",
"Oa17",
"Oa18",
"Oa21",
]
elif asset_key == "chlOc4meData":
band_key_list = ["Oa03", "Oa04", "Oa05", "Oa06"]
elif asset_key == "iopNnData":
band_key_list = [
"Oa01",
"Oa12",
"Oa16",
"Oa17",
"Oa21",
]
elif asset_key == "iwvData":
band_key_list = [
"Oa18",
"Oa19",
]
elif asset_key == "parData":
band_key_list = []
elif asset_key == "trspData":
band_key_list = ["Oa04", "Oa06"]
elif asset_key == "wAerData":
band_key_list = ["Oa05", "Oa06", "Oa17"]
elif any(
asset_key == key
for key in constants.OLCI_L2_WATER_ASSET_KEYS[-7:]
# Iterate over both the legacy water keys and the Collection 4
# (v4.01) additions. Data objects that are not present in this
# particular manifest are skipped, so the same code handles
# both the old and new processing baselines.
present_asset_keys = []
for asset_key in (
constants.OLCI_L2_WATER_ASSET_KEYS
+ constants.OLCI_L2_WATER_ASSET_KEYS_C4
):
if len(manifest.findall(f".//dataObject[@ID='{asset_key}']")) == 0:
continue
if asset_key in constants.OLCI_L2_WATER_BAND_KEYS:
band_key_list = constants.OLCI_L2_WATER_BAND_KEYS[asset_key]
elif asset_key.startswith("Oa") and asset_key.endswith(
"_reflectanceData"
):
band_key_list = []
else:
band_key_list = [asset_key[:4]]
else:
band_key_list = []
asset_location = self.read_href(
f".//dataObject[@ID='{asset_key}']//fileLocation"
)
Expand Down Expand Up @@ -653,8 +623,12 @@ def strip_prefix(prefix: str, content: str) -> str:
roles=["data"],
extra_fields={"s3:spatial_resolution": asset_resolution},
)
present_asset_keys.append(asset_key)
asset_identifier_list.append(asset_key)
asset_list.append(asset_obj)
# Return only the keys actually present in this manifest so the
# asset keys stay aligned with asset_identifier_list/asset_list.
asset_key_list = present_asset_keys
elif instrument_bands == constants.SENTINEL_SLSTR_BANDS:
if "SL_1_" in product_type:
asset_key_list = constants.SLSTR_L1_ASSET_KEYS
Expand Down
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading
Loading