Skip to content

Commit e3443ff

Browse files
authored
Beam groups (#12)
* move non-psf changes to seperate branch * finalize miniscope tutorial
1 parent f6e736f commit e3443ff

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+961
-360
lines changed

Project.toml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
name = "BeamletOptics"
22
uuid = "c387492b-ffec-4e51-9a46-bd230226031c"
33
authors = ["Hugo Uittenbosch <hugo.uittenbosch@dlr.de>, Oliver Kliebisch <oliver.kliebisch@dlr.de> and Thomas Dekorsy <thomas.dekorsy@dlr.de>"]
4-
version = "0.9.0"
5-
4+
version = "0.10.0"
65

76
[deps]
87
AbstractTrees = "1520ce14-60c1-5f80-bbc7-55ef81b5835c"
98
FileIO = "5789e2e9-d7fb-5bc7-8068-2c6fae9b9549"
9+
ForwardDiff = "f6369f11-7733-5829-9624-2563aa707210"
1010
GeometryBasics = "5c1252a2-5f33-56bf-86c9-59e7332b4326"
1111
InteractiveUtils = "b77e0a4c-d291-57a0-90e8-8db25a27a240"
1212
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
@@ -26,6 +26,7 @@ BeamletOpticsMakieExt = "Makie"
2626
AbstractTrees = "0.4"
2727
Aqua = "0.8"
2828
FileIO = "1"
29+
ForwardDiff = "0.10, 1.0.1"
2930
GeometryBasics = "0.5"
3031
InteractiveUtils = "1"
3132
LinearAlgebra = "1"

docs/src/assets/beam_renders/beam_showcase.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,12 +52,12 @@ render!(ax, m2)
5252
render!(ax, m3)
5353
render!(ax, prism; color=RGBAf(1, 1, 1, .25))
5454

55-
arrow!(ax, BMO.position(first(BMO.rays(beam))), BMO.direction(first(BMO.rays(beam))); scale=2)
55+
arrow!(ax, position(first(BMO.rays(beam))), BMO.direction(first(BMO.rays(beam))); scale=2)
5656

5757

5858
for _ray in BMO.rays(beam)
5959
dir = BMO.direction(_ray)
60-
pos = BMO.position(_ray)
60+
pos = position(_ray)
6161
arrow!(ax, pos, dir; scale=2)
6262
end
6363

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
using GLMakie, BeamletOptics
2+
3+
GLMakie.activate!(; ssao=true)
4+
5+
const BMO = BeamletOptics
6+
7+
include(joinpath(@__DIR__, "..", "render_utils.jl"))
8+
9+
## collimated source
10+
cs = CollimatedSource([0,0,0], [0,1,0], 15e-3; num_rings=3, num_rays=200)
11+
12+
cs_fig = Figure(; size=(600,200))
13+
display(cs_fig)
14+
cs_ax = LScene(cs_fig[1,1])
15+
hide_axis(cs_ax)
16+
17+
render!(cs_ax, cs, show_pos=true, flen=0.05, color=:red, render_every=1)
18+
19+
cs_view = [
20+
0.26513 0.964213 7.68482e-16 -0.0180273
21+
0.0488896 -0.0134432 0.998714 0.00108822
22+
0.962972 -0.264789 -0.0507042 -0.025119
23+
0.0 0.0 0.0 1.0
24+
]
25+
26+
set_view(cs_ax, cs_view)
27+
save("collimated_beam_source.png", cs_fig; px_per_unit=8, update = false)
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
using GLMakie, BeamletOptics
2+
3+
GLMakie.activate!(; ssao=true)
4+
5+
const BMO = BeamletOptics
6+
7+
include(joinpath(@__DIR__, "..", "render_utils.jl"))
8+
9+
## point source
10+
ps = PointSource([0,0,0], [0,1,0], deg2rad(10); num_rings=3, num_rays=200)
11+
12+
ps_fig = Figure(; size=(600,200))
13+
display(ps_fig)
14+
ps_ax = LScene(ps_fig[1,1])
15+
hide_axis(ps_ax)
16+
17+
render!(ps_ax, ps, show_pos=true, flen=0.1, color=:red)
18+
19+
ps_view = [
20+
0.00272773 0.999996 5.03287e-16 -0.0584386
21+
0.424361 -0.00115755 0.905492 2.95341e-5
22+
0.905489 -0.00246994 -0.424362 -0.04708
23+
0.0 0.0 0.0 1.0
24+
]
25+
26+
set_view(ps_ax, ps_view)
27+
save("point_beam_source.png", ps_fig; px_per_unit=8, update = false)

docs/src/assets/mi_assets/michelson_plots.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ hidedecorations!(heat2)
130130
hm = heatmap!(heat1, pd.x*1e3, pd.y*1e3, BeamletOptics.intensity(pd), colormap=:viridis)
131131

132132
zrotate3d!(m1, 1e-3)
133-
BeamletOptics.reset_detector!(pd)
133+
empty!(pd)
134134
solve_system!(system, beam)
135135

136136
hm = heatmap!(heat2, pd.x*1e3, pd.y*1e3, BeamletOptics.intensity(pd), colormap=:viridis)
@@ -148,7 +148,7 @@ n = 100
148148
P = zeros(n+1)
149149

150150
for i in eachindex(P)
151-
BeamletOptics.reset_detector!(pd)
151+
empty!(pd)
152152
solve_system!(system, beam)
153153
P[i] = BeamletOptics.optical_power(pd)
154154
# translate by Δy

docs/src/assets/ms_assets/miniscope_showcase.jl

Lines changed: 50 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ function objective_lens_2()
5050
surf_3 = SphericalSurface(-5.020mm, 2*2.380mm)
5151
dl11 = Lens(surf_1, surf_2, 0.5mm, NSF4)
5252
dl12 = Lens(surf_2, surf_3, 2.5mm, NLAK22)
53-
translate3d!(dl12, [0, BMO.thickness(dl11), 0])
53+
translate3d!(dl12, [0, thickness(dl11), 0])
5454
obj_lens_2 = DoubletLens(dl11, dl12)
5555
return obj_lens_2
5656
end
@@ -62,7 +62,7 @@ function tube_doublet()
6262
surf_3 = SphericalSurface(-14.413mm, 2*2.812mm, 2*3mm)
6363
dl21 = Lens(surf_1, surf_2, 3.4mm, NLAK22)
6464
dl22 = Lens(surf_2, surf_3, 1.0mm, NSF4)
65-
translate3d!(dl22, [0, BMO.thickness(dl21), 0])
65+
translate3d!(dl22, [0, thickness(dl21), 0])
6666
tube_lens = DoubletLens(dl21, dl22)
6767
return tube_lens
6868
end
@@ -71,8 +71,8 @@ function objective_group()
7171
obj_lens_1 = objective_lens_1()
7272
obj_lens_2 = objective_lens_2()
7373
tube_lens = tube_doublet()
74-
translate_to3d!(obj_lens_2, [0, BMO.position(obj_lens_1)[2] + BMO.thickness(obj_lens_1) + 3.344mm, 0])
75-
translate_to3d!(tube_lens, [0, BMO.position(obj_lens_2)[2] + BMO.thickness(obj_lens_2) + 2mm, 0])
74+
translate_to3d!(obj_lens_2, [0, position(obj_lens_1)[2] + thickness(obj_lens_1) + 3.344mm, 0])
75+
translate_to3d!(tube_lens, [0, position(obj_lens_2)[2] + thickness(obj_lens_2) + 2mm, 0])
7676
_objective_group = ObjectGroup([obj_lens_1, obj_lens_2, tube_lens])
7777
xrotate3d!(_objective_group, deg2rad(90))
7878
return _objective_group
@@ -106,8 +106,8 @@ function collection_group()
106106
NLASF44
107107
)
108108

109-
translate3d!(collect_lens, [0, BMO.position(ef_1)[2] + BMO.thickness(ef_1) + 0.1mm, 0])
110-
translate3d!(ef_2, [0, BMO.position(collect_lens)[2] + BMO.thickness(collect_lens) + 0.25mm, 0])
109+
translate3d!(collect_lens, [0, position(ef_1)[2] + thickness(ef_1) + 0.1mm, 0])
110+
translate3d!(ef_2, [0, position(collect_lens)[2] + thickness(collect_lens) + 0.25mm, 0])
111111

112112
collect_group = ObjectGroup([ef_1, collect_lens, ef_2])
113113

@@ -117,7 +117,7 @@ function collection_group()
117117
return collect_group
118118
end
119119

120-
optical_system() = System([objective_group(), dichroic_splitter(), collection_group()])
120+
optical_system_group() = ObjectGroup([objective_group(), dichroic_splitter(), collection_group()])
121121

122122
##
123123
miniscope = miniscope_body()
@@ -175,7 +175,7 @@ c_view = [
175175
set_view(ax, c_view)
176176
save("objective_lens_1.png", fig; px_per_unit=8, update = false)
177177

178-
##
178+
## lens 2 render
179179
fig = Figure(size=(600, 200))
180180
display(fig)
181181
ax = LScene(fig[1,1])
@@ -201,8 +201,8 @@ set_view(ax, c_view)
201201
save("objective_lens_2.png", fig; px_per_unit=8, update = false)
202202

203203
## full group render
204-
translate_to3d!(obj_lens_2, [0, BMO.position(obj_lens_1)[2] + BMO.thickness(obj_lens_1) + 3.344mm, 0])
205-
translate_to3d!(tube_lens, [0, BMO.position(obj_lens_2)[2] + BMO.thickness(obj_lens_2) + 2mm, 0])
204+
translate_to3d!(obj_lens_2, [0, position(obj_lens_1)[2] + thickness(obj_lens_1) + 3.344mm, 0])
205+
translate_to3d!(tube_lens, [0, position(obj_lens_2)[2] + thickness(obj_lens_2) + 2mm, 0])
206206

207207
fig = Figure(size=(600, 300))
208208
display(fig)
@@ -212,9 +212,9 @@ render!(ax, obj_lens_1, transparency=true, color=lens_color(0.5))
212212
render!(ax, obj_lens_2, transparency=true, color=lens_color(0.5))
213213
render!(ax, tube_lens, transparency=true, color=lens_color(0.5))
214214

215-
tp1 = BMO.position(obj_lens_1) + [0, -.5mm, 2mm]
216-
tp2 = BMO.position(obj_lens_2) + [0, .2mm, 3mm]
217-
tp3 = BMO.position(tube_lens) + [0, 1.3mm, 4mm]
215+
tp1 = position(obj_lens_1) + [0, -.5mm, 2mm]
216+
tp2 = position(obj_lens_2) + [0, .2mm, 3mm]
217+
tp3 = position(tube_lens) + [0, 1.3mm, 4mm]
218218

219219
text!(tp1, text="obj_lens_1")
220220
text!(tp2, text="obj_lens_2")
@@ -234,7 +234,7 @@ c_view = [
234234
set_view(ax, c_view)
235235
save("full_objective_lens.png", fig; px_per_unit=8, update = false)
236236

237-
##
237+
## full optical system render
238238
fig = Figure(size=(600,400))
239239
display(fig)
240240
ax = LScene(fig[1,1])
@@ -251,4 +251,39 @@ c_view = [
251251
]
252252

253253
set_view(ax, c_view)
254-
save("full_optical_system.png", fig; px_per_unit=8, update = false)
254+
save("full_optical_system.png", fig; px_per_unit=8, update = false)
255+
256+
##
257+
osg = optical_system_group()
258+
system = System([osg])
259+
260+
# for tutorial
261+
ps_green = PointSource([0, 0, -0.5mm], [0, 0, 1], deg2rad(20), λ_green, num_rays=1000, num_rings=5)
262+
ps_red = PointSource([0, 0, -0.5mm], [0, 0, 1], deg2rad(30), λ_red, num_rays=1000, num_rings=5)
263+
264+
solve_system!(system, ps_green)
265+
solve_system!(system, ps_red)
266+
267+
##
268+
fig = Figure(size=(600,200))
269+
ax = LScene(fig[1,1])
270+
hide_axis(ax)
271+
272+
render!(ax, system; color=lens_color())
273+
render!(ax, ps_green; color=RGBAf(0,1,0,1.00), render_every=5, flen=3mm, show_pos=false)
274+
render!(ax, ps_red; color=RGBAf(1,0,0,0.25), render_every=5, flen=3mm, show_pos=false)
275+
276+
display(fig)
277+
278+
set_orthographic(ax)
279+
280+
c_view = [
281+
0 0 1 -0.015
282+
0 -1 0 0
283+
1 0 0 -0.55
284+
0 0 0 1
285+
]
286+
287+
set_view(ax, c_view)
288+
289+
save("miniscope_trace.png", fig; px_per_unit=8, update = false)

docs/src/assets/ms_assets/ucla.jl

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ surf_3 = SphericalSurface(-5.020mm, 2*2.380mm)
3838
dl11 = Lens(surf_1, surf_2, 0.5mm, NBK7)
3939
dl12 = Lens(surf_2, surf_3, 2.5mm, NBK7)
4040

41-
translate3d!(dl12, [0, BMO.thickness(dl11), 0])
41+
translate3d!(dl12, [0, thickness(dl11), 0])
4242

4343
obj_lens_2 = DoubletLens(dl11, dl12)
4444

@@ -58,13 +58,13 @@ end
5858
dl21 = Lens(surf_1, surf_2, 3.4mm, NBK7)
5959
dl22 = Lens(surf_2, surf_3, 1.0mm, NBK7)
6060

61-
translate3d!(dl22, [0, BMO.thickness(dl21), 0])
61+
translate3d!(dl22, [0, thickness(dl21), 0])
6262

6363
tube_lens = DoubletLens(dl21, dl22)
6464

6565
## Objective group
66-
translate_to3d!(obj_lens_2, [0, BMO.position(obj_lens_1)[2] + BMO.thickness(obj_lens_1) + 3.344mm, 0])
67-
translate_to3d!(tube_lens, [0, BMO.position(obj_lens_2)[2] + BMO.thickness(obj_lens_2) + 2mm, 0])
66+
translate_to3d!(obj_lens_2, [0, position(obj_lens_1)[2] + thickness(obj_lens_1) + 3.344mm, 0])
67+
translate_to3d!(tube_lens, [0, position(obj_lens_2)[2] + thickness(obj_lens_2) + 2mm, 0])
6868

6969
objective_group = ObjectGroup([obj_lens_1, obj_lens_2, tube_lens])
7070

@@ -91,8 +91,8 @@ collect_lens = Lens(
9191
NBK7
9292
)
9393

94-
translate3d!(collect_lens, [0, BMO.position(ef_1)[2] + BMO.thickness(ef_1) + 0.1mm, 0])
95-
translate3d!(ef_2, [0, BMO.position(collect_lens)[2] + BMO.thickness(collect_lens) + 0.25mm, 0])
94+
translate3d!(collect_lens, [0, position(ef_1)[2] + thickness(ef_1) + 0.1mm, 0])
95+
translate3d!(ef_2, [0, position(collect_lens)[2] + thickness(collect_lens) + 0.25mm, 0])
9696

9797
collect_group = ObjectGroup([ef_1, collect_lens, ef_2])
9898

docs/src/assets/ray_renders/ray_showcase.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ zrotate3d!(cube, deg2rad(-30))
3131

3232
ray_pos = [0mm,5mm,5mm]
3333
ray_pos = [5mm,1mm,10mm]
34-
ray_dir = BMO.position(cube) - ray_pos + [5mm, 0, 1mm]
34+
ray_dir = position(cube) - ray_pos + [5mm, 0, 1mm]
3535
ray = Ray(ray_pos, ray_dir)
3636

3737
ray_dir = BMO.direction(ray)

docs/src/assets/spotdetector_showcase.jl

Lines changed: 12 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -24,34 +24,30 @@ render!(system_ax, system)
2424
beam = Beam([0,-50mm,0], [0,1,0], 1e-6)
2525

2626
aperture = BeamletOptics.inch*0.8
27+
num_rings = 20
28+
num_rays = 5000
2729

28-
zs = LinRange(-aperture/2, aperture/2, 25)
30+
cs = CollimatedSource([0,-50mm,0], [0,1,0], aperture, 1e-6; num_rings, num_rays)
2931

30-
for z in zs
31-
x = BeamletOptics.position(first(beam.rays))[1]
32-
y = BeamletOptics.position(first(beam.rays))[2]
33-
BeamletOptics.position!(first(beam.rays), Point3{Float64}(x, y, z))
34-
solve_system!(system, beam)
35-
render!(system_ax, beam, show_pos=true)
32+
t1 = @timed solve_system!(system, cs)
33+
34+
for i = 1:50:length(BeamletOptics.beams(cs))
35+
render!(system_ax, BeamletOptics.beams(cs)[i], color=:blue, show_pos=true)
3636
end
3737

3838
## render diagram
39-
n_rings = 20
40-
n_rays = 5000
41-
BeamletOptics.create_spot_diagram(system, beam, aperture; n_rings, n_rays)
42-
# Rerun for time without compile
43-
t1 = @timed BeamletOptics.create_spot_diagram(system, beam, aperture; n_rings, n_rays)
44-
4539
spot_fig = Figure(size=(600,400))
4640
spot_ax = Axis(spot_fig[1,1], aspect=1, xlabel="x [mm]", ylabel="y [mm]")
4741
sc = scatter!(spot_ax, sd.data, markersize=3, color=:blue)
4842

4943
extime = trunc(t1.time*1e3, digits=2)
5044

5145
leg_string = "
52-
# of traces: $n_rays \n
53-
# of rings: $n_rings \n
46+
# of traces: $num_rays \n
47+
# of rings: $num_rings \n
5448
Ex. Time: $extime ms \n
5549
"
5650

57-
Legend(spot_fig[1,2], [sc], [leg_string], "Quick stats.")
51+
Legend(spot_fig[1,2], [sc], [leg_string], "Quick stats.")
52+
53+
spot_fig

docs/src/basics/beams.md

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ beam_showcase_dir = joinpath(@__DIR__, "..", "assets", "beam_renders")
33
44
include(joinpath(beam_showcase_dir, "beam_showcase.jl"))
55
include(joinpath(beam_showcase_dir, "gb_showcase.jl"))
6+
include(joinpath(beam_showcase_dir, "collimated_sc.jl"))
7+
include(joinpath(beam_showcase_dir, "pointsource_sc.jl"))
68
```
79

810
# Beams
@@ -23,6 +25,39 @@ A ray tracing example through an arbitrary system using a [`Beam`](@ref) is show
2325

2426
![Beam structure](beam_showcase.png)
2527

28+
## Beam groups
29+
30+
For convenience, the [`BeamletOptics.AbstractBeamGroup`](@ref) offers a container-like interface for groups of [`Beam`](@ref)s as commonly used in other software packages. The following concrete implementations are currently provided:
31+
32+
```@repl
33+
using BeamletOptics # hide
34+
BeamletOptics.list_subtypes(BeamletOptics.AbstractBeamGroup);
35+
```
36+
37+
Refer to the following sections for convenience constructors to generate the sources listed above.
38+
39+
### Collimated beam source
40+
41+
The collimated beam source is ideal to model light coming from a focal plane at infinity. This is useful for simulating plane wavefronts. You can define a collimated monochromatic [`Beam`](@ref) source as follows:
42+
43+
```@docs; canonical=false
44+
CollimatedSource(::AbstractArray{<:Real}, ::AbstractArray{<:Real}, ::Real, ::Real)
45+
```
46+
47+
![Collimated group of beams](collimated_beam_source.png)
48+
49+
### Point beam source
50+
51+
The `PointSource` type is used to model emission from a spatially localized source that radiates [`Beam`](@ref)s in a range of directions. This is commonly used to simulate conical emission patterns, such as light emerging from a fiber tip or a light source for a lens objective with a known focal distance. You can specify the origin and a propagation direction, which are then used to construct the monochromatic `PointSource`.
52+
53+
```@docs; canonical=false
54+
PointSource(::AbstractArray{<:Real}, ::AbstractArray{<:Real}, ::Real, ::Real)
55+
```
56+
57+
Below you can find an exemplary illustration of a `PointSource`.
58+
59+
![Point source of beams](point_beam_source.png)
60+
2661
## Gaussian beamlet
2762

2863
Lasers are common devices in modern optical laboratories. Modeling their propagation through an optical setup can be of interest when planning new experiments. Geometrical ray tracing struggles to capture the propagation of a laser beam correctly, since it can not inherently capture the wave nature of e.g. the [Gaussian beam](https://www.rp-photonics.com/gaussian_beams.html).

0 commit comments

Comments
 (0)