Point Spread Functions

To implement your own subtype of a PointSpreadFunction you need to decide if the type you want to implement is a model (PSFModel) or something else.

TransferFunctions.PSFModelType
PSFModel <: PointSpreadFunction

PointSpreadFunction subtype for PSF models. A PSF model is a PointSpreadFunction that has parameters accessible through params and can be fitted to data.

source

If there is some symmetry in the PSF, you should implement the TransferFunctions.symmetry method which may lead to optimization of the methods that are defined on the abstract types.

There are two types of symmetries as of now

TransferFunctions.NoSymmetryType
NoSymmetry <: PointSpreadFunctionSymmetry

NoSymmetry marks a PointSpreadFunction that is not symmetric in any way. You need to compute every $x$, $y$, $z$ coordinate separately.

source
TransferFunctions.ZAxisRadialSymmetryType
ZAxisRadialSymmetry <: PointSpreadFunctionSymmetry

$z$ axis radial symmetry of a PointSpreadFunction indicates that the PSF is symmetric in the radially around the z-axis.

source

Next you have to implement the TransferFunctions.intensity method for the correct arguments which you have to determine from the type of TransferFunctions.PointSpreadFunctionSymmetry that is used for the type of PSF that you want to implement.

TransferFunctions.intensityFunction
intensity(psf::PointSpreadFunction, r::Length...)

The intensity of the PointSpreadFunction at the given coordinates.

For different PointSpreadFunctionSymmetry of the psf, it has to be defined for different arguments.

  • symmetry(psf) == ZAxisRadialSymmetry() && psf isa PointSpreadFunction{2} then a single argument version must be defined
intensity(psf, r::Length) = # ...
  • symmetry(psf) == ZAxisRadialSymmetry() && psf isa PointSpreadFunction{3} then a two argument version must be defined
intensity(psf, r::Length, z::Length) = # ...
  • symmetry(psf) == NoSymmetry() && psf isa PointSpreadFunction{2} then a two argument version must be defined
intensity(psf, x::Length, y::Length) = # ...
  • symmetry(psf) == NoSymmetry() && psf isa PointSpreadFunction{3} then a three argument version must be defined
intensity(psf, x::Length, y::Length, z::Length) = # ...
source
intensity(psf::AiryDisc, r::Length)

Compute the intensity of the AiryDisc PSF at a distance r from its center.

Intensity of the Airy disc is given by $h(r) = (2J₁(αr)/(αr))²$ where $α = 2πNA/λ$ and $J₁$ is the first order Bessel function of the first kind.

source
intensity(tf::AiryDisc{3}, r::Length, z::Length)

Compute the intensity of the AiryDisc PSF at a distance r from its center and $z$-offset z.

It is defined as the product of the lateral intensity and the axial intensity.

source

For a subtype that has parameters that may be optimized to fit the PSF to data, you should implement the TransferFunctions.params method