23.9. Simulating Detector Resolution
Table of Contents
Why Detector Resolution Matters
In the idealized simulations you have met so far, the energy deposited in the scintillator is treated as if the detector could measure it perfectly. Real detectors never behave like this. Even if the same gamma ray deposits the same energy many times, the measured energy values form a distribution around the true energy, not a single number.
This spread is called detector energy resolution. It determines how well you can distinguish nearby gamma lines, identify isotopes, and separate signal from background. If you want your Geant4 results to be comparable to real measurements, you must include this finite resolution in your analysis.
Detector resolution is not simulated automatically by Geant4 for you. Geant4 provides the true deposited energy. You then apply detector effects in your user code or in a separate analysis step.
Ideal vs measured energy
For a monoenergetic gamma ray of energy $E_0$, an ideal detector would always return exactly $E_0$. A real detector instead produces a peak that is approximately Gaussian in shape, centered at $E_0$ with a finite width. The peak width is usually quantified by the full width at half maximum (FWHM).
In your gamma-ray detector example, you have a scintillation crystal and you record the true deposited energy $E_{\text{dep}}$ in each event. To simulate resolution, you transform this $E_{\text{dep}}$ into a smeared, measured energy $E_{\text{meas}}$ before filling histograms or writing to output.
Gaussian Smearing of Energy
For many scintillation and semiconductor detectors, the energy response near a photopeak can be well approximated by a Gaussian. In that approximation, detector resolution is represented by a standard deviation $\sigma(E)$ that depends on the energy.
Key model: The measured energy is modeled as a random variable
$$
E_{\text{meas}} = E_{\text{dep}} + \delta E,
$$
where $\delta E$ is drawn from a Gaussian distribution with mean 0 and standard deviation $\sigma(E_{\text{dep}})$.
In C++ terms, you will compute $\sigma$ from your resolution model, then use a Geant4 random Gaussian to obtain $\delta E$.
Typical energy resolution specifications are given as FWHM at a certain energy, for example "7% FWHM at 662 keV". From such a number you can derive $\sigma$ and construct a simple model.
FWHM and sigma
For a Gaussian peak, the relation between the standard deviation $\sigma$ and the full width at half maximum (FWHM) is
$$
\text{FWHM} = 2 \sqrt{2 \ln 2} \, \sigma \approx 2.355 \, \sigma.
$$
Conversion rule:
$$
\sigma = \frac{\text{FWHM}}{2.355}, \quad \text{FWHM} = 2.355 \, \sigma.
$$
Resolution is often expressed as a relative value $R$:
$$
R = \frac{\text{FWHM}}{E_0}.
$$
So for a detector with 7 percent resolution at 662 keV,
$$
R = 0.07, \quad
\text{FWHM}(662 \, \text{keV}) = 0.07 \times 662 \, \text{keV} \approx 46.3 \, \text{keV},
$$
and
$$
\sigma(662 \, \text{keV}) = \frac{46.3 \, \text{keV}}{2.355} \approx 19.7 \, \text{keV}.
$$
Energy-dependent Resolution Models
Real detectors do not have constant absolute resolution. The width of the peak typically changes with energy. For scintillators and semiconductor detectors, a common assumption is that the resolution scales roughly with the square root of the energy.
Square-root model
In the simplest model, the standard deviation scales as
$$
\sigma(E) = a \sqrt{E},
$$
where $a$ is a constant. This reflects the fact that the number of detected scintillation photons or charge carriers is proportional to $E$, while the statistical fluctuations are proportional to $\sqrt{N}$, and therefore $\sqrt{E}$.
You can determine $a$ if you know the resolution at one reference energy $E_{\text{ref}}$:
- Compute FWHM at $E_{\text{ref}}$ from the quoted percentage.
- Compute $\sigma_{\text{ref}} = \text{FWHM}(E_{\text{ref}}) / 2.355$.
- Set $a = \sigma_{\text{ref}} / \sqrt{E_{\text{ref}}}$.
Then for any deposited energy $E_{\text{dep}}$ in your simulation, compute
$$
\sigma(E_{\text{dep}}) = a \sqrt{E_{\text{dep}}}.
$$
Square-root resolution model:
Given a reference point $(E_{\text{ref}}, R_{\text{ref}})$,
$$
\text{FWHM}_{\text{ref}} = R_{\text{ref}} E_{\text{ref}},
$$
$$
\sigma_{\text{ref}} = \frac{\text{FWHM}_{\text{ref}}}{2.355},
$$
$$
a = \frac{\sigma_{\text{ref}}}{\sqrt{E_{\text{ref}}}},
$$
and
$$
\sigma(E) = a \sqrt{E}.
$$
This model is a good first approximation for your gamma-ray detector example and is simple to implement.
More flexible models
If you want more realism later, you can use a quadratic form,
$$
\sigma^2(E) = a^2 E + b^2 E^2 + c^2,
$$
where the terms represent statistical fluctuations, non-statistical effects, and electronic noise. For an absolute beginner course, it is usually enough to start with the $\sigma \propto \sqrt{E}$ model and understand its impact on the spectrum.
Implementing Smearing in Geant4
Geant4 does not automatically smear energies. The usual place to apply detector resolution is in your analysis code, for example in the class where you fill histograms or ntuples. In the gamma-ray detector example, this is typically in the EndOfEventAction, in a hit class, or in your analysis manager logic when you handle event-level energy.
Getting a Gaussian random number
Geant4 provides a Gaussian random generator through CLHEP. You can access it as
#include "Randomize.hh"
// ...
G4double deltaE = G4RandGauss::shoot(mean, sigma);To generate a Gaussian variable with mean zero and standard deviation sigma, call
G4double deltaE = G4RandGauss::shoot(0.0, sigma);You then add this to the true deposited energy to get the smeared energy.
Typical smearing workflow
The basic workflow inside your event processing or hit processing code is:
- Accumulate the total deposited energy in the scintillator for the event:
$E_{\text{dep}}$. - Compute the resolution at that energy, that is $\sigma(E_{\text{dep}})$.
- Generate a random Gaussian offset $\delta E$.
- Compute $E_{\text{meas}} = E_{\text{dep}} + \delta E$.
- Optionally enforce that $E_{\text{meas}}$ is non-negative.
- Fill your histogram or ntuple with $E_{\text{meas}}$ instead of $E_{\text{dep}}$.
This approach treats the detector resolution as a final measurement effect and leaves the underlying physics simulation unchanged.
Practical C++ Example
To make the procedure concrete, consider a NaI-like detector with 7 percent FWHM at 662 keV. The example below shows how you might implement a simple smearing function and use it when filling an energy histogram.
First, define a small helper function, for example in your analysis or utility code.
#include "Randomize.hh"
#include "G4SystemOfUnits.hh"
class ResolutionModel {
public:
ResolutionModel()
{
// Reference: 7% FWHM at 662 keV
G4double Eref = 662.0 * keV;
G4double Rref = 0.07; // 7%
G4double fwhm_ref = Rref * Eref;
G4double sigma_ref = fwhm_ref / 2.355;
// Square-root model: sigma(E) = a * sqrt(E)
fA = sigma_ref / std::sqrt(Eref);
}
G4double SmearEnergy(G4double Edep) const
{
if (Edep <= 0.) return 0.;
// Compute sigma(E)
G4double sigma = fA * std::sqrt(Edep);
// Gaussian fluctuation with mean 0, width sigma
G4double deltaE = G4RandGauss::shoot(0.0, sigma);
G4double Emeas = Edep + deltaE;
if (Emeas < 0.) Emeas = 0.; // no negative energies
return Emeas;
}
private:
G4double fA; // resolution parameter
};In your event analysis, after you have computed the total deposited energy in the crystal for the event, you would do something like:
extern ResolutionModel gResolutionModel;
// Inside EndOfEventAction or a similar place:
void MyEventAction::EndOfEventAction(const G4Event* /*event*/)
{
// Suppose fEdep is the total energy deposition accumulated this event
if (fEdep > 0.)
{
G4double smearedE = gResolutionModel.SmearEnergy(fEdep);
// Fill histogram with smeared energy
auto analysisManager = G4AnalysisManager::Instance();
analysisManager->FillH1(0, smearedE);
}
// Reset event accumulator
fEdep = 0.;
}Note that you always use the Geant4 unit system. If your histogram is defined in MeV, convert energies appropriately when you define the histogram or when you fill it.
Interpreting the Smeared Spectrum
Once you apply detector resolution, the gamma-ray spectrum in your example will look much more like a real measurement.
For a monoenergetic gamma source, you will see the following differences compared to the ideal case:
- The full energy peak becomes broader and has a finite width.
- The peak height drops, because the total counts are now spread over several bins instead of a few.
- Low-energy features such as Compton continua are smoothed, and sharp edges become less pronounced.
In many applications, you will tune your resolution model parameters so that the simulated peak widths match those measured with a physical detector. This tuning can be done by comparing the simulated and measured spectra for one or more calibration sources and adjusting the coefficients in your $\sigma(E)$ formula.
Practical rule: Always compare the smeared simulated spectrum, not the ideal one, when matching Geant4 results to real detector data.
Where to Apply Smearing
For this gamma-ray detector example, it is usually sufficient to smear the event-level energy sum, because a scintillation detector integrates the light from an event and delivers a single pulse with a measured amplitude.
The typical locations in your code where you might implement smearing are:
- In the event action, after you have summed the energy deposited in the scintillator volume.
- In a hit class that represents a readout channel, if you want to simulate resolution separately for each element in an array.
- In a post-processing step outside Geant4, using the stored true energies and applying smearing in a separate analysis program or ROOT macro.
Applying smearing during the Geant4 run, as described in this chapter, has the advantage that the output files already contain values that are close to what an experiment would measure. It also allows you to propagate the smeared energies directly into later analysis steps in your simulation chain.
Summary
To simulate detector resolution in your gamma-ray detector example, you keep the Geant4 physics unchanged and modify only the way you record energy. You model the finite resolution with a Gaussian response function, relate the FWHM and $\sigma$, choose a simple energy dependence such as $\sigma(E) \propto \sqrt{E}$, and use Geant4’s Gaussian random generator to convert the true deposited energy into a smeared, measured value. This lets your simulated spectra resemble realistic detector data and prepares you to compare simulations with real experiments.
Views: 9
KAHIBARO