KAHIBARO
Discord Login Register

23.7. Recording Energy Deposition

Connecting Energy Deposition to Physics

In a gamma ray detector, you rarely measure the gamma directly. Instead, the gamma interacts in the detector, produces charged particles, and those particles deposit energy in the detector material. Your simulation must therefore record the energy deposited in the sensitive parts of the detector, not the primary particle energy itself.

Geant4 gives you energy deposition information step by step, through the stepping mechanism and through hits in sensitive detectors. In a simple scintillation detector example, you usually want, for each event, the total energy deposited in the crystal so that you can build an energy spectrum and compare it to a real detector.

This chapter focuses on how to extract energy deposition from Geant4, how to organize it per event and per detector, and how to pass it to your analysis code in the context of the gamma ray detector example.

In Geant4, measured energy almost always comes from energy deposition in matter, not from the particle’s kinetic energy directly.

Using `G4Step` and `GetTotalEnergyDeposit()`

Every time a particle advances through the geometry, Geant4 creates a G4Step. A step contains information about what happened to the particle in that small path segment, including how much energy was deposited in the current volume.

The central quantity is the total energy deposit in the step, returned by
step->GetTotalEnergyDeposit().

In C++ this typically appears inside a UserSteppingAction or a sensitive detector:

cpp
G4double edep = step->GetTotalEnergyDeposit();

The value is given in internal Geant4 energy units, usually MeV if you use the standard units system and construct your physics normally. You do not need to convert it for internal accumulation, but you should be consistent when printing or storing to file.

Many steps have zero energy deposit. Your code must check and skip those if you are only interested in nonzero energy deposition, for example in a scintillator crystal.

Key rule: The energy deposition in a step is obtained with
G4double edep = step->GetTotalEnergyDeposit();
Always handle the case edep == 0. to avoid filling your histograms with empty entries.

Collecting Energy per Event

For a gamma ray detector, the main observable is usually the total energy deposited in the detector during one event. An event can contain many tracks and many steps, distributed over one or multiple detector volumes. You must therefore:

  1. Sum the deposited energy over all relevant steps in the detector crystal(s) during the event.
  2. Store the resulting total at the end of the event, for example in a histogram or an ntuple.

A typical pattern is:

  1. Initialize an event-level variable, for example fEventEdep, to zero at the start of each event inside your EventAction::BeginOfEventAction.
  2. In your stepping logic, every time a step occurs inside the scintillator, add its GetTotalEnergyDeposit() to fEventEdep.
  3. At EndOfEventAction, use fEventEdep to fill a histogram or write it to an ntuple.

In code, the stepping part might look like this:

cpp
void SteppingAction::UserSteppingAction(const G4Step* step)
{
  G4double edep = step->GetTotalEnergyDeposit();
  if (edep <= 0.) return;
  // Check if we are in the scintillator crystal
  auto volume = step->GetPreStepPoint()->GetTouchableHandle()->GetVolume();
  if (volume == fScintillatorPV)
  {
    fEventAction->AddEdep(edep);
  }
}

Here fEventAction is a pointer to your EventAction, and AddEdep is a small helper that adds energy to the event sum:

cpp
void EventAction::AddEdep(G4double edep)
{
  fEdep += edep;
}

Important pattern:
Initialize an event sum in BeginOfEventAction, add GetTotalEnergyDeposit() from every relevant step during the event, and finally process the sum in EndOfEventAction.

Energy Deposition in a Gamma Detector Crystal

In the gamma ray detector example, the detector is a scintillator crystal, for instance a G4Box or G4Tubs logical volume filled with a scintillating material such as NaI(Tl) or a plastic scintillator.

Your aim is to record only the energy deposited in this scintillator, not in the world, air, or supporting structures. The simplest way to do this in code is to compare the current volume to a saved pointer to the crystal’s physical or logical volume.

After you construct the detector geometry, store a pointer:

cpp
// In DetectorConstruction::Construct()
fScintillatorPV = new G4PVPlacement(
  0,                       // rotation
  G4ThreeVector(),         // position
  scintillatorLV,          // logical volume
  "Scintillator",          // name
  worldLV,                 // mother volume
  false,                   // no boolean operation
  0,                       // copy number
  true                     // check overlaps
);

Then pass fScintillatorPV to your SteppingAction, so that you can test:

cpp
auto volume = step->GetPreStepPoint()->GetTouchableHandle()->GetVolume();
if (volume == fScintillatorPV) {
  // this step is inside the scintillator
}

Only for those steps do you accumulate GetTotalEnergyDeposit(). This ensures that the final event energy corresponds to what your detector would measure.

If you build an array of crystals, you can use the copy number or detector ID to separate the deposited energy per element. That is covered later in the course, but the principle is the same: use GetTouchableHandle() and its copy number to identify which element was hit.

To record energy in the scintillator only, always check the current volume or its copy number before adding GetTotalEnergyDeposit() to your event sum.

Hits, Sensitive Detectors, and Energy

Instead of collecting energy in SteppingAction, you can use a sensitive detector attached to the crystal’s logical volume. The sensitive detector approach is closer to the realistic concept of a detector, especially when you have many detector elements.

In the gamma ray detector example, a simple hit class might record, for a given event:

A minimal hit class can store just energy and time for a single interaction. The sensitive detector class then implements ProcessHits:

cpp
G4bool MySD::ProcessHits(G4Step* step, G4TouchableHistory*)
{
  G4double edep = step->GetTotalEnergyDeposit();
  if (edep <= 0.) return false;
  // Access or create a hit for this event / crystal
  // and add the deposited energy:
  fHit->AddEdep(edep);
  return true;
}

Geant4 automatically calls ProcessHits for each step that occurs inside the logical volume to which your sensitive detector has been assigned. At the end of the event, you can access the hit collection in EventAction::EndOfEventAction, retrieve the total energy for the crystal, and pass it to the analysis manager.

Using sensitive detectors is especially powerful when your gamma detector has many crystals. Each crystal can correspond to one hit or one cell in a hit collection. For a single large crystal the stepping-based accumulation and the sensitive detector approach are functionally similar, but sensitive detectors integrate more naturally with Geant4’s event and hits system.

Energy deposition inside a sensitive detector volume is best handled through a custom hit class and a class derived from G4VSensitiveDetector, which uses ProcessHits and GetTotalEnergyDeposit().

Building an Energy Spectrum from Deposited Energy

Once you have the total deposited energy per event, you can create an energy spectrum, which is the main observable for a gamma ray detector. The spectrum is usually a histogram of energy, where each bin counts how many events had a given deposited energy.

The typical workflow in the gamma detector example is:

  1. In EventAction::EndOfEventAction, get the event’s total energy deposition in the scintillator, for example fEdep.
  2. Pass fEdep to the analysis manager and fill a 1D histogram.

Using G4AnalysisManager, the code might look like:

cpp
void EventAction::EndOfEventAction(const G4Event*)
{
  auto analysisManager = G4AnalysisManager::Instance();
  // Histogram 0: deposited energy per event
  analysisManager->FillH1(0, fEdep);
  // Optionally, also write to an ntuple column
  analysisManager->FillNtupleDColumn(0, fEdep);
  analysisManager->AddNtupleRow();
}

The histogram is configured elsewhere in your run or analysis setup, with binning appropriate to your detector and gamma energies.

For example, for a 662 keV gamma ray from Cs-137 detected in a NaI(Tl) crystal, you might choose a histogram range of 0 to 1 MeV with a few thousand bins. The raw simulation spectrum corresponds to an ideal detector with perfect energy resolution. In later chapters, detector resolution effects are added by smearing this deposited energy with a Gaussian.

In this way, the link from physics to output is:

Gamma interaction in crystal
→ charged secondaries deposit energy
GetTotalEnergyDeposit() summed per event
→ event energy filled into a histogram
→ resulting energy spectrum shows photopeak, Compton continuum, and escape features.

To build an energy spectrum, use total event energy deposition in the detector, not individual step energies, and fill one histogram entry per event.

Practical Considerations for the Gamma Detector Example

In a simple scintillation detector simulation, a few practical points help you record energy deposition correctly:

First, ensure that production cuts and physics settings are chosen so that low energy secondary particles that contribute to the energy deposition are produced and tracked. If the cuts are too large, some energy might be discarded as continuous energy loss below threshold, which still appears in GetTotalEnergyDeposit(), but details of microscopic tracks will be lost. For the purpose of recording macroscopic energy deposition in a scintillator, this is usually acceptable.

Second, avoid summing deposited energy in multiple places. Choose either a stepping based approach or the sensitive detector / hits based approach for your main observable, not both at once, to prevent double counting.

Third, when comparing to experiment later, always remember that the simulated deposited energy per event is the ideal signal. Real detectors have finite energy resolution, nonlinearity, thresholds, and dead material. This chapter only prepares the ideal deposited energy. Detector effects are added later by post processing the recorded energy.

Finally, verify your implementation with simple checks, for example by sending noninteracting particles through the world and checking that the total energy deposition is zero, or by placing a very thin crystal so that most events produce partial energy deposition and the histogram shows the expected Compton shape.

With these practices in place, your gamma ray detector simulation will provide a reliable per event energy deposition that forms the basis of realistic detector response studies.

Views: 8

Comments

Please login to add a comment.

Don't have an account? Register now!