Static SMLM Simulation Overview
Static SMLM simulation creates fixed molecular patterns with realistic blinking kinetics and localization uncertainty. This approach is ideal for simulating structured biological samples like protein complexes, filaments, and other cellular structures.
Simulation Workflow
Static simulations follow this general workflow:
- Pattern definition: Define molecular arrangements (e.g., oligomers, lines)
- Pattern distribution: Distribute patterns throughout the field of view
- Photophysics: Apply stochastic blinking behavior to each molecule
- Localization uncertainty: Add realistic position errors based on photon counts
Simulation Parameters
Static simulations are configured using the StaticSMLMConfig type:
# Default parameters
params = StaticSMLMConfig()
# Custom parameters
params = StaticSMLMConfig(
density=2.0, # 2 patterns per μm²
σ_psf=0.15, # 150nm PSF width
minphotons=100, # Minimum photons for detection
ndatasets=5, # Number of independent datasets
nframes=2000, # Frames per dataset
framerate=100.0, # Frames per second
ndims=3, # 3D simulation
zrange=[-2.0, 2.0] # 4μm axial range
)Key Parameters
density: Number of patterns per square micronσ_psf: Point spread function width in microns (impacts localization precision)minphotons: Minimum photons required for detectionnframes: Number of frames in the simulationframerate: Frame rate in frames per secondndims: Dimensionality (2 or 3)zrange: Axial range for 3D simulations
Running a Simulation
The high-level simulate() function provides a simple interface for static simulations:
# Define a camera
camera = IdealCamera(128, 128, 0.1) # 128×128 pixels, 100nm pixels
# Run simulation with parameters
smld_noisy, info = simulate(
params,
pattern=Nmer2D(n=6, d=0.2), # hexamer with 200nm diameter
molecule=GenericFluor(1e4, [-10.0 10.0; 0.5 -0.5]), # fluorophore model
camera=camera
)Alternatively, you can use keyword arguments directly:
smld_noisy, info = simulate(
density=1.0, # patterns per μm²
σ_psf=0.13, # PSF width in μm
nframes=1000, # frames
framerate=50.0, # frames per second
pattern=Nmer2D(n=8, d=0.1), # pattern type
molecule=GenericFluor(1e4, [-10.0 10.0; 0.5 -0.5]), # γ=1e4, k_off=10, k_on=0.5
camera=camera
)Understanding Simulation Results
The simulate() function returns a tuple (smld_noisy, info::SimInfo):
smld_noisy: Positions with blinking and localization uncertainty- Position noise based on photon statistics
- Realistic blinking behavior based on kinetic model
- Most comparable to real experimental data
info: ASimInfostruct containing additional simulation data:info.smld_true: Ground truth emitter positions (exact coordinates, no blinking or noise)info.smld_model: Positions with blinking kinetics (no position uncertainty)info.elapsed_s: Simulation elapsed time in seconds
Each SMLD object contains emitters with properties like position, frame number, photon count, and uncertainties.
Working with Results
You can extract information from the simulation results for analysis or visualization:
# Extract coordinates from noisy emitters
x_noisy = [e.x for e in smld_noisy.emitters]
y_noisy = [e.y for e in smld_noisy.emitters]
photons = [e.photons for e in smld_noisy.emitters]
frames = [e.frame for e in smld_noisy.emitters]
# Group emitters by original position using track_id
emitters_by_position = Dict()
for e in smld_noisy.emitters
if !haskey(emitters_by_position, e.track_id)
emitters_by_position[e.track_id] = []
end
push!(emitters_by_position[e.track_id], e)
end2D vs 3D Simulations
The dimensionality of the simulation is controlled by both the ndims parameter and the pattern type:
# 2D simulation
params = StaticSMLMConfig(ndims=2)
pattern2d = Nmer2D(n=6, d=0.2)
smld_noisy_2d, info_2d = simulate(params, pattern=pattern2d)
# 3D simulation
params = StaticSMLMConfig(ndims=3, zrange=[-2.0, 2.0])
pattern3d = Nmer3D(n=6, d=0.2)
smld_noisy_3d, info_3d = simulate(params, pattern=pattern3d)For 3D simulations, the localization uncertainty is automatically scaled in the axial dimension to reflect the typically lower z-resolution in SMLM experiments.