smlmlp.detect_gain module

smlmlp.detect_gain(channels, /, nbins=50, *, cuda=False, parallel=False)[source]

Estimate gain values and gain-related maps from image stacks.

This function computes, for each channel, robust mean and variance maps from the temporal median and median absolute deviation. A gain map is then derived as the ratio between the mean and variance. In addition, binned mean-variance samples are built and a linear regression is fitted on the central intensity range in order to estimate a scalar gain value for each channel.

Parameters:
  • channels (sequence of ndarray) – Sequence of image stacks, one per channel. Each channel is expected to have shape (n_frames, height, width).

  • nbins (int, optional) – Number of bins used to build the binned mean-variance relationship.

  • cuda (bool, optional) – Whether to use GPU acceleration when supported.

  • parallel (bool, optional) – Unused in this function. It is kept for API consistency.

Returns:

A tuple (gains, info) where:

  • gains is the list of scalar gain estimates, one per channel,

  • info is a dictionary containing reusable intermediate results.

The dictionary contains the following keys:

'gain'

List of gain maps computed as mean / var.

'mean'

List of robust mean maps computed from the temporal median.

'var'

List of robust variance maps computed from the median absolute deviation.

'mean_bins'

List of binned mean values used for the linear fit.

'var_bins'

List of binned variance values used for the linear fit.

'fit'

List of scipy.stats.linregress() results for each channel.

Return type:

tuple

Notes

The robust variance estimate is computed from the median absolute deviation using:

\[\mathrm{var} = (1.4826 \times \mathrm{MAD})^2\]

The scalar gain is then estimated from the slope of the linear regression fitted on the central third of the mean distribution:

\[\mathrm{gain} = \frac{1}{\mathrm{slope}}\]

Examples

Estimate the gain for one channel:

>>> import numpy as np
>>> channel = np.random.rand(20, 32, 32).astype(np.float32)
>>> gains, info = detect_gain([channel], nbins=50)
>>> len(gains)
1
>>> sorted(info.keys())
['fit', 'gain', 'mean', 'mean_bins', 'var', 'var_bins']

Estimate the gain for multiple channels:

>>> channels = [
...     np.random.rand(20, 32, 32).astype(np.float32),
...     np.random.rand(20, 32, 32).astype(np.float32),
... ]
>>> gains, info = detect_gain(channels, nbins=40)
>>> len(gains)
2
>>> len(info["gain"])
2