@@ -218,30 +218,36 @@ camera_scmos = SCMOSCamera(
218218
219219#### simulate
220220
221- The main simulation function with multiple methods for different simulation types.
221+ The main simulation function with multiple methods for different simulation types. All simulation functions return a ` (result, info) ` tuple.
222222
223223``` julia
224224# Static SMLM simulation
225225# First create simulation parameters
226226params = StaticSMLMParams()
227227
228- # Then run simulation
229- smld_true, smld_model, smld_noisy = simulate(
228+ # Then run simulation - returns (smld_noisy, SimInfo) tuple
229+ smld_noisy, info = simulate(
230230 params;
231231 pattern= Nmer2D(),
232232 molecule= GenericFluor(),
233233 camera= IdealCamera(128 , 128 , 0.1 )
234234)
235235
236+ # Access ground truth and kinetic model from info
237+ smld_true = info. smld_true # Ground truth positions
238+ smld_model = info. smld_model # Positions with blinking kinetics
239+ # info also contains: elapsed_ns, backend, device_id, n_frames, n_emitters, n_localizations
240+
236241# Diffusion simulation
237242# First create simulation parameters
238243params_diff = DiffusionSMLMParams()
239244
240- # Then run simulation
241- smld = simulate(
245+ # Then run simulation - returns (smld, SimInfo) tuple
246+ smld, info = simulate(
242247 params_diff;
243248 photons= 1000.0
244249)
250+ # info contains: elapsed_ns, backend, device_id, n_frames
245251```
246252
247253#### kinetic_model
@@ -289,10 +295,10 @@ smld_noisy_3d = apply_noise(smld_model_3d, [0.13, 0.13, 0.39]) # [x, y, z] widt
289295
290296#### gen_images
291297
292- Generate camera images from SMLD data using the specified PSF model.
298+ Generate camera images from SMLD data using the specified PSF model. Returns a ` (images, ImageInfo) ` tuple.
293299
294300``` julia
295- images = gen_images(
301+ images, img_info = gen_images(
296302 smld:: SMLD ,
297303 psf:: AbstractPSF ;
298304 dataset:: Int = 1 , # Dataset number to use from SMLD
@@ -307,6 +313,8 @@ images = gen_images(
307313 # - For IdealCamera: ignored (use poisson_noise instead)
308314)
309315
316+ # ImageInfo contains: elapsed_ns, backend, device_id, frames_generated, n_photons_total, output_size
317+
310318# The support parameter controls PSF computation region:
311319# 1. Inf (default): Compute PSF over entire image (most accurate but slowest)
312320support= Inf
@@ -321,18 +329,18 @@ support=(4.0, 6.0, 4.0, 6.0) # Only compute PSF within this region
321329# Example: sCMOS camera with realistic noise
322330camera_scmos = SCMOSCamera(128 , 128 , 0.1 , 1.6 )
323331smld = BasicSMLD(emitters, camera_scmos, n_frames, n_datasets)
324- images_scmos = gen_images(smld, psf, bg= 10.0 , camera_noise= true )
332+ images_scmos, img_info = gen_images(smld, psf, bg= 10.0 , camera_noise= true )
325333# Applies: QE → Poisson → read noise → gain → offset
326334
327335# Example: IdealCamera with Poisson noise only
328336camera_ideal = IdealCamera(128 , 128 , 0.1 )
329337smld = BasicSMLD(emitters, camera_ideal, n_frames, n_datasets)
330- images_poisson = gen_images(smld, psf, bg= 10.0 , poisson_noise= true )
338+ images_poisson, img_info = gen_images(smld, psf, bg= 10.0 , poisson_noise= true )
331339```
332340
333341#### gen_image
334342
335- Generate a single frame camera image.
343+ Generate a single frame camera image. Returns a ` (image, ImageInfo) ` tuple.
336344
337345``` julia
338346# Example of generating a single frame image
@@ -342,9 +350,9 @@ smld = ... # Your SMLD data
342350psf = GaussianPSF(0.15 ) # PSF model with 150nm width
343351frame_number = 10 # The frame you want to generate
344352
345- # Generate image for a specific frame
346- single_frame = gen_image(
347- smld, # SMLD data
353+ # Generate image for a specific frame - returns (image, ImageInfo) tuple
354+ single_frame, img_info = gen_image(
355+ smld, # SMLD data
348356 psf, # PSF model
349357 frame_number; # Frame to generate
350358 support= 1.0 , # Same keyword arguments as gen_images
@@ -387,7 +395,7 @@ state_history = track_state_changes(smld)
387395
388396# First, run a simulation
389397params = StaticSMLMParams()
390- smld_true, smld_model, smld_noisy = simulate(params)
398+ smld_noisy, info = simulate(params)
391399
392400# Specify a track ID to extract
393401track_id = 1 # ID of the track to extract
@@ -441,7 +449,7 @@ x, y, z = uniform3D(density, pattern3d, field_x, field_y, zrange=[-2.0, 2.0])
4414491 . Define simulation parameters
4424502 . Create a pattern (or use default)
4434513 . Define a fluorophore model (or use default)
444- 4 . Run simulation to get true positions, kinetic model, and noisy localizations
452+ 4 . Run simulation to get noisy localizations and info (containing ground truth)
4454535 . Generate microscope images or analyze the data
446454
447455``` julia
@@ -458,16 +466,17 @@ pattern = Nmer2D(n=6, d=0.2) # hexamer with 200nm diameter
458466# 3. Define fluorophore model
459467fluor = GenericFluor(photons= 1e5 , k_off= 50.0 , k_on= 1e-2 )
460468
461- # 4. Run simulation
462- smld_true, smld_model, smld_noisy = simulate(
469+ # 4. Run simulation - returns (smld_noisy, SimInfo) tuple
470+ smld_noisy, info = simulate(
463471 params;
464472 pattern= pattern,
465473 molecule= fluor
466474)
475+ # Access ground truth from info: info.smld_true, info.smld_model
467476
468477# 5. Create microscope images with efficient PSF support
469478psf = GaussianPSF(0.15 ) # 150nm PSF width
470- images = gen_images(smld_model, psf;
479+ images, img_info = gen_images(info . smld_model, psf;
471480 support= 1.0 , # 1.0 μm radius around each emitter
472481 poisson_noise= true # Add realistic photon counting noise
473482)
@@ -491,8 +500,8 @@ params = DiffusionSMLMParams(
491500 t_max = 10.0 # s
492501)
493502
494- # 2. Run simulation
495- smld = simulate(params)
503+ # 2. Run simulation - returns (smld, SimInfo) tuple
504+ smld, sim_info = simulate(params)
496505
497506# 3. Analyze the results
498507dimer_smld = get_dimers(smld)
@@ -505,7 +514,7 @@ camera_scmos = SCMOSCamera(n_pixels, n_pixels, 0.1, 1.6)
505514smld_cam = BasicSMLD(smld. emitters, camera_scmos, smld. n_frames, 1 )
506515
507516psf = GaussianPSF(0.15 ) # 150nm PSF width
508- images = gen_images(smld_cam, psf;
517+ images, img_info = gen_images(smld_cam, psf;
509518 support= 1.0 , # 1.0 μm PSF support radius (faster)
510519 bg= 5.0 , # Background photons per pixel
511520 camera_noise= true # Full sCMOS noise model (QE, Poisson, read noise, gain, offset)
@@ -522,27 +531,32 @@ using MicroscopePSFs
522531
523532# Define a camera and simulation parameters
524533camera = IdealCamera(128 , 128 , 0.1 ) # 128×128 pixels, 100nm pixels
525- params = StaticSMLMParams(density= 1.0 , σ_psf= 0.13 , nframes= 1000 )
534+ params = StaticSMLMParams(density= 1.0 , σ_psf= 0.13 , nframes= 1000 )
526535
527- # Run simulation for an 8-molecule ring pattern
528- smld_true, smld_model, smld_noisy = simulate(
536+ # Run simulation for an 8-molecule ring pattern - returns (smld_noisy, SimInfo) tuple
537+ smld_noisy, info = simulate(
529538 params;
530539 pattern= Nmer2D(n= 8 , d= 0.1 ), # 100nm diameter ring
531540 molecule= GenericFluor(1e5 , [- 10.0 10.0 ; 0.5 - 0.5 ]), # γ=100,000, k_off=10, k_on=0.5
532541 camera= camera
533542)
534543
544+ # Access ground truth and kinetic model from info
545+ smld_true = info. smld_true
546+ smld_model = info. smld_model
547+
535548# Create a PSF model
536549psf = GaussianPSF(0.15 ) # 150nm PSF width
537550
538- # Generate microscope images with finite PSF support
539- images = gen_images(smld_model, psf;
551+ # Generate microscope images with finite PSF support - returns (images, ImageInfo) tuple
552+ images, img_info = gen_images(smld_model, psf;
540553 support= 1.0 , # 1.0 μm PSF support radius (faster than Inf)
541554 bg= 5.0 , # 5 background photons per pixel
542555 poisson_noise= true # Add realistic photon counting noise
543556)
544557
545558println(" Generated $(length(smld_noisy. emitters)) localizations and $(size(images,3 )) images." )
559+ println(" Image generation took $(img_info. elapsed_ns / 1e6 ) ms." )
546560```
547561
548562### Diffusion with Dimer Analysis
@@ -562,22 +576,23 @@ params = DiffusionSMLMParams(
562576 boundary = " reflecting" # Use reflecting boundaries
563577)
564578
565- # Run diffusion simulation
566- smld = simulate(params)
579+ # Run diffusion simulation - returns (smld, SimInfo) tuple
580+ smld, sim_info = simulate(params)
567581
568582# Analyze dimer formation
569583frames, dimer_fraction = analyze_dimer_fraction(smld)
570584avg_lifetime = analyze_dimer_lifetime(smld)
571585
572- # Generate microscope images with finite PSF support
586+ # Generate microscope images with finite PSF support - returns (images, ImageInfo) tuple
573587psf = GaussianPSF(0.15 ) # 150nm PSF width
574- images = gen_images(smld, psf;
588+ images, img_info = gen_images(smld, psf;
575589 support= 1.0 , # 1.0 μm PSF support radius (faster)
576590 bg= 2.0 , # Background photons per pixel
577591 poisson_noise= true # Add realistic photon counting noise
578592)
579593
580594println(" Simulation complete with $(length(smld. emitters)) emitters" )
595+ println(" Simulation took $(sim_info. elapsed_ns / 1e6 ) ms" )
581596println(" Average dimer fraction: $(mean(dimer_fraction)) " )
582597println(" Average dimer lifetime: $(avg_lifetime) seconds" )
583598```
@@ -638,12 +653,13 @@ params = StaticSMLMParams(
638653# Create custom pattern
639654double_ring = DoubleRing3D(n= 6 , d1= 0.15 , d2= 0.3 , z1= - 0.3 , z2= 0.3 )
640655
641- # Run simulation
642- smld_true, smld_model, smld_noisy = simulate(
656+ # Run simulation - returns (smld_noisy, SimInfo) tuple
657+ smld_noisy, info = simulate(
643658 params;
644659 pattern= double_ring,
645660 camera= camera
646661)
662+ smld_model = info. smld_model
647663
648664# Generate images with a 3D astigmatic PSF and finite support
649665# Create a PSF with astigmatism using Zernike coefficients
@@ -658,12 +674,13 @@ x_range = y_range = -1.0:xy_sampling:1.0
658674z_range = - 1.0 : z_sampling: 1.0
659675psf_spline = SplinePSF(psf_scalar, x_range, y_range, z_range)
660676
661- # Generate images using the spline PSF with finite support
662- images = gen_images(smld_model, psf_spline;
677+ # Generate images using the spline PSF with finite support - returns (images, ImageInfo) tuple
678+ images, img_info = gen_images(smld_model, psf_spline;
663679 support= 0.5 , # 0.5 μm PSF support radius for performance
664680 bg= 5.0 , # Background photons per pixel
665681 poisson_noise= true # Add realistic photon counting noise
666682)
667683
668684println(" Generated $(length(smld_noisy. emitters)) localizations in 3D" )
685+ println(" Generated $(img_info. frames_generated) frames with $(img_info. n_photons_total) total photons" )
669686```
0 commit comments