prysm.otf#
MTF/PTF/OTF calculations.
- prysm.otf.transform_psf(psf, dx=None)#
Transform a PSF to k-space without further modification.
- prysm.otf.transform_psf_adjoint(data_bar)#
Apply the adjoint of the linear FT performed by transform_psf.
transform_psf maps a real PSF to the complex k-space field fftshift(fft2(ifftshift(psf))). This is its conjugate-transpose: it maps a gradient defined on the k-space field back to the PSF plane. The df scalar returned by transform_psf is sampling metadata and carries no gradient.
- Parameters:
data_bar (ndarray) – gradient at the k-space (OTF) plane
- Returns:
gradient at the PSF plane
- Return type:
ndarray
- prysm.otf.mtf_from_psf(psf, dx=None, return_more=False)#
Compute the MTF from a given PSF.
- Parameters:
psf (prysm.RichData or ndarray) – object with data property having 2D data containing the psf, or the array itself
dx (float) – sample spacing of the data
return_more (bool) – if True, also return the complex k-space transform of the PSF (the same array transform_psf produces). Hand it to mtf_from_psf_adjoint as data to skip recomputing the forward FT in the reverse pass.
- Returns:
RichData – container holding the MTF, ready for plotting or slicing.
ndarray – the complex transform; only returned if return_more is True.
- prysm.otf.ptf_from_psf(psf, dx=None, return_more=False)#
Compute the PTF from a given PSF.
- Parameters:
psf (prysm.RichData or ndarray) – object with data property having 2D data containing the psf, or the array itself
dx (float) – sample spacing of the data
return_more (bool) – if True, also return the complex k-space transform of the PSF (the same array transform_psf produces). Hand it to ptf_from_psf_adjoint as data to skip recomputing the forward FT in the reverse pass.
- Returns:
RichData – container holding the MTF, ready for plotting or slicing.
ndarray – the complex transform; only returned if return_more is True.
- prysm.otf.otf_from_psf(psf, dx=None, return_more=False)#
Compute the OTF from a given PSF.
- Parameters:
psf (ndarray) – 2D data containing the psf
dx (float) – sample spacing of the data
return_more (bool) – if True, also return the complex k-space transform of the PSF (the same array transform_psf produces, prior to the center normalization). Hand it to otf_from_psf_adjoint as data to skip recomputing the forward FT in the reverse pass.
- Returns:
RichData – container holding the OTF, complex.
ndarray – the unnormalized complex transform; only returned if return_more is True.
- prysm.otf.mtf_ptf_otf_from_psf(psf, dx=None, return_more=False)#
Compute the MTF, PTF, and OTF from a PSF with a single forward transform.
The three transfer functions are the modulus, argument, and complex value of the same center-normalized transform, so computing them together does the forward FT once instead of once per quantity.
- Parameters:
- Returns:
mtf, ptf, otf (RichData) – the modulation, phase, and complex optical transfer functions
ndarray – the raw complex transform; only returned if return_more is True.
- prysm.otf.mtf_from_psf_adjoint(mtf_bar, psf=None, dx=None, data=None)#
Apply the adjoint of mtf_from_psf.
Maps a gradient defined on the (center-normalized) MTF back to the real PSF. The forward map is mtf = abs(F[psf]) / abs(F[psf])[center]; this differentiates through both the modulus and the normalization by the central value.
- Parameters:
mtf_bar (ndarray) – gradient at the MTF plane
psf (prysm.RichData or ndarray) – the PSF the MTF was computed from; used to recompute the forward FT when data is not supplied
dx (float) – sample spacing of the PSF; required if psf is a bare array
data (ndarray) – the complex transform from mtf_from_psf(…, return_more=True). When given, the forward FT is reused instead of recomputed and psf/dx are ignored.
- Returns:
gradient at the PSF plane
- Return type:
ndarray
- prysm.otf.ptf_from_psf_adjoint(ptf_bar, psf=None, dx=None, data=None)#
Apply the adjoint of ptf_from_psf.
Maps a gradient defined on the (center-referenced) PTF back to the real PSF. The forward map is ptf = angle(F[psf]) - angle(F[psf])[center].
- Parameters:
ptf_bar (ndarray) – gradient at the PTF plane
psf (prysm.RichData or ndarray) – the PSF the PTF was computed from; used to recompute the forward FT when data is not supplied
dx (float) – sample spacing of the PSF; required if psf is a bare array
data (ndarray) – the complex transform from ptf_from_psf(…, return_more=True). When given, the forward FT is reused instead of recomputed and psf/dx are ignored.
- Returns:
gradient at the PSF plane
- Return type:
ndarray
- prysm.otf.otf_from_psf_adjoint(otf_bar, psf=None, dx=None, data=None)#
Apply the adjoint of otf_from_psf.
Maps a gradient defined on the (center-normalized) complex OTF back to the real PSF. The forward map is otf = F[psf] / F[psf][center].
- Parameters:
otf_bar (ndarray) – gradient at the OTF plane; complex
psf (prysm.RichData or ndarray) – the PSF the OTF was computed from; used to recompute the forward FT when data is not supplied
dx (float) – sample spacing of the PSF; required if psf is a bare array
data (ndarray) – the unnormalized complex transform from otf_from_psf(…, return_more=True). When given, the forward FT is reused instead of recomputed and psf/dx are ignored.
- Returns:
gradient at the PSF plane
- Return type:
ndarray
- prysm.otf.encircled_energy(psf, dx, radius, return_more=False)#
Compute the encircled energy of the PSF.
- Parameters:
psf (ndarray) – 2D array containing PSF data
dx (float) – sample spacing of psf
radius (float or iterable) – radius or radii to evaluate encircled energy at
return_more (bool) – if True, also return the complex k-space transform of the PSF. Hand it to encircled_energy_adjoint as data to skip recomputing the forward FT in the reverse pass.
- Returns:
encircled energy – if radius is a float, returns a float, else returns an array.
ndarray – the complex transform; only returned if return_more is True.
Notes
implementation of “Simplified Method for Calculating Encircled Energy,” Baliga, J. V. and Cohn, B. D., doi: 10.1117/12.944334
- prysm.otf.encircled_energy_adjoint(ee_bar, psf=None, dx=None, radius=None, data=None)#
Apply the adjoint of encircled_energy.
Encircled energy is a linear functional of the MTF (a radius-weighted sum of a Hankel kernel against the MTF), so its adjoint folds the per-radius gradients into a single MTF-plane gradient and routes that back through mtf_from_psf_adjoint to the PSF.
- Parameters:
ee_bar (float or ndarray) – gradient of the loss with respect to the encircled energy; a scalar for a single radius, otherwise one value per radius matching radius
psf (prysm.RichData or ndarray) – the PSF the encircled energy was computed from; used to recompute the forward FT when data is not supplied
dx (float) – sample spacing of the PSF; always required, as it sets the frequency grid
radius (float or iterable) – the radius/radii encircled_energy was evaluated at
data (ndarray) – the complex transform from encircled_energy(…, return_more=True). When given, the forward FT is reused instead of recomputed.
- Returns:
gradient at the PSF plane
- Return type:
ndarray
- prysm.otf.analytical_encircled_energy_circular_aperture(fno, wavelength, points)#
Compute the analytical encircled energy for a diffraction limited circular aperturnp.
- prysm.otf.diffraction_limited_mtf(fno, wavelength, frequencies=None, samples=128)#
Give the diffraction limited MTF for a circular pupil and the given parameters.
- Parameters:
- Returns:
if frequencies not given –
- frequenciesndarray
array of ordinate data
- mtfndarray
array of coordinate data
else –
- mtfndarray
array of MTF data
Notes
If frequencies are given, just returns the MTF. If frequencies are not given, returns both the frequencies and the MTF.
- prysm.otf.longexposure_otf(nu, Cn, z, f, lambdabar, h_z_by_r=2.91)#
Compute the long exposure OTF for given parameters.
- Parameters:
nu (ndarray) – spatial frequencies, cy/mm
Cn (float) – atmospheric structure constant of refractive index, ranges ~ 10^-13 - 10^-17
z (float) – propagation distance through atmosphere, m
f (float) – effective focal length of the optical system, mm
lambdabar (float) – mean wavelength, microns
h_z_by_r (float, optional) – constant for h[z/r] – see Eq. 8.5-37 & 8.5-38 in Statistical Optics, J. Goodman, 2nd ed.
- Returns:
the OTF
- Return type:
ndarray
- prysm.otf.komogorov(r, r0)#
Calculate the phase structure function D_phi in the komogorov approximation.
- Parameters:
r (ndarray) – r, radial frequency parameter (object space)
r0 (float) – Fried parameter
- Return type:
ndarray
- prysm.otf.estimate_Cn(P=1013, T=273.15, Ct=0.0001)#
Use Weng et al to estimate Cn from meteorological data.