Data sources & the wider-MI fit

How external data / models feed the risk framework, what new dimensions they unlock, and how it sits alongside Market Insights · 2026-07-16

The framework is source-agnostic: anything that emits a field on the grid — a pipeline, an EO product, a detection model — can become a dimension, once its output is turned into a severity curve. This doc maps what the tf_environmental_factors_preparation GEE workflow can feed in (by severity-curve role), the new dimensions it unlocks beyond weather, and — as an open review question — how the approach sits alongside MI's own yield / area models.

1. How it wires into MI — the live core + the upstream feed

The live v1 path is deliberately simple and self-contained (solid below): weather feeds plus the two libraries — twx-phenoweight (WHEN) and twx-risk-severity-library (HOW BAD) — drive the config-driven engine to gridded scores. The wider MI interaction sits upstream (dashed, blue): MI's yield / hindcast models and the EO / anomaly work do the feature-importance + calibration, and that output becomes a curve deposited into the HOW-BAD library — the engine never scores from a model directly. It's drawn dashed on purpose: this feed is the roadmap, not wired in v1 — today's curves are literature-anchored, and the MI→library loop is designed but not yet built.

ag_risk core flow and the upstream MI feed into the severity library ▨ UPSTREAM — MI infrastructure (roadmap, not wired in v1) MI models crop_yield · commodity_hindcast yield forecast + hindcast gee_prep — EO features + anomaly / stress cascade feature importance + calibration which drivers matter → curve shape driver→yield fit → anchor on the ruler (the "fun stuff" lives here, upstream) twx-phenoweight WHEN — timing twx-risk-severity-library HOW BAD — severity curves weather feeds ERA5 / SEAS5 config-driven ag_risk engine gridded risk scores (0–1)
Solid = live v1 (self-contained scoring). Dashed blue = upstream MI: feature-importance + calibration turn MI's models and EO work into curves that land in the HOW-BAD library — the engine consumes the curve, never the model. The dashed arrow is the roadmap; v1 curves are literature-anchored.

2. What the GEE workflow produces, by severity-curve role

tf_environmental_factors_preparation (the gee_prep toolkit) pulls Sentinel-1/2, MODIS, ERA5-Land, SMAP, Landsat, CHIRPS, GRIDMET and more, and emits gridded feature fields. Mapped to how each could feed a severity curve:

Factor (source)Role
LST · EDD · GDD · VPD · CDD (MODIS/VIIRS, GRIDMET, ERA5-Land)dose → damage curve heat / cold
Precip · SPI / SPEI / EDDI / PDSI · SMAP soil moisture · ESI = 1−ET/PET (CHIRPS, gridmet_drought, SMAP, OpenET/MOD16/WaPOR)dose → damage curve drought / water
VHI = 0.5·VCI + 0.5·TCI (MODIS NDVI + LST)dose + threshold → exposure fraction
Flood mask (Sentinel-1 backscatter drop − JRC permanent water)exposure fraction (new)
Burn ratio NBR / dNBR (Landsat)exposure (fire — building block, not built)
Pest/disease z-score (red-edge NDVI + LST anomaly)dose (screening-grade, low confidence)
NDVI · EVI · NDWI · LAI / FPAR · phenology (SOS/POS/EOS)consequence / validation — outcome proxy, not a driver
Soil (SoilGrids/OpenLandMap) · terrain (SRTM)susceptibility modifiers (could scale a curve), not doses
Land cover / crop mask (CDL, WorldCover, Dynamic World) · AlphaEarth embeddingsmasks / denominators / ML features — not risk doses

3. New dimensions it unlocks (beyond ag_risk's weather-only v1)

ag_risk today scores four weather dimensions (drought / heat / cold / water). The temperature/precip families here largely overlap those. The genuinely new ones:

Scope note: this GEE env-factors path (fire / flood / disease — the EO dimensions) is not part of the weather-only v1 / Model Foundry production model. It lives on a separate testbed branch for testing and expansion; the weather-only v1 shipped in Model Foundry does not depend on it.

A ready severity-engine template already exists in that repo. The Vietnam-coffee cascade (anomaly.py) already turns each layer into a robust z-anomaly, maps z → [0,1] stress, and phenology-weights it into a composite score — directly analogous to a severity curve, and a concrete pattern for turning any of the doses above into a curve.

4. Caveats — what makes a factor hard to turn into a curve

5. How MI models feed the library — three routes

The split is the whole point (and it's what the repos already do): the scoring engine stays simple downstream; the region-specific science — "how bad is this, really?" — happens upstream in MI and is deposited into the library as a finished curve. Three concrete routes, each grounded in code that exists today:

RouteWhat it producesWhere it lives (today)
a · curve shape feature importance which drivers matter + their effect sizes → the shape of a damage curve crop_yield StackedResidual (Ridge coefficients on the yield residual); commodity_hindcast PCA-ridge signed components + Cook's-distance influence
b · calibration consequence fit driver-vs-outcome relationship → anchors a curve onto the 0–1 loss ruler (and validates it) crop_yield plot_stress_vs_residual (stress vs log-detrended yield, Ridge fit); commodity_hindcast run_meta_models (bias-correct + conformal calibration against observed NASS/WASDE yield)
c · new signal EO product a new exposure fraction or a new dimension's driver field gee_prep — 29 EO/climate/soil datasets; the anomaly.py robust-z → stress → phenology-weighted cascade_score (a worked composite)

Two things to keep honest about this picture:

The design rule (from the §4 note): we do not want competing scoring frameworks. All the hard, fun, region-specific work — working out how bad a peril is, per crop and place, from models and consequence data — happens upstream and feeds the shared libraries. The engine downstream just reads them.

Sources: review of treefera-market-insights (crop_yield, commodity_hindcast), tf_environmental_factors_preparation (gee_prep + anomaly.py cascade), and the twx-risk-severity-library / ag_risk charters (EXTENDING.md, OUTPUT_CONTRACT.md, VALIDATION.md). The stress maths itself lives in tf-data-ml-utils/weather (Tommy).