baselines 0.1.0

Baseline correction algorithms for signals, spectra, and images
Documentation

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.

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:

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:

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:

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.