ATLAS Offline Software
Loading...
Searching...
No Matches
SkimmingToolHIGG2.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// SkimmingToolHIGG2.cxx, (c) ATLAS Detector software
8// Author: Susumu Oda (Susumu.Oda@cern.ch)
9// Based on DerivationFramework::SkimmingToolExample
10
12#include <vector>
13#include <string>
14
15#include "CLHEP/Units/SystemOfUnits.h"
16
21
22
23// Constructor
25 const std::string& n,
26 const IInterface* p) :
27 base_class(t, n, p),
28 m_trigDecisionTool("Trig::TrigDecisionTool/TrigDecisionTool"),
29 m_ntot(0),
30 m_npass(0)
31{
32
33 declareProperty("SkipTriggerRequirement", m_skipTriggerRequirement=false);
34
35 declareProperty("FilterType", m_filterType="2L");
36
37 declareProperty("ElectronContainerKey", m_electronSGKey="Electrons");
38 declareProperty("MuonContainerKey", m_muonSGKey="Muons");
39 declareProperty("JetContainerKey", m_jetSGKey="AntiKt4EMTopoJets");
40 declareProperty("MergedJetContainerKey0", m_mergedJetSGKey[0]="AntiKt4EMTopoJets");
41 declareProperty("MergedJetContainerKey1", m_mergedJetSGKey[1]="AntiKt10LCTopoJets");
42 declareProperty("MergedJetContainerKey2", m_mergedJetSGKey[2]="CamKt12LCTopoJets");
43 declareProperty("PhotonContainerKey", m_photonSGKey="Photons");
44 declareProperty("TrackContainerKey", m_trackSGKey="InDetTrackParticles");
45
46 declareProperty("NumberOfLeptons", m_nLeptons=2);
47 declareProperty("NumberOfElectrons", m_nElectrons=0);
48 declareProperty("NumberOfMuons", m_nMuons=0);
49 declareProperty("NumberOfJets", m_nJets=0);
50 declareProperty("NumberOfMergedJets0", m_nMergedJets[0]=0);
51 declareProperty("NumberOfMergedJets1", m_nMergedJets[1]=0);
52 declareProperty("NumberOfMergedJets2", m_nMergedJets[2]=0);
53 declareProperty("NumberOfPhotons", m_nPhotons=0);
54 declareProperty("NumberOfTracks", m_nTracks=0);
55
56 declareProperty("ElectronQuality", m_electronQual="any");
57 declareProperty("MuonQuality", m_muonQual="inMS");
58 declareProperty("TightElectronQuality", m_tightElectronQual="DFCommonElectronsLHVeryLoose");
59 declareProperty("TightMuonQuality", m_tightMuonQual="DFCommonGoodMuon");
60 declareProperty("JetQuality", m_jetQual="any");
61 declareProperty("MergedJetQuality0", m_mergedJetQual[0]="any");
62 declareProperty("MergedJetQuality1", m_mergedJetQual[1]="any");
63 declareProperty("MergedJetQuality2", m_mergedJetQual[2]="any");
64 declareProperty("PhotonQuality", m_photonQual="any");
65
66 declareProperty("PrimaryElectronQuality4L", m_primaryElectronQual4L="DFCommonElectronsLHLoose");
67
68 declareProperty("Trigger2L", m_trigger2L=std::vector<std::string>());
69 declareProperty("TriggerTP", m_triggerTP=std::vector<std::string>());
70 declareProperty("Trigger2L2Q", m_trigger2L2Q=std::vector<std::string>());
71 declareProperty("TriggerJPSI", m_triggerJPSI=std::vector<std::string>());
72 declareProperty("TriggerPHI", m_triggerPHI=std::vector<std::string>());
73
74 declareProperty("ElectronEtCut", m_electronEtCut=10.*CLHEP::GeV);
75 declareProperty("MuonPtCut", m_muonPtCut=10.*CLHEP::GeV);
76 declareProperty("TightElectronEtCut", m_tightElectronEtCut=15.*CLHEP::GeV);
77 declareProperty("TightMuonPtCut", m_tightMuonPtCut=15.*CLHEP::GeV);
78 declareProperty("JetPtCut", m_jetPtCut=15.*CLHEP::GeV);
79 declareProperty("MergedJetPtCut0", m_mergedJetPtCut[0]=100.*CLHEP::GeV);
80 declareProperty("MergedJetPtCut1", m_mergedJetPtCut[1]=150.*CLHEP::GeV);
81 declareProperty("MergedJetPtCut2", m_mergedJetPtCut[2]=150.*CLHEP::GeV);
82 declareProperty("PhotonPtCut", m_photonPtCut=15.*CLHEP::GeV);
83 declareProperty("TrackPtCut", m_trackPtCut=20.*CLHEP::GeV);
84
85 declareProperty("ElectronEtaCut", m_electronEtaCut=9999.);
86 declareProperty("MuonEtaCut", m_muonEtaCut=9999.);
87 declareProperty("CaloMuonEtaCut", m_caloMuonEtaCut=0.2);
88 declareProperty("JetEtaCut", m_jetEtaCut=2.6);
89 declareProperty("MergedJetEtaCut0", m_mergedJetEtaCut[0]=2.6);
90 declareProperty("MergedJetEtaCut1", m_mergedJetEtaCut[1]=2.6);
91 declareProperty("MergedJetEtaCut2", m_mergedJetEtaCut[2]=2.6);
92 declareProperty("PhotonEtaCut", m_photonEtaCut=2.5);
93
94 declareProperty("InvariantMassCut", m_invariantMassCut=0.*CLHEP::GeV);
95 declareProperty("InvariantMassJpsiLowCut", m_invariantMassJpsiLowCut=2.0*CLHEP::GeV);
96 declareProperty("InvariantMassJpsiUpCut", m_invariantMassJpsiUpCut=4.3*CLHEP::GeV);
97 declareProperty("InvariantMassUpsilonLowCut", m_invariantMassUpsilonLowCut=8.0*CLHEP::GeV);
98 declareProperty("InvariantMassUpsilonUpCut", m_invariantMassUpsilonUpCut=12.0*CLHEP::GeV);
99 declareProperty("InvariantMassPhiLowCut", m_invariantMassPhiLowCut=2.*s_MKplus);
100 declareProperty("InvariantMassPhiUpCut", m_invariantMassPhiUpCut=1.2*CLHEP::GeV);
101
102 declareProperty("LeadingElectronEtCut", m_leadingElectronEtCut=0.*CLHEP::GeV);
103 declareProperty("LeadingMuonPtCut", m_leadingMuonPtCut=0.*CLHEP::GeV);
104
105 declareProperty("DRElectronJetCut", m_dRElectronJetCut=0.05);
106
107 declareProperty("CheckLArError", m_checkLArError=true);
108 declareProperty("UseDefaultElectronFourMomentum", m_defaultElectronFourMomentum=true);
109
110 declareProperty("UseDFCommonJetFourMomentum", m_DFCommonJetFourMomentum=true);
111
112 declareProperty("RequireTightLeptons", m_requireTightLeptons=false);
113}
114
115// Destructor
118
119// Athena initialize and finalize
121{
122 ATH_MSG_VERBOSE("initialize() ...");
123
124 // if(m_defaultElectronFourMomentum==true and m_DFCommonElectronFourMomentum==true) {
125 // ATH_MSG_FATAL("Wrong setting both m_defaultElectronFourMomentum and m_DFCommonElectronFourMomentum are true.");
126 // return StatusCode::FAILURE;
127 // }
128
129 // trigger decision tool
130 if(m_trigDecisionTool.retrieve(DisableTool{m_skipTriggerRequirement}).isFailure()) {
131 ATH_MSG_FATAL("Failed to retrieve tool: " << m_trigDecisionTool);
132 return StatusCode::FAILURE;
133 }
134 ATH_MSG_INFO("Retrieved tool: " << m_trigDecisionTool);
135
136 return StatusCode::SUCCESS;
137}
138
140{
141 ATH_MSG_VERBOSE("finalize() ...");
142 ATH_MSG_INFO("Processed " << m_ntot << " events, " << m_npass << " events passed filter ");
143 return StatusCode::SUCCESS;
144}
145
146// The filter itself
148{
149 m_ntot++;
150 bool acceptEvent(false);
151 StatusCode sc(StatusCode::SUCCESS);
152
153 // Retrieve EventInfo
154 const xAOD::EventInfo *eventInfo(nullptr);
155 ATH_CHECK(evtStore()->retrieve(eventInfo), false);
156
157 // LAr error check
158 if(m_checkLArError) {
160 return acceptEvent;
161 }
162 }
163
165 // Electrons
166 if(m_nElectrons>0 or m_nLeptons>0) {
167 const xAOD::ElectronContainer *electrons(nullptr);
168 ATH_CHECK(evtStore()->retrieve(electrons, m_electronSGKey), false);
169 for(const auto *el: *electrons) {
170 if(this->checkElectronQuality(el)) evt.goodElectrons.push_back(el);
171 }
172 }
173
174 // Muons
175 if(m_nMuons>0 or m_nLeptons>0) {
176 const xAOD::MuonContainer *muons(nullptr);
177 ATH_CHECK(evtStore()->retrieve(muons, m_muonSGKey), false);
178 for(const auto *mu: *muons) {
179 if(this->checkMuonQuality(mu)) evt.goodMuons.push_back(mu);
180 }
181 }
182
183 // Jets
184 if(m_nJets>0) {
185 const xAOD::JetContainer *jets(nullptr);
186 ATH_CHECK(evtStore()->retrieve(jets, m_jetSGKey), false);
187 for(const auto *jet: *jets) {
188 if(this->checkJetQuality(jet)) evt.goodJets.push_back(jet);
189 }
190 }
191 for(unsigned int type(0); type<NUMBER_OF_MERGED_JET_TYPES; type++) {
192 if(m_nMergedJets[type]>0) {
193 const xAOD::JetContainer *jets(nullptr);
194 ATH_CHECK(evtStore()->retrieve(jets, m_mergedJetSGKey[type]), false);
195 for(const auto *jet: *jets) {
196 if(this->checkMergedJetQuality(jet, type)) evt.goodMergedJets[type].push_back(jet);
197 }
198 }
199 }
200
201 // Photons
202 if(m_nPhotons>0) {
203 const xAOD::PhotonContainer *photons(nullptr);
204 ATH_CHECK(evtStore()->retrieve(photons, m_photonSGKey), false);
205 for(const auto *ph: *photons) {
206 if(this->checkPhotonQuality(ph)) evt.goodPhotons.push_back(ph);
207 }
208 }
209
210 // Tracks
211 if(m_nTracks>0) {
212 const xAOD::TrackParticleContainer *tracks(nullptr);
213 ATH_CHECK(evtStore()->retrieve(tracks, m_trackSGKey), false);
214 for(const auto *trk: *tracks) {
215 if(this->checkTrackQuality(trk)) evt.goodTracks.push_back(trk);
216 }
217 }
218
219 // Check conditions of filters
220 if(m_filterType=="2L") {
221 if(this->check2L(evt)) acceptEvent = true;
222 } else if(m_filterType=="4L") {
223 if(this->check4L(evt)) acceptEvent = true;
224 } else if(m_filterType=="TP") {
225 if(this->checkTP(evt)) acceptEvent = true;
226 } else if(m_filterType=="2L2Q") {
227 if(this->check2L2Q(evt)) acceptEvent = true;
228 } else if(m_filterType=="JPSI") {
229 if(this->checkJPSI(evt) or this->checkPHI(evt)) acceptEvent = true;
230 }
231
232 if(acceptEvent) m_npass++;
233 return acceptEvent;
234}
235
237{
238 if(!el) return false;
239
240 const std::string electronQual(isTight ? m_tightElectronQual : m_electronQual);
241 const double electronEtCut(isTight ? m_tightElectronEtCut : m_electronEtCut);
242
243 if(electronQual!="any") {
244 bool value(false);
245 bool defined(false);
246 if(electronQual=="DFCommonElectronsLHVeryLoose" or
247 electronQual=="DFCommonElectronsLHLoose" or
248 electronQual=="DFCommonElectronsLHMedium" or
249 electronQual=="DFCommonElectronsLHTight" or
250 electronQual=="DFCommonElectronsML") {
251 // Use Derivation Framework variable to pickup possible new correction result
252 // If the same electron likelihood configuration is used in AOD creation and DAOD creation,
253 // DFCommonElectronsLHLoose and LHLoose are identical.
254 SG::ConstAccessor<char> qualAcc(electronQual);
255 if(qualAcc.isAvailable(*el)) {
256 defined = true;
257 value = static_cast<bool>(qualAcc(*el));
258 }
259 } else {
260 // Electron menu is defined in http://acode-browser.usatlas.bnl.gov/lxr/source/atlas/Reconstruction/egamma/egammaTools/python/EMPIDBuilderBase.py
261 defined = el->passSelection(value, electronQual);
262 }
263 if(not(value and defined)) return false;
264 }
265
266 const xAOD::TrackParticle *trackParticle(el->trackParticle());
267 if(!trackParticle) {
268 ATH_MSG_DEBUG("xAOD::TrackParticle pointer is null");
269 return false;
270 }
271 uint8_t numberOfPixelHits(0);
272 if(!trackParticle->summaryValue(numberOfPixelHits, xAOD::numberOfPixelHits)) {
273 ATH_MSG_WARNING("xAOD::TrackParticle does not give summaryValue correctly for xAOD::numberOfPixelHits");
274 return false;
275 }
276 uint8_t numberOfSCTHits(0);
277 if(!trackParticle->summaryValue(numberOfSCTHits, xAOD::numberOfSCTHits)) {
278 ATH_MSG_WARNING("xAOD::TrackParticle does not give summaryValue correctly for xAOD::numberOfSCTHits");
279 return false;
280 }
281 if(numberOfPixelHits+numberOfSCTHits==0) return false;
282
283 const xAOD::CaloCluster *caloCluster(el->caloCluster());
284 if(!caloCluster) {
285 ATH_MSG_WARNING("xAOD::CaloCluster pointer is null");
286 return false;
287 }
288
289 double eta(trackParticle->eta());
290 if(fabs(eta)>10.) return false;
291 double et(caloCluster->e()/cosh(eta));
292
293 if(et<electronEtCut) return false;
294 if(fabs(eta)>m_electronEtaCut) return false;
295
296 return true;
297}
298
300{
301 if(!mu) return false;
302
303 const std::string muonQual(isTight ? m_tightMuonQual : m_muonQual);
304 const double muonPtCut(isTight ? m_tightMuonPtCut : m_muonPtCut);
305
306 if(muonQual=="any") {
307 // do nothing
308 } else if(muonQual=="combined") {
309 if(mu->muonType()!=xAOD::Muon::Combined) return false;
310 } else if(muonQual=="standalone") {
311 if(mu->muonType()!=xAOD::Muon::MuonStandAlone) return false;
312 } else if(muonQual=="lowpt") {
313 if(mu->muonType()!=xAOD::Muon::SegmentTagged) return false;
314 } else if(muonQual=="combined+lowpt") {
315 if(mu->muonType()!=xAOD::Muon::Combined and mu->muonType()!=xAOD::Muon::SegmentTagged) return false;
316 } else if(muonQual=="inMS") {
317 if(mu->muonType()==xAOD::Muon::MuonStandAlone and fabs(fabs(mu->eta())-2.6)>0.12) return false;
318 } else if(muonQual=="DFCommonGoodMuon") { // Derivation Framework variable
319 static const SG::ConstAccessor<char> DFCommonGoodMuonAcc("DFCommonGoodMuon");
320 if(!DFCommonGoodMuonAcc.withDefault(*mu, false)) return false;
321 } else if(muonQual=="DFCommonMuonsLoose") { // Derivation Framework variable
322 static const SG::ConstAccessor<char> DFCommonMuonsLooseAcc("DFCommonMuonsLoose");
323 if(!DFCommonMuonsLooseAcc.withDefault(*mu, false)) return false;
324 } else if(muonQual=="DFCommonMuonsMedium") { // Derivation Framework variable
325 static const SG::ConstAccessor<char> DFCommonMuonsMediumAcc("DFCommonMuonsMedium");
326 if(!DFCommonMuonsMediumAcc.withDefault(*mu, false)) return false;
327 } else if(muonQual=="DFCommonMuonsTight") { // Derivation Framework variable
328 static const SG::ConstAccessor<char> DFCommonMuonsTightAcc("DFCommonMuonsTight");
329 if(!DFCommonMuonsTightAcc.withDefault(*mu, false)) return false;
330 } else {
331 ATH_MSG_WARNING("Muon quality " << muonQual << "is not defined");
332 return false;
333 }
334
335 if(mu->pt()<muonPtCut) return false;
336 if(fabs(mu->eta())>m_muonEtaCut) return false;
337 if(muonQual!="DFCommonGoodMuon" and
338 (mu->muonType()==xAOD::Muon::CaloTagged and fabs(mu->eta())>m_caloMuonEtaCut)) return false;
339
340 return true;
341}
342
344{
345 if(!jet) return false;
346
347 if(m_jetQual!="any") {
348 // do something
349 }
350
351 TLorentzVector tlv(this->jetFourMomentum(jet));
352 if(tlv.Pt()<m_jetPtCut) return false;
353 if(fabs(tlv.Eta())>m_jetEtaCut) return false;
354
355 return true;
356}
357
359{
360 if(!jet) return false;
361
362 if(m_mergedJetQual[type]!="any") {
363 // do something
364 }
365
366 if(jet->pt()<m_mergedJetPtCut[type]) return false;
367 if(fabs(jet->eta())>m_mergedJetEtaCut[type]) return false;
368
369 return true;
370}
371
373{
374 if(!ph) return false;
375
376 if(m_photonQual!="any") {
377 bool value(false);
378 if(!ph->passSelection(value, m_photonQual)) {
379 ATH_MSG_WARNING("xAOD::Photon does not have menu of " << m_photonQual);
380 return false;
381 }
382 if(!value) return false;
383 }
384
385 if(ph->pt()<m_photonPtCut) return false;
386 if(fabs(ph->eta())>m_photonEtaCut) return false;
387
388 return true;
389}
390
392{
393 if(!trk) return false;
394
395 if(trk->pt()<m_trackPtCut) return false;
396
397 return true;
398}
399
401{
402 if(!(m_nLeptons>0 and evt.goodElectrons.size()+evt.goodMuons.size()>=m_nLeptons)) return false;
403 if(!(evt.goodJets.size()>=m_nJets and evt.goodPhotons.size()>=m_nPhotons)) return false;
404
405 bool isTriggerFired(m_trigger2L.empty() or m_skipTriggerRequirement);
406 for(unsigned int i(0); i<m_trigger2L.size(); i++) {
407 if(m_trigDecisionTool->isPassed(m_trigger2L.at(i))) {
408 isTriggerFired = true;
409 break;
410 }
411 }
412 if(!isTriggerFired) return false;
413
414 unsigned int nGoodLeptons(evt.goodElectrons.size()+evt.goodMuons.size());
415 std::vector<TLorentzVector> v_tlv(nGoodLeptons);
416 std::vector<bool> v_isElectron(nGoodLeptons);
417 std::vector<bool> v_isTight(nGoodLeptons);
418
419 for(unsigned int el_i(0); el_i<evt.goodElectrons.size(); el_i++) {
420 const xAOD::Electron *el(evt.goodElectrons.at(el_i));
421 TLorentzVector tlv(this->electronFourMomentum(el));
422 v_tlv.at(el_i) = tlv;
423 v_isElectron.at(el_i) = true;
424 v_isTight.at(el_i) = this->checkElectronQuality(el, true);
425 }
426
427 for(unsigned int mu_i(0); mu_i<evt.goodMuons.size(); mu_i++) {
428 const xAOD::Muon *mu(evt.goodMuons.at(mu_i));
430 unsigned int mu_j(evt.goodElectrons.size()+mu_i);
431 v_tlv.at(mu_j) = tlv;
432 v_isElectron.at(mu_j) = false;
433 v_isTight.at(mu_j) = this->checkMuonQuality(mu, true);
434 }
435
436 for(unsigned int i0(0); i0<nGoodLeptons; i0++) {
437 for(unsigned int i1(i0+1); i1<nGoodLeptons; i1++) {
438 if(m_requireTightLeptons and (not (v_isTight.at(i0) or v_isTight.at(i1)))) continue;
439
440 TLorentzVector tlv_2lep(v_tlv.at(i0) + v_tlv.at(i1));
441 // Check two lepton mass
442 if(tlv_2lep.M()>m_invariantMassCut) return true;
443 }
444 }
445
446 return false;
447}
448
450{
451 if(!(m_nLeptons>0 and evt.goodElectrons.size()+evt.goodMuons.size()>=m_nLeptons)) return false;
452 if(!(evt.goodJets.size()>=m_nJets and evt.goodPhotons.size()>=m_nPhotons)) return false;
453
454 unsigned int nGoodLeptons(evt.goodElectrons.size()+evt.goodMuons.size());
455 std::vector<TLorentzVector> v_tlv(nGoodLeptons);
456 std::vector<bool> v_pid(nGoodLeptons);
457
458 for(unsigned int el_i(0); el_i<evt.goodElectrons.size(); el_i++) {
459 const xAOD::Electron *el(evt.goodElectrons.at(el_i));
460 TLorentzVector tlv(this->electronFourMomentum(el));
461 v_tlv.at(el_i) = tlv;
462
463 bool value(false);
464 bool defined(false);
465 if(m_primaryElectronQual4L.empty()) {
466 // In the case of no identification requirement
467 defined = true;
468 value = true;
469 } else if(m_primaryElectronQual4L=="DFCommonElectronsLHVeryLoose" or
470 m_primaryElectronQual4L=="DFCommonElectronsLHLoose" or
471 m_primaryElectronQual4L=="DFCommonElectronsLHMedium" or
472 m_primaryElectronQual4L=="DFCommonElectronsLHTight" or
473 m_primaryElectronQual4L=="DFCommonElectronsML") {
474 // Use Derivation Framework variable to pickup possible new correction result
475 // If the same electron likelihood configuration is used in AOD creation and DAOD creation,
476 // DFCommonElectronsLHLoose and LHLoose are identical.
478 if(primEleAcc.isAvailable(*el)) {
479 defined = true;
480 value = static_cast<bool>(primEleAcc(*el));
481 }
482 } else {
483 // Electron menu is defined in http://acode-browser.usatlas.bnl.gov/lxr/source/atlas/Reconstruction/egamma/egammaTools/python/EMPIDBuilderBase.py
484 defined = el->passSelection(value, m_primaryElectronQual4L);
485 }
486
487 v_pid.at(el_i) = (value and defined);
488 }
489
490 for(unsigned int mu_i(0); mu_i<evt.goodMuons.size(); mu_i++) {
491 const xAOD::Muon *mu(evt.goodMuons.at(mu_i));
493 unsigned int mu_j(evt.goodElectrons.size()+mu_i);
494 v_tlv.at(mu_j) = tlv;
495 v_pid.at(mu_j) = true;
496 }
497
498 for(unsigned int i0(0); i0<nGoodLeptons; i0++) {
499 for(unsigned int i1(i0+1); i1<nGoodLeptons; i1++) {
500 for(unsigned int i2(i1+1); i2<nGoodLeptons; i2++) {
501 for(unsigned int i3(i2+1); i3<nGoodLeptons; i3++) {
502 TLorentzVector tlv_4lep(v_tlv.at(i0) + v_tlv.at(i1) + v_tlv.at(i2) + v_tlv.at(i3));
503 // Check four lepton mass
504 if(tlv_4lep.M()<m_invariantMassCut) continue;
505
506 // Check primary dilepton's electron PID (muon PID is always true)
507 if(fabs((v_tlv.at(i0)+v_tlv.at(i1)).M()-s_MZ)<fabs((v_tlv.at(i2)+v_tlv.at(i3)).M()-s_MZ)) {
508 if(v_pid.at(i0) and v_pid.at(i1)) return true;
509 } else {
510 if(v_pid.at(i2) and v_pid.at(i3)) return true;
511 }
512 if(fabs((v_tlv.at(i0)+v_tlv.at(i2)).M()-s_MZ)<fabs((v_tlv.at(i1)+v_tlv.at(i3)).M()-s_MZ)) {
513 if(v_pid.at(i0) and v_pid.at(i2)) return true;
514 } else {
515 if(v_pid.at(i1) and v_pid.at(i3)) return true;
516 }
517 if(fabs((v_tlv.at(i0)+v_tlv.at(i3)).M()-s_MZ)<fabs((v_tlv.at(i1)+v_tlv.at(i2)).M()-s_MZ)) {
518 if(v_pid.at(i0) and v_pid.at(i3)) return true;
519 } else {
520 if(v_pid.at(i1) and v_pid.at(i2)) return true;
521 }
522 }
523 }
524 }
525 }
526
527 return false;
528}
529
531{
532 if(!(m_nLeptons>0 and evt.goodElectrons.size()+evt.goodMuons.size()>=m_nLeptons)) return false;
533
534 bool isTriggerFired(m_triggerTP.empty() or m_skipTriggerRequirement);
535 for(unsigned int i(0); i<m_triggerTP.size(); i++) {
536 if(m_trigDecisionTool->isPassed(m_triggerTP.at(i))) {
537 isTriggerFired = true;
538 break;
539 }
540 }
541 if(!isTriggerFired) return false;
542
543 unsigned int nGoodLeptons(evt.goodElectrons.size()+evt.goodMuons.size());
544 std::vector<TLorentzVector> v_tlv(nGoodLeptons);
545 std::vector<bool> v_isElectron(nGoodLeptons);
546
547 for(unsigned int el_i(0); el_i<evt.goodElectrons.size(); el_i++) {
548 const xAOD::Electron *el(evt.goodElectrons.at(el_i));
549 TLorentzVector tlv(this->electronFourMomentum(el));
550 v_tlv.at(el_i) = tlv;
551 v_isElectron.at(el_i) = true;
552 }
553
554 for(unsigned int mu_i(0); mu_i<evt.goodMuons.size(); mu_i++) {
555 const xAOD::Muon *mu(evt.goodMuons.at(mu_i));
557 unsigned int mu_j(evt.goodElectrons.size()+mu_i);
558 v_tlv.at(mu_j) = tlv;
559 v_isElectron.at(mu_j) = false;
560 }
561
562 for(unsigned int i0(0); i0<nGoodLeptons; i0++) {
563 for(unsigned int i1(i0+1); i1<nGoodLeptons; i1++) {
564 if(v_isElectron.at(i0)!=v_isElectron.at(i1)) continue;
565
566 TLorentzVector tlv_2lep(v_tlv.at(i0) + v_tlv.at(i1));
567 // Check two lepton mass
568 if(tlv_2lep.M()<m_invariantMassCut) continue;
569
570 // Leading lepton ET/pT cut
571 if((v_tlv.at(i0).Pt()>v_tlv.at(i1).Pt() ? v_tlv.at(i0).Pt() : v_tlv.at(i1).Pt()) > (v_isElectron.at(i0) ? m_leadingElectronEtCut : m_leadingMuonPtCut)) return true;
572 }
573 }
574
575 return false;
576}
577
579{
580 if(!(m_nLeptons>0 and evt.goodElectrons.size()+evt.goodMuons.size()>=m_nLeptons)) return false;
581
582 bool isTriggerFired(m_trigger2L2Q.empty() or m_skipTriggerRequirement);
583 for(unsigned int i(0); i<m_trigger2L2Q.size(); i++) {
584 if(m_trigDecisionTool->isPassed(m_trigger2L2Q.at(i))) {
585 isTriggerFired = true;
586 break;
587 }
588 }
589 if(!isTriggerFired) return false;
590
591 bool checkGoodJets(evt.goodJets.size()>=m_nJets and m_nJets>0);
592 for(unsigned int type(0); type<NUMBER_OF_MERGED_JET_TYPES; type++) {
593 if(m_nMergedJets[type]>0) {
594 checkGoodJets = (checkGoodJets or (evt.goodMergedJets[type].size()>=m_nMergedJets[type]));
595 }
596 }
597 if(!checkGoodJets) return false;
598
599 unsigned int nGoodLeptons(evt.goodElectrons.size()+evt.goodMuons.size());
600 std::vector<TLorentzVector> v_tlv(nGoodLeptons);
601 std::vector<bool> v_isElectron(nGoodLeptons);
602 std::vector<bool> v_isTight(nGoodLeptons);
603
604 for(unsigned int el_i(0); el_i<evt.goodElectrons.size(); el_i++) {
605 const xAOD::Electron *el(evt.goodElectrons.at(el_i));
606 TLorentzVector tlv(this->electronFourMomentum(el));
607 v_tlv.at(el_i) = tlv;
608 v_isElectron.at(el_i) = true;
609 v_isTight.at(el_i) = this->checkElectronQuality(el, true);
610 }
611
612 for(unsigned int mu_i(0); mu_i<evt.goodMuons.size(); mu_i++) {
613 const xAOD::Muon *mu(evt.goodMuons.at(mu_i));
615 unsigned int mu_j(evt.goodElectrons.size()+mu_i);
616 v_tlv.at(mu_j) = tlv;
617 v_isElectron.at(mu_j) = false;
618 v_isTight.at(mu_j) = this->checkMuonQuality(mu, true);
619 }
620
621 for(unsigned int i0(0); i0<nGoodLeptons; i0++) {
622 for(unsigned int i1(i0+1); i1<nGoodLeptons; i1++) {
623 // if(v_isElectron.at(i0)!=v_isElectron.at(i1)) continue; // Events with N(e)=1 and N(mu)=1 are kept.
624 if(m_requireTightLeptons and (not (v_isTight.at(i0) or v_isTight.at(i1)))) continue;
625
626 TLorentzVector tlv_2lep(v_tlv.at(i0) + v_tlv.at(i1));
627 // Check two lepton mass
628 if(tlv_2lep.M()<m_invariantMassCut) continue;
629
630 // dR(e-jet)>0.05 is required for at least two jets
631 if(v_isElectron.at(i0)) {
632 unsigned int nGoodJetsWithDRCut(0);
633 unsigned int nGoodJets(evt.goodJets.size());
634 for(unsigned int j(0); j<nGoodJets; j++) {
635 const xAOD::Jet *jet(evt.goodJets.at(j));
636 TLorentzVector jet_tlv(this->jetFourMomentum(jet));
637
638 double dR_0(DerivationFramework::SkimmingToolHIGG2::getDeltaR(v_tlv.at(i0).Eta(), v_tlv.at(i0).Phi(), jet_tlv.Eta(), jet_tlv.Phi()));
639 if(dR_0<m_dRElectronJetCut) continue;
640
641 double dR_1(DerivationFramework::SkimmingToolHIGG2::getDeltaR(v_tlv.at(i1).Eta(), v_tlv.at(i1).Phi(), jet_tlv.Eta(), jet_tlv.Phi()));
642 if(dR_1<m_dRElectronJetCut) continue;
643
644 nGoodJetsWithDRCut++;
645 }
646
647 bool checkGoodJetsWithDRCut(nGoodJetsWithDRCut>=m_nJets and m_nJets>0);
648
649 for(unsigned int type(0); type<NUMBER_OF_MERGED_JET_TYPES; type++) {
650 if(m_nMergedJets[type]>0) {
651 unsigned int nGoodMergedJetsWithDRCut(0);
652 unsigned int nGoodMergedJets(evt.goodMergedJets[type].size());
653 for(unsigned int j(0); j<nGoodMergedJets; j++) {
654 const xAOD::Jet *jet(evt.goodMergedJets[type].at(j));
655
656 double dR_0(DerivationFramework::SkimmingToolHIGG2::getDeltaR(v_tlv.at(i0).Eta(), v_tlv.at(i0).Phi(), jet->eta(), jet->phi()));
657 if(dR_0<m_dRElectronJetCut) continue;
658
659 double dR_1(DerivationFramework::SkimmingToolHIGG2::getDeltaR(v_tlv.at(i1).Eta(), v_tlv.at(i1).Phi(), jet->eta(), jet->phi()));
660 if(dR_1<m_dRElectronJetCut) continue;
661
662 nGoodMergedJetsWithDRCut++;
663 }
664
665 checkGoodJetsWithDRCut = (checkGoodJetsWithDRCut or (nGoodMergedJetsWithDRCut>=m_nMergedJets[type]));
666 }
667 }
668 if(!checkGoodJetsWithDRCut) return false;
669 }
670
671 // Leading lepton ET/pT cut
672 if((v_tlv.at(i0).Pt()>v_tlv.at(i1).Pt() ? v_tlv.at(i0).Pt() : v_tlv.at(i1).Pt()) > (v_isElectron.at(i0) ? m_leadingElectronEtCut : m_leadingMuonPtCut)) return true;
673 }
674 }
675
676 return false;
677}
678
680{
681 if(!(m_nMuons>0 and evt.goodMuons.size()>=m_nMuons)) return false;
682 if(!(evt.goodPhotons.size()>=m_nPhotons)) return false;
683
684 bool isTriggerFired(m_triggerJPSI.empty() or m_skipTriggerRequirement);
685 for(unsigned int i(0); i<m_triggerJPSI.size(); i++) {
686 if(m_trigDecisionTool->isPassed(m_triggerJPSI.at(i))) {
687 isTriggerFired = true;
688 break;
689 }
690 }
691 if(!isTriggerFired) return false;
692
693 std::vector<TLorentzVector> v_tlv(evt.goodMuons.size());
694
695 for(unsigned int mu_i(0); mu_i<evt.goodMuons.size(); mu_i++) {
696 const xAOD::Muon *mu(evt.goodMuons.at(mu_i));
698 v_tlv.at(mu_i) = tlv;
699 }
700
701 unsigned int nGoodLeptons(v_tlv.size());
702 for(unsigned int i0(0); i0<nGoodLeptons; i0++) {
703 for(unsigned int i1(i0+1); i1<nGoodLeptons; i1++) {
704 TLorentzVector tlv_2lep(v_tlv.at(i0) + v_tlv.at(i1));
705
706 // Check di-muon mass
707 if((tlv_2lep.M()<m_invariantMassJpsiLowCut or tlv_2lep.M()>m_invariantMassJpsiUpCut) and
708 (tlv_2lep.M()<m_invariantMassUpsilonLowCut or tlv_2lep.M()>m_invariantMassUpsilonUpCut)) continue;
709
710 // Check leading muon pT
711 if((v_tlv.at(i0).Pt()>v_tlv.at(i1).Pt() ? v_tlv.at(i0).Pt() : v_tlv.at(i1).Pt())>m_leadingMuonPtCut) return true;
712 }
713 }
714
715 return false;
716}
717
719{
720 // Check if there are candidates
721 if(!(m_nTracks>0 and evt.goodTracks.size()>=m_nTracks)) return false;
722 if(!(evt.goodPhotons.size()>=m_nPhotons)) return false;
723
724 // Check if triggers are OK
725 bool isTriggerFired(m_triggerPHI.empty() or m_skipTriggerRequirement);
726 for(unsigned int i(0); i<m_triggerPHI.size(); i++) {
727 if(m_trigDecisionTool->isPassed(m_triggerPHI.at(i))) {
728 isTriggerFired = true;
729 break;
730 }
731 }
732 if(!isTriggerFired) return false;
733
734 // Get 4-momentum of tracks (=charged kaons)
735 std::vector<TLorentzVector> v_tlv[2];
736 for(unsigned int trk_i(0); trk_i<evt.goodTracks.size(); trk_i++) {
737 const xAOD::TrackParticle *trk(evt.goodTracks.at(trk_i));
738 TLorentzVector tlv;
739 tlv.SetPtEtaPhiM(trk->pt(), trk->eta(), trk->phi(), s_MKplus); // Kaon is assumed.
740 v_tlv[trk->charge()>0. ? 0 : 1].push_back(tlv); // 0 is positive, 1 is negative
741 }
742
743 // Check track pair mass
744 unsigned int nGoodTracks[2];
745 nGoodTracks[0] = v_tlv[0].size();
746 nGoodTracks[1] = v_tlv[1].size();
747 for(unsigned int i0(0); i0<nGoodTracks[0]; i0++) {
748 for(unsigned int i1(0); i1<nGoodTracks[1]; i1++) {
749 TLorentzVector tlv_2trk(v_tlv[0].at(i0) + v_tlv[1].at(i1));
750 if(tlv_2trk.M()<m_invariantMassPhiLowCut or tlv_2trk.M()>m_invariantMassPhiUpCut) continue;
751 return true; // One candidate is found.
752 }
753 }
754
755 return false; // No candidate is found.
756}
757
759{
760 TLorentzVector tlv;
761 tlv.SetPtEtaPhiE(el->pt(), el->eta(), el->phi(), el->e());
762 if(m_defaultElectronFourMomentum) return tlv;
763
764 const xAOD::TrackParticle *trackParticle(el->trackParticle());
765 if(!trackParticle) {
766 ATH_MSG_WARNING("xAOD::TrackParticle pointer is null");
767 return tlv;
768 }
769 const xAOD::CaloCluster *caloCluster(el->caloCluster());
770 if(!caloCluster) {
771 ATH_MSG_WARNING("xAOD::CaloCluster pointer is null");
772 return tlv;
773 }
774
775 double eta(trackParticle->eta());
776 double phi(trackParticle->phi());
777 if(fabs(eta)>10.) {
778 ATH_MSG_WARNING("fabs(trackParticle->eta()) = " << eta << " > 10.");
779 return tlv;
780 }
781 double e(caloCluster->e());
782 double et(e/cosh(eta));
783
784 tlv.SetPtEtaPhiE(et, eta, phi, e);
785 return tlv;
786}
787
789{
790 TLorentzVector tlv;
791 tlv.SetPtEtaPhiM(mu->pt(), mu->eta(), mu->phi(), mu->m());
792 return tlv;
793}
794
796{
797 TLorentzVector tlv;
799 static const SG::ConstAccessor<float> DFCommonJets_Calib_ptAcc("DFCommonJets_Calib_pt");
800 static const SG::ConstAccessor<float> DFCommonJets_Calib_etaAcc("DFCommonJets_Calib_eta");
801 static const SG::ConstAccessor<float> DFCommonJets_Calib_phiAcc("DFCommonJets_Calib_phi");
802 static const SG::ConstAccessor<float> DFCommonJets_Calib_mAcc("DFCommonJets_Calib_m");
803
804 const float& pt =DFCommonJets_Calib_ptAcc(*jet);
805 const float& eta=DFCommonJets_Calib_etaAcc(*jet);
806 const float& phi=DFCommonJets_Calib_phiAcc(*jet);
807 const float& m =DFCommonJets_Calib_mAcc(*jet);
808 tlv.SetPtEtaPhiM(pt, eta, phi, m);
809 }
810 else
811 tlv.SetPtEtaPhiM(jet->pt(), jet->eta(), jet->phi(), jet->m());
812
813 return tlv;
814}
815
816double DerivationFramework::SkimmingToolHIGG2::getDeltaR(const double eta1, const double phi1, const double eta2, const double phi2)
817{
818 double dEta(eta1 - eta2);
819 double dPhi(phi1 - phi2);
820 if(dPhi>+M_PI) dPhi -= 2.*M_PI;
821 if(dPhi<-M_PI) dPhi += 2.*M_PI;
822 double dR(sqrt(dEta*dEta + dPhi*dPhi));
823 return dR;
824}
825
#define M_PI
Scalar eta() const
pseudorapidity method
Scalar phi() const
phi method
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_FATAL(x)
#define ATH_MSG_INFO(x)
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
Helper class to provide constant type-safe access to aux data.
float et(const xAOD::jFexSRJetRoI *j)
static Double_t sc
A number of constexpr particle constants to avoid hardcoding them directly in various places.
std::vector< std::string > m_triggerJPSI
std::string m_mergedJetQual[NUMBER_OF_MERGED_JET_TYPES]
static double getDeltaR(const double eta1, const double phi1, const double eta2, const double phi2)
bool checkMuonQuality(const xAOD::Muon *mu, const bool isTight=false) const
TLorentzVector electronFourMomentum(const xAOD::Electron *el) const
bool checkTP(const Candidates &evt) const
bool check2L(const Candidates &evt) const
static TLorentzVector muonFourMomentum(const xAOD::Muon *mu)
bool checkJPSI(const Candidates &evt) const
bool checkPhotonQuality(const xAOD::Photon *ph) const
bool check2L2Q(const Candidates &evt) const
std::vector< std::string > m_trigger2L
virtual StatusCode finalize() override
virtual StatusCode initialize() override
double m_mergedJetEtaCut[NUMBER_OF_MERGED_JET_TYPES]
SkimmingToolHIGG2(const std::string &t, const std::string &n, const IInterface *p)
Constructor with parameters.
unsigned int m_nMergedJets[NUMBER_OF_MERGED_JET_TYPES]
bool checkPHI(const Candidates &evt) const
std::string m_mergedJetSGKey[NUMBER_OF_MERGED_JET_TYPES]
bool checkJetQuality(const xAOD::Jet *jet) const
bool checkElectronQuality(const xAOD::Electron *el, const bool isTight=false) const
TLorentzVector jetFourMomentum(const xAOD::Jet *jet) const
virtual bool eventPassesFilter() const override
Check that the current event passes this filter.
std::atomic< unsigned int > m_npass
ToolHandle< Trig::TrigDecisionTool > m_trigDecisionTool
bool checkMergedJetQuality(const xAOD::Jet *jet, const unsigned int type) const
std::vector< std::string > m_triggerPHI
std::vector< std::string > m_trigger2L2Q
bool checkTrackQuality(const xAOD::TrackParticle *trk) const
bool check4L(const Candidates &evt) const
double m_mergedJetPtCut[NUMBER_OF_MERGED_JET_TYPES]
Helper class to provide constant type-safe access to aux data.
bool isAvailable(const ELT &e) const
Test to see if this variable exists in the store.
const_reference_type withDefault(const ELT &e, const T &deflt) const
Fetch the variable for one element, as a const reference, with a default.
virtual double e() const
The total energy of the particle.
virtual double pt() const override final
The transverse momentum ( ) of the particle.
Definition Egamma_v1.cxx:66
virtual double eta() const override final
The pseudorapidity ( ) of the particle.
Definition Egamma_v1.cxx:71
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...
@ LAr
The LAr calorimeter.
@ Error
The sub-detector issued an error.
EventFlagErrorState errorState(EventFlagSubDet subDet) const
Get the error state for a particular sub-detector.
virtual double phi() const override final
The azimuthal angle ( ) of the particle (has range to .)
bool summaryValue(uint8_t &value, const SummaryType &information) const
Accessor for TrackSummary values.
virtual double pt() const override final
The transverse momentum ( ) of the particle.
virtual double eta() const override final
The pseudorapidity ( ) of the particle.
float charge() const
Returns the charge.
constexpr double chargedKaonMassInMeV
the mass of the charged kaon (in MeV)
constexpr double ZMassInMeV
the mass of the Z0 boson (in MeV)
Jet_v1 Jet
Definition of the current "jet version".
PhotonContainer_v1 PhotonContainer
Definition of the current "photon container version".
ElectronContainer_v1 ElectronContainer
Definition of the current "electron container version".
EventInfo_v1 EventInfo
Definition of the latest event info version.
CaloCluster_v1 CaloCluster
Define the latest version of the calorimeter cluster class.
TrackParticle_v1 TrackParticle
Reference the current persistent version:
TrackParticleContainer_v1 TrackParticleContainer
Definition of the current "TrackParticle container version".
Muon_v1 Muon
Reference the current persistent version:
Photon_v1 Photon
Definition of the current "egamma version".
JetContainer_v1 JetContainer
Definition of the current "jet container version".
MuonContainer_v1 MuonContainer
Definition of the current "Muon container version".
@ numberOfSCTHits
number of hits in SCT [unit8_t].
@ numberOfPixelHits
these are the pixel hits, including the b-layer [unit8_t].
Electron_v1 Electron
Definition of the current "egamma version".
Extra patterns decribing particle interation process.