Pupils

Most any physical optics model begins with a description of a wave at a pupil plane. This page will cover the core functionality of pupils; each analytical variety has its own documentation.

All Pupil parameters have default values, so one may be created with no arguments;

>>> from prysm import Pupil
>>> p = Pupil()

Pupils will be modeled using square arrays, the shape of which is controlled by a samples argument. They also accept an epd argument which controls their diameter in mm, as well as a wavelength which sets the wavelength of light used in microns. There is also an opd_unit argument that tells prysm what units are used to describe the phase associated with the pupil. Finally, a mask may be specified, either as a string using prysm’s built-in masking capabilities, or as an array of the same shape as the pupil. Putting it all together,

>>> p = Pupil(samples=123, epd=456.7, wavelength=1.0, opd_unit='nm', mask='dodecagon')

p is a pupil with a 12-sided aperture backed by a 123x123 array which spans 456.7 mm and is impinged on by light of wavelength 1 micron.

Pupils have some more advanced parameters. mask_target determines if the phase (‘phase’), wavefunction (‘fcn’), or both (‘both’) will be masked. When embedding prysm in a task that repeatedly creates pupils, e.g. an optimizer for wavefront sensing, applying the mask to the phase is wasted computation and can be avoided.

If you wish to provide your own data for a pupil model, simply provide the ux, uy, and phase arguments, which are the x and y unit axes of shape (n,) and (m,), and phase is in units of opd_unit and of shape (m,n).

>>> p = Pupil(ux=x, uy=y, phase=phase, opd_unit='um')

Once a pupil is created, you can access quick access slices,

>>> p.slice_x  # returns tuple of unit, slice_of_phase
>>> p.slice_y

or evaluate the wavefront,

>>> p.pv, p.rms # in units of opd_unit

or Strehl ratio under the approximation given in [Welford],

>>> p.strehl  # ∈ [0,1]

The pupil may also be plotted. Plotting functions have defaults for all arguments, but may be overriden

>>> p.plot2d(cmap='RdYlBu', clim=(-100,100), interp_method='sinc')

cmap, clim and interp_method are passed directly to matplotlib. A figure and axis may also be provided if you would like to control these, for e.g. making a figure with multiple axes for different stages of the model

>>> from matplotlib import pyplot as plt
>>> fig, ax = plt.subplots(figsize=(10,10))
>>> p.plot2d(fig=fig, ax=ax)

A synthetic interferogram may be generated,

>>> fig, ax = plt.subplots(figsize=(4,4))
>>> p.interferogram(passes=2, visibility=0.5, fig=fig, ax=ax)

Pupils also support addition and subtraction with other pupil objects,

>>> p2 = p + p - p
[Welford]
    1. Welford, Aberrations of Optical Systems. CRC Press, 1986.

The complete API documentation is below.


class prysm.pupil.Pupil(samples=128, epd=1.0, wavelength=0.55, opd_unit='waves', mask='circle', mask_target='both', ux=None, uy=None, phase=None)[source]

Bases: prysm._phase.OpticalPhase

Pupil of an optical system.

slice_x: numpy.ndarray
slice through the x axis of the pupil. Returns (x,y) data where x is the sample coordinate and y is the phase.
slice_y: numpy.ndarray
slice through the y axis of the pupil. Returns (x,y) data where x is the sample coordinate and y is the phase.
pv: float
Peak-To-Valley wavefront error.
rms: float
Root Mean Square wavefront error.
Sa: float
Sa wavefront error.

subclasses should implement a build() method and their own way of expressing OPD.

center : int
index of the center sample, may be sheared by 1/2 for even sample counts
epd : float
entrance pupil diameter, mm
fcn : numpy.ndarray
wavefunction, complex 2D array
opd_unit : str
unit used to m.express phase errors
phase : numpy.ndarray
phase, real 2D array
rho : numpy.ndarray
radial ordinate axis, normalized units
sample_spacing : float
spacing of samples, mm
samples : int
number of samples across the pupil diameter
unit : numpy.ndarray
1D array which gives the sample locations across the 2D pupil region
wavelength : float
wavelength of light, um
_mask : numpy.ndarray
mask used to define pupil extent and amplitude
mask_target : str
target for automatic masking on pupil creation
build()[source]

Construct a numerical model of a Pupil.

The method should be overloaded by all subclasses to impart their unique mathematical models to the simulation.

Pupil
this pupil instance
clone()[source]

Create a copy of this pupil.

Pupil
a deep copy duplicate of this pupil
fcn

Complex wavefunction associated with the pupil.

static from_interferogram(interferogram, wvl=None)[source]

Create a new Pupil instance from an interferogram.

interferogram : Interferogram
an interferogram object
wvl : float, optional
wavelength of light, in micrometers, if not present in interferogram.meta
Pupil
new Pupil instance
ValueError
wavelength not present
mask(mask, target)[source]

Apply a mask to the pupil.

Used to implement vignetting, chief ray angles, etc.

mask : str or numpy.ndarray
if a string, uses geometry.mcache for high speed access to a mask with a given shape, e.g. mask=’circle’ or mask=’hexagon’. If an ndarray, directly use the mask.
target : str, {‘phase’, ‘fcn’, ‘both’}
which array to mask;
Pupil
self, the pupil instance
strehl

Strehl ratio of the pupil.