odak.learn.wave.propagate_beam¶
Definitions for Fresnel impulse respone (IR), Fresnel Transfer Function (TF), Fraunhofer diffraction in accordence with "Computational Fourier Optics" by David Vuelz.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
field |
torch.complex |
Complex field (MxN). |
required |
k |
odak.wave.wavenumber |
Wave number of a wave, see odak.wave.wavenumber for more. |
required |
distance |
float |
Propagation distance. |
required |
dx |
float |
Size of one single pixel in the field grid (in meters). |
required |
wavelength |
float |
Wavelength of the electric field. |
required |
propagation_type |
str |
Type of the propagation (IR Fresnel, TR Fresnel, Fraunhofer). |
'IR Fresnel' |
kernel |
torch.complex |
Custom complex kernel. |
None |
Returns:
Type | Description |
---|---|
torch.complex128 |
Final complex field (MxN). |
Source code in odak/learn/wave/classical.py
def propagate_beam(field, k, distance, dx, wavelength, propagation_type='IR Fresnel', kernel=None, zero_padding=False):
"""
Definitions for Fresnel impulse respone (IR), Fresnel Transfer Function (TF), Fraunhofer diffraction in accordence with "Computational Fourier Optics" by David Vuelz.
Parameters
----------
field : torch.complex
Complex field (MxN).
k : odak.wave.wavenumber
Wave number of a wave, see odak.wave.wavenumber for more.
distance : float
Propagation distance.
dx : float
Size of one single pixel in the field grid (in meters).
wavelength : float
Wavelength of the electric field.
propagation_type : str
Type of the propagation (IR Fresnel, TR Fresnel, Fraunhofer).
kernel : torch.complex
Custom complex kernel.
Returns
-------
result : torch.complex128
Final complex field (MxN).
"""
if propagation_type == 'IR Fresnel':
result = impulse_response_fresnel(field, k, distance, dx, wavelength)
elif propagation_type == 'Angular Spectrum':
result = angular_spectrum(field, k, distance, dx, wavelength)
elif propagation_type == 'Bandlimited Angular Spectrum':
result = band_limited_angular_spectrum(field, k, distance, dx, wavelength)
elif propagation_type == 'TR Fresnel':
result = transfer_function_fresnel(field, k, distance, dx, wavelength, zero_padding)
elif propagation_type == 'custom':
result = custom(field, kernel, zero_padding)
elif propagation_type == 'Fraunhofer':
nv, nu = field.shape[-1], field.shape[-2]
x = torch.linspace(-nv*dx/2, nv*dx/2, nv, dtype=torch.float32)
y = torch.linspace(-nu*dx/2, nu*dx/2, nu, dtype=torch.float32)
Y, X = torch.meshgrid(y, x, indexing='ij')
Z = torch.pow(X, 2) + torch.pow(Y, 2)
c = 1./(1j*wavelength*distance)*torch.exp(1j*k*0.5/distance*Z)
c = c.to(field.device)
result = c * \
torch.fft.ifftshift(torch.fft.fft2(
torch.fft.fftshift(field)))*pow(dx, 2)
else:
assert True == False, "Propagation type not recognized."
return result
Notes¶
We provide a sample usage of this function as below.
from odak.learn.wave import propagate_beam,generate_complex_field,wavenumber
from odak.learn.tools import zero_pad
import torch
wavelength = 0.5*pow(10,-6)
pixeltom = 6*pow(10,-6)
distance = 0.2
propagation_type = 'TR Fresnel'
k = wavenumber(wavelength)
sample_phase = torch.rand((500,500))
sample_amplitude = torch.zeros((500,500))
sample_amplitude[
240:260,
240:260
] = 1000
sample_field = generate_complex_field(sample_amplitude,sample_phase)
sample_field = zero_pad(sample_field)
reconstruction = propagate_beam(
sample_field,
k,
distance,
pixeltom,
wavelength,
propagation_type
)