# baselines
`baselines` is a Rust crate for baseline correction of signals, spectra, and
row-major two-dimensional surfaces. It is an independent Rust implementation
inspired by the baseline correction literature and by the public behavior of
[`pybaselines`](https://pybaselines.readthedocs.io/).
```rust
use baselines::prelude::*;
let y = vec![1.0, 1.1, 4.2, 1.2, 1.0];
let fit = Baseline::new(&y)
.asls()
.lambda(1.0e6)
.p(0.01)
.fit()?;
let corrected = fit.corrected(&y)?;
# Ok::<(), baselines::BaselineError>(())
```
## Scope
The crate starts with CPU `f64` implementations and public entry points for
the current one-dimensional `pybaselines.Baseline` algorithm families:
polynomial, Whittaker, morphology, penalized spline, smoothing,
classification, optimizer, and miscellaneous methods. Two-dimensional support
is staged under `baselines::two_d`; all pinned `pybaselines.Baseline2D` 1.2.1
families now have first-pass native Rust implementations.
Algorithms are organized by family module. Core data types such as `Fit1D`,
`Fit2D`, and row-major matrix views are available at the crate root. The
recommended Rust API starts from `Baseline::new(&y)` for 1D data and
`Baseline2D::row_major(&data, rows, cols)` for row-major 2D data. The explicit
family modules and parameter structs remain public for advanced workflows and
for users who prefer free functions.
Golden fixtures generated from a pinned `pybaselines` release check the
one-dimensional algorithms with algorithm-specific tolerances. GPU support is
feature-gated behind `gpu-wgpu`; the experimental WGPU path provides batched
`f32` morphology kernels for moving minimum, moving maximum, opening, and the
top-hat baseline primitive.
See `docs/PARITY.md` for the current pybaselines parity matrix, 2D tolerance
ledger, and known limits.
See `docs/performance/` for checked-in benchmark records, including the
2026-05-24 full Criterion baseline and the measured BEADS optimization result.
## Visual examples
The crate includes `ruviz` examples for inspecting generated baselines as PNGs:
```console
cargo run --example ruviz_1d
cargo run --example ruviz_2d
cargo run --example ruviz_lam_effects
```
The examples write images to `docs/assets/ruviz/`. The generated PNGs are
tracked for Markdown preview and excluded from Cargo packages. The 1D example plots
observed spectra, AsLS/arPLS baselines, and corrected signals. The 2D example
writes heatmaps for the observed surface, fitted AsLS baseline, true synthetic
baseline, and corrected surface.
`ruviz_lam_effects` mirrors the upstream Whittaker gallery example from
pybaselines for arPLS lambda selection, using the same synthetic signal,
exponential baseline, noise scale, and lambda values. The noise is generated by
a small deterministic Rust generator rather than NumPy's bit generator, so the
shape and parameters match the gallery example but the exact noise samples do
not.
See `docs/GALLERY.md` for the generated-output index and runnable source files,
or open the `gallery` page in generated Rust docs. See
`docs/PYBASELINES_EXAMPLES.md` or the `reference_examples` rustdoc page for
the upstream gallery coverage matrix.
## API style
Use the method-chain API for ordinary fits:
```rust
use baselines::prelude::*;
let fit = Baseline::new(&y)
.arpls()
.lambda(1.0e6)
.max_iter(50)
.tol(1.0e-3)
.fit()?;
# Ok::<(), baselines::BaselineError>(())
```
Use the lower-level family modules when you want to pass a complete params
struct, reuse workspaces, or compare directly against existing code:
```rust
use baselines::whittaker::{AslsParams, asls};
let fit = asls(&y, AslsParams::default())?;
# Ok::<(), baselines::BaselineError>(())
```
See `docs/API.md` for more examples.
## Attribution
This project does not copy implementation code from `pybaselines`. The Python
project is used as a documentation and behavioral reference, and golden
fixtures should record the pybaselines version that generated them.
Please cite the original algorithm papers as appropriate. See `NOTICE.md` and
`CITATION.cff` for project-level attribution.