Quickstart
The basics of SVETlANNa in five minutes.
Imports
import torch
from svetlanna import SimulationParameters, Wavefront, LinearOpticalSetup
from svetlanna.elements import FreeSpace, ThinLens, RoundAperture
from svetlanna.units import uregSimulation parameters
Everything starts with SimulationParameters — the description of your coordinate grid:
params = SimulationParameters.from_ranges(
x_range=(-2*ureg.mm, 2*ureg.mm), x_points=512, # X: from -2 to 2 mm
y_range=(-2*ureg.mm, 2*ureg.mm), y_points=512, # Y: from -2 to 2 mm
wavelength=632.8*ureg.nm # HeNe laser
)ureg is the SVETlANNa unit registry. It provides mm, um, nm, cm, m and more.
Creating a wavefront
# Gaussian beam with a 0.5 mm waist radius
wf = Wavefront.gaussian_beam(params, waist_radius=0.5*ureg.mm)
print(f"Shape: {wf.shape}") # torch.Size([512, 512])
print(f"Dtype: {wf.dtype}") # torch.complex64
print(f"Max I: {wf.max_intensity}") # ~1.0Optical elements
# round aperture
aperture = RoundAperture(params, radius=1*ureg.mm)
# thin lens
lens = ThinLens(params, focal_length=100*ureg.mm)
# free space (zero-padded angular spectrum method)
propagate = FreeSpace(params, distance=100*ureg.mm, method='zpASM')method is required in FreeSpace. Choose from 'ASM', 'zpASM', 'RSC' and 'zpRSC'.
The zero-padded variants are slower but avoid wrap-around artefacts — prefer them unless
you have measured that you do not need them.
Propagating through the system
Optical elements are nn.Modules, so they are called like functions:
# option 1: element by element
wf = aperture(wf)
wf = lens(wf)
wf = propagate(wf)
# option 2: as a LinearOpticalSetup
setup = LinearOpticalSetup([
RoundAperture(params, radius=1*ureg.mm),
ThinLens(params, focal_length=100*ureg.mm),
FreeSpace(params, distance=100*ureg.mm, method='zpASM'),
])
wf_focus = setup(wf)Analysing the result
# intensity
intensity = wf.intensity # |E|²
# phase
phase = wf.phase # arg(E)
# full width at half maximum
fwhm_x, fwhm_y = wf.fwhm(params)
print(f"FWHM: {fwhm_x*1e6:.1f} × {fwhm_y*1e6:.1f} um")Visualisation
import matplotlib.pyplot as plt
fig, axes = plt.subplots(1, 2, figsize=(12, 5))
extent = [
params.x[0].item()*1e3, params.x[-1].item()*1e3,
params.y[0].item()*1e3, params.y[-1].item()*1e3
]
im0 = axes[0].imshow(intensity.cpu(), cmap='hot', extent=extent)
axes[0].set_title('Intensity')
axes[0].set_xlabel('x, mm')
axes[0].set_ylabel('y, mm')
plt.colorbar(im0, ax=axes[0])
im1 = axes[1].imshow(phase.cpu(), cmap='twilight', extent=extent)
axes[1].set_title('Phase')
axes[1].set_xlabel('x, mm')
plt.colorbar(im1, ax=axes[1])
plt.tight_layout()
plt.show()Full code
import torch
import matplotlib.pyplot as plt
from svetlanna import SimulationParameters, Wavefront, LinearOpticalSetup
from svetlanna.elements import FreeSpace, ThinLens, RoundAperture
from svetlanna.units import ureg
# 1. parameters
params = SimulationParameters.from_ranges(
x_range=(-2*ureg.mm, 2*ureg.mm), x_points=512,
y_range=(-2*ureg.mm, 2*ureg.mm), y_points=512,
wavelength=632.8*ureg.nm
)
# 2. wavefront
wf = Wavefront.gaussian_beam(params, waist_radius=0.5*ureg.mm)
# 3. optical system
setup = LinearOpticalSetup([
RoundAperture(params, radius=1*ureg.mm),
ThinLens(params, focal_length=100*ureg.mm),
FreeSpace(params, distance=100*ureg.mm, method='zpASM'),
])
# 4. focus
wf_focus = setup(wf)
# 5. result
print(f"FWHM: {wf_focus.fwhm(params)[0]*1e6:.1f} um")
print(f"Max I: {wf_focus.max_intensity:.2e}")What next?
- Core concepts — how the library is put together
- SimulationParameters — the grid in detail
- Tutorial: beam focusing — a full example with the theory