# Algorithm Refinement & ML Training Design ## Goal Refine the propagation scoring algorithm using 57K+ historical QSOs matched to HRRR atmospheric conditions, then train the Axon ML model on the refined algorithm's output for fast inference from HRRR forecast data. ## Data Assets - 57,488 tropospheric QSOs (1992-2024) with distance as ground truth - 54M HRRR grid profiles (2016-2026) at 0.125° resolution - 326K surface observations - 58K terrain profiles (97% BLOCKED — confirms atmospheric propagation) - 3M propagation_scores (current algorithm output) - Band distribution: 53K at 10G, 3.8K at 24G, 800 at 47G, 141 at 75G, sparse above ## Design Decisions - **Target variable**: Hybrid — refine algorithm from QSO data, then train ML on refined scores - **QSO-HRRR matching**: Endpoint average — HRRR conditions at both QSO endpoints, averaged - **Algorithm scope**: Full re-examination — weights, thresholds, add/remove factors - **ML deployment**: ML primary scorer with algorithm fallback for missing data ## Implementation Plan ### Stage 1: Analysis Mix Task (`mix propagation.analyze`) Build QSO↔HRRR analysis dataset: - For each QSO, find nearest HRRR grid point to pos1 and pos2 (round to 0.125°) - Find HRRR profile at nearest hour to qso_timestamp - Average atmospheric conditions across both endpoints - Output: CSV or in-memory dataset with columns: - qso_id, band, distance_km, month, utc_hour - avg_surface_temp_c, avg_surface_dewpoint_c, avg_surface_pressure_mb - avg_min_refractivity_gradient, avg_hpbl_m, avg_pwat_mm - avg_surface_refractivity, ducting_at_either_endpoint - terrain_verdict (BLOCKED/CLEAR/FRESNEL_PARTIAL) Run correlation analysis: - Spearman rank correlation of each variable with distance_km, stratified by band - Bin each variable into deciles, compute median distance per bin (natural breakpoint curves) - Check for interaction effects (e.g., gradient × time_of_day, hpbl × month) - Look for currently-missing predictive factors - Compare factor distributions for short (<100km) vs long (>300km) contacts Output: printed report with findings and recommended changes. ### Stage 2: Update algo.md Document all findings with data backing: - Which factors gained/lost predictive power - New threshold curves derived from data - Revised weights with justification - Any new factors added or old factors removed - Before/after comparison of scoring behavior ### Stage 3: Update scorer.ex + band_config.ex Implement revised algorithm: - Updated scoring functions with new thresholds - Updated weights in band_config - New factors if analysis warrants - All changes match algo.md documentation - Run `mix test` to verify no regressions (update tests for new behavior) ### Stage 4: Recompute Propagation Scores Run refined algorithm across HRRR grid: - Either `mix propagation_grid` or a targeted recompute task - Generates fresh propagation_scores with refined algorithm - These become ML training data ### Stage 5: Training Mix Task (`mix propagation.train`) Build training pipeline: - Query propagation_scores joined to hrrr_profiles by lat/lon/valid_time - Features: raw atmospheric inputs + cyclical temporal + log frequency - Target: refined composite score normalized to 0-1 - 80/10/10 train/val/test split, stratified by band and score quartile - MSE loss, Adam optimizer, early stopping on validation loss - Save trained weights to priv/models/propagation_v1.nx - Print evaluation metrics (RMSE, R², per-band performance) ### Stage 6: Integrate ML into Grid Worker - model.ex: `predict_score/2` for inference - PropagationGridWorker: try ML prediction first, fall back to Scorer.composite_score/2 - Graceful degradation when model file missing or inputs incomplete