ATLAS Offline Software
Loading...
Searching...
No Matches
AthenaDebugStackingAction.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// System includes
6#include <iostream>
7#include <memory>
8#include <string>
9
10// Local includes
12
13// Truth includes
18
19// Geant4 includes
20#include "G4Track.hh"
21#include "G4Event.hh"
22#include "G4EventManager.hh"
23
25#include "CxxUtils/fpcompare.h"
26
27namespace G4UA
28{
29
30 //---------------------------------------------------------------------------
31 // Constructor
32 //---------------------------------------------------------------------------
35
36 //---------------------------------------------------------------------------
37 // Classify a new track
38 //---------------------------------------------------------------------------
39 G4ClassificationOfNewTrack
41 {
42 // Kill neutrinos if enabled
43 if(m_config.killAllNeutrinos && isNeutrino(track)) {
44 return fKill;
45 }
46
47 // Kill super-low-E photons
48 const double safeCut = 0.00005;
49 double totalE = track->GetTotalEnergy();
50 if(isGamma(track) && totalE < safeCut) {
51 return fKill;
52 }
53
54 // TODO: Why is this here? Can I remove it?
55 G4Event* ev = G4EventManager::GetEventManager()->GetNonconstCurrentEvent();
56 AtlasG4EventUserInfo* atlasG4EvtUserInfo __attribute__ ((unused)) =
57 static_cast<AtlasG4EventUserInfo*> (ev->GetUserInformation());
58
59 // Was track subject to a RR?
60 bool rouletted = false;
61
62 // Neutron Russian Roulette
63 if (m_config.russianRouletteNeutronThreshold > 0 && isNeutron(track) &&
64 CxxUtils::fpcompare::equal(track->GetWeight(), 1.0) && // do not re-Roulette particles
65 track->GetKineticEnergy() < m_config.russianRouletteNeutronThreshold) {
66 // shoot random number
67 if ( CLHEP::RandFlat::shoot() > m_oneOverWeightNeutron ) {
68 if (m_config.applyNRR) {
69 // Kill (w-1)/w neutrons
70 return fKill;
71 } else {
72 // process them at the end of the stack
73 return fWaiting;
74 }
75 }
76 rouletted = true;
77 // Weight the rest 1/w neutrons with a weight of w
78 if (m_config.applyNRR) {
79 // TODO There may be another way to set the weights via
80 // another G4 interface avoiding the const_cast, but the
81 // changes are more major and will need more careful validation.
82 G4Track* mutableTrack ATLAS_THREAD_SAFE = const_cast<G4Track*> (track);
83 mutableTrack->SetWeight(m_config.russianRouletteNeutronWeight);
84 }
85 }
86
87 // Photon Russian Roulette
88 if (m_config.russianRoulettePhotonThreshold > 0 && isGamma(track) && track->GetOriginTouchable() &&
89 track->GetOriginTouchable()->GetVolume()->GetName().substr(0, 3) == "LAr" && // only for photons created in LAr
90 CxxUtils::fpcompare::equal(track->GetWeight(), 1.0) && // do not re-Roulette particles
91 track->GetKineticEnergy() < m_config.russianRoulettePhotonThreshold) {
92 // shoot random number
93 if ( CLHEP::RandFlat::shoot() > m_oneOverWeightPhoton ) {
94 if (m_config.applyPRR) {
95 // Kill (w-1)/w photons
96 return fKill;
97 } else {
98 // process them at the end of the stack
99 return fWaiting;
100 }
101 }
102 rouletted = true;
103 // Weight the rest 1/w neutrons with a weight of w
104 if (m_config.applyPRR) {
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 mutableTrack->SetWeight(m_config.russianRoulettePhotonWeight);
110 }
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);
126 ti->SetClassification(TrackInformation::Primary);
127 // regNr=0 and classify=Primary are default values anyway
131 track->SetUserInformation(ti.release());
132 }
133 // 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) &&
147 m_config.photonEnergyCut > 0 &&
148 totalE < m_config.photonEnergyCut )
149 {
150 return fKill;
151 }
152 // Put rouletted tracks at the end of the stack
153 if (rouletted)
154 return fWaiting;
155 else
156 return fUrgent;
157 }
158
159} // namespace G4UA
__attribute__((always_inline)) inline uint16_t TileCalibDrawerBase
void unused(Args &&...)
Define macros for attributes used to control the static checker.
#define ATLAS_THREAD_SAFE
This class is attached to G4Event objects as UserInformation.
virtual G4ClassificationOfNewTrack ClassifyNewTrack(const G4Track *track) override final
Classify a new track.
AthenaDebugStackingAction(const Config &config)
Constructor with configuration.
Config m_config
Configuration options.
AthenaStackingAction(const Config &config)
Constructor with configuration.
bool isNeutrino(const G4Track *) const
Identify track as a neutrino.
bool isNeutron(const G4Track *) const
Identify track as a neutron.
bool isGamma(const G4Track *) const
Identify track as a photon.
PrimaryParticleInformation * getPrimaryParticleInformation(const G4Track *track) const
obtain the PrimaryParticleInformation from the current G4Track
This class is attached to G4PrimaryParticle objects as UserInformation.
HepMC::ConstGenParticlePtr GetHepMCParticle() const
return a pointer to the GenParticle used to create the G4PrimaryParticle
Workaround x86 precision issues for FP inequality comparisons.
int ev
Definition globals.cxx:25
bool equal(double a, double b)
Compare two FP numbers, working around x87 precision issues.
Definition fpcompare.h:114
Configuration option struct for AthenaStackingAction.