Risk indicators — catalog & behaviour (offline)¶
Inspect the bundled dataset catalogue and the backend's design rules
without touching the network: which datasets ship, their provider and
output kind, the per-instance OUTPUT_KIND (tabular vs vector), the
did-you-mean hint on a bad id, and why aggregate= is rejected. This is
the no-network companion to the live
quickstart.
import tempfile
import pandas as pd
from earthlens.earthlens import EarthLens
The shipped datasets¶
EarthLens.list_datasets("risk-indicators") lists every dataset id the
backend accepts in variables= — no construction, no network.
EarthLens.list_datasets("risk-indicators")
2026-06-27 04:27:46 | INFO | pyramids.base.config | Logging is configured.
['gfw:admin_boundary', 'gfw:tree_cover_loss', 'gfw:tree_cover_loss_summary', 'inform:climate_risk', 'inform:coping_capacity', 'inform:hazard_exposure', 'inform:risk', 'inform:vulnerability', 'thinkhazard:all', 'thinkhazard:cyclone', 'thinkhazard:earthquake', 'thinkhazard:extreme_heat', 'thinkhazard:flood_coastal', 'thinkhazard:flood_river', 'thinkhazard:flood_urban', 'thinkhazard:landslide', 'thinkhazard:tsunami', 'thinkhazard:volcano', 'thinkhazard:water_scarcity', 'thinkhazard:wildfire']
Catalogue rows — provider and output kind¶
EarthLens.catalog("risk-indicators") returns the bundled Catalog.
Each row is a frozen pydantic Dataset carrying its provider,
output_kind, and human label. The ids group cleanly by source —
thinkhazard:*, inform:*, gfw:*.
catalog = EarthLens.catalog("risk-indicators")
pd.DataFrame(
[
{
"id": i,
"provider": catalog.get(i).provider,
"output_kind": catalog.get(i).output_kind,
"long_name": catalog.get(i).long_name,
}
for i in catalog.available()
]
).set_index("id")
| provider | output_kind | long_name | |
|---|---|---|---|
| id | |||
| gfw:admin_boundary | gfw | vector | GADM admin boundary geometry the GFW indicator... |
| gfw:tree_cover_loss | gfw | tabular | Annual tree-cover loss (ha) by country (UMD/Ha... |
| gfw:tree_cover_loss_summary | gfw | tabular | Total tree-cover loss (ha) by country (UMD/Han... |
| inform:climate_risk | inform | tabular | INFORM Climate Change Risk (SSP5 2050) |
| inform:coping_capacity | inform | tabular | INFORM Lack of Coping Capacity dimension |
| inform:hazard_exposure | inform | tabular | INFORM Hazard & Exposure dimension |
| inform:risk | inform | tabular | INFORM Risk composite index |
| inform:vulnerability | inform | tabular | INFORM Vulnerability dimension |
| thinkhazard:all | thinkhazard | tabular | All ThinkHazard! hazard levels for a division |
| thinkhazard:cyclone | thinkhazard | tabular | Cyclone hazard level (ThinkHazard!) |
| thinkhazard:earthquake | thinkhazard | tabular | Earthquake hazard level (ThinkHazard!) |
| thinkhazard:extreme_heat | thinkhazard | tabular | Extreme heat hazard level (ThinkHazard!) |
| thinkhazard:flood_coastal | thinkhazard | tabular | Coastal flood hazard level (ThinkHazard!) |
| thinkhazard:flood_river | thinkhazard | tabular | River flood hazard level (ThinkHazard!) |
| thinkhazard:flood_urban | thinkhazard | tabular | Urban flood hazard level (ThinkHazard!) |
| thinkhazard:landslide | thinkhazard | tabular | Landslide hazard level (ThinkHazard!) |
| thinkhazard:tsunami | thinkhazard | tabular | Tsunami hazard level (ThinkHazard!) |
| thinkhazard:volcano | thinkhazard | tabular | Volcano hazard level (ThinkHazard!) |
| thinkhazard:water_scarcity | thinkhazard | tabular | Water scarcity hazard level (ThinkHazard!) |
| thinkhazard:wildfire | thinkhazard | tabular | Wildfire hazard level (ThinkHazard!) |
Per-instance OUTPUT_KIND¶
The backend's return shape is decided per dataset, not fixed for the
whole backend. A thinkhazard:* / inform:* / gfw:tree_cover_loss row
is tabular → it returns a pandas.DataFrame; gfw:admin_boundary is
vector → it returns a pyramids FeatureCollection. The facade reads the
resolved dataset's output_kind onto the instance OUTPUT_KIND to know
the return shape (and to gate aggregate=).
pd.DataFrame(
[
{"id": i, "output_kind": catalog.get(i).output_kind}
for i in [
"thinkhazard:flood_river",
"inform:risk",
"gfw:tree_cover_loss",
"gfw:admin_boundary",
]
]
).set_index("id")
| output_kind | |
|---|---|
| id | |
| thinkhazard:flood_river | tabular |
| inform:risk | tabular |
| gfw:tree_cover_loss | tabular |
| gfw:admin_boundary | vector |
Resolving ids — with a did-you-mean hint¶
An unknown id raises a ValueError that suggests the closest match,
rather than failing silently. (The cell below is expected to raise — it
carries the raises-exception tag so notebook execution still passes.)
EarthLens.catalog("risk-indicators").get("inform:rsk")
--------------------------------------------------------------------------- ValueError Traceback (most recent call last) Cell In[5], line 1 ----> 1 EarthLens.catalog("risk-indicators").get("inform:rsk") File C:\gdrive\algorithms\remote-sensing\earthlens\.claude\worktrees\risk-indicators\src\earthlens\risk_indicators\catalog.py:322, in Catalog.get(self, dataset_id) 305 def get(self, dataset_id: str) -> Dataset: 306 """Resolve a dataset id to its :class:`Dataset` row. 307 308 Thin wrapper over the inherited :meth:`get_dataset`, which raises a (...) 320 did-you-mean hint. 321 """ --> 322 return self.get_dataset(dataset_id) File C:\gdrive\algorithms\remote-sensing\earthlens\.claude\worktrees\risk-indicators\src\earthlens\base\abstractdatasource.py:1072, in AbstractCatalog.get_dataset(self, name) 1070 close = difflib.get_close_matches(name, self.datasets, n=1) 1071 hint = f" Did you mean {close[0]!r}?" if close else "" -> 1072 raise ValueError( 1073 f"{name!r} is not in the {self._catalog_kind}. " 1074 f"Known {self._entry_noun}: {sorted(self.datasets)}.{hint}" 1075 ) from None ValueError: 'inform:rsk' is not in the risk-indicators catalog. Known datasets: ['gfw:admin_boundary', 'gfw:tree_cover_loss', 'gfw:tree_cover_loss_summary', 'inform:climate_risk', 'inform:coping_capacity', 'inform:hazard_exposure', 'inform:risk', 'inform:vulnerability', 'thinkhazard:all', 'thinkhazard:cyclone', 'thinkhazard:earthquake', 'thinkhazard:extreme_heat', 'thinkhazard:flood_coastal', 'thinkhazard:flood_river', 'thinkhazard:flood_urban', 'thinkhazard:landslide', 'thinkhazard:tsunami', 'thinkhazard:volcano', 'thinkhazard:water_scarcity', 'thinkhazard:wildfire']. Did you mean 'inform:risk'?
aggregate= is rejected¶
These are pre-computed country-indexed indices, not gridded rasters, so
there is no meaningful gridded reduction: passing a non-None
aggregate= raises NotImplementedError. The guard fires in the facade
before any network call (the inform:risk backend constructs without
touching the network). Again shown via a raises-exception-tagged cell.
EarthLens(
data_source="inform",
variables=["inform:risk"],
country="KEN",
path=tempfile.mkdtemp(),
).download(aggregate=object())
--------------------------------------------------------------------------- NotImplementedError Traceback (most recent call last) Cell In[6], line 6 2 data_source="inform", 3 variables=["inform:risk"], 4 country="KEN", 5 path=tempfile.mkdtemp(), ----> 6 ).download(aggregate=object()) File C:\gdrive\algorithms\remote-sensing\earthlens\.claude\worktrees\risk-indicators\src\earthlens\earthlens.py:1599, in EarthLens.download(self, progress_bar, aggregate, *args, **kwargs) 1486 def download( 1487 self, 1488 progress_bar: bool = True, (...) 1491 **kwargs: object, 1492 ) -> Any: 1493 """Delegate the download to the bound backend. 1494 1495 Forwards every argument verbatim to `self.datasource.download`. (...) 1597 synchronous cap). 1598 """ -> 1599 return self._dispatch_download( 1600 *args, progress_bar=progress_bar, aggregate=aggregate, **kwargs 1601 ) File C:\gdrive\algorithms\remote-sensing\earthlens\.claude\worktrees\risk-indicators\src\earthlens\earthlens.py:1656, in EarthLens._dispatch_download(self, progress_bar, aggregate, *args, **kwargs) 1654 output_kind = getattr(self.datasource, "OUTPUT_KIND", "raster") 1655 if output_kind not in {"raster", "mixed"}: -> 1656 raise NotImplementedError( 1657 f"aggregate= is not supported for " 1658 f"{type(self.datasource).__name__} backends " 1659 f"(OUTPUT_KIND={output_kind!r}). The aggregator only " 1660 f"handles gridded raster outputs; vector / tabular " 1661 f"backends emit GeoDataFrames or DataFrames that do " 1662 f"not have a meaningful gridded reduction." 1663 ) 1664 kwargs["aggregate"] = aggregate 1666 return self.datasource.download(*args, progress_bar=progress_bar, **kwargs) NotImplementedError: aggregate= is not supported for RiskIndicators backends (OUTPUT_KIND='tabular'). The aggregator only handles gridded raster outputs; vector / tabular backends emit GeoDataFrames or DataFrames that do not have a meaningful gridded reduction.
Takeaway¶
EarthLens.list_datasets("risk-indicators")andEarthLens.catalog(...)enumerate the shipped datasets and their metadata with no network.OUTPUT_KINDis per dataset: tabular ids return aDataFrame,gfw:admin_boundaryreturns aFeatureCollection.- A bad id raises with a did-you-mean hint;
aggregate=is rejected by design. See the quickstart and GFW notebook for the live calls.