Mediterranean Sea — surface temperature map¶
Demonstrates the regional-reanalysis map pattern: pull one summer
day of the Mediterranean physics reanalysis potential temperature
(thetao), clipped to the surface layer, and render the basin-wide SST
field.
Dataset cmems_mod_med_phy-temp_my_4.2km_P1D-m is a multi-year
reanalysis on a ~4 km grid (stable historical coverage, so a fixed date
works). It is 4-D, so we clip minimum_depth / maximum_depth to the top
few metres to fetch just the surface field.
Reads credentials from
COPERNICUSMARINE_SERVICE_USERNAME/COPERNICUSMARINE_SERVICE_PASSWORD.
Setup¶
Imports up front: pyramids provides NetCDF (reading the downloaded cube)
and ColorBar (labelling the map), and earthlens provides the unified
EarthLens entry point and the CMEMS Catalog. The reduction and the plot
both go through pyramids, so no second array library is needed.
import os
from pathlib import Path
from pyramids.netcdf import NetCDF
from pyramids.plot import ColorBar
from earthlens.cmems import Catalog
from earthlens.core import EarthLens
Request parameters¶
Pin the dataset id, the mid-summer day (strong basin-wide SST gradient), and an output directory for the downloaded NetCDF.
OUT_DIR = Path('data/cmems-medsst')
OUT_DIR.mkdir(parents=True, exist_ok=True)
DATASET_ID = 'cmems_mod_med_phy-temp_my_4.2km_P1D-m'
DAY = '2020-08-15' # mid-summer, strong basin-wide SST gradient
Inspect the dataset metadata¶
Look up the dataset in the CMEMS Catalog to confirm its domain,
cadence, and the units of the thetao variable before downloading.
ds_meta = Catalog().get_dataset(DATASET_ID)
print(ds_meta)
print(f'domain: {ds_meta.domain}')
print(ds_meta.variables['thetao'])
Download one day, surface layer, whole basin¶
Build the EarthLens request first — dataset, day window, basin bounding
box, and the minimum_depth / maximum_depth clip that keeps only the
top model level.
el = EarthLens(
data_source='cmems',
start=DAY,
end=DAY,
cadence='daily',
dataset=DATASET_ID,
variables=['thetao'],
aoi=[-6.0, 30.0, 36.5, 46.0],
path=OUT_DIR,
minimum_depth=0.0,
maximum_depth=2.0,
service_username=os.environ.get('COPERNICUSMARINE_SERVICE_USERNAME'),
service_password=os.environ.get('COPERNICUSMARINE_SERVICE_PASSWORD'),
)
Run the download. download() returns the list of written file paths;
this request writes a single NetCDF cube.
paths = el.download()
print(paths)
Open the cube¶
Read it with pyramids' NetCDF. It decodes the CF metadata itself, so the
cube is ready to query without a second library.
nc = NetCDF.read_file(paths[0], read_only=True)
print('variables :', nc.variable_names)
print('dimensions:', nc.dimension_sizes)
get_variable returns the georeferenced thetao field. time and depth
are both length 1 here — the request already clipped to one day and the top
model level — so the variable is the 2-D surface field. stats reports over
the valid cells only, because the band's own no-data marks the land.
sst = nc.get_variable('thetao')
stats = sst.stats(approx_ok=False)
low, mean, high = (float(stats[k].iloc[0]) for k in ('min', 'mean', 'max'))
print(f'grid: {sst.rows} x {sst.columns}, epsg {sst.epsg}')
print(f'surface thetao min/mean/max: {low:.1f} / {mean:.1f} / {high:.1f} degrees_C')
Map the surface temperature¶
Warm eastern-basin / Levantine waters versus the cooler Gulf of Lions and Aegean — the classic August Mediterranean SST signature.
sst.plot(
cmap='inferno',
colorbar=ColorBar(label='SST (degrees_C)'),
title=f'Mediterranean surface temperature ({DAY})',
)
nc.close()