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