prop/lib/microwaveprop/workers
Graham McIntire 622edee180
feat(propagation): per-contact mechanism classification
Classifies every contact's likely non-LOS propagation mechanism and
persists the result on contacts.propagation_mechanism. Mechanism is
determined in priority order:

  1. user_declared_prop_mode (ADIF PROP_MODE from the operator log)
  2. EME — moon-ephemeris check, ≥2m band, >1800 km path
  3. aurora — Kp≥5 + high-lat path, 50-432 MHz
  4. sporadic-E — foEs × 5 ≥ band_mhz, 400-2500 km path
  5. meteor_scatter — ±3 days of a shower peak, VHF/UHF
  6. rain_scatter — common-volume radar heavy rain, 5-11 GHz ≤800 km
  7. tropo_duct — HRRR native_best_duct ≥ band or ducting_detected
  8. line_of_sight — ≤50 km path
  9. troposcatter — default

Persisted via MechanismClassifyWorker (queue: :mechanism, unique on
contact_id). Submit-time enqueue path includes :mechanism by default;
BackfillEnqueueWorker cron now handles :mechanism alongside existing
types so prod continuously backfills any contact with
propagation_mechanism_status in (:pending, :queued, :failed). Also
added :radar to the cron's type list so common-volume radar backfill
runs automatically rather than only via `mix radar_backfill`.

New modules:
- Microwaveprop.Propagation.MoonEphemeris — Meeus low-precision moon
  position, accuracy ±1° — enough for the mutual-visibility EME test
- Microwaveprop.Propagation.MechanismClassifier — plug-in priority
  chain over the evidence map
- Microwaveprop.Workers.MechanismClassifyWorker — assembles inputs
  from HRRR / native profiles / common-volume radar / solar_indices /
  ionosonde + calls the classifier

ADIF importer now reads PROP_MODE into user_declared_prop_mode so
operator-tagged mechanisms (EME/ES/MS/RS/AS/AUR) become ground truth.
2026-04-18 10:42:08 -05:00
..
admin_task_worker.ex fix(admin_task_worker): unknown feature now returns error instead of falling through 2026-04-16 14:58:55 -05:00
backfill_enqueue_worker.ex feat(propagation): per-contact mechanism classification 2026-04-18 10:42:08 -05:00
canadian_sounding_fetch_worker.ex Ingest Canadian radiosondes via UWYO + plans for RDPS/HRDPS 2026-04-13 09:14:34 -05:00
common_volume_radar_worker.ex feat(rainscatter): classify QSO propagation mechanism from common-volume radar 2026-04-17 15:57:59 -05:00
contact_import_worker.ex feat(import): async CSV import with progress-tracking schema 2026-04-17 09:31:22 -05:00
contact_position_backfill_worker.ex test: override stale distance_km when filling a missing pos 2026-04-16 14:09:45 -05:00
contact_weather_enqueue_worker.ex feat(propagation): per-contact mechanism classification 2026-04-18 10:42:08 -05:00
hrrr_fetch_worker.ex fix(workers): make weather/hrrr job uniqueness horizon indefinite 2026-04-17 10:15:30 -05:00
hrrr_native_grid_worker.ex refactor: normalize pos1/pos2 JSONB key to 'lon' everywhere 2026-04-17 09:10:32 -05:00
iemre_fetch_worker.ex Fix credo warnings: struct specs, length/1, and test patterns 2026-04-12 10:26:53 -05:00
ionosphere_fetch_worker.ex Ionosphere: GIRO ionosonde ingestion (foF2/foEs/hmF2/MUFD) 2026-04-15 14:37:43 -05:00
mechanism_classify_worker.ex feat(propagation): per-contact mechanism classification 2026-04-18 10:42:08 -05:00
mrms_fetch_worker.ex Add MRMS rain mosaic, fix beacons crash, fix UTC clock flash 2026-04-12 14:49:20 -05:00
narr_fetch_worker.ex Rename ERA5 → NARR across the codebase 2026-04-16 09:22:23 -05:00
nexrad_worker.ex refactor: normalize pos1/pos2 JSONB key to 'lon' everywhere 2026-04-17 09:10:32 -05:00
propagation_grid_worker.ex feat(propagation): record per-forecast-hour chain step timings 2026-04-18 09:36:52 -05:00
propagation_prune_worker.ex Decouple propagation_scores pruning from the compute worker 2026-04-09 12:30:10 -05:00
rtma_fetch_worker.ex Add ERA5 reanalysis and RTMA data sources 2026-04-07 12:04:16 -05:00
solar_index_worker.ex Database performance fixes and async backfill enqueue 2026-04-04 19:19:18 -05:00
space_weather_fetch_worker.ex SpaceWeather: SWPC JSON ingestion (Kp, F10.7, GOES X-ray) 2026-04-15 14:55:24 -05:00
terrain_profile_worker.ex refactor: normalize pos1/pos2 JSONB key to 'lon' everywhere 2026-04-17 09:10:32 -05:00
weather_fetch_worker.ex fix(workers): make weather/hrrr job uniqueness horizon indefinite 2026-04-17 10:15:30 -05:00