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")){
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 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 }
364 else{
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.contains("HLT")) hltinfo.erase(0,4);
680 std::vector<std::string> parts;
681 for (auto&& part : hltinfo | std::views::split('_')) parts.emplace_back(part.begin(), part.end());
682 std::string pidname;
683
684 // e/gXX_(pidname/etcut/idperf)_*_L1EMXX
685 if(parts.at(0).contains("e")) {
686 signature = "Electron";
688 }else if(parts.at(0).contains("g")) {
689 signature = "Photon";
690 pidname = m_defaultProbePidPhoton;
691 }else {
692 ATH_MSG_ERROR("Cannot set trigger type from name");
693 }
694
695 ATH_MSG_DEBUG(parts.at(1));
696 if(parts.at(1) == "idperf"){
697 ATH_MSG_DEBUG("This is idperf");
698 idperf=true;
699 }
700 else if( parts.at(1)== "etcut"){
701 ATH_MSG_DEBUG("This is etcut");
702 etcut=true;
703 }
704 else { // remap online pidname to offline pidname
705 ATH_MSG_DEBUG("This is nominal");
706 if (pidMap.count(parts.at(1)) != 1) {
707 ATH_MSG_ERROR("Unknown trigger type: " << parts.at(1) << " (" << trigger << ")");
708 }
709 pidname = pidMap.at(parts.at(1));
710 }
711
712
713 // extra information
714 nogsf = trigger.contains("nogsf");
715 lrt = trigger.contains("lrt");
716 ion = trigger.contains("ion");
717
718 for(auto& iso : isoNames){
719 if(trigger.contains(iso)){
720 isolation=iso; isolated=true; break;
721 }
722 }
723
724 // Get the threshold
725 std::string str_thr = parts.at(0);
726 str_thr.erase( 0, 1);
727 threshold = atof(str_thr.c_str());
728
729 // L1EMXX
730 std::string l1seed = getL1Item(trigger);
731 l1legacy = !l1seed.contains("eEM");
732
733
734 ATH_MSG_DEBUG("=================== Chain Parser =======================");
735 ATH_MSG_DEBUG( "trigger : " << trigger );
736 ATH_MSG_DEBUG( "threshold : " << threshold);
737 ATH_MSG_DEBUG( "Pidname : " << pidname );
738 ATH_MSG_DEBUG( "signature : " << signature);
739 ATH_MSG_DEBUG( "etcut : " << (etcut?"Yes":"No"));
740 ATH_MSG_DEBUG( "idperf : " << (idperf?"Yes":"No"));
741 ATH_MSG_DEBUG( "nogsf : " << (nogsf?"Yes":"No"));
742 ATH_MSG_DEBUG( "lrt : " << (lrt?"Yes":"No"));
743 ATH_MSG_DEBUG( "HeavyIon : " << (ion?"Yes":"No"));
744 ATH_MSG_DEBUG( "Isolation : " << isolation);
745 ATH_MSG_DEBUG( "Isolated : " << (isolated?"Yes":"No"));
746 ATH_MSG_DEBUG( "L1Seed : " << l1seed << " (Is Legacy? " << (l1legacy?"Yes":"No") << ")");
747 ATH_MSG_DEBUG("========================================================");
748
749 TrigInfo info{l1legacy,l1seed,trigger,signature,threshold,pidname,idperf,etcut,nogsf,lrt,ion,isolation,isolated};
750 m_trigInfo[trigger] = info;
751
752}
753
754std::vector<ChainNameParser::LegInfo>
755TrigEgammaMonitorBaseAlgorithm::getProbeTriggerLeg(const std::string& triggerName) const
756{
757 std::vector<ChainNameParser::LegInfo> result;
758
759 for (const ChainNameParser::LegInfo& legInfo : ChainNameParser::HLTChainInfo(triggerName))
760 {
761 ATH_MSG_DEBUG("Full trigger name = " << triggerName
762 << ", multiplicity = " << legInfo.multiplicity
763 << ", signature = " << legInfo.signature
764 << ", threshold = " << legInfo.threshold
765 << ", leg parts = "<< legInfo.legParts); //Gives the pidname
766
767 result.push_back(legInfo);
768 }
769
770 return result;
771}
772
773
774// This is not const function and can not be used in execute mode (not thread safe)
775// adds entry in TrigInfo map to retrieve later via trigger name
776void TrigEgammaMonitorBaseAlgorithm::setTrigInfoR3(const std::string& trigger){
777
778 ATH_MSG_DEBUG("Entering function");
779 /********************************************
780 // Trigger Information struct
781 typedef struct _triginfo
782 {
783 // L1 information
784 bool L1Legacy; (done)
785 std::string L1Threshold; //EM22VHI
786 // HLT information
787 std::string trigger; //Trigger Name (done)
788 std::string signature; //Electron or Photon (done)
789 float etthr; // HLT Et threshold (done)
790 // if trigger is etcut OR idperf, pidname should be default (usually lhloose)
791 std::string pidname; // Offline loose, medium, tight, etc...(done)
792 // extra HLT information
793 bool idperf; // Performance chain
794 bool etcut; // Et cut only chain
795 bool nogsf; // chain without gsf reconstruction
796 bool lrt; // LRT chain
797 bool ion; // Heavy Ion chain
798 std::string isolation;
799 bool isolated;
800 } TrigInfo;
801 *******************************************/
802
803 std::map<std::string, std::string> pidMap = { {"vloose" , "loose" },
804 {"loose" , "loose" },
805 {"medium" , "medium" },
806 {"tight" , "tight" },
807 {"loose1" , "loose" },
808 {"medium1" , "medium" },
809 {"tight1" , "tight" },
810 {"lhvloose" , "lhvloose" },
811 {"lhloose" , "lhloose" },
812 {"lhmedium" , "lhmedium" },
813 {"lhtight" , "lhtight" },
814 {"dnnloose" , "dnnloose" },
815 {"dnnmedium", "dnnmedium"},
816 {"dnntight" , "dnntight" },
817 {"nopid" , "nopid" } };
818
819 //Get information about each signature of the trigger
820 //Each signature counts as a leg
821 //HLT_2e17_medium_g22_medium_probe_L12eEM24H
822 //Leg 1 : 2e17_medium
823 //Leg2: g22_medium_probe
824
825 float threshold = 0;
826 std::string signature = "";
827 std::string etthr = "";
828 std::string pidname = "";
829
830
831 auto LegParts = getProbeTriggerLeg(trigger);
832
833 //Get the probe leg
834 if(!LegParts.empty())
835 {
836 //Looping over signatures
837 for( const auto& leg: LegParts)
838 {
839 //Grab the requested signature
840 if (leg.signature != "g") continue;
841
842 //Building the probe trigger name
843 signature = leg.signature;
844 if (signature == "g"){
845 signature = "Photon";
846 }
847 threshold = leg.threshold;
848 //threshold = std::to_string(leg.threshold);
849 pidname = leg.legParts[0];
850 }
851 }
852
853
854 bool l1legacy=true;
855 // L1EMXX
856 std::string l1seed = getL1Item(trigger);
857 l1legacy = !l1seed.contains("eEM");
858
859
860 std::vector<std::string> isoNames = {"ivarloose","ivarmedium","ivartight","icaloloose","icalomedium","icalotight"};
861
862 bool nogsf = false;
863 bool lrt = false;
864 bool ion = false;
865 bool etcut = false;
866 bool idperf = false;
867 bool isolated = false;
868
869 std::string isolation="";
870
871 // extra information
872 nogsf = trigger.contains("nogsf");
873 lrt = trigger.contains("lrt");
874 ion = trigger.contains("ion");
875
876 for(auto& iso : isoNames){
877 if(trigger.contains(iso)){
878 isolation=iso; isolated=true; break;
879 }
880 }
881 std::vector<std::string> parts;
882 for (auto&& part : trigger | std::views::split('_')) parts.emplace_back(part.begin(), part.end());
883 if(trigger.contains("idperf")){
884 ATH_MSG_DEBUG("This is idperf");
885 idperf=true;
886 }
887 else if(trigger.contains("etcut")){
888 ATH_MSG_DEBUG("This is etcut");
889 etcut=true;
890 }
891 else { // remap online pidname to offline pidname
892 //ATH_MSG_DEBUG("Problem: 3");
893 // ATH_MSG_DEBUG("This is nominal");
894 // if (pidMap.count(parts.at(4)) != 4) {
895 // ATH_MSG_DEBUG("Unknown trigger type: " << parts.at(4) << " (" << trigger << ")");
896 // }
897 // pidname = pidMap.at(parts.at(4));
898 }
899
900
901 ATH_MSG_DEBUG("Problem: 5");
902 ATH_MSG_DEBUG("=================== R3 Chain Parser R3 =======================");
903 ATH_MSG_DEBUG( "trigger : " << trigger );
904 ATH_MSG_DEBUG( "threshold : " << threshold);
905 ATH_MSG_DEBUG( "Pidname : " << pidname );
906 ATH_MSG_DEBUG( "signature : " << signature);
907 ATH_MSG_DEBUG( "etcut : " << (etcut?"Yes":"No"));
908 ATH_MSG_DEBUG( "idperf : " << (idperf?"Yes":"No"));
909 ATH_MSG_DEBUG( "nogsf : " << (nogsf?"Yes":"No"));
910 ATH_MSG_DEBUG( "lrt : " << (lrt?"Yes":"No"));
911 ATH_MSG_DEBUG( "HeavyIon : " << (ion?"Yes":"No"));
912 ATH_MSG_DEBUG( "Isolation : " << isolation);
913 ATH_MSG_DEBUG( "Isolated : " << (isolated?"Yes":"No"));
914 ATH_MSG_DEBUG( "L1Seed : " << l1seed << " (Is Legacy? " << (l1legacy?"Yes":"No") << ")");
915 ATH_MSG_DEBUG("========================================================");
916
917 TrigInfo info{l1legacy,l1seed,trigger,signature,threshold,pidname,idperf,etcut,nogsf,lrt,ion,isolation,isolated};
918 m_trigInfoR3[trigger] = info;
919
920}
921
922
923// For Run-3, all triggers must have the L1 seed in name (last part)
924std::string TrigEgammaMonitorBaseAlgorithm::getL1Item(const std::string& trigger) const{
925 const auto pos = trigger.rfind('_');
926 return pos == std::string::npos ? trigger : trigger.substr(pos + 1);
927}
928
929
931 return m_trigdec->ExperimentalAndExpertMethods().isHLTTruncated();
932}
933
934
935
936
938
939// Define the parser
940#include "Gaudi/Parsers/Factory.h"
941
942namespace Gaudi
943{
944 namespace Parsers
945 {
946 // Parse function... nothing special, but it must be done explicitely.
947 StatusCode parse( VecDict_t& result, const std::string& input ) { return parse_( result, input ); }
948 }
949}
950
951// We also need to be able to print an object of our type as a string that both
952// Python and our parser can understand,
953#include "GaudiKernel/ToStream.h"
954namespace std
955{
956 // This is an example valid for any mapping type.
957 ostream& operator<<( ostream& s, const Gaudi::Parsers::VecDict_t& vecDict )
958 {
959 s << '{';
960 for ( const auto& dict : vecDict ) {
961 Gaudi::Utils::toStream( dict, s );
962 }
963 s << '}';
964 return s;
965 }
966}
967
Scalar eta() const
pseudorapidity method
Scalar phi() const
phi method
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x)
#define ATH_MSG_INFO(x)
#define ATH_MSG_DEBUG(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.
=============================================================================
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".
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".
Struct containing information on each leg of a chain.
Extra patterns decribing particle interation process.