Skip to content

Parallel Geometry

Michal Mazurek requested to merge mimazure-parallel-geometry into master

Parallel Geometry

@gcorti @adavis @kreps @bsiddi

needs: !757 (merged)

This adds a new package ParallelGeometry that allows for adding external detectors (from ExternalDetector package) in parallel worlds on top of mass geometry. This can be used in studies where we would like to have volumes / sensitive detectors overlapping each other.

Note: an interface to ExternalDetector had to be modified a little bit.


Embedding a volume / sensitive detector in a parallel world is almost the same as for the mass geometry with the exception that materials are not required to be defined i.e. can be nullptr. If that is the case, then all the particles just "see" the boundaries coming from the parallel world.

If you actually want to set any material in your parallel world, then make sure you have LayeredMass=True in the configuration of parallel world physics. Otherwise, it won't work. If LayeredMass=True, then all the worlds below in your stack will see the material of that world.

Example 1: an empty cube in a parallel world

Here's an example of how you can embed an empty cube in a parallel world that will also be activated as an MCCollector type of sensitive detector:

from Configurables import Gauss
Gauss().ParallelGeometry = True

from Configurables import ExternalDetectorEmbedder
parallel_embedder = ExternalDetectorEmbedder("CubeEmbedder")

parallel_embedder.Shapes = {
    "Cube": {
        "Type": "Cuboid",
        "xSize": 1. * m,
        "ySize": 1. * m,
        "zSize": 1. * m,
        "MaterialName": '/dd/Materials/Vacuum', # make sure to prefetch your material!

parallel_embedder.Sensitive = {
    "Cube": {
        "Type": "MCCollectorSensDet",

from Configurables import ParallelGeometry
ParallelGeometry().ParallelWorlds = {
    'ParallelCubeWorld': {
        'ExternalDetectorEmbedder': 'CubeEmbedder',
        'WorldMaterial': '/dd/Materials/Air',

ParallelGeometry().ParallelPhysics = {
    'ParallelCubeWorld': {
        'LayeredMass': True, # if true, then materials will be overridden down the stack

# optional, if you want to save your parallel world to a gdml file
# note: this only works if you have materials defined in your parallel world
# G4GDMLParser crashes if any of the volumes have a nullptr material

ParallelGeometry().SaveGDML = {
    'ParallelCubeWorld': {
        "Output": "ParallelCubeWorld.gdml",
        "ExportSD": True, # other options of the GDMLRunAction

# optional, if you want to use material from GaussGeo
from Configurables import GaussGeo
GaussGeo().PrefetchMaterials = ['/dd/Materials/Vacuum']

test mixed_geometry.qmt

In this test, you'll find 3 same-size sensitive detectors (of type MCCollector) each placed in a different world. One of them is placed in the mass world and is made out of the lead. The second one is made out of the vacuum and placed in a parallel world, right on top of the mass world. Finally, the last one is placed in another parallel world on top of the other worlds.

A single 1 GeV photon is released along the z-axis. Because the last world on the stack has LayerdMass=False, the material is not overridden and the photon "sees" vacuum as the material of the plane. As a result, it does not deposit any energy within its body.

The test checks whether the hits generated in all three sensitive detectors are EXACTLY the same. They should be registered in the same place and have 0 energy deposit.


Edited by Michal Mazurek

Merge request reports