35.7. Implement Sensitive Detectors
Table of Contents
Connecting Physics to Readout
In the final project, sensitive detectors are the bridge between the physics happening in your geometry and the data you will analyze. Geometry alone only describes where materials are. A sensitive detector turns specific volumes into “measurement devices” that can react to energy deposition, count particles, or record timing information.
In Geant4, this is done by assigning a sensitive detector object to one or more logical volumes. Whenever a step occurs in one of those volumes, your sensitive detector code has the opportunity to create a hit and store whatever information you consider relevant.
In the context of the final project, you will already have defined your detector geometry, materials, and physics list. Implementing sensitive detectors is the step where you design how your virtual detector “responds” and what quantities you will write out for analysis.
A volume is only “detected” if you assign a sensitive detector to its logical volume. Without this assignment, no hits or detector signals are recorded, even if energy deposition takes place.
Designing What You Want to Record
Before you write any code, decide what a “measurement” in your final project should look like. Different projects require different hit information:
For a calorimeter-like detector you often need total energy deposited per detector element per event, and maybe the position of the energy deposit to reconstruct shower shapes.
For a tracking detector you are usually interested in the position of each crossing, the time, and sometimes the momentum or particle type.
For a PET or gamma detector project you may care about deposited energy, time, and which crystal (ID) was hit, so you can build energy spectra and coincidence events.
For the final project, write down a minimal set of quantities such as energy, time, detector ID and position, that you will store for each interaction or for each detector element per event. This design choice will guide your hit class and sensitive detector implementation. Collecting too much detail can slow the simulation and produce unnecessarily large output. Collecting too little can make later analysis impossible.
Decide your hit content before coding. Changing the hit structure later usually means changing your analysis code and may invalidate data you already produced.
Creating a Hit Class for Your Detector
A hit represents the response of a single detector element or channel during an event. In Geant4, a hit is an object derived from a hit base class such as G4VHit. For the final project you will typically create one hit class per detector type, for example MyDetectorHit for a generic detector, CalorimeterHit for a calorimeter, or CrystalHit for scintillator crystals.
A minimal hit class usually contains:
An identifier of the detector element, like copy number or channel ID.
Measured (or simulated) energy $E_{\text{dep}}$ in that element.
Time information, for example the earliest time or the time of the energy deposit.
Position, such as the step position or the center of the detector element.
Optionally, particle or track information, for example PDG code or track ID, useful for debugging or detailed studies.
In C++ terms, your hit class is a small data container with member variables, setters and getters, and the methods required by Geant4, such as a constructor, destructor, and potentially Draw() or Print() methods. For large simulations you usually do not draw hits but having a Print() method can be helpful when debugging your final project.
Even if in your analysis you plan to use summed quantities per event, it is still useful to record step-level hits during early development, then later simplify or aggregate them once you know exactly what you need.
Implementing a Sensitive Detector Class
The core of the detector response is your sensitive detector class, derived from G4VSensitiveDetector. In the final project it will be one of your main user-defined classes, for example MyDetectorSD or CrystalSD. This class defines how each step inside a sensitive volume is translated into hits.
A typical sensitive detector needs to:
Declare the name of its hit collection.
Create the collection at the beginning of each event.
Respond to each step inside its attached volumes via the ProcessHits method.
Store hits into the collection for later access by your event or run actions.
The key method is usually
G4bool ProcessHits(G4Step step, G4TouchableHistory history);
Inside ProcessHits, you will extract information from the step such as total energy deposited, global time or position, then either create a new hit object or update an existing hit for that detector element.
For a calorimetric detector you often sum all energy in a cell, so ProcessHits will look up if a hit for that cell already exists in the current event and add the new step’s energy. For a tracker-style detector you may create a separate hit per step or per crossing.
Even though the detailed C++ code belongs to other chapters, conceptually your sensitive detector is where physics events become detector signals that you will later convert into histograms and ntuples.
ProcessHits is called for every step in your sensitive volume. Unnecessary complex logic inside this method can strongly affect performance, especially in large final project runs.
Attaching Sensitive Detectors to Logical Volumes
Once you have a sensitive detector class, you must attach instances of it to the logical volumes that represent the active parts of your detector. This is usually done in your detector construction class or in a dedicated geometry setup method.
You normally:
Create an instance of your sensitive detector, often via the Geant4 SD manager.
Register that sensitive detector with the SD manager.
Assign it to the logical volume that should be sensitive.
If you have many identical detector elements such as an array of crystals or layers, you typically assign one sensitive detector instance to the logical volume that is replicated or parameterized. Geant4 then uses the copy number of the physical volume to distinguish which element was hit. This avoids creating thousands of sensitive detector objects.
In the final project, ensure that only the appropriate volumes are marked as sensitive. Support structures, shielding or world volumes should remain non sensitive to avoid useless hits and slower simulations. The boundary between sensitive and non sensitive volumes should match the conceptual “active area” of your detector.
Attaching a sensitive detector to a physical volume is not supported. Always attach to the corresponding logical volume so that all of its placements share the same sensitive behavior.
Managing Hit Collections per Event
Hits created by your sensitive detector are stored in hit collections. Each sensitive detector usually has one hit collection type, and each event has its own instance of that collection. This organization is important for your final project, because you will usually analyze or write out the data event by event.
Conceptually, the sequence is:
At the beginning of an event, your sensitive detector creates a fresh hit collection and registers it with the event’s collection of collections.
During the event, each call to ProcessHits creates or updates hits in that collection.
At the end of the event, your event action can retrieve the hit collection by its ID and process or copy the information into analysis structures such as histograms or ntuples.
For example, in a PET-like final project you might, at the end of each event, inspect the hit collection to find which crystals were hit and with what energy and time. You can then apply an energy window, build coincidence pairs, and fill your analysis output.
Pay attention to the mapping between collection names and IDs. Once initialized, these IDs stay constant within a run. It is good practice in your final project to obtain the IDs once during initialization of your event action and store them, instead of looking them up every event.
Never keep hit pointers from one event and use them in another. Hits are owned by the event’s hit collections and are only valid for the lifetime of that event.
Planning Data Flow into the Analysis Stage
Sensitive detectors are the first stage of your data pipeline. The information they produce must match what your analysis code expects. In the context of the final project, you already know that later you will:
Create histograms and ntuples.
Write output files for ROOT or other tools.
Validate detector performance and physics.
To make this smooth, design a clear mapping from hit information to analysis variables. For instance:
If your analysis will plot an energy spectrum per detector element, ensure that each hit carries a detector ID, and that you sum energy per detector element before filling the histogram.
If you need time versus energy information, your hits must carry both, not just one.
If you plan to calculate efficiency or spatial resolution, you will need counts of incident vs detected particles and accurate positions.
A simple and robust strategy for the final project is:
Keep sensitive detectors responsible only for collecting raw detector-like information, like energy deposits and times.
Use event and run actions to transform that raw information into higher level quantities and fill the analysis manager.
By keeping responsibilities separated, it is easier to adjust your analysis logic without touching the detector response implementation, and vice versa. This also improves clarity when you later document your final project.
Do not perform file I/O or heavy analysis directly inside ProcessHits. Use user actions and the Geant4 analysis system to write data in a controlled and efficient way.
Testing and Debugging Your Detector Response
After implementing sensitive detectors, you must verify that they behave as intended before running long final project simulations. A few targeted tests can save a lot of wasted computation time.
First, run with a small number of events and simple particle sources that hit a known part of your detector. Use verbose stepping or dedicated printouts to check that:
Steps in sensitive volumes produce hits.
Energy deposition values are non zero where expected and zero where not.
Detector IDs or copy numbers correspond to the physical locations you think they do.
Second, visualize your geometry and particle tracks, and compare with printed hit positions. This helps you confirm that the geometry, placement, and sensitive assignments are consistent.
Third, cross check energy conservation qualitatively. For example, if particles are stopped in your detector, the sum of energy deposited in the hits should be close to the initial particle energy (minus any escaping secondaries). This connects to later validation steps but can already reveal obvious bugs such as missing sensitive volumes or wrong unit usage.
Finally, once basic behavior is confirmed, remove or reduce debug printouts and move to using histograms and ntuples. This keeps your final project efficient and makes the analysis workflow more realistic.
By following this approach, your sensitive detector implementation becomes a reliable and well understood component in your complete Geant4 final project.
Views: 8
KAHIBARO