Fixed Optics#
Beam Corset supports working around existing optics, both in setup characterization and during mode matching.
Characterization with Fixed Optics#
When characterizing an existing setup, it may not always be possible or desirable to remove all refractive optics to take beam profile measurements. For these situations, Beam Corset also allows beam characterization with existing optics in place. Instead of using Beam.fit(), we use OpticalSetup.fit() which works similarly but also takes in a list of tuples of lens positions and optical elements.
[1]:
from corset import Beam, OpticalSetup, ThinLens, Units
import numpy as np
import matplotlib.pyplot as plt
np.random.seed(42)
# generate reference setup
lens = ThinLens(200e-3)
ref_beam = Beam.from_gauss(focus=0.1, waist=300e-6, wavelength=1064e-9)
ref_setup = OpticalSetup(ref_beam, [(0.2, lens)])
# generate noisy measurements
meas_positions = np.linspace(0.0, 0.4, 10)
meas_radii = ref_setup.radius(meas_positions) + np.random.normal(0, 10e-6, size=len(meas_positions))
fit_setup = OpticalSetup.fit(meas_positions, meas_radii, ref_beam.wavelength, [(0.2, lens)])
fit_beam = fit_setup.initial_beam
print(f"Reference beam: focus = {Units.mm.format(ref_beam.focus)}, waist = {Units.um.format(ref_beam.waist)}")
print(f"Fitted beam: focus = {Units.mm.format(fit_beam.focus, dev=fit_beam.focus_dev * 1.96)}",
f"waist = {Units.um.format(fit_beam.waist, dev=fit_beam.waist_dev * 1.96)}")
fit_setup
Reference beam: focus = 100 mm, waist = 300 μm
Fitted beam: focus = (92 ± 17) mm waist = (304 ± 7) μm
[1]:
One problem with this approach is that it relies on knowing the exact position of the existing lenses. If the assumed lens position deviates from the true lens position, the fitted beam parameters will likely be off as well, leading to inaccurate mode matching results down the line.
To prevent this, we can include the lens position as a free parameter in the fit. To do this, we replace the lens position with a tuple of the estimated position and a maximum deviation from that position. Note that since we are now fitting an additional parameter, we will need to provide more measurements to achieve the same level statistical confidence.
[2]:
fit_setup_lens = OpticalSetup.fit(meas_positions, meas_radii, ref_beam.wavelength, [((0.2, 0.01), lens)])
fit_beam_lens = fit_setup_lens.initial_beam
print(f"Reference beam: focus = {Units.mm.format(ref_beam.focus)}, waist = {Units.um.format(ref_beam.waist)}")
print(f"Fitted beam: focus = {Units.mm.format(fit_beam_lens.focus, dev=fit_beam_lens.focus_dev * 1.96)},",
f"waist = {Units.um.format(fit_beam_lens.waist, dev=fit_beam_lens.waist_dev * 1.96)}")
print(f"Fitted lens position = {Units.mm.format(fit_setup_lens.elements[0][0])}")
Reference beam: focus = 100 mm, waist = 300 μm
Fitted beam: focus = (93 ± 29) mm, waist = (304 ± 8) μm
Fitted lens position = 201 mm
We can see that the uncertainty increases when fitting with the lens, because the same amount of measurement information now needs to constrain an additional parameter and we can effectively do less averaging.
Mode Matching with Fixed Optics#
We can also account for fixed optics during mode matching. This may, for example, be needed when a cavity’s in-coupler has curved surfaces. We do this like we would with a normal mode matching, except that we pass an optical setup to the mode_match() call instead in place the initial beam. The fixed optics do not participate in the optimization, but are still respected when propagating the beam through the setup. Since they are assumed to be immovable, they are also excluded from the analysis.
[3]:
from corset import ShiftingRange, mode_match
initial_beam = Beam.from_gauss(focus=0.0, waist=500e-6, wavelength=1064e-9)
initial_setup = OpticalSetup(initial_beam, [(0.95, ThinLens(100e-3))])
desired_beam = Beam.from_gauss(focus=1.0, waist=50e-6, wavelength=initial_beam.wavelength)
solutions = mode_match(
initial_setup, # pass an optical setup that includes the fixed optic(s)
desired_beam,
[ShiftingRange(0.0, 0.8)],
[ThinLens(f) for f in [100e-3, 150e-3]],
max_elements=2,
)
solutions[2]
[3]:
Element Summary
| element | shape | focal_length | position | clearance_left | clearance_right | dof | sensitivity | grad_focus | grad_waist | sensitivities | couplings | shifting_range | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | f=150mm | | | 150 mm | 296 mm | 296 mm | 454 mm | 0 | 1.56 %/cm² | 0.260 mm/mm | 0.073 μm/mm | [ 1.56, -0.08] %/cm² | [100. , -14.2] % | ShiftingRange(left=0.0, right=0.8, min_element... |
| 1 | f=150mm | | | 150 mm | 750 mm | 454 mm | 50 mm | 1 | 0.22 %/cm² | -0.006 mm/mm | -0.333 μm/mm | [-0.08, 0.22] %/cm² | [-14.2, 100. ] % | ShiftingRange(left=0.0, right=0.8, min_element... |
| 2 | f=100mm | | | 100 mm | 950 mm | None | None | None |
The fixed optics does not get its own \(L_n\) degree of freedom and is simply displayed as is.