rexafs for Rust
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.
Publication on crates.io is pending. In this checkout, run cargo test -p rexafs.
After publication, add the library with cargo add rexafs.
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. The standalone process() facade has been removed.
Configure methods with NormalizationMethod, BackgroundMethod, PrePostEdge,
AUTOBK and XrayFFTF. 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. Result getters expose the spectrum's intermediate and final arrays.
See the API guide for examples, units and ownership.
Spectrum and Group remain aliases for XASSpectrum and XASGroup.
Features and scope
- Default
trust-region: optional fitting solver support. refeff-runner: ReFEFF's Rust EXAFS engine, with path outputs for fitting.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.
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.
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:
Strict FEFF fit parity 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).- Multi-panel output is PNG-only in this phase.
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::