ATLAS Offline Software
AthenaStackingAction.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3 */
4 
5 
6 
7 // Local includes
8 #include "AthenaStackingAction.h"
9 
10 // Truth includes
15 
16 // Geant4 includes
17 #include "G4Track.hh"
18 #include "G4Event.hh"
19 #include "G4EventManager.hh"
20 #include "G4NeutrinoE.hh"
21 #include "G4NeutrinoMu.hh"
22 #include "G4NeutrinoTau.hh"
23 #include "G4AntiNeutrinoE.hh"
24 #include "G4AntiNeutrinoMu.hh"
25 #include "G4AntiNeutrinoTau.hh"
26 #include "G4Gamma.hh"
27 #include "G4Neutron.hh"
28 
30 
31 // System includes
32 #include <memory>
33 #include <string>
34 
35 namespace G4UA
36 {
37 
38  //---------------------------------------------------------------------------
39  // Constructor
40  //---------------------------------------------------------------------------
42  m_config(config),
43  m_oneOverWeightNeutron(0),
44  m_oneOverWeightPhoton(0)
45  {
46  // calculate this division only once
47  if (m_config.applyNRR)
49 
50  // calculate this division only once
51  if (m_config.applyPRR)
53  }
54 
55  //---------------------------------------------------------------------------
56  // Classify a new track
57  //---------------------------------------------------------------------------
58  G4ClassificationOfNewTrack
60  {
61  // Kill neutrinos if enabled
63  return fKill;
64  }
65 
66  // Kill super-low-E photons
67  const double safeCut = 0.00005;
68  double totalE = track->GetTotalEnergy();
69  if(isGamma(track) && totalE < safeCut) {
70  return fKill;
71  }
72 
73  // TODO: Why is this here? Can I remove it?
74  G4Event* ev = G4EventManager::GetEventManager()->GetNonconstCurrentEvent();
75  AtlasG4EventUserInfo* atlasG4EvtUserInfo __attribute__ ((unused)) =
76  static_cast<AtlasG4EventUserInfo*> (ev->GetUserInformation());
77 
78  // Neutron Russian Roulette
79  if (m_config.applyNRR && isNeutron(track) &&
80  track->GetWeight() < m_config.russianRouletteNeutronWeight && // do not re-Roulette particles
81  track->GetKineticEnergy() < m_config.russianRouletteNeutronThreshold) {
82  // shoot random number
83  if ( CLHEP::RandFlat::shoot() > m_oneOverWeightNeutron ) {
84  // Kill (w-1)/w neutrons
85  return fKill;
86  }
87  // TODO There may be another way to set the weights via
88  // another G4 interface avoiding the const_cast, but the
89  // changes are more major and will need more careful validation.
90  G4Track* mutableTrack ATLAS_THREAD_SAFE = const_cast<G4Track*> (track);
91  // Weight the rest 1/w neutrons with a weight of w
92  mutableTrack->SetWeight(m_config.russianRouletteNeutronWeight);
93  }
94 
95  // Photon Russian Roulette
96  if (m_config.applyPRR && isGamma(track) && track->GetOriginTouchable() &&
97  track->GetOriginTouchable()->GetVolume()->GetName().substr(0, 3) == "LAr" && // only for photons created in LAr
98  track->GetWeight() < m_config.russianRoulettePhotonWeight && // do not re-Roulette particles
99  track->GetKineticEnergy() < m_config.russianRoulettePhotonThreshold) {
100  // shoot random number
101  if ( CLHEP::RandFlat::shoot() > m_oneOverWeightPhoton ) {
102  // Kill (w-1)/w photons
103  return fKill;
104  }
105  // TODO There may be another way to set the weights via
106  // another G4 interface avoiding the const_cast, but the
107  // changes are more major and will need more careful validation.
108  G4Track* mutableTrack ATLAS_THREAD_SAFE = const_cast<G4Track*> (track);
109  // Weight the rest 1/w neutrons with a weight of w
110  mutableTrack->SetWeight(m_config.russianRoulettePhotonWeight);
111  }
112 
113  // Handle primary particles
114  if(track->GetParentID() == 0) { // Condition for Primaries
115  // Extract the PrimaryParticleInformation
116  PrimaryParticleInformation* primaryPartInfo = this->getPrimaryParticleInformation(track);
117  // Fill some information for this track
118  if(primaryPartInfo) {
119  if (!m_config.isISFJob) {
120  // don't do anything
121  auto part = primaryPartInfo->GetHepMCParticle();
122  if (part) {
123  // OK, we got back to HepMC
124  std::unique_ptr<TrackInformation> ti = std::make_unique<TrackInformation>(part);
125  ti->SetRegenerationNr(0);
127  // regNr=0 and classify=Primary are default values anyway
131  track->SetUserInformation(ti.release());
132  }
133  // TODO What does this condition mean?
134  else if(primaryPartInfo->GetParticleUniqueID() >= 0 && primaryPartInfo->GetParticleBarcode() >= 0) {
135  // PrimaryParticleInformation should at least provide a barcode
136  std::unique_ptr<TrackBarcodeInfo> bi = std::make_unique<TrackBarcodeInfo>(primaryPartInfo->GetParticleUniqueID(), primaryPartInfo->GetParticleBarcode());
140  track->SetUserInformation(bi.release());
141  }
142  } // no ISFParticle attached
143  } // has PrimaryParticleInformation
144  }
145  // Secondary track; decide whether to save or kill
146  else if( isGamma(track) &&
148  totalE < m_config.photonEnergyCut )
149  {
150  return fKill;
151  }
152  return fUrgent;
153  }
154 
156  {
157  const G4DynamicParticle* dp = track->GetDynamicParticle();
158  if(dp) {
159  const G4PrimaryParticle* pp = nullptr;
160  pp = dp->GetPrimaryParticle();
161  if(pp) {
162  // Extract the PrimaryParticleInformation
163  return dynamic_cast<PrimaryParticleInformation*>
164  ( pp->GetUserInformation() );
165  }
166  }
167  return nullptr;
168  }
169 
170  //---------------------------------------------------------------------------
171  // Identify track definition
172  //---------------------------------------------------------------------------
173  bool AthenaStackingAction::isNeutrino(const G4Track* track) const
174  {
175  auto particleDef = track->GetParticleDefinition();
176  return (particleDef == G4NeutrinoE::NeutrinoEDefinition() ||
177  particleDef == G4AntiNeutrinoE::AntiNeutrinoEDefinition() ||
178  particleDef == G4NeutrinoMu::NeutrinoMuDefinition() ||
179  particleDef == G4AntiNeutrinoMu::AntiNeutrinoMuDefinition() ||
180  particleDef == G4NeutrinoTau::NeutrinoTauDefinition() ||
181  particleDef == G4AntiNeutrinoTau::AntiNeutrinoTauDefinition());
182  }
183 
184  //---------------------------------------------------------------------------
185  bool AthenaStackingAction::isGamma(const G4Track* track) const
186  {
187  return track->GetParticleDefinition() == G4Gamma::Gamma();
188  }
189 
190  //---------------------------------------------------------------------------
191  bool AthenaStackingAction::isNeutron(const G4Track* track) const
192  {
193  return track->GetParticleDefinition() == G4Neutron::Neutron();
194  }
195 
196 } // namespace G4UA
LArG4FSStartPointFilter.part
part
Definition: LArG4FSStartPointFilter.py:21
G4UA::AthenaStackingAction::m_config
Config m_config
Configuration options.
Definition: AthenaStackingAction.h:61
G4UA::AthenaStackingAction::AthenaStackingAction
AthenaStackingAction(const Config &config)
Constructor with configuration.
Definition: AthenaStackingAction.cxx:41
G4UA::AthenaStackingAction::Config::isISFJob
bool isISFJob
Is this an ISF job.
Definition: AthenaStackingAction.h:47
TileDCSDataPlotter.dp
dp
Definition: TileDCSDataPlotter.py:840
G4UA::AthenaStackingAction::Config::photonEnergyCut
double photonEnergyCut
Photon energy cut.
Definition: AthenaStackingAction.h:33
AtlasG4EventUserInfo
This class is attached to G4Event objects as UserInformation. It holds a pointer to the HepMC::GenEve...
Definition: AtlasG4EventUserInfo.h:21
VP1PartSpect::Neutron
@ Neutron
Definition: VP1PartSpectFlags.h:25
G4UA
for nSW
Definition: CalibrationDefaultProcessing.h:19
G4UA::AthenaStackingAction::Config::russianRouletteNeutronThreshold
double russianRouletteNeutronThreshold
Energy threshold for the Neutron Russian Roulette.
Definition: AthenaStackingAction.h:37
G4UA::AthenaStackingAction::m_oneOverWeightNeutron
double m_oneOverWeightNeutron
Definition: AthenaStackingAction.h:78
G4UA::AthenaStackingAction::Config::russianRoulettePhotonThreshold
double russianRoulettePhotonThreshold
Energy threshold for the Photon Russian Roulette.
Definition: AthenaStackingAction.h:43
VP1PartSpect::Gamma
@ Gamma
Definition: VP1PartSpectFlags.h:22
G4UA::AthenaStackingAction::isNeutron
bool isNeutron(const G4Track *) const
Identify track as a neutron.
Definition: AthenaStackingAction.cxx:191
G4UA::AthenaStackingAction::Config::killAllNeutrinos
bool killAllNeutrinos
Flag to toggle killing neutrinos at tracking stage.
Definition: AthenaStackingAction.h:31
G4UA::AthenaStackingAction::ClassifyNewTrack
virtual G4ClassificationOfNewTrack ClassifyNewTrack(const G4Track *track) override
Classify a new track.
Definition: AthenaStackingAction.cxx:59
config
Definition: PhysicsAnalysis/AnalysisCommon/AssociationUtils/python/config.py:1
PrimaryParticleInformation::GetParticleBarcode
int GetParticleBarcode() const
Definition: PrimaryParticleInformation.cxx:18
G4UA::AthenaStackingAction::Config
Configuration option struct for AthenaStackingAction.
Definition: AthenaStackingAction.h:29
G4UA::AthenaStackingAction::Config::applyPRR
bool applyPRR
Apply the Photon Russian Roulette.
Definition: AthenaStackingAction.h:41
G4UA::AthenaStackingAction::isGamma
bool isGamma(const G4Track *) const
Identify track as a photon.
Definition: AthenaStackingAction.cxx:185
G4UA::AthenaStackingAction::Config::russianRoulettePhotonWeight
double russianRoulettePhotonWeight
Weight for the Photon Russian Roulette.
Definition: AthenaStackingAction.h:45
ev
int ev
Definition: globals.cxx:25
VTrackInformation::Primary
@ Primary
Definition: VTrackInformation.h:32
VTrackInformation::SetClassification
void SetClassification(TrackClassification tc)
update the classification of the currently tracked particle, usually called when a new G4Track is cre...
Definition: VTrackInformation.h:45
TrackInformation::SetRegenerationNr
void SetRegenerationNr(int i)
update the number of times the particle represented by the G4Track has undergone a non-destructive in...
Definition: TrackInformation.h:96
TrackInformation.h
G4UA::AthenaStackingAction::getPrimaryParticleInformation
PrimaryParticleInformation * getPrimaryParticleInformation(const G4Track *track) const
obtain the PrimaryParticleInformation from the current G4Track
Definition: AthenaStackingAction.cxx:155
PrimaryParticleInformation::GetHepMCParticle
HepMC::ConstGenParticlePtr GetHepMCParticle() const
return a pointer to the GenParticle used to create the G4PrimaryParticle
Definition: PrimaryParticleInformation.h:47
PrimaryParticleInformation
This class is attached to G4PrimaryParticle objects as UserInformation. The member variable m_thePart...
Definition: PrimaryParticleInformation.h:39
unused
void unused(Args &&...)
Definition: VP1ExpertSettings.cxx:39
__attribute__
__attribute__((always_inline)) inline uint16_t TileCalibDrawerBase
Definition: TileCalibDrawerBase.h:190
AtlasG4EventUserInfo.h
G4UA::AthenaStackingAction::m_oneOverWeightPhoton
double m_oneOverWeightPhoton
Definition: AthenaStackingAction.h:81
PrimaryParticleInformation.h
G4UA::AthenaStackingAction::Config::russianRouletteNeutronWeight
double russianRouletteNeutronWeight
Weight for the Neutron Russian Roulette.
Definition: AthenaStackingAction.h:39
G4UA::AthenaStackingAction::isNeutrino
bool isNeutrino(const G4Track *) const
Identify track as a neutrino.
Definition: AthenaStackingAction.cxx:173
TrackBarcodeInfo.h
xAOD::track
@ track
Definition: TrackingPrimitives.h:512
ATLAS_THREAD_SAFE
#define ATLAS_THREAD_SAFE
Definition: checker_macros.h:211
checker_macros.h
Define macros for attributes used to control the static checker.
AthenaStackingAction.h
PrimaryParticleInformation::GetParticleUniqueID
int GetParticleUniqueID() const
Definition: PrimaryParticleInformation.cxx:28
G4UA::AthenaStackingAction::Config::applyNRR
bool applyNRR
Apply the Neutron Russian Roulette.
Definition: AthenaStackingAction.h:35