finesse.knm package

Submodules

finesse.knm.bayerhelms module

Computation of modal coupling coefficients via the Bayer-Helms analytic formalism.

finesse.knm.bayerhelms.compute_bayerhelms_coeff(qx1, qx2, qy1, qy2, double xgamma, double ygamma, int n1, int m1, int n2, int m2, double nr=1.0, double wavelength=1064e-9, bool reverse_gouy=False)

Computes the coupling coefficient, via Bayer-Helms [33], from mode (n1, m1) -> mode (n2, m2).

Note

Use make_bayerhelms_matrix() to compute a scattering matrix of these coefficients rather than calling this function in a loop.

Parameters

qx1BeamParam or complex

Input beam parameter in the tangential plane.

qx2BeamParam or complex

Output beam parameter in the tangential plane.

qy1BeamParam or complex

Input beam parameter in the sagittal plane.

qy2BeamParam or complex

Output beam parameter in the sagittal plane.

xgammafloat

Misalignment angle in the tangential plane (in radians).

ygammafloat

Misalignment angle in the sagittal plane (in radians).

n1int

Input tangential mode index.

m1int

Input sagittal mode index.

n2int

Output tangential mode index.

m2int

Output sagittal mode index.

nrfloat, optional; default: 1.0

Refractive index of the associated medium.

wavelengthfloat, optional; default: 1064 nm

Wavelength of the beam (in metres).

Returns

coeffcomplex

The complex coupling coefficient for the specified mode coupling.

finesse.knm.bayerhelms.make_bayerhelms_matrix(qx1, qx2, qy1, qy2, double xgamma, double ygamma, double nr=1.0, double wavelength=1064e-9, bool reverse_gouy=False, bool parallel=True, **mode_selection_kwargs)

Constructs and computes a coupling coefficient scattering matrix using the Bayer-Helms [33] analytic formalism.

See the function make_modes() for the arguments which should be passed via mode_selection_kwargs.

Parameters

qx1BeamParam or complex

Input beam parameter in the tangential plane.

qx2BeamParam or complex

Output beam parameter in the tangential plane.

qy1BeamParam or complex

Input beam parameter in the sagittal plane.

qy2BeamParam or complex

Output beam parameter in the sagittal plane.

xgammafloat

Misalignment angle in the tangential plane (in radians).

ygammafloat

Misalignment angle in the sagittal plane (in radians).

nrfloat, optional; default: 1.0

Refractive index of the associated medium.

wavelengthfloat, optional; default: 1064 nm

Wavelength of the beam (in metres).

reverse_gouybool, optional

Removing Gouy phase terms from calculated matrix

parallelbool, optional; default: True

Whether to enable multi-threaded execution via OpenMP. The number of threads used scales with the number of modes; bounded by the maximum thread count as given by omp_get_max_threads.

mode_selection_kwargskeyword arguments

See make_modes().

Returns

kmatKnmMatrix

The resulting scattering matrix as a KnmMatrix object.

Examples

See Computing arbitrary scattering matrices.

finesse.knm.integrators module

A collection of methods to compute overlap integrals for modal scattering matrices. Essentially this involves solving the following integral

\[K_{abnm} = \iint^{\infty}_{-\infty} U_{nm}(x,y,q_i) M(x,y) U^*_{ab}(x,y,q_o) \, dy \, dx \]

\(U_nm\) is the initial modes in the basis \(q_i\) we are converting from and \(U_ab\) are the target modes in a basis \(q_o\) we are projecting into.

TODO

Should explore if decomposing compute_map_knm_matrix_riemann_optimised into real and imaginary integrals might be faster. In cases where q_in == q_out then integrals are real, apart from the map component which can be complex.

Explore use of zgemm3m which is 25% faster than zgemm

Probably look into using CUDA if necessary for more speed.

finesse.knm.integrators.composite_newton_cotes_weights(N, order)

Constructs the weights for a composite Newton-Cotes rule for integration along 1-dimensional line with equally spaced steps. Newton-Cotes are a generalisation of a various discrete integration methods that are approximating an integrated by some polynomial. Common methods are:

N = 0 : Riemann sum N = 1 : Trapezoid rule N = 2 : Simpsons rule N = 4 : Simpsons 3/8 rule

Approximating a large bound with a high order polynomial can be numerically problematic. Thus a composite rule is generated by subdividing a larger area into multiple chunks and applying each rule along it.

If the order Newton-Cotes order specified does not produce a rule that fits into N, the order is decremented and that is used to fill gaps that do no fit.

See https://mathworld.wolfram.com/Newton-CotesFormulas.html

Parameters

Ninteger >= 0

1D size of array being ingrated over

orderinteger >= 0

Order of Newton-Cotes rule to use

Returns

weightsarray

Array of weights to multiply data with before summing

finesse.knm.integrators.compute_map_scattering_coeffs_riemann_optimised(double dA, double complex[:, ::1] Z, double complex[:, :, ::1] Unn_, double complex[:, :, ::1] Umm_, double complex[:, :, ::1] tmp, double complex[:, :, :, ::1] result)

Calculates a mode scattering matrix using a Riemann sum. This method uses an computationally optimised approach making use of fast BLAS functions. This requires the input modes to be specified in specific formats and memory layouts. What this functions computes is the following via a Riemann sum:

\[K_{abnm} = \int^{\infty}_{-\infty} u_{m}(y,q^y_i) u^*_{b}(y,q^y_o) \Bigg[ \int^{\infty}_{-\infty} Z(x,y) u_{n}(x,q^x_i) u^*_{a}(x,q^x_o) \, dx \Bigg] \, dy \]

This integral is not actually performed to infinity, it is bound by the dimensions of the discretised map \(Z\). The map bound and uniform discretisation must be chosen to efficiently sample the size of any of the beams and maximum mode order being used.

Due to the optimised calculation method, the result indexing is not [a,b,n,m] but [m,a,n,b]. To convert it back to a more usable indexing use:

>>> result = np.transpose(result, (2,1,0,3))

Notes

Nx - number of x samples Ny - number of y samples Nm - number of modes (n, m) being calculated

Parameters

dAdouble

Area of discrete integral, dx * dy

Zarray[complex]

2D map of size [Ny, Nx]

Unnarray[complex]

3D array of size [Nm, Nm, Nx]. This should contain the Un(x) * Un’(x)**C products

Ummarray[complex]

3D array of size [Nm, Nm, Ny]. This should contain the Um(x) * Um’(x)**C products

tmparray[complex]

Temporary storage that can be used to compute the dot products between Z and Unn. Should be of size (Nm, Nm, Ny)

resultarray[complex]

Resulting Knmnm output of size [Nm, Nm, Nm, Nm]. IMPORTANT: Note output indexing of result K[m,a,n,b]

finesse.knm.integrators.map_coupling_matrix_riemann(double complex[:, ::1] Y, double dx, double dy, double complex[:, ::1] Un, double complex[:, ::1] Um, long[:, ::1] index_map)
finesse.knm.integrators.outer_conj_product(double complex[:, ::1] U, double complex[:, :, ::1] result) void

Computes U * U^C and returns the output into the result array. Result array must be of shape (N,N,M) where U is shape (N,M).

finesse.knm.integrators.outer_conj_product_2(double complex[:, ::1] U1, double complex[:, ::1] U2, double complex[:, :, ::1] result) void

Computes U1 * U2**C and returns the output into the result array. Result array must be of shape (N,N,M) where U is shape (N,M).

finesse.knm.maps module

class finesse.knm.maps.Map(ndarray x, ndarray y, opd=None, amplitude=None, auto_remove_tilts=False, auto_remove_curvatures=False, auto_remove_astigmatism=False, is_focusing_element=False, put_focal_length=None)

Bases: object

A Map is an object that stores an optical path difference (OPD) and amplitude variations over some 2D surface. This represents a spatial distortion to an optical field and is used to model features such as surface defects, thermal lenses, and apertures.

The complex value of the map is described:

z(x,y) = amplitude(x,y) * exp[-1j * k * factor * opd(x,y)]

Where k is the wavenumber for the wavelength being used, and factor is some arbitrary scaling factor. This scaling is 2 for reflections, and for transmission will be some difference in refractive index between the two surfaces. Multiple z arrays can be generated from the same maps. z arrays are generated using the get_z method.

Multiple options exist for automatic removal of tilts, curvatures, and astigmatisms in maps too. When these options are defined and new map data is generated by calling get_z these terms will be removed from the OPD data. This allows changing maps defined with functions to constantly have these terms being removed during a simulation, simplifying their use. When automatic removal is used the terms are weighted with the current complex beam parameter spot size as a weight.

Parameters

xdouble[::1]

1D uniformally sample horizontal x array of size Nx

ydouble[::1]

1D uniformally sample vertical y array of size Ny

opd[double[:, ::1] | callable], optional

2D array of size [Ny, Nx] which describes the optical path difference over the grid defined by x and y. Units of meters. If a callable is provided it should be of the form f(smap, Model) argument and return a OPD array when called. smap is the current map object and model is the current model this Map’s element is a part of. This allows you to access other elements and information if needed.

amplitude[double[:, ::1] | callable], optional

2D array of size [Ny, Nx] which describes a amplitude over the grid defined by x and y. Units of meters. If a callable is provided it should be of the form f(smap, Model) argument and return an amplitude array when called. smap is the current map object and model is the current model this Map’s element is a part of. This allows you to access other elements and information if needed.

auto_remove_tiltsbool

When True any tilts present in the map will be removed when used during simulations. Can only be used if a callable is specified for opd then the tilts will be removed after each call to get new map data from the function.

auto_remove_curvaturesbool

When True any curvatures present in the map will be removed when used during simulations. Can only be used if callable is specified for opd then the tilts will be removed after each call to get new map data from the function. This will remove the average of the x and y curvatures, so will still leave astigmatisms present.

auto_remove_astigmatismbool

When True any astigmatism present in the map will be removed when used during simulations. Can only be used if a callable is specified for opd then the tilts will be removed after each call to get new map data from the function. This will remove astigmatic curvatures in both x and y, so is similar to using auto_remove_curvatures.

is_focusing_elementbool

When True this map is representing a focusing element like a curved mirror or lens. In such cases the large scale curvature has not been removed from the map. When set to True the mode projection will be done using the map integration and q_in != q_out. Therefore this map must include the focusing OPD to correctly project q_in -> q_out to be mode matched.

If False, the input and output q value is the same, and the mode projection is done using the analytic Bayer-Helms solution to the overlap integrals.

put_focal_lengthfinesse.parameter.Parameter

A lens element added to the model to put any removed focal length in the map OPD into to. This is only updated when the remove_curvatures() is called. This can happen at the user request or automatically if auto_remove_curvatures or auto_remove_astigmatism are True.

OPD_function

Returns the function that defines the OPD of this map, if there is one. Otherwise it returns None.

R
X
Y
amplitude
amplitude_function

Returns the function that defines the amplitude of this map, if there is one. Otherwise it returns None.

dx
dy
get_linear_terms(self, double spot_size: float)

Returns the spot weighted x and y linear terms from the OPD map data. For a surface z this is:

\[z(x,y) = a x + b y \]

Parameters

spot_sizefloat

Spot size to use for weighting during curvature removal

Returns

a, b(float, float)

Linear terms in x and y

get_quadratic_terms(self, double spot_size: float)

Returns the spot weighted x and y quadratic terms from the OPD map data. For a surface z this is:

\[z(x,y) = a x^2 + b y^2 \]

It’s common to want to get an equivalent curvature or thin-lens focal length for a map. The quadratic component can be related to the curvature on reflection as

\[a = \frac{1}{2 R} \]

or a single pass of a thin lens

\[a = -\frac{1}{2 f} \]

Parameters

spot_sizefloat

Spot size to use for weighting during curvature removal

Returns

a, b(float, float)

Quadratic terms in x and y

get_radius_of_curvature_reflection(self, double spot_size: float)

Assuming this map’s OPD array describes a surface, this function will compute the equivalent radius of curvature from it. Uses get_quadratic_terms().

Returns

Rcx, Rcy

Radius of curvature in each direction, in units of meters

Notes

An ideal parabolic reflecting surface has a surface shape:

\[z = \\frac{1}{4 f} r^{2} = a r^{2} \]

where \(a\) is the quadratic component of the surface, and \(f\) is the focal length of the reflecting surface. The radius of curvature of a mirror is related to the focal length by \(2f=R\), therefore the optical path depth is

\[z = \\frac{1}{2 R} r^{2} \]
get_thin_lens_f(self, double spot_size: float, *, average=False)

Computes the equivalent thin lens focal length from the optical path depth (OPD) in this map. Uses get_quadratic_terms().

Parameters

spot_sizefloat

Circular spot size weighting for curvature removal [m]

averagebool, optional

Whether to return the average in x and y of the focal length

Returns

focal_lengthtuple|float

If average==False returns focal_length_x, focal_length_y Focal length in each direction. Otherwise a singular average of the values

Notes

An ideal thin lens has an optical path length of

\[z = -\frac{1}{2 f} r^{2} = a r^{2}\]

where a is the quadratic component of the OPD, and f is the focal length of the lens.

get_z(self, double k, double phase_factor, model=None)

Calculates the 2D complex-valued array combining both the amplitude and OPD data stored in this map. This returned value is the 2D data that is integrated over to computed higher order mode scattering matrices.

Parameters

kfloat

Wave number

phase_factordouble

Optical path difference scaling factor

modelfinesse.model.Model, optional

Model object to use in calculating the map

Returns

complex_mapndarray

Complex map array

Notes

Note that if the maps amplitude or OPD data is defined by a custom function that relies on model parameter data you will have to provide a current model to call this function.

The phase definition used here for converting OPD to phase is

\[\mathrm{amplitude}(x,y) exp(-i k \mathrm{OPD}(x,y)) \]

The phase_factor sign should be used to convert between different coordinates and types of. For example, reflections from port 1 side of a mirror phase_factor=-2. A minus sign is here because the surface normal is pointing back towards the beam, and the 2 is double passing the OPD.

opd
remove_curvatures(self, double spot_size: float, str mode: str = 'average', model=None)

Removes average weighted quadratic terms from the OPD map data. To get the value of the quadratic term being removed use get_quadratic_terms() before calling this. If put_focal_length has been set then calling this method will put the removed curvatures into the parameter put_focal_length.

Parameters

spot_sizefloat

spot size to use for weighting during curvature removal

modestr

Different options for curvatures removal are available

  • “average” : removes average of x and y curvatures

  • “astigmatic” : removes astigmatic x and y curvatures

modelfinesse.model.Model

If put_focal_length has been set then it can be used against a specific model object. If None it will use the model of the element provided.

Returns

ax, ayfloat

Quadratic coefficients in the x and y direction. Same as returned by get_quadratic_terms().

remove_piston(self, float spot_size: float | None)

Removes any piston term from the optical path difference data. This corresponds to removing a constant term averaged over the spotsize.

Note this will only operate on data stored in the .opd attribute. If the OPD data is determined using a custom function then this method will not work. Instead, you can specify the map to auto-remove any tilts which ensures this method is called after any update to the map is made during the simulation.

Parameters

spot_sizefloat or None

spot size to use for weighting. If None then a full area average is done.

Returns

pistonfloat

Removed piston term

remove_tilts(self, double spot_size: float)

Removes any tilts from the optical path difference data. This corresponds to removing the linear term in the OPD data.

Note this will only operate on data stored in the .opd attribute. If the OPD data is determined using a custom function then this method will not work. Instead, you can specify the map to auto-remove any tilts which ensures this method is called after any update to the map is made during the simulation.

Parameters

spot_sizefloat

spot size to use for weighting during tilt removal

Returns

yaw, pitch(float, float)

Removed linear terms

rms(self, double spot_size: float)

Computes the spot size weighted RMS of this maps OPD.

Parameters

spot_sizefloat

spot size to use for weighting during tilt removal

Returns

rmsfloat

Root mean square of OPD in metres

scatter_matrix(self, q, k0, phase_scale, homs, reverse_gouy=False, flip_lr=False)

Computes a modal scattering matrix for this map. Careful consideration should be applied to reversing of the Gouy phase. By default this will compute the scattering matrix with the Gouy phase included in each input and output field. If this scattering matrix is to be used as an operator then the Gouy phase should be removed. The map can also be flipped left-to-right, this allows the backwards propagation to be computed assuming that the left-handed coordating of the beam has been reflected so that the x and z axes are inverted.

Parameters

qBeamParam

Setting input and output complex beam parameters for overlap calcuations. Options are: - q : all input/output beam parameters are the same - (qx, qy) : astigmatic input/output beam parameters - (q_ix, q_iy, q_ox, q_oy) : general case, each x/y input/out can be different

k0float

Wavenumber of the light to compute scatter for, 2*pi/wavelength

phase_scalefloat

Scaling to apply to the map data to generate the phase information. This sets whether the map is representing a transmission, or reflection. The phase used to compute the scatter is given by:

\[exp(-i extrm{phase}_{ extrm{scale}} k \mathrm{OPD}(x,y))\]
for example. Some typical values are
  • phase_scale = 1 : transmission

  • phase_scale = 2 : reflection

homsarray_like

A 2D array of (n,m) values for the Hermite-Gaussian modes to compute the scattering for. e.g [[0,0], [1,0], [4,2], …].

reverse_gouybool, optional

If true, the gouy phase terms are removed from the scattering coefficients.

flip_lrbool, optional

If true, the x map data is flipped left to right before computing the scattering. This can be used to compute the backwards propagating beam through a map as the coordinate system is flipped.

Returns

A finesse.knm.matrix.KnmMatrix object with the HOM scattering terms.

update(self, model=None, float weight_spot_size: float = None)

If the optical path difference or ampltiude data for this map is defined by some callable function you will need to call this update method before accessing its data. If the functions rely on Model parameter values you will also need to provide a Model to evaluate the map with. If automatic tilt or curvature removal is used you will also have to specify the spot size to use as a weighting.

Parameters

modelfinesse.model.Model

Model to use for passing to any map functions.

weight_spot_sizefloat

Spot size to use for automatic weighting curvature and tilt removal

x
y
finesse.knm.maps.map_scattering_coefficients(q: BeamParam, int max_order, double[::1] x, double[::1] y, double complex[:, ::1] Z, bool reverse_gouy=False, bool flip_lr=False)

Calculates the mode scattering coefficients up to some maximum mode order for a uniformly spaced 2-dimensional map. Essentially it is computing multiple overlap integrals between each input and output mode for some complex valued abberation map, Z.

\[K_{abnm} = \iint^{\infty}_{-\infty} U_{nm}(x,y,q_{ix},q_{iy}) Z(x,y) U^*_{ab}(x,y,q_{ox},q_{oy}) \, dy \, dx \]
  • ab are the output mode indicies

  • nm are the input mode indicies

Parameters

qBeamParam

Setting input and output complex beam parameters for overlap calcuations. Options are: - q : all input/output beam parameters are the same - (qx, qy) : astigmatic input/output beam parameters - (q_ix, q_iy, q_ox, q_oy) : general case, each x/y input/out can be different

max_orderint

Maximum order of mode scattering to compute up to.

x, yarray[double]

1-dimensional arrays specifying the x and y uniformally sampled axis for the map

Zarray[complex]

2-dimensional array describing the complex abberation being applied to some input beam. The shape of this array should be Z[Ny, Nx], where Ny and Nx are the number of y and x samples respectively.

reverse_gouybool, optional

If true, the gouy phase terms are removed from the scattering coefficients

flip_lrbool, optional

If true, the x map data is flipped left to right before computing the scattering. This can be used to compute the backwards propagating beam through a map as the coordinate system is flipped.

Returns

Karray[complex]

Coupling coefficients array with indexing (inx, outx, iny, outy) upto max_order input.

Examples

Same input and output beam parameter but computing the scattering from some arbitrary map:

import finesse
from finesse.knm.maps import map_scattering_coefficients
import numpy as np

maxtem = 10
q = finesse.BeamParam(w0=1e-3, z=0)
x = np.linspace(-4*q.w, 4*q.w, 201)
y = np.linspace(-4*q.w, 4*q.w, 200)
X, Y = np.meshgrid(x, y)
# Mix of liner and quadratic phase terms to compute scattering
# coefficients for
Z = np.exp(
    1j * 1e-6 * 2 * np.pi
    * (0.2*X + 0.1*Y + 1000*X**2 - 1000*Y**2) / 1064e-9
)
K = map_scattering_coefficients(q, maxtem, x, y, Z)
print("HG 10 -> 30", K[1,3,0,0])
print("HG 00 -> 00", K[0,0,0,0])
print("HG 00 -> 21", K[0,2,0,1])

Different input and output beam parameters. Here modelling mode mismatch between different beam parameters:

qx1 = finesse.BeamParam(w0=1e-3, z=0)
qy1 = qx1
qx2 = finesse.BeamParam(w0=1.2e-3, z=0)
qy2 = qx2

Z = np.ones_like(Z)
K = map_scattering_coefficients((qx1,qy1,qx2,qy2), maxtem, x, y, Z)
print("HG 00 -> 20", K[0,2,0,0])
print("HG 00 -> 00", K[0,0,0,0])
finesse.knm.maps.scattering_coefficients_to_KnmMatrix(modes, K)

Converts a 4-D scattering coefficient array into a 2D KnmMatrix object to be used in simulations.

Parameters

modestuple, array

Array of 2D modes indicies (n,m) to specify the order in which they appear in the returned matrix.

Karray

4D array of coefficients indexed with [in_x, out_x, in_y, out_y]

Returns

KnmKnmMatrix

A KnmMatrix class representing a 2D scattering matrix for the requested modes.

Examples

Compute KNM matrix from a previously calculated 4-D scattering coefficient array:

import finesse
from finesse.knm.maps import (
    map_scattering_coefficients,
    scattering_coefficients_to_KnmMatrix
)
import numpy as np

# compute all scatterings up to maximum TEM order
maxtem = 3
q = finesse.BeamParam(w0=1e-3, z=0)
x = np.linspace(-4*q.w, 4*q.w, 201)
y = np.linspace(-4*q.w, 4*q.w, 200)
X, Y = np.meshgrid(x, y)
# Mix of liner and quadratic phase terms to compute scattering
# coefficients for
Z = np.exp(1j * 1e-6 * 2 * np.pi * X / 1064e-9)
K = map_scattering_coefficients(q, maxtem, x, y, Z)
# Generate specific ordering of coefficients into a 2D matrix that can
# be used in simulations for propagating and array of modes.
modes = (
    (0,0),
    (1,0),
    (2,1),
)
Knm = scattering_coefficients_to_KnmMatrix(modes, K)
# Propagate some mode amplitudes
Knm.data @ [1, 0.1, 0]
>>> array([9.99995641e-01+2.95261180e-04j,
           9.99986923e-02+2.95261180e-03j,
           4.23516474e-22+2.16840434e-20j])

finesse.knm.matrix module

Scattering matrix data structure and associated functions for constructing different formats of this object.

class finesse.knm.matrix.KnmMatrix(const int[:, ::1] modes, comp_name='', kdir='')

Bases: object

Higher-Order-Mode scattering matrix container. Essentially a wrapper around a 2D NumPy array with methods for conveniently accessing specific couplings and plotting the matrix as a color-mesh.

The underlying numpy.ndarray object can be accessed via the data attribute.

Construction of KnmMatrix objects should, generally, not be performed manually. Objects of this type are the return type of the general scattering matrix computing routines, see make_scatter_matrix(). To make a KnmMatrix object from a pre-existing matrix of complex coupling coefficients, use KnmMatrix.from_buffer().

Parameters

modesarray-like

A 2D array, or memory-view to the array, of the mode indices associated with the scattering matrix.

comp_namestr, optional; default: “”

Name of the component associated with the matrix (if any).

kdirstr, optional; default: “”

A string representing the coupling direction of the matrix, e.g. “11” for a reflection at the first surface of a mirror-like optic.

data
static from_buffer(ndarray buffer, const int[:, ::1] modes, **kwargs)

Construct a KnmMatrix object from a pre-existing 2D array buffer.

This method is useful for creating KnmMatrix objects from scattering matrix data which have been computed elsewhere. One of the most common use-cases is when using KnmDetector objects in “matrix-mode”; see the documentation of this class for an example.

Parameters

buffernumpy.ndarray

A 2D array of complex values corresponding to the underlying buffer of scattering matrix data.

modesarray-like

A 2D array, or memory-view to the array, of the mode indices associated with the scattering matrix.

kwargskeyword arguments, optional

Additional args to pass to constructor of KnmMatrix.

Returns

kmatKnmMatrix

The KnmMatrix wrapper around the array buffer.

get(self, key, default=None)

Retrieves the coupling coefficient corresponding to the key, returning default if this key is invalid.

Parameters

keystr or integer sequence

A string of the format:

  • “nm->n’m’” or,

  • “nmn’m’”,

where n, m, n’ and m’ are all convertible to integers

Or an integer sequence of:

  • length 2 – i.e. an i, j pair corresponding to the field indices.

  • or length 4 – i.e. a n1, m1, n2, m2 coupling.

defaultAny, optional

The default value returned if the key is invalid.

Returns

outcomplex

The value of the coupling coefficient associated with key.

homs
modes
name
static of_zeros(const int[:, ::1] modes, **kwargs)

Constuct a KnmMatrix where each element is (complex) zero.

Parameters

modesarray-like

A 2D array, or memory-view to the array, of the mode indices associated with the scattering matrix.

kwargskeyword arguments, optional

Additional args to pass to constructor of KnmMatrix.

Returns

kmatKnmMatrix

The KnmMatrix object consisting of a matrix of zeroes.

plot(self, mode='amplitude', log=False, deg=False, cmap=None, show=True, filename=None)

Plots the coupling coefficient matrix as a color-mesh.

Parameters

modestr, optional

Specifier for which attribute of the coupling coefficient to plot. This can be one of ‘amplitude’, ‘phase’, ‘real’, ‘imag’, ‘amplitude/phase’, or ‘real/imag’. Defaults to ‘amplitude’.

logbool, optional

Whether the log of the data should be plotted. This is only used for ‘amplitude’ and is ignored for all other options. Defaults to False.

degbool, optional

Whether the data should be plotted in degrees or radians. This is only used for ‘phase’ and is ignored for all other options. Defaults to False.

cmapstr, matplotlib colormap, optional

Colormap to use. Defaults to the default colormap loaded in matplotlib.rcParams.

showbool, optional

Whether to show plot or not. Defaults to true.

filenamestr, path, optional

The name of a file to save the figure to. Defaults to None so that no file is saved.

Returns

figmatplotlib figure

A handle to the figure.

finesse.knm.matrix.make_unscaled_X_scatter_knm_matrix(int[:, ::1] modes)

This method returns an unscaled KnmMatrix object that represents a distortion from the integral:

iint_inf U_nm(x,y) x U_n’m’(x,y) dx dy

This essentially scatters modes by mode index n ± 1. There are some scalings proportional to w(x)*exp(±1j*Gouy(z)) missing as these can be applied as single scalars in addition to this matrix if needed.

Returns

KnmMatrix

finesse.knm.matrix.make_unscaled_Y_scatter_knm_matrix(int[:, ::1] modes)

This method returns an unscaled KnmMatrix object that represents a distortion from the integral:

iint_inf U_nm(x,y) y U_n’m’(x,y) dx dy

This essentially scatters modes by mode index m ± 1. There are some scalings proportional to w(x)*exp(±1j*Gouy(z)) missing as these can be applied as single scalars in addition to this matrix if needed.

Returns

KnmMatrix

finesse.knm.matrix.reverse_gouy_phases(x_gouy1, y_gouy1, x_gouy2, y_gouy2, knm_matrix)

Adjust the phase of all coupling coefficients in the matrix knm_mat with respect to the Gouy phases.

This is required for \(k_{nmn'm'}\) calculations because in Finesse the Gouy phase is added explicitly to the amplitude coefficients in a Space whereas the coupling coefficients are derived using a formula in which the Gouy phase resides in the equation for the spatial profile.

finesse.knm.tools module

Tools for calculating coupling coefficients and modal scattering matrices of different types.

finesse.knm.tools.make_scatter_matrix(mtype, *args, **kwargs)

Constructs and computes a coupling coefficient scattering matrix of the specified type (via mtype).

Parameters

mtypestr

Type of scattering matrix to compute.

The valid options are:

*argspositional arguments

The positional arguments to pass to the relevant scatter matrix function.

**kwargskeyword arguments

The keyword arguments to pass to the relevant scatter matrix function.

Returns

kmatKnmMatrix

The resulting scattering matrix as a KnmMatrix object.

Examples

See Computing arbitrary scattering matrices.

Module contents

Library of coupling coefficient data structures and calculations.

Much of the code in this sub-package exists in a Cythonised form which should only be used internally for calculating modal scattering during simulations.

For the user, the tools sub-module provides Python facing functions for calculating certain types of coupling coefficients, and scattering matrices of these, directly. The bayerhelms module also contains Python exposed functions for calculating Bayer-Helms [33] coefficients directly.

A data structure, KnmMatrix, representing a scattering matrix is documented in matrix. Objects of this type are returned whenever using functions in this library which compute coupling coefficient matrices.

See Computing arbitrary scattering matrices for details and examples on using some of the Python-facing tools in this library.

Note that these tools use the same internal C code as that which gets executed during simulations, and so will be very efficient off-the-shelf.

class finesse.knm.Map(ndarray x, ndarray y, opd=None, amplitude=None, auto_remove_tilts=False, auto_remove_curvatures=False, auto_remove_astigmatism=False, is_focusing_element=False, put_focal_length=None)

Bases: object

A Map is an object that stores an optical path difference (OPD) and amplitude variations over some 2D surface. This represents a spatial distortion to an optical field and is used to model features such as surface defects, thermal lenses, and apertures.

The complex value of the map is described:

z(x,y) = amplitude(x,y) * exp[-1j * k * factor * opd(x,y)]

Where k is the wavenumber for the wavelength being used, and factor is some arbitrary scaling factor. This scaling is 2 for reflections, and for transmission will be some difference in refractive index between the two surfaces. Multiple z arrays can be generated from the same maps. z arrays are generated using the get_z method.

Multiple options exist for automatic removal of tilts, curvatures, and astigmatisms in maps too. When these options are defined and new map data is generated by calling get_z these terms will be removed from the OPD data. This allows changing maps defined with functions to constantly have these terms being removed during a simulation, simplifying their use. When automatic removal is used the terms are weighted with the current complex beam parameter spot size as a weight.

Parameters

xdouble[::1]

1D uniformally sample horizontal x array of size Nx

ydouble[::1]

1D uniformally sample vertical y array of size Ny

opd[double[:, ::1] | callable], optional

2D array of size [Ny, Nx] which describes the optical path difference over the grid defined by x and y. Units of meters. If a callable is provided it should be of the form f(smap, Model) argument and return a OPD array when called. smap is the current map object and model is the current model this Map’s element is a part of. This allows you to access other elements and information if needed.

amplitude[double[:, ::1] | callable], optional

2D array of size [Ny, Nx] which describes a amplitude over the grid defined by x and y. Units of meters. If a callable is provided it should be of the form f(smap, Model) argument and return an amplitude array when called. smap is the current map object and model is the current model this Map’s element is a part of. This allows you to access other elements and information if needed.

auto_remove_tiltsbool

When True any tilts present in the map will be removed when used during simulations. Can only be used if a callable is specified for opd then the tilts will be removed after each call to get new map data from the function.

auto_remove_curvaturesbool

When True any curvatures present in the map will be removed when used during simulations. Can only be used if callable is specified for opd then the tilts will be removed after each call to get new map data from the function. This will remove the average of the x and y curvatures, so will still leave astigmatisms present.

auto_remove_astigmatismbool

When True any astigmatism present in the map will be removed when used during simulations. Can only be used if a callable is specified for opd then the tilts will be removed after each call to get new map data from the function. This will remove astigmatic curvatures in both x and y, so is similar to using auto_remove_curvatures.

is_focusing_elementbool

When True this map is representing a focusing element like a curved mirror or lens. In such cases the large scale curvature has not been removed from the map. When set to True the mode projection will be done using the map integration and q_in != q_out. Therefore this map must include the focusing OPD to correctly project q_in -> q_out to be mode matched.

If False, the input and output q value is the same, and the mode projection is done using the analytic Bayer-Helms solution to the overlap integrals.

put_focal_lengthfinesse.parameter.Parameter

A lens element added to the model to put any removed focal length in the map OPD into to. This is only updated when the remove_curvatures() is called. This can happen at the user request or automatically if auto_remove_curvatures or auto_remove_astigmatism are True.

OPD_function

Returns the function that defines the OPD of this map, if there is one. Otherwise it returns None.

R
X
Y
amplitude
amplitude_function

Returns the function that defines the amplitude of this map, if there is one. Otherwise it returns None.

dx
dy
get_linear_terms(self, double spot_size: float)

Returns the spot weighted x and y linear terms from the OPD map data. For a surface z this is:

\[z(x,y) = a x + b y \]

Parameters

spot_sizefloat

Spot size to use for weighting during curvature removal

Returns

a, b(float, float)

Linear terms in x and y

get_quadratic_terms(self, double spot_size: float)

Returns the spot weighted x and y quadratic terms from the OPD map data. For a surface z this is:

\[z(x,y) = a x^2 + b y^2 \]

It’s common to want to get an equivalent curvature or thin-lens focal length for a map. The quadratic component can be related to the curvature on reflection as

\[a = \frac{1}{2 R} \]

or a single pass of a thin lens

\[a = -\frac{1}{2 f} \]

Parameters

spot_sizefloat

Spot size to use for weighting during curvature removal

Returns

a, b(float, float)

Quadratic terms in x and y

get_radius_of_curvature_reflection(self, double spot_size: float)

Assuming this map’s OPD array describes a surface, this function will compute the equivalent radius of curvature from it. Uses get_quadratic_terms().

Returns

Rcx, Rcy

Radius of curvature in each direction, in units of meters

Notes

An ideal parabolic reflecting surface has a surface shape:

\[z = \\frac{1}{4 f} r^{2} = a r^{2} \]

where \(a\) is the quadratic component of the surface, and \(f\) is the focal length of the reflecting surface. The radius of curvature of a mirror is related to the focal length by \(2f=R\), therefore the optical path depth is

\[z = \\frac{1}{2 R} r^{2} \]
get_thin_lens_f(self, double spot_size: float, *, average=False)

Computes the equivalent thin lens focal length from the optical path depth (OPD) in this map. Uses get_quadratic_terms().

Parameters

spot_sizefloat

Circular spot size weighting for curvature removal [m]

averagebool, optional

Whether to return the average in x and y of the focal length

Returns

focal_lengthtuple|float

If average==False returns focal_length_x, focal_length_y Focal length in each direction. Otherwise a singular average of the values

Notes

An ideal thin lens has an optical path length of

\[z = -\frac{1}{2 f} r^{2} = a r^{2}\]

where a is the quadratic component of the OPD, and f is the focal length of the lens.

get_z(self, double k, double phase_factor, model=None)

Calculates the 2D complex-valued array combining both the amplitude and OPD data stored in this map. This returned value is the 2D data that is integrated over to computed higher order mode scattering matrices.

Parameters

kfloat

Wave number

phase_factordouble

Optical path difference scaling factor

modelfinesse.model.Model, optional

Model object to use in calculating the map

Returns

complex_mapndarray

Complex map array

Notes

Note that if the maps amplitude or OPD data is defined by a custom function that relies on model parameter data you will have to provide a current model to call this function.

The phase definition used here for converting OPD to phase is

\[\mathrm{amplitude}(x,y) exp(-i k \mathrm{OPD}(x,y)) \]

The phase_factor sign should be used to convert between different coordinates and types of. For example, reflections from port 1 side of a mirror phase_factor=-2. A minus sign is here because the surface normal is pointing back towards the beam, and the 2 is double passing the OPD.

opd
remove_curvatures(self, double spot_size: float, str mode: str = 'average', model=None)

Removes average weighted quadratic terms from the OPD map data. To get the value of the quadratic term being removed use get_quadratic_terms() before calling this. If put_focal_length has been set then calling this method will put the removed curvatures into the parameter put_focal_length.

Parameters

spot_sizefloat

spot size to use for weighting during curvature removal

modestr

Different options for curvatures removal are available

  • “average” : removes average of x and y curvatures

  • “astigmatic” : removes astigmatic x and y curvatures

modelfinesse.model.Model

If put_focal_length has been set then it can be used against a specific model object. If None it will use the model of the element provided.

Returns

ax, ayfloat

Quadratic coefficients in the x and y direction. Same as returned by get_quadratic_terms().

remove_piston(self, float spot_size: float | None)

Removes any piston term from the optical path difference data. This corresponds to removing a constant term averaged over the spotsize.

Note this will only operate on data stored in the .opd attribute. If the OPD data is determined using a custom function then this method will not work. Instead, you can specify the map to auto-remove any tilts which ensures this method is called after any update to the map is made during the simulation.

Parameters

spot_sizefloat or None

spot size to use for weighting. If None then a full area average is done.

Returns

pistonfloat

Removed piston term

remove_tilts(self, double spot_size: float)

Removes any tilts from the optical path difference data. This corresponds to removing the linear term in the OPD data.

Note this will only operate on data stored in the .opd attribute. If the OPD data is determined using a custom function then this method will not work. Instead, you can specify the map to auto-remove any tilts which ensures this method is called after any update to the map is made during the simulation.

Parameters

spot_sizefloat

spot size to use for weighting during tilt removal

Returns

yaw, pitch(float, float)

Removed linear terms

rms(self, double spot_size: float)

Computes the spot size weighted RMS of this maps OPD.

Parameters

spot_sizefloat

spot size to use for weighting during tilt removal

Returns

rmsfloat

Root mean square of OPD in metres

scatter_matrix(self, q, k0, phase_scale, homs, reverse_gouy=False, flip_lr=False)

Computes a modal scattering matrix for this map. Careful consideration should be applied to reversing of the Gouy phase. By default this will compute the scattering matrix with the Gouy phase included in each input and output field. If this scattering matrix is to be used as an operator then the Gouy phase should be removed. The map can also be flipped left-to-right, this allows the backwards propagation to be computed assuming that the left-handed coordating of the beam has been reflected so that the x and z axes are inverted.

Parameters

qBeamParam

Setting input and output complex beam parameters for overlap calcuations. Options are: - q : all input/output beam parameters are the same - (qx, qy) : astigmatic input/output beam parameters - (q_ix, q_iy, q_ox, q_oy) : general case, each x/y input/out can be different

k0float

Wavenumber of the light to compute scatter for, 2*pi/wavelength

phase_scalefloat

Scaling to apply to the map data to generate the phase information. This sets whether the map is representing a transmission, or reflection. The phase used to compute the scatter is given by:

\[exp(-i extrm{phase}_{ extrm{scale}} k \mathrm{OPD}(x,y))\]
for example. Some typical values are
  • phase_scale = 1 : transmission

  • phase_scale = 2 : reflection

homsarray_like

A 2D array of (n,m) values for the Hermite-Gaussian modes to compute the scattering for. e.g [[0,0], [1,0], [4,2], …].

reverse_gouybool, optional

If true, the gouy phase terms are removed from the scattering coefficients.

flip_lrbool, optional

If true, the x map data is flipped left to right before computing the scattering. This can be used to compute the backwards propagating beam through a map as the coordinate system is flipped.

Returns

A finesse.knm.matrix.KnmMatrix object with the HOM scattering terms.

update(self, model=None, float weight_spot_size: float = None)

If the optical path difference or ampltiude data for this map is defined by some callable function you will need to call this update method before accessing its data. If the functions rely on Model parameter values you will also need to provide a Model to evaluate the map with. If automatic tilt or curvature removal is used you will also have to specify the spot size to use as a weighting.

Parameters

modelfinesse.model.Model

Model to use for passing to any map functions.

weight_spot_sizefloat

Spot size to use for automatic weighting curvature and tilt removal

x
y