stdpipe.fringe_removal module¶
Fringe removal for astronomical images.
The main routine, remove_fringes(), models the fringe pattern as a
smooth two-dimensional field at intermediate spatial scales (between stellar
FWHM and the coarse sky background) and estimates it directly in image space:
sources are masked, and the masked pixels are transparently “inpainted” by
NaN-aware Gaussian smoothing, so the fringe structure is continued under the
stars. This works for realistic curved, non-stationary fringes where
frequency-domain methods fail.
The module also provides Fourier notch filtering
(remove_fringes_fourier()) for genuinely periodic patterns such as
electronic pickup noise, and visualize_fourier_spectrum() for
diagnostics.
- stdpipe.fringe_removal.remove_fringes(image, mask=None, scale='auto', noise_frac=0.25, bg_size=256, threshold=2.0, dilate=2, iterations=3, halo_sn=20.0, get_fringe_model=False, verbose=False)[source]¶
Remove fringes by estimating a smooth intermediate-scale background map with sources masked and inpainted.
The algorithm exploits the scale separation between stars (~FWHM, a few pixels), fringes (tens of pixels) and the sky background (hundreds of pixels):
Subtract a coarse sky background (SEP mesh of
bg_sizepixels)Around bright stars (peaks above
halo_snsigmas with footprints wider than the smoothing kernel), model the non-monotone azimuthally symmetric circumstellar structure - ghost reflection rings, background estimation bowls - as azimuthal-median radial profiles with their smooth monotone envelope (the stellar wings and halo) removed, and subtract it from the working residual. This captures circular artifacts with full circular fidelity, which isotropic smoothing cannot doMask pixels deviating by more than
thresholdsigma (sources and outliers), grow the mask bydilatepixelsSmooth the masked residual with a Gaussian of sigma
scalepixels using mask-aware normalized convolution - masked pixels are filled by the weighted average of the surrounding fringe structure (inpainting), each region by the finest scale of a multi-scale ladder that still has unmasked support there. The smoothing also absorbs the smooth sub-threshold envelope of stellar halos and wingsIterate: re-mask on the fringe-subtracted residual (so that fringe crests are not mistaken for sources), smooth it again and add to the fringe map. The additive refinement also recovers the part of the fringe structure attenuated by the smoothing, so narrower fringes are progressively captured with each iteration
The radial circumstellar fields are included in the returned fringe map and thus subtracted from the image along with the fringes.
The resulting fringe map is defined everywhere, including under the stars, and is subtracted from the original image. The coarse sky background is left in the image.
- Parameters:
- imagendarray
Input image
- maskndarray, optional
Boolean mask (True = masked pixels to exclude from fringe estimation)
- scalefloat or ‘auto’
Sigma of the Gaussian smoothing kernel in pixels. Should be of order the stellar FWHM or somewhat larger, and well below the narrowest fringe period. Smaller values track narrower fringes at the cost of slightly more noise and source flux absorbed into the map. If
'auto'(default), the scale is selected from the measured fringe-to-noise ratio (6 px for strong, sharp fringes up to a few tens of px for faint, broad ones), so that noise does not leak into the fringe model. Pass a number to set it explicitly.- noise_fracfloat
Aggressiveness of the automatic scale selection (used only when
scale='auto'). The smallest scale whose predicted noise floor falls belownoise_fractimes the fringe amplitude is chosen. Smaller values give cleaner (less noisy) models but larger kernels, which can over-smooth very faint, broad fringes; larger values keep smaller kernels at the cost of more noise in the model. Default: 0.25- bg_sizeint or None
Mesh size in pixels for the coarse sky background subtracted before fringe estimation. Should be much larger than the fringe scale. If None, the global median is used instead. Default: 256
- thresholdfloat
Source masking threshold in sigmas of the local background RMS. Applied symmetrically (both positive and negative outliers are masked) to avoid biasing the fringe map. Default: 2.0
- dilateint
Number of binary dilation iterations applied to the source mask to cover the wings of the sources. Default: 2
- iterationsint
Number of refinement iterations. Each iteration re-derives the source mask from the fringe-subtracted residual (the first one has to mask on the raw residual where fringe crests may exceed the threshold) and accumulates the smoothed residual into the fringe map. More iterations capture narrower fringes but absorb more noise. Default: 3
- halo_snfloat or None
Peak significance (in sigmas) above which a source is considered bright enough to have halos and gets the radial halo treatment. Should be well above the peak significance of the fringe crests. Only sources whose thresholded footprint radius also exceeds
scaleare treated (ordinary stars have compact footprints and are not affected). None disables the halo modeling. Default: 20- get_fringe_modelbool
If True, return (corrected_image, fringe_model). Default: False
- verbosebool or callable
Whether to show verbose messages during the run. May be either boolean, or a
print-like function.
- Returns:
- corrected_imagendarray
Image with the fringe map subtracted
- fringe_modelndarray, optional
The subtracted fringe map (if get_fringe_model=True)
Notes
Circumstellar structures - halos, ghost rings, background bowls - are locally indistinguishable from fringes (smooth structures at similar scales). The smooth ones are absorbed by the masked multi-scale smoothing along with the fringes; sharply circular ones (ghost donuts, bowls) are additionally captured with full circular fidelity by azimuthal-median radial profiles around bright stars (the
halo_snmechanism), which average the oscillating fringes passing through to nearly zero. Everything smooth or circular around bright stars is thus subtracted, including the sub-threshold part of their PSF wings; the star cores and everything above the masking threshold stay in the image. Use halo_sn=None to disable the radial modeling (isotropic smoothing only).Faint extended sources (low surface brightness galaxies, nebulae) whose peaks stay below
halo_snremain partially degenerate with the fringe pattern: the part below the masking threshold gets absorbed into the fringe map and over-subtracted. For fields dominated by such sources, lowerhalo_sn, increasescale, or mask the sources explicitly via themaskargument.Examples
>>> corrected = remove_fringes(image, mask=mask, scale=6) >>> corrected, fringes = remove_fringes(image, get_fringe_model=True)
- stdpipe.fringe_removal.remove_fringes_fourier(image, mask=None, fwhm=None, method='global', period_range=(30, 200), sigma_threshold=2.0, notch_width=3.0, protect_low_freq=True, protect_high_freq=True, get_fringe_model=False, verbose=False)[source]¶
Remove periodic patterns from image using Fourier notch filtering.
Suitable for genuinely periodic, stationary patterns (electronic pickup noise, readout banding) that produce sharp peaks in Fourier space. Realistic sky fringes are usually curved and non-stationary, with power spread over a broad frequency annulus - use
remove_fringes()for those instead.- Parameters:
- imagendarray
Input image
- maskndarray, optional
Boolean mask (True = masked pixels to exclude from analysis)
- fwhmfloat, optional
Stellar FWHM (pixels) for protecting high-frequency stellar content. If None, no high-frequency protection is applied.
- methodstr
Pattern removal method:
‘global’: Detect and notch out power spectrum peaks (default)
‘bandpass’: Suppress a whole frequency range given by period_range
- period_rangetuple
Expected pattern period range (min, max) in pixels. Default: (30, 200)
- sigma_thresholdfloat
Threshold for automatic peak detection (in sigma above median power). Higher = more conservative. Default: 2.0
- notch_widthfloat
Width of notch filter in frequency pixels. Larger = more aggressive. Default: 3.0
- protect_low_freqbool
If True, don’t filter very low frequencies (large-scale background). Default: True
- protect_high_freqbool
If True, protect high frequencies based on stellar FWHM. Requires
fwhm. Default: True- get_fringe_modelbool
If True, return (corrected_image, fringe_model). Default: False
- verbosebool or callable
Print diagnostic information
- Returns:
- corrected_imagendarray
Image with the periodic pattern removed
- fringe_modelndarray, optional
Removed pattern (if get_fringe_model=True)
Examples
>>> # Automatic peak detection and notching >>> corrected = remove_fringes_fourier(image, fwhm=3.0) >>> # Bandpass filtering for known period range >>> corrected = remove_fringes_fourier( ... image, method='bandpass', period_range=(50, 150), fwhm=3.0)
- stdpipe.fringe_removal.detect_fringe_peaks_fft(image, mask=None, sigma_threshold=5.0, period_range=(30, 200), fwhm=None, protect_low_freq=True, protect_high_freq=True, verbose=False)[source]¶
Detect peaks in the Fourier power spectrum corresponding to periodic patterns (e.g. electronic pickup noise).
Note that realistic sky fringes are usually not periodic - their power is spread over a broad annulus in frequency space with no distinct peaks. Use
remove_fringes()for those.- Parameters:
- imagendarray
Input image
- maskndarray, optional
Boolean mask (True = masked pixels)
- sigma_thresholdfloat
Detection threshold in sigma above median power
- period_rangetuple
(min_period, max_period) in pixels
- fwhmfloat, optional
Stellar FWHM for protecting high frequencies
- protect_low_freqbool
Exclude very low frequencies (large-scale background)
- protect_high_freqbool
Exclude high frequencies (stellar content); requires
fwhm- verbosebool
Print diagnostic information
- Returns:
- peakslist of tuples
List of (fy, fx, period) peak positions in Fourier space (pixel offsets relative to the spectrum center) and the corresponding spatial period in pixels
- stdpipe.fringe_removal.create_notch_filter(shape, peaks, width=3.0, smooth=True)[source]¶
Create notch filter to suppress specific Fourier peaks.
- Parameters:
- shapetuple
Image shape (ny, nx)
- peakslist of tuples
Peak positions [(fy1, fx1), (fy2, fx2), …] or [(fy1, fx1, period1), …]
- widthfloat
Notch width in frequency pixels
- smoothbool
If True, use Gaussian notch; if False, use hard cutoff
- Returns:
- filterndarray
2D filter mask (1 = pass, 0 = suppress)
- stdpipe.fringe_removal.create_bandpass_filter(shape, period_range, smooth=True)[source]¶
Create band-stop (notch) filter to suppress specific period range.
This is actually a band-STOP filter that suppresses frequencies corresponding to the given period range while passing others.
- Parameters:
- shapetuple
Image shape (ny, nx)
- period_rangetuple
(min_period, max_period) in pixels to SUPPRESS
- smoothbool
If True, use smooth Gaussian rolloff; if False, hard cutoff
- Returns:
- filterndarray
2D band-stop filter (1 = pass, 0 = suppress, smooth transition if smooth=True)
- stdpipe.fringe_removal.visualize_fourier_spectrum(image, peaks=None, period_range=None, fwhm=None, log_scale=True, vmax_percentile=99.9, save_path=None)[source]¶
Visualize 2D Fourier power spectrum with detected peaks.
Useful for debugging and parameter tuning.
- Parameters:
- imagendarray
Input image
- peakslist of tuples, optional
Detected peak positions [(fy, fx), …]
- period_rangetuple, optional
If provided, overlay search region
- fwhmfloat, optional
If provided, overlay high-frequency protection boundary
- log_scalebool
Use log scale for power spectrum
- vmax_percentilefloat
Percentile for color scale maximum
- save_pathstr, optional
If provided, save plot to this path
- Returns:
- figmatplotlib.figure.Figure
The figure object