TablePSF

class gammapy.irf.TablePSF(rad, dp_domega, spline_kwargs={'k': 1, 's': 0})[source]

Bases: object

Radially-symmetric table PSF.

This PSF represents a \(PSF(r)=dP / d\Omega(r)\) spline interpolation curve for a given set of offset \(r\) and \(PSF\) points.

Uses scipy.interpolate.UnivariateSpline.

Parameters:

rad : Quantity with angle units

Offset wrt source position

dp_domega : Quantity with sr^-1 units

PSF value array

spline_kwargs : dict

Keyword arguments passed to UnivariateSpline

Notes

  • This PSF class works well for model PSFs of arbitrary shape (represented by a table), but might give unstable results if the PSF has noise. E.g. if dp_domega was estimated from histograms of real or simulated event data with finite statistics, it will have noise and it is your responsibility to check that the interpolating spline is reasonable.
  • To customize the spline, pass keyword arguments to UnivariateSpline in spline_kwargs. E.g. passing dict(k=1) changes from the default cubic to linear interpolation.
  • TODO: evaluate spline for (log(rad), log(PSF)) for numerical stability?
  • TODO: merge morphology.theta class functionality with this class.
  • TODO: add FITS I/O methods
  • TODO: add normalize argument to __init__ with default True?
  • TODO: __call__ doesn’t show up in the html API docs, but it should: https://github.com/astropy/astropy/pull/2135

Methods Summary

__call__(lon, lat) Evaluate PSF at a 2D position.
broaden(factor[, normalize]) Broaden PSF by scaling the offset array.
containment_radius(fraction) Containment radius.
evaluate(rad[, quantity]) Evaluate PSF.
from_shape(shape, width, rad) Make TablePSF objects with commonly used shapes.
info() Print basic info.
integral([rad_min, rad_max]) Compute PSF integral, aka containment fraction.
normalize() Normalize PSF to unit integral.
plot_psf_vs_rad([ax, quantity]) Plot PSF vs radius.

Methods Documentation

__call__(lon, lat)[source]

Evaluate PSF at a 2D position.

The PSF is centered on (0, 0).

Parameters:

lon, lat : Angle

Longitude / latitude position

Returns:

psf_value : Quantity

PSF value

broaden(factor, normalize=True)[source]

Broaden PSF by scaling the offset array.

For a broadening factor \(f\) and the offset array \(r\), the offset array scaled in the following way:

\[r_{new} = f \times r_{old} \frac{dP}{dr}(r_{new}) = \frac{dP}{dr}(r_{old})\]
Parameters:

factor : float

Broadening factor

normalize : bool

Normalize PSF after broadening

containment_radius(fraction)[source]

Containment radius.

Parameters:

fraction : array_like

Containment fraction (range 0 .. 1)

Returns:

rad : Angle

Containment radius angle

evaluate(rad, quantity='dp_domega')[source]

Evaluate PSF.

The following PSF quantities are available:

  • ‘dp_domega’: PDF per 2-dim solid angle \(\Omega\) in sr^-1

    \[\frac{dP}{d\Omega}\]
  • ‘dp_dr’: PDF per 1-dim offset \(r\) in radian^-1

    \[\frac{dP}{dr} = 2 \pi r \frac{dP}{d\Omega}\]
Parameters:

rad : Angle

Offset wrt source position

quantity : {‘dp_domega’, ‘dp_dr’}

Which PSF quantity?

Returns:

psf_value : Quantity

PSF value

classmethod from_shape(shape, width, rad)[source]

Make TablePSF objects with commonly used shapes.

This function is mostly useful for examples and testing.

Parameters:

shape : {‘disk’, ‘gauss’}

PSF shape.

width : Quantity with angle units

PSF width angle (radius for disk, sigma for Gauss).

rad : Quantity with angle units

Offset angle

Returns:

psf : TablePSF

Table PSF

Examples

>>> import numpy as np
>>> from astropy.coordinates import Angle
>>> from gammapy.irf import TablePSF
>>> TablePSF.from_shape(shape='gauss', width='0.2 deg',
...                     rad=Angle(np.linspace(0, 0.7, 100), 'deg'))
info()[source]

Print basic info.

integral(rad_min=None, rad_max=None)[source]

Compute PSF integral, aka containment fraction.

Parameters:

rad_min, rad_max : Quantity with angle units

Offset angle range

Returns:

integral : float

PSF integral

normalize()[source]

Normalize PSF to unit integral.

Computes the total PSF integral via the \(dP / dr\) spline and then divides the \(dP / dr\) array.

plot_psf_vs_rad(ax=None, quantity='dp_domega', **kwargs)[source]

Plot PSF vs radius.

TODO: describe PSF quantity argument in a central place and link to it from here.