pyoptics.raytrace

Sequential ray tracing through optical systems.

A System is a sequence of Surface objects (spheres, conics and even aspheres, refracting or reflecting), optional IdealLens surfaces, cones (Axicon), surfaces with a Fringe Zernike departure (ZernikeSurface: figure errors, mount deformations, freeforms) and CoordinateBreak elements. Surfaces can be decentred and tilted. Rays are traced exactly (exact intersections, vector law of refraction and reflection); paraxial marginal and chief rays, the pupils, the powers of the system, its surfaces and elements, the Seidel sums of every surface, the Petzval sum, the third order image surfaces and distortion, the primary colour and the closeness of the surfaces to a pupil or a field come from a paraxial y-nu trace, whose system matrix agrees with pyoptics.abcd (the ray footprints on the surfaces give the real ray closeness). The main result is the optical path difference (OPD) over the pupil, which can be fitted with Fringe Zernikes and handed on to pyoptics.imaging for PSFs, MTFs and Strehl ratios.

Sign conventions

  • The optical axis is z, light enters the system travelling in +z. The vertex of the first surface lies at z = 0. The field lies in the meridional y-z plane (field points at +y).

  • Radii R > 0 if the centre of curvature lies in +z of the vertex (as in abcd). A biconvex lens has R1 > 0 and R2 < 0; a concave mirror facing light that travels in +z has R < 0.

  • The sag of a surface is

    z(r) = c r**2/(1 + sqrt(1 - (1 + K) c**2 r**2)) + A4 r**4 + A6 r**6 + ...
    

    with c = 1/R, the conic constant K (0 sphere, -1 paraboloid, < -1 hyperboloid, (-1, 0) prolate ellipsoid, > 0 oblate ellipsoid) and the aspheric coefficients aspheric = (A4, A6, …).

  • thickness is the signed distance in z from a vertex to the next vertex (for the last surface: to the image plane). Behind a mirror, light travels in -z and thicknesses are negative. Refractive indices stay positive.

  • Paraxial slopes u = dy/dz. Internally, the paraxial trace uses signed indices (-n while light travels in -z), so that mirrors are refractions with n’ = -n.

  • Field: for an object at infinity, the field is the angle in radians of the incoming rays with the z axis (rays point upwards, +y, for field > 0). For a finite object, it is the object height y. Fields can also be given as pairs (x, y): angles whose tangents are the direction slopes dx/dz and dy/dz, or object points (x, y).

  • Pupil coordinates (P_x, P_y) are normalized coordinates in the paraxial entrance pupil (unit disk). With ray aiming (default), a ray with pupil coordinates (P_x, P_y) hits the stop at (P_x, P_y) times its semi diameter; the chief ray passes the centre of the stop.

Optical path difference

The OPD of a ray is its optical path to the reference sphere minus that of the chief ray, OPD = OPL_ray - OPL_chief. The reference sphere is centred on the point where the real chief ray hits the image plane and passes through the point where the chief ray crosses the paraxial exit pupil plane. With the pyoptics convention exp(i(k.r - omega*t)), the field on the reference sphere is proportional to exp(+i k_0 OPL), so the pupil phase is

phase = +2*pi*OPD/wavelength.

E.g. an image plane dz behind a perfect focus gives OPD = n’ dz (cos(alpha) - 1) < 0 at the rim, the same phase that the angular spectrum propagator applies over dz. A positive lens with undercorrected spherical aberration (marginal rays focus short) has OPD < 0 at the rim (W040 < 0). The transverse ray aberration is eps = (R/n’) dW/dY (R: radius of the reference sphere, Y: height in the exit pupil).

Fresnel lenses (a parent surface collapsed into zones, with real facets and risers) are fresnel.FresnelSurface, a subclass of Surface.

Tilts and decentres

Every surface has a local frame in which it is the centred surface described above. A surface’s decenter=(dx, dy) and tilt=(a_x, a_y, a_z) move it relative to the current axis frame: first the decentre, then the rotations about the local x, y and z axes in this order (the local-to-axis rotation is R_x(a_x) R_y(a_y) R_z(a_z), counterclockwise about the respective axis, so a_x > 0 turns +z towards -y). Like Zemax’s “decenter and return”, this only moves the surface itself; the axis for the following surfaces is unchanged. A CoordinateBreak instead changes the axis frame for all following surfaces (fold mirrors, tilted sub-assemblies). The image plane can be decentred and tilted with image_decenter and image_tilt of System.

First order properties (paraxial(), seidel(), third_order(), chromatic_seidel(), the powers, the pupils used for ray aiming and for the reference sphere) are those of the nominal system with all tilts and decentres set to zero; a fold mirror is then an unfolded plane mirror. Real rays always see the actual geometry. Spot diagrams, ray fans, OPDs and PSFs are evaluated in the local frame of the image plane.

Interferometers and other double pass setups are traced unfolded: the surfaces up to a mirror and back again in reverse order (double_pass()). System.ray_map() interpolates the optical path of the rays onto a detector grid in the image plane; the phase difference of two such maps (test and reference arm) is the phase of the interferogram.

Polarization and energy

System.trace_polarization() follows the polarization and the power of every ray with Chipman’s 3 x 3 polarization ray tracing matrices P (global coordinates, E_out = P E_in). Each surface contributes

  • refraction: the Fresnel transmission of the s and p components, through the thin film coatings.Coating of the surface if it has one, times sqrt(n’ cos(theta’)/(n cos(theta))), so that |P E|**2 is the transmitted power fraction,

  • reflection (mirrors): the reflection coefficients of the coating on its substrate; a mirror without a coating is a perfect reflector,

  • ideal lenses: a rotation of the field with the ray (no loss),

and the medium behind it, if it is a materials.Material, its absorption, retardance and diattenuation along the path. PolarizedBundle turns the matrices into the power along the trace, the transmittance and Jones matrices on the aplanatic bases of the object and image space ray directions. The optical path (and with it the OPD) stays the scalar one; P holds only the polarization dependent part of the phase. System.vectorial_focus() sums the traced rays, with their output fields and OPDs, as plane waves into the vectorial focus (Debye-Wolf integral).

Speed: if numba is installed (pip install pyoptics[fast]), System.trace() uses a compiled kernel that traces each ray through all surfaces in one loop (Surface, IdealLens, Axicon and CoordinateBreak; other surface types use the NumPy code). It agrees with the NumPy trace to rounding and is several times faster, most for the small bundles of ray aiming. The first trace in a session compiles the kernel (once, the result is cached on disk). Set raytrace.use_numba = False to trace with NumPy only.

Units: all lengths (radii, thicknesses, wavelength) share one unit, set by units of System (“mm” by default). It is only used to convert the wavelength to nm for the dispersion of materials.

Limitations: monochromatic traces (build systems at several wavelengths for colour), uniform pupil amplitude in the PSF, surfaces of revolution (no toroids) apart from the Zernike departures of ZernikeSurface, paraxial data only for the nominal centred system, no ray splitting in birefringent media (see materials).

References

    1. Welford, “Aberrations of Optical Systems”, Adam Hilger (1986).

R. Kingslake and R. B. Johnson, “Lens Design Fundamentals”, 2nd ed., Academic Press (2010).

G. H. Spencer and M. V. R. K. Murty, “General ray-tracing procedure”, J. Opt. Soc. Am. 52, 672-678 (1962).

J. B. Caldwell, “All-fused-silica 248-nm lithographic projection lens”, Optics & Photonics News 9(11), 40-41 (1998).

H.-J. Rostalski, A. Dodoc, A. Epple and H. Beierl, “Refractive projection objective for immersion lithography”, US 7,187,503 B2 (2007).

G. Fürter, J. Wangler, U. Dinger and G. Ittner, “REMA objective for microlithographic projection exposure systems”, US 5,982,558 (1999).

J. Wangler and J. Liegel, “Illuminating arrangement including a zoom objective incorporating two axicons”, US 5,675,401 (1997).

I. H. Malitson, “Interspecimen comparison of the refractive index of fused silica”, J. Opt. Soc. Am. 55, 1205-1209 (1965).

Classes

Axicon

Conical refracting surface (axicon).

ChromaticSeidel

Primary (first order) chromatic aberrations.

CoordinateBreak

Change of the axis frame for all following surfaces.

Footprints

Ray footprints on the surfaces (local frames), see System.footprints().

IdealLens

Ideal (paraxial) thin lens of focal length f in a plane.

OPDMap

OPD over the pupil: W[i, j] at (P_x, P_y) = (px[j], py[i]), NaN outside the pupil and for vignetted rays.

Paraxial

Paraxial (first order) properties of a System.

PolarizedBundle

Rays traced with their polarization (System.trace_polarization()).

Pupil

Exit pupil for pyoptics.imaging: image space NA, vacuum wavenumber k and callables phase(P_x, P_y) (radians) and mask(P_x, P_y) of the normalized imaging pupil coordinates, e.g. imaging.get_psf(x, y, pupil.NA, pupil.k, pupil.mask, pupil.phase).

RayBundle

Rays traced through a System.

RayFan

Transverse ray aberrations relative to the chief ray: tangential fan ey(P_y = p, P_x = 0) and sagittal fan ex(P_x = p, P_y = 0).

RayMap

Ray data interpolated onto a grid (x, y) of the image plane (in its local frame): opl[i, j] at (x[j], y[i]) is the optical path of the ray that arrives there, i.e. the phase of the field is k_0*opl (geometrical optics).

Rays

Rays: start points and unit directions, shape (N, 3), and the optical path already accumulated, shape (N,).

Seidel

Seidel sums.

SpotDiagram

Image plane intersections x, y relative to the chief ray, RMS radius about the centroid and the centroid (x, y).

Surface

Rotationally symmetric refracting or reflecting surface.

System

Sequential optical system.

ThirdOrder

Image surfaces and distortion from the Seidel sums.

ZernikeSurface

Surface with a Fringe Zernike departure from its base sag (freeform).

Functions

caldwell_krf_lens

All fused silica KrF lithography projection lens by J.

delano_krf_lens

20 element all fused silica KrF projection lens with 5 aspheres, NA 0.7, 4x, 1 m.

double_pass

Unfold a double pass: surfaces up to a mirror and back again.

fused_silica

Refractive index of fused silica (Malitson's Sellmeier formula, valid from 0.21 to 3.7 um).

fused_silica_arf

Fused silica for ArF lenses: Malitson's dispersion shifted to the index 1.56078570 at 193.368 nm of the Zeiss designs (Malitson's formula itself gives 1.56019 there); dn/dlambda = -1.58e-3 per nm.

rotation

Rotation matrix R_x(a_x) @ R_y(a_y) @ R_z(a_z).

zeiss_arfi_lens

Dioptric water immersion ArF projection lens, NA 1.35, by Carl Zeiss.

zeiss_krf_rema

REMA objective of a KrF illuminator (Carl Zeiss, US 5,982,558).

zeiss_zoom_axicon

Zoom-axicon objective of a lithography illuminator (Carl Zeiss, US 5,675,401), adapted to KrF.

pyoptics.raytrace.rotation(a_x=0.0, a_y=0.0, a_z=0.0)[source]

Rotation matrix R_x(a_x) @ R_y(a_y) @ R_z(a_z).

Parameters:
a_x, a_y, a_znumbers, optional

Angles in radians, counterclockwise about the respective axis.

Returns:
R3x3 array
class pyoptics.raytrace.Surface(R=inf, thickness=0.0, n_after=None, material=None, conic=0.0, aspheric=(), semi_diameter=None, mirror=False, decenter=(0.0, 0.0), tilt=(0.0, 0.0, 0.0), coating=None, label=None, index_offset=0.0)[source]

Bases: object

Rotationally symmetric refracting or reflecting surface.

Parameters:
Rnumber, optional

Vertex radius of curvature (R > 0: centre of curvature in +z). np.inf (default) for a plane.

thicknessnumber, optional

Signed axial distance to the next vertex (or to the image plane).

n_afternumber, optional

Refractive index behind the surface. If neither n_after nor material are given, the medium does not change (dummy surfaces, stops, mirrors).

materialtuple, callable or materials.Material, optional

(n_d, V_d) for materials.abbe_dispersion(), a function n(wavelength_nm) or a Material (absorbing or anisotropic media for trace_polarization(); rays see its n_geometric()). Overrides n_after.

conicnumber, optional

Conic constant K.

asphericsequence, optional

Coefficients (A4, A6, A8, …) of r**4, r**6, r**8, …

semi_diameternumber, optional

Clear aperture radius; rays outside are vignetted. None: unlimited. On the stop surface it defines the aperture of the system.

mirrorbool, optional

Reflecting surface.

decenter(dx, dy), optional

Decentre of the surface in the axis frame.

tilt(a_x, a_y, a_z), optional

Tilt angles (radians) of the surface after the decentre, see the module docstring. Neither changes the axis of the following surfaces; the thickness is measured along the (untilted) axis from the undisplaced vertex.

coatingcoatings.Coating, optional

Thin film stack for trace_polarization() (layers from the medium in front of the surface); None: bare surface.

labelstr, optional
index_offsetnumber, optional

Added to the index of the medium behind the surface at every wavelength (index errors of a melt, see System.with_index_change()). Only for surfaces that change the medium. A Material keeps its own index in the polarization propagation of trace_polarization().

property c

Vertex curvature 1/R.

index(wavelength_nm, n_before)[source]

Refractive index behind the surface.

From the material (a materials.Material, a callable n(wavelength_nm) or a pair (n_d, V_d) for materials.abbe_dispersion), else from n_after, else the index in front of the surface is kept.

Parameters:
wavelength_nmnumber

Vacuum wavelength in nm.

n_beforenumber

Refractive index in front of the surface.

Returns:
nnumber
sag(r2)[source]

Sag z at the squared radius r2 = x**2 + y**2 (NaN beyond the conic).

intersect(P, d)[source]

Distance along the rays from their points to the surface.

Parameters:
P(N, 3) array

Start points relative to the vertex, in the local frame of the surface.

d(N, 3) array

Unit directions.

Returns:
t(N,) array

Distances to the intersections; NaN for rays that miss the surface.

normal(Q)[source]

Unit normals (pointing into +z) at the points Q relative to the vertex.

deflect(Q, d, n1, n2)[source]

Refract (or reflect) the directions d at the points Q.

Parameters:
Q(N, 3) array

Intersection points in the local frame of the surface.

d(N, 3) array

Unit directions of the incident rays.

n1, n2numbers

Refractive indices in front of and behind the surface.

Returns:
d2array

New unit directions, NaN under total internal reflection.

doplarray

Extra optical path (zero for real surfaces).

paraxial_power(n1, n2)[source]

Paraxial power of the surface.

Parameters:
n1, n2numbers

Signed refractive indices in front of and behind the surface (negative behind a mirror).

Returns:
powernumber

c*(n2 - n1), with n2*u2 = n1*u1 - y*power.

abcd_matrix(n1, n2, sigma)[source]

Unfolded ABCD matrix of the surface (see pyoptics.abcd).

Parameters:
n1, n2numbers

Refractive indices in front of and behind the surface.

sigma{1, -1}

Direction of the light along z.

Returns:
M2x2 array
class pyoptics.raytrace.IdealLens(f, thickness=0.0, semi_diameter=None, decenter=(0.0, 0.0), tilt=(0.0, 0.0, 0.0), label=None)[source]

Bases: Surface

Ideal (paraxial) thin lens of focal length f in a plane.

Every ray is bent towards the point where the parallel ray through the centre of the lens meets the focal plane, and the optical path is corrected such that collimated light is focused without aberrations at any field angle (like the paraxial surface of commercial codes). The medium does not change; f is the focal length in that medium.

deflect(Q, d, n1, n2)[source]

Deflect the rays towards the focal point of their bundle.

Parameters:
Q(N, 3) array

Intersection points in the plane of the lens.

d(N, 3) array

Unit directions of the incident rays.

n1, n2numbers

Refractive indices (equal for an ideal lens).

Returns:
d2array

New unit directions.

doplarray

Optical path correction that makes the lens free of aberrations.

paraxial_power(n1, n2)[source]

Paraxial power |n1|/f of the lens.

Parameters:
n1, n2numbers

Signed refractive indices in front of and behind the lens.

Returns:
powernumber
abcd_matrix(n1, n2, sigma)[source]

ABCD matrix of a thin lens with the focal length f/n1.

Parameters:
n1, n2numbers

Refractive indices in front of and behind the lens.

sigma{1, -1}

Direction of the light along z (unused).

Returns:
M2x2 array
class pyoptics.raytrace.Axicon(slope, thickness=0.0, n_after=None, material=None, semi_diameter=None, decenter=(0.0, 0.0), tilt=(0.0, 0.0, 0.0), coating=None, label=None)[source]

Bases: Surface

Conical refracting surface (axicon).

The sag is z(r) = slope*r: the surface is a cone around the axis whose generatrix makes the angle arctan(1/|slope|) with the axis (the “conical angle” of the patents). With slope > 0 the cone opens towards +z, e.g. a concave exit face of a glass element or a convex entrance face. Two cones of the same slope in contact act like a plane plate; pulled apart, they shift rays radially by about gap*tan(deviation), which turns a disk into a ring (annular illumination).

A cone has no paraxial power, the paraxial trace treats it as a plane.

Parameters:
slopenumber

dz/dr of the cone.

thickness, n_after, material, semi_diameter, decenter, tilt, coating, label

As for Surface.

sag(r2)[source]

Sag z = slope*r at the squared radius r2.

intersect(P, d)[source]

Distance along the rays from their points to the cone.

Parameters:
P(N, 3) array

Start points relative to the apex, in the local frame of the surface.

d(N, 3) array

Unit directions.

Returns:
t(N,) array

Distances to the intersections (the one next to the plane of the apex); NaN for rays that miss the cone.

class pyoptics.raytrace.ZernikeSurface(R=inf, thickness=0.0, zernike=None, norm_radius=1.0, **kwargs)[source]

Bases: Surface

Surface with a Fringe Zernike departure from its base sag (freeform).

The sag is

z(x, y) = z_base(r**2) + sum_j c_j Z_j(x/r_norm, y/r_norm)

with the sag z_base of Surface (sphere, conic, aspheric terms) and the Fringe Zernikes Z_j of bases.fringe_zernike() (peak value 1 on the unit circle) in the local frame of the surface. Like Zemax’s “Zernike Fringe Sag” surface, it models figure errors and mount deformations of a surface (a mirror on a three point mount, a clamped window) and freeforms. The departure only enters the real ray trace; the paraxial data, Seidel sums and draw() use the base surface. The compiled kernel does not cover it, systems with Zernike surfaces are traced with NumPy.

Parameters:
R, thickness, …optional

As for Surface (all keyword arguments are passed on).

zernikedict, optional

{j: c_j}, Fringe index and coefficient in length units.

norm_radiusnumber, optional

Normalization radius r_norm of the Zernikes.

departure(x, y)[source]

Zernike part of the sag at the points (x, y) of the local frame.

sag_xy(x, y)[source]

Sag z(x, y), base sag plus the Zernike departure.

intersect(P, d)[source]

Distance along the rays to the surface: from the base surface by Newton steps on the full sag (see Surface.intersect()).

normal(Q)[source]

Unit normals (pointing into +z) at the points Q relative to the vertex.

class pyoptics.raytrace.CoordinateBreak(decenter=(0.0, 0.0), tilt=(0.0, 0.0, 0.0), thickness=0.0, label=None)[source]

Bases: Surface

Change of the axis frame for all following surfaces.

The new frame is the current one moved by decenter = (dx, dy) and then rotated by tilt = (a_x, a_y, a_z) (see the module docstring); thickness is measured along the new z axis. A coordinate break does not interact with the rays. For a fold mirror tilted by a about x, put CoordinateBreak(tilt=(a, 0, 0)), the plane mirror, CoordinateBreak(tilt=(a, 0, 0), thickness=-d): behind the mirror, light travels in -z of the new frame. For a = pi/4, the beam is folded from +z to +y.

paraxial_power(n1, n2)[source]

Paraxial power, zero for a coordinate break.

Parameters:
n1, n2numbers

Refractive indices (unused).

Returns:
powerfloat
abcd_matrix(n1, n2, sigma)[source]

ABCD matrix of a coordinate break, the identity.

Parameters:
n1, n2numbers

Refractive indices (unused).

sigma{1, -1}

Direction of the light along z (unused).

Returns:
M2x2 array
class pyoptics.raytrace.PolarizedBundle(bundle, P, image_rotation)[source]

Bases: object

Rays traced with their polarization (System.trace_polarization()).

Attributes:
bundleRayBundle

The traced rays.

P(S + 2, N, 3, 3) complex array

Accumulated polarization ray tracing matrices (global frame) from the start of the rays to each plane of the bundle (the start, behind each surface, the image plane), including the media in between. NaN for lost rays.

image_rotation(3, 3) array

Rotation R of the image frame (global = R @ local).

property basis_in

Aplanatic bases (N, 3, 2) of the object space ray directions (global frame), the basis of the input Jones vectors.

property basis_out

Aplanatic bases (N, 3, 2) of the image space ray directions in the image frame, the basis of the output Jones vectors.

power(E_in=None)[source]

Power fractions (S + 2, N) of the rays at each plane: 1 at the start, then after every surface (and the medium in front of it).

E_inJones vector (2,) or (N, 2) on basis_in, optional

Input polarization (normalized here); None: unpolarized.

transmittance(E_in=None)[source]

Power transmittance (N,) of the rays to the image plane.

field(E_in)[source]

Output fields (N, 3) in the image frame for the input Jones vectors E_in (2,) or (N, 2) on basis_in (not normalized).

jones()[source]

Jones matrices (N, 2, 2) from basis_in to basis_out (see litho.jones_pupil.decompose() for diattenuation and retardance).

class pyoptics.raytrace.Rays(points, directions, opl)

Bases: tuple

Rays: start points and unit directions, shape (N, 3), and the optical path already accumulated, shape (N,).

directions

Alias for field number 1

opl

Alias for field number 2

points

Alias for field number 0

class pyoptics.raytrace.RayBundle(points, directions, opl, valid, n)

Bases: tuple

Rays traced through a System.

points(S + 2, N, 3) array

Start points (plane 0), intersections with the S surfaces and with the image plane (plane S + 1). NaN after a ray was lost.

directions(S + 2, N, 3) array

Unit directions behind each plane.

opl(S + 2, N) array

Accumulated optical path length.

valid(N,) bool array

Rays that reached the image plane (not vignetted, no misses, no TIR).

n(S + 1,) array

Refractive indices in front of the first surface and behind each surface.

directions

Alias for field number 1

n

Alias for field number 4

opl

Alias for field number 2

points

Alias for field number 0

valid

Alias for field number 3

class pyoptics.raytrace.Paraxial(efl, bfl, ffl, cardinal_points, ep_z, ep_radius, xp_z, xp_radius, image_distance, image_height, magnification, f_number, na, lagrange, marginal, chief, matrix)

Bases: tuple

Paraxial (first order) properties of a System.

Attributes:
efl, bfl, ffleffective, back and front focal length (bfl from the last

vertex, ffl in front of the first vertex)

cardinal_pointsabcd.CardinalPoints along the unfolded axis, z = 0 at the

first vertex

ep_z, ep_radiusz position and radius of the entrance pupil
xp_z, xp_radiusz position (global) and radius of the exit pupil
image_distancesigned z distance of the paraxial image from the last vertex
image_heightparaxial chief ray height in the paraxial image plane
magnificationlateral magnification (0 for an object at infinity)
f_numberefl/(2*ep_radius) (working F-number 1/(2*na) for finite objects)
naimage space numerical aperture n'*|u'| of the marginal ray
lagrangeLagrange invariant H = n*(u_chief*y_marginal - u_marginal*y_chief)
marginal, chief(S, 2) arrays of the ray height y at each vertex and the

slope u = dy/dz behind each surface

matrixABCD matrix (reduced angles n*theta, unfolded) from the first to

the last vertex

bfl

Alias for field number 1

cardinal_points

Alias for field number 3

chief

Alias for field number 15

efl

Alias for field number 0

ep_radius

Alias for field number 5

ep_z

Alias for field number 4

f_number

Alias for field number 11

ffl

Alias for field number 2

image_distance

Alias for field number 8

image_height

Alias for field number 9

lagrange

Alias for field number 13

magnification

Alias for field number 10

marginal

Alias for field number 14

matrix

Alias for field number 16

na

Alias for field number 12

xp_radius

Alias for field number 7

xp_z

Alias for field number 6

class pyoptics.raytrace.OPDMap(px, py, W)

Bases: tuple

OPD over the pupil: W[i, j] at (P_x, P_y) = (px[j], py[i]), NaN outside the pupil and for vignetted rays.

W

Alias for field number 2

px

Alias for field number 0

py

Alias for field number 1

class pyoptics.raytrace.Pupil(NA, k, phase, mask)

Bases: tuple

Exit pupil for pyoptics.imaging: image space NA, vacuum wavenumber k and callables phase(P_x, P_y) (radians) and mask(P_x, P_y) of the normalized imaging pupil coordinates, e.g. imaging.get_psf(x, y, pupil.NA, pupil.k, pupil.mask, pupil.phase).

NA

Alias for field number 0

k

Alias for field number 1

mask

Alias for field number 3

phase

Alias for field number 2

class pyoptics.raytrace.Seidel(S, total, W040, W131, W222, W220, W311, W, aspheric)

Bases: tuple

Seidel sums.

Attributes:
S(S_surfaces, 5) array of the contributions S_I…S_V of each surface
totalthe five sums S_I (spherical aberration), S_II (coma), S_III

(astigmatism), S_IV (Petzval curvature), S_V (distortion)

W040, W131, W222, W220, W311wavefront coefficients in waves at full

aperture and the given field, in the OPD convention of this module (Welford’s sums S_I…S_V are positive for undercorrected systems, which have W040 < 0 here):

W = W040 rho**4 + W131 H rho**3 cos(theta) + W222 H**2 rho**2 cos(theta)**2
    + W220 H**2 rho**2 + W311 H**3 rho cos(theta),
W040 = -S_I/8, W131 = -S_II/2, W222 = -S_III/2, W220 = -(S_III + S_IV)/4,
W311 = -S_V/2

(divided by the wavelength), theta measured from the y axis.

W(S_surfaces, 5) array of the per surface wavefront coefficients W040,

W131, W222, W220, W311 in waves (they add up to the totals)

aspheric(S_surfaces, 5) array, the part of S that comes from the

departure of the surface from its vertex sphere (conic and A4 r**4); S - aspheric is the contribution of the vertex sphere

The contributions of a surface depend on the paraxial marginal and chief
rays that reach it, i.e. on the surfaces in front of it and on the stop;
only their sum is a property of the system (Welford).
S

Alias for field number 0

W

Alias for field number 7

W040

Alias for field number 2

W131

Alias for field number 3

W220

Alias for field number 5

W222

Alias for field number 4

W311

Alias for field number 6

aspheric

Alias for field number 8

total

Alias for field number 1

class pyoptics.raytrace.ThirdOrder(petzval_sum, petzval_radius, sagittal_radius, tangential_radius, medial_radius, distortion)

Bases: tuple

Image surfaces and distortion from the Seidel sums.

Attributes:
petzval_sumsum of c*(n’ - n)/(n n’) = sum(phi/(n n’)) over the surfaces,

i.e. S_IV/H**2 (for thin lenses in air sum(phi_k/n_k))

petzval_radiusradius of the Petzval surface, -1/(n’_k*petzval_sum),

with the sign convention of the radii (R < 0: centre of curvature in -z, the image surface bends towards the lens, as for a positive singlet)

sagittal_radius, tangential_radius, medial_radiusradii of the third

order sagittal, tangential and medial (best, midway) image surfaces, 1/R_s = -n’_k (S_III + S_IV)/H**2, 1/R_t = -n’_k (3 S_III + S_IV)/H**2, 1/R_m = -n’_k (2 S_III + S_IV)/H**2 (np.inf for a flat surface)

distortionrelative third order distortion at the field, (real chief ray

height - paraxial image height)/paraxial image height = S_V/(2 n’_k u’_k eta’), with the paraxial marginal ray slope u’_k and image height eta’ (> 0: pincushion, < 0: barrel)

n’_k is the image space index (signed, -n’ behind an odd number of
mirrors). The astigmatic surfaces lie on the same side of the Petzval
surface, the tangential one three times as far away (Welford;
Kingslake and Johnson, ch. 4).
distortion

Alias for field number 5

medial_radius

Alias for field number 4

petzval_radius

Alias for field number 1

petzval_sum

Alias for field number 0

sagittal_radius

Alias for field number 2

tangential_radius

Alias for field number 3

class pyoptics.raytrace.ChromaticSeidel(C, total, axial, lateral, delta_n)

Bases: tuple

Primary (first order) chromatic aberrations.

Attributes:
C(S_surfaces, 2) array of the contributions C_I (axial colour) and C_II

(lateral colour) of each surface, C_I = A y Delta(dn/n), C_II = Abar y Delta(dn/n), with dn = n(short) - n(long) of the medium (Welford)

totalthe two sums
axialz position of the short wavelength paraxial image minus that of the

long one, -C_I/(n’_k u’_k**2) (< 0 for an undercorrected positive lens)

lateralparaxial chief ray height at the short wavelength minus that at

the long one, in the image plane of the system, C_II/(n’_k u’_k) (with the slope u = dy/dz of this module; Welford’s -C_II/(n’u’) in his angle convention)

delta_n(S + 1,) array of dn in object space and behind each surface
C

Alias for field number 0

axial

Alias for field number 2

delta_n

Alias for field number 4

lateral

Alias for field number 3

total

Alias for field number 1

class pyoptics.raytrace.Footprints(fields, centre, radius, total_radius, ratio, closeness)

Bases: tuple

Ray footprints on the surfaces (local frames), see System.footprints().

Attributes:
fieldsthe fields traced
centre(F, S, 2) array, centre (x, y) of the bounding box of the bundle of

each field on each surface

radius(F, S) array, radius sqrt(A/pi) of the circle with the area A of the

footprint (convex hull of the ray hits)

total_radius(S,) array, semi diameter filled by the rays of all fields

(largest distance of a ray from the vertex), or the semi diameters of the surfaces (relative_to=”aperture”)

ratio(F, S) array radius/total_radius, 1 at a pupil, near 0 at a field

surface; ratio**2 is the share of the area that one field fills

closeness(S,) array, the ratio averaged over the fields (NaN where all

rays were lost)

Coordinate breaks report the footprint in their own frame.
centre

Alias for field number 1

closeness

Alias for field number 5

fields

Alias for field number 0

radius

Alias for field number 2

ratio

Alias for field number 4

total_radius

Alias for field number 3

class pyoptics.raytrace.SpotDiagram(x, y, rms, centroid)

Bases: tuple

Image plane intersections x, y relative to the chief ray, RMS radius about the centroid and the centroid (x, y).

centroid

Alias for field number 3

rms

Alias for field number 2

x

Alias for field number 0

y

Alias for field number 1

class pyoptics.raytrace.RayFan(p, ey, ex)

Bases: tuple

Transverse ray aberrations relative to the chief ray: tangential fan ey(P_y = p, P_x = 0) and sagittal fan ex(P_x = p, P_y = 0).

ex

Alias for field number 2

ey

Alias for field number 1

p

Alias for field number 0

class pyoptics.raytrace.RayMap(x, y, opl, points, directions, mask)

Bases: tuple

Ray data interpolated onto a grid (x, y) of the image plane (in its local frame): opl[i, j] at (x[j], y[i]) is the optical path of the ray that arrives there, i.e. the phase of the field is k_0*opl (geometrical optics). points and directions (shape opl.shape + (3,)) are the global intersections with and unit directions behind the selected surface of the same rays. NaN and mask False where no ray arrives.

directions

Alias for field number 4

mask

Alias for field number 5

opl

Alias for field number 2

points

Alias for field number 3

x

Alias for field number 0

y

Alias for field number 1

class pyoptics.raytrace.System(surfaces, stop_index, wavelength, object_distance=inf, field_angle=0.0, object_height=0.0, n_object=1.0, units='mm', entrance_pupil_radius=None, ray_aiming=True, image_decenter=(0.0, 0.0), image_tilt=(0.0, 0.0, 0.0), background=None)[source]

Bases: object

Sequential optical system.

Parameters:
surfacessequence of Surface

Surfaces in the order the light meets them. The thickness of the last surface is the distance to the image plane.

stop_indexint

Index of the aperture stop surface. Its semi_diameter (or entrance_pupil_radius) sets the aperture.

wavelengthnumber

Vacuum wavelength in the length unit of the system.

object_distancenumber, optional

Distance of the object in front of the first vertex, np.inf (default) for an object at infinity.

field_anglenumber or pair, optional

Maximum field angle in radians (object at infinity); used as the default field of the methods.

object_heightnumber or pair, optional

Maximum object height (finite object).

n_objectnumber, optional

Refractive index of the object space.

unitsstr, optional

Length unit, one of NM_PER_UNIT (“mm” default).

entrance_pupil_radiusnumber, optional

If given, the semi diameter of the stop is set such that the paraxial entrance pupil has this radius.

ray_aimingbool, optional

Aim the rays at the real stop (default) instead of the paraxial entrance pupil.

image_decenter, image_tiltoptional

Decentre (dx, dy) and tilt (a_x, a_y, a_z) of the image plane relative to the final axis frame.

backgroundnumber or callable, optional

Index (or function n(wavelength_nm)) of a gas that fills the air spaces, e.g. the helium or nitrogen purge of lithography lenses. Only used by draw(), which outlines spaces of index 1 or of the background index as gaps rather than as lenses; the media of the trace are those of the surfaces.

The surfaces are copied, later changes to the Surface objects passed in
do not affect the system.
property n

Indices in object space and behind each surface, shape (S + 1,).

property sigma

Direction of travel (+1: +z, -1: -z) in object space and behind each surface.

property vertex_z

z positions of the vertices.

property image_z

z position of the image plane.

frames()[source]

Local frames (origin, R) of the surfaces and of the image plane.

A point q in the local frame of surface i lies at origin + R @ q in global coordinates.

Returns:
surface_frameslist of (origin, R)
image_frame(origin, R)
property tilted

True if any surface or the image plane is decentred or tilted.

to_image_frame(points, directions=None)[source]

Transform points (and directions) to the local frame of the image plane.

Parameters:
points(…, 3) array

Points in global coordinates.

directions(…, 3) array, optional

Directions in global coordinates.

Returns:
localarray

Points in the image plane frame.

local_directionsarray

Directions in the image plane frame (only if directions is given).

with_wavelength(wavelength)[source]

Copy of the system at another wavelength (same geometry).

with_image_distance(distance)[source]

Copy of the system with the image plane at distance (signed, in z) behind the last vertex.

with_axial_shift(first, last, dz)[source]

Copy with a group of surfaces moved along the axis.

All other surfaces, the object and the image plane stay in place: the gap in front of first (or the object distance for first = 0) grows by dz and the gap behind last shrinks by dz.

Parameters:
first, lastint

Indices of the first and last surface of the group (inclusive, e.g. the two surfaces of a lens).

dznumber

Axial shift.

Returns:
System

The modified copy.

with_radius_change(index, dR)[source]

Copy with the vertex radius of one surface changed by dR.

Conic and aspheric coefficients, thicknesses and apertures stay the same. Together with with_axial_shift() and decentred surfaces this gives the radius sensitivities of tolerancing.

Parameters:
indexint

Index of the surface.

dRnumber

Change of the (signed) radius, R -> R + dR.

Returns:
System

The modified copy.

with_index_change(index, dn)[source]

Copy with the refractive index behind a surface changed by dn.

The offset applies at every wavelength (dispersion unchanged) to the medium that starts at surface index, i.e. to the glass of a lens when index is its first surface, up to the next surface that changes the medium. Paraxial data, Seidel terms and real rays all see it.

Parameters:
indexint

Index of the surface behind which the medium starts. It has to change the medium (n_after or material).

dnnumber

Index change.

Returns:
System

The modified copy.

at_paraxial_focus()[source]

Copy of the system with the image plane in the paraxial image.

abcd_matrix()[source]

ABCD matrix from the first to the last vertex, assembled from pyoptics.abcd elements (reduced angles, mirrors unfolded).

to_abcd()[source]

Equivalent abcd.OpticalSystem from the first vertex to the image plane (unfolded).

paraxial(field=None)[source]

First order properties, see Paraxial.

fieldnumber, optional

Field for the chief ray (default: the maximum field).

seidel(field=None)[source]

Seidel sums of the surfaces for the paraxial marginal ray at full aperture and the chief ray at field (default: maximum field).

Ideal lenses have no Seidel sums (NaN). See Seidel.

third_order(field=None)[source]

Petzval sum, third order image surfaces and distortion, see ThirdOrder.

Parameters:
fieldnumber, optional

Field for the chief ray (default: the maximum field). The radii do not depend on it, the relative distortion grows with field**2.

Returns:
ThirdOrder
chromatic_seidel(d_wavelength, field=None)[source]

Primary axial and lateral colour from the paraxial rays, see ChromaticSeidel.

Parameters:
d_wavelengthnumber

Width of the band (in the length unit), the indices are taken at wavelength -+ d_wavelength/2 (e.g. 486.1 - 656.3 nm for F - C).

fieldnumber, optional

Field for the chief ray (default: the maximum field).

Returns:
ChromaticSeidel
power()[source]

Power of the system, n’/f’ (reciprocal of the efl in air), from the paraxial matrix.

surface_powers()[source]

Paraxial powers c*(n’ - n) of the surfaces (signed indices, so -2 n c for a mirror in a medium n), shape (S,).

power_contributions()[source]

Share of each surface in the power of the system: y_i phi_i/y_1 for a ray that enters parallel to the axis (heights y_i at the vertices). The contributions add up to power() exactly. A surface far from the axis ray (large y) weighs more than its own power phi_i.

elements()[source]

Index ranges (first, last) of the elements: runs of surfaces from a surface with glass behind it to the next one with air (or the background gas) behind it (cemented groups are one element). A mirror or ideal lens in air is an element of its own.

element_powers()[source]

Powers of the elements() (thick lens powers in their surrounding media, phi = phi_1 + phi_2 - (t/n) phi_1 phi_2 for a singlet in air), shape (number of elements,).

pupil_closeness(field=None)[source]

Paraxial closeness of the surfaces to a pupil, the sub aperture ratio |y_m|/(|y_m| + |y_c|) of the marginal ray height y_m (full aperture) and the chief ray height y_c (field, default: the maximum field) at each vertex, shape (S,).

1 at a pupil (stop, y_c = 0), 0 at a field surface (object, image or an intermediate image, y_m = 0). Near a pupil a surface acts on all fields alike (spherical aberration, power), near a field on each field point separately (distortion, field curvature; dust and defects there are imaged sharply). The ratio does not depend on the field to first order: y_c is linear in the field, but its sign is lost, so a surface on either side of the stop gets the same value. See footprints() for the real ray version.

footprints(fields=None, N=15, n_rim=64, relative_to='footprint', clip=True)[source]

Footprints of the ray bundles of field points on the surfaces and the closeness of the surfaces to a pupil from real rays.

For each field, a grid of rays over the entrance pupil (with its rim) is traced. On each surface (in its local frame) the footprint of the bundle (convex hull of the ray hits) has an area A and the radius sqrt(A/pi) of the circle of equal area. The ratio of that radius to the semi diameter r that the rays of all fields fill (the largest distance of any ray from the vertex), i.e. (A/(pi r**2))**0.5, tells how much of the surface a single field point lights up: 1 at a pupil, where all bundles overlap, and near 0 at a field surface, where each field point lights a small patch. ratio**2 is the share of the used area (the disc of radius r) that a single field fills; the ratio lies between 0 and 1. For a rotationally symmetric system the total radius is centre + radius of the bundle of the largest field, and the ratio of that field matches the paraxial pupil_closeness().

Parameters:
fieldssequence, optional

Fields (numbers for y fields or (x, y) pairs). Default: 0, 0.5 and 1 times the maximum field; with rotational symmetry the fields of opposite sign light up mirrored footprints of equal reach.

Nint, optional

Rays across the pupil diameter of the grid.

n_rimint, optional

Rays on the rim of the pupil, which outline the footprints.

relative_to“footprint” or “aperture”, optional

Divide by the semi diameter that all fields fill (default) or by the semi diameter of the surface (y_max/y_max_possible with the clear aperture, smaller where the apertures have margins; NaN for surfaces without one).

clipbool, optional

Vignette rays outside the semi diameters.

Returns:
Footprints
rays(field=None, px=0.0, py=0.0, aim=None)[source]

Rays from an object point through points of the entrance pupil.

Parameters:
fieldnumber or pair, optional

Field angle in radians (object at infinity) or object height; a number is a y field, a pair (x, y). Default: the maximum field.

px, pynumbers or arrays, optional

Normalized entrance pupil coordinates (broadcast against each other).

aimbool, optional

Ray aiming at the real stop (default: self.ray_aiming).

Returns:
Rays

Start points, directions and optical paths for trace().

trace(rays, clip=True, last=None)[source]

Trace rays through the system.

Parameters:
raysRays

Start points (in object space, in front of the first surface), unit directions and optical path, e.g. from rays().

clipbool, optional

Vignette rays outside the semi diameters.

lastint, optional

Stop at this surface (no image plane); default: trace to the image plane.

Returns:
RayBundle
trace_pupil(field=None, px=0.0, py=0.0, clip=True)[source]

Trace rays through the pupil points (px, py) at field.

Parameters:
fieldnumber or pair, optional

See rays().

px, pynumbers or arrays, optional

Normalized entrance pupil coordinates.

clipbool, optional

Vignette rays outside the semi diameters.

Returns:
RayBundle
trace_polarization(rays, clip=True, coatings=None, media=None)[source]

Trace rays with their polarization and power (see the module docstring).

Parameters:
raysRays
clipbool, optional

Vignette rays outside the semi diameters.

coatingsdict {i: Coating or None}, optional

Coatings that replace those of the surfaces i.

mediadict {i: Material}, optional

Media behind the surfaces i for the polarization (e.g. a materials.CubicCrystal); the refractive index of the rays stays that of the system.

Returns:
PolarizedBundle
trace_pupil_polarization(field=None, px=0.0, py=0.0, clip=True, coatings=None, media=None)[source]

trace_polarization() of the rays through the pupil points (px, py).

Parameters:
fieldnumber or pair, optional

See rays().

px, pynumbers or arrays, optional

Normalized entrance pupil coordinates.

clipbool, optional

Vignette rays outside the semi diameters.

coatings, mediadicts, optional

See trace_polarization().

Returns:
PolarizedBundle
opd(field=None, N=64, units='waves')[source]

OPD map over the pupil.

Parameters:
fieldnumber, optional

Default: maximum field.

Nint, optional

Samples across the pupil (a grid on [-1, 1]**2).

units{“waves”, “length”}, optional
Returns:
OPDMap
zernike(field=None, n_terms=16, N=64)[source]

Fringe Zernike fit to the OPD map.

Least squares fit of Z_1…Z_n_terms on the unit disk of pupil coordinates.

Parameters:
fieldnumber or pair, optional

See rays().

n_termsint, optional

Number of Fringe Zernikes.

Nint, optional

Samples across the pupil, see opd().

Returns:
coeffsarray

Coefficients in waves, coeffs[j - 1] belongs to Z_j.

rms_opd(field=None, N=64, remove_tilt=True)[source]

RMS OPD over the (vignetted) pupil with uniform weighting.

Parameters:
fieldnumber or pair, optional

See rays().

Nint, optional

Samples across the pupil.

remove_tiltbool, optional

Remove the best fitting tilt (piston is always removed).

Returns:
rmsnumber

RMS OPD in waves.

strehl(field=None, N=64, remove_tilt=True)[source]

Strehl ratio |<exp(2*pi*i*W)>|**2 over the (vignetted) pupil.

With remove_tilt (default), the best fitting tilt is removed, i.e. the reference point is moved close to the diffraction focus. Without, it is the intensity at the chief ray image point, which is the centre of psf().

Parameters:
fieldnumber or pair, optional

See rays().

Nint, optional

Samples across the pupil.

remove_tiltbool, optional
Returns:
strehlnumber
pupil(field=None, N=64)[source]

Exit pupil in the coordinates of pyoptics.imaging.

The imaging pupil is parametrized by the transverse wave vector, (P_x, P_y) = n’ (d_x, d_y)/NA with the image space ray directions d taken relative to the chief ray. The OPD of the traced rays is interpolated there; vignetted and unsampled regions are masked. NA is the largest n'|d - d_chief| of all rays.

Parameters:
fieldnumber or pair, optional

See rays().

Nint, optional

Samples across the pupil.

Returns:
Pupil

NA, vacuum wavenumber, phase and mask for imaging.get_psf().

psf(x, y, field=None, N=64, normalization='peak')[source]

Amplitude PSF on an image plane grid, centred on the chief ray.

Computed with imaging.get_psf() from the traced pupil. With normalization=”peak”, |psf|**2 is relative to the peak of the aberration-free PSF of the same pupil (Strehl ratio at the centre).

Parameters:
x, yarrays

Image plane coordinates relative to the chief ray.

fieldnumber or pair, optional

See rays().

Nint, optional

Samples across the pupil.

normalizationstr, optional

See imaging.get_psf().

Returns:
psf2d array

Complex amplitude PSF.

mtf(x, y, field=None, N=64)[source]

MTF from imaging.get_mtf() with the traced pupil.

Parameters:
x, yarrays

Image plane grid; the MTF is given on its frequency grid.

fieldnumber or pair, optional

See rays().

Nint, optional

Samples across the pupil.

Returns:
mtf2d array
vectorial_focus(x, y, z=0.0, field=None, E_in=(1.0, 0.0), N=64, coatings=None, media=None, normalization='peak')[source]

Vectorial focus (Debye-Wolf integral) of the polarization traced rays.

Every image space ray is a plane wave in the direction d of the ray with the field of trace_polarization() (coatings, media, the transmittance of the surfaces) and the phase 2*pi*OPD/wavelength. The fields and OPDs are interpolated on the plane wave grid of the window x, y, weighted by 1/sqrt(|d_z|) as in propagators.vectorial_mansuripur() (uniform amplitude over the pupil, as in psf(), and energy conservation for an aplanatic system) and summed by an FFT. The field stays the same when the light travels in -z of the image frame (behind an odd number of mirrors); the plane waves then have k_z < 0.

Parameters:
x, yarrays

Linear coordinates (centred, as pyoptics.fft expects) in the image plane relative to the chief ray image point. The window sets the sampling of the pupil: its radius spans n'*NA*L/wavelength samples for a window of width L.

znumber, optional

Distance from the image plane along the z axis of the image frame.

fieldnumber or pair, optional

Default: maximum field.

E_inJones vector (2,), optional

Input polarization on PolarizedBundle.basis_in (normalized here).

Nint, optional

Rays across the pupil.

coatings, mediadict, optional

See trace_polarization().

normalization{“peak”, None}, optional

“peak”: relative to the peak amplitude of the scalar focus of the same, lossless and aberration-free pupil, so that |E|**2 at the centre is the Strehl ratio times the transmittance (for small NA). None: unnormalized.

Returns:
Earray

Field [E_x, E_y, E_z] of shape (Ny, Nx, 3) in the image frame.

ray_map(x, y, field=None, N=128, surface=None, clip=True)[source]

Optical path and ray data on a grid of the image plane.

Traces an N x N grid of rays over the entrance pupil and interpolates (linearly between the rays) the optical path of the rays arriving at the image plane onto the grid x, y of its local frame. Unlike opd(), this needs no reference sphere: the field on the image plane is proportional to exp(i*k_0*opl). Use it for afocal and double pass systems (interferometers, see double_pass()), whose output beam is (nearly) collimated, or wherever the image plane is a detector.

Parameters:
x, yarrays

Linear coordinates of the grid in the image plane.

fieldnumber or pair, optional

Default: maximum field.

Nint, optional

Rays across the pupil diameter.

surfaceint, optional

Surface whose ray intersections and directions are returned as well (default: the image plane).

clipbool, optional

Vignette rays outside the semi diameters.

Returns:
RayMap
spot_diagram(field=None, N=31)[source]

Spot diagram relative to the chief ray.

Image plane intersections of a square grid of N x N pupil rays inside the unit disk.

Parameters:
fieldnumber or pair, optional

See rays().

Nint, optional

Rays across the pupil.

Returns:
SpotDiagram

Intersections, RMS spot radius and centroid.

ray_fan(field=None, N=51)[source]

Transverse ray aberrations of the tangential and sagittal fans.

Parameters:
fieldnumber or pair, optional

See rays().

Nint, optional

Rays per fan.

Returns:
RayFan

Pupil coordinates and the aberrations relative to the chief ray.

draw(ax=None, fields=None, n_rays=7, colors=None, lw=0.8, plane='yz')[source]

Draw the meridional (or sagittal) section of the system with ray fans.

Parameters:
axmatplotlib axis, optional

Defaults to the current axis.

fieldssequence, optional

Fields to trace (default: 0 and the maximum field).

n_raysint, optional

Rays per field across the pupil.

colorssequence of colors, optional

One color per field.

lwnumber, optional

Line width of the rays.

plane{“yz”, “xz”}, optional

Section to draw: the y-z plane (default) with fans of rays across P_y, or the x-z plane with fans across P_x (seen from +y, x up), e.g. for decentres, tilts or fields in x.

Returns:
axmatplotlib axis
plot_spot_diagram(fields=None, N=31, axes=None, scale=None)[source]

Spot diagrams for several fields side by side.

Parameters:
fieldssequence, optional

Fields (default: 0 and the maximum field).

Nint, optional

Rays across the pupil.

axessequence of matplotlib axes, optional

One axis per field; created if omitted.

scalenumber, optional

Half width of the plotted region; default: 1.1 times the largest spot.

Returns:
axessequence of matplotlib axes
plot_ray_fan(fields=None, N=51, axes=None)[source]

Tangential and sagittal ray fans for several fields.

Parameters:
fieldssequence, optional

Fields (default: 0 and the maximum field).

Nint, optional

Rays per fan.

axespair of matplotlib axes, optional

Axes for the tangential and sagittal fan; created if omitted.

Returns:
axespair of matplotlib axes
pyoptics.raytrace.double_pass(surfaces, image_distance=0.0, n_object=None)[source]

Unfold a double pass: surfaces up to a mirror and back again.

Light travels through surfaces[:-1], reflects at the mirror surfaces[-1] and returns through the same surfaces in reverse order, as in Twyman-Green and Fizeau interferometers, retroreflectors or double pass setups. The returned surfaces can be passed to System; the surfaces of the return pass are copies at the same places (with the same decentres and tilts), the media between them are those of the forward pass.

Parameters:
surfacessequence of Surface

The forward pass, the last one a mirror. The thickness of surfaces[-2] is the distance to the mirror; the thickness of the mirror itself is ignored. CoordinateBreaks are not supported.

image_distancenumber, optional

Signed z distance from the vertex of surfaces[0] to the image plane of the return pass (e.g. -d for a detector plane at z = -d).

n_objectnumber, optional

Index in front of surfaces[0] (the medium of the return path behind surfaces[0]); default 1. Pass the n_object of the System if it differs.

Returns:
list of Surface
pyoptics.raytrace.fused_silica(wavelength_nm)[source]

Refractive index of fused silica (Malitson’s Sellmeier formula, valid from 0.21 to 3.7 um).

pyoptics.raytrace.caldwell_krf_lens(wavelength=0.0002483, aperture_margin=1.02, refocus=True)[source]

All fused silica KrF lithography projection lens by J. B. Caldwell.

J. Brian Caldwell, “All-fused-silica 248-nm lithographic projection lens”, Optics & Photonics News 9(11), 40-41 (1998). Reduction 4x (magnification -0.25), image side NA 0.56, image field diameter 23.4 mm (object height up to 46.8 mm), 1 m from object to image, telecentric on both sides. The prescription is that of the paper as reproduced in the COMSOL application “Microlithography Lens” (lens data in mm).

The aperture stop is not marked in the published table; it is placed at surface 30 (index 29), whose clear aperture limits the axial beam to the design NA 0.56 and which makes the chief rays telecentric to a few mrad. The other semi diameters of the table clip the rim of the full field beam by about 1%; they are enlarged by aperture_margin.

Parameters:
wavelengthnumber, optional

Vacuum wavelength in mm (default: KrF, 248.3 nm). The index of fused silica follows Malitson’s formula, n = 1.5084 at 248.3 nm.

aperture_marginnumber, optional

Factor for the semi diameters of all surfaces but the stop.

refocusbool, optional

Put the image plane into the paraxial image at this wavelength (default). The lens has a large axial colour (about 0.25 um per pm), so the image distance of the table (13.168 mm, for n = 1.5084) changes by micrometres with the wavelength.

Returns:
System

Lengths in mm, object 107.954 mm in front of the first surface, maximum field object_height = 46.8 mm.

pyoptics.raytrace.fused_silica_arf(wavelength_nm)[source]

Fused silica for ArF lenses: Malitson’s dispersion shifted to the index 1.56078570 at 193.368 nm of the Zeiss designs (Malitson’s formula itself gives 1.56019 there); dn/dlambda = -1.58e-3 per nm.

pyoptics.raytrace.zeiss_arfi_lens(wavelength=0.000193368, aperture_margin=1.01, refocus=True, n_water=1.43662694)[source]

Dioptric water immersion ArF projection lens, NA 1.35, by Carl Zeiss.

US patent 7,187,503 B2, “Refractive projection objective for immersion lithography” (H.-J. Rostalski, A. Dodoc, A. Epple, H. Beierl; Carl Zeiss SMT AG, 2007), second embodiment (FIG. 4, Tables 6 and 7). Reduction 8x (magnification -0.125), image side NA 1.35 in water, image field radius 7 mm (object height up to 56 mm), 960 mm from object to image; all lenses of fused silica, filled with helium, 11 even aspheres (no conics), 1 mm of water between the last lens (a plane surface) and the wafer. The image side chief rays are not telecentric: up to 40 mrad (in water) at the rim of the field.

The aperture stop is the plane surface 38 of the patent (index 37 of the system, in the air space in front of lens 39, which it reaches back into with the negative thickness); with the semi diameter of the table the real NA is 1.35 and all other semi diameters of the table are met by the rim rays of the full field to 0.1%. They are enlarged by aperture_margin. On axis the RMS wavefront error is about 16 mwaves, at the rim of the field about 24 mwaves.

The first embodiment of the patent (NA 1.3, 5x, Tables 1 and 2) is not included: its aspheric constants are printed without decimal points and, read as d.dddddddd, leave several waves of spherical aberration.

Parameters:
wavelengthnumber, optional

Vacuum wavelength in mm (default: 193.368 nm, the design wavelength of the patent). Fused silica follows fused_silica_arf(); helium (1.00003289) and water (n_water) are taken as constant, so the axial colour (about 0.3 um per pm) is that of the glass only.

aperture_marginnumber, optional

Factor for the semi diameters of all surfaces but the stop.

refocusbool, optional

Move the image plane by the change of the paraxial image distance relative to 193.368 nm, so that it stays at the best focus of the design (the table’s image distance, 20 nm behind the paraxial image).

n_waternumber, optional

Index of the immersion water (patent: 1.43662694 at 193.368 nm).

Returns:
System

Lengths in mm, object 29.960 mm in front of the first (dummy) surface, maximum field object_height = 56 mm, background helium (the gaps are drawn as such). Surface labels are the surface numbers of the patent.

pyoptics.raytrace.zeiss_krf_rema(wavelength=0.00024838, na_object=0.6, object_height=10.5, thickness_19=91.56)[source]

REMA objective of a KrF illuminator (Carl Zeiss, US 5,982,558).

G. Fürter, J. Wangler, U. Dinger, G. Ittner, “REMA objective for microlithographic projection exposure systems”, US 5,982,558 (1999), Table 1. The reticle masking (REMA) objective images the exit face of the glass rod of the illuminator, where the masking blades sit, onto the reticle: magnification -4.44, object side NA 0.6 (image side about 0.135), 1200 mm long, all fused silica, spherical. A pupil plane with a plane plate (filters, diaphragms) lies in the diaphragm plane 14; the deflection mirror of the patent at plane 24 is unfolded here. The image side is telecentric (chief rays within a few mrad), matched to a projection lens whose entrance pupil lies almost at infinity, e.g. caldwell_krf_lens(): object side NA 0.56/4 = 0.14, so the REMA carries a pupil fill up to sigma = 0.135/0.14, about 0.96.

The printed thickness behind surface 19 (36.53 mm) is a misprint: with it, the sines of the angles of incidence that the patent lists for the marginal, chief and coma rays at every surface agree only up to surface 19 and the paraxial image lies 19 mm behind the reticle plane. With 91.56 mm, 115 of the 116 listed sines agree to within the rounding of the table (0.01; the remaining one differs in sign only), the length from object to reticle is the 1200 mm of the text, the magnification is -4.457 and the best focus (on axis) lies at the printed 94.55 mm behind the last surface.

Parameters:
wavelengthnumber, optional

Vacuum wavelength in mm (default: 248.38 nm, the design wavelength).

na_objectnumber, optional

Sine of the object side marginal ray (on axis) that the semi diameter of the stop (diaphragm plane 14) passes; the patent’s NA is 0.6.

object_heightnumber, optional

Maximum object (rod exit) height: 10.5 mm (default) is the corner of a square of 14.8 mm, which the REMA images onto the 66 mm square that Caldwell’s lens (46.8 mm object field radius) takes.

thickness_19number, optional

Air space behind surface 19, see above.

Returns:
System

Lengths in mm, object (rod exit) 30.72 mm in front of surface 2, reticle 94.55 mm behind surface 32. Surface labels are the surface numbers of the patent; no clear apertures are given except the stop.

pyoptics.raytrace.zeiss_zoom_axicon(zoom=0.0, axicon_gap=0.0, wavelength=0.00024838, original=False, source_radius=1.0)[source]

Zoom-axicon objective of a lithography illuminator (Carl Zeiss, US 5,675,401), adapted to KrF.

J. Wangler, J. Liegel, “Illuminating arrangement including a zoom objective incorporating two axicons”, US 5,675,401 (1997), Table 2 (Figs. 5 and 6). The objective takes the light from a secondary source (plane 130 of the patent, here the object plane, 35 mm in front of the first surface) to the pupil intermediate plane 30 (the image plane of the system) and sets the size and shape of the illuminated area there, i.e. the pupil fill (sigma) of the illuminator:

  • zoom: two elements move. 2121/2120 (zoom[0]) from next to 2113 (d210 = 0.2) to next to 2150, the zoom lens 2410/2420 (zoom[1]) from 143.1 mm behind the axicon (d232) to next to it. 0 is the small sigma end, 1 the large one; the scale of the pupil grows about threefold (sigma 0.3 … 0.8 in the patent).

  • axicon_gap: the convex axicon 2310/2320 moves away from the concave one (cone angle 62°, which they meet at gap 0, where they act as a plate). The light is shifted outwards into a ring, the dark centre grows with the gap (annular illumination). The gap is taken from the space d232 in front of the zoom lens, and from d240 once d232 has reached 0.2 mm, so that plane 30 stays where it is.

The patent’s design is for the i-line of a mercury lamp (quartz and Schott FK5). For 248 nm the FK5 elements are made of fused silica too, and the radii of every element are scaled by (n - 1)/(n_i - 1) so that each element keeps its power (n: fused silica at 248.38 nm; n_i: its glass at 365 nm, FK5 from its n_d and V_d). The cones are kept.

Parameters:
zoomnumber or pair, optional

Positions in [0, 1] of the two zoom elements; a number moves both.

axicon_gapnumber, optional

Distance of the axicons in mm (0: in contact).

wavelengthnumber, optional

Vacuum wavelength in mm.

originalbool, optional

The patent’s prescription with its glasses (for 365 nm) instead of the KrF adaptation.

source_radiusnumber, optional

Radius of the secondary source (object height of the system).

Returns:
System

Lengths in mm; stop at the first surface (the aperture is set by the source, not by the objective). Surface labels are the surface numbers of the patent.

pyoptics.raytrace.delano_krf_lens(wavelength=0.0002483)[source]

20 element all fused silica KrF projection lens with 5 aspheres, NA 0.7, 4x, 1 m.

Designed in notebook 43 (“Delano diagrams”): first order layout in the y-ybar diagram (delano.refine(): two waists, Petzval sum zero, telecentric on both sides), thick singlets (delano.thicken()) and real ray correction (lens_optimization.LensOptimizer, aperture and field opened in stages, r**4 to r**8 aspheres on 5 surfaces spread from the reticle to the wafer, centre and edge thicknesses of at least 10 mm). Magnification -0.25, image side NA 0.7, image field radius 13.6 mm (a 26 x 8 mm slit), object to image 1000 mm, image side working distance 8 mm. Corrected to about 0.1 to 0.25 waves RMS over the field (not quite diffraction limited, the Marechal limit is 0.07 waves), distortion of the real chief ray below 20 nm, telecentric to 1.5 mrad on the reticle side and 0.3 mrad on the wafer side. Real KrF lenses of NA 0.7 have about 30 elements; and the last element, a 108 mm thick block in front of the wafer, would not be built like this: an example of a first order layout and its correction, not a production design.

Parameters:
wavelengthnumber, optional

Vacuum wavelength in mm (default: KrF, 248.3 nm, the design wavelength). Fused silica after Malitson.

Returns:
System

Lengths in mm, maximum field object_height = 54.4 mm. Only the stop has a semi diameter.