Skip to main content

kernels.minmax

kernels.minmax(arr, *, mask=None, n_min=1, n_max=1, grow=None, validate=True)

Reject the n_min smallest and n_max largest unmasked values at each pixel. Single-pass.

Parameters

arr : (ndarray, shape(N, *spatial))

Image stack. Accepted dtypes are uint8, uint16, int16, int32, float32, and float64. Integer inputs are promoted to the package’s floating workspace when validate is True. Inputs with more than 3 dimensions are flattened internally; output shapes match the trailing spatial dimensions of the input.

mask : ndarray of bool = None

Input mask; True means already masked. Must have the same shape as arr before any internal flattening.

n_min : int or float = 1

Number of minimum-side values to reject at each pixel. Values >= 1 are treated as a frame count. Values in [0, 1) are treated as a fraction of the total frame count N and converted via int(N * n_min + 0.001), matching IRAF’s internal fraction arithmetic.

n_max : int or float = 1

Same convention as n_min, applied to the maximum-side tail.

grow : float or None = None

Optional radius in pixels used to grow mask_rej spatially after rejection. Axis 0 is the stack axis and is never grown across. None disables growth and skips the extra calculation.

validate : bool = True

If True, check dimensionality and normalize dtype/contiguity before entering the Rust kernel. If False, callers must provide inputs that satisfy the compiled kernel assumptions.

Returns

mask_rej : ndarray of bool, shape (N, *spatial)

True for excluded samples, including input masks and non-finite values. LinearClip excludes input-mask entries; its disabled default returns an all-false mask (see Notes). Thus mask_rej.sum(axis=0) need not count only newly rejected samples.

std : (ndarray, shape(*spatial) or None)

Clipping spread for SigClip; reference noise for CCDClip (see Notes). None for rejection algorithms without a spread diagnostic.

low : (ndarray, shape(*spatial))

Minimum retained value before growth. LinearClip instead reports its last accepted lower interval bound. Use mask_rej to identify survivors.

upp : (ndarray, shape(*spatial))

Maximum retained value before growth. LinearClip instead reports its last accepted upper interval bound. Use mask_rej to identify survivors.

nit : ndarray of uint8, shape (*spatial)

Iteration-count map.

output_flags : ndarray of uint8, shape (*spatial)

Bit-coded status. 0 means normal completion; bit 1 means at least one pre-masked sample at this output element; bit 16 means grow added at least one rejected sample at this output element. Iterative kernels also use bit 2 for maxiters, bit 4 for nkeep, and bit 8 for maxrej. Bits are OR-ed. output_flags is a per-output diagnostic; use mask_rej to inspect individual samples.

Notes

Sort the M finite, unmasked samples at each output pixel. With N the original image count, a request a (n_min or n_max) resolves to::

A = int(N * a + 0.001) if 0 <= a < 1 else int(a)
k = int(M * A / N + 0.001)

Reject k samples from that tail, first the low tail, then the high tail of the remaining values. Both counts use the initial M; available samples limit the cuts. Thus masked/non-finite inputs reduce even count-based requests proportionally. For example, N=10, M=5, n_min=2 removes one minimum. This is rank selection, not a value threshold: tied values may be split. There is no spread estimate or iteration; low/upp are retained extrema. For derivations and worked examples, see the Rejection Methods tutorial.