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}(0x000000005b625ee0))

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...
 60.644431 seconds (434.60 M allocations: 20.039 GiB, 29.28% gc time, 8.11% compilation time)
Drawning 172553 meshes with total of 50547542 points in 9 steps.
 62.307017 seconds (270.00 M allocations: 210.795 GiB, 37.76% gc time, 4.07% compilation time)
Drawing logical volume: LongStrips
Collecting LV meshes with clip=xy...
 11.094305 seconds (90.10 M allocations: 4.266 GiB, 32.45% gc time)
Drawning 48779 meshes with total of 10514826 points in 6 steps.
 15.656342 seconds (61.32 M allocations: 44.492 GiB, 38.26% gc time)
Drawing logical volume: Pixels
Collecting LV meshes with clip=xy...
  3.504488 seconds (23.34 M allocations: 1.202 GiB, 10.17% gc time)
Drawning 16103 meshes with total of 3000736 points in 6 steps.
  9.786519 seconds (19.80 M allocations: 12.732 GiB, 72.03% gc time)

Show the resulting images

CMS detector rendering

Tracker (long strips) rendering

Pixels rendering


This page was generated using Literate.jl.