66from pystac .extensions .sat import OrbitState
77from pystac .item_assets import ItemAssetDefinition
88from pystac .utils import str_to_datetime
9- from stactools .sentinel3 .constants import SENTINEL_OLCI_BANDS
9+ from stactools .sentinel3 .constants import SENTINEL_OLCI_BANDS , SENTINEL_SLSTR_BANDS
1010
1111from eopf_stac .common .constants import (
1212 DATASET_ASSET_EXTRA_FIELDS ,
@@ -205,6 +205,124 @@ def get_olci_bands(band_keys: list[str] | None = None) -> list[dict]:
205205 PRODUCT_METADATA_ASSET_KEY : PRODUCT_METADATA_PATH ,
206206}
207207
208+ # SENTINEL_SLSTR_BANDS
209+ # SLSTR_BANDS_TO_RESOLUTIONS
210+
211+
212+ def get_slstr_bands (band_keys : list [str ] | None = None ) -> list [dict ]:
213+ bands = []
214+ if band_keys is None :
215+ for _ , band in SENTINEL_SLSTR_BANDS .items ():
216+ bands .append (band .to_dict ())
217+ else :
218+ for key in band_keys :
219+ bands .append (SENTINEL_SLSTR_BANDS [key ].to_dict ())
220+
221+ return bands
222+
223+
224+ SLSTR_L1_ASSETS : dict [str , ItemAssetDefinition ] = {
225+ "radiance_an" : ItemAssetDefinition .create (
226+ title = "TOA radiance - stripe A, nadir view" ,
227+ media_type = pystac .MediaType .ZARR ,
228+ description = ("Dataset of the TOA radiances for the 500m grid, stripe A, nadir view" ),
229+ roles = [ROLE_DATA , ROLE_DATASET ],
230+ extra_fields = {"bands" : get_slstr_bands (["S01" , "S02" , "S03" , "S04" , "S05" , "S06" ]), "gsd" : 500 },
231+ ),
232+ "radiance_ao" : ItemAssetDefinition .create (
233+ title = "TOA radiance - stripe A, oblique view" ,
234+ media_type = pystac .MediaType .ZARR ,
235+ description = ("Dataset of the TOA radiances for the 500m grid, stripe A, oblique view" ),
236+ roles = [ROLE_DATA , ROLE_DATASET ],
237+ extra_fields = {"bands" : get_slstr_bands (["S01" , "S02" , "S03" , "S04" , "S05" , "S06" ]), "gsd" : 500 },
238+ ),
239+ "radiance_bn" : ItemAssetDefinition .create (
240+ title = "TOA radiance - stripe B, nadir view" ,
241+ media_type = pystac .MediaType .ZARR ,
242+ description = ("Dataset of the TOA radiances for the 500m grid, stripe B, nadir view" ),
243+ roles = [ROLE_DATA , ROLE_DATASET ],
244+ extra_fields = {"bands" : get_slstr_bands (["S04" , "S05" , "S06" ]), "gsd" : 500 },
245+ ),
246+ "radiance_bo" : ItemAssetDefinition .create (
247+ title = "TOA radiance - stripe B, oblique view" ,
248+ media_type = pystac .MediaType .ZARR ,
249+ description = ("Dataset of the TOA radiances for the 500m grid, stripe B, oblique view" ),
250+ roles = [ROLE_DATA , ROLE_DATASET ],
251+ extra_fields = {"bands" : get_slstr_bands (["S04" , "S05" , "S06" ]), "gsd" : 500 },
252+ ),
253+ "BT_in" : ItemAssetDefinition .create (
254+ title = "TOA brightness temperature - TIR, nadir view" ,
255+ media_type = pystac .MediaType .ZARR ,
256+ description = ("Dataset of the TOA brightness temperature for channels S7-S9 and F2 in the 1km grid, nadir view" ),
257+ roles = [ROLE_DATA , ROLE_DATASET ],
258+ extra_fields = {"bands" : get_slstr_bands (["S07" , "S08" , "S09" , "S11" ]), "gsd" : 1000 },
259+ ),
260+ "BT_io" : ItemAssetDefinition .create (
261+ title = "TOA brightness temperature - TIR, oblique view" ,
262+ media_type = pystac .MediaType .ZARR ,
263+ description = ("Dataset of the TOA brightness temperature for channels S7-S9 and F2, 1km grid, oblique view" ),
264+ roles = [ROLE_DATA , ROLE_DATASET ],
265+ extra_fields = {"bands" : get_slstr_bands (["S07" , "S08" , "S09" , "S11" ]), "gsd" : 1000 },
266+ ),
267+ "BT_fn" : ItemAssetDefinition .create (
268+ title = "TOA brightness temperature - F1, nadir view" ,
269+ media_type = pystac .MediaType .ZARR ,
270+ description = ("Dataset of the TOA brightness temperature for the F1 channel, 1km grid, nadir view" ),
271+ roles = [ROLE_DATA , ROLE_DATASET ],
272+ extra_fields = {"bands" : get_slstr_bands (["S10" ]), "gsd" : 1000 },
273+ ),
274+ "BT_fo" : ItemAssetDefinition .create (
275+ title = "TOA brightness temperature - F1, oblique view" ,
276+ media_type = pystac .MediaType .ZARR ,
277+ description = ("Dataset of the TOA brightness temperature for the F1 channel, 1km grid, oblique view" ),
278+ roles = [ROLE_DATA , ROLE_DATASET ],
279+ extra_fields = {"bands" : get_slstr_bands (["S10" ]), "gsd" : 1000 },
280+ ),
281+ PRODUCT_ASSET_KEY : get_item_asset_product (),
282+ PRODUCT_METADATA_ASSET_KEY : get_item_asset_metadata (),
283+ }
284+
285+ SLSTR_L1_ASSETS_KEY_TO_PATH : dict [str :str ] = {
286+ "radiance_an" : "measurements/anadir" ,
287+ "radiance_ao" : "measurements/aoblique" ,
288+ "radiance_bn" : "measurements/bnadir" ,
289+ "radiance_bo" : "measurements/boblique" ,
290+ "BT_in" : "measurements/inadir" ,
291+ "BT_io" : "measurements/ioblique" ,
292+ "BT_fn" : "measurements/fnadir" ,
293+ "BT_fo" : "measurements/foblique" ,
294+ PRODUCT_ASSET_KEY : "" ,
295+ PRODUCT_METADATA_ASSET_KEY : PRODUCT_METADATA_PATH ,
296+ }
297+
298+ SLSTR_L2_LST_ASSETS : dict [str , ItemAssetDefinition ] = {
299+ "lst" : ItemAssetDefinition .create (
300+ title = "Land Surface Temperature (LST)" ,
301+ media_type = pystac .MediaType .ZARR ,
302+ description = ("Gridded Land Surface Temperature generated on the wide 1 km measurement grid" ),
303+ roles = [ROLE_DATA , ROLE_DATASET ],
304+ extra_fields = {"bands" : get_slstr_bands (["S07" , "S08" , "S09" ]), "gsd" : 1000 },
305+ ),
306+ PRODUCT_ASSET_KEY : get_item_asset_product (),
307+ PRODUCT_METADATA_ASSET_KEY : get_item_asset_metadata (),
308+ }
309+
310+ SLSTR_L2_LST_ASSETS_KEY_TO_PATH : dict [str :str ] = {
311+ "lst" : "measurements" ,
312+ PRODUCT_ASSET_KEY : "" ,
313+ PRODUCT_METADATA_ASSET_KEY : PRODUCT_METADATA_PATH ,
314+ }
315+
316+ SLSTR_L2_FRP_ASSETS : dict [str , ItemAssetDefinition ] = {
317+ PRODUCT_ASSET_KEY : get_item_asset_product (),
318+ PRODUCT_METADATA_ASSET_KEY : get_item_asset_metadata (),
319+ }
320+
321+ SLSTR_L2_FRP_ASSETS_KEY_TO_PATH : dict [str :str ] = {
322+ PRODUCT_ASSET_KEY : "" ,
323+ PRODUCT_METADATA_ASSET_KEY : PRODUCT_METADATA_PATH ,
324+ }
325+
208326# -- Collection metadata
209327
210328S3_OLCI_L1_EFR = {
@@ -218,7 +336,7 @@ def get_olci_bands(band_keys: list[str] | None = None) -> list[dict]:
218336 "product_type" : "S03OLCEFR" ,
219337 "processing_level" : "L1" ,
220338 "instrument" : "olci" ,
221- "gsd" : 300 ,
339+ "gsd" : [ 300 ] ,
222340 "item_assets" : {** OLCI_L1_ASSETS },
223341}
224342
@@ -233,7 +351,7 @@ def get_olci_bands(band_keys: list[str] | None = None) -> list[dict]:
233351 "product_type" : "S03OLCERR" ,
234352 "processing_level" : "L1" ,
235353 "instrument" : "olci" ,
236- "gsd" : 1200 ,
354+ "gsd" : [ 1200 ] ,
237355 "item_assets" : {** OLCI_L1_ASSETS },
238356}
239357
@@ -246,21 +364,10 @@ def get_olci_bands(band_keys: list[str] | None = None) -> list[dict]:
246364 "product_type" : "S03OLCLFR" ,
247365 "processing_level" : "L2" ,
248366 "instrument" : "olci" ,
249- "gsd" : 300 ,
367+ "gsd" : [ 300 ] ,
250368 "item_assets" : {** OLCI_L2_ASSETS },
251369}
252370
253-
254- # S03SLSRBT / SL_1_RBT
255- S3_SLSTR_L1_RBT = {}
256-
257- # S03SLSLST / SL_2_LST
258- S3_SLSTR_L2_LST = {}
259-
260- # TBD: SRAL, SYN
261-
262- # Conversion not supported by CPM; no mapping
263-
264371S3_OLCI_L2_LRR = {
265372 "id" : "sentinel-3-olci-l2-lrr" ,
266373 "title" : "Sentinel-3 OLCI Level-2 LRR" ,
@@ -270,10 +377,53 @@ def get_olci_bands(band_keys: list[str] | None = None) -> list[dict]:
270377 "product_type" : "S03OLCLRR" ,
271378 "processing_level" : "L2" ,
272379 "instrument" : "olci" ,
273- "gsd" : 1200 ,
380+ "gsd" : [ 1200 ] ,
274381 "item_assets" : {** OLCI_L2_ASSETS },
275382}
276383
384+ S3_SLSTR_L1_RBT = {
385+ "id" : "sentinel-3-slstr-l1-rbt" ,
386+ "title" : "Sentinel-3 SLSTR Level-1 RBT" ,
387+ "description" : (
388+ "The Sentinel-3 SLSTR Level-1B RBT product provides radiances and brightness temperatures for each pixel "
389+ "in a regular image grid for each view and SLSTR channel. In addition, it also contains annotations data "
390+ "associated with each image pixels."
391+ ),
392+ "product_type" : "S03SLSRBT" ,
393+ "processing_level" : "L1" ,
394+ "instrument" : "slstr" ,
395+ "gsd" : [500 , 1000 ],
396+ "item_assets" : {** SLSTR_L1_ASSETS },
397+ }
398+
399+ S3_SLSTR_L2_LST = {
400+ "id" : "sentinel-3-slstr-l2-lst" ,
401+ "title" : "Sentinel-3 SLSTR Level-2 LST" ,
402+ "description" : "The Sentinel-3 SLSTR Level-2 LST product provides land surface temperature." ,
403+ "product_type" : "S03SLSLST" ,
404+ "processing_level" : "L2" ,
405+ "instrument" : "slstr" ,
406+ "gsd" : [500 , 1000 ],
407+ "item_assets" : {** SLSTR_L2_LST_ASSETS },
408+ }
409+
410+ S3_SLSTR_L2_FRP = {
411+ "id" : "sentinel-3-slstr-l2-frp" ,
412+ "title" : "Sentinel-3 SLSTR Level-2 FRP" ,
413+ "description" : (
414+ "The Sentinel-3 SLSTR Level-2 FRP product provides global (over land and water) fire radiative power."
415+ ),
416+ "product_type" : "S03SLSFRP" ,
417+ "processing_level" : "L2" ,
418+ "instrument" : "slstr" ,
419+ "gsd" : [500 , 1000 ],
420+ "item_assets" : {** SLSTR_L2_FRP_ASSETS },
421+ }
422+
423+ # TBD: SRAL, SYN
424+
425+ # Conversion not supported by CPM; no mapping
426+
277427S3_OLCI_L2_WFR = {
278428 "id" : "sentinel-3-olci-l2-wfr" ,
279429 "title" : "Sentinel-3 OLCI Level-2 WFR" ,
0 commit comments