ATLAS Offline Software
SkimmingToolHIGG1.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3 */
4 
6 // SkimmingToolHIGG1.cxx, (c) ATLAS Detector software
8 // Based on DerivationFramework::SkimmingToolExample
9 
11 #include <vector>
12 #include <string>
13 
14 #include "CLHEP/Units/SystemOfUnits.h"
15 
20 
21 // Constructor
23  const std::string& n,
24  const IInterface* p) :
25  AthAlgTool(t, n, p),
26  m_trigDecisionTool("Trig::TrigDecisionTool/TrigDecisionTool"),
27  m_mergedCutTools("")
28 {
29 
30  declareInterface<DerivationFramework::ISkimmingTool>(this);
31 
32  declareProperty("RequireGRL", m_reqGRL = true);
33  declareProperty("ReqireLArError", m_reqLArError = true);
34  declareProperty("RequireTrigger", m_reqTrigger = true);
35  declareProperty("RequirePreselection", m_reqPreselection = true);
36  declareProperty("IncludeSingleMergedElectronPreselection", m_incMergedElectron = false);
37  declareProperty("IncludeSingleElectronPreselection", m_incSingleElectron = true);
38  declareProperty("IncludeDoubleElectronPreselection", m_incDoubleElectron = false);
39  declareProperty("IncludeSingleMuonPreselection", m_incSingleMuon = true);
40  declareProperty("IncludeDoubleMuonPreselection", m_incDoubleMuon = false);
41  declareProperty("IncludePhotonDoubleElectronPreselection", m_incDoubleElectronPhoton = false);
42  declareProperty("IncludePhotonMergedElectronPreselection", m_incMergedElectronPhoton = false);
43  declareProperty("IncludeHighPtPhotonElectronPreselection", m_incHighPtElectronPhoton = false);
44  declareProperty("IncludeDoublePhotonPreselection", m_incTwoPhotons = true);
45 
46  declareProperty("RequireKinematic", m_reqKinematic = true);
47  declareProperty("RequireQuality", m_reqQuality = true);
48  declareProperty("RequireIsolation", m_reqIsolation = true);
49  declareProperty("RequireInvariantMass", m_reqInvariantMass = true);
50 
51  declareProperty("GoodRunList", m_goodRunList = "");
52 
53  declareProperty("DefaultTrigger", m_defaultTrigger = "EF_g35_loose_g25_loose");
54  declareProperty("Triggers", m_triggers = std::vector<std::string>());
55  declareProperty("MergedElectronTriggers",m_mergedtriggers = std::vector<std::string>() );
56 
57  declareProperty("MinimumPhotonPt", m_minPhotonPt = 20*CLHEP::GeV);
58  declareProperty("MinimumElectronPt", m_minElectronPt = 20*CLHEP::GeV);
59  declareProperty("MinimumMergedElectronPt", m_minMergedElectronPt = 18*CLHEP::GeV);
60 
61  declareProperty("MinimumMuonPt", m_minMuonPt = 20*CLHEP::GeV);
62  declareProperty("MaxMuonEta", m_maxMuonEta = 2.7);
63  declareProperty("RemoveCrack", m_removeCrack = true);
64  declareProperty("MaxEta", m_maxEta = 2.47);
65 
66  declareProperty("RelativePtCuts", m_relativePtCuts = true);
67  declareProperty("LeadingPhotonPtCut", m_leadingPhotonPt = 0.35);
68  declareProperty("SubleadingPhotonPtCut", m_subleadingPhotonPt = 0.25);
69 
70  declareProperty("MinInvariantMass", m_minInvariantMass = 105*CLHEP::GeV);
71  declareProperty("MaxInvariantMass", m_maxInvariantMass = 160*CLHEP::GeV);
72 
73  declareProperty("MergedElectronCutTool", m_mergedCutTools);
74 
75 }
76 
77 // Destructor
79 }
80 
81 // Athena initialize and finalize
83 {
84  ATH_MSG_VERBOSE("INITIALIZING HSG1 SELECTOR TOOL");
85 
87  // trigger decision tool
88  if(m_trigDecisionTool.retrieve(DisableTool{!m_reqTrigger}).isFailure()) {
89  ATH_MSG_FATAL("Failed to retrieve tool: " << m_trigDecisionTool);
90  return StatusCode::FAILURE;
91  }
92  if (m_triggers.empty()) m_triggers.push_back(m_defaultTrigger);
93  ATH_MSG_INFO("Retrieved tool: " << m_trigDecisionTool);
95  //
96  if(m_incMergedElectronPhoton){
97  if( m_mergedCutTools.retrieve().isFailure() )
98  {
99  ATH_MSG_FATAL("Failed to retrieve tool: ElectronPhotonSelectorTools");
100  return StatusCode::FAILURE;
101  }
102  }
103 
104  ATH_CHECK( m_eventInfoKey.initialize() );
105 
106  ATH_CHECK( m_photonKey.initialize() );
107 
108  ATH_CHECK( m_electronKey.initialize() );
109 
110  ATH_CHECK( m_muonKey.initialize() );
111 
113  return StatusCode::SUCCESS;
114 }
115 
117 {
118  ATH_MSG_VERBOSE("finalize() ...");
119  ATH_MSG_INFO("Processed " << m_n_tot << " events, " << m_n_pass << " events passed filter ");
120 
121 
122  ATH_MSG_INFO("GRL :: " << m_n_passGRL);
123  ATH_MSG_INFO("lar :: " << m_n_passLArError);
124  ATH_MSG_INFO("trig :: " << m_n_passTrigger);
125  ATH_MSG_INFO("----------------------------");
126  if(m_incDoubleElectron)
127  ATH_MSG_INFO("2e :: " << m_n_passDoubleElectronPreselect);
128  if(m_incSingleElectron)
129  ATH_MSG_INFO("1y1e :: " << m_n_passSingleElectronPreselect);
130  if(m_incSingleMuon)
131  ATH_MSG_INFO("1y1mu :: " << m_n_passSingleMuonPreselect);
132  if(m_incDoubleMuon)
133  ATH_MSG_INFO("1y2mu :: " << m_n_passSinglePhotonDoubleMuonPreselect);
134  if(m_incDoubleElectronPhoton)
135  ATH_MSG_INFO("1y2e :: " << m_n_passSinglePhotonDoubleElectronPreselect);
136  if(m_incMergedElectronPhoton)
137  ATH_MSG_INFO("1y1eMerge :: " << m_n_passSinglePhotonMergedElectronPreselect);
138  if(m_incHighPtElectronPhoton)
139  ATH_MSG_INFO("1y1e HiPt :: " << m_n_passHighPtPhotonMergedElectronPreselect);
140  if(m_incMergedElectron)
141  ATH_MSG_INFO("1eMerge :: " << m_n_passSingleMergedElectronPreselect);
142 
143  if(m_incTwoPhotons){
144  ATH_MSG_INFO("2y :: " << m_n_passPreselect);
145  ATH_MSG_INFO("----------------------------");
146  ATH_MSG_INFO("2y - kin :: " << m_n_passKinematic);
147  ATH_MSG_INFO("2y - qual :: " << m_n_passQuality);
148  ATH_MSG_INFO("2y - iso :: " << m_n_passIsolation);
149  ATH_MSG_INFO("2y - inv :: " << m_n_passInvariantMass);
150  }
151  ATH_MSG_INFO("----------------------------");
152  ATH_MSG_INFO("passed :: " << m_n_pass);
153 
154  return StatusCode::SUCCESS;
155 }
156 
157 // The filter itself
159 {
160 
161  m_n_tot++;
162 
163  bool writeEvent(false);
164  const EventContext& ctx = Gaudi::Hive::currentContext();
165  SG::ReadHandle<xAOD::EventInfo> eventInfo (m_eventInfoKey, ctx);
166 
167  if (m_reqGRL && !SubcutGoodRunList() ) return false;
168  if (m_reqLArError && !SubcutLArError(*eventInfo) ) return false;
169  if (m_reqTrigger && !SubcutTrigger() ) return false;
170 
171  const auto leadingPhotons = SubcutPreselect();
172  if (m_incTwoPhotons && !m_reqPreselection) writeEvent = true;
173 
174  // ey, ee, muy events
175  if (m_incSingleElectron && SubcutOnePhotonOneElectron() ) writeEvent = true;
176  if (m_incDoubleElectron && SubcutTwoElectrons() ) writeEvent = true;
177  if (m_incSingleMuon && SubcutOnePhotonOneMuon() ) writeEvent = true;
178 
179  // eey, mumuy events
180  if (m_incMergedElectronPhoton && SubcutOnePhotonMergedElectrons(*eventInfo)) writeEvent = true;
181  if (m_incDoubleMuon && SubcutOnePhotonTwoMuons() ) writeEvent = true;
182  if (m_incDoubleElectronPhoton && SubcutOnePhotonTwoElectrons() ) writeEvent = true;
183  if (m_incHighPtElectronPhoton && SubcutHighPtOnePhotonOneElectron() ) writeEvent = true;
184 
185  if (m_incMergedElectron && SubcutOneMergedElectron() ) writeEvent = true;
186  // There *must* be two photons for the remaining
187  // pieces, but you can still save the event...
188  if (m_incTwoPhotons && leadingPhotons) {
189  GetDiphotonVertex();
190  const double mass = CalculateInvariantMass(leadingPhotons.value());
191 
192  bool passTwoPhotonCuts(true);
193  if (m_reqQuality && !SubcutQuality(leadingPhotons.value())) passTwoPhotonCuts = false;
194  if (m_reqKinematic && !SubcutKinematic(leadingPhotons.value(), mass)) passTwoPhotonCuts = false;
195  if (m_reqIsolation && !SubcutIsolation()) passTwoPhotonCuts = false;
196  if (m_reqInvariantMass && !SubcutInvariantMass(mass)) passTwoPhotonCuts = false;
197  // yy events
198  if (passTwoPhotonCuts) writeEvent = true;
199 
200  }
201 
202 
203  if (!writeEvent) return false;
204 
205  m_n_pass++;
206  return true;
207 }
208 
210 
211  // Placeholder
212  m_n_passGRL++;
213  return true;
214 }
215 
216 
218 
220  m_n_passLArError++;
221  return true;
222  }
223  else return false;
224 }
225 
226 
228 
229  //just for counting purposes
230  bool passTrigger = !m_reqTrigger;
231 
232  if(m_triggers.empty()) passTrigger = true;
233 
234  for (unsigned int i = 0; i < m_triggers.size(); i++) {
235  ATH_MSG_DEBUG("TRIGGER = " << m_triggers.at(i));
236  if(m_trigDecisionTool->isPassed(m_triggers.at(i)))
237  passTrigger = true;
238  }
239 
240  if (passTrigger) m_n_passTrigger++;
241  return passTrigger;
242 
243 }
244 
245 
246 std::optional<DerivationFramework::SkimmingToolHIGG1::LeadingPhotons_t>
248 
249  SG::ReadHandle<xAOD::PhotonContainer> photons (m_photonKey);
250 
251  xAOD::PhotonContainer::const_iterator ph_itr(photons->begin());
252  xAOD::PhotonContainer::const_iterator ph_end(photons->end());
253 
254  int ph_pos_lead = -1;
255  int ph_pos_subl = -1;
256  int ph_pt_lead = 0;
257  int ph_pt_subl = 0;
258 
259  for(int i = 0; ph_itr != ph_end; ++ph_itr, ++i) {
260 
261  if (PhotonPreselect(*ph_itr)) {
262 
263  if ((*ph_itr)->pt() > ph_pt_lead) {
264 
265  ph_pos_subl = ph_pos_lead; ph_pos_lead = i;
266  ph_pt_subl = ph_pt_lead;
267  ph_pt_lead = (*ph_itr)->pt();
268 
269  } else if ((*ph_itr)->pt() > ph_pt_subl) {
270  ph_pos_subl = i;
271  ph_pt_subl = (*ph_itr)->pt();
272  }
273  }
274  }
275 
276  // save this for the derivation.
277  //std::vector<int> *leadingV = new std::vector<int>();
278  //leadingV->push_back(m_ph_pos_lead);
279  //leadingV->push_back(m_ph_pos_subl);
280  //if (!evtStore()->contains<std::vector<int> >("leadingV")) CHECK(evtStore()->record(leadingV, "leadingV"));
281 
282  // save this for this code.
283  if (ph_pos_subl != -1) {
284  const xAOD::Photon* ph_lead = *(photons->begin() + ph_pos_lead);
285  const xAOD::Photon* ph_subl = *(photons->begin() + ph_pos_subl);
286  m_n_passPreselect++;
287 
288  return LeadingPhotons_t{ph_lead,ph_subl};
289  }
290 
291  return {};
292 }
293 
294 
296 
297  if (!ph) return false;
298 
299  if (!ph->isGoodOQ(34214)) return false;
300 
301  bool val(false);
302  bool defined(false);
303 
304  static const SG::ConstAccessor<char> DFCommonPhotonsIsEMLooseAcc("DFCommonPhotonsIsEMLoose");
305  if(DFCommonPhotonsIsEMLooseAcc.isAvailable(*ph)){
306  defined = true;
307  val = static_cast<bool>(DFCommonPhotonsIsEMLooseAcc(*ph));
308  }
309  else{
310  defined = ph->passSelection(val, "Loose");
311  }
312 
313  if(!defined || !val) return false;
314 
315 
316  // veto topo-seeded clusters
317  // uint16_t author = 0;
318  // author = ph->author();
319  // if (author & xAOD::EgammaParameters::AuthorCaloTopo35) return false;
320 
321  // Check which variable versions are best...
322  const xAOD::CaloCluster *caloCluster(ph->caloCluster());
323  double eta = std::abs(caloCluster->etaBE(2));
324 
325  if (eta > m_maxEta) return false;
326  if (m_removeCrack &&
327  1.37 <= eta && eta <= 1.52) return false;
328  if (caloCluster->e()/cosh(eta) < m_minPhotonPt) return false;
329 
330  return true;
331 
332 }
333 
335 
336  bool passKinematic;
337  if (m_relativePtCuts) {
338  passKinematic = (leadingPhotons[0]->pt() > invariantMass * m_leadingPhotonPt);
339  passKinematic &= (leadingPhotons[1]->pt() > invariantMass * m_subleadingPhotonPt);
340  } else {
341  passKinematic = (leadingPhotons[0]->pt() > m_leadingPhotonPt);
342  passKinematic &= (leadingPhotons[1]->pt() > m_subleadingPhotonPt);
343  }
344 
345  if (passKinematic) m_n_passKinematic++;
346  return passKinematic;
347 
348 }
349 
351 
352  bool val(0);
353  bool passQuality = false;
354  leadingPhotons[0]->passSelection(val, "Tight");
355  const int ph_tight_lead = val;
356 
357  leadingPhotons[1]->passSelection(val, "Tight");
358  const int ph_tight_subl = val;
359 
360  passQuality = (ph_tight_lead && ph_tight_subl);
361 
362  if (passQuality) m_n_passQuality++;
363  return passQuality;
364 
365 }
366 
368 
369  // PLACEHOLDER!!!
370  m_n_passIsolation++;
371  return true;
372 }
373 
374 
376 
377  bool passInvariantMass = (!m_minInvariantMass ||
378  m_minInvariantMass < invariantMass);
379 
380  passInvariantMass &= (!m_maxInvariantMass ||
381  invariantMass < m_maxInvariantMass);
382 
383  if (passInvariantMass) m_n_passInvariantMass++;
384  return passInvariantMass;
385 
386 }
387 
389 
391  const double ph_e_lead = CorrectedEnergy(leadingPhotons[0]);
392  const double ph_e_subl = CorrectedEnergy(leadingPhotons[1]);
393 
395  const double ph_eta_lead = CorrectedEta(leadingPhotons[0]);
396  const double ph_eta_subl = CorrectedEta(leadingPhotons[1]);
397 
398  const double ph_phi_lead = leadingPhotons[0]->phi();
399  const double ph_phi_subl = leadingPhotons[1]->phi();
400 
401  const double ph_pt_lead = ph_e_lead / cosh(ph_eta_lead);
402  const double ph_pt_subl = ph_e_subl / cosh(ph_eta_subl);
403 
404  TLorentzVector leadPhotonLV;
405  TLorentzVector sublPhotonLV;
406  leadPhotonLV.SetPtEtaPhiM(ph_pt_lead, ph_eta_lead, ph_phi_lead, 0.);
407  sublPhotonLV.SetPtEtaPhiM(ph_pt_subl, ph_eta_subl, ph_phi_subl, 0.);
408 
409  return (leadPhotonLV + sublPhotonLV).M();
410 
411 }
412 
413 
414 
416 
417  return 0;
418 
419 }
420 
423 
424  return ph->e();
425 
426 }
427 
428 
432 
433  double eta1 = ph->caloCluster()->etaBE(1);
434 
435  double R_photom_n_front, Z_photom_n_front;
436  if (std::abs(eta1) < 1.5) { // barrel
437  R_photom_n_front = ReturnRZ_1stSampling_cscopt2(eta1);
438  Z_photom_n_front = R_photom_n_front*sinh(eta1);
439  } else { // endcap
440  Z_photom_n_front = ReturnRZ_1stSampling_cscopt2(eta1);
441  R_photom_n_front = Z_photom_n_front/sinh(eta1);
442  }
443 
444  return asinh((Z_photom_n_front - GetDiphotonVertex())/R_photom_n_front);
445 
446 }
447 
448 
450 
451  float abs_eta1 = std::abs(eta1);
452 
453  double radius = -99999;
454  if (abs_eta1 < 0.8) {
455  radius = 1558.859292 - 4.990838 * abs_eta1 - 21.144279 * abs_eta1 * abs_eta1;
456  } else if (abs_eta1 < 1.5) {
457  radius = 1522.775373 + 27.970192 * abs_eta1 - 21.104108 * abs_eta1 * abs_eta1;
458  } else { //endcap
459  radius = 3790.671754;
460  if (eta1 < 0.) radius = -radius;
461  }
462 
463  return radius;
464 
465 }
466 
468 
469  SG::ReadHandle<xAOD::PhotonContainer> photons (m_photonKey);
470 
471  xAOD::PhotonContainer::const_iterator ph_itr(photons->begin());
472  xAOD::PhotonContainer::const_iterator ph_end(photons->end());
473 
475 
478 
479  bool passSingleElectronPreselect = false;
480 
481  for( ; ph_itr != ph_end; ++ph_itr){
482  if(PhotonPreselect(*ph_itr)){
483  for( ; el_itr != el_end; ++el_itr){
484  if(ElectronPreselect(*el_itr)){
485  passSingleElectronPreselect = true;
486  }
487  }
488  }
489  }
490 
491 
492  if(passSingleElectronPreselect) m_n_passSingleElectronPreselect++;
493  return passSingleElectronPreselect;
494 }
495 
496 
498 
500 
501  int nEle(0);
502  for(const auto *const el: *electrons){
503  if( el->pt() < m_minElectronPt)
504  continue;
505  //Count the number of Si tracks matching the electron
506  int nSiTrack(0);
507  int z0_1 = 1;
508  for( unsigned int trk_i(0); trk_i < el->nTrackParticles(); ++trk_i){
509  const auto *ele_tp = el->trackParticle(trk_i);
510  if(!ele_tp){
511  continue;
512  }
513  uint8_t nPixHits(0), nPixDead(0), nSCTHits(0), nSCTDead(0);
514  bool allFound = true;
515  allFound = allFound && ele_tp->summaryValue(nPixHits, xAOD::numberOfPixelHits);
516  allFound = allFound && ele_tp->summaryValue(nPixDead, xAOD::numberOfPixelDeadSensors);
517  allFound = allFound && ele_tp->summaryValue(nSCTHits, xAOD::numberOfSCTHits);
518  allFound = allFound && ele_tp->summaryValue(nSCTDead, xAOD::numberOfSCTDeadSensors);
519 
520  // Require that the track be a reasonble silicon track
521  int nSiHitsPlusDeadSensors = nPixHits + nPixDead + nSCTHits + nSCTDead;
522  if(nSiHitsPlusDeadSensors >= 7)
523  {
524  //Ensure that the tracks come from roughly the same region of the detector
525  if(nSiTrack == 0)
526  z0_1 = ele_tp->z0();
527  else if( std::abs(z0_1 - ele_tp->z0()) > 10 )
528  continue;
529  ++nSiTrack;
530  }
531  }
532  //If 2 or more the electron is selected
533  if(nSiTrack>1)
534  ++nEle;
535  }
536  if(nEle>0){
537  ++m_n_passSingleMergedElectronPreselect;
538  return true;
539  }
540  return false;
541 }
542 
544 
546 
549 
550  int nEle(0);
551  bool passDoubleElectronPreselect = false;
552 
553  for( ; el_itr != el_end; ++el_itr){
554  if(ElectronPreselect(*el_itr))
555  nEle++;
556  }
557 
558  if(nEle >=2) passDoubleElectronPreselect = true;
559 
560  if(passDoubleElectronPreselect) m_n_passDoubleElectronPreselect++;
561  return passDoubleElectronPreselect;
562 }
563 
564 
566 
567  SG::ReadHandle<xAOD::PhotonContainer> photons (m_photonKey);
568 
569  xAOD::PhotonContainer::const_iterator ph_itr(photons->begin());
570  xAOD::PhotonContainer::const_iterator ph_end(photons->end());
571 
572  SG::ReadHandle<xAOD::MuonContainer> muons (m_muonKey);
573 
575  xAOD::MuonContainer::const_iterator mu_end(muons->end());
576 
577  bool passSingleMuonPreselect = false;
578 
579  for( ; ph_itr != ph_end; ++ph_itr){
580  if(PhotonPreselect(*ph_itr)){
581  for( ; mu_itr != mu_end; ++mu_itr){
582  if(MuonPreselect(*mu_itr)){
583  passSingleMuonPreselect = true;
584  }
585  }
586  }
587  }
588 
589 
590  if(passSingleMuonPreselect) m_n_passSingleMuonPreselect++;
591  return passSingleMuonPreselect;
592 }
593 
595 {
596  SG::ReadHandle<xAOD::PhotonContainer> photons (m_photonKey);
597 
598  xAOD::PhotonContainer::const_iterator ph_itr(photons->begin());
599  xAOD::PhotonContainer::const_iterator ph_end(photons->end());
600 
601  SG::ReadHandle<xAOD::MuonContainer> muons (m_muonKey);
602 
604  xAOD::MuonContainer::const_iterator mu_end(muons->end());
605 
606  int nPhoton = 0;
607  int nMuon = 0;
608 
609  for( ; ph_itr != ph_end; ++ph_itr){
610  if(PhotonPreselect(*ph_itr)){
611  ++nPhoton;
612  }
613  }
614 
615  for( ; mu_itr != mu_end; ++mu_itr){
616  if(MuonPreselect(*mu_itr)){
617  ++nMuon;
618  }
619  }
620 
621 
622  if(nPhoton >= 1 && nMuon >= 2){
623  ATH_MSG_DEBUG("Event selected with " << nPhoton << " photons and " << nMuon << " muons");
624  m_n_passSinglePhotonDoubleMuonPreselect++;
625  return true;
626  } else {
627  return false;
628  }
629 }
630 
631 
633 {
634  SG::ReadHandle<xAOD::PhotonContainer> photons (m_photonKey);
635 
636  xAOD::PhotonContainer::const_iterator ph_itr(photons->begin());
637  xAOD::PhotonContainer::const_iterator ph_end(photons->end());
638 
640 
643 
644  int nPhoton = 0;
645  int nElectron = 0;
646 
647  for( ; ph_itr != ph_end; ++ph_itr){
648  if(PhotonPreselect(*ph_itr)){
649  ++nPhoton;
650  }
651  }
652 
653  for( ; el_itr != el_end; ++el_itr){
654  if(ElectronPreselect(*el_itr)){
655  ++nElectron;
656  }
657  }
658 
659  if(nPhoton >= 1 && nElectron >= 2){
660  ATH_MSG_DEBUG("Event selected with " << nPhoton << " photons and " << nElectron << " electrons");
661  ++m_n_passSinglePhotonDoubleElectronPreselect;
662  return true;
663  } else {
664  return false;
665  }
666 
667 }
668 
670 {
671 
672 
673  bool passTrigger=false;
674  if(!m_mergedtriggers.empty()) {
675  for (unsigned int i = 0; i < m_mergedtriggers.size(); i++) {
676  ATH_MSG_DEBUG("TRIGGER = " << m_mergedtriggers.at(i));
677  if(m_trigDecisionTool->isPassed(m_mergedtriggers.at(i)))
678  passTrigger = true;
679  }
680  } else {
682  ATH_MSG_WARNING("Selecting Merged electrons but no Merged Triggers Selected ! -- was that intentional?");
683  passTrigger = true;
684  }
685  if(!passTrigger)
686  return false;
687 
688 
689  SG::ReadHandle<xAOD::PhotonContainer> photons (m_photonKey);
690 
692 
693  bool passSelection = false;
694 
695  for(const auto *el : *electrons){
696  if(MergedElectronPreselect(el)){
697  for(const auto *ph: *photons){
698  if(PhotonPreselect(ph)){
699  passSelection = true;
700  auto eph = ph->p4() + el->p4();
701  if(eph.M() > 90 * CLHEP::GeV)
702  {
703  break;
704  }
705  }
706  }
707  }
708  if(passSelection)
709  {
710  break;
711  }
712  }
713 
714  if(passSelection){
715  ATH_MSG_DEBUG("Event selected with a photons and a merged electron");
716  ++m_n_passSinglePhotonMergedElectronPreselect;
717  return true;
718  } else {
719  return false;
720  }
721 
722 }
723 
724 
726 {
727 
728 
729  SG::ReadHandle<xAOD::PhotonContainer> photons (m_photonKey);
730 
731  xAOD::PhotonContainer::const_iterator ph_itr(photons->begin());
732  xAOD::PhotonContainer::const_iterator ph_end(photons->end());
733 
735 
738 
739  int nPhoton = 0;
740  int nElectron = 0;
741 
742  for( ; ph_itr != ph_end; ++ph_itr){
743  if(PhotonPreselect(*ph_itr) && (*ph_itr)->pt() > 500*CLHEP::GeV){
744  ++nPhoton;
745  }
746  }
747 
748  for( ; el_itr != el_end; ++el_itr){
749  if( std::abs((*el_itr)->eta()) <= m_maxEta && (*el_itr)->pt() > m_minElectronPt){
750  ++nElectron;
751  }
752  }
753 
754  if(nPhoton >= 1 && nElectron >= 1 ){
755  ATH_MSG_DEBUG("Event selected with " << nPhoton << " high pt photons and " << nElectron << " merged electron");
756  ++m_n_passHighPtPhotonMergedElectronPreselect;
757  return true;
758  } else {
759  return false;
760  }
761 
762 }
763 
764 
765 
767 
768  if (!el) return false;
769 
770  bool val(false);
771  bool defined(false);
772 
773  static const SG::ConstAccessor<char> DFCommonElectronsLooseAcc("DFCommonElectronsLoose");
774  if(DFCommonElectronsLooseAcc.isAvailable(*el)){
775  defined = true;
776  val = val || static_cast<bool>(DFCommonElectronsLooseAcc(*el));
777  }else{
778  defined = el->passSelection(val, "Loose");
779  }
780 
781  static const SG::ConstAccessor<char> DFCommonElectronsLHLooseAcc("DFCommonElectronsLHLoose");
782  if(DFCommonElectronsLHLooseAcc.isAvailable(*el)){
783  defined = true;
784  val = val || static_cast<bool>(DFCommonElectronsLHLooseAcc(*el));
785  }
786 
787  if(!defined || !val) return false;
788 
789  double eta = std::abs(el->eta());
790  double pt = el->pt();
791 
792  if (eta > m_maxEta) return false;
793  if (m_removeCrack && 1.37 <= eta && eta <= 1.52) return false;
794  if (pt <= m_minElectronPt) return false;
795 
796  return true;
797 
798 }
799 
801 
802  if (!el) return false;
803 
804  double eta = std::abs(el->eta());
805  double pt = el->pt();
806 
807  if (eta > m_maxEta) return false;
808  if (m_removeCrack && 1.37 <= eta && eta <= 1.52) return false;
809  if (pt <= m_minMergedElectronPt) return false;
810 
811  return m_mergedCutTools->accept(el) || ElectronPreselect(el);
812 
813 }
814 
816 
817  if (!mu) return false;
818 
819  static const SG::ConstAccessor<char> DFCommonGoodMuonAcc("DFCommonGoodMuon");
820  if(DFCommonGoodMuonAcc.isAvailable(*mu))
821  if( !static_cast<bool>(DFCommonGoodMuonAcc(*mu)) )
822  return false;
823 
824  static const SG::ConstAccessor<char> DFCommonMuonsPreselectionAcc("DFCommonMuonsPreselection");
825  if(DFCommonMuonsPreselectionAcc.isAvailable(*mu))
826  if( !static_cast<bool>(DFCommonMuonsPreselectionAcc(*mu)) )
827  return false;
828 
829  double eta = std::abs(mu->eta());
830  double pt = mu->pt();
831 
832  if (eta > m_maxMuonEta) return false;
833  if (pt <= m_minMuonPt) return false;
834 
835  return true;
836 
837 }
838 
840 
841 
842 
DerivationFramework::SkimmingToolHIGG1::SubcutTrigger
bool SubcutTrigger() const
Definition: SkimmingToolHIGG1.cxx:227
DerivationFramework::SkimmingToolHIGG1::m_minMergedElectronPt
double m_minMergedElectronPt
Definition: SkimmingToolHIGG1.h:113
DerivationFramework::SkimmingToolHIGG1::initialize
virtual StatusCode initialize() override
Definition: SkimmingToolHIGG1.cxx:82
DerivationFramework::SkimmingToolHIGG1::MergedElectronPreselect
bool MergedElectronPreselect(const xAOD::Electron *el) const
Definition: SkimmingToolHIGG1.cxx:800
SkimmingToolHIGG1.h
DerivationFramework::SkimmingToolHIGG1::SubcutOneMergedElectron
bool SubcutOneMergedElectron() const
Definition: SkimmingToolHIGG1.cxx:497
DerivationFramework::SkimmingToolHIGG1::m_triggers
std::vector< std::string > m_triggers
Definition: SkimmingToolHIGG1.h:98
ATH_MSG_FATAL
#define ATH_MSG_FATAL(x)
Definition: AthMsgStreamMacros.h:34
DataModel_detail::const_iterator
Const iterator class for DataVector/DataList.
Definition: DVLIterator.h:82
DerivationFramework::SkimmingToolHIGG1::~SkimmingToolHIGG1
~SkimmingToolHIGG1()
Destructor.
Definition: SkimmingToolHIGG1.cxx:78
DerivationFramework::SkimmingToolHIGG1::SubcutInvariantMass
bool SubcutInvariantMass(double invariantMass) const
Definition: SkimmingToolHIGG1.cxx:375
DerivationFramework::SkimmingToolHIGG1::m_incSingleMuon
bool m_incSingleMuon
Definition: SkimmingToolHIGG1.h:81
python.PerfMonSerializer.p
def p
Definition: PerfMonSerializer.py:743
top::invariantMass
double invariantMass(const xAOD::IParticle &p1, const xAOD::IParticle &p2)
Calculate the invariant mass of two particles.
Definition: EventTools.cxx:48
DerivationFramework::SkimmingToolHIGG1::m_reqPreselection
bool m_reqPreselection
Definition: SkimmingToolHIGG1.h:77
DerivationFramework::SkimmingToolHIGG1::SkimmingToolHIGG1
SkimmingToolHIGG1(const std::string &t, const std::string &n, const IInterface *p)
Constructor with parameters.
Definition: SkimmingToolHIGG1.cxx:22
DerivationFramework::SkimmingToolHIGG1::SubcutGoodRunList
bool SubcutGoodRunList() const
Definition: SkimmingToolHIGG1.cxx:209
ATH_MSG_INFO
#define ATH_MSG_INFO(x)
Definition: AthMsgStreamMacros.h:31
DerivationFramework::SkimmingToolHIGG1::m_minElectronPt
double m_minElectronPt
Definition: SkimmingToolHIGG1.h:112
xAOD::uint8_t
uint8_t
Definition: Muon_v1.cxx:575
DerivationFramework::SkimmingToolHIGG1::m_incTwoPhotons
bool m_incTwoPhotons
Definition: SkimmingToolHIGG1.h:86
DerivationFramework::SkimmingToolHIGG1::m_maxMuonEta
double m_maxMuonEta
Definition: SkimmingToolHIGG1.h:115
eta
Scalar eta() const
pseudorapidity method
Definition: AmgMatrixBasePlugin.h:79
SG::ReadHandle
Definition: StoreGate/StoreGate/ReadHandle.h:70
AthCommonDataStore< AthCommonMsg< AlgTool > >::declareProperty
Gaudi::Details::PropertyBase & declareProperty(Gaudi::Property< T > &t)
Definition: AthCommonDataStore.h:145
xAOD::Egamma_v1::e
virtual double e() const override final
The total energy of the particle.
Definition: Egamma_v1.cxx:90
DerivationFramework::SkimmingToolHIGG1::m_maxEta
double m_maxEta
Definition: SkimmingToolHIGG1.h:103
DerivationFramework::SkimmingToolHIGG1::finalize
virtual StatusCode finalize() override
Definition: SkimmingToolHIGG1.cxx:116
DerivationFramework::SkimmingToolHIGG1::m_reqLArError
bool m_reqLArError
Definition: SkimmingToolHIGG1.h:75
python.SystemOfUnits.MeV
int MeV
Definition: SystemOfUnits.py:154
DerivationFramework::SkimmingToolHIGG1::m_reqTrigger
bool m_reqTrigger
Definition: SkimmingToolHIGG1.h:76
test_pyathena.pt
pt
Definition: test_pyathena.py:11
xAOD::eta1
setEt setPhi setE277 setWeta2 eta1
Definition: TrigEMCluster_v1.cxx:41
xAOD::numberOfPixelHits
@ numberOfPixelHits
these are the pixel hits, including the b-layer [unit8_t].
Definition: TrackingPrimitives.h:259
SG::ConstAccessor< char >
DerivationFramework::SkimmingToolHIGG1::m_incMergedElectronPhoton
bool m_incMergedElectronPhoton
Definition: SkimmingToolHIGG1.h:84
read_hist_ntuple.t
t
Definition: read_hist_ntuple.py:5
ATH_MSG_VERBOSE
#define ATH_MSG_VERBOSE(x)
Definition: AthMsgStreamMacros.h:28
DerivationFramework::SkimmingToolHIGG1::PhotonPreselect
bool PhotonPreselect(const xAOD::Photon *ph) const
Definition: SkimmingToolHIGG1.cxx:295
DerivationFramework::SkimmingToolHIGG1::SubcutOnePhotonTwoMuons
bool SubcutOnePhotonTwoMuons() const
Definition: SkimmingToolHIGG1.cxx:594
xAOD::EventInfo_v1::IS_SIMULATION
@ IS_SIMULATION
true: simulation, false: data
Definition: EventInfo_v1.h:151
DerivationFramework::SkimmingToolHIGG1::m_incSingleElectron
bool m_incSingleElectron
Definition: SkimmingToolHIGG1.h:79
xAOD::EventInfo_v1::LAr
@ LAr
The LAr calorimeter.
Definition: EventInfo_v1.h:335
DerivationFramework::SkimmingToolHIGG1::m_subleadingPhotonPt
double m_subleadingPhotonPt
Definition: SkimmingToolHIGG1.h:107
xAOD::Muon_v1
Class describing a Muon.
Definition: Muon_v1.h:38
dqt_zlumi_pandas.mass
mass
Definition: dqt_zlumi_pandas.py:170
DerivationFramework::SkimmingToolHIGG1::m_incDoubleMuon
bool m_incDoubleMuon
Definition: SkimmingToolHIGG1.h:82
xAOD::EventInfo_v1::Error
@ Error
The sub-detector issued an error.
Definition: EventInfo_v1.h:349
DerivationFramework::SkimmingToolHIGG1::SubcutHighPtOnePhotonOneElectron
bool SubcutHighPtOnePhotonOneElectron() const
Definition: SkimmingToolHIGG1.cxx:725
DerivationFramework::SkimmingToolHIGG1::s_MZ
static const double s_MZ
Definition: SkimmingToolHIGG1.h:180
DerivationFramework::SkimmingToolHIGG1::MuonPreselect
bool MuonPreselect(const xAOD::Muon *mu) const
Definition: SkimmingToolHIGG1.cxx:815
DerivationFramework::SkimmingToolHIGG1::m_mergedCutTools
ToolHandle< IAsgElectronIsEMSelector > m_mergedCutTools
Definition: SkimmingToolHIGG1.h:185
DerivationFramework::SkimmingToolHIGG1::SubcutPreselect
std::optional< LeadingPhotons_t > SubcutPreselect() const
Definition: SkimmingToolHIGG1.cxx:247
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
DerivationFramework::SkimmingToolHIGG1::m_minInvariantMass
double m_minInvariantMass
Definition: SkimmingToolHIGG1.h:109
xAOD::CaloCluster_v1
Description of a calorimeter cluster.
Definition: CaloCluster_v1.h:59
DerivationFramework::SkimmingToolHIGG1::CalculateInvariantMass
double CalculateInvariantMass(const LeadingPhotons_t &leadingPhotons) const
Definition: SkimmingToolHIGG1.cxx:388
DerivationFramework::SkimmingToolHIGG1::m_incHighPtElectronPhoton
bool m_incHighPtElectronPhoton
Definition: SkimmingToolHIGG1.h:85
DerivationFramework::SkimmingToolHIGG1::m_incMergedElectron
bool m_incMergedElectron
Definition: SkimmingToolHIGG1.h:78
DerivationFramework::SkimmingToolHIGG1::m_mergedtriggers
std::vector< std::string > m_mergedtriggers
Definition: SkimmingToolHIGG1.h:99
DerivationFramework::SkimmingToolHIGG1::SubcutKinematic
bool SubcutKinematic(const LeadingPhotons_t &leadingPhotons, double invariantMass) const
Definition: SkimmingToolHIGG1.cxx:334
DerivationFramework::SkimmingToolHIGG1::SubcutOnePhotonTwoElectrons
bool SubcutOnePhotonTwoElectrons() const
Definition: SkimmingToolHIGG1.cxx:632
lumiFormat.i
int i
Definition: lumiFormat.py:92
DerivationFramework::SkimmingToolHIGG1::SubcutLArError
bool SubcutLArError(const xAOD::EventInfo &eventInfo) const
Definition: SkimmingToolHIGG1.cxx:217
beamspotman.n
n
Definition: beamspotman.py:731
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
DerivationFramework::SkimmingToolHIGG1::m_reqQuality
bool m_reqQuality
Definition: SkimmingToolHIGG1.h:88
DerivationFramework::SkimmingToolHIGG1::m_maxInvariantMass
double m_maxInvariantMass
Definition: SkimmingToolHIGG1.h:110
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
plotIsoValidation.el
el
Definition: plotIsoValidation.py:197
DerivationFramework::SkimmingToolHIGG1::CorrectedEnergy
static double CorrectedEnergy(const xAOD::Photon *ph)
Definition: SkimmingToolHIGG1.cxx:422
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
IPhotonVertexSelectionTool.h
DerivationFramework::SkimmingToolHIGG1::LeadingPhotons_t
std::array< const xAOD::Photon *, 2 > LeadingPhotons_t
Leading and sub-leading photon (in that order)
Definition: SkimmingToolHIGG1.h:127
python.Dumpers.asinh
def asinh(x)
helper methods ---------------------------------------------------------—
Definition: Dumpers.py:89
DerivationFramework::SkimmingToolHIGG1::m_defaultTrigger
std::string m_defaultTrigger
Definition: SkimmingToolHIGG1.h:97
DerivationFramework::SkimmingToolHIGG1::m_reqIsolation
bool m_reqIsolation
Definition: SkimmingToolHIGG1.h:89
DerivationFramework::SkimmingToolHIGG1::m_relativePtCuts
bool m_relativePtCuts
Definition: SkimmingToolHIGG1.h:105
DerivationFramework::SkimmingToolHIGG1::SubcutOnePhotonOneElectron
bool SubcutOnePhotonOneElectron() const
Definition: SkimmingToolHIGG1.cxx:467
DerivationFramework::SkimmingToolHIGG1::CorrectedEta
double CorrectedEta(const xAOD::Photon *ph) const
Definition: SkimmingToolHIGG1.cxx:431
DerivationFramework::SkimmingToolHIGG1::eventPassesFilter
virtual bool eventPassesFilter() const override
Check that the current event passes this filter.
Definition: SkimmingToolHIGG1.cxx:158
DerivationFramework::SkimmingToolHIGG1::GetDiphotonVertex
double GetDiphotonVertex() const
Definition: SkimmingToolHIGG1.cxx:415
DerivationFramework::SkimmingToolHIGG1::m_reqGRL
bool m_reqGRL
Definition: SkimmingToolHIGG1.h:74
DerivationFramework::SkimmingToolHIGG1::SubcutIsolation
bool SubcutIsolation() const
Definition: SkimmingToolHIGG1.cxx:367
DerivationFramework::SkimmingToolHIGG1::m_goodRunList
std::string m_goodRunList
Definition: SkimmingToolHIGG1.h:95
TauGNNUtils::Variables::Track::nSCTHits
bool nSCTHits(const xAOD::TauJet &, const xAOD::TauTrack &track, double &out)
Definition: TauGNNUtils.cxx:549
DerivationFramework::SkimmingToolHIGG1::ElectronPreselect
bool ElectronPreselect(const xAOD::Electron *el) const
Definition: SkimmingToolHIGG1.cxx:766
xAOD::Electron_v1
Definition: Electron_v1.h:34
ParticleGun_SamplingFraction.radius
radius
Definition: ParticleGun_SamplingFraction.py:96
DerivationFramework::SkimmingToolHIGG1::m_reqInvariantMass
bool m_reqInvariantMass
Definition: SkimmingToolHIGG1.h:90
xAOD::EventInfo_v1
Class describing the basic event information.
Definition: EventInfo_v1.h:43
DataVector::end
const_iterator end() const noexcept
Return a const_iterator pointing past the end of the collection.
DerivationFramework::SkimmingToolHIGG1::m_leadingPhotonPt
double m_leadingPhotonPt
Definition: SkimmingToolHIGG1.h:106
IAsgElectronIsEMSelector.h
DerivationFramework::SkimmingToolHIGG1::m_minMuonPt
double m_minMuonPt
Definition: SkimmingToolHIGG1.h:114
DerivationFramework::SkimmingToolHIGG1::SubcutOnePhotonMergedElectrons
bool SubcutOnePhotonMergedElectrons(const xAOD::EventInfo &eventInfo) const
Definition: SkimmingToolHIGG1.cxx:669
xAOD::Photon_v1
Definition: Photon_v1.h:37
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
xAOD::numberOfSCTDeadSensors
@ numberOfSCTDeadSensors
number of dead SCT sensors crossed [unit8_t].
Definition: TrackingPrimitives.h:273
DerivationFramework::SkimmingToolHIGG1::SubcutTwoElectrons
bool SubcutTwoElectrons() const
Definition: SkimmingToolHIGG1.cxx:543
DerivationFramework::SkimmingToolHIGG1::ReturnRZ_1stSampling_cscopt2
static double ReturnRZ_1stSampling_cscopt2(double eta1)
Definition: SkimmingToolHIGG1.cxx:449
Pythia8_RapidityOrderMPI.val
val
Definition: Pythia8_RapidityOrderMPI.py:14
DerivationFramework::SkimmingToolHIGG1::m_minPhotonPt
double m_minPhotonPt
Definition: SkimmingToolHIGG1.h:101
xAOD::EventInfo_v1::errorState
EventFlagErrorState errorState(EventFlagSubDet subDet) const
Get the error state for a particular sub-detector.
Definition: EventInfo_v1.cxx:817
xAOD::numberOfSCTHits
@ numberOfSCTHits
number of hits in SCT [unit8_t].
Definition: TrackingPrimitives.h:268
SG::ConstAccessor::isAvailable
bool isAvailable(const ELT &e) const
Test to see if this variable exists in the store.
DerivationFramework::SkimmingToolHIGG1::m_incDoubleElectron
bool m_incDoubleElectron
Definition: SkimmingToolHIGG1.h:80
xAOD::numberOfPixelDeadSensors
@ numberOfPixelDeadSensors
number of dead pixel sensors crossed [unit8_t].
Definition: TrackingPrimitives.h:266
DerivationFramework::SkimmingToolHIGG1::SubcutOnePhotonOneMuon
bool SubcutOnePhotonOneMuon() const
Definition: SkimmingToolHIGG1.cxx:565
DerivationFramework::SkimmingToolHIGG1::SubcutQuality
bool SubcutQuality(const LeadingPhotons_t &leadingPhotons) const
Definition: SkimmingToolHIGG1.cxx:350
DerivationFramework::SkimmingToolHIGG1::m_removeCrack
bool m_removeCrack
Definition: SkimmingToolHIGG1.h:102
ConstAccessor.h
Helper class to provide constant type-safe access to aux data.
AthAlgTool
Definition: AthAlgTool.h:26
DerivationFramework::SkimmingToolHIGG1::m_reqKinematic
bool m_reqKinematic
Definition: SkimmingToolHIGG1.h:87
CaloNoise_fillDB.mu
mu
Definition: CaloNoise_fillDB.py:53
GeV
#define GeV
Definition: CaloTransverseBalanceVecMon.cxx:30
DerivationFramework::SkimmingToolHIGG1::m_incDoubleElectronPhoton
bool m_incDoubleElectronPhoton
Definition: SkimmingToolHIGG1.h:83
TrackingPrimitives.h
xAOD::CaloCluster_v1::e
virtual double e() const
The total energy of the particle.
Definition: CaloCluster_v1.cxx:265
InDetDD::electrons
@ electrons
Definition: InDetDD_Defs.h:17
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...
DataVector::begin
const_iterator begin() const noexcept
Return a const_iterator pointing at the beginning of the collection.
xAOD::EventInfo_v1::eventType
bool eventType(EventType type) const
Check for one particular bitmask value.
xAOD::Egamma_v1::isGoodOQ
bool isGoodOQ(uint32_t mask) const
Check object quality. Return True is it is Good Object Quality.
Definition: Egamma_v1.cxx:236