Production Threshold versus Tracking Cut

General considerations

We have to fulfill two contradictory requirements. It is the responsibility of each individual process to produce secondary particles according to its own capabilities. On the other hand, it is only the Geant4 kernel (i.e., tracking) which can ensure an overall coherence of the simulation.

The general principles in Geant4 are the following:

  1. Each process has its intrinsic limit(s) to produce secondary particles.

  2. All particles produced (and accepted) will be tracked up to zero range.

  3. Each particle has a suggested cut in range (which is converted to energy for all materials), and defined via a SetCut() method (see Range Cuts).

Points 1 and 2 imply that the cut associated with the particle is a (recommended) production threshold of secondary particles.

Set production threshold (SetCut methods)

As already mentioned, each kind of particle has a suggested production threshold. Some of the processes will not use this threshold (e.g., decay), while other processes will use it as a default value for their intrinsic limits (e.g., ionisation and bremsstrahlung).

See Range Cuts to see how to set the production threshold.

Apply cut

The DoIt methods of each process can produce secondary particles. Two cases can happen:

  • a process sets its intrinsic limit greater than or equal to the recommended production threshold. OK. Nothing has to be done (nothing can be done !).

  • a process sets its intrinsic limit smaller than the production threshold (for instance 0).

The list of secondaries is sent to the SteppingManager via a ParticleChange object.

Before being recopied to the temporary stack for later tracking, the particles below the production threshold will be kept or deleted according to the safe mechanism explained hereafter.

  • The ParticleDefinition (or ParticleWithCuts) has a Boolean data member: ApplyCut.

  • ApplyCut is OFF: do nothing. All the secondaries are stacked (and then tracked later on), regardless of their initial energy. The Geant4 kernel respects the best that the physics can do, but neglects the overall coherence and the efficiency. Energy conservation is respected as far as the processes know how to handle correctly the particles they produced! This is the main used during Geant4 tracking.

  • ApplyCut in ON: this feature is not normally used but is potentially available; the TrackingManager checks the range of each secondary against the production threshold and against the safety. The particle is stacked if range > min(cut,safety).

    • If not, check if the process has nevertheless set the flag “good for tracking” and then stack it (see Why produce secondaries below threshold in some processes? below for the explanation of the GoodForTracking flag).

    • If not, recuperate its kinetic energy in the localEnergyDeposit, and set tkin=0.

    • Then check in the ProcessManager if the vector of ProcessAtRest is not empty. If yes, stack the particle for performing the “Action At Rest” later. If not, and only in this case, abandon this secondary.

With this sophisticated mechanism we have the global cut that we wanted, but with energy conservation, and we respect boundary constraint (safety) and the wishes of the processes (via “good for tracking”). Note, that for electromagnetic processes for gamma incident a specific ApplyCut option is used which guarantees energy balance and is more efficient because secondary tracks are not produced at all.

Why produce secondaries below threshold in some processes?

A process may have good reasons to produce particles below the recommended threshold:

  • checking the range of the secondary versus geometrical quantities like safety may allow one to realize the possibility that the produced particle, even below threshold, will reach a sensitive part of the detector;

  • another example is the gamma conversion: the positron is always produced, even at zero energy, for further annihilation;

  • if a process is rare there is not practical reason make it complicate checking cut value.

These secondary particles are sent to the “Stepping Manager” with a flag GoodForTracking to pass the filter explained in the previous section (even when ApplyCut is ON).

Cuts in stopping range or in energy?

The cuts in stopping range allow one to say that the energy has been released at the correct space position, limiting the approximation within a given distance. On the contrary, cuts in energy imply accuracies of the energy depositions which depend on the material.


In summary, we do not have tracking cuts; we only have production thresholds in range. All particles produced and accepted are tracked up to zero range.

It must be clear that the overall coherency that we provide cannot go beyond the capability of processes to produce particles down to the recommended threshold.

In other words a process can produce the secondaries down to the recommended threshold, and by interrogating the geometry, or by realizing when mass-to-energy conversion can occur, recognize when particles below the threshold have to be produced.

Special tracking cuts

One may need to cut given particle types in given volumes for optimisation reasons. This decision is under user control, and can happen for particles during tracking as well.

The user must be able to apply these special cuts only for the desired particles and in the desired volumes, without introducing an overhead for all the rest.

The approach is as follows:

  • special user cuts are registered in the UserLimits class (or its descendant), which is associated with the logical volume class.

    The current default list is:

    • max allowed step size

    • max total track length

    • max total time of flight

    • min kinetic energy

    • min remaining range

    The user can instantiate a UserLimits object only for the desired logical volumes and do the association.

    The first item (max step size) is automatically taken into account by the G4 kernel while the others items must be managed by the user, as explained below.

    Example(see basic/B2/B2a or B2b): in the Tracker region, in order to force the step size not to exceed one half of the Tracker chamber thickness (chamberWidth), it is enough to put the following code in B2aDetectorConstruction::DefineVolumes():

    G4double maxStep = 0.5*chamberWidth;
    fStepLimit = new G4UserLimits(maxStep);

    and in PhysicsList, the process G4StepLimiter needs to be attached to each particle’s process manager where step limitation in the Tracker region is required:

    // Step limitation seen as a process
    G4StepLimiter* stepLimiter = new G4StepLimiter();

    If a provided Geant4 physics list is used, as FTFP_BERT in B2 example, then the G4StepLimiterPhysics, which will take care of attaching the G4StepLimiter process to all particles, can be added to the physics list in the main() function:

    G4VModularPhysicsList* physicsList = new FTFP_BERT;
    physicsList->RegisterPhysics(new G4StepLimiterPhysics());

    The G4UserLimits class is in source/global/management.

  • Concerning the others cuts, the user must define dedicated process(es). He registers this process (or its descendant) only for the desired particles in their process manager. He can apply his cuts in the DoIt of this process, since, via G4Track, he can access the logical volume and UserLimits.

    An example of such process (called UserSpecialCuts) is provided in the repository, but not inserted in any process manager of any particle.

    Example: neutrons. One may need to abandon the tracking of neutrons after a given time of flight (or a charged particle in a magnetic field after a given total track length … etc …).

    Example(see basic/B2/B2a or B2b): in the Tracker region, in order to force the total time of flight of the neutrons not to exceed 10 milliseconds, put the following code in B2aDetectorConstruction::DefineVolumes():

    G4double maxTime = 10*ms;
    fStepLimit = new G4UserLimits(DBL_MAX,DBL_MAX,maxTime);

    and put the following code in a physics list:

    G4ProcessManager* pmanager = G4Neutron::Neutron->GetProcessManager();
    pmanager->AddProcess(new G4UserSpecialCuts(),-1,-1,1);

    If a provided Geant4 physics list is used, then a SpecialCutsBuilder class can be defined in a similar way as G4StepLimiterPhysics and added to the physics list in the main() function:

    G4VModularPhysicsList* physicsList = new FTFP_BERT;
    physicsList->RegisterPhysics(new SpecialCutsBuilder());

    (The default G4UserSpecialCuts class is in source/processes/transportation.)