Skip to content

Structured light (Laguerre–Gaussian / OAM)

Modal decomposition, overlap integrals and transverse-profile plotting. Docstrings are the source of truth, rendered with mkdocstrings (numpydoc style).

photonics_helper.structured

Structured light: Laguerre-Gaussian / OAM transverse modes.

Analytic Laguerre-Gaussian (LG) modes carrying orbital angular momentum (OAM), the propagation helpers that describe how such a beam evolves (beam waist, radius of curvature, Gouy phase), discrete overlap integrals on a transverse (x, y) grid, and transverse-profile visualization.

Conventions

The normalized LG mode used here is

.. math::

u_p^l(r, \varphi) = \frac{1}{w}
    \sqrt{\frac{2\,p!}{\pi\,(p+|l|)!}}
    \left(\frac{\sqrt{2}\,r}{w}\right)^{|l|}
    L_p^{|l|}\!\left(\frac{2 r^2}{w^2}\right)
    e^{-r^2/w^2} e^{i l \varphi},

so that :math:\int |u|^2 \, r\,dr\,d\varphi = 1 and the OAM phase winds as exp(i l phi) (a closed loop enclosing the axis accumulates 2 pi l). Propagation to z substitutes w -> w(z), adds the wavefront curvature exp(-i k r^2 / 2R(z)) and the Gouy phase exp(i (2p+|l|+1) arctan(z/zR)).

References
  • L. Allen, M. W. Beijersbergen, R. J. C. Spreeuw & J. P. Woerdman, Phys. Rev. A 45, 8185 (1992) (LG modes carrying OAM).
  • A. E. Siegman, Lasers, University Science Books (1986), Ch. 16-17 (Gaussian beam propagation, Gouy phase).
  • M. J. Padgett & L. Allen, Contemp. Phys. 41, 275 (2000).

FloatArray module-attribute

FloatArray = NDArray[np.float64]

ComplexArray module-attribute

ComplexArray = NDArray[np.complex128]

StructuredField dataclass

StructuredField(field: ComplexArray, dx: float, dy: float | None = None, x0: float = 0.0, y0: float = 0.0)

A complex scalar transverse field sampled on a uniform (x, y) grid.

Parameters:

Name Type Description Default
field complex 2-D array with shape ``(ny, nx)``.
required
dx grid spacing along ``x`` (metres).
required
dy grid spacing along ``y`` (metres); defaults to ``dx`` when ``None``.
None
x0 optional offsets of the grid centre (metres
0).
y0 optional offsets of the grid centre (metres
0).

field instance-attribute

field: ComplexArray

dx instance-attribute

dx: float

dy class-attribute instance-attribute

dy: float | None = None

x0 class-attribute instance-attribute

x0: float = 0.0

y0 class-attribute instance-attribute

y0: float = 0.0

shape property

shape: tuple[int, int]

Grid shape (ny, nx).

ny property

ny: int

nx property

nx: int

spacing property

spacing: tuple[float, float]

(dx, dy) in metres.

x property

x: FloatArray

1-D x coordinates of the grid columns (metres).

y property

y: FloatArray

1-D y coordinates of the grid rows (metres).

extent property

extent: tuple[float, float, float, float]

(xmin, xmax, ymin, ymax) pixel-edge extent in metres.

intensity property

intensity: FloatArray

|E(x, y)|^2.

power property

power: float

Discrete power sum |E|^2 dx dy (arbitrary units).

normalize

normalize() -> StructuredField

Return a copy scaled to unit discrete power.

centroid

centroid() -> tuple[float, float]

Intensity-weighted centroid (xc, yc) in metres.

second_moment_radius

second_moment_radius() -> float

Intensity-weighted RMS radius sqrt(<r^2>) in metres.

For a Laguerre-Gaussian mode this equals w(z)/sqrt(2) * sqrt(2p + |l| + 1).

overlap

overlap(other: StructuredField, *, normalize: bool = True) -> complex

Return the inner product integral conj(E1) E2 dx dy.

With normalize=True (default) both fields are first scaled to unit discrete power, so the auto-overlap of a mode is exactly 1 and the result is the modal overlap coefficient.

plot

plot(**kwargs: Any) -> Any

Plot intensity and phase; see :func:plot_transverse_profile.

LaguerreGaussianMode dataclass

LaguerreGaussianMode(p: int, l: int, w0: float, wavelength: float | None = None)

An analytic Laguerre-Gaussian mode LG(p, l).

Parameters:

Name Type Description Default
p radial index (integer >= 0).
required
l azimuthal index (integer); the OAM carried by the mode is ``l * hbar``.
required
w0 beam waist at ``z = 0`` (metres).
required
wavelength vacuum wavelength (metres). Required for any ``z != 0``

evaluation; None restricts the mode to its waist.

None

p instance-attribute

p: int

l instance-attribute

l: int

w0 instance-attribute

w0: float

wavelength class-attribute instance-attribute

wavelength: float | None = None

order property

order: int

Gouy order 2p + |l| + 1.

z_r property

z_r: float

Rayleigh range (requires wavelength).

waist

waist(z: float = 0.0) -> float

Beam radius w(z) (metres).

radius_of_curvature

radius_of_curvature(z: float) -> float

Wavefront radius of curvature R(z) (metres).

gouy

gouy(z: float) -> float

Gouy phase at z (radians).

field

field(x: FloatArray, y: FloatArray, z: float = 0.0) -> ComplexArray

Evaluate the mode on the Cartesian product of x and y.

Returns an array of shape (len(y), len(x)).

evaluate

evaluate(x: FloatArray, y: FloatArray, z: float = 0.0) -> ComplexArray

Evaluate the mode elementwise at coordinates x, y.

Unlike :meth:field, this does not form a grid: x and y are broadcast together. Use it to sample arbitrary points, e.g. a closed loop around the optical axis for the OAM winding number.

structured

structured(*, half_width: float | None = None, n: int = 257, z: float = 0.0) -> StructuredField

Sample the mode on a square grid.

Parameters:

Name Type Description Default
half_width half the physical grid size (metres). Defaults to

6 * w(z) so the tails are contained at any plane.

None
n number of samples per axis (default 257, odd to include the axis).
257
z propagation distance (metres
0).

plot

plot(**kwargs: Any) -> Any

Plot the mode; see :func:plot_transverse_profile.

rayleigh_range

rayleigh_range(w0: float, wavelength: float) -> float

Return the Rayleigh range z_R = pi w0^2 / lambda (metres).

Parameters:

Name Type Description Default
w0 beam waist (metres), must be positive.
required
wavelength vacuum wavelength (metres), must be positive.
required

beam_waist

beam_waist(w0: float, z: float, wavelength: float) -> float

Return the 1/e^2 beam radius w(z) = w0 sqrt(1 + (z/z_R)^2) (metres).

radius_of_curvature

radius_of_curvature(z: float, z_r: float) -> float

Return the wavefront radius of curvature R(z) = z (1 + (z_R/z)^2).

R(0) is infinite (a flat wavefront at the waist).

gouy_phase

gouy_phase(order: int, z: float, z_r: float) -> float

Return the Gouy phase (order) * arctan(z / z_R) (radians).

For a Laguerre-Gaussian mode order = 2p + |l| + 1.

overlap

overlap(a: LaguerreGaussianMode | StructuredField, b: LaguerreGaussianMode | StructuredField, *, half_width: float | None = None, n: int = 257, z: float = 0.0, normalize: bool = True) -> complex

Return the overlap integral integral conj(E_a) E_b dx dy.

Accepts two :class:LaguerreGaussianMode instances (sampled on a common grid) or two :class:StructuredField instances (integrated directly). Modal auto-overlaps are exactly 1 when normalize is True.

plot_transverse_profile

plot_transverse_profile(source: LaguerreGaussianMode | StructuredField, *, backend: Literal['matplotlib', 'plotly'] = 'matplotlib', half_width: float | None = None, n: int = 257, z: float = 0.0, figsize: tuple[float, float] | None = None, title: str | None = None, theme: Literal['light', 'dark'] = 'light') -> Any

Plot the intensity and phase of a transverse field.

Parameters:

Name Type Description Default
source a :class:`LaguerreGaussianMode` (sampled on the fly) or an

already-sampled :class:StructuredField.

required
backend ``"matplotlib"`` (default) or ``"plotly"`` (optional dependency).
'matplotlib'
half_width sampling controls used when ``source`` is a mode.
None
n sampling controls used when ``source`` is a mode.
None
z sampling controls used when ``source`` is a mode.
None
figsize figure size for the matplotlib backend.
None
title optional title override.
None
theme ``"light"`` or ``"dark"`` (plotly template / matplotlib facecolor).
'light'

Returns:

Type Description
Figure or Figure