rexafs for Rust
Published user guide · Versioned API reference
Rust-powered X-ray absorption analysis, developed under the codename xraytsubaki. The core includes normalization, AUTOBK, Fourier transforms, group processing, EXAFS fitting, structure handling, LCF/PCA and spectrum tools.
Install the library with cargo add rexafs. In this checkout, run
cargo test -p rexafs to exercise the core regression suite.
Start with a spectrum
use ;
let mut spectrum = read_qas_transmission?;
spectrum.fft?;
assert_eq!;
// For your own data: Spectrum::from_arrays(&energy, &mu)?;
# Ok::
fft() calculates missing normalization and background results using the selected
methods and defaults. normalize(), calc_background(), fft() and ifft()
also support explicit chaining. The same stage names are used in Python and
TypeScript. There is no separate process() facade.
Configure methods with NormalizationMethod, BackgroundMethod, PrePostEdge,
AUTOBK, XrayFFTF and XrayFFTR (the inverse-transform settings). In 0.2.5 and
later, pass settings directly:
use ;
# let energy = ;
# let mu = ;
let mut spectrum = from_arrays?;
let mut background = AUTOBKnew;
background.rbkg = Some; // Low-R background cutoff, in angstroms.
spectrum.set_normalization_method?;
spectrum.set_background_method?;
# Ok::
Rust setters move configurations into the spectrum; clone a reusable setting
explicitly. Version 0.2.4 uses Some(BackgroundMethod::AUTOBK(background)) and
Some(NormalizationMethod::PrePostEdge(parameters)). Those forms and None for
default settings remain supported. Setters invalidate dependent results. Alternative methods
remain selectable; unimplemented methods return explicit errors. Inputs to
from_arrays must be finite, equal-length arrays with strictly increasing energy
in eV. k(), chi() and chir() borrow stored buffers; the other public array
getters return owned copies. A getter returns None when its result is unavailable
and never computes it implicitly.
See the API guide for examples, units and ownership.
Spectrum and Group remain aliases for XASSpectrum and XASGroup.
What the calculations mean
Normalization subtracts a fitted pre-edge baseline and divides absorption by its edge step. AUTOBK estimates the smooth background to obtain the EXAFS oscillations, chi(k). The Fourier transform weights and windows those oscillations to display them against R; its peaks are not automatically phase-corrected bond lengths. An inverse transform filters selected R contributions back into q space.
The processing theory guide explains the equations, symbols, units, assumptions and implementation choices, with scientific references. Use the fitting-statistics guide when interpreting structural fits and uncertainties.
Features and scope
- Default
trust-region: optional fitting solver support. refeff-runner: ReFEFF's Rust EXAFS engine, with path outputs for fitting and therexafs::rmccoordinate-refinement backend (since 0.2.10).feff10-runner: the FEFF10 backend through thefeff10dependency.plotting: core plot builders through ruviz.amcsd,materials-project,cod: optional structure sources.ndarray-compat: legacy ndarray calculation path; the default is nalgebra.
Existing FEFF path files can be fitted without compiling a calculation backend.
FeffFit and the fitting module support single and joint datasets, independent
batches and k/R/q fit spaces. FeffFlavor::Feff10 parsing is still separate from
FEFF10 execution; see the historical compatibility notes in the repository.
The native core has broader APIs than the Python and JavaScript bindings.
Version 0.2.10 includes a reverse Monte Carlo (RMC) engine with ReFEFF as its primary calculator. It supports constrained atomic
moves, finite and periodic geometry, weighted structures, k/R/q/wavelet objectives,
resumable sessions, evolutionary search and structural reports. ReFEFF offers
exact local-input caching and prepared path updates at fixed potentials.
PreparedRefeffCalculator with AccelerationSettings::default() is the recommended
exact caching path. Adaptive scattering is experimental, disabled by default,
and requires explicit opt-in with exact accuracy audits. See the
RMC guide for Rust examples, performance measurements,
scientific assumptions and validation limits. The desktop exposes guided
single-spectrum RMC with live results and saved-run recovery; evolutionary and
weighted-structure controls currently remain Rust APIs.
Licensed under MIT OR Apache-2.0; dependency and fixture notices remain applicable.
Plotting (Feature-Gated)
Core plotting is available behind the plotting feature using ruviz.
The complete plot_demo also runs external FEFF85L modules. Install the FEFF
binaries supplied with XrayLarch and set REXAFS_FEFF8L_RDINP to the path of
feff8l_rdinp if the example cannot discover it. The plotting builders themselves
do not require that executable when plotting existing spectra or fit results.
On Apple Silicon, if your linker resolution requires an explicit target linker:
CARGO_TARGET_AARCH64_APPLE_DARWIN_LINKER=clang
plot_demo writes outputs to:
crates/rexafs/target/plot_demo
plot_demo coverage:
- FEFF85L module runs from full
feff.inp:Co,FeO_withPb,MnO2,ZnSe - Real fitting via
FeffFit::fit():Cu,ZnSe - Fit plots per material:
k,k + window,r,r + window range
To regenerate Cu/ZnSe fit references directly from XrayLarch:
FEFF fit compatibility is regression-tested against these regenerated Cu/ZnSe fixtures:
- compared fields:
amp,de0,sig2,drvalues andstderr - compared stats:
chi_square,reduced_chi_square,n_idp,r_factor - tolerance policy: relative tolerance
20%with absolute fallback1e-8(de0value uses0.2 eVabsolute fallback near zero)
Important behavior
- Plotting APIs are available through
PlotXASwith a mutable entrypoint:plot(&mut self). - Plot text rendering uses
typst(true)by default for scientific notation-friendly labels/ticks. - Plotting auto-computes missing intermediates when required:
mu()may callnormalize()and renders flattenedmu(E)by defaultnorm()may callnormalize()k()may callcalc_background()r()may callcalc_background()andfft()
k()panels use symmetric y-limits (-y_lim..y_lim) and y-axis units derived fromkweight.FeffFitResult::plot().k()defaults to fit/datasetkweightunless.kweight(...)overrides it.r()panels default toxlim(0.0, 6.0).r()defaults to magnitude traces. Calling.real()and/or.imag()switches to those components unless.mag()is also included (e.g..r().mag().real().imag()).FeffFitResult::plot().r()includes path|chi(R)|traces when magnitude is active.- Window overlays are disabled by default.
.window(true)is an alias that enables both.window_fn(true)and.window_box(true)fork()panels..window_fn(...)is supported only onk()panels..window_box(...)is supported onk()panels, and onr()panels forFeffFitResultplots; it renders two range markers (min/max), not a rectangle.FeffFitResultnow includesvarying_names,covariance, andcorrelation(matrix order followsvarying_names).save_png()combines multiple panels.to_svg()andrender_plot()require a single panel;to_svg_panels()returns a separate SVG string for each panel.
XASSpectrum examples
use *;
use load_spectrum_QAS_trans;
let path = format!;
let mut spectrum = load_spectrum_QAS_trans?;
spectrum.plot.mu.save_png?;
spectrum.plot.norm.edges.save_png?;
spectrum.plot.k.kweight.window.save_png?;
spectrum.plot.r.save_png?;
spectrum.plot.r.real.save_png?;
spectrum.plot.r.mag.real.imag.save_png?;
spectrum
.plot
.mu
.norm
.k
.r
.title
.save_png?;
# Ok::
XASGroup examples
use *;
let mut group = new;
// populate group.spectra ...
group.plot.mu.save_png?;
group.plot.mu.select.save_png?;
group.plot.mu.stacked.save_png?;
# Ok::
FeffFitResult examples
use *;
let mut fit = default;
// populate fit result vectors or datasets ...
fit.plot.k.save_png?; // uses fit kweight by default
fit.plot.k.window.save_png?; // with window
fit.plot.r.save_png?; // includes path |chi(R)| traces
fit.plot.r.window_box.save_png?; // with range markers
fit.plot.r.real.save_png?;
fit.plot.r.mag.real.imag.save_png?;
fit.plot.k.dataset.save_png?;
# Ok::
Universal measurement reader (since 0.2.6)
Version 0.2.6 adds content-detected beamline text, CSV, Athena, XTUNES and HDF5 import through the shared Rust reader. Read a document, inspect its scans, columns, units and warnings, then select a signal mapping. Ambiguous channels require explicit selection; detector images require reduction before creating an absorption spectrum. Reading performs no processing or corrections. See the reader guide for language examples, unit conversions, dataset selection, fixture coverage and limits. This API is not included in the published 0.2.5 packages.
Larix 1.0 session import is available in the shared reader since 0.2.6, including stored absorption, complex saved arrays and inert session metadata. See the Larix import guide.