Skip to content
This repository has been archived by the owner on Oct 23, 2022. It is now read-only.

Poor performance of ray generation in Emitters.jl because of abstract struct field #208

Merged
merged 3 commits into from
Jun 25, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 0 additions & 28 deletions src/Examples/other_examples.jl
Original file line number Diff line number Diff line change
Expand Up @@ -254,34 +254,6 @@ function fresnel(convex = true; kwargs...)
Vis.drawtracerays(sys; test = true, trackallrays = true, numdivisions = 30, kwargs...)
end

function grating(; period = 1.0, θ = 0.0, λ = 0.55, kwargs...)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These removals seem unrelated to the PR - is this intentional? If so maybe should be a separate PR

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It was intentional. A separate PR would be better in an ideal world but because it was a deletion of code that didn't work anymore it was simpler to add it into a single PR.

int = ThinGratingInterface(SVector(0.0, 1.0, 0.0), period, Air, Air, minorder = -2, maxorder = 2, reflectance = [0.0, 0.0, 0.1, 0.0, 0.0], transmission = [0.05, 0.1, 0.4, 0.1, 0.05])
grating = ThinGratingSurface(Rectangle(5.0, 5.0, SVector(0.0, 0.0, 1.0), SVector(0.0, 0.0, 0.0)), int)
back = Rectangle(30.0, 30.0, SVector(0.0, 0.0, 1.0), SVector(0.0, 0.0, 25.0))
sys = CSGOpticalSystem(LensAssembly(grating, back), Rectangle(30.0, 30.0, SVector(0.0, 0.0, 1.0), SVector(0.0, 0.0, -25.0), interface = opaqueinterface()))
Vis.drawtracerays(sys; raygenerator = UniformOpticalSource(CollimatedSource(OriginPoint{Float64}(100, position = SVector(0.0, 0.0, 10.0), direction = SVector(0.0, sind(θ), -cosd(θ)))), λ), trackallrays = true, rayfilter = nothing, kwargs...)
end

function reflgrating(; period = 1.0, θ = 0.0, λ = 0.55, kwargs...)
int = ThinGratingInterface(SVector(0.0, 1.0, 0.0), period, Air, Air, minorder = -2, maxorder = 2, transmission = [0.0, 0.0, 0.1, 0.0, 0.0], reflectance = [0.05, 0.1, 0.4, 0.1, 0.05])
grating = ThinGratingSurface(Rectangle(5.0, 5.0, SVector(0.0, 0.0, 1.0), SVector(0.0, 0.0, 0.0)), int)
back = Rectangle(30.0, 30.0, SVector(0.0, 0.0, 1.0), SVector(0.0, 0.0, -25.0))
sys = CSGOpticalSystem(LensAssembly(grating, back), Rectangle(30.0, 30.0, SVector(0.0, 0.0, 1.0), SVector(0.0, 0.0, 25.0), interface = opaqueinterface()))
Vis.drawtracerays(sys; raygenerator = UniformOpticalSource(CollimatedSource(OriginPoint{Float64}(100, position = SVector(0.0, 0.0, 10.0), direction = SVector(0.0, sind(θ), -cosd(θ)))), λ), trackallrays = true, rayfilter = nothing, kwargs...)
end

function HOE(refl = false, firstorderonly = false; kwargs...)
rect = Rectangle(5.0, 5.0, SVector(0.0, 0.0, 1.0), SVector(0.0, 0.0, 0.0))
if refl
int = HologramInterface(SVector(0.0, -10.0, 20.0), ConvergingBeam, SVector(0.0, 0.0, -200), ConvergingBeam, 0.55, 9.0, Air, SCHOTT.N_BK7, Air, Air, Air, 0.05, !firstorderonly)
else
int = HologramInterface(SVector(0.0, -10.0, -20.0), ConvergingBeam, SVector(0.0, 0.0, -200), ConvergingBeam, 0.55, 5.0, Air, SCHOTT.N_BK7, Air, Air, Air, 0.05, !firstorderonly)
end
obj = HologramSurface(rect, int)
back = Rectangle(50.0, 50.0, SVector(0.0, 0.0, 1.0), SVector(0.0, 0.0, 25.0))
sys = CSGOpticalSystem(LensAssembly(obj, back), Rectangle(50.0, 50.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}(10, position = SVector(0.0, 0.0, 10.0), direction = SVector(0.0, 0.0, -1.0)), 1, 15, 0.0, π / 6), 0.55), trackallrays = true, rayfilter = nothing, kwargs...)
end

function eyetrackHOE(nrays = 5000, det = false, showhead = true, zeroorder = false; kwargs...)
# TODO update for new specs from Chris
Expand Down
42 changes: 21 additions & 21 deletions src/Optical/Emitters/Directions.jl
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ struct Constant{T} <: AbstractDirectionDistribution{T}
end

Base.length(d::Constant) = 1
Emitters.generate(d::Constant, ::Integer) = d.direction
Emitters.generate(d::Constant, ::Int64) = d.direction

"""
RectGrid{T} <: AbstractDirectionDistribution{T}
Expand All @@ -62,31 +62,31 @@ struct RectGrid{T} <: AbstractDirectionDistribution{T}
direction::Vec3{T}
halfangleu::T
halfanglev::T
nraysu::Integer
nraysv::Integer
nraysu::Int64
nraysv::Int64
uvec::Vec3{T}
vvec::Vec3{T}

function RectGrid(direction::Vec3{T}, halfangleu::T, halfanglev::T, numraysu::Integer, numraysv::Integer) where {T<:Real}
function RectGrid(direction::Vec3{T}, halfangleu::T, halfanglev::T, numraysu::Int64, numraysv::Int64) where {T<:Real}
(uvec, vvec) = get_orthogonal_vectors(direction)
return new{T}(direction, halfangleu, halfanglev, numraysu, numraysv, uvec, vvec)
end

function RectGrid(halfangleu::T, halfanglev::T, numraysu::Integer, numraysv::Integer) where {T<:Real}
function RectGrid(halfangleu::T, halfanglev::T, numraysu::Int64, numraysv::Int64) where {T<:Real}
direction = unitZ3(T)
return RectGrid(direction, halfangleu, halfanglev, numraysu, numraysv)
end
end

Base.length(d::RectGrid) = d.nraysu * d.nraysv
function Emitters.generate(d::RectGrid{T}, n::Integer) where {T<:Real}
function Emitters.generate(d::RectGrid{T}, n::Int64) where {T<:Real}
direction = d.direction
uvec = d.uvec
vvec = d.vvec

# distributing evenly across the area of the rectangle which subtends the given angle (*not* evenly across the angle range)
dindex = mod(n, d.nraysu * d.nraysv)
v = d.nraysv == 1 ? zero(T) : 2 * Integer(floor(dindex / d.nraysu)) / (d.nraysv - 1) - 1.0
v = d.nraysv == 1 ? zero(T) : 2 * Int64(floor(dindex / d.nraysu)) / (d.nraysv - 1) - 1.0
u = d.nraysu == 1 ? zero(T) : 2 * mod(dindex, d.nraysu) / (d.nraysu - 1) - 1.0
θu = atan(u * tan(d.halfangleu) / 2) * d.halfangleu
θv = atan(v * tan(d.halfanglev) / 2) * d.halfanglev
Expand All @@ -100,30 +100,30 @@ end
Encapsulates `numsamples` rays sampled uniformly from a cone with max angle θmax.

```julia
UniformCone(direction::Vec3{T}, θmax::T, numsamples::Integer) where {T<:Real}
UniformCone(θmax::T, numsamples::Integer) where {T<:Real}
UniformCone(direction::Vec3{T}, θmax::T, numsamples::Int64) where {T<:Real}
UniformCone(θmax::T, numsamples::Int64) where {T<:Real}
```
"""
struct UniformCone{T} <: AbstractDirectionDistribution{T}
direction::Vec3{T}
θmax::T
numsamples::Integer
numsamples::Int64
uvec::Vec3{T}
vvec::Vec3{T}

function UniformCone(direction::Vec3{T}, θmax::T, numsamples::Integer) where {T<:Real}
function UniformCone(direction::Vec3{T}, θmax::T, numsamples::Int64) where {T<:Real}
(uvec, vvec) = get_orthogonal_vectors(direction)
return new{T}(direction, θmax, numsamples, uvec, vvec)
end

function UniformCone(θmax::T, numsamples::Integer) where {T<:Real}
function UniformCone(θmax::T, numsamples::Int64) where {T<:Real}
direction = unitZ3(T)
return UniformCone(direction, θmax, numsamples)
end
end

Base.length(d::UniformCone) = d.numsamples
function Emitters.generate(d::UniformCone{T}, ::Integer) where {T<:Real}
function Emitters.generate(d::UniformCone{T}, ::Int64) where {T<:Real}
direction = d.direction
θmax = d.θmax
uvec = d.uvec
Expand All @@ -138,34 +138,34 @@ end
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(Integer, (nrings * (nrings + 1) / 2) * 6)`
`1 + round(Int64, (nrings * (nrings + 1) / 2) * 6)`

```julia
HexapolarCone(direction::Vec3{T}, θmax::T, nrings::Integer) where {T<:Real}
HexapolarCone(θmax::T, nrings::Integer = 3) where {T<:Real}
HexapolarCone(direction::Vec3{T}, θmax::T, nrings::Int64) where {T<:Real}
HexapolarCone(θmax::T, nrings::Int64 = 3) where {T<:Real}
```
"""
struct HexapolarCone{T} <: AbstractDirectionDistribution{T}
direction::Vec3{T}
θmax::T
nrings::Integer
nrings::Int64
uvec::Vec3{T}
vvec::Vec3{T}

function HexapolarCone(direction::Vec3{T}, θmax::T, nrings::Integer) where {T<:Real}
function HexapolarCone(direction::Vec3{T}, θmax::T, nrings::Int64) where {T<:Real}
(uvec, vvec) = get_orthogonal_vectors(direction)
return new{T}(direction, θmax, nrings, uvec, vvec)
end

# assume canonical directions
function HexapolarCone(θmax::T, nrings::Integer = 3) where {T<:Real}
function HexapolarCone(θmax::T, nrings::Int64 = 3) where {T<:Real}
direction = unitZ3(T)
return HexapolarCone(direction, θmax, nrings)
end
end

Base.length(d::HexapolarCone) = 1 + round(Integer, (d.nrings * (d.nrings + 1) / 2) * 6)
function Emitters.generate(d::HexapolarCone{T}, n::Integer) where {T<:Real}
Base.length(d::HexapolarCone) = 1 + round(Int64, (d.nrings * (d.nrings + 1) / 2) * 6)
function Emitters.generate(d::HexapolarCone{T}, n::Int64) where {T<:Real}
dir = d.direction
θmax = d.θmax
uvec = d.uvec
Expand Down
34 changes: 17 additions & 17 deletions src/Optical/Emitters/Origins.jl
Original file line number Diff line number Diff line change
Expand Up @@ -48,23 +48,23 @@ end

Base.length(::Point) = 1
Emitters.visual_size(::Point) = 1
Emitters.generate(o::Point, ::Integer) = o.origin
Emitters.generate(o::Point, ::Int64) = o.origin

"""
RectUniform{T} <: AbstractOriginDistribution{T}

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

```julia
RectUniform(width::T, height::T, samples_count::Integer) where {T<:Real}
RectUniform(width::T, height::T, samples_count::Int64) where {T<:Real}
```
"""
struct RectUniform{T} <: AbstractOriginDistribution{T}
width::T
height::T
samples_count::Integer
samples_count::Int64

function RectUniform(width::T, height::T, samples_count::Integer) where {T<:Real}
function RectUniform(width::T, height::T, samples_count::Int64) where {T<:Real}
return new{T}(width, height, samples_count)
end
end
Expand All @@ -73,7 +73,7 @@ Base.length(o::RectUniform) = o.samples_count
Emitters.visual_size(o::RectUniform) = max(o.width, o.height)

# generate origin on the agrid
function Emitters.generate(o::RectUniform{T}, n::Integer) where {T<:Real}
function Emitters.generate(o::RectUniform{T}, n::Int64) where {T<:Real}
n = mod(n, length(o))
u = rand(Distributions.Uniform(-one(T), one(T)))
v = rand(Distributions.Uniform(-one(T), one(T)))
Expand All @@ -86,29 +86,29 @@ end
Encapsulates a rectangle sampled in a grid fashion.

```julia
RectGrid(width::T, height::T, usamples::Integer, vsamples::Integer) where {T<:Real}
RectGrid(width::T, height::T, usamples::Int64, vsamples::Int64) where {T<:Real}
```
"""
struct RectGrid{T} <: AbstractOriginDistribution{T}
width::T
height::T
usamples::Integer
vsamples::Integer
usamples::Int64
vsamples::Int64
ustep::T
vstep::T

function RectGrid(width::T, height::T, usamples::Integer, vsamples::Integer) where {T<:Real}
function RectGrid(width::T, height::T, usamples::Int64, vsamples::Int64) where {T<:Real}
return new{T}(width, height, usamples, vsamples, width / (usamples - 1), height / (vsamples - 1))
end
end

Base.length(o::RectGrid) = o.usamples * o.vsamples
Emitters.visual_size(o::RectGrid) = max(o.width, o.height)

# generate origin on the agrid
function Emitters.generate(o::RectGrid{T}, n::Integer) where {T<:Real}
# generate origin on the grid
function Emitters.generate(o::RectGrid{T}, n::Int64) where {T<:Real}
n = mod(n, length(o))
v = o.vsamples == 1 ? zero(T) : 2 * Integer(floor(n / o.usamples)) / (o.vsamples - 1) - 1.0
v = o.vsamples == 1 ? zero(T) : 2 * Int64(floor(n / o.usamples)) / (o.vsamples - 1) - 1.0
u = o.usamples == 1 ? zero(T) : 2 * mod(n, o.usamples) / (o.usamples - 1) - 1.0
return zeros(Vec3{T}) + ((o.width / 2) * u * unitX3(T)) + ((o.height/2) * v * unitY3(T))
end
Expand All @@ -119,23 +119,23 @@ end
Encapsulates an ellipse (or a circle where halfsizeu=halfsizev) sampled in an hexapolar fashion (rings).

```julia
Hexapolar(nrings::Integer, halfsizeu::T, halfsizev::T) where {T<:Real}
Hexapolar(nrings::Int64, halfsizeu::T, halfsizev::T) where {T<:Real}
```
"""
struct Hexapolar{T} <: AbstractOriginDistribution{T}
halfsizeu::T
halfsizev::T
nrings::Integer
nrings::Int64

function Hexapolar(nrings::Integer, halfsizeu::T, halfsizev::T) where {T<:Real}
function Hexapolar(nrings::Int64, halfsizeu::T, halfsizev::T) where {T<:Real}
return new{T}(halfsizeu, halfsizev, nrings)
end
end

Base.length(o::Hexapolar) = 1 + round(Integer, (o.nrings * (o.nrings + 1) / 2) * 6)
Base.length(o::Hexapolar) = 1 + round(Int64, (o.nrings * (o.nrings + 1) / 2) * 6)
Emitters.visual_size(o::Hexapolar) = max(o.halfsizeu*2, o.halfsizev*2)

function Emitters.generate(o::Hexapolar{T}, n::Integer) where {T<:Real}
function Emitters.generate(o::Hexapolar{T}, n::Int64) where {T<:Real}
n = mod(n, length(o))
if n == 0
return zeros(Vec3{T})
Expand Down
28 changes: 14 additions & 14 deletions src/Optical/Emitters/Sources.jl
Original file line number Diff line number Diff line change
Expand Up @@ -34,15 +34,15 @@ Source(::Type{T} = Float64;
origins::O = Origins.Point(),
directions::D = Directions.Constant(),
power::P = AngularPower.Lambertian(),
sourcenum::Integer = 0) where {
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::Integer = 0) where {
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,
Expand All @@ -64,7 +64,7 @@ struct Source{
origins::O
directions::D
power_distribution::P
sourcenum::Integer
sourcenum::Int64

function Source(
::Type{T} = Float64;
Expand All @@ -73,7 +73,7 @@ struct Source{
origins::O = Origins.Point(T),
directions::D = Directions.Constant(T),
power::P = AngularPower.Lambertian(T),
sourcenum::Integer = 0
sourcenum::Int64 = 0
) where {
Tr<:Transform,
S<:Spectrum.AbstractSpectrum,
Expand All @@ -92,7 +92,7 @@ struct Source{
directions::D,
power::P,
::Type{T} = Float64;
sourcenum::Integer = 0
sourcenum::Int64 = 0
) where {
Tr<:Transform,
S<:Spectrum.AbstractSpectrum,
Expand All @@ -107,23 +107,23 @@ end

# used to not generate new origin points if we can use last points - mainly to keep consistency of origin generation when randomness is involved
struct SourceGenerationState{T<:Real}
n::Integer
last_index_used::Integer
n::Int64
last_index_used::Int64
last_point_generated::Vec3{T}
end

Base.length(s::Source) = length(s.origins) * length(s.directions)
Base.iterate(s::Source{T}) where {T<:Real} = iterate(s, SourceGenerationState(1, -1, zeros(Vec3{T})))
Base.iterate(s::Source, state::SourceGenerationState) = state.n > length(s) ? nothing : generate(s, state)

function Emitters.generate(s::Source{T}, n::Integer) where {T<:Real}
function Emitters.generate(s::Source{T}, n::Int64) where {T<:Real}
return generate(s, SourceGenerationState(n+1, -1, zeros(Vec3{T})))[1]
end

function Emitters.generate(s::Source{T}, state::SourceGenerationState{T} = SourceGenerationState(-1, -1, zeros(Vec3{T}))) where {T<:Real}
# @info "New State Generation"
n::Integer = state.n - 1
origin_index = floor(Integer, (n / length(s.directions)))
n::Int64 = state.n - 1
origin_index = floor(Int64, (n / length(s.directions)))
direction_index = mod(n, length(s.directions))

if (origin_index == state.last_index_used)
Expand Down Expand Up @@ -196,16 +196,16 @@ Base.length(s::CompositeSource) = s.total_length
Base.iterate(s::CompositeSource{T}) where {T<:Real} = iterate(s, SourceGenerationState(1, -1, zeros(Vec3{T})))
Base.iterate(s::CompositeSource, state::SourceGenerationState) = state.n > length(s) ? nothing : generate(s, state)

function Emitters.generate(s::CompositeSource{T}, n::Integer) where {T<:Real}
function Emitters.generate(s::CompositeSource{T}, n::Int64) where {T<:Real}
return generate(s, SourceGenerationState(n+1, -1, zeros(Vec3{T})))[1]
end

function Emitters.generate(s::CompositeSource{T}, state::SourceGenerationState{T} = SourceGenerationState(-1, -1, zeros(Vec3{T}))) where {T<:Real}
# @info "New Composite State Generation"
n::Integer = state.n - 1
n::Int64 = state.n - 1

if (s.uniform_length != -1)
source_index = floor(Integer, (n / s.uniform_length))
source_index = floor(Int64, (n / s.uniform_length))
ray_index = mod(n, s.uniform_length)
# @info "New Composite State Generation: source=$source_index ray=$ray_index ($(length(s.sources)))"
else
Expand All @@ -216,7 +216,7 @@ function Emitters.generate(s::CompositeSource{T}, state::SourceGenerationState{T
high = length(s.start_indexes) - 1 # last cell in this vector is a dummy cell containing the index after the last ray
source_index = -1
while (low <= high)
mid = floor(Integer, (low + high) / 2)
mid = floor(Int64, (low + high) / 2)

if (n < s.start_indexes[mid])
high = mid - 1
Expand Down
10 changes: 5 additions & 5 deletions src/Optical/Emitters/Spectrum.jl
Original file line number Diff line number Diff line change
Expand Up @@ -72,17 +72,17 @@ Measured(samples::DataFrame)
```
"""
struct Measured{T} <: AbstractSpectrum{T}
low_wave_length::Integer
high_wave_length::Integer
wave_length_step::Integer
low_wave_length::Int64
high_wave_length::Int64
wave_length_step::Int64
power_samples::Vector{T}

function Measured(samples::DataFrame)
colnames = names(samples)
@assert "Wavelength" in colnames
@assert "Power" in colnames
wavelengths = samples[!, :Wavelength]
@assert eltype(wavelengths) <: Integer
@assert eltype(wavelengths) <: Int64

power::Vector{T} where {T<:Real} = samples[!, :Power] # no missing values allowed and must be real numbers
maxpower = maximum(power)
Expand Down Expand Up @@ -118,7 +118,7 @@ function spectrumpower(spectrum::Measured{T}, λ::T) where {T<:Real}
return nothing
end

lowindex = floor(Integer, (λ - spectrum.low_wave_length)) ÷ spectrum.wave_length_step + 1
lowindex = floor(Int64, (λ - spectrum.low_wave_length)) ÷ spectrum.wave_length_step + 1

if lowindex == length(spectrum.power_samples)
return convert(T, spectrum.power_samples[end])
Expand Down
Loading