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

Commit

Permalink
Fix type validation and parsing in Parameter column (#187)
Browse files Browse the repository at this point in the history
* Fix type validation and parsing in Parameter column

* Better use of type declarations across AxisymmetricOpticalSystem
  • Loading branch information
alfredclwong authored May 19, 2021
1 parent 13844d1 commit 7d8b4b8
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 43 deletions.
6 changes: 3 additions & 3 deletions src/Examples/docs_examples.jl
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,9 @@ function draw_zoomlenses(filenames::Vector{<:Union{Nothing,AbstractString}} = re
raygenerator = Sources.Source(; transform, origins, directions)

aspherics = [
[4 => 1.0386E-04, 6 => 1.4209E-07, 8 => -8.8495E-09, 10 => 1.2477E-10, 12 => -1.0367E-12, 14 => 3.6556E-15],
[4 => 4.2721E-05, 6 => 1.2484E-07, 8 => 9.7079E-09, 10 => -1.8444E-10, 12 => 1.8644E-12, 14 => -7.7975E-15],
[4 => 1.1339E-04, 6 => 4.8165E-07, 8 => 1.8778E-08, 10 => -5.7571E-10, 12 => 8.9994E-12, 14 => -4.6768E-14],
["4" => 1.0386E-04, "6" => 1.4209E-07, "8" => -8.8495E-09, "10" => 1.2477E-10, "12" => -1.0367E-12, "14" => 3.6556E-15],
["4" => 4.2721E-05, "6" => 1.2484E-07, "8" => 9.7079E-09, "10" => -1.8444E-10, "12" => 1.8644E-12, "14" => -7.7975E-15],
["4" => 1.1339E-04, "6" => 4.8165E-07, "8" => 1.8778E-08, "10" => -5.7571E-10, "12" => 8.9994E-12, "14" => -4.6768E-14],
]
syss = [
AxisymmetricOpticalSystem{Float64}(DataFrame(
Expand Down
2 changes: 1 addition & 1 deletion src/Examples/other_examples.jl
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ function convexplano(::Type{T} = Float64) where {T<:Real}
)
end

function doubleconvex(frontradius::T,rearradius::T) where{T<:Real}
function doubleconvex(frontradius::T, rearradius::T) where {T<:Real}
AxisymmetricOpticalSystem{T}(
DataFrame(
SurfaceType = ["Object", "Standard", "Standard", "Image"],
Expand Down
3 changes: 3 additions & 0 deletions src/Optical/Lenses.jl
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,9 @@ function AsphericLens(insidematerial::T, frontvertex::S, frontradius::S, frontco
end
else
#conic or aspheric
if backaspherics !== nothing
backaspherics = Tuple{Int,S}.(backaspherics)
end
surf = AcceleratedParametricSurface(ZernikeSurface(semidiameter + backdecenter_l + S(0.01), radius = backradius, conic = backconic, aspherics = backaspherics), nsamples, interface = opticinterface(S, insidematerial, nextmaterial, backsurfacereflectance, interfacemode))
lens_rear = leaf(surf, Transform{S}(zero(S), S(π), zero(S), backdecenter[1], backdecenter[2], frontvertex - thickness))
end
Expand Down
77 changes: 38 additions & 39 deletions src/Optical/OpticalSystem.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,15 @@
# Copyright (c) Microsoft Corporation. All rights reserved.
# See LICENSE in the project root for full license information.

using DataFrames
using Unitful.DefaultSymbols
using .OpticSim.GlassCat: AbstractGlass, TEMP_REF, PRESSURE_REF, Glass, Air

export AbstractOpticalSystem
export CSGOpticalSystem, temperature, pressure, detectorimage, resetdetector!, assembly
export AxisymmetricOpticalSystem, semidiameter
export trace, traceMT, tracehits, tracehitsMT

using DataFrames
using Unitful.DefaultSymbols

"""
AbstractOpticalSystem{T<:Real}
Expand Down Expand Up @@ -55,8 +56,8 @@ struct CSGOpticalSystem{T,D<:Number,S<:Surface{T},L<:LensAssembly{T}} <: Abstrac
detectorpixelsx::Int = 1000,
detectorpixelsy::Int = 1000,
::Type{D} = Float32;
temperature::Union{T,Unitful.Temperature} = convert(T, OpticSim.GlassCat.TEMP_REF),
pressure::T = convert(T, OpticSim.GlassCat.PRESSURE_REF)
temperature::Union{T,Unitful.Temperature} = convert(T, TEMP_REF),
pressure::T = convert(T, PRESSURE_REF)
) where {T<:Real,S<:Surface{T},L<:LensAssembly{T},D<:Number}
@assert hasmethod(uv, (S, SVector{3,T})) "Detector must implement uv()"
@assert hasmethod(uvtopix, (S, SVector{2,T}, Tuple{Int,Int})) "Detector must implement uvtopix()"
Expand Down Expand Up @@ -180,7 +181,7 @@ function trace(
# this will almost always not apply as the detector will be in air, but it's possible that the detector is
# not in air, in which case this is necessary
if !isair(m)
mat = glassforid(m)::OpticSim.GlassCat.Glass
mat::Glass = glassforid(m)
nᵢ = index(mat, λ, temperature = temperature(system), pressure = pressure(system))::T
α = absorption(mat, λ, temperature = temperature(system), pressure = pressure(system))::T
if α > zero(T)
Expand Down Expand Up @@ -228,14 +229,14 @@ function validate_axisymmetricopticalsystem_dataframe(prescription::DataFrame)
# the prescription DataFrame columns; the former refers to the actual `surface_type` values, which are all strings
required_cols = ["SurfaceType", "Radius", "Thickness", "Material", "SemiDiameter"]
supported_col_types = Dict(
"SurfaceType" => String,
"SurfaceType" => AbstractString,
"Radius" => Real,
"Thickness" => Real,
"Material" => GlassCat.AbstractGlass,
"Material" => AbstractGlass,
"SemiDiameter" => Real,
"Conic" => Real,
"Reflectance" => Real,
"Parameters" => Vector{<:Real},
"Parameters" => Vector{<:Pair{<:AbstractString,<:Real}},
)
cols = names(prescription)

Expand Down Expand Up @@ -312,54 +313,52 @@ struct AxisymmetricOpticalSystem{T,C<:CSGOpticalSystem{T}} <: AbstractOpticalSys
detectorpixelsx::Int = 1000,
detectorpixelsy::Int = 1000,
::Type{D} = Float32;
temperature::Union{T,Unitful.Temperature} = convert(T, OpticSim.GlassCat.TEMP_REF),
pressure::T = convert(T, OpticSim.GlassCat.PRESSURE_REF)
temperature::Union{T,Unitful.Temperature} = convert(T, TEMP_REF),
pressure::T = convert(T, PRESSURE_REF)
) where {T<:Real,D<:Number}
validate_axisymmetricopticalsystem_dataframe(prescription)

elements = Vector{Union{Surface{T},CSGTree{T}}}()
systemsemidiameter = zero(T)
firstelement = true
elements::Vector{Union{Surface{T},CSGTree{T}}} = []
systemsemidiameter::T = zero(T)
firstelement::Bool = true

# track sequential movement along the z-axis
vertices = convert(Vector{T}, -cumsum(replace(prescription[!, "Thickness"], Inf => 0, missing => 0)))
vertices::Vector{T} = -cumsum(replace(prescription[!, "Thickness"], Inf => 0, missing => 0))

# pre-construct list of rows which we will skip over (e.g. air gaps, but never Stop surfaces)
# later on, this may get more complicated as we add in compound surfaces
function skip_row(i::Int)
return (
prescription[i, "SurfaceType"] != "Stop" &&
(prescription[i, "Material"] === missing || prescription[i, "Material"] == GlassCat.Air)
(prescription[i, "Material"] === missing || prescription[i, "Material"] == Air)
)
end
skips = skip_row.(1:nrow(prescription))
skips::Vector{Bool} = skip_row.(1:nrow(prescription))

for i in 2:nrow(prescription)-1
if skips[i]
continue
end

surface_type = prescription[i, "SurfaceType"]
lastmaterial, material, nextmaterial = prescription[i-1:i+1, "Material"]
thickness = convert(T, prescription[i, "Thickness"])
surface_type::String = prescription[i, "SurfaceType"]
lastmaterial::AbstractGlass, material::AbstractGlass, nextmaterial::AbstractGlass = prescription[i-1:i+1, "Material"]
thickness::T = prescription[i, "Thickness"]

frontradius, backradius = get_front_back_property(prescription, i, "Radius")
frontsurfacereflectance, backsurfacereflectance = get_front_back_property(
frontradius::T, backradius::T = get_front_back_property(prescription, i, "Radius")
frontsurfacereflectance::T, backsurfacereflectance::T = get_front_back_property(
prescription, i, "Reflectance", zero(T)
)
frontconic::T, backconic::T = get_front_back_property(prescription, i, "Conic", zero(T))
frontparams::Vector{Pair{String,T}}, backparams::Vector{Pair{String,T}} = get_front_back_property(
prescription, i, "Parameters", Vector{Pair{String,T}}()
)

semidiameter = NaN
semidiameter::T = max(get_front_back_property(prescription, i, "SemiDiameter", zero(T))...)

if surface_type == "Stop"
newelement = CircularAperture(
convert(T, prescription[i, "SemiDiameter"]),
SVector{3,T}(0.0, 0.0, 1.0),
SVector{3,T}(0.0, 0.0, vertices[i-1])
)
semidiameter = prescription[i, "SemiDiameter"]
newelement = CircularAperture(semidiameter, SVector{3,T}(0, 0, 1), SVector{3,T}(0, 0, vertices[i-1]))
elseif surface_type == "Standard"
semidiameter = convert(T, max(get_front_back_property(prescription, i, "SemiDiameter", zero(T))...))
frontconic, backconic = get_front_back_property(prescription, i, "Conic", zero(T))

if frontconic != zero(T) || backconic != zero(T)
newelement = ConicLens(
material, vertices[i-1], frontradius, frontconic, backradius, backconic, thickness,
Expand All @@ -372,9 +371,9 @@ struct AxisymmetricOpticalSystem{T,C<:CSGOpticalSystem{T}} <: AbstractOpticalSys
)()
end
elseif surface_type == "Aspheric"
semidiameter = convert(T, max(get_front_back_property(prescription, i, "SemiDiameter", zero(T))...))
frontconic, backconic = get_front_back_property(prescription, i, "Conic", zero(T))
frontaspherics, backaspherics = get_front_back_property(prescription, i, "Parameters", Vector{Pair{Int,Float64}}())
frontaspherics::Vector{Pair{Int,T}}, backaspherics::Vector{Pair{Int,T}} = [
[parse(Int, k) => v for (k, v) in params] for params in [frontparams, backparams]
]

newelement = AsphericLens(
material, vertices[i-1], frontradius, frontconic, frontaspherics, backradius, backconic,
Expand All @@ -388,7 +387,7 @@ struct AxisymmetricOpticalSystem{T,C<:CSGOpticalSystem{T}} <: AbstractOpticalSys
)
end

if firstelement && semidiameter !== NaN
if firstelement
systemsemidiameter = semidiameter
firstelement = false
end
Expand All @@ -397,8 +396,8 @@ struct AxisymmetricOpticalSystem{T,C<:CSGOpticalSystem{T}} <: AbstractOpticalSys
end

# make the detector (Image)
imagesize = prescription[end, "SemiDiameter"]
imagerad = prescription[end, "Radius"]
imagesize::T = prescription[end, "SemiDiameter"]
imagerad::T = prescription[end, "Radius"]
if imagerad != zero(T) && imagerad != typemax(T)
det = SphericalCap(
abs(imagerad),
Expand All @@ -409,8 +408,8 @@ struct AxisymmetricOpticalSystem{T,C<:CSGOpticalSystem{T}} <: AbstractOpticalSys
)
else
det = Rectangle(
convert(T, imagesize),
convert(T, imagesize),
imagesize,
imagesize,
SVector{3,T}(0, 0, 1),
SVector{3,T}(0, 0, vertices[end-1]),
interface = opaqueinterface(T)
Expand Down

2 comments on commit 7d8b4b8

@alfredclwong
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

@JuliaRegistrator register()

@JuliaRegistrator
Copy link

Choose a reason for hiding this comment

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

Registration pull request created: JuliaRegistries/General/37080

After the above pull request is merged, it is recommended that a tag is created on this repository for the registered package version.

This will be done automatically if the Julia TagBot GitHub Action is installed, or can be done manually through the github interface, or via:

git tag -a v0.5.0 -m "<description of version>" 7d8b4b8d0e4d1612f50db4baf8755301693b9219
git push origin v0.5.0

Please sign in to comment.