viz.enhance.azimuthal_normalize

viz.enhance.azimuthal_normalize(
    image,
    center,
    *,
    nrad,
    ntheta,
    statistic='median',
    sigma=None,
    maxiters=1,
    clip_center='mean',
    clip_scale='std',
    subpixels=10,
    mask=None,
    statistic_mask=None,
    return_stats=False,
)

Divide polar rings by a mean, median, mode estimate, or custom statistic.

Use statistic="mode", sigma=3, maxiters=5 for a sigma-clipped mode estimate. Clipping changes the ring divisor; bright features remain in the image being normalized.

Parameters

image : array - like

Nonempty, real 2-D image. Masked and nonfinite pixels are missing. Pass CCDData pixels and its mask separately.

center : tuple of float

Zero-based (x, y) nucleus coordinates within the image.

nrad : int

Number of integer radius rings, starting at radius 1 pixel.

ntheta : int

Number of equal-angle cells per radius.

statistic : ('mean', 'median', 'mode') = "mean"

Ring divisor. "mode" estimates 3*median - 2*mean; it is an empirical approximation, not a histogram mode, and may lie outside the observed range. A callable receives a private finite 1-D array after clipping and must return a real scalar. Empty rings skip the callable. Nonfinite results make the ring undefined.

sigma : float, tuple of float, or None = None

Nonnegative clipping threshold, or (lower, upper) thresholds. None disables clipping. Every statistic supports clipping.

maxiters : int or None = 1

Maximum clipping passes. The default 1 preserves the original one-pass mean rejection. None clips until no values are rejected.

clip_center : ('mean', 'median') = "mean"

Location used for clipping bounds, independently of statistic.

clip_scale : ('std', 'mad_std') = "std"

Clipping spread: sample standard deviation (ddof=1) or Gaussian-consistent median absolute deviation. A singleton has zero spread. Zero-width bounds retain only samples equal to the center.

subpixels : int = 10

Midpoints per axis for polar sampling and reconstruction. The default 10 preserves the source’s 10-by-10 quadrature.

mask : array - like or None = None

Additional exclusion mask with the image shape.

statistic_mask : array - like or None = None

Exclude these pixels from ring estimates only. Original valid samples remain in the output. A polar cell is excluded from estimation if any midpoint touches this mask. The hard mask still excludes output.

return_stats : bool = False

Return an EnhancementResult with .image and .stats when True. The statistics include levels, sample standard deviations, and counts. The default False returns only the image and avoids diagnostic work.

Returns

: ndarray or EnhancementResult

Float64 image with unchanged shape. The input is never modified. Zero divisors and incomplete sampling neighborhoods produce NaN. Negative finite divisors are retained.

Notes

Each polar cell averages equal-angle, equal-radius midpoint samples, using nearest-pixel lookup. A missing midpoint invalidates that cell. Ring statistics use the remaining finite cells. Reconstruction again averages midpoint samples; all must have valid polar cells. Radii below 0.5 or at or above nrad + 0.5 have no ring.

Polar angle zero lies along +y and increases toward -x. Angular cells are centered at (j + 0.5) * 2*pi / ntheta. This polar round trip changes spatial sampling. Use annular_normalize for direct normalization of pixel-center annuli.

The mode formula matches the MMM estimator described by Photutils: https://photutils.readthedocs.io/en/stable/api/photutils.background.MMMBackground.html. No automatic estimator fallback or denominator floor is applied.