Skip to main content

SpectrumFitResult

Struct SpectrumFitResult 

Source
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: f64

Reduced chi-squared of the fit.

§converged: bool

Whether the fit converged.

§iterations: usize

Number 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: f64

Fitted 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

Source

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

Source§

fn clone(&self) -> SpectrumFitResult

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for SpectrumFitResult

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts 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 more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts 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
§

impl<T> Pointable for T

§

const ALIGN: usize

The alignment of pointer.
§

type Init = T

The type for initializers.
§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
§

impl<T> PolicyExt for T
where T: ?Sized,

§

fn and<P, B, E>(self, other: P) -> And<T, P>
where T: Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns [Action::Follow] only if self and other return Action::Follow. Read more
§

fn or<P, B, E>(self, other: P) -> Or<T, P>
where T: Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns [Action::Follow] if either self or other returns Action::Follow. Read more
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a [WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a [WithDispatch] wrapper. Read more