Files
minicalosim/docs/plan_parent_step_no.md
T
2026-06-11 10:22:43 +02:00

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:

  1. Tag at creation — in UserSteppingAction, iterate step->GetSecondaryInCurrentStep() and attach a TrackUserInfo(track->GetCurrentStepNumber()) object to each secondary via const_cast<G4Track*>(sec)->SetUserInformation(...). Geant4 takes ownership and deletes it with the track.

  2. Read at tracking — when filling a Steps ntuple row, retrieve dynamic_cast<TrackUserInfo*>(track->GetUserInformation()) and write info->parentStepNo, or -1 if null (primary).

Files

  • include/TrackUserInfo.hh — new: minimal G4VUserTrackInformation subclass storing int parentStepNo
  • src/RunAction.cc — add column 27 parent_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.