ATLAS Offline Software
Loading...
Searching...
No Matches
TRTSensitiveDetector.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
3*/
4
5
6// Class header
8
9// Athena includes
11#include "TRT_G4Utilities/TRTParameters.hh"
12#include "TRT_G4Utilities/TRTOutputFile.hh"
17
18//Geant4 includes
19//#include "Randomize.hh"
20#include "G4TouchableHistory.hh"
21#include "G4Step.hh"
22#include "G4Track.hh"
23#include "G4VProcess.hh"
24#include "G4ParticleDefinition.hh"
25#include "G4StepPoint.hh"
26#include "G4ThreeVector.hh"
27#include "G4Geantino.hh"
28#include "G4ChargedGeantino.hh"
29#include <G4EventManager.hh>
30#include "G4Gamma.hh"
31#include "G4Electron.hh"
32#include "G4Positron.hh"
33#include "G4ProcessManager.hh"
34#include "G4ProcessVector.hh"
35#include "G4GammaGeneralProcess.hh"
36#include "G4NistManager.hh"
37
38//stl includes
39#include <cmath>
40#include <utility>
41
42TRTSensitiveDetector::TRTSensitiveDetector(const std::string& name, const std::string& hitCollectionName, int setVerboseLevel)
43 : G4VSensitiveDetector( name ),
44 //Variables properly set during InitializeHitProcessing() method
49 m_boundaryZ(0.0),
50 //End of variables properly set during InitializeHitProcessing() method
51 //Properties of current TRTUncompressedHit
54 m_preStepY(0.0), m_preStepZ(0.0), m_postStepX(0.0), m_postStepY(0.0),
55 m_postStepZ(0.0), m_globalTime(0.0),
56 //End of Properties of current TRTUncompressedHit
57 m_HitCollName( hitCollectionName ), m_pParameters(nullptr),
59 m_pMaterialXe(nullptr), m_pMaterialKr(nullptr), m_pMaterialAr(nullptr)
60{
61 m_pParameters = TRTParameters::GetPointer();
62
63 m_printMessages = m_pParameters->GetInteger("PrintMessages"); //FIXME not used - remove?
64 verboseLevel = setVerboseLevel;
65
67
68 m_pParameters = nullptr;
69}
70
71
72// Called by TRTSensitiveDetector
73// Once per run
74
76{
77 if(verboseLevel>4)
78 {
79 G4cout << GetName() << " InitializeHitProcessing()" << G4endl;
80 }
82 m_pParameters->GetInteger("HitsWithZeroEnergyDeposit");
83
84 m_phot = nullptr;
85
86 // Parameters describing flourecense in Xe gas mixture:
87 // Units of these numbers in management file are in keV; change to default units
88
89 m_energyThreshold = m_pParameters->GetDouble("EnergyThreshold" ) * CLHEP::keV;
90 m_energyThresholdKr = m_pParameters->GetDouble("EnergyThresholdKr") * CLHEP::keV;
91 m_energyThresholdAr = m_pParameters->GetDouble("EnergyThresholdAr") * CLHEP::keV;
92 m_probabilityThreshold = m_pParameters->GetDouble("ProbabilityThreshold" );
93 m_probabilityThresholdKr = m_pParameters->GetDouble("ProbabilityThresholdKr");
94 m_probabilityThresholdAr = m_pParameters->GetDouble("ProbabilityThresholdAr");
95 m_energyDepositCorrection = m_pParameters->GetDouble("EnergyDepositCorrection" ) * CLHEP::keV;
96 m_energyDepositCorrectionKr = m_pParameters->GetDouble("EnergyDepositCorrectionKr") * CLHEP::keV;
97 m_energyDepositCorrectionAr = m_pParameters->GetDouble("EnergyDepositCorrectionAr") * CLHEP::keV;
98 if(verboseLevel>9)
99 {
100 G4cout << GetName() << " Fluorescence parameters: EnergyThreshold "
101 << m_energyThreshold << G4endl;
102 G4cout << GetName() << " Fluorescence parameters: EnergyThresholdKr "
103 << m_energyThresholdKr << G4endl;
104 G4cout << GetName() << " Fluorescence parameters: EnergyThresholdAr "
105 << m_energyThresholdAr << G4endl;
106 G4cout << GetName() << " Fluorescence parameters: ProbabilityThreshold "
107 << m_probabilityThreshold << G4endl;
108 G4cout << GetName() << " Fluorescence parameters: ProbabilityThresholdKr "
109 << m_probabilityThresholdKr << G4endl;
110 G4cout << GetName() << " Fluorescence parameters: ProbabilityThresholdAr "
111 << m_probabilityThresholdAr << G4endl;
112 G4cout << GetName() << " Fluorescence parameters: EnergyDepositCorrection "
113 << m_energyDepositCorrection << G4endl;
114 G4cout << GetName() << " Fluorescence parameters: EnergyDepositCorrectionKr "
115 << m_energyDepositCorrectionKr << G4endl;
116 G4cout << GetName() << " Fluorescence parameters: EnergyDepositCorrectionAr "
117 << m_energyDepositCorrectionAr << G4endl;
118 }
119 m_boundaryZ = m_pParameters->GetDouble("LengthOfBarrelVolume") / 2.;
120
121 TRTParametersForBarrelHits* pParametersForBarrelHits = nullptr;
122 TRTParametersForEndCapHits* pParametersForEndCapHits = nullptr;
123
126
127 pParametersForBarrelHits =
129 pParametersForEndCapHits =
131
132 delete pParametersForBarrelHits;
133 delete pParametersForEndCapHits;
134
135 // Get nist material manager
136 G4NistManager* nist = G4NistManager::Instance();
137 m_pMaterialXe = nist->FindOrBuildMaterial("trt::XeCO2O2");
138 if (!m_pMaterialXe && verboseLevel>4)
139 {
140 G4cout << GetName() << " Could not find Xe material (Only OK if no TRT straws are filled with Xenon)" << G4endl;
141 }
142 m_pMaterialKr = nist->FindOrBuildMaterial("trt::KrCO2O2");
143 if (!m_pMaterialKr && verboseLevel>4)
144 {
145 G4cout << GetName() << " Could not find Kr material (Only OK if no TRT straws are filled with Krypton)" << G4endl;
146 }
147 m_pMaterialAr = nist->FindOrBuildMaterial("trt::ArCO2O2");
148 if (!m_pMaterialAr && verboseLevel>4)
149 {
150 G4cout << GetName() << " Could not find Ar material (Only OK if no TRT straws are filled with Argon)" << G4endl;
151 }
153 {
154 G4ExceptionDescription description;
155 description << "InitializeHitProcessing: Could not find Xe, Kr or Ar materials (Not OK!)";
156 G4Exception("TRTSensitiveDetector", "NoTRTGasesFound", FatalException, description);
157 }
158
159 if(verboseLevel>4)
160 {
161 G4cout << GetName() << " InitializeHitProcessing() done" << G4endl;
162 }
163}
164
165
166// Called by Geant4
167// For each event
168
169void TRTSensitiveDetector::Initialize(G4HCofThisEvent* /*pHCofThisEvent*/)
170{
171 if(verboseLevel>4)
172 {
173 G4cout << GetName() << " Initialize()" << G4endl;
174 }
175
176 // The following code etablishes a pointer to the "phot" process.
177 // This pointer is used in ProcessHits.
178 // For performance reasons we test directly on the pointer address rather
179 // than doing the string comparison for each hit in ProcessHits.
180
181 if(!m_phot) { // Only for the first event
182 const G4ProcessVector* pVec =
183 G4Gamma::Definition()->GetProcessManager()->GetProcessList();
184 for(size_t ip=0;ip<pVec->entries();ip++)
185 {
186 if((*pVec)[ip]->GetProcessName()=="phot")
187 {
188 m_phot = (*pVec)[ip];
189 break;
190 }
191 if((*pVec)[ip]->GetProcessName()=="GammaGeneralProc")
192 {
193 G4GammaGeneralProcess *genproc = static_cast<G4GammaGeneralProcess*>((*pVec)[ip]);
194 G4VEmProcess *proc = genproc->GetEmProcess("phot");
195 if (proc && proc->GetProcessName()=="phot")
196 {
197 m_phot = proc;
198 break;
199 }
200 }
201 }
202 }
203 if(!m_phot) {
204 G4cout << GetName() << "ERROR Did not find the photoelectic process!!!" << G4endl;
205 }
206
207 // nullptr checks are needed for unit tests because geant4 run is not initialized
208 // in real jobs, event manager, and event info are always set
209 if(auto* eventManager = G4EventManager::GetEventManager())
210 {
211 if(auto* eventInfo = static_cast<AtlasG4EventUserInfo*>(eventManager->GetUserInformation())) {
212 m_HitColl = eventInfo->GetHitCollectionMap()->Find<TRTUncompressedHitCollection>(m_HitCollName);
213 m_g4UserEventInfo = eventInfo;
214 }
215 }
216
217 if(verboseLevel>4)
218 {
219 G4cout << GetName() << " Initialize() done" << G4endl;
220 }
221}
222
223
224
225// Called by Geant4
226
228 G4TouchableHistory* /*pTouchableHistory*/)
229{
230 m_energyDeposit = pStep->GetTotalEnergyDeposit();
231
232 G4Track* pTrack = pStep->GetTrack();
233 G4ParticleDefinition* pParticleDefinition = pTrack->GetDefinition();
234
235 // Skip particles which deposit no energy
237 {
238 if ( pParticleDefinition != G4Geantino::Definition() &&
239 pParticleDefinition != G4ChargedGeantino::Definition() )
240 {
241 return false;
242 }
243 }
244
245 // Skip electrons which originate from a photoelectric process.
246 // These electrons have very low energy and even the PAI model will
247 // give the wrong energy deposit.
248 // Instead we count for a photon which undergoes a "phot" reaction
249 // the full energy as deposited in the interaction point (see below)
250 if(pTrack->GetCreatorProcess()==m_phot)
251 {
252 return false;
253 }
254
255 // Get kinetic energy of depositing particle
256 m_kineticEnergy = pStep->GetPreStepPoint()->GetKineticEnergy();
257
258 // If we are dealing with a photon undergoing a "phot" reaction, count
259 // the photon kinetic energy as deposited energy in the point of
260 // the reaction
261
262 if ( pParticleDefinition==G4Gamma::GammaDefinition() &&
263 pStep->GetPostStepPoint()->GetProcessDefinedStep()==m_phot )
264 {
266 double current_energyThreshold = 1E+99;
267 double current_probabilityThreshold = 2.0;
268 double current_energyDepositCorrection = 0.0;
269 G4Material *pPreStepMaterial = pStep->GetPreStepPoint()->GetMaterial();
270 if (pPreStepMaterial == m_pMaterialXe)
271 {
272 current_energyThreshold = m_energyThreshold;
273 current_probabilityThreshold = m_probabilityThreshold;
274 current_energyDepositCorrection = m_energyDepositCorrection;
275 }
276 else if (pPreStepMaterial == m_pMaterialKr)
277 {
278 current_energyThreshold = m_energyThresholdKr;
279 current_probabilityThreshold = m_probabilityThresholdKr;
280 current_energyDepositCorrection = m_energyDepositCorrectionKr;
281 }
282 else if (pPreStepMaterial == m_pMaterialAr)
283 {
284 current_energyThreshold = m_energyThresholdAr;
285 current_probabilityThreshold = m_probabilityThresholdAr;
286 current_energyDepositCorrection = m_energyDepositCorrectionAr;
287 }
288 else
289 {
290 G4ExceptionDescription description;
291 description << "ProcessHits: Unknown prestep material";
292 G4Exception("TRTSensitiveDetector", "UnknownGasFound", FatalException, description);
293 return false; //The G4Exception call above should abort the job, but Coverity does not seem to pick this up.
294 }
295 // Correct for flourescence (a la Nevski):
296 // - For some percentage (15%) of photons with
297 // energy above threshold (4.9 keV) reduce deposited energy
298 // by correction (4.0 keV)
299 // (Different numbers for Ar and Kr)
300 if ( m_energyDeposit > current_energyThreshold &&
301 CLHEP::RandFlat::shoot() > current_probabilityThreshold )
302 {
303 m_energyDeposit -= current_energyDepositCorrection;
304 }
305 }
306
307
308 // Particle code of depositing particle
309 m_particleEncoding = pParticleDefinition->GetPDGEncoding();
310
311 bool trackerHit = false;
312
313 if ( std::fabs(pStep->GetPreStepPoint()->GetPosition().z()) < m_boundaryZ )
314 {
315 trackerHit = m_pProcessingOfBarrelHits->ProcessHit(pStep);
316 }
317 else
318 {
319 trackerHit = m_pProcessingOfEndCapHits->ProcessHit(pStep);
320 }
321
322 // TRTUncompressedHit appearently expects energyDeposit in keV.
323 // Convert:
325
326 // Create UncompressedHit
327
328 if (trackerHit)
329 {
330 // Build the hit straight onto the vector
332 (float) m_kineticEnergy, (float) m_energyDepositInKeV,
333 (float) m_preStepX, (float) m_preStepY, (float) m_preStepZ,
334 (float) m_postStepX, (float) m_postStepY, (float) m_postStepZ,
335 (float) m_globalTime );
336 }
337
338 return true;
339}
340
341
342// It was called by TRTRunAction::EndOfRunAction ...
343
345{
346 if(verboseLevel>4)
347 {
348 G4cout << GetName() << " DeleteObjects()" << G4endl;
349 }
350
353
354 if(verboseLevel>4)
355 {
356 G4cout << GetName() << " DeleteObjects() done" << G4endl;
357 }
358}
AtlasHitsVector< TRTUncompressedHit > TRTUncompressedHitCollection
This class is attached to G4Event objects as UserInformation.
std::string m_HitCollName
Other member variables.
TRTSensitiveDetector(const std::string &name, const std::string &hitCollectionName, int setVerboseLevel=0)
TRTUncompressedHitCollection * m_HitColl
void Initialize(G4HCofThisEvent *) override final
void DeleteObjects()
Called by TRTRunAction::EndOfRunAction ...
HepMcParticleLink m_partLink
friend class TRTProcessingOfEndCapHits
int m_hitID
Properties of current TRTUncompressedHit, set by TRTProcessingOfBarrelHits and TRTProcessingOfEndCapH...
const TRTParameters * m_pParameters
TRTProcessingOfEndCapHits * m_pProcessingOfEndCapHits
int m_printMessages
Configuration paremeters.
G4bool ProcessHits(G4Step *, G4TouchableHistory *) override final
friend class TRTProcessingOfBarrelHits
TRTProcessingOfBarrelHits * m_pProcessingOfBarrelHits
AtlasG4EventUserInfo * m_g4UserEventInfo
std::string description
glabal timer - how long have I taken so far?
Definition hcg.cxx:91