KAHIBARO
Discord Login Register

17.1. Particle Position

Global coordinates

In Geant4 every point in space is first expressed in a single, common reference frame called the global coordinate system. This is the master frame that covers the entire simulation world. When you ask for a particle or interaction position in most tracking classes, the position is given in these global coordinates.

A global position is represented by a G4ThreeVector, usually obtained from objects like G4Track, G4StepPoint, or G4TouchableHistory. For example, in a stepping action you can write:

cpp
G4StepPoint* prePoint  = step->GetPreStepPoint();
G4StepPoint* postPoint = step->GetPostStepPoint();
G4ThreeVector globalPosPre  = prePoint->GetPosition();
G4ThreeVector globalPosPost = postPoint->GetPosition();

Here globalPosPre and globalPosPost are the particle positions at the beginning and end of the step, expressed in the global frame. Their components have units, for example millimeters, and you can access them as globalPosPre.x(), globalPosPre.y(), and globalPosPre.z().

The origin of the global system is fixed by your world volume definition. When you create the world in DetectorConstruction, its center is, by convention, the global origin. All placements of physical volumes are then specified relative to this origin through translations and rotations.

A key feature of global coordinates is that they are directly comparable anywhere in the geometry. If you record global positions in your analysis, you can later plot hit maps for the whole detector or reconstruct particle trajectories across multiple volumes without additional transformations. This is why most high level analysis quantities, such as depth dose in a phantom or hit positions in a detector array, are stored in global coordinates.

Global coordinates are also what you use when you want to apply simple geometric selections. For example, to restrict analysis to a certain region of space you might check that

cpp
if (std::abs(globalPosPre.z()) < 50.*cm) {
  // process this step
}

Because this cut is written in global coordinates, it does not depend on how individual detector components are placed or rotated.

In visualization, by default, the viewer displays geometry and tracks using the global system as well. When you rotate or zoom the view, you change only how this system is projected on the screen, not the underlying coordinates. This consistent use of a single master frame helps keep geometry building, tracking, and analysis aligned.

Important rule: Unless clearly documented otherwise, positions you get from Geant4 tracking classes are in the global coordinate system. You should only mix them with local coordinates after applying the appropriate transformations.

Local coordinates

While the global frame describes the whole world, each volume in Geant4 can also have its own local coordinate system. Local coordinates are defined relative to a specific volume, most often a logical volume or a particular physical placement. In the local frame of a volume, the volume is usually centered at the origin, and its axes follow its own orientation, before any placement transformation is applied.

This idea is crucial once you start rotating and translating detector components. Suppose you build a detector module as a box centered at $(0,0,0)$ in its own local system. Later you place many copies of this module at different positions and with different rotations in the global world. Inside each module, you often want to describe positions relative to the module itself, not to the entire world. Local coordinates allow you to do this.

Working with local coordinates usually involves the touchable history of a step or track, which keeps track of the complete hierarchy of placements that lead from the world to the current volume. From a step point you can obtain the touchable and ask it to transform a global position into the local frame of a given level in the hierarchy. A common pattern in a stepping action looks like this:

cpp
G4StepPoint* prePoint = step->GetPreStepPoint();
auto touchable = prePoint->GetTouchableHandle();
G4ThreeVector globalPos = prePoint->GetPosition();
G4ThreeVector localPos  = touchable->GetHistory()
                             ->GetTopTransform()
                             .TransformPoint(globalPos);

Here localPos is the same physical point as globalPos, but now expressed in the local frame of the current volume. If that volume is a rectangular crystal, for example, you might find that localPos.z() measures how deep into the crystal the interaction occurred, with z = -length/2 at one face and z = +length/2 at the opposite face.

Local coordinates are particularly useful when you want to express detector specific quantities, such as distance from a particular surface, hit position along a strip, or pixel indices. Since these quantities are naturally defined in the detector’s own frame, using local coordinates often simplifies the logic and makes your code independent of where the detector is placed in the world.

For example, in a sensitive detector you might compute the index of a pixel as

cpp
G4ThreeVector localPos = aStep->GetPreStepPoint()
                            ->GetTouchableHandle()
                            ->GetHistory()
                            ->GetTopTransform()
                            .TransformPoint(aStep->GetPreStepPoint()->GetPosition());
G4int ix = G4int((localPos.x() + halfSizeX) / pixelSizeX);
G4int iy = G4int((localPos.y() + halfSizeY) / pixelSizeY);

Here the mapping from position to pixel indices only depends on the geometry of the pixelated sensor, not on its placement. You can move or rotate the sensor in the global world, and this code stays valid.

It is important to keep track of which frame your data is in when saving it for analysis or using it in further calculations. Mixing global and local positions without applying the right transformations can lead to subtle and hard to find errors, for example misaligned hit maps or incorrect reconstruction of particle paths.

To move between frames, you can use the affine transformations stored in the touchables. Any point can be transformed from local to global or from global to local using the appropriate TransformPoint calls. No manual rotation or translation calculations are necessary, since Geant4 tracks all placement transformations for you.

Important rule: Local coordinates are defined relative to a specific volume and are valid only with respect to that volume’s placement and orientation. Always convert explicitly between global and local frames when needed, and never assume that a local position can be compared directly to a global one.

Views: 10

Comments

Please login to add a comment.

Don't have an account? Register now!