From 9ea071813904e7629d33818469da70c93ce5daa4 Mon Sep 17 00:00:00 2001 From: Lars Bogner Date: Thu, 11 Jun 2026 10:25:08 +0200 Subject: [PATCH] add Spawning ntuple recording secondary births per step Each step that spawns secondaries now writes one row per secondary to a new Spawning ntuple (event_id, parent_track_id, parent_step_no, child_track_id). This enables direct shower-tree reconstruction without position joins. Requires the companion Geant4 submodule change that pre-assigns track IDs in ProcessSecondariesFromParticleChange. Co-Authored-By: Claude Sonnet 4.6 --- lib/geant4 | 2 +- src/RunAction.cc | 8 ++++++++ src/SteppingAction.cc | 12 ++++++++++++ 3 files changed, 21 insertions(+), 1 deletion(-) diff --git a/lib/geant4 b/lib/geant4 index 41f2dd7..e7827c9 160000 --- a/lib/geant4 +++ b/lib/geant4 @@ -1 +1 @@ -Subproject commit 41f2dd79968018de4efb966f2546970b30c4af78 +Subproject commit e7827c9b07aa6788f37e70658302945d6f129c70 diff --git a/src/RunAction.cc b/src/RunAction.cc index c14ef49..d9d9afa 100644 --- a/src/RunAction.cc +++ b/src/RunAction.cc @@ -112,6 +112,14 @@ RunAction::RunAction() analysisManager->CreateNtupleDColumn("Ey"); // col 25 [V/m] analysisManager->CreateNtupleDColumn("Ez"); // col 26 [V/m] analysisManager->FinishNtuple(); + + // Spawning ntuple (one row per secondary born, ntuple id=2) + analysisManager->CreateNtuple("Spawning", "Spawning"); + analysisManager->CreateNtupleIColumn("event_id"); // col 0 + analysisManager->CreateNtupleIColumn("parent_track_id"); // col 1 + analysisManager->CreateNtupleIColumn("parent_step_no"); // col 2 + analysisManager->CreateNtupleIColumn("child_track_id"); // col 3 + analysisManager->FinishNtuple(); } //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... diff --git a/src/SteppingAction.cc b/src/SteppingAction.cc index 964c28c..4a6ac67 100644 --- a/src/SteppingAction.cc +++ b/src/SteppingAction.cc @@ -87,6 +87,18 @@ void SteppingAction::UserSteppingAction(const G4Step* step) auto track = step->GetTrack(); int evtId = G4RunManager::GetRunManager()->GetCurrentEvent()->GetEventID(); + // Write one Spawning row per secondary born in this step (track IDs pre-assigned) + const auto* secondaries = step->GetSecondaryInCurrentStep(); + if (secondaries) { + for (const G4Track* sec : *secondaries) { + analysisManager->FillNtupleIColumn(2, 0, evtId); + analysisManager->FillNtupleIColumn(2, 1, track->GetTrackID()); + analysisManager->FillNtupleIColumn(2, 2, track->GetCurrentStepNumber()); + analysisManager->FillNtupleIColumn(2, 3, sec->GetTrackID()); + analysisManager->AddNtupleRow(2); + } + } + analysisManager->FillNtupleIColumn(1, 0, evtId); analysisManager->FillNtupleIColumn(1, 1, track->GetTrackID()); analysisManager->FillNtupleIColumn(1, 2, track->GetCurrentStepNumber());