This page explains exactly how the numbers are produced: the data sources, the physics model behind the Predicted scores, the catchment maths behind the Observed scores, and the rule that compares them. Nothing here is a black box.
Two principles shape everything:
| Source | Provides | Used for |
|---|---|---|
| NOAA SWPC | Planetary Kp, geomagnetic storm alerts | Kp tile, storm state & watch, Kp penalty |
| N0NBH / HamQSL | Solar Flux Index (SFI) | SFI tile, MUF fallback estimate |
| KC2G (GIRO/LGDC) | Real-time ionosonde foF2 from worldwide Digisondes | MUF/LUF at your QTH |
| Reverse Beacon Network | CW/RTTY & FT8/FT4 skimmer spots | Observed catchment |
| WSPR.live | WSPR beacon receptions (both ends located) | Observed catchment |
| PSK Reporter | FT8/FT4/digital receptions worldwide | Observed catchment |
| DX cluster | Human-posted SSB/CW spots (voice + by-ear CW) | Activity page (collecting; not in the forecast score, see below) |
Indices are polled every 15–20 minutes; ionosondes every 20 minutes; the spot networks stream continuously into a local store with a rolling window. The Status page shows the live state of every feed.
The single most important measurement is foF2, the critical frequency of the F2 layer above you, read from the nearest ionosondes. From it everything about the high bands follows.
Ionosondes are sparse, so foF2 is interpolated from nearby stations, weighting each by distance and freshness:
exp(−age / 60 min));foF2 is the frequency that bounces straight back from directly overhead. Signals sent at a
low angle for a long hop reflect at a much higher frequency: the obliquity effect. The
effective MUF for a path is foF2 × k, where k grows with hop length up to
one ~3000 km hop, then plateaus:
| Range | Distance | Obliquity k | Effective MUF |
|---|---|---|---|
| Local | 0–500 km | 1.2 | ≈ critical freq (near-vertical) |
| Regional | 500–1500 km | 1.9 | foF2 × 1.9 |
| Continental | 1500–3000 km | 2.8 | foF2 × 2.8 |
| DX | 3000 km + | 3.35 | foF2 × 3.35 |
So a single foF2 reading produces four different MUFs, and the same band can be open for DX while closed locally. The headline MUF tile shows the DX figure (foF2 × 3.35).
For each band and range, the 0–10 predicted score is a product of four factors, each between 0 and 1. Multiplicative, not additive, so any single show-stopper (band above the MUF, band below the LUF, a severe storm) correctly closes the band:
sigmoid((MUF − f) / 2.5 MHz). ≈1 well below the MUF, falling through ½ at the MUF,
to near-zero above it. This is the dominant term for the high bands.sigmoid((f − LUF + 0.8) / 0.6 MHz). Closes the low bands by day when D-layer
absorption is high. The LUF itself is modelled from solar zenith angle and SFI (defaults roughly
4.0 MHz by day, 3.0 at greyline, 1.8 at night). The LUF is also mode-aware: D-layer absorption
falls as roughly 1/f², so a more sensitive mode tolerates more of it and works to a lower frequency.
We scale the floor by sqrt(D / (D + ΔSNR)), with ΔSNR the mode class's sensitivity over
CW/SSB (about 27 dB for the weak-signal modes) and D the absorption depth at the floor. This is
the one place the chosen mode touches the predicted score, and it moves only the low bands.exp(−0.35 × (Kp − 3)) (so Kp 5 ≈ 0.50,
Kp 7 ≈ 0.25), floored at 0.05. A storm pulls every band down together.sigmoid((f − 12) / 4)) combined with the local day/night/greyline
phase, with a small greyline bonus.The 0–10 result is labelled:
| Score | Label |
|---|---|
| ≥ 7.5 | Open |
| 5.0 – 7.5 | Fair |
| 2.5 – 5.0 | Poor |
| < 2.5 | Closed |
Day/night and greyline come from the solar zenith angle at your location (horizon at 90.83° with refraction; civil twilight to 96° marks the greyline band).
Everything above assumes fresh local ionosonde data and quiet geomagnetic conditions. During a solar storm neither holds, so it is worth being explicit about what the dashboard does, and what it is telling you, when the inputs degrade. This is exactly when a propagation page is easiest to misread.
The MUF starts from a real measurement: an ionosonde (digisonde) sweeps upward through the HF spectrum and reads the critical frequency foF2 off the returned echo, automatically. A disturbed ionosphere breaks that. Storm-time spread-F smears the trace and absorption weakens the echo, so the automatic scaling can no longer pick a clean foF2 and the station stops publishing new values. Lag from the global data centres adds to it. The last good reading simply ages. We only trust a reading under 60 minutes old and within 6000 km, so once the nearby sondes fall behind, none qualifies, even though the stations are still online. The dashboard says so plainly: it names the nearest sonde and how long ago it last updated, rather than pretending there is nothing there.
With no fresh sonde in range, the MUF is modelled instead of measured: foF2 is estimated from the
solar flux (SFI) and solar zenith angle, then the same obliquity factors give the per-range MUF. That
keeps a sensible ceiling on the page, but it is a model, not a measurement, so the MUF tile is greyed
and relabelled (QTH · est.). The caveat that matters: SFI changes slowly and cannot see the
storm-time depression a real sonde would catch, so a modelled MUF tends to look healthier than the
ionosphere actually is.
This is the trap a high flux sets. SFI raises the MUF, so a value like 187 looks like fine
conditions, but it is only one of the four factors in the predicted score. The geomagnetic penalty
fKp multiplies the whole score, so an elevated Kp caps every band regardless of
the flux: Kp 4.7 holds the ceiling near 5.5/10 (nothing reaches Open), and a G-storm at Kp 7
pulls it under 2.5 (everything Closed). A high SFI is the ceiling, not the outcome, which is why the SFI
tile carries a caveat line when geomagnetic activity is overriding it.
When any of this is in play a box appears above the per-band forecast, naming the cause so a suppressed table is never a mystery. It is composed from whatever applies at the time:
The observed side asks a concrete question: "in the last hour, who actually heard a station in my area, and how far away were they?" This is the DX direction (what you can reach), which is what most operators want to know.
500 → 1000 → 1500 → 2500 → 4000 km, stopping at the first radius that is
sufficient: at least 10 distinct transmitters across at least 3 bands. The radius used is
reported in the Observations chip.Counting spots directly would just measure how many receivers happen to surround you. Instead the score is a reach fraction: of the receivers actually listening on that band at that distance, what proportion heard your area?
heard = distinct receivers that heard your area; available = distinct receivers
monitoring that band at that distance (the same mode class, see below).OPEN_FRACTION calibrates "fully open" per range, since propagation only ever reaches a
favoured slice of the far receiver pool: Local 0.90, Regional 0.70, Continental 0.65, DX 0.18
(you can't be heard by every distant receiver even on a great day).damping = min(1, available / 8) stops a tiny pool (e.g. 2 of 2 receivers)
masquerading as fully open.This makes a sparse region and a dense region directly comparable, and it's why a quiet QTH honestly reports "unconfirmed" rather than inventing an opening.
The receiver networks decode weak digital modes far below the level a human can copy:
| Mode | Typical decode floor |
|---|---|
| WSPR | ≈ −28 dB |
| FT8 | ≈ −21 dB |
| FT4 | ≈ −16 dB |
| CW / SSB | much higher |
So a path that only WSPR can see is no use for a voice contact. The Modes control filters the observed catchment (and crucially its denominator) to one class:
Classification is by the spot's actual mode, not its network (PSK Reporter, for instance, carries some WSPR-mode reports, which count as weak-signal). Filtering the available-receiver denominator to the same class keeps a sparser CW opening from being diluted by all the WSPR-only skimmers that would never report it.
The Modes control also reaches the predicted side, through the mode-aware LUF above: in a weaker-signal class the low-band floor drops, so a band sitting right at the edge can read open for FT8 while staying closed for voice. The higher bands are limited by the MUF rather than absorption, so they do not move with the mode.
When a band is heard at short range that ordinary F2 sky-wave can't explain, the cause is named:
These are pure annotations on the observed side; they never alter the physics prediction.
The indicator compares the two scores, gated by how much evidence there is:
The "materially apart" threshold (2.0 on the 0–10 scale) and the evidence threshold (3 receivers) are the only two tuning knobs, and both are deliberately conservative.
The Activity page is deliberately not a forecast and not scored; it's a direct, browsable view of recent spots, answering "what's on the air now?" rather than "is it open for me?".
For the chosen time window it takes the recent spots (filtered by the Modes control) and groups them by the DXCC country of one end:
Per country it reports the distinct callsigns, the bands-active count (the liveliness grade, where a country active on more bands is livelier), per-band call counts, and a sample of recent spots for the drill-down.
"My area" pins the other end within ~1000 km of your QTH, so the far countries you see are anchored to your location (with "Stations heard", that's what your local receivers can actually hear). "Global" drops that filter.
There is no density normalisation here; it's raw presence, on purpose. That's also why the sparse human SSB/CW from DX cluster earns its place on this page even though it's too thin to drive the forecast's observed score: counting who's active doesn't need the volume a calibrated density score does.
The voice and by-ear CW spots come from the worldwide DX cluster network: operators manually spotting stations, the only source that captures voice at all. We rotate across several interconnected nodes for reliability (primarily GB7MBC in Morecambe, with dxspider.co.uk, dxc.hamserve.uk and dxc.ve7cc.net as fallbacks; all carry the same global stream). Two honest caveats shape how we use it:
For both reasons we collect it and surface it on Activity as presence, and deliberately keep it out of the forecast's observed score, which needs the dense, even coverage the automated networks provide. (Self-spots, where a station spots itself, are filtered out as they aren't reception reports.)
The Map plots the same spots geographically. Like Activity, it is observed only; nothing on it is predicted. Two things make it work.
It uses an azimuthal-equidistant projection centred on your QTH. On this projection every straight line from the centre is a true great-circle bearing, and radial distance is true ground distance, which is exactly how HF propagation is reckoned. Each spot's latitude/longitude is projected to the disc; the antipode maps to the outer edge. The whole map is drawn live on a canvas, so zoom (scale) and pan (offset) just re-run the projection, and points stay vector-crisp at any zoom. Coastline outlines are from Natural Earth (public domain).
The day/night shading is computed from the sun's position, not fetched. From the current time we find the subsolar point (the latitude/longitude where the sun is overhead) by standard solar geometry, then for any point on Earth the solar elevation is simply 90° minus its great-circle angle to that subsolar point. Points below −6° are shaded as night; the −6°…+6° band around the horizon is the greyline (civil-twilight) zone. When that band falls over your own QTH, around your local sunrise and sunset, the map flags it, because greyline paths are often prime DX.
For a non-technical tour of the controls, see the User Guide.
This site stands entirely on data generously made available by others. None of it would be possible without their work, and all rights in that data remain with the organisations and individuals who produce it; this site claims no ownership of any of it and uses it gratefully, under each provider's terms (including non-commercial use where required).
To every operator who runs a skimmer, beacon or reporting receiver: thank you. Your stations are the "observed" half of this site.
The idea, the design direction, the amateur-radio domain knowledge and all the decisions about how this should work are a collaboration between the author and the AI. The code itself was written entirely by Claude (Anthropic's AI assistant): every line of the engine, the collectors and this site was authored by Claude, working to the author's brief.