pyoptics.modes

Mode analysis of beams and step-index fibre modes.

Hermite- and Laguerre-Gaussian decomposition

decompose_hg() and decompose_lg() expand a sampled field in the paraxial modes of beams.gauss_hermite() and beams.gauss_laguerre(),

E(x, y) = sum_j c_j u_j(x, y; w0, z),

for a basis with waist radius w0 whose waist lies a distance z in front of the plane of the field (z > 0: the basis diverges in the plane, R(z) > 0). The modes include the Gouy phase, so the coefficients do not change when the field and the basis are propagated together. The modes are normalized numerically on the grid, |c_j|**2/P is the fraction of the power P in mode j, and the expansion is truncated at the mode order N = l + m (HG) or N = 2p + |l| (LG) <= max_order.

The basis (w0, z and the centre x0, y0) can be given or fitted (fit_basis()). The choice matters: any w0 gives a complete basis, but a basis that is too wide or too narrow needs many modes for the same field. The fit maximizes the power that is captured by the truncated basis.

M² from the mode content

The Hermite functions are the eigenstates of the harmonic oscillator. With xi = sqrt(2)*x/w0 the position xi and the (dimensionless) direction p are xi = (a + a^+)/sqrt(2) and p = i*(a^+ - a)/sqrt(2), so the second moments of any coherent superposition follow from <a>, <a^+ a> and <a^2>, which are sums over the HG coefficients. Then

M²_x = 2*sqrt(Var(xi)*Var(p) - Cov(xi, p)**2),

which is the M² of ISO 11146 (second moments, beam_quality.fit_caustic()) along x, and analogously along y. For a pure HG_lm mode, M²_x = 2l + 1, M²_y = 2m + 1. The result is exact for the truncated expansion; if the captured power is not close to 1, the field has content beyond max_order.

Step-index fibres

In the weakly guiding approximation (n_core - n_clad << n_core), the modes of a step-index fibre with core radius a are linearly polarized LP_lm modes with the field

E(r, phi) = J_l(U*r/a)/J_l(U) * cos(l*phi)   for r <= a,
E(r, phi) = K_l(W*r/a)/K_l(W) * cos(l*phi)   for r >  a

(or sin(l*phi), or exp(+-i*l*phi)). U and W follow from the characteristic equation

U*J_{l-1}(U)/J_l(U) = -W*K_{l-1}(W)/K_l(W),   U**2 + W**2 = V**2,

with the V number V = 2*pi*a/wavelength*NA and NA = sqrt(n_core**2 - n_clad**2). The normalized propagation constant b = W**2/V**2 gives n_eff**2 = n_clad**2 + b*(n_core**2 - n_clad**2). LP_lm is cut off at V = U_c, the m-th zero of J_{l-1} (for l = 0 counting U_c = 0 as the first zero): LP01 has no cutoff, LP11 is guided above V = 2.405. LP_0m modes are twofold degenerate (polarization), LP_lm with l >= 1 fourfold (cos/sin and polarization). Vectorial effects (splitting into HE, EH, TE, TM modes) are not modelled.

Marcuse’s Gaussian approximation of LP01 has the mode field radius

w/a = 0.65 + 1.619/V**1.5 + 2.879/V**6

(D. Marcuse, Bell Syst. Tech. J. 56, 703 (1977)), better than 1 % for 1.2 < V < 2.4.

Coupling efficiency

coupling_efficiency() is the power coupling efficiency of a field into a mode (or any other field), the normalized overlap integral

eta = |<u|E>|**2/(<u|u>*<E|E>).

It generalizes abcd.coupling_efficiency(), which only handles coaxial Gaussian beams. coupling_vs_offset(), coupling_vs_tilt() and coupling_vs_defocus() sweep a misalignment of the field relative to the mode.

All functions use the pyoptics convention exp(i(k.r - omega*t)), and the wavelength is the wavelength in the medium in which the beams are given (the beams module uses k = 2*pi/wavelength).

References

    1. Siegman, “Lasers”, University Science Books (1986).

D. Marcuse, “Loss analysis of single-mode fiber splices”, Bell Syst. Tech. J. 56, 703-718 (1977).

  1. Gloge, “Weakly guiding fibers”, Appl. Opt. 10, 2252-2258 (1971).

A. W. Snyder and J. D. Love, “Optical Waveguide Theory”, Chapman and Hall (1983).

Classes

BasisParameters

Parameters of a Gaussian mode basis.

LPMode

Linearly polarized mode LP_lm of a weakly guiding step-index fibre.

ModeDecomposition

Expansion of a field in Hermite- or Laguerre-Gaussian modes.

Functions

coupling_efficiency

Power coupling efficiency of a field into a mode (or any other field).

coupling_vs_defocus

Coupling efficiency with the field propagated along z.

coupling_vs_offset

Coupling efficiency with the field shifted laterally.

coupling_vs_tilt

Coupling efficiency with the field tilted.

decompose_hg

Decompose a field into Hermite-Gaussian modes HG_lm, l + m <= max_order.

decompose_lg

Decompose a field into Laguerre-Gaussian modes LG_pl, 2p + |l| <= max_order.

fit_basis

Fit the parameters of a Gaussian mode basis to a field.

hg_indices

Indices (l, m) of all HG modes with l + m <= max_order, by order.

hg_mode

Hermite-Gaussian mode HG_lm of beams.gauss_hermite.

lg_indices

Indices (p, l) of all LG modes with 2p + |l| <= max_order, by order.

lg_mode

Laguerre-Gaussian mode LG_pl of beams.gauss_laguerre.

lp_cutoff

Cutoff V number of the LP_lm mode.

lp_mode

The single guided mode LP_lm.

lp_mode_field

Field of an LP mode on a grid, normalized numerically to unit power.

lp_modes

Guided LP modes of a weakly guiding step-index fibre.

m2_from_hg_coefficients

M²_x and M²_y of a coherent superposition of HG modes with coefficients {(l, m): c} (normalized modes, any common basis).

marcuse_mode_field_radius

Mode field radius of LP01 after Marcuse.

mode_power_fractions

Fractions of the power of a field coupled into each of a set of modes.

numerical_aperture

Numerical aperture of a step-index fibre.

plane_from_waist

Beam radius and wavefront radius a distance z from a waist.

v_number

V number of a step-index fibre.

waist_from_plane

Waist of a Gaussian beam from its radius and wavefront radius in a plane.

class pyoptics.modes.BasisParameters(w0, z, x0, y0, w, R)

Bases: tuple

Parameters of a Gaussian mode basis.

w0: waist radius; z: distance of the plane from the waist (z > 0 behind the waist, diverging); x0, y0: centre; w, R: beam radius and wavefront radius of curvature in the plane (R = inf at the waist).

R

Alias for field number 5

w

Alias for field number 4

w0

Alias for field number 0

x0

Alias for field number 2

y0

Alias for field number 3

z

Alias for field number 1

pyoptics.modes.waist_from_plane(w, R, wavelength)[source]

Waist of a Gaussian beam from its radius and wavefront radius in a plane.

Uses 1/q = 1/R - i*wavelength/(pi*w**2), q = z + i*z_R.

Parameters:
wnumber

Beam radius (1/e**2 intensity) in the plane.

Rnumber

Wavefront radius of curvature in the plane (np.inf: flat, R > 0: diverging).

wavelengthnumber

Wavelength in the medium.

Returns:
w0number

Waist radius.

znumber

Distance of the plane from the waist (z > 0: behind the waist).

pyoptics.modes.plane_from_waist(w0, z, wavelength)[source]

Beam radius and wavefront radius a distance z from a waist.

Parameters:
w0number

Waist radius.

znumber

Distance from the waist.

wavelengthnumber

Wavelength in the medium.

Returns:
wnumber

Beam radius (1/e**2 intensity).

Rnumber

Wavefront radius of curvature, np.inf at the waist.

pyoptics.modes.hg_mode(l, m, x, y, w0, wavelength, z=0.0, x0=0.0, y0=0.0)[source]

Hermite-Gaussian mode HG_lm of beams.gauss_hermite.

Parameters:
l, mint

Mode indices in x and y.

x, yarrays

Linear or meshed coordinates.

w0number

Waist radius.

wavelengthnumber

Wavelength in the medium.

znumber, optional

Distance from the waist.

x0, y0numbers, optional

Centre of the mode.

Returns:
field2d array

Mode field (including the Gouy phase).

pyoptics.modes.lg_mode(p, l, x, y, w0, wavelength, z=0.0, x0=0.0, y0=0.0)[source]

Laguerre-Gaussian mode LG_pl of beams.gauss_laguerre.

l > 0 has the helical phase exp(+i*l*phi).

Parameters:
p, lint

Radial and azimuthal index.

x, yarrays

Linear or meshed coordinates.

w0number

Waist radius.

wavelengthnumber

Wavelength in the medium.

znumber, optional

Distance from the waist.

x0, y0numbers, optional

Centre of the mode.

Returns:
field2d array

Mode field (including the Gouy phase).

pyoptics.modes.hg_indices(max_order)[source]

Indices (l, m) of all HG modes with l + m <= max_order, by order.

pyoptics.modes.lg_indices(max_order)[source]

Indices (p, l) of all LG modes with 2p + |l| <= max_order, by order.

pyoptics.modes.fit_basis(field, x, y, wavelength, max_order=0, family='hg', method='overlap', x0=None, y0=None)[source]

Fit the parameters of a Gaussian mode basis to a field.

Parameters:
fieldarray
x, yarrays
wavelengthnumber
max_orderint, optional

Highest mode order of the truncated basis whose captured power is maximized (method “overlap”). 0 (default) fits the fundamental mode.

familystr, optional

“hg” or “lg”.

methodstr, optional

“overlap” (default) maximizes the power in the truncated basis, starting from “moments”, which takes the radius from the second moments and the curvature from the phase gradient. “moments” alone is a good basis for near Gaussian beams; for multimode beams it gives a basis that is about sqrt(M²) too wide.

x0, y0numbers, optional

Centre of the basis. If omitted, fitted as well (“overlap”), or the intensity centroid (“moments”).

Returns:
basisBasisParameters

Notes

The basis is coaxial: a tilted beam needs many modes (or remove the tilt first).

class pyoptics.modes.ModeDecomposition(family, coefficients, basis, wavelength, power, reconstruction_error)[source]

Bases: object

Expansion of a field in Hermite- or Laguerre-Gaussian modes.

Attributes:
familystr

“hg” or “lg”.

coefficientsdict

Complex coefficients c_j of the numerically normalized modes, keyed by (l, m) for HG and (p, l) for LG modes.

basisBasisParameters

Waist, distance from the waist and centre of the basis.

wavelengthnumber
powernumber

Power <E|E> of the decomposed field.

reconstruction_errornumber

Relative rms error ||E - sum_j c_j u_j||/||E|| on the grid.

property power_fractions

Fractions |c_j|**2/P of the power in each mode (dict).

property captured_power

Fraction of the power in the truncated basis.

order_fractions()[source]

Power fractions summed per mode order N (array, index N).

mode(key, x, y)[source]

The normalized basis mode of a given key.

Parameters:
keytuple of int

(l, m) for HG or (p, l) for LG modes.

x, yarrays

Linear or meshed coordinates.

Returns:
field2d array

Mode, normalized to unit power on the grid.

reconstruct(x, y, keys=None)[source]

Sum of the modes with their coefficients.

Parameters:
x, yarrays

Linear or meshed coordinates.

keysiterable of tuples, optional

Modes to include. Defaults to all modes of the decomposition.

Returns:
field2d array

Reconstructed field.

propagate(distance)[source]

The same expansion a distance further along z (paraxial free propagation): the modes contain the Gouy phase, so only the basis changes. Use reconstruct() on the result to get the propagated field.

to_hg(x, y)[source]

HG decomposition of the same (truncated) field in the same basis.

HG and LG modes up to the same order span the same space.

Parameters:
x, yarrays

Grid on which the LG expansion is reconstructed and decomposed again.

Returns:
ModeDecomposition

The decomposition itself if it already uses HG modes.

M2(x=None, y=None)[source]

Beam propagation ratios from the mode content.

Second moments of the truncated expansion, see the module docstring. An LG decomposition is converted with to_hg(), which needs x and y.

Parameters:
x, yarrays, optional

Grid for the conversion of an LG decomposition.

Returns:
M2_x, M2_ynumbers

M² along x and y.

Raises:
ValueError

For an LG decomposition without x and y.

pyoptics.modes.m2_from_hg_coefficients(coefficients)[source]

M²_x and M²_y of a coherent superposition of HG modes with coefficients {(l, m): c} (normalized modes, any common basis).

pyoptics.modes.decompose_hg(field, x, y, w0=None, wavelength=1.0, z=0.0, max_order=10, x0=None, y0=None, method='projection', fit_kwargs=None)[source]

Decompose a field into Hermite-Gaussian modes HG_lm, l + m <= max_order.

Parameters:
fieldarray
x, yarrays

Linear or meshed coordinates.

w0number, optional

Waist radius of the basis. If omitted, the basis (w0, z, x0, y0) is fitted with fit_basis().

wavelengthnumber

Wavelength in the medium.

znumber, optional

Distance of the plane from the waist of the basis (z > 0: diverging basis). Use waist_from_plane() to get w0, z from a beam radius and a radius of curvature in the plane.

max_orderint, optional
x0, y0numbers, optional

Centre of the basis (default 0, or the centroid if the basis is fitted).

methodstr, optional

“projection” (default): overlap integrals with the numerically normalized modes, one mode at a time. “lstsq”: least squares fit, accounts for the residual non-orthogonality of the sampled modes, but holds all modes in memory.

fit_kwargsdict, optional

Keyword arguments for fit_basis() (e.g. method=”moments”).

Returns:
decompositionModeDecomposition
pyoptics.modes.decompose_lg(field, x, y, w0=None, wavelength=1.0, z=0.0, max_order=10, x0=None, y0=None, method='projection', fit_kwargs=None)[source]

Decompose a field into Laguerre-Gaussian modes LG_pl, 2p + |l| <= max_order.

The coefficients are keyed by (p, l).

Parameters:
fieldarray
x, yarrays

Linear or meshed coordinates.

w0number, optional

Waist radius of the basis. If omitted, the basis is fitted with fit_basis().

wavelengthnumber

Wavelength in the medium.

znumber, optional

Distance of the plane from the waist of the basis.

max_orderint, optional
x0, y0numbers, optional

Centre of the basis.

method{“projection”, “lstsq”}, optional

See decompose_hg().

fit_kwargsdict, optional

Keyword arguments for fit_basis().

Returns:
decompositionModeDecomposition
pyoptics.modes.numerical_aperture(n_core, n_clad)[source]

Numerical aperture of a step-index fibre.

Parameters:
n_core, n_cladnumbers

Refractive indices of core and cladding.

Returns:
NAnumber

sqrt(n_core**2 - n_clad**2).

pyoptics.modes.v_number(core_radius, n_core, n_clad, wavelength)[source]

V number of a step-index fibre.

Parameters:
core_radiusnumber

Core radius a.

n_core, n_cladnumbers

Refractive indices of core and cladding.

wavelengthnumber

Vacuum wavelength.

Returns:
Vnumber

2*pi*a/wavelength*NA.

pyoptics.modes.lp_cutoff(l, m)[source]

Cutoff V number of the LP_lm mode.

Parameters:
lint

Azimuthal index.

mint

Radial index, m >= 1.

Returns:
V_cnumber

The m-th zero of J_{l-1}, counting U = 0 as the first zero for l = 0.

class pyoptics.modes.LPMode(l, m, U, W, V, b, n_eff)[source]

Bases: LPMode

Linearly polarized mode LP_lm of a weakly guiding step-index fibre.

l, m: azimuthal and radial index; U, W: normalized transverse wavenumbers in core and cladding; V: V number; b = W**2/V**2: normalized propagation constant; n_eff: effective index (None if the indices are unknown).

property degeneracy

Number of degenerate modes: 2 for l = 0, 4 for l >= 1.

radial(r, core_radius)[source]

Radial profile of the mode.

Parameters:
rnumber or array

Distance from the fibre axis.

core_radiusnumber

Core radius a.

Returns:
profilearray

J_l in the core, K_l in the cladding, 1 at the core-cladding interface.

field(x, y, core_radius, orientation='cos', x0=0.0, y0=0.0)[source]

Mode field on a grid, normalized to unit power.

Parameters:
x, yarrays

Linear or meshed coordinates.

core_radiusnumber

Core radius.

orientation{“cos”, “sin”, “+”, “-“}, optional

Azimuthal dependence, see lp_mode_field().

x0, y0numbers, optional

Position of the fibre axis.

Returns:
field2d array
pyoptics.modes.lp_modes(V=None, core_radius=None, n_core=None, n_clad=None, wavelength=None, l_max=None, samples_per_unit=200)[source]

Guided LP modes of a weakly guiding step-index fibre.

Parameters:
Vnumber, optional

V number. If omitted, computed from core_radius, n_core, n_clad and the vacuum wavelength, which also give n_eff.

core_radius, n_core, n_clad, wavelengthnumbers, optional
l_maxint, optional

Largest azimuthal index (default: all guided modes).

samples_per_unitint, optional

Sampling density of U for bracketing the roots.

Returns:
modeslist of LPMode

Sorted by decreasing b (n_eff). Modes extremely close to their cutoff (W below about 1E-300, e.g. LP01 for V < 0.04) are not found.

pyoptics.modes.lp_mode(l, m, V=None, **kwargs)[source]

The single guided mode LP_lm.

Parameters:
l, mint

Mode indices.

Vnumber, optional

V number.

**kwargs

Further arguments of lp_modes(), e.g. the fibre parameters instead of V.

Returns:
LPMode
Raises:
ValueError

If LP_lm is not guided.

pyoptics.modes.lp_mode_field(mode, x, y, core_radius, orientation='cos', x0=0.0, y0=0.0)[source]

Field of an LP mode on a grid, normalized numerically to unit power.

Parameters:
modeLPMode
x, yarrays
core_radiusnumber
orientationstr, optional

“cos” (default) or “sin” for the real modes cos(l*phi), sin(l*phi), “+” or “-” for the helical modes exp(+-i*l*phi). Ignored for l = 0.

x0, y0numbers, optional

Position of the fibre axis.

Returns:
fieldarray
pyoptics.modes.marcuse_mode_field_radius(V, core_radius)[source]

Mode field radius of LP01 after Marcuse.

w/a = 0.65 + 1.619/V**1.5 + 2.879/V**6, the 1/e**2 intensity radius of the best matching Gaussian, better than 1 % for 1.2 < V < 2.4. The mode field diameter is 2*w.

Parameters:
Vnumber or array

V number.

core_radiusnumber

Core radius a.

Returns:
wnumber or array

Mode field radius.

pyoptics.modes.coupling_efficiency(field, mode, x, y)[source]

Power coupling efficiency of a field into a mode (or any other field).

eta = |<mode|field>|**2/(<mode|mode>*<field|field>).

Parameters:
field2d array

Incident field.

mode2d array

Mode field on the same grid (need not be normalized).

x, yarrays

Coordinates.

Returns:
etanumber

Efficiency between 0 and 1.

pyoptics.modes.mode_power_fractions(field, modes, x, y)[source]

Fractions of the power of a field coupled into each of a set of modes.

Parameters:
field2d array

Incident field.

modessequence of 2d arrays

(Orthogonal) mode fields, e.g. the fields of all LP modes of a fibre.

x, yarrays

Coordinates.

Returns:
fractions1d array

Coupling efficiency into each mode.

pyoptics.modes.coupling_vs_offset(field, mode, x, y, offsets, axis='x')[source]

Coupling efficiency with the field shifted laterally.

The field is shifted with a Fourier shift; keep it away from the grid edges.

Parameters:
field2d array

Incident field.

mode2d array

Mode field on the same grid.

x, yarrays

Coordinates.

offsetssequence of numbers

Lateral shifts of the field.

axis{“x”, “y”}, optional

Direction of the shift.

Returns:
eta1d array

Coupling efficiency for each offset.

pyoptics.modes.coupling_vs_tilt(field, mode, x, y, wavelength, angles, axis='x', n=1.0)[source]

Coupling efficiency with the field tilted.

The field is multiplied by exp(i*k*sin(theta)*x) (or y).

Parameters:
field2d array

Incident field.

mode2d array

Mode field on the same grid.

x, yarrays

Coordinates.

wavelengthnumber

Vacuum wavelength.

anglessequence of numbers

Tilt angles in radians in the medium, in the xz or yz plane.

axis{“x”, “y”}, optional

Plane of the tilt.

nnumber, optional

Refractive index of the medium.

Returns:
eta1d array

Coupling efficiency for each angle.

pyoptics.modes.coupling_vs_defocus(field, mode, x, y, wavelength, distances, n=1.0, propagator=None)[source]

Coupling efficiency with the field propagated along z.

The mode stays in the plane of the field, so positive distances mean the fibre end is behind the plane of the field.

Parameters:
field2d array

Incident field.

mode2d array

Mode field on the same grid.

x, yarrays

Coordinates.

wavelengthnumber

Vacuum wavelength.

distancessequence of numbers

Propagation distances (positive or negative).

nnumber, optional

Refractive index of the medium.

propagatorcallable, optional

propagator(field, x, y, z, wavelength, n) returning the propagated field first. The default is the angular spectrum method without the evanescent waves; pass e.g. propagators.fresnel_TF to compare with paraxial (ABCD) results.

Returns:
eta1d array

Coupling efficiency for each distance.