make_kernel#

photutils.psf_matching.make_kernel(source_psf, target_psf, *, window=None, regularization=0.0001)[source]#

Make a convolution kernel that matches an input PSF to a target PSF using the ratio of Fourier transforms.

This function computes the matching kernel in the Fourier domain by dividing the target PSF’s Fourier transform by the source PSF’s Fourier transform. To avoid division by near-zero values, the Fourier ratio is set to zero at frequencies where the source OTF (Optical Transfer Function) amplitude falls below a threshold.

The kernel is computed as:

\[K = \mathcal{F}^{-1} \left[ W \cdot R \right]\]

where the Fourier-space ratio \(R\) is defined as:

\[\begin{split}R = \begin{cases} \frac{T}{S} & \text{if } |S| > \lambda \cdot \max(|S|) \\ 0 & \text{otherwise} \end{cases}\end{split}\]

Here, \(\mathcal{F}^{-1}\) is the inverse Fourier transform, \(S\) and \(T\) are the Fourier transforms of the source and target PSFs (the optical transfer functions, OTFs), \(\lambda\) is the regularization parameter, and \(W\) is the optional window function (defaulting to 1 if not provided).

Parameters:
source_psf2D ndarray

The source PSF. The source PSF should have higher resolution (i.e., narrower) than the target PSF. source_psf and target_psf must have the same shape and pixel scale. It is assumed to be centered on the central pixel.

target_psf2D ndarray

The target PSF. The target PSF should have lower resolution (i.e., broader) than the source PSF. source_psf and target_psf must have the same shape and pixel scale. It is assumed to be centered on the central pixel.

windowcallable, optional

The window (taper) function or callable class instance used to remove high frequency noise from the PSF matching kernel. The window function should be a callable that accepts a single shape parameter (a tuple defining the 2D array shape) and returns a 2D array of the same shape. The returned window values must be in the range [0, 1], where 1.0 indicates full preservation of that spatial frequency and 0.0 indicates complete suppression. The window must be centered on the central pixel. Built-in window classes include:

For more information on window functions, custom windows, and example usage, see PSF Matching.

regularizationfloat, optional

The regularization parameter that controls the OTF amplitude threshold for the source OTF (Optical Transfer Function, the Fourier transform of the PSF). At frequencies where the source OTF amplitude is below regularization times the peak amplitude, the Fourier ratio is set to zero to avoid division by near-zero values. Must be in the range [0, 1), where 0 provides no thresholding (only exact zeros are excluded) and values closer to 1 apply more aggressive thresholding. A value of 1 would zero out all frequencies and produce a degenerate kernel.

Returns:
kernel2D ndarray

The matching kernel to go from source_psf to target_psf. The output matching kernel is normalized such that it sums to 1.

Raises:
ValueError

If the PSFs are not 2D arrays, have even dimensions, or do not have the same shape, if regularization is not in the range [0, 1), or if the window function output is invalid (not a 2D array, wrong shape, or values outside [0, 1]).

TypeError

If the input window is not callable.

See also

make_wiener_kernel

Make a matching kernel using Wiener (Tikhonov) regularization instead of hard amplitude thresholding.

Examples

Make a matching kernel between two Gaussian PSFs:

>>> import numpy as np
>>> from astropy.modeling.models import Gaussian2D
>>> from photutils.psf_matching import make_kernel
>>> y, x = np.mgrid[0:51, 0:51]
>>> psf1 = Gaussian2D(100, 25, 25, 3, 3)(x, y)
>>> psf2 = Gaussian2D(100, 25, 25, 5, 5)(x, y)
>>> psf1 /= psf1.sum()
>>> psf2 /= psf2.sum()
>>> kernel = make_kernel(psf1, psf2)
>>> print(f'{kernel.sum():.1f}')
1.0