ATLAS Offline Software
DQTGlobalWZFinderAlg.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
3 */
4 
5 // ********************************************************************
6 //
7 // NAME: DQTGlobalWZFinderAlg.cxx
8 // PACKAGE: DataQualityTools
9 //
10 // AUTHORS: Jahred Adelman (jahred.adelman@cern.ch)
11 // Simon Viel (svielcern.ch)
12 // Sam King (samking@physics.ubc.ca)
13 // Koos van Nieuwkoop (jvannieu@cern.ch)
14 // Samuel Alibocus (salibocu@cern.ch)
15 //
16 // ********************************************************************
17 
20 
21 #include "GaudiKernel/MsgStream.h"
22 #include "GaudiKernel/ITHistSvc.h"
23 
24 #include "xAODTracking/Vertex.h"
26 #include "xAODTruth/TruthVertex.h"
28 
30 
31 #include <vector>
32 
33 using Gaudi::Units::GeV;
34 using Gaudi::Units::mm;
35 
36 
37 //----------------------------------------------------------------------------------
39  ISvcLocator* pSvcLocator )
40  : AthMonitorAlgorithm(name, pSvcLocator)
41 //----------------------------------------------------------------------------------
42 {
43 }
44 
47  ATH_CHECK(m_muonSelectionTool.retrieve());
48  ATH_CHECK(m_r3MatchingTool.retrieve());
50  ATH_CHECK(m_truthClassifier.retrieve());
51  } else {
52  m_truthClassifier.disable();
53  }
54 
56  ATH_CHECK(m_MuonContainerKey.initialize());
57  ATH_CHECK(m_PhotonContainerKey.initialize());
58  ATH_CHECK(m_VertexContainerKey.initialize());
62  ATH_CHECK(m_isoMuonContainerKey.initialize());
64  return StatusCode::SUCCESS;
65 }
66 
67 //----------------------------------------------------------------------------------
68 StatusCode DQTGlobalWZFinderAlg::fillHistograms( const EventContext& ctx ) const
69 //----------------------------------------------------------------------------------
70 {
71  ATH_MSG_DEBUG("in DQTGlobalWZFinderAlg::fillHistograms()");
72 
73  using namespace Monitored;
74 
75  if (m_doRunBeam) {
76 
77  auto group = getGroup("default");
78 
79  //Get LumiBlock and EventNumber
80  SG::ReadHandle<xAOD::EventInfo> thisEventInfo { GetEventInfo(ctx) };
81  if(! thisEventInfo.isValid()) {
82  ATH_MSG_ERROR("Could not find EventInfo in evtStore()");
83  return StatusCode::FAILURE;
84  }
85 
86  bool isSimulation = thisEventInfo->eventType(xAOD::EventInfo::IS_SIMULATION);
87  auto writeTTrees = Scalar("writeTTrees", isSimulation);
88 
89  auto LB = Scalar<int>("LB", thisEventInfo->lumiBlock());
90  auto eventNumber = Scalar<int>("eventNumber", thisEventInfo->eventNumber());
91  auto runNumber = Scalar<int>("runNumber", thisEventInfo->runNumber());
92 
93  auto avgLiveFrac = Scalar("avgLiveFrac", lbAverageLivefraction(ctx));
94  auto duration = Scalar("duration", lbDuration(ctx));
95  auto avgIntPerXing = Scalar("avgIntPerXing", lbAverageInteractionsPerCrossing(ctx));
96 
97  fill(group, LB, avgLiveFrac, duration, avgIntPerXing);
98 
99  ATH_MSG_DEBUG("Filled LB hists");
100 
101 
102  auto evtWeight = Scalar("evtWeight", 1.0);
103  if (thisEventInfo->eventType(xAOD::EventInfo::IS_SIMULATION)) {
104  evtWeight = thisEventInfo->mcEventWeight();
105  ATH_MSG_DEBUG("Event Weight: " << evtWeight);
106  }
107 
108  //Get Electrons
109  SG::ReadHandle<xAOD::ElectronContainer> elecTES(m_ElectronContainerKey, ctx);
110  if ( ! elecTES.isValid() ) {
111  ATH_MSG_ERROR("No electron container" << m_ElectronContainerKey << " found in evtStore");
112  return StatusCode::FAILURE;
113  }
114 
115  ATH_MSG_DEBUG("ElectronContainer successfully retrieved");
116 
117 
118  //Get Muons
119 
120  SG::ReadHandle<xAOD::MuonContainer> muons(m_MuonContainerKey, ctx);
121  if (! muons.isValid() ) {
122  ATH_MSG_ERROR("evtStore() does not contain muon Collection with name "<< m_MuonContainerKey);
123  return StatusCode::FAILURE;
124  }
125 
126  ATH_MSG_DEBUG("Got muon collection!");
127 
128  std::vector<const xAOD::Electron*> goodelectrons;
129  std::vector<const xAOD::Muon*> goodmuonsZ;
130  std::vector<const xAOD::Muon*> goodmuonsTP;
131 
132  //get primary vertex info
133  const xAOD::Vertex* pVtx(0);
134  SG::ReadHandle<xAOD::VertexContainer> vertices(m_VertexContainerKey, ctx);
135  if (vertices.isValid()) {
136  ATH_MSG_DEBUG("Collection with name " << m_VertexContainerKey << " with size " << vertices->size() << " found in evtStore()");
137  for(const auto vtx : * vertices) {
138  if(vtx->vertexType()==xAOD::VxType::PriVtx) {
139  pVtx = vtx;
140  break;
141  }
142  }
143  } else {
144  ATH_MSG_WARNING("No collection with name " << m_VertexContainerKey << " found in evtStore()");
145  }
146 
147  const xAOD::Electron* leadingAllEle(0);
148  const xAOD::Electron* subleadingAllEle(0);
149  std::vector<const xAOD::Electron*> allElectrons;
150 
151 
152  // Electron Cut Flow
153  ATH_MSG_DEBUG("Start electron selection");
154 
155  auto elegroup = getGroup("electron");
156 
157  for(const auto electron : *elecTES) {
158  allElectrons.push_back(electron);
159 
160  if(goodElectrons(electron, pVtx, ctx)){
161  ATH_MSG_DEBUG("Good electron");
162 
163  auto ele_Et = Scalar("ele_Et", electron->pt()/GeV);
164  auto ele_Eta = Scalar("ele_Eta", electron->eta());
165  auto ele_Phi = Scalar("ele_Phi", electron->phi());
166  fill(elegroup, ele_Et, ele_Eta, ele_Phi, evtWeight);
167  goodelectrons.push_back(electron);
168  }
169  }
170 
171  // Muon Cut Flow
172 
173  auto muongroup = getGroup("muon");
174  ATH_MSG_DEBUG("Start muon selection");
175  static const SG::AuxElement::Accessor<float> aptc20("ptcone20");
176 
177  for (const xAOD::Muon* muon : *muons){
178  auto muTrk = (muon)->primaryTrackParticle();
179  float d0sig;
180  if (!muTrk) {
181  ATH_MSG_WARNING("No muon track! " << thisEventInfo->runNumber() << " " << thisEventInfo->eventNumber());
182  continue;
183  }
184  try {
185  d0sig = xAOD::TrackingHelpers::d0significance(muTrk, thisEventInfo->beamPosSigmaX(), thisEventInfo->beamPosSigmaY(), thisEventInfo->beamPosSigmaXY());
186  } catch (...) {
187  ATH_MSG_DEBUG("Invalid beamspot - muon");
188  try {
190  } catch (...) {
191  ATH_MSG_WARNING("Ridiculous exception thrown - muon");
192  continue;
193  }
194  }
195 
196  float ptcone20 = 0;
197  if (! aptc20.isAvailable(*muon)) {
198  ATH_MSG_WARNING("aptc20 is not available - muon");
199  } else {
200  ptcone20 = aptc20(*muon);
201  }
202 
203  float muonIso = 0.0;
204  if ((muon)->pt() != 0.0){
205  muonIso = ptcone20/((muon)->pt());
206  }
207 
208  ATH_MSG_DEBUG("Muon accept: " << static_cast<bool>(m_muonSelectionTool->accept(*muon)));
209  ATH_MSG_DEBUG("Muon pt: " << (muon)->pt() << " " << m_muonPtCut*GeV);
210  ATH_MSG_DEBUG("Muon iso: " << static_cast<bool>(muonIso < 0.1 ));
211  ATH_MSG_DEBUG("Muon d0sig: " << d0sig);
212  ATH_MSG_DEBUG("Muon Good vtx: " << pVtx);
213  if (pVtx) ATH_MSG_DEBUG("Muon z0sinth: " << std::abs((muTrk->z0()+muTrk->vz()-pVtx->z())*std::sin(muTrk->theta())) << " " << 0.5*mm);
214 
215  if (m_muonSelectionTool->accept(*muon) &&
216  ((muon)->pt() > 0.8*m_muonPtCut*GeV) &&
217  muonIso < 0.1 &&
218  std::abs(d0sig) < 3 &&
219  pVtx &&
220  std::abs((muTrk->z0()+muTrk->vz()-pVtx->z())*std::sin(muTrk->theta())) < 0.5*mm)
221  {
222 
223  goodmuonsTP.push_back(muon);
224  if (((muon)->pt() > m_muonPtCut*GeV))
225  {
226  auto muon_Pt = Scalar("muon_Pt", (muon)->pt()/GeV);
227  auto muon_Eta = Scalar("muon_Eta", (muon)->eta());
228  auto muon_Phi = Scalar("muon_Phi", (muon)->phi());
229  fill(muongroup, muon_Pt, muon_Eta, muon_Phi, evtWeight);
230  goodmuonsZ.push_back(muon);
231  }
232  }
233 
234  }
235 
236  if (isSimulation) {
237  doMuonTruthEff(goodmuonsZ, ctx);
238  }
239 
240  for (const auto iEle : allElectrons) {
241  Float_t pt = iEle->pt();
242  ATH_MSG_DEBUG("Ele pt " << pt);
243  if (!leadingAllEle || pt > leadingAllEle->pt()){
244  subleadingAllEle = leadingAllEle;
245  leadingAllEle = iEle;
246  }
247  else if (!subleadingAllEle || pt > subleadingAllEle->pt()){
248  subleadingAllEle = iEle;
249  }
250  }
251 
252  // Perform all Tag and Probe Procedures
253 
254  doMuonLooseTP(goodmuonsTP, pVtx, ctx, isSimulation, writeTTrees, evtWeight);
255  doMuonInDetTP(goodmuonsTP, pVtx, ctx, isSimulation, writeTTrees, evtWeight);
256  doEleTP(leadingAllEle, subleadingAllEle, pVtx, ctx, writeTTrees, isSimulation, evtWeight);
257  doEleContainerTP(allElectrons, goodelectrons, ctx);
258 
259  // Sort Candidates by Pt
260  const xAOD::Electron* leadingEle(0);
261  const xAOD::Electron* subleadingEle(0);
262  const xAOD::Muon* leadingMuZ(0);
263  const xAOD::Muon* subleadingMuZ(0);
264 
265  ATH_MSG_DEBUG("Beginning ele loop");
266  for (const auto iEle : goodelectrons) {
267  Float_t pt = iEle->pt();
268  ATH_MSG_DEBUG("Ele pt " << pt);
269  if (! leadingEle || pt > leadingEle->pt()) {
270  subleadingEle = leadingEle;
271  leadingEle = iEle;
272  }
273  else if (! subleadingEle || pt > subleadingEle->pt()) {
274  subleadingEle = iEle;
275  }
276  }
277  ATH_MSG_DEBUG("Done ele loop");
278 
279  ATH_MSG_DEBUG("Start mu Z loop");
280  for (const auto iMu : goodmuonsZ) {
281  Float_t pt = iMu->pt();
282  if (! leadingMuZ || pt > leadingMuZ->pt()) {
283  subleadingMuZ = leadingMuZ;
284  leadingMuZ = iMu;
285  }
286  else if (! subleadingMuZ || pt > subleadingMuZ->pt()) {
287  subleadingMuZ = iMu;
288  }
289  }
290  ATH_MSG_DEBUG("Done mu Z loop");
291 
292  // Z Mass
293  bool isZee = (goodelectrons.size() > 1);
294  bool isZmumu = (goodmuonsZ.size() > 1);
295  ATH_MSG_DEBUG("Evaluated Event");
296  auto ZeeGroup = getGroup("Zee");
297  auto ZmumuGroup = getGroup("Zmumu");
298 
299  if(isZee){
300  ATH_MSG_DEBUG("Zee found");
301  TLorentzVector Zee = (leadingEle->p4() + subleadingEle->p4());
302  auto mass = Scalar("mass", Zee.M());
303  auto Zeecharge = Scalar("Zeecharge", leadingEle->charge() + subleadingEle->charge());
304  bool passTrig = true;
305  if (m_doTrigger){
306  passTrig = trigChainsArePassed(m_Z_ee_trigger);
307  }
308  bool inMassWindow = (mass > m_zCutLow*GeV && mass < m_zCutHigh*GeV);
309  auto osel = Scalar<bool>("osel", false);
310  auto ssel = Scalar<bool>("ssel", false);
311  (Zeecharge == 0) ? (osel = true) : (ssel = true);
312  if (inMassWindow){
313  fill(ZeeGroup, Zeecharge, evtWeight);
314  ATH_MSG_DEBUG("Found a Z to ee candidate! Mass = " << mass << ", and charge = " << Zeecharge );
315  if(osel && passTrig){
316  auto eta1 = Scalar("eta1", leadingEle->caloCluster()->etaBE(2));
317  auto eta2 = Scalar("eta2", subleadingEle->caloCluster()->etaBE(2));
318  auto phi1 = Scalar("phi1", leadingEle->phi());
319  auto phi2 = Scalar("phi2", subleadingEle->phi());
320  auto pT1 = Scalar("pT1", leadingEle->pt());
321  auto pT2 = Scalar("pT2", subleadingEle->pt());
322  auto isTruth = Scalar("isTruth", false);
323 
324  if(writeTTrees){
325  isTruth = checkTruthElectron(leadingEle) && checkTruthElectron(subleadingEle);
326  }
327  fill(ZeeGroup, mass, eta1, eta2, phi1, phi2, pT1, pT2, evtWeight, LB, runNumber, eventNumber, isTruth, writeTTrees, osel);
328  }
329  if(ssel && passTrig){
330  if (!isSimulation){
331  fill(ZeeGroup, mass, LB, evtWeight, ssel);
332  }
333  }
334  if(m_doTrigger){
335  doEleTriggerTP(leadingEle, subleadingEle, ctx, writeTTrees, evtWeight, osel, ssel);
336  }
337  }
338  }
339  if (isZmumu){
340  ATH_MSG_DEBUG("Zmumu found");
341  TLorentzVector Zmumu = leadingMuZ->p4() + subleadingMuZ->p4();
342  auto mass = Scalar("mass", Zmumu.M());
343  auto Zmumucharge = Scalar("Zmumucharge", leadingMuZ->charge() + subleadingMuZ->charge());
344  // potentially ignore trigger...
345  bool oktrig = true;
346  if (m_doTrigger){
347  oktrig = trigChainsArePassed(m_Z_mm_trigger);
348  }
349  bool inMassWindow = (mass > m_zCutLow*GeV && mass < m_zCutHigh*GeV);
350  auto osmu = Scalar<bool>("osmu", false);
351  auto ssmu = Scalar<bool>("ssmu", false);
352  (Zmumucharge == 0) ? (osmu = true) : (ssmu = true);
353  if(inMassWindow){
354  fill(ZmumuGroup, Zmumucharge, evtWeight);
355  ATH_MSG_DEBUG("Found a Z to mumu candidate! Mass = " << mass << ", and charge = " << Zmumucharge);
356  if(osmu && oktrig){
357  auto eta1 = Scalar("eta1", leadingMuZ->eta());
358  auto eta2 = Scalar("eta2", subleadingMuZ->eta());
359  auto phi1 = Scalar("phi1", leadingMuZ->phi());
360  auto phi2 = Scalar("phi2", subleadingMuZ->phi());
361  auto pT1 = Scalar("pT1", leadingMuZ->pt());
362  auto pT2 = Scalar("pT2", subleadingMuZ->pt());
363  auto isTruth = Scalar("isTruth", false);
364  if (writeTTrees){
365  isTruth = checkTruthMuon(leadingMuZ) && checkTruthMuon(subleadingMuZ);
366  }
367  fill(ZmumuGroup, eta1, eta2, phi1, phi2, pT1, pT2, isTruth, evtWeight, LB, runNumber, eventNumber, mass, writeTTrees, osmu);
368  }
369  if(osmu && !oktrig){
370  ATH_MSG_DEBUG("Trigger failure!");
371  }
372  if(osmu && m_doTrigger){
373  doMuonTriggerTP(leadingMuZ, subleadingMuZ, ctx, isSimulation, writeTTrees, evtWeight);
374  }
375  if(ssmu && oktrig){
376  if (!isSimulation){
377  fill(ZmumuGroup, mass, LB, evtWeight, ssmu);
378  }
379  }
380  }
381  }
382  }
383 
384  return StatusCode::SUCCESS;
385 }
386 
387 void DQTGlobalWZFinderAlg::doEleTriggerTP(const xAOD::Electron* el1, const xAOD::Electron* el2, const EventContext& ctx, bool writeTTrees, const float evtWeight, bool osel, bool ssel) const{
388 
389  using namespace Monitored;
390 
391  SG::ReadHandle<xAOD::EventInfo> thisEventInfo { GetEventInfo(ctx) };
392 
393  auto group_EleTrigTP = getGroup("EleTrigTP");
394  auto matched = Scalar("matched", 0);
395  auto weight = Scalar("weight", evtWeight);
396  auto os = Scalar<bool>("os", osel);
397  auto ss = Scalar<bool>("ss", ssel);
398 
399  std::vector<const xAOD::Electron*> electrons{el1, el2};
400 
401  for (const auto el: electrons) {
402  for (const auto &chain: m_Z_ee_trigger) {
403  if (m_r3MatchingTool->match(*el, chain, 0.1, false)) {
404  matched++;
405  break;
406  }
407  }
408  }
409 
410  fill(group_EleTrigTP, matched, weight, os, ss);
411 
412  if (!writeTTrees){
413  return;
414  }
415 
416  for (const auto& tagel : electrons) {
417  bool matched_tag = false;
418  for (const auto &chain: m_Z_ee_trigger) {
419  if (m_r3MatchingTool->match(*tagel, chain, 0.1, false)) {
420  matched_tag = true;
421  break;
422  }
423  }
424 
425 
426  auto tagelp4(tagel->p4());
427  if (!matched_tag) continue;
428  for (const auto& probeel : electrons) {
429  if (tagel == probeel) {
430  continue;
431  }
432  auto probeelp4(probeel->p4());
433  auto mass = Scalar("mass", (tagelp4+probeelp4).M());
434  bool matched_probe = false;
435  if (mass < m_zCutLow*GeV || mass > m_zCutHigh*GeV) continue;
436 
437  auto pT = Scalar("pT", probeel->pt());
438  auto phi = Scalar("phi", probeel->phi());
439  auto eta = Scalar("eta", probeel->caloCluster()->etaBE(2));
440  auto runNumber = Scalar("runNumber", thisEventInfo->runNumber());
441  auto eventNumber = Scalar("eventNumber", thisEventInfo->eventNumber());
442  auto LB = Scalar("LB", thisEventInfo->lumiBlock());
443  auto mtype = Scalar("mtype", -1000);
444 
445  for (const auto &chain: m_Z_ee_trigger){
446  if (m_r3MatchingTool->match(*probeel, chain, 0.1, false)) {
447  matched_probe = true;
448  break;
449  }
450  }
451 
452  if (matched_probe) {
453  mtype = osel ? 0 : 1;
454  }
455  else if (!matched_probe) {
456  mtype = osel ? 2 : 3;
457  }
458 
459  if (writeTTrees){
460  fill(group_EleTrigTP, pT, phi, eta, mass, runNumber, eventNumber, LB, mtype, weight);
461  }
462  }
463  }
464 }
465 
466 void DQTGlobalWZFinderAlg::doEleTP(const xAOD::Electron* leadingAllEle, const xAOD::Electron* subleadingAllEle, const xAOD::Vertex* pVtx, const EventContext& ctx, bool writeTTrees, bool isSimulation, const float evtWeight) const{
467 
468  using namespace Monitored;
469 
470  SG::ReadHandle<xAOD::EventInfo> thisEventInfo { GetEventInfo(ctx) };
471 
472  auto group_EleTP = getGroup("EleTP");
473 
474  // first check we have both electrons
475  if(leadingAllEle && subleadingAllEle){
476 
477  // Truth matching
478  if (isSimulation) {
479  if (!(checkTruthElectron(leadingAllEle) && checkTruthElectron(subleadingAllEle))) return;
480  }
481 
482  // then get all the parameters we will need ready
483  auto Zeecharge = Scalar("Zeecharge", (leadingAllEle->charge() + subleadingAllEle->charge()));
484  auto p1(leadingAllEle->p4());
485  auto p2(subleadingAllEle->p4());
486  auto mass = Scalar("mass", (p1+p2).M());
487 
488  bool leadingPassKinematics = kinematicCuts(leadingAllEle);
489  bool subleadPassKinematics = kinematicCuts(subleadingAllEle);
490 
491  if(!leadingPassKinematics || !subleadPassKinematics) return;
492 
493  bool leading_good = goodElectrons(leadingAllEle, pVtx, ctx);
494  bool subleading_good = goodElectrons(subleadingAllEle, pVtx, ctx);
495 
496  bool leading_antigood = antiGoodElectrons(leadingAllEle, pVtx, ctx);
497  bool subleading_antigood = antiGoodElectrons(subleadingAllEle, pVtx, ctx);
498 
499  // do trigger matching
500  bool leading_trig = false;
501  for (const auto &chain: m_Z_ee_trigger) {
502  if (m_r3MatchingTool->match(*leadingAllEle, chain, 0.1, false)){
503  leading_trig = true;
504  break;
505  }
506  }
507 
508  bool subleading_trig = false;
509  for (const auto &chain: m_Z_ee_trigger) {
510  if (m_r3MatchingTool->match(*subleadingAllEle, chain, 0.1, false)){
511  subleading_trig = true;
512  break;
513  }
514  }
515 
516  bool opp_sign = (Zeecharge==0);
517 
518  bool tag_good1 = (leadingAllEle->passSelection("LHTight") && leading_trig && leading_good);
519  bool tag_good2 = (subleadingAllEle->passSelection("LHTight") && subleading_trig && subleading_good);
520 
521  fillEleEffHistos(tag_good1, subleading_good, subleading_antigood, opp_sign, mass);
522  fillEleEffHistos(tag_good2, leading_good, leading_antigood, opp_sign, mass);
523 
524  if (!writeTTrees)
525  return;
526 
527  auto pT = Scalar("pT", -1000.0);
528  auto phi = Scalar("phi", -1000.0);
529  auto eta = Scalar("eta", -1000.0);
530  auto weight = Scalar("weight", -1000.0);
531  auto runNumber = Scalar("runNumber", -1000);
532  auto eventNumber = Scalar("eventNumber", -1000);
533  auto LB = Scalar("LB", -1000);
534  auto mtype = Scalar("mtype", -1000);
535 
536  // now fill the trees
537  if(tag_good1){
538  pT = subleadingAllEle->pt();
539  phi = subleadingAllEle->phi();
540  eta = subleadingAllEle->caloCluster()->etaBE(2);
541  weight = evtWeight;
542  runNumber = thisEventInfo->runNumber();
543  eventNumber = thisEventInfo->eventNumber();
544  LB = thisEventInfo->lumiBlock();
545 
546  if(opp_sign){
547  mtype = subleading_good ? 0 : 2;
548  if(subleading_antigood)
549  mtype = 4;
550  }else{
551  mtype = subleading_good ? 1 : 3;
552  if(subleading_antigood)
553  mtype = 5;
554  }
555 
556  fill(group_EleTP, pT, phi, eta, mass, runNumber, eventNumber, LB, mtype, weight);
557  }
558 
559  if(tag_good2){
560  pT = leadingAllEle->pt();
561  phi = leadingAllEle->phi();
562  eta = leadingAllEle->caloCluster()->etaBE(2);
563  weight = evtWeight;
564  runNumber = thisEventInfo->runNumber();
565  eventNumber = thisEventInfo->eventNumber();
566  LB = thisEventInfo->lumiBlock();
567 
568  if(opp_sign){
569  if(leading_good)
570  mtype = 0;
571  if(!leading_good)
572  mtype = 2;
573  if(leading_antigood)
574  mtype = 4;
575  }else{
576  if(leading_good)
577  mtype = 1;
578  if(!leading_good)
579  mtype = 3;
580  if(leading_antigood)
581  mtype = 5;
582  }
583  }
584  fill(group_EleTP, pT, phi, eta, mass, runNumber, eventNumber, LB, mtype, weight);
585  }
586 }
587 
588 void DQTGlobalWZFinderAlg::doEleContainerTP(std::vector<const xAOD::Electron*>& allElectrons, std::vector<const xAOD::Electron*>& goodelectrons, const EventContext& ctx) const{
589 
590  using namespace Monitored;
591 
592  auto group_EleContainerTP = getGroup("EleContainerTP");
593  auto pass_kine = Scalar<bool>("pass_kine", false);
594  auto container_nomatch = Scalar<bool>("container_nomatch", false);
595 
597  if ( ! photons.isValid() ) {
598  ATH_MSG_ERROR("No photon container" << m_PhotonContainerKey << "found in evtStore");
599  return;
600  }
601 
602  ATH_MSG_DEBUG("PhotonContainer successfully retrieved");
603 
604  for (const auto& tagEl : goodelectrons) {
605  bool matched = false;
606  for (const auto &chain: m_Z_ee_trigger) {
607  if (m_r3MatchingTool->match(*tagEl, chain, 0.1, false) || ! m_doTrigger) {
608  matched=true;
609  break;
610  }
611  }
612 
613  if (!matched) continue;
614  auto tagElp4(tagEl->p4());
615 
616  if (tagEl->passSelection("LHTight")){
617  for (const auto& el2 : allElectrons){
618  if (el2 != tagEl && kinematicCuts(el2)){
619  auto probeElp4(el2->p4());
620  auto mass = Scalar("mass", (tagElp4+probeElp4).M());
621  pass_kine = true;
622  fill(group_EleContainerTP, mass, pass_kine);
623  break;
624  }
625  }
626  }
627 
628  for (const xAOD::Photon* photon : *photons) {
629  auto photonp4(photon->p4());
630  auto mass = Scalar("mass", (tagElp4+photonp4).M());
631 
632  if (!kinematicCuts(photon))
633  continue;
634 
635  for (const auto& el2 : allElectrons){
636  // slightly relax pT cut for probe electron
637  bool passKinematics = true;
638  if (el2->pt() < (m_electronEtCut-2)*GeV)
639  passKinematics = false;
640  if (std::abs(el2->caloCluster()->etaBE(2)) > 2.4)
641  passKinematics = false;
642  if (std::abs(el2->caloCluster()->etaBE(2)) > 1.37 && std::abs(el2->caloCluster()->etaBE(2)) < 1.52)
643  passKinematics = false;
644 
645  double deltaR = (el2->p4()).DeltaR(photon->p4());
646  if (!passKinematics || tagEl == el2 || deltaR < 0.1)
647  continue;
648 
649  container_nomatch = true;
650  fill(group_EleContainerTP, mass, container_nomatch);
651  break;
652  }
653  }
654  }
655 }
656 
658 
659  bool isGood = true;
660  if(particle->pt() < m_electronEtCut*GeV) isGood = false;
661 
662  if(std::abs(particle->caloCluster()->etaBE(2)) > 2.4) isGood = false;
663 
664  if(std::abs(particle->caloCluster()->etaBE(2)) > 1.37 &&
665  std::abs(particle->caloCluster()->etaBE(2)) < 1.52) isGood = false;
666 
667  return isGood;
668 }
669 
670 
671 bool DQTGlobalWZFinderAlg::goodElectrons(const xAOD::Electron* electron_itr, const xAOD::Vertex* pVtx, const EventContext& ctx) const{
672 
673  using namespace Monitored;
674 
675  SG::ReadHandle<xAOD::EventInfo> thisEventInfo { GetEventInfo(ctx) };
676 
677  bool isGood = false;
678 
679  static const SG::AuxElement::Accessor<float> aptc20("ptcone20");
680  float ptcone20 = 0;
681  if (! aptc20.isAvailable(*electron_itr)) {
682  ATH_MSG_WARNING("aptc20 is not available - goodElectron");
683  } else {
684  ptcone20 = aptc20(*electron_itr);
685  }
686 
687  float eleIso = 0.0;
688  if ((electron_itr)->pt() != 0.0){
689  eleIso = ptcone20/((electron_itr)->pt());
690  }
691 
692  bool passSel = electron_itr->passSelection("LHMedium");
693  auto elTrk = (electron_itr)->trackParticle();
694 
695  if (!elTrk) {
696  return false;
697  }
698  float d0sig;
699  try {
700  d0sig = xAOD::TrackingHelpers::d0significance(elTrk, thisEventInfo->beamPosSigmaX(), thisEventInfo->beamPosSigmaY(), thisEventInfo->beamPosSigmaXY());
701  } catch (...) {
702  ATH_MSG_DEBUG("Invalid beamspot - electron");
703  try {
705  } catch (...) {
706  ATH_MSG_WARNING("Ridiculous exception thrown - electron");
707  return false;
708  }
709  }
710 
711  if ( ((electron_itr)->pt() > m_electronEtCut*GeV) &&
712  std::abs(electron_itr->caloCluster()->etaBE(2)) < 2.4 &&
713  passSel &&
714  (eleIso < 0.1) &&
715  std::abs(d0sig) < 5 &&
716  pVtx &&
717  std::abs((elTrk->z0()+elTrk->vz()-pVtx->z())*std::sin(elTrk->theta())) < 0.5*mm)
718  { // electron dead zone
719  if (std::abs((electron_itr)->caloCluster()->etaBE(2)) > 1.37 && std::abs((electron_itr)->caloCluster()->etaBE(2)) < 1.52 ){
720  isGood = false;
721  } else{
722  isGood = true;
723  }
724  }
725 
726  return isGood;
727 }
728 
729 bool DQTGlobalWZFinderAlg::antiGoodElectrons(const xAOD::Electron* electron_itr, const xAOD::Vertex* pVtx, const EventContext& ctx) const{
730 
731  using namespace Monitored;
732 
733  SG::ReadHandle<xAOD::EventInfo> thisEventInfo { GetEventInfo(ctx) };
734 
735  bool antiGood = false;
736 
737  static const SG::AuxElement::Accessor<float> aptc20("ptcone20");
738  float ptcone20 = 0;
739  if (! aptc20.isAvailable(*electron_itr)) {
740  ATH_MSG_WARNING("aptc20 is not available - antiGoodElectron");
741  } else {
742  ptcone20 = aptc20(*electron_itr);
743  }
744 
745  float eleIso = 0.0;
746  if ((electron_itr)->pt() != 0.0){
747  eleIso = ptcone20/((electron_itr)->pt());
748  }
749 
750  bool passID = electron_itr->passSelection("LHLoose");
751  bool passIso = false;
752  if(eleIso < 0.1) passIso = true;
753  auto elTrk = (electron_itr)->trackParticle();
754 
755  if (!elTrk) {
756  return false;
757  }
758  float d0sig;
759  try {
760  d0sig = xAOD::TrackingHelpers::d0significance(elTrk, thisEventInfo->beamPosSigmaX(), thisEventInfo->beamPosSigmaY(), thisEventInfo->beamPosSigmaXY());
761  } catch (...) {
762  ATH_MSG_DEBUG("Invalid beamspot - electron");
763  try {
765  } catch (...) {
766  ATH_MSG_WARNING("Ridiculous exception thrown - electron");
767  return false;
768  }
769  }
770 
771  // pass basic selection, except ID+Isolation
772  if (((electron_itr)->pt() > m_electronEtCut*GeV) &&
773  std::abs(electron_itr->caloCluster()->etaBE(2)) < 2.4 &&
774  std::abs(d0sig) < 5 &&
775  pVtx &&
776  std::abs((elTrk->z0()+elTrk->vz()-pVtx->z())*std::sin(elTrk->theta())) < 0.5*mm)
777  {
778  if(std::abs((electron_itr)->caloCluster()->etaBE(2)) > 1.37 && std::abs((electron_itr)->caloCluster()->etaBE(2)) < 1.52){
779  antiGood = false;
780 
781  }else{
782  if(!passID && !passIso) antiGood = true;
783  }
784  }
785 
786  return antiGood;
787 }
788 
789 
790 //compute trigger efficiencies
791 void DQTGlobalWZFinderAlg::doMuonTriggerTP(const xAOD::Muon* mu1, const xAOD::Muon* mu2, const EventContext& ctx, bool isSimulation, bool writeTTrees, const float evtWeight) const{
792  //algorithm: plot # events with zero, one or two SL triggers
793  //zero triggers for MC closure checks
794 
795  using namespace Monitored;
796 
797  SG::ReadHandle<xAOD::EventInfo> thisEventInfo { GetEventInfo(ctx) };
798 
799  auto group_MuonTriggerTP = getGroup("MuonTriggerTP");
800  auto do_BCID = Scalar("do_BCID", false);
801  auto isOS = Scalar("isOS", false);
802  auto matched = Scalar("matched", 0);
803  auto weight = Scalar("weight", evtWeight);
804  std::vector<const xAOD::Muon*> muons{mu1, mu2};
805 
806  //Truth matching
807  if (isSimulation) {
808  int truthMatching = 0;
809  for (const auto mu: muons) {
810  if (checkTruthMuon(mu)) {
811  truthMatching++;
812  }
813  }
814  if (truthMatching < 2) return;
815  }
816 
817  for (const auto mu: muons) {
818  for (const auto &chain: m_Z_mm_trigger) {
819  if (m_r3MatchingTool->match(*mu, chain, 0.1, false)) {
820  matched++;
821  break;
822  }
823  }
824  }
825  fill(group_MuonTriggerTP, matched, weight);
826 
827  for (const auto& tagmu : muons) {
828  bool matched_tag = false;
829  for (const auto &chain: m_Z_mm_trigger) {
830  if (m_r3MatchingTool->match(*tagmu, chain, 0.1, false)) {
831  matched_tag=true;
832  break;
833  }
834  }
835  auto tagmup4(tagmu->p4());
836  if (!matched_tag) continue;
837 
838  for (const auto& probemu : muons) {
839  if (tagmu == probemu) {
840  continue;
841  }
842  auto probemup4(probemu->p4());
843  auto mass = Scalar("mass", (tagmup4+probemup4).M());
844  bool matched_probe = false;
845  if (mass < m_zCutLow*GeV || mass > m_zCutHigh*GeV) continue;
846 
847  auto pT = Scalar("pT", probemu->pt());
848  auto eta = Scalar("eta", probemu->eta());
849  auto phi = Scalar("phi", probemu->phi());
850  auto isTruth = Scalar("isTruth", checkTruthMuon(probemu));
851  auto mtype = Scalar("mtype", -1000);
852  auto runNumber = Scalar("runNumber", thisEventInfo->runNumber());
853  auto eventNumber = Scalar("eventNumber", thisEventInfo->eventNumber());
854  auto LB = Scalar("LB", thisEventInfo->lumiBlock());
855 
856  if (!m_doTrigger){
857  ATH_MSG_WARNING("Warning, the m_doTrigger activated");
858  }
859 
860  for (const auto &chain: m_Z_mm_trigger) {
861  if (m_r3MatchingTool->match(*probemu, chain, 0.1, false)) {
862  matched_probe=true;
863  break;
864  }
865  }
866 
867  if (matched_probe) {
868  if (probemu->charge() != tagmu->charge()) {
869  mtype = 0;
870  }
871  else {
872  mtype = 1;
873  }
874  break;
875  }
876 
877 
878  else if (!matched_probe) {
879  if (probemu->charge() != tagmu->charge()) {
880  mtype = 2;
881  }
882  else {
883  mtype = 3;
884  }
885  }
886  if (writeTTrees){
887  fill(group_MuonTriggerTP, pT, eta, phi, mass, isTruth, runNumber, LB, eventNumber, mtype, weight);
888  }
889  }
890  }
891 }
892 
893 void DQTGlobalWZFinderAlg::doMuonTruthEff(std::vector<const xAOD::Muon*>& goodmuonsZ, const EventContext& ctx) const{
895  auto group_MuonTruthEff = getGroup("MuonTruthEff");
896  if (! vtruth.isValid() ) {
897  ATH_MSG_WARNING("No muon truth particles");
898  return;
899  }
900  auto match = Monitored::Scalar("match", 0);
901  for (const xAOD::TruthParticle* truthmu : *vtruth) {
902  if (truthmu->abseta() > m_muonMaxEta || truthmu->pt() < m_muonPtCut*GeV) {
903  continue;
904  }
905  TLorentzVector truthp4(truthmu->p4());
906  match = 0;
907  for (const auto& foundmu : goodmuonsZ) {
908  if (foundmu->p4().DeltaR(truthp4) < 0.05) {
909  match = 1;
910  break;
911  }
912  }
913  fill(group_MuonTruthEff, match);
914  }
915 
916 }
917 
918 
919 
920 void DQTGlobalWZFinderAlg::doMuonLooseTP(std::vector<const xAOD::Muon*>& goodmuonsTP, const xAOD::Vertex* pVtx, const EventContext& ctx, bool isSimulation, bool writeTTrees, const float evtWeight) const{
921 
922  using namespace Monitored;
923 
924  auto group_MuonLooseTP = getGroup("MuonLooseTP");
925  auto osmatch = Scalar<bool>("osmatch", false);
926  auto ssmatch = Scalar<bool>("ssmatch", false);
927  auto osnomatch = Scalar<bool>("osnomatch", false);
928  auto ssnomatch = Scalar<bool>("ssnomatch", false);
929 
930  SG::ReadHandle<xAOD::EventInfo> thisEventInfo { GetEventInfo(ctx) };
931 
933 
934  const xAOD::TrackParticleContainer* idTracks = idTracks_container_handle.cptr();
935 
936  if (not idTracks) {
937  ATH_MSG_FATAL("Unable to retrieve ID tacks to do muon T&P");
938  return;
939  }
940 
941  for (const auto& tagmu : goodmuonsTP) {
942 
943  // Truth matching
944  if (isSimulation) {
945  if (!checkTruthMuon(tagmu)) continue;
946  }
947 
948  // only consider trigger-matched tags to avoid bias on probes
949  bool matched = false;
950  for (const auto &chain: m_Z_mm_trigger) {
951  if (m_r3MatchingTool->match(*tagmu, chain, 0.1, false) || ! m_doTrigger) {
952  matched=true;
953  break;
954  }
955  }
956  if (!matched) continue;
957  auto tagmup4(tagmu->p4());
958  for (const auto* trk : *idTracks) {
959 
960  // Truth matching
961  if (isSimulation) {
962  if (!checkTruthTrack(trk)) continue;
963  }
964 
965  if (trk->pt() < m_muonPtCut*GeV || std::abs(trk->eta()) > m_muonMaxEta)
966  continue;
967  if (std::abs((trk->z0()+trk->vz()-pVtx->z())*std::sin(trk->theta())) > 2*mm) continue;
968 
969  auto trkp4(trk->p4());
970  auto mass = Scalar("mass", (tagmup4+trkp4).M());
971  if (mass < m_zCutLow*GeV || mass > m_zCutHigh*GeV) continue;
972  auto pT = Scalar("pT", trk->pt());
973  auto phi = Scalar("phi", trk->phi());
974  auto eta = Scalar("eta", trk->eta());
975  auto isTruth = Scalar("isTruth", checkTruthTrack(trk));
976  auto runNumber = Scalar<int>("runNumber", thisEventInfo->runNumber());
977  auto eventNumber = Scalar("eventNumber", thisEventInfo->eventNumber());
978  auto mtype = Scalar("mtype", -1000);
979  auto LB = Scalar("LB", thisEventInfo->lumiBlock());
980  auto weight = Scalar("weight", evtWeight);
981 
982  bool opp_sign = (trk->charge() != tagmu->charge());
983  bool matched = false;
984  for (const auto& mu2: goodmuonsTP) {
985  if (tagmu == mu2) continue;
986  auto dR = Scalar("dR", trkp4.DeltaR(mu2->p4()));
987  auto dPT = Scalar("dPT", ((mu2->p4()).Pt() - trkp4.Pt()));
988 
989  if (std::abs(dPT) < 10000 && dR < 0.05) {
990  matched = true;
991  break;
992  }
993  }
994 
995  osmatch = false;
996  ssmatch = false;
997  osnomatch = false;
998  ssnomatch = false;
999 
1000  if (matched){
1001  mtype = (trk->charge() != tagmu->charge()) ? 0 : 1;
1002  if (opp_sign) {
1003  osmatch = true;
1004  } else {
1005  ssmatch = true;
1006  }
1007  }
1008  else {
1009  mtype = (trk->charge() != tagmu->charge()) ? 2 : 3;
1010  if (opp_sign) {
1011  osnomatch = true;
1012  } else {
1013  ssnomatch = true;
1014  }
1015  }
1016  if (writeTTrees){
1017  fill(group_MuonLooseTP, pT, phi, eta, mass, isTruth, runNumber, LB, eventNumber, mtype, weight);
1018  }
1019  fill(group_MuonLooseTP, mass, osmatch, ssmatch, osnomatch, ssnomatch);
1020  }
1021  }
1022 }
1023 
1024 void DQTGlobalWZFinderAlg::doMuonInDetTP(std::vector<const xAOD::Muon*>& goodmuonsZ, const xAOD::Vertex* pVtx, const EventContext& ctx, bool isSimulation, bool writeTTrees, const float evtWeight) const{
1025 
1026  using namespace Monitored;
1027 
1028  if (isSimulation) {
1029  int truthMatched = 0;
1030  for (const auto mu: goodmuonsZ) {
1031  if (checkTruthMuon(mu) == true) {
1032  truthMatched++;
1033  }
1034  }
1035  if (truthMatched < 2) return;
1036  }
1037 
1038  auto group_MuonInDetTP = getGroup("MuonInDetTP");
1039  auto osmatch = Scalar<bool>("osmatch", false);
1040  auto ssmatch = Scalar<bool>("ssmatch", false);
1041  auto osnomatch = Scalar<bool>("osnomatch", false);
1042  auto ssnomatch = Scalar<bool>("ssnomatch", false);
1043 
1044  SG::ReadHandle<xAOD::EventInfo> thisEventInfo { GetEventInfo(ctx) };
1045 
1048 
1049  const xAOD::TrackParticleContainer* idTracks = idTracks_container_handle.cptr();
1050  const xAOD::TrackParticleContainer* msTracks = msTracks_container_handle.cptr();
1051 
1052  if (not idTracks) {
1053  ATH_MSG_FATAL("Unable to retrieve ID tracks to do muon T&P");
1054  }
1055  if (not msTracks) {
1056  ATH_MSG_FATAL("Unable to retrieve MS tracks to do muon T&P");
1057  }
1058 
1059  for (const auto& tagmu : goodmuonsZ) {
1060 
1061  bool matched = false;
1062  for (const auto &chain: m_Z_mm_trigger) {
1063  if (m_r3MatchingTool->match(*tagmu, chain, 0.1, false) || ! m_doTrigger) {
1064  matched=true;
1065  break;
1066  }
1067  }
1068  if (!matched) continue;
1069  auto tagmup4(tagmu->p4());
1070  // For Every MS track....
1071  for (const xAOD::TrackParticle* trk : *msTracks) {
1072  if (trk->pt() < m_muonPtCut*GeV || std::abs(trk->eta()) > m_muonMaxEta)
1073  continue;
1074  if (std::abs((trk->z0()+trk->vz()-pVtx->z())*std::sin(trk->theta())) > 2*mm)
1075  continue;
1076  auto trkp4(trk->p4());
1077  auto mass = Scalar("mass", (tagmup4+trkp4).M());
1078  bool matched = false;
1079 
1080  if (mass < m_zCutLow*GeV || mass > m_zCutHigh*GeV) continue;
1081 
1082  auto pT = Scalar("pT", trk->pt());
1083  auto phi = Scalar("phi", trk->phi());
1084  auto eta = Scalar("eta", trk->eta());
1085  auto isTruth = Scalar("isTruth", checkTruthTrack(trk));
1086  auto mtype = Scalar("mtype", -1000);
1087  auto runNumber = Scalar("runNumber", thisEventInfo->runNumber());
1088  auto eventNumber = Scalar("eventNumber", thisEventInfo->eventNumber());
1089  auto weight = Scalar("weight", evtWeight);
1090  auto LB = Scalar("LB", thisEventInfo->lumiBlock());
1091 
1092  // for all ID tracks
1093  for (const xAOD::TrackParticle* mu2 : *idTracks) {
1094  auto idtrkp4(mu2->p4());
1095  auto mstrkp4(trk->p4());
1096 
1097  auto dR = Scalar("dR", idtrkp4.DeltaR(mstrkp4));
1098  auto dPT = Scalar("dPT", mstrkp4.Pt() - idtrkp4.Pt());
1099 
1100  //Currently using magic numbers tuned by eye, may want to fix in the future...
1101  if (std::abs(dPT) < 10000 && dR < 0.05){
1102  matched = true;
1103  break;
1104  }
1105  }
1106 
1107  if (matched){
1108  (trk->charge() != tagmu->charge()) ? osmatch = true : ssmatch = true;
1109  mtype = (trk->charge() != tagmu->charge()) ? 0 : 1;
1110  if (writeTTrees) {
1111  fill(group_MuonInDetTP, pT, eta, phi, mass, mtype, isTruth, runNumber, LB, eventNumber, weight);
1112  }
1113  fill(group_MuonInDetTP, mass, osmatch, ssmatch);
1114  } else {
1115  (trk->charge() != tagmu->charge()) ? osnomatch = true : ssnomatch = true;
1116  mtype = (trk->charge() != tagmu->charge()) ? 2 : 3;
1117  if (writeTTrees) {
1118  fill(group_MuonInDetTP, pT, eta, phi, mass, mtype, isTruth, runNumber, LB, eventNumber, weight);
1119  }
1120  fill(group_MuonInDetTP, mass, osnomatch, ssnomatch);
1121  }
1122  }
1123  }
1124 }
1125 
1127 
1128  using namespace MCTruthPartClassifier;
1129 
1130  // Check if input electron originates from a ZBoson, following EGamma recipe
1131  bool truthMatched = false;
1132 
1133  std::pair<unsigned int, unsigned int> res;
1134 
1136  if( lastElTruth ){
1137  res=m_truthClassifier->particleTruthClassifier(lastElTruth);
1138 
1139  unsigned int iTypeOfPart = res.first;
1140  unsigned int iPartOrig = res.second;
1141 
1142  if((iTypeOfPart == MCTruthPartClassifier::IsoElectron && iPartOrig == MCTruthPartClassifier::ZBoson) || (iPartOrig == MCTruthPartClassifier::FSRPhot)){
1143  truthMatched = true;
1144  }
1145  }
1146 
1147  return truthMatched;
1148 
1149 }
1150 
1152 
1153  using namespace MCTruthPartClassifier;
1154 
1155  // Check if input muon originates from a ZBoson
1156  bool truthMatched = false;
1157 
1158  std::pair<unsigned int, unsigned int> res;
1159  ParticleDef partDef;
1160 
1161  res=m_truthClassifier->particleTruthClassifier(muon);
1162 
1163  unsigned int iTypeOfPart = res.first;
1164  unsigned int iPartOrig = res.second;
1165 
1166  auto muTrk = muon->primaryTrackParticle();
1167 
1168  const auto* thePart = m_truthClassifier->getGenPart(muTrk);
1169 
1170  if(thePart){
1171  if(iTypeOfPart == MCTruthPartClassifier::IsoMuon && iPartOrig == MCTruthPartClassifier::ZBoson){
1172  truthMatched = true;
1173  }
1174  }
1175 
1176  return truthMatched;
1177 
1178 }
1179 
1181 
1182  using namespace MCTruthPartClassifier;
1183 
1184  // Check if input track originates from a Z boson
1185  bool truthMatched = false;
1186 
1187  std::pair<unsigned int, unsigned int> res;
1188  ParticleDef partDef;
1189 
1190  res=m_truthClassifier->particleTruthClassifier(trk);
1191 
1192  unsigned int iTypeOfPart = res.first;
1193  unsigned int iPartOrig = res.second;
1194 
1195  const auto* thePart = m_truthClassifier->getGenPart(trk);
1196 
1197  if(thePart){
1198  if(iTypeOfPart == MCTruthPartClassifier::IsoMuon && iPartOrig == MCTruthPartClassifier::ZBoson){
1199  truthMatched = true;
1200  }
1201  }
1202 
1203  return truthMatched;
1204 
1205 }
1206 
1207 
1208 void DQTGlobalWZFinderAlg::fillEleEffHistos(bool tag_good, bool probe_good, bool probe_anti_good, bool os, double el_mass) const{
1209 
1210  using namespace Monitored;
1211 
1212  if(!tag_good)
1213  return;
1214 
1215  auto group_EleTP = getGroup("EleTP");
1216  auto mass = Scalar("mass", el_mass);
1217  auto good_os = Scalar("good_os", false);
1218  auto good_ss = Scalar("good_ss", false);
1219  auto bad_os = Scalar("bad_os", false);
1220  auto bad_ss = Scalar("bad_ss", false);
1221  auto template_os = Scalar("template_os", false);
1222  auto template_ss = Scalar("template_ss", false);
1223 
1224  if(os){
1225  if(probe_good) good_os = true;
1226  else bad_os = true;
1227  if(probe_anti_good) template_os = true;
1228  fill(group_EleTP, mass, good_os, bad_os, template_os);
1229  }else{
1230  if(probe_good) good_ss = true;
1231  else bad_ss = true;
1232  if(probe_anti_good) template_ss = true;
1233  fill(group_EleTP, mass, good_ss, bad_ss, template_ss);
1234  }
1235 }
DQTGlobalWZFinderAlg::doMuonTruthEff
void doMuonTruthEff(std::vector< const xAOD::Muon * > &goodmuonsZ, const EventContext &ctx) const
Definition: DQTGlobalWZFinderAlg.cxx:893
CalculateHighPtTerm.pT
pT
Definition: ICHEP2016/CalculateHighPtTerm.py:57
xAOD::muon
@ muon
Definition: TrackingPrimitives.h:195
AthMonitorAlgorithm::dataType
DataType_t dataType() const
Accessor functions for the data type.
Definition: AthMonitorAlgorithm.h:221
ATH_MSG_FATAL
#define ATH_MSG_FATAL(x)
Definition: AthMsgStreamMacros.h:34
Trk::ParticleSwitcher::particle
constexpr ParticleHypothesis particle[PARTICLEHYPOTHESES]
the array of masses
Definition: ParticleHypothesis.h:76
xAOD::Electron_v1::charge
float charge() const
Obtain the charge of the object.
DQTGlobalWZFinderAlg::m_MuonContainerKey
SG::ReadHandleKey< xAOD::MuonContainer > m_MuonContainerKey
Definition: DQTGlobalWZFinderAlg.h:93
runLayerRecalibration.chain
chain
Definition: runLayerRecalibration.py:175
DQTGlobalWZFinderAlg::fillEleEffHistos
void fillEleEffHistos(bool tag_good, bool probe_good, bool probe_anti_good, bool os, double el_mass) const
Definition: DQTGlobalWZFinderAlg.cxx:1208
ParticleGun_SamplingFraction.eta2
eta2
Definition: ParticleGun_SamplingFraction.py:96
PowhegControl_ttHplus_NLO.ss
ss
Definition: PowhegControl_ttHplus_NLO.py:83
TrackParticlexAODHelpers.h
phi
Scalar phi() const
phi method
Definition: AmgMatrixBasePlugin.h:64
DQTGlobalWZFinderAlg::doMuonLooseTP
void doMuonLooseTP(std::vector< const xAOD::Muon * > &goodmuonsZ, const xAOD::Vertex *pVtx, const EventContext &ctx, bool isSimulation, bool writeTTrees, const float evtWeight) const
Definition: DQTGlobalWZFinderAlg.cxx:920
SG::ReadHandle::cptr
const_pointer_type cptr()
Dereference the pointer.
SG::Accessor
Helper class to provide type-safe access to aux data.
Definition: Control/AthContainers/AthContainers/Accessor.h:66
xAOD::Muon_v1::p4
virtual FourMom_t p4() const
The full 4-momentum of the particle.
Definition: Muon_v1.cxx:79
eta
Scalar eta() const
pseudorapidity method
Definition: AmgMatrixBasePlugin.h:79
SG::ReadHandle
Definition: StoreGate/StoreGate/ReadHandle.h:70
DQTGlobalWZFinderAlg::fillHistograms
virtual StatusCode fillHistograms(const EventContext &ctx) const override
adds event to the monitoring histograms
Definition: DQTGlobalWZFinderAlg.cxx:68
xAOD::Muon_v1::phi
virtual double phi() const
The azimuthal angle ( ) of the particle.
DQTGlobalWZFinderAlg::m_Z_mm_trigger
Gaudi::Property< std::vector< std::string > > m_Z_mm_trigger
Definition: DQTGlobalWZFinderAlg.h:61
met::DeltaR
@ DeltaR
Definition: METRecoCommon.h:11
DQTGlobalWZFinderAlg::doMuonTriggerTP
void doMuonTriggerTP(const xAOD::Muon *mu1, const xAOD::Muon *mu2, const EventContext &ctx, bool isSimulation, bool writeTTrees, const float evtWeight) const
Definition: DQTGlobalWZFinderAlg.cxx:791
xAOD::TrackingHelpers::d0significance
double d0significance(const xAOD::TrackParticle *tp, double d0_uncert_beam_spot_2)
Definition: TrackParticlexAODHelpers.cxx:42
xAOD::Muon_v1::eta
virtual double eta() const
The pseudorapidity ( ) of the particle.
test_pyathena.pt
pt
Definition: test_pyathena.py:11
DQTGlobalWZFinderAlg::checkTruthElectron
bool checkTruthElectron(const xAOD::Electron *electron) const
Definition: DQTGlobalWZFinderAlg.cxx:1126
xAOD::Iso::ptcone20
@ ptcone20
Track isolation.
Definition: IsolationType.h:40
DQTGlobalWZFinderAlg::m_Z_ee_trigger
Gaudi::Property< std::vector< std::string > > m_Z_ee_trigger
Definition: DQTGlobalWZFinderAlg.h:60
DQTGlobalWZFinderAlg::kinematicCuts
bool kinematicCuts(const xAOD::Egamma *particle) const
Definition: DQTGlobalWZFinderAlg.cxx:657
xAOD::eta1
setEt setPhi setE277 setWeta2 eta1
Definition: TrigEMCluster_v1.cxx:41
xAOD::Egamma_v1::p4
virtual FourMom_t p4() const override final
The full 4-momentum of the particle as a TLoretzVector.
Definition: Egamma_v1.cxx:98
DQTGlobalWZFinderAlg::initialize
virtual StatusCode initialize() override
initialize
Definition: DQTGlobalWZFinderAlg.cxx:45
xAOD::Egamma_v1
Definition: Egamma_v1.h:56
DQTGlobalWZFinderAlg::m_electronEtCut
Gaudi::Property< float_t > m_electronEtCut
Definition: DQTGlobalWZFinderAlg.h:54
ZBoson
@ ZBoson
Definition: TruthClasses.h:67
pool::getGroup
std::string getGroup(const std::string &encoded)
xAOD::EventInfo_v1::IS_SIMULATION
@ IS_SIMULATION
true: simulation, false: data
Definition: EventInfo_v1.h:151
DQTGlobalWZFinderAlg::m_isoMuonContainerKey
SG::ReadDecorHandleKeyArray< xAOD::MuonContainer > m_isoMuonContainerKey
Definition: DQTGlobalWZFinderAlg.h:106
xAOD::Muon_v1
Class describing a Muon.
Definition: Muon_v1.h:38
dqt_zlumi_pandas.mass
mass
Definition: dqt_zlumi_pandas.py:170
xAOD::EgammaHelpers::getBkgElectronMother
const xAOD::TruthParticle * getBkgElectronMother(const xAOD::Electron *el, const bool allTheWayBack=true)
Helper wrapper function for calling the function below that accepts truth input.
Definition: EgammaTruthxAODHelpers.cxx:91
FSRPhot
@ FSRPhot
Definition: TruthClasses.h:96
dqt_zlumi_pandas.weight
int weight
Definition: dqt_zlumi_pandas.py:200
AthMonitorAlgorithm
Base class for Athena Monitoring Algorithms.
Definition: AthMonitorAlgorithm.h:36
xAOD::Muon_v1::charge
float charge() const
xAOD::CaloCluster_v1::etaBE
float etaBE(const unsigned layer) const
Get the eta in one layer of the EM Calo.
Definition: CaloCluster_v1.cxx:644
DQTGlobalWZFinderAlg::doEleTP
void doEleTP(const xAOD::Electron *leadingAllEle, const xAOD::Electron *subleadingAllEle, const xAOD::Vertex *pVtx, const EventContext &ctx, bool writeTTrees, bool isSimulation, const float evtWeight) const
Definition: DQTGlobalWZFinderAlg.cxx:466
DQTGlobalWZFinderAlg::checkTruthMuon
bool checkTruthMuon(const xAOD::Muon *muon) const
Definition: DQTGlobalWZFinderAlg.cxx:1151
DQTGlobalWZFinderAlg::m_TruthParticleContainerKey
SG::ReadHandleKey< xAOD::TruthParticleContainer > m_TruthParticleContainerKey
Definition: DQTGlobalWZFinderAlg.h:99
MCTruthClassifierDefs.h
DQTGlobalWZFinderAlg::doMuonInDetTP
void doMuonInDetTP(std::vector< const xAOD::Muon * > &goodmuonsZ, const xAOD::Vertex *pVtx, const EventContext &ctx, bool isSimulation, bool writeTTrees, const float evtWeight) const
Definition: DQTGlobalWZFinderAlg.cxx:1024
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
DQTGlobalWZFinderAlg::m_truthClassifier
ToolHandle< IMCTruthClassifier > m_truthClassifier
Definition: DQTGlobalWZFinderAlg.h:88
DQTGlobalWZFinderAlg::antiGoodElectrons
bool antiGoodElectrons(const xAOD::Electron *electron_itr, const xAOD::Vertex *pVtx, const EventContext &ctx) const
Definition: DQTGlobalWZFinderAlg.cxx:729
Monitored
Generic monitoring tool for athena components.
Definition: GenericMonitoringTool.h:30
DQTGlobalWZFinderAlg::doEleContainerTP
void doEleContainerTP(std::vector< const xAOD::Electron * > &allElectrons, std::vector< const xAOD::Electron * > &goodelectrons, const EventContext &ctx) const
Definition: DQTGlobalWZFinderAlg.cxx:588
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
xAOD::TruthParticle_v1
Class describing a truth particle in the MC record.
Definition: TruthParticle_v1.h:41
DQTGlobalWZFinderAlg::m_muonSelectionTool
ToolHandle< CP::IMuonSelectionTool > m_muonSelectionTool
Definition: DQTGlobalWZFinderAlg.h:85
AthAlgTool.h
DQTGlobalWZFinderAlg::doEleTriggerTP
void doEleTriggerTP(const xAOD::Electron *el1, const xAOD::Electron *el2, const EventContext &ctx, bool writeTTrees, const float evtWeight, bool osel, bool ssel) const
Definition: DQTGlobalWZFinderAlg.cxx:387
xAOD::Egamma_v1::caloCluster
const xAOD::CaloCluster * caloCluster(size_t index=0) const
Pointer to the xAOD::CaloCluster/s that define the electron candidate.
Definition: Egamma_v1.cxx:388
res
std::pair< std::vector< unsigned int >, bool > res
Definition: JetGroupProductTest.cxx:14
xAOD::VxType::PriVtx
@ PriVtx
Primary vertex.
Definition: TrackingPrimitives.h:571
DQTGlobalWZFinderAlg::m_zCutHigh
Gaudi::Property< float_t > m_zCutHigh
Definition: DQTGlobalWZFinderAlg.h:57
plotIsoValidation.el
el
Definition: plotIsoValidation.py:197
xAOD::Muon_v1::pt
virtual double pt() const
The transverse momentum ( ) of the particle.
DQTGlobalWZFinderAlg::m_PhotonContainerKey
SG::ReadHandleKey< xAOD::PhotonContainer > m_PhotonContainerKey
Definition: DQTGlobalWZFinderAlg.h:95
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
xAOD::Egamma_v1::phi
virtual double phi() const override final
The azimuthal angle ( ) of the particle.
Definition: Egamma_v1.cxx:75
xAOD::eventNumber
eventNumber
Definition: EventInfo_v1.cxx:124
xAOD::Vertex_v1::z
float z() const
Returns the z position.
AthMonitorAlgorithm::fill
void fill(const ToolHandle< GenericMonitoringTool > &groupHandle, std::vector< std::reference_wrapper< Monitored::IMonitoredVariable >> &&variables) const
Fills a vector of variables to a group by reference.
DQTGlobalWZFinderAlg::m_ElectronContainerKey
SG::ReadHandleKey< xAOD::ElectronContainer > m_ElectronContainerKey
Definition: DQTGlobalWZFinderAlg.h:91
DQTGlobalWZFinderAlg::m_r3MatchingTool
ToolHandle< Trig::R3MatchingTool > m_r3MatchingTool
Definition: DQTGlobalWZFinderAlg.h:86
SG::VarHandleKey::initialize
StatusCode initialize(bool used=true)
If this object is used as a property, then this should be called during the initialize phase.
Definition: AthToolSupport/AsgDataHandles/Root/VarHandleKey.cxx:103
IsoMuon
@ IsoMuon
Definition: TruthClasses.h:15
python.BuildSignatureFlags.muonIso
AthConfigFlags muonIso(AthConfigFlags flags, str instanceName, str recoMode)
Definition: BuildSignatureFlags.py:292
top::isSimulation
bool isSimulation(const top::Event &event)
Is this event MC simulation (True) or data (False)?
Definition: EventTools.cxx:52
DQTGlobalWZFinderAlg::m_idTrackParticleContainerKey
SG::ReadHandleKey< xAOD::TrackParticleContainer > m_idTrackParticleContainerKey
Definition: DQTGlobalWZFinderAlg.h:101
ParticleDef
Definition: TruthClasses.h:122
AthMonitorAlgorithm::GetEventInfo
SG::ReadHandle< xAOD::EventInfo > GetEventInfo(const EventContext &) const
Return a ReadHandle for an EventInfo object (get run/event numbers, etc.)
Definition: AthMonitorAlgorithm.cxx:107
DataVector< xAOD::TrackParticle_v1 >
Vertex.h
Monitored::fill
void fill(const ToolHandle< GenericMonitoringTool > &tool, T &&... variables)
Definition: MonitoredGroup.h:122
ReadFromCoolCompare.os
os
Definition: ReadFromCoolCompare.py:231
SG::ReadHandle::isValid
virtual bool isValid() override final
Can the handle be successfully dereferenced?
PixelAthHitMonAlgCfg.duration
duration
Definition: PixelAthHitMonAlgCfg.py:152
DQTGlobalWZFinderAlg.h
TruthVertex.h
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:195
DQTGlobalWZFinderAlg::m_muonPtCut
Gaudi::Property< float_t > m_muonPtCut
Definition: DQTGlobalWZFinderAlg.h:55
python.ElectronD3PDObject.matched
matched
Definition: ElectronD3PDObject.py:138
xAOD::Electron_v1
Definition: Electron_v1.h:34
AthMonitorAlgorithm::initialize
virtual StatusCode initialize() override
initialize
Definition: AthMonitorAlgorithm.cxx:18
python.SystemOfUnits.mm
int mm
Definition: SystemOfUnits.py:83
DeMoAtlasDataLoss.runNumber
string runNumber
Definition: DeMoAtlasDataLoss.py:64
DQTGlobalWZFinderAlg::checkTruthTrack
bool checkTruthTrack(const xAOD::TrackParticle *trk) const
Definition: DQTGlobalWZFinderAlg.cxx:1180
xAOD::photon
@ photon
Definition: TrackingPrimitives.h:199
DQTGlobalWZFinderAlg::m_isoElectronContainerKey
SG::ReadDecorHandleKeyArray< xAOD::ElectronContainer > m_isoElectronContainerKey
Definition: DQTGlobalWZFinderAlg.h:108
CaloLCW_tf.group
group
Definition: CaloLCW_tf.py:28
xAOD::Vertex_v1
Class describing a Vertex.
Definition: Vertex_v1.h:42
xAOD::Photon_v1
Definition: Photon_v1.h:37
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
MCTruthPartClassifier
Definition: TruthClassifiers.h:12
xAOD::EgammaParameters::electron
@ electron
Definition: EgammaEnums.h:18
xAOD::Egamma_v1::pt
virtual double pt() const override final
The transverse momentum ( ) of the particle.
Definition: Egamma_v1.cxx:65
SG::ConstAccessor< T, AuxAllocator_t< T > >::isAvailable
bool isAvailable(const ELT &e) const
Test to see if this variable exists in the store.
DQTGlobalWZFinderAlg::m_doTrigger
BooleanProperty m_doTrigger
Definition: DQTGlobalWZFinderAlg.h:64
DQTGlobalWZFinderAlg::DQTGlobalWZFinderAlg
DQTGlobalWZFinderAlg(const std::string &name, ISvcLocator *pSvcLocator)
Definition: DQTGlobalWZFinderAlg.cxx:38
DQTGlobalWZFinderAlg::m_muonMaxEta
Gaudi::Property< float_t > m_muonMaxEta
Definition: DQTGlobalWZFinderAlg.h:58
xAOD::TrackParticle_v1
Class describing a TrackParticle.
Definition: TrackParticle_v1.h:43
drawFromPickle.sin
sin
Definition: drawFromPickle.py:36
Monitored::Scalar
Declare a monitored scalar variable.
Definition: MonitoredScalar.h:34
DQTGlobalWZFinderAlg::goodElectrons
bool goodElectrons(const xAOD::Electron *electron_itr, const xAOD::Vertex *pVtx, const EventContext &ctx) const
Definition: DQTGlobalWZFinderAlg.cxx:671
CaloNoise_fillDB.mu
mu
Definition: CaloNoise_fillDB.py:53
DQTGlobalWZFinderAlg::m_msTrackParticleContainerKey
SG::ReadHandleKey< xAOD::TrackParticleContainer > m_msTrackParticleContainerKey
Definition: DQTGlobalWZFinderAlg.h:103
GeV
#define GeV
Definition: CaloTransverseBalanceVecMon.cxx:30
makeComparison.deltaR
float deltaR
Definition: makeComparison.py:36
DataVector::size
size_type size() const noexcept
Returns the number of elements in the collection.
AthMonitorAlgorithm::getGroup
const ToolHandle< GenericMonitoringTool > & getGroup(const std::string &name) const
Get a specific monitoring tool from the tool handle array.
Definition: AthMonitorAlgorithm.cxx:164
InDetDD::electrons
@ electrons
Definition: InDetDD_Defs.h:17
DQTGlobalWZFinderAlg::m_VertexContainerKey
SG::ReadHandleKey< xAOD::VertexContainer > m_VertexContainerKey
Definition: DQTGlobalWZFinderAlg.h:97
EgammaTruthxAODHelpers.h
match
bool match(std::string s1, std::string s2)
match the individual directories of two strings
Definition: hcg.cxx:356
AthMonitorAlgorithm::DataType_t::monteCarlo
@ monteCarlo
xAOD::Egamma_v1::passSelection
bool passSelection(bool &value, const std::string &menu) const
Check if the egamma object pass a selection menu (using the name) If the menu decision is stored in t...