smlmlp.bkgd_spatial_mean module

smlmlp.bkgd_spatial_mean(channels, /, channels_mean_radii_pix=7.0, bkgds=None, noise_corrections=None, *, cuda=False, parallel=False)[source]

Compute a spatially local mean background for each channel.

The background is estimated by applying a Gaussian filter independently to each input channel stack. A per-channel noise correction factor is also updated from the corresponding Gaussian kernels so that downstream code can reuse intermediate calibration information.

Parameters:
  • channels (sequence of ndarray) – Sequence of image stacks, one per channel. Each element is passed to arrlp.img_gaussianfilter() with stacks=True.

  • channels_mean_radii_pix (float or sequence, optional) –

    Spatial averaging radius in pixels.

    Accepted forms are:

    • a single scalar, applied as (radius, radius) to every channel,

    • a sequence of length 2, applied to every channel as (radius_y, radius_x),

    • a sequence with the same length as channels, where each element contains the per-channel radii.

    Internally, the Gaussian standard deviation is set to (radius_y / 2, radius_x / 2) for each channel.

  • bkgds (sequence of ndarray or None, optional) – Optional preallocated output arrays for the backgrounds. If provided and longer than the corresponding input acquisition, each background stack is truncated to the channel length.

  • noise_corrections (sequence of float or None, optional) – Optional per-channel noise correction factors. If None, they are initialized to 1.0 for every channel. Each value is then updated in-place by multiplying it with the norm-based correction induced by the Gaussian filtering kernels.

  • cuda (bool, optional) – Whether to enable CUDA processing in arrlp.img_gaussianfilter().

  • parallel (bool, optional) – Whether to enable parallel processing in arrlp.img_gaussianfilter().

Returns:

A tuple (new_bkgds, noise_corrections, info) where:

  • new_bkgds is the list of spatially smoothed background stacks,

  • noise_corrections is the updated list of correction factors,

  • info is a dictionary containing reusable intermediate results.

The dictionary contains the following keys:

'channels_mean_radius_pix'

Normalized per-channel spatial radii used for the Gaussian filter.

'spatial_mean_sigmas'

Per-channel Gaussian standard deviations used for filtering.

'spatial_mean_kernels_y'

List of 1D kernels used to compute the noise correction factors for each channel in y direction.

'spatial_mean_kernels_x'

List of 1D kernels used to compute the noise correction factors for each channel in x direction.

Return type:

tuple

Raises:

ValueError – If channels_mean_radii_pix is a sequence whose length is neither equal to len(channels) nor equal to 2.

Notes

The noise correction is computed from two 1D kernels derived from the Gaussian sigmas. Each kernel is negated, then its center value is incremented by 1. The correction factor for a given channel is:

\[\sqrt{\sum k_1^2} \times \sqrt{\sum k_2^2}\]

This factor is multiplied into the corresponding entry of noise_corrections.

Examples

Use a single isotropic radius for all channels:

>>> import numpy as np
>>> channels = [
...     np.random.rand(4, 16, 16).astype(np.float32),
...     np.random.rand(4, 16, 16).astype(np.float32),
... ]
>>> bkgds, noise_corr, info = bkgd_spatial_mean(channels, 7.0)
>>> len(bkgds) == len(channels)
True
>>> len(noise_corr) == len(channels)
True
>>> "spatial_mean_sigmas" in info
True

Use anisotropic radii shared across channels:

>>> radii = (6.0, 10.0)
>>> bkgds, noise_corr, info = bkgd_spatial_mean(channels, radii)
>>> info["channels_mean_radii_pix"][0]
(6.0, 10.0)

Use one radius pair per channel and provide initial corrections:

>>> radii = [(6.0, 6.0), (8.0, 10.0)]
>>> init_corr = [np.float32(1.0), np.float32(2.0)]
>>> bkgds, noise_corr, info = bkgd_spatial_mean(
...     channels,
...     radii,
...     noise_corrections=init_corr,
... )
>>> len(info["spatial_mean_kernels_x"]) == 2
True