ATLAS Offline Software
Loading...
Searching...
No Matches
LengthIntegrator.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
4
5#include "LengthIntegrator.h"
7
8#include "TProfile.h"
9#include "TProfile2D.h"
10#include "TTree.h"
11
12#include "GaudiKernel/ISvcLocator.h"
13#include "GaudiKernel/Bootstrap.h"
14
15
16#include "G4PrimaryVertex.hh"
17#include "G4PrimaryParticle.hh"
18#include "G4Event.hh"
19#include "G4Material.hh"
20#include "G4StepPoint.hh"
21#include "G4TouchableHistory.hh"
22#include "G4LogicalVolume.hh"
23#include "G4Step.hh"
24#include "G4Pow.hh"
25#include "G4Types.hh"
26#include "G4PhysicalConstants.hh"
27#include "G4SystemOfUnits.hh"
28
29// System includes
30#include <mutex>
31
32// Framework includes
33#include "GaudiKernel/GaudiException.h"
34
35// Anonymous namespace for file-global mutexes and helper functions
36namespace
37{
39 std::mutex gHistSvcMutex;
40
42 template<class HistType>
43 bool getHist(const ServiceHandle<ITHistSvc>& hSvc,
44 const std::string& histPath, HistType*& ptr){
45 TH1* h = nullptr;
46 if(hSvc->exists(histPath)) {
47 if(hSvc->getHist(histPath, h).isSuccess()) {
48 if((ptr = dynamic_cast<HistType*>(h))) return true;
49 }
50 else throw GaudiException("Failed to getHist", "GetHistErr", StatusCode::FAILURE);
51 }
52 return false;
53 }
54
56 template<class HistType>
57 void regHist(const ServiceHandle<ITHistSvc>& hSvc,
58 const std::string& histPath, HistType*& ptr)
59 {
60 if(hSvc->regHist(histPath, ptr).isFailure()) {
61 delete ptr; // Cleanup here, for convenience.
62 throw GaudiException("Failed to regHist", "RegHistErr", StatusCode::FAILURE);
63 }
64 }
65
66 template<class HistType>
67 void regTree(const ServiceHandle<ITHistSvc>& hSvc,
68 const std::string& treeName, HistType*& ptr)
69 {
70 if(hSvc->regTree(treeName,ptr).isFailure()){
71 delete ptr; //pie?
72 throw GaudiException("Failed to register Tree", "RegTreeErr", StatusCode::FAILURE);
73 }
74 }
75
76 template<class HistType>
77 bool getTree(const ServiceHandle<ITHistSvc>& hSvc,
78 const std::string& treeName, HistType*& ptr)
79 {
80 TTree* t = nullptr;
81 if(hSvc->exists(treeName) && hSvc->getTree(treeName, t).isSuccess() &&
82 (ptr = dynamic_cast<HistType*>(t)))
83 {
84 return true;
85 }
86 else throw GaudiException("Failed to getHist", "GetHistErr", StatusCode::FAILURE);
87
88 return false;
89
90 }
91
92}
93
94namespace G4UA
95{
96
97 //---------------------------------------------------------------------------
98 // Constructor
99 //---------------------------------------------------------------------------
100 LengthIntegrator::LengthIntegrator(const std::string& histSvcName, bool doHistos=false)
101 : m_g4pow(0),
102 m_hSvc(histSvcName, "LengthIntegrator"),
103 m_doHistos(doHistos),
105 m_rzProfRL(nullptr), m_rzProfIL(nullptr)
106 {
107 // Protect concurrent access to the non-thread-safe hist svc
108 std::lock_guard<std::mutex> lock(gHistSvcMutex);
109
110
111 if(m_doHistos){
112 // Register the RZ profiles. The other profiles need to wait until the end
113 // of the events as they are created only if used.
114 const char* radName = "/lengths/radLen/RZRadLen";
115 if(!getHist(m_hSvc, radName, m_rzProfRL)) {
116 m_rzProfRL = new TProfile2D("RZRadLen","RZRadLen",1000,-25000.,25000.,2000,0.,15000.);
117 regHist(m_hSvc, radName, m_rzProfRL);
118 }
119
120 const char* intName = "/lengths/intLen/RZIntLen";
121 if(!getHist(m_hSvc, intName, m_rzProfIL)) {
122 m_rzProfIL = new TProfile2D("RZIntLen","RZIntLen",1000,-25000.,25000.,2000,0.,15000.);
123 regHist(m_hSvc, intName, m_rzProfIL);
124 }
125
126 }
127 m_tree = new TTree( "TheLarch", "And now, the Larch" );
128 //Add Braches to the tree
129 //Particle properties
130 m_tree->Branch("genNPart", &m_genNPart, "genNPart/I");
131 m_tree->Branch("genEta", &m_genEta, "genEta/F");
132 m_tree->Branch("genPhi", &m_genPhi, "genPhi/F");
133 m_tree->Branch("genZ", &m_genZ, "genZ/F");
134 m_tree->Branch("genR", &m_genR, "genR/F");
135 m_tree->Branch("total_X0", &m_total_X0, "total_X0/F");
136 m_tree->Branch("total_L0", &m_total_L0, "total_L0/F");
137
138// m_tree->Branch("collected_sensitivehit", &m_collected_sensitivehit); //Vector
139
140 m_tree->Branch("collected_X0", &m_collected_X0); //Vector
141 m_tree->Branch("collected_L0", &m_collected_L0); //Vector
142
143 m_tree->Branch("collected_inhitr", &m_collected_hitr); //Vector
144 m_tree->Branch("collected_inhitz", &m_collected_hitz); //Vector
145 m_tree->Branch("collected_inhitx", &m_collected_hitx); //Vector
146 m_tree->Branch("collected_inhity", &m_collected_hity); //Vector
147
148 m_tree->Branch("collected_outhitr", &m_collected_outhitr); //Vector
149 m_tree->Branch("collected_outhitz", &m_collected_outhitz); //Vector
150 m_tree->Branch("collected_outhitx", &m_collected_outhitx); //Vector
151 m_tree->Branch("collected_outhity", &m_collected_outhity); //Vector
152
153 m_tree->Branch("collected_material", &m_collected_material); //Vector
154 m_tree->Branch("collected_density", &m_collected_density); //Vector
155 m_tree->Branch("collected_volume", &m_collected_volume); //Vector
156 m_tree->Branch("collected_groupedmaterial", &m_collected_groupedmaterial); //Vector
157 m_tree->Branch("collected_volumetype", &m_collected_volumetype); //Vector
158
159 regTree(m_hSvc, "/lengths/TheLarch", m_tree );
160
161 //find a good way to configure this?
162 m_splitModerator = true;
163 m_splitPP1 = true;
164
165
166 m_g4pow = G4Pow::GetInstance();
167
168 }
169
170 //---------------------------------------------------------------------------
171 // Cache primary info at beginning of event
172 //---------------------------------------------------------------------------
173 void LengthIntegrator::BeginOfEventAction(const G4Event* event)
174 {
175 m_detThickMap.clear();
176 G4PrimaryVertex* vert = event->GetPrimaryVertex(0);
177 G4PrimaryParticle* part = vert->GetPrimary();
178 G4ThreeVector mom = part->GetMomentum();
179 m_etaPrimary = mom.eta();
180 m_phiPrimary = mom.phi();
181
182 m_genEta = std::isfinite(mom.eta()) ? mom.eta() : -999;
183 m_genPhi = mom.phi();
184 m_genZ = vert->GetZ0();
185 m_genR = sqrt((vert->GetX0()*vert->GetX0())+(vert->GetY0()*vert->GetY0()));
186 m_genNPart++;
187
188 m_total_X0 = 0;
189 m_total_L0 = 0;
190
191
192 }
193
194 //---------------------------------------------------------------------------
195 // Finalize event measurements
196 //---------------------------------------------------------------------------
198 {
199 // Lazily protect this whole code from concurrent access
200 std::lock_guard<std::mutex> lock(gHistSvcMutex);
201
202 if(m_doHistos){
203
204 // Loop over volumes
205 for (const auto& it : m_detThickMap) {
206
207 // If histos already exist, then fill them
208 if (m_etaMapRL.find(it.first) != m_etaMapRL.end()) {
209 m_etaMapRL[it.first]->Fill(m_etaPrimary, it.second.first, 1.);
210 m_phiMapRL[it.first]->Fill(m_phiPrimary, it.second.first, 1.);
211
212 m_etaMapIL[it.first]->Fill(m_etaPrimary, it.second.second, 1.);
213 m_phiMapIL[it.first]->Fill(m_phiPrimary, it.second.second, 1.);
214 }
215 // New detector volume; register it
216 else {
217 regAndFillHist(it.first, it.second);
218 }
219
220 } // Loop over detectors
221
222 }
223
224 fillNtuple();
225
226 }
227
228
229 std::string LengthIntegrator::getMaterialClassification(const std::string& name)
230 {
231
232 if((name.find("DM_Atlas_Air") != std::string::npos) || (name.find("DM_Atlas") != std::string::npos) ||
233 (name.find("pix::HEX") != std::string::npos)){
234 return "NONE";
235 }
236
237 if((name.find("Silicon") != std::string::npos) || (name.find("SiMetal") != std::string::npos)){
238 return "ActiveSensors";
239 }
240
241
242 //These material categories and groupings are based on the ITk
243 //for other purposes these need to be different
244
245 if(name.find("SCT_TiMetal_heat") != std::string::npos) return "HeatExchangers";
246 if(name.find("pix::HEX") != std::string::npos) return "HeatExchangers";
247 if(name.find("HeatExchangers") != std::string::npos) return "PP1"; // comment out this line to see the Heat Exchangers separately in the final plot
248
249 //----HYBRID----:
250 if(name.find("matEC_Hybrid") != std::string::npos) return "StripChips"; //"Hybrid";
251 else if(name.find("matB_HybridPCB") != std::string::npos) return "StripChips"; //"Hybrid";
252 //----SERVICES----:
253 else if(name.find("matSV_Endcap") != std::string::npos) return "Services";
254 else if(name.find("matSV_Barrel") != std::string::npos) return "Services";
255 //----ADHESIVE----
256 else if(name.find("BoronNitrideEpoxy") != std::string::npos) return "SupportStructure"; //"Adhesive";
257 else if(name.find("SE4445") != std::string::npos) return "SupportStructure"; //"Adhesive";
258 //----SUPPORT STRUCTURE----
259 else if(name.find("Peek") != std::string::npos) return "SupportStructure";
260 else if(name.find("CFRP") != std::string::npos) return "SupportStructure";
261 else if(name.find("CFoam") != std::string::npos) return "SupportStructure";
262 else if(name.find("K13C2U") != std::string::npos) return "SupportStructure";
263 else if(name.find("K13D2U") != std::string::npos) return "SupportStructure";
264 else if(name.find("Rohacell110A") != std::string::npos) return "SupportStructure";
265 //----SUPPORT HONEYCOMB----
266 else if(name.find("Honeycomb10pcf") != std::string::npos) return "SupportStructure"; //"HoneyComb";
267 else if(name.find("Honeycomb2pcf") != std::string::npos) return "SupportStructure"; //"HoneyComb";
268 else if(name.find("Honeycomb3pcf") != std::string::npos) return "SupportStructure"; //"HoneyComb";
269 //----Copper----
270 else if(name.find("CuMetal") != std::string::npos) return "Services"; //"Copper";
271 else if(name.find("Copper") != std::string::npos) return "Services"; //"Copper";
272 //----Active Sensors---- (includes sensors, ABC and HCC chips)
273 else if(name.find("SiMetal") != std::string::npos) return "ActiveSensors";
274 //----Air----
275 else if(name.find("Air") != std::string::npos) return "Air";
276 else if(name.find("N2") != std::string::npos) return "Air";
277 //----Cooling----
278 else if(name.find("CO2Liquid") != std::string::npos) return "Cooling";
279 else if(name.find("k9Allcomp") != std::string::npos) return "Cooling";
280 else if(name.find("TiMetal") != std::string::npos) return "Cooling";
281 //----BusTape----
282 else if(name.find("Kapton") != std::string::npos) return "Services"; //"BusTape";
283 else if(name.find("matPetalBusKapton") != std::string::npos) return "Services"; //"BusTape";
284 //----closeouts and connectors----
285 else if(name.find("T300CF") != std::string::npos) return "Cooling"; //"CloseoutsAndConnectors";
286 else if(name.find("Torlon") != std::string::npos) return "Cooling"; //"CloseoutsAndConnectors";
287 //----strip chips----
288 else if(name.find("matDCDC") != std::string::npos) return "StripChips";
289 else if(name.find("matEOS") != std::string::npos) return "StripChips";
290 //else return "OtherSCT";
291
292 // Older stuff
293 if(name.find("CO2") != std::string::npos) return "Cooling";
294 //if(name.find("BoronNitrideEpoxy") != std::string::npos) return "Cooling";
295 if(name.find("BoronNitrideEpoxy") != std::string::npos) return "SupportStructure";
296 if(name.find("FwdSpineOutBase") != std::string::npos) return "SupportStructure";
297 if(name.find("Rohacell") != std::string::npos) return "SupportStructure";
298 if(name.find("Honeycomb") != std::string::npos) return "SupportStructure";
299 if(name.find("matSV") != std::string::npos) return "Services";
300 if(name.find("matEOS") != std::string::npos) return "Services";
301 if(name.find("matDCDC") != std::string::npos) return "Services";
302 if(name.find("PCB") != std::string::npos) return "Services";
303
304 if(name.find("N2") != std::string::npos) return "DryNitrogen";
305 if(name.find("TiMetal") != std::string::npos) return "Services";
306 if(name.find("CuMetal") != std::string::npos) return "Services";
307 if(name.find("Aluminium") != std::string::npos) return "BeamPipe";
308
309 // Do you want to split cooling and services where possible?
310 if(name.find("Cooling") != std::string::npos) return "Services";
311
312 if(name.find("Inconel") != std::string::npos) return "BeamPipe";
313 if(name.find("Aerogel") != std::string::npos) return "BeamPipe";
314 if(name.find("Beryllium") != std::string::npos) return "BeamPipe";
315 if(name.find("Getter") != std::string::npos) return "BeamPipe";
316 if(name.find("Vacuum") != std::string::npos) return "BeamPipe";
317
318
319 if(name.find("Iron") != std::string::npos) return "SupportStructure";
320 if(name.find("Peek") != std::string::npos) return "SupportStructure";
321 if(name.find("CFRP") != std::string::npos) return "SupportStructure";
322 if(name.find("CFoam") != std::string::npos) return "SupportStructure";
323 if(name.find("K13D2U") != std::string::npos) return "SupportStructure";
324 if(name.find("BoratedPolyethylene") != std::string::npos) return "Moderator";
325
326
327 if(name.find("TiMetal") != std::string::npos) return "Titanium";
328 if(name.find("CuMetal") != std::string::npos) return "Copper";
329
330 if(name.find("Alpine") != std::string::npos) return "SupportStructure";
331
332 if(name.find("Support") != std::string::npos) return "SupportStructure";
333 if(name.find("Carbon") != std::string::npos) return "SupportStructure";
334 if(name.find("Default") != std::string::npos) return "SupportStructure";
335 if(name.find("Moderator") != std::string::npos) return "Moderator";
336 if(name.find("Steel") != std::string::npos) return "Steel";
337 if(name.find("BarrelStrip") != std::string::npos) return "Services";
338 if(name.find("Brl") != std::string::npos) return "Services";
339 if(name.find("Svc") != std::string::npos) return "Services";
340 if(name.find("InnerIST") != std::string::npos) return "Services";
341 if(name.find("InnerPST") != std::string::npos) return "Services";
342 if(name.find("BarrelPixel") != std::string::npos) return "Services";
343 if(name.find("EndcapPixel") != std::string::npos) return "Services";
344 if(name.find("InnerPixel") != std::string::npos) return "Services";
345 if(name.find("OuterPixel") != std::string::npos) return "Services";
346 if(name.find("pix::Chip") != std::string::npos) return "PixelChips";
347 if(name.find("pix::Hybrid") != std::string::npos) return "PixelChips";
348 if(name.find("PP0") != std::string::npos) return "PP0";
349 if(name.find("PP1") != std::string::npos) return "PP1";
350
351 if(name.find("PP0") != std::string::npos) return "PP1"; //Grouping PP0 and PP1
352
353 if(name.find("PST") != std::string::npos) return "SupportStructure";
354 if(name.find("IST") != std::string::npos) return "SupportStructure";
355 if(name.find("Silicon") != std::string::npos) return "ActiveSensors";
356 if(name.find("Straw") != std::string::npos) return "ActiveSensors";
357 if(name.find("Diamond") != std::string::npos) return "ActiveSensors";
358 if(name.find("SiMetal") != std::string::npos) return "ActiveSensors";
359 if(name.find("Air") != std::string::npos) return "Air";
360
361 //FIXME hack while we fix the air->nitrogen issue
362 if(name.find("DryNitrogen") != std::string::npos) return "Air";
363
364 if(name.find("CurlyPipeMountain") != std::string::npos) return "SupportStructure";
365 if(name.find("Flange") != std::string::npos) return "SupportStructure";
366
367 if(name.find("Pigtail") != std::string::npos) return "Services"; //Overwritten by some other statement...
368
369 return "NONE";
370
371 }
372
373 std::string LengthIntegrator::getVolumeType(const std::string& s){
374
375 std::string type = "";
376 if(m_splitModerator && ( s.find("Moderator") != std::string::npos || s.find("BoratedPolyethylene") != std::string::npos)) type = "Moderator";
377 else if(m_splitPP1 && ( s.find("PP0") != std::string::npos || s.find("PP1") != std::string::npos)) type = "PP1";
378 else{
379 auto colsPos = s.find("::");
380 if (colsPos != std::string::npos)
381 type = s.substr(0, colsPos);
382 else
383 type=s;
384 }
385
386 return type;
387 }
388
389
390
392
393 m_tree->Fill();
394
395
396 //Clean vectors and such
397 m_collected_X0.clear();
398 m_collected_L0.clear();
399
400 m_collected_hitr.clear();
401 m_collected_hitx.clear();
402 m_collected_hity.clear();
403 m_collected_hitz.clear();
404
405 m_collected_outhitr.clear();
406 m_collected_outhitx.clear();
407 m_collected_outhity.clear();
408 m_collected_outhitz.clear();
409
410 m_collected_material.clear();
411 m_collected_density.clear();
412 m_collected_volume.clear();
413
416
417 }
418
419
420 //---------------------------------------------------------------------------
421 // Accumulate results from one step
422 //---------------------------------------------------------------------------
423 void LengthIntegrator::UserSteppingAction(const G4Step* aStep)
424 {
425
426 const G4TouchableHistory* touchHist =
427 static_cast<const G4TouchableHistory*>(aStep->GetPreStepPoint()->GetTouchable());
428 G4LogicalVolume* lv = touchHist->GetVolume()->GetLogicalVolume();
429 G4ThreeVector hitPoint = aStep->GetPreStepPoint()->GetPosition();
430 G4ThreeVector endPoint = aStep->GetPostStepPoint()->GetPosition();
431 G4Material* mat = lv->GetMaterial();
432
433 const std::string& volName = lv->GetName();
434 const std::string& matName = mat->GetName();
435
436 double radl = mat->GetRadlen();
437 double intl = mat->GetNuclearInterLength();
438 double stepl = aStep->GetStepLength();
439 double density = mat->GetDensity()*CLHEP::cm3/CLHEP::gram;
440
441 // FIXME: using DBL_MAX just ensures double overflow below.
442 double thickstepRL = radl != 0 ? stepl/radl : DBL_MAX;
443 double thickstepIL = intl != 0 ? stepl/intl : DBL_MAX;
444
445 //Fill information for the step
446 m_collected_X0.push_back(thickstepRL);
447 m_collected_L0.push_back(thickstepIL);
448
449 m_collected_material.push_back(matName);
450 m_collected_density.push_back(density);
451 m_collected_volume.push_back(volName);
452
453 m_total_X0+=thickstepRL;
454 m_total_L0+=thickstepIL;
455
456 m_collected_hitr.push_back(hitPoint.perp());
457 m_collected_hitz.push_back(hitPoint.z());
458 m_collected_hitx.push_back(hitPoint.x());
459 m_collected_hity.push_back(hitPoint.y());
460
461 m_collected_outhitr.push_back(endPoint.perp());
462 m_collected_outhitz.push_back(endPoint.z());
463 m_collected_outhitx.push_back(endPoint.x());
464 m_collected_outhity.push_back(endPoint.y());
465
466 std::string groupmaterial = getMaterialClassification(matName);
467
468 std::string volumetype = getVolumeType(matName);
469
470 m_collected_groupedmaterial.push_back(std::move(groupmaterial));
471 m_collected_volumetype.push_back(std::move(volumetype));
472
473 if(m_doHistos){
474 // Protect concurrent histo filling
475 {
476 static std::mutex mutex_instance;
477 std::lock_guard<std::mutex> lock(mutex_instance);
478 m_rzProfRL->Fill( hitPoint.z() , hitPoint.perp() , thickstepRL , 1. );
479 m_rzProfIL->Fill( hitPoint.z() , hitPoint.perp() , thickstepIL , 1. );
480 m_rzProfRL->Fill( endPoint.z() , endPoint.perp() , thickstepRL , 1. );
481 m_rzProfIL->Fill( endPoint.z() , endPoint.perp() , thickstepIL , 1. );
482 }
483 }
484
485 }
486
488
489 TProfile2D* LengthIntegrator::getOrCreateProfile(const std::string& regName, const TString& histoname, const TString& xtitle, int nbinsx, float xmin, float xmax,const TString& ytitle, int nbinsy,float ymin, float ymax,const TString& ztitle){
490
491 if(m_hSvc->exists(regName)){
492 TH2* histo=nullptr;
493 if(m_hSvc->getHist(regName,histo).isSuccess())
494 return dynamic_cast<TProfile2D*>(histo);
495 } else {
496 TProfile2D* result= new TProfile2D(histoname,histoname,nbinsx,xmin,xmax,nbinsy,ymin,ymax);
497 result->GetXaxis()->SetTitle(xtitle);
498 result->GetYaxis()->SetTitle(ytitle);
499 result->GetZaxis()->SetTitle(ztitle);
500
501 if (m_hSvc && m_hSvc->regHist(regName,result).isFailure()){
502 //ATH_MSG_FATAL( "Registration of histogram " << rznameReg << " failed" );
503 throw GaudiException("Registration of histogram " + regName + " failed", "RegHistErr", StatusCode::FAILURE);
504 }
505 return result;
506 }
507
508 // should never be here
509 G4cout<<"ERROR something went wrong in handling of THistSvc "<<regName <<" "<<histoname<<G4endl;
510 return nullptr;
511 }
512
513 //---------------------------------------------------------------------------
514 // Add elements and values to the map
515 //---------------------------------------------------------------------------
516 void LengthIntegrator::addToDetThickMap(const std::string& name, double thickstepRL, double thickstepIL)
517 {
518 auto it=m_detThickMap.find(name);
519 if(it!=m_detThickMap.end()){
520 (*it).second.first+=thickstepRL;
521 (*it).second.second+=thickstepIL;
522 } else {
523 m_detThickMap.insert(std::map<std::string,std::pair<double,double>,std::less<std::string> >::value_type( name, std::pair<double,double>( thickstepRL, thickstepIL) ) );
524 }
525 }
526
527 //---------------------------------------------------------------------------
528 // Setup hists for one detector
529 //---------------------------------------------------------------------------
530 void LengthIntegrator::regAndFillHist(const std::string& detName,
531 const std::pair<double, double>& thicks)
532 {
533 TProfile* profEtaRL = nullptr;
534 TProfile* profEtaIL = nullptr;
535 TProfile* profPhiRL = nullptr;
536 TProfile* profPhiIL = nullptr;
537
538 auto pathEtaRL = "/lengths/radLen/" + detName + "_RL";
539 auto pathEtaIL = "/lengths/intLen/" + detName + "_IL";
540 auto pathPhiRL = "/lengths/radLen/" + detName + "Phi_RL";
541 auto pathPhiIL = "/lengths/intLen/" + detName + "Phi_IL";
542
543 // Eta rad profile
544 if(!getHist(m_hSvc, pathEtaRL, profEtaRL)) {
545 const std::string name(detName+"_RL");
546 profEtaRL = new TProfile(name.c_str(), name.c_str(), 1000, -6., 6.);
547 profEtaRL->GetXaxis()->SetTitle("#eta");
548 profEtaRL->GetYaxis()->SetTitle("%X0");
549 regHist(m_hSvc, pathEtaRL, profEtaRL);
550 }
551 // Eta int profile
552 if(!getHist(m_hSvc, pathEtaIL, profEtaIL)) {
553 const std::string name(detName+"_IL");
554 profEtaIL = new TProfile(name.c_str(), name.c_str(), 1000, -6., 6.);
555 profEtaIL->GetXaxis()->SetTitle("#eta");
556 profEtaIL->GetYaxis()->SetTitle("#lambda");
557 regHist(m_hSvc, pathEtaIL, profEtaIL);
558 }
559 // Phi rad profile
560 if(!getHist(m_hSvc, pathPhiRL, profPhiRL)) {
561 const std::string name(detName+"Phi_RL");
562 profPhiRL = new TProfile(name.c_str(), name.c_str(), 500, -M_PI, M_PI);
563 profPhiRL->GetXaxis()->SetTitle("#phi");
564 profPhiRL->GetYaxis()->SetTitle("%X0");
565 regHist(m_hSvc, pathPhiRL, profPhiRL);
566 }
567 // Phi int profile
568 if(!getHist(m_hSvc, pathPhiIL, profPhiIL)) {
569 const std::string name(detName+"Phi_IL");
570 profPhiIL = new TProfile(name.c_str(), name.c_str(), 500, -M_PI, M_PI);
571 profPhiIL->GetXaxis()->SetTitle("#phi");
572 profPhiIL->GetYaxis()->SetTitle("#lambda");
573 regHist(m_hSvc, pathPhiIL, profPhiIL);
574 }
575
576 m_etaMapRL[detName] = profEtaRL;
577 m_etaMapIL[detName] = profEtaIL;
578 m_phiMapRL[detName] = profPhiRL;
579 m_phiMapIL[detName] = profPhiIL;
580
581 profEtaRL->Fill(m_etaPrimary, thicks.first, 1.);
582 profEtaIL->Fill(m_etaPrimary, thicks.second, 1.);
583 profPhiRL->Fill(m_phiPrimary, thicks.first, 1.);
584 profPhiIL->Fill(m_phiPrimary, thicks.second, 1.);
585 }
586
587} // namespace G4UA
#define M_PI
Header file for AthHistogramAlgorithm.
std::vector< float > m_collected_outhitz
std::string getVolumeType(const std::string &s)
std::vector< double > m_collected_L0
std::vector< double > m_collected_X0
TProfile2D * m_rzProfRL
Rad-length profile hist in R-Z.
std::vector< float > m_collected_outhity
double m_phiPrimary
Cached phi of the current primary.
std::vector< float > m_collected_density
std::map< std::string, TProfile * > m_phiMapIL
Int-length profile hist in phi.
std::vector< float > m_collected_hitr
std::vector< std::string > m_collected_groupedmaterial
std::string getMaterialClassification(const std::string &name)
void regAndFillHist(const std::string &, const std::pair< double, double > &)
Setup one set of measurement hists for a detector name.
std::vector< float > m_collected_outhitr
std::vector< float > m_collected_outhitx
virtual void EndOfEventAction(const G4Event *) override
Called at end of G4 event to finalize measurements and fill hists.
std::map< std::string, TProfile * > m_phiMapRL
Rad-length profile hist in phi.
LengthIntegrator(const std::string &histSvcName, bool doHistos)
Constructor takes the name of the histogram service as argument.
double m_etaPrimary
Cached eta of the current primary.
std::vector< float > m_collected_hitz
void addToDetThickMap(const std::string &, double, double)
std::vector< std::string > m_collected_volumetype
TProfile2D * m_rzProfIL
Int-length profile hist in R-Z.
std::map< std::string, TProfile * > m_etaMapRL
Rad-length profile hist in eta.
std::vector< std::string > m_collected_volume
TProfile2D * getOrCreateProfile(const std::string &regName, const TString &histoname, const TString &xtitle, int nbinsx, float xmin, float xmax, const TString &ytitle, int nbinsy, float ymin, float ymax, const TString &ztitle)
this method checks if a histo is on THsvc already and caches a local pointer to it if the histo is no...
virtual void BeginOfEventAction(const G4Event *) override
Called at beginning of G4 event to cache some details about the current primary vertex and particle.
std::map< std::string, TProfile * > m_etaMapIL
Int-length profile hist in eta.
virtual void UserSteppingAction(const G4Step *) override
Called at every particle step to accumulate thickness.
ServiceHandle< ITHistSvc > m_hSvc
Handle to the histogram service.
std::map< std::string, std::pair< double, double > > m_detThickMap
Map of detector thickness measurements for current event.
std::vector< float > m_collected_hitx
std::vector< std::string > m_collected_material
std::vector< float > m_collected_hity
double xmax
Definition listroot.cxx:61
double ymin
Definition listroot.cxx:63
double xmin
Definition listroot.cxx:60
double ymax
Definition listroot.cxx:64
void * ptr(T *p)
Definition SGImplSvc.cxx:74