GaussMLE.jl

Fast Maximum Likelihood Estimation of Gaussian PSF parameters for single-molecule localization microscopy. Automatic GPU acceleration with CPU fallback.

Installation

using Pkg
Pkg.add("GaussMLE")

Quick Start

using GaussMLE

# 1. Define camera (provides pixel size for unit conversion)
camera = IdealCamera(0:511, 0:511, 0.1)  # 512×512 sensor, 100nm pixels

# 2. Create ROIBatch (typically from SMLMBoxer.jl, here using test generator)
batch = generate_roi_batch(
    camera,
    GaussianXYNB(0.13f0),  # PSF σ = 130nm
    n_rois = 100,
    roi_size = 11
)

# 3. Create fitter and fit
fitter = GaussMLEConfig(psf_model = GaussianXYNB(0.13f0))
smld, info = fit(batch, fitter)

# 4. Results in microns (camera pixel_size used for conversion)
for e in smld.emitters[1:3]
    println("Position: ($(e.x), $(e.y)) μm ± ($(e.σ_x*1000), $(e.σ_y*1000)) nm")
end
Re-exports from SMLMData

GaussMLE re-exports ROIBatch, IdealCamera, SCMOSCamera, and @filter from SMLMData.jl.

Overview

GaussMLE.jl provides a modern, minimal API for fitting Gaussian PSF models to single-molecule localization microscopy data. The package supports multiple PSF models, camera noise models, and automatic GPU acceleration.

Key Features

  • Multiple PSF Models: 2D Gaussian (fixed/variable sigma), 3D astigmatic
  • Physical Units: All PSF parameters in microns (camera-independent)
  • Automatic GPU Acceleration: CUDA support with automatic CPU fallback
  • Camera Models: Ideal (Poisson) and sCMOS (pixel-dependent noise)
  • CRLB Uncertainties: Cramer-Rao lower bound for each parameter
  • SMLMData Integration: Returns BasicSMLD with ecosystem-compatible emitter types

Unit Convention

All user-facing parameters use physical units (microns):

  • PSF widths: specified in microns (e.g., GaussianXYNB(0.13) for 130nm PSF)
  • Output positions: microns
  • Output uncertainties: microns
  • Internally converted to pixels for computation based on camera pixel size

Supported PSF Models

ModelParametersUse Case
GaussianXYNB(sigma)x, y, N, bgFixed PSF width (fastest)
GaussianXYNBS()x, y, N, bg, sigmaVariable PSF width
GaussianXYNBSXSY()x, y, N, bg, sigmax, sigmayAnisotropic PSF
AstigmaticXYZNB{T}(...)x, y, z, N, bg3D astigmatic imaging

Typical SMLM Pipeline

In a real workflow, ROIs come from a boxer that detects candidates in raw movie frames:

Raw Movie → SMLMBoxer.jl → ROIBatch → GaussMLE.fit() → BasicSMLD → Analysis

Examples

Variable PSF Width

using GaussMLE
using Statistics

# Fit PSF width per localization
fitter = GaussMLEConfig(psf_model = GaussianXYNBS())
smld, info = fit(data, fitter)

# Access fitted sigma from Emitter2DFitSigma type
sigmas = [e.σ for e in smld.emitters]
println("Mean sigma: $(mean(sigmas)) microns")

GPU Acceleration

using GaussMLE

# Auto-detect backend (default: GPU if available, CPU fallback)
fitter = GaussMLEConfig(backend = :auto, batch_size = 5000)
smld, info = fit(large_dataset, fitter)
println("Ran on $(info.backend)")  # :cpu or :gpu

sCMOS Camera

The sCMOS noise model follows Huang et al. (2013):

using GaussMLE

# Create sCMOS camera with calibration
camera = SCMOSCamera(
    512, 512, 0.065,    # nx, ny, pixel_size (μm)
    readnoise_map;      # Per-pixel readnoise σ (electrons)
    offset = 100.0f0,   # Dark level (ADU)
    gain = 0.5f0,       # Conversion (e⁻/ADU)
    qe = 0.82f0         # Quantum efficiency
)

# Generate or load ROI data with camera
batch = generate_roi_batch(camera, GaussianXYNB(0.13f0), n_rois = 1000)

# Fit - automatically uses variance map from camera
fitter = GaussMLEConfig(psf_model = GaussianXYNB(0.13f0))
smld, info = fit(batch, fitter)

3D Astigmatic Localization

using GaussMLE

# Astigmatic PSF calibration (all spatial params in microns)
psf_3d = AstigmaticXYZNB{Float32}(
    0.13f0, 0.13f0,  # sigma_x0, sigma_y0
    0.05f0, 0.05f0,  # Ax, Ay
    0.3f0, 0.3f0,    # Bx, By
    0.05f0,          # gamma
    0.4f0            # d
)

fitter = GaussMLEConfig(psf_model = psf_3d)
smld, info = fit(data, fitter)

# Z positions from Emitter3DFitGaussMLE type
z_positions = [e.z for e in smld.emitters]
z_precision = [e.σ_z for e in smld.emitters]

Output Format

BasicSMLD with Emitter Types

fit() returns a tuple of (SMLMData.BasicSMLD, GaussMLEFitInfo) containing a vector of emitter structs and fit metadata:

smld, info = fit(data, fitter)

# Access emitters
for e in smld.emitters
    println("x=$(e.x), y=$(e.y), photons=$(e.photons), σ_x=$(e.σ_x)")
end

Emitter type depends on PSF model:

PSF ModelEmitter TypeFitted Parameters
GaussianXYNBEmitter2DFitGaussMLEx, y, photons, bg
GaussianXYNBSEmitter2DFitSigma+ σ (PSF width)
GaussianXYNBSXSYEmitter2DFitSigmaXY+ σx, σy (PSF widths)
AstigmaticXYZNBEmitter3DFitGaussMLEx, y, z, photons, bg

Emitter2DFitGaussMLE Fields

The base 2D emitter type (Emitter2DFitGaussMLE) contains:

FieldDescriptionUnits
x, yFitted positionmicrons
photonsTotal photon countphotons
bgBackground levelphotons/pixel
σ_x, σ_yPosition uncertainty (CRLB)microns
σ_xyPosition covariance (off-diagonal of Fisher matrix inverse)microns²
σ_photons, σ_bgPhotometry uncertaintiesphotons
pvalueGoodness-of-fit p-value (χ² test)0-1
frameFrame numberinteger
dataset, track_id, idMetadata fieldsinteger

Filtering with SMLMData

Use the @filter macro from SMLMData for quality control:

using GaussMLE

smld, info = fit(data, fitter)

# Filter by precision and photon count
good = @filter(smld, σ_x < 0.020 && photons > 500)

# Filter by multiple criteria
precise = @filter(smld, σ_x < 0.015 && σ_y < 0.015 && bg < 50)

println("Kept $(length(good.emitters)) / $(length(smld.emitters)) localizations")

Mathematical Foundation

The Gaussian expectation model for pixel (i,j) is:

\[\mu_{i,j}(\theta) = \theta_{bg} + \theta_N \int_{i-0.5}^{i+0.5} \int_{j-0.5}^{j+0.5} \frac{1}{2\pi \sigma_x \sigma_y} \exp\left(-\frac{(x-\theta_x)^2}{2\sigma_x^2} - \frac{(y-\theta_y)^2}{2\sigma_y^2}\right) dx \, dy\]

The fitting uses Newton-Raphson optimization with:

  • Diagonal Hessian: For fast parameter updates
  • Full Fisher Information: For accurate CRLB uncertainties

References

This package implements algorithms from:

MLE Algorithm:

Smith, C.S., Joseph, N., Rieger, B., & Lidke, K.A. (2010). Fast, single-molecule localization that achieves theoretically minimum uncertainty. Nature Methods, 7(5), 373-375. DOI: 10.1038/nmeth.1449

sCMOS Camera Model:

Huang, F., Hartwich, T.M.P., Rivera-Molina, F.E., et al. (2013). Video-rate nanoscopy using sCMOS camera-specific single-molecule localization algorithms. Nature Methods, 10(7), 653-658. DOI: 10.1038/nmeth.2488