PSFPhotometry#

class photutils.psf.PSFPhotometry(psf_model, fit_shape, *, finder=None, grouper=None, fitter=None, fitter_maxiters=100, xy_bounds=None, aperture_radius=None, local_bkg_estimator=None, group_warning_threshold=25, progress_bar=False)[source]#

Bases: object

Class to perform PSF photometry.

This class implements a flexible PSF photometry algorithm that can find sources in an image, group overlapping sources, fit the PSF model to the sources, and subtract the fit PSF models from the image.

Parameters:
psf_model2D astropy.modeling.Model

The PSF model to fit to the data. The model must have parameters named x_0, y_0, and flux, corresponding to the center (x, y) position and flux, or it must have ‘x_name’, ‘y_name’, and ‘flux_name’ attributes that map to the x, y, and flux parameters. The model must be two-dimensional such that it accepts 2 inputs (e.g., x and y) and provides 1 output.

fit_shapeint or length-2 array_like

The rectangular shape around the initial source position that will be used to define the PSF-fitting data. If fit_shape is a scalar then a square shape of size fit_shape will be used. If fit_shape has two elements, they must be in (ny, nx) order. Each element of fit_shape must be an odd number greater than or equal to 3. In general, fit_shape should be set to a small size (e.g., (5, 5)) that covers the region with the highest flux signal-to-noise.

findercallable or StarFinderBase or None, optional

A callable used to identify sources in an image. The finder must accept a 2D image as input and return a Table containing the x and y centroid positions. These positions are used as the starting points for the PSF fitting. The allowed x column names are (same suffix for y): 'x_init', 'xinit', 'x', 'x_0', 'x0', 'xcentroid', 'x_centroid', 'x_peak', 'xcen', 'x_cen', 'xpos', 'x_pos', 'x_fit', and 'xfit'. If None, then the initial (x, y) model positions must be input using the init_params keyword when calling the class. The (x, y) values in init_params override this keyword. If this class is run on an image that has units (i.e., a Quantity array), then certain finder keywords (e.g., threshold) must have the same units. Please see the documentation for the specific finder class for more information.

grouperSourceGrouper or callable or None, optional

A callable used to group sources. Typically, grouped sources are those that overlap with their neighbors. Sources that are grouped are fit simultaneously. The grouper must accept the x and y coordinates of the sources and return an integer array of the group ID numbers (starting from 1) indicating the group in which a given source belongs. If None, then no grouping is performed, i.e. each source is fit independently. The group_id values in init_params override this keyword. A warning is raised if any group size is larger than group_warning_threshold sources.

fitterFitter, optional

The fitter object used to perform the fit of the model to the data. If None, then the default astropy.modeling.fitting.TRFLSQFitter is used.

fitter_maxitersint, optional

The maximum number of iterations in which the fitter is called for each source. The value can be increased if the fit is not converging for sources. This parameter is passed to the fitter if it supports the maxiter parameter and ignored otherwise.

xy_boundsNone, float, or 2-tuple of float, optional

The maximum distance in pixels that a fitted source can be from the initial (x, y) position. If a single float, then the same maximum distance is used for both x and y. If a 2-tuple of floats, then the distances are in (x, y) order. If None, then no bounds are applied. Either value can also be None to indicate no bound along that axis.

aperture_radiusfloat or None, optional

The radius of the circular aperture used to estimate the initial flux of each source. If None, then the initial flux values must be provided in the init_params table. The aperture radius must be a strictly positive scalar. If initial flux values are present in the init_params table, they will override this keyword.

local_bkg_estimatorLocalBackground or None, optional

The object used to estimate the local background around each source. If None, then no local background is subtracted. The local_bkg values in init_params override this keyword. This option should be used with care, especially in crowded fields where the fit_shape of sources overlap (see Notes below).

group_warning_thresholdint, optional

The maximum number of sources in a group before a warning is raised. If the number of sources in a group exceeds this value, a warning is raised to inform the user that fitting such large groups may take a long time and be error-prone. The default is 25 sources.

progress_barbool, optional

Whether to display a progress bar when fitting the sources (or groups). The progress bar requires that the tqdm optional dependency be installed.

Notes

The data that will be fit for each source is defined by the fit_shape parameter. A cutout will be made around the initial center of each source with a shape defined by fit_shape. The PSF model will be fit to the data in this region. The cutout region that is fit does not shift if the source center shifts during the fit iterations. Therefore, the initial source positions should be close to the true source positions. One way to ensure this is to use a finder to identify sources in the data.

If the fitted positions are significantly different from the initial positions, one can rerun the PSFPhotometry class using the fit results as the input init_params, which will change the fitted cutout region for each source. After running PSFPhotometry, you can use the results_to_init_params method to generate a table of initial parameters that can be used in a subsequent call to PSFPhotometry. This table will contain the fitted (x, y) positions, fluxes, and any other model parameters that were fit.

If the fitted model parameters are NaN, then the source was not valid, likely due to not enough valid data pixels in the fit_shape region. The flags column in the output results table indicates the reason why a source was not valid.

If the fitted model parameter errors are NaN, then either the fit did not converge, the model parameter was fixed, or the input fitter did not return parameter errors. For the later case, one can try a different Astropy fitter that returns parameter errors.

The local background value around each source is optionally estimated using the local_bkg_estimator or obtained from the local_bkg column in the input init_params table. This local background is then subtracted from the data over the fit_shape region for each source before fitting the PSF model. For sources where their fit_shape regions overlap, the local background will effectively be subtracted twice in the overlapping fit_shape regions, even if the source grouper is input. This is not an issue if the sources are well-separated. However, for crowded fields, please use the local_bkg_estimator (or local_bkg column in init_params) with care.

Care should be taken in defining the source groups. Simultaneously fitting very large source groups is computationally expensive and error-prone. Internally, source grouping requires the creation of a compound Astropy model. Due to the way compound Astropy models are currently constructed, large groups also require excessively large amounts of memory; this will hopefully be fixed in a future Astropy version. A warning will be raised if the number of sources in a group exceeds the group_warning_threshold value.

Attributes Summary

Methods Summary

__call__(data, *[, mask, error, init_params])

Perform PSF photometry.

decode_flags([return_bit_values])

Decode the PSF photometry flags from the results table.

make_model_image(shape, *[, psf_shape, ...])

Create a 2D image from the fit PSF models and optional local background.

make_residual_image(data, *[, psf_shape, ...])

Create a 2D residual image from the fit PSF models and local background.

results_to_init_params(*[, remove_invalid, ...])

Create a table of the fitted model parameters from the results.

results_to_model_params(*[, remove_invalid, ...])

Create a table of the fitted model parameters from the results.

Attributes Documentation

fit_params#

Deprecated since version 2.3.0: The fit_params function is deprecated and may be removed in a future version. Use results instead.

The table of fit parameters and their errors.

This table is a subset of the results table, containing only the fit parameters and their errors. It can be used as the init_params for subsequent PSFPhotometry fits.

Methods Documentation

__call__(data, *, mask=None, error=None, init_params=None)[source]#

Perform PSF photometry.

Parameters:
data2D ndarray

The 2D array on which to perform photometry. Invalid data values (i.e., NaN or inf) are automatically masked.

mask2D bool ndarray, optional

A boolean mask with the same shape as data, where a True value indicates the corresponding element of data is masked.

error2D ndarray, optional

The pixel-wise 1-sigma errors of the input data. error is assumed to include all sources of error, including the Poisson error of the sources. error must have the same shape as the input data. If data is a Quantity array, then error must also be a Quantity array with the same units.

init_paramsTable or None, optional

A table containing the initial guesses of the model parameters (e.g., x, y, flux) for each source. If the initial x and y values are not included, then the finder keyword must be defined. If the initial flux values are not included, then the aperture_radius keyword must be defined to measure the initial flux values. Note that the initial flux values refer to the model flux parameters and are not corrected for local background values (computed using local_bkg_estimator or input in a local_bkg column). The allowed column names are:

  • x_init, xinit, x, x_0, x0, xcentroid, x_centroid, x_peak, xcen, x_cen, xpos, x_pos, x_fit, and xfit.

  • y_init, yinit, y, y_0, y0, ycentroid, y_centroid, y_peak, ycen, y_cen, ypos, y_pos, y_fit, and yfit.

  • flux_init, fluxinit, flux, flux_0, flux0, flux_fit, fluxfit, source_sum, segment_flux, and kron_flux.

  • If the PSF model has additional free parameters that are fit, they can be included in the table. The column names must match the parameter names in the PSF model. They can also be suffixed with either the “_init” or “_fit” suffix. The suffix search order is “_init”, “” (no suffix), and “_fit”. For example, if the PSF model has an additional parameter named “sigma”, then the allowed column names are: “sigma_init”, “sigma”, and “sigma_fit”. If the column name is not found in the table, then the default value from the PSF model will be used.

The parameter names are searched in the input table in the above order, stopping at the first match.

If data is a Quantity array, then the initial flux values in this table must also must also have compatible units.

The table can also have group_id and local_bkg columns. If group_id is input, the values will be used and grouper keyword will be ignored. If local_bkg is input, those values will be used and the local_bkg_estimator will be ignored. If data has units, then the local_bkg values must have the same units.

Returns:
tableQTable

An astropy table with the PSF-fitting results. The table will contain the following columns:

  • id : unique identification number for the source

  • group_id : unique identification number for the source group

  • group_size : the total number of sources in the group. This number includes sources that are in the group, but were not fit due to being masked, having no overlap with the input data, or having too few pixels for a fit.

  • x_init, x_fit, x_err : the initial, fit and error of the source x center

  • y_init, y_fit, y_err : the initial, fit, and error of the source y center

  • flux_init, flux_fit, flux_err : the initial, fit, and error of the source flux

  • n_pixels_fit : the number of unmasked pixels used to fit the source

  • qfit : a quality-of-fit metric defined as the sum of the absolute value of the fit residuals divided by the fit flux. qfit is zero for sources that are perfectly fit by the PSF model.

  • cfit : a quality-of-fit metric defined as the fit residual (data - model) in the initial central pixel value divided by the fit flux. NaN values indicate that the central pixel was masked. Large positive values indicate sources that are sharper than the PSF model (e.g., cosmic ray, hot pixel, etc.). Large negative values indicate sources that are broader than the PSF model

  • reduced_chi2 : the reduced chi-squared statistic. If no error array is provided, reduced_chi2 values will be NaN.

  • flags : bitwise flag values

    • 0 : no flags

    • 1 : n_pixels_fit smaller than full fit_shape region

    • 2 : fitted position outside input image bounds

    • 4 : non-positive flux

    • 8 : possible non-convergence

    • 16 : missing parameter covariance

    • 32 : fitted parameter near a bound

    • 64 : no overlap with data

    • 128 : fully masked source

    • 256 : too few pixels for fitting

    • 512 : non-finite fitted position

    • 1024 : non-finite fitted flux

    • 2048 : non-finite local background

Notes

The qfit and cfit metrics are equivalent to the q and C fits metrics defined by the HST PSF photometry hst1pass software. They are also similar to the chi (qfit) and sharp (cfit) metrics used by DAOPHOT.

decode_flags(return_bit_values=False)[source]#

Decode the PSF photometry flags from the results table.

This is a convenience method that calls decode_psf_flags with the ‘flags’ column from the results table.

Parameters:
return_bit_valuesbool, optional

If True, return the decoded bit flags (integers) instead of the flag descriptions (strings). Default is False.

Returns:
decodedlist of list of str or list of list of int

List of lists where each inner list contains the active flag names (or bit values) for the corresponding source in the results table. If no flags are set for a source, an empty list is returned for that source.

Raises:
ValueError

If no results are available. Please run the PSFPhotometry instance first.

Examples

Decode flags from PSF photometry results:

>>> import numpy as np
>>> from astropy.table import Table
>>> from photutils.psf import CircularGaussianPRF, PSFPhotometry
>>> yy, xx = np.mgrid[:21, :21]
>>> psf_model = CircularGaussianPRF(flux=1, x_0=10, y_0=10, fwhm=2)
>>> # Create a source with negative flux to trigger a flag
>>> m1 = CircularGaussianPRF(flux=100, x_0=10, y_0=10, fwhm=2)
>>> m2 = CircularGaussianPRF(flux=-50, x_0=5, y_0=5, fwhm=2)
>>> data = m1(xx, yy) + m2(xx, yy)
>>> init_params = Table({'x': [10, 5], 'y': [10, 5],
...                      'flux': [100, 100]})
>>> photometry = PSFPhotometry(psf_model, (3, 3))
>>> results = photometry(data, init_params=init_params)
>>> decoded_flags = photometry.decode_flags()
>>> for i, flags in enumerate(decoded_flags):
...     print(f'Source {i+1}: {flags}')
Source 1: []
Source 2: ['negative_flux']
make_model_image(shape, *, psf_shape=None, include_local_bkg=False)[source]#

Create a 2D image from the fit PSF models and optional local background.

Parameters:
shape2 tuple of int

The shape of the output array.

psf_shape2-tuple of int, optional

The shape of the region around the center of the fit model to render in the output image. If psf_shape is a scalar integer, then a square shape of size psf_shape will be used. If None, then the bounding box of the model will be used. This keyword must be specified if the model does not have a bounding_box attribute.

include_local_bkgbool, optional

Whether to include the local background in the rendered output image. Note that the local background level is included around each source over the region defined by psf_shape. Thus, regions where the psf_shape of sources overlap will have the local background added multiple times. Non-finite local background values (NaN or inf) are treated as zero and not included in the output image.

Returns:
array2D ndarray

The rendered image from the fit PSF models. This image will not have any units.

make_residual_image(data, *, psf_shape=None, include_local_bkg=False)[source]#

Create a 2D residual image from the fit PSF models and local background.

Parameters:
data2D ndarray

The 2D array on which photometry was performed. This should be the same array input when calling the PSF-photometry class.

psf_shape2-tuple of int, optional

The shape of the region around the center of the fit model to subtract. If psf_shape is a scalar integer, then a square shape of size psf_shape will be used. If None, then the bounding box of the model will be used. This keyword must be specified if the model does not have a bounding_box attribute.

include_local_bkgbool, optional

Whether to include the local background in the subtracted model. Note that the local background level is subtracted around each source over the region defined by psf_shape. Thus, regions where the psf_shape of sources overlap will have the local background subtracted multiple times. Non-finite local background values (NaN or inf) are not subtracted from the residual image.

Returns:
array2D ndarray

The residual image of the data minus the fit PSF models minus the optional``local_bkg``.

results_to_init_params(*, remove_invalid=True, reset_ids=True)[source]#

Create a table of the fitted model parameters from the results.

The table columns are named according to those expected for the initial parameters table. It can be used as the init_params for subsequent PSFPhotometry fits.

Parameters:
remove_invalidbool, optional

If True, rows that contain non-finite fitted values are removed.

reset_idsbool, optional

If True, the ‘id’ column will be reset to a sequential numbering starting from 1. If False, the ‘id’ column will remain unchanged from the results table. This option is ignored if remove_invalid is False.

results_to_model_params(*, remove_invalid=True, reset_ids=True)[source]#

Create a table of the fitted model parameters from the results.

The table columns are named according to the PSF model parameter names. It can also be used to reconstruct the fitted PSF models for visualization or further analysis.

Parameters:
remove_invalidbool, optional

If True, rows that contain non-finite fitted values are removed.

reset_idsbool, optional

If True, the ‘id’ column will be reset to a sequential numbering starting from 1. If False, the ‘id’ column will remain unchanged from the results table. This option is ignored if remove_invalid is False.