Skip to content

Commit ee26058

Browse files
kalidkeclaude
andcommitted
Add tuple-pattern return format for simulate and gen_images
BREAKING CHANGE: All simulation and image generation functions now return (output, info) tuples instead of single values or 3-tuples. Changes: - simulate(::StaticSMLMParams) returns (smld_noisy, SimInfo) - SimInfo contains smld_true, smld_model, timing, and counts - simulate(::DiffusionSMLMParams) returns (smld, SimInfo) - gen_images() returns (images, ImageInfo) - gen_image() returns (image, ImageInfo) New types: - SimInfo: elapsed_ns, backend, device_id, seed, smld_true, smld_model, n_patterns, n_emitters, n_localizations, n_frames - ImageInfo: elapsed_ns, backend, device_id, frames_generated, n_photons_total, output_size Bump version to 0.5.0 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1 parent 2bc3267 commit ee26058

File tree

15 files changed

+510
-195
lines changed

15 files changed

+510
-195
lines changed

Project.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
name = "SMLMSim"
22
uuid = "5a0a87e4-02d4-41f5-bf26-b8c94c784a04"
3-
version = "0.4.0"
3+
version = "0.5.0"
44
authors = ["klidke@unm.edu"]
55

66
[deps]

README.md

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -38,16 +38,17 @@ camera = IdealCamera(128, 128, 0.1) # 128×128 pixels, 100nm pixels
3838
params = StaticSMLMParams(density=1.0, σ_psf=0.13) # Density 1/μm², PSF 130nm
3939

4040
# Run simulation for an 8-molecule ring pattern
41-
smld_true, smld_model, smld_noisy = simulate(
41+
smld_noisy, info = simulate(
4242
params; # Use semicolon to separate positional and keyword arguments
4343
pattern=Nmer2D(n=8, d=0.1), # 100nm diameter ring
4444
camera=camera
4545
)
4646

4747
# smld_noisy contains realistic SMLM coordinates
48+
# info.smld_true and info.smld_model contain intermediate results
4849
println("Generated $(length(smld_noisy.emitters)) localizations.")
4950
```
50-
*Output:* `smld_true` (ground truth), `smld_model` (kinetics), `smld_noisy` (kinetics + noise).
51+
*Output:* `smld_noisy` (kinetics + noise), `info` (SimInfo with `smld_true`, `smld_model`, timing).
5152

5253
### Diffusion & Interaction Simulation
5354

@@ -69,7 +70,7 @@ params = DiffusionSMLMParams(
6970
)
7071

7172
# Run diffusion simulation
72-
smld = simulate(params) # Returns a BasicSMLD object with all emitters
73+
smld, info = simulate(params) # Returns (BasicSMLD, SimInfo)
7374

7475
println("Simulated diffusion for $(params.t_max) seconds.")
7576
# 'smld' can be used for analysis or image generation
@@ -111,12 +112,12 @@ using MicroscopePSFs # Needed for PSF types
111112
# Note: Frame timing is controlled by DiffusionSMLMParams (camera_framerate, camera_exposure)
112113
# Multiple simulation timesteps are automatically integrated during simulate()
113114
psf = GaussianPSF(0.15) # 150nm PSF width
114-
images = gen_images(smld, psf;
115+
images, img_info = gen_images(smld, psf;
115116
support=1.0, # PSF support radius in μm (faster than default Inf)
116117
poisson_noise=true # Add shot noise
117118
)
118119

119-
println("Generated $(size(images,3)) camera images.")
120+
println("Generated $(img_info.frames_generated) camera images.")
120121
```
121122

122123
### sCMOS Camera with Realistic Noise
@@ -132,7 +133,7 @@ camera_scmos = SCMOSCamera(128, 128, 0.1, 1.6)
132133

133134
# Run static simulation with sCMOS camera
134135
params = StaticSMLMParams(density=1.0, σ_psf=0.13)
135-
smld_true, smld_model, smld_noisy = simulate(
136+
smld_noisy, info = simulate(
136137
params,
137138
pattern=Nmer2D(n=8, d=0.1),
138139
camera=camera_scmos
@@ -141,11 +142,11 @@ smld_true, smld_model, smld_noisy = simulate(
141142
# Generate images with full sCMOS noise model
142143
# (quantum efficiency, Poisson, read noise, gain, offset)
143144
psf = GaussianPSF(0.15)
144-
images_scmos = gen_images(smld_noisy, psf, bg=10.0, camera_noise=true)
145+
images_scmos, img_info = gen_images(smld_noisy, psf, bg=10.0, camera_noise=true)
145146

146147
# For diffusion simulations
147148
diff_params = DiffusionSMLMParams(density=0.5, box_size=10.0)
148-
smld_diff = simulate(diff_params; camera=camera_scmos, override_count=10)
149+
smld_diff, diff_info = simulate(diff_params; camera=camera_scmos, override_count=10)
149150
```
150151

151152
The sCMOS noise model applies:
@@ -165,7 +166,7 @@ using MicroscopePSFs
165166
# --- Simulation Setup ---
166167
camera = IdealCamera(128, 128, 0.1) # 128×128 pixels, 100nm pixels
167168
params = StaticSMLMParams(density=1.0, σ_psf=0.13)
168-
smld_true, smld_model, smld_noisy = simulate(
169+
smld_noisy, info = simulate(
169170
params,
170171
pattern=Nmer2D(n=6, d=0.2), # Hexamer
171172
camera=camera
@@ -209,17 +210,17 @@ params = DiffusionSMLMParams(
209210
t_max = 0.5, # 0.5 second total
210211
camera_framerate = 100.0 # 100 fps
211212
)
212-
smld = simulate(params; camera=camera_scmos, photons=200.0)
213+
smld, info = simulate(params; camera=camera_scmos, photons=200.0)
213214

214215
# Generate images with full sCMOS noise model
215216
# (quantum efficiency, Poisson, read noise, gain, offset)
216217
psf = GaussianPSF(0.13) # 130nm PSF
217-
images_scmos = gen_images(smld, psf, bg=10.0, camera_noise=true)
218+
images_scmos, _ = gen_images(smld, psf, bg=10.0, camera_noise=true)
218219

219220
# For comparison: same data with ideal camera (Poisson noise only)
220221
camera_ideal = IdealCamera(64, 64, 0.1)
221222
smld_ideal = BasicSMLD(smld.emitters, camera_ideal, smld.n_frames, smld.n_datasets)
222-
images_ideal = gen_images(smld_ideal, psf, bg=10.0, poisson_noise=true)
223+
images_ideal, _ = gen_images(smld_ideal, psf, bg=10.0, poisson_noise=true)
223224

224225
# Compare statistics
225226
println("sCMOS: mean=$(round(mean(images_scmos), digits=1)) ADU, std=$(round(std(images_scmos), digits=1))")

0 commit comments

Comments
 (0)