KAHIBARO
Discord Login Register

Applying an Energy Window

Why PET Uses an Energy Window

In a PET scanner, you are interested in detecting 511 keV annihilation photons that originate from positron annihilation events. In practice, the detector also records:

  1. Photons that have scattered in the patient or in the detector material.
  2. Background radiation and noise.
  3. Events that deposit only part of their energy in a crystal.

If you accepted every hit regardless of energy, your coincidence data would be dominated by scattered and background events, and your reconstructed images would be blurred and biased.

An energy window is a simple selection around the expected full‑energy peak, usually centered near 511 keV, that keeps mostly good events and rejects many scattered ones. In Geant4, you implement this window in your analysis or hit processing code by comparing the deposited energy with configurable limits.

Energy window selection is a simple but crucial filter that strongly affects PET image quality, scatter fraction, and sensitivity. You should always be able to reproduce and document the energy window used in any PET simulation study.

Choosing an Energy Window

In a real scanner, the usable energy spectrum is not a perfect sharp line at 511 keV. Due to finite energy resolution, the full‑energy peak has an approximately Gaussian shape, and some scattered photons overlap with it. A typical PET energy window might be, for example, from 350 keV to 650 keV, but the optimal values depend on the detector material, geometry, and research goals.

In your simulation, you represent the window with two parameters:

You can store these values in a configuration object, in G4UIcommand controlled parameters, or as constants that you later expose via macros. Use Geant4 units directly, for example 350.keV or 650.keV, so your code clearly communicates the physical meaning of the numbers.

A simple way to express the window is

$$
E_{\text{min}} \le E_{\text{det}} \le E_{\text{max}},
$$

where $E_{\text{det}}$ is the measured or simulated deposited energy in a detector element.

Define the energy window once in a central place (for example, your analysis or detector configuration class) and use that definition consistently throughout your code. Avoid scattering "magic numbers" like 350.keV or 650.keV in multiple files.

Implementing the Window in Geant4 Code

In a PET simulation, you usually record the energy in each detector crystal as part of a hit or an event‑level structure. The energy window is then applied at the analysis or selection stage. The exact location depends on how you have organized the example, but the logic is always similar.

A typical workflow is:

  1. Your sensitive detector class creates a hit each time a gamma deposits energy in a crystal.
  2. Each hit stores at least the detector ID, the total energy deposited in that crystal, and the time.
  3. At the end of the event, your EventAction or a dedicated PET event builder collects the hits in each detector and determines which crystals had significant energy.
  4. You apply the energy window to each detector energy to decide whether that detector should contribute to coincidences.

The core of the selection is a simple condition, for example inside your event or coincidence logic:

cpp
G4double eDep = hit->GetEdep();  // energy deposited in this crystal, in MeV
if (eDep >= fEmin && eDep <= fEmax) {
  // This detector hit passes the energy window
  // It can be used for coincidence finding and analysis
}

Here, fEmin and fEmax are member variables you set during initialization, perhaps from macro commands such as:

tcl
/pet/energyWindow/min 350 keV
/pet/energyWindow/max 650 keV

In this way, you can change the energy window without recompiling, which is important when you study how different windows affect scatter fraction, sensitivity, and image quality.

Apply the energy window after you have accumulated all energy in a detector element for an event or for a candidate hit. Do not apply the window to each individual Geant4 step, otherwise partial deposits from a single photon may be incorrectly rejected.

Event and Coincidence Selection with an Energy Window

The PET example chapter focuses on coincidences, that is, pairs of detectors that fire within a short time window. The energy window is naturally combined with the coincidence logic.

A typical sequence is:

  1. For each event, identify all detector crystals that received non‑zero energy.
  2. Sum the energy per crystal if there are multiple hits in the same detector during the event.
  3. For each crystal energy, test the energy window condition.
  4. Keep only those hits (or reconstructed detector events) that pass the window.
  5. Among the surviving hits, search for pairs of detectors that also satisfy your time coincidence condition.

In code, you might first build a simple structure like this for each event:

cpp
struct DetectorHitSummary {
  G4int    detectorID;
  G4double energy; // summed energy in this crystal
  G4double time;   // e.g. time of the first or maximum energy deposit
};

Then you filter:

cpp
std::vector<DetectorHitSummary> acceptedHits;
for (const auto& h : allDetectorHits) {
  if (h.energy >= fEmin && h.energy <= fEmax) {
    acceptedHits.push_back(h);
  }
}

Only acceptedHits are passed to your coincidence finder. This keeps the code modular: one part handles hit building, one part applies the energy window, and another part finds coincidences.

When you design your coincidence selection, apply the energy window to each detector separately, not to the sum of energies in both detectors. Each annihilation photon should independently satisfy the energy criterion.

Using the Energy Window in Analysis

Once you have implemented energy window selection, you can study its impact through analysis. Within your Geant4 analysis code, the window will typically be reflected in:

You might, for example, fill two energy histograms:

In pseudocode:

cpp
auto analysis = G4AnalysisManager::Instance();
analysis->FillH1(energyHistAllID, eDep);
if (eDep >= fEmin && eDep <= fEmax) {
  analysis->FillH1(energyHistWindowID, eDep);
}

The difference between these histograms illustrates how the window suppresses the low‑energy tail that is typically dominated by scattered photons and partial energy deposits.

In a full PET workflow, you will later export the selected coincidence events to ROOT for further processing. Make sure that the output format includes enough information to reconstruct which energy window was used, either by:

This lets you reliably compare simulations that used different energy windows.

Never analyze PET coincidence data without documenting the exact energy window used. Results from different windows are not directly comparable and can lead to incorrect physical conclusions if mixed.

Exploring and Tuning the Energy Window

One of the advantages of a Geant4 PET simulation is that you can systematically investigate the effect of the energy window on performance and image quality without hardware limitations.

Typical studies include:

To support such studies, keep your window configurable via macros. For example, you can define UI commands that apply during initialization:

tcl
/pet/energyWindow/useDefault true
/pet/energyWindow/min 400 keV
/pet/energyWindow/max 650 keV

Then run multiple jobs with different settings, each time recording both the total number of accepted coincidences and key image quality metrics that you compute later in ROOT.

In the context of this PET example, the main goal is clarity rather than optimization. However, even at this level, you already see how a simple energy condition, implemented with a few lines of code, becomes a central part of a realistic PET simulation chain.

Views: 9

Comments

Please login to add a comment.

Don't have an account? Register now!