Home › overview
Harmonic analysis of water-level time series
tidalcore takes a record from a water-level gauge, fits the tidal constituents in it by least squares, and gives you back two separate series: the part the tide explains and the part it does not. It is a library and a command-line tool, about 4 200 lines of Python, with NumPy and SciPy as its only required dependencies.
This site is both the documentation and the data registry. The library is one half; the other is three static, versioned datasets anyone can pull without an account - the constituent catalogue, the machine-readable API reference, and the release feed. They are listed with record counts and retrieval paths on the API and data access page.
What it does
- Fits constituent amplitudes and phase lags by weighted least squares on irregularly or regularly sampled records, with the 18.61-year nodal correction applied by default.
- Reconstructs the tidal signal over any set of timestamps, including timestamps outside the analysed record.
- Returns the non-tidal residual, which is where storm surge, river discharge, gauge faults and datum shifts live.
- Flags spikes, gaps and repeated values, and keeps those flags with the data instead of silently dropping samples.
- Fills short gaps from the fitted solution, marking every filled sample so that a later analysis can exclude them.
- Estimates the usual high- and low-water levels from a solution, with the averaging window stated in the output.
What it does not do
Do not use tidalcore for navigation. It is an analysis tool, not a prediction service. It knows nothing about your datum, your chart reference, meteorological forcing or local port corrections, and it will happily extrapolate a one-month record a decade into the future and give you a confidently wrong number.
- No surge or weather model. The residual is returned, never predicted.
- No datum transformations. Whatever vertical reference your file uses comes out the other end unchanged, and the reference string is copied into the solution so you can see what it was.
- No spatial interpolation, no co-tidal charts, no model grids. One gauge at a time.
- No inference of missing metadata. If a file does not state its time zone, the reader raises an error rather than assuming UTC.
Who it is for
People who have a text file from a gauge and a question about it: a technician checking whether a sensor drifted, a student separating surge from tide for a storm case study, a hydrographer re-analysing an old record with a modern constituent set. If your record is shorter than a month, the library will still run, but read the note on which constituents a short record can actually resolve before you quote the numbers.
Quickstart
python -m pip install tidalcore
import tidalcore as tc
rec = tc.read_gauge("station-7.csv", format="csv-flagged")
sol = tc.analyse(rec)
print(sol.table(top=4))
# name amplitude_m phase_deg snr
# M2 1.412 211.6 318.4
# S2 0.463 238.2 104.1
# N2 0.281 190.8 63.2
# K2 0.126 235.9 28.4
Two more calls give you the split that most people came for:
tide = tc.reconstruct(sol, rec.time) # metres, same length as rec
rest = tc.residual(rec, sol) # observed minus tide
The same thing from a shell, writing a JSON solution instead of printing it:
tidalcore analyse station-7.csv --format csv-flagged -o station-7.json
Project status
The current release is 0.9.3, published on 2 October 2026. The version number is honest: this is pre-1.0 software and the public surface is not frozen yet.
| Area | Status | Notes |
|---|---|---|
| analyse, reconstruct, residual | stable since 0.7.0 | signatures frozen; new keyword arguments only |
| Record, Solution | stable since 0.7.0 | attributes may be added, never renamed |
| qc thresholds | unstable | default spike window and factor are still being tuned |
| JSON output schema | unstable | key names may change once; a converter will ship with that release |
| catalogue ids | mostly stable | shallow-water compound names may be regularised |
Dependencies are kept deliberately small, and the package is a pure-Python wheel with no compiled extensions, so it installs on anything that runs Python 3.10 or newer. The whole test suite runs in about six seconds, which is the main reason the suite gets run.
Sections of this registry
pip, conda environments, extras, and how to check that the install works.
One record from file to fitted solution to plotted decomposition, with real numbers.
Every public function, its return type, the exceptions it raises, and the CLI flags.
26 constituents with speeds and periods, plus how long a record must be to separate them.
Which file layouts the readers accept and what each quality-control flag means.
MIT terms and what to put in a reference list when the work is published.