Skip to content

Commit 69104fe

Browse files
committed
Support tori with partial θ ranges in Geant4 extension
1 parent e0e2451 commit 69104fe

File tree

1 file changed

+60
-14
lines changed

1 file changed

+60
-14
lines changed

ext/Geant4/io_gdml.jl

+60-14
Original file line numberDiff line numberDiff line change
@@ -322,21 +322,26 @@ function parse_geometry(e::Ellipsoid{T,<:Any, TR, Nothing, Nothing}, x_solids::X
322322
nothing
323323
end
324324

325-
# @inline parse_θ(::Type{T}, θ::Nothing) where {T} = (T(0), T(360), "deg")
326-
# @inline parse_θ(::Type{T}, θ::Tuple{T, T}) where {T} = throw(AssertionError("Torus: θ values are currently not supported"))
327-
function parse_geometry(e::Torus, x_solids::XMLElement, x_define::XMLElement, id::Integer, pf::AbstractString, v::Bool)::Nothing
328-
if has_volume(e, v)
325+
function parse_geometry(e::Torus{T,<:Any,<:Any,Nothing,Nothing}, x_solids::XMLElement, x_define::XMLElement, id::Integer, pf::AbstractString, v::Bool)::Nothing where {T}
326+
327+
# if e.r_torus == 0, the torus is basically a sphere => convert it to a sphere
328+
if iszero(e.r_torus)
329+
parse_geometry(
330+
if isa(e.r_tube, Tuple)
331+
CSGDifference(
332+
Ellipsoid{T}(r = e.r_tube[2], origin = e.origin, rotation = e.rotation),
333+
Ellipsoid{T}(r = e.r_tube[1], origin = e.origin, rotation = e.rotation)
334+
)
335+
else
336+
Ellipsoid{T}(r = e.r_tube, origin = e.origin, rotation = e.rotation)
337+
end,
338+
x_solids, x_define, id, pf, v
339+
)
340+
341+
elseif has_volume(e, v)
329342
y = new_child(x_solids, "torus")
330-
# phi, aunit = parse_φ(T, e.φ)
331-
# theta1, theta2, aunit = parse_θ(T, e.θ)
332343

333-
rmin, rmax = if isa(e.r_tube, Tuple)
334-
e.r_tube[1], e.r_tube[2]
335-
else
336-
0, e.r_tube
337-
end
338-
339-
# rmin = 0
344+
rmin, rmax = isa(e.r_tube, Tuple) ? e.r_tube : (0, e.r_tube)
340345

341346
set_attributes(y, OrderedDict(
342347
"name" => pf * string(id),
@@ -348,7 +353,48 @@ function parse_geometry(e::Torus, x_solids::XMLElement, x_define::XMLElement, id
348353
"lunit" => SolidStateDetectors.internal_length_unit,
349354
"aunit" => "deg"
350355
))
351-
356+
end
357+
end
358+
359+
function _rectangle_point(x::T)::Tuple{T,T} where {T <: Real}
360+
return (
361+
clamp(tand(abs(mod(x-90,360)-180)-90),-1,1),
362+
clamp(tand(abs(mod( x,360)-180)-90),-1,1)
363+
)
364+
end
365+
366+
function parse_geometry(e::Torus{T,<:Any,<:Any,Nothing,Tuple{T,T}}, x_solids::XMLElement, x_define::XMLElement, id::Integer, pf::AbstractString, v::Bool)::Nothing where {T}
367+
if has_volume(e, v)
368+
369+
theta1::T, theta2::T = rad2deg.(e.θ)
370+
rmax = isa(e.r_tube, Tuple) ? e.r_tube[2] : e.r_tube
371+
372+
parse_geometry(
373+
CSGIntersection(
374+
# create full-θ Torus
375+
Torus(r_torus = e.r_torus, r_tube = e.r_tube, φ = e.φ, θ = nothing, origin = e.origin, rotation = e.rotation),
376+
377+
# create Polycone to intersect with
378+
begin
379+
points = Tuple{T,T}[(zero(T), zero(T))]
380+
push!(points, _rectangle_point(theta2))
381+
tmp::T = theta2 - mod(theta2 - 45, 90)
382+
while theta1 < tmp && tmp > 0
383+
push!(points, _rectangle_point(tmp))
384+
tmp -= 90
385+
end
386+
push!(points, _rectangle_point(theta1))
387+
push!(points, (zero(T), zero(T)))
388+
Polycone(
389+
r = getindex.(points,1) .* rmax .+ e.r_torus,
390+
z = getindex.(points,2) .* rmax,
391+
origin = e.origin,
392+
rotation = e.rotation
393+
)
394+
end
395+
),
396+
x_solids, x_define, id, pf, v
397+
)
352398
end
353399
end
354400

0 commit comments

Comments
 (0)