ATLAS Offline Software
Loading...
Searching...
No Matches
DecoratePromptLeptonImproved.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
4
5// Local
8
9#include "GaudiKernel/ThreadLocalContext.h"
10
11
12// ROOT
13#include "TMVA/Config.h"
14#include "TH1.h"
15
16// C/C++
17#include <cmath>
18#include <iostream>
19#include <sstream>
20#include <sys/stat.h>
21
22
23namespace {
24
25
26// Accessor constants.
27static const SG::ConstAccessor<float> accessCalIsolation30 ("topoetcone30");
28static const SG::ConstAccessor<float> accessTrackIsolation30 ("ptvarcone30");
29static const SG::ConstAccessor<float> accessTrackIsolation30TTVA ("ptvarcone30_Nonprompt_All_MaxWeightTTVA_pt500");
30static const SG::ConstAccessor<float> accessMuonCalE ("calE");
31static const SG::ConstAccessor<float> accessMuonParamEnergyLoss ("ParamEnergyLoss");
32
33
34} // anonymous namespace
35
36
37//======================================================================================================
38Prompt::DecoratePromptLeptonImproved::DecoratePromptLeptonImproved(const std::string& name, ISvcLocator* pSvcLocator):
39 AthAlgorithm(name, pSvcLocator),
40 m_BDTVarKey(Def::NONE)
41{}
42
43//=============================================================================
45{
46 ATH_MSG_DEBUG("Initializing DecoratePromptLeptonImproved...");
47 ATH_MSG_DEBUG("m_leptonsName = " << m_leptonsName);
48 if (m_printTime)
49 {
50 //
51 // Reset timers
52 //
53 m_timerAll .Reset();
54 m_timerExec.Reset();
55 m_timerMuon.Reset();
56 m_timerElec.Reset();
57
58 //
59 // Start full timer
60 //
61 m_timerAll.Start();
62 }
63
64 ATH_CHECK(m_trackJetsKey.initialize());
65 ATH_CHECK(m_primaryVertexKey.initialize());
66 ATH_CHECK(m_clusterContainerKey.initialize());
67
68 ATH_MSG_DEBUG("Initializing " << m_electronsKey);
69
70 ATH_CHECK(m_electronsKey.initialize(m_leptonsName == "Electrons"));
71 ATH_CHECK(m_muonsKey.initialize(m_leptonsName == "Muons"));
72
73 ATH_MSG_DEBUG("Number of int vars to read: " << m_stringIntVars.size());
74 ATH_MSG_DEBUG("Number of float vars to read: " << m_stringFloatVars.size());
75
76 // Setup variable holder
77 m_vars = std::make_unique<Prompt::VarHolder>();
78
79 //
80 // Read vector<string> vars into vector<Var> and append
81 //
82 m_intVars = m_vars->readVectorVars(m_stringIntVars);
83 m_floatVars = m_vars->readVectorVars(m_stringFloatVars);
84
85 m_allVars.insert(m_allVars.end(), m_intVars .begin(), m_intVars .end());
86 m_allVars.insert(m_allVars.end(), m_floatVars.begin(), m_floatVars.end());
87
88 m_varTMVA.resize(m_allVars.size());
89
90
91 //
92 // Get key for recording BDT output
93 //
94 m_BDTVarKey = m_vars->registerDynamicVar(m_BDTName);
95
96 if(m_BDTVarKey == Def::NONE) {
97 ATH_MSG_ERROR("Failed to create key for BDT name=" << m_BDTName);
98 return StatusCode::FAILURE;
99 }
100
101 //
102 // Fill decorator maps
103 //
105
106 //
107 // Initialize const accessors
108 //
110
111 ATH_MSG_DEBUG("Initialized DecoratePromptLeptonImproved.");
112
113 //
114 // Initialize TMVA Reader
115 //
117
118 ATH_MSG_DEBUG("Initialized TMVA Reader.");
119
120 return StatusCode::SUCCESS;
121}
122
123//=============================================================================
125{
126 if(m_printTime) {
127 //
128 // Print full time stopwatch
129 //
130 m_timerAll.Stop();
131
132 ATH_MSG_INFO("Real time: " << m_timerAll.RealTime() << "\t CPU time: " << m_timerAll.CpuTime());
133
134 ATH_MSG_INFO("Execute time: " << PrintResetStopWatch(m_timerExec));
137 }
138
139 return StatusCode::SUCCESS;
140}
141
142
143//=============================================================================
145{
146 //
147 // Start execute timer
148 //
150
151 const EventContext& ctx = Gaudi::Hive::currentContext();
152
153 //
154 // Retrieve containers from evtStore
155 //
159
160 ATH_MSG_DEBUG("======================================="
161 << "\n\t\t\t Size of vertex container: " << vertices ->size()
162 << "\n\t\t\t Size of track jet container: " << trackJets->size()
163 << "\n-----------------------------------------------------------------");
164
165 //
166 // Find default Primary Vertex
167 //
168 const xAOD::Vertex *primaryVertex = nullptr;
169
170 for(const xAOD::Vertex *vertex: *vertices) {
171 if(vertex->vertexType() == xAOD::VxType::PriVtx) {
172 primaryVertex = vertex;
173 break;
174 }
175 }
176
177 std::vector<decoratorFloatH_t> floatDecors;
178 floatDecors.reserve (m_floatDecorHandleKeys.size());
180 floatDecors.emplace_back (k, ctx);
181 }
182
183 std::vector<decoratorShortH_t> shortDecors;
184 shortDecors.reserve (m_shortDecorHandleKeys.size());
186 shortDecors.emplace_back (k, ctx);
187 }
188
189 if(m_leptonsName == "Electrons") {
190 //
191 // Process electrons
192 //
193 ATH_MSG_DEBUG("Reading " << m_electronsKey);
195
196 for(const xAOD::Electron *elec: *electrons) {
197 decorateElec(*elec, *trackJets, *clusters, primaryVertex, floatDecors, shortDecors);
198 }
199 } else if(m_leptonsName == "Muons") {
200 //
201 // Process muons
202 //
203 ATH_MSG_DEBUG("Reading " << m_muonsKey);
205
206 for(const xAOD::Muon *muon: *muons) {
207 decorateMuon(*muon, *trackJets, primaryVertex, floatDecors, shortDecors);
208 ATH_MSG_DEBUG("Muon decorated");
209 }
210 } else {
211 ATH_MSG_ERROR("Must specify Electrons or Muons");
212 return StatusCode::FAILURE;
213 }
214
215 return StatusCode::SUCCESS;
216}
217
218
219//=============================================================================
221{
222 //
223 // Make new instance of TMVA Reader and add variables
224 //
225 m_TMVAReader = std::make_unique<TMVA::Reader>();
226
227 for(unsigned i = 0; i < m_allVars.size(); ++i) {
228 m_TMVAReader->AddVariable(m_vars->asStr(m_allVars.at(i)), &m_varTMVA[i]);
229 }
230
231 //
232 // Get path to xml training file
233 //
234 std::string fullPathToFile = PathResolverFindCalibFile("JetTagNonPromptLepton/"
236 + "/TMVAClassification_" + m_methodTitleMVA + ".weights.xml");
237
238 if(!m_configPathOverride.empty()) {
239 ATH_MSG_INFO("Override path resolver result");
240 fullPathToFile = m_configPathOverride;
241 }
242
243 ATH_MSG_INFO("TMVA configuration file: " + fullPathToFile);
244 ATH_MSG_INFO("TMVA method name: " + m_methodTitleMVA);
245
246 //
247 // Book an instance of BDT reader if path is available
248 //
249 if(fullPathToFile == "") {
250 ATH_MSG_ERROR("Could not find path to xml training file");
251 return false;
252 }
253 else {
254 m_TMVAReader->BookMVA(m_methodTitleMVA.toString(), fullPathToFile);
255 }
256
257 return true;
258}
259
260
261//=============================================================================
263{
264 std::string inputContName;
265 if (m_leptonsName == "Electrons") {
266 inputContName = m_electronsKey.key();
267 }
268 else if (m_leptonsName == "Muons") {
269 inputContName = m_muonsKey.key();
270 }
271 else {
272 ATH_MSG_ERROR ("LeptonContainerName was " << m_leptonsName <<
273 "; must be either Electrons or Muons");
274 return StatusCode::FAILURE;
275 }
276
277 DecorMap_t vetoedVars;
278 for(const std::string &vvar: m_vetoDecoratorFloatVars) {
279 const Def::Var vkey = m_vars->registerDynamicVar(vvar);
280
281 if(vkey == Def::NONE) {
282 ATH_MSG_ERROR("Failed to create key for variable name=" << vvar);
283 return StatusCode::FAILURE;
284 }
285
286 vetoedVars.try_emplace (vkey, 0);
287 }
288 for(const std::string &vvar: m_vetoDecoratorShortVars) {
289 const Def::Var vkey = m_vars->registerDynamicVar(vvar);
290
291 if(vkey == Def::NONE) {
292 ATH_MSG_ERROR("Failed to create key for variable name=" << vvar);
293 return StatusCode::FAILURE;
294 }
295
296 vetoedVars.try_emplace (vkey, 0);
297 }
298
299 //
300 // Fill short variable map
301 //
302 for(Prompt::Def::Var &var: m_intVars) {
303 if (!vetoedVars.contains (var)) {
304 m_shortDecorMap.try_emplace (var, m_shortDecorHandleKeys.size());
305 m_shortDecorHandleKeys.push_back (SG::makeContDecorKey (inputContName, m_inputVarDecoratePrefix + m_vars->asStr(var)));
306 }
307 }
308
309 //
310 // Fill float variable map
311 //
313 for(Prompt::Def::Var &var: m_floatVars) {
314 if (!vetoedVars.contains (var)) {
315 m_floatDecorMap.try_emplace (var, m_floatDecorHandleKeys.size());
316 m_floatDecorHandleKeys.push_back (SG::makeContDecorKey (inputContName, m_inputVarDecoratePrefix + m_vars->asStr(var)));
317 }
318 }
319
320 //
321 // Fill additional variables
322 //
323 if (!vetoedVars.contains (m_BDTVarKey)) {
325 m_floatDecorHandleKeys.push_back (SG::makeContDecorKey (inputContName, m_BDTName));
326 }
327
328 for(const std::string &evar: m_extraDecoratorFloatVars) {
329 const Def::Var ekey = m_vars->registerDynamicVar(evar);
330
331 if(ekey == Def::NONE) {
332 ATH_MSG_ERROR("Failed to create key for variable name=" << evar);
333 return StatusCode::FAILURE;
334 }
335
336 if (!vetoedVars.contains (ekey)) {
337 m_floatDecorMap.try_emplace (ekey, m_floatDecorHandleKeys.size());
338 m_floatDecorHandleKeys.push_back (SG::makeContDecorKey (inputContName, m_inputVarDecoratePrefix + evar));
339 }
340 }
341
342 for(const std::string &evar: m_extraDecoratorShortVars) {
343 const Def::Var ekey = m_vars->registerDynamicVar(evar);
344
345 if(ekey == Def::NONE) {
346 ATH_MSG_ERROR("Failed to create key for variable name=" << evar);
347 return StatusCode::FAILURE;
348 }
349
350 if (!vetoedVars.contains (ekey)) {
351 m_shortDecorMap.try_emplace (ekey, m_shortDecorHandleKeys.size());
352 m_shortDecorHandleKeys.push_back (SG::makeContDecorKey (inputContName, m_inputVarDecoratePrefix + evar));
353 }
354 }
355
356 ATH_CHECK(m_shortDecorHandleKeys.initialize());
357 ATH_CHECK(m_floatDecorHandleKeys.initialize());
358
359 // Print decorator counts
360 ATH_MSG_DEBUG("Added " << m_shortDecorHandleKeys.size() << " short decorators");
361 ATH_MSG_DEBUG("Added " << m_floatDecorHandleKeys.size() << " float decorators");
362
363 // Instantiate MVA X bin
364 if(m_leptonPtBinsVector.size() < 2) {
365 ATH_MSG_ERROR("Invalid PtBins size=" << m_leptonPtBinsVector.size());
366 return StatusCode::FAILURE;
367 }
368
369 std::unique_ptr<double []> PtBins = std::make_unique<double []>(m_leptonPtBinsVector.size());
370
371 for(unsigned i = 0; i < m_leptonPtBinsVector.size(); i++) {
372 PtBins[i] = m_leptonPtBinsVector[i];
373 }
374
375 m_leptonPtBinHist = std::make_unique<TH1D>("PtBin", "PtBin", m_leptonPtBinsVector.size() - 1, PtBins.get());
376
377 return StatusCode::SUCCESS;
378}
379
380//=============================================================================
382{
383 //
384 // Instantiate isolation accessors
385 //
387
388 //
389 // Instantiate accessors for RNN variables
390 //
391 for(const std::string &name: m_accessorRNNVars) {
392 const Def::Var akey = m_vars->registerDynamicVar(name);
393
394 if(m_accessRNNMap.insert(floatAccessorMap::value_type(akey, AccessFloat(name))).second) {
395 ATH_MSG_DEBUG("Add float RNN accessor: " << name);
396 }
397 else {
398 ATH_MSG_WARNING("Skip duplicate float accessor: " << name);
399 }
400 }
401}
402
403//=============================================================================
405 const xAOD::Electron &electron,
406 const xAOD::JetContainer &trackJets,
407 const xAOD::CaloClusterContainer &clusters,
408 const xAOD::Vertex *primaryVertex,
409 std::vector<decoratorFloatH_t>& floatDecors,
410 std::vector<decoratorShortH_t>& shortDecors
411)
412{
413 //
414 // Find nearest track jet to electron
415 //
417
419
420 std::pair<double, const xAOD::Jet*> match = findTrackJet(electron, trackJets);
421
422 if(match.second) {
423 //
424 // Get muon calorimeter energy variable, RNN and secondary vertex variables
425 //
426 getElectronAnpVariables(electron, clusters, vars, primaryVertex);
427
428 //
429 // Get mutual variables, passing track as argument
430 //
431 getMutualVariables(electron, *match.second, electron.trackParticle(), vars);
432
433 //
434 // Pass variables to TMVA
435 //
436 addVarsToTMVA(vars);
437 }
438 else {
439 //
440 // Decorate electron with default values
441 //
442 fillVarDefault(vars);
443
444 ATH_MSG_DEBUG("No track jet found near to electron");
445 }
446
447 //
448 // Decorate electron with input vars and BDT weight
449 //
450 decorateAuxLepton(electron, vars, floatDecors, shortDecors);
451}
452
453
454//=============================================================================
456 const xAOD::Muon &muon,
457 const xAOD::JetContainer &trackJets,
458 const xAOD::Vertex *primaryVertex,
459 std::vector<decoratorFloatH_t>& floatDecors,
460 std::vector<decoratorShortH_t>& shortDecors
461)
462{
463 //
464 // Find nearest track jet to muon
465 //
467
469
470 std::pair<double, const xAOD::Jet*> match = findTrackJet(muon, trackJets);
471
472 if(match.second) {
473 //
474 // Get muon calorimeter energy variable, RNN and secondary vertex variables
475 //
476 getMuonAnpVariables(muon, vars, primaryVertex);
477
478 //
479 // Get mutual variables, passing track as argument
480 //
481 getMutualVariables(muon, *match.second, muon.primaryTrackParticle(), vars);
482
483 //
484 // Add variables to TMVA Reader
485 //
486 addVarsToTMVA(vars);
487 }
488 else {
489 //
490 // Decorate muon with default values
491 //
492 fillVarDefault(vars);
493
494 ATH_MSG_DEBUG("No track jet found near to muon");
495 }
496
497 //
498 // Decorate muon with input vars and BDT weight
499 //
500 decorateAuxLepton(muon, vars, floatDecors, shortDecors);
501}
502
503//=============================================================================
505 const xAOD::Electron &elec,
506 const xAOD::CaloClusterContainer &clusters,
507 Prompt::VarHolder &vars,
508 const xAOD::Vertex *primaryVertex
509)
510{
511 //
512 // Get Muon variables - calorimeter
513 //
514 double sumCoreEt_large = 0.0, CaloClusterSumEtRel = 0.0;
515
516 if(elec.caloCluster()) {
517 const double elec_calEta = elec.caloCluster()->eta();
518 const double elec_calPhi = elec.caloCluster()->phi();
519
520 for(const xAOD::CaloCluster *cluster: clusters) {
521 const double deta = elec_calEta - cluster->eta();
522 const double dphi = TVector2::Phi_mpi_pi(elec_calPhi - cluster->phi());
523 const double dr = std::sqrt(deta*deta + dphi*dphi);
524
525 if(dr < m_elecMinCalErelConeSize) {
526 sumCoreEt_large += cluster->pt();
527 }
528 }
529 }
530
531 if(elec.pt() > 0.0) CaloClusterSumEtRel = sumCoreEt_large/elec.pt();
532
533 vars.addVar(Prompt::Def::CaloClusterSumEtRel, CaloClusterSumEtRel);
534
535 //
536 // Get lepton isolation variables
537 //
538 const double Topoetcone30rel = accessIsolation(accessCalIsolation30, elec);
539 const double Ptvarcone30rel = accessIsolation(accessTrackIsolation30, elec);
540
541 vars.addVar(Prompt::Def::Topoetcone30rel, Topoetcone30rel);
542 vars.addVar(Prompt::Def::Ptvarcone30rel, Ptvarcone30rel);
543
544 //
545 // Get secondary vertex variable
546 //
547 std::vector<double> goodVertexNdistLong;
548
549 if(m_accessDeepSecondaryVertex->isAvailable(elec)) {
550 std::vector<ElementLink<xAOD::VertexContainer> > vtxLinks = (*m_accessDeepSecondaryVertex)(elec);
551
552 for(ElementLink<xAOD::VertexContainer> &vtxLink: vtxLinks) {
553 if(!vtxLink.isValid()) {
554 ATH_MSG_WARNING("VertexContainer : invalid link");
555 continue;
556 }
557
558 const xAOD::Vertex *vtx = *vtxLink;
559
560 const double fitProb = Prompt::getVertexFitProb(vtx);
561
562 if(fitProb < m_vertexMinChiSquaredProb) {
563 continue;
564 }
565
566 const double theta = std::acos(getVertexCosThetaWithLepDir(elec, vtx, primaryVertex));
567
568 if (theta < m_vertexMinThetaBarrElec && std::fabs(elec.eta()) <= m_vertexBarrEcapAbsEtaAt) continue;
569 else if (theta < m_vertexMinThetaEcapElec && std::fabs(elec.eta()) > m_vertexBarrEcapAbsEtaAt) continue;
570
571 const double vertex_ndist_long = getVertexLongitudinalNormDist(elec, vtx, primaryVertex);
572
573 goodVertexNdistLong.push_back(vertex_ndist_long);
574 }
575 }
576 else {
577 ATH_MSG_WARNING("VertexContainer : " << m_vertexLinkName << " not found for the electron");
578 }
579
580 double best_vertex_ndist_long = 0.0;
581
582 if(goodVertexNdistLong.size() > 0) {
583 std::sort(goodVertexNdistLong.begin(), goodVertexNdistLong.end());
584 best_vertex_ndist_long = goodVertexNdistLong.back();
585 }
586
588 vars.addVar(Prompt::Def::CandVertex_NPassVtx, goodVertexNdistLong.size());
589}
590
591//=============================================================================
593 const xAOD::Muon &muon,
594 Prompt::VarHolder &vars,
595 const xAOD::Vertex *primaryVertex
596) const
597{
598 //
599 // Get Muon variables - calorimeter
600 //
601 double calE = -99.0, peloss = -99.0, caloClusterERel = -99.0;
602
603 if(muon.clusterLink().isValid()) {
604 const xAOD::CaloCluster* cluster = *(muon.clusterLink());
605
606 if(accessMuonCalE.isAvailable(*cluster) && accessMuonParamEnergyLoss.isAvailable(muon)) {
607 calE = accessMuonCalE(*cluster);
608 peloss = accessMuonParamEnergyLoss(muon);
609
610 caloClusterERel = calE/peloss;
611 }
612 else {
613 ATH_MSG_WARNING("Muon calE or ParamEnergyLoss not found in auxiliary store");
614 }
615 }
616
617 vars.addVar(Prompt::Def::CaloClusterERel, caloClusterERel);
618
619 //
620 // Get lepton isolation variables
621 //
622 const double Topoetcone30rel = accessIsolation(accessCalIsolation30, muon);
623 const double ptvarcone30TightTTVAPt500rel = accessIsolation(accessTrackIsolation30TTVA, muon);
624
625 vars.addVar(Prompt::Def::Topoetcone30rel, Topoetcone30rel);
626 vars.addVar(Prompt::Def::Ptvarcone30_TightTTVA_pt500rel, ptvarcone30TightTTVAPt500rel);
627
628 //
629 // Get Muon Secondary Vertex variable
630 //
631 std::vector<double> goodVertexNdistLong;
632
633 if(m_accessDeepSecondaryVertex->isAvailable(muon)) {
634 std::vector<ElementLink<xAOD::VertexContainer> > vtxLinks = (*m_accessDeepSecondaryVertex)(muon);
635 goodVertexNdistLong.reserve(vtxLinks.size());
636
637 for(ElementLink<xAOD::VertexContainer> &vtxLink: vtxLinks) {
638 if(!vtxLink.isValid()) {
639 ATH_MSG_WARNING("VertexContainer : invalid link");
640 continue;
641 }
642
643 const xAOD::Vertex *vtx = *vtxLink;
644
645 const double fitProb = Prompt::getVertexFitProb(vtx);
646
647 if(fitProb > m_vertexMinChiSquaredProb) {
648 const double vertex_ndist_long = getVertexLongitudinalNormDist(muon, vtx, primaryVertex);
649
650 goodVertexNdistLong.push_back(vertex_ndist_long);
651 }
652 }
653 }
654 else {
655 ATH_MSG_WARNING("VertexContainer : " << m_vertexLinkName << " not found for the muon");
656 }
657
658 double best_vertex_ndist_long = 0.0;
659
660 if(goodVertexNdistLong.size() > 0) {
661 std::sort(goodVertexNdistLong.begin(), goodVertexNdistLong.end());
662 best_vertex_ndist_long = goodVertexNdistLong.back();
663 }
664
666 vars.addVar(Prompt::Def::CandVertex_NPassVtx, goodVertexNdistLong.size());
667}
668
669//=============================================================================
671 const xAOD::IParticle &particle,
672 const xAOD::Jet &track_jet,
673 const xAOD::TrackParticle *track,
675) const
676{
677 //
678 // Add lepton - jet variables to VarHolder
679 //
680 double PtFrac = -99.;
681 double PtRel = -99.;
682
683 if(particle.pt() > 0.0 && track_jet.pt() > 0.0) {
684
685 if(track) {
686 PtFrac = track->pt()/track_jet.pt();
687 }
688
689 const double angle = particle.p4().Vect().Angle(track_jet.p4().Vect());
690
691 PtRel = particle.pt() * std::sin(angle);
692 }
693
694 //
695 // Add vars to VarHolder
696 //
697 vars.addVar(Prompt::Def::PtFrac, PtFrac);
698 vars.addVar(Prompt::Def::PtRel, PtRel);
699 vars.addVar(Prompt::Def::DRlj, track_jet.p4().DeltaR(particle.p4()));
701
702 //
703 // Get RNN variables
704 //
705 for(const floatAccessorMap::value_type &acc: m_accessRNNMap) {
706 if(acc.second.isAvailable(particle)) {
707 vars.addVar(acc.first, acc.second(particle));
708 }
709 else {
710 ATH_MSG_WARNING("LeptonTagger RNN not found in auxiliary store for variable=" << vars.asStr(acc.first));
711 }
712 }
713
714 //
715 // Get lepton variables - pT X bin
716 //
717 const double lepPt = particle.pt();
718
719 const double xmax = m_leptonPtBinHist->GetXaxis()->GetXmax();
720 const double xmin = m_leptonPtBinHist->GetXaxis()->GetXmin();
721
722 int curr_bin = 0;
723
724 if(xmin < lepPt && lepPt < xmax) {
725 curr_bin = m_leptonPtBinHist->FindBin(lepPt);
726 }
727 else if (!(lepPt < xmax)) {
728 curr_bin = m_leptonPtBinHist->GetNbinsX();
729 }
730 else if (!(lepPt > xmin)) {
731 curr_bin = 1;
732 }
733
734 vars.addVar(Prompt::Def::MVAXBin, curr_bin);
735 vars.addVar(Prompt::Def::RawPt, lepPt);
736
737 ATH_MSG_DEBUG("getMutualVariables - lepPt = " << lepPt << ", MVAXBin = " << curr_bin);
738}
739
740//=============================================================================
742 const AccessFloat &isoAccessor,
743 const xAOD::IParticle &particle
744) const {
745 double isolation = -99., isolationrel = -99.;
746
747 if(isoAccessor.isAvailable(particle)) {
748 isolation = isoAccessor(particle);
749 }
750 else {
751 ATH_MSG_WARNING("Lepton isolation not found in auxiliary store");
752 }
753
754 if(particle.pt() > 0.0) {
755 isolationrel = isolation / particle.pt();
756 }
757
758 return isolationrel;
759}
760
761//=============================================================================
763{
764 //
765 // Add variables to TMVA reader
766 //
767 for(unsigned i = 0; i < m_allVars.size(); ++i) {
768 m_varTMVA[i] = 0.0;
769
770 if(!vars.getVar(m_allVars.at(i), m_varTMVA[i])) {
771 ATH_MSG_WARNING("Missing input variable: " << m_vars->asStr(m_allVars.at(i)));
772 }
773 }
774
775 //
776 // Decorate lepton with classifier response, if goodJet
777 //
778 float bdt_weight = m_TMVAReader->EvaluateMVA(m_methodTitleMVA.toString());
779
780 if(m_BDTVarKey != Def::NONE) {
781 vars.addVar(m_BDTVarKey, bdt_weight);
782 }
783 else {
784 ATH_MSG_WARNING("addVarsToTMVA - invalid Def::Var key for " << m_BDTName);
785 }
786}
787
788//=============================================================================
790{
791 //
792 // Add default values to VarHolder
793 //
794 for(const DecorMap_t::value_type &dec: m_floatDecorMap) {
795 vars.addVar(dec.first, -99.0);
796 }
797
798 for(const DecorMap_t::value_type &dec: m_shortDecorMap) {
799 vars.addVar(dec.first, -99.0);
800 }
801}
802
803//=============================================================================
805 const xAOD::IParticle &particle,
806 Prompt::VarHolder &vars,
807 std::vector<decoratorFloatH_t>& floatDecors,
808 std::vector<decoratorShortH_t>& shortDecors
809) const
810{
811 //
812 // Decorate lepton with input short variables
813 //
814 for(const DecorMap_t::value_type &dec: m_shortDecorMap) {
815 double val = 0.0;
816
817 if(vars.getVar(dec.first, val)) {
818 shortDecors.at(dec.second)(particle) = static_cast<short>(val);
819
820 ATH_MSG_DEBUG("Short variable: " << vars.asStr(dec.first) << " = " << val);
821 }
822 else {
823 ATH_MSG_WARNING("Short variable " << vars.asStr(dec.first) << " not decorated to lepton");
824 }
825 }
826
827 //
828 // Decorate lepton with input float variables
829 //
830 for(const DecorMap_t::value_type &dec: m_floatDecorMap) {
831 double val = 0.0;
832
833 if(vars.getVar(dec.first, val)) {
834 floatDecors.at(dec.second)(particle) = val;
835
836 ATH_MSG_DEBUG("Float variable: " << vars.asStr(dec.first) << " = " << val);
837 }
838 else {
839 ATH_MSG_WARNING("Float variable " << vars.asStr(dec.first) << " not decorated to lepton");
840 }
841 }
842}
843
844//=============================================================================
845template<class T> std::pair<double, const xAOD::Jet*> Prompt::DecoratePromptLeptonImproved::findTrackJet(const T &part,
846 const xAOD::JetContainer &jets)
847{
848 //
849 // Find nearest track jet and a return a pair of dR and xAOD::Jet*
850 //
851 const xAOD::Jet *minjet = 0;
852 double mindr = 10.0;
853 std::pair<double, const xAOD::Jet*> match(mindr, minjet);
854
855 for(const xAOD::Jet* jet: jets) {
856 const double dr = part.p4().DeltaR(jet->p4());
857
858 if(!minjet || dr < mindr) {
859 mindr = dr;
860 minjet = jet;
861 match = std::make_pair(mindr, minjet);
862 }
863 }
864
865
866 if(minjet && mindr < m_maxLepTrackJetDR) {
867 return match;
868 }
869
870 minjet = 0;
871 return std::make_pair(10., minjet);
872}
873
874//=============================================================================
876 const xAOD::IParticle &lepton,
877 const xAOD::Vertex *secondaryVertex,
878 const xAOD::Vertex *primaryVertex
879) const
880{
881 //
882 // get the Longitudinal normalized distance between the secondary vertex and primary vertex
883 //
884 if(!secondaryVertex || !primaryVertex) {
885 ATH_MSG_WARNING("getVertexLongitudinalNormDist - invalid pointer of lepton/secondaryVertex/primaryVertex");
886 return 0.0;
887 }
888
889
890 float normDist_SVPV = 0.0;
891
892 if(!Prompt::GetAuxVar(*secondaryVertex, normDist_SVPV, "normDistToPriVtx")) {
893 ATH_MSG_WARNING("getVertexLongitudinalNormDist - missing \"normDistToPriVtx\"");
894 }
895
896 double cos_theta = getVertexCosThetaWithLepDir(lepton, secondaryVertex, primaryVertex);
897
898 return normDist_SVPV*cos_theta;
899}
900
901//=============================================================================
903 const xAOD::Vertex *secondaryVertex,
904 const xAOD::Vertex *primaryVertex) const
905{
906 //
907 // get the Longitudinal nomalized distance between the secondary vertex and primary vertex
908 //
909 if(!secondaryVertex || !primaryVertex) {
910 ATH_MSG_WARNING("GetVertexThetaWithLepDir - invalid pointer of lepton/secondaryVertex/primaryVertex");
911 return 0.0;
912 }
913
914 const Amg::Vector3D sv_to_pv_v3 = secondaryVertex->position() - primaryVertex->position();
915
916 const TVector3 sv_to_pv_t3 = TVector3(sv_to_pv_v3.x(), sv_to_pv_v3.y(), sv_to_pv_v3.z());
917 const TVector3 lepton_dirt = lepton.p4().Vect();
918
919 const double cos_theta = sv_to_pv_t3.Unit()*lepton_dirt.Unit();
920
921 return cos_theta;
922}
923
Scalar theta() const
theta method
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x)
#define ATH_MSG_INFO(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
std::string PathResolverFindCalibFile(const std::string &logical_file_name)
double angle(const GeoTrf::Vector2D &a, const GeoTrf::Vector2D &b)
AthAlgorithm(const std::string &name, ISvcLocator *pSvcLocator)
Constructor with parameters:
std::pair< double, const xAOD::Jet * > findTrackJet(const T &part, const xAOD::JetContainer &jets)
Gaudi::Property< std::string > m_configFileVersion
Gaudi::Property< std::vector< double > > m_leptonPtBinsVector
Gaudi::Property< std::vector< std::string > > m_vetoDecoratorShortVars
void getMutualVariables(const xAOD::IParticle &particle, const xAOD::Jet &track_jet, const xAOD::TrackParticle *track, Prompt::VarHolder &vars) const
SG::ReadHandleKey< xAOD::VertexContainer > m_primaryVertexKey
SG::WriteDecorHandleKeyArray< xAOD::IParticleContainer > m_shortDecorHandleKeys
Gaudi::Property< std::vector< std::string > > m_stringFloatVars
std::unordered_map< Def::Var, size_t > DecorMap_t
Gaudi::Property< std::vector< std::string > > m_extraDecoratorShortVars
SG::WriteDecorHandleKeyArray< xAOD::IParticleContainer > m_floatDecorHandleKeys
SG::ReadHandleKey< xAOD::CaloClusterContainer > m_clusterContainerKey
double getVertexCosThetaWithLepDir(const xAOD::IParticle &lepton, const xAOD::Vertex *secondaryVertex, const xAOD::Vertex *primaryVertex) const
void fillVarDefault(Prompt::VarHolder &vars) const
Gaudi::Property< std::string > m_inputVarDecoratePrefix
SG::ReadHandleKey< xAOD::ElectronContainer > m_electronsKey
void decorateElec(const xAOD::Electron &electron, const xAOD::JetContainer &trackJets, const xAOD::CaloClusterContainer &clusters, const xAOD::Vertex *primaryVertex, std::vector< decoratorFloatH_t > &floatDecors, std::vector< decoratorShortH_t > &shortDecors)
DecoratePromptLeptonImproved(const std::string &name, ISvcLocator *pSvcLocator)
void getMuonAnpVariables(const xAOD::Muon &muon, Prompt::VarHolder &vars, const xAOD::Vertex *primaryVertex) const
Gaudi::Property< std::vector< std::string > > m_extraDecoratorFloatVars
void getElectronAnpVariables(const xAOD::Electron &elec, const xAOD::CaloClusterContainer &clusters, Prompt::VarHolder &vars, const xAOD::Vertex *primaryVertex)
Gaudi::Property< std::vector< std::string > > m_accessorRNNVars
double getVertexLongitudinalNormDist(const xAOD::IParticle &lepton, const xAOD::Vertex *secondaryVertex, const xAOD::Vertex *primaryVertex) const
SG::ReadHandleKey< xAOD::MuonContainer > m_muonsKey
void decorateAuxLepton(const xAOD::IParticle &particle, Prompt::VarHolder &vars, std::vector< decoratorFloatH_t > &floatDecors, std::vector< decoratorShortH_t > &shortDecors) const
std::unique_ptr< Prompt::VarHolder > m_vars
Gaudi::Property< std::vector< std::string > > m_vetoDecoratorFloatVars
std::optional< AccessVertex > m_accessDeepSecondaryVertex
Gaudi::Property< std::string > m_configPathOverride
Gaudi::Property< std::vector< std::string > > m_stringIntVars
float accessIsolation(const SG::ConstAccessor< float > &isoAccessor, const xAOD::IParticle &particle) const
SG::ReadHandleKey< xAOD::JetContainer > m_trackJetsKey
void decorateMuon(const xAOD::Muon &muon, const xAOD::JetContainer &trackJets, const xAOD::Vertex *primaryVertex, std::vector< decoratorFloatH_t > &floatDecors, std::vector< decoratorShortH_t > &shortDecors)
double getVar(const unsigned key) const
Definition VarHolder.h:265
std::string asStr(const uint32_t key, const double val)
bool addVar(unsigned key, double value)
Adds a variable to the VarHolder.
Definition VarHolder.h:200
Helper class to provide constant type-safe access to aux data.
bool isAvailable(const ELT &e) const
Test to see if this variable exists in the store.
Property holding a SG store/key/clid/attr name from which a WriteDecorHandle is made.
virtual double eta() const
The pseudorapidity ( ) of the particle.
virtual double phi() const
The azimuthal angle ( ) of the particle.
virtual double pt() const override final
The transverse momentum ( ) of the particle.
Definition Egamma_v1.cxx:66
virtual double eta() const override final
The pseudorapidity ( ) of the particle.
Definition Egamma_v1.cxx:71
const xAOD::CaloCluster * caloCluster(size_t index=0) const
Pointer to the xAOD::CaloCluster/s that define the electron candidate.
Class providing the definition of the 4-vector interface.
virtual FourMom_t p4() const =0
The full 4-momentum of the particle.
size_t size() const
number of constituents
virtual FourMom_t p4() const
The full 4-momentum of the particle.
Definition Jet_v1.cxx:71
JetConstituentVector getConstituents() const
Return a vector of consituents. The object behaves like vector<const IParticle*>. See JetConstituentV...
Definition Jet_v1.cxx:147
virtual double pt() const
The transverse momentum ( ) of the particle.
Definition Jet_v1.cxx:44
const Amg::Vector3D & position() const
Returns the 3-pos.
bool match(std::string s1, std::string s2)
match the individual directories of two strings
Definition hcg.cxx:357
double xmax
Definition listroot.cxx:61
double xmin
Definition listroot.cxx:60
Eigen::Matrix< double, 3, 1 > Vector3D
@ Topoetcone30rel
Definition VarHolder.h:60
@ CandVertex_normDistToPriVtxLongitudinalBest_ThetaCutVtx
Definition VarHolder.h:69
@ CandVertex_NPassVtx
Definition VarHolder.h:70
@ Ptvarcone30_TightTTVA_pt500rel
Definition VarHolder.h:62
@ CaloClusterSumEtRel
Definition VarHolder.h:66
@ CaloClusterERel
Definition VarHolder.h:65
@ CandVertex_normDistToPriVtxLongitudinalBest
Definition VarHolder.h:68
bool GetAuxVar(const T1 &obj, T2 &value, const std::string &var_name)
Definition PromptUtils.h:83
std::string PrintResetStopWatch(TStopwatch &watch)
double getVertexFitProb(const xAOD::Vertex *vtx)
std::string makeContDecorKey(const std::string &cont, const std::string &decor)
Make a StoreGate key from container and decoration name.
void sort(typename DataModel_detail::iterator< DVL > beg, typename DataModel_detail::iterator< DVL > end)
Specialization of sort for DataVector/List.
@ PriVtx
Primary vertex.
Jet_v1 Jet
Definition of the current "jet version".
CaloCluster_v1 CaloCluster
Define the latest version of the calorimeter cluster class.
TrackParticle_v1 TrackParticle
Reference the current persistent version:
Vertex_v1 Vertex
Define the latest version of the vertex class.
Muon_v1 Muon
Reference the current persistent version:
CaloClusterContainer_v1 CaloClusterContainer
Define the latest version of the calorimeter cluster container.
JetContainer_v1 JetContainer
Definition of the current "jet container version".
Electron_v1 Electron
Definition of the current "egamma version".