pub struct MultiplicativeBaselineConfig {
pub b0_init: f64,
pub b1_init: f64,
pub b2_init: f64,
pub fit_b0: bool,
pub fit_b1: bool,
pub fit_b2: bool,
pub spatial_global: bool,
pub b0_bounds: (f64, f64),
pub b1_bounds: (f64, f64),
pub b2_bounds: (f64, f64),
}Expand description
Bounded multiplicative polynomial baseline (issue #635):
y(E) = (b0 + b1·z + b2·z²) · T_model(E) with z = ln(E/E_ref) and
E_ref = √(E_min·E_max) of the fit grid.
A NEREIDS extension (see MultiplicativeBaselineModel for the SAMMY
departure record): real VENUS sample/open-beam ratios sit a few % from
unity with smooth energy dependence, and freeing the SAMMY Anorm
together with temperature and density is degenerate on such data
(IPTS-37432 finding A3: T → 4471 K with no warning). The bounded
multiplicative form fitted jointly with temperature at fixed density is
the production recipe (χ²/ν ≈ 2–8 across the 20-run campaign).
b0 is exactly degenerate with Anorm, so a free Anorm alongside ANY
configured baseline — even a fully frozen one — is rejected
(validate_multiplicative_baseline). A frozen-b0 + free-Anorm
combination would be well-posed, but supporting it buys nothing (Anorm
would just play b0’s role at a rescaled value); the sanctioned
combination is the additive ABC(+DF) background with fit_anorm = false.
What prevents the A3-style runaway is SMOOTHNESS, not amplitude: a
single global quadratic in ln E cannot produce a narrow local feature at
a resonance whatever its coefficients, so the dips stay attributed to
the physics model. The (configurable) coefficient boxes bound the
baseline’s overall tilt/curvature PER ln-E UNIT, not the evaluated
B(E) itself: the worst-case excursion from b0 grows with the grid’s
log-width, |B − b0| ≤ |b1|·|z|_max + |b2|·z²_max (≈ ±0.23 beyond
b0’s own ±0.1 box on a 1–30 eV grid at the default ±0.05 boxes; more
on wider grids, where only the runtime B(E) > 0 guard applies).
“A few % off unity” describes the typical FITTED values on campaign
data and the hard b0 box at mid-grid — not a hard envelope on B(E)
across the grid.
Fields§
§b0_init: f64Initial mid-grid baseline value b0 (default 1.0).
b1_init: f64Initial slope per ln-E unit b1 (default 0.0).
b2_init: f64Initial curvature per ln-E² unit b2 (default 0.0).
fit_b0: boolWhether b0 is free (default true). All-false = frozen baseline
(the #633 fixed-parameter pattern; used by the spatial global mode).
fit_b1: boolWhether b1 is free (default true).
fit_b2: boolWhether b2 is free (default true).
spatial_global: boolspatial_map_typed only: fit ONE baseline on the aggregated mean
spectrum, then freeze it for every pixel (default true — per-pixel
baselines on <500 counts/bin biased fitted temperatures by up to
+150 K on IPTS-37432; the global mode removed 80 % of that).
Ignored by the single-spectrum fitters.
b0_bounds: (f64, f64)Optimizer box for b0 (default (0.9, 1.1) — “a few % off unity”).
b1_bounds: (f64, f64)Optimizer box for b1 (default (-0.05, 0.05)).
b2_bounds: (f64, f64)Optimizer box for b2 (default (-0.05, 0.05)).
Trait Implementations§
Source§impl Clone for MultiplicativeBaselineConfig
impl Clone for MultiplicativeBaselineConfig
Source§fn clone(&self) -> MultiplicativeBaselineConfig
fn clone(&self) -> MultiplicativeBaselineConfig
1.0.0 · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreSource§impl Debug for MultiplicativeBaselineConfig
impl Debug for MultiplicativeBaselineConfig
Auto Trait Implementations§
impl Freeze for MultiplicativeBaselineConfig
impl RefUnwindSafe for MultiplicativeBaselineConfig
impl Send for MultiplicativeBaselineConfig
impl Sync for MultiplicativeBaselineConfig
impl Unpin for MultiplicativeBaselineConfig
impl UnsafeUnpin for MultiplicativeBaselineConfig
impl UnwindSafe for MultiplicativeBaselineConfig
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