API reference#
The package exposes one function and two result types.
- fft_cnr.fft_cnr(x, template=None, *, fit_model=None, window='tukey', tukey_alpha=0.25, welch_nperseg=None, welch_noverlap=None, cutoff_guard=(0.05, 0.5), fallback_cut_frac=0.25, roi=None, return_bandpassed_noise=False, estimate_noise_model=False, rng=None)[source]#
Estimate contrast-to-noise ratio from a single 1-D profile using FFT methods.
Uses unitary FFT normalization, Welch PSD estimation with degrees-of-freedom tracking, AIC-based objective cutoff selection, white-noise matched-filter amplitude estimation, and analytical confidence intervals.
- Parameters:
x (np.ndarray) – Input 1-D signal (e.g., a line profile or spectrum).
template (np.ndarray or None) – Expected signal shape for matched-filter amplitude estimation. If None, amplitude is estimated using the method specified by
fit_model(default:"peak").fit_model (str or None) – Amplitude estimation method when no template is provided.
"peak"(default) applies a spectral low-pass filter and reads the peak from the smoothed signal – robust across arbitrary profile shapes."generalized_gaussian"fits a 5-parameter generalized Gaussian with a shape exponent that accommodates non-zero excess kurtosis, providing fitted parameters (center, width, shape) in diagnostics. Ignored whentemplateis given.window (str) – Tapering window:
"tukey","hann", or"none".tukey_alpha (float) – Shape parameter for the Tukey window (0 = rectangular, 1 = Hann).
welch_nperseg (int or None) – Segment length for Welch PSD estimation. Defaults to max(16, N//8). With 50% overlap this heuristic produces approximately 15 Welch segments at any signal length, giving consistent degrees of freedom for the noise confidence interval. Longer segments reduce the segment count and widen the noise CI substantially without improving CNR accuracy.
welch_noverlap (int or None) – Overlap for Welch segments. Defaults to nperseg // 2.
cutoff_guard (tuple[float, float]) – Fractional bounds for the AIC knee search range.
fallback_cut_frac (float) – Fallback cutoff fraction if AIC selection fails.
roi (str, tuple[int, int], or None) – Restrict the estimate to a region of interest.
None(default) uses the full profile. A(start, stop)index pair estimates on that slice."auto"locates the largest feature (peak or dip) and takes a window scaled to its own width (about +/- 2.5 sigma). Windowing removes off-center low-frequency baseline structure that would otherwise be counted as signal; the chosen bounds are reported indiagnostics["roi"]."auto"locates the largest feature, so when an off-center baseline exceeds the peak of interest, pass explicit bounds instead. The window must span at least 16 points.return_bandpassed_noise (bool) – If True, include the bandpassed noise array in diagnostics.
estimate_noise_model (bool) – If True, fit the photon-transfer relation (var = gain * signal + read**2) to the residual, test the fitted gain for significance against a null calibrated through this same pipeline, and attach the result as
noise_model. Works with every amplitude method. Adds a Monte Carlo cost of about 200 re-runs of the spectral decomposition.rng (numpy.random.Generator or None) – Random generator for the noise-model null calibration. None (default) uses a fixed seed, so repeated calls on the same input give identical results; pass a Generator for independent draws. Unused unless
estimate_noise_modelis True.
- Returns:
Dataclass containing CNR, amplitude, noise, confidence intervals, and diagnostic information. On the localized-peak methods (
peakandgeneralized_gaussian) the diagnostics carrylowfreq_offpeak_ratio– the RMS of low-frequency structure away from the peak, in units of the noise RMS – and the booleanlowfreq_dominated(true above an off-peak ratio of 2.5). A true flag means smooth baseline or fringe structure dominates the profile, so the reported CNR may reflect baseline power rather than the peak; narrow the estimate withroi. The ratio is NaN on the matched-filter (template) path, where the template defines the signal and the off-peak statistic does not apply.The localized-peak methods also carry
amplitude_sign_ambiguous: true when an opposite-sign excursion at least half the chosen feature’s magnitude rivals it, so the largest-magnitude read could switch features (and flip the amplitude sign) under noise. It is False on the matched-filter path, where the template fixes the feature.- Return type:
- Raises:
ValueError – If the input profile has fewer than 16 points, a region of interest spans fewer than 16 points, or a supplied
templateis constant after mean-subtraction (the matched filter is then undefined).
- class fft_cnr.CNREstimate(cnr, cnr_ci95, amplitude, amplitude_se, noise_rms, noise_ci95, cutoff_index, diagnostics, noise_model=None)[source]#
Result of an FFT-based CNR estimation.
- Parameters:
- amplitude#
Estimated signal amplitude. Signed on the peak and generalized-Gaussian paths: negative for a downward (absorption / dark-contrast) feature.
cnruses its magnitude.- Type:
- amplitude_se#
Standard error of the amplitude estimate (NaN if unavailable). On the matched-filter and generalized-Gaussian paths this is a derived standard error; on the default peak path it is an uncharacterized proxy (
sigma / sqrt(kc_full)) that understates the true scatter, so it feedscnr_ci95(where the noise term dominates) but is not exposed throughamplitude_snr.- Type:
- noise_model#
Estimated noise structure, or None when no detector has run.
- Type:
NoiseModel or None
- property amplitude_snr: float#
amplitude over its standard error.
Defined only on the matched-filter (
template) path, where the standard error is the whitened estimator’s, so the ratio is the efficient detectability member of the contrast-to-noise-ratio family. It is NaN on every other path: the peak proxy standard error is uncharacterized, and the generalized-Gaussian standard error is denominated in the fit residual rather than the noise spectrum, so neither is the same statistical object and the values are not comparable. Those paths still exposeamplitude_sedirectly for any caller that wants the raw ratio.- Type:
Matched-filter signal-to-noise ratio
- class fft_cnr.NoiseModel(read, gain, spectral_exponent, white_floor, signal_dependent, correlated)[source]#
Estimated structure of the noise, beyond a single RMS level.
Characterizes the noise along two orthogonal axes. The real-space axis (
read,gain) captures signal-dependent noise via the photon-transfer relationvar = gain * signal + read**2and is populated by theestimate_noise_modeldetector. The spectral axis (spectral_exponent,white_floor,correlated) names spatially correlated,1/f-type noise; these fields are reserved and are not populated. Single-frame quantitative correction of correlated noise is unsupported: the low-frequency model error left by an estimated signal shape is indistinguishable from1/fnoise in one frame, so the spectral exponent and white floor cannot be recovered without bias. Use multiple frames, interleaved acquisition, or a reference channel to characterize and correct correlated noise. White, signal-independent noise is the degenerate case of the real-space axis (zero gain).Real-space numeric fields are NaN and
signal_dependentis None until the detector has run, so “not tested” is distinguishable from “tested, not significant”; the spectral-axis fields stay at those sentinels.- Parameters:
- spectral_exponent#
Reserved (correlated-noise axis); always NaN. Single-frame
1/fcorrection is unsupported (see the class notes above).- Type:
Reserved flag for a correlated-noise detector; always None (detection deferred, no single-frame correction).
- Type:
bool or None