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
- qx1
BeamParamor complex Input beam parameter in the tangential plane.
- qx2
BeamParamor complex Output beam parameter in the tangential plane.
- qy1
BeamParamor complex Input beam parameter in the sagittal plane.
- qy2
BeamParamor 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.
- qx1
- 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
- qx1
BeamParamor complex Input beam parameter in the tangential plane.
- qx2
BeamParamor complex Output beam parameter in the tangential plane.
- qy1
BeamParamor complex Input beam parameter in the sagittal plane.
- qy2
BeamParamor 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
Examples
- qx1
finesse.knm.integrators module
A collection of methods to compute overlap integrals for modal scattering matrices. Essentially this involves solving the following integral
\(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:
objectA 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
opdthen 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
opdthen 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
opdthen 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_length
finesse.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
- model
finesse.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_factorsign should be used to convert between different coordinates and types of. For example, reflections from port 1 side of a mirrorphase_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
- model
finesse.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
.opdattribute. 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
.opdattribute. 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.KnmMatrixobject 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
- model
finesse.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
- model
- 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:
objectHigher-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.ndarrayobject can be accessed via thedataattribute.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, useKnmMatrix.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
KnmDetectorobjects in “matrix-mode”; see the documentation of this class for an example.Parameters
- buffer
numpy.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
- kmat
KnmMatrix The KnmMatrix wrapper around the array buffer.
- 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
- kmat
KnmMatrix 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
Spacewhereas 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:
- “bayerhelms” — computes a Bayer-Helms scattering matrix,
- *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
Examples
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:
objectA 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
opdthen 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
opdthen 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
opdthen 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_length
finesse.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
- model
finesse.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_factorsign should be used to convert between different coordinates and types of. For example, reflections from port 1 side of a mirrorphase_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
- model
finesse.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
.opdattribute. 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
.opdattribute. 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.KnmMatrixobject 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
- model
finesse.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
- model
- x
- y