specsrbench.classical¶
Classical deconvolution methods, parameterised for the log constant-R grid.
The algorithms are carried over unchanged from the original linear-grid build.
What changes here is that the grid-dependent constants are arguments rather
than literals, because every one of them was sized for the old 2,500-point
linear grid where the LSF was ~3 pixels wide. On the specsr DEFAULT_GRID
(log, R=4000, 6,671 points) the same LSF spans ~25 pixels, so the published
defaults are far off.
Two fixes are structural rather than a matter of tuning:
matched_filtertook a fixedwindow_half_um. At 0.015 um that window is 1.11 sigma wide on this grid – narrower than the line being fitted, so the continuum sidebands land inside the line. The window is now set as a multiple of the local LSF width.wiener_deconvandtikhonov_deconvsegment the spectrum before taking an FFT. A 128-sample segment holds only 3 usable Fourier modes at sigma=25 px (it held 21 at sigma=3 px), sosegment_lenis exposed too.
Functions
|
The LSF every classical method deconvolves with, and where it came from. |
|
|
|
|
|
Redshift-informed matched filter. |
|
|
|
|
|
|
|
|
|
Wiener deconvolution, normalised to unit gain at zero frequency. |
- specsrbench.classical.load_sigma_pix(out_dir=None, eval_npz=None)[source]¶
The LSF every classical method deconvolves with, and where it came from.
eval_set.npzships asigma_pixthat nothing in either repo generates and that does not describe the blur in the data: it is roughly constant in nanometres, whereas a spectrograph’s LSF is fixed in detector pixels. Measured against the paired data it is up to 2.3x too broad at 5 um, enough to make Wiener, Tikhonov and TV merge line pairs their own input still resolves.specsrbench.build.lsfmeasures the real one.Every caller that deconvolves reads the kernel through this function, so the tuner, the cache build and the line fits cannot disagree about it – which is exactly how the shipped caches came to be built with one kernel while the parameters had been tuned against another.
Returns
(sigma_pix, provenance). The provenance string starts withSHIPPEDwhen the derived kernel is absent, and callers that write a cache refuse to proceed on that rather than quietly producing wrong numbers.
- specsrbench.classical.wiener_deconv(spec, sigma_pix_arr, snr=10.0, segment_len=128, overlap=32, unit_gain=True)[source]¶
Wiener deconvolution, normalised to unit gain at zero frequency.
The raw MMSE filter W = H/(H^2 + 1/snr) has DC gain 1/(1 + 1/snr), so it rescales the whole spectrum: 0.91 at snr=10, 0.44 at snr=0.8. Tuning it against MAE on z-scored spectra therefore drives snr toward zero, because shrinking a noisy estimate toward the mean lowers absolute error regardless of whether any deconvolution occurred. That is shrinkage, not deconvolution, and it is invisible to any scale-free diagnostic: line S/N is amplitude over sideband noise, so a global rescale leaves it unchanged.
Dividing by W(0) keeps the filter’s shape – which is what distinguishes Wiener from the other methods – while removing its ability to buy MAE with a global rescale. Tikhonov needs no such correction: its W(0) is already 1, which is why it was the one linear filter that did not degenerate.
- specsrbench.classical.matched_filter(spec, wl, z, line_rest_um, sigma_pix_arr, window_nsigma=4.0, detect_snr=3.0, core_nsigma=3.0, sideband_nsigma=2.0, width_scale=0.07)[source]¶
Redshift-informed matched filter.
window_nsigmareplaces the old fixedwindow_half_um: the fitting window is set to this many local LSF sigmas, so it scales with the grid instead of being a constant in microns.width_scalesets the template width as a fraction of the local LSF width, and is the fix for a bug the log grid exposed. The template used to be the prism LSF itself, ~13.5 nm here, while a real line in the high-resolution reference has sigma ~0.96 nm – 14x narrower. Writing a template that wide back over the line core injects flux across a region an order of magnitude broader than the line, inflating the reconstruction’s amplitude by a factor of 1.4-2.2. The old 2,500-point grid hid this: its downsampled reference had broader lines and its LSF was narrower in microns, leaving only a ~3x mismatch.The window, sidebands and continuum fit stay anchored to the LSF width, which is the scale over which local continuum must be estimated; only the template itself is narrowed.