Drought catalog explorer¶
Walk through the 43 datasets the earthlens.drought backend curates across four public services —
USDM, Copernicus EDO, Copernicus GDO, and CSIC SPEIbase — and the helper utilities the backend leans
on. Network-free: every cell reads the bundled sharded catalog under src/earthlens/drought/catalog/.
Setup¶
We use the Catalog loader and the pure-Python helpers from earthlens.drought._helpers (date
snapping, per-source attribution).
import datetime as dt
import pandas as pd
from earthlens.drought import Catalog
from earthlens.drought._helpers import attribution_for, snap_to_cadence
Full curated catalog¶
Catalog().datasets is a dict of typed Dataset rows keyed by id. Each row pins:
source— human-readable source string used in the success log line.transport— one ofusdm-geojson/edo-wcs/netcdf-url(the backend dispatches_fetchon it).endpoint— URL or URL template.coverage— WCS coverage id for EDO/GDO rows;Nonefor the other transports.output_kind—vectorfor USDM,rasterfor the rest. Copied onto the backend instance'sOUTPUT_KINDso the facade gatesaggregate=correctly.cadence—weekly/10day/monthly. Drives date snapping.native_crs— the CRS the source delivers in (EPSG:4326 everywhere today).license_note— short attribution string the backend logs on success.
cat = Catalog()
frame = pd.DataFrame(
[
{
'id': ds.id,
'transport': ds.transport,
'output_kind': ds.output_kind,
'cadence': ds.cadence,
'coverage': ds.coverage,
'source': ds.source.split(' (')[0],
}
for ds in cat.datasets.values()
]
)
print('curated datasets:', len(frame))
frame
curated datasets: 43
| id | transport | output_kind | cadence | coverage | source | |
|---|---|---|---|---|---|---|
| 0 | edo-spaST | edo-wcs | raster | 10day | spaST | Copernicus European Drought Observatory |
| 1 | edo-spaLT | edo-wcs | raster | 10day | spaLT | Copernicus European Drought Observatory |
| 2 | edo-spcST | edo-wcs | raster | 10day | spcST | Copernicus European Drought Observatory |
| 3 | edo-spcLT | edo-wcs | raster | 10day | spcLT | Copernicus European Drought Observatory |
| 4 | edo-spgTS | edo-wcs | raster | monthly | spgTS | Copernicus European Drought Observatory |
| 5 | edo-smian | edo-wcs | raster | 10day | smian | Copernicus European Drought Observatory |
| 6 | edo-smang | edo-wcs | raster | 10day | smang | Copernicus European Drought Observatory |
| 7 | edo-smand | edo-wcs | raster | 10day | smand | Copernicus European Drought Observatory |
| 8 | edo-fpanv | edo-wcs | raster | 10day | fpanv | Copernicus European Drought Observatory |
| 9 | edo-cdiad | edo-wcs | raster | 10day | cdiad | Copernicus European Drought Observatory |
| 10 | edo-cdirc | edo-wcs | raster | 10day | cdirc | Copernicus European Drought Observatory |
| 11 | edo-cdinx | edo-wcs | raster | 10day | cdinx | Copernicus European Drought Observatory |
| 12 | edo-lfinx-lgs | edo-wcs | raster | 10day | lfinx_300_lgs | Copernicus European Drought Observatory |
| 13 | edo-twsan | edo-wcs | raster | monthly | twsan | Copernicus European Drought Observatory |
| 14 | edo-snwvi | edo-wcs | raster | 10day | snwvi | Copernicus European Drought Observatory |
| 15 | edo-rdria | edo-wcs | raster | monthly | rdria | Copernicus European Drought Observatory |
| 16 | edo-msfTS | edo-wcs | raster | monthly | msfTS | Copernicus European Drought Observatory |
| 17 | gdo-spaST | edo-wcs | raster | 10day | spaST | Copernicus Global Drought Observatory |
| 18 | gdo-spaLT | edo-wcs | raster | 10day | spaLT | Copernicus Global Drought Observatory |
| 19 | gdo-spgTS | edo-wcs | raster | monthly | spgTS | Copernicus Global Drought Observatory |
| 20 | gdo-smand | edo-wcs | raster | 10day | smand | Copernicus Global Drought Observatory |
| 21 | gdo-fpanv | edo-wcs | raster | 10day | fpanv | Copernicus Global Drought Observatory |
| 22 | gdo-cdinx | edo-wcs | raster | 10day | cdinx | Copernicus Global Drought Observatory |
| 23 | gdo-twsan | edo-wcs | raster | monthly | twsan | Copernicus Global Drought Observatory |
| 24 | gdo-lfinx-sms | edo-wcs | raster | 10day | lfinx_300_sms | Copernicus Global Drought Observatory |
| 25 | gdo-lfinx-mds | edo-wcs | raster | 10day | lfinx_300_mds | Copernicus Global Drought Observatory |
| 26 | gdo-smian | edo-wcs | raster | 10day | smian | Copernicus Global Drought Observatory |
| 27 | gdo-smang | edo-wcs | raster | 10day | smang | Copernicus Global Drought Observatory |
| 28 | gdo-spcST | edo-wcs | raster | 10day | spcST | Copernicus Global Drought Observatory |
| 29 | gdo-spcLT | edo-wcs | raster | 10day | spcLT | Copernicus Global Drought Observatory |
| 30 | gdo-cdiad | edo-wcs | raster | 10day | cdiad | Copernicus Global Drought Observatory |
| 31 | gdo-cdirc | edo-wcs | raster | 10day | cdirc | Copernicus Global Drought Observatory |
| 32 | gdo-lfinx-lgs | edo-wcs | raster | 10day | lfinx_300_lgs | Copernicus Global Drought Observatory |
| 33 | gdo-msfTS | edo-wcs | raster | monthly | msfTS | Copernicus Global Drought Observatory |
| 34 | gdo-snwvi | edo-wcs | raster | 10day | snwvi | Copernicus Global Drought Observatory |
| 35 | gdo-rdria | edo-wcs | raster | monthly | rdria | Copernicus Global Drought Observatory |
| 36 | speibase-01 | netcdf-url | raster | monthly | NaN | CSIC SPEIbase v2.11 |
| 37 | speibase-03 | netcdf-url | raster | monthly | NaN | CSIC SPEIbase v2.11 |
| 38 | speibase-06 | netcdf-url | raster | monthly | NaN | CSIC SPEIbase v2.11 |
| 39 | speibase-12 | netcdf-url | raster | monthly | NaN | CSIC SPEIbase v2.11 |
| 40 | speibase-24 | netcdf-url | raster | monthly | NaN | CSIC SPEIbase v2.11 |
| 41 | speibase-48 | netcdf-url | raster | monthly | NaN | CSIC SPEIbase v2.11 |
| 42 | usdm | usdm-geojson | vector | weekly | NaN | US Drought Monitor |
Counts per transport / output kind / cadence¶
USDM is one vector dataset; SPEIbase fans out into one NetCDF per timescale; EDO/GDO is the biggest fan, one row per Copernicus drought indicator.
frame.groupby(['transport', 'output_kind', 'cadence']).size().rename('n').reset_index()
| transport | output_kind | cadence | n | |
|---|---|---|---|---|
| 0 | edo-wcs | raster | 10day | 28 |
| 1 | edo-wcs | raster | monthly | 8 |
| 2 | netcdf-url | raster | monthly | 6 |
| 3 | usdm-geojson | vector | weekly | 1 |
Date snapping by cadence¶
Every requested date snaps onto the source's release calendar before fetching, so a date range
collapses to one fetch per release / dekad / month. The snap_to_cadence helper is pure Python and
module-scope — no I/O, easy to drop into your own pre-processing.
The USDM weekly snap takes an optional today= reference: when the snapped Tuesday's release Thursday
is in the future relative to today, the snap walks back one extra week to the prior Tuesday's
composite (this week's isn't published yet).
weekly_today = dt.date(2026, 6, 23) # the Tuesday itself — pre-release
examples = [
('USDM weekly (queried on Tue 2026-06-23 — pre-release)',
'weekly', dt.date(2026, 6, 23), weekly_today),
('USDM weekly (queried on Fri 2026-06-26 — post-release)',
'weekly', dt.date(2026, 6, 23), dt.date(2026, 6, 26)),
('EDO/GDO 10-day dekad', '10day', dt.date(2026, 6, 15), None),
('SPEIbase / EDO monthly', 'monthly', dt.date(2026, 6, 25), None),
]
for label, cadence, when, today in examples:
if today is None:
snapped = snap_to_cadence([when], cadence)[0]
else:
snapped = snap_to_cadence([when], cadence, today=today)[0]
print(f'{label}: {when} -> {snapped}')
USDM weekly (queried on Tue 2026-06-23 — pre-release): 2026-06-23 -> 2026-06-16 USDM weekly (queried on Fri 2026-06-26 — post-release): 2026-06-23 -> 2026-06-23 EDO/GDO 10-day dekad: 2026-06-15 -> 2026-06-11 SPEIbase / EDO monthly: 2026-06-25 -> 2026-06-01
A multi-day range collapses to one entry per snapped period — so an arbitrary span over USDM yields one FeatureCollection per Tuesday valid date, deduplicated across overlapping days.
span = [dt.date(2026, 6, 10) + dt.timedelta(days=i) for i in range(14)]
today = dt.date(2026, 7, 15) # well past every snap candidate's release Thursday
print('input span :', span[0], 'to', span[-1], '(14 days)')
print('snapped weekly:', snap_to_cadence(span, 'weekly', today=today))
print('snapped 10day :', snap_to_cadence(span, '10day'))
input span : 2026-06-10 to 2026-06-23 (14 days) snapped weekly: [datetime.date(2026, 6, 9), datetime.date(2026, 6, 16), datetime.date(2026, 6, 23)] snapped 10day : [datetime.date(2026, 6, 1), datetime.date(2026, 6, 11), datetime.date(2026, 6, 21)]
Per-source attribution¶
Three transports, three attribution strings. attribution_for(transport) returns the exact line the
backend logs once per download() — handy if you want to surface attribution next to a map or a CSV.
for transport in ('usdm-geojson', 'edo-wcs', 'netcdf-url'):
print(transport, '\n ', attribution_for(transport), '\n')
usdm-geojson USDM: U.S. Drought Monitor — public-domain weekly composite produced by NDMC / UNL / USDA / NOAA. Cite the National Drought Mitigation Center. edo-wcs EDO/GDO: Copernicus European/Global Drought Observatory (EMS) — free reuse with attribution to Copernicus EMS. netcdf-url SPEIbase: CSIC Standardised Precipitation-Evapotranspiration Index database v2.11 (Vicente-Serrano et al.), CC-BY 4.0.
Did-you-mean on unknown ids¶
Catalog lookups raise ValueError (not KeyError) with a sorted Known-datasets list and a difflib
best-match hint.
try:
cat.get('usdmm')
except ValueError as exc:
print(str(exc)[:140], '...')
'usdmm' is not in the drought catalog. Known datasets: ['edo-cdiad', 'edo-cdinx', 'edo-cdirc', 'edo-fpanv', 'edo-lfinx-lgs', 'edo-msfTS', 'e ...
Status — what's wired today¶
- USDM (vector) — fully wired. Returns a
FeatureCollectionin EPSG:4326. See thequickstart.ipynbnotebook for the live demo. - SPEIbase (raster NetCDF) — fully wired. Downloads the per-scale NetCDF once, slices each
requested month via
pyramids.netcdf.NetCDF.subset, writes one GeoTIFF per period. Requires an explicitpath=(a raster transport without one raises before any download starts). - Copernicus EDO / GDO (raster WCS) — catalog and routing in place, but
download()raisesNotImplementedErrorpending the pyramids temporalread_wcsextension (cross-repoPY-A).