Skip to content

v2.8 — Darwin v5 initial conditions + L2 POC observation loss

Date: 2026-05-17 Status: Findings doc; PR in flight. Branch: v2.8-darwin-ic-poc-sub Parent finding: v2.6 GEOTRACES hybrid (scav_rat and R_PICPOC framed as HNLC-region structural limits at ~0.92 and ~2.92 off Carroll)

Headline

v2.8 produces the project's first reproducible scav_rat Cal-grade recovery and the first non-noise Biggrow Excellent. At the anchor config (Darwin IC, GEOTRACES_SUB_W=1.0, POC_SUB_W=3.0, PINN_drift_w=3.0, n=10), the new scoreboard is:

Parameter Mean ± std (n=10) Mean offset vs Carroll Cal-grade hits Excellent hits
scav_rat 7.66e-7 ± 4.23e-7 0.403 7/10 4/10
Smallgrow 0.632 ± 0.178 0.204 9/10 2/10
diatomgraz 0.717 ± 0.228 0.162 9/10 2/10
Biggrow 0.407 ± 0.142 0.262 7/10 1/10
alpfe 0.336 ± 0.226 0.638 2/10 0/10
R_PICPOC 0.0055 ± 0.00045 0.870 0/10 0/10

Aggregate: 6/10 seeds reach 4/6 Cal-grade — twice the previous project best (3/10) for the v2.7 anchor config.

The cost of this scoreboard is alpfe, which trades from project-best (7/10 Excellent at sub_w=1.0 with Darwin IC alone) into Drifted (2/10 Cal-grade). The two recoveries are joint-incompatible under the v2.7 box-model + observation set; see the bimodal-degeneracy section.

What changed vs v2.7

Two orthogonal additions, both implemented in scripts/run_v2.7_multilayer_batched.py:

1. Darwin v5 pickup-derived initial conditions (DARWIN_IC=1)

The v2.7 box-model state vector previously initialised from literature-plausible defaults:

state0_single = [DFe_1=5e-4, ..., POC_2=0.05, ..., DIC_2=2204, ALK_2=2460]

These are global-ocean averages, NOT Eq Pacific HNLC values. Two of them are wildly off vs the actual Darwin v5 Eq-Pacific surface state at iteration 78912 (~March 1994):

Tracer × Layer Literature default Darwin v5 mean Ratio
FeT_L1 5.0e-4 mmol/m³ 1.7e-5 0.035 (30× too high)
FeT_L2 5.0e-4 5.3e-4 1.06 ✓
POC_L1 0.5 0.29 0.58
POC_L2 0.05 0.42 8.4 (8× too low)
PIC_L1 0.025 0.0084 0.34
PIC_L2 0.003 0.013 4.4
DIC_L1 2101 1973 0.94 ✓
DIC_L2 2204 2320 1.05 ✓
ALK_L1 2409 2326 0.97 ✓
ALK_L2 2460 2386 0.97 ✓

The literature default's 30× FeT_L1 overestimate in Eq Pacific HNLC was the largest mismatch — the box-model integrator started from a non-HNLC iron state and the optimizer chose parameters that reproduced surface obs without ever needing alpfe near Carroll's value. The literature default's 8× POC_L2 underestimate is the candidate mechanism for the scav_rat undershoot in v2.6/v2.7: iron sink rate is scav_rat × DFe × POC, so underestimating POC by 8× forces scav_rat to fit 8× too low to match the surface iron balance.

The new scripts/build_darwin_ic_cache.py opens D:/ecco_darwin_v5/input/darwin_initial_conditions/pickup_ptracers.0000000001.data (10.94 GB, MITgcm float64 big-endian, 31 records of 50 × 3510 × 270), extracts 5 inorganic tracers (DIC, FeT, POC, PIC, ALK), depth-averages over L1 (levels 0-4, 0-50 m) and L2 (levels 5-28, 50-1056 m) with the L2 wet-cell mask, and bins to the same 1° Eq Pacific grid the runner uses. Cache is scripts/darwin_ic_cache.npz (80 KiB, deterministic; rebuild in ~5 s).

Phyto biomass IC stays at literature defaults — the 7-PFT (Darwin v5) → 5-PFT (box model) mapping is non-trivial (Chl tracked for only c01-c05; c06 likely coccolithophores, c07 likely Trichodesmium / N-fixers) and biomass equilibrates fast under the integrator so initialisation matters less.

2. L2 POC observation loss (POC_SUB_W > 0)

A new z-score loss term constrains the integrator's L2 POC trajectory directly:

l_poc_sub = term_batched(state[I_POC_2], poc_l2_z)
z_term = z_term + POC_SUB_W * l_poc_sub

The target poc_l2_z is built from the same IC cache (Darwin's depth-averaged POC over L2). The choice of Darwin self-target is intentional: Carroll's calibration should reproduce Darwin's POC field, so constraining against Darwin POC gives a methodologically consistent test of whether L2 POC observability resolves the scav_rat degeneracy. Swapping the target for real GEOTRACES POC (POC_LPT_CONC + POC_SPT_CONC, already in D:/geotraces/GEOTRACES_IDP2025_Seawater.nc) is a 50-line refactor of geotraces_loader.py for the next iteration.

Filename / JSON tagging

New CLI tags so the new experiments don't collide with v2.7:

Variant Filename suffix
Default (literature IC, no POC_SUB) _pinn3.0.json (no extra suffix)
Darwin IC only _pinn3.0_darwinic.json
Darwin IC + POC_SUB_W=W _pinn3.0_darwinic_pocsubW.json
Darwin IC, alternate cache _pinn3.0_<DARWIN_IC_TAG>_pocsubW.json

JSON output also carries use_darwin_ic and poc_sub_w keys for downstream provenance.

Bimodal degeneracy

Sweeping POC_SUB_W at the (Darwin IC, sub_w=1.0) anchor cleanly switches the optimizer between two loss-surface basins:

POC_SUB_W n="alpfe-correct" basin n="scav-correct" basin scav_rat Excellents Aggregate 4+/6
0.0 10/10 0/10 0 1/10
0.3 9/10 1/10 1 1/10
1.0 8/10 2/10 1 2/10
3.0 3/10 7/10 4 6/10

Definition: a seed lands in the "scav-correct" basin if its recovered scav_rat is within 50 % of Carroll's 6.025e-7.

Interpretation. The v2.7 box-model + observation set supports two distinct local minima of the loss:

  • alpfe-correct basin (alpfe ≈ 0.9, scav_rat ≈ 1-2e-7 — Drifted): the optimizer matches surface FeT magnitude by tuning the dust-iron source, then leans on a small particle scavenging rate to balance the iron budget. Reaches 10/10 Cal-grade on alpfe (7/10 Excellent at the sub_w=1.0 anchor) but never reaches Cal-grade on scav_rat.

  • scav-correct basin (alpfe ≈ 0.2-0.3 — Drifted, scav_rat ≈ 6-7e-7 — Excellent / Cal-grade): the optimizer matches surface FeT pattern (not magnitude) with a small dust source and a large scavenging rate that produces the right iron sink at depth. Reaches 4/10 Excellent on scav_rat but never reaches Cal-grade on alpfe.

Carroll's published calibration sits at the joint constraint (alpfe=0.928, scav_rat=6.025e-7) — both correct — which is not a local minimum of our loss with the current 6-parameter / ~11-target structure. It would require the loss surface to have a single minimum that satisfies both, which is identifiability-blocked unless additional observational constraints disambiguate the two basins.

POC_SUB_W is the lever that chooses which basin the optimizer falls into. Higher weights push the optimizer to match Darwin's L2 POC pattern, which is what scav_rat × DFe × POC is supposed to produce — so the scav-correct basin gets selected.

This is the first time the project has produced direct empirical evidence of a bimodal degeneracy in the alpfe ↔ scav_rat axis. Prior work (v2.2 closeout, v2.6 GEOTRACES hybrid, v2.7 2-layer box) all reported the "alpfe Cal-grade / scav_rat Drifted" basin as if it were the only one available.

Best single seed

Seed 0 at the v2.8 anchor (Darwin IC, sub_w=1.0, POC_SUB_W=3.0) is the closest single seed to "both Cal-grade" in the project so far:

Parameter Recovered Carroll rel_off Band
alpfe 0.686 0.928 0.261 Cal-grade
scav_rat 6.18e-7 6.025e-7 0.026 Excellent
Smallgrow 0.634 0.661 0.041 Excellent
Biggrow 0.316 0.431 0.267 Cal-grade
diatomgraz 0.054 0.830 0.934 Drifted
R_PICPOC 0.00651 0.0424 0.847 Drifted

4/6 Cal-grade (2 Excellent including scav_rat); diatomgraz collapsed but the alpfe + scav_rat pair landed Cal-grade or better simultaneously. First seed in the project to do this.

What's still stuck

R_PICPOC stays at 0/10 Cal-grade across every POC_SUB_W tested (0, 0.3, 1.0, 3.0). The Darwin IC moved its sign (overshoot → undershoot) compared to literature IC but didn't reduce its absolute offset. The structural argument from v2.6 stands: R_PICPOC needs independent PIC observations as a loss term; the current observable set (surface bin-average tracers + sparse GEOTRACES DFe + Darwin L2 POC) doesn't differentiate the PIC/POC stoichiometric ratio from PIC dynamics.

alpfe in the scav-correct basin is Drifted. This is identifiability-mode, not a model failure: the basin exists because two parameter combinations explain the surface observations equally well. Disambiguating requires either:

  • A new observable that's sensitive to dust-iron source (e.g., aerosol Fe deposition data colocated with the AOI)
  • Cross-regime training (v3.0 multi-AOI) where iron-replete N Atlantic forces a different alpfe-scav_rat balance than Eq Pacific HNLC
  • Time-resolved fitting (cluster-gated) where the seasonal cycle of dust deposition vs scavenging adds dynamical contrast

Reproducing

# 1. Build the Darwin v5 IC cache (one-time, ~5 s; requires the 10.94 GB
#    pickup file at D:/ecco_darwin_v5/input/darwin_initial_conditions/).
python scripts/build_darwin_ic_cache.py

# 2. Headline scav-correct experiment (n=10 seeds, ~2 min on RTX 5090).
NB23_SEEDS=0,1,2,3,4,5,6,7,8,9 \
DARWIN_IC=1 POC_SUB_W=3.0 \
GEOTRACES_W=0.3 GEOTRACES_SUB_W=1.0 NB23_PINN_WEIGHT=3.0 \
python scripts/run_v2.7_multilayer_batched.py

# 3. alpfe-correct comparison config (n=10, ~2 min).
NB23_SEEDS=0,1,2,3,4,5,6,7,8,9 \
DARWIN_IC=1 \
GEOTRACES_W=0.3 GEOTRACES_SUB_W=1.0 NB23_PINN_WEIGHT=3.0 \
python scripts/run_v2.7_multilayer_batched.py

JSONs land in scripts/run_v2.7_multilayer_result_*.json with the _darwinic / _pocsubW* tags.

Limitations / next steps

  1. Only one AOI tested (Eq Pacific). The bimodal degeneracy might collapse under multi-AOI training where the iron-replete N Atlantic subpolar regime disambiguates alpfe from scav_rat. This is the v3.0 multi-AOI design (PR #44 merged 2026-05-17).
  2. Darwin self-target POC, not real obs. Swapping in GEOTRACES POC (LPT + SPT particulate) is straightforward; the loader already exposes the variables.
  3. No block-CV check yet. The seed-0 "alpfe + scav_rat both Cal-grade" result is single-AOI single-split — needs spatial cross-validation before claiming structural identifiability.
  4. No prognostic validation. Recovered v2.8 parameters haven't been run forward through Darwin v05 to check long-term stability. Cluster-gated (Brenowitz & Bretherton 2018 §3.4).
  5. PIC observations remain the R_PICPOC unblock. Same conclusion as v2.6, unchanged by v2.8.