12#include "GaudiKernel/ISvcLocator.h"
13#include "GaudiKernel/Bootstrap.h"
16#include "G4PrimaryVertex.hh"
17#include "G4PrimaryParticle.hh"
19#include "G4Material.hh"
20#include "G4StepPoint.hh"
21#include "G4TouchableHistory.hh"
22#include "G4LogicalVolume.hh"
26#include "G4PhysicalConstants.hh"
27#include "G4SystemOfUnits.hh"
33#include "GaudiKernel/GaudiException.h"
39 std::mutex gHistSvcMutex;
42 template<
class HistType>
44 const std::string& histPath, HistType*& ptr){
46 if(hSvc->exists(histPath)) {
47 if(hSvc->getHist(histPath,
h).isSuccess()) {
48 if((ptr =
dynamic_cast<HistType*
>(
h)))
return true;
50 else throw GaudiException(
"Failed to getHist",
"GetHistErr", StatusCode::FAILURE);
56 template<
class HistType>
58 const std::string& histPath, HistType*& ptr)
60 if(hSvc->regHist(histPath, ptr).isFailure()) {
62 throw GaudiException(
"Failed to regHist",
"RegHistErr", StatusCode::FAILURE);
66 template<
class HistType>
68 const std::string& treeName, HistType*& ptr)
70 if(hSvc->regTree(treeName,ptr).isFailure()){
72 throw GaudiException(
"Failed to register Tree",
"RegTreeErr", StatusCode::FAILURE);
76 template<
class HistType>
78 const std::string& treeName, HistType*& ptr)
81 if(hSvc->exists(treeName) && hSvc->getTree(treeName, t).isSuccess() &&
82 (ptr =
dynamic_cast<HistType*
>(t)))
86 else throw GaudiException(
"Failed to getHist",
"GetHistErr", StatusCode::FAILURE);
102 m_hSvc(histSvcName,
"LengthIntegrator"),
108 std::lock_guard<std::mutex> lock(gHistSvcMutex);
114 const char* radName =
"/lengths/radLen/RZRadLen";
116 m_rzProfRL =
new TProfile2D(
"RZRadLen",
"RZRadLen",1000,-25000.,25000.,2000,0.,15000.);
120 const char* intName =
"/lengths/intLen/RZIntLen";
122 m_rzProfIL =
new TProfile2D(
"RZIntLen",
"RZIntLen",1000,-25000.,25000.,2000,0.,15000.);
127 m_tree =
new TTree(
"TheLarch",
"And now, the Larch" );
166 m_g4pow = G4Pow::GetInstance();
176 G4PrimaryVertex* vert =
event->GetPrimaryVertex(0);
177 G4PrimaryParticle* part = vert->GetPrimary();
178 G4ThreeVector mom = part->GetMomentum();
182 m_genEta = std::isfinite(mom.eta()) ? mom.eta() : -999;
185 m_genR = sqrt((vert->GetX0()*vert->GetX0())+(vert->GetY0()*vert->GetY0()));
200 std::lock_guard<std::mutex> lock(gHistSvcMutex);
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)){
237 if((name.find(
"Silicon") != std::string::npos) || (name.find(
"SiMetal") != std::string::npos)){
238 return "ActiveSensors";
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";
250 if(name.find(
"matEC_Hybrid") != std::string::npos)
return "StripChips";
251 else if(name.find(
"matB_HybridPCB") != std::string::npos)
return "StripChips";
253 else if(name.find(
"matSV_Endcap") != std::string::npos)
return "Services";
254 else if(name.find(
"matSV_Barrel") != std::string::npos)
return "Services";
256 else if(name.find(
"BoronNitrideEpoxy") != std::string::npos)
return "SupportStructure";
257 else if(name.find(
"SE4445") != std::string::npos)
return "SupportStructure";
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";
266 else if(name.find(
"Honeycomb10pcf") != std::string::npos)
return "SupportStructure";
267 else if(name.find(
"Honeycomb2pcf") != std::string::npos)
return "SupportStructure";
268 else if(name.find(
"Honeycomb3pcf") != std::string::npos)
return "SupportStructure";
270 else if(name.find(
"CuMetal") != std::string::npos)
return "Services";
271 else if(name.find(
"Copper") != std::string::npos)
return "Services";
273 else if(name.find(
"SiMetal") != std::string::npos)
return "ActiveSensors";
275 else if(name.find(
"Air") != std::string::npos)
return "Air";
276 else if(name.find(
"N2") != std::string::npos)
return "Air";
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";
282 else if(name.find(
"Kapton") != std::string::npos)
return "Services";
283 else if(name.find(
"matPetalBusKapton") != std::string::npos)
return "Services";
285 else if(name.find(
"T300CF") != std::string::npos)
return "Cooling";
286 else if(name.find(
"Torlon") != std::string::npos)
return "Cooling";
288 else if(name.find(
"matDCDC") != std::string::npos)
return "StripChips";
289 else if(name.find(
"matEOS") != std::string::npos)
return "StripChips";
293 if(name.find(
"CO2") != 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";
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";
310 if(name.find(
"Cooling") != std::string::npos)
return "Services";
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";
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";
327 if(name.find(
"TiMetal") != std::string::npos)
return "Titanium";
328 if(name.find(
"CuMetal") != std::string::npos)
return "Copper";
330 if(name.find(
"Alpine") != std::string::npos)
return "SupportStructure";
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";
351 if(name.find(
"PP0") != std::string::npos)
return "PP1";
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";
362 if(name.find(
"DryNitrogen") != std::string::npos)
return "Air";
364 if(name.find(
"CurlyPipeMountain") != std::string::npos)
return "SupportStructure";
365 if(name.find(
"Flange") != std::string::npos)
return "SupportStructure";
367 if(name.find(
"Pigtail") != std::string::npos)
return "Services";
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";
379 auto colsPos = s.find(
"::");
380 if (colsPos != std::string::npos)
381 type = s.substr(0, colsPos);
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();
433 const std::string& volName = lv->GetName();
434 const std::string& matName = mat->GetName();
436 double radl = mat->GetRadlen();
437 double intl = mat->GetNuclearInterLength();
438 double stepl = aStep->GetStepLength();
439 double density = mat->GetDensity()*CLHEP::cm3/CLHEP::gram;
442 double thickstepRL = radl != 0 ? stepl/radl : DBL_MAX;
443 double thickstepIL = intl != 0 ? stepl/intl : DBL_MAX;
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. );
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){
491 if(
m_hSvc->exists(regName)){
493 if(
m_hSvc->getHist(regName,histo).isSuccess())
494 return dynamic_cast<TProfile2D*
>(histo);
497 result->GetXaxis()->SetTitle(xtitle);
498 result->GetYaxis()->SetTitle(ytitle);
499 result->GetZaxis()->SetTitle(ztitle);
503 throw GaudiException(
"Registration of histogram " + regName +
" failed",
"RegHistErr", StatusCode::FAILURE);
509 G4cout<<
"ERROR something went wrong in handling of THistSvc "<<regName <<
" "<<histoname<<G4endl;
520 (*it).second.first+=thickstepRL;
521 (*it).second.second+=thickstepIL;
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) ) );
531 const std::pair<double, double>& thicks)
533 TProfile* profEtaRL =
nullptr;
534 TProfile* profEtaIL =
nullptr;
535 TProfile* profPhiRL =
nullptr;
536 TProfile* profPhiIL =
nullptr;
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";
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);
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);
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);
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);
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 ®Name, 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