6.1. DetectorConstruction
Table of Contents
Purpose of `G4VUserDetectorConstruction`
In every Geant4 application, the geometry of your simulation is defined by a user class that inherits from G4VUserDetectorConstruction. This class is your entry point for describing what exists in the simulated world, where it is placed, and which parts of it will act as detectors.
G4VUserDetectorConstruction is an abstract base class provided by Geant4. It does not implement any actual geometry itself. Instead, it defines the interface that Geant4 uses to ask your code: “Please build the geometry now.” You provide the answer by writing your own derived class and implementing the required virtual method, Construct().
At program startup, you create an instance of your detector construction class and give it to the run manager. A very common pattern in the main() function looks like this:
auto runManager = new G4RunManager();
// Your own detector construction
runManager->SetUserInitialization(new MyDetectorConstruction());
From this point, the run manager knows which object to call when it needs the geometry. Geant4 will call your detector construction at initialization time. This typically happens when you run /run/initialize in a macro or when you start a run.
Conceptually, your G4VUserDetectorConstruction derived class has three main responsibilities.
First, it defines the world volume. This is the outermost volume that contains everything else. Without a valid world volume, the simulation cannot start. Geant4 will transport particles only within this world. Any track that tries to leave the world volume will be killed.
Second, it defines all other logical and physical volumes that build your detector or experimental setup. This includes shapes, sizes, positions, and orientations of volumes, and which materials they are made from. The link between geometry and materials is usually handled inside this class.
Third, it optionally connects geometry to readout mechanisms, such as sensitive detectors or fields, by assigning appropriate objects to logical volumes. While sensitive detectors are covered in detail elsewhere, it is useful to know that the assignment itself normally happens inside the detector construction.
Because G4VUserDetectorConstruction is part of the initialization stage, any change to the geometry requires reinitialization of the run manager. For small exploratory changes, you can sometimes reconfigure things with macro commands, but structural changes to shapes or materials almost always mean you must rebuild and reinitialize the geometry.
Your simulation must always define exactly one valid world volume through a class derived from G4VUserDetectorConstruction. If the world is missing, invalid, or not returned correctly, Geant4 cannot run any events.
The `Construct()` method
Construct() is the central method where you actually build the geometry. It is declared as a pure virtual function in G4VUserDetectorConstruction:
virtual G4VPhysicalVolume* Construct() = 0;You must implement this method in your derived class. Geant4 will call it once during initialization to create the full geometry hierarchy. The method must return a pointer to the world physical volume, which is the top of the volume tree.
A typical minimal implementation of Construct() follows a clear sequence.
First, you define materials. Often you use G4NistManager to retrieve common materials such as air or water. While the main details of material creation are covered elsewhere, it is important that material pointers are ready before you create logical volumes.
Second, you define the world solid, logical volume, and physical volume. A usual pattern is to create a simple shape such as a G4Box that is larger than all other volumes you plan to place. For example:
G4VPhysicalVolume* MyDetectorConstruction::Construct()
{
// 1. Get materials
auto nist = G4NistManager::Instance();
G4Material* air = nist->FindOrBuildMaterial("G4_AIR");
// 2. World volume
G4double worldSize = 1.0*m;
auto solidWorld = new G4Box("World",
0.5*worldSize,
0.5*worldSize,
0.5*worldSize);
auto logicWorld = new G4LogicalVolume(solidWorld,
air,
"World");
auto physWorld = new G4PVPlacement(nullptr,
G4ThreeVector(),
logicWorld,
"World",
nullptr,
false,
0,
true);
// 3. Define and place other volumes here
return physWorld;
}This example shows the three levels that you will use repeatedly. A solid describes only the shape and dimensions. A logical volume combines a solid with a material and optional properties such as visualization attributes or a sensitive detector. A physical volume places an instance of a logical volume at a particular position and orientation inside a mother logical volume. The world logical volume has no mother, so its placement uses a null mother pointer.
Inside Construct(), after creating the world, you build the rest of your detector. For each component you typically follow the same pattern. You choose a solid class that matches the shape, such as G4Box, G4Tubs, or others. Then you create a logical volume using that solid and the appropriate material. Finally, you place the logical volume using a G4PVPlacement or another placement class inside its mother logical volume, often the world or a larger enclosing detector volume.
All geometry objects created in Construct() are normally allocated with new. Geant4 takes ownership of your geometry and will manage the objects for you. You do not need to delete them manually. This is why you can safely return a raw pointer to the world G4VPhysicalVolume.
The Construct() method is also the right place to enable optional checks on the geometry. The last argument of G4PVPlacement allows you to turn on overlap checking. If you set it to true, Geant4 will test whether the placed volume overlaps with its mother in an illegal way during initialization. This can be very helpful when you are first building your detector.
Construct() must return a valid pointer to the world G4VPhysicalVolume. All other volumes must be placed inside this world directly or indirectly. Any volume that is not attached to the world will not exist in the simulation.
There is one more related method that you may encounter, ConstructSDandField(). It belongs to the same class but is separate from Construct(). Geant4 calls it after the geometry is built. Its purpose is to attach sensitive detectors and fields to logical volumes. Keeping geometry construction in Construct() and detector assignment in ConstructSDandField() helps keep your geometry code organized and easier to maintain.
In simple beginner applications, you will often put everything directly in Construct() for clarity, then gradually move to a clearer structure as your detector becomes more complex. The key idea is that Construct() is the one place where you describe what your experimental world looks like, how large it is, what it is made of, and how all its pieces are arranged.
Views: 10
KAHIBARO