prop/docs/algo-reports/2026-05-24-full-recalibration.md
Graham McIntire daafa5a02a
perf(algo): unify recalibration into single Python pipeline with JSON output
Replace the two-script Python pipeline (analysis report + Elixir-source
emitter) with a single `scripts/recalibrate.py` that fits per-band
weights from PSKR spot density (VHF/UHF) and contacts↔HRRR correlations
(microwave), writing `priv/algo/band_weights.json` as a machine-readable
artifact. A new Elixir BandWeights module loads this JSON once via
`:persistent_term` cache; BandConfig.weights/1 consults it before falling
back to in-source overrides or global defaults. The script never touches
Elixir source — recalibration is now `python3 scripts/recalibrate.py`
followed by an app restart.
2026-05-25 14:45:55 -05:00

4.1 KiB
Raw Permalink Blame History

Full Recalibration Report — 2026-05-24

Auto-generated by scripts/recalibrate.py. The companion JSON file at priv/algo/band_weights.json is the machine-readable output that Elixir loads at runtime. This report is the human-readable audit trail.

Connection: postgres://prop:***@10.0.15.30:5432/prop Generated: 2026-05-24T18:53:32+00:00

Data sources

  • PSKR (VHF/UHF, label = spot_count): bands [50, 144, 432, 1296, 2304, 10000], 386,782 samples
  • Contacts ↔ HRRR (microwave, label = distance_km): 12 bands, 81,571 matched contacts

Per-band evidence

Band Source n label avg ρ_tc ρ_dpc ρ_pr ρ_pwat ρ_grad
50 MHz pskr 372,468 1.80 -0.013 +0.014 +0.025 +0.023 +0.000
144 MHz pskr 12,927 4.41 +0.184 +0.223 +0.163 +0.209 -0.073
222 MHz contacts 7,518 229.14 -0.081 +0.077 -0.014 +0.068 +0.039
432 MHz pskr 975 1.54 +0.260 -0.047 +0.085 -0.052 +0.141
902 MHz contacts 1,754 172.14 -0.070 +0.097 +0.080 +0.051 -0.038
1296 MHz contacts 2,951 160.95 -0.041 +0.102 +0.025 +0.053 -0.080
2304 MHz contacts 719 154.51 -0.060 +0.162 +0.076 +0.130 -0.114
3400 MHz contacts 335 153.71 -0.062 +0.155 -0.027 +0.150 +0.063
5760 MHz contacts 321 127.55 -0.065 +0.075 +0.153 +0.099 -0.012
10000 MHz contacts 54,161 209.29 -0.004 -0.021 -0.085 -0.029 +0.030
24000 MHz contacts 3,808 95.19 -0.210 -0.334 -0.217 -0.360 +0.018
47000 MHz contacts 759 62.72 -0.114 -0.216 -0.253 -0.233 -0.023
75000 MHz contacts 109 47.53 -0.680 -0.699 -0.768 -0.620 +0.434
122000 MHz contacts 63 16.26 +0.039 -0.129 -0.041 -0.127 +0.355

Derived per-band weights

Band n source humidity time_of_day td_depression refractivity sky season wind rain pwat pressure
50 MHz 372,468 pskr 0.1352 0.0271 0.1415 0.0736 0.0999 0.2156 0.0999 0.0170 0.1263 0.0639
144 MHz 12,927 pskr 0.1862 0.0196 0.1491 0.1118 0.0621 0.1172 0.0621 0.0106 0.1693 0.1121
222 MHz 7,518 contacts 0.2012 0.0272 0.1806 0.0986 0.0752 0.1318 0.0752 0.0128 0.1541 0.0432
432 MHz 975 pskr 0.1472 0.0261 0.1735 0.1694 0.0722 0.1169 0.0722 0.0123 0.1272 0.0830
902 MHz 1,754 contacts 0.2206 0.0299 0.1765 0.0955 0.0735 0.1090 0.0735 0.0125 0.1279 0.0810
1296 MHz 2,951 contacts 0.2255 0.0339 0.1519 0.1433 0.0751 0.1013 0.0751 0.0128 0.1334 0.0476
2304 MHz 719 contacts 0.1890 0.0285 0.1512 0.1477 0.0630 0.0849 0.0630 0.0339 0.1718 0.0672
3400 MHz 335 contacts 0.2000 0.0301 0.1601 0.1107 0.0666 0.0899 0.0666 0.0507 0.1818 0.0434
5760 MHz 321 contacts 0.1719 0.0297 0.1577 0.0599 0.0656 0.0885 0.0656 0.0790 0.1689 0.1133
10000 MHz 54,161 contacts 0.1262 0.0380 0.1010 0.0986 0.0841 0.1134 0.0841 0.1431 0.1147 0.0967
24000 MHz 3,808 contacts 0.1485 0.0403 0.1189 0.0498 0.0495 0.0734 0.0495 0.2228 0.1350 0.1123
47000 MHz 759 contacts 0.1406 0.0529 0.1125 0.0500 0.0468 0.0758 0.0468 0.2391 0.1278 0.1077

Changes vs prior band_weights.json

No prior file, or no factor moved by ≥0.005. First-run values can be compared to the in-tree @band_configs weights in lib/microwaveprop/propagation/band_config.ex.

Applying these weights

This script writes priv/algo/band_weights.json and stops there — it never edits band_config.ex. To make the weights live, BandConfig.weights(band_mhz) needs a one-time edit to read this JSON at app start (cache in :persistent_term) and merge band_overrides[band].weights over the in-source defaults. Until then, the JSON is documentation only.