POP description

Brief description of some concepts of physical optics wavefront propagation (POP) and how they are implemented in PAOS.

In PAOS, this is handled by the class WFO.

General diffraction

Diffraction is the deviation of a wave from the propagation that would be followed by a straight ray, which occurs when part of the wave is obstructed by the presence of a boundary. Light undergoes diffraction because of its wave nature.

The Huygens-Fresnel principle is often used to explain diffraction intuitively. Each point on the wavefront propagating from a single source can be though of as being the source of spherical secondary wavefronts (wavelets). The combination of all wavelets cancels except at the boundary, which is locally parallel to the initial wavefront.

However, if there is an object or aperture which obstructs some of the wavelets, changing their phase or amplitude, these wavelets interfere with the unobstructed wavelets, resulting in the diffraction of the wave.

Fresnel diffraction theory

Fresnel diffraction theory requires the following conditions to be met (see e.g. Lawrence et al., Applied Optics and Optical Engineering, Volume XI (1992)):

  1. aperture sized significantly larger than the wavelength

  2. modest numerical apertures

  3. thin optical elements

PAOS is implemented assuming that Fresnel diffraction theory holds.

Coordinate breaks

Coordinate breaks are implemented as follows:

  1. Decenter by \(x_{dec}, y_{dec}\)

  2. Rotation XYZ (first X, then Y, then Z)

The rotation is intrinsic (X, then around new Y, then around new Z).

To transform the sagittal coordinates (\(x, u_{x}\)) and the tangential coordinates (\(y, u_{y}\)), define the position vector

(18)\[\vec{R_0} = (x-x_{dec}, y-y_{dec}, 0)\]

and the unit vector of the light ray

(19)\[\vec{n_0} = (z u_{x}, z u_{y}, z)\]

where z is an appropriate projection of the unit vector such that \(u_{x}\) and \(u_{y}\) are the tangent of the angles (though we are in the paraxial approximation and this might not be necessary).

Note

z does not need to be calculated because it gets normalised away.

The position on the rotated \(x', y'\) plane would be \(\vec{R_0}'=(x', y', 0)\) and the relation is

(20)\[U^{T} \vec{R_0} + \rho U^{T} \vec{n_0} = \vec{R_0}'\]

that can be solved as

(21)\[\begin{split}U^{T} \vec{n_0} = \vec{n_0}' = z'(u_x', u_y', 1) \\ \rho = -\frac{z_0'}{z'}\end{split}\]

Example

Code example to use coordinate_break to simulate a coordinate break where the input field is centered on the origin and has null angles \(u_{s}\) and \(u_{t}\) and is subsequently decentered on the Y axis by \(y_{dec} = 10.0 \ \textrm{mm}\) and rotated around the X axis by \(x_{rot} = 0.1 ^{\circ}\).

import numpy as np
from paos.core.coordinateBreak import coordinate_break

field = {'us': 0.0, 'ut': 0.0}
vt = np.array([0.0, field['ut']])
vs = np.array([0.0, field['us']])

xdec, ydec = 0.0, 10.0e-3  # m
xrot, yrot, zrot = 0.1, 0.0, 0.0  # deg
vt, vs = coordinate_break(vt, vs, xdec, ydec, xrot, yrot, zrot, order=0.0)

print(vs, vt)
[0. 0.] [-0.01000002  0.00174533]

Gaussian beams

For a Gaussian beam, i.e. a beam with an irradiance profile that follows an ideal Gaussian distribution (see e.g. Smith, Modern Optical Engineering, Third Edition (2000))

(22)\[I(r) = I_0 e^{-\frac{2 r^2}{w(z)^2}} = \frac{2 P}{\pi w(z)^2} e^{-\frac{2 r^2}{w(z)^2}}\]

where \(I_0\) is the beam intensity on axis, \(r\) is the radial distance and \(w\) is the radial distance at which the intensity falls to \(I_0 / e^2\), i.e., to 13.5 percent of its value on axis.

Note

\(w(z)\) is the semi-diameter of the beam and it encompasses \(86.5 \%\) of the beam power.

Due to diffraction, a Gaussian beam will converge and diverge from the beam waist \(w_0\), an area where the beam diameter reaches a minimum size, hence the dependence of \(w(z)\) on z, the longitudinal distance from the waist \(w_0\) to the plane of \(w(z)\), henceforward “distance to focus”.

A Gaussian beam spreads out as

(23)\[w(z)^2 = w_0^2 \left[ 1 + \left(\frac{\lambda z}{\pi w_0^2} \right)^2 \right] = w_0^2 \left[ 1 + \left(\frac{z}{z_R} \right)^2 \right]\]

where \(z_R\) is the Rayleigh distance.

A Gaussian beam is defined by just three parameters: \(w_0\), \(z_R\) and the divergence angle \(\theta\), as in Fig. 17 (from Edmund Optics, Gaussian beam propagation).

../../_images/gaussianbeams.png

Fig. 17 Gaussian beam diagram

The complex amplitude of a Gaussian beam is of the form (see e.g. Lawrence et al., Applied Optics and Optical Engineering, Volume XI (1992))

(24)\[a(r, 0) = e^{-\frac{r^2}{w_0^2}} e^{-\frac{j k r^2}{R}}\]

where \(k\) is the wavenumber and \(R\) is the radius of the quadratic phase factor, henceforward “phase radius”. This reduces to

(25)\[a(r, 0) = e^{-\frac{r^2}{w_0^2}}\]

at the waist, where the wavefront is planar (\(R \rightarrow \infty\)).

Rayleigh distance

The Rayleigh distance of a Gaussian beam is defined as the value of z where the cross-sectional area of the beam is doubled. This occurs when w(z) has increased to \(\sqrt{2} w_0\).

Explicitly:

(26)\[z_R = \frac{\pi w_0^2}{\lambda}\]

The physical significance of the Rayleigh distance is that it indicates the region where the curvature of the wavefront reaches a minimum value. Since

(27)\[R(z) = z + \frac{z_R^2}{z}\]

in the Rayleigh range, the phase radius is \(R = 2 z_R\).

From the point of view of the PAOS code implementation, the Rayleigh distance is used to develop a concept of near- and far-field, to define specific propagators (see Wavefront propagation).

Gaussian beam propagation

To the accuracy of Fresnel diffraction, a Gaussian beam propagates as (see e.g. Lawrence et al., Applied Optics and Optical Engineering, Volume XI (1992))

(28)\[a(r, z) = e^{- j \left[k z - \theta(z)\right]} e^{-\frac{r^2}{w(z)^2}} e^{-\frac{j k r^2}{R(z)}}\]

where \(\theta(z)\) is a piston term referred to as the phase factor, given by

(29)\[\theta(z) = tan^{-1}\left(\frac{z_R}{z}\right)\]

\(\theta(z)\) varies from \(\pi\) to \(-\pi\) when propagating from \(z = -\infty\) to \(z = \infty\).

The Gaussian beam propagation can also be described using ABCD matrix optics. A complex radius of curvature \(q(z)\) is defined as:

(30)\[\frac{1}{q(z)} = \frac{1}{R(z)} - \frac{j \lambda}{\pi n w(z)^2}\]

Propagating a Gaussian beam from some initial position (1) through an optical system (ABCD) to a final position (2) gives the following transformation:

(31)\[\frac{1}{q_2} = \frac{C + D/q_1}{A + B/q_1}\]

Example

Code example to use WFO to estimate Gaussian beam properties for a given beam with diameter \(d = 1.0\) m, before and after inserting a Paraxial lens with focal length \(f = 1.0\) m, and after propagating to the lens focus. The zoom parameter is set to \(z = 4\).

Important

The zoom parameter is the ratio between the grid’s linear dimension and the beam size.

from paos.classes.wfo import WFO

beam_diameter = 1.0  # m
wavelength = 3.0e-6
grid_size = 512
zoom = 4

wfo = WFO(beam_diameter, wavelength, grid_size, zoom)

print('Pilot Gaussian beam properties\n')

print('Before lens\n')
print(f'Beam waist: {wfo.w0:.1e}')
print(f'Beam waist at current beam position: {wfo.wz:.1f}')
print(f'z-coordinate of the beam waist: {wfo.zw0:.1f}')
print(f'Rayleigh distance: {wfo.zr:.1e}')
print(f'Focal ratio: {wfo.fratio}')

fl = 1.0  # m
wfo.lens(lens_fl=fl)

print('\nAfter lens\n')
print(f'Beam waist: {wfo.w0:.1e}')
print(f'Beam waist at current beam position: {wfo.wz:.1f}')
print(f'z-coordinate of the beam waist: {wfo.zw0:.1f}')
print(f'Rayleigh distance: {wfo.zr:.1e}')
print(f'Focal ratio: {wfo.fratio:.1f}')

wfo.propagate(dz=fl)

print('\nAfter propagation to lens focus\n')
print(f'Beam waist: {wfo.w0:.1e}')
print(f'Beam waist at current beam position: {wfo.wz:.1e}')
print(f'z-coordinate of the beam waist: {wfo.zw0:.1f}')
print(f'Rayleigh distance: {wfo.zr:.1e}')
print(f'Focal ratio: {wfo.fratio:.1f}')
Pilot Gaussian beam properties

Before lens

Beam waist: 5.0e-01
Beam waist at current beam position: 0.5
z-coordinate of the beam waist: 0.0
Rayleigh distance: 2.6e+05
Focal ratio: inf

After lens

Beam waist: 1.9e-06
Beam waist at current beam position: 0.5
z-coordinate of the beam waist: 1.0
Rayleigh distance: 3.8e-06
Focal ratio: 1.0

After propagation to lens focus

Beam waist: 1.9e-06
Beam waist at current beam position: 1.9e-06
z-coordinate of the beam waist: 1.0
Rayleigh distance: 3.8e-06
Focal ratio: 1.0

Gaussian beam magnification

The Gaussian beam magnification can also be described using ABCD matrix optics. Using the definition given in Magnification, in this case

(32)\[\begin{split}A = M \\ D = 1/M \\ B = C = 0\end{split}\]

Therefore, for the complex radius of curvature we have that

(33)\[q_2 = M^2 q_1\]

Using the definition of \(q(z)\) it follows that

  1. \(R_2 = M^2 R_1\)

  2. \(w_2 = M w_1\)

for the phase radius and the semi-diameter of the beam, while from the definition of Rayleigh distance it follows that

  1. \(z_{R,2} = M^2 z_{R,1}\)

  2. \(w_{0,2} = M w_{0,1}\)

  3. \(z_2 = M^2 z_1\)

for the Rayleigh distance, the Gaussian beam waist and the distance to focus.

Note

In the current version of PAOS, the Gaussian beam width is set along x. So, only the sagittal magnification changes the Gaussian beam properties. A tangential magnification changes only the curvature of the propagating wavefront.

Example

Code example to use WFO to simulate a magnification of the beam for the tangential direction \(M_t = 3.0\), while keeping the sagittal direction unchanged (\(M_s = 1.0\)).

from paos.classes.wfo import WFO

beam_diameter = 1.0  # m
wavelength = 3.0e-6
grid_size = 512
zoom = 4

wfo = WFO(beam_diameter, wavelength, grid_size, zoom)

print('Before magnification\n')
print(f'Beam waist: {wfo.w0}')

Ms, Mt = 1.0, 3.0
wfo.Magnification(Ms, Mt)

print('\nAfter magnification\n')
print(f'Beam waist: {wfo.w0}')
Before magnification

Beam waist: 0.5

After magnification

Beam waist: 1.5

As a result, the semi-diameter of the beam increases three-fold.

Gaussian beam change of medium

As seen in Medium change, a change of medium from \(n_1\) to \(n_2\) can be described using an ABCD matrix with

(34)\[\begin{split}A = 1 \\ D = n_1/n_2 \\ B = C = 0\end{split}\]

Therefore, for the complex radius of curvature we have that

(35)\[q_2 = q_1 n_2/n_1\]

Using the definition of \(q(z)\) it follows that

  1. \(R_2 = R_1 n_2/n_1\)

  2. \(w_2 = w_1\)

  3. \(z_{R,2} = z_{R,1} n_2/n_1\)

  4. \(w_{0,2} = w_{0,1}\)

  5. \(z_2 = z_1 n_2/n_1\)

For the phase radius, the semi-diameter of the beam, the Rayleigh distance, the Gaussian beam waist and the distance to focus, respectively.

Moreover, since \(\lambda_{2} = \lambda_{1} n_2/n_1\), it follows that

(36)\[f_{num, 2} = f_{num, 1} n_1/n_2\]

Example

Code example to use WFO to simulate a change of medium from \(n_1 = 1.0\) to \(n_2 = 1.5\), to point out the change in distance to focus.

from paos.classes.wfo import WFO

beam_diameter = 1.0  # m
wavelength = 3.0e-6
grid_size = 512
zoom = 4

wfo = WFO(beam_diameter, wavelength, grid_size, zoom)
fl = 1.0  # m
wfo.lens(lens_fl=fl)

print('Before medium change\n')
print(f'Distance to focus: {wfo.distancetofocus:.1f}')

n1, n2 = 1.0, 1.5
wfo.ChangeMedium(n1n2=n1/n2)

print('\nAfter medium change\n')
print(f'Distance to focus: {wfo.distancetofocus:.1f}')
Before medium change

Distance to focus: 1.0

After medium change

Distance to focus: 1.5

Wavefront propagation

The methods for propagation are the hardest part of the problem of modelling the propagation through a well-behaved optical system. A thorough discussion of this problem is presented in Lawrence et al., Applied Optics and Optical Engineering, Volume XI (1992). Here we discuss the relevant aspects for the PAOS code implementation.

Once an acceptable initial sampling condition is established and the propagation is initiated, the beam starts to spread due to diffraction. Therefore, to control the size of the array so that beam aliasing does not change much from the initial state it is important to choose the right propagator (far-field or near-field).

PAOS propagates the pilot Gaussian beam through all optical surfaces to calculate the beam width at all points in space. The Gaussian beam acts as a surrogate of the actual beam and the Gaussian beam parameters inform the POP simulation. In particular the Rayleigh distance \(z_R\) is used to inform the choice of specific propagators.

Aliasing occurs when the beam size becomes comparable to the array size. Instead of adjusting the sampling period to track exactly, it is more effective to have a region of constant sampling period near the beam waist (constant coordinates system of the form \(\Delta x_2 = \Delta x_1\)) and a linearly increasing sampling period far from the waist (expanding coordinates system of the form \(\Delta x_2 = \lambda |z|/M \Delta x_1\)).

For a given point, there are four possibilities in moving from inside or outside to inside or outside the Rayleigh range (RR), defined as the region between \(-z_R\) and \(z_R\) from the beam waist:

(37)\[\begin{split}\textrm{inside} \leftrightarrow |z - z(w)| \leq z_R \\ \textrm{outside} \leftrightarrow |z - z(w)| > z_R\end{split}\]

The situation is described in Fig. 18, taken from Lawrence et al., Applied Optics and Optical Engineering, Volume XI (1992).

../../_images/propagators.png

Fig. 18 Wavefront propagators

Explicitly, these possibilities are:

  1. II(\(z_1\), \(z_2\)): inside RR to inside RR

  2. IO(\(z_1\), \(z_2\)): inside RR to outside RR

  3. OI(\(z_1\), \(z_2\)): outside RR to inside RR

  4. OO(\(z_1\), \(z_2\)): outside RR to outside RR

To move from any point in space to any other, following Lawrence et al., Applied Optics and Optical Engineering, Volume XI (1992), PAOS implements three primitive operators:

  1. plane-to-plane (PTP)

  2. waist-to-spherical (WTS)

  3. spherical-to-waist (STW)

Using these primitive operators, PAOS implements all possible propagations:

  1. II(\(z_1\), \(z_2\)) = PTP(\(z_2-z_1\))

  2. IO(\(z_1\), \(z_2\)) = WTS(\(z_2-z(w)\)) PTP(\(z_2-z(w)\))

  3. OI(\(z_1\), \(z_2\)) = PTP(\(z_2-z(w)\)) STW(\(z_2-z(w)\))

  4. OO(\(z_1\), \(z_2\)) = WTS(\(z_2-z(w)\)) STW(\(z_2-z(w)\))

Example

Code example to use WFO to propagate the beam over a thickness of \(10.0 \ \textrm{mm}\).

from paos.classes.wfo import WFO

wfo = WFO(beam_diameter, wavelength, grid_size, zoom)
print(f'Initial beam position: {wfo.z}')

thickness = 10.0e-3  # m
wfo.propagate(dz = thickness)
print(f'Final beam position: {wfo.z}')
Initial beam position: 0.0
Final beam position: 0.01

The current beam position along the z-axis is now updated.

Wavefront phase

A lens modifies the phase of an incoming beam.

Consider a monochromatic collimated beam travelling with slope \(u = 0\), incident on a paraxial lens, orthogonal to the direction of propagation of the beam. The planar beam is transformed into a converging or diverging beam. That means, a spherical wavefront with curvature \(>0\) for a converging beam, or a \(<0\) for a diverging beam.

The convergent beam situation is described in Fig. 19.

../../_images/convergent.png

Fig. 19 Diagram for convergent beam

where:

  1. the paraxial lens is coloured in red

  2. the converging beam cone is coloured in blue

  3. the incoming beam intersects the lens at a coordinate y

and

  1. \(z\) is the propagation axis (\(>0\) at the right of the lens)

  2. \(f\) is the optical focal length

  3. \(\Delta z\) is the sag

  4. \(\theta\) is the angle corresponding to the sag

\(\Delta z\) depends from the x and y coordinates, and it introduces a delay in the complex wavefront \(a_1(x, y, z) = e^{2\pi j z / \lambda}\) incident on the lens (\(z=0\) can be assumed). That is:

(38)\[a_2(x, y, z) = a_1(x, y, z) e^{2\pi j \Delta z / \lambda}\]

The sag can be estimated using the Pythagoras theorem and evaluated in small angle approximation, that is

(39)\[\Delta z = f - \sqrt{f^2 - y^2} \simeq \frac{y^2}{2f}\]

The phase delay over the whole lens aperture is then

(40)\[\Delta \Phi = - \Delta z / \lambda = - \frac{x^2 + y^2}{2 f \lambda}\]

Sloped incoming beam

When the incoming collimated beam has a slope \(u_1\), its phase on the plane of the lens is given by \(e^{2\pi j y u_1 / \lambda}\) to which the lens adds a spherical sag.

This situation is described in Fig. 20.

../../_images/convergent_sloped.png

Fig. 20 Diagram for convergent sloped beam

The total phase delay is then

(41)\[\Delta \Phi = - \frac{x^2 + y^2}{2 f \lambda} + \frac{y u_1}{\lambda} = - \frac{x^2 + (y - f u_1)^2}{2 f \lambda} + \frac{y u_1^2}{2 \lambda} = - \frac{x^2 + (y - y_0)^2}{2 f \lambda} + \frac{y_0^2}{2 f \lambda}\]

Apart from the constant phase term, that can be neglected, this is a spherical wavefront centred in \((0, y_0, f)\), with \(y_0 = f u_1\).

Note

In this approximation, the focal plane is planar.

Off-axis incoming beam

The case of off-axis optics is described in Fig. 21.

../../_images/convergent_offaxis.png

Fig. 21 Diagram for off-axis beam

In this case, the beam centre is at \(y_c\).

Let \(\delta y\) be a displacement from \(y_c\) along y. The lens induced phase change is then

(42)\[\Delta \Phi = - \frac{x^2 + y^2}{2 f \lambda} = - \frac{x^2 + (y_c - \delta y)^2}{2 f \lambda} = - \frac{x^2 + \delta y^2}{2 f \lambda} + \frac{\delta y u_2}{\lambda} - \frac{y_c^2}{2 f \lambda}\]

If the incoming beam has a slope \(u_1\), then

(43)\[\Delta \Phi = - \frac{x^2 + \delta y^2}{2 f \lambda} + \frac{\delta y (u_1 + u_2)}{\lambda} - \frac{y_c^2}{2 f \lambda} + y_c u_1\]

Apart from constant phase terms, that can be neglected, this is equivalent to a beam that is incident on-axis on the lens. The overall slope shifts the focal point in a planar focal plane. No aberrations are introduced.

Paraxial phase correction

For an optical element that can be modeled using its focal length \(f\) (that is, mirrors, thin lenses and refractive surfaces), the paraxial phase effect is

\[t(x, y) = e^{j k \left( x^2 + y^2 \right) / 2 f}\]

where t(x, y) is the complex transmission function. In other words, the element imposes a quadratic phase shift. The phase shift depends on initial and final position with respect to the Rayleigh range (see Wavefront propagation).

As usual, in PAOS this is informed by the Gaussian beam parameters. The code implementation consists of four steps:

  1. estimate the Gaussian beam curvature after the element (object space) using Eq. (27)

  2. check the initial position using Eq. (37)

  3. estimate the Gaussian beam curvature after the element (image space)

  4. check the final position

By combining the result of the second and the fourth step, PAOS selects the propagator (see Wavefront propagation). and the phase shift is imposed accordingly by defining a phase bias (see Lawrence et al., Applied Optics and Optical Engineering, Volume XI (1992)):

Propagator

Phase bias

Description

II

\(1/f \rightarrow 1/f\)

No phase bias

IO

\(1/f \rightarrow 1/f + 1/R'\)

Phase bias after lens

OI

\(1/f \rightarrow 1/f - 1/R\)

Phase bias before lens

OO

\(1/f \rightarrow 1/f - 1/R + 1/R'\)

Phase bias before and after lens

where \(R\) is the radius of curvature in object space and \(R'\) in image space.

Apertures

The actual wavefront propagated through an optical system intersects real optical elements (e.g. mirrors, lenses, slits) and can be obstructed by an object causing an obscuration.

For each one of these cases, PAOS implements an appropriate aperture mask. The aperture must be projected on the plane orthogonal to the beam. If the aperture is (\(y_c, \phi_x, \phi_y\)), the aperture should be set as

\[\left( y_a - y_c, \phi_x, \frac{1}{\sqrt{u^2 + 1}} \phi_y \right)\]

Supported aperture shapes are elliptical, circular or rectangular.

Example

Code example to use WFO to simulate the beam propagation through an elliptical aperture with semi-major axes \(x_{rad} = 0.55\) and \(y_{rad} = 0.365\), positioned at \(x_{dec} = 0.0\), \(y_{dec} = 0.0\).

from paos.classes.wfo import WFO

xrad = 0.55  # m
yrad = 0.365
xdec = ydec = 0.0

field = {'us': 0.0, 'ut': 0.1}
vt = np.array([0.0, field['ut']])
vs = np.array([0.0, field['us']])

xrad *= np.sqrt(1 / (vs[1] ** 2 + 1))
yrad *= np.sqrt(1 / (vt[1] ** 2 + 1))
xaper = xdec - vs[0]
yaper = ydec - vt[0]

wfo = WFO(beam_diameter, wavelength, grid_size, zoom)

aperture_shape = 'elliptical'  # or 'rectangular'
obscuration = False  # if True, applies obscuration

aperture = wfo.aperture(xaper, yaper, hx=xrad, hy=yrad,
                        shape=aperture_shape, obscuration=obscuration)

print(aperture)
Aperture: EllipticalAperture
positions: [256., 256.]
a: 70.4
b: 46.48813752661069
theta: 0.0

Stops

An aperture stop is an element of an optical system that determines how much light reaches the image plane. It is often the boundary of the primary mirror. An aperture stop has an important effect on the sizes of system aberrations.

The field stop limits the field of view of an optical instrument.

PAOS implements a generic stop normalizing the wavefront at the current position to unit energy.

Example

Code example to use WFO to simulate an aperture stop.

import numpy as np
from paos.classes.wfo import WFO

wfo = WFO(beam_diameter, wavelength, grid_size, zoom)

print('Before stop\n')
print(f'Total throughput: {np.sum(wfo.amplitude**2)}')

wfo.make_stop()

print('\nAfter stop\n')
print(f'Total throughput: {np.sum(wfo.amplitude**2)}')
Before stop

Total throughput: 262144.0

After stop

Total throughput: 1.0

POP propagation loop

PAOS implements the POP simulation through all elements of an optical system. The simulation run is implemented in a single loop.

At first, PAOS initializes the beam at the centre of the aperture. Then, it initializes the ABCD matrix.

Once the initialization is completed, PAOS repeats these actions in a loop:

  1. Apply coordinate break

  2. Apply aperture

  3. Apply stop

  4. Apply aberration (see Aberration description)

  5. Save wavefront properties

  6. Apply magnification

  7. Apply medium change

  8. Apply lens

  9. Apply propagation by thickness

  10. Update ray vectors and ABCD matrices (and save them)

  11. Repeat over all optical elements

Note

Each action is performed according to the configuration file, see Input system.

Example

Code example to use WFO to simulate a simple propagation loop that involves key actions such as applying a circular aperture, the throughput normalization, applying a Paraxial lens with focal length \(f=1.0\) m, and propagating to the lens focus.

import matplotlib.pyplot as plt
from paos.classes.wfo import WFO

fig, (ax0, ax1) = plt.subplots(nrows=1, ncols=2, figsize=(12, 6))
wfo = WFO(beam_diameter, wavelength, grid_size, zoom)

wfo.aperture(xc=xdec, yc=ydec, r=beam_diameter/2, shape='circular')
wfo.make_stop()
ax0.imshow(wfo.amplitude**2)
ax0.set_title('Aperture')

fl = 1.0  # m
thickness = 1.0

wfo.lens(lens_fl=fl)
wfo.propagate(dz=thickness)
ax1.imshow(wfo.amplitude**2)
ax1.set_title('Focus')

zoomin = 16
shapex, shapey = wfo.amplitude.shape
ax1.set_xlim(shapex // 2 - shapex // 2 // zoomin, shapex // 2 + shapex // 2 // zoomin)
ax1.set_ylim(shapey // 2 - shapey // 2 // zoomin, shapey // 2 + shapey // 2 // zoomin)

plt.show()
../../_images/index_8_0.png