BDSIM
BDSIM is a Geant4 extension toolkit for simulation of particle transport in accelerator beamlines.
Loading...
Searching...
No Matches
BDSStackingAction.cc
1/*
2Beam Delivery Simulation (BDSIM) Copyright (C) BDSIM Collaboration, 2001 - 2026.
3
4This file is part of BDSIM.
5
6BDSIM is free software: you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published
8by the Free Software Foundation version 3 of the License.
9
10BDSIM is distributed in the hope that it will be useful, but
11WITHOUT ANY WARRANTY; without even the implied warranty of
12MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13GNU General Public License for more details.
14
15You should have received a copy of the GNU General Public License
16along with BDSIM. If not, see <http://www.gnu.org/licenses/>.
17*/
18#include "BDSDebug.hh"
19#include "BDSGlobalConstants.hh"
20#include "BDSMultiSensitiveDetectorOrdered.hh"
21#include "BDSRunManager.hh"
22#include "BDSSDEnergyDeposition.hh"
23#include "BDSSDEnergyDepositionGlobal.hh"
24#include "BDSStackingAction.hh"
25
26#include "globals.hh" // geant4 globals / types
27#include "G4Run.hh"
28#include "G4Event.hh"
29#include "G4ThreeVector.hh"
30#include "G4Track.hh"
31#include "G4TrackStatus.hh"
32#include "G4ParticleDefinition.hh"
33#include "G4ParticleTypes.hh"
34#include "G4VSensitiveDetector.hh"
35#include "G4Version.hh"
36
37#if G4VERSION_NUMBER > 1029
38#include "G4MultiSensitiveDetector.hh"
39#endif
40
41G4double BDSStackingAction::energyKilled = 0;
42
44{
45 killNeutrinos = globals->KillNeutrinos();
46 stopSecondaries = globals->StopSecondaries();
47 maxTracksPerEvent = globals->MaximumTracksPerEvent();
48 if (maxTracksPerEvent == 0) // 0 is default -> no action - set maximum possible number
49 {maxTracksPerEvent = LONG_MAX;}
50 minimumEK = globals->MinimumKineticEnergy();
51 particlesToExcludeFromCuts = globals->ParticlesToExcludeFromCutsAsSet();
52}
53
54BDSStackingAction::~BDSStackingAction()
55{;}
56
57G4ClassificationOfNewTrack BDSStackingAction::ClassifyNewTrack(const G4Track * aTrack)
58{
59 G4ClassificationOfNewTrack classification = fUrgent;
60
61#ifdef BDSDEBUG
62 G4cout<<"StackingAction: ClassifyNewtrack "<<aTrack->GetTrackID()<<
63 " "<<aTrack->GetDefinition()->GetParticleName()<<G4endl;
64 G4StackManager* SM = G4EventManager::GetEventManager()->GetStackManager();
65 G4cout<<"N total, waiting, urgent, postponed tracks: "
66 << std::setw(6) << SM->GetNTotalTrack() << " : "
67 << std::setw(6) << SM->GetNWaitingTrack() << " : "
68 << std::setw(6) << SM->GetNUrgentTrack() << " : "
69 << std::setw(6) << SM->GetNPostponedTrack()
70 << G4endl;
71#endif
72 G4int pdgCode = aTrack->GetParticleDefinition()->GetPDGEncoding();
73 if ( (aTrack->GetKineticEnergy() < minimumEK) && (particlesToExcludeFromCuts.count(pdgCode) == 0) )
74 {classification = fKill;}
75
76 // If beyond max number of tracks, kill it
77 if (aTrack->GetTrackID() > maxTracksPerEvent)
78 {classification = fKill;}
79
80 // Optionally kill all neutrinos
81 if (killNeutrinos)
82 {
83 G4int pdgNr = std::abs(pdgCode);
84 if( pdgNr == 12 || pdgNr == 14 || pdgNr == 16)
85 {classification = fKill;}
86 }
87
88 // Optionally kill secondaries
89 if (stopSecondaries && (aTrack->GetParentID() > 0))
90 {classification = fKill;}
91
92 // Here we must take care of energy conservation. If we artificially kill the track
93 // we should record its loss as energy deposition. Find if the volume is sensitive
94 // and if so record the track there. Note a track is not a step and is a snap shot at
95 // one particular point. Therefore, it has a different method in BDSSDEnergyDeposition.
96 if (classification == fKill)
97 {
98 G4VPhysicalVolume* pv = aTrack->GetVolume();
99 if (pv)
100 {
101 G4VSensitiveDetector* sd = pv->GetLogicalVolume()->GetSensitiveDetector();
102 if (sd) // SD optional attachment to logical volume
103 {
104 if (auto ecSD = dynamic_cast<BDSSDEnergyDeposition*>(sd))
105 {ecSD->ProcessHitsTrack(aTrack, nullptr);}
106#if G4VERSION_NUMBER > 1029
107 else if (auto mSD = dynamic_cast<G4MultiSensitiveDetector*>(sd))
108 {
109 for (G4int i=0; i < (G4int)mSD->GetSize(); ++i)
110 {
111 if (auto ecSD2 = dynamic_cast<BDSSDEnergyDeposition*>(mSD->GetSD(i)))
112 {ecSD2->ProcessHitsTrack(aTrack, nullptr);}
113 if (auto egSD = dynamic_cast<BDSSDEnergyDepositionGlobal*>(mSD->GetSD(i)))
114 {egSD->ProcessHitsTrack(aTrack, nullptr);}
115 else if (auto mSDO = dynamic_cast<BDSMultiSensitiveDetectorOrdered*>(sd))
116 {
117 for (G4int j=0; j < (G4int)mSDO->GetSize(); ++j)
118 {
119 if (auto ecSD3 = dynamic_cast<BDSSDEnergyDeposition*>(mSDO->GetSD(j)))
120 {ecSD3->ProcessHitsTrack(aTrack, nullptr);}
121 // else another SD -> don't use -> based on which SDs are constructed with BDSMultiSensitiveDetectorOrdered
122 // in BDSSDManager. e.g. we dont' need BDSSDEnergyDepositionGlobal here
123 }
124 // else another SD -> don't use
125 }
126 }
127 }
128#endif
129 else if (auto mSDO = dynamic_cast<BDSMultiSensitiveDetectorOrdered*>(sd))
130 {
131 for (G4int i=0; i < (G4int)mSDO->GetSize(); ++i)
132 {
133 if (auto ecSD2 = dynamic_cast<BDSSDEnergyDeposition*>(mSDO->GetSD(i)))
134 {ecSD2->ProcessHitsTrack(aTrack, nullptr);}
135 // else another SD -> don't use
136 }
137 }
138 else
139 {energyKilled += aTrack->GetTotalEnergy();} // no suitable SD, but add up anyway
140 }
141 else
142 {energyKilled += aTrack->GetTotalEnergy();} // no SD, but add up anyway
143 }
144 else
145 {energyKilled += aTrack->GetTotalEnergy();} // no PV - unusual but possible - add up anyway
146 }
147
148 return classification;
149}
150
152{
153 // urgent stack empty, looking into the waiting stack
154#ifdef BDSDEBUG
155 G4cout<<"StackingAction: New stage"<<G4endl;
156#endif
157}
158
161
162
A class that holds global options and constants.
Modified G4MultiSensitiveDetector that retains order and passes hits in sequence.
Generates BDSHitsEnergyDepositionGlobal from step information.
Generates BDSHitsEnergyDepositions from step information - uses curvilinear coords.
G4long maxTracksPerEvent
Maximum number of tracks before start killing.
virtual void PrepareNewEvent()
We don't do anything here.
BDSStackingAction()=delete
Force use of supplied constructor.
G4bool killNeutrinos
Local copy of whether to kill neutrinos for tracking efficiency.
virtual G4ClassificationOfNewTrack ClassifyNewTrack(const G4Track *aTrack)
G4bool stopSecondaries
Whether particles with parentID > 0 will be killed.
virtual void NewStage()
We don't do anything here.