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