10.3. Particle Energy
Table of Contents
Monoenergetic particles
In a first Geant4 simulation it is common to use monoenergetic primary particles. A monoenergetic source means that every primary particle starts with exactly the same kinetic energy. This is very useful when you want to understand the basic response of your geometry or detector without adding any complexity from an energy spectrum.
The primary particle energy in Geant4 is always interpreted as kinetic energy. The rest mass of the particle is already known from the physics list and particle definitions, so you never have to add it yourself. When you say “1 MeV electron” in Geant4, you set the kinetic energy to $1\ \text{MeV}$ and Geant4 internally combines this with the electron mass to get the total energy.
If you use the Geant4 unit system correctly, a monoenergetic source is simply a constant numerical value multiplied by the appropriate energy unit, such as $500 \ \text{keV}$ or $2 \ \text{MeV}$. The same value will be used for all primaries until you change it in code or in a macro.
For absolute beginners, monoenergetic beams are particularly important for:
- Testing geometry and physics. With a fixed energy, differences in the simulation outcome can be traced to geometry or physics changes more easily.
- Building reference curves. For example, scanning a detector response by running several simulations, each with a different single energy, and later combining the results.
- Learning how Geant4 handles units and energies. Since the energy is fixed, you can more easily see the effect of unit mistakes.
Important rule: The energy that you give to a primary particle in Geant4 is always the kinetic energy. Do not add the rest mass. Also, always multiply numeric values by a Geant4 energy unit (for example keV, MeV, GeV) and never write “bare” numbers like 1.0 without a unit.
Setting particle energy
When you use the basic G4ParticleGun in your PrimaryGeneratorAction class, you set the energy of the primary particle with the SetParticleEnergy method. This method expects a value with a Geant4 energy unit. A typical pattern in your constructor or in GeneratePrimaries looks like this:
// In your PrimaryGeneratorAction constructor
G4int nParticle = 1;
fParticleGun = new G4ParticleGun(nParticle);
// Example: 1 MeV gamma
auto particleTable = G4ParticleTable::GetParticleTable();
auto gamma = particleTable->FindParticle("gamma");
fParticleGun->SetParticleDefinition(gamma);
fParticleGun->SetParticleEnergy(1.0 * MeV);
Here, 1.0 MeV is a monoenergetic setting. Every primary gamma produced by this G4ParticleGun will have 1 MeV kinetic energy. If you change that line to 511 keV, then all gammas will have 511 keV kinetic energy.
You can change the particle energy either in C++ or through macro commands. If you use macro control, you usually create a UI command in your PrimaryGeneratorAction or use the built in /gun commands. For the basic particle gun, Geant4 already provides a convenient command:
# In a macro file
/run/initialize
/gun/particle e-
/gun/energy 1 MeV
/run/beamOn 1000
The /gun/energy command sets the kinetic energy of the particles emitted by G4ParticleGun. You can change it between runs without recompiling. For example, to scan energies you might write:
/run/initialize
/gun/particle gamma
/gun/energy 200 keV
/run/beamOn 10000
/gun/energy 500 keV
/run/beamOn 10000
/gun/energy 1 MeV
/run/beamOn 10000This will produce three separate batches of events, each with a different monoenergetic gamma beam.
When you set the energy in C++, it is common to keep the value in a member variable so that you can later connect it to a UI command. A simple pattern is:
class PrimaryGeneratorAction : public G4VUserPrimaryGeneratorAction {
public:
PrimaryGeneratorAction();
void SetBeamEnergy(G4double energy) { fBeamEnergy = energy; }
virtual void GeneratePrimaries(G4Event* event) override;
private:
G4ParticleGun* fParticleGun = nullptr;
G4double fBeamEnergy = 1.0 * MeV;
};
PrimaryGeneratorAction::PrimaryGeneratorAction() {
fParticleGun = new G4ParticleGun(1);
auto particleTable = G4ParticleTable::GetParticleTable();
auto proton = particleTable->FindParticle("proton");
fParticleGun->SetParticleDefinition(proton);
}
void PrimaryGeneratorAction::GeneratePrimaries(G4Event* event) {
fParticleGun->SetParticleEnergy(fBeamEnergy);
fParticleGun->GeneratePrimaryVertex(event);
}
Then a custom UI command or a macro can change fBeamEnergy at runtime. This approach is helpful when you want to run parameter scans without recompiling.
A frequent source of mistakes is forgetting the unit or choosing the wrong one. The following table shows some correct examples and typical wrong ones:
| Intended energy | Correct in C++ | Wrong example | Result of wrong example |
|---|---|---|---|
| 1 MeV | 1.0 * MeV | 1.0 | 1 eV, because Geant4 default is 1 internal unit = 1 eV |
| 511 keV | 511. * keV | 511 * MeV | 511 MeV, much higher than intended |
| 10 GeV | 10. * GeV | 10. * MeV | 10 MeV, much lower than intended |
Always multiply energy values by the correct Geant4 unit, for example keV, MeV, GeV. If you omit the unit, Geant4 interprets the number in its internal base units, which for energy correspond to 1 eV. This can silently produce completely wrong energies.
When debugging your primary energy, you can print the value together with a unit using G4BestUnit from G4UnitsTable.hh:
#include "G4UnitsTable.hh"
// ...
G4cout << "Primary energy: "
<< G4BestUnit(fBeamEnergy, "Energy") << G4endl;
This prints a human readable energy such as 1 MeV, which lets you verify that the value you set in C++ or via macros is really what you intended.
Views: 7
KAHIBARO