Commit 876135d1 authored by Turner, Sean's avatar Turner, Sean
Browse files

Update CLAUDE.md with diagnostics module documentation



Add Diagnostics section, mixed package layout details, updated test
counts (148 tests across 8 files), and plotly optional dependency.

Co-Authored-By: default avatarClaude Opus 4.6 <noreply@anthropic.com>
parent 34af6f0b
Loading
Loading
Loading
Loading
+31 −3
Original line number Diff line number Diff line
@@ -32,9 +32,13 @@ After any Rust code changes, run `maturin develop` to recompile.

**Entry Point**: `powersheds.simulate_cascade(cascade_data: dict) -> dict[str, Result]`

**Mixed Rust+Python Package**: Uses maturin's `python-source = "python"` layout. Rust compiles to `powersheds._lib`, re-exported by `python/powersheds/__init__.py`.

**Source Structure**:
- `src/lib.rs` - Main module: data structures (`ReservoirData`, `RiverData`, `ConfluenceData`), `simulate_cascade()` orchestration, per-timestep reservoir simulation
- `src/helpers.rs` - Interpolation functions: `interpolate_elevation()`, `interpolate_storage()`, bilinear HPF interpolation for power/release computation
- `python/powersheds/__init__.py` - Package init, re-exports from `_lib`
- `python/powersheds/diagnostics.py` - Interactive diagnostic visualization (see Diagnostics section)

**Three Object Types**:
- **Reservoir**: Pool elevation from storage-elevation curves, head calculation, release/power via bilinear HPF interpolation, storage/capacity constraints
@@ -57,10 +61,32 @@ After any Rust code changes, run `maturin develop` to recompile.
- Power: MW
- HPF flows (`hpf_q`): m³/s (cumecs)

## Diagnostics

The `powersheds.diagnostics` module provides interactive visualization for simulation results. Requires the `viz` optional dependency: `uv pip install -e ".[viz]"`

**Public API** (`from powersheds.diagnostics import ...`):
- `cascade_diagnostics(results, ...)` → Plotly `go.Figure` with dropdown reservoir selector, three linked time series panels (flows, elevation, power), and infeasible power shading
- `network_diagram(cascade_data, ...)` → matplotlib `Figure` with publication-quality static network diagram (trapezoid reservoir nodes, Bezier edges, lag labels)
- `save_diagnostics_html(results, output_path, ...)` → writes standalone HTML file

**Internal helpers** (prefixed with `_`):
- `_build_topology(cascade_data)` - Extract nodes/edges from CascadeData
- `_compute_network_layout(nodes, edges)` - Topological-sort layered layout
- `_detect_reservoirs(results)` - Filter result keys to reservoir names
- `_build_flow_traces`, `_build_elevation_traces`, `_build_power_traces` - Per-panel Plotly trace builders

## Example

The `examples/Cumberland/` directory contains a full working example with 8 reservoirs. Run the Quarto notebook:
The `examples/Cumberland/` directory contains a full working example with 8 reservoirs.

**Python notebook** (recommended):
```bash
# Run examples/Cumberland/notebook.ipynb in Jupyter
# Produces network diagram + interactive Plotly diagnostics
```

**R/Quarto notebook**:
```r
reticulate::use_virtualenv(".venv", required = TRUE)
# quarto render examples/Cumberland/script.qmd
@@ -74,15 +100,16 @@ After any major code changes to `src/helpers.rs` or `src/lib.rs`, run the test s
# Rebuild the module first
uv pip install -e .

# Run all tests (117 tests)
# Run all tests (148 tests)
uv run python -m pytest tests/ -v

# Run a specific test file
uv run python -m pytest tests/test_cascade.py -v
```

**Test Coverage** (117 tests across 7 files):
**Test Coverage** (148 tests across 8 files):
- `tests/test_hpf.py` - HPF bilinear interpolation (74 tests): grid corner/edge/interior roundtrips, statistical robustness, performance benchmarks, edge cases
- `tests/test_diagnostics.py` - Diagnostics visualization (28 tests): topology extraction, network layout, axis ranges, network_diagram matplotlib output, cascade_diagnostics Plotly output, HTML export, Cumberland integration, edge cases
- `tests/test_cascade.py` - Full cascade integration (13 tests): output structure, multi-reservoir routing, simulation ordering, mass balance, physical invariants, Cumberland NaN check
- `tests/test_simulate_timestep.py` - Per-timestep reservoir constraints (10 tests): below power pool, min/max release, insufficient water, spill, mass balance, unconstrained power equality
- `tests/test_interpolation.py` - Storage-elevation interpolation (10 tests): breakpoints, midpoints, clamping, roundtrip, monotonicity, Cumberland validation
@@ -104,3 +131,4 @@ uv run python -m pytest tests/test_cascade.py -v
- **Build**: maturin 1.9.4 (Rust-to-Python bridge)
- **Rust**: PyO3 0.23.3
- **Python**: pandas, numpy, scipy, matplotlib, PyYAML, pyarrow (pinned in `uv.lock`)
- **Optional** (`viz`): plotly >=5.18 (for diagnostics module)