32.1. Parameterized Geometry
Table of Contents
Motivation for Parameterized Geometry
Geant4 often needs many repeated detector elements, for example long calorimeter stacks, pixel or strip detectors, or voxelized phantoms. Creating a separate volume and placement for every single copy is possible, but it becomes hard to maintain and slow to initialize when you have thousands or millions of elements.
Parameterized geometry offers a compact way to describe such repeated structures with a small amount of C++ code. Instead of explicitly placing every copy, you define a single logical volume and a parameterization class that tells Geant4 how to position and shape each copy when needed.
Using parameterized geometry can reduce memory usage, simplify your geometry description, and speed up navigation in large regular structures.
Basic Idea of Parameterized Volumes
In a parameterized geometry, you have three key ingredients. First, a logical volume that describes the basic type of object you are repeating, including its material and its solid class. Second, a placement volume that contains an arbitrary number of copies of that logical volume. Third, a parameterization class that, for each copy number, defines the solid dimensions, the transformation, and possibly the material.
Geant4 then treats each copy as an independent physical volume for tracking purposes, but you do not create them one by one. Instead, the geometry system queries the parameterization when it needs information about a specific copy, identified by its copy number.
Important rule: In a parameterized geometry, all copies share the same G4LogicalVolume object, but they can differ in size, position, and even material if your parameterization defines these quantities per copy.
The copy number is an integer index assigned by Geant4, usually from 0 up to the number of parameterized placements minus 1. Your parameterization class uses this index to compute the properties of that copy.
The G4VPVParameterisation Class
Parameterized geometry in Geant4 is controlled by user classes derived from G4VPVParameterisation. This is an abstract base class that defines the interface that Geant4 calls when it needs information about a particular copy.
You typically subclass G4VPVParameterisation and implement methods such as:
ComputeTransformation(G4int copyNo, G4VPhysicalVolume* physVol)to set the translation and rotation for each copy.ComputeDimensions(...)to set the size of the solid for a given copy.- Optionally,
ComputeMaterial(G4int copyNo, G4VPhysicalVolume physVol, const G4VTouchable parentTouch)if you want different materials for different copies.
Your parameterization object is then passed to a special placement class, G4PVParameterised, which uses it to create a family of parameterized volumes inside a mother volume.
Important rule: Any class derived from G4VPVParameterisation must correctly implement ComputeTransformation and at least one appropriate ComputeDimensions method that matches the solid type used in the logical volume.
If you mismatch the solid type and the ComputeDimensions function, Geant4 will either report errors at initialization or misinterpret your geometry.
Defining Dimensions of Parameterized Solids
In a parameterized geometry, the same logical volume can represent elements of different sizes. For example, a sampling calorimeter might have absorber plates that get thicker with depth, or a voxelized phantom might have different slice thicknesses.
To describe this, you implement ComputeDimensions in your parameterization class. The exact signature of this function depends on the solid type of your logical volume. For instance:
- For
G4Box:void ComputeDimensions(G4Box& box, const G4int copyNo, const G4VPhysicalVolume* physVol) const; - For
G4Tubs:void ComputeDimensions(G4Tubs& tubs, const G4int copyNo, const G4VPhysicalVolume* physVol) const; - For
G4Sphere:void ComputeDimensions(G4Sphere& sphere, const G4int copyNo, const G4VPhysicalVolume* physVol) const;
Inside this method, you typically compute the half lengths or radii based on the copy number. Geant4 calls ComputeDimensions during geometry setup, so you must not rely on event dependent information here.
For example, consider a stack of boxes whose thickness in $z$ increases linearly with copy number. If $t_0$ is the base half thickness for copy 0, and $\Delta t$ is the increment per copy, you might implement:
$$
t_z(\text{copyNo}) = t_0 + \text{copyNo} \cdot \Delta t
$$
and then set box.SetZHalfLength(t_z(copyNo)); inside ComputeDimensions.
Important rule: ComputeDimensions must be deterministic and must not depend on random numbers or run, event, or track state. The geometry must be fixed before the run starts.
As long as the volume type and the ComputeDimensions method match, you can achieve a wide variety of shapes that vary from copy to copy.
Positioning Parameterized Volumes
While ComputeDimensions defines the shape, ComputeTransformation sets the position and orientation of each copy. Geant4 calls this method with the copy number and a pointer to the physical volume. Inside, you typically compute a translation and rotation based on the index and apply them to physVol.
A simple and common example is a linear array or a stack. For instance, to place $N$ identical detector strips of width $w$ along the $x$ axis, with their centers separated by $d = w + g$, where $g$ is a gap:
$$
x(\text{copyNo}) = \left(\text{copyNo} - \frac{N - 1}{2}\right) \cdot d
$$
You would then call physVol->SetTranslation(G4ThreeVector(x(copyNo), 0, 0)); in ComputeTransformation.
You can create 2D or 3D grids similarly. For a 2D grid with indices $(i,j)$, you convert from the linear copyNo to two indices by:
$$
i = \text{copyNo} \bmod N_x, \quad j = \left\lfloor \frac{\text{copyNo}}{N_x} \right\rfloor
$$
Then you can compute positions $x(i)$ and $y(j)$ and set the translation accordingly.
Rotations are handled by constructing a G4RotationMatrix, setting the desired angles, and then calling physVol->SetRotation(&rotationMatrix); or using a precomputed matrix.
Important rule: ComputeTransformation defines the position and rotation of the copy relative to the mother volume, not in global coordinates.
The center of each parameterized volume must lie entirely inside its mother volume and must not overlap other volumes in an inconsistent way. If you get the positioning wrong, you can create overlaps that are difficult to debug.
Material and Copy Number Handling
In many applications, all elements in a parameterized family share the same material. In that case, you simply assign the material once when creating the logical volume and do nothing else. However, parameterized geometry also allows you to vary material by copy if necessary.
You can override ComputeMaterial in your parameterization class to return a different G4Material pointer for each copy based on its copy number or position. This is useful when building complex phantoms where different regions represent different tissues, or for layered detectors with alternating materials.
Even if you do not vary the material, the copy number is valuable. Each physical step in a parameterized volume carries a copy number, which you can access in sensitive detectors or user actions through the touchable history or directly from the step. This allows you to identify which element has been hit and associate it with an index in an array or an external file.
For example, for a 1D stack along $z$ you might define the copy number as an index $k$ that maps to a depth:
$$
z_k = z_0 + k \cdot \Delta z
$$
When you record energy deposition, you can fill a depth dose or profile histogram at bin $k$ based on the copy number, instead of computing the position directly from coordinates.
Important rule: The copy number is the primary way to distinguish individual elements within a parameterized family when you process hits and energy deposition.
Using copy numbers consistently simplifies analysis, since you can map from a single integer index to geometry properties or detector calibration information stored in arrays or external configuration.
Views: 11
KAHIBARO