SteppingAction
Table of Contents
Accessing simulation steps
A SteppingAction is your way to look at every step that a particle takes in your simulation. While EventAction works once per event, and RunAction once per run, SteppingAction is called for each individual step of each track. This gives you very fine control over what happens inside your detector.
To use SteppingAction you create a class that derives from G4UserSteppingAction and implement the method
void UserSteppingAction(const G4Step* step) override;
Geant4 calls this method automatically for every step in every event where tracking is active. The pointer step provides access to detailed information about the step, the track, and the physical process that limited the step.
Inside UserSteppingAction you normally start by extracting the G4Track and the step points. The track tells you which particle is stepping and its global information. The step points give you the conditions at the beginning and at the end of the step.
void SteppingAction::UserSteppingAction(const G4Step* step)
{
// Access the track
G4Track* track = step->GetTrack();
// Access pre and post step points
G4StepPoint* preStep = step->GetPreStepPoint();
G4StepPoint* postStep = step->GetPostStepPoint();
}The pre step point corresponds to the point where the step starts, and the post step point corresponds to the point where the step ends. From these you can obtain positions, times, volumes, and processes.
For example, you can obtain the position and time of the pre step point in global coordinates:
G4ThreeVector pos = preStep->GetPosition();
G4double time = preStep->GetGlobalTime();You can also access the logical or physical volume that contains the step point. This is commonly used to restrict your analysis to particular detector parts:
G4VPhysicalVolume* preVolume =
preStep->GetPhysicalVolume();
if (!preVolume) return; // Outside the world
G4String volumeName =
preVolume->GetLogicalVolume()->GetName();The post step point provides information about what happened at the end of the step. You can access the process that defined the step, for example to check whether a particle was absorbed, scattered, or interacted in a particular way:
const G4VProcess* process =
postStep->GetProcessDefinedStep();
if (process)
{
G4String procName = process->GetProcessName();
}
The SteppingAction is also a good place to apply custom tracking logic, such as killing tracks that leave a region, or limiting tracking for low energy particles. You can change the status of the track inside UserSteppingAction:
if (track->GetKineticEnergy() < 10.*keV)
{
track->SetTrackStatus(fStopAndKill);
}
Since UserSteppingAction is called very frequently, any code inside it must be efficient. Intensive work such as writing to disk or heavy logging should be minimized or delegated to higher level user actions.
To make your SteppingAction active, you register it in your ActionInitialization class, usually in the Build() method:
void ActionInitialization::Build() const
{
SetUserAction(new PrimaryGeneratorAction);
SetUserAction(new RunAction);
SetUserAction(new EventAction);
SetUserAction(new SteppingAction);
}
After registration, every step in your simulation will pass through your UserSteppingAction method, and you can selectively extract the information you need for analysis, debugging, or control of the simulation flow.
In a SteppingAction you see every step for every track. This is powerful but can be expensive. Always restrict your operations to relevant volumes and conditions to avoid a severe slowdown of your simulation.
Energy deposition
One of the most common tasks in a SteppingAction is to access the energy deposited in the detector during each step. The G4Step object directly provides the total energy deposit in the current step through the method GetTotalEnergyDeposit().
G4double edep = step->GetTotalEnergyDeposit();
This value is given in internal Geant4 energy units (usually MeV when you work with MeV, GeV, and related units). You can add units explicitly for clarity:
G4double edepMeV = edep / MeV;
Energy deposition is often used to build quantities such as total energy per event, energy per detector element, or to fill histograms. In practice, you rarely use the raw edep in SteppingAction alone; instead you pass it to an accumulator or an analysis manager.
A typical pattern combines volume selection and energy deposition. For example, to accumulate the total energy deposited in a specific volume named "Detector" you might write:
void SteppingAction::UserSteppingAction(const G4Step* step)
{
G4double edep = step->GetTotalEnergyDeposit();
if (edep <= 0.) return;
G4StepPoint* preStep = step->GetPreStepPoint();
G4VPhysicalVolume* volume =
preStep->GetPhysicalVolume();
if (!volume) return;
if (volume->GetLogicalVolume()->GetName() == "Detector")
{
// Forward edep to your event action or analysis
fEventAction->AddEdep(edep);
}
}
Here fEventAction is a pointer that you provide, typically by passing it to the SteppingAction constructor. The EventAction then keeps an event-level sum, which you can use later to fill histograms or store in ntuples.
If your detector consists of many repeated elements, such as an array of crystals, you usually want to record energy per element. You can obtain an identifier from the copy number of the volume:
G4int copyID =
volume->GetCopyNo();You then use this ID as an index in your own array or map of energy sums.
Energy deposition is not the same as the total energy lost by the particle in the step. In some processes, such as bremsstrahlung or pair production, part of the lost energy can go into secondary particles that leave the step without being deposited locally as energy in the medium. Geant4 calculates GetTotalEnergyDeposit() as the energy actually transferred to the material in the step, which is the quantity that corresponds to a local dose.
If you need to study the spatial distribution of energy deposition, you can combine the deposited energy with the step position. A simple choice is to associate the energy with the pre step or post step position. More sophisticated approaches use the step length to distribute the energy along the step path, but that belongs to more advanced analysis.
For time dependent detectors, you can combine energy deposition with the global time associated with the step point. For example:
G4double time = preStep->GetGlobalTime();You can then build time spectra of energy deposition or apply timing cuts.
Finally, you can forward the step level energy directly to the Geant4 analysis system through G4AnalysisManager. This is useful when you want to build histograms of deposited energy per step or per event. For example, if you have already accumulated the energy in your EventAction, you might fill a histogram at the end of the event. The SteppingAction remains responsible only for providing the per step edep to the event level accumulator.
Use GetTotalEnergyDeposit() when you want local deposited energy, for example for dose or detector signals. Do not confuse it with the particle kinetic energy or total energy loss, which can be larger if part of the energy leaves the step as secondary particles.
Views: 11
KAHIBARO