Skip to content

Commit

Permalink
Update documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
Sagnac committed Jul 3, 2023
1 parent 9729b25 commit 03da7db
Show file tree
Hide file tree
Showing 2 changed files with 76 additions and 39 deletions.
41 changes: 28 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,19 +48,31 @@ The radial polynomial coefficients are computed using a fast and accurate algori

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.
`ρ`, `θ`, and `OPD` must be floating-point vectors of equal length; at each specific index the values are elements of an ordered triple over the exit pupil.

* `ρ`: 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.

You can input normalized Cartesian coordinates using the 3-positional argument method:<br>
`W(x, y, OPD; n_max, options...)`.
Note that specifying `n_max` will fit using the full range of Zernike polynomials from `j = 0` to `j_max` corresponding to the last polynomial with degree `n_max`. If instead you only want to fit to a subset of Zernike polynomials you can specify a vector of `(m, n)` tuples in place of `n_max` using the method:
```
W(ρ, θ, OPD, orders::Vector{Tuple{Int, Int}})
```

If your phase data is in the form of a floating-point matrix instead you can call the method:
```
W(OPD, fit_to; options...)
```

This assumes the wavefront error was uniformly measured using polar coordinates; the matrix is expected to be a polar grid of regularly spaced periodic samples with the first element referring to the value at the origin. The first axis of the matrix (the rows) must correspond to the angular variable `θ` while the second axis (the columns) must correspond to the radial variable `ρ`.

The phase profile data can also be input as a 3 column matrix.
`fit_to` can be either `n_max::Int` or `orders::Vector{Tuple{Int, Int}}`.

Returns four values contained within a WavefrontOutput type, with fields:
It is also possible to input normalized Cartesian coordinates using the method with 3 positional arguments and passing `fit_to` as a keyword argument:<br>
`W(x, y, OPD; fit_to, options...)`.

The function 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 wavefront error expansion coefficients;
Expand Down Expand Up @@ -106,11 +118,11 @@ The transformed expansion coefficients are computed using a fast and accurate al

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 which should avoid aliasing up to ~317 radially and ~499 azimuthally.
* `finesse::Int`: `{1 ≤ finesse ≤ 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 for reasonable orders. 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 `finesse` parameter controls how fine the granularity is subsequently at the expense of performance.

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

Expand All @@ -122,29 +134,32 @@ If you want full 64-bit floating-point precision use `precision = "full"`.

## Model functions

There exists a special method dispatch which avoids plotting and instead returns the `(ρ, θ)` functions as essentially closures. This is done by calling the 3 main functions with the `Model` constructor as the last positional argument. The pupil can then be evaluated using these functions with polar coordinates:
There exists a special method dispatch which avoids plotting and instead returns the `(ρ, θ)` functions as essentially closures. This is done by calling the 3 main functions with the `Model` type as the last positional argument. The pupil can then be evaluated using these functions with polar coordinates:

```
Z40 = Z(0, 4, Model())
Z40 = Z(0, 4, Model)
Z40(0.7, π/4)
```

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:
This package uses the ANSI Z80.28-2004 standard sequential ordering scheme where applicable, but provides several functions for converting from two other ordering methods, namely `Noll` and `Fringe`. The following methods 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.
* `standardize(fringe::Vector)`: formats a Fringe specified Zernike expansion coefficient vector according to the ANSI standard;
* `standardize(v_sub::Vector, orders::Vector{Tuple{Int, Int}})`: pads a subset Zernike expansion coefficient vector to the full standard length up to `n_max` (`1:j_max+1`).

The `standardize` fringe method 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.

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.
For the `standardize` subset method the tuples in `orders` must be of the form `(m, n)` associated with the respective coefficients at each index in `v_sub`.

## Additional Notes

* The output types for the 3 main functions can also be accessed by indexing them and regular destructuring in addition to property destructuring and getting the fields directly.
* The values contained within the output types can also be accessed through numerical indexing and regular destructuring in addition to property destructuring and getting the fields directly.

* The Zernike polynomials are currently only valid up to degree ~812 at which point the maximum coefficient approaches the maximum for double-precision floating-point numbers (~1e308).

Expand Down
74 changes: 48 additions & 26 deletions src/Docstrings.jl
Original file line number Diff line number Diff line change
Expand Up @@ -24,37 +24,34 @@ See also [`W`](@ref), [`P`](@ref).
# Positional argument options:
Z(m, n, Model())
Z(m, n, ::Type{Model})
Return the Zernike polynomial function `Z(ρ, θ)` corresponding to indices `m` and `n`.
# Keyword argument options:
Z(m, n; scale::Int = 100)
Z(m, n; [finesse::Int = 100])
`scale`: `{1 ≤ scale ≤ 100}`: multiplicative factor determining the size of the plotted matrix; the total number of elements is capped at 1 million.
`finesse`: `{1 ≤ finesse ≤ 100}`: multiplicative factor determining the size of the plotted matrix; the total number of elements is capped at 1 million.
"""
Z

"""
W(ρ, θ, OPD, n_max)
W(data::Matrix, n_max; options...)
Fit wavefront errors up to order n_max.
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.
# Main arguments
`ρ`, `θ`, and `OPD` must be vectors of equal length; at each specific index the values are elements of an ordered triple over the exit pupil.
`ρ`, `θ`, and `OPD` must be floating-point vectors of equal length; at each specific index the values are elements of an ordered triple over the exit pupil.
* `ρ`: 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.
The phase profile data can also be input as a 3 column matrix.
# Return values
Returns four values contained within a WavefrontOutput type, with fields:
Expand All @@ -70,32 +67,48 @@ See also [`Z`](@ref), [`P`](@ref).
----
W(x, y, OPD; n_max, options...)
W(ρ, θ, OPD, orders::Vector{Tuple{Int, Int}})
Fit wavefront errors to specific Zernike polynomials specified in `orders` containing Zernike `(m, n)` tuples.
----
W(OPD, fit_to; options...)
Fitting method accepting a floating-point matrix of phase data uniformly produced in a polar coordinate system over the pupil.
The matrix is expected to be a polar grid of regularly spaced periodic samples with the first element referring to the value at the origin. The first axis of the matrix (the rows) must correspond to the angular variable `θ` while the second axis (the columns) must correspond to the radial variable `ρ`.
`fit_to` can be either `n_max::Int` or `orders::Vector{Tuple{Int, Int}}`.
----
W(x, y, OPD; fit_to, options...)
Method accepting normalized Cartesian coordinate data.
Fitting method accepting normalized Cartesian coordinate data.
----
# Positional argument options:
W(ρ, θ, OPD, n_max, Model())
W(ρ, θ, OPD, n_max, ::Type{Model})
Return the wavefront error function `ΔW(ρ, θ)` corresponding to an `n_max` fit.
# Keyword argument options:
W(ρ, θ, OPD, n_max; precision = 3, scale)
W(ρ, θ, OPD, n_max; [precision = 3], [finesse::Int])
* `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.
\u2063\u2063\u2063\u2063 If you want full 64-bit floating-point precision use `precision = "full"`.
* `scale`: `{1 ≤ scale ≤ 100}`: multiplicative factor determining the size of the plotted matrix; the total number of elements is capped at 1 million.
* `finesse`: `{1 ≤ finesse ≤ 100}`: multiplicative factor determining the size of the plotted matrix; the total number of elements is capped at 1 million.
"""
W

"""
P(v::Vector{T}, ε::T, δ::Complex{T}, ϕ::T, ω::Tuple{T,T}) where T <: Float64
P(v::Vector{T}, ε::T, [δ::Complex{T}], [ϕ::T], [ω::Tuple{T,T}]) where T <: Float64
Compute a new set of Zernike wavefront error expansion coefficients under a given set of transformation factors and plot the result.
Expand All @@ -112,27 +125,25 @@ Available transformations are scaling, translation, & rotation for circular and
The order the transformations are applied is:\\
scaling --> translation --> rotation --> elliptical transform.
The translation, rotation, and elliptical arguments are optional.
See also [`Z`](@ref), [`W`](@ref).
----
# Positional argument options:
P(v, ε, δ, ϕ, ω, Model())
P(v, ε, [δ], [ϕ], [ω], ::Type{Model})
Return the wavefront error function `ΔW(ρ, θ)` corresponding to the input transform parameters.
# Keyword argument options:
P(v, ε, δ, ϕ, ω; precision = 3, scale::Int)
P(v, ε, [δ], [ϕ], [ω]; [precision = 3], [finesse::Int])
* `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.
\u2063\u2063\u2063\u2063 If you want full 64-bit floating-point precision use `precision = "full"`.
* `scale`: `{1 ≤ scale ≤ 100}`: multiplicative factor determining the size of the plotted matrix; the total number of elements is capped at 1 million.
* `finesse`: `{1 ≤ finesse ≤ 100}`: multiplicative factor determining the size of the plotted matrix; the total number of elements is capped at 1 million.
# Extended help
Expand All @@ -159,10 +170,10 @@ Callable type: function `Z(ρ, θ)` bound to a given set of Zernike indices `m`
Fields:
1. `inds`: named tuple containing the Zernike polynomial indices;
2. `N`: normalization factor;
3. `R`: RadialPolynomial callable type: function `R(ρ)`;
4. `M`: Sinusoid callable type: function `M(θ)`.
* `inds`: named tuple containing the Zernike polynomial indices;
* `N`: normalization factor;
* `R`: RadialPolynomial callable type: function `R(ρ)`;
* `M`: Sinusoid callable type: function `M(θ)`.
See also [`Zernike.WavefrontError`](@ref).
"""
Expand All @@ -177,10 +188,13 @@ Specifically, `ΔW(ρ, θ)` = `∑aᵢZᵢ(ρ, θ)`
Fields:
1. `i`: vector of named tuples containing the Zernike polynomial indices and the corresponding expansion coefficients;
2. `n_max`: maximum radial degree fit to;
3. `a`: vector of the Zernike expansion coefficients used in the fit;
4. `Z`: the respective Zernike polynomial functions.
* `i`: vector of named tuples containing the Zernike polynomial indices and the corresponding expansion coefficients;
* `n_max`: maximum radial degree fit to;
* `fit_to`: vector of `(m, n)` tuples specifying the polynomials used for the fit;
* `a`: vector of the Zernike expansion coefficients;
* `Z`: the respective Zernike polynomial functions.
The `fit_to` field is an empty vector if the default full range up to `n_max` (`0:j_max`) was used with no `orders` specified. Note that these orders could differ from the polynomials determined after the fit; they are simply what was passed to the fitting function and may refer to polynomials not present in the reconstruction if after filtering the corresponding coefficients are zero.
See also [`Zernike.Polynomial`](@ref).
"""
Expand Down Expand Up @@ -225,5 +239,13 @@ Format a Fringe specified Zernike expansion coefficient vector according to the
This 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.
See also [`standardize!`](@ref), [`fringe_to_j`](@ref), [`noll_to_j`](@ref).
----
standardize(v_sub::Vector, orders::Vector{Tuple{Int, Int}})
Pad a subset Zernike expansion coefficient vector to the full standard length up to `n_max` (`1:j_max+1`).
The tuples in `orders` must be of the form `(m, n)` associated with the respective coefficients at each index in `v_sub`.
"""
standardize

0 comments on commit 03da7db

Please sign in to comment.