hswfs.zernike

This module provides methods related to Zernike polynomials and their derivatives.

class hswfs.zernike.Wavefront(coefficients: Union[Sequence[float], Dict[int, float]])[source]

A wavefront, expressed as a weighted sum of Zernike polynomials. The wavefront is returned as a sy.Expr. This is useful if we, for example, also want to compute the derivative of the wavefront. Both the polar and the Cartesian representation of the wavefront are available.

Parameters

coefficients

The coefficients to be used as weights for the Zernike polynomials. There are two ways to specify this:

  1. As a sequence of floats. In this case, the \(j\)-th entry of the sequence will be used as the weight for the \(j\)-th Zernike polynomial. That means:

    >>> coefficients = [0, 1, 2, 0, 4]
    

    will produce the following wavefront:

    \[\text{WF} = Z_1 + 2 \cdot Z_2 + 4 \cdot Z_4\]
  2. As a dictionary with entries of the form (j, weight). To reproduce the previous example, we could therefore also write:

    >>> coefficients = {1: 1, 2: 2, 4: 4}
    

Note that there is per se no limit of the number of Zernike polynomials that can be used for a wavefront; however, things of course will get slower for higher orders.

property cartesian: Expr

Get the Cartesian representation of the wavefront.

property polar: Expr

Get the polar representation of the wavefront.

class hswfs.zernike.ZernikePolynomial(m: Optional[int] = None, n: Optional[int] = None, j: Optional[int] = None)[source]

Implements the Zernike polynomial \(Z^m_n\) (in double-index notation), or \(Z_j\) (in single-index notation).

property azimuthal_part: Expr

The azimuthal component of \(Z^m_n\), which is given by:

\[\begin{split}\Phi_m ( \phi ) = \begin{cases} \cos( m \, \phi ) & \text{for}\ m \geq 0 \\ \sin( m \, \phi ) & \text{for}\ m < 0 \end{cases}\end{split}\]
Returns

The azimuthal part of \(Z^m_n\).

property cartesian: Expr

\(Z^m_n(x, y)\), that is, the full Zernike polynomial in Cartesian coordinates \(x, y\).

Returns

The Zernike polynomial \(Z^m_n(x, y)\).

property fourier_transform: Expr

The 2D Fourier transform of \(Z^m_n\).

This function essentially implements eq. (7) of [Tatulli_2013].

Note

Compared to [Tatulli_2013], we are using a slightly different notation. Instead of indexing the dimensions of the Fourier space (or \(k\)-space) using \(\kappa\) and \(\alpha\), we use \(k_1\) and \(k_2\).

Returns

The 2D Fourier transform of \(Z^m_n\), that is, \(\mathcal{F}\lbrace Z^m_n \rbrace (k_1, k_2)\).

property normalization: Expr

The normalization factor of \(Z^m_n\).

Zernike polynomials are normalized such that:

\[\int_0^1 d\rho \int_0^{2\pi}d\phi \ Z^2(\rho, \phi) \, \rho = \pi\]

Note

Note that this choice of normalization is not universal, and that some authors choose different normalizations; for example, they normalize the above integral to 1 instead of \(\pi\).

Returns

The normalization factor of \(Z^m_n\).

property polar: Expr

\(Z^m_n(\rho, \phi)\), that is, the full Zernike polynomial in polar coordinates \(\rho, \phi\).

Returns

The Zernike polynomial \(Z^m_n(\rho, \phi)\).

property radial_part: Expr

The radial polynomial \(R^m_n\), which is given by:

\[R^m_n ( \rho ) = \sum_{k=0}^{\frac{n-m}{2}} (-1)^{k} \, {{n - k} \choose {k}} \, {{n - 2k} \choose {\frac{n - m}{2} - k}} \, \rho^{n - 2k}\]
Returns

The radial polynomial \(R^m_n\).

hswfs.zernike.derive(expression: Expr, wrt: Union[str, Symbol]) Expr[source]

Compute the derivative of expression with respect to wrt.

Parameters
  • expression – A sympy expression.

  • wrt – The variable with respect to which to take the derivative. Can either be a sy.Symbol or a string containing the name of the variable.

Returns

The derivative of expression with respect to wrt.

hswfs.zernike.eval_cartesian(expression: Expr, x_0: Union[float, ndarray], y_0: Union[float, ndarray]) Union[float, ndarray][source]

Evaluate an expression that is in in Cartesian coordinates, either at a single position or on a grid of positions.

Parameters
  • expression – A sympy expression.

  • x_0 – The value(s) of \(x\) at which to evaluate the given expression. This can either be a single float, or an array of arbitrary size (its shape, however, must match y_0).

  • y_0 – The value(s) of \(y\) at which to evaluate the given expression. This can either be a single float, or an array of arbitrary size (its shape, however, must match x_0).

Returns

The value of expression at the given position(s). The type and shape of the output matches the one of the input: for x_0, y_0 as floats, a float is returned; for numpy array inputs, a numpy array is returned.

hswfs.zernike.is_cartesian(expression: Expr) bool[source]

Check if a given expression is in Cartesian coordinates, that is, if the names of its free symbols are a subset of {“x”, “y”}.

Parameters

expression – A sympy expression.

Returns

True if expression is in Cartesian coordinates; else False.

hswfs.zernike.is_polar(expression: Expr) bool[source]

Check if a given expression is in polar coordinates, that is, if the names of its free symbols are a subset of {“rho”, “phi”}.

Parameters

expression – A sympy expression.

Returns

True if expression is in polar coordinates; else False.

hswfs.zernike.j_to_mn(j: int) Tuple[int, int][source]

Map the index \(j\) of the single-indexing scheme to the corresponding indices \(m, n\) from the double-indexing scheme.

Mathematically, the mapping is given by:

\[n = \left\lceil (-3 + \sqrt{9 + 8 j})\, /\, 2 \right\rceil \quad \text{and} \quad m = 2 j - n \cdot (n + 2)\]
Parameters

j – Index \(j\) of \(Z_j\).

Returns

The pair of indices \(m, n\) which correspond to \(j\).

hswfs.zernike.mn_to_j(m: int, n: int) int[source]

Map the indices \(m, n\) from the double-indexing scheme to the corresponding index \(j\) of the single-indexing scheme. Basically, we are just counting the Zernike polynomials in a well-defined fashion.

Mathematically, the mapping is given by:

\[j = \frac{n \cdot (n + 2) + m}{2}\]
Parameters
  • m – Index \(m\) of \(Z^m_n\).

  • n – Index \(m\) of \(Z^m_n\).

Returns

The single index \(j\) which corresponds to \(m, n\).

hswfs.zernike.polar_to_cartesian(expression: Expr) Expr[source]

Convert a sympy expression (sy.Expr) from polar coordinates to Cartesian coordinates by substituting \(\rho\) and \(\phi\) by the appropriate functions of \(x\) and \(y\).

Mathematically, the coordinate transformation is given by the following substitutions:

\[\rho = \sqrt{x^2 + y^2} \quad \text{and} \quad \phi = \arctan\left( \frac{y}{x} \right)\]
Parameters

expression – A sympy expression in polar coordinates, i.e., it must contain two free symbols named “rho” and “phi”.

Returns

The original expression, converted to Cartesian coordinates.