Skip to main content

kernels.pclip

kernels.pclip(
    arr,
    *,
    mask=None,
    frac=-0.5,
    sigma=3.0,
    nkeep=1,
    grow=None,
    validate=True,
)

IRAF-style percentile clipping at each pixel.

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.

frac : float = -0.5

IRAF pclip value. If abs(frac) < 1, it is converted to an integer rank offset using half of the input image count. Positive values estimate sigma from the high side of the sorted median; negative values estimate sigma from the low side.

sigma : float or tuple of float = 3.0

User-supplied lower and upper clipping multipliers applied to the pclip-estimated spread. This maps to IRAF lsigma and hsigma.

nkeep : int = 1

Minimum number of unmasked samples to retain after pclip rejection.

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 finite, unmasked samples and let m be their median. frac selects an offset rank r below (negative) or above (positive) the median; it is not a percentage of samples to reject. For abs(frac) < 1, scale by max(N // 2, 1) for the original image count N and truncate to an integer, with a minimum offset magnitude of one. Estimate::

d = sign(frac) * (x_sorted[r] - m)

Reject sorted endpoints while (m-x)/d >= sigma_lower or (x-m)/d >= sigma_upper, using the two sigma multipliers. Unlike sigma/CCD clipping, equality is rejected. The center and spread are computed once. If needed, restore the least-extreme rejected endpoints to satisfy nkeep, including IRAF’s residual-tie handling. With fewer than three usable samples, at most nkeep usable samples, or d == 0, no additional samples are rejected. In diagnostic calls, std is None and low/upp report retained extrema. The tutorial specifies the full rank convention. For derivations and worked examples, see the Rejection Methods tutorial.