Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1.9 KiB
Design: parent_step_no Column on Steps Ntuple
Problem
The Steps ntuple records parent_id (which track created a secondary) but not at which step of the parent the secondary was born. Finding this after the fact requires a position join: match the secondary's first pre-step point against the parent's post-step points across ntuple rows.
Proposed solution
Add a parent_step_no integer column to the Steps ntuple. Value is -1 for the primary particle and the parent's step number for every step of any secondary.
Mechanism
Use G4VUserTrackInformation to carry the parent step number forward from creation time to the secondary's tracking phase:
-
Tag at creation — in
UserSteppingAction, iteratestep->GetSecondaryInCurrentStep()and attach aTrackUserInfo(track->GetCurrentStepNumber())object to each secondary viaconst_cast<G4Track*>(sec)->SetUserInformation(...). Geant4 takes ownership and deletes it with the track. -
Read at tracking — when filling a Steps ntuple row, retrieve
dynamic_cast<TrackUserInfo*>(track->GetUserInformation())and writeinfo->parentStepNo, or-1if null (primary).
Files
include/TrackUserInfo.hh— new: minimalG4VUserTrackInformationsubclass storingint parentStepNosrc/RunAction.cc— add column 27parent_step_no(Integer) to ntuple 1 (Steps)src/SteppingAction.cc— tag new secondaries; fill column 27
Note on const_cast
GetSecondaryInCurrentStep() returns const G4Track*. The const is a conservative API choice, not a physics invariant. G4VUserTrackInformation is an explicit user-side side-channel; using const_cast here is standard Geant4 practice.
Superseded by
This approach was superseded by the Spawning ntuple (branch spawning-ntuple), which avoids the per-row overhead and const_cast by pre-assigning track IDs in G4SteppingManager and writing a dedicated secondary-birth table.