finesse.knm.maps module

class finesse.knm.maps.Map(ndarray[double,ndim=1], ndarray[double,ndim=1], opd=None, amplitude=None, auto_remove_tilts=False, auto_remove_curvatures=False, auto_remove_astigmatism=False, is_focusing_element=False, put_focal_length=None)[source]

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.

Note: in either branch, on a connection that carries both an analytic Bayer-Helms (BH) contribution and a numerical map-integration (MAP) contribution, the final scattering matrix is composed as a single matrix product of the two. The order of that product is controlled per element by the attribute knm_apply_bayer_helms_first on finesse.components.mirror.Mirror, finesse.components.beamsplitter.Beamsplitter and finesse.components.lens.Lens. This is implemented in the shared base class finesse.components.general.MapAndKNMOptic. See How Bayer-Helms and map contributions are combined.

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.

Attributes

parameter_dependenciesOrderedSet

A set of all the parameters that this map depends on. This is used to automatically update the map data when any of these parameters change during a simulation.

OPD_function[source]

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

R
X
Y
amplitude
amplitude_function[source]

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

dx[source]
dy[source]
get_linear_terms(self, double spot_size: float)[source]

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)[source]

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)[source]

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)[source]

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)[source]

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
parameter_dependencies
remove_curvatures(self, double spot_size: float, str mode: str = 'average', model=None)[source]

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)[source]

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)[source]

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)[source]

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)[source]

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 \textrm{phase}_{\textrm{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, sim_carrier=None)[source]

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

sim_carrierfinesse.simulation.BaseSimulation, optional

Current simulation object for the carrier to use for updating the map data, None if being updated outside of a simulation. Which the map function should handle gracefully.

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)[source]

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)[source]

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])