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.
4.1 KiB
Full Recalibration Report — 2026-05-24
Auto-generated by
scripts/recalibrate.py. The companion JSON file atpriv/algo/band_weights.jsonis 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.