Skip to content
WU6PPublic

About

VOACAP HF propagation prediction ported to JavaScript, proven bit-identical to the IONCAP/VOACAP Fortran. Runs in the browser, offline.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

24 Commits

Folders and files

Repository files navigation

VOA: VOACAP in JavaScript

A dependency-free JavaScript port of VOACAP, the Voice of America / NTIA-ITS HF propagation predictor (IONCAP lineage). It runs in node and in the browser, and it is bit-identical to the original Fortran: the full COMMON-block state matches exactly (tolerance 0) at every checkpoint, not just the printed output.

Live: https://wu6p.github.io/VOA/web/ (GitHub Pages, the same static page).

./start        # serves the page at http://localhost:8700/web/  (./stop to stop)

The page has two tabs:

  • Point to point: a reliability-by-hour heatmap, the exact voacapx.out VOACAP prints, and the input deck, so you can re-run it in real VOACAP.
  • Area map: an azimuthal-equidistant coverage map of REL, SNR, field strength, signal, MUF or SNRxx around the transmitter.

For hams:

  • A station can be typed as a Maidenhead grid (CM87xi), a callsign (JA1XYZ, KH6LC, VE7CC; hamcore's DXCC resolution, with US/Canadian call-area centres) or lat, lon.
  • Mode presets set the required SNR, with its basis shown:
    • CW 38 dB-Hz, fitted to RBN skimmer spots in validate/;
    • SSB 48 dB-Hz;
    • FT8 13 dB-Hz, WSJT-X's −21 dB in 2.5 kHz.
  • Band chips put a frequency in that mode's segment of each band.
  • The area map can run all 24 hours and play them as an animation.

All computation happens in a Web Worker in the page; the server only hands out files.

Offline, in one file

npm run single      # -> dist/voacap.html (3.7 MB)

This builds the whole page as one HTML file: the engine, coefficients, antennas, coastlines and callsign tables all inline. It opens straight from file:// (a phone's Files app, a laptop on a plane) with no server and no network. The engine runs in a Blob worker, or in the page if the browser refuses one. tests/single_build.test.mjs runs the bundled engine against the golden Fortran outputs, and node tools/web_check.mjs --url file://$PWD/dist/voacap.html drives the page itself.

Use from node

import { runDeck, runArea } from './engine/voacap.js';
import { loadData } from './engine/data_node.js';
const { out } = runDeck(deckText, { data: loadData() });          // voacapx.out text
const { vg } = runArea(voaText, 'my.voa', { data: loadData() });  // .vg1 … grid files

What is ported

  • Point to point:
    • all 30 METHODs;
    • OUTGRAPH extra plots;
    • all antenna types (CCIR Rec.705 0–12, gain tables 13/14, IONCAP 21–30, HFMUFES/ITS-78 31–47 with complex arithmetic, NOSC 48).
  • Area coverage (voacapl … area calc) and inverse area (inv calc). This covers AREAMAP's .voa → deck conversion (including the ICEPAC, REC533 and map-only deck formats and areafreq.dat), the 360°×91 area antenna tables, the grid geometry, the .vgN output and batch area runs (voaareaw.cir, runAreaBatch).
  • Also:
    • daily URSI maps (MONTH with a day);
    • the 2–30 MHz sweep;
    • distance and time plots (.out/.idx/.dst);
    • batch point to point (runBatch, B and S);
    • absorption modes;
    • S/I output (METHOD > 200, the .si file);
    • CIRAF-zone test points (ZONES).
  • Not ported: Harris antennas (≥ 90), which run an external program voacapl doesn't ship. ICEPAC and REC533 themselves aren't in voacapl either: there, those area models only change the deck format.

Tests

npm test        # ~15 s, no Fortran needed

tests/golden/golden.json.gz (1.8 MB) holds 128 inputs and what the Fortran produced for them:

  • 98 point-to-point decks (every METHOD, every shipped antenna, perturbed and synthesised antennas, absorption modes, S/I, ZONES);
  • 17 area runs, 6 distance/time plots, 4 batch runs and 3 batch area runs.

The tests compare every output file byte for byte. For 57 of the cases they also compare a SHA-256 digest of the full COMMON-block state at every checkpoint. Changing one constant in the noise model by 1 part in 10^8 fails 17 of them. npm run golden (tools/make_golden.py) regenerates the file from the oracles in ref/.

How parity is proven

The reference is jawatson/voacapl @ c12a98b (in ref/, untracked; tools/make_oracles.sh builds everything).

  • Oracles. r4 is the program as shipped. r8 is the float64 build. r8v/dbgv are the r8 build linked against V8's own fdlibm (ref/v8math), so sin, log, exp… return the same bits as node.
  • State dumps. tools/commons.py inventories every COMMON block. From that one inventory, a generated Fortran DUMPST and the JS engine/state.js dump identical state at the same checkpoints.
  • Differential fuzz on random inputs:
    • tools/fuzz.py: point to point; --state for exact full-state comparison, --rich for varied hours, months, OUTGRAPH and second runs, --rand-ants for perturbed antenna files.
    • tools/fuzz_area.py: area and inverse area, the same options.
    • tools/fuzz_plot.py, tools/fuzz_batch.py, tools/fuzz_ciraf.py: distance/time plots, batch runs, and S/I + CIRAF + area models + area batch.
  • Unit tools. tools/antdrv runs one antenna model in both languages, and tools/constcheck.py checks every numeric literal against the Fortran.

Vs the VOACAP you download: that build computes in REAL*4, this port in float64. On 1,000 random circuits, 99.74% of SNR cells print the same and 99.98% are within 1 dB. The rest is a different ray in 21 of 219,072 cells, or SNRs far below −250 dB. Details: DRIFT.md (tools/drift.py).

NOTES.md lists every trap found on the way: ~50 of them, including upstream bugs that are deliberately reproduced, such as uninitialised locals, continuation-line constants and integer-literal typos.

Licence

MIT for this port (LICENSE). VOACAP/IONCAP are US-Government works (not copyrighted); voacapl's modifications are CC0. Natural Earth land data is public domain.

About

VOACAP HF propagation prediction ported to JavaScript, proven bit-identical to the IONCAP/VOACAP Fortran. Runs in the browser, offline.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages