Source code for hsr4hci.psf
"""
Methods for working with point spread functions.
"""
# -----------------------------------------------------------------------------
# IMPORTS
# -----------------------------------------------------------------------------
from typing import Any
from astropy.modeling import models, fitting
import numpy as np
from hsr4hci.coordinates import get_center
from hsr4hci.general import crop_center
# -----------------------------------------------------------------------------
# FUNCTION DEFINITIONS
# -----------------------------------------------------------------------------
[docs]def get_psf_fwhm(psf_template: np.ndarray) -> float:
"""
Fit a symmetric 2D Gaussian to the given ``psf_template`` to
estimate the full width half maximum (FWHM) of the central "blob".
Args:
psf_template: A 2D numpy array containing the unsaturated
PSF template.
Returns:
The FWHM of the PSF template (in pixels).
"""
# Crop PSF template: too large templates (which are mostly zeros) can
# cause problems when fitting them with a 2D Gauss function
psf_cropped = np.copy(psf_template)
if psf_template.shape[0] >= 33 or psf_template.shape[1] >= 33:
psf_cropped = crop_center(psf_cropped, (33, 33))
# Define the grid for the fit
x, y = np.meshgrid(
np.arange(psf_cropped.shape[0]), np.arange(psf_cropped.shape[1])
)
# Create a new Gaussian2D object
center = get_center((psf_cropped.shape[0], psf_cropped.shape[1]))
gaussian = models.Gaussian2D(x_mean=center[0], y_mean=center[1])
# Define auxiliary function for tieing the standard deviations
def tie_stddev(gaussian: Any) -> Any:
return gaussian.y_stddev
# Enforce symmetry: tie standard deviation parameters to same value to
# ensure that the resulting 2D Gaussian is always circular
gaussian.x_stddev.tied = tie_stddev
# Fix the position (= mean) of the 2D Gaussian
gaussian.x_mean.fixed = True
gaussian.y_mean.fixed = True
# Fit the model to the data
fit_p = fitting.LevMarLSQFitter()
gaussian_model = fit_p(gaussian, x, y, np.nan_to_num(psf_cropped))
# Make sure the returned FWHM is positive
return abs(float(gaussian_model.x_fwhm))