Amphidrome

Tidal prediction by harmonic synthesis

Soundings inMetres
DatumLowest astronomical tide
ProjectionMercator
Station0447 · Calder Sound
Record length19 years
m
Predicted height above datum

A tide is not a forecast. It is an ephemeris.

Weather is chaotic, so a weather-derived marine feed decays with its horizon and returns a different answer tomorrow than it returned today. Tides are not weather. They are driven by the relative motion of Earth, Moon and Sun — orbital mechanics, known to extraordinary precision and running on a clock that does not care what century you ask about.

Fit a station once against its observation record and the station is solved. The same ten numbers that give you Tuesday at 0412 give you the afternoon of 3 March 2184, at the same confidence, on a phone in airplane mode.

Move the scale. The curve does not degrade, because there is nothing in it to decay.

Predicted water level · 48 h 01 JAN 2026

Withdraw one constituent, and watch the water go quiet.

Sum of all constituents · 72 h Range 13.12 m

Every speed above is a physical constant in degrees per mean solar hour, fixed by orbital period. Only amplitude H and phase lag g belong to the station. Each preview wave is drawn to its own height, so every constituent's period stays legible however small it is. The previews compare shape, never size — amplitude is the H column.

What we do not predict.

Harmonic synthesis gives the astronomical tide. Observed water level also carries a meteorological residual — storm surge, barometric pressure, wind setup — and that part is weather, with all of weather's honesty problems.

We do not fold the two into one confident number. The astronomical tide is returned at full weight because it is knowable. The residual is returned as a bounded band, drawn thin, because it is not.

Astronomical tideDeterministic. Evaluated from the constituent set, identical every time you ask.

Observed levelWhat the gauge actually read. Astronomical tide plus whatever the weather added.

Meteorological residualBounded, not predicted. Line weight carries confidence, so the uncertain part never looks certain.

Ten numbers and a clock.

Station 0447 · offline synthesisJS
// The fit. Speeds are physical constants; H and g are the station's.
const CALDER_SOUND = [
  //  σ °/h        H (m)   g (°)
  [28.9841042, 3.952, 184.2], // M2
  [30.0000000, 1.318, 231.7], // S2
  [28.4397295, 0.762, 165.8], // N2
  [30.0821373, 0.359, 229.4], // K2
  [57.9682084, 0.211, 88.5],  // M4
  [58.9841042, 0.147, 142.0], // MS4
  [15.0410686, 0.138, 118.6], // K1
  [13.9430356, 0.104, 342.9], // O1
  [14.9589314, 0.046, 115.2], // P1
  [13.3986609, 0.029, 331.4], // Q1
];

const DEG = Math.PI / 180;

// Metres above chart datum, at any instant, for ever.
export const level = (hours) =>
  6.10 + CALDER_SOUND.reduce(
    (h, [σ, H, g]) => h + H * Math.cos((σ * hours - g) * DEG),
    0
  );

Notes

The network call is the fit, not the prediction.

Resolve a station once and you hold its constituent set. Every prediction after that is arithmetic on the client — no round trip, no rate limit, no signal.

Nodal corrections are applied, not assumed away.

The lunar node precesses on an 18.61-year cycle, so amplitudes and phases drift. Long-horizon predictions correct for it. This is where naïve implementations quietly lose centimetres.

Every height carries its datum.

Heights are returned against a declared datum, stated on every response. A number without its datum is not a measurement, and confusing chart datum with sea level is how vessels find the bottom.

A short record is a weaker station, and says so.

Accuracy follows the length and quality of the observations behind the fit. Stations report their record length so you can decide whether to trust the eighth decimal.