Port ddrs ddr_match corrections: outflow_idx fix, neg-solve counter, signed tau, β + Cunge X - #192
Merged
Merged
Conversation
…LID) Generated by ~/projects/ddrs/scripts/build_gages_2000_area_balanced.py (seed 42). Corrects the absolute DA_VALID criterion that preferentially deleted large basins; see gage_info README for the derivation. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…counter, signed tau, β + Cunge X Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Ported from ddrs (.claude/PHYSICS-CORRECTIONS.md): summing upstream columns dropped the gauge reach's own local drainage (0.215x observed on the worst small basins; 26/1841 gauges below 0.5x baseline). The MC solve at the gauge reach already carries upstream flow plus its own lateral inflow. Side effect: partial-area flow_scale corrections now actually reach MERIT gauge predictions. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The clamp to discharge_lb silently creates mass and hides Courant instability. ddrs measured ~0.03-0.14% of reach-timesteps negative under corrected physics; this counter is the tripwire for the Cunge-X port. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Slice [tau : -(24-tau)], pooled day i scored against obs day i (dMC-Juniata sign; tau=0 day-aligned). Shipped legacy tau=3 was signed -8 — mis-set in the wrong direction; ddrs measured the fix alone at +0.086 median NSE, flipping routing from losing to the summed-Q' baseline to beating it. Also unifies train.py's inline slice (was [13 : -11+tau], a fractional-day window) with the shared helper. BREAKING: pre-port checkpoints trained on the legacy window; config tau values do not carry across. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
c = v·β with β = 5/3 − (4/3)·A·√(1+z²)/(T·P) — the hardcoded 5/3 is the wide-rectangular limit, 22-27% high on real channels. X is now computed per timestep from Cunge's diffusion matching, clamp(0.5·(1 − Q/(T·S·c·L)), 0, 0.5), replacing the static per-reach x (MERIT constant 0.3, Lynker zarr) — that plumbing is removed. Ported from ddrs ddr_match:false physics (.claude/PHYSICS-CORRECTIONS.md). BREAKING: pre-port checkpoints were trained against the legacy physics. Known trade: Cunge X≈0.5 narrows the non-negative-coefficient window; the negative-solve counter reports the clamp rate every forward (~0.1% expected, ddrs-measured). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…dits Master (DeepGroundwater#188) replaced the static architecture doc with the LLM-wiki schema; the tau/celerity/Muskingum-x corrections this branch made to the old doc now live in the local wiki/ pages instead. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
CI resolves ruff 0.16.3, which now formats Python code blocks inside markdown; local lock has 0.15.4, which does not. Applied 0.16.3's formatting so the ruff CI job passes. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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.
Summary
Ports the corrections the
ddrsrepo developed behind itsddr_matchconfig flag (whereddr_match: truereproduced this repo bit-for-bit andfalseenabled corrected behavior — all ddrs production configs now runfalse). This lands as a clean break: no compatibility flag; old results reproduce from old commit hashes.Sources of truth: ddrs
.claude/PHYSICS-CORRECTIONS.md,docs/2026-08-03-ddr-match-findings.md,docs/2026-08-06-tau-sweep-pilot-findings.md§5i. Spec and plan are committed underdocs/superpowers/.Changes (one commit per stage, in dependency order)
outflow_idxextraction — the MERIT collate summed a gauge's upstream columns, dropping the gauge reach's own local drainage (0.215× observed on the worst small basins; 26/1841 gauges below 0.5× baseline). The MC solve at the gauge reach already carries upstream flow plus its own lateral inflow. Side effect: partial-areaflow_scalecorrections now actually reach MERIT predictions.< 0before thedischarge_lbclamp rewrites it (mass creation), logs the per-forward rate. Tripwire for stage 4 (~0.1% expected, ddrs-measured).[tau : -(24−tau)], pooled day i scored against obs day i (tau=0 day-aligned). The shipped legacytau=3was signed −8, mis-set in the wrong direction; ddrs measured the fix alone at +0.086 median NSE, flipping routing from losing to the summed-Q' baseline to beating it. Also unifies train.py's inconsistent inline slice ([13 : -11+tau], a fractional-day window) with the shared helper. Legacy pin: new tau=16 cuts the same hour window as legacy tau=3.c = v·βwithβ = 5/3 − (4/3)·A·√(1+z²)/(T·P)(the hardcoded 5/3 is the wide-rectangular limit, 22–27% high on real channels), andX = clamp(0.5·(1 − Q/(T·S·c·L)), 0, 0.5)computed per timestep, replacing the static per-reach x (MERIT constant 0.3, Lynker zarr) whose plumbing is removed end to end. Autograd supplies the backward.Deliberately not ported (measured NO-GOs in ddrs):
enforce_positivity, reach subdivision, Courant sub-stepping, slope-floor removal, leakance.Breaking changes
tauvalues do not carry across the convention change.RoutingDataclass.xis removed.Known trade
Cunge X ≈ 0.5 on most CONUS reaches narrows the non-negative-coefficient window
2X ≤ Cr ≤ 2(1−X); negative Muskingum coefficients rise (artifacts), while negative solves stayed ~0.1% in ddrs. The stage-2 counter reports the rate every forward — a retrain showing a rate far above ~0.1% is a stop-and-investigate signal.Test plan
c1+c2+c3 = 1, gradient flow through the X path, tau legacy-equivalence pin, gauge-reach extraction🤖 Generated with Claude Code