Repository navigation
Address the review of the example notebooks (into #26) - #34
Merged
Merged
Conversation
…lotting, add cheap first plots Acts on an independent review of the five examples as of #26. Every notebook changed here was re-executed end-to-end against the xgcm#711 (north-fold) build, 0 cell errors. Correctness - 02_mitgcm: the boundary->padding migration mistranslated a deliberate non-periodic Y into `padding={'Y': 'periodic'}`, wrapping the Antarctic edge (YG=-80) onto the Arctic row (YC=+78). The domain is global in longitude but spans only 78S-78N, so Y must be 'extend'. Measured: exactly one row (39, the northernmost) changes, max|div| 2.55e-6 -> 3.29e-6 against an interior scale of 6.23e-6 -- the same order as the interior, which is why it survived review. psi is unaffected (it passes an explicit padding='fill' to cumsum). Plotting moved into modules (plotting only -- every xgcm call stays inline) - llc_plots.py: LLCMapper out of 01 (56 lines of pyresample/cartopy vs ~4 lines of xgcm). Drops a dead `else` branch that built a stray unused axes, and documents the antimeridian split and the resampling constants. - tripolar_plots.py: the ~250-line matplotlib layer out of 05. The notebook now computes every halo with xgcm up front and the module only draws. A cheap first plot in each notebook - 02: `ds.THETA[0, 0].plot()` before any xgcm -- the grid is a plain lon/lat rectangle, so no projection is needed. - 03: plots in nominal index coordinates first, then explains why they mislead. The top row's nominal y reads as a single 89.95, while the true 2-D lat along that row runs 64.11-89.94 -- it is the fold seam, flattened into a straight line. Motivates the 2-D lon/lat map that follows. - 05: a raw index-space overview of each model before any fold machinery. - 01 already had one (per-tile in index space); reframed so it reads as the honest layout view rather than a failed map. Clarity - 02: prose said xgcm found "five axes ... 1RHO"; it reports four (X/Y/Z/T) and the dataset has no 1RHO dim. Rewritten, along with the pre-rename "periodic" framing. Four empty trailing cells removed. - 01: the 13-tile face_connections dict now says how to read a (tile, axis, reverse) triple and links to the Face Connections Spec. - 05: dropped three dead `padding=` kwargs. On a fold axis the north edge always folds (topology) and only the south edge honours a per-call padding; these operators pad only the north edge, so the kwargs were exact no-ops. Verified behaviour-preserving: fold vs extend gives max|diff| = 0 on real data. They misled a reviewer into a false bug report, which is reason enough to go. - 05: explained autoparse_metadata=False, and framed the xgcm.padding.pad use explicitly as an under-the-hood aside. - 04: dropped the cell printing a dev version hash into the rendered docs. environment.yml advertised the pre-rename `boundary={"Y": {"fold": ...}}`. Readme documents the module convention and the cheap-plot-first guidance. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01C2MVD2DtZLieu1zXgEoXbv
|
Check out this pull request on See visual diffs & provide feedback on Jupyter Notebooks. Powered by ReviewNB |
Renumbering (simplest -> most complex)
- 02_mitgcm -> 01_mitgcm simplest grid, plain .plot()
- 04_nemo_idealized -> 02_nemo_idealized closed basin; adds metrics/derivative/
integrate/cumint/transform
- 03_MOM6 -> 03_MOM6 first real curvilinear grid (unchanged)
- 01_eccov4 -> 04_eccov4 hardest topology (13-tile LLC), 1.1 GB
- 05_tripolar_fold -> 05_tripolar_fold most specialized (unchanged)
Filenames now match the nav rather than the order the examples happened to be
written in. Cross-refs in Readme.md and llc_plots.py updated; the mkdocs nav and
the docs/ links live in the xgcm repo and land with #711.
05 restructured to start where 03 leaves off
03 computes GFDL-CM4's relative vorticity and then admits it "just looks away
from the Arctic seam". 05 now opens by finishing that sentence: same dataset,
same grid, same diff, same Robinson/RdBu_r figure -- the only change is
padding={"Y": {"fold": "corner"}} instead of {"Y": "extend"}. Load, grid,
compute, plot; the machinery comes after.
Vorticity rather than surface speed, because speed cannot show this: MOM6 puts vo
on the north face, so interpolating it to centres pads the SOUTH edge and the
fold never enters -- fold vs extend is bit-identical (max|diff| = 0). diff(uo,'Y')
goes centre -> north face and does pad north, so vorticity changes at the seam
(max|diff| = 9.3e-02, and 95th-pct seam |zeta| roughly doubles, 2.0e-2 -> 4.0e-2).
It is also the diagnostic 03 explicitly punts on.
The opening figure is 03's map redrawn, and deliberately shows no visible change:
the correction is one row of 1080, a hairline near the pole an order of magnitude
below the coastal vorticity that sets the colour scale. That is what motivates
the index-space zoom-ins that follow.
Then: why "corner" is not a magic word (the four pivots, linked to the topology
docs), the same fold on three models with two pivots, and only then the
under-the-hood pad() asides and the seam figures.
03_MOM6: dropped the per-call padding="fill" from the vorticity, which overrode
the grid's periodic X and put a spurious seam at the dateline. X now wraps and Y
uses the grid's 'extend' -- so 05 recomputes exactly 03's field and the two agree.
Prose reframed to hand off to 05.
All notebooks re-executed against the xgcm#711 build, 0 cell errors.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01C2MVD2DtZLieu1zXgEoXbv
The prose added in this PR was overwritten and dramatic. Rewritten across all five
notebooks, the two plotting modules and the Readme: fewer rhetorical set-pieces
("this notebook stops looking away", "that is the honest situation", "the mirror
symmetry is the tell", "that 'extend' is a lie"), less bolding, fewer em-dashes,
and plain declarative sentences instead.
05 specifically
- Opens with what a tripolar grid is ("Many ocean models, like MOM6, NEMO and
Oceananigans, have tripolar grids: ...") rather than a build-up to a reveal.
- Refers to "the MOM6 example earlier in these docs", not "03_MOM6" -- readers see
page titles in the rendered docs, not notebook filenames. Same for the summary
and the module docstrings.
- The "picking up where 03_MOM6 left off" section is cut to the two things a
reader needs: same velocities and grid as before, and why each component is
passed as a {"X": vo} dict.
Also drops an unverified claim from the pivot table: the "center"/"t" row said
"some MOM5 configurations", which is not something the topology docs state and I
have not confirmed. The table now lists only what each pivot means, and the prose
names the two pivots this notebook actually exercises ("corner" for MOM6/NEMO,
"u" for Oceananigans).
Prose-only, except the pivot table and two figure titles. 05 re-executed (its
suptitle lives in the module); all five notebooks show 0 cell errors.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01C2MVD2DtZLieu1zXgEoXbv
The text said "the red line marks the top edge of the array" but there was no red
line. index_space_overview drew ax.axhline(ny - 0.5), and imshow's default extent
makes the y range exactly [-0.5, ny - 0.5], so the line landed on the top of the
axes and was hidden under the frame.
The folded edge is the top of the array, so there is nothing to draw a line at:
mark the frame instead. The top spine is now red and 3pt, which is visible in all
three panels. Text and suptitle updated to match ("the red edge along the top of
each panel").
05 re-executed; 0 cell errors.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01C2MVD2DtZLieu1zXgEoXbv
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Targets
examples-06-tripolar-fold(the branch behind #26), so the diff is only the review fixes on top of the five examples.Acts on an independent review of the examples as of #26, against the stated goal of demonstrating xgcm's functionality for common ocean-modelling workflows. All five notebooks were re-executed end-to-end against the xgcm#711 build — 0 cell errors. The 1.1 GB ECCOv4r4 download was pulled and
01genuinely re-run.The one correctness bug
02_mitgcmwas shipping wrong physics. Theboundary→paddingmigration in 20bb1a1 turned the deliberate non-periodic Y from 534d73a ("make Y non-periodic (extend)") intopadding={'Y': 'periodic'}. The domain is global in longitude but spans only 78°S–78°N, so periodic Y wraps the Antarctic edge (YG=−80) onto the Arctic row (YC=+78).Measured impact — narrower than it looks, which is why it survived review:
periodicvsextend)[39]of 40 — the northernmost onlyperiodic(wrong)2.553e-06extend(correct)3.289e-066.233e-06Only the north edge is padded by
diff/interpon aleft-edge Y axis, so exactly one row moves, by the same order as the interior.psiis unaffected — it passes an explicitpadding='fill'tocumsum.Plotting into modules
Per the brief: modules for plotting routines and nothing else. Every xgcm call stays inline in the notebook where a reader can see it.
llc_plots.py—LLCMapperout of01(56 lines of pyresample/cartopy against ~4 lines of xgcm, reused 6×). Drops a deadelsebranch that built a stray unused axes; documents the antimeridian split and theradius_of_influence/dxconstants.tripolar_plots.py— the ~250-line matplotlib layer out of05. The notebook now computes every halo with xgcm up front; the module only draws.A cheap first plot everywhere
02—ds.THETA[0, 0].plot()before any xgcm; the grid is a plain lon/lat rectangle.03— plots in nominal index coordinates first, then explains why they mislead. The top row's nominalyreads as a single89.95, while the true 2-Dlatalong that row runs 64.11°–89.94°: it is the fold seam, flattened into a straight line. That motivates the 2-Dlon/latmap that follows.05— a raw index-space overview before any fold machinery.01— already had one (per-tile in index space); reframed as the honest layout view rather than a failed map.Clarity
02: prose claimed xgcm found "five axes … 1RHO"; it reports four (X/Y/Z/T) and the dataset has no1RHOdim. Rewritten, along with the pre-rename "periodic" framing. Four empty trailing cells removed.01: the 13-tileface_connectionsdict now explains how to read a(tile, axis, reverse)triple and links to the Face Connections Spec.05: dropped three deadpadding=kwargs — see below.05: explainedautoparse_metadata=False; framed thexgcm.padding.paduse explicitly as an under-the-hood aside.04: dropped the cell printing a dev version hash (0.9.1.dev59+g...) into the rendered docs.environment.yml: advertised the pre-renameboundary={"Y": {"fold": ...}}.Readme.md: documents the module convention and the cheap-plot-first guidance.On
05'spadding=kwargs — a correction worth recordingAn initial review claimed
05'sinterp/diffnever cross the fold, becausepadding="extend"/"fill"at the call site would override the grid's fold viadefaults | user_kwargs(grid.py:311). That is false, and so was a follow-up claim that the kwarg is silently ignored on a fold axis.What is actually true, per
padding.py:53–55andtest_fold_south_edge_respects_per_call_padding:_pad_face_connectionsdispatches on grid state and likewise cannot be overridden);padding.The kwargs in
05are no-ops for a mundane reason: these operators pad only the north edge (padding_width=(0, 1)), so the south mode is never consulted. Verified behaviour-preserving before removal — fold vsextendgivesmax|diff| = 0on real Oceananigans data for bothinterpanddiff.05's thesis stands and its outputs are unchanged. The kwargs go because they misled a careful reader into a false bug report.Not done here (deliberately)
apply_as_grid_ufunc/as_grid_ufunc, despite two dedicated tutorial pages. Also uncovered:average,interp_like,get_metric/set_metrics,interp_2d_vector,Grid.min/max. Worth a follow-up.02 → 04 → 03 → 01 → 05, renumbering files to match) — touchesmkdocs.ymlin the main repo, so it belongs with #711.04is the only notebook usingmetrics/derivative/integrate/cumint/transform.Follow-up for xgcm#711
Passing
padding=on a fold axis quietly does nothing whenever only the north edge is padded — the common case. It misled two consecutive readers. xgcm should warn in that situation; it would have caught these dead kwargs immediately.🤖 Generated with Claude Code
https://claude.ai/code/session_01C2MVD2DtZLieu1zXgEoXbv