Commit graph

383 commits

Author SHA1 Message Date
FluxCD
024735009b chore: update prop image to git.mcintire.me/graham/prop:main-1775587689-be8e23c [skip ci] 2026-04-07 13:52:46 -05:00
5acaaa9fa1 Support source=gps in URL for dynamic GPS-based bookmarks
Bookmarking /path?source=gps&destination=K5TR&band=10000 will use
the viewer's device GPS to resolve the source location on load.
The LocateMe hook handles both button clicks and server-pushed
request_gps events. Once coords are resolved, the URL is updated
with actual lat,lon and calculation runs automatically.
2026-04-07 13:48:03 -05:00
FluxCD
8242ba682c chore: update prop image to git.mcintire.me/graham/prop:main-1775587563-40c1bb3 [skip ci] 2026-04-07 13:48:03 -05:00
e20fd27998 Add forecast timeline, shareable URLs, and real-time form updates to /path
- 18-hour propagation forecast bar chart from grid scores at path midpoint
  Shows best/worst score and time, color-coded bars
- URL query params: all form fields reflected in URL, auto-calculates
  when source+destination present. Bookmarkable/shareable links.
- phx-change on form updates assigns in real-time as user types
- Removed LiveStash in favor of URL-based state persistence
2026-04-07 13:46:00 -05:00
FluxCD
4f756e7e48 chore: update prop image to git.mcintire.me/graham/prop:main-1775587147-44fef0d [skip ci] 2026-04-07 13:46:00 -05:00
c5fdef2675 Add station parameters, GPS locate, and detailed budgets to /path
- TX/RX height in feet (converted to meters for terrain analysis)
- TX power in dBm with mW equivalent display
- TX gain and RX gain (dBi) inputs
- Power budget: TX power + TX gain - feed loss = EIRP - path loss
  + RX gain = RX power vs CW sensitivity = margin
- Loss budget: FSPL + gaseous (O2+H2O) + diffraction + rain
  with per-km gas rate detail
- GPS "Locate Me" button using browser geolocation API
- Lat,lon coordinate pairs accepted as input
- Weather displayed in F with C below
- LiveStash preserves form inputs across page reloads
- Terrain cross-section with beam line and Fresnel zone
2026-04-07 13:39:02 -05:00
FluxCD
c1e6d924eb chore: update prop image to git.mcintire.me/graham/prop:main-1775586313-259b9cd [skip ci] 2026-04-07 13:39:02 -05:00
c68774dd66 Add /path calculator page
LiveView page for analyzing microwave propagation between two points.
Features:
- Source/destination input: callsign (via gridmap.org API) or Maidenhead grid
- Band selector for all 8 microwave bands (10-241 GHz)
- Leaflet map showing path line (reuses ContactMap hook)
- Terrain elevation cross-section (reuses ElevationProfile hook)
- Link summary: distance, bearing, terrain verdict
- Loss budget: FSPL + O2 + H2O + rain + diffraction
- Propagation score with 10-factor breakdown
- Current atmospheric conditions from path-integrated HRRR

New CallsignClient for gridmap.org location lookup.
Navigation links added to main navbar and map control panel.
2026-04-07 13:25:07 -05:00
FluxCD
aaba91d5e3 chore: update prop image to git.mcintire.me/graham/prop:main-1775583477-ad44acb [skip ci] 2026-04-07 13:25:07 -05:00
a49b233e4d Document ERA5, RTMA, and path-integrated HRRR in algo.md
Add sections for all three new data sources in Meteorological
Foundations: path-integrated scoring strategy, ERA5 reanalysis
for pre-2014 contacts, RTMA 15-minute surface analysis. Update
calibration dataset summary with ERA5/RAOB/RTMA coverage.
2026-04-07 12:37:53 -05:00
FluxCD
2b815215c3 chore: update prop image to git.mcintire.me/graham/prop:main-1775583149-7ccbe77 [skip ci] 2026-04-07 12:37:53 -05:00
430a07240e Fix ERA5 CDS API endpoint for new v1 API
- Submit: /api/retrieve/v1/processes/{dataset}/execution
- Request body wrapped in {"inputs": ...}
- Poll: /api/retrieve/v1/jobs/{jobId}
- Status field: "status" not "state", values: accepted/running/successful/failed
- Download: GET {job_url}/results, follow asset href link
- Add ERA5 credentials to k8s secret manifest
2026-04-07 12:32:24 -05:00
FluxCD
29e3c118e4 chore: update prop image to git.mcintire.me/graham/prop:main-1775582667-e47c6ac [skip ci] 2026-04-07 12:32:24 -05:00
bbf3e67d85 Add ERA5 to backfill dashboard and enrichment pipeline
- ERA5 checkbox on /backfill page alongside HRRR/weather/terrain/IEMRE
- BackfillEnqueueWorker handles era5 type (targets hrrr_status=unavailable)
- ContactWeatherEnqueueWorker.build_era5_jobs/1 creates ERA5 fetch jobs
  for path points without existing ERA5 profiles
- Progress bar shows ERA5 candidate count (HRRR-unavailable contacts)
- Status panel shows ERA5 candidates and fetched profile count
2026-04-07 12:24:21 -05:00
77397a1625 Add mix era5_backfill task and gitignore .envrc
Enqueues ERA5 fetch jobs for contacts where HRRR is unavailable.
Deduplicates by rounded grid point and hour, skips existing profiles.

Usage: mix era5_backfill [limit]
2026-04-07 12:24:21 -05:00
FluxCD
05e3702b1b chore: update prop image to git.mcintire.me/graham/prop:main-1775581463-2286725 [skip ci] 2026-04-07 12:24:21 -05:00
29fef2afed Add ERA5 reanalysis and RTMA data sources
ERA5 (Copernicus CDS API):
- Era5Profile schema matching HRRR profile structure for interop
- Era5Client with async job submission, polling, GRIB2 download
- Era5FetchWorker (Oban queue: era5, max_attempts: 5)
- Unified lookup: Weather.best_profile_for_contact/1 tries HRRR
  first, falls back to ERA5 for pre-2014 contacts

RTMA (NOAA S3, 2.5km/15-min):
- RtmaObservation schema for surface-only fields
- RtmaClient with byte-range GRIB2 requests (same pattern as HRRR)
- RtmaFetchWorker (Oban queue: rtma, max_attempts: 10)
- Weather.find_nearest_rtma/3 for surface condition lookup

Both queues added to production Oban config (2 workers each).
2026-04-07 12:04:19 -05:00
0623c339ca Path-integrated HRRR scoring across pos1/mid/pos2
Contact scoring now uses all HRRR profiles along the path instead of
just pos1. Aggregation strategy:
- Best along path for beneficial factors (refractivity, pressure)
- Worst along path for harmful factors (rain, wind)
- Average for neutral factors (temp, dewpoint, PWAT, BL depth)

Scorer.path_integrated_conditions/2 merges multiple profiles into a
single conditions map. Falls back gracefully to single-profile scoring
when only one profile is available.
2026-04-07 12:04:19 -05:00
FluxCD
b5d86ab58b chore: update prop image to git.mcintire.me/graham/prop:main-1775580351-12b8bdb [skip ci] 2026-04-07 12:04:19 -05:00
62d15f39d6 Update seasonal scores from sounding data, document commercial link patterns
Soundings (10,935): October has strongest gradients (-350 N/km) and
65.7% ducting, raised seasonal score 82→88. February ducting (20.2%)
exceeds January (14.8%), raised 32→40.

Commercial links (12,068 samples): 68 GHz shows 3.9 dB diurnal swing,
11 GHz shows 1.7 dB with inverted multipath pattern, 24 GHz remarkably
stable at 0.9 dB. Diurnal sensitivity is non-monotonic with frequency.

RAOB gradients avg -265 N/km vs HRRR -107 (2.5x stronger) — confirms
HRRR misses thin surface ducts that soundings resolve.
2026-04-07 11:45:46 -05:00
FluxCD
adb610686f chore: update prop image to git.mcintire.me/graham/prop:main-1775578557-be70d39 [skip ci] 2026-04-07 11:19:43 -05:00
b2f3098083 Data-driven algorithm refinements from full dataset analysis
Analyzed 37,925 HRRR-matched contacts from 58,367 total.

- Remove shallow BL bonus (score 82 for HPBL < 300m): data shows
  medium BL (1000-2000m) produces longest contacts (222 km avg),
  not shallow (210 km). Refractivity fallback now uses default score.

- Refine pressure scoring bins: add <980 mb tier (score 88), steeper
  gradient from low to high. Contacts at <970 mb avg 242.7 km vs
  184.1 km at 990-1000 mb.

- Update algo.md calibration stats (58,367 contacts, 41M HRRR
  profiles, 58,361 terrain profiles) and document dataset bias
  (99.5% Aug-Sep).

- Create updates.md with full binned analysis tables for all factors.
2026-04-07 11:19:43 -05:00
03aa72ae80 Fix livebook path resolution in bin/notebook
Falls back to mix escripts directory when livebook isn't in PATH.
2026-04-07 11:19:42 -05:00
3b7711f01d Auto-deploy analysis notebook as Livebook app
Add app_settings metadata to notebook and set LIVEBOOK_APPS_PATH
so it shows up under Apps on the Livebook home page.
2026-04-07 11:19:42 -05:00
cf9c0a5e04 Add bin/notebook script to start Phoenix + Livebook together
Starts Phoenix with a named node and Livebook attached to it on
port 8081. Single command, Ctrl-C stops both.
2026-04-07 11:19:42 -05:00
ab811ae463 Add mix notebook task for Livebook attached to dev node
Run `mix notebook` for instructions to start Livebook at localhost:8081
connected to the running Phoenix node with full Repo/Scorer access.
2026-04-07 11:19:42 -05:00
b204b08751 Rewrite analysis notebook to attach to running node
Uses Repo, Scorer, BandConfig, Weather directly instead of raw SQL.
Scores all historical contacts with the real composite_score/2 and
includes factor heatmaps and weight sensitivity analysis.
2026-04-07 11:19:42 -05:00
af5a48b797 Add Livebook notebook for propagation algorithm analysis
Connects to local dev DB to analyze contacts, HRRR conditions,
terrain impact, commercial link correlation, and score sensitivity.
Ready for use once prod data is imported locally.
2026-04-07 11:19:42 -05:00
FluxCD
6b9ef24c81 chore: update prop image to git.mcintire.me/graham/prop:main-1775566243-7f457e4 [skip ci] 2026-04-07 11:19:42 -05:00
214b706ba8 Remove icons from navigation links in map control panels 2026-04-07 07:50:39 -05:00
d1e42dd8a0 Smooth viewshed boundary to remove SRTM elevation spikes
Apply 5-point circular moving average to reach_km values before
rendering the boundary polygon. Eliminates sharp spikes caused by
isolated terrain anomalies in SRTM data.
2026-04-07 07:42:35 -05:00
FluxCD
114f25a461 chore: update prop image to git.mcintire.me/graham/prop:main-1775565490-61e4196 [skip ci] 2026-04-07 07:42:35 -05:00
FluxCD
f17dfc7270 chore: update prop image to git.mcintire.me/graham/prop:main-1775565429-f0340a2 [skip ci] 2026-04-07 07:42:35 -05:00
970bc29afe Remove stale propagation scores maintenance banner 2026-04-07 07:38:12 -05:00
51c73a3cbd Add periodic enrichment backfill cron and terrain reconciliation
Runs BackfillEnqueueWorker every 30 minutes to pick up contacts with
pending/queued/failed enrichment status and enqueue missing jobs.
Before enqueueing, reconciles terrain contacts stuck in "queued" by
checking the terrain_profiles FK directly.
2026-04-07 07:37:08 -05:00
FluxCD
ec82f4ae71 chore: update prop image to git.mcintire.me/graham/prop:main-1775513079-b5a87e0 [skip ci] 2026-04-07 07:37:08 -05:00
5bd2516c15 Bump terrain queue concurrency to 3 per pod 2026-04-06 17:04:38 -05:00
FluxCD
5583fb6167 chore: update prop image to git.mcintire.me/graham/prop:main-1775512945-6ab4ba7 [skip ci] 2026-04-06 17:04:37 -05:00
c68e1ba108 Re-enable hourly propagation grid scoring in production 2026-04-06 17:02:12 -05:00
FluxCD
da4979751d chore: update prop image to git.mcintire.me/graham/prop:main-1775512477-be9b890 [skip ci] 2026-04-06 17:02:12 -05:00
FluxCD
25df2e6766 chore: update prop image to git.mcintire.me/graham/prop:main-1775509847-dcf5190 [skip ci] 2026-04-06 17:02:12 -05:00
25d7ec317a Mark terrain status complete when profile already exists
TerrainProfileWorker early-exited with :ok when a profile existed
but never updated the contact status, leaving contacts stuck at queued.
2026-04-06 16:54:23 -05:00
FluxCD
00bacae2c2 chore: update prop image to git.mcintire.me/graham/prop:main-1775499376-15ec8af [skip ci] 2026-04-06 16:54:23 -05:00
1f7e9e18a4 Store stub records on empty weather fetches to prevent infinite backfill retries
When ASOS/RAOB/IEMRE APIs return empty data, store a stub record so
dedup checks (has_surface_observations?, has_sounding?, has_iemre_observation?)
see coverage and don't recreate the same jobs on future backfill runs.
2026-04-06 16:10:28 -05:00
c3819112fe Persist checkbox and limit state across backfill enqueue submissions 2026-04-06 12:46:08 -05:00
FluxCD
ef44109351 chore: update prop image to git.mcintire.me/graham/prop:main-1775494893-2fd0175 [skip ci] 2026-04-06 17:02:37 +00:00
98289ec16e Fix format_number reversing digits
Enum.reverse/1 was reversing each chunk's characters, scrambling the
displayed numbers (e.g. 58,363 displayed as 85,363).
2026-04-06 12:01:25 -05:00
FluxCD
f9e2ba294d chore: update prop image to git.mcintire.me/graham/prop:main-1775494509-975e6c9 [skip ci] 2026-04-06 16:56:34 +00:00
9ffeba3fc9 Suppress health check request logs
/health gets hit constantly by k8s probes, drowning out useful logs.
2026-04-06 11:55:01 -05:00
FluxCD
88783765f1 chore: update prop image to git.mcintire.me/graham/prop:main-1775494141-8768175 [skip ci] 2026-04-06 16:50:32 +00:00