Catalog explorer — browse CMEMS without downloading anything¶
This notebook needs no credentials and no network. It reads the
bundled earthlens.cmems catalog (a directory of per-domain YAML files)
to answer the first questions every CMEMS user has: what's in here, how
is it organised, and what's the dataset id / variable name I need to
pass to download().
The catalog has two tiers, mirroring the GEE and ECMWF backends:
available_datasets— the informational index of every dataset id the Copernicus Marine toolbox publishes (~1,251).datasets— the curated map earthlens models in detail (variable lists, units, cadence, domain). A subset ofavailable_datasets.
Uncurated ids still work — pass any id copernicusmarine.describe()
recognises straight to CMEMS(variables={id: [...]}).
Setup¶
The only imports we need: Counter for the tallies further down and the
earthlens.cmems Catalog loader. No backend SDK, no credentials.
from collections import Counter
from earthlens.cmems import Catalog
Load the catalog¶
Constructing Catalog() parses the bundled YAML files into memory. We
print the two tiers' sizes and confirm the curated map is a strict subset
of the full index.
cat = Catalog()
print(f'available_datasets (index): {len(cat.available_datasets)}')
print(f'curated datasets: {len(cat.datasets)}')
print(f'curated is subset of index: {set(cat.datasets) <= set(cat.available_datasets)}')
Curated datasets by domain¶
Every curated row carries a domain label inferred from its CMEMS
product id. This is also how the catalog files are split on disk
(catalog/global-*.yaml, catalog/mediterranean.yaml, …).
by_domain = Counter(d.domain for d in cat.datasets.values())
for domain, n in by_domain.most_common():
print(f' {domain:15s} {n:4d}')
by_cadence = Counter(d.cadence for d in cat.datasets.values())
print('\nby cadence:')
for cadence, n in by_cadence.most_common():
print(f' {cadence:12s} {n:4d}')
Search the index by keyword¶
available_datasets is just a list of ids — grep it for the basin /
theme / cadence token you want. CMEMS encodes a lot in the id itself
(_phy physics, _bgc biogeochem, _wav wave, _P1D-m daily mean,
med Mediterranean, …).
def search(token, limit=8):
hits = [d for d in cat.available_datasets if token in d]
print(f'{token!r}: {len(hits)} matches')
for d in hits[:limit]:
curated = ' (curated)' if d in cat.datasets else ''
print(f' {d}{curated}')
if len(hits) > limit:
print(f' ... and {len(hits) - limit} more')
search('glo_phy_my')
print()
search('_wav_')
Inspect one curated dataset¶
Once you have an id, get_dataset gives the full curated row and
get_variable resolves a single (dataset, variable) pair — units and
long-name without ever touching the network.
ds = cat.get_dataset('cmems_mod_glo_phy_my_0.083deg_P1D-m')
print(f'product: {ds.product}')
print(f'title: {ds.title}')
print(f'cadence: {ds.cadence} domain: {ds.domain}')
print(f'temporal: {ds.temporal.start} -> {ds.temporal.end}')
print('variables:')
for name, var in sorted(ds.variables.items()):
print(f' {name:10s} {var.units:10s} {var.long_name}')
Next steps¶
Pick an id + variable from above and hand it to a download — see the quickstart for the facade call. The other notebooks in this folder show concrete workflows: GLORYS thermocline (depth axis), PISCES chlorophyll (multi-variable seasonal cycle), altimetry SLA (coastal time-series), Arctic sea ice (polar map), global waves, and Mediterranean SST (regional map).