diff --git a/docs/plan_parent_step_no.md b/docs/plan_parent_step_no.md new file mode 100644 index 0000000..4198d59 --- /dev/null +++ b/docs/plan_parent_step_no.md @@ -0,0 +1,31 @@ +# 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(sec)->SetUserInformation(...)`. Geant4 takes ownership and deletes it with the track. + +2. **Read at tracking** — when filling a Steps ntuple row, retrieve `dynamic_cast(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.