Releases: anrobiadev/HF_Prop
HF Propagation V 3.0.0
HF PROP – A Field Companion · v3.0.0
Released: June 2026
Previous version: v2.71
Repository: [anrobiadev/HF_Prop](https://github.com/anrobiadev/HF_Prop)
License: MIT
Overview
Version 3.0.0 is a major update that fundamentally rewrites the propagation engine, integrates real-time ionospheric data from the GIRO network, and introduces a redesigned Signal Footprint Map. The jump from v2.7.1 to v3.0.0 reflects the depth of these changes — the core calculation engine is essentially new.
Propagation Engine (voacap_engine.py)
IRI-2016 Lookup Table
A pre-computed IRI-2016 ionospheric table (fof2_iri2016.npz) is now included in the app's DVoaData folder. The table covers 3 SSN levels × 12 months × 24 hours × 17 latitudes × 18 longitudes and replaces the purely analytic CCIR fallback as the primary foF2 source when available.
VOACAP Calibration
The engine has been calibrated against real VOACAP Online predictions across four independent scenarios (short path NVIS, medium path ~2000 km, long path ~3500 km, and winter conditions). Key changes:
calc_muf()— completely rewritten with correct multi-hop geometry. For distances > 3000 km, the number of F2 hops is computed asceil(d / 2000)and a per-hop D-layer absorption factor is applied. Calibrated result: 392 km → 8.0 MHz ✓, 2000 km → 15.8 MHz ✓, 3500 km → 9.5 MHz ✓ (vs. VOACAP 8.0 / 15.6 / 9.6 respectively).- Global scaling — latitude and season-dependent foF2 scaling corrects systematic IRI-2016 overestimation at mid-latitudes in summer. At night (solar zenith > 85°), scaling is reduced to 20% of the daytime correction, matching the more uniform nocturnal ionosphere.
- Winter anomaly — a +25% foF2 boost at latitudes > 35° in winter months (November–February) accounts for the well-known ionospheric winter anomaly.
- Evening enhancement — a Gaussian +8% foF2 enhancement centred at ~19 LT models the double-hump diurnal pattern observed at mid-latitudes in summer.
- D-layer absorption fix — the absorption formula previously used total slant distance (up to 6000 km) as the path through the D-layer. This is now correctly computed as
40 km / sin(elevation), the actual path through the ~40 km thick D-layer. This eliminated the spurious LUF values of 20–60 MHz that appeared in the previous version. - MUF curve smoothing — a 3-point weighted average (0.25 / 0.50 / 0.25) is applied to the 24-hour MUF and FOT output curves to remove interpolation artefacts.
Real-Time GIRO Ionosonde Data
The engine now accepts a measured foF2 value (avg_fof2) from the GIRO ionosonde network. When real data is available, the internally computed foF2 curve is anchored to the measured value while preserving the modelled diurnal shape:
foF2_real(hr) = avg_fof2_GIRO × (foF2_model(hr) / foF2_model(12h))
This applies to both the MUF/FOT/LUF chart and the 24-hour band reliability heatmap. If no GIRO data is present (avg_fof2 = 0), the engine behaves exactly as before.
GIRO Ionosonde Integration (SolarUtils.kt)
The GIRO DIDBase integration has been migrated to the new FastChar API (/fastchar/getbest) confirmed by LGDC/Ivan Galkin in June 2026. The old /common/DIDBGetValues endpoint is retired.
- Two separate requests per station:
charName=foF2andcharName=MUF%28D%29 - Mandatory 2-second delay between requests, per LGDC policy
- URL format:
fromDate=2026%2F06%2F10+05%3A00%3A00(confirmed working format) - CS filter: confidence score ≥ 40 (or 999 for manual scaling), foF2 range 4.0–20.0 MHz
- Data persistence — downloaded foF2, MUF, and the fetch timestamp are saved to SharedPreferences and restored on app restart
Signal Footprint Map
The coverage engine (coverage_engine.py) has been rewritten from scratch:
- Physics-based skip distance —
skip_minis derived from MUF geometry inversion rather than empirical look-up tables - foF2 evaluated at TX — eliminates the artificial geographic asymmetry that previously produced triangular coverage shapes
- Per-band maximum distances — calibrated reference distances (40m: 3000 km, 20m: 6000 km, 15m: 8000 km, etc.) replace the single
max_reachvalue - Skip zone rendering — the dead zone between TX and the skip distance is now drawn as a diagonal-hatched overlay with a dashed boundary
- NVIS detection — 160m, 80m, and 40m automatically switch to NVIS mode when
f < foF2 × 0.95, displaying a small filled circle with no skip zone - Layers FAB — a floating action button (top-right of the map) opens a dropdown containing per-band checkboxes, a skip zones toggle, and an inline legend. The separate checkbox row above the map has been removed.
- 72 bearings — increased from 36 to 72 for smoother polygon edges
Settings — Solar Data Panel
A new Solar Data card in the Settings tab shows:
- SSN (SILSO), SFI (DRAO), K-Index (NOAA) with source labels
- Per-station ionosonde data: foF2 and MUF values from each GIRO station
- Last update timestamp:
DD.MM.YYYY HH:mm UTC - All labels fully translated (EN / RO / HU)
Help Tab
A new Section 7 — Propagation Engine has been added, describing the CCIR/ITU methodology, the IRI-2016 table, the George & Bradley D-layer absorption model, ITU-R P.533/P.372 SNR calculation, NVIS logic, and all data sources. Available in English, Romanian, and Hungarian.
Translations (TranslationProvider.kt)
Seven new string keys added to all three languages:
solarDataTitle · noDataLabel · ionosondeTitle · noIonoData · lastIonoUpdate · engineTitle · helpEngine
Bug Fixes
- Fixed
BuildConfigunresolved reference — replaced withPackageManager.getPackageInfo() - Fixed
drawscope.rotatevsui.draw.rotateimport conflict - Fixed D-layer absorption producing LUF values of 20–60 MHz at long distances
- Fixed
MAX_HOP_KM(4000 → 2000 km) causing incorrect single-hop geometry at distances > 2000 km - Fixed
calc_mufextrapolating to physically impossible values (> 100 MHz) at distances > 3000 km - Fixed discontinuity in the diurnal foF2 formula at solar zenith = 90° that caused spikes in MUF curves around sunrise/sunset
- Fixed
inner_pointsandis_nvisnot being parsed from Python coverage data (were silently cast to strings)
Notes for Developers
- The IRI-2016 table (
fof2_iri2016.npz) must be placed inapp/src/main/python/DVoaData/. Generation script:generate_fof2_table.py(requiresiri2016,numpy,cmake,gfortran). - The GIRO FastChar API requires residential or mobile IP — datacenter IPs receive HTTP 403. No proxy is needed from a phone.
- Tested with Chaquopy Python 3.11, numpy added to pip dependencies in
build.gradle.kts.
73 de YO7ZRO — developed for RVSU (Radioamatori Voluntari în Situații de Urgență)
v2.7.1 - Initial Public Release
This is the first version released for public. Enjoy! Rob.