@@ -208,17 +208,25 @@ The main simulation function with multiple methods for different simulation type
208208
209209``` julia
210210# Static SMLM simulation
211+ # First create simulation parameters
212+ params = StaticSMLMParams()
213+
214+ # Then run simulation
211215smld_true, smld_model, smld_noisy = simulate(
212- StaticSMLMParams ;
213- pattern:: Pattern = Nmer2D(),
214- molecule:: Molecule = GenericFluor(),
215- camera:: AbstractCamera = IdealCamera(128 , 128 , 0.1 )
216+ params ;
217+ pattern= Nmer2D(),
218+ molecule= GenericFluor(),
219+ camera= IdealCamera(128 , 128 , 0.1 )
216220)
217221
218222# Diffusion simulation
223+ # First create simulation parameters
224+ params_diff = DiffusionSMLMParams()
225+
226+ # Then run simulation
219227smld = simulate(
220- DiffusionSMLMParams ;
221- photons:: Float64 = 1000.0
228+ params_diff ;
229+ photons= 1000.0
222230)
223231```
224232
@@ -227,14 +235,22 @@ smld = simulate(
227235Generate kinetic blinking model from existing localization data.
228236
229237``` julia
238+ # Example of how to call kinetic_model
239+ # First create or obtain the required inputs
240+ smld_true = ... # Some BasicSMLD with true positions
241+ fluor = GenericFluor(1e4 , [- 10.0 10.0 ; 0.5 - 0.5 ]) # Fluorophore model
242+ nframes = 1000 # Number of frames
243+ framerate = 50.0 # Frames per second
244+
245+ # Call the function
230246smld_model = kinetic_model(
231- smld :: BasicSMLD ,
232- f :: Molecule ,
233- nframes:: Int ,
234- framerate:: Real ;
235- ndatasets:: Int = 1 ,
236- minphotons= 50.0 ,
237- state1:: Union{Int, Symbol} = :equilibrium
247+ smld_true, # BasicSMLD with emitter positions
248+ fluor, # Molecule with kinetic rates
249+ nframes, # Number of frames
250+ framerate; # Frames per second
251+ ndatasets= 1 , # Number of independent datasets
252+ minphotons= 50.0 , # Minimum photons for detection
253+ state1= :equilibrium # Initial state sampling
238254)
239255```
240256
@@ -243,11 +259,16 @@ smld_model = kinetic_model(
243259Add localization uncertainty to emitter positions based on photon counts.
244260
245261``` julia
246- # Add noise to 2D emitters
247- smld_noisy = apply_noise(smld_model, 0.13 ) # 130nm PSF width
262+ # Example usage of apply_noise
248263
249- # Add noise to 3D emitters
250- smld_noisy_3d = apply_noise(smld_model_3d, [0.13 , 0.13 , 0.39 ]) # [σx, σy, σz] in μm
264+ # First, you need smld_model from a previous step
265+ # For example, from the output of kinetic_model()
266+
267+ # For 2D emitters - add noise with 130nm PSF width
268+ smld_noisy = apply_noise(smld_model, 0.13 ) # 0.13 μm = 130nm PSF width
269+
270+ # For 3D emitters - specify PSF width in each dimension
271+ smld_noisy_3d = apply_noise(smld_model_3d, [0.13 , 0.13 , 0.39 ]) # [x, y, z] widths in μm
251272```
252273
253274### Image Generation
@@ -262,25 +283,46 @@ images = gen_images(
262283 psf:: AbstractPSF ;
263284 dataset:: Int = 1 , # Dataset number to use from SMLD
264285 frames= nothing , # Specific frames to generate (default: all frames)
265- support= Inf , # PSF support region size in μm
286+ support= Inf , # PSF support region size (see details below)
266287 sampling= 2 , # Supersampling factor for PSF integration
267288 threaded= true , # Enable multithreading
268289 bg= 0.0 , # Background signal level (photons per pixel)
269290 poisson_noise= false , # Apply Poisson noise
270291 camera_noise= false # Apply camera read noise
271292)
293+
294+ # The support parameter controls PSF computation region:
295+ # 1. Inf (default): Compute PSF over entire image (most accurate but slowest)
296+ support= Inf
297+
298+ # 2. Real number: Use circular region with given radius around each emitter
299+ # Typically 3-5× the PSF width is sufficient for accuracy with better performance
300+ support= 1.0 # 1.0 µm radius around each emitter
301+
302+ # 3. Tuple (xmin, xmax, ymin, ymax): Explicit region in microns
303+ support= (4.0 , 6.0 , 4.0 , 6.0 ) # Only compute PSF within this region
272304```
273305
274306#### gen_image
275307
276308Generate a single frame camera image.
277309
278310``` julia
279- image = gen_image(
280- smld:: SMLD ,
281- psf:: AbstractPSF ,
282- frame:: Int ;
283- # Same keyword arguments as gen_images
311+ # Example of generating a single frame image
312+
313+ # First, define variables
314+ smld = ... # Your SMLD data
315+ psf = GaussianPSF(0.15 ) # PSF model with 150nm width
316+ frame_number = 10 # The frame you want to generate
317+
318+ # Generate image for a specific frame
319+ single_frame = gen_image(
320+ smld, # SMLD data
321+ psf, # PSF model
322+ frame_number; # Frame to generate
323+ support= 1.0 , # Same keyword arguments as gen_images
324+ bg= 5.0 ,
325+ poisson_noise= true
284326)
285327```
286328
@@ -289,6 +331,12 @@ image = gen_image(
289331#### Diffusion Analysis
290332
291333``` julia
334+ # Example usage of diffusion analysis functions
335+
336+ # First, run a diffusion simulation
337+ params = DiffusionSMLMParams()
338+ smld = simulate(params)
339+
292340# Extract dimers from diffusion simulation
293341dimer_smld = get_dimers(smld)
294342
@@ -308,31 +356,54 @@ state_history = track_state_changes(smld)
308356#### Track Utilities
309357
310358``` julia
359+ # Example usage of track utilities
360+
361+ # First, run a simulation
362+ params = StaticSMLMParams()
363+ smld_true, smld_model, smld_noisy = simulate(params)
364+
365+ # Specify a track ID to extract
366+ track_id = 1 # ID of the track to extract
367+
311368# Get a specific track by ID
312- track_smld = get_track(smld , track_id)
369+ track_smld = get_track(smld_noisy , track_id)
313370
314371# Get number of unique tracks
315- n_tracks = get_num_tracks(smld )
372+ n_tracks = get_num_tracks(smld_noisy )
316373
317374# Get all tracks as separate SMLDs
318- track_smlds = get_tracks(smld )
375+ track_smlds = get_tracks(smld_noisy )
319376```
320377
321378### Pattern Manipulation
322379
323380``` julia
324- # Rotate a 2D pattern
325- rotate!(pattern2d, π/ 4 ) # Rotate 45 degrees
381+ # Example usage of pattern manipulation
382+
383+ # Create patterns
384+ pattern2d = Nmer2D(n= 6 , d= 0.2 )
385+ pattern3d = Nmer3D(n= 8 , d= 0.15 )
326386
327- # Rotate a 3D pattern with Euler angles
387+ # Rotate a 2D pattern by 45 degrees
388+ rotate!(pattern2d, π/ 4 )
389+
390+ # Rotate a 3D pattern with Euler angles (ZYZ convention)
328391rotate!(pattern3d, π/ 4 , π/ 6 , π/ 3 ) # α, β, γ angles
329392
330393# Rotate a 3D pattern with a rotation matrix
394+ θ = π/ 2 # 90 degrees
331395R = [cos(θ) - sin(θ) 0 ; sin(θ) cos(θ) 0 ; 0 0 1 ] # Z-axis rotation
332396rotate!(pattern3d, R)
333397
334- # Generate random pattern distribution
335- x, y = uniform2D(density, pattern, field_x, field_y)
398+ # Generate random pattern distribution in a field
399+ field_x = 10.0 # μm
400+ field_y = 10.0 # μm
401+ density = 1.0 # patterns per μm²
402+
403+ # Get coordinates for 2D distribution
404+ x, y = uniform2D(density, pattern2d, field_x, field_y)
405+
406+ # Get coordinates for 3D distribution
336407x, y, z = uniform3D(density, pattern3d, field_x, field_y, zrange= [- 2.0 , 2.0 ])
337408```
338409
@@ -367,9 +438,12 @@ smld_true, smld_model, smld_noisy = simulate(
367438 molecule= fluor
368439)
369440
370- # 5. Create microscope images
441+ # 5. Create microscope images with efficient PSF support
371442psf = GaussianPSF(0.15 ) # 150nm PSF width
372- images = gen_images(smld_model, psf; poisson_noise= true )
443+ images = gen_images(smld_model, psf;
444+ support= 1.0 , # 1.0 μm radius around each emitter
445+ poisson_noise= true # Add realistic photon counting noise
446+ )
373447```
374448
375449### Diffusion Simulation Workflow
@@ -397,9 +471,13 @@ smld = simulate(params)
397471dimer_smld = get_dimers(smld)
398472frames, fractions = analyze_dimer_fraction(smld)
399473
400- # 4. Generate microscope images
474+ # 4. Generate microscope images with finite PSF support
401475psf = GaussianPSF(0.15 ) # 150nm PSF width
402- images = gen_images(smld, psf; bg= 5.0 , poisson_noise= true )
476+ images = gen_images(smld, psf;
477+ support= 1.0 , # 1.0 μm PSF support radius (faster)
478+ bg= 5.0 , # Background photons per pixel
479+ poisson_noise= true # Add realistic photon counting noise
480+ )
403481```
404482
405483## Complete Examples
@@ -425,8 +503,9 @@ smld_true, smld_model, smld_noisy = simulate(
425503# Create a PSF model
426504psf = GaussianPSF(0.15 ) # 150nm PSF width
427505
428- # Generate microscope images
506+ # Generate microscope images with finite PSF support
429507images = gen_images(smld_model, psf;
508+ support= 1.0 , # 1.0 μm PSF support radius (faster than Inf)
430509 bg= 5.0 , # 5 background photons per pixel
431510 poisson_noise= true # Add realistic photon counting noise
432511)
@@ -458,9 +537,13 @@ smld = simulate(params)
458537frames, dimer_fraction = analyze_dimer_fraction(smld)
459538avg_lifetime = analyze_dimer_lifetime(smld)
460539
461- # Generate microscope images
540+ # Generate microscope images with finite PSF support
462541psf = GaussianPSF(0.15 ) # 150nm PSF width
463- images = gen_images(smld, psf; bg= 2.0 , poisson_noise= true )
542+ images = gen_images(smld, psf;
543+ support= 1.0 , # 1.0 μm PSF support radius (faster)
544+ bg= 2.0 , # Background photons per pixel
545+ poisson_noise= true # Add realistic photon counting noise
546+ )
464547
465548println(" Simulation complete with $(length(smld. emitters)) emitters" )
466549println(" Average dimer fraction: $(mean(dimer_fraction)) " )
@@ -530,9 +613,25 @@ smld_true, smld_model, smld_noisy = simulate(
530613 camera= camera
531614)
532615
533- # Generate images with a 3D astigmatic PSF
534- psf = AstigmaticPSF(σ_x= 0.13 , σ_y= 0.13 , γ_x= 0.08 , γ_y= - 0.08 , z_range= [- 1.0 , 1.0 ])
535- images = gen_images(smld_model, psf; bg= 5.0 , poisson_noise= true )
616+ # Generate images with a 3D astigmatic PSF and finite support
617+ # Create a PSF with astigmatism using Zernike coefficients
618+ using MicroscopePSFs
619+ zc = ZernikeCoefficients(15 )
620+ zc. phase[6 ] = 0.5 # Add vertical astigmatism
621+ psf_scalar = ScalarPSF(1.4 , 0.532 , 1.52 ; zernike_coeffs= zc)
622+
623+ # Create SplinePSF for speed
624+ xy_sampling, z_sampling = 0.05 , 0.1
625+ x_range = y_range = - 1.0 : xy_sampling: 1.0
626+ z_range = - 1.0 : z_sampling: 1.0
627+ psf_spline = SplinePSF(psf_scalar, x_range, y_range, z_range)
628+
629+ # Generate images using the spline PSF with finite support
630+ images = gen_images(smld_model, psf_spline;
631+ support= 0.5 , # 0.5 μm PSF support radius for performance
632+ bg= 5.0 , # Background photons per pixel
633+ poisson_noise= true # Add realistic photon counting noise
634+ )
536635
537636println(" Generated $(length(smld_noisy. emitters)) localizations in 3D" )
538637```
0 commit comments