Configuration
The primary interface follows the JuliaSMLM tuple pattern:
(smld_corrected, info) = driftcorrect(smld, config)where config is a DriftConfig and info is a DriftInfo.
Input: DriftConfig
SMLMDriftCorrection.DriftConfig — Type
DriftConfig <: AbstractSMLMConfigConfiguration for drift correction, holding all algorithm parameters. Constructed with keyword arguments; all fields have sensible defaults.
Fields
| Field | Default | Description |
|---|---|---|
quality | :singlepass | Quality tier: :fft, :singlepass, or :iterative |
degree | 2 | Legendre polynomial degree for intra-dataset drift |
dataset_mode | :registered | Multi-dataset handling: :registered or :continuous |
chunk_frames | 0 | Split datasets into chunks of N frames (0 = no chunking) |
n_chunks | 0 | Alternative: number of chunks per dataset (0 = use chunk_frames) |
maxn | 200 | Maximum neighbors for entropy calculation |
max_iterations | 10 | Maximum iterations for :iterative mode |
convergence_tol | 0.001 | Convergence tolerance in μm for :iterative mode |
warm_start | nothing | Previous info.model for warm starting optimization |
verbose | 0 | Verbosity level: 0=quiet, 1=info, 2=debug |
auto_roi | false | Use dense ROI subset for faster estimation |
σ_loc | 0.010 | Typical localization precision (μm) for ROI sizing |
σ_target | 0.001 | Target drift precision (μm) for ROI sizing |
roi_safety_factor | 4.0 | Safety multiplier for required localizations |
Example
julia> config = DriftConfig(quality=:iterative, degree=3);
julia> config.quality
:iterative
julia> config.degree
3
julia> config.convergence_tol
0.001Quality Tiers
The quality parameter selects the algorithm complexity:
:fft– Fast cross-correlation of histogram images. No intra-dataset correction. Best for quick previews or very large datasets.:singlepass(default) – One pass of entropy-based intra-dataset correction followed by inter-dataset alignment. Good balance of speed and accuracy.:iterative– Iterates intra and inter correction until convergence. Most accurate; resolves the coupling between intra and inter drift estimates.
Dataset Modes
The dataset_mode parameter controls how multiple datasets are related:
:registered(default) – Datasets are independent acquisitions of the same field of view (e.g., SeqSRM). Inter-dataset alignment finds the best constant shift for each dataset against the others.:continuous– One long acquisition split into multiple files or chunks. Polynomials are warm-started from the previous chunk's endpoint, and inter-shifts are regularized to maintain continuity.
Chunking (Continuous Mode)
For long continuous acquisitions, a single polynomial may not capture complex drift. Use chunk_frames or n_chunks to split each dataset into temporal segments, each modeled independently:
# Split into ~4000-frame chunks
config = DriftConfig(dataset_mode=:continuous, chunk_frames=4000)
# Or specify number of chunks
config = DriftConfig(dataset_mode=:continuous, n_chunks=3)Each chunk gets its own polynomial. Warm-starting from the previous chunk's endpoint ensures smooth transitions.
Auto-ROI
When auto_roi=true, the algorithm selects a dense rectangular subregion of the field of view for drift estimation, then applies the fitted model to all localizations. This can significantly speed up processing for large datasets while trading some accuracy (~1.4 nm vs ~0.5 nm RMSD in testing).
The ROI size is determined by σ_loc, σ_target, and roi_safety_factor:
config = DriftConfig(auto_roi=true, σ_loc=0.010, σ_target=0.001)The estimated ROI indices are stored in info.roi_indices.
Warm Starting
Pass a previously fitted model to initialize optimization:
# From a previous correction
(smld1, info1) = driftcorrect(smld1, DriftConfig(degree=2))
# Use as starting point for new data
config2 = DriftConfig(warm_start=info1.model)
(smld2, info2) = driftcorrect(smld2, config2)Output: DriftInfo
SMLMDriftCorrection.DriftInfo — Type
DriftInfo <: AbstractSMLMInfoMetadata from drift correction, returned as second element of tuple. Supports warm start via info.model.
Fields
model::LegendrePolynomial: Fitted drift model (intra + inter)elapsed_s::Float64: Wall time in secondsbackend::Symbol: Computation backend (:cpu)iterations::Int: Number of iterations completed (0 for :fft, 1 for :singlepass, N for :iterative)converged::Bool: Whether convergence criterion was met (always true for :fft/:singlepass)entropy::Float64: Final entropy value after correctionhistory::Vector{Float64}: Entropy per iteration (empty for :fft)roi_indices::Union{Nothing, Vector{Int}}: Indices used for ROI subsampling (nothing if not used)
Usage
(smld_corrected, info) = driftcorrect(smld)
info.converged # check convergence
info.entropy # final value
info.elapsed_s # timing
plot(info.history) # diagnostics
info.roi_indices # ROI used for estimation (nothing if auto_roi=false)
# Warm start from previous result
(smld2, info2) = driftcorrect(smld2; warm_start=info.model)Accessing Results
(smld_corrected, info) = driftcorrect(smld, DriftConfig())
# Diagnostics
info.converged # true if convergence criterion met
info.entropy # final entropy value
info.elapsed_s # wall time in seconds
info.iterations # iterations completed (0 for :fft, 1 for :singlepass)
info.history # entropy per iteration (for plotting convergence)
info.roi_indices # indices used for ROI subset (nothing if auto_roi=false)Drift Trajectory
Extract the fitted drift model for plotting:
traj = drift_trajectory(info.model)
# traj.frames, traj.x, traj.y (and traj.z for 3D)
# For continuous mode, chain datasets end-to-end
traj = drift_trajectory(info.model; cumulative=true)Continuation
Pass DriftInfo directly to continue iterating from a previous result:
(smld1, info1) = driftcorrect(smld, DriftConfig(quality=:singlepass))
# Continue with more iterations
(smld2, info2) = driftcorrect(smld, info1; max_iterations=5)