Home › reference › api
API and data access
Fifteen public functions and two objects. This page is a map, not a full reference: every signature below has a docstring with the argument semantics spelled out, and help(tc.analyse) is the authoritative text if this page and the code disagree.
Machine-readable datasets
Three files make up the published side of the registry. They are static documents served as-is; a retrieval is an ordinary GET with no key, no quota and no session. Record counts and the schema version are stated so a downstream script can check them before parsing.
| Dataset | Contents | Version | Records | Format | Updated | Retrieve |
|---|---|---|---|---|---|---|
| Constituent catalogue | speed, period, species, origin, station-7 fit | 0.9.3 | 28 | JSON | 2 Oct 2026 | /api/constituents.json |
| API reference | 15 functions, 2 objects, 6 exceptions, 4 exit codes | 0.9.3 | 27 | JSON | 20 Sep 2026 | /api/reference.json |
| Release feed | changelog entries, newest first | - | 12 | Atom XML | 2 Oct 2026 | /feed.xml |
Data access policy. Everything above is MIT-licensed and open to anonymous retrieval; nothing here is rate-limited and nothing is logged. The sign-in page exists only for partner institutions staging unpublished gauge records, and that path is currently unavailable - request a guest token by email if you were sent here for one. A machine-readable function list duplicates the table further down this page.
Conventions that apply everywhere
- Levels keep the units of the input file and are never converted. The unit string travels with the record.
- Times are
numpy.datetime64in UTC. A file without a declared zone is an error, not a guess. - Phase is a lag in degrees at the solution's reference time, increasing with delay.
- Durations are given as strings with a unit suffix:
"3h","25h","72h","18.6y". - Nothing mutates in place. Functions that look like modifiers return a new object.
Record
A parsed gauge series. Built by the readers, never by hand in normal use.
- time, level, flags
- Three arrays of equal length: timestamps, values with NaN for gaps, and
uint8quality flags. - station, units, reference
- Strings copied from the file header.
referenceis the vertical datum as the file names it; the library does not interpret it. - n, missing, step, span
- Sample count, count of NaN values, median sampling interval and total span as a duration.
- subset(start, end)
- A new record over a closed time interval. Both bounds accept ISO 8601 strings.
- to_frame()
- A pandas frame with a UTC index. Needs the
framesextra.
Solution
The result of a fit. Immutable and cheap to keep around; a 68-constituent solution is a few kilobytes.
- names
- Fitted constituent names in catalogue order, as a tuple.
- amplitude(name), phase(name), error(name), snr(name)
- Scalar accessors. Unknown names raise rather than returning zero.
- table(top=None)
- A printable table sorted by amplitude. Terms with a signal-to-noise ratio under 2 get a trailing asterisk.
- ref_time, nodal
- The phase reference and whether the 18.61-year correction was applied.
- coverage, n_used, weights_used
- Fraction of the span that entered the fit, number of samples used, and the flag-to-weight mapping that produced them.
- to_json(path, include=...), to_frame()
- Serialisation. The JSON schema is not frozen before 1.0.
Functions
The same list, machine-readable: /api/reference.json.
| Signature | Returns | Notes |
|---|---|---|
| read_gauge(path, format="auto", tz=None) | Record | format ids are listed under formats; "auto" sniffs the header only |
| analyse(record, constituents="auto", nodal=True, ref_time=None, min_coverage=0.75) | Solution | weighted least squares; raises if coverage is below the bar |
| reconstruct(solution, time) | ndarray | accepts timestamps outside the analysed record; no extrapolation warning is issued |
| residual(record, solution) | ndarray | observed minus reconstructed, NaN preserved at gaps |
| resolvable(span, catalogue="default") | tuple of str | Rayleigh-separable set for a given record length |
| catalogue(name="default") | dict | 68 entries with speed, species and origin |
| infer(solution, pairs=DEFAULT_PAIRS) | Solution | fills unresolvable terms from resolved partners at fixed ratios |
| fill_gaps(record, solution, max_gap="72h") | Record | filled samples are marked with flag 5 |
| levels(solution, window="18.6y") | dict | mean high and low water estimates; the window is reported in the result |
| rms(x) | float | NaN-aware root mean square, used for residual summaries |
| qc.flag_gaps(record, max_gap="3h") | Record | marks absent samples and spans longer than max_gap |
| qc.flag_spikes(record, window="25h", k=6) | Record | running-median test; k is in robust deviations |
| qc.flag_flat(record, window="2h") | Record | catches a frozen sensor repeating one value |
| qc.summary(record) | str | flag counts and percentages as printed in the tutorial |
| plots.decomposition(record, solution, start=None, days=7) | Figure | needs the plots extra; also plots.spectrum and plots.constituents |
Exceptions
| Exception | Raised when |
|---|---|
| ShortRecordError | the requested constituents are not separable over the record span |
| CoverageError | usable samples fall below min_coverage after flag exclusion |
| UnknownConstituentError | a name is absent from the catalogue; the message lists near matches |
| FormatError | the file does not match the declared format, with the offending line number |
| TimeZoneUnknownError | timestamps carry no zone and tz was not supplied |
Command line
Four subcommands: analyse, reconstruct, qc and catalogue. The flags below belong to analyse; the others share the input and output flags.
| Flag | Default | Effect |
|---|---|---|
| --format ID | auto | force a reader instead of sniffing |
| --constituents SPEC | auto | a count, a comma-separated list, or auto |
| --nodal / --no-nodal | --nodal | apply the 18.61-year correction |
| --min-coverage F | 0.75 | fraction of the span that must survive flag exclusion |
| --ref-time ISO | record midpoint | phase reference, printed in the output either way |
| -o, --output PATH | stdout | JSON solution; a single dash also means stdout |
| --table | off | print the human table instead of JSON |
| --quiet | off | suppress progress notes on stderr; errors still print |
tidalcore qc station-7.csv --format csv-flagged --table
tidalcore catalogue --species semidiurnal --table
tidalcore reconstruct station-7.json --from 2026-11-01 --to 2026-11-08 --step 10min
Exit codes are meant for scripts: 0 success, 2 bad usage, 3 the record was too short or too sparse, 4 the input could not be read. Anything else is a bug worth reporting.
Determinism
Two runs on the same input with the same arguments produce bit-identical output; there is no random seed anywhere in the fit and no iteration limit that could stop early. The only module-level state is the constituent catalogue, which is read-only after import, so calling analyse from several threads is safe. It will not be faster, because the work happens inside NumPy.
See also: the tutorial uses most of these calls in order, and the changelog records when each of them last changed shape.