Processing and reporting for shipboard CTD and LADCP data: from raw instrument files through QC'd, CF/CCHDO-aligned netCDF and a compiled profiles grid, to self-contained HTML. The reports are portable HTML files — all figures embedded as base64 PNGs, no external requests — in three types: per-cast station pages, transect section pages, and a cruise-wide time series page.
Designed for use at sea where internet connectivity is limited or absent. All output files are fully self-contained and work offline.
pip install ctdcastFor development (editable install from source):
git clone https://github.com/ocean-uhh/ctdcast
cd ctdcast
python -m venv venv
source venv/bin/activate # macOS / Linux
# venv\Scripts\activate # Windows
pip install -e ".[dev]" # runtime + tests + docs + ruffDependencies: gsw, matplotlib, pillow, numpy, xarray, netcdf4, jinja2, pyyaml, ruamel.yaml, scipy
CTD conversion: seasenselib converts raw CNV files to the netCDF format expected by ctdcast (ctdcast draft or ctdcast run). Install with pip install seasenselib. Pre-converted netCDF files from other tools must match ctdcast's variable naming convention (see docs).
To verify the installation, run the bundled demo against the committed fixture casts:
ctdcast run config_demo.yaml # writes demo_report/index.htmlFor a full walkthrough see the Quickstart guide.
Raw CNV files fresh off the instrument? One command gives you station pages + index + map:
ctdcast draft /path/to/cnv/ # generates ./ctd_draft/index.html
ctdcast draft /path/to/cnv/ out/ --cruise odb2026 # with cruise ID
ctdcast draft /path/to/cnv/ --dry-run # preview what would happenRequires seasenselib for CNV conversion (pip install seasenselib).
For sections, time series, and LADCP panels you need a config.yaml:
ctdcast init # writes a template config.yaml
ctdcast init --interactive # guided setup: prompts for paths and
# auto-detects sections/timeseries from profiles.nc
ctdcast validate config.yaml # check paths before the first runctdcast run config.yaml # smart update — skips up-to-date pages
ctdcast run config.yaml --force # rebuild everything
ctdcast run config.yaml --only 42 # rebuild one cast pageOpen <output.dir>/index.html in any browser.
Diagnose the acquisition-clock error (System vs GPS clock) for a cruise with ctdcast clock config.yaml — it prints a verdict and a paste-ready processing.clock block without writing anything.
| File | Description |
|---|---|
ctd_nc/stageN/*_stageN.nc |
Per-cast netCDF files, one per CTD cast per stage |
profiles.nc |
Compiled profiles on a 1 dbar grid |
ctd_sections.yaml |
Section definitions — which casts belong to each transect |
sections:
KTout:
description: "Kögur Transect outflow"
color: "#e41a1c"
cast_numbers: [[1, 12], 15] # ranges and/or individual cast numbers
FARDWO:
description: "FARDWO mooring array"
color: "#377eb8"
cast_numbers: [[20, 35], "22b"] # add "NNNb" to include a lettered sibling castCast numbers are kept in the order written. An integer or range selects the
plain casts; a lettered sibling event (from a NNNb / NNN_b file) is a
distinct cast and must be named explicitly as a quoted "NNNb" string.
<output.dir>/
index.html front page — map + stats + navigation
casts.html table of all casts (latest first)
sections.html section cards with links
timeseries.html T, S, O₂ vs time × pressure
sbe_sensors.html sensor inventory + which sensor was used on which cast
casts/
cast_001.html
cast_002.html
...
sections/
section_KTout.html
...
Each station page shows: CT profile, T/S/σ₀ triple-axis profile, T-S diagram coloured by O₂ saturation, auxiliary profiles (O₂, fluorescence, turbidity), N²/Turner-angle stability panels, and a cruise-track map with the cast highlighted.
Maps show GEBCO 2025 bathymetry when gebco_nc is set in config.yaml.
The file (~8 GB) is not bundled. Maps render without bathymetry if the path is missing — not an error.
Full documentation: ocean-uhh.github.io/ctdcast
Development of this package started during the Odón de Buen cruise of AEI-DFG DS-MIXSED. DS-MIXSED is funded by the Agencia Estatal de Investigación (AEI) through the PCI 2024 call — projects PCI2024-155022-2 and PCI2024-155084-2 — and the Deutsche Forschungsgemeinschaft (DFG, German Research Foundation) — Projektnummer 541914507.
Development was assisted by Claude Code (Anthropic) and GitHub Copilot code review.