ATLAS Offline Software
Loading...
Searching...
No Matches
DileptonOSSFInvariantMassWindowSelectorAlg.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
4
6
8
9using ROOT::Math::PtEtaPhiEVector;
10
11namespace CP {
12
14 : EL::AnaAlgorithm(name, pSvcLocator)
15 {}
16
34
36 // accessors
37 static const SG::ConstAccessor<float> acc_pt_dressed("pt_dressed");
38 static const SG::ConstAccessor<float> acc_eta_dressed("eta_dressed");
39 static const SG::ConstAccessor<float> acc_phi_dressed("phi_dressed");
40 static const SG::ConstAccessor<float> acc_e_dressed("e_dressed");
41
42 for (const auto &sys : m_systematicsList.systematicsVector()) {
43 // retrieve the EventInfo
44 const xAOD::EventInfo *evtInfo = nullptr;
45 ANA_CHECK(m_eventInfoHandle.retrieve(evtInfo, sys));
46
47 // default-decorate EventInfo
48 m_decoration.setBool(*evtInfo, 0, sys);
49
50 // check the preselection
51 if (m_preselection && !m_preselection.getBool(*evtInfo, sys))
52 continue;
53
54 // retrieve the electron container
55 const xAOD::ElectronContainer *electrons = nullptr;
57 ANA_CHECK(m_electronsHandle.retrieve(electrons, sys));
58 // retrieve the muon container
59 const xAOD::MuonContainer *muons = nullptr;
60 if (m_muonsHandle)
61 ANA_CHECK(m_muonsHandle.retrieve(muons, sys));
62 // retrieve the truth electron container
63 const xAOD::TruthParticleContainer *truthElectrons = nullptr;
65 ANA_CHECK(m_electronsTruthHandle.retrieve(truthElectrons, sys));
66 // retrieve the truth muon container
67 const xAOD::TruthParticleContainer *truthMuons = nullptr;
69 ANA_CHECK(m_muonsTruthHandle.retrieve(truthMuons, sys));
70
71 bool decision = false;
72
74 if (electrons->size() >= 2) {
75 for (size_t i = 0; i < electrons->size() - 1 && !decision; ++i) {
76 const xAOD::Electron* firstElectron = (*electrons)[i];
77 if (!m_electronSelection || m_electronSelection.getBool(*firstElectron, sys)) {
78 for (size_t j = i + 1; j < electrons->size() && !decision; ++j) {
79 const xAOD::Electron* secondElectron = (*electrons)[j];
80 if (!m_electronSelection || m_electronSelection.getBool(*secondElectron, sys)) {
81 if (firstElectron->charge() != secondElectron->charge()){
82 float mll = (firstElectron->p4() + secondElectron->p4()).M();
83 decision |= (mll < m_mll_upper && mll > m_mll_lower);
84 }
85 }
86 }
87 }
88 }
89 }
90
91 // If a pair of electrons satisfies the mass requirements, there is no need to loop over muon pairs. The event is either kept or vetoed hereafter.
92 if (!decision && muons->size() >= 2) {
93 for (size_t i = 0; i < muons->size() - 1 && !decision; ++i) {
94 const xAOD::Muon* firstMuon = (*muons)[i];
95 if (!m_muonSelection || m_muonSelection.getBool(*firstMuon, sys)) {
96 for (size_t j = i + 1; j < muons->size() && !decision; ++j) {
97 const xAOD::Muon* secondMuon = (*muons)[j];
98 if (!m_muonSelection || m_muonSelection.getBool(*secondMuon, sys)) {
99 if (firstMuon->charge() != secondMuon->charge()){
100 float mll = (firstMuon->p4() + secondMuon->p4()).M();
101 decision |= (mll < m_mll_upper && mll > m_mll_lower);
102 }
103 }
104 }
105 }
106 }
107 }
108 }
109 else {
110 if (truthElectrons->size() >= 2) {
111 for (size_t i = 0; i < truthElectrons->size() - 1 && !decision; ++i) {
112 const xAOD::TruthParticle* firstElectron = (*truthElectrons)[i];
113 if (!m_electronTruthSelection || m_electronTruthSelection.getBool(*firstElectron, sys)) {
114 for (size_t j = i + 1; j < truthElectrons->size() && !decision; ++j) {
115 const xAOD::TruthParticle* secondElectron = (*truthElectrons)[j];
116 if (!m_electronTruthSelection || m_electronTruthSelection.getBool(*secondElectron, sys)) {
117 if (firstElectron->charge() != secondElectron->charge()){
118 float mll = -1.;
120 PtEtaPhiEVector el0, el1;
121 el0.SetCoordinates(acc_pt_dressed(*firstElectron),
122 acc_eta_dressed(*firstElectron),
123 acc_phi_dressed(*firstElectron),
124 acc_e_dressed(*firstElectron));
125 el1.SetCoordinates(acc_pt_dressed(*secondElectron),
126 acc_eta_dressed(*secondElectron),
127 acc_phi_dressed(*secondElectron),
128 acc_e_dressed(*secondElectron));
129 mll = (el0+el1).M();
130 } else {
131 mll = (firstElectron->p4() + secondElectron->p4()).M();
132 }
133 decision |= (mll < m_mll_upper && mll > m_mll_lower);
134 }
135 }
136 }
137 }
138 }
139 }
140
141 // If a pair of electrons satisfies the mass requirements, there is no need to loop over muon pairs. The event is either kept or vetoed hereafter.
142 if (!decision && truthMuons->size() >= 2) {
143 for (size_t i = 0; i < truthMuons->size() - 1 && !decision; ++i) {
144 const xAOD::TruthParticle* firstMuon = (*truthMuons)[i];
145 if (!m_muonTruthSelection || m_muonTruthSelection.getBool(*firstMuon, sys)) {
146 for (size_t j = i + 1; j < truthMuons->size() && !decision; ++j) {
147 const xAOD::TruthParticle* secondMuon = (*truthMuons)[j];
148 if (!m_muonTruthSelection || m_muonTruthSelection.getBool(*secondMuon, sys)) {
149 if (firstMuon->charge() != secondMuon->charge()){
150 float mll = -1.;
152 PtEtaPhiEVector mu0, mu1;
153 mu0.SetCoordinates(acc_pt_dressed(*firstMuon),
154 acc_eta_dressed(*firstMuon),
155 acc_phi_dressed(*firstMuon),
156 acc_e_dressed(*firstMuon));
157 mu1.SetCoordinates(acc_pt_dressed(*secondMuon),
158 acc_eta_dressed(*secondMuon),
159 acc_phi_dressed(*secondMuon),
160 acc_e_dressed(*secondMuon));
161 mll = (mu0+mu1).M();
162 } else {
163 mll = (firstMuon->p4() + secondMuon->p4()).M();
164 }
165 decision |= (mll < m_mll_upper && mll > m_mll_lower);
166 }
167 }
168 }
169 }
170 }
171 }
172 }
173
174 if (m_veto) decision = !decision;
175 m_decoration.setBool(*evtInfo, decision, sys);
176
177 }
178 return StatusCode::SUCCESS;
179 }
180}
#define ANA_CHECK(EXP)
check whether the given expression was successful
CP::SysReadHandle< xAOD::TruthParticleContainer > m_electronsTruthHandle
DileptonOSSFInvariantMassWindowSelectorAlg(const std::string &name, ISvcLocator *pSvcLocator)
the standard constructor
Gaudi::Property< bool > m_veto
whether to veto events instead of selecting them
Gaudi::Property< bool > m_useDressedProperties
use dressed kinematics
CP::SysReadHandle< xAOD::TruthParticleContainer > m_muonsTruthHandle
size_type size() const noexcept
Returns the number of elements in the collection.
AnaAlgorithm(const std::string &name, ISvcLocator *pSvcLocator)
constructor with parameters
Helper class to provide constant type-safe access to aux data.
virtual FourMom_t p4() const override final
The full 4-momentum of the particle as a TLoretzVector.
Definition Egamma_v1.cxx:94
float charge() const
Obtain the charge of the object.
virtual FourMom_t p4() const
The full 4-momentum of the particle.
Definition Muon_v1.cxx:71
float charge() const
double charge() const
Physical charge.
virtual FourMom_t p4() const override final
The full 4-momentum of the particle.
Select isolated Photons, Electrons and Muons.
This module defines the arguments passed from the BATCH driver to the BATCH worker.
ElectronContainer_v1 ElectronContainer
Definition of the current "electron container version".
EventInfo_v1 EventInfo
Definition of the latest event info version.
TruthParticle_v1 TruthParticle
Typedef to implementation.
Muon_v1 Muon
Reference the current persistent version:
MuonContainer_v1 MuonContainer
Definition of the current "Muon container version".
TruthParticleContainer_v1 TruthParticleContainer
Declare the latest version of the truth particle container.
Electron_v1 Electron
Definition of the current "egamma version".