Absorption imaging analysis for cold atom experiments. Camera-agnostic, multi-species, pip-installable.
- OD calculation: probe/reference/dark → optical depth image
- 2D Gaussian fit: atom number, cloud center, cloud size
- Time-of-flight: temperature from expansion series (sigma² vs t²)
- 15+ species presets: Sr, Rb, Cs, Yb, Ca, Dy, Li, Na, K, Er (cross-sections auto-calculated)
- Folder watcher: auto-process images as they appear
- GUI: PyQt5 interface with OD display + fit overlay + marginal projections
- CLI: single-shot analysis, ToF series, folder watching
- Export: CSV and HDF5
pip install -e ".[all]"Minimal (CLI only, no GUI):
pip install -e .coldatom-imaging analyze probe.tiff reference.tiff dark.tiff --species Sr -m 2.0coldatom-imaging tof ./tof_images/ --tof-times 1,2,5,10,15,20 --species Rbcoldatom-imaging watch ./data/ --species Sr --pattern "*.tiff" -o results.csvcoldatom-imaging guicoldatom-imaging list-speciesfrom coldatom_imaging import process_shot, load_image_set, ImagingConfig, CameraConfig
config = ImagingConfig(
species="Sr",
camera=CameraConfig(pixel_size_um=6.45, magnification=2.0),
)
probe, ref, dark = load_image_set("probe.tiff", "ref.tiff", "dark.tiff")
result = process_shot(probe, ref, dark, config)
print(f"Atom number: {result.fit.atom_number:.2e}")
print(f"Cloud size: {result.fit.sigma_x_um:.1f} x {result.fit.sigma_y_um:.1f} um")
print(f"Temperature: run ToF series for this")from coldatom_imaging import measure_temperature, get_species, ToFPoint
points = [
ToFPoint(tof_ms=1, sigma_x_um=50, sigma_y_um=48, atom_number=1e6),
ToFPoint(tof_ms=5, sigma_x_um=120, sigma_y_um=115, atom_number=9e5),
ToFPoint(tof_ms=10, sigma_x_um=210, sigma_y_um=200, atom_number=8e5),
ToFPoint(tof_ms=15, sigma_x_um=300, sigma_y_um=290, atom_number=7e5),
ToFPoint(tof_ms=20, sigma_x_um=400, sigma_y_um=385, atom_number=6e5),
]
result = measure_temperature(points, get_species("Sr"))
print(f"Temperature: {result.temperature_avg_uK:.1f} uK")from coldatom_imaging import Species
# Just need: name, symbol, transition wavelength, mass, linewidth
my_atom = Species("Francium-223", "Fr", 718.0, 223.0, 5.0)
print(f"Cross-section: {my_atom.sigma0:.4e} m^2")| Parameter | Description | Default |
|---|---|---|
species |
Atom species (preset name or custom Species) | "Sr" |
pixel_size_um |
Camera sensor pixel size | 6.45 |
magnification |
Imaging system magnification | 1.0 |
od_clamp |
Maximum OD value (prevents log artifacts) | 4.0 |
roi |
Region of interest (x0, y0, x1, y1) |
None (full image) |
- Optical depth:
OD(x,y) = -ln((I_probe - I_dark) / (I_ref - I_dark)) - Gaussian fit:
A * exp(-((x-x0)²/2σx² + (y-y0)²/2σy²)) + C - Atom number:
N = 2π·A·σx·σy·(pixel_area) / σ₀whereσ₀ = 3λ²/2π - Temperature:
σ(t)² = σ₀² + (kB·T/m)·t²(linear fit of σ² vs t²)
MIT