MTFs

Prysm models often include analysis of Modulation Transfer Function (MTF) data. The MTF is formally defined as:

the normalized magnitude of the Fourier transform of the point spread function

It is nothing more and nothing less. It may not be negative, complex-valued, or equal to any value other than unity at the origin.

Initializing an MTF model should feel similar to a PSF,

>>> import numpy as np
>>> from prysm import MTF
>>> x = y = 1/np.linspace(-1,1,128)
>>> z = np.random.random((128,128))
>>> mt = MTF(data=z, unit_x=x, unit_y=y)

MTFs are usually created from a PSF instance

>>> mt = MTF.from_psf(your_psf_instance)

If modeling the MTF directly from a pupil plane, the intermediate PSF plane may be skipped;

>>> mt = MTF.from_pupil(your_pupil_instance, Q=2, efl=2)

Much like a PSF or other Convolvable, MTFs have quick-access slices

>>> print(mt.tan)
    (array([...]), array([...]))
>>> print(mt.sag)
    (array([...]), array([...]))

The tangential MTF is a slice through the x=0 axis, and assumes the usual optics sign convention of an object extended in y. The sagittal MTF is a slice through the y=0 axis.

The MTF at exact frequencies may be queried through any of the following methods: (MTF).exact_polar, takes arguments of freqs and azimuths. If there is a single frequency and multiple azimuths, the MTF at each azimuth and and the specified radial spatial frequency will be returned. The reverse is true for a single azimuth and multiple frequencies. (MTF).exact_xy follows the same semantics, but with Cartesian coordinates instead of polar. (MTF).exact_tan and (MTF).exact_sag both take a single argument of freq, which may be an int, float, or ndarray.

Finally, MTFs may be plotted:

>>> mt.plot_tan_sag(max_freq=200, fig=None, ax=None, labels=('Tangential', 'Sagittal'))
>>> mt.plot2d(max_freq=200, power=1, fig=None, ax=None)

all arguments have these default values. The axes of plot2d will span (-max_freq, max_freq) on both x and y.

The complete API documentation is below.


class prysm.otf.MTF(data, unit_x, unit_y=None)[source]

Bases: object

Modulation Transfer Function.

tan: slice along the X axis of the MTF object.

sag: slice along the Y axis of the MTF object.

center_x : int
x center pixel location (MTF == 1 here by definition)
center_y : int
y center pixel location (MTF == 1 here by definition)
data : numpy.ndarray
MTF data array, 2D
interpf_2d : scipy.interpolate.RegularGridInterpolator
2D interpolation function used to compute exact values of the 2D MTF
interpf_sag : scipy.interpolate.interp1d
1D interpolation function used to compute exact values of the sagittal MTF
interpf_tan : scipy.interpolate.interp1d
1D interpolation function used to compute exact values of the tangential MTF
unit_x : numpy.ndarray
ordinate x coordinates
unit_y : TYPE
ordinate y coordinates
azimuthal_average()[source]

Return the azimuthally averaged MTF.

nu : numpy.ndarray
spatial frequencies
mtf : numpy.ndarray
mtf values
exact_polar(freqs, azimuths=None)[source]

Retrieve the MTF at the specified frequency-azimuth pairs.

freqs : iterable
radial frequencies to retrieve MTF for
azimuths : iterable
corresponding azimuths to retrieve MTF for
list
MTF at the given points
exact_sag(freq)[source]

Return data at an exact y coordinate along the x=0 axis.

freq : number or numpy.ndarray
frequency or frequencies to return
numpy.ndarray
ndarray of MTF values
exact_tan(freq)[source]

Return data at an exact x coordinate along the y=0 axis.

freq : number or numpy.ndarray
frequency or frequencies to return
numpy.ndarray
ndarray of MTF values
exact_xy(x, y=None)[source]

Retrieve the MTF at the specified X-Y frequency pairs.

x : iterable
X frequencies to retrieve the MTF at
y : iterable
Y frequencies to retrieve the MTF at
list
MTF at the given points
static from_psf(psf)[source]

Generate an MTF from a PSF.

psf : PSF
PSF to compute an MTF from
MTF
A new MTF instance
static from_pupil(pupil, efl, Q=2)[source]

Generate an MTF from a pupil, given a focal length (propagation distance).

pupil : Pupil
A pupil to propagate to a PSF, and convert to an MTF
efl : float
Effective focal length or propagation distance of the wavefunction
Q : number
ratio of pupil sample count to PSF sample count. Q > 2 satisfies nyquist
MTF
A new MTF instance
plot2d(max_freq=200, power=1, fig=None, ax=None)[source]

Create a 2D plot of the MTF.

max_freq : float
Maximum frequency to plot to. Axis limits will be ((-max_freq, max_freq), (-max_freq, max_freq)).
power : float
inverse of power to stretch the MTF to/by, e.g. power=2 will plot MTF^(1/2)
fig : matplotlib.figure.Figure, optional:
Figure to draw plot in
ax : matplotlib.axes.Axis, optional:
Axis to draw plot in
fig : matplotlib.figure.Figure
Figure to draw plot in
ax : matplotlib.axes.Axis
Axis to draw plot in
plot_tan_sag(max_freq=200, fig=None, ax=None, labels=('Tangential', 'Sagittal'))[source]

Create a plot of the tangential and sagittal MTF.

max_freq : float
Maximum frequency to plot to. Axis limits will be ((-max_freq, max_freq), (-max_freq, max_freq))
fig : matplotlib.figure.Figure, optional:
Figure to draw plot in
ax : matplotlib.axes.Axis, optional:
Axis to draw plot in
labels : iterable
set of labels for the two lines that will be plotted
fig : matplotlib.figure.Figure
Figure to draw plot in
ax : matplotlib.axes.Axis
Axis to draw plot in
sag

Retrieve the sagittal MTF.

Assumes the object is extended in y. If the object is extended along a different azimuth, this will not return the sagittal MTF.

self.unit_x : numpy.ndarray
ordinate
self.data : numpy.ndarray
coordiante
tan

Retrieve the tangential MTF.

Assumes the object is extended in y. If the object is extended along a different azimuth, this will not return the tangential MTF.

self.unit_x : numpy.ndarray
ordinate
self.data : numpy.ndarray
coordiante