The siting check on real soil#
2026-10-08. The §4.1 depth-from-temperature siting check (sdk/siting.py) had only
ever met the simulator's heat model. ISMN carries real soil temperature at five depths at
each Tennessee SCAN station, so this note runs the check against real soil — and then lies
to it, to see whether it notices.
Method#
tools/ismn_siting.py assembles a farm of real probes from one station's record, each recorded at its true depth, for one 48-hour window, and asks the check about each.
- Control. Every probe is where its record says. Anything but
consistentis either a false alarm (displaced) or the check admitting it cannot see (indeterminate). - Unlogged moves. A probe recorded at one depth is fed the readings actually taken at
another. The real probe at that other depth stays, as a second probe at that depth would
on a farm with redundancy. The check should say
displaced, and the depth it implies should be near the true one.
Only readings ISMN rates good are used. Three stations (Allen Farms, Eastview Farm, McAllister Farm), 2003–2026, weekly windows — about 10,000 in all.
What the real soil gives the check to read#
A real station is one profile with one probe per depth. Only the top three depths carry a daily temperature wave strong enough to read:
| depth | daily amplitude |
|---|---|
| 5 cm | ±1.4 °C |
| 10 cm | ±0.9 °C |
| 20 cm | ±0.45 °C |
| 51 cm | ±0.06 °C |
| 1.02 m | ±0.01 °C |
So every shallow probe has exactly two usable peers. The check first required three —
which the simulated farm's twelve probes always met — and on real soil it said "cannot
tell" 73–100% of the time. Two peers at two depths is the minimum that fixes the line, so
the check now accepts two, widens its tolerance to 12 cm (two points give no scatter to set
it from, and cannot outvote a displaced peer), and marks the finding robust: false.
The real wave is also about four times weaker than the simulator's, whose bare-soil solar gain is generous for vegetated ground. Simulator results on this check overstate it.
Control: probes where their record says#
| season | depth | consistent | displaced | cannot tell | median depth error |
|---|---|---|---|---|---|
| winter | 5 cm | 73% | 6% | 21% | 2.7 cm |
| winter | 10 cm | 80% | 3% | 17% | 1.7 cm |
| winter | 20 cm | 74% | 3% | 23% | 4.0 cm |
| spring | 5 cm | 93% | 3% | 4% | 2.5 cm |
| spring | 10 cm | 96% | 2% | 2% | 1.6 cm |
| spring | 20 cm | 91% | 4% | 6% | 3.5 cm |
| summer | 5 cm | 92% | 3% | 4% | 2.3 cm |
| summer | 10 cm | 97% | 2% | 1% | 1.6 cm |
| summer | 20 cm | 92% | 2% | 6% | 3.1 cm |
| autumn | 5 cm | 86% | 3% | 11% | 2.5 cm |
| autumn | 10 cm | 93% | 2% | 5% | 1.6 cm |
| autumn | 20 cm | 85% | 2% | 13% | 3.6 cm |
At 51 cm and 1 m the check says "cannot tell" 87–98% of the time, which is correct: there is no wave there to read.
The depth estimate works — 1.6 to 4 cm median error in the root zone. The false
alarms do not pass: 2–4% per window, 6% at 5 cm in winter. Assessed once a day, that is
roughly one false displaced per probe per month.
Unlogged moves#
| move | recorded → really | caught (displaced) |
median implied depth |
|---|---|---|---|
| lifted 15 cm | 20 → 5 cm | 86% winter, 92–96% otherwise | 5 cm |
| lifted 10 cm | 20 → 10 cm | 4–7% | 10 cm |
| pushed 10 cm | 10 → 20 cm | 3–11% | 20 cm |
| lifted 5 cm | 10 → 5 cm | 0% | 5 cm |
| pushed 31 cm | 20 → 51 cm | 4–13%; otherwise "cannot tell" | 51 cm |
The median implied depth is exactly right for every move. What fails to catch the 10 cm moves is the decision, not the estimate: 10 cm is under the 12 cm two-peer tolerance, so the check knows where the probe is and declines to call it. A move to 51 cm goes where the wave is too weak to read, and the check correctly says it cannot tell.
A week, not a window#
One window at a time, a correctly placed probe is called displaced often enough to
matter. A real move is permanent and shows on every day after it; a bad window rarely
repeats. So the check was run every day at all three stations — about 22,000 daily
windows per scenario — and scored under rules that require several of the last few days
to agree. Counted as episodes, runs of consecutive alarmed days, because that is what a
farmer is told about.
On profiles with no move — 169 probe-years, leaving out the McAllister period in the next section:
| rule | false episodes per probe-year | 5 cm | 10 cm | 20 cm | 15 cm lift caught |
|---|---|---|---|---|---|
| one window | 3.87 | 5.94 | 1.49 | 4.17 | 100% |
| 2 of last 3 days | 0.76 | 1.28 | 0.20 | 0.82 | 100% |
| 3 of last 5 days | 0.29 | 0.59 | 0.00 | 0.28 | 100% |
| 4 of last 7 days | 0.15 | 0.37 | 0.00 | 0.09 | 100% |
| 5 of last 7 days | 0.04 | 0.09 | 0.00 | 0.02 | 100% |
"Caught" is the share of days on which the check could decide. Five of the last seven takes false alarms from about four a year per probe to one in 25 probe-years, and still catches a 15 cm lift on every day it can see one. It costs about a week — from any start date, a 15 cm move is called after a median of 8 days, and always within 8 weeks — which siting can afford: a probe at the wrong depth misleads slowly, and the finding flags every reading from the first displaced day, not just the last two.
Adopted as siting.assess_siting_persistent, the function to act on. It returns
displaced only when five of the last seven daily assessments are, and widens the flagged
span to cover all of them. When today's window alone says displaced, it returns
indeterminate with the reason siting.unconfirmed ("displaced in 2 of the last 7 days")
rather than a quiet consistent.
What persistence does not buy is resolution. Two ways to use a week of windows to call smaller moves were tried and rejected:
- The median implied depth over 7 or 14 days, against a tighter tolerance. At 5 or 6 cm it would catch a 10 cm move, but correctly recorded probes then alarm one to three times a year, because some implied depths sit 3–6 cm from the record for a decade. At Allen Farms before 2023 the 5 cm probe read as −1 cm and the 20 cm as 15 cm, year after year. The geometry in the next section traces both to the 10 cm probe sitting about 3 cm deeper than recorded — an installation error nobody would notice, amplified by extrapolation. That is a bias, and averaging does not remove a bias.
- Change from the probe's own baseline — the last 14 days against the half-year before. The implied depth also wanders with the season, as water content changes the soil's diffusivity: 0.3–1.7 false episodes per probe-year at 3–6 cm.
For a two-peer profile the practical floor is a little over 10 cm, set by how precisely probes are really installed — and amplified by extrapolation — rather than by noise.
The check found a real one#
All of McAllister Farm's long "false alarm" episodes fall after January 2023, on the 20 cm probe. Through 2012–2021 the check implied 0.15–0.16 m for it; from 2023, 0.25–0.30 m. The cause turned out not to be the 20 cm probe.
The 10 cm temperature record has a gap from 2021-07-23 to 2023-01-15, and ISMN's metadata logs a new sensor at that position on 2023-01-17, recorded at the same depth, 10.16 cm. Suppose that probe alone changed, and the 5 and 20 cm probes are where their records say. Then each probe's implied depth is fixed by geometry — each is read against the line through the other two. With the 10 cm probe really at 12.0 cm before the gap and 7.9 cm after (the depths the check itself implied for it, from the 5 and 20 cm line), the check's yearly medians for 2012–2021 and 2023–2026 are reproduced:
| the probe recorded at | before 2023: predicted | observed | from 2023: predicted | observed |
|---|---|---|---|---|
| 5 cm | 1.3 cm | 0–2 cm | 7.6 cm | 7–8 cm |
| 10 cm | 12.0 cm | 12 cm | 7.9 cm | 8 cm |
| 20 cm | 15.7 cm | 15–16 cm | 31 cm | 25–30 cm |
The last cell is an extrapolation, and sensitive: each millimetre of the 10 cm probe's depth moves it by about a centimetre.
The amplitude, an independent reading of depth, says the same. Placed by its daily swing against the 20 and 51 cm probes, whose swings did not change, the 10 cm probe sat at 11.5–11.9 cm every summer 2015–2020 and 7.0–8.2 cm every summer 2023–2026.
So the replacement 10 cm probe has read, since the day it went in, like one about 4 cm shallower than the probe before it. The simplest explanation is that it was installed shallower. Disturbed soil around a new installation could contribute, though it would be expected to damp the wave rather than strengthen it. ISMN rates every one of these readings good, and nothing in the record says the depth changed.
The check noticed — and blamed the wrong probe. The 10 cm probe's own offset, 2 cm
from its record, is within tolerance. But the 20 cm probe is judged by extrapolating a
line through the 5 and 10 cm probes, and that line now spanned 3 cm of real depth where the
record said 5. A 4 cm change in a peer became a 10–15 cm change in the probe extrapolated
from it. With two peers there is nothing to outvote, which is what the finding's
robust: false was written to say: something in this profile moved. Under 5 of 7 the
profile first alarmed on 2023-04-08, once spring brought the wave back, and on 8% of days
after. Which probe moved, and how to tell, is now
open question Q25, and largely answered in the next section.
The same arithmetic explains the bias before the gap: a 10 cm probe actually at 12 cm is why McAllister's 5 cm probe read as 0–2 cm for a decade.
Allen Farms shows the same thing, below the threshold. Its 10 cm probe also went silent in late July 2021 and was also replaced in January 2023 — the same week as McAllister's, one field visit by the look of it. The same geometry says it went from about 13 cm to about 11 cm, nearer its record, and every implied depth in the profile moved as that predicts:
| the probe recorded at | before 2023: predicted | observed | from 2023: predicted | observed |
|---|---|---|---|---|
| 5 cm | −1.4 cm | −3 to 2 cm | 3.3 cm | 3–6 cm |
| 10 cm | 13 cm | 12–14 cm | 11 cm | 10–11 cm |
| 20 cm | 14.4 cm | 14–16 cm | 17.5 cm | 18–22 cm |
A 2 cm change stays within tolerance, and nothing alarmed. Eastview Farm, where nothing was replaced in 2023, is the control: its three probes imply 3–6, 9–11 and 18–22 cm in every year from 2003 to 2026. (Amplitude placement is too noisy to use at Allen Farms, whose 51 cm swing is 0.04 °C.)
Both replacements went in at a different depth from the probe before. A replacement is exactly when a depth error is most likely, and the record at both stations kept the old depth.
A deeper peer, over two weeks#
The fix for a two-peer profile turned out to be already in the ground. Over two days only 5, 10 and 20 cm carry a wave above the check's 0.10 °C floor. Over fourteen days a fit resolves a far smaller one, and the 51 cm probe every one of these stations has — its swing 0.04–0.10 °C — becomes a third peer. Three peers make the fit robust, so one displaced peer is outvoted instead of blamed on its neighbour, and the tolerance tightens from 12 cm to 8.
Adopted as siting.assess_siting_weekly: two-week windows, once a week, displaced
on 3 of the last 4. A peer needs a swing of 0.03 °C; the probe being judged still needs
0.10. Measured through the SDK, on profiles with no known disturbance:
| schedule | false episodes per probe-year | 15 cm move called | 10 cm move called within six months |
|---|---|---|---|
| daily, 5 of 7 | 0.04 | median 8 days; always within 8 weeks | 7–8% |
| weekly, 3 of 4 | 0.04 | median 5 weeks; always within 8 weeks | 78–83%, median 5–9 weeks |
Counting Allen Farms after its 2023 visit as undisturbed, the weekly figure is 0.07 — see below. The two are complements: the daily check catches a big move in a week, the weekly one catches a 10 cm move the daily one almost never does, and attributes it.
McAllister Farm, through the SDK. The 20 cm probe's implied depth, by year:
| 2015 | 2016 | 2017 | 2018 | 2019 | 2020 | 2021 | 2023 | 2024 | 2025 | 2026 | |
|---|---|---|---|---|---|---|---|---|---|---|---|
| daily, two peers | 16 | 16 | 16 | 16 | 16 | 17 | 16 | 29 | 24 | 25 | 28 cm |
| weekly, three peers | 21 | 21 | 21 | 21 | 20 | 20 | 20 | 20 | 20 | 20 | 20 cm |
Daily, the 20 cm probe was called displaced in 26% of windows after 2023; weekly, in 1%. The 10 cm probe, weekly, reads 12–13 cm through 2021 and 8 cm from 2023 — the change now sits on the probe that changed, at a size, 2 cm from its record, below what either schedule calls.
Allen Farms may have a second disturbance. Weekly, its 20 cm probe reads 20–23 cm through 2021 and 26–27 cm from 2023, and is called displaced in 28% of windows after the visit. Its sensor was not replaced. The daily figures fit "both the 10 cm probe (13 → 11 cm) and the 20 cm probe (20 → about 25 cm) changed at the 2023 visit" better than the 10 cm probe alone, which predicted 17.5 cm for the 20 cm probe where 18–23 was observed. Digging to reach one probe can disturb its neighbour. That is a hypothesis, not a finding.
Naming the culprit is harder than not blaming the wrong one. With four probes, the probe whose omission lets the other three line up best is the obvious candidate. On constructed moves it is right 78–100% of the time for 10 cm or more, and 57–62% for 5 cm. It cannot resolve the real 2–4 cm shifts. And with nothing moved, it still names someone — at Eastview usually the 51 cm probe, which sits in a different soil horizon from the others — so it may only speak when the profile as a whole fails to line up.
Phase and amplitude together do not help, by the physics. In uniform soil the log of the daily swing and the lag of its peak are both straight lines in depth with the same damping depth, so they are two noisy readings of one number per probe: any single-culprit explanation still fits exactly. Measured, amplitude named the culprit about as often as phase. What the pair does catch is a clock offset, which moves the phase and not the swing.
Caveats#
- One region, one sensor make. Three Tennessee stations, Stevens Hydraprobes, humid subtropical climate. Snow cover and long overcast spells weaken the wave further north.
- One profile per station. Over two days a real station has two usable peers per probe; over two weeks, three. A farm with more probes per profile gets the robust fit even daily.
- The moves are constructed. Real moves happen once, not in every window; what is measured is how often a window would notice one already made. The one real event, McAllister's 10 cm replacement, is inferred from the readings: no record says where either probe was actually placed.
Attribution#
ISMN data is used under CC-BY-4.0; this note publishes only derived statistics. See ismn-scoring.md for the citations. The SCAN stations are operated by the USDA Natural Resources Conservation Service.
Reproducing#
cd /tmp
python3 -I ~/dev/fieldmesh/tools/ismn_siting.py ~/Downloads/ISMN_archive_20261008.zip \
--stations AllenFarms,EastviewFarm,McAllisterFarm # weekly windows
python3 -I ~/dev/fieldmesh/tools/ismn_siting.py ~/Downloads/ISMN_archive_20261008.zip \
--persistence --exclude McAllisterFarm:2023-01-17 # daily, k-of-n
python3 -I ~/dev/fieldmesh/tools/ismn_siting.py ~/Downloads/ISMN_archive_20261008.zip \
--persistence --weekly \
--exclude McAllisterFarm:2023-01-17,AllenFarms:2023-01-20 # weekly, k-of-n
Run from a neutral directory with -I, because the archive is downloaded data. Each
persistence run takes about twelve minutes a station. The culprit-naming measurement was
a scratch analysis on the same windows and is not in the tool.