flint.bane

BANE, the background and noise estimator, computed with FFTs.

Ported from AegeanTools.BANE_fft, single planes only. step is a downsampling factor and box a kernel size.

Attributes

Classes

BANEMaps

The pair of maps bane_fits_image writes

Functions

_downsample_slices(→ tuple[slice, slice])

Slices taking every step_size_pix pixel from step_size_pix on, an even count

_ft_kernel(→ numpy.typing.NDArray[numpy.float32])

FFT of kernel, zero-padded out to shape

_needs_a_beam(→ bool)

Whether get_kernel will read the beam, rather than take both sizes as given

bane_fft(→ tuple[numpy.typing.NDArray[numpy.float32], ...)

Background and RMS of image, which must be zero wherever valid is

bane_fits_image(→ BANEMaps)

Write _bkg.fits and _rms.fits maps beside a single-plane FITS image.

bane_round(...)

Clip sources against background and rms, refill them with noise, smooth

bilinear_upsample(→ numpy.typing.NDArray[numpy.float32])

Interpolate grid, sampled at pixels start + k * step, onto shape

box_stats(→ tuple[numpy.typing.NDArray[numpy.float32], ...)

Clipped median and sigma of a box-wide square every step pixels.

clipped_stats(→ tuple[float, float])

Median and MAD-based sigma of sorted values, clipped at 3 sigma until stable

fft_average(→ numpy.typing.NDArray[numpy.float32])

Convolve image by kernel, normalised so a flat image is unchanged

gaussian_kernel(→ numpy.typing.NDArray[numpy.float32])

Gaussian kernel of fwhm pixels

get_kernel(...)

The convolution kernel and downsampling factor, in pixels.

local_seed(...)

Background and RMS maps from the clipped statistics of overlapping boxes.

pad_reflect(→ numpy.typing.NDArray[numpy.float32])

np.pad(array, pad_width, mode="reflect"), in a form numba can compile

robust_bane(...)

Background and RMS maps of a single image plane.

tophat_kernel(→ numpy.typing.NDArray[numpy.float32])

Circular tophat kernel of diameter pixels

Module Contents

class flint.bane.BANEMaps[source]

Bases: NamedTuple

The pair of maps bane_fits_image writes

bkg_image: pathlib.Path[source]

Background map

rms_image: pathlib.Path[source]

RMS noise map

flint.bane._downsample_slices(shape: tuple[int, int], step_size_pix: int) → tuple[slice, slice][source]

Slices taking every step_size_pix pixel from step_size_pix on, an even count

flint.bane._ft_kernel(kernel: numpy.typing.NDArray[numpy.float32], shape: tuple) → numpy.typing.NDArray[numpy.float32][source]

FFT of kernel, zero-padded out to shape

flint.bane._needs_a_beam(fft_bane_options: flint.options.FFTBANEOptions) → bool[source]

Whether get_kernel will read the beam, rather than take both sizes as given

flint.bane.bane_fft(image: numpy.typing.NDArray[numpy.float32], kernel: numpy.typing.NDArray[numpy.float32], valid: numpy.typing.NDArray[numpy.float32]) → tuple[numpy.typing.NDArray[numpy.float32], numpy.typing.NDArray[numpy.float32]][source]

Background and RMS of image, which must be zero wherever valid is

flint.bane.bane_fits_image(image: pathlib.Path, fft_bane_options: flint.options.FFTBANEOptions | None = None) → BANEMaps[source]

Write _bkg.fits and _rms.fits maps beside a single-plane FITS image.

Parameters:
  • image (Path) – Single-plane FITS image to measure

  • fft_bane_options (FFTBANEOptions | None, optional) – Step, box, kernel, clip and seed. Defaults to FFTBANEOptions().

Returns:

The background and RMS maps written

Return type:

BANEMaps

flint.bane.bane_round(image: numpy.typing.NDArray[numpy.float32], nan_mask: numpy.typing.NDArray[numpy.bool_], background: numpy.typing.NDArray[numpy.float32], rms: numpy.typing.NDArray[numpy.float32], kernel: numpy.typing.NDArray[numpy.float32], step_size_pix: int, clip_sigma: float, rng: numpy.random.Generator, round_number: int) → tuple[numpy.typing.NDArray[numpy.float32], numpy.typing.NDArray[numpy.float32]][source]

Clip sources against background and rms, refill them with noise, smooth

flint.bane.bilinear_upsample(grid: numpy.typing.NDArray[numpy.float32], start: float, step: float, shape: tuple[int, int]) → numpy.typing.NDArray[numpy.float32][source]

Interpolate grid, sampled at pixels start + k * step, onto shape

flint.bane.box_stats(image: numpy.typing.NDArray[numpy.float32], nan_mask: numpy.typing.NDArray[numpy.bool_], step: int, box: int) → tuple[numpy.typing.NDArray[numpy.float32], numpy.typing.NDArray[numpy.float32]][source]

Clipped median and sigma of a box-wide square every step pixels.

About 20 by 20 pixels are sampled from each box. NaN where fewer than 30 of them are valid.

flint.bane.clipped_stats(values: numpy.typing.NDArray[numpy.float32]) → tuple[float, float][source]

Median and MAD-based sigma of sorted values, clipped at 3 sigma until stable

flint.bane.fft_average(image: numpy.typing.NDArray[numpy.float32], kernel: numpy.typing.NDArray[numpy.float32]) → numpy.typing.NDArray[numpy.float32][source]

Convolve image by kernel, normalised so a flat image is unchanged

flint.bane.gaussian_kernel(fwhm: int) → numpy.typing.NDArray[numpy.float32][source]

Gaussian kernel of fwhm pixels

flint.bane.get_kernel(header: astropy.io.fits.Header | dict[str, Any], step_size: int | None = None, box_size: int | None = None, kernel_func: collections.abc.Callable[[int], numpy.typing.NDArray[numpy.float32]] = gaussian_kernel) → tuple[numpy.typing.NDArray[numpy.float32], int][source]

The convolution kernel and downsampling factor, in pixels.

A size that is None or negative is taken from the beam: 3 beams for the step and 10 for the box, or abs(value) beams when negative.

Parameters:
  • header (fits.Header | dict[str, Any]) – Header of the image, for the beam and pixel scale

  • step_size (int | None, optional) – Downsampling factor in pixels. Defaults to 3 beams.

  • box_size (int | None, optional) – Kernel size in pixels. Defaults to 10 beams.

  • kernel_func (Callable, optional) – Kernel shape. Defaults to gaussian_kernel.

Returns:

The kernel, peak-normalised, and the step size in pixels

Return type:

tuple[NDArray[np.float32], int]

flint.bane.local_seed(image: numpy.typing.NDArray[numpy.float32], nan_mask: numpy.typing.NDArray[numpy.bool_], step: int, box: int) → tuple[numpy.typing.NDArray[numpy.float32], numpy.typing.NDArray[numpy.float32]][source]

Background and RMS maps from the clipped statistics of overlapping boxes.

What the first round clips against. Anything of either sign covering a small part of a box is clipped as a source, and a loud region filling most of one is measured as noise.

flint.bane.pad_reflect(array: numpy.typing.NDArray[numpy.float32], pad_width: tuple[int, int]) → numpy.typing.NDArray[numpy.float32][source]

np.pad(array, pad_width, mode="reflect"), in a form numba can compile

flint.bane.robust_bane(image: numpy.typing.NDArray[numpy.float32], header: astropy.io.fits.Header | dict[str, Any], fft_bane_options: flint.options.FFTBANEOptions | None = None) → tuple[numpy.typing.NDArray[numpy.float32], numpy.typing.NDArray[numpy.float32]][source]

Background and RMS maps of a single image plane.

Two rounds: the first clips against local_seed, the second against the first’s maps. Non-finite pixels are blank, as are zeros unless invalidate_zeros is unset. A plane that is all blank, or has no usable beam when one is needed, gets blank maps.

Peaks at roughly five times the plane in memory.

Parameters:
  • image (NDArray[np.float32]) – The image plane to measure

  • header (fits.Header | dict[str, Any]) – Its header, for the beam and pixel scale

  • fft_bane_options (FFTBANEOptions | None, optional) – Step, box, kernel, clip, seed and zero blanking. Defaults to FFTBANEOptions().

Returns:

Background and RMS, shaped like image

Return type:

tuple[NDArray[np.float32], NDArray[np.float32]]

flint.bane.tophat_kernel(diameter: int) → numpy.typing.NDArray[numpy.float32][source]

Circular tophat kernel of diameter pixels

flint.bane.PARALLEL_KERNEL_LOCK[source]