ATLAS Offline Software
Loading...
Searching...
No Matches
TrigEgammaMonitorBaseAlgorithm.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#include <ranges>
8#include <string_view>
9#include <vector>
10
11TrigEgammaMonitorBaseAlgorithm::TrigEgammaMonitorBaseAlgorithm( const std::string& name, ISvcLocator* pSvcLocator )
12 : AthMonitorAlgorithm(name,pSvcLocator),
13 m_trigdec("Trig::TrigDecisionTool/TrigDecisionTool"),
14 //m_matchTool("Trig::TrigEgammaMatchingToolMT/TrigEgammaMatchingToolMT")
15 m_matchTool("Trig::R3MatchingTool/TrigR3MatchingTool")
16
17{
18 declareProperty( "MatchTool" , m_matchTool );
19 declareProperty( "EmulationTool" , m_emulatorTool );
20}
21
22
24
25
26
27
29{
30 ATH_MSG_INFO("TrigEgammaMonitorBaseAlgorithm::initialize()...");
32 ATH_MSG_INFO("TrigEgammaMonitorBaseAlgorithm DONE INITIALIZING...");
33 ATH_CHECK(m_trigdec.retrieve());
34 ATH_CHECK(m_photonIsEMTool.retrieve());
35 ATH_CHECK(m_electronIsEMTool.retrieve());
36 ATH_CHECK(m_electronLHTool.retrieve());
37 ATH_CHECK(m_electronDNNTool.retrieve());
38
39 std::vector<std::string> steps = {"L1Calo","L2Calo","L2","EFCalo","EFTrack","HLT"};
40 for(const auto& step:steps)
41 m_accept.addCut(step,step);
42
43
44
45 return StatusCode::SUCCESS;
46}
47
48
49// ************************************************************************************************
50
51bool TrigEgammaMonitorBaseAlgorithm::ApplyElectronPid(const EventContext& ctx, const xAOD::Electron *eg, const std::string& pidname) const
52{
53 if (pidname == "tight"){
54 return (bool) this->m_electronIsEMTool[0]->accept(ctx,eg);
55 }
56 else if (pidname == "medium"){
57 return (bool) this->m_electronIsEMTool[1]->accept(ctx,eg);
58 }
59 else if (pidname == "loose"){
60 return (bool) this->m_electronIsEMTool[2]->accept(ctx,eg);
61 }
62 else if (pidname == "lhtight"){
63 if (!m_doEffwithDNN) return (bool) this->m_electronLHTool[0]->accept(ctx,eg);
64 else return (bool) this->m_electronDNNTool[0]->accept(ctx,eg);
65 }
66 else if (pidname == "lhmedium"){
67 if (!m_doEffwithDNN) return (bool) this->m_electronLHTool[1]->accept(ctx,eg);
68 else return (bool) this->m_electronDNNTool[1]->accept(ctx,eg);
69 }
70 else if (pidname == "lhloose"){
71 if (!m_doEffwithDNN) return (bool) this->m_electronLHTool[2]->accept(ctx,eg);
72 else return (bool) this->m_electronDNNTool[2]->accept(ctx,eg);
73 }
74 else if (pidname == "lhvloose"){
75 return (bool) this->m_electronLHTool[3]->accept(ctx,eg);
76 }
77 else if (pidname == "dnntight"){
78 if (!m_doEffwithLH) return (bool) this->m_electronDNNTool[0]->accept(ctx,eg);
79 else return (bool) this->m_electronLHTool[0]->accept(ctx,eg);
80 }
81 else if (pidname == "dnnmedium"){
82 if (!m_doEffwithLH) return (bool) this->m_electronDNNTool[1]->accept(ctx,eg);
83 else return (bool) this->m_electronLHTool[1]->accept(ctx,eg);
84 }
85 else if (pidname == "dnnloose"){
86 if (!m_doEffwithLH) return (bool) this->m_electronDNNTool[2]->accept(ctx,eg);
87 else return (bool) this->m_electronLHTool[2]->accept(ctx,eg);
88 }
89 else ATH_MSG_DEBUG("No Pid tool, continue without PID");
90 return false;
91}
92
93
94
95// ************************************************************************************************
96
97
98bool TrigEgammaMonitorBaseAlgorithm::ApplyPhotonPid(const EventContext& ctx, const xAOD::Photon *eg, const std::string& pidname) const
99{
100 if (pidname == "tight"){
101 return (bool) this->m_photonIsEMTool[0]->accept(ctx,eg);
102 }
103 else if (pidname == "medium"){
104 return (bool) this->m_photonIsEMTool[1]->accept(ctx,eg);
105 }
106 else if (pidname == "loose"){
107 return (bool) this->m_photonIsEMTool[2]->accept(ctx,eg);
108 }
109 else ATH_MSG_DEBUG("No Pid tool, continue without PID");
110 return false;
111}
112
113
114// ************************************************************************************************
115
116
117
118bool TrigEgammaMonitorBaseAlgorithm::isIsolated(const xAOD::Electron *eg, const std::string& isolation) const {
119 ATH_MSG_DEBUG("Apply Isolation " << isolation);
120 float ptcone20=0;
121 bool isoStat=eg->isolationValue(ptcone20, xAOD::Iso::ptcone20);
122 if (!isoStat) {
123 ATH_MSG_DEBUG("Electron doesn't provide isolation for ptcone20");
124 return false;
125 }
126 if (!(fabs(eg->pt()) > 0)) {
127 ATH_MSG_DEBUG("Electron pt is zero, can't calculate relative isolation");
128 return false;
129 }
130 ATH_MSG_DEBUG("ptcone20 " << ptcone20);
131 float ptcone20_rel = ptcone20/eg->pt();
132 ATH_MSG_DEBUG("Relative isolation value " << ptcone20_rel);
133 if (isolation == "loose"){
134 if (ptcone20_rel > 0.1) {
135 ATH_MSG_DEBUG("Probe failing isolation");
136 return false;
137 } else {
138 ATH_MSG_DEBUG("Probe passing isolation");
139 return true;
140 }
141 }
142 else {
143 ATH_MSG_DEBUG("No valid working point defined for " << isolation << " continue without isolation");
144 }
145 return false;
146}
147
148
149
150bool TrigEgammaMonitorBaseAlgorithm::isPrescaled(const std::string& trigger) const {
151
152 bool efprescale=false;
153 bool l1prescale=false;
154 bool prescale=false;
155 bool rerun=true; //assume rerun for l1
156 std::string l1item="";
157
158 if(trigger.starts_with( "L1" ))
159 l1item=trigger;
160 if(trigger.starts_with("HLT") || trigger.starts_with("EF")){
161 l1item = getL1Item(trigger);
162 const unsigned int bit=tdt()->isPassedBits(trigger);
163 efprescale=bit & TrigDefs::EF_prescaled;
164 rerun=bit&TrigDefs::EF_resurrected; //Rerun, only check for HLT
165 }
166
167
168 ATH_MSG_DEBUG("Checking prescale for " << trigger << " " << l1item);
169 const unsigned int l1bit=tdt()->isPassedBits(l1item);
170 bool l1_afterpre=l1bit&TrigDefs::L1_isPassedAfterPrescale;
171 bool l1_beforepre=l1bit&TrigDefs::L1_isPassedBeforePrescale;
172 l1prescale=l1_beforepre && !l1_afterpre;
173 prescale=efprescale || l1prescale;
174 ATH_MSG_DEBUG("L1 prescale " << l1item << " " << l1prescale << " before " << l1_beforepre << " after " << l1_afterpre);
175 ATH_MSG_DEBUG("EF prescale " << trigger << " " << efprescale << " Prescale " << prescale);
176 if(rerun) return false; // Rerun use the event
177 if(prescale) return true; // Prescaled, reject event
178 return false; // Not prescaled, use event
179}
180
181
182
183asg::AcceptData TrigEgammaMonitorBaseAlgorithm::setAccept(const EventContext& ctx, const TrigCompositeUtils::Decision *dec, const TrigInfo& info, const bool onlyHLT) const {
184
185 ATH_MSG_DEBUG("setAccept");
186
187 unsigned int condition=TrigDefs::includeFailedDecisions;
188
189 asg::AcceptData acceptData (&m_accept);
190
191 bool passedL1Calo=false;
192 bool passedL2Calo=false;
193 bool passedEFCalo=false;
194 bool passedL2=false;
195 bool passedEFTrk=false;
196 bool passedEF=false;
197
198 if (dec) {
199 const auto & trigger = info.trigger;
200 if (!onlyHLT){
201 // Step 1
202 passedL1Calo = match()->ancestorPassed<TrigRoiDescriptorCollection>(ctx, dec , trigger , "initialRois", condition);
203
204 if( passedL1Calo ){ // HLT item get full decision
205 // Step 2
206 passedL2Calo = match()->ancestorPassed<xAOD::TrigEMClusterContainer>(ctx, dec, trigger, match()->key("FastCalo"), condition);
207
208 if(passedL2Calo){
209
210 // Step 3
211 if(info.signature == "Electron" or info.signature == "e"){
212 std::string key = match()->key("FastElectrons");
213 if(info.lrt) key = match()->key("FastElectrons_LRT");
214 passedL2 = match()->ancestorPassed<xAOD::TrigElectronContainer>(ctx, dec, trigger, key, condition);
215 }else if(info.signature == "Photon" or info.signature == "g"){
216 passedL2 = match()->ancestorPassed<xAOD::TrigPhotonContainer>(ctx, dec, trigger, match()->key("FastPhotons"), condition);
217 }
218
219 if(passedL2){
220
221 // Step 4
222 std::string key = match()->key("PrecisionCalo_Electron");
223 if(info.signature == "Photon" or info.signature == "g") key = match()->key("PrecisionCalo_Photon");
224 if(info.lrt) key = match()->key("PrecisionCalo_LRT");
225 if(info.ion) key = match()->key("PrecisionCalo_HI");
226
227 passedEFCalo = match()->ancestorPassed<xAOD::CaloClusterContainer>(ctx, dec, trigger, key, condition);
228
229 if(passedEFCalo){
230
231 // Step 5
232 passedEFTrk=true;// Assume true for photons
233
234 // Step 6
235 if(info.signature == "Electron" or info.signature == "e"){
236 if( info.etcut || info.idperf){// etcut or idperf
237 passedEF = true; // since we dont run the preciseElectron step
238 }else{
239 std::string key = match()->key("Electrons_GSF");
240 if(info.lrt) key = match()->key("Electrons_LRT");
241 if(info.nogsf) key = match()->key("Electrons");
242 passedEF = match()->ancestorPassed<xAOD::ElectronContainer>(ctx, dec, trigger, key, condition);
243 }
244
245 }else if(info.signature == "Photon" or info.signature == "g"){
246 if (info.etcut){
247 passedEF = true; // since we dont run the precisePhoton step
248 }else{
249 passedEF = match()->ancestorPassed<xAOD::PhotonContainer>(ctx, dec, trigger, match()->key("Photons"), condition);
250 }
251 }
252 } // EFCalo
253 }// L2
254 }// L2Calo
255 }// L2Calo
256
257 }
258 else{
259 if(info.signature == "Electron" or info.signature == "e"){
260 if( info.etcut || info.idperf){// etcut or idperf
261 passedEF = true; // since we dont run the preciseElectron step
262 }else{
263 std::string key = match()->key("Electrons_GSF");
264 if(info.lrt) key = match()->key("Electrons_LRT");
265 if(info.nogsf) key = match()->key("Electrons");
266 passedEF = match()->ancestorPassed<xAOD::ElectronContainer>(ctx, dec, trigger, key, condition);
267 }
268
269 }else if(info.signature == "Photon" or info.signature == "g"){
270 if (info.etcut){
271 passedEF = true; // since we dont run the precisePhoton step
272 }else{
273 passedEF = match()->ancestorPassed<xAOD::PhotonContainer>(ctx, dec, trigger, match()->key("Photons"), condition);
274 }
275 }
276 }
277 }
278
279 acceptData.setCutResult("L1Calo",passedL1Calo);
280 acceptData.setCutResult("L2Calo",passedL2Calo);
281 acceptData.setCutResult("L2",passedL2);
282 acceptData.setCutResult("EFCalo",passedEFCalo);
283 acceptData.setCutResult("EFTrack",passedEFTrk);
284 acceptData.setCutResult("HLT",passedEF);
285 ATH_MSG_DEBUG("Accept results:");
286 ATH_MSG_DEBUG("L1: "<< passedL1Calo);
287 ATH_MSG_DEBUG("L2Calo: " << passedL2Calo);
288 ATH_MSG_DEBUG("L2: "<< passedL2);
289 ATH_MSG_DEBUG("EFCalo: "<< passedEFCalo);
290 ATH_MSG_DEBUG("HLT: "<<passedEF);
291
292 return acceptData;
293}
294
295
296
297
298float TrigEgammaMonitorBaseAlgorithm::dR(const float eta1, const float phi1, const float eta2, const float phi2) const {
299 float deta = fabs(eta1 - eta2);
300 float dphi = fabs(phi1 - phi2) < TMath::Pi() ? fabs(phi1 - phi2) : 2*TMath:: \
301 Pi() - fabs(phi1 - phi2);
302 return sqrt(deta*deta + dphi*dphi);
303}
304
305
306
307
309 if(eg && (eg->caloCluster())){
310 const xAOD::CaloCluster* cluster = eg->caloCluster();
311 return fabs(cluster->etaBE(2));
312 }
313 else return -99.;
314}
315
316
318 if(eg && (eg->caloCluster()) && (eg->trackParticle())){
319 const xAOD::TrackParticle *trk=eg->trackParticle();
320 const xAOD::CaloCluster *clus=eg->caloCluster();
321 float eta = fabs(trk->eta());
322 return clus->e()/cosh(eta);
323 }
324 else return -99.;
325}
326
327
329 if(eg && (eg->caloCluster())){
330 const xAOD::CaloCluster* cluster = eg->caloCluster();
331 float eta2 = fabs(cluster->etaBE(2));
332 return cluster->e()/cosh(eta2);
333 }
334 else return -99.;
335}
336
337
339 if(eg){
340 float emax2=0.;
342 float emax=0.;
344 float den = emax+emax2;
345
346 if (fabs(den) < 1e-6) return -99.;
347
348 float val = (emax-emax2)/(den);
349 return val;
350 }
351 else return -99.;
352}
353
354
356 if(eg && eg->trackParticle()){
357 uint8_t trtHits = 0;
359 uint8_t trtHTHits = 0;
361 if (fabs(trtHits) < 1e-6) {
362 return -99.;
363 } else {
364 //coverity[DIVIDE_BY_ZERO:FALSE]
365 return ( (double)trtHTHits / (double)trtHits );
366 }
367 }
368 else return -99.;
369}
370
371
373 const xAOD::TrackParticle* t = eg->trackParticle();
374 float d0sigma=0.;
375 if (t)
376 {
377 float vard0 = t->definingParametersCovMatrix()(0,0);
378 if (vard0 > 0) {
379 d0sigma=sqrtf(vard0);
380 }
381 else return -99.;
382 return d0sigma;
383 }
384 else return -99.;
385}
386
387
389 const xAOD::TrackParticle* t = eg->trackParticle();
390 float d0sigma=0.;
391 if (t)
392 {
393 float vard0 = t->definingParametersCovMatrix()(0,0);
394 if (vard0 > 0) {
395 d0sigma=sqrtf(vard0);
396 }
397 else return -99.;
398
399 if (fabs(d0sigma) < 1e-6) return -99.;
400 return t->d0()/d0sigma;
401 }
402 else return -99.;
403}
404
405
407 if(eg && (eg->caloCluster())){
408 const xAOD::CaloCluster* cluster = eg->caloCluster();
409 return cluster->energyBE(0);
410 }
411 else return 0;
412}
413
414
416 if(eg && (eg->caloCluster())){
417 const xAOD::CaloCluster* cluster = eg->caloCluster();
418 return cluster->energyBE(1);
419 }
420 else return 0.;
421}
422
423
425 if(eg && (eg->caloCluster())){
426 const xAOD::CaloCluster* cluster = eg->caloCluster();
427 return cluster->energyBE(2);
428 }
429 else return 0.;
430}
431
432
434 if(eg && (eg->caloCluster())){
435 const xAOD::CaloCluster* cluster = eg->caloCluster();
436 return cluster->energyBE(3);
437 }
438 else return 0.;
439}
440
441
443 if(eg && (eg->caloCluster())){
444 const xAOD::CaloCluster* cluster = eg->caloCluster();
445 float ebe1 = cluster->energyBE(1);
446 float ebe2 = cluster->energyBE(2);
447 float ebe3 = cluster->energyBE(3);
448 return (ebe1+ebe2+ebe3);
449 }
450 else return 0.;
451}
452
453
455 if(eg && (eg->caloCluster())){
456 const xAOD::CaloCluster* cluster = eg->caloCluster();
457 float ebe0 = cluster->energyBE(0);
458 float ebe1 = cluster->energyBE(1);
459 float ebe2 = cluster->energyBE(2);
460 float ebe3 = cluster->energyBE(3);
461 float eacc = ebe1+ebe2+ebe3;
462 if(eacc==0.) return 0.;
463 return (ebe0/eacc);
464 }
465 else return 0.;
466}
467
468
470#define GETTER(_name_) float TrigEgammaMonitorBaseAlgorithm::getShowerShape_##_name_(const xAOD::Egamma* eg) const \
471{ float val{-99}; \
472 eg->showerShapeValue(val,xAOD::EgammaParameters::_name_); \
473 return val; }
474 GETTER(e011)
475 GETTER(e132)
476 GETTER(e237)
477 GETTER(e277)
478 GETTER(ethad)
479 GETTER(ethad1)
480 GETTER(weta1)
481 GETTER(weta2)
482 GETTER(f1)
483 GETTER(e2tsts1)
484 GETTER(emins1)
485 GETTER(emaxs1)
486 GETTER(wtots1)
487 GETTER(fracs1)
488 GETTER(Reta)
489 GETTER(Rphi)
490 GETTER(f3)
491 GETTER(f3core)
492 GETTER(Eratio)
493 GETTER(Rhad)
494 GETTER(Rhad1)
495 GETTER(DeltaE)
496#undef GETTER
497
498
499// GETTER for Isolation monitoring
500#define GETTER(_name_) float TrigEgammaMonitorBaseAlgorithm::getIsolation_##_name_(const xAOD::Electron* eg) const\
501{ float val{-99}; \
502 eg->isolationValue(val,xAOD::Iso::_name_); \
503 return val; }
504 GETTER(ptcone20)
505 GETTER(ptcone30)
506 GETTER(ptcone40)
507 GETTER(ptvarcone20)
508 GETTER(ptvarcone30)
509 GETTER(ptvarcone40)
510#undef GETTER
511
512
513#define GETTER(_name_) float TrigEgammaMonitorBaseAlgorithm::getIsolation_##_name_(const xAOD::Egamma* eg) const\
514{ float val{-99}; \
515 eg->isolationValue(val,xAOD::Iso::_name_); \
516 return val; }
517 GETTER(ptcone20)
518 GETTER(etcone20)
519 GETTER(etcone30)
520 GETTER(etcone40)
521 GETTER(topoetcone20)
522 GETTER(topoetcone30)
523 GETTER(topoetcone40)
524#undef GETTER
525
526
527// GETTERs for CaloCluster monitoring
528#define GETTER(_name_) float TrigEgammaMonitorBaseAlgorithm::getCluster_##_name_(const xAOD::Egamma* eg) const\
529{ if(eg && eg->caloCluster()) \
530 return eg->caloCluster()->_name_(); \
531 else return -99.;}
532 GETTER(et)
533 GETTER(phi)
534 GETTER(eta)
535#undef GETTER
536
537
538// GETTERs for Track monitoring
539#define GETTER(_name_) float TrigEgammaMonitorBaseAlgorithm::getTrack_##_name_(const xAOD::Electron* eg) const\
540{ if(eg && eg->trackParticle()) \
541 return eg->trackParticle()->_name_(); \
542 else return -99.;}
543 GETTER(pt)
544 GETTER(phi)
545 GETTER(eta)
546 GETTER(d0)
547 GETTER(z0)
548#undef GETTER
549
550
551// GETTERs for Track details monitoring
552#define GETTER(_name_) float TrigEgammaMonitorBaseAlgorithm::getTrackSummary_##_name_(const xAOD::Electron* eg) const \
553{ uint8_t val_uint8{0}; \
554 if(eg){ \
555 eg->trackParticleSummaryValue(val_uint8,xAOD::_name_); \
556 return val_uint8; } \
557 else return -99; }
558 GETTER(numberOfInnermostPixelLayerHits)
559 GETTER(numberOfInnermostPixelLayerOutliers)
560 GETTER(numberOfPixelHits)
561 GETTER(numberOfPixelOutliers)
562 GETTER(numberOfSCTHits)
563 GETTER(numberOfSCTOutliers)
564 GETTER(numberOfTRTHits)
565 GETTER(numberOfTRTHighThresholdHits)
566 GETTER(numberOfTRTHighThresholdOutliers)
567 GETTER(numberOfTRTOutliers)
568 GETTER(expectInnermostPixelLayerHit)
569 GETTER(numberOfPixelDeadSensors)
570 GETTER(numberOfSCTDeadSensors)
571 GETTER(numberOfTRTXenonHits)
572#undef GETTER
573
574
575#define GETTER(_name_) float TrigEgammaMonitorBaseAlgorithm::getTrackSummaryFloat_##_name_(const xAOD::Electron* eg) const\
576{ float val_float{0}; \
577 if(eg){ \
578 eg->trackParticleSummaryValue(val_float,xAOD::_name_); \
579 return val_float; } \
580 else return -99; }
581 GETTER(eProbabilityComb)
582 GETTER(eProbabilityHT)
583 GETTER(pixeldEdx)
584#undef GETTER
585
586
587// GETTERs for Calo-Track monitoring
588#define GETTER(_name_) float TrigEgammaMonitorBaseAlgorithm::getCaloTrackMatch_##_name_(const xAOD::Electron* eg) const\
589{ float val={-99.}; \
590 if(eg){ \
591 eg->trackCaloMatchValue(val,xAOD::EgammaParameters::_name_);} \
592 return val; }
593 GETTER(deltaEta0)
594 GETTER(deltaPhi0)
595 GETTER(deltaPhiRescaled0)
596 GETTER(deltaEta1)
597 GETTER(deltaPhi1)
598 GETTER(deltaPhiRescaled1)
599 GETTER(deltaEta2)
600 GETTER(deltaPhi2)
601 GETTER(deltaPhiRescaled2)
602 GETTER(deltaEta3)
603 GETTER(deltaPhi3)
604 GETTER(deltaPhiRescaled3)
605#undef GETTER
606
607
608
609TrigInfo TrigEgammaMonitorBaseAlgorithm::getTrigInfo(const std::string& trigger) const{
610 return m_trigInfo.at(trigger);
611}
612
614 return m_trigInfoR3.at(trigger);
615}
616
617
618
619// This is not const function and can not be used in execute mode (not thread safe)
620// adds entry in TrigInfo map to retrieve later via trigger name
621void TrigEgammaMonitorBaseAlgorithm::setTrigInfo(const std::string& trigger){
622
623 /********************************************
624 // Trigger Information struct
625 typedef struct _triginfo
626 {
627 // L1 information
628 bool L1Legacy;
629 std::string L1Threshold; //EM22VHI
630 // HLT information
631 std::string trigger; //Trigger Name
632 std::string signature; //Electron or Photon
633 float etthr; // HLT Et threshold
634 // if trigger is etcut OR idperf, pidname should be default (usually lhloose)
635 std::string pidname; // Offline loose, medium, tight, etc...
636 // extra HLT information
637 bool idperf; // Performance chain
638 bool etcut; // Et cut only chain
639 bool nogsf; // chain without gsf reconstruction
640 bool lrt; // LRT chain
641 bool ion; // Heavy Ion chain
642 std::string isolation;
643 bool isolated;
644 } TrigInfo;
645 *******************************************/
646
647 std::map<std::string, std::string> pidMap = { {"vloose" , "loose" },
648 {"loose" , "loose" },
649 {"medium" , "medium" },
650 {"tight" , "tight" },
651 {"loose1" , "loose" },
652 {"medium1" , "medium" },
653 {"tight1" , "tight" },
654 {"lhvloose" , "lhvloose" },
655 {"lhloose" , "lhloose" },
656 {"lhmedium" , "lhmedium" },
657 {"lhtight" , "lhtight" },
658 {"dnnloose" , "dnnloose" },
659 {"dnnmedium", "dnnmedium"},
660 {"dnntight" , "dnntight" },
661 {"nopid" , "nopid" } };
662
663 std::vector<std::string> isoNames = {"ivarloose","ivarmedium","ivartight","icaloloose","icalomedium","icalotight"};
664
665 bool nogsf = false;
666 bool lrt = false;
667 bool ion = false;
668 bool etcut = false;
669 bool idperf = false;
670 bool isolated = false;
671
672 std::string isolation="";
673 bool l1legacy=true;
674
675 std::string hltinfo=trigger;
676 std::string signature = "";
677 float threshold = 0;
678 // HLT_e/gXX_(pidname/etcut/idperf)_*_L1EMXX to e/gXX_(pidname/etcut/idperf)_*_L1EMXX
679 if(hltinfo.starts_with("HLT_")) hltinfo.erase(0,4);
680 if(hltinfo.contains("EF")) hltinfo.erase(0,3);
681 std::vector<std::string> parts;
682 for (auto&& part : hltinfo | std::views::split('_')) parts.emplace_back(part.begin(), part.end());
683 std::string pidname;
684
685 // e/gXX_(pidname/etcut/idperf)_*_L1EMXX
686 if(parts.at(0).contains("e")) {
687 signature = "Electron";
689 }else if(parts.at(0).contains("g")) {
690 signature = "Photon";
691 pidname = m_defaultProbePidPhoton;
692 }else {
693 ATH_MSG_ERROR("Cannot set trigger type from name");
694 }
695
696 ATH_MSG_DEBUG(parts.at(1));
697 if(parts.at(1) == "idperf"){
698 ATH_MSG_DEBUG("This is idperf");
699 idperf=true;
700 }
701 else if( parts.at(1)== "etcut"){
702 ATH_MSG_DEBUG("This is etcut");
703 etcut=true;
704 }
705 else { // remap online pidname to offline pidname
706 ATH_MSG_DEBUG("This is nominal");
707 if (pidMap.count(parts.at(1)) != 1) {
708 ATH_MSG_ERROR("Unknown trigger type: " << parts.at(1) << " (" << trigger << ")");
709 }
710 pidname = pidMap.at(parts.at(1));
711 }
712
713
714 // extra information
715 nogsf = trigger.contains("nogsf");
716 lrt = trigger.contains("lrt");
717 ion = trigger.contains("ion");
718
719 for(auto& iso : isoNames){
720 if(trigger.contains(iso)){
721 isolation=iso; isolated=true; break;
722 }
723 }
724
725 // Get the threshold
726 std::string str_thr = parts.at(0);
727 str_thr.erase( 0, 1);
728 threshold = atof(str_thr.c_str());
729
730 // L1EMXX
731 std::string l1seed = getL1Item(trigger);
732 l1legacy = !l1seed.contains("eEM");
733
734
735 ATH_MSG_DEBUG("=================== Chain Parser =======================");
736 ATH_MSG_DEBUG( "trigger : " << trigger );
737 ATH_MSG_DEBUG( "threshold : " << threshold);
738 ATH_MSG_DEBUG( "Pidname : " << pidname );
739 ATH_MSG_DEBUG( "signature : " << signature);
740 ATH_MSG_DEBUG( "etcut : " << (etcut?"Yes":"No"));
741 ATH_MSG_DEBUG( "idperf : " << (idperf?"Yes":"No"));
742 ATH_MSG_DEBUG( "nogsf : " << (nogsf?"Yes":"No"));
743 ATH_MSG_DEBUG( "lrt : " << (lrt?"Yes":"No"));
744 ATH_MSG_DEBUG( "HeavyIon : " << (ion?"Yes":"No"));
745 ATH_MSG_DEBUG( "Isolation : " << isolation);
746 ATH_MSG_DEBUG( "Isolated : " << (isolated?"Yes":"No"));
747 ATH_MSG_DEBUG( "L1Seed : " << l1seed << " (Is Legacy? " << (l1legacy?"Yes":"No") << ")");
748 ATH_MSG_DEBUG("========================================================");
749
750 TrigInfo info{l1legacy,std::move(l1seed),trigger,std::move(signature),threshold,
751 std::move(pidname),idperf,etcut,nogsf,lrt,ion,std::move(isolation),isolated};
752 m_trigInfo[trigger] = std::move(info);
753
754}
755
756std::vector<ChainNameParser::LegInfo>
757TrigEgammaMonitorBaseAlgorithm::getProbeTriggerLeg(const std::string& triggerName) const
758{
759 std::vector<ChainNameParser::LegInfo> result;
760
761 for (const ChainNameParser::LegInfo& legInfo : ChainNameParser::HLTChainInfo(triggerName))
762 {
763 ATH_MSG_DEBUG("Full trigger name = " << triggerName
764 << ", multiplicity = " << legInfo.multiplicity
765 << ", signature = " << legInfo.signature
766 << ", threshold = " << legInfo.threshold
767 << ", leg parts = "<< legInfo.legParts); //Gives the pidname
768
769 result.push_back(legInfo);
770 }
771
772 return result;
773}
774
775
776// This is not const function and can not be used in execute mode (not thread safe)
777// adds entry in TrigInfo map to retrieve later via trigger name
778void TrigEgammaMonitorBaseAlgorithm::setTrigInfoR3(const std::string& trigger){
779
780 ATH_MSG_DEBUG("Entering function");
781 /********************************************
782 // Trigger Information struct
783 typedef struct _triginfo
784 {
785 // L1 information
786 bool L1Legacy; (done)
787 std::string L1Threshold; //EM22VHI
788 // HLT information
789 std::string trigger; //Trigger Name (done)
790 std::string signature; //Electron or Photon (done)
791 float etthr; // HLT Et threshold (done)
792 // if trigger is etcut OR idperf, pidname should be default (usually lhloose)
793 std::string pidname; // Offline loose, medium, tight, etc...(done)
794 // extra HLT information
795 bool idperf; // Performance chain
796 bool etcut; // Et cut only chain
797 bool nogsf; // chain without gsf reconstruction
798 bool lrt; // LRT chain
799 bool ion; // Heavy Ion chain
800 std::string isolation;
801 bool isolated;
802 } TrigInfo;
803 *******************************************/
804
805 std::map<std::string, std::string> pidMap = { {"vloose" , "loose" },
806 {"loose" , "loose" },
807 {"medium" , "medium" },
808 {"tight" , "tight" },
809 {"loose1" , "loose" },
810 {"medium1" , "medium" },
811 {"tight1" , "tight" },
812 {"lhvloose" , "lhvloose" },
813 {"lhloose" , "lhloose" },
814 {"lhmedium" , "lhmedium" },
815 {"lhtight" , "lhtight" },
816 {"dnnloose" , "dnnloose" },
817 {"dnnmedium", "dnnmedium"},
818 {"dnntight" , "dnntight" },
819 {"nopid" , "nopid" } };
820
821 //Get information about each signature of the trigger
822 //Each signature counts as a leg
823 //HLT_2e17_medium_g22_medium_probe_L12eEM24H
824 //Leg 1 : 2e17_medium
825 //Leg2: g22_medium_probe
826
827 float threshold = 0;
828 std::string signature = "";
829 std::string etthr = "";
830 std::string pidname = "";
831
832
833 auto LegParts = getProbeTriggerLeg(trigger);
834
835 //Get the probe leg
836 if(!LegParts.empty())
837 {
838 //Looping over signatures
839 for( const auto& leg: LegParts)
840 {
841 //Grab the requested signature
842 if (leg.signature != "g") continue;
843
844 //Building the probe trigger name
845 signature = leg.signature;
846 if (signature == "g"){
847 signature = "Photon";
848 }
849 threshold = leg.threshold;
850 //threshold = std::to_string(leg.threshold);
851 pidname = leg.legParts[0];
852 }
853 }
854
855
856 bool l1legacy=true;
857 // L1EMXX
858 std::string l1seed = getL1Item(trigger);
859 l1legacy = !l1seed.contains("eEM");
860
861
862 std::vector<std::string> isoNames = {"ivarloose","ivarmedium","ivartight","icaloloose","icalomedium","icalotight"};
863
864 bool nogsf = false;
865 bool lrt = false;
866 bool ion = false;
867 bool etcut = false;
868 bool idperf = false;
869 bool isolated = false;
870
871 std::string isolation="";
872
873 // extra information
874 nogsf = trigger.contains("nogsf");
875 lrt = trigger.contains("lrt");
876 ion = trigger.contains("ion");
877
878 for(auto& iso : isoNames){
879 if(trigger.contains(iso)){
880 isolation=iso; isolated=true; break;
881 }
882 }
883 std::vector<std::string> parts;
884 for (auto&& part : trigger | std::views::split('_')) parts.emplace_back(part.begin(), part.end());
885 if(trigger.contains("idperf")){
886 ATH_MSG_DEBUG("This is idperf");
887 idperf=true;
888 }
889 else if(trigger.contains("etcut")){
890 ATH_MSG_DEBUG("This is etcut");
891 etcut=true;
892 }
893 else { // remap online pidname to offline pidname
894 //ATH_MSG_DEBUG("Problem: 3");
895 // ATH_MSG_DEBUG("This is nominal");
896 // if (pidMap.count(parts.at(4)) != 4) {
897 // ATH_MSG_DEBUG("Unknown trigger type: " << parts.at(4) << " (" << trigger << ")");
898 // }
899 // pidname = pidMap.at(parts.at(4));
900 }
901
902
903 ATH_MSG_DEBUG("Problem: 5");
904 ATH_MSG_DEBUG("=================== R3 Chain Parser R3 =======================");
905 ATH_MSG_DEBUG( "trigger : " << trigger );
906 ATH_MSG_DEBUG( "threshold : " << threshold);
907 ATH_MSG_DEBUG( "Pidname : " << pidname );
908 ATH_MSG_DEBUG( "signature : " << signature);
909 ATH_MSG_DEBUG( "etcut : " << (etcut?"Yes":"No"));
910 ATH_MSG_DEBUG( "idperf : " << (idperf?"Yes":"No"));
911 ATH_MSG_DEBUG( "nogsf : " << (nogsf?"Yes":"No"));
912 ATH_MSG_DEBUG( "lrt : " << (lrt?"Yes":"No"));
913 ATH_MSG_DEBUG( "HeavyIon : " << (ion?"Yes":"No"));
914 ATH_MSG_DEBUG( "Isolation : " << isolation);
915 ATH_MSG_DEBUG( "Isolated : " << (isolated?"Yes":"No"));
916 ATH_MSG_DEBUG( "L1Seed : " << l1seed << " (Is Legacy? " << (l1legacy?"Yes":"No") << ")");
917 ATH_MSG_DEBUG("========================================================");
918
919 TrigInfo info{l1legacy,std::move(l1seed),trigger,std::move(signature),threshold,std::move(pidname),idperf,etcut,nogsf,lrt,ion,std::move(isolation),isolated};
920 m_trigInfoR3[trigger] = std::move(info);
921
922}
923
924
925// For Run-3, all triggers must have the L1 seed in name (last part)
926std::string TrigEgammaMonitorBaseAlgorithm::getL1Item(const std::string& trigger) const{
927 const auto pos = trigger.rfind('_');
928 return pos == std::string::npos ? trigger : trigger.substr(pos + 1);
929}
930
931
933 return m_trigdec->ExperimentalAndExpertMethods().isHLTTruncated();
934}
935
936
937
938
940
941// Define the parser
942#include "Gaudi/Parsers/Factory.h"
943
944namespace Gaudi
945{
946 namespace Parsers
947 {
948 // Parse function... nothing special, but it must be done explicitely.
949 StatusCode parse( VecDict_t& result, const std::string& input ) { return parse_( result, input ); }
950 }
951}
952
953// We also need to be able to print an object of our type as a string that both
954// Python and our parser can understand,
955#include "GaudiKernel/ToStream.h"
956namespace std
957{
958 // This is an example valid for any mapping type.
959 ostream& operator<<( ostream& s, const Gaudi::Parsers::VecDict_t& vecDict )
960 {
961 s << '{';
962 for ( const auto& dict : vecDict ) {
963 Gaudi::Utils::toStream( dict, s );
964 }
965 s << '}';
966 return s;
967 }
968}
969
Scalar eta() const
pseudorapidity method
Scalar phi() const
phi method
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_DEBUG(x,...)
#define ATH_MSG_ERROR(x,...)
#define ATH_MSG_INFO(x,...)
#define GETTER(_name_)
Macros for plotting.
Gaudi::Details::PropertyBase & declareProperty(Gaudi::Property< T, V, H > &t)
virtual StatusCode initialize() override
initialize
AthMonitorAlgorithm(const std::string &name, ISvcLocator *pSvcLocator)
Constructor.
Helper class that provides access to information about individual legs.
bool ApplyElectronPid(const EventContext &ctx, const xAOD::Electron *eg, const std::string &) const
Get offline electron decision.
float getEnergyBE2(const xAOD::Egamma *eg) const
ToolHandleArray< IAsgElectronLikelihoodTool > m_electronLHTool
Offline LH Selectors.
float getEnergyBE3(const xAOD::Egamma *eg) const
float getSigmaD0(const xAOD::Electron *eg) const
std::map< std::string, TrigInfo > m_trigInfo
creates map of trigger name and TrigInfo struct
float getEtCluster37(const xAOD::Egamma *eg) const
TrigEgammaMonitorBaseAlgorithm(const std::string &name, ISvcLocator *pSvcLocator)
const ToolHandle< TrigEgammaMatchingToolMT > & match() const
Get the e/g match tool.
Gaudi::Property< std::string > m_defaultProbePidPhoton
default probe pid for photon trigitems that don't have pid in their name
float dR(const float, const float, const float, const float) const
Get delta R.
float getEnergyBE1(const xAOD::Egamma *eg) const
float getDEmaxs1(const xAOD::Egamma *eg) const
float rTRT(const xAOD::Electron *eg) const
ToolHandle< TrigEgammaMatchingToolMT > m_matchTool
const ToolHandle< Trig::TrigDecisionTool > & tdt() const
Get the TDT.
float getE0Eaccordion(const xAOD::Egamma *eg) const
Gaudi::Property< std::string > m_defaultProbePidElectron
default probe pid for electron trigitems that don't have pid in their name
ToolHandleArray< IAsgPhotonIsEMSelector > m_photonIsEMTool
Offline isEM Photon Selectors.
ToolHandle< Trig::TrigDecisionTool > m_trigdec
Trigger decision tool.
float getEt(const xAOD::Electron *eg) const
asg::AcceptData setAccept(const EventContext &ctx, const TrigCompositeUtils::Decision *, const TrigInfo &, const bool) const
Set the accept object for all trigger levels.
ToolHandleArray< IAsgElectronIsEMSelector > m_electronIsEMTool
Offline isEM Selectors.
bool isPrescaled(const std::string &) const
Check if the event is prescaled.
std::map< std::string, TrigInfo > m_trigInfoR3
virtual StatusCode initialize() override
initialize
TrigInfo getTrigInfo(const std::string &) const
Get the trigger info parsed from the chain name (only single lepton triggers).
bool isIsolated(const xAOD::Electron *, const std::string &) const
Check if electron fulfils isolation criteria.
void setTrigInfo(const std::string &)
Set the trigger info parsed from the chain name.
float getD0sig(const xAOD::Electron *eg) const
float getEta2(const xAOD::Egamma *eg) const
Features helper.
bool ApplyPhotonPid(const EventContext &ctx, const xAOD::Photon *eg, const std::string &) const
Get offline electron decision.
float getEaccordion(const xAOD::Egamma *eg) const
std::string getL1Item(const std::string &trigger) const
Creates static map to return L1 item from trigger name.
ToolHandle< Trig::TrigEgammaEmulationToolMT > m_emulatorTool
TrigInfo getTrigInfoR3(const std::string &) const
float getEnergyBE0(const xAOD::Egamma *eg) const
std::vector< ChainNameParser::LegInfo > getProbeTriggerLeg(const std::string &triggerName) const
ToolHandleArray< IAsgElectronLikelihoodTool > m_electronDNNTool
Offline DNN Selectors.
void setCutResult(const std::string &cutName, bool cutResult)
Set the result of a cut, based on the cut name (safer).
Definition AcceptData.h:135
virtual double e() const
The total energy of the particle.
float energyBE(const unsigned layer) const
Get the energy in one layer of the EM Calo.
float etaBE(const unsigned layer) const
Get the eta in one layer of the EM Calo.
virtual double pt() const override final
The transverse momentum ( ) of the particle.
Definition Egamma_v1.cxx:66
bool showerShapeValue(float &value, const EgammaParameters::ShowerShapeType information) const
Accessor for ShowerShape values.
bool isolationValue(float &value, const Iso::IsolationType information) const
old Accessor for Isolation values.
Definition Egamma_v1.h:251
const xAOD::CaloCluster * caloCluster(size_t index=0) const
Pointer to the xAOD::CaloCluster/s that define the electron candidate.
const xAOD::TrackParticle * trackParticle(size_t index=0) const
Pointer to the xAOD::TrackParticle/s that match the electron candidate.
bool trackParticleSummaryValue(uint8_t &value, const SummaryType information, int index=0) const
Accessor to the matching track(s) float information (index = 0 is the best match) If 'information' is...
virtual double eta() const override final
The pseudorapidity ( ) of the particle.
std::vector< Dict_t > VecDict_t
StatusCode parse(std::tuple< Tup... > &tup, const Gaudi::Parsers::InputData &input)
std::ostream & toStream(const SG::VarHandleKeyArray &v, std::ostream &o)
Gaudi function used to convert a property to a string.
=============================================================================
xAOD::TrigComposite Decision
static const unsigned int includeFailedDecisions
Run3 synonym of alsoDeactivateTEs.
STL namespace.
ostream & operator<<(ostream &s, const SG::VarHandleKey &m)
@ emaxs1
energy of strip with maximal energy deposit
@ e2tsts1
energy of the cell corresponding to second energy maximum in the first sampling
@ ptcone20
Track isolation.
PhotonContainer_v1 PhotonContainer
Definition of the current "photon container version".
TrigElectronContainer_v1 TrigElectronContainer
Declare the latest version of the container.
ElectronContainer_v1 ElectronContainer
Definition of the current "electron container version".
CaloCluster_v1 CaloCluster
Define the latest version of the calorimeter cluster class.
TrigEMClusterContainer_v1 TrigEMClusterContainer
Define the latest version of the trigger EM cluster container.
TrigPhotonContainer_v1 TrigPhotonContainer
Declare the latest version of the container.
TrackParticle_v1 TrackParticle
Reference the current persistent version:
Egamma_v1 Egamma
Definition of the current "egamma version".
Definition Egamma.h:17
Photon_v1 Photon
Definition of the current "egamma version".
Definition Photon.h:17
CaloClusterContainer_v1 CaloClusterContainer
Define the latest version of the calorimeter cluster container.
@ numberOfTRTHits
number of TRT hits [unit8_t].
@ numberOfTRTHighThresholdHits
number of TRT hits which pass the high threshold (only xenon counted) [unit8_t].
Electron_v1 Electron
Definition of the current "egamma version".
Definition Electron.h:17
Struct containing information on each leg of a chain.
Extra patterns decribing particle interation process.