Skip to main content

Module resolution_calib

Module resolution_calib 

Source
Expand description

Instrument-resolution calibration.

Fits the instrument-resolution parameters of a chosen model family to a known-(ρ, T) calibrant, holding the sample density and temperature FIXED. This is the calibrate step of the standard calibrate→pin→fit procedure: characterize the beamline resolution once on a known standard, pin it, then fit unknown samples (crate::transmission_model / the typed fitters).

Mechanism: an outer crate::nelder_mead optimizer over the few resolution parameters; each evaluation builds a ResolutionFunction from the parameter vector, runs the existing forward_model at the fixed SampleParams, and returns χ²/dof after analytically fitting a normalization (anorm) and optional low-order baseline (so a baseline offset does not leak into the resolution). Calibration is once-per-experiment, so a derivative-free outer loop — not LM resolution-Jacobians — is the right tool; this mirrors the established outer-loop pattern in crate::joint_poisson’s polish stage.

Families (ResolutionFamily):

  • Gaussian — fit (Δt, ΔL).
  • UdrCorr — fit a shape-preserving width correction s(E)=s0·(E/Eref)^p on a base tabulated UDR (TabulatedResolution::width_corrected); trusts the Monte-Carlo shape, calibrates its width/energy-dependence. UDR = User-Defined Resolution, SAMMY’s term for a numerical (table-supplied) resolution function.
  • IkedaCarpenter — physics-complete bounded moderator fit (#642): α(E) = e^{θ0}·√E + e^{θ1} (positive at every energy by construction), β = e^{θ2} (bounded), scalar storage fraction R = θ3 ∈ [0, 1], all folded with the SNS PSR channel triangle (CalibrationConfig::psr_fwhm_ns, default 350 ns; optionally fitted via fit_psr). Beware the β↔R ridge: as R → 0 the storage term vanishes and β is unconstrained — such a fit reports "r:lower" in CalibrationResult::bounds_hit and its β carries no information.

Structs§

CalibrationConfig
Configuration for calibrate_resolution.
CalibrationResult
Result of a resolution calibration.

Enums§

ResolutionFamily
The resolution-model family to calibrate.

Constants§

DEFAULT_PSR_FWHM_NS
Default SNS PSR (proton-storage-ring / accumulator) channel-triangle FWHM in ns, folded into the IC family’s kernel. The SNS proton pulse is shaped by the accumulator ring into an ~triangular ~700 ns base (FWHM ≈ 350 ns) — the VENUS tabulated FTS kernel header records exactly this (“folded triang FWHM 350 ns PSR”). SAMMY’s analog is the Gaussian-burst FWHM DELTAG (Manual Sec. III.C.1.a, eq. III C1 a.12) or square BURST width (Sec. III.C.2.a). pub so the Python binding’s default and the Rust default cannot drift apart.
NS_TO_US
Nanoseconds → microseconds (CalibrationConfig::psr_fwhm_ns is in ns to match the FTS header convention; the kernel synthesis takes µs). pub so the Python binding’s mirrored PSR_FWHM_PIN_CEILING_US check converts with the identical factor.
PSR_FWHM_PIN_CEILING_US
Sanity ceiling (µs) on the configured PSR triangle FWHM: one decade above the PSR_FWHM_US_MAX fit bound. CalibrationConfig::psr_fwhm_ns is in NANOSECONDS (the VENUS FTS header convention: “folded triang FWHM 350 ns PSR”), and kernel-synthesis cost grows QUADRATICALLY with a wide fold’s width. The mechanism is NOT τ-step refinement — that applies only to folds FINER than the prompt design step, and a 50–350 µs fold’s FWHM/3 resolution floor is far coarser, leaving the step unchanged — it is the convolution itself: the ±FWHM fold-reach margin adds O(FWHM/step) τ-samples, each folded in convolve_same against a sampled triangle itself O(FWHM/step) long. Measured ~12 ms at 0.35 µs but ~1.3 s at 50 µs and ~28 s at 350 µs per single kernel-table synthesis at the default grid. A µs-as-ns unit slip (passing 350 meaning µs → interpreted as a 350 µs pin) would therefore turn a calibration into a multi-hour silent hang behind a physically fictitious fold. Any genuine width sits inside the fitted box; one decade of headroom keeps deliberate sensitivity studies possible while still catching the 1000× ns↔µs slip. 0.0 (fold disabled) is always accepted. pub for parity with the Python binding’s mirrored validation.
UDR_S0_MAX
Upper width-scale clamp; see UDR_S0_MIN.
UDR_S0_MIN
Width-scale clamp for the UDR correction (s0 = clamp(exp(log_s0), …)). pub so the Python binding decodes the reported s0 against the same bounds the optimizer used, rather than duplicating the literals.

Functions§

calibrate_resolution
Calibrate the resolution parameters of family against a known-(ρ,T) calibrant.
corrected_energy_grid
Map an energy grid through the SAMMY energy-scale (t0, L_scale), using the SAME convention as EnergyScaleTransmissionModel::corrected_energies: with nominal tof(E) = TOF_FACTOR·L/√E, the corrected energy is E' = (TOF_FACTOR·L·L_scale / (tof − t0))². Identity at (t0, L_scale) = (0, 1).