baselines 0.1.1

Baseline correction algorithms for signals, spectra, and images
Documentation
# Reference Gallery Examples

This page tracks Rust `ruviz` examples inspired by the upstream pybaselines
gallery at <https://pybaselines.readthedocs.io/en/latest/generated/examples/index.html>.
pybaselines is credited as a documentation and behavioral reference only; the
example code and rendered outputs are native Rust implementations.

The examples write PNGs to `docs/assets/ruviz/`. The generated PNGs are tracked
for Markdown preview and excluded from Cargo packages.

See [`GALLERY.md`](GALLERY.md) for the generated-output index and the working
Rust source file that creates each output set.

```console
cargo run --example ruviz_lam_effects
cargo run --example ruviz_gallery_basic
cargo run --release --example ruviz_gallery_whittaker_sweeps
cargo run --release --example ruviz_gallery_whittaker_solver_timings
cargo run --release --example ruviz_gallery_beads_preprocessing
cargo run --release --example ruviz_gallery_pspline_whittaker
cargo run --release --example ruviz_gallery_spline_lam_vs_num_knots
cargo run --release --example ruviz_gallery_whittaker_2d_dof
```

## Coverage

| Upstream example | Rust example | Parameter status |
| --- | --- | --- |
| `general/plot_algorithm_convergence.py` | `ruviz_gallery_basic` | Uses `lam=5e6`, `tol=1e-3`, `max_iter=20` and `100`; Rust now exposes and renders full `tol_history` diagnostics for the AsLS and asPLS fits used in this example. |
| `general/plot_masked_data.py` | `ruviz_gallery_basic` | Uses the same synthetic data, mask region, `lam=1e5`, `half_window=35`, linear interpolation, mask-aware arPLS demonstration, and arPLS weighted-interpolation pass using the final arPLS weights. |
| `general/plot_noisy_data.py` | `ruviz_gallery_basic` | Uses the same signal, baseline, noise scale, 11-point smoothing, `modpoly(poly_order=3)`, and `imodpoly(poly_order=3, num_std=0.7)` settings. |
| `general/plot_padding.py` | `ruviz_gallery_basic` | Uses `half_window=80`, `num_points=1000`, `pad_len=161`, and the same padding mode names. |
| `general/plot_padding_extrapolate.py` | `ruviz_gallery_basic` | Uses `num_points=1000`, `pad_len=100`, and `extrapolate_window` values `1`, `100`, and `[100, 40]`. |
| `general/plot_reuse_Baseline.py` | `ruviz_gallery_basic` | Uses matching `num_points=1000` data and the same six method parameter sets: `penalized_poly(poly_order=4)`, `mixture_model(lam=1e5)`, `iarpls(lam=1e5)`, `mor(half_window=30)`, `ria(half_window=20)`, and `std_distribution(half_window=25)`. The timing comparison is represented by Rust's allocation/workspace reuse patterns rather than pybaselines' reusable `Baseline` object. |
| `general/plot_sorted_data.py` | `ruviz_gallery_basic` | Uses matching data and `iarpls(lam=1e6)` on forward and reversed input. |
| `whittaker/plot_lam_effects.py` | `ruviz_lam_effects` | Uses matching signal, baseline, noise scale, arPLS, and lambda values `1`, `1e3`, `1e6`, and `1e10`. |
| `whittaker/plot_lam_vs_data_size.py` | `ruviz_gallery_whittaker_sweeps` | Uses the same `_make_data` baseline formulas, data sizes `[499, 1045, 2186, 4573, 9563, 20000]`, algorithms, coarse/fine lambda search, `tol=1e-2`, and `max_iter=50`. Candidate lambda values that fail a solve are skipped, matching the upstream example behavior. |
| `whittaker/plot_whittaker_solvers.py` | `ruviz_gallery_whittaker_solver_timings` | Uses the same `_make_data` default signal, lambda equation, data sizes `[499, 935, 1748, 3270, 6115, 11437, 21388, 40000]`, `repeats=25`, AsLS, `max_iter=8`, and `tol=-1` to force fixed iterations. The Rust-native timing comparison is allocating `asls` vs reusable-workspace `asls_into`, since this crate has one native pentadiagonal solver instead of SciPy/pentapy backend selection. |
| `morphological/plot_half_window_effects.py` | `ruviz_gallery_basic` | Uses matching data and `half_window` values `30`, `60`, and `120` through Rust full-window sizes `61`, `121`, and `241`. |
| `spline/plot_lam_vs_num_knots.py` | `ruviz_gallery_spline_lam_vs_num_knots` | Uses the same exponential `_make_data` baseline, `mixture_model`, `diff_order=2`, knot counts `[20, 53, 141, 376, 1000]`, data sizes `[500, 1045, 2186, 4573, 9563, 20000]`, coarse/fine lambda search, `tol=1e-2`, and `max_iter=50`. |
| `spline/plot_pspline_whittaker.py` | `ruviz_gallery_pspline_whittaker` | Uses the same exponential `_make_data` baseline, `arpls`, `pspline_arpls`, data sizes `[499, 1045, 2186, 4573, 9563, 20000]`, coarse/fine lambda search, `tol=1e-2`, and `max_iter=50`. |
| `classification/plot_classifier_masks.py` | `ruviz_gallery_basic` | Uses matching data, `std_distribution`, `half_window` values `15` and `45`, `smooth_half_window=10`, and renders the returned baseline masks as signal-context ribbons instead of standalone 0/1 traces. |
| `classification/plot_fastchrom_threshold.py` | `ruviz_gallery_basic` | Uses matching data, `half_window=15`, fixed threshold `1.5`, default 15th-percentile threshold, and the same median fallback used by the upstream example when `scikit-image` is unavailable; renders the returned masks as signal-context ribbons plus rolling standard-deviation thresholds. |
| `misc/plot_beads_preprocessing.py` | `ruviz_gallery_beads_preprocessing` | Uses the same 1000-point grid, signal, three baseline formulas, noise scale, endpoint parabola preprocessing formula, and BEADS parameter sets. The preprocessing figure shows the endpoint parabola against the raw data and known baseline to avoid overlaying parabola-subtracted data on the raw intensity scale. The Rust implementation now uses a banded BEADS solve for this workload. |
| `optimizers/plot_custom_bc_1_whittaker.py` | `ruviz_gallery_basic` | Uses matching data, `lam_flexible=1e2`, `lam_stiff=5e5`, `crossover_index` near `x=160`, `sampling=15`, and smoothing `lam=1e1`. |
| `two_d/plot_along_axes_1d_baseline.py` | `ruviz_gallery_basic` | Uses matching data and the same axis-1 row-wise `pspline_arpls` correction with `lam=1e4`; this is implemented directly in the gallery example because the Rust `individual_axes` helper is intentionally narrower than pybaselines' dynamic method dispatch. |
| `two_d/plot_whittaker_2d_dof.py` | `ruviz_gallery_whittaker_2d_dof` | Uses the same 100x100 grid, `gaussian2d` peak parameters, polynomial and sinusoidal baselines, `lam_poly=(1e2, 1e4)`, `lam_sine=(1e2, 1e0)`, analytical solves, eigen-count cases `(40, 40)`, `(10, 4)`, `(8, 35)`, `(3, 3)`, and `(5, 12)`, `return_dof=true`, `tol=1e-3`, and `max_iter=50`. Rust exposes this through a reduced eigenspace `arpls_eigen` API and returns a diagonal DOF estimate for the plotted eigenvector-selection surface. |

Generated examples should cite pybaselines as a behavioral and documentation
reference only. The Rust implementation does not copy pybaselines implementation
code.