This page is generated from the live data files, not written by hand. Regenerated 2026-09-18. If the model changes and this page is not rebuilt, the build gate fails. It cannot describe a system we are not running.
The short version
We measure how much a crop has grown this season from satellite greenness, sunlight and temperature, and compare it against the same measurement for the eleven seasons before it. That comparison is the index. We then scale the index back to the part of its movement that survived being tested against every harvest USDA has published here — which for dry beans in Nebraska and Colorado is none of it. We publish the scaled figure, the raw figure, and the scaling, so you can see exactly what we took out.
What we do not have
This is remote data. We have no buried probes, no tensiometers or Watermark sensors, no hand-probe checks, and no irrigation-flow records. Commercial growers here use all four, and those are what actually measure a root zone. Nothing on this site measures soil moisture. Where we publish a water figure it is an estimated water-stress proxy and it is labelled that way in the data itself.
Step 1 — where the crop is
USDA's Cropland Data Layer gives the ground each class is grown on. We reduce it to 1969 bean cells with acreages, and every regional figure is weighted by those acres, not averaged flat.
python3 scripts/build_crop_footprint.py
Step 2 — how much it has grown
Daily, from planting to maturity, for every season since 2015:
biomass += RUE × solar × 0.48 × fAPAR(greenness) × temperature term
- solar — NASA POWER daily shortwave at the acre-weighted centre of the crop.
- 0.48 — the share of shortwave that is photosynthetically active. Standard.
- fAPAR — the fraction of that light the canopy intercepts, from satellite greenness (Myneni & Williams 1994). Readings land every ten days and are interpolated between, not held flat.
- temperature term — growth slows away from the crop's optimum. Heat above the flowering threshold is counted and reported, not subtracted, because tested against ten years of harvests on this ground it predicted nothing.
- planting — derived from soil-temperature threshold and observed green-up, per class, not assumed.
- maturity — growing degree days, base 50°F for beans and 41°F for pulses, against commercial-variety requirements.
A finished past season is truncated to the day of the year this season has actually reached. Without that, every class in every region reads below normal in September, which is an artefact and not a crop.
Step 3 — the index
raw index = biomass(this season) ÷ mean biomass(2015–2025)
Dividing by the model's own history is deliberate: the constants we cannot source sit on both sides of that division and largely cancel. This is why we publish an index rather than a bushel figure derived from first principles.
Step 4 — scaling it back to what the record supports
The raw index moves far harder than reality. We measured how much harder, against every year USDA has published a yield for these classes in these states, refitting with each year held out and scoring the year that was held out.
| State | Class | Years | Correlation with real yield | Scale we publish | Skill when held out |
|---|---|---|---|---|---|
| CO | Light Red Kidney | 8 | -0.25 | 0.0 | 0.0 |
| CO | Pinto | 10 | -0.351 | 0.0 | 0.0 |
| NE | Great Northern | 10 | -0.679 | 0.0 | 0.0 |
| NE | Light Red Kidney | 9 | -0.341 | 0.0 | 0.0 |
| NE | Peas | 10 | 0.588 | 1.02 | 12.2 |
| NE | Pinto | 10 | -0.445 | 0.0 | 0.0 |
| WY | Pinto | 8 | 0.38 | 0.139 | -12.9 |
Read that table before you read anything else on this site. A scale of 0 means the model, tested properly, could not call that crop in that state, so we publish a normal year and show you the raw figure beside it. Peas are the one crop whose swing survived intact. Negative correlations are not flipped and used: we tested that too, and the inversion did not hold out of sample.
published index = 1 + scale × (raw index − 1)
python3 scripts/backtest.py · python3 scripts/backtest.py --write-calibration gwet · python3 scripts/backtest.py --inverted
The scaling is fitted on 2015-2025 and applied to 2026, which is not among them. The bar every variant must clear is not zero error — it is the naive forecast, "this year will yield what the other years averaged", scored on the same years.
Step 5 — pounds per acre
The index is multiplied by what USDA says that class actually yielded in that state, averaged over the published years. Where USDA publishes no yield for a class in a state — chickpeas in all three states, for example — we publish no pounds per acre. We do not invent a level.
Water: what we do, and what we refuse to call it
Three water terms were built and tested. All three are reported. None is allowed to move a yield.
- Inferred balance — rainfall minus Hargreaves reference evapotranspiration, FAO-56 crop coefficient curve, root zone opened by the winter's recharge. Tested: made the forecast worse in all seven crop-and-state combinations.
- Estimated water-stress proxy from a land-surface model — NASA POWER root-zone soil wetness (MERRA-2/GEOS assimilation), converted to plant-available millimetres using the measured soil capacity below. Checked against the USDA in-ground probe at Torrington, fifteen kilometres from Wyoming bean ground, which has recorded at five depths since 1997: the two agree across 3,801 days at r = +0.62, and both put summer 2026 as the driest root zone in the eleven-year record. Tested as a yield term: still short of guesswork. Published as an observation.
- Winter recharge — October to March precipitation against each region's own previous thirty winters. An observation of cause, never a predictor.
The proxy is damped by the irrigated share of the ground, from USGS MIrAD-US, in the open rather than as a hidden floor. That file states plainly that its share is the share of ground that is irrigated, not the share of this crop that is watered, and treating one as the other is an assumption we make and record.
| Region | Water-stress proxy (1.00 = no estimated shortage) | Root-zone available water, mm | Winter that fed it |
|---|---|---|---|
| Big Horn Basin | 0.856 | 87.6 | 88% of normal |
| Northeast Colorado | 0.751 | 75.5 | 43% of normal |
| Nebraska Panhandle | 0.725 | 99.0 | 44% of normal |
| Northwest Kansas | 0.741 | 117.9 | 62% of normal |
| Southeast Wyoming | 0.727 | 85.8 | 53% of normal |
| Southwest Nebraska | 0.705 | 61.3 | 39% of normal |
| Western Colorado | 0.851 | 89.7 | 86% of normal |
How accurate is the remote water figure, and does that accuracy travel?
Neither question can be answered by looking at the satellite. It has to be scored against something buried in the ground. The United States has 181 soil-moisture stations that have been running since 2015, from Alabama clay to Nevada desert, and the remote figure was scored against every one of them: median correlation +0.57 across 41 states.
Then the harder question, which matters for every country that has no such stations. Each station was held out — the correction fitted on the others, then used to predict the station it had never seen. Error in percentage points of volumetric water content, lower is better:
| Method | Error at a station it never saw | Better than assuming local average |
|---|---|---|
| Assume the local average — no satellite at all | 13.778 | — |
| The remote figure, one fixed scaling, no fitting | 9.572 | +30% |
| One correction fitted on every other station | 10.356 | +25% |
| A correction predicted from this place's climate and terrain | 9.878 | +28% |
| A probe buried in that ground (not available abroad) | 4.065 | +70% |
The clever method lost. Predicting a local correction from a place's own climate and terrain beat the alternatives — until stations within 500 km of the held-out one were barred from voting. They had been neighbours, not evidence. With real separation, the simplest method wins: the raw remote figure with one fixed scaling and no fitting anywhere.
So for ground with no instruments, that is what we carry, and we quote ±9.57 percentage points of volumetric water content with it. A probe actually buried in that ground gives 4.06 — less than half the error. That gap is the honest measure of what remote sensing cannot do, and it is the reason a grower's own reading is worth more to this model than any satellite.
python3 scripts/refresh/remote_soil_calibration.py · python3 scripts/remote_soil_transfer.py --min-km 500
Two independent readings of the water, every day
Every region here carries both remote products, side by side, on every run: a land-surface model and the SMAP satellite. Neither is chosen over the other. Each is compared against its own eleven-year average for the same stretch of the calendar, so the units cancel and the two are directly comparable — and so the method carries unchanged to any country with eleven years of its own.
The gap between them is the useful part. Two independent instruments agreeing is worth more than either alone. Where they part company, the water reading there is uncertain and we say so on the page rather than averaging the disagreement away. That is the judgement a region with no probes in the ground cannot make for itself.
| Region | Land-surface model vs its own normal | SMAP satellite vs its own normal | Gap | Read as |
|---|---|---|---|---|
| Big Horn Basin | -15.0% | -16.1% | 1.1 | Both agree |
| Northeast Colorado | -9.3% | -7.0% | 2.3 | Both agree |
| Nebraska Panhandle | -15.6% | -12.6% | 3.0 | Both agree |
| Northwest Kansas | -4.3% | -8.3% | 4.0 | Both agree |
| Southeast Wyoming | -12.3% | -16.4% | 4.1 | Both agree |
| Southwest Nebraska | -6.3% | -1.2% | 5.1 | Broadly agree |
| Western Colorado | -4.8% | -1.7% | 3.1 | Both agree |
Is the actual satellite better than the model we use?
The water figure here comes from a land-surface model. SMAP is the NASA satellite that measures soil wetness directly. The obvious assumption is that the satellite wins. We scored both against the same 181 buried probes, the same days, the same arithmetic.
SMAP is better at 125 of 181 stations — a real result, not chance. The median improvement is 0.09 of a percentage point of water content. That is statistically certain and agronomically nothing. And at Torrington, on the Wyoming bean ground this site actually covers, the model we already use is the better of the two.
So we did not switch. SMAP is collected, scored and published here so the comparison can be checked, and if it pulls ahead the decision reverses on evidence rather than on which name sounds more impressive. It is also worth recording that SMAP needed no NASA account: USDA's Foreign Agricultural Service republishes it openly, worldwide, daily, back to April 2015.
python3 scripts/refresh/smap_probe_scores.py · python3 scripts/remote_soil_transfer.py --source smap --min-km 500
Soil and slope
Until 17 September 2026 every water calculation used one root-zone capacity of 120 mm for all seven regions, and that number was invented. These are the measured capacities, sampled at the centre of every bean cell from the USDA soil survey and aggregated on bean acres. A field that holds 61 mm reaches stress in half the time of one that holds 118 mm, and the model could not see that at all.
| Region | Most common soil under the beans | Available water, root zone, mm | Mean slope, % | Cells sampled |
|---|---|---|---|---|
| Big Horn Basin | Garland-Emblem complex, 0 to 3 percent slopes -- Draft | 87.6 | 3.9 | 155 |
| Northeast Colorado | Haxtun loamy sand, 0 to 3 percent slopes | 75.5 | 2.8 | 231 |
| Nebraska Panhandle | Mitchell silt loam, 0 to 1 percent slopes | 99.0 | 3.5 | 704 |
| Northwest Kansas | Keith silt loam, 0 to 1 percent slopes | 117.9 | 1.3 | 76 |
| Southeast Wyoming | Dacono-Albinas complex, 1 to 3 percent slopes | 85.8 | 4.3 | 200 |
| Southwest Nebraska | Valent sand, 3 to 9 percent slopes | 61.3 | 7.0 | 383 |
| Western Colorado | Mesa clay loam, 0 to 2 percent slopes | 89.7 | 7.1 | 189 |
Root zone taken as 60 cm, the middle of the 0.5–0.7 m effective rooting depth FAO-56 Table 22 gives for green and dry beans. Slope and drainage class are collected and published; slope is not yet in the arithmetic, because putting it there means choosing a runoff coefficient and we have not sourced one. Saying so is better than a number nobody can check.
python3 scripts/refresh/soils.py
Constants we could not source
Listed in UNSOURCED.md in the repository, and a build gate fails if a constant in the model is not either cited or listed there. At the time this page was generated the list includes the 0.30 winter recharge efficiency, the 0.55 wetness threshold at which stress is taken to begin, and the mapping of a saturation fraction onto a soil-water depletion fraction.
Every gate that must pass before anything is published
bash scripts/verify_all.sh
Rendered-page checks, a data check of every dataset against a source that did not produce it, a replication check that every published number recomputes from the figures printed beside it, a truth firewall, and a regression file that re-tests every defect that was ever live here. A syntax check is not a test.
What we know is wrong with this
The model has no demonstrated skill for dry beans on this ground, which is why its swing is scaled to zero there. Weather features were tested against yield at state level and again at county level with twenty times the data, and failed both. A remote water term cannot see a centre pivot. The satellite sees a canopy, and a canopy is not a seed. Read what we have gotten wrong before you decide how much of this to trust.