Sentinel-3 Patchwork L1 OLCI EFR L2 SLSTR FPR SYN AOD product format prototype
Sentinel-3 L1 OLCI EFR, Sentinel-3 L2 SLSTR FPR, Sentinel-3 SYN AOD product
Table of ContentsΒΆ
Run this notebook interactively with all dependencies pre-installed
IntroductionΒΆ
In this notebook we will show an example of using Sentinel-3 L1 OLCI EFR, Sentinel-3 L2 SLSTR FPR, Sentinel-3 SYN AOD product
import matplotlib.pyplot as plt
import cartopy.crs as ccrs
import fsspec # For remote access
import datatree
L1 OLCI EFRΒΆ
Product can only be accessed locally and also remotely, even if it is a zarr.zip
# Define the remote product path
remote_product_path = "https://eopf-public.s3.sbg.perf.cloud.ovh.net/eoproducts/S03OLCEFR_20230506T015316_0180_B117_T883.zarr.zip"
# Construct the fsspec mapper path
store = fsspec.get_mapper(f"zip::{remote_product_path}")
# Load it with datatree
dt = datatree.open_datatree(store, engine="zarr", consolidated=False, chunks={})
Open the product using EOPF API and visualize the tree structureΒΆ
print(dt)
DataTree('None', parent=None)
β Dimensions: ()
β Data variables:
β *empty*
β Attributes:
β other_metadata: {'absolute_pass_number': 52368, 'cycle_number': 79, 'dat...
β stac_discovery: {'assets': [], 'bbox': [132.954, 29.0715, 115.986, 41.97...
βββ DataTree('conditions')
β βββ DataTree('geometry')
β β Dimensions: (tp_rows: 4092, tp_columns: 77)
β β Coordinates:
β β latitude (tp_rows, tp_columns) float64 3MB dask.array<chunksize=(4092, 77), meta=np.ndarray>
β β longitude (tp_rows, tp_columns) float64 3MB dask.array<chunksize=(4092, 77), meta=np.ndarray>
β β Dimensions without coordinates: tp_rows, tp_columns
β β Data variables:
β β oaa (tp_rows, tp_columns) float64 3MB dask.array<chunksize=(4092, 77), meta=np.ndarray>
β β oza (tp_rows, tp_columns) float64 3MB dask.array<chunksize=(4092, 77), meta=np.ndarray>
β β saa (tp_rows, tp_columns) float64 3MB dask.array<chunksize=(4092, 77), meta=np.ndarray>
β β sza (tp_rows, tp_columns) float64 3MB dask.array<chunksize=(4092, 77), meta=np.ndarray>
β βββ DataTree('image')
β β Dimensions: (rows: 4092, columns: 4865)
β β Coordinates:
β β altitude (rows, columns) float32 80MB dask.array<chunksize=(1024, 1024), meta=np.ndarray>
β β latitude (rows, columns) float64 159MB dask.array<chunksize=(1024, 1024), meta=np.ndarray>
β β longitude (rows, columns) float64 159MB dask.array<chunksize=(1024, 1024), meta=np.ndarray>
β β Dimensions without coordinates: rows, columns
β β Data variables:
β β detector_index (rows, columns) float32 80MB dask.array<chunksize=(1024, 1024), meta=np.ndarray>
β β frame_offset (rows, columns) float32 80MB dask.array<chunksize=(1024, 1024), meta=np.ndarray>
β βββ DataTree('instrument')
β β Dimensions: (bands: 21, detectors: 3700, bands1: 21,
β β bands2: 21)
β β Dimensions without coordinates: bands, detectors, bands1, bands2
β β Data variables:
β β fwhm (bands, detectors) float32 311kB dask.array<chunksize=(21, 3700), meta=np.ndarray>
β β lambda0 (bands, detectors) float32 311kB dask.array<chunksize=(21, 3700), meta=np.ndarray>
β β relative_spectral_covariance (bands1, bands2) float32 2kB dask.array<chunksize=(21, 21), meta=np.ndarray>
β β solar_flux (bands, detectors) float32 311kB dask.array<chunksize=(21, 3700), meta=np.ndarray>
β βββ DataTree('meteorology')
β β Dimensions: (tp_rows: 4092, tp_columns: 77,
β β pressure_level: 25, wind_vector: 2)
β β Coordinates:
β β * pressure_level (pressure_level) float32 100B 1e+03 ... 1.0
β β Dimensions without coordinates: tp_rows, tp_columns, wind_vector
β β Data variables:
β β atmospheric_temperature_profile (tp_rows, tp_columns, pressure_level) float32 32MB dask.array<chunksize=(4092, 77, 25), meta=np.ndarray>
β β horizontal_wind (tp_rows, tp_columns, wind_vector) float32 3MB dask.array<chunksize=(4092, 77, 2), meta=np.ndarray>
β β humidity (tp_rows, tp_columns) float32 1MB dask.array<chunksize=(4092, 77), meta=np.ndarray>
β β sea_level_pressure (tp_rows, tp_columns) float32 1MB dask.array<chunksize=(4092, 77), meta=np.ndarray>
β β total_columnar_water_vapour (tp_rows, tp_columns) float32 1MB dask.array<chunksize=(4092, 77), meta=np.ndarray>
β β total_ozone (tp_rows, tp_columns) float32 1MB dask.array<chunksize=(4092, 77), meta=np.ndarray>
β βββ DataTree('orphans')
β Dimensions: (rows: 4092, removed_pixels: 150)
β Coordinates:
β altitude (rows, removed_pixels) float32 2MB dask.array<chunksize=(1024, 150), meta=np.ndarray>
β latitude (rows, removed_pixels) float64 5MB dask.array<chunksize=(1024, 150), meta=np.ndarray>
β longitude (rows, removed_pixels) float64 5MB dask.array<chunksize=(1024, 150), meta=np.ndarray>
β Dimensions without coordinates: rows, removed_pixels
β Data variables:
β detector_index (rows, removed_pixels) float32 2MB dask.array<chunksize=(1024, 150), meta=np.ndarray>
β frame_offset (rows, removed_pixels) float32 2MB dask.array<chunksize=(1024, 150), meta=np.ndarray>
β nb_removed_pixels (rows) uint16 8kB dask.array<chunksize=(1024,), meta=np.ndarray>
β sza (rows, removed_pixels) float64 5MB dask.array<chunksize=(1024, 150), meta=np.ndarray>
βββ DataTree('measurements')
β β Dimensions: (rows: 4092, columns: 4865)
β β Coordinates:
β β latitude (rows, columns) float64 159MB dask.array<chunksize=(1024, 1024), meta=np.ndarray>
β β longitude (rows, columns) float64 159MB dask.array<chunksize=(1024, 1024), meta=np.ndarray>
β β time_stamp (rows) datetime64[ns] 33kB dask.array<chunksize=(1024,), meta=np.ndarray>
β β Dimensions without coordinates: rows, columns
β β Data variables: (12/21)
β β oa01_radiance (rows, columns) float64 159MB dask.array<chunksize=(1024, 1024), meta=np.ndarray>
β β oa02_radiance (rows, columns) float64 159MB dask.array<chunksize=(1024, 1024), meta=np.ndarray>
β β oa03_radiance (rows, columns) float64 159MB dask.array<chunksize=(1024, 1024), meta=np.ndarray>
β β oa04_radiance (rows, columns) float64 159MB dask.array<chunksize=(1024, 1024), meta=np.ndarray>
β β oa05_radiance (rows, columns) float64 159MB dask.array<chunksize=(1024, 1024), meta=np.ndarray>
β β oa06_radiance (rows, columns) float64 159MB dask.array<chunksize=(1024, 1024), meta=np.ndarray>
β β ... ...
β β oa16_radiance (rows, columns) float64 159MB dask.array<chunksize=(1024, 1024), meta=np.ndarray>
β β oa17_radiance (rows, columns) float64 159MB dask.array<chunksize=(1024, 1024), meta=np.ndarray>
β β oa18_radiance (rows, columns) float64 159MB dask.array<chunksize=(1024, 1024), meta=np.ndarray>
β β oa19_radiance (rows, columns) float64 159MB dask.array<chunksize=(1024, 1024), meta=np.ndarray>
β β oa20_radiance (rows, columns) float64 159MB dask.array<chunksize=(1024, 1024), meta=np.ndarray>
β β oa21_radiance (rows, columns) float64 159MB dask.array<chunksize=(1024, 1024), meta=np.ndarray>
β βββ DataTree('orphans')
β Dimensions: (rows: 4092, removed_pixels: 150)
β Coordinates:
β altitude (rows, removed_pixels) float32 2MB dask.array<chunksize=(1024, 150), meta=np.ndarray>
β latitude (rows, removed_pixels) float64 5MB dask.array<chunksize=(1024, 150), meta=np.ndarray>
β longitude (rows, removed_pixels) float64 5MB dask.array<chunksize=(1024, 150), meta=np.ndarray>
β Dimensions without coordinates: rows, removed_pixels
β Data variables: (12/21)
β oa01_radiance (rows, removed_pixels) float64 5MB dask.array<chunksize=(1024, 150), meta=np.ndarray>
β oa02_radiance (rows, removed_pixels) float64 5MB dask.array<chunksize=(1024, 150), meta=np.ndarray>
β oa03_radiance (rows, removed_pixels) float64 5MB dask.array<chunksize=(1024, 150), meta=np.ndarray>
β oa04_radiance (rows, removed_pixels) float64 5MB dask.array<chunksize=(1024, 150), meta=np.ndarray>
β oa05_radiance (rows, removed_pixels) float64 5MB dask.array<chunksize=(1024, 150), meta=np.ndarray>
β oa06_radiance (rows, removed_pixels) float64 5MB dask.array<chunksize=(1024, 150), meta=np.ndarray>
β ... ...
β oa16_radiance (rows, removed_pixels) float64 5MB dask.array<chunksize=(1024, 150), meta=np.ndarray>
β oa17_radiance (rows, removed_pixels) float64 5MB dask.array<chunksize=(1024, 150), meta=np.ndarray>
β oa18_radiance (rows, removed_pixels) float64 5MB dask.array<chunksize=(1024, 150), meta=np.ndarray>
β oa19_radiance (rows, removed_pixels) float64 5MB dask.array<chunksize=(1024, 150), meta=np.ndarray>
β oa20_radiance (rows, removed_pixels) float64 5MB dask.array<chunksize=(1024, 150), meta=np.ndarray>
β oa21_radiance (rows, removed_pixels) float64 5MB dask.array<chunksize=(1024, 150), meta=np.ndarray>
βββ DataTree('quality')
β Dimensions: (rows: 4092, columns: 4865)
β Coordinates:
β latitude (rows, columns) float64 159MB dask.array<chunksize=(1024, 1024), meta=np.ndarray>
β longitude (rows, columns) float64 159MB dask.array<chunksize=(1024, 1024), meta=np.ndarray>
β Dimensions without coordinates: rows, columns
β Data variables: (12/22)
β oa01_radiance_unc (rows, columns) float64 159MB dask.array<chunksize=(1024, 1024), meta=np.ndarray>
β oa02_radiance_unc (rows, columns) float64 159MB dask.array<chunksize=(1024, 1024), meta=np.ndarray>
β oa03_radiance_unc (rows, columns) float64 159MB dask.array<chunksize=(1024, 1024), meta=np.ndarray>
β oa04_radiance_unc (rows, columns) float64 159MB dask.array<chunksize=(1024, 1024), meta=np.ndarray>
β oa05_radiance_unc (rows, columns) float64 159MB dask.array<chunksize=(1024, 1024), meta=np.ndarray>
β oa06_radiance_unc (rows, columns) float64 159MB dask.array<chunksize=(1024, 1024), meta=np.ndarray>
β ... ...
β oa17_radiance_unc (rows, columns) float64 159MB dask.array<chunksize=(1024, 1024), meta=np.ndarray>
β oa18_radiance_unc (rows, columns) float64 159MB dask.array<chunksize=(1024, 1024), meta=np.ndarray>
β oa19_radiance_unc (rows, columns) float64 159MB dask.array<chunksize=(1024, 1024), meta=np.ndarray>
β oa20_radiance_unc (rows, columns) float64 159MB dask.array<chunksize=(1024, 1024), meta=np.ndarray>
β oa21_radiance_unc (rows, columns) float64 159MB dask.array<chunksize=(1024, 1024), meta=np.ndarray>
β quality_flags (rows, columns) uint32 80MB dask.array<chunksize=(1024, 1024), meta=np.ndarray>
βββ DataTree('orphans')
Dimensions: (rows: 4092, removed_pixels: 150)
Coordinates:
altitude (rows, removed_pixels) float32 2MB dask.array<chunksize=(1024, 150), meta=np.ndarray>
latitude (rows, removed_pixels) float64 5MB dask.array<chunksize=(1024, 150), meta=np.ndarray>
longitude (rows, removed_pixels) float64 5MB dask.array<chunksize=(1024, 150), meta=np.ndarray>
Dimensions without coordinates: rows, removed_pixels
Data variables: (12/22)
oa01_radiance_unc (rows, removed_pixels) float64 5MB dask.array<chunksize=(1024, 150), meta=np.ndarray>
oa02_radiance_unc (rows, removed_pixels) float64 5MB dask.array<chunksize=(1024, 150), meta=np.ndarray>
oa03_radiance_unc (rows, removed_pixels) float64 5MB dask.array<chunksize=(1024, 150), meta=np.ndarray>
oa04_radiance_unc (rows, removed_pixels) float64 5MB dask.array<chunksize=(1024, 150), meta=np.ndarray>
oa05_radiance_unc (rows, removed_pixels) float64 5MB dask.array<chunksize=(1024, 150), meta=np.ndarray>
oa06_radiance_unc (rows, removed_pixels) float64 5MB dask.array<chunksize=(1024, 150), meta=np.ndarray>
... ...
oa17_radiance_unc (rows, removed_pixels) float64 5MB dask.array<chunksize=(1024, 150), meta=np.ndarray>
oa18_radiance_unc (rows, removed_pixels) float64 5MB dask.array<chunksize=(1024, 150), meta=np.ndarray>
oa19_radiance_unc (rows, removed_pixels) float64 5MB dask.array<chunksize=(1024, 150), meta=np.ndarray>
oa20_radiance_unc (rows, removed_pixels) float64 5MB dask.array<chunksize=(1024, 150), meta=np.ndarray>
oa21_radiance_unc (rows, removed_pixels) float64 5MB dask.array<chunksize=(1024, 150), meta=np.ndarray>
quality_flags (rows, removed_pixels) uint32 2MB dask.array<chunksize=(1024, 150), meta=np.ndarray>
Opening measurement dataΒΆ
rad = dt.measurements.oa01_radiance
rad.encoding
{'chunks': (1024, 1024),
'preferred_chunks': {'rows': 1024, 'columns': 1024},
'compressor': Blosc(cname='zstd', clevel=3, shuffle=BITSHUFFLE, blocksize=0),
'filters': None,
'_FillValue': 65535,
'scale_factor': 0.013634907081723213,
'add_offset': 0.0,
'dtype': dtype('uint16'),
'coordinates': 'time_stamp latitude longitude'}
Underlying data is dask.array
rad.data
Loading...
rad.attrs
{'long_name': 'TOA radiance for OLCI acquisition band oa01',
'short_name': 'oa01_radiance',
'standard_name': 'toa_upwelling_spectral_radiance',
'units': 'mW.m-2.sr-1.nm-1',
'valid_max': 65534,
'valid_min': 0}
rad.units ## Serving Ambiguity as a replacement for rad.is_scaled
rad.to_masked_array()
rad.sel()
Loading...
Simple raster plotΒΆ
Note that using xarray, data is correctly decoded and masked
rad.plot()

Plot using the coordinates (lon,lat)ΒΆ
plt.figure(figsize=(14, 6))
ax = plt.axes()
rad.plot.pcolormesh(ax=ax, x="longitude", y="latitude", add_colorbar=False)

Open Meteorological conditionsΒΆ
meteo = dt.conditions.meteorology
Interpolate the atmo. temp. profile at p=832.2 hPa and plotΒΆ
tp = meteo["atmospheric_temperature_profile"].interp(pressure_level=832.2)
tp.plot()

Open sat/sun anglesΒΆ
Angles are stored on a tiepoint subgrid
ds = dt.conditions.geometry
ds
Loading...
Have a look at condition parameters for removed pixelsΒΆ
ds = dt.conditions.orphans
ds
Loading...
SLSTR FRPΒΆ
# Define the remote product path
remote_product_path = "https://eopf-public.s3.sbg.perf.cloud.ovh.net/eoproducts/S03SLSFRP_20200908T182648_0179_A298_S883.zarr.zip"
# Construct the fsspec mapper path
store = fsspec.get_mapper(f"zip::{remote_product_path}")
# Load it with datatree
dt = datatree.open_datatree(store, engine="zarr", consolidated=False, chunks={})
Opening measurement data (1D)ΒΆ
Cannot find the lat/lon in this product ....
meas_in = dt.measurements.inadir
meas_in
Loading...
Plot Active Fire pixels positions on a PlateCarree gridΒΆ
import matplotlib.pyplot as plt
fig = plt.figure()
ax = plt.axes(projection=ccrs.PlateCarree())
# ax.set_global()
ax.coastlines()
ax.gridlines(draw_labels=True)
plt.scatter(meas_in.longitude, meas_in.latitude, c=meas_in.frp_mwir, vmax=100)
plt.colorbar()

SYN AODΒΆ
# Define the remote product path
remote_product_path = "https://eopf-public.s3.sbg.perf.cloud.ovh.net/eoproducts/S03SYNAOD_20191227T124211_0060_A109_T883.zarr.zip"
# Construct the fsspec mapper path
store = fsspec.get_mapper(f"zip::{remote_product_path}")
# Load it with datatree
dt = datatree.open_datatree(store, engine="zarr", consolidated=False, chunks={})
aod550 = dt.measurements.aod_550
aod550
Loading...
aod550.plot()

Plot using the coordinates (lon,lat)ΒΆ
Note that in SYN AOD product, lat/lon are undefined when the data is missing, which is not correctly handled by matplotlib pcolormesh
# Remove margins
aod550_dropna = aod550.dropna("columns", how="all")
aod550_dropna = aod550_dropna.dropna("rows", how="all")
# Fill remaining missing values
aod550_dropna["latitude"] = (
["rows", "columns"],
aod550_dropna.latitude.bfill("columns").data,
)
aod550_dropna["longitude"] = (
["rows", "columns"],
aod550_dropna.longitude.bfill("columns").data,
)
import matplotlib.pyplot as plt
plt.figure(figsize=(14, 6))
ax = plt.axes()
aod550_dropna.plot.pcolormesh(ax=ax, x="longitude", y="latitude", add_colorbar=False)

