Efficient Propagations
They create efficient functions which avoid recalculating some parts.
WaveOpticsPropagation.AngularSpectrum — FunctionAngularSpectrum(field, z, λ, L; kwargs...)Returns a function for efficient reuse of pre-calculated kernels. This function returns the electrical field with physical length L and wavelength λ propagated with the angular spectrum method of plane waves (AS) by the propagation distance z.
This method is efficient but to avoid recalculating some arrays (such as the phase kernel), see AngularSpectrum.
Arguments
field: Input fieldz: propagation distance. Can be a single number or a vector ofzs (OrCuVector). In this case the returning array has one dimension more.λ: wavelength of fieldL: field size (can be a scalar or a tuple) indicating field size
Keyword Arguments
padding=true: applies padding to avoid convolution wraparoundbandlimit=true: applies the bandlimit to avoid circular wraparound due to undersampling of the complex propagation kernel [1]bandlimit_border=(0.8, 1): applies a smooth bandlimit cut-off instead of hard-edge.
See angular_spectrum for the full documentation.
Example
julia> field = zeros(ComplexF32, (4,4)); field[3,3] = 1
1
julia> as = AngularSpectrum(field, 100e-9, 632e-9, 10e-6);
julia> as(field);WaveOpticsPropagation.Fraunhofer — FunctionFraunhofer(U, z, λ, L; skip_final_phase=true)This returns a function for efficient reuse of pre-calculated kernels. This function then returns the electrical field with physical length L and wavelength λ propagated with the Fraunhofer propagation (a single FFT) by the propagation distance z. This is based on a far field approximation.
Arguments
U: Input fieldz: propagation distanceλ: wavelength of fieldL: field size indicating field size
Keyword Arguments
skip_final_phase=trueskip the final phase which is multiplied to the propagated field at the end
See fraunhofer for the full documentation.
Example
julia> field = zeros(ComplexF32, (256,256)); field[130,130] = 1;
julia> field = zeros(ComplexF32, (256,256)); field[130,130] = 1;
julia> f = Fraunhofer(field, 4f-3, 632f-9, 100f-6);
julia> res = f(field);
julia> f.params.Lp[1] / 100f-6
64.71681f0
julia> 4f-3 * 632f-9 * 256 / (100f-6)^2
64.71681f0WaveOpticsPropagation.ScalableAngularSpectrum — FunctionScalableAngularSpectrum(field, z, λ, L; kwargs...)Returns the electrical field with physical length L and wavelength λ propagated with the scalable angular spectrum method of plane waves (SAS) by the propagation distance z.
Arguments
field: Input fieldz: propagation distanceλ: wavelength of fieldL: field size (can be a scalar or a tuple) indicating field size
Keyword Arguments
skip_final_phase=true: avoid multiplying with final phase. This phase is also undersampled.
Example
julia> field = zeros(ComplexF32, (256,256)); field[130,130] = 1;
julia> f = ScalableAngularSpectrum(field, 10f-3, 633f-9, 500f-6);
julia> f.params.Lp
0.00162048f0
julia> f.params.Lp / 500f-6 # calculate magnification
3.24096f0
julia> 10f-3 * 633f-9 * 256 / 500f-6^2 / 2 # equation from paper
3.2409596f0References
WaveOpticsPropagation.ShiftedAngularSpectrum — TypeShiftedAngularSpectrum(field, z, λ, L, α; kwargs...)Returns a method to propagate the electrical field with physical length L and wavelength λ with the shifted angular spectrum method of plane waves (AS) by the propagation distance z. α should be a tuple containing the offset angles with respect to the optical axis.
Arguments
field: Input fieldz: propagation distance. Can be a single number or a vector ofzs (OrCuVector). In this case the returning array has one dimension more.λ: wavelength of fieldL: field size (can be a scalar or a tuple) indicating field sizeαis the tuple of shift angles with respect to the optical axis.
Keyword Arguments
pad_factor=2: padding of 2. Larger numbers are not recommended since they don't provide better results.bandlimit=true: applies the bandlimit to avoid circular wraparound due to undersampling of the complex propagation kernel [1]extract_ramp=true: divides the field by phase rampexp.(1im * 2π / λ * (sin(α[2]) .* x .+ sin(α[1]) .* y))and multiplies after propagation the ramp (with new real space coordinates) back to the field
Examples
julia> field = zeros(ComplexF32, (4,4)); field[3,3] = 1
1
julia> shifted_AS = ShiftedAngularSpectrum(field, 100e-6, 633e-9, 100e-6, (deg2rad(10), 0));
julia> shifted_AS(field);References
- Matsushima, Kyoji. "Shifted angular spectrum method for off-axis numerical propagation." Optics Express 18.17 (2010): 18453-18463.
(shifted_as::ShiftedAngularSpectrum)(field)Uses the struct to efficiently store some pre-calculated objects. Propagate the field.
Propagation
Those were merely for testing purposes.
Utilities
WaveOpticsPropagation.pad — Functionpad(arr::AbstractArray{T, N}, new_size; value=zero(T))Pads arr with values around such that the resulting array size is new_size.
See also crop_center, set_center!.
julia> pad(ones((2,2)), 2)
4×4 Matrix{Float64}:
0.0 0.0 0.0 0.0
0.0 1.0 1.0 0.0
0.0 1.0 1.0 0.0
0.0 0.0 0.0 0.0pad(arr::AbstractArray{T, N}, M; value=zero(T))Pads arr with values around such that the resulting array size is round(Int, M .* size(arr)). If M isa Integer, no rounding is needed.
If M isa AbstractFloat, automatic differentation might fail because of size failures
See also crop_center, set_center!.
julia> pad(ones((2,2)), 2)
4×4 Matrix{Float64}:
0.0 0.0 0.0 0.0
0.0 1.0 1.0 0.0
0.0 1.0 1.0 0.0
0.0 0.0 0.0 0.0WaveOpticsPropagation.crop_center — Functioncrop_center(arr, new_size)Extracts a center of an array. new_size_array must be list of sizes indicating the output size of each dimension. Centered means that a center frequency stays at the center position. Works for even and uneven. If length(new_size_array) < length(ndims(arr)) the remaining dimensions are untouched and copied.
See also pad, set_center!.
Examples
julia> crop_center([1 2; 3 4], (1,))
1×2 Matrix{Int64}:
3 4
julia> crop_center([1 2; 3 4], (1,1))
1×1 Matrix{Int64}:
4
julia> crop_center([1 2; 3 4], (2,2))
2×2 Matrix{Int64}:
1 2
3 4WaveOpticsPropagation.set_center! — Functionset_center!(arr_large, arr_small; broadcast=false)Puts the arr_small central into arr_large.
The convention, where the center is, is the same as the definition as for FFT based centered.
Function works both for even and uneven arrays. See also crop_center, pad, set_center!.
Keyword
- If
broadcast==falsethen a lower dimensionalarr_smallwill not be broadcasted along the higher dimensions. - If
broadcast==trueit will be broadcasted along higher dims.
See also crop_center, pad.
Examples
julia> set_center!([1, 1, 1, 1, 1, 1], [5, 5, 5])
6-element Vector{Int64}:
1
1
5
5
5
1
julia> set_center!([1, 1, 1, 1, 1, 1], [5, 5, 5, 5])
6-element Vector{Int64}:
1
5
5
5
5
1
julia> set_center!(ones((3,3)), [5])
3×3 Matrix{Float64}:
1.0 1.0 1.0
1.0 5.0 1.0
1.0 1.0 1.0
julia> set_center!(ones((3,3)), [5], broadcast=true)
3×3 Matrix{Float64}:
1.0 1.0 1.0
5.0 5.0 5.0
1.0 1.0 1.0