Examples
Pluto Notebooks
The OpticSim package comes with several Pluto notebooks (code snippets are coming soon) that allow the user to change and run sample code and view the results in real-time. We highly recommend for you to try these out. The notebooks are located in the samples folder, and you can try them by running:
import OpticSim.NotebooksUtils as NB # the **as** option was added in Julia v1.6
NB.run_sample("EmittersIntro.jl")The run_sample method will copy the notebook to your current folder (if it does not exist) and launch Pluto to run the notebook in the browser.
Cooke Triplet
using OpticSim
using DataFrames
sys = AxisymmetricOpticalSystem(
DataFrame(Surface = [:Object, 1, 2, 3, :Stop, 5, 6, :Image],
Radius = [Inf, 26.777, 66.604, -35.571, 35.571, 35.571, -26.777, Inf],
Thickness = [Inf, 4.0, 2.0, 4.0, 2.0, 4.0, 44.748, missing],
Material = [OpticSim.GlassCat.Air, OpticSim.GlassCat.SCHOTT.N_SK16, OpticSim.GlassCat.Air, OpticSim.GlassCat.SCHOTT.N_SF2, OpticSim.GlassCat.Air, OpticSim.GlassCat.SCHOTT.N_SK16, OpticSim.GlassCat.Air, missing],
SemiDiameter = [Inf, 8.580, 7.513, 7.054, 6.033, 7.003, 7.506, 15.0]))
@show sys
f1 = HexapolarField(sys, collimated = true, samples = 4, sourcenum = 1)
f2 = HexapolarField(sys, collimated = true, samples = 4, sourceangle = -10 / 180 * π, sourcenum = 2)
Vis.drawtracerays(sys, raygenerator = f1, test = true, trackallrays = true, colorbysourcenum = true, resolution = (1000, 700))
Vis.drawtracerays!(sys, raygenerator = f2, test = true, trackallrays = true, colorbysourcenum = true)sys = 8×5 DataFrame
Row │ Surface Radius Thickness Material SemiDiameter
│ Any Float64 Float64? Abstract…? Float64
─────┼────────────────────────────────────────────────────────────
1 │ Object Inf Inf Air Inf
2 │ 1 26.777 4.0 SCHOTT.N_SK16 8.58
3 │ 2 66.604 2.0 Air 7.513
4 │ 3 -35.571 4.0 SCHOTT.N_SF2 7.054
5 │ Stop 35.571 2.0 Air 6.033
6 │ 5 35.571 4.0 SCHOTT.N_SK16 7.003
7 │ 6 -26.777 44.748 Air 7.506
8 │ Image Inf missing missing 15.0
Zoom Lens
using OpticSim
using DataFrames
function zoom_lens(pos = 1)
if pos == 0
stop = 2.89
zoom = 9.48
dist = 4.46970613
elseif pos == 1
stop = 3.99
zoom = 4.48
dist = 21.21
else
stop = 4.90
zoom = 2.00
dist = 43.81
end
return AxisymmetricOpticalSystem{Float64}(
DataFrame(Surface = [:Object, :Stop, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, :Image],
Radius = [Inf64, Inf64, -1.6202203499676E+01, -4.8875855327468E+01, 1.5666614444619E+01, -4.2955326460481E+01, 1.0869565217391E+02, 2.3623907394283E+01, -1.6059097478722E+01, -4.2553191489362E+02, -3.5435861091425E+01, -1.4146272457208E+01, -2.5125628140704E+02, -2.2502250225023E+01, -1.0583130489999E+01, -4.4444444444444E+01, Inf64],
Aspherics = [missing, missing, missing, missing, missing, [(4, 1.03860000000E-04), (6, 1.42090000000E-07), (8, -8.84950000000E-09), (10, 1.24770000000E-10), (12, -1.03670000000E-12), (14, 3.65560000000E-15)], missing, missing, [(4, 4.27210000000E-05), (6, 1.24840000000E-07), (8, 9.70790000000E-09), (10, -1.84440000000E-10), (12, 1.86440000000E-12), (14, -7.79750000000E-15)], [(4, 1.13390000000E-04), (6, 4.81650000000E-07), (8, 1.87780000000E-08), (10, -5.75710000000E-10), (12, 8.99940000000E-12), (14, -4.67680000000E-14)], missing, missing, missing, missing, missing, missing, missing],
Thickness = [Inf64, 0.0, 5.18, 0.10, 4.40, 0.16, 1.0, 4.96, zoom, 4.04, 1.35, 1.0, 2.80, 3.0, 1.22, dist, missing],
Material = [OpticSim.GlassCat.Air, OpticSim.GlassCat.Air, OpticSim.GlassCat.OHARA.S_LAH66, OpticSim.GlassCat.Air, OpticSim.GlassCat.NIKON.LLF6, OpticSim.GlassCat.Air, OpticSim.GlassCat.OHARA.S_TIH6, OpticSim.GlassCat.OHARA.S_FSL5, OpticSim.GlassCat.Air, OpticSim.GlassCat.OHARA.S_FSL5, OpticSim.GlassCat.Air, OpticSim.GlassCat.OHARA.S_LAL8, OpticSim.GlassCat.OHARA.S_FSL5, OpticSim.GlassCat.Air, OpticSim.GlassCat.OHARA.S_LAH66, OpticSim.GlassCat.Air, missing],
SemiDiameter = [Inf64, stop, 3.85433218451, 3.85433218451, 4.36304692871, 4.36304692871, 4.72505505439, 4.72505505439, 4.72505505439, 4.45240784026, 4.45240784026, 4.50974054117, 4.50974054117, 4.50974054117, 4.76271114409, 4.76271114409, 15.0]))
end
@show zoom_lens(0)
Vis.drawtracerays(zoom_lens(0), test = true, trackallrays = true, numdivisions = 50, resolution = (1200, 600))
Vis.drawtracerays(zoom_lens(1), test = true, trackallrays = true, numdivisions = 50, resolution = (1200, 600))
Vis.drawtracerays(zoom_lens(2), test = true, trackallrays = true, numdivisions = 50, resolution = (1200, 600))zoom_lens(0) = 17×6 DataFrame
Row │ Surface Radius Aspherics Thickness Material SemiDiameter
│ Any Float64 Array…? Float64? Abstract…? Float64
─────┼───────────────────────────────────────────────────────────────────────────────────────────────────
1 │ Object Inf missing Inf Air Inf
2 │ Stop Inf missing 0.0 Air 2.89
3 │ 1 -16.2022 missing 5.18 OHARA.S_LAH66 3.85433
4 │ 2 -48.8759 missing 0.1 Air 3.85433
5 │ 3 15.6666 missing 4.4 NIKON.LLF6 4.36305
6 │ 4 -42.9553 [(4, 0.00010386), (6, 1.4209e-7)… 0.16 Air 4.36305
7 │ 5 108.696 missing 1.0 OHARA.S_TIH6 4.72506
8 │ 6 23.6239 missing 4.96 OHARA.S_FSL5 4.72506
9 │ 7 -16.0591 [(4, 4.2721e-5), (6, 1.2484e-7),… 9.48 Air 4.72506
10 │ 8 -425.532 [(4, 0.00011339), (6, 4.8165e-7)… 4.04 OHARA.S_FSL5 4.45241
11 │ 9 -35.4359 missing 1.35 Air 4.45241
12 │ 10 -14.1463 missing 1.0 OHARA.S_LAL8 4.50974
13 │ 11 -251.256 missing 2.8 OHARA.S_FSL5 4.50974
14 │ 12 -22.5023 missing 3.0 Air 4.50974
15 │ 13 -10.5831 missing 1.22 OHARA.S_LAH66 4.76271
16 │ 14 -44.4444 missing 4.46971 Air 4.76271
17 │ Image Inf missing missing missing 15.0

Schmidt Cassegrain Telescope
using OpticSim, OpticSim.Geometry
using StaticArrays
# glass entrance lens on telescope
topsurf = Plane(SVector(0.0, 0.0, 1.0), SVector(0.0, 0.0, 0.0), interface = FresnelInterface{Float64}(OpticSim.GlassCat.SCHOTT.N_BK7, OpticSim.GlassCat.Air), vishalfsizeu = 12.00075, vishalfsizev = 12.00075)
botsurf = AcceleratedParametricSurface(ZernikeSurface(12.00075, radius = -1.14659768e+4, aspherics = [(4, 3.68090959e-7), (6, 2.73643352e-11), (8, 3.20036892e-14)]), 17, interface = FresnelInterface{Float64}(OpticSim.GlassCat.SCHOTT.N_BK7, OpticSim.GlassCat.Air))
coverlens = csgintersection(leaf(Cylinder(12.00075, 1.4)), csgintersection(leaf(topsurf), leaf(botsurf, Transform(OpticSim.rotmatd(0, 180, 0), Vec3(0.0, 0.0, -0.65)))))
# big mirror with a hole in it
bigmirror = ConicLens(OpticSim.GlassCat.SCHOTT.N_BK7, -72.65, -95.2773500000134, 0.077235, Inf, 0.0, 0.2, 12.18263, frontsurfacereflectance = 1.0)
bigmirror = csgdifference(bigmirror, leaf(Cylinder(4.0, 0.3, interface = opaqueinterface()), translation(0.0, 0.0, -72.75)))
# small mirror supported on a spider
smallmirror = SphericalLens(OpticSim.GlassCat.SCHOTT.N_BK7, -40.65, Inf, -49.6845, 1.13365, 4.3223859, backsurfacereflectance = 1.0)
obscuration1 = Circle(4.5, SVector(0.0, 0.0, 1.0), SVector(0.0, 0.0, -40.649), interface = opaqueinterface())
obscurations2 = Spider(3, 0.5, 12.0, SVector(0.0, 0.0, -40.65))
# put it together with the detector
la = LensAssembly(coverlens(), bigmirror(), smallmirror(), obscuration1, obscurations2...)
det = Circle(3.0, SVector(0.0, 0.0, 1.0), SVector(0.0, 0.0, -92.4542988), interface = opaqueinterface())
tele = CSGOpticalSystem(la, det)
Vis.drawtracerays(tele, raygenerator = UniformOpticalSource(CollimatedSource(GridRectOriginPoints(5, 5, 10.0, 10.0, position = SVector(0.0, 0.0, 20.0))), 0.55), trackallrays = true, colorbynhits = true, test = true)
Lens Construction
using OpticSim, OpticSim.Geometry
using StaticArrays
topsurface = leaf(AcceleratedParametricSurface(QTypeSurface(9.0, radius = -25.0, conic = 0.3, αcoeffs = [(1, 0, 0.3), (1, 1, 1.0)], βcoeffs = [(1, 0, -0.1), (2, 0, 0.4), (3, 0, -0.6)], normradius = 9.5), interface = FresnelInterface{Float64}(OpticSim.GlassCat.SCHOTT.N_BK7, OpticSim.GlassCat.Air)), translation(0.0, 0.0, 5.0))
botsurface = leaf(Plane(0.0, 0.0, -1.0, 0.0, 0.0, -5.0, vishalfsizeu = 9.5, vishalfsizev = 9.5, interface = FresnelInterface{Float64}(OpticSim.GlassCat.SCHOTT.N_BK7, OpticSim.GlassCat.Air)))
barrel = leaf(Cylinder(9.0, 20.0, interface = FresnelInterface{Float64}(OpticSim.GlassCat.SCHOTT.N_BK7, OpticSim.GlassCat.Air, reflectance = zero(Float64), transmission = zero(Float64))))
lens = csgintersection(barrel, csgintersection(topsurface, botsurface))(Transform{Float64}(0.0, Float64(π), 0.0, 0.0, 0.0, -5.0))
sys = CSGOpticalSystem(LensAssembly(lens), Rectangle(15.0, 15.0, [0.0, 0.0, 1.0], [0.0, 0.0, -67.8], interface = opaqueinterface()))
Vis.drawtracerays(sys, test = true, trackallrays = true)
HOEs
Focusing
using OpticSim
using StaticArrays
rect = Rectangle(5.0, 5.0, SVector(0.0, 0.0, 1.0), SVector(0.0, 0.0, 0.0))
int = HologramInterface(SVector(0.0, -3.0, -20.0), ConvergingBeam, SVector(0.0, 0.0, -1.0), CollimatedBeam, 0.55, 9.0, OpticSim.GlassCat.Air, OpticSim.GlassCat.SCHOTT.N_BK7, OpticSim.GlassCat.Air, OpticSim.GlassCat.Air, OpticSim.GlassCat.Air, 0.05, false)
obj = HologramSurface(rect, int)
sys = CSGOpticalSystem(LensAssembly(obj), Rectangle(10.0, 10.0, SVector(0.0, 0.0, 1.0), SVector(0.0, 0.0, -25.0), interface = opaqueinterface()))
Vis.drawtracerays(sys; raygenerator = UniformOpticalSource(CollimatedSource(GridRectOriginPoints(5, 5, 3.0, 3.0, position = SVector(0.0, 0.0, 10.0), direction = SVector(0.0, 0.0, -1.0))), 0.55), trackallrays = true, rayfilter = nothing, test = true)
Collimating
using OpticSim
using StaticArrays
rect = Rectangle(5.0, 5.0, SVector(0.0, 0.0, 1.0), SVector(0.0, 0.0, 0.0))
int = HologramInterface(SVector(0.1, -0.05, -1.0), CollimatedBeam, SVector(0.0, 0.0, 10), DivergingBeam, 0.55, 9.0, OpticSim.GlassCat.Air, OpticSim.GlassCat.SCHOTT.N_BK7, OpticSim.GlassCat.Air, OpticSim.GlassCat.Air, OpticSim.GlassCat.Air, 0.05, false)
obj = HologramSurface(rect, int)
sys = CSGOpticalSystem(LensAssembly(obj), Rectangle(10.0, 10.0, SVector(0.0, 0.0, 1.0), SVector(0.0, 0.0, -25.0), interface = opaqueinterface()))
Vis.drawtracerays(sys; raygenerator = UniformOpticalSource(GridSource(OriginPoint{Float64}(1, position = SVector(0.0, 0.0, 10.0), direction = SVector(0.0, 0.0, -1.0)), 5, 5, π / 4, π / 4), 0.55), trackallrays = true, rayfilter = nothing, test = true)
Multi
using OpticSim
using StaticArrays
rect = Rectangle(5.0, 5.0, SVector(0.0, 0.0, 1.0), SVector(0.0, 0.0, 0.0))
int1 = HologramInterface(SVector(-5.0, 0.0, -20.0), ConvergingBeam, SVector(0.0, -1.0, -1.0), CollimatedBeam, 0.55, 100.0, OpticSim.GlassCat.Air, OpticSim.GlassCat.SCHOTT.N_BK7, OpticSim.GlassCat.Air, OpticSim.GlassCat.Air, OpticSim.GlassCat.Air, 0.05, false)
int2 = HologramInterface(SVector(5.0, 0.0, -20.0), ConvergingBeam, SVector(0.0, 1.0, -1.0), CollimatedBeam, 0.55, 100.0, OpticSim.GlassCat.Air, OpticSim.GlassCat.SCHOTT.N_BK7, OpticSim.GlassCat.Air, OpticSim.GlassCat.Air, OpticSim.GlassCat.Air, 0.05, false)
mint = MultiHologramInterface(int1, int2)
obj = MultiHologramSurface(rect, mint)
sys = CSGOpticalSystem(LensAssembly(obj), Rectangle(10.0, 10.0, SVector(0.0, 0.0, 1.0), SVector(0.0, 0.0, -20.0), interface = opaqueinterface()))
s1 = UniformOpticalSource(CollimatedSource(RandomRectOriginPoints(500, 3.0, 3.0, position = SVector(0.0, 3.0, 3.0), direction = SVector(0.0, -1.0, -1.0))), 0.55, sourcenum = 1)
s2 = UniformOpticalSource(CollimatedSource(RandomRectOriginPoints(500, 3.0, 3.0, position = SVector(0.0, -3.0, 3.0), direction = SVector(0.0, 1.0, -1.0))), 0.55, sourcenum = 2)
s3 = UniformOpticalSource(CollimatedSource(RandomRectOriginPoints(500, 3.0, 3.0, position = SVector(0.0, 0.0, 3.0), direction = SVector(0.0, 0.0, -1.0))), 0.55, sourcenum = 3)
Vis.drawtracerays(sys; raygenerator = s1, trackallrays = true, colorbysourcenum = true, rayfilter = nothing)
Vis.drawtracerays!(sys; raygenerator = s2, trackallrays = true, colorbysourcenum = true, rayfilter = nothing, drawgen = true)
Vis.drawtracerays!(sys; raygenerator = s3, trackallrays = true, colorbysourcenum = true, rayfilter = nothing, drawgen = true)┌ Warning: Order 1 not valid for this configuration, skipping this ray └ @ OpticSim ~/work/OpticSim.jl/OpticSim.jl/src/Optical/Grating.jl:282 ┌ Warning: Order 1 not valid for this configuration, skipping this ray └ @ OpticSim ~/work/OpticSim.jl/OpticSim.jl/src/Optical/Grating.jl:282

Deterministic Raytracing
using OpticSim
using OpticSim.GlassCat
using OpticSim.Geometry
using StaticArrays
function stacked_beamsplitters(interfacemode)
bs_1 = leaf(
leaf(
Cuboid(10.0, 20.0, 2.0;
interface = FresnelInterface{Float64}(SCHOTT.N_BK7, Air;
reflectance=0.5, transmission=0.5,
interfacemode=interfacemode)),
rotationX(pi/4)),
translation(0.0, 0.0, -30.0-2*sqrt(2)))
l1 = leaf(SphericalLens(SCHOTT.N_BK7, -70.0, 30.0, Inf, 5.0, 10.0), translation(0.0, -1.34, 0.0))
bs_2 = leaf(
leaf(
Cuboid(10.0, 20.0, 2.0;
interface = FresnelInterface{Float64}(SCHOTT.N_BK7, Air;
reflectance=0.5, transmission=0.5,
interfacemode=interfacemode)),
rotationX(pi/4)),
translation(0.0, 40.0, -30.0+2*sqrt(2)))
l2 = leaf(SphericalLens(SCHOTT.N_BK7, -70.0, 30.0, Inf, 5.0, 10.0), translation(0.0, 40.0, 0.0))
la = LensAssembly(bs_1(), l1(), bs_2(), l2())
detector = Rectangle(20.0, 40.0, SVector(0.0, 0.0, 1.0), SVector(0.0, 20.0, -130.0); interface = opaqueinterface())
CSGOpticalSystem(la, detector)
end
# nondeterministic
Vis.drawtracerays(stacked_beamsplitters(ReflectOrTransmit); trackallrays=true, rayfilter=nothing, colorbynhits=true)
# deterministic, all beamsplitters transmissive
Vis.drawtracerays(stacked_beamsplitters(Transmit); trackallrays=true, rayfilter=nothing, colorbynhits=true)
# deterministic, all beamsplitters reflective
Vis.drawtracerays(stacked_beamsplitters(Reflect); trackallrays=true, rayfilter=nothing, colorbynhits=true)
