The peak-search-and-gate pipeline had reached the point where each field
test added another veto, and vetoes only subtract sensitivity: ~28 tuned
constants and 6 boolean gates. Measured on the real uranium capture, it
was correct at 300s and 600s, wrong at 900s and 1200s, correct again at
1800s - more data made it worse.
Identification is now a Poisson maximum-likelihood fit of the whole
spectrum against per-nuclide response templates. Nuclides compete through
the likelihood, so the competitive-assignment, share-margin and
better-explained-elsewhere tie-breakers are gone, along with ~20 of the
constants. Detection is one threshold that means the same thing for every
nuclide: 3 sigma on a fitted amplitude.
Four things this needed, each found by measurement:
- 16 broad continuum bumps, not 4 exponentials. chi2 62 -> 3.3, and
stopped nuclide templates being recruited as continuum filler.
- Full Fisher covariance, not the diagonal, which claimed Co-60 12.8
sigma on background containing none.
- Chain-coupled columns at secular equilibrium. Six free U-238
amplitudes let Tl-208 eat Bi-214's 609 keV line - the NATURAL MIX bug.
- FIT_MIN_KEV 150: the X-ray region is unmodelled, and Ba-133 scored 70%
on real ore largely on its 81 keV line.
Also:
- spectrum_window: analysis runs on counts since a baseline that rolls
forward on a confirmed rate step, so a source presented to a long
accumulation is seen without pressing RESET.
- PSRAM was never actually enabled. BOARD_HAS_PSRAM alone does nothing;
memory_type selects the sdkconfig. getPsramSize() was 0, the template
matrix could not allocate, and analyzeSpectrum() silently fell back to
the old path while looking perfectly healthy on serial.
- The fit no longer runs inside DataGuard. Holding the mutex for the
1-3s fit blocked every draw and touch on core 1.
- BACKGROUND is no longer claimed after 120s. This ore needs ~600s, so
the device announced "background" with a real source in front of it.
- quality.weakestKeySigma held the strongest sigma while labelled
weakest, so grade, progress and "measurement complete" were all wrong.
- Chain members are listed as evidence (Pb-212/Tl-208/Ac-228) instead of
one representative.
- DataGuard added to the UI screens that read g_data on core 1.
host/ is an offline replay harness that compiles the real analysis
sources against shims and replays captured spectra, with sweep and
presentation modes. host/spectra/ holds three real captures.
Verified on hardware: uranium ore identified at 5.0 sigma and held;
thorium mantle correct; WiFi/BLE coexistence measured across a full OTA
check with the fit resident.
Known: Eu-152 reads ~5.4 sigma on the ore - genuine template degeneracy
with Pb-214, not a threshold problem. Am-241 is no longer identifiable
below the fit range.