13#include "GaudiKernel/ISvcLocator.h"
14#include "GaudiKernel/Bootstrap.h"
17#include "G4PrimaryVertex.hh"
18#include "G4PrimaryParticle.hh"
20#include "G4Material.hh"
21#include "G4StepPoint.hh"
22#include "G4TouchableHistory.hh"
23#include "G4LogicalVolume.hh"
27#include "G4PhysicalConstants.hh"
28#include "G4SystemOfUnits.hh"
34#include "GaudiKernel/GaudiException.h"
40 std::mutex gHistSvcMutex;
43 template<
class HistType>
45 const std::string& histPath, HistType*& ptr){
47 if(hSvc->exists(histPath)) {
48 if(hSvc->getHist(histPath,
h).isSuccess()) {
49 if((ptr =
dynamic_cast<HistType*
>(
h)))
return true;
51 else throw GaudiException(
"Failed to getHist",
"GetHistErr", StatusCode::FAILURE);
57 template<
class HistType>
59 const std::string& histPath, HistType*& ptr)
61 if(hSvc->regHist(histPath, ptr).isFailure()) {
63 throw GaudiException(
"Failed to regHist",
"RegHistErr", StatusCode::FAILURE);
67 template<
class HistType>
69 const std::string& treeName, HistType*& ptr)
71 if(hSvc->regTree(treeName,ptr).isFailure()){
73 throw GaudiException(
"Failed to register Tree",
"RegTreeErr", StatusCode::FAILURE);
77 template<
class HistType>
79 const std::string& treeName, HistType*& ptr)
82 if(hSvc->exists(treeName) && hSvc->getTree(treeName, t).isSuccess() &&
83 (ptr =
dynamic_cast<HistType*
>(t)))
87 else throw GaudiException(
"Failed to getHist",
"GetHistErr", StatusCode::FAILURE);
103 m_hSvc(histSvcName,
"LengthIntegrator"),
109 std::lock_guard<std::mutex>
lock(gHistSvcMutex);
115 const std::string radName =
"/lengths/radLen/RZRadLen";
117 m_rzProfRL =
new TProfile2D(
"RZRadLen",
"RZRadLen",1000,-25000.,25000.,2000,0.,15000.);
121 const std::string intName =
"/lengths/intLen/RZIntLen";
123 m_rzProfIL =
new TProfile2D(
"RZIntLen",
"RZIntLen",1000,-25000.,25000.,2000,0.,15000.);
128 m_tree =
new TTree(
"TheLarch",
"And now, the Larch" );
167 m_g4pow = G4Pow::GetInstance();
177 G4PrimaryVertex* vert =
event->GetPrimaryVertex(0);
178 G4PrimaryParticle* part = vert->GetPrimary();
179 G4ThreeVector mom = part->GetMomentum();
183 m_genEta = std::isfinite(mom.eta()) ? mom.eta() : -999;
186 m_genR = sqrt((vert->GetX0()*vert->GetX0())+(vert->GetY0()*vert->GetY0()));
201 std::lock_guard<std::mutex>
lock(gHistSvcMutex);
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)){
238 if((name.find(
"Silicon") != std::string::npos) || (name.find(
"SiMetal") != std::string::npos)){
239 return "ActiveSensors";
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";
251 if(name.find(
"matEC_Hybrid") != std::string::npos)
return "StripChips";
252 else if(name.find(
"matB_HybridPCB") != std::string::npos)
return "StripChips";
254 else if(name.find(
"matSV_Endcap") != std::string::npos)
return "Services";
255 else if(name.find(
"matSV_Barrel") != std::string::npos)
return "Services";
257 else if(name.find(
"BoronNitrideEpoxy") != std::string::npos)
return "SupportStructure";
258 else if(name.find(
"SE4445") != std::string::npos)
return "SupportStructure";
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";
267 else if(name.find(
"Honeycomb10pcf") != std::string::npos)
return "SupportStructure";
268 else if(name.find(
"Honeycomb2pcf") != std::string::npos)
return "SupportStructure";
269 else if(name.find(
"Honeycomb3pcf") != std::string::npos)
return "SupportStructure";
271 else if(name.find(
"CuMetal") != std::string::npos)
return "Services";
272 else if(name.find(
"Copper") != std::string::npos)
return "Services";
274 else if(name.find(
"SiMetal") != std::string::npos)
return "ActiveSensors";
276 else if(name.find(
"Air") != std::string::npos)
return "Air";
277 else if(name.find(
"N2") != std::string::npos)
return "Air";
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";
283 else if(name.find(
"Kapton") != std::string::npos)
return "Services";
284 else if(name.find(
"matPetalBusKapton") != std::string::npos)
return "Services";
286 else if(name.find(
"T300CF") != std::string::npos)
return "Cooling";
287 else if(name.find(
"Torlon") != std::string::npos)
return "Cooling";
289 else if(name.find(
"matDCDC") != std::string::npos)
return "StripChips";
290 else if(name.find(
"matEOS") != std::string::npos)
return "StripChips";
294 if(name.find(
"CO2") != 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";
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";
311 if(name.find(
"Cooling") != std::string::npos)
return "Services";
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";
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";
327 if(name.find(
"Alpine") != std::string::npos)
return "SupportStructure";
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";
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";
357 if(name.find(
"DryNitrogen") != std::string::npos)
return "Air";
359 if(name.find(
"CurlyPipeMountain") != std::string::npos)
return "SupportStructure";
360 if(name.find(
"Flange") != std::string::npos)
return "SupportStructure";
362 if(name.find(
"Pigtail") != std::string::npos)
return "Services";
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";
374 auto colsPos = s.find(
"::");
375 if (colsPos != std::string::npos)
376 type = s.substr(0, colsPos);
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();
428 const std::string& volName = lv->GetName();
429 const std::string& matName = mat->GetName();
431 double radl = mat->GetRadlen();
432 double intl = mat->GetNuclearInterLength();
433 double stepl = aStep->GetStepLength();
434 double density = mat->GetDensity()*CLHEP::cm3/CLHEP::gram;
437 double thickstepRL = radl != 0 ? stepl/radl : DBL_MAX;
438 double thickstepIL = intl != 0 ? stepl/intl : DBL_MAX;
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. );
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){
486 if(
m_hSvc->exists(regName)){
488 if(
m_hSvc->getHist(regName,histo).isSuccess())
489 return dynamic_cast<TProfile2D*
>(histo);
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);
496 if (
m_hSvc &&
m_hSvc->regHist(regName,result).isFailure()){
498 throw GaudiException(
"Registration of histogram " + regName +
" failed",
"RegHistErr", StatusCode::FAILURE);
504 G4cout<<
"ERROR something went wrong in handling of THistSvc "<<regName <<
" "<<histoname<<G4endl;
515 (*it).second.first+=thickstepRL;
516 (*it).second.second+=thickstepIL;
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) ) );
526 const std::pair<double, double>& thicks)
528 TProfile* profEtaRL =
nullptr;
529 TProfile* profEtaIL =
nullptr;
530 TProfile* profPhiRL =
nullptr;
531 TProfile* profPhiIL =
nullptr;
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";
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);
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);
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);
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);
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 ®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
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)