Skip to content

Commit

Permalink
Update documentation, brief notes on the v2.0.0 release
Browse files Browse the repository at this point in the history
So I've left both the original radial coefficient function and the
original aperture scaling algorithm in without exporting them. They
serve as comparisons and sanity checks and so it doesn't hurt to keep
them.

For scaling under low order aberrations, the ScaleAperture algorithm
based on Janssen & Dirksen's formula matches the TransformAperture
algorithm based on Lundström & Unsbo's paper in terms of accuracy and is
comparable in terms of speed, but for high orders and larger numbers of
aberrations the TransformAperture algorithm is not only much faster, but
also more accurate; this can be tested by generating a random set of
expansion coefficients along with a set of corresponding Zernike model
functions in order to compare.

I suspect that because the ScaleAperture algorithm has to evaluate the
radial polynomials it's susceptible to floating point errors, especially
since for high orders the aberrations are concentrated near the edges of
the pupil and so for scaling factors very close to 1 the errors end up
propagating such that the new expansion coefficients reflect a very
different wavefront, even in the region of the pupil which is unclipped.

The matrix formulation doesn't suffer from this, and since it uses the
radial coefficients directly (which are computed accurately) it's much
more robust. Its implementation isn't the prettiest (due to the
transform chaining optimization), but it gets the job done.
  • Loading branch information
Sagnac committed Jun 21, 2023
1 parent 4e6120d commit a3e171d
Show file tree
Hide file tree
Showing 3 changed files with 148 additions and 39 deletions.
62 changes: 44 additions & 18 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ This package can be added from the Julia REPL by:
using Pkg
Pkg.add(url="https://github.com/Sagnac/Zernike.jl")
```
or entering the package mode by pressing `]` and entering
or entering the package mode by pressing `]` and entering:
```
add https://github.com/Sagnac/Zernike.jl
```
Expand All @@ -20,7 +20,7 @@ The package provides 3 main functions for modelling Zernike polynomials and wave

* `W(ρ, θ, OPD, n_max)`: Fits wavefront errors up to radial order `n_max` given an input set of data over the pupil, returns the Zernike expansion coefficients & various metrics, and plots the modelled wavefront error using Makie;

* `S(ε, v)`: Aperture scaling function which takes a scaling factor and a vector of Zernike expansion coefficients and returns the new set of expansion coefficients over the smaller pupil; the clipped wavefront error is also plotted using Makie.
* `P(v, ε, δ, ϕ, ω)`: Aperture transform function which takes a vector of Zernike expansion coefficients and a set of transformation factors and returns a new set of expansion coefficients over the transformed pupil; the wavefront error over the new pupil is also plotted using Makie.

----

Expand All @@ -38,19 +38,19 @@ Returns three values contained within a Zernike.Output type, with fields:
2. `coeffs`: vector of radial polynomial coefficients;
3. `latex`: LaTeX string of the Zernike polynomial.

The coefficients belong to terms with exponent `n - 2(i - 1)` where `i` is the vector's index.
The coefficients belong to terms with exponent `n 2(i 1)` where `i` is the vector's index.

The radial polynomial coefficients are computed using a fast and accurate algorithm suitable for high orders; it is based on a recursive relation presented by [Honarvar & Paramesran (2013)](https://doi.org/10.1364/OL.38.002487).

----

## `W(ρ, θ, OPD, n_max)`

Estimates wavefront error by expressing optical aberrations as a linear combination of weighted Zernike polynomials using a linear least squares method. This representation as an expanded series is approximate, especially if the phase field is not sufficiently sampled.
Estimates wavefront error by expressing optical aberrations as a linear combination of weighted Zernike polynomials using a linear least squares method. The accuracy of this type of wavefront reconstruction represented as an expanded series depends upon a sufficiently sampled phase field and a suitable choice of the fitting order n_max.

`ρ`, `θ`, and `OPD` must be vectors of equal length; at each specific index the values are elements of an ordered triple over the exit pupil.

* `ρ`: normalized radial exit pupil variable `{0 ≤ ρ ≤ 1}`;
* `ρ`: normalized radial exit pupil position variable `{0 ≤ ρ ≤ 1}`;
* `θ`: angular exit pupil variable in radians `(mod 2π)`, defined positive counter-clockwise from the horizontal x-axis;
* `OPD`: measured optical path difference in waves;
* `n_max`: maximum radial degree to fit to.
Expand All @@ -63,41 +63,56 @@ The phase profile data can also be input as a 3 column matrix.
Returns four values contained within a WavefrontOutput type, with fields:

1. `a`: vector of named tuples containing the Zernike polynomial indices and the corresponding expansion coefficients rounded according to `precision`;
2. `v`: full vector of Zernike expansion coefficients;
3. `metrics`: 3-tuple with the peak-to-valley error, RMS wavefront error, and Strehl ratio;
2. `v`: full vector of Zernike wavefront error expansion coefficients;
3. `metrics`: named 3-tuple with the peak-to-valley error, RMS wavefront error, and Strehl ratio;
4. `fig`: the plotted Makie figure.

----

## `S(ε, v)`
## `P(v, ε, δ, ϕ, ω)`

Pupil scaling function which computes a new set of Zernike expansion coefficients under aperture down-scaling and plots the result.
Pupil transform function; computes a new set of Zernike wavefront error expansion coefficients under a given set of transformation factors and plots the result.

Available transformations are scaling, translation, & rotation for circular and elliptical exit pupils. These are essentially coordinate transformations in the pupil plane over the wavefront map.

* `ε::Float64`: scaling factor `{0 ≤ ε ≤ 1}`;
* `v::Vector{Float64}`: vector of full Zernike expansion coefficients ordered in accordance with the ANSI / OSA single index standard. This is the `v` vector returned by the wavefront error fitting function `W(ρ, θ, OPD, n_max)`.
* `ε::Float64`: scaling factor `{0 ≤ ε ≤ 1}`;
* `δ::ComplexF64`: translational complex coordinates (displacement of the pupil center in the complex plane);
* `ϕ::Float64`: rotation of the pupil in radians `(mod 2π)`, defined positive counter-clockwise from the horizontal x-axis;
* `ω::Tuple{Float64,Float64}`: elliptical pupil transform parameters; 2-tuple where `ω[1]` is the ratio of the minor radius to the major radius of the ellipse and `ω[2]` is the angle defined positive counter-clockwise from the horizontal coordinate axis of the exit pupil to the minor axis of the ellipse.

`ε` = `r₂/r₁` where `r₂` is the new radius, `r₁` the original
The order the transformations are applied is:<br>
scaling --> translation --> rotation --> elliptical transform.

The translation, rotation, and elliptical arguments are optional.

`ε` = `r₂/r₁` where `r₂` is the new smaller radius, `r₁` the original

In particular the radial variable corresponding to the rescaled exit pupil is normalized such that:<br>
`ρ` = `r/r₂`; `{0 ≤ ρ ≤ 1}`<br>
`r`: radial pupil position, `r₂`: max. radius<br>
`W₂(ρ₂)` = `W₁(ερ₂)`
`ΔW₂(ρ₂, θ)` = `ΔW₁(ερ₂, θ)`

For translation the shift must be within the bounds of the scaling applied such that:<br>
`0.0 ≤ ε + |δ| ≤ 1.0`.

The rescaled expansion coefficients are computed using a fast and accurate algorithm suitable for high orders; it is based on a formula presented by [Janssen & Dirksen (2007)](https://doi.org/10.2971/jeos.2007.07012).
For elliptical pupils (usually the result of measuring the wavefront off-axis), the major radius is defined such that it equals the radius of the circle and so `ω[1]` is the fraction of the circular pupil covered by the minor radius (this is approximated well by a cosine projection factor for angles up to 40 degrees); `ω[2]` is then the direction of the stretching applied under transformation in converting the ellipse to a circle before fitting the expansion coefficients.

The transformed expansion coefficients are computed using a fast and accurate algorithm suitable for high orders; it is based on a formulation presented by [Lundström & Unsbo (2007)](https://doi.org/10.1364/JOSAA.24.000569).

----

## Options

There are 2 options you can vary using keyword arguments. All 3 main functions support:

* `scale`: `{1 ≤ scale ≤ 100}`: multiplicative factor determining the size of the plotted matrix; the total number of elements is capped at 1 million.
* `scale`: `{1 ≤ scale ≤ 100}`: multiplicative factor determining the size of the plotted matrix; the total number of elements is capped at 1 million which should avoid aliasing up to ~317 radially and ~499 azimuthally.

Default: `100` (for `Z`, proportionally scaled according to the number of polynomials for the wavefront errors).

In creating the plot matrix the step size / length of the variable ranges is automatically chosen such that aliasing is avoided up to order ~317 radially and ~499 azimuthally. The `scale` parameter controls how fine the granularity is subsequently at the expense of performance.
In creating the plot matrix the step size / length of the variable ranges is automatically chosen such that aliasing is avoided for reasonable orders. The `scale` parameter controls how fine the granularity is subsequently at the expense of performance.

Additionally, the wavefront error functions `W(ρ, θ, OPD, n_max)` and `S(ε, v)` support:
Additionally, the wavefront error functions `W(ρ, θ, OPD, n_max)` and `P(v, ε, δ, ϕ, ω)` support:

* `precision`: number of digits to use after the decimal point in computing the expansion coefficients. Results will be rounded according to this precision and any polynomials with zero-valued coefficients will be ignored when pulling in the Zernike functions while constructing the composite wavefront error; this means lower precision values yield faster results.

Expand All @@ -114,7 +129,18 @@ Z40 = Z(0, 4, Model())
Z40(0.7, π/4)
```

For the wavefront errors this is equivalent to `ΔW(ρ, θ)` = `∑aᵢZᵢ(ρ, θ)` where `aᵢ` and `Zᵢ` were determined from the fitting process according to `precision`.
For wavefront reconstruction this is equivalent to `ΔW(ρ, θ)` = `∑aᵢZᵢ(ρ, θ)` where `aᵢ` and `Zᵢ` were determined from the fitting process according to `precision`.

## Single-Index Ordering Schemes

This package uses the the ANSI Z80.28-2004 standard ordering scheme where applicable, but provides several functions for converting from two other ordering methods, namely `Noll` and `Fringe`. The following functions are available:

* `noll_to_j(noll::Int)`: converts Noll indices to ANSI standard indices;
* `standardize!(noll::Vector)`: re-orders a Noll specified Zernike expansion coefficient vector according to the ANSI standard; this requires a full ordered vector up to n_max;
* `fringe_to_j(fringe::Int)`: converts Fringe indices to ANSI standard indices; only indices 1:37 are valid;
* `standardize(fringe::Vector)`: formats a Fringe specified Zernike expansion coefficient vector according to the ANSI standard.

The last function expects unnormalized coefficients; the input coefficients will be re-ordered and normalized in line with the orthonormal standard. As Fringe is a 37 polynomial subset of the full set of Zernike polynomials any coefficients in the standard order missing a counterpart in the input vector will be set to zero.

## Additional Notes

Expand All @@ -128,4 +154,4 @@ For the wavefront errors this is equivalent to `ΔW(ρ, θ)` = `∑aᵢZᵢ(ρ,
```
Zernike.Wf(ρ, θ, OPD, n_max)[1]
```
Similarly you can do this for the radial polynomial coefficients and the NA scaled wavefront error expansion coefficients by importing the functions `Φ` and `Π`, respectively.
Similarly you can do this for the radial polynomial coefficients and the NA transformed wavefront error expansion coefficients by importing the functions `Φ` and `S`, respectively.
Loading

0 comments on commit a3e171d

Please sign in to comment.