KAHIBARO
Discord Login Register

13.1. Tracks

`G4Track`

In Geant4, the central object that represents a moving particle inside the simulation is the G4Track class. Every time a particle is transported, Geant4 creates a G4Track instance that stores the full state of that particle at a given moment in its life. You do not create tracks yourself. The tracking system and physics processes create and update them automatically. Your user code can only read or sometimes modify information contained in a track.

The G4Track object exists only while the particle is being transported. When the track is finished, for example when the particle has stopped or left the world, the corresponding G4Track is destroyed. This means that you should never keep raw pointers or references to a G4Track object beyond the scope where Geant4 gives it to you, for example inside a stepping action or tracking action.

G4Track is passed to you mainly through user action classes. The most common places where you see it are in G4UserSteppingAction::UserSteppingAction(const G4Step), where you can get the current track through step->GetTrack(), and in G4UserTrackingAction, where PreUserTrackingAction(G4Track) and PostUserTrackingAction(G4Track*) give you direct access to the track at the beginning and at the end of its life.

Internally, a track connects three important concepts in Geant4: the particle type and its physical processes, the current kinematic state of that particle, and its history in the event, including its parentage and status. Understanding what lives in a G4Track is essential for analysis, debugging, and for implementing advanced logic such as filtering or killing tracks.

The main categories of information in a G4Track are:

CategoryExamples of data
IdentityTrack ID, parent ID, track status
KinematicsPosition, momentum, energy, time
Particle definitionPDG-like information through G4ParticleDefinition
Geometry and volumeCurrent volume, touchable, logical and physical volumes
Step and path informationCurrent step number, track length, global time
User informationOptional user-defined data attached to the track

Most of these are accessed with getter methods such as GetPosition(), GetMomentum(), GetKineticEnergy(), GetTrackStatus(), and others. They are read-only from the point of view of typical user code. If you need to store your own flags or analysis-related data with a track, Geant4 allows you to attach a G4VUserTrackInformation object to it. That mechanism is specific and is covered in more advanced parts of a course.

G4Track objects are controlled by Geant4. Never store them in containers or keep their pointers for later use. Use them only in the scope where they are provided.

Particle information

G4Track holds the instantaneous information about the particle as it is being transported. This describes where the particle is, how it moves, what type of particle it is, how much energy it has, and how long it has been traveling inside the event.

The current position of the particle is given in global coordinates by GetPosition(), which returns a G4ThreeVector. The units of position follow the Geant4 unit system, so the coordinates are usually in millimeters, centimeters, or meters, depending on what units you used when building the geometry. The direction of motion is given by the momentum direction, accessed with GetMomentumDirection(). This is a unit G4ThreeVector that indicates direction only, without magnitude.

The full momentum is available through GetMomentum(), and the kinetic energy through GetKineticEnergy(). These are consistent with the chosen energy units, for example keV, MeV, or GeV. At any point in the tracking, these values include the effect of interactions that have already happened. After a step where the particle loses energy, the kinetic energy stored in the track is reduced accordingly.

The particle type is not stored directly as a name or code inside G4Track. Instead, the track holds a pointer to a G4ParticleDefinition object. You access it with GetDefinition(). From that definition object you can obtain properties such as the particle name, its PDG encoding, charge, and mass. For example, you can check whether a track is a gamma or an electron by looking at track->GetDefinition()->GetParticleName() or by using pointers to predefined particles such as G4Gamma::Definition() or G4Electron::Definition() in comparisons.

Time information on the track is given by GetGlobalTime(). This is the time since the beginning of the event when the particle is at its current position. It includes any delays due to production of secondary particles or drift through the geometry. You can also access the local time of the track if you need to measure lifetime from the moment the particle was created, but the most common quantity is the global time, useful for time-of-flight and detector timing studies.

The track also keeps a record of how far the particle has traveled. The method GetTrackLength() returns the total path length since the creation of the particle inside the event. This includes any curved or zigzag path resulting from magnetic fields or multiple scattering, not just a straight line from the production point to the current position.

Geometry information is embedded through the track's associated volume and touchable. With GetVolume() you can retrieve the current G4VPhysicalVolume that the particle is in at this moment. From that you can access the logical volume, and from there the material. This is important when you want to know which detector element the particle is crossing, or which material properties affect the physics processes.

Finally, the track status is stored as an enumeration accessed via GetTrackStatus(). It tells you whether the track is still alive, has been stopped, or is about to be killed. This is useful in tracking and stepping actions where you want to take special actions when a particle leaves the world or reaches the end of its range.

When you read position, momentum, energy, and time from a G4Track, all values are in Geant4 internal units. Always multiply or divide by the appropriate unit constants when you store or print them in human-readable form.

Track ID

Each track inside an event is labeled with a unique integer identifier called the track ID. This ID is managed by Geant4 and can be retrieved from a G4Track using GetTrackID(). Inside a single event, no two active tracks share the same track ID. However, the numbering restarts in each new event, so you cannot compare track IDs across different events.

The track ID has several important uses. It allows you to distinguish between multiple tracks that exist at the same time, for example when a high energy particle creates many secondaries. You can use it to organize your analysis data, such as storing one row per track in an ntuple, or to associate hits and steps with the track that produced them.

There is a close connection between track IDs and parent IDs. When a primary particle is first generated at the start of the event, its track is usually given ID 1, 2, and so on, and its parent ID is set to 0 to signal that it has no parent. When this primary creates a secondary particle, the new particle receives its own new track ID and its parent ID is set equal to the track ID of the particle that created it. The methods GetTrackID() and GetParentID() together define a tree structure that represents the entire particle cascade in the event.

A simple pattern emerges:

Particle typeGetTrackID()GetParentID()
Primary particle1, 2, ...0
Direct secondaryNew IDID of primary
Secondary of secondaryNew IDID of secondary

By examining these two numbers, you can reconstruct which particles came from which ancestors. For example, if you find a gamma with track ID 10 and parent ID 3, you know that it was produced by the particle with track ID 3, which might be an electron or a positron, and you can trace further back if you store the information.

Track IDs are especially useful when you want to limit analysis to primary particles only. In a stepping or tracking action, you can quickly check if (track->GetParentID() == 0) to select only primaries. Similarly, you can tag all secondaries originating from a specific track ID, for example to follow a single neutron and all its descendants.

In most beginner applications you do not need to modify the way track IDs are assigned. You simply read them from the track when needed. Since Geant4 controls their life cycle, you should not attempt to store or reuse track IDs from one event in another. Always combine the track ID with the event ID when you create unique labels for analysis.

Views: 10

Comments

Please login to add a comment.

Don't have an account? Register now!