ATLAS Offline Software
Loading...
Searching...
No Matches
TestActionTimer.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
3*/
4
6// //
7// TestActionTimer //
8// Code for text output (into the athena.out files) //
9// of information about the time spent simulating //
10// various pieces of the detector and particles. //
11// //
12// Written by Zachary Marshall //
13// Caltech //
14// zmarshal@caltech.edu //
15// //
16// Last update 08.07.08 //
17// //
19
20
21#include "TestActionTimer.h"
22
23#include "G4Version.hh"
24#include "G4Run.hh"
25#include "G4Event.hh"
26#include "G4Step.hh"
27
28#include "G4String.hh"
29#include "G4Timer.hh"
30#include "G4Track.hh"
31#include "G4Electron.hh"
32#include "G4Gamma.hh"
33#include "G4Positron.hh"
34#include "G4Neutron.hh"
35
36// For file output
37#include "GaudiKernel/ITHistSvc.h"
38#include "TH1D.h"
39#include <string_view>
40
41// #define _myDebug
42
43
44namespace G4UA
45{
46 // Helper for G4String changes
47 bool G4StrContains(const G4String& s, const char* v)
48 {
49#if G4VERSION_NUMBER < 1100
50 return s.contains(v);
51#else
52 return G4StrUtil::contains(s, v);
53#endif
54 }
55
56 bool G4StrContains(const std::string_view& s, const char* v)
57 {
58 return s.find(v) != std::string_view::npos;
59 }
60
62 {
63 m_report.timeName.resize(eMax);
64 m_report.timeName[eEMB] = "EMB";
65 m_report.timeName[eEMEC] = "EMEC";
66 m_report.timeName[eFC1] = "FC1";
67 m_report.timeName[eFC23] = "FC23";
68 m_report.timeName[eFCO] = "FCO";
69 m_report.timeName[eHEC] = "HEC";
70 m_report.timeName[eCry] = "Cry";
71 m_report.timeName[eLAr] = "LAr";
72 m_report.timeName[eHCB] = "HCB";
73 m_report.timeName[eITkPix] = "ITkPixel";
74 m_report.timeName[eITkStrip] = "ITkStrip";
75 m_report.timeName[ePre] = "Pre";
76 m_report.timeName[eMu] = "Mu";
77 m_report.timeName[ePx] = "Px";
78 m_report.timeName[eTrt] = "TRT";
79 m_report.timeName[eHGTD] = "HGTD";
80 m_report.timeName[eSev] = "IDServ";
81 m_report.timeName[eSct] = "SCT";
82 m_report.timeName[eOther] = "Other";
83
84 m_report.timeName[eElec] = "Elec";
85 m_report.timeName[ePos] = "Pos";
86 m_report.timeName[eGam] = "Gam";
87 m_report.timeName[eNeut] = "Neut";
88
89 G4cout<< "TestActionTimer::Constructor: Labels "
90 <<" Run Event ";
91 for (int i(0); i < eMax; ++i) G4cout << m_report.timeName[i] << " ";
92 G4cout << "Particle Dead" << G4endl;
93
94 // init timers
95
96 m_runTimer = new G4Timer();
97 m_runTimer->Start();
98
99 // create all timers, start and stop, init counters
100 for (int i(0); i < eMax; ++i) {
101 G4Timer* timer = new G4Timer();
102 timer->Start();
103
104 m_timer.push_back(timer);
105 m_report.time.push_back(0.);
106 }
107
108 PPanic();
109 VPanic();
110
111#ifdef _myDebug
112 G4cout << "TestActionTimer::Constructor done" << G4endl;
113#endif
114 }
115
117 {
118 m_report.nev++;
119
120 if (m_eventTimer != 0) {
121 delete m_eventTimer;
122 m_eventTimer = 0;
123 }
124 m_eventTime = 0.;
125 m_eventTimer = new G4Timer();
126 m_eventTimer->Start();
127
128 m_runTimer->Start();
129 }
130
132 {
133 m_report.runTime += TimerSum(m_runTimer);
135
136 VPanic();
137 PPanic();
138 }
139
141 {
142 m_report.runTime=0.;
143 m_runTimer->Start();
144 }
145
147 {
148 std::cerr<<"TestActionTimer::EndOfRunAction "<< m_report.runTime <<std::endl;
149 m_report.runTime += TimerSum(m_runTimer);
150 VPanic();
151 PPanic();
152 }
153
154 void TestActionTimer::UserSteppingAction(const G4Step* aStep)
155 {
156 // HERE IS WHERE WE BEGIN OUR CLOCKING
157
158 // Get basic information about the event
159 G4Track* track = aStep->GetTrack();
160
161 G4String thePrePVname = track->GetVolume()->GetName();
162 G4String thePostPVname;
163 if (track->GetNextVolume() != 0) {
164 thePostPVname = track->GetNextVolume()->GetName();
165 } else {
166 thePostPVname = "OutOfWorld";
167 }
168
169 // Check what volume we are in. If the volume does not agree with the clock, kill the clock
170 G4Timer* timer = 0;
171 int preIndex = ClassifyVolume( thePrePVname );
172 int postIndex=-1;
173 if (thePrePVname != thePostPVname){
174 timer = m_timer[preIndex];
175 if (!timer->IsValid()){ m_report.time[preIndex] += TimerSum(timer); } else { VPanic(); }
176
177 // Now start the appropriate clock
178 postIndex = ClassifyVolume( thePostPVname );
179 m_timer[postIndex]->Start();
180
181 // Otherwise it's going into "out of world"
182 } else {
183 timer = m_timer[preIndex];
184 if (timer->IsValid()) {
185 VPanic(); timer->Start();
186 }
187 }
188
189 // Now for the particle based timers
190 if (track->GetDefinition() == G4Electron::ElectronDefinition() ){
191 if ( m_timer[eElec]->IsValid() ){
192 m_timer[eElec]->Start();
193 }
194 } else if (!m_timer[eElec]->IsValid()){
196 }
197 if (track->GetDefinition() == G4Positron::PositronDefinition() ){
198 if ( m_timer[ePos]->IsValid() ){
199 m_timer[ePos]->Start();
200 }
201 } else if (!m_timer[ePos]->IsValid()){
202 m_report.time[ePos] += TimerSum(m_timer[ePos]);
203 }
204 if (track->GetDefinition() == G4Gamma::GammaDefinition() &&
205 m_timer[eGam]->IsValid()){
206 m_timer[eGam]->Start();
207 } else if ( !m_timer[eGam]->IsValid() ){
208 m_report.time[eGam] += TimerSum(m_timer[eGam]);
209 }
210 if (track->GetDefinition() == G4Neutron::NeutronDefinition() &&
211 m_timer[eNeut]->IsValid()){
212 m_timer[eNeut]->Start();
213 } else if ( !m_timer[eNeut]->IsValid() ){
215 }
216 }
217
218
219 double TestActionTimer::TimerSum(G4Timer* timer) const
220 {
221 if (timer == 0) return -999.;
222 timer->Stop();
223 return (timer->GetUserElapsed() + timer->GetSystemElapsed());
224 }
225
227 {
228#ifdef _myDebug
229 G4cout << "TestActionTimer::PPanic" << G4endl;
230#endif
231
232 // stop all particle counters and add time
233 for (int i(eElec); i < eMax; ++i) {
234 G4Timer* timer = m_timer[i];
235#ifdef _myDebug
236 G4cout << "TestActionTimer::PPanic stopping counter i:" << i << " " << timer << G4endl;
237#endif
238 if (!timer->IsValid()){
239 m_report.time[i] += TimerSum(timer);
240 }
241 }
242
243#ifdef _myDebug
244 G4cout << "TestActionTimer::PPanic done" << G4endl;
245#endif
246 }
247
249 {
250#ifdef _myDebug
251 G4cout << "TestActionTimer::VPanic" << G4endl;
252#endif
253
254 // stop all volume counters and add time
255 for (int i(0); i <= eOther; ++i) {
256 G4Timer* timer = m_timer[i];
257#ifdef _myDebug
258 G4cout << "TestActionTimer::VPanic stopping counter i:" << i << " " << timer << G4endl;
259#endif
260 if (!timer->IsValid()){
261 m_report.time[i] += TimerSum(timer);
262 }
263 }
264
265#ifdef _myDebug
266 G4cout << "TestActionTimer::VPanic done" << G4endl;
267#endif
268 }
269
270 int TestActionTimer::ClassifyVolume( G4String& nomstr ) const
271 {
272 std::string_view nom(nomstr); //Avoid copying characters during comparison
273 if( nom.length() >= 17 &&
274 nom.substr(13,4) == "EMEC" ){
275 return eEMEC;
276 }
277 else if ( nom.length() >= 16 &&
278 nom.substr(13,3) == "EMB" ){
279 return eEMB;
280 }
281 else if( nom.length() >= 25 &&
282 nom.substr(21,4) == "Cryo" ) {
283 return eCry;
284 }
285 else if( nom.length() >= 26 &&
286 nom.substr(13,13) == "FCAL::Module1"){
287 return eFC1;
288 }
289 else if( nom.length() >= 25 &&
290 nom.substr(13,12) == "FCAL::Module" ){
291 return eFC23;
292 }
293 else if ( nom.length() >= 17 &&
294 nom.substr(13,4) == "FCAL" ){
295 return eFCO;
296 }
297 else if ( nom.length() >= 16 &&
298 nom.substr(13,3) == "HEC" ){
299 return eHEC;
300 }
301 else if( nom.length() >= 31 &&
302 nom.substr(21,10) == "Presampler" ) {
303 return ePre;
304 }
305 else if ( nom.length() >= 3 &&
306 nom.substr(0,3) == "LAr" ){
307 return eLAr;
308 }
309 else if( ( (nom.length() >= 4 &&
310 nom.substr(0,4) == "Muon") ||
311 nom.substr(0,4) == "MUON" ) ||
312 ( nom.length() >= 9 &&
313 nom.substr(0,9) == "DriftTube" ) ||
314 G4StrContains(nom, "MDT") ||
315 ( nom.length() >= 12 &&
316 nom.substr(0,12) == "SensitiveGas" ) ||
317 G4StrContains(nom, "MDT") ||
318 G4StrContains(nom, "station") ){
319 return eMu;
320 }
321 else if ( nom.length() >= 8 &&
322 nom.substr(0,8) == "ITkPixel" ){
323 return eITkPix;
324 }
325 else if ( nom.length() >= 8 &&
326 nom.substr(0,8) == "ITkStrip" ){
327 return eITkStrip;
328 }
329 else if ((nom.length() >= 5 &&
330 nom.substr(0,5) == "Pixel") ||
331 nom == "Outside Barrel Service"){
332 return ePx;
333 }
334 else if ( nom.length() >= 3 &&
335 nom.substr(0,3) == "SCT" ){
336 return eSct;
337 }
338 else if ( ( nom.length() >= 3 &&
339 nom.substr(0,3) == "TRT" ) ||
340 nom == "GasMANeg" ){
341 return eTrt;
342 }
343 else if ( nom.length() >= 4 &&
344 nom.substr(0,4) == "HGTD"){
345 return eHGTD;
346 }
347 else if ( nom.length() >= 4 &&
348 nom.substr(0,4) == "Tile"){
349 return eHCB;
350 }
351 else if ( ( nom.length() >= 12 &&
352 nom.substr(0,12) == "InDetServMat" ) ||
353 ( nom.length() >= 4 &&
354 nom.substr(0,4) == "IDET" ) ||
355 ( nom.length() >= 3 &&
356 nom.substr(0,3) == "ITK" ) ||
357 ( nom.length() >= 8 &&
358 nom.substr(0,8) == "BeamPipe" ) ||
359 ( nom.length() >= 7 &&
360 nom.substr(0,7) == "Section" ) ||
361 ( nom.length() >= 3 &&
362 ( nom.substr(0,3) == "BLM" ||
363 nom.substr(0,3) == "BCM" ||
364 nom.substr(0,3) == "PLR" ) ) ||
365 ( nom.length() >= 8 &&
366 nom.substr(0,8) == "BCMPrime" ) ){
367 return eSev;
368 }
369 return eOther;
370 }
371
372} // namespace G4UA
G4Timer * m_runTimer
Timer for the entire run.
int ClassifyVolume(G4String &) const
Method to sort out which volume we are in.
double TimerSum(G4Timer *timer) const
Gets the appropriate time from the timer for adding to the sum.
G4Timer * m_eventTimer
Timer for this event.
std::vector< G4Timer * > m_timer
Vector of timers for each of the enum.
virtual void UserSteppingAction(const G4Step *) override
virtual void EndOfRunAction(const G4Run *) override
double m_eventTime
Double for storing this event.
virtual void BeginOfRunAction(const G4Run *) override
virtual void EndOfEventAction(const G4Event *) override
virtual void BeginOfEventAction(const G4Event *) override
void PPanic()
Method to shut down all particle timers.
void VPanic()
Method to shut down all volume timers.
bool G4StrContains(const G4String &s, const char *v)