@@ -15,11 +15,11 @@ using SMLMSim
1515using CairoMakie
1616
1717# Create camera with physical pixel size
18- camera = IdealCamera(128, 256 , 0.1) # 128×256 pixels, 100nm pixels
18+ camera = IdealCamera(128, 64 , 0.1) # 128×64 pixels, 100nm pixels
1919
2020# Create simulation parameters
2121params = StaticSMLMParams(
22- density = 1.0, # emitters per μm²
22+ density = 1.0, # patterns per μm²
2323 σ_psf = 0.13, # PSF width in μm
2424)
2525
@@ -56,26 +56,6 @@ scatter!(ax1, x_noisy, y_noisy,
5656 alpha=0.6
5757)
5858
59- Colorbar(fig[1, 2], colormap=:viridis, label="Photons")
60-
61- # Temporal color-coding in second plot
62- ax2 = Axis(fig[2, 1],
63- title="Temporal Color-Coding",
64- xlabel="x (μm)",
65- ylabel="y (μm)",
66- aspect=DataAspect(),
67- yreversed=true
68- )
69-
70- scatter!(ax2, x_noisy, y_noisy,
71- color=frame_nums,
72- colormap=:plasma,
73- markersize=4,
74- alpha=0.6
75- )
76-
77- Colorbar(fig[2, 2], colormap=:plasma, label="Frame Number")
78-
7959# Return the figure
8060fig
8161
@@ -120,8 +100,7 @@ ax3d = Axis3(fig[1, 1],
120100 xlabel="x (μm)",
121101 ylabel="y (μm)",
122102 zlabel="z (μm)",
123- title="3D SMLM Simulation",
124- aspect=(1, 1, 1)
103+ title="3D SMLM Simulation"
125104)
126105
127106# Plot localizations with z-dependent color
@@ -132,28 +111,6 @@ scatter!(ax3d, x, y, z,
132111 alpha=0.6
133112)
134113
135- Colorbar(fig[1, 2], colormap=:viridis, label="z position (μm)")
136-
137- # Create 2D projections
138- ax_xy = Axis(fig[2, 1],
139- title="XY Projection",
140- xlabel="x (μm)",
141- ylabel="y (μm)",
142- aspect=DataAspect(),
143- yreversed=true
144- )
145-
146- ax_xz = Axis(fig[2, 2],
147- title="XZ Projection",
148- xlabel="x (μm)",
149- ylabel="z (μm)",
150- aspect=DataAspect()
151- )
152-
153- scatter!(ax_xy, x, y, color=z, colormap=:viridis, markersize=3, alpha=0.6)
154- scatter!(ax_xz, x, z, color=z, colormap=:viridis, markersize=3, alpha=0.6)
155-
156- # Return the figure
157114fig
158115
159116```
@@ -172,7 +129,7 @@ camera = IdealCamera(128, 128, 0.1) # 128×128 pixels, 100nm pixels
172129
173130# Create simulation parameters
174131params = StaticSMLMParams(
175- density = 0.5 , # patterns per μm²
132+ density = 2.0 , # patterns per μm²
176133 σ_psf = 0.13, # 130nm PSF width
177134 nframes = 100, # 100 frames
178135 framerate = 20.0 # 20 fps
@@ -193,7 +150,7 @@ psf = MicroscopePSFs.GaussianPSF(0.15) # 150nm PSF width
193150# naturally introduces noise, so using smld_noisy would apply noise twice
194151# Generate image stack from emitter data with Poisson noise
195152images = gen_images(smld_model, psf;
196- bg=10 .0, # background photons per pixel
153+ bg=5 .0, # background photons per pixel
197154 poisson_noise=true # add realistic shot noise
198155)
199156
@@ -230,145 +187,13 @@ scatter!(ax2, x, y,
230187 alpha=0.8
231188)
232189
233- # Set same limits as the image
234- limits!(ax2, 0, 12.8, 0, 12.8) # 128 pixels * 0.1 μm = 12.8 μm
235-
236-
237190# Return the figure
238191fig
239192
240193```
241194
242-
243195The resulting ` images ` is a 3D array with dimensions ` [height, width, frames] ` that can be used for visualization, algorithm testing, or benchmarking localization software.
244196
245- ## Customizing Photophysics
246-
247- This example demonstrates customizing the photophysical properties of fluorophores.
248-
249- ``` @example
250- using SMLMSim
251- using CairoMakie
252-
253- # Create camera
254- camera = IdealCamera(128, 128, 0.1)
255-
256- # Define different fluorophore models
257- # 1. Slow blinking (long on/off times)
258- fluor_slow = GenericFluor(; photons=10000.0, k_off=0.5, k_on=0.05) # Slow rates
259-
260- # 2. Fast blinking (short on/off times)
261- fluor_fast = GenericFluor(; photons=10000.0, k_off=50.0, k_on=5.0) # Fast rates
262-
263- # 3. Three-state model (using direct constructor for advanced models)
264- # Note: This example uses internal format and should be adapted for your use case
265- fluor_bleach = GenericFluor(; photons=10000.0, k_off=10.0, k_on=1.0)
266-
267- # Create simulation parameters
268- params = StaticSMLMParams(
269- density = 0.2,
270- nframes = 2000
271- )
272-
273- # Run simulations with different fluorophore models
274- _, _, smld_slow = simulate(
275- params;
276- pattern=Nmer2D(n=3, d=0.2),
277- molecule=fluor_slow,
278- camera=camera
279- )
280-
281- _, _, smld_fast = simulate(
282- params;
283- pattern=Nmer2D(n=3, d=0.2),
284- molecule=fluor_fast,
285- camera=camera
286- )
287-
288- _, _, smld_bleach = simulate(
289- params;
290- pattern=Nmer2D(n=3, d=0.2),
291- molecule=fluor_bleach,
292- camera=camera
293- )
294-
295- # Extract data for analysis
296- function get_time_traces(smld)
297- # Group emitters by track_id (original position)
298- emitters_by_track = Dict()
299- for e in smld.emitters
300- if !haskey(emitters_by_track, e.track_id)
301- emitters_by_track[e.track_id] = []
302- end
303- push!(emitters_by_track[e.track_id], e)
304- end
305-
306- # Get a representative trace (first track_id with emitters)
307- # Find first track with emitters
308- valid_tracks = filter(k -> !isempty(emitters_by_track[k]), collect(keys(emitters_by_track)))
309-
310- # If no valid tracks, return empty array
311- if isempty(valid_tracks)
312- return Float64[]
313- end
314-
315- first_track = minimum(valid_tracks)
316- emitters = emitters_by_track[first_track]
317-
318- max_frame = maximum([e.frame for e in emitters])
319- trace = zeros(max_frame)
320- for e in emitters
321- trace[e.frame] = e.photons
322- end
323-
324- return trace
325- end
326-
327- # Get traces for each model
328- trace_slow = get_time_traces(smld_slow)
329- trace_fast = get_time_traces(smld_fast)
330- trace_bleach = get_time_traces(smld_bleach)
331-
332- # Visualization
333- fig = Figure(size=(900, 700))
334-
335- # Plot time traces
336- ax1 = Axis(fig[1, 1],
337- title="Slow Blinking",
338- xlabel="Frame",
339- ylabel="Photons"
340- )
341-
342- ax2 = Axis(fig[2, 1],
343- title="Fast Blinking",
344- xlabel="Frame",
345- ylabel="Photons"
346- )
347-
348- ax3 = Axis(fig[3, 1],
349- title="Photobleaching Model",
350- xlabel="Frame",
351- ylabel="Photons"
352- )
353-
354- # Plot traces
355- if !isempty(trace_slow)
356- stem!(ax1, 1:length(trace_slow), trace_slow)
357- end
358- if !isempty(trace_fast)
359- stem!(ax2, 1:length(trace_fast), trace_fast)
360- end
361- if !isempty(trace_bleach)
362- stem!(ax3, 1:length(trace_bleach), trace_bleach)
363- end
364-
365-
366- # Return the figure
367- fig
368-
369- ```
370-
371-
372197## Advanced: Custom Pattern
373198
374199This example demonstrates creating a custom pattern type for simulation.
@@ -415,10 +240,10 @@ function JitteredGrid2D(; nx=5, ny=5, dx=0.05, dy=0.05, jitter=0.01)
415240end
416241
417242# Create camera
418- camera = IdealCamera(128, 128 , 0.1)
243+ camera = IdealCamera(64, 64 , 0.1)
419244
420245# Create custom pattern
421- grid = JitteredGrid2D(nx=8, ny=8, dx=0.05, dy=0.05, jitter=0.01 )
246+ grid = JitteredGrid2D()
422247
423248# Create simulation parameters
424249params = StaticSMLMParams(
@@ -467,4 +292,3 @@ scatter!(ax2, x_noisy, y_noisy, color=photons, colormap=:viridis, markersize=3,
467292fig
468293
469294```
470-
0 commit comments