Source code for photutils.background.local_background

# Licensed under a 3-clause BSD style license - see LICENSE.rst
"""
Tools for estimating local background using a circular annulus aperture.
"""

import numpy as np

from photutils.aperture import CircularAnnulus
from photutils.background import MedianBackground
from photutils.utils._deprecation import deprecated_positional_kwargs
from photutils.utils._repr import make_repr

__all__ = ['LocalBackground']


[docs] class LocalBackground: """ Class to compute a local background using a circular annulus aperture. Parameters ---------- inner_radius : float The inner radius of the circular annulus in pixels. outer_radius : float The outer radius of the circular annulus in pixels. bkg_estimator : callable, optional A callable object (a function or e.g., an instance of any `~photutils.background.BackgroundBase` subclass) used to estimate the background in each aperture. The callable object must take in a 1D `~numpy.ndarray` or `~numpy.ma.MaskedArray`. The default is an instance of `~photutils.background.MedianBackground` with sigma clipping (i.e., sigma-clipped median). Examples -------- >>> import numpy as np >>> from photutils.background import LocalBackground >>> data = np.ones((101, 101)) >>> local_bkg = LocalBackground(5, 10) >>> bkg = local_bkg(data, 50, 50) >>> print(bkg) # doctest: +FLOAT_CMP 1.0 >>> # Multiple positions >>> x = [30, 50, 70] >>> y = [30, 50, 70] >>> bkg = local_bkg(data, x, y) >>> print(bkg) # doctest: +FLOAT_CMP [1. 1. 1.] """ @deprecated_positional_kwargs(since='3.0', until='4.0') def __init__(self, inner_radius, outer_radius, bkg_estimator=None): if inner_radius <= 0: msg = 'inner_radius must be positive.' raise ValueError(msg) if outer_radius <= 0: msg = 'outer_radius must be positive.' raise ValueError(msg) if outer_radius <= inner_radius: msg = 'outer_radius must be greater than inner_radius.' raise ValueError(msg) self.inner_radius = inner_radius self.outer_radius = outer_radius if bkg_estimator is None: bkg_estimator = MedianBackground() self.bkg_estimator = bkg_estimator def __repr__(self): params = ('inner_radius', 'outer_radius', 'bkg_estimator') return make_repr(self, params)
[docs] def to_aperture(self, x, y): """ Return a `~photutils.aperture.CircularAnnulus` instance representing the local background annulus at the given positions. Parameters ---------- x, y : float or 1D float `~numpy.ndarray` The aperture center (x, y) position(s) at which to create the annulus aperture. Returns ------- apertures : `~photutils.aperture.CircularAnnulus` instance The circular annulus aperture(s) at the given position(s). Examples -------- >>> from photutils.background import LocalBackground >>> local_bkg = LocalBackground(5, 10) >>> aperture = local_bkg.to_aperture(50, 50) >>> aperture # doctest: +FLOAT_CMP <CircularAnnulus([[50., 50.]], r_in=5.0, r_out=10.0)> >>> # Multiple positions >>> aperture = local_bkg.to_aperture([30, 70], [40, 80]) >>> aperture # doctest: +FLOAT_CMP <CircularAnnulus([[30., 40.], [70., 80.]], r_in=5.0, r_out=10.0)> >>> print(len(aperture.positions)) 2 """ x = np.atleast_1d(x) y = np.atleast_1d(y) positions = np.array(list(zip(x, y, strict=True))) return CircularAnnulus(positions, self.inner_radius, self.outer_radius)
[docs] @deprecated_positional_kwargs(since='3.0', until='4.0') def __call__(self, data, x, y, mask=None): """ Measure the local background in a circular annulus. Parameters ---------- data : 2D `~numpy.ndarray` The 2D array on which to measure the local background. x, y : float or 1D float `~numpy.ndarray` The aperture center (x, y) position(s) at which to measure the local background. mask : 2D bool `~numpy.ndarray`, optional A boolean mask with the same shape as ``data`` where a `True` value indicates the corresponding element of ``data`` is masked. Masked data are excluded from all calculations. Returns ------- value : float or 1D float `~numpy.ndarray` The local background values. If all pixels in an annulus are masked or outside the data bounds, the corresponding value will be NaN. Examples -------- >>> import numpy as np >>> from photutils.background import LocalBackground >>> data = np.ones((101, 101)) >>> local_bkg = LocalBackground(5, 10) >>> bkg = local_bkg(data, 50, 50) >>> print(bkg) # doctest: +FLOAT_CMP 1.0 >>> # Multiple positions >>> bkg = local_bkg(data, [30, 50], [40, 60]) >>> print(bkg) # doctest: +FLOAT_CMP [1. 1.] >>> # Position outside data returns NaN >>> bkg = local_bkg(data, -50, -50) >>> print(np.isnan(bkg)) True """ apertures = self.to_aperture(x, y) apermasks = apertures.to_mask(method='center') n_apertures = len(apermasks) bkg = np.empty(n_apertures) for i, apermask in enumerate(apermasks): values = apermask.get_values(data, mask=mask) bkg[i] = self.bkg_estimator(values) if bkg.size == 1: bkg = bkg[0] return bkg