You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
feat: climatological anomalies, a comparable x-axis, and a methods panel
Three additions, plus the fixes they surfaced.
ANOMALIES
build_sections.sql now builds a monthly climatology — a plain mean per
(station, 5 m depth bin, calendar month) over 1993-2013 — and differences each
section against it. The window is stated once at the top of that file and
carried through to the app's methods panel, because an anomaly whose baseline
is not on screen is not interpretable.
1993-2013 is available for the first time in this release: the Wilkinson
archive backfills 1993-08 through 2002, where the published record jumped
1998 -> 2003. Ask for it a month ago and it would have quietly meant "1998 plus
2003-2013". 21 years averages over the 1997-99 El Nino/La Nina and ends before
the 2014-16 heatwave, so the heatwave and what has followed read as departures
rather than being folded into the normal.
The anomaly join is INNER, so a cell with no baseline is absent, never zero —
an unsampled baseline is not a zero anomaly. 89.8% of section values have one;
each section reports its own share in the note under the plot rather than
leaving the reader to estimate blank area by eye.
Rudnick et al. (2017) fit harmonics for the CUGN glider climatology, which
suits near-continuous glider sampling. CalCOFI's is episodic and unevenly
spaced, so a monthly mean is used instead — defensible, and legible enough that
a reader can say what the departure is from. The same definition is available
in R as calcofi4r::cc_climatology(); the two are separate implementations of
one definition because this repo's CI has no R.
COMPARABLE X-AXIS (default off)
The x-axis defaults to distance between the stations the cruise actually
occupied, so the section fills the plot. The new toggle switches to distance
along the full line, with the axis range fixed to the LINE's extent rather than
the cruise's — an axis that resizes with the selection is not a comparison.
Line 93.3 has not been sampled past station 90 since 2025-01, though 113 of the
130 cruises before it reached station 120. Under the default ruler a recent
section is drawn the same width as a historical one covering 40% more ocean.
MAP: THREE CLASSES, NOT TWO
A station absent from the section is absent for two unrelated reasons — it is
on another line, or this cruise did not reach it. Drawn identically, a
shortened line 93.3 looks like a line that simply ends at station 90. Stations
on this line but unoccupied are now hollow rings in the transect's own hue, and
the panel states the count.
METHODS PANEL
A closed-by-default accordion covering all of the above, with links to both
build scripts and to calcofi4r's transect.R.
Fixes found while checking it in a browser:
* The y-axis zeroline draws a dark rule along depth 0. Invisible under a
full-width section; under the comparable ruler it runs on past the last
station occupied and reads as data.
* The seafloor is warped onto each cruise's occupied x, so under the
along-line ruler it placed the shelf break tens of km from where it is. The
line's own profile now ships once per line in index.json.
* connectgaps must stay ON in the anomaly view. `obs` carries the THINNED CTD
series, so most holes are depths with no scan rather than missing baseline —
and tracing a contour over a matrix that sparse locked the page.
* Plotly measures its container before the map and notes settle the grid, so
the first paint overflowed its panel and put the colorbar on the map until
the user resized. Re-measured on the next frame.
Data shards are deliberately NOT in this commit: the current release carries a
CTD temperature defect being re-ingested now, and publishing anomalies computed
against it would ship known-wrong numbers. refresh.yml rebuilds them from the
corrected release.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DDEjUhDHbK9RUfqkfkDMjr
0 commit comments