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