Source code for astrowisp.piecewise_bicubic_psf

"""A wrapper class for working with PSFs/PRFs from the C/C++ library."""

from ctypes import c_double
import numpy

from astrowisp.psf_base import PSFBase
from astrowisp._initialize_library import get_astrowisp_library

[docs] class PiecewiseBicubicPSF(PSFBase): """Implement the PSFBase methods for libary PSFs."""
[docs] def __init__(self, library_psf): """Wrap the given library PSF in a convenient python interface.""" self._astrowisp_library = get_astrowisp_library() self._library_psf = library_psf
#(x, y) is a reasonable way to specify the components of an offset vector. #pylint: disable=invalid-name
[docs] def __call__(self, x, y): """ Return the value(s) of the PSF at the given point(s). Args: x(float or numpy array): The horizontal offset(s) from center of the point at which to return the PSF value. y(float or numpy array): The vertical offset(s) from center of the point at which to return the PSF value. Returns: numpy array: The value(s) of the PSF at (x, y) relative to the source center. """ print('Evaluating PRF at x with shape ' + repr(numpy.atleast_1d(x).shape)) print('Evaluating PRF at y with shape ' + repr(numpy.atleast_1d(y).shape)) if isinstance(x, numpy.ndarray): if not isinstance(y, numpy.ndarray): y = numpy.full(x.shape, y) else: if isinstance(y, numpy.ndarray): x = numpy.full(y.shape, x) else: x = numpy.array([float(x)]) y = numpy.array([float(y)]) assert x.size == y.size result = numpy.empty(x.size, dtype=c_double) self._astrowisp_library.evaluate_piecewise_bicubic_psf( self._library_psf, x.flatten(), y.flatten(), x.size, result ) return result.reshape(x.shape)
#pylint: enable=invalid-name
[docs] def integrate(self, *, center_x, center_y, width, height, circle_radius=None): """ Return integrals of the PSF over circle-rectangle overlaps. Args: center_x(float or array): The x coordinate(s) of the center(s) of the rectangle(s) to integrate over. center_y(float or array): The y coordinate(s) of the center(s) of the rectangle(s) to integrate over. width(float or array): The width(s) of the rectangle(s). height(float or array): The height(s) of the rectangle(s). circle_radius(float or array): The rad(ii/us) of the circle(s). For zero entries or None, the integral is over the full rectangle(s). Returns: float or array: The integral of the PSF over the specified area(s). """ if not isinstance(center_x, numpy.ndarray): center_x = numpy.array([center_x]) center_y = numpy.array([center_y]) width = numpy.array([width]) height = numpy.array([height]) circle_radius = numpy.array( [0.0 if circle_radius is None else circle_radius] ) else: assert center_x.shape == center_y.shape assert center_x.shape == width.shape assert center_x.shape == height.shape if circle_radius is None: circle_radius = numpy.full(center_x.shape, 0.0) else: assert center_x.shape == circle_radius.shape result = numpy.empty(center_x.shape, dtype=float, order='C') self._astrowisp_library.integrate_piecewise_bicubic_psf( self._library_psf, center_x.astype(c_double, order='C', copy=False).ravel(), center_y.astype(c_double, order='C', copy=False).ravel(), width.astype(c_double, order='C', copy=False).ravel(), height.astype(c_double, order='C', copy=False).ravel(), circle_radius.astype(c_double, order='C', copy=False).ravel(), result.size, result.astype(c_double, order='C', copy=False).ravel() ) if not isinstance(center_x, numpy.ndarray): result = float(result) return result
[docs] def __del__(self): """Delete the underlying library PSF.""" self._astrowisp_library.destroy_piecewise_bicubic_psf(self._library_psf)
[docs] def get_left_range(self): raise NotImplementedError
[docs] def get_right_range(self): raise NotImplementedError
[docs] def get_down_range(self): raise NotImplementedError
[docs] def get_up_range(self): raise NotImplementedError