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 ofz
s (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=true
skip 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.71681f0
WaveOpticsPropagation.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.2409596f0
References
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 ofz
s (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.0
pad(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.0
WaveOpticsPropagation.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 4
WaveOpticsPropagation.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==false
then a lower dimensionalarr_small
will not be broadcasted
along the higher dimensions.
- If
broadcast==true
it 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