API Reference
This page provides a comprehensive reference for the types and functions in SMLMSim.
SMLMSim.SMLMSim
— ModuleSMLMSim
Main module for the SMLMSim.jl package.
API Overview
For a comprehensive overview of the API, use the help mode on api_overview
:
?api_overview
Or access the complete API documentation programmatically:
docs = SMLMSim.api_overview()
This package provides tools for simulating Single Molecule Localization Microscopy (SMLM) data. It includes modules for:
- Core: Fundamental types (molecules, patterns) and photophysics simulation (CTMC, blinking).
- StaticSMLM: Simulating static emitters with blinking and localization noise.
- InteractionDiffusion: Simulating diffusing and interacting emitters (e.g., dimerization) using Smoluchowski dynamics.
- CameraImages: Generating simulated camera images from emitter data, including noise models.
The main SMLMSim
module re-exports key types and functions from these submodules to provide a unified user interface.
Usage
using SMLMSim
# Example: Static simulation
params_static = StaticSMLMParams(density=1.0, σ_psf=0.13)
_, _, smld_noisy = simulate(params_static)
# Example: Diffusion simulation
params_diff = DiffusionSMLMParams(density=0.5, diff_monomer=0.1)
smld_diff = simulate(params_diff)
# Example: Generate images
psf = GaussianPSF(0.15)
images = gen_images(smld_noisy, psf)
SMLMSim.api_overview
— MethodSMLMSim.jl API Overview
SMLMSim is a Julia package for simulating Single Molecule Localization Microscopy (SMLM) data with realistic physical properties. It provides tools for generating static SMLM simulations, diffusion-interaction simulations, and microscope image generation.
Key Concepts
Physical Units
All simulations use consistent physical units:
- Spatial dimensions: microns (μm)
- Time: seconds (s)
- Diffusion coefficients: μm²/s
- Rate constants: s⁻¹
Core Components
- Patterns: Spatial arrangements of molecules (e.g., oligomers, lines)
- Molecules: Photophysical models of fluorophores with state transitions
- Simulation: Parameters and functions for different simulation types
- Noise: Realistic localization uncertainty based on photon statistics
- Camera Images: Generation of microscope images from simulation data
Type Hierarchy
AbstractSim
: Base type for all simulation typesSMLMSimParams
: Base type for simulation parametersStaticSMLMParams
: Parameters for static SMLM simulationDiffusionSMLMParams
: Parameters for diffusion simulation
Pattern
: Base type for all molecular patternsPattern2D
: Base type for 2D patternsNmer2D
: N molecules arranged in a circleLine2D
: Molecules arranged along a line
Pattern3D
: Base type for 3D patternsNmer3D
: N molecules arranged in a circle in 3DLine3D
: Molecules arranged along a 3D line
Molecule
: Base type for all photophysical modelsGenericFluor
: General fluorophore with kinetic state model
AbstractDiffusingEmitter
: Base type for diffusing emittersDiffusingEmitter2D
: 2D emitter with diffusion stateDiffusingEmitter3D
: 3D emitter with diffusion state
Essential Types
StaticSMLMParams
Parameters for static SMLM simulation with fixed molecular patterns.
Base.@kwdef mutable struct StaticSMLMParams <: SMLMSimParams
density::Float64 = 1.0 # density in particles per square micron
σ_psf::Float64 = 0.13 # PSF width in microns
minphotons::Int = 50 # minimum photons for detection
ndatasets::Int = 10 # number of datasets to simulate
nframes::Int = 1000 # number of frames per dataset
framerate::Float64 = 50.0 # frames per second
ndims::Int = 2 # dimensionality (2 or 3)
zrange::Vector{Float64} = [-1.0, 1.0] # axial range for 3D simulations [min_z, max_z]
end
DiffusionSMLMParams
Parameters for diffusion-based SMLM simulation using Smoluchowski dynamics.
Base.@kwdef mutable struct DiffusionSMLMParams <: SMLMSimParams
density::Float64 = 1.0 # number density (molecules/μm²)
box_size::Float64 = 10.0 # simulation box size (μm)
diff_monomer::Float64 = 0.1 # monomer diffusion coefficient (μm²/s)
diff_dimer::Float64 = 0.05 # dimer diffusion coefficient (μm²/s)
diff_dimer_rot::Float64 = 0.5 # dimer rotational diffusion coefficient (rad²/s)
k_off::Float64 = 0.2 # dimer dissociation rate (s⁻¹)
r_react::Float64 = 0.01 # reaction radius (μm)
d_dimer::Float64 = 0.05 # monomer separation in dimer (μm)
dt::Float64 = 0.01 # time step (s)
t_max::Float64 = 10.0 # total simulation time (s)
ndims::Int = 2 # number of dimensions (2 or 3)
boundary::String = "periodic" # boundary condition type ("periodic" or "reflecting")
camera_framerate::Float64 = 10.0 # camera frames per second (Hz)
camera_exposure::Float64 = 0.1 # camera exposure time per frame (s)
end
Molecular Patterns
Nmer2D
N molecules symmetrically organized around a circle with diameter d.
mutable struct Nmer2D <: Pattern2D
n::Int # Number of molecules in the pattern
d::Float64 # Diameter of the circle in microns
x::Vector{Float64} # X positions of molecules in microns
y::Vector{Float64} # Y positions of molecules in microns
end
Line2D
Points with uniform random distribution between two endpoints.
mutable struct Line2D <: Pattern2D
n::Int # Number of molecules in the pattern
x::Vector{Float64} # X positions of molecules in microns
y::Vector{Float64} # Y positions of molecules in microns
λ::Float64 # Linear molecule density (molecules per micron)
endpoints::Vector{Tuple{Float64,Float64}} # Vector of endpoint coordinates
end
Fluorophore Models
GenericFluor
Defines a fluorophore with photophysical properties.
struct GenericFluor <: Molecule
γ::AbstractFloat # Photon emission rate in Hz
q::Array{<:AbstractFloat} # Rate matrix for state transitions
end
Constructor Examples
Creating Simulation Parameters
# Static SMLM with default parameters
params_static = StaticSMLMParams()
# Custom parameters for static simulation
params_static = StaticSMLMParams(
density = 2.0, # 2 patterns per μm²
σ_psf = 0.15, # 150nm PSF width
nframes = 2000, # 2000 frames
framerate = 20.0 # 20 fps
)
# Diffusion simulation with default parameters
params_diff = DiffusionSMLMParams()
# Custom parameters for diffusion simulation
params_diff = DiffusionSMLMParams(
density = 0.5, # molecules per μm²
box_size = 15.0, # 15μm box size
diff_monomer = 0.2, # 0.2 μm²/s diffusion coefficient
k_off = 0.1, # 0.1 s⁻¹ dissociation rate
t_max = 20.0 # 20s simulation time
)
Creating Patterns
# Create an 8-molecule pattern with 100nm diameter (default)
nmer = Nmer2D()
# Create a custom pattern with 6 molecules and 200nm diameter
hexamer = Nmer2D(n=6, d=0.2) # d is in microns
# Create a 3D pattern
octamer3d = Nmer3D(n=8, d=0.15)
# Create a line pattern
line = Line2D(λ=5.0, endpoints=[(-2.0, 0.0), (2.0, 0.0)]) # 5 molecules/μm
# Create a 3D line pattern
line3d = Line3D(λ=8.0, endpoints=[(-1.0, 0.0, -0.5), (1.0, 0.0, 0.5)])
Creating Fluorophore Models
# Create a fluorophore with default parameters
fluor = GenericFluor()
# Create a fluorophore with custom parameters
# γ=10,000 photons/s, k_off=10 Hz, k_on=0.1 Hz
fluor = GenericFluor(1e4, [-10.0 10.0; 0.1 -0.1])
# Create a fluorophore using the 2-state keyword constructor
fluor = GenericFluor(photons=1e4, k_off=5.0, k_on=0.5)
Creating a Camera
# Create a camera with 100nm pixels (128x128 pixels)
camera = IdealCamera(128, 128, 0.1) # 128×128 pixels, 100nm pixels
# Specify field of view with an array of pixel edges
pixel_edges_x = 0.0:0.1:12.8 # 0 to 12.8μm in 0.1μm steps
pixel_edges_y = 0.0:0.1:12.8
camera = IdealCamera(pixel_edges_x, pixel_edges_y)
Core Functions
Simulation
simulate
The main simulation function with multiple methods for different simulation types.
# Static SMLM simulation
# First create simulation parameters
params = StaticSMLMParams()
# Then run simulation
smld_true, smld_model, smld_noisy = simulate(
params;
pattern=Nmer2D(),
molecule=GenericFluor(),
camera=IdealCamera(128, 128, 0.1)
)
# Diffusion simulation
# First create simulation parameters
params_diff = DiffusionSMLMParams()
# Then run simulation
smld = simulate(
params_diff;
photons=1000.0
)
kinetic_model
Generate kinetic blinking model from existing localization data.
# Example of how to call kinetic_model
# First create or obtain the required inputs
smld_true = ... # Some BasicSMLD with true positions
fluor = GenericFluor(1e4, [-10.0 10.0; 0.5 -0.5]) # Fluorophore model
nframes = 1000 # Number of frames
framerate = 50.0 # Frames per second
# Call the function
smld_model = kinetic_model(
smld_true, # BasicSMLD with emitter positions
fluor, # Molecule with kinetic rates
nframes, # Number of frames
framerate; # Frames per second
ndatasets=1, # Number of independent datasets
minphotons=50.0, # Minimum photons for detection
state1=:equilibrium # Initial state sampling
)
apply_noise
Add localization uncertainty to emitter positions based on photon counts.
# Example usage of apply_noise
# First, you need smld_model from a previous step
# For example, from the output of kinetic_model()
# For 2D emitters - add noise with 130nm PSF width
smld_noisy = apply_noise(smld_model, 0.13) # 0.13 μm = 130nm PSF width
# For 3D emitters - specify PSF width in each dimension
smld_noisy_3d = apply_noise(smld_model_3d, [0.13, 0.13, 0.39]) # [x, y, z] widths in μm
Image Generation
gen_images
Generate camera images from SMLD data using the specified PSF model.
images = gen_images(
smld::SMLD,
psf::AbstractPSF;
dataset::Int=1, # Dataset number to use from SMLD
frames=nothing, # Specific frames to generate (default: all frames)
support=Inf, # PSF support region size (see details below)
sampling=2, # Supersampling factor for PSF integration
threaded=true, # Enable multithreading
bg=0.0, # Background signal level (photons per pixel)
poisson_noise=false, # Apply Poisson noise
camera_noise=false # Apply camera read noise
)
# The support parameter controls PSF computation region:
# 1. Inf (default): Compute PSF over entire image (most accurate but slowest)
support=Inf
# 2. Real number: Use circular region with given radius around each emitter
# Typically 3-5× the PSF width is sufficient for accuracy with better performance
support=1.0 # 1.0 µm radius around each emitter
# 3. Tuple (xmin, xmax, ymin, ymax): Explicit region in microns
support=(4.0, 6.0, 4.0, 6.0) # Only compute PSF within this region
gen_image
Generate a single frame camera image.
# Example of generating a single frame image
# First, define variables
smld = ... # Your SMLD data
psf = GaussianPSF(0.15) # PSF model with 150nm width
frame_number = 10 # The frame you want to generate
# Generate image for a specific frame
single_frame = gen_image(
smld, # SMLD data
psf, # PSF model
frame_number; # Frame to generate
support=1.0, # Same keyword arguments as gen_images
bg=5.0,
poisson_noise=true
)
Analysis Functions
Diffusion Analysis
# Example usage of diffusion analysis functions
# First, run a diffusion simulation
params = DiffusionSMLMParams()
smld = simulate(params)
# Extract dimers from diffusion simulation
dimer_smld = get_dimers(smld)
# Extract monomers
monomer_smld = get_monomers(smld)
# Analyze dimer formation over time
frames, fractions = analyze_dimer_fraction(smld)
# Analyze average dimer lifetime
lifetime = analyze_dimer_lifetime(smld)
# Track state changes over time
state_history = track_state_changes(smld)
Track Utilities
# Example usage of track utilities
# First, run a simulation
params = StaticSMLMParams()
smld_true, smld_model, smld_noisy = simulate(params)
# Specify a track ID to extract
track_id = 1 # ID of the track to extract
# Get a specific track by ID
track_smld = get_track(smld_noisy, track_id)
# Get number of unique tracks
n_tracks = get_num_tracks(smld_noisy)
# Get all tracks as separate SMLDs
track_smlds = get_tracks(smld_noisy)
Pattern Manipulation
# Example usage of pattern manipulation
# Create patterns
pattern2d = Nmer2D(n=6, d=0.2)
pattern3d = Nmer3D(n=8, d=0.15)
# Rotate a 2D pattern by 45 degrees
rotate!(pattern2d, π/4)
# Rotate a 3D pattern with Euler angles (ZYZ convention)
rotate!(pattern3d, π/4, π/6, π/3) # α, β, γ angles
# Rotate a 3D pattern with a rotation matrix
θ = π/2 # 90 degrees
R = [cos(θ) -sin(θ) 0; sin(θ) cos(θ) 0; 0 0 1] # Z-axis rotation
rotate!(pattern3d, R)
# Generate random pattern distribution in a field
field_x = 10.0 # μm
field_y = 10.0 # μm
density = 1.0 # patterns per μm²
# Get coordinates for 2D distribution
x, y = uniform2D(density, pattern2d, field_x, field_y)
# Get coordinates for 3D distribution
x, y, z = uniform3D(density, pattern3d, field_x, field_y, zrange=[-2.0, 2.0])
Common Workflows
Static SMLM Simulation Workflow
- Define simulation parameters
- Create a pattern (or use default)
- Define a fluorophore model (or use default)
- Run simulation to get true positions, kinetic model, and noisy localizations
- Generate microscope images or analyze the data
# 1. Define parameters
params = StaticSMLMParams(
density = 1.0,
σ_psf = 0.13,
nframes = 1000
)
# 2. Create a pattern
pattern = Nmer2D(n=6, d=0.2) # hexamer with 200nm diameter
# 3. Define fluorophore model
fluor = GenericFluor(photons=1e4, k_off=10.0, k_on=0.5)
# 4. Run simulation
smld_true, smld_model, smld_noisy = simulate(
params;
pattern=pattern,
molecule=fluor
)
# 5. Create microscope images with efficient PSF support
psf = GaussianPSF(0.15) # 150nm PSF width
images = gen_images(smld_model, psf;
support=1.0, # 1.0 μm radius around each emitter
poisson_noise=true # Add realistic photon counting noise
)
Diffusion Simulation Workflow
- Define diffusion parameters
- Run simulation to get emitter trajectories
- Analyze the diffusion and interaction dynamics
- Generate microscope images
# 1. Define parameters
params = DiffusionSMLMParams(
density = 0.5, # molecules per μm²
box_size = 10.0, # μm
diff_monomer = 0.1, # μm²/s
diff_dimer = 0.05, # μm²/s
k_off = 0.2, # s⁻¹
t_max = 10.0 # s
)
# 2. Run simulation
smld = simulate(params)
# 3. Analyze the results
dimer_smld = get_dimers(smld)
frames, fractions = analyze_dimer_fraction(smld)
# 4. Generate microscope images with finite PSF support
psf = GaussianPSF(0.15) # 150nm PSF width
images = gen_images(smld, psf;
support=1.0, # 1.0 μm PSF support radius (faster)
bg=5.0, # Background photons per pixel
poisson_noise=true # Add realistic photon counting noise
)
Complete Examples
Static SMLM with Image Generation
using SMLMSim
using MicroscopePSFs
# Define a camera and simulation parameters
camera = IdealCamera(128, 128, 0.1) # 128×128 pixels, 100nm pixels
params = StaticSMLMParams(density=1.0, σ_psf=0.13, nframes=1000)
# Run simulation for an 8-molecule ring pattern
smld_true, smld_model, smld_noisy = simulate(
params;
pattern=Nmer2D(n=8, d=0.1), # 100nm diameter ring
molecule=GenericFluor(1e4, [-10.0 10.0; 0.5 -0.5]), # γ=10,000, k_off=10, k_on=0.5
camera=camera
)
# Create a PSF model
psf = GaussianPSF(0.15) # 150nm PSF width
# Generate microscope images with finite PSF support
images = gen_images(smld_model, psf;
support=1.0, # 1.0 μm PSF support radius (faster than Inf)
bg=5.0, # 5 background photons per pixel
poisson_noise=true # Add realistic photon counting noise
)
println("Generated $(length(smld_noisy.emitters)) localizations and $(size(images,3)) images.")
Diffusion with Dimer Analysis
using SMLMSim
using MicroscopePSFs
# Set diffusion simulation parameters
params = DiffusionSMLMParams(
density = 0.5, # molecules per μm²
box_size = 10.0, # μm
diff_monomer = 0.1, # μm²/s
diff_dimer = 0.05, # μm²/s
k_off = 0.2, # s⁻¹
t_max = 10.0, # s
boundary = "reflecting" # Use reflecting boundaries
)
# Run diffusion simulation
smld = simulate(params)
# Analyze dimer formation
frames, dimer_fraction = analyze_dimer_fraction(smld)
avg_lifetime = analyze_dimer_lifetime(smld)
# Generate microscope images with finite PSF support
psf = GaussianPSF(0.15) # 150nm PSF width
images = gen_images(smld, psf;
support=1.0, # 1.0 μm PSF support radius (faster)
bg=2.0, # Background photons per pixel
poisson_noise=true # Add realistic photon counting noise
)
println("Simulation complete with $(length(smld.emitters)) emitters")
println("Average dimer fraction: $(mean(dimer_fraction))")
println("Average dimer lifetime: $(avg_lifetime) seconds")
Custom Pattern with 3D Simulation
using SMLMSim
using MicroscopePSFs
# Define a custom 3D pattern: two rings at different z-positions
mutable struct DoubleRing3D <: Pattern3D
n::Int
d1::Float64
d2::Float64
z1::Float64
z2::Float64
x::Vector{Float64}
y::Vector{Float64}
z::Vector{Float64}
end
function DoubleRing3D(; n=8, d1=0.1, d2=0.2, z1=-0.2, z2=0.2)
total_n = 2*n
x = zeros(total_n)
y = zeros(total_n)
z = zeros(total_n)
# First ring (bottom)
for i = 1:n
θ = 2π * (i-1) / n
x[i] = d1/2 * cos(θ)
y[i] = d1/2 * sin(θ)
z[i] = z1
end
# Second ring (top)
for i = 1:n
θ = 2π * (i-1) / n + π/n # Offset angle for second ring
x[n+i] = d2/2 * cos(θ)
y[n+i] = d2/2 * sin(θ)
z[n+i] = z2
end
return DoubleRing3D(n, d1, d2, z1, z2, x, y, z)
end
# Create camera and parameters
camera = IdealCamera(128, 128, 0.1)
params = StaticSMLMParams(
density = 0.5,
σ_psf = 0.13,
nframes = 2000,
ndims = 3,
zrange = [-1.0, 1.0]
)
# Create custom pattern
double_ring = DoubleRing3D(n=6, d1=0.15, d2=0.3, z1=-0.3, z2=0.3)
# Run simulation
smld_true, smld_model, smld_noisy = simulate(
params;
pattern=double_ring,
camera=camera
)
# Generate images with a 3D astigmatic PSF and finite support
# Create a PSF with astigmatism using Zernike coefficients
using MicroscopePSFs
zc = ZernikeCoefficients(15)
zc.phase[6] = 0.5 # Add vertical astigmatism
psf_scalar = ScalarPSF(1.4, 0.532, 1.52; zernike_coeffs=zc)
# Create SplinePSF for speed
xy_sampling, z_sampling = 0.05, 0.1
x_range = y_range = -1.0:xy_sampling:1.0
z_range = -1.0:z_sampling:1.0
psf_spline = SplinePSF(psf_scalar, x_range, y_range, z_range)
# Generate images using the spline PSF with finite support
images = gen_images(smld_model, psf_spline;
support=0.5, # 0.5 μm PSF support radius for performance
bg=5.0, # Background photons per pixel
poisson_noise=true # Add realistic photon counting noise
)
println("Generated $(length(smld_noisy.emitters)) localizations in 3D")
api_overview()
returns this documentation as a plain String
.
SMLMSim.simulate
— Methodsimulate(sim::AbstractSim; kwargs...)
Generic interface for all simulation types. Dispatches to the appropriate method based on the concrete simulation type.
Arguments
sim::AbstractSim
: The simulation configuration objectkwargs...
: Additional keyword arguments specific to the simulation type
Returns
- The result of the specific simulation method
Example
# Create a static SMLM simulation configuration
params = StaticSMLMParams(
density = 1.0, # Changed from ρ to density
σ_psf = 0.13
)
# Run the simulation
results = simulate(params)
SMLMSim.Core
— ModuleCore
Core module with shared utilities for SMLM simulation.
This module contains fundamental components that can be used across different simulation types (static, diffusion, etc.) including:
- Abstract types for simulation
- Molecule and pattern definitions
- CTMC (Continuous Time Markov Chain) for stochastic state transitions
- Photophysics modeling for blinking kinetics and detection
Usage
using SMLMSim.Core
SMLMSim.Core.AbstractSim
— TypeAbstractSim
Abstract type for all simulation types in SMLMSim. Concrete subtypes should implement their own simulate methods.
SMLMSim.Core.CTMC
— TypeCTMC{T<:AbstractFloat, U<:Int}
A Continuous Time Markov Chain representation storing the full trajectory of state transitions.
Fields
simulation_time::T
: Total simulation time spantransition_times::Vector{T}
: Time points at which state changes occurred, starting at 0.0states::Vector{U}
: Sequence of states entered at each transition time, starting with initial state
Type Parameters
T
: Floating point type for time valuesU
: Integer type for state indices
Note
The states
and transition_times
vectors have the same length, with each entry in states[i]
representing the state entered at time transition_times[i]
. The system remains in states[i]
until time transition_times[i+1]
.
SMLMSim.Core.CTMC
— MethodCTMC(q::Array{T}, simulation_time::T, state1::Int) where {T<:AbstractFloat}
Construct a Continuous Time Markov Chain simulation from a rate matrix.
Arguments
q::Array{T}
: Rate matrix where q[i,j] for i≠j is the transition rate from state i to j, and q[i,i] is the negative exit rate from state isimulation_time::T
: Total time to simulatestate1::Int
: Initial state
Returns
CTMC{T,Int}
: Simulated CTMC with transition times and states
Details
Simulates a CTMC using the Gillespie algorithm:
- Start in state1 at time 0
- For current state i:
- Calculate total exit rate ktot = Σj q[i,j]
- Sample time until next transition from Exp(k_tot)
- Sample next state j with probability q[i,j]/k_tot
- Repeat until exceeding simulation_time
SMLMSim.Core.GenericFluor
— TypeGenericFluor <: Molecule
Defines a fluorophore with photophysical properties.
Fields
γ::AbstractFloat
: Photon emission rate in Hz. Default: 1e5q::Array{<:AbstractFloat}
: Rate matrix where q[i,j] for i≠j is the transition rate from state i to j, and q[i,i] is the negative exit rate from state i. Default: standard 2-state model with on->off rate of 50Hz and off->on rate of 1e-2Hz
Examples
# Create a fluorophore with default parameters (using the 2-state keyword constructor)
fluor = GenericFluor()
# Create a fluorophore with custom parameters using the positional constructor
fluor = GenericFluor(1e5, [-50.0 50.0; 1e-2 -1e-2])
# Create a fluorophore using the 2-state keyword constructor
fluor = GenericFluor(; photons=1e5, k_off=10.0, k_on=1e-1)
SMLMSim.Core.GenericFluor
— MethodGenericFluor(; photons::AbstractFloat=1e5, k_off::AbstractFloat=50.0, k_on::AbstractFloat=1e-2)
Create a simple two-state (on/off) fluorophore with specified parameters.
Arguments
photons::AbstractFloat
: Photon emission rate in Hzk_off::AbstractFloat
: Off-switching rate (on→off) in Hzk_on::AbstractFloat
: On-switching rate (off→on) in Hz
Details
Creates a fluorophore with a 2-state model and the specified rates. State 1 is the on (bright) state, and state 2 is the off (dark) state. The rate matrix is constructed as: q = [-koff koff; kon -kon]
SMLMSim.Core.Line2D
— TypeLine2D <: Pattern2D
Points with uniform random distribution between two endpoints.
Fields
λ::Float64
: Linear molecule density (molecules per micron)endpoints::Vector{Tuple{Float64,Float64}}
: Vector of endpoint coordinatesn::Int
: Number of molecules in the patternx::Vector{Float64}
: X positions of molecules in micronsy::Vector{Float64}
: Y positions of molecules in microns
Examples
# Create a line with default parameters
line = Line2D()
# Create a custom line
line = Line2D(; λ=5.0, endpoints=[(-2.0, 0.0), (2.0, 0.0)])
SMLMSim.Core.Line3D
— TypeLine3D <: Pattern3D
Points with uniform random distribution between two 3D endpoints.
Fields
λ::Float64
: Linear molecule density (molecules per micron)endpoints::Vector{Tuple{Float64,Float64,Float64}}
: Vector of 3D endpoint coordinatesn::Int
: Number of molecules in the patternx::Vector{Float64}
: X positions of molecules in micronsy::Vector{Float64}
: Y positions of molecules in micronsz::Vector{Float64}
: Z positions of molecules in microns
Examples
# Create a line with default parameters
line = Line3D()
# Create a custom 3D line
line = Line3D(; λ=5.0, endpoints=[(-1.0, 0.0, -0.5), (1.0, 0.0, 0.5)])
SMLMSim.Core.Molecule
— TypeMolecule
Abstract type for representing photophysical properties of a molecule.
This is the most general type of luminescent or scattering single molecule. Inherited types will define the properties of specific classes of molecules.
SMLMSim.Core.Nmer2D
— TypeNmer2D <: Pattern2D
N molecules symmetrically organized around a circle with diameter d.
Fields
n::Int
: Number of molecules in the patternd::Float64
: Diameter of the circle in micronsx::Vector{Float64}
: X positions of molecules in micronsy::Vector{Float64}
: Y positions of molecules in microns
Examples
# Create an 8-molecule pattern with 100nm diameter
nmer = Nmer2D()
# Create a custom pattern with 6 molecules and 200nm diameter
nmer = Nmer2D(; n=6, d=0.2)
SMLMSim.Core.Nmer3D
— TypeNmer3D <: Pattern3D
N molecules symmetrically organized around a circle with diameter d at z=0.
Fields
n::Int
: Number of molecules in the patternd::Float64
: Diameter of the circle in micronsx::Vector{Float64}
: X positions of molecules in micronsy::Vector{Float64}
: Y positions of molecules in micronsz::Vector{Float64}
: Z positions of molecules in microns
Examples
# Create an 8-molecule pattern with 100nm diameter
nmer = Nmer3D()
# Create a custom pattern with 6 molecules and 200nm diameter
nmer = Nmer3D(; n=6, d=0.2)
SMLMSim.Core.Pattern
— TypePattern
Abstract type for all molecular spatial patterns.
SMLMSim.Core.Pattern2D
— TypePattern2D <: Pattern
Abstract type for 2D molecular spatial patterns.
SMLMSim.Core.Pattern3D
— TypePattern3D <: Pattern
Abstract type for 3D molecular spatial patterns.
SMLMSim.Core.SMLMSimParams
— TypeSMLMSimParams <: AbstractSim
Abstract type for all SMLM simulation parameter types. Provides a common parent for different types of SMLM simulations.
SMLMSim.Core.compute_equilibrium_distribution
— Methodcompute_equilibrium_distribution(q::Matrix{<:AbstractFloat})
Calculate the equilibrium probability distribution for a CTMC rate matrix.
Arguments
q::Matrix{<:AbstractFloat}
: Rate matrix where q[i,j] for i≠j is the transition rate from state i to j, and q[i,i] is the negative exit rate from state i
Returns
Vector{Float64}
: Equilibrium probabilities for each state
Details
For a rate matrix Q, the equilibrium distribution π satisfies π·Q = 0 subject to Σπ = 1. This function solves the linear system directly to find the equilibrium distribution.
SMLMSim.Core.get_next
— Methodget_next(ctmc::CTMC, t::AbstractFloat)
Get the next state transition after a specific time point.
Arguments
ctmc::CTMC
: The CTMC to queryt::AbstractFloat
: Current time point
Returns
Tuple{Int,AbstractFloat}
: (nextstate, transitiontime)
Note
Returns the next state that will be entered and when it will be entered, searching from the current time point forward.
SMLMSim.Core.get_num_tracks
— Methodget_num_tracks(smld::BasicSMLD)
Return the number of unique tracks (based on track_id) in the SMLD.
Arguments
smld::BasicSMLD
: The SMLD to analyze
Returns
Int
: Number of unique track IDs
Example
# Get the number of tracks
n_tracks = get_num_tracks(smld)
SMLMSim.Core.get_state
— Methodget_state(ctmc::CTMC, t::AbstractFloat)
Get the state of the CTMC at a specific time point.
Arguments
ctmc::CTMC
: The CTMC to queryt::AbstractFloat
: Time point of interest
Returns
Int
: State of the chain at time t
Note
Searches through transition times to find the state active at time t. Returns the state that was entered at the last transition before t.
SMLMSim.Core.get_track
— Methodget_track(smld::BasicSMLD, id::Int)
Return a new SMLD containing only emitters with the specified track_id.
Arguments
smld::BasicSMLD
: The original SMLDid::Int
: Track ID to filter by
Returns
BasicSMLD
: New SMLD containing only emitters from the specified track
Example
# Get all emitters belonging to track 5
track_smld = get_track(smld, 5)
SMLMSim.Core.get_tracks
— Methodget_tracks(smld::BasicSMLD)
Return a vector of SMLD objects, one for each unique track (based on track_id).
Arguments
smld::BasicSMLD
: The original SMLD
Returns
Vector{BasicSMLD}
: Vector of SMLD objects, one per track
Example
# Get all tracks as separate SMLD objects
track_smlds = get_tracks(smld)
# Access the first track
first_track = track_smlds[1]
SMLMSim.Core.intensity_trace
— Methodintensity_trace(f::GenericFluor, nframes::Int, framerate::Real; state1=1)
Calculate a fluorescence intensity trace by integrating emission during fluorescent state occupancy.
Arguments
f::GenericFluor
: Fluorophore model containing transition rates (q) and emission rate (γ)nframes::Int
: Number of frames to simulateframerate::Real
: Frame rate in Hzstate1::Int=1
: Initial state (default: 1 for fluorescent state)
Returns
Vector{Float64}
: Integrated photon counts for each frame
Details
For each frame:
- Determines state occupancy using CTMC
- Integrates emission (rate f.γ) during fluorescent state periods
- Accumulates photons within frame exposure time (1/framerate)
Example
fluor = GenericFluor(; γ=10000.0, q=[-10.0 10.0; 1e-1 -1e-1])
photons = intensity_trace(fluor, 1000, 10.0)
Note
- State 1 is assumed to be the fluorescent state
- Emission only occurs in state 1 with rate f.γ
- Frame exposure is assumed to be 1/framerate (100% duty cycle)
SMLMSim.Core.kinetic_model
— Methodkinetic_model(smld::BasicSMLD, f::Molecule, nframes::Int, framerate::Real;
ndatasets::Int=1, minphotons=50.0, state1::Int=2)
Generate kinetic blinking model from existing localization data.
Arguments
smld::BasicSMLD
: Input SMLD containing true emitter positionsf::Molecule
: Fluorophore model with kinetic ratesnframes::Int
: Number of frames to simulateframerate::Real
: Frame rate in Hzndatasets::Int=1
: Number of independent datasets to generateminphotons::Float64=50.0
: Minimum photons for detectionstate1::Union{Int, Symbol}=:equilibrium
: Initial state specification:::Int
: Specific state to start in (1=on, 2=off typically):equilibrium
: Sample from equilibrium distribution (default)
Returns
BasicSMLD
: New SMLD with simulated blinking kinetics
Details
For each unique position in the input SMLD:
- Simulates fluorophore blinking using the kinetic model
- Creates emitters for frames where photon count exceeds threshold
- Preserves track_id for linking emitters from same position
- Maintains camera and extends metadata from input SMLD
Example
camera = IdealCamera(1:128, 1:128, 0.1)
pattern = Nmer2D()
smld_true, _, _ = simulate(pattern=pattern, camera=camera)
# Add blinking kinetics
fluor = GenericFluor(; γ=10000.0, q=[-10.0 10.0; 1e-1 -1e-1])
smld_model = kinetic_model(smld_true, fluor, 1000, 10.0)
Note
The emitter type (2D/3D) is automatically determined from the input SMLD. Position uncertainties are initialized to 0 and can be set using the apply_noise() function.
SMLMSim.Core.rotate!
— Methodrotate!(p::Pattern2D, θ::Float64)
Rotate a 2D pattern by angle θ (in radians).
Arguments
p::Pattern2D
: Pattern to rotateθ::Float64
: Rotation angle in radians
Example
nmer = Nmer2D()
rotate!(nmer, π/4) # Rotate 45 degrees
SMLMSim.Core.rotate!
— Methodrotate!(p::Pattern3D, R::Matrix{Float64})
Rotate a 3D pattern by rotation matrix R.
Arguments
p::Pattern3D
: Pattern to rotateR::Matrix{Float64}
: 3x3 rotation matrix
Example
nmer = Nmer3D()
# Create a rotation matrix for 90 degrees around z-axis
θ = π/2
R = [cos(θ) -sin(θ) 0; sin(θ) cos(θ) 0; 0 0 1]
rotate!(nmer, R)
SMLMSim.Core.rotate!
— Methodrotate!(p::Pattern3D, α::Float64, β::Float64, γ::Float64)
Rotate a 3D pattern by Euler angles α, β, γ (in radians). Uses ZYZ convention.
Arguments
p::Pattern3D
: Pattern to rotateα::Float64
: First rotation angle (around Z axis)β::Float64
: Second rotation angle (around Y' axis)γ::Float64
: Third rotation angle (around Z'' axis)
Example
nmer = Nmer3D()
rotate!(nmer, π/4, π/6, π/3)
SMLMSim.Core.sample_discrete
— Methodsample_discrete(p::Vector{<:AbstractFloat})
Sample from a discrete probability distribution.
Arguments
p::Vector{<:AbstractFloat}
: Probability distribution
Returns
Int
: Sampled state index
Details
Samples a state index i with probability p[i] using the inverse CDF method.
SMLMSim.Core.sample_discrete_with_probs
— Methodsample_discrete_with_probs(indices, probs)
Sample a discrete value from indices with corresponding probabilities.
Arguments
indices::Vector{Int}
: Vector of possible indices to sampleprobs::Vector{<:AbstractFloat}
: Corresponding probabilities
Returns
Int
: Sampled index
SMLMSim.Core.uniform2D
— Methoduniform2D(ρ::Float64, p::Pattern2D, field_x::Float64, field_y::Float64)
Create coordinate arrays for randomly placed and rotated 2D patterns.
Arguments
ρ::Float64
: Pattern density (patterns per square micron)p::Pattern2D
: Pattern to replicatefield_x::Float64
: Field width in micronsfield_y::Float64
: Field height in microns
Returns
Tuple{Vector{Float64}, Vector{Float64}}
: (x, y) coordinates in microns
Example
# Generate coordinates for randomly placed Nmer2D patterns
nmer = Nmer2D(; n=6, d=0.2)
x, y = uniform2D(1.0, nmer, 10.0, 10.0)
SMLMSim.Core.uniform3D
— Methoduniform3D(ρ::Float64, p::Pattern3D, field_x::Float64, field_y::Float64;
zrange::Vector{Float64}=[-1.0, 1.0])
Create coordinate arrays for randomly placed and rotated 3D patterns.
Arguments
ρ::Float64
: Pattern density (patterns per square micron)p::Pattern3D
: Pattern to replicatefield_x::Float64
: Field width in micronsfield_y::Float64
: Field height in micronszrange::Vector{Float64}=[-1.0, 1.0]
: [minz, maxz] range in microns
Returns
Tuple{Vector{Float64}, Vector{Float64}, Vector{Float64}}
: (x, y, z) coordinates
Example
# Generate coordinates for randomly placed Nmer3D patterns
nmer = Nmer3D(; n=6, d=0.2)
x, y, z = uniform3D(1.0, nmer, 10.0, 10.0; zrange=[-2.0, 2.0])
SMLMSim.StaticSMLM
— ModuleStaticSMLM
Module for simulating static (non-diffusing) SMLM data with blinking kinetics.
This module provides functionality for:
- Generating spatial distributions of emitters based on patterns
- Simulating fluorophore blinking based on stochastic kinetic models
- Adding realistic localization uncertainties
- Creating complete SMLM datasets
Usage
using SMLMSim.StaticSMLM
SMLMSim.StaticSMLM.StaticSMLMParams
— TypeStaticSMLMParams <: SMLMSimParams
Parameters for static SMLM simulation.
Fields
density::Float64
: density in particles per square micronσ_psf::Float64
: PSF width in micronsminphotons::Int
: minimum photons for detectionndatasets::Int
: number of datasets to simulatenframes::Int
: number of frames per datasetframerate::Float64
: frames per secondndims::Int
: dimensionality (2 or 3)zrange::Vector{Float64}
: axial range for 3D simulations [minz, maxz]
Examples
# Default parameters
params = StaticSMLMParams()
# Custom parameters
params = StaticSMLMParams(
density = 2.0, # 2 particles per μm²
σ_psf = 0.15, # 150nm PSF width
minphotons = 100, # minimum photons for detection
ndatasets = 5, # 5 independent datasets
nframes = 2000, # 2000 frames per dataset
framerate = 100.0, # 100 frames per second
ndims = 3, # 3D simulation
zrange = [-2.0, 2.0] # 4μm axial range
)
SMLMSim.StaticSMLM.add_coordinate_noise
— Methodadd_coordinate_noise(emitter, σ)
Helper function to add position noise to an emitter with appropriate uncertainty. Returns new coordinate values and uncertainty values.
For 2D emitters, σ is a scalar. For 3D emitters, σ is a 3-element vector.
SMLMSim.StaticSMLM.apply_noise
— Methodapply_noise(smld::BasicSMLD, σ_psf::AbstractFloat)
Add localization uncertainty to 2D emitter positions based on photon counts.
Arguments
smld::BasicSMLD
: Input SMLD containing 2D emittersσ_psf::AbstractFloat
: PSF width in microns
Returns
BasicSMLD
: New SMLD with noisy positions and updated uncertainties
Example
# Then add localization noise with specific PSF width
smld_noisy = apply_noise(smld_model, 0.13) # 130nm PSF width
SMLMSim.StaticSMLM.apply_noise
— Methodapply_noise(smld::BasicSMLD, σ_psf::Vector{<:AbstractFloat})
Add localization uncertainty to 3D emitter positions based on photon counts.
Arguments
smld::BasicSMLD
: Input SMLD containing 3D emittersσ_psf::Vector{<:AbstractFloat}
: PSF widths [σx, σy, σz] in microns
Returns
BasicSMLD
: New SMLD with noisy positions and updated uncertainties
Example
# Then add localization noise with specific PSF widths
σ_psf = [0.13, 0.13, 0.39] # 130nm lateral, 390nm axial
smld_noisy = apply_noise(smld_model, σ_psf)
SMLMSim.simulate
— Methodsimulate(params::StaticSMLMParams;
starting_conditions::Union{Nothing, SMLD, Vector{<:AbstractEmitter}}=nothing,
pattern::Pattern=nothing,
molecule::Molecule=GenericFluor(photons=1e4, k_off=50.0, k_on=1e-2),
camera::AbstractCamera=IdealCamera(1:128, 1:128, 0.1))
Generate simulated static SMLM data with realistic blinking kinetics and localization uncertainty.
Arguments
params::StaticSMLMParams
: Simulation parametersstarting_conditions::Union{Nothing, SMLD, Vector{<:AbstractEmitter}}
: Optional starting conditions instead of generating patternspattern::Pattern
: Pattern to use (default depends on params.ndims)molecule::Molecule
: Fluorophore model for blinking simulationcamera::AbstractCamera
: Camera model for detection simulation
Returns
Tuple{BasicSMLD, BasicSMLD, BasicSMLD}
: (truepositions, modelkinetics, noisy_data)- true_positions: Ground truth emitter positions
- model_kinetics: Positions with simulated blinking
- noisy_data: Positions with blinking and localization uncertainty
Example
# Create parameters
params = StaticSMLMParams(
density = 2.0, # 2 patterns per μm²
σ_psf = 0.15, # 150nm PSF width
minphotons = 100, # 100 photons for detection
ndatasets = 5, # 5 independent datasets
nframes = 2000, # 2000 frames
framerate = 100.0 # 100 frames per second
)
# Run simulation with Nmer pattern
pattern = Nmer3D(n=6, d=0.2)
smld_true, smld_model, smld_noisy = simulate(params; pattern=pattern)
# Run with custom starting conditions
custom_emitters = [
Emitter2DFit{Float64}(x, y, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0; track_id=i)
for (i, (x, y)) in enumerate(zip(rand(10), rand(10)))
]
smld_true, smld_model, smld_noisy = simulate(params; starting_conditions=custom_emitters)
Note
- The
params.σ_psf
value is used directly for lateral uncertainty (σx, σy) in both 2D and 3D. - For 3D simulations, the axial uncertainty (σz) is scaled by a factor of 3 (i.e., σz = 3 * σ_psf).
- If
starting_conditions
is provided, it will be used instead of generating patterns.
SMLMSim.InteractionDiffusion
— ModuleInteractionDiffusion
This module provides simulation tools for diffusion and interaction between particles.
Overview
Simulates diffusion and interaction dynamics between particles in 2D/3D space. Includes functionality for generating microscope images, analyzing dimers, and visualizing particle dynamics.
Components
- Abstract and concrete emitter types (AbstractDiffusingEmitter, DiffusingEmitter2D, DiffusingEmitter3D)
- Smoluchowski dynamics simulation
- Analysis tools for dimers and state transitions
- SMLD conversion utilities
Examples
# Set up simulation parameters
params = DiffusionSMLMParams(
density = 0.5, # molecules per μm²
box_size = 10.0, # μm
diff_monomer = 0.1, # μm²/s
diff_dimer = 0.05, # μm²/s
k_off = 0.2, # s⁻¹
r_react = 0.01, # μm
d_dimer = 0.05, # μm
dt = 0.01, # s
t_max = 10.0, # s
camera_framerate = 20.0, # fps
camera_exposure = 0.04 # s
)
# Run simulation - returns a single SMLD with all emitters
smld = simulate(params)
# Generate images for microscopy
psf = GaussianPSF(0.15) # 150nm PSF width
images = gen_images(psf, smld)
# Analyze results
dimer_smld = get_dimers(smld)
frames, dimer_fractions = analyze_dimer_fraction(smld)
SMLMSim.InteractionDiffusion.AbstractDiffusingEmitter
— TypeAbstractDiffusingEmitter <: AbstractEmitter
Abstract type for all diffusing emitters to enable dispatch-based operations. This provides a common parent for 2D and 3D diffusing emitters.
SMLMSim.InteractionDiffusion.DiffusingEmitter2D
— TypeDiffusingEmitter2D{T<:AbstractFloat} <: AbstractDiffusingEmitter
A 2D emitter type for diffusion simulations that contains both spatial and temporal information, plus molecular state information.
Fields
x::T
: x-coordinate in micronsy::T
: y-coordinate in micronsphotons::T
: number of photons emittedtimestamp::T
: actual simulation time in secondsframe::Int
: camera frame number based on framerate and exposuredataset::Int
: dataset identifiertrack_id::Int
: unique molecule identifierstate::Symbol
: molecular state (:monomer or :dimer)partner_id::Union{Int,Nothing}
: ID of linked molecule (for dimers), or nothing for monomers
SMLMSim.InteractionDiffusion.DiffusingEmitter3D
— TypeDiffusingEmitter3D{T<:AbstractFloat} <: AbstractDiffusingEmitter
A 3D emitter type for diffusion simulations that contains both spatial and temporal information, plus molecular state information.
Fields
x::T
: x-coordinate in micronsy::T
: y-coordinate in micronsz::T
: z-coordinate in micronsphotons::T
: number of photons emittedtimestamp::T
: actual simulation time in secondsframe::Int
: camera frame number based on framerate and exposuredataset::Int
: dataset identifiertrack_id::Int
: unique molecule identifierstate::Symbol
: molecular state (:monomer or :dimer)partner_id::Union{Int,Nothing}
: ID of linked molecule (for dimers), or nothing for monomers
SMLMSim.InteractionDiffusion.DiffusionSMLMParams
— TypeDiffusionSMLMParams <: SMLMSimParams
Parameters for diffusion-based SMLM simulation using Smoluchowski dynamics.
Fields
density::Float64
: number density (molecules/μm²)box_size::Float64
: simulation box size (μm)diff_monomer::Float64
: monomer diffusion coefficient (μm²/s)diff_dimer::Float64
: dimer diffusion coefficient (μm²/s)diff_dimer_rot::Float64
: dimer rotational diffusion coefficient (rad²/s)k_off::Float64
: dimer dissociation rate (s⁻¹)r_react::Float64
: reaction radius (μm)d_dimer::Float64
: monomer separation in dimer (μm)dt::Float64
: time step (s)t_max::Float64
: total simulation time (s)ndims::Int
: number of dimensions (2 or 3)boundary::String
: boundary condition type ("periodic" or "reflecting")camera_framerate::Float64
: camera frames per second (Hz)camera_exposure::Float64
: camera exposure time per frame (s)
Examples
# Default parameters
params = DiffusionSMLMParams()
# Custom parameters
params = DiffusionSMLMParams(
density = 1.0, # 1 molecule per μm²
box_size = 20.0, # 20μm × 20μm box
diff_monomer = 0.2, # 0.2 μm²/s
diff_dimer = 0.1, # 0.1 μm²/s
diff_dimer_rot = 0.8, # 0.8 rad²/s
k_off = 0.1, # 0.1 s⁻¹
r_react = 0.02, # 20nm reaction radius
d_dimer = 0.06, # 60nm dimer separation
dt = 0.005, # 5ms time step
t_max = 20.0, # 20s simulation
ndims = 3, # 3D simulation
boundary = "reflecting", # reflecting boundaries
camera_framerate = 20.0, # 20 frames per second
camera_exposure = 0.04 # 40ms exposure per frame
)
Base.copy
— MethodBase.copy(e::DiffusingEmitter2D)
Create a copy of a 2D diffusing emitter.
Base.copy
— MethodBase.copy(e::DiffusingEmitter3D)
Create a copy of a 3D diffusing emitter.
SMLMSim.InteractionDiffusion.add_camera_frame_emitters!
— Methodadd_camera_frame_emitters!(camera_emitters, emitters, time, frame_num, params)
Add emitters to camera frames when they fall within an exposure window.
Arguments
camera_emitters::Vector{<:AbstractDiffusingEmitter}
: Collection of emitters for camera framesemitters::Vector{<:AbstractDiffusingEmitter}
: Current emitters from simulationtime::Float64
: Current simulation timeframe_num::Int
: Current frame numberparams::DiffusionSMLMParams
: Simulation parameters
Returns
Nothing
SMLMSim.InteractionDiffusion.analyze_dimer_fraction
— Methodanalyze_dimer_fraction(smld::BasicSMLD)
Calculate the fraction of dimers per frame.
Arguments
smld::BasicSMLD
: SMLD containing all emitters
Returns
Tuple{Vector{Int}, Vector{Float64}}
: Frame numbers and dimer fractions
Example
# Calculate dimer fraction over time
frames, fractions = analyze_dimer_fraction(smld)
plot(frames, fractions, xlabel="Frame", ylabel="Dimer Fraction")
SMLMSim.InteractionDiffusion.analyze_dimer_lifetime
— Methodanalyze_dimer_lifetime(smld::BasicSMLD)
Calculate the average lifetime of dimers.
Arguments
smld::BasicSMLD
: SMLD containing all emitters
Returns
Float64
: Average dimer lifetime in seconds
SMLMSim.InteractionDiffusion.apply_boundary
— Methodapply_boundary(e::AbstractDiffusingEmitter, box_size::Float64, boundary::String)
Apply boundary conditions to an emitter (generic fallback).
Arguments
e::AbstractDiffusingEmitter
: Emitter to apply boundary tobox_size::Float64
: Simulation box size in micronsboundary::String
: Boundary condition type ("periodic" or "reflecting")
Returns
AbstractDiffusingEmitter
: Emitter with boundary conditions applied
SMLMSim.InteractionDiffusion.apply_boundary
— Methodapply_boundary(e::DiffusingEmitter2D, box_size::Float64, boundary::String)
Apply boundary conditions to a 2D emitter.
Arguments
e::DiffusingEmitter2D
: Emitter to apply boundary tobox_size::Float64
: Simulation box size in micronsboundary::String
: Boundary condition type ("periodic" or "reflecting")
Returns
DiffusingEmitter2D
: New emitter with position constrained to the box
SMLMSim.InteractionDiffusion.apply_boundary
— Methodapply_boundary(e::DiffusingEmitter3D, box_size::Float64, boundary::String)
Apply boundary conditions to a 3D emitter.
Arguments
e::DiffusingEmitter3D
: Emitter to apply boundary tobox_size::Float64
: Simulation box size in micronsboundary::String
: Boundary condition type ("periodic" or "reflecting")
Returns
DiffusingEmitter3D
: New emitter with position constrained to the box
SMLMSim.InteractionDiffusion.can_dimerize
— Methodcan_dimerize(e1::AbstractDiffusingEmitter, e2::AbstractDiffusingEmitter, r_react::Float64)
Check if two emitters can form a dimer.
Arguments
e1::AbstractDiffusingEmitter
: First emittere2::AbstractDiffusingEmitter
: Second emitterr_react::Float64
: Reaction radius in microns
Returns
Bool
: True if emitters can form a dimer
SMLMSim.InteractionDiffusion.convert_to_diffusing_emitters
— Functionconvert_to_diffusing_emitters(emitters::Vector{<:AbstractEmitter}, photons::Float64=1000.0, state::Symbol=:monomer)
Convert regular emitters to diffusing emitters for use as starting conditions.
Arguments
emitters::Vector{<:AbstractEmitter}
: Vector of static emitters to convertphotons::Float64=1000.0
: Number of photons to assignstate::Symbol=:monomer
: Initial state (:monomer or :dimer)
Returns
Vector{<:AbstractDiffusingEmitter}
: Vector of diffusing emitters
Example
# Convert static emitters to diffusing emitters
static_emitters = smld_static.emitters
diffusing_emitters = convert_to_diffusing_emitters(static_emitters)
# Use as starting conditions for a diffusion simulation
params = DiffusionSMLMParams(t_max=10.0)
smld = simulate(params; starting_conditions=diffusing_emitters)
SMLMSim.InteractionDiffusion.create_smld
— Methodcreate_smld(emitters::Vector{<:AbstractDiffusingEmitter}, camera::AbstractCamera, params::DiffusionSMLMParams)
Convert a collection of diffusing emitters to a BasicSMLD object.
Arguments
emitters::Vector{<:AbstractDiffusingEmitter}
: Collection of emitters from simulationcamera::AbstractCamera
: Camera model for imagingparams::DiffusionSMLMParams
: Simulation parameters
Returns
BasicSMLD
: SMLD containing all emitters for further analysis or visualization
SMLMSim.InteractionDiffusion.diffuse
— Methoddiffuse(e::DiffusingEmitter2D, diff_coef::Float64, dt::Float64)
Create a new emitter with updated position based on Brownian motion.
Arguments
e::DiffusingEmitter2D
: Emitter to updatediff_coef::Float64
: Diffusion coefficient (μm²/s)dt::Float64
: Time step (s)
Returns
DiffusingEmitter2D
: New emitter with updated position
SMLMSim.InteractionDiffusion.diffuse
— Methoddiffuse(e::DiffusingEmitter3D, diff_coef::Float64, dt::Float64)
Create a new 3D emitter with updated position based on Brownian motion.
Arguments
e::DiffusingEmitter3D
: Emitter to updatediff_coef::Float64
: Diffusion coefficient (μm²/s)dt::Float64
: Time step (s)
Returns
DiffusingEmitter3D
: New emitter with updated position
SMLMSim.InteractionDiffusion.diffuse_dimer
— Methoddiffuse_dimer(e1::DiffusingEmitter2D, e2::DiffusingEmitter2D, diff_trans::Float64, diff_rot::Float64, d_dimer::Float64, dt::Float64)
Diffuse a dimer with both translational and rotational components.
Arguments
e1::DiffusingEmitter2D
: First emitter in dimere2::DiffusingEmitter2D
: Second emitter in dimerdiff_trans::Float64
: Translational diffusion coefficient (μm²/s)diff_rot::Float64
: Rotational diffusion coefficient (rad²/s)d_dimer::Float64
: Dimer separation distance (μm)dt::Float64
: Time step (s)
Returns
Tuple{DiffusingEmitter2D, DiffusingEmitter2D}
: Two new emitters with updated positions
SMLMSim.InteractionDiffusion.diffuse_dimer
— Methoddiffuse_dimer(e1::DiffusingEmitter3D, e2::DiffusingEmitter3D, diff_trans::Float64, diff_rot::Float64, d_dimer::Float64, dt::Float64)
Diffuse a 3D dimer with both translational and rotational components.
Arguments
e1::DiffusingEmitter3D
: First emitter in dimere2::DiffusingEmitter3D
: Second emitter in dimerdiff_trans::Float64
: Translational diffusion coefficient (μm²/s)diff_rot::Float64
: Rotational diffusion coefficient (rad²/s)d_dimer::Float64
: Dimer separation distance (μm)dt::Float64
: Time step (s)
Returns
Tuple{DiffusingEmitter3D, DiffusingEmitter3D}
: Two new emitters with updated positions
SMLMSim.InteractionDiffusion.dimerize
— Methoddimerize(e1::DiffusingEmitter2D, e2::DiffusingEmitter2D, d_dimer::Float64)
Create two new emitters in dimer state from two monomers.
Arguments
e1::DiffusingEmitter2D
: First emittere2::DiffusingEmitter2D
: Second emitterd_dimer::Float64
: Dimer separation distance in microns
Returns
Tuple{DiffusingEmitter2D, DiffusingEmitter2D}
: Two new emitters in dimer state
SMLMSim.InteractionDiffusion.dimerize
— Methoddimerize(e1::DiffusingEmitter3D, e2::DiffusingEmitter3D, d_dimer::Float64)
Create two new emitters in dimer state from two monomers in 3D.
Arguments
e1::DiffusingEmitter3D
: First emittere2::DiffusingEmitter3D
: Second emitterd_dimer::Float64
: Dimer separation distance in microns
Returns
Tuple{DiffusingEmitter3D, DiffusingEmitter3D}
: Two new emitters in dimer state
SMLMSim.InteractionDiffusion.dissociate
— Methoddissociate(e::DiffusingEmitter2D, emitters::Vector{<:AbstractDiffusingEmitter})
Create two new monomers from a dimer.
Arguments
e::DiffusingEmitter2D
: Emitter part of a dimeremitters::Vector{<:AbstractDiffusingEmitter}
: All emitters in the system
Returns
Tuple{DiffusingEmitter2D, DiffusingEmitter2D}
: Two new emitters in monomer state
SMLMSim.InteractionDiffusion.dissociate
— Methoddissociate(e::DiffusingEmitter3D, emitters::Vector{<:AbstractDiffusingEmitter})
Create two new monomers from a 3D dimer.
Arguments
e::DiffusingEmitter3D
: Emitter part of a dimeremitters::Vector{<:AbstractDiffusingEmitter}
: All emitters in the system
Returns
Tuple{DiffusingEmitter3D, DiffusingEmitter3D}
: Two new emitters in monomer state
SMLMSim.InteractionDiffusion.extract_final_state
— Methodextract_final_state(smld::SMLD)
Extract the emitters from the final frame of a simulation to use as starting conditions.
Arguments
smld::SMLD
: SMLD containing emitters from a simulation
Returns
Vector{<:AbstractEmitter}
: Emitters from the final frame
Example
# Run a simulation
params = DiffusionSMLMParams(t_max=5.0)
smld = simulate(params)
# Extract final state
final_state = extract_final_state(smld)
# Continue simulation with new parameters
params_new = DiffusionSMLMParams(t_max=10.0, diff_monomer=0.2)
smld_continued = simulate(params_new; starting_conditions=final_state)
SMLMSim.InteractionDiffusion.filter_by_state
— Methodfilter_by_state(smld::BasicSMLD, state::Symbol)
Filter emitters by their state (monomer or dimer).
Arguments
smld::BasicSMLD
: The original SMLD with diffusing emittersstate::Symbol
: State to filter by (:monomer or :dimer)
Returns
BasicSMLD
: New SMLD containing only emitters with the specified state
Example
# Get only monomers
monomer_smld = filter_by_state(smld, :monomer)
# Get only dimers
dimer_smld = filter_by_state(smld, :dimer)
SMLMSim.InteractionDiffusion.get_dimers
— Methodget_dimers(smld::BasicSMLD)
Extract a new BasicSMLD containing only emitters in dimer state.
Arguments
smld::BasicSMLD
: Original SMLD with all emitters
Returns
BasicSMLD
: New SMLD containing only dimers
Example
# Extract only dimers from simulation results
smld = simulate(params)
dimer_smld = get_dimers(smld)
SMLMSim.InteractionDiffusion.get_frame
— Methodget_frame(smld::BasicSMLD, frame_num::Int)
Extract emitters from a specific frame.
Arguments
smld::BasicSMLD
: SMLD containing all emittersframe_num::Int
: Frame number to extract
Returns
BasicSMLD
: New SMLD containing only emitters from the specified frame
SMLMSim.InteractionDiffusion.get_monomers
— Methodget_monomers(smld::BasicSMLD)
Extract a new BasicSMLD containing only emitters in monomer state.
Arguments
smld::BasicSMLD
: Original SMLD with all emitters
Returns
BasicSMLD
: New SMLD containing only monomers
SMLMSim.InteractionDiffusion.initialize_emitters
— Functioninitialize_emitters(params::DiffusionSMLMParams, photons::Float64=1000.0; override_count::Union{Nothing, Int}=nothing)
Create initial emitter positions for the simulation.
Arguments
params::DiffusionSMLMParams
: Simulation parametersphotons::Float64=1000.0
: Number of photons per emitteroverride_count::Union{Nothing, Int}=nothing
: Optional override for the number of molecules
Returns
Vector{<:AbstractDiffusingEmitter}
: Vector of initialized emitters
SMLMSim.InteractionDiffusion.should_dissociate
— Methodshould_dissociate(e::AbstractDiffusingEmitter, k_off::Float64, dt::Float64)
Check if a dimer should dissociate based on stochastic rate.
Arguments
e::AbstractDiffusingEmitter
: Emitter to checkk_off::Float64
: Dissociation rate (s⁻¹)dt::Float64
: Time step (s)
Returns
Bool
: True if dimer should dissociate
SMLMSim.InteractionDiffusion.track_state_changes
— Methodtrack_state_changes(smld::BasicSMLD)
Track state changes of molecules over time.
Arguments
smld::BasicSMLD
: SMLD containing all emitters
Returns
Dict{Int, Vector{Tuple{Int, Symbol}}}
: Dictionary mapping molecule IDs to vectors of (frame, state) pairs
Example
# Track state changes of molecules
state_history = track_state_changes(smld)
# Plot state history for molecule 1
history = state_history[1]
frames = [h[1] for h in history]
states = [h[2] for h in history]
SMLMSim.InteractionDiffusion.update_system
— Methodupdate_system(emitters::Vector{<:AbstractDiffusingEmitter}, params::DiffusionSMLMParams, dt::Float64)
Update all emitters based on Smoluchowski diffusion dynamics.
Arguments
emitters::Vector{<:AbstractDiffusingEmitter}
: Current emitters stateparams::DiffusionSMLMParams
: Simulation parametersdt::Float64
: Time step
Returns
Vector{<:AbstractDiffusingEmitter}
: Updated emitters
SMLMSim.simulate
— Methodsimulate(params::DiffusionSMLMParams;
starting_conditions::Union{Nothing, SMLD, Vector{<:AbstractDiffusingEmitter}}=nothing,
photons::Float64=1000.0,
override_count::Union{Nothing, Int}=nothing,
kwargs...)
Run a Smoluchowski diffusion simulation and return a BasicSMLD object with emitters that have both frame number and timestamp information.
Arguments
params::DiffusionSMLMParams
: Simulation parametersstarting_conditions::Union{Nothing, SMLD, Vector{<:AbstractDiffusingEmitter}}
: Optional starting emittersphotons::Float64=1000.0
: Number of photons per emitteroverride_count::Union{Nothing, Int}=nothing
: Optional override for the number of molecules
Keyword Arguments
- Any additional parameters are ignored (allows unified interface with other simulate methods)
Returns
BasicSMLD
: Single SMLD object containing all emitters across all frames
Example
# Set up parameters with camera settings
params = DiffusionSMLMParams(
density = 0.5, # molecules per μm²
box_size = 10.0, # μm
camera_framerate = 20.0, # 20 fps
camera_exposure = 0.04 # 40ms exposure
)
# Run basic simulation
smld = simulate(params)
# Run simulation with exactly 2 particles
smld = simulate(params; override_count=2)
# Use previous simulation state as starting conditions for a new simulation
final_frame = maximum([e.frame for e in smld.emitters])
final_state_emitters = filter(e -> e.frame == final_frame, smld.emitters)
smld_continued = simulate(params; starting_conditions=final_state_emitters)
SMLMSim.CameraImages
— ModuleCameraImages
Module for generating simulated camera images from SMLM data.
This module provides functions to:
- Generate ideal camera images by integrating emitter photons over a PSF.
- Add realistic camera noise (e.g., Poisson noise).
Usage
using SMLMSim.CameraImages
SMLMSim.CameraImages.gen_image
— Methodgen_image(smld::SMLD, psf::AbstractPSF, frame::Int; kwargs...) -> Matrix{T} where T<:Real
Generate a single camera image for a specific frame from SMLD data. See gen_images
for full documentation of parameters.
Returns
- A 2D camera image as Matrix{T} where T matches the type of emitter.photons
SMLMSim.CameraImages.gen_images
— Methodgen_images(smld::SMLD, psf::AbstractPSF; kwargs...) -> Array{T, 3} where T<:Real
Generate camera images from SMLD data using the specified PSF model.
Arguments
smld::SMLD
: Single molecule localization data containerpsf::AbstractPSF
: Point spread function model
Keyword arguments
dataset::Int=1
: Dataset number to use from SMLDframes=nothing
: Specific frames to generate (default: all frames in smld.n_frames)support::Union{Real,Tuple{<:Real,<:Real,<:Real,<:Real}}=Inf
: PSF support region size:Inf
(default): Calculate PSF over the entire image (most accurate but slowest)Real
: Circular region with specified radius (in microns) around each emitterTuple{<:Real,<:Real,<:Real,<:Real}
: Explicit region as (xmin, xmax, ymin, ymax) in microns
sampling::Int=2
: Supersampling factor for PSF integrationthreaded::Bool=true
: Enable multithreading for faster computationbg::Float64=0.0
: Background signal level (photons per pixel)poisson_noise::Bool=false
: Apply Poisson noisecamera_noise::Bool=false
: Apply camera read noise (Note: This feature is not yet implemented)
Returns
- 3D array of camera images with dimensions [height, width, num_frames]
- The element type T matches the type of emitter.photons (typically Float64)
Performance Note
For the support
parameter, using a finite radius (typically 3-5× the PSF width) provides a good balance between accuracy and performance. For example, with a PSF width of 0.15μm, a support radius of 0.5-1.0μm is usually sufficient.
SMLMSim.CameraImages.poisson_noise!
— Methodpoisson_noise!(image::AbstractArray{T}) where T<:Real -> nothing
Apply Poisson noise to an image or image stack in-place.
Arguments
image::AbstractArray{T}
: Input image or image stack with values representing photon counts
Returns
nothing
: The input array is modified in-place
Details
Same as poisson_noise
, but modifies the input array directly instead of creating a new one. This can be more memory-efficient for large images or when processing multiple frames.
Example
# Add Poisson noise to an image in-place
image = ones(100, 100) * 100.0 # 100 expected photons per pixel
poisson_noise!(image) # image is modified in-place
SMLMSim.CameraImages.poisson_noise
— Methodpoisson_noise(image::AbstractArray{T}) where T<:Real -> Array{Float64}
Apply Poisson noise to an image or image stack.
Arguments
image::AbstractArray{T}
: Input image or image stack with values representing photon counts
Returns
- Array with same dimensions as input, with Poisson noise applied to each pixel
Details
This function creates a copy of the input array and applies Poisson noise to each pixel using the in-place poisson_noise! function.
Non-integer and negative values are handled specially:
- Non-integer values are accepted (treating them as expected photon counts)
- Negative values are clipped to zero before applying noise
- Zero values remain zero (as Poisson(0) always returns 0)
Example
# Add Poisson noise to a clean image
clean_image = ones(100, 100) * 100.0 # 100 expected photons per pixel
noisy_image = poisson_noise(clean_image)