Emitters

Warning

The old emitter implementation is deprecated as of v0.5! See below for the new API.

Emitters create rays in a certain pattern, usually controlled by some parameters. Emitters are defined by Pixels and Spatial Layouts, and have a spectrum and an optical power distribution over the hemisphere. These are intrinsic physical properties of the emitter.

The basic emitter (Source) is constructed as a combination of 4 basic elements and a 3D Transform. The basic elements include:

The OpticSim package comes with various implementations of each of these basic elements:

Examples of Basic Emitters

Note: All of the examples on this page assume that the following statement was executed:

using OpticSim, OpticSim.Geometry, OpticSim.Emitters

Simple functions for creating commonly used emitters

Many optical systems by convention have their optical axis parallel to the z axis. These utility functions provide a simple interface to the Emitters package to create emitters that direct their rays in the negative z direction, toward the entrance of the optical system.

OpticSim.Emitters.pointemitterFunction
pointemitter(origin::AbstractVector{T}, coneangle; λ::Length = 500nm, numrays = 100) where {T<:Real}

Creates a point source with Lambertian emission power and cone distribution of rays, emitting in the -z direction. λ is a unitful Length quantity, e.g., 550nm.

source
pt = Emitters.pointemitter([0.0,0.0,.5],.3)
Vis.draw(pt, debug=true, resolution = (800, 600))
OpticSim.Emitters.collimatedemitterFunction
collimatedemitter(origin::AbstractVector{T}, halfsquaresize; λ::Length = 500nm, numrays = 100) where {T<:Real}

Creates a square collimated emitter, emitting rays in the -z direction. Rays are emitted on a square grid with sqrt(numrays) on a side. λ can be a unitful quantity, e.g., 550nm, or a number. In the latter case the units are implicitly microns.

source
pt = Emitters.collimatedemitter([0.0,0.0,1.0],.5)
Vis.draw(pt, debug=true, resolution = (800, 600))

Point origin with various Direction distributions

src = Sources.Source(origins=Origins.Point(), directions=Directions.RectGrid(π/4, π/4, 15, 15))
Vis.draw(src, debug=true, resolution = (800, 600))
src = Sources.Source(origins=Origins.Point(), directions=Directions.UniformCone(π/6, 1000))
Vis.draw(src, debug=true, resolution = (800, 600))
src = Sources.Source(origins=Origins.Point(), directions=Directions.HexapolarCone(π/6, 10))
Vis.draw(src, debug=true, resolution = (800, 600))

Various origins distributions

src = Sources.Source(origins=Origins.RectGrid(1.0, 1.0, 10, 10), directions=Directions.Constant())
Vis.draw(src, debug=true, resolution = (800, 600))
src = Sources.Source(origins=Origins.Hexapolar(5, 1.0, 2.0), directions=Directions.Constant())
Vis.draw(src, debug=true, resolution = (800, 600))

Examples of Angular Power Distribution

In these example, the arrow width is proportional to the ray power.

src = Sources.Source(
    origins=Origins.Hexapolar(1, 8.0, 8.0),             # Hexapolar Origins
	directions=Directions.RectGrid(π/6, π/6, 15, 15),   # RectGrid Directions
	power=AngularPower.Cosine(10.0)                     # Cosine Angular Power
)
Vis.draw(src, debug=true, resolution = (800, 600))
src = Sources.Source(
	origins=Origins.RectGrid(1.0, 1.0, 3, 3),           # RectGrid Origins
	directions=Directions.HexapolarCone(π/6, 10),       # HexapolarCone Directions
	power=AngularPower.Gaussian(2.0, 2.0)               # Gaussian Angular Power
)
Vis.draw(src, debug=true, resolution = (800, 600))

Composite Sources - Display Example

# construct the emitter's basic components
S = Spectrum.Uniform()
P = AngularPower.Lambertian()
O = Origins.RectGrid(1.0, 1.0, 3, 3)
D = Directions.HexapolarCone(deg2rad(5.0), 3)

# construct the source. in this example a "pixel" source will contain only one source as we are simulating a "b/w" display.
# for RGB displays we can combine 3 sources to simulate "a pixel".
Tr = Transform(Vec3(0.5, 0.5, 0.0))
source1 = Sources.Source(Tr, S, O, D, P)

# create a list of pixels - each one is a composite source
pixels = Vector{Sources.CompositeSource{Float64}}(undef, 0)
for y in 1:5 # image_height
    for x in 1:10 # image_width
        # pixel position relative to the display's origin
        local pixel_position = Vec3((x-1) * 1.1, (y-1) * 1.5, 0.0)
        local Tr = Transform(pixel_position)

        # constructing the "pixel"
        pixel = Sources.CompositeSource(Tr, [source1])

        push!(pixels, pixel)
    end
end

Tr = Transform(Vec3(0.0, 0.0, 0.0))
my_display = Sources.CompositeSource(Tr, pixels)

Vis.draw(my_display)                                                # render the display - nothing but the origins primitives
rays = AbstractArray{OpticalRay{Float64, 3}}(collect(my_display))   # collect the rays generated by the display
Vis.draw!(rays)                                                     # render the rays

Spectrum

OpticSim.Emitters.Spectrum.UniformType
Uniform{T} <: AbstractSpectrum{T}

Encapsulates a flat spectrum range which is sampled uniformly. Unless stated diferrently, the range used will be 450nm to 680nm.

Uniform(low_end::T, high_end::T) where {T<:Real}
Uniform(::Type{T} = Float64) where {T<:Real}
source
OpticSim.Emitters.Spectrum.MeasuredType
Measured{T} <: AbstractSpectrum{T}

Encapsulates a measured spectrum to compute emitter power. Create spectrum by reading CSV files. Evaluate spectrum at arbitrary wavelength with spectrumpower (more technical details coming soon)

Measured(samples::DataFrame)
source

Angular Power Distribution

OpticSim.Emitters.AngularPower.GaussianType
Gaussian{T} <: AbstractAngularPowerDistribution{T}

GGaussian power distribution. Ray power is calculated by:

power = power * exp(-(gaussianu * l^2 + gaussianv * m^2)) where l and m are the cos_angles between the two axes respectivly.

source

Rays Origins Distribution

OpticSim.Emitters.Origins.PointType
Point{T} <: AbstractOriginDistribution{T}

Encapsulates a single point origin.

Point(position::Vec3{T}) where {T<:Real}
Point(x::T, y::T, z::T) where {T<:Real}
Point(::Type{T} = Float64) where {T<:Real}
source
OpticSim.Emitters.Origins.RectUniformType
RectUniform{T} <: AbstractOriginDistribution{T}

Encapsulates a uniformly sampled rectangle with user defined number of samples.

RectUniform(width::T, height::T, samples_count::Int64) where {T<:Real}
source
OpticSim.Emitters.Origins.RectGridType
RectGrid{T} <: AbstractOriginDistribution{T}

Encapsulates a rectangle sampled in a grid fashion.

RectGrid(width::T, height::T, usamples::Int64, vsamples::Int64) where {T<:Real} 
source
OpticSim.Emitters.Origins.HexapolarType
Hexapolar{T} <: AbstractOriginDistribution{T}

Encapsulates an ellipse (or a circle where halfsizeu=halfsizev) sampled in an hexapolar fashion (rings).

Hexapolar(nrings::Int64, halfsizeu::T, halfsizev::T) where {T<:Real} 
source

Rays Directions Distribution

OpticSim.Emitters.Directions.ConstantType
Constant{T} <: AbstractDirectionDistribution{T}

Encapsulates a single ray direction, where the default direction is unitZ3 [0, 0, 1].

Constant(direction::Vec3{T}) where {T<:Real}
Constant(::Type{T} = Float64) where {T<:Real}
source
OpticSim.Emitters.Directions.RectGridType
RectGrid{T} <: AbstractDirectionDistribution{T}

Encapsulates a single ray direction, where the default direction is unitZ3 [0, 0, 1].

Constant(direction::Vec3{T}) where {T<:Real}
Constant(::Type{T} = Float64) where {T<:Real}
source
OpticSim.Emitters.Directions.UniformConeType
UniformCone{T} <: AbstractDirectionDistribution{T}

Encapsulates numsamples rays sampled uniformly from a cone with max angle θmax.

UniformCone(direction::Vec3{T}, θmax::T, numsamples::Int64) where {T<:Real}
UniformCone(θmax::T, numsamples::Int64) where {T<:Real}
source
OpticSim.Emitters.Directions.HexapolarConeType
HexapolarCone{T} <: AbstractDirectionDistribution{T}

Rays are generated by sampling a cone with θmax angle in an hexapolar fashion. The number of rays depends on the requested rings and is computed using the following formula: 1 + round(Int64, (nrings * (nrings + 1) / 2) * 6)

HexapolarCone(direction::Vec3{T}, θmax::T, nrings::Int64) where {T<:Real}
HexapolarCone(θmax::T, nrings::Int64 = 3) where {T<:Real}
source

Sources

OpticSim.Emitters.Sources.SourceType
Source{T<:Real, Tr<:Transform{T}, S<:Spectrum.AbstractSpectrum{T}, O<:Origins.AbstractOriginDistribution{T}, D<:Directions.AbstractDirectionDistribution{T}, P<:AngularPower.AbstractAngularPowerDistribution{T}} <: AbstractSource{T}

This data-type represents the basic emitter (Source), which is a combination of a Spectrum, Angular Power Distribution, Origins and Directions distibution and a 3D Transform.

Source(::Type{T} = Float64;
       transform::Tr = Transform(),
       spectrum::S = Spectrum.Uniform(),
       origins::O = Origins.Point(),
       directions::D = Directions.Constant(),
       power::P = AngularPower.Lambertian(),
       sourcenum::Int64 = 0) where {
            Tr<:Transform,
            S<:Spectrum.AbstractSpectrum,
            O<:Origins.AbstractOriginDistribution,
            D<:Directions.AbstractDirectionDistribution,
            P<:AngularPower.AbstractAngularPowerDistribution,
            T<:Real}

Source(transform::Tr, spectrum::S, origins::O, directions::D, power::P, ::Type{T} = Float64; sourcenum::Int64 = 0) where {   
            Tr<:Transform,
            S<:Spectrum.AbstractSpectrum,
            O<:Origins.AbstractOriginDistribution,
            D<:Directions.AbstractDirectionDistribution,
            P<:AngularPower.AbstractAngularPowerDistribution,
            T<:Real}
source
OpticSim.Emitters.Sources.CompositeSourceType
CompositeSource{T} <: AbstractSource{T}

This data-type represents the composite emitter (Source) which is constructed with a list of basic or composite emitters and a 3D Transform.

CompositeSource(transform::Transform{T}, sources::Vector{<:AbstractSource}) where {T<:Real} 
source