pub struct SpectrumFitResult {Show 18 fields
pub densities: Vec<f64>,
pub uncertainties: Option<Vec<f64>>,
pub reduced_chi_squared: f64,
pub converged: bool,
pub iterations: usize,
pub temperature_k: Option<f64>,
pub temperature_k_unc: Option<f64>,
pub anorm: f64,
pub background: [f64; 3],
pub back_d: Option<f64>,
pub back_f: Option<f64>,
pub t0_us: Option<f64>,
pub l_scale: Option<f64>,
pub energy_scale_flight_path_m: Option<f64>,
pub deviance_per_dof: Option<f64>,
pub baseline: Option<[f64; 3]>,
pub baseline_e_ref_ev: Option<f64>,
pub warnings: Vec<String>,
}Expand description
Result of fitting a single spectrum.
Fields§
§densities: Vec<f64>Fitted areal densities (atoms/barn), one per isotope.
uncertainties: Option<Vec<f64>>Uncertainty on each density.
None when covariance computation was skipped.
reduced_chi_squared: f64Reduced chi-squared of the fit.
converged: boolWhether the fit converged.
iterations: usizeNumber of iterations.
temperature_k: Option<f64>Fitted temperature in Kelvin (only when fit_temperature is true).
temperature_k_unc: Option<f64>1-sigma uncertainty on the fitted temperature (from covariance matrix).
Covariance-only lower bound for the raw-covariance solver paths
(Poisson-KL, joint-Poisson): this is sqrt of the temperature diagonal
of the inverse curvature (Fisher) matrix at convergence. It reflects only
statistical curvature — baseline/model noise is not in the covariance —
so on real data it can underestimate the observed per-superpixel scatter
by ~3–4×. Set UnifiedFitConfig::scale_by_chi2 to inflate it by sqrt
of the goodness-of-fit this result reports (Gaussian reduced_chi_squared
on the transmission paths, deviance_per_dof on the counts joint-Poisson
path) for a goodness-of-fit-scaled estimate. The LM transmission path is
already χ²-scaled (Numerical Recipes §15.6), so the flag is a no-op there.
anorm: f64Fitted normalization scale (SAMMY Anorm). When background
fitting is disabled, the pipeline emits 1.0 (λ̂ absorbs
the scale).
background: [f64; 3]Fitted background polynomial coefficients [BackA, BackB, BackC]
for the SAMMY-style 6-term background:
bg(E) = BackA + BackB / √E + BackC · √E + BackD · exp(-BackF / √E)Both LM-transmission and counts-KL solver paths use the same
SAMMY semantics here — the legacy alpha-fitting [b0, b1, alpha_2] layout was removed when fit_counts_poisson was
retired. When background fitting is disabled, the
pipeline emits [0.0, 0.0, 0.0].
back_d: Option<f64>Fitted exponential background amplitude (SAMMY BackD).
None when the exponential tail is not fitted; Some(value)
when the LM transmission background was active with
fit_back_d=true. Mirrors Self::t0_us /
Self::l_scale semantics so the GUI overlay can
distinguish “unfit” from “fitted to zero” without an ambiguous
0.0 sentinel.
back_f: Option<f64>Fitted exponential background decay constant (SAMMY BackF).
None when the exponential tail is not fitted; Some(value)
when the LM transmission background was active with
fit_back_f=true. Paired with Self::back_d — SAMMY
requires both flags toggled together (see
validate_transmission_background).
t0_us: Option<f64>Fitted TOF offset in microseconds (SAMMY TZERO t₀).
None when energy-scale fitting is not enabled.
l_scale: Option<f64>Fitted flight-path scale factor (SAMMY TZERO L₀, dimensionless).
None when energy-scale fitting is not enabled.
energy_scale_flight_path_m: Option<f64>The nominal flight path (m) the energy-scale fit was configured
with — stored so Self::corrected_energies reproduces the
transform with the SAME flight path the fit used, closing the
caller-resupplied-mismatch channel (issue #634 review: a wrong but
positive flight path silently changes the t₀ term). None when
energy-scale fitting is not enabled.
deviance_per_dof: Option<f64>Conditional binomial deviance divided by (n − k)
(primary GOF for the counts-KL dispatch, i.e.
SolverConfig::PoissonKL on InputData::Counts or
InputData::CountsWithNuisance).
Some(D/dof) when the counts-KL (joint-Poisson) path was used;
None for the LM path and for transmission + PoissonKL (those
populate reduced_chi_squared with Pearson χ² / (n−k) instead).
baseline: Option<[f64; 3]>Fitted multiplicative-baseline coefficients [b0, b1, b2] (issue
#635) for
B(E) = b0 + b1·ln(E/E_ref) + b2·ln²(E/E_ref)applied OUTERMOST: y(E) = B(E)·[Anorm·T + additive background].
None when no multiplicative baseline was configured (values that
were configured but frozen via fit_b0/b1/b2 = false still report
Some — they are part of the model that produced the fit).
baseline_e_ref_ev: Option<f64>Reference energy E_ref (eV) the baseline’s ln(E/E_ref) basis was
centered on — the geometric midpoint √(E_min·E_max) of the fit
grid, stored so consumers reconstruct B(E) with the EXACT
reference the fit used (the same resupply-mismatch channel
Self::energy_scale_flight_path_m closes for the energy scale).
None when no multiplicative baseline was configured.
warnings: Vec<String>Structured fit-configuration warnings (issue #635). Non-fatal
conditions the caller should surface to the user — currently the
degenerate normalization trio (free Anorm + free temperature +
≥1 free density), which on real VENUS data converged to T = 4471 K
with χ²/ν = 932 and no diagnostic. Empty when nothing is flagged.
A Vec<String> rather than tracing: nereids-pipeline has no
tracing dependency, and structured warnings survive across the
PyO3 / GUI boundaries.
Implementations§
Source§impl SpectrumFitResult
impl SpectrumFitResult
Sourcepub fn corrected_energies(
&self,
nominal_energies: &[f64],
) -> Option<Result<Vec<f64>, PipelineError>>
pub fn corrected_energies( &self, nominal_energies: &[f64], ) -> Option<Result<Vec<f64>, PipelineError>>
Map a nominal energy grid through the fitted SAMMY energy scale
(t0_us, l_scale) to the corrected (calibrated) energies the fit
evaluated the physics on (issue #634).
This exposes the transform the fitter used so downstream code never
has to re-derive it — replicating it by hand with a +t0 sign
(instead of the correct −t0) caused a silent +400 K temperature bias
in the field. It reuses the canonical
corrected_energy_grid
(SAMMY dat/mdat0.f90:189, −t0 convention) with the SAME flight path
the fit was configured with (stored on the result), so a mismatched
caller-supplied flight path cannot silently skew the t₀ term.
One divergence from the fit’s internal evaluation: at a DEGENERATE
t0 at/past the grid’s shortest flight time, the model clamps t0
just below the limit and keeps evaluating, while this accessor
returns Some(Err(_)) — a degenerate calibration should be
re-examined, not silently reproduced.
Returns None when energy-scale fitting was not enabled — the
corrected grid would equal the input, but None distinguishes
“not fitted” from “fitted to the identity”.
Trait Implementations§
Source§impl Clone for SpectrumFitResult
impl Clone for SpectrumFitResult
Source§fn clone(&self) -> SpectrumFitResult
fn clone(&self) -> SpectrumFitResult
1.0.0 · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreAuto Trait Implementations§
impl Freeze for SpectrumFitResult
impl RefUnwindSafe for SpectrumFitResult
impl Send for SpectrumFitResult
impl Sync for SpectrumFitResult
impl Unpin for SpectrumFitResult
impl UnsafeUnpin for SpectrumFitResult
impl UnwindSafe for SpectrumFitResult
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
§impl<T> Instrument for T
impl<T> Instrument for T
§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more