Beam groups
For convenience, the BeamletOptics.AbstractBeamGroup offers a container-like interface for groups of Beams as commonly used in other software packages. The following concrete implementations are currently provided:
julia> BeamletOptics.list_subtypes(BeamletOptics.AbstractBeamGroup);
└── BeamletOptics.AbstractBeamGroup
├── AstigmaticBeamGroup{T, R} where {T<:Real, R<:BeamletOptics.AbstractRay{T}}
├── CollimatedSource{T, R} where {T<:Real, R<:BeamletOptics.AbstractRay{T}}
└── PointSource{T, R} where {T<:Real, R<:BeamletOptics.AbstractRay{T}}
At least 3 types have been found.Refer to the following sections for convenience constructors to generate the sources listed above.
Moving a beam group
Every beam group has a source position (center) and an orientation matrix, whose second column is the central source direction and whose first column is the sampling reference vector (basis). Both are updated when the group is moved. Refer to BeamletOptics.AbstractBeamGroup for the convention and to Moving sources for the kinematic API.
Center ray
The first beam of every CollimatedSource and PointSource generated by one of the constructors below is the center ray: it starts at the source position along the central source direction. This does not apply to sources that wrap given beams.
Collimated beam source
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 source as follows:
BeamletOptics.CollimatedSource Method
CollimatedSource(pos, dir, diameter, λ; num_rings, num_rays, basis)Spawns a bundle of collimated Beams at the specified position and direction. The source is modelled as a ring of concentric beam rings around the center beam. The amount of beam rings between the center ray and outer diameter can be specified via num_rings.
Info
Note that for correct sampling, the number of rays should be atleast 20x the number of rings.
Arguments
The following inputs and arguments can be used to configure the CollimatedSource:
Inputs
pos: center beam starting positiondir: center beam starting directiondiameter: outer beam bundle diameter in [m]λ = 1e-6: wavelength in [m], default val. is 1000 nm
Keyword Arguments
num_rings: number of concentric beam rings, default is 10; the number of rings counts the center as the innermost one, i.e.num_rings - 1rings lie around itnum_rays: total number of rays in the source, default is 100x num_ringsbasis: Optional reference vector (e.g.[1,0,0]) to define the starting azimuthal angle for the beam rings.
Reproducible sampling
If no basis is passed, the orthogonal basis vectors spanning the pupil plane are derived from dir deterministically, so two sources sharing the same dir, diameter, num_rings and num_rays sample exactly the same ray positions. Pass a basis to rotate the azimuthal sampling of a source about its own axis, e.g. to interleave several otherwise identical sources.

Already existing beams, e.g. Beams of PolarizedRays as in the Vectorial focusing at high NA example, can be wrapped into a group with CollimatedSource(beams, diameter, pos, dir). PointSource(beams, NA, pos, dir) and AstigmaticBeamGroup(beams, pos, dir) work analogously; instead of dir, a full orientation matrix can be passed.
A special constructor called UniformDiscSource is available, which offers an equal-area sampling (Fibonacci pattern) and is thus favorable in situations where the weighting of the individual beams becomes important, e.g. for calculating a point spread function using the intensity function.
BeamletOptics.UniformDiscSource Function
UniformDiscSource(pos, dir, diameter, λ; num_rays=1_000, basis)Generates a ray fan with equal area per ray across a circular pupil using the deterministic sunflower (Fibonacci) pattern.
The spiral starts with the center ray at pos (k = 0). The radius of the k-th ray (k = 1 … N-1) is ρₖ = diameter/2 ⋅ √((k + ½)/N), its azimuth is k times the golden angle π(3 - √5).
Note
This is merely a CollimatedSource constructor which uses Fibonacci sampling instead of concentric rings. All rays are equally weighted samples of the pupil: ray k represents the part of the disc between the radii diameter/2 ⋅ √(k/N) and diameter/2 ⋅ √((k + 1)/N). The center ray represents the innermost of these parts, a disc, by its center.
Arguments
The following inputs and arguments can be used to configure the underlying CollimatedSource:
Inputs
pos: center of the pupil disc, i.e. the source positiondir: starting direction of all beamsdiameter: outer beam bundle diameter in [m]λ = 1e-6: wavelength in [m]
Keyword Arguments
num_rays=1000: total number of rays in the source, must be≥ 1basis: Optional reference vector (e.g.[1,0,0]) to define the starting azimuthal angle of the sunflower pattern.
Reproducible sampling
If no basis is passed, the orthogonal basis vectors spanning the pupil plane are derived from dir deterministically, so two sources sharing the same dir, diameter and num_rays sample exactly the same ray positions. Pass a basis to rotate the sunflower pattern about its own axis, e.g. to interleave several otherwise identical sources.

Point beam source
The PointSource type is used to model emission from a spatially localized source that radiates Beams 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.
BeamletOptics.PointSource Method
PointSource(pos, dir, θ, λ; num_rings, num_rays, basis)Spawns a point source of Beams at the specified position and direction. The point source is modelled as a collection of concentric beam fans centered around the center beam. The amount of beam rings between the center ray and half-spread-angle θ can be specified via num_rings.
Info
Note that for correct sampling, the number of rays should be atleast 20x the number of rings.
Arguments
The following inputs and arguments can be used to configure the PointSource:
Inputs
pos: center beam starting positiondir: center beam starting directionθ: half spread angle in rad, must be< πλ = 1e-6: wavelength in [m], default val. is 1000 nm
Keyword Arguments
num_rings: number of concentric beam rings, default is 10; the number of rings counts the center as the innermost one, i.e.num_rings - 1rings lie around itnum_rays: total number of rays in the source, default is 100x num_ringsbasis: Optional reference vector (e.g.[1,0,0]) to define the starting azimuthal angle for the source rings.
Reproducible sampling
If no basis is passed, the orthogonal basis vectors are derived from dir deterministically, so two sources sharing the same dir, θ, num_rings and num_rays sample exactly the same ray directions. Pass a basis to rotate the azimuthal sampling of a source about its own axis, e.g. to interleave several otherwise identical sources.
Below you can find an exemplary illustration of a PointSource.

Analogous to UniformDiscSource, a special constructor called UniformPointSource is available, which samples the spherical cap around dir with an equal solid angle per ray (Fibonacci/sunflower pattern), rather than in concentric rings. It returns a plain PointSource.
BeamletOptics.UniformPointSource Function
UniformPointSource(pos, dir, θ, λ; num_rays=1_000, basis)Generates a cone of Beams emitted from pos with equal solid angle per ray across the spherical cap 0 ≤ ϑ ≤ θ around dir, using the deterministic sunflower (Fibonacci) pattern. The spiral starts with the center ray along dir (k = 0). The polar angle ϑₖ of the k-th ray (k = 1 … N-1) follows from cos ϑₖ = 1 - (k + ½)/N ⋅ (1 - cos θ), its azimuth is k times the golden angle π(3 - √5).
Note
This is merely a PointSource constructor which uses Fibonacci sampling instead of concentric rings. All rays are equally weighted samples of the cap: ray k represents the part of the cap with 1 - (k + 1)/N ⋅ (1 - cos θ) ≤ cos ϑ ≤ 1 - k/N ⋅ (1 - cos θ). The center ray represents the innermost of these parts, a cap, by its center.
Arguments
The following inputs and arguments can be used to configure the underlying PointSource:
Inputs
pos: starting position of all beamsdir: central source direction, i.e. the cone axisθ: half spread angle in rad, must be< πλ = 1e-6: wavelength in [m], default val. is 1000 nm
Keyword Arguments
num_rays=1000: total number of rays in the source, must be≥ 1basis: Optional reference vector (e.g.[1,0,0]) to define the starting azimuthal angle of the sunflower pattern. Must not be zero or parallel todir.
Reproducible sampling
If no basis is passed, the orthogonal basis vectors are derived from dir deterministically, so two sources sharing the same dir, θ and num_rays sample exactly the same ray directions. Pass a basis to rotate the sunflower pattern about its own axis, e.g. to interleave several otherwise identical sources.
Line and fan sources
For layout sketches, or to trace only one section of a system (e.g. the meridional plane), a two-dimensional source is often sufficient. The UniformLineSource is the two-dimensional counterpart of the collimated source: a plane sheet of parallel Beams that start equidistantly on a line. It returns a plain CollimatedSource.
BeamletOptics.UniformLineSource Function
UniformLineSource(pos, dir, width, λ; num_rays=101, basis)Generates a plane sheet of parallel Beams, i.e. a two-dimensional collimated source: the rays start equidistantly on a line of the length width centered at pos and travel along dir. The line lies along basis, such that all rays lie in the plane spanned by dir and basis. This is useful for layout sketches and for tracing a single (e.g. meridional or sagittal) section of a system.
The first ray is the center ray at pos. It is followed by h = (N - 1) ÷ 2 rays on each side of it, at pos + j/h ⋅ width/2 ⋅ basis for j = -h … h without j = 0, i.e. from one marginal ray at the end of the line to the other. A single ray starts at pos.
Use an odd number of rays
A pattern that is symmetric to its center ray has an odd number of rays. An even num_rays yields the pattern of num_rays - 1 rays and a second ray at pos.
Note
This is merely a CollimatedSource constructor which samples one diameter of the disc instead of concentric rings. width is stored as the diameter of the source.
Warning
The rays sample a line, not an area: they are not equal-area samples of a circular pupil. For a point spread function or an intensity use UniformDiscSource.
Arguments
The following inputs and arguments can be used to configure the underlying CollimatedSource:
Inputs
pos: center of the line, i.e. the source positiondir: starting direction of all beamswidth: length of the line in [m], i.e. the distance between the marginal raysλ = 1e-6: wavelength in [m]
Keyword Arguments
num_rays=101: total number of rays in the source, must be≥ 1basis: direction of the line (e.g.[1,0,0]), projected into the plane normal todir. Must not be zero or parallel todir.
Orientation of the line
If no basis is passed, the direction of the line is derived from dir deterministically via normal3d, which is rarely the section of interest: pass a basis to choose the plane of the rays. The line can also be turned about dir afterwards with rotate3d!.

The UniformFanSource is the two-dimensional counterpart of the point source: a plane fan of Beams from a single point with equidistant angles. It returns a plain PointSource.
BeamletOptics.UniformFanSource Function
UniformFanSource(pos, dir, θ, λ; num_rays=101, basis)Generates a plane fan of Beams emitted from pos, i.e. a two-dimensional point source: the rays lie in the plane spanned by dir and basis, with equidistant angles between -θ and θ to dir. This is useful for layout sketches and for tracing a single (e.g. meridional or sagittal) section of a system.
The first ray is the center ray along dir. It is followed by h = (N - 1) ÷ 2 rays on each side of it, which enclose the angles φⱼ = j/h ⋅ θ with dir for j = -h … h without j = 0 and point along cos φⱼ ⋅ dir + sin φⱼ ⋅ basis, i.e. from one marginal ray at the edge of the fan to the other. A single ray points along dir.
Use an odd number of rays
A pattern that is symmetric to its center ray has an odd number of rays. An even num_rays yields the pattern of num_rays - 1 rays and a second ray along dir.
Note
This is merely a PointSource constructor which samples one section of the cone instead of concentric rings.
Warning
The rays sample a plane angle, not a solid angle: they are not equal solid angle samples of a cone. For a point spread function or an intensity use UniformPointSource.
Arguments
The following inputs and arguments can be used to configure the underlying PointSource:
Inputs
pos: starting position of all beamsdir: central source direction, i.e. the axis of the fanθ: half spread angle in rad, must be< πλ = 1e-6: wavelength in [m], default val. is 1000 nm
Keyword Arguments
num_rays=101: total number of rays in the source, must be≥ 1basis: direction (e.g.[1,0,0]) that spans the plane of the fan together withdir, projected into the plane normal todir. Rays with a positive angle are tilted towards it. Must not be zero or parallel todir.
Orientation of the fan
If no basis is passed, the plane of the fan is derived from dir deterministically via normal3d, which is rarely the section of interest: pass a basis to choose the plane of the rays. The fan can also be turned about dir afterwards with rotate3d!.

Both sources include the marginal rays and should be used with an odd number of rays. The plane of the rays is spanned by dir and the basis keyword argument. The rays stay in this plane only if the system is symmetric with respect to it. Since the rays sample a line or a plane angle instead of an area or a solid angle, these sources are not suited for calculating a point spread function with the intensity function.
Astigmatic Beam Groups
For complex sources, the package provides the AstigmaticBeamGroup container. Several constructors are available for different scenarios:
GaussianBeamletDecomposition: Tiling a large Gaussian beam into many small stable beamlets.WavefrontBeamletDecomposition: Importing an arbitrary complex scalar field (e.g. from a phase screen or camera data), or a vector field with an independent, spatially varying polarization (e.g.OpticsBase'sPlaneField, see OpticsBase fields as beam groups).CollimatedGaussianBeamletSource: A square grid of parallel beamlets (ideal for aperture diffraction).SphericalGaussianBeamletSource: A point-like source emitting a cone of beamlets (ideal for focused/divergent beams).EllipticalGaussianBeamletSource: A point-like source emitting an elliptical cone of beamlets (ideal for sources with different fast/slow axis divergence).
A field that is close to one Gaussian mode and too small to be tiled into beamlets, e.g. the output of a single-mode fiber, is not turned into a group: GaussianModeDecomposition fits a single AstigmaticGaussianBeamlet to it.
OpticsBase fields as beam groups
With using OpticsBase, a PlaneField handed over by another solver (e.g. the exit field of a fiber computed by a beam propagation method) becomes BMO beams again. WavefrontBeamletDecomposition tiles it into one beamlet per sample, which needs beamlets much larger than λ. GaussianModeDecomposition fits a single Gaussian beamlet instead, for small fields close to one Gaussian mode such as single-mode fiber output. Both take only the forward-travelling part of the field and require the plane to lie in vacuum or air. The detector side, PlaneField(::Detector), is described under OpticsBase interoperability.
BeamletOptics.WavefrontBeamletDecomposition Method
BeamletOptics.WavefrontBeamletDecomposition(f::OpticsBase.PlaneField; kwargs...)Decomposes the forward-travelling part of a PlaneField f into an AstigmaticBeamGroup of AstigmaticGaussianBeamlets, placed on f's plane and travelling along f's normal n. This is the return path for OpticsBase.PlaneField(detector; ...): passing the result back into this constructor and tracing the resulting beam group reproduces the original field (round trip), up to beamlet-grid discretization error.
Arguments
f: the field to decompose. Onlyforward(f)(the part travelling along+n) is used; the backward part is dropped (aPlaneFieldhas no ready single propagation direction for its backward part in this constructor, which needs one direction per call).kwargs...: forwarded toWavefrontBeamletDecomposition(x, y, Eu, Ev, dir, λ; kwargs...)(threshold,overlap,randomize_axes,rng);basisis fixed tof's own(u, v)andRtof.R, neither can be overridden.
Conventions
The physical field used is
forward(f).E .* reference_phase(f): the stored array with the local-plane-wave forward/backward split and the reference-sphere phase (if any) applied, in [V/m] peak amplitude, matching the unitsAstigmaticGaussianBeamlet'sE0expects. The samples and the sphere are handed on separately (R = f.R), so the grid only has to resolve the phase of the stored array, not that of the sphere.forwardsplits each sample as a local plane wave along the reference direction; a beam at the angleθto it loses an amplitude of the order(1 − cos θ)/2. Keep the plane close to normal to the beam, which the beamlet size requires anyway (seeWavefrontBeamletDecomposition).The beam group's sampling grid is
f's own(u, v)grid (OpticsBase.coordinates), placed atf.originwith local axesf.axes[:, 1:2](translate_to3d!after construction;WavefrontBeamletDecompositionitself always centers the undecomposed group on the global origin).fmust lie in vacuum or air (f.n == 1): BMO starts beams in vacuum, and a field in a medium would need a medium-to-vacuum conversion of amplitude and optical path. AnArgumentErroris thrown otherwise.
Throws an ArgumentError if f has no forward-travelling light (e.g. a purely backward wave), and whatever WavefrontBeamletDecomposition(x, y, Eu, Ev, dir, λ) throws.
BeamletOptics.GaussianModeDecomposition Method
BeamletOptics.GaussianModeDecomposition(f::OpticsBase.PlaneField)Fits a single AstigmaticGaussianBeamlet to the forward-travelling part of a PlaneField, e.g. the output of a single-mode fiber. The beamlet starts on f's plane at the centroid of the field; see GaussianModeDecomposition for the fit. Use it for fields close to one Gaussian mode that are too small for WavefrontBeamletDecomposition (which needs beamlets much larger than λ).
optical_power(beamlet) / OpticsBase.power(f) is the fraction of the power captured by the Gaussian mode. The field used is forward(f).E .* reference_phase(f); the reference sphere enters the fit analytically (R = f.R), so the grid only has to resolve the phase of the stored array. f must lie in vacuum or air (f.n == 1), where BMO starts beams, and must contain forward-travelling light; an ArgumentError is thrown otherwise.