Skip to main content

petektools/
lib.rs

1//! # petekTools
2//!
3//! Standalone numerics & geostatistics kernels for Rust — the layer Rust is
4//! missing. Mature crates cover linear algebra (`faer`), statistics/distributions
5//! (`statrs`, `rand_distr`), FFT (`rustfft`) and spatial indexing (`kiddo`,
6//! `rstar`), but there is **no production-grade scattered-data gridding /
7//! geostatistics** crate. petekTools fills exactly that gap and curates the
8//! rest behind one front-door.
9//!
10//! ## The pillars (module map)
11//! - [`gridding`] — the core gap: scattered-data → grid kernels (`nearest`,
12//!   `idw`, `min_curvature`), warm-start / [`ConvergentGridder`], the
13//!   [`Gridder`] trait + [`OrdinaryKriging`], and the grid → grid [`resample`]
14//!   (native regular grid onto a foreign [`Lattice`], bilinear/nearest).
15//! - [`geostat`] — the geostatistics workflow beyond one global krige:
16//!   experimental variogram + [`Variogram::fit`], moving-neighbourhood
17//!   [`LocalKriging`](geostat::LocalKriging) (scales to tens of thousands of
18//!   points), the [`NormalScore`](geostat::NormalScore) transform, and
19//!   conditional [`sgs`](geostat::sgs) simulation (with collocated cokriging).
20//! - [`stats`] — curated descriptive statistics (unweighted + weighted).
21//! - [`sampling`] — reproducible draws from the common appraisal distributions
22//!   (incl. truncated/clamped bounding), plus the realization-set helpers
23//!   [`reservoir_summary`](sampling::reservoir_summary) (P90=low digest) and
24//!   [`aggregate`](sampling::aggregate).
25//! - [`units`] — domain-agnostic unit conversions (imperial + SI).
26//! - [`container`] — a domain-agnostic single-file section container.
27//! - [`store`] — a domain-agnostic chunked, memory-mapped lane store: the
28//!   spill-to-disk backing for larger-than-memory models (k-slab-major lanes,
29//!   `f32`/`f64`/`u16`/`u32`, deterministic layout, zero-copy views).
30//! - [`formula`] — domain-free assignment parsing, dependency ordering, and
31//!   vectorized scalar/array expression evaluation.
32//! - [`foundation`] — the shared vocabulary ([`Lattice`], [`BBox`],
33//!   [`AlgoError`]).
34//!
35//! A thin **PyO3 wheel** (`petektools` on PyPI) re-exports the Python-relevant
36//! front-door — `sampling` (all `Sampler` variants + a seeded `Rng` giving the
37//! same stream as this crate), `stats`, `reservoir_summary`/`aggregate`, and the
38//! `geostat` kernels. It lives in the `py/` workspace member (maturin,
39//! `publish = false`); `API.md` §"Python (PyO3) surface" is its contract.
40//!
41//! `gridding` and `foundation` are re-exported at the crate root for the common
42//! path; `stats` / `sampling` / `units` / `container` stay deliberately
43//! namespaced (import e.g. `petektools::stats::percentile`,
44//! `petektools::units::bbl_to_m3`).
45//!
46//! ## Charter (what belongs here — and what does not)
47//! - **In:** scattered-data gridding/interpolation (minimum-curvature, IDW,
48//!   nearest today; kriging / RBF later), plus thin curation over the mature
49//!   numeric crates.
50//! - **Out:** file I/O of any kind (that is petekio), and reservoir-domain
51//!   modeling — PVT, rel-perm, material balance, decline, GRV (that is peteksim).
52//!   The deliberate exceptions are [`container`] — a **domain-agnostic** file
53//!   container lifted here so every layer shares one framing — and [`store`],
54//!   the domain-agnostic mmap lane store; both do generic, opaque array/blob I/O
55//!   only (domain/format I/O stays in petekio).
56//!
57//! ## Dependency rule: this crate is a **pure leaf**
58//! It depends only on general-purpose numeric crates — never on petekio or
59//! peteksim. petekio depends on petekTools (for the gridding kernels);
60//! peteksim depends on both. One direction, no cycles.
61//!
62//! ## Type-agnostic boundary
63//! Kernels speak [`Lattice`] (this crate's own geometry vocabulary) + plain
64//! `[[f64; 3]]` coordinate arrays — never a consumer's domain type. petekio's
65//! `GridGeometry` maps onto [`Lattice`] field-for-field, so a future delegation
66//! is a 1:1 conversion at the call site, not a rewrite.
67//!
68//! ## Status
69//! GATE-0 is locked (the [`Lattice`] / [`GridMethod`] / [`grid`] contract + the
70//! three kernels ported from petekio 0.2.0). Shipped since (unreleased, on the
71//! way to 0.2.0): warm-start / [`ConvergentGridder`] gridding, the [`Gridder`]
72//! trait + [`OrdinaryKriging`], the curated [`stats`] and [`sampling`]
73//! front-doors, the [`units`] / [`container`] modules, and the PyO3 `petektools`
74//! wheel (the `py/` member) over the front-door. See `API.md` for the contract.
75
76// The crate is unsafe-free everywhere except the `store` unit, which needs two
77// `memmap2` map calls (each carries a `SAFETY` note + `#[allow(unsafe_code)]`).
78// `deny` (not `forbid`) is what lets that single, documented carve-out compile.
79#![deny(unsafe_code)]
80
81pub mod container;
82pub mod formula;
83pub mod foundation;
84pub mod geostat;
85pub mod gridding;
86pub mod interp;
87pub mod sampling;
88pub mod stats;
89pub mod store;
90pub mod synth;
91pub mod units;
92
93// Curated top-level surface — the front-door consumers import. (Unit conversions
94// stay namespaced under `units` to keep the numeric front-door uncluttered.)
95pub use foundation::{AlgoError, BBox, Lattice, Result};
96pub use gridding::{
97    grid, grid_min_curvature_conditioned, grid_min_curvature_seeded, resample,
98    AnisotropicVariogram, Conditioning, ConvergentGridder, GridMethod, Gridder,
99    MinCurvatureOperator, OrdinaryKriging, ResampleMethod, SpatialVariogram, Variogram,
100    VariogramModel,
101};
102pub use interp::{interp1d, CubicSpline1d, Interp1dMethod};