pub fn fit_open_beam(
time_edges_us: &[f64],
open_counts: &[f64],
calibration: &Calibration,
open_live: Option<&[f64]>,
) -> Result<OpenBeamFit, PipelineError>Expand description
Fit the beam to the raw open-beam counts open_counts of the time bins
time_edges_us (µs), each bin recording the fraction open_live of the
neutrons arriving in it, or every one when that is None. ln φ, the
logarithm of the beam, is a cubic spline in ln u with knots from the
first edge’s flight time to the last edge’s; outside them the beam is the
spline’s continuation, which reaches the bins only through the pulse’s
delay or, for a folded pulse, its early tail. Neutrons faster than the
grid’s range, each reaching the bins with less than
NEGLIGIBLE_ARRIVAL_PROBABILITY
chance, are left out.
The number of spline intervals doubles from one while the coefficients
number at most half the bins. Each candidate is fitted on a grid halved,
and the beam refitted on each finer grid, until the refitted beam’s
predicted counts differ from the coarser grid’s by at most BOUND. A
candidate that does not converge, or needs more grid points than allowed,
ends the ladder. The candidate with the lowest D / overdispersion + 2k is
returned, D twice its deviance and k its coefficients.
Counts too sparse to determine the beam are not supported: the fit may not
converge, may leave coefficients undetermined (NaN in covariance), or,
when its beam varies faster than a grid within the point cap resolves, end
the ladder or, for the first candidate, refuse the fit.
Beam structure at or near the window’s first edge is not supported: before
the edge, where neutrons reach the bins only through the pulse’s delay, the
beam is the spline’s continuation, which the counts cannot check. Its error
biases the fitted beam near that edge and, through the continuation’s mean
curvature, elsewhere; structure just before the edge can leave the first
bins unmatched, which shows as at_limit with an overdispersion far above
the detector’s. Start the window where the beam is smooth.
§Errors
PipelineError::ShapeMismatch unless there is one count, and one live
fraction when given, per bin;
PipelineError::InvalidParameter if a count is not a whole non-negative
number, every count is zero, a live fraction is not in (0, 1], or there are
fewer than 8 bins (one interval’s four coefficients and as many bins again
to measure the noise);
PipelineError::FlightTimeGrid for the grid’s refusals, including the
first candidate’s halving past the point cap; PipelineError::Fitting if
the fitter refuses.