This is the multi-page printable view of this section. Click here to print.

Return to the regular view of this page.

Application examples

End-to-end examples from real experiments.

The repository contains complete experiment examples. They are intended to be read together with their project configuration, not as standalone snippets.

ExampleDemonstrates
MOT loading optimisationabsorption imaging, MOT sequence, parameter scans and live evaluation
Absorption imagingcamera handling, ROI analysis and optical-density calculation
Optical dipole traptrap loading, intensity ramps, calibration and lifetime measurement
Ion loading / state detectionion-trap control, detection thresholds and event processing
Quantum-state detectionrepeated readout, statistics and state assignment
Atom–ion interactioncombining cold-atom and ion-trap subsystems in one experiment
System calibrationreference measurements, fitting and calibration persistence

Each example project includes a README.md, configuration/ and experiments/. Start with the project launcher and run it in simulation mode before connecting hardware.

Structure of an example

  1. Physical goal — what is measured and why.
  2. Device setup — the device database entries and calibration files.
  3. Experiment class — parameters, sequence and analysis hooks.
  4. Data and analysis — expected HDF5 content and fitting.
  5. Operational notes — safety checks, common failures and tuning advice.

1 - Atom–ion collision experiment

Study the collision dynamics between cold atoms and a single ion with Quatm’s coordinated multi-system control.

Overview

This experiment provides the class secondinteraction: it integrates the lithium-atom MOT with ion loading, state preparation and shuttling into one atom–ion collision/interaction experiment. Each stage is encapsulated in its own method, which makes it easy to reuse and extend.

Stage methods

MethodDescription
load_ionsAblation loading + laser cooling of the ions
count_ionsFluorescence counting to determine whether an ion is in the trap
Ion_to_D_state / Ion_to_S_stateState preparation
load_MOT / MOT_offLoads / switches off the lithium MOT
ion_state_preparationIon state preparation before the interaction
runOrchestrates the loading–state preparation–collision–detection sequence

Parameters (build excerpt)

Loading_Time, Nr_Ablation_Pulses, Det_Time, Nr_Pictures, loadingtime_MOT, detection_time, RF_Voltage_Final and others.

Key code (excerpt)

from quatm.experiment import Experiment, delay, realtime

class secondinteraction(Experiment):
    def run(self):
        self.load_ions()        # ablation loading + laser cooling
        self.Ion_to_S_state()   # prepare in S1/2
        self.load_MOT()         # load the lithium MOT
        # interaction … then imaging/counting

2 - Dipole-trap optimisation helper

ODT alignment with the experiment helper tool: xODT alignment + stray-field compensation.

Overview

Before an optical dipole trap (xODT/cODT) experiment, the beam has to be aligned onto the atoms/ions with the dipole-trap optimisation helper. The experiment-helper main window odt_utils on the GUI side (quatm/GUI/entries/odt_utils.py) aggregates two kinds of alignment tool as tabs:

TabReal componentPurpose
xODT alignmentalignment/odt_utils.odtpiezo-mirror axis scan → Gaussian fit → publish, aligning the xODT/cODT onto the atom cloud
Stray-field compensationalignment/odt_utils.compensationfind the compensation voltage along each trap axis to minimise the stray field

Usage

from quatm.GUI.entries.odt_utils import odt_utils

helper = odt_utils()   # started as a separate process, with xODT alignment and stray-field compensation tabs

For the complete description see Experiment helper in the GUI components section; for the ODT experiment after alignment see Optical dipole trap.

3 - Electric-field offset compensation helper

Compensating the stray electric field of an ion trap: a GUI tool + a trap-axis voltage-scan script.

Overview

Ion-trap experiments are often affected by stray electric fields (ion-position offsets/micromotion). The electric-field offset compensation helper brings together voltage scanning, data plotting and the determination of the compensation voltage: on the GUI side it is provided by CompensationHelper in quatm/GUI/alignment/comp_helper.py; on the experiment side Usage Example/experiments/compensation.py (class compensation) applies shim voltages to the ion and triggers multi-frame images, scanning axes such as trap_x / trap_y.

GUI components (comp_helper)

ComponentDescription
CompensationCompensation main panel (one plot per trap axis + controls)
PlotWidget / TabWidgetPlot with one tab per trap axis
ControlWidget / SingleAxisWidgetScan controls per axis and “find the compensation voltage” (intersection of two fitted lines)
CompVoltageScanExecutes a voltage scan on the rf confinement

Usage

from quatm.GUI.alignment.comp_helper import CompensationHelper

comp = CompensationHelper(parent=parent)

For a fuller description see Experiment helper.

4 - Ion loading and cooling

A complete ion-loading routine from laser ablation to fluorescence detection, using Quatm’s multi-stage timing control.

Overview

This script provides the class loading_ion: it orchestrates the complete ion-loading routine from switching on the RF trap, producing ions by ablation and laser cooling through to fluorescence detection. The number of ablation pulses, the pulse width and the cooling/detection durations are all GUI parameters.

Parameters (build excerpt)

Nr_Ablation_Pulses, tune_pulse_number, pulse_duration, det_time, shutter_time, V_rf (trap voltage), ion_cool_power.

Timing

Switch on the RF trap (V_rf) → ablation pulses (several) → laser cooling
  → fluorescence detection (count to decide whether the ion loaded successfully)

Key code (excerpt)

from quatm.experiment import Experiment

class loading_ion(Experiment):
    def build(self):
        self.setattr_argument("Nr_Ablation_Pulses", NumberValue(...))
        self.setattr_argument("V_rf", NumberValue(...))
        # ... remainder omitted

ablation_pulse.py (single ablation), deterministic_loading.py and loading_deterministic.py (deterministic loading: retry on failure).

Companion

The cooling and fluorescence counting after ion loading can be combined with quantum-state detection for state-dependent measurements; the default parameters of the RF trap are in rf_trap.py.

5 - MOT loading optimisation

Automatically optimise the magneto-optical trap loading efficiency with Quatm’s parameter scans and multi-dimensional timing control.

Overview

This experiment script provides the class mot_settings: build() declares the full set of lithium MOT/CMOT devices and exposes the axial / radial magnetic-field currents and the MOT/CMOT detunings as GUI parameters, so that the magneto-optical trap loading can be optimised manually or by scanning. run() contains an empty timing sequence, on top of which imaging/counting can be added to assess the loading.

Devices (build excerpt)

DevicePurpose
li_cooling_aom / li_repump_aom / li_zeeman_aomcooling / repump / Zeeman light switches
li_cooling_power / li_repump_power / li_zeeman_powerpower of the individual beams
li_lock_mot / li_lock_cmotfrequency-lock references

Parameters (build excerpt)

MOT_Axial / _Radial, CMOT_Axial / _Radial (gradient/homogeneous-field currents), MOT_Current / CMOT_Current (trap currents), MOT_detuning / CMOT_detuning (detunings).

Key code (excerpt)

from quatm.experiment import Experiment, NumberValue

class mot_settings(Experiment):
    def build(self):
        self.setattr_device("li_cooling_power")
        self.setattr_argument("MOT_detuning", NumberValue(...))
        # ... remaining devices/parameters omitted

Loading optimisation

After changing the magnetic-field currents and the detuning, the loading efficiency can be judged from the atom number measured by fluorescence counting or absorption imaging (see Absorption imaging in the same directory).

6 - System calibration

Automated applications of Quatm in routine system calibration and maintenance.

Overview

Besides physics experiments, Quatm also codes routine calibration tasks as standard experiment scripts, giving one-click execution and automatic recording. This covers common calibration needs such as camera dark noise, shutter response, frequency synthesiser verification and trigger-delay calibration.

Code structure

All calibration experiments follow the same structural pattern:

  • subclass the Experiment class
  • declare the device under test and the calibration parameters in build()
  • execute the calibration procedure in run() and record the results automatically

Typical calibration tasks

Camera dark-noise characterisation

Function: acquire image frames continuously under dark conditions and characterise the dark-current noise distribution.

Main steps:

  1. Switch off all light sources and set the camera exposure time
  2. Acquire N dark frames in a loop
  3. Compute the mean and the standard deviation of each pixel
  4. Save the noise map to HDF5

Devices involved: camera

Shutter response time measurement

Function: measure the delay of a mechanical shutter from the TTL trigger to fully open/closed.

Main steps:

  1. Align a photodetector with the beam behind the shutter
  2. Trigger the shutter open with a TTL signal and start high-speed acquisition synchronously
  3. Record the rise/fall edge times of the detector signal
  4. Repeat the measurement and average

Devices involved: shutter (TTL), photodetector

Frequency synthesiser verification

Function: verify the actual output frequency and power of a Valon 5009 or DDS frequency synthesiser.

Main steps:

  1. Set the frequency synthesiser to the target frequency
  2. Measure the actual output with a spectrum analyser
  3. Scan the frequency range and record the deviation
  4. Generate a calibration curve

Devices involved: Valon 5009/DDS (serial port), spectrum analyser

Camera trigger delay calibration

Function: measure the delay between the TTL trigger and the actual exposure window of the camera.

Main steps:

  1. Share the same TTL signal between the pulsed light source and the camera trigger
  2. Scan the trigger-delay parameter
  3. Detect the position at which the light pulse appears in each frame
  4. Calibrate the optimal delay value

Devices involved: camera, pulsed light source (TTL)

7 - Absorption imaging

Automated acquisition and analysis of atom-cloud absorption images with Quatm’s camera control and image analysis.

Overview

This experiment script provides the class absorption_imaging: build() declares the cooling/imaging light and the camera trigger and exposes the MOT loading, the probe flash and the free-flight expansion time as parameters; run() orchestrates the imaging sequence and provides two detection modes, fluorescence_imaging and absorption_imaging.

Parameters (build excerpt)

Mot_loading, Flash_us (duration of the probe flash), expansiontime_ms (free-flight expansion), image_detuning (imaging detuning), MOT_detuning.

Devices (build excerpt)

li_cooling_aom / li_repump_aom / li_zeeman_aom (cooling/repump/Zeeman), li_absorption_h (horizontal absorption probe beam), li_imaging_valon + dds_0 (imaging frequency source), trigger_radba (trigger).

Key code (excerpt)

from quatm.experiment import Experiment, NumberValue, delay

class absorption_imaging(Experiment):
    def build(self):
        self.setattr_device("li_absorption_h")
        self.setattr_device("li_imaging_valon")
        self.setattr_argument("expansiontime_ms", NumberValue(...))
        # ... remainder omitted

    def absorption_imaging(self):
        # three frames with atoms / without atoms / background, computing the optical depth
        ...

Data analysis

The optical depth (column density) is computed and published by the analysis process ImageDivider, see Data and analysis/Absorption imaging.

8 - Atom–ion interaction in an optical dipole trap

Example experiment on the interaction of a neutral atom with a single ion in an optical dipole trap.

Overview

In this example we combine a lithium MOT / optical dipole trap (ODT) with the cooling, shuttling and state detection of a barium ion into one complete atom–ion interaction experiment. The experiment class interaction_optical_trapping subclasses Experiment, and the main sequence is assembled in stages by methods such as init_CMOT, absorption_imaging, expose_camera and run.

A typical sequence is roughly: load the MOT and pre-cool the ion and shuttle it “out of the way”, then load the atom cloud into the CMOT and the optical dipole trap, and after evaporation and spin polarisation move the ion back and let it interact with the atoms (loss spectroscopy or Feshbach resonance measurements are possible); finally perform optical thermometry, absorption imaging and detection of the ionic product state.

Main devices

CategoryDevice (excerpt)Purpose
Lithium MOT/CMOTli_cooling_aom / li_repump_aom / li_zeeman_aom, dds_0/1, li_mot_det_switchcooling/repump/Zeeman light and frequency, detuning switching
Magnetic fieldb_quadrupole, b_homogen, quadrupole_fet_off, homogen_fet_off, Feshbach coil relaysMOT gradient, homogeneous field, Feshbach/evaporation field
Ba lasers and statesaom_1(_ttl), aom_2(_ttl), the shutters, trigger_camion cooling, pumping, ion state detection
Optical dipole trapli_odt_* (xODT/cODT), laser poweroptical trap for atoms/ions
Imagingli_absorption_h, li_imaging_freq, trigger_absabsorption imaging and vertical trigger

Timing stages (summarised from the comments in run)

MOT loading → ion pre-cooling and shuttling (making room for the atom loading)
  → CMOT (optional high-gradient/power/detuning stage) → transfer into the ODT / two-colour trap
  → evaporative cooling (optional rf association) → spin polarisation
  → ion moved back into the atom cloud → interaction / loss / Feshbach measurement
  → trap-frequency measurement / time of flight (TOF) → ion optical thermometry → absorption imaging + ion state detection

Key code (excerpt)

from quatm.experiment import NumberValue, BoolValue, Experiment, delay, realtime

class interaction_optical_trapping(Experiment):
    def build(self):
        # devices for the lithium MOT/CMOT
        self.setattr_device("li_cooling_power")
        self.setattr_device("li_cooling_aom")
        self.setattr_device("b_quadrupole")
        self.setattr_device("b_homogen")
        # ... remaining devices omitted

    def run(self):
        # keep the ion inside the atom cloud during the interaction
        with realtime():
            self.li_cooling_aom = False
            delay(0.5)
            # ... timing omitted

Running

After placing the script in the corresponding directory under experiments/, open it in the experiment browser (Browser) to see the parameter panel generated by build; clicking run executes the whole sequence according to the timing in run. The script can also serve as a template for writing custom atom–ion interaction experiments (note the ion-shuttling ramps, the CMOT loading and the ODT transfer stages).

9 - Quantum-state manipulation and detection

Optical pumping and state-dependent fluorescence detection of ionic quantum states, using Quatm’s precise timing and statistical analysis.

Overview

This experiment script provides the class state_prep: it optically pumps the ion into the S1/2 or D3/2 state and can optionally apply one more cooling cycle at the end. State-dependent detection then distinguishes the bright/dark states by fluorescence counting.

Parameters

on_s_off_d (pump to S1/2 (650 off) or to D3/2 (493 off)), cooling_end (whether to add one cooling step before the end).

State-preparation logic

  • S1/2: switch off the 650 light first → the ion falls into S1/2;
  • D3/2: switch off the 493 light first → the ion is pumped into D3/2.

The same logic also appears in Ion_to_S_state / Ion_to_D_state of secondinteraction, where count_ions fluorescence counting performs the state-dependent detection (bright = S1/2, dark = D3/2, etc.).

Key code (excerpt)

from quatm.experiment import Experiment, BoolValue

class state_prep(Experiment):
    def build(self):
        self.setattr_argument("on_s_off_d", BoolValue(value=False))
        self.setattr_argument("cooling_end", BoolValue(value=True))
        # ... remainder omitted

optical_dark_pumping.py (dark pumping, pumping_time_us), d_shelving.py (D-state related measurements).

10 - Optical dipole trap experiment

Study the trapping and loss characteristics of cold atoms in an ODT with Quatm’s two-parameter scans and lifetime measurements.

Overview

This experiment script provides the class optical_trapping: build() declares the lithium MOT/CMOT and the imaging devices and exposes the key timing parameters for loading / trapping / imaging as GUI parameters; run() orchestrates the complete optical dipole trap (ODT) experiment sequence through methods such as init_CMOT, fluorescence_imaging and absorption_imaging.

Timing stages

MOT loading (Mot_loading) → CMOT (init_CMOT: gradient/detuning/power switching)
  → ODT trapping (trapping_time_ms) → release → time of flight (time_of_flight)
  → absorption imaging / fluorescence imaging

Parameters (build excerpt)

Mot_loading, Flash_us, trapping_time_ms, resonance_shift, image_detuning, detuning_ramp_slope_MHz_ms, time_of_flight, MOT_detuning / CMOT_detuning, MOT_Current_Loading / CMOT_Current and the Homogenous_Current_* series, etc.

Key code (excerpt)

from quatm.experiment import Experiment, NumberValue, delay

class optical_trapping(Experiment):
    def build(self):
        self.setattr_device("li_cooling_aom")
        self.setattr_device("li_absorption_h")
        self.setattr_argument("trapping_time_ms", NumberValue(...))
        # ... remainder omitted

    def init_CMOT(self):
        # CMOT stage: gradient, detuning and power switching
        ...

Companion

The xODT/cODT beam path can be aligned with the dipole-trap optimisation helper; for imaging data analysis see Absorption imaging and Absorption imaging in the data and analysis section.

11 - Optically trapped ion

Purely optical trapping of an ion in an optical dipole trap, with state detection.

Overview

This example uses the experiment class OpticalTrappingIon to demonstrate purely optical trapping of a single ion in an optical dipole trap. The radio-frequency trap (rf) can optionally be switched off in order to measure the performance of the pure optical trap, and optical trapping can also be performed in an adjustable magnetic field; together with ion laser cooling, spin preparation and product-state detection, the ion can also be moved into and out of the trap via the axial electrodes.

Main devices

CategoryDevice (excerpt)Purpose
Ba lasersba_493_aom(_ttl), ba_493_vert_aom, ba_650_aom(_ttl), ba_493_res_shut, ba_493_det_shut, ba_615_shutcooling, pumping (S1/2↔P1/2, D3/2, etc.), shutters
Optical dipole trapodt_power / odt_aom / odt_shutpower and on/off of the optical trapping beam
RF traprf, rf_offradio-frequency Paul trap confinement (can be switched off for a pure optical trap)
Axial movementtrap_ax, trap_ax_pc, trap_ax_wall, trap_ax_offsaxial shuttling of the ion
Magnetic fieldb_homogen, shimquantisation field for pre-cooling/trapping
Detectiontrigger_camtrigger for radial ion fluorescence/state detection

Parameters (excerpt of setattr_argument in build)

trapping_time, odtpower, rf_init and rf_ramp_duration, opt_ramp_duration, repumpers_on, pump_d32, ba_spin_prep, b_field_precooling(_applied) / b_field_opt_trap(_applied), shuttle_ion / shift_voltage, shutter_time, detect_ba_product_state and others.

Timing stages

Initialisation
  → ion spin preparation
  → magnetic-field switching (optional high-field probing)
  → (optional) shuttle the ion out and back
  → linear ramp-up of the optical trapping beam power → switch off the RF confinement (pure optical trapping)
  → switch off the optical trap (release) and the magnetic field
  → product-state/fluorescence detection

Key code (excerpt)

from quatm.experiment import *   # Experiment, NumberValue, BoolValue, delay, realtime ...

class OpticalTrappingIon(Experiment):
    def build(self):
        self.setattr_device("ba_493_aom")
        self.setattr_device("odt_power")
        self.setattr_device("rf")
        self.setattr_argument("trapping_time", NumberValue(ndecimals=0, step=10,
                             value=100, unit="µs"))
        # ... remaining parameters omitted

    def run(self):
        with realtime():
            # ramp up the optical trapping beam and switch off the RF confinement for pure optical trapping
            self.odt_power = self.odtpower
            self.rf_trap_off = True
            # ... timing omitted

Running

Once the script is placed in experiments, opening it in the experiment browser (Browser) generates the parameter panel; adjusting odtpower and trapping_time scans the power and duration of the optical trapping, while detect_ba_product_state reads out the ionic product state.