ag_risk — one command, two roles. Prereqs, env, run modes, outputs, offline testing · 2026-07-16
(region, commodity):
ag-risk run score --config <region>_<commodity> --role realised|forecast.
The role is the only real switch — it selects the feed (ERA5 vs SEAS5) and the
output store (realised vs forecast). Same engine, same curves, same phenoweight either way.
model-foundry
(model_foundry/models/ag_risk/) and runs inside the uv workspace. It exposes both the
ag-risk CLI and the AgRiskModel Python API
(from_config / score / render / validate), and gets
phenoweight + twx-risk-severity-library as deps — severity-lib is floored at >=0.1.0, though [tool.uv.sources] still git-pins both to main (the CodeArtifact repoint is pending).
ag-risk CLI (the ag_risk package installed in the repo venv).precip, edd, aet, pet, soil_moisture_l1–3, hot_night_min, frost, …) on (time, latitude, longitude). ERA5 for realised, SEAS5 for forecast.| Var | Required | What |
|---|---|---|
INPUT_DATA_DIR | yes | root all local paths anchor under (fails loud if unset) |
CROP_CALENDAR_NC | yes | the GGCMI planting-DOY NetCDF |
AG_RISK_INDICES_ZARR | feed fallback | the indices zarr, if not set via feeds.<role>.indices_uri in the config (used offline / legacy) |
AWS_DEFAULT_REGION | for S3 | us-east-2 when feeds are on S3 |
AG_RISK_AOI_GEOMETRY / AG_RISK_CROP_MASK | optional | AOI clip / crop-pixel mask, if not in the config |
SEVERITY_LIBRARY_DIR | optional | optional — point at an external severity-curve dir; default is the CodeArtifact-published twx-risk-severity-library catalogue (shipped in the wheel) |
The P0 gate — checks the config + severity-library wiring (every referenced curve resolves) and exits:
INPUT_DATA_DIR=<dir> ag-risk run score --config kenya_maize --dry-run
Scores the just-elapsed season on actuals and writes the realised store:
INPUT_DATA_DIR=<dir> AWS_DEFAULT_REGION=us-east-2 \ AG_RISK_INDICES_ZARR=<era5_indices.zarr> \ CROP_CALENDAR_NC=<mai_rf_ggcmi_…_v1.01.nc4> \ ag-risk run score --config kenya_maize --role realised --run-date 2024-08-01 # → runs/<stamp>/archive/realised_risk_kenya_maize.zarr
Same engine, forecast feed + store. Needs a feeds.forecast block in the config (points at the SEAS5 indices):
ag-risk run score --config kenya_maize --role forecast --run-date 2025-01-01 # → runs/<stamp>/archive/forecast_risk_kenya_maize.zarr
Only kenya_maize ships today (TZ/ZM configs to come). --config takes a stem (resolved under configs/) or a path.
ag-risk run all ECS entrypoint; see
the downstream-integration doc for the two-append lifecycle and the store format.
A run writes an on-disk run directory (<data_root>/runs/<stamp>/, local or s3://) containing archive/<role>_risk_<region>_<commodity>.zarr plus map panels. The two zarr stores are the contract output (realised: valid_time; forecast: init_time × horizon vintages). Re-render maps from a saved run without re-scoring:
ag-risk render --run-dir <run_dir> --month 2024-06
Point the feed at a small synthetic indices zarr in the pipeline's shape — variable names on (time, latitude, longitude) — and run --role realised:
# write a synthetic feed, then: AG_RISK_INDICES_ZARR=synthetic_kenya.zarr ag-risk run score --config kenya_maize --role realised --run-date 2024-08-01
This exercises the same weather connector production uses, so an offline run is representative. Make it a pytest fixture for CI.
cd model_foundry/models/ag_risk && uv run pytest
| Command | Does |
|---|---|
ag-risk run score | read → dose → severity → compose → render one season's gridded risk zarr |
ag-risk run all | score + downstream stages — the ECS / model-runner entrypoint |
ag-risk render --run-dir … | re-render map panels from a saved run (no re-score) |
Key flags: --config <stem|path>, --role realised|forecast,
--run-date YYYY-MM-DD, --dose-mode phenoweight (default: the config's),
--dry-run, --write-run-dir-to <file> (hand the run_dir to an orchestrator).
Source: model-foundry: model_foundry/models/ag_risk/ — cli.py · README.md · MODEL_CARD.md.