GDML rendering example (ODD)

In this example we demonstrate how to render detector geometries from a GDML file in Geant4. The example uses the OpenDataDetector model and renders a number of logical volumes to a PNG image. The rendering is done using the GLMakie backend of the Makie.jl graphics library.

Note that

You can also download this example as a Jupyter notebook and a plain Julia source file.

Loading the necessary Julia modules

  • Geant4 and Geant4.SystemOfUnits for the Geant4 interface and units
  • GLMakie for the OpenGL-based rendering backend of Makie
using Geant4
using Geant4.SystemOfUnits
using GLMakie

Set the number of rotation steps for polyhedra to get smoother meshes

HepPolyhedron!SetNumberOfRotationSteps(64)
set_theme!(backgroundcolor = :black)

Create the detector geometry from a GDML file

The function G4JLDetectorGDML reads a GDML file and creates the corresponding Geant4 geometry. The validate_schema=false option is used to skip GDML schema validation for faster loading.

detname = "OpenDataDetector"
detector = G4JLDetectorGDML("$(@__DIR__)/$(detname).gdml"; validate_schema=false);
G4GDML: Reading '/home/runner/work/Geant4.jl/Geant4.jl/docs/src/examples/OpenDataDetector.gdml'...
G4GDML: Reading definitions...
G4GDML: Reading materials...
G4GDML: Reading solids...
G4GDML: Reading structure...
G4GDML: Reading setup...
G4GDML: Reading '/home/runner/work/Geant4.jl/Geant4.jl/docs/src/examples/OpenDataDetector.gdml' done!
Stripping off GDML names of materials, solids and volumes ...

Get the logical volumes to render

odd     = GetVolume("world_volume")[]
lstrips = GetVolume("LongStrips")[]
pixels  = GetVolume("Pixels")[]
Geant4.G4LogicalVolumeDereferenced(Ptr{Nothing}(0x000000005cfefc70))

Create and render scenes

  • You can adjust the maxlevel keyword argument in the draw! function to control the level of detail in the rendering.
  • The clip keyword argument can be used to apply clipping planes to the geometry for better visibility of internal structures. In this example, we use clip=:xy to clip along the X=0 and Y=0 planes. Other possible values are :x, :y, :z for single-plane, :xz, :yz, :xyz clipping for double and triple planes, and :none for no clipping.
  • Lighting options and camera position can be adjusted. See the Lighting and Camera3D documentation of Makie.
for lv in (odd, lstrips, pixels)
  lvname = GetName(lv) |> String
  println("Drawing logical volume: $lvname")
  fig = Figure(size=(1080, 800))
  ax = LScene(fig[1, 1]; show_axis=false, scenekw=(;
      lights=[ PointLight(RGBf(1, 1, 1), Vec3f(1, 1, 0)),
               DirectionalLight(RGBf(1, 1, 1), Vec3f(1, 1, 1) ),
               AmbientLight(RGBf(.5, .5, .5)),
             ]))
  Camera3D(ax.scene, upvector=Vec3f(0, 1, 0), eyeposition=Vec3f(8m, 8m, 2m), lookat=Vec3f(0, 0, 0))
  draw!(ax, lv; maxlevel=7, clip=:xy);
  #display(fig)
  save("$(detname)_$(lvname).png", fig)
end
Drawing logical volume: world_volume
Collecting LV meshes with clip=xy...
 61.253084 seconds (434.21 M allocations: 20.032 GiB, 28.98% gc time, 6.30% compilation time)
Drawning 172553 meshes with total of 50547542 points in 9 steps.
 64.597506 seconds (270.38 M allocations: 211.232 GiB, 36.12% gc time, 4.02% compilation time)
Drawing logical volume: LongStrips
Collecting LV meshes with clip=xy...
 10.997262 seconds (89.62 M allocations: 4.260 GiB, 32.48% gc time)
Drawning 48779 meshes with total of 10514826 points in 6 steps.
 15.196297 seconds (61.81 M allocations: 44.548 GiB, 37.80% gc time)
Drawing logical volume: Pixels
Collecting LV meshes with clip=xy...
  3.101205 seconds (20.32 M allocations: 1.157 GiB, 4.40% gc time)
Drawning 16103 meshes with total of 3000736 points in 6 steps.
 25.021206 seconds (22.83 M allocations: 12.768 GiB, 82.41% gc time)

Show the resulting images

CMS detector rendering

Tracker (long strips) rendering

Pixels rendering


This page was generated using Literate.jl.