10.5. Particle Direction
Table of Contents
Fixed direction
In Geant4 you control the direction of a primary particle with a 3D unit vector. For the particle gun this is done with the method
SetParticleMomentumDirection(const G4ThreeVector&). The vector defines the direction of the particle momentum in the global coordinate system and must be normalized to length 1.
A direction vector is written as G4ThreeVector(x, y, z), where x, y, and z are the components along the global axes. For example, to shoot particles along the positive $z$ axis you can use:
particleGun->SetParticleMomentumDirection(G4ThreeVector(0., 0., 1.));Similarly, you can point the beam along the negative $x$ axis with:
particleGun->SetParticleMomentumDirection(G4ThreeVector(-1., 0., 0.));or at an arbitrary angle, for instance 45 degrees between the $z$ and $x$ axes:
G4ThreeVector dir(1., 0., 1.);
dir = dir.unit(); // normalize to a unit vector
particleGun->SetParticleMomentumDirection(dir);You can also control the direction from a macro file. The equivalent UI command for the particle gun is:
/gun/direction 0. 0. 1.The three numbers are again the components of the direction vector. You do not need to normalize them in the macro. Geant4 will normalize the direction internally before using it.
For many simulations a fixed direction is appropriate. Examples include a narrow beam experiment, a test-beam setup, or a collimated laboratory source where all particles are nominally aligned with the detector axis. In those cases you typically choose a constant direction for all primaries in GeneratePrimaries() or in the corresponding macro commands.
If you want a beam that is nearly but not perfectly parallel, for example to model a finite beam divergence, you can generate directions with a small random spread around a central axis. A common way is to sample a small angle $\theta$ from a Gaussian distribution around zero and a random azimuthal angle $\phi$ around the axis, then convert these to Cartesian components. The details of the random sampling itself belong to the more general topic of random numbers and are not covered here, but it is important to remember that the final result must again be a unit vector passed to SetParticleMomentumDirection().
Always pass a unit vector as the particle direction in C++ code. Use dir.unit() to normalize arbitrary vectors before calling SetParticleMomentumDirection().
Isotropic emission
An isotropic source emits particles equally in all directions. This is very common when you want to model a point-like radioactive source in free space or an uncollimated emission from a volume.
A naive approach might be to choose the polar angle $\theta$ and the azimuthal angle $\phi$ uniformly in their ranges,
$$
\theta \in [0, \pi], \quad \phi \in [0, 2\pi),
$$
and then construct the direction vector as
$$
\vec{u} = (\sin\theta \cos\phi,\ \sin\theta \sin\phi,\ \cos\theta).
$$
However, if you choose $\theta$ uniformly, you do not obtain a truly isotropic distribution on the sphere. The surface element on a sphere is proportional to $\sin\theta$, so equal steps in $\theta$ correspond to different surface areas near the poles and near the equator. This leads to a higher density of directions near the poles.
To obtain an isotropic distribution, you must choose $\cos\theta$ uniformly in the interval $[-1, 1]$ and $\phi$ uniformly in $[0, 2\pi)$. A simple way to implement this in C++ is:
G4double cosTheta = 2.*G4UniformRand() - 1.; // uniform in [-1, 1]
G4double sinTheta = std::sqrt(1. - cosTheta*cosTheta);
G4double phi = 2.*CLHEP::pi*G4UniformRand();
G4double ux = sinTheta*std::cos(phi);
G4double uy = sinTheta*std::sin(phi);
G4double uz = cosTheta;
G4ThreeVector dir(ux, uy, uz);
particleGun->SetParticleMomentumDirection(dir);
Here G4UniformRand() returns a random number in the range $[0,1)$, and the resulting vector is automatically a unit vector due to the trigonometric construction.
For true isotropic emission, sample $\cos\theta$ uniformly in $[-1,1]$ and $\phi$ uniformly in $[0,2\pi)$, then convert to Cartesian components. Do not sample $\theta$ uniformly.
If you prefer to use macro commands rather than C++ code, an easy way to configure isotropic emission is to use the General Particle Source, which provides built-in options for isotropic angular distributions. With GPS you can write in a macro:
/gps/ang/type isoand GPS will generate isotropic emission automatically. The detailed use of GPS is discussed separately, but here it is important to recognize that isotropic options exist and are often simpler than writing the angular sampling yourself.
In many realistic setups you might need emission that is isotropic over a hemisphere rather than the full sphere. For example, a source on a surface should emit only into the half-space above that surface. This can be achieved by restricting $\cos\theta$ to $[0,1]$ instead of $[-1,1]$, which selects only one hemisphere. The procedure is otherwise identical.
An isotropic source changes the character of a simulation compared to a fixed direction beam. It spreads particles over a large solid angle, reduces fluence in any given direction, and often requires more events to achieve good statistics in a small detector. Understanding the difference between fixed and isotropic directions helps you match your source model to real experimental conditions and to interpret your simulation results correctly.
Views: 9
KAHIBARO