ATLAS Offline Software
Loading...
Searching...
No Matches
DiTauMassCalculatorAlg.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
3*/
4
6
9
10namespace CP {
11 using ROOT::Math::PtEtaPhiMVector;
12
14 {
15
16 // the Missing Mass Calculator tool
17 ANA_CHECK(m_mmc.retrieve());
18
19 // input handles
22
25
28
31
35
36 // output handles
51
55
56 ANA_CHECK(m_systematicsList.initialize());
57
58 return StatusCode::SUCCESS;
59 }
60
61 StatusCode DiTauMassCalculatorAlg::execute(const EventContext& ctx)
62 {
63 // decorate the default (failed-fit) values, for events where the MMC is not run
64 auto decorateDefaults = [this](const xAOD::EventInfo &evtInfo, const CP::SystematicSet &sys)
65 {
66 PtEtaPhiMVector null4V(0.0, 0.0, 0.0, 0.0);
67 if (m_doMAXW) {
68 m_maxw_mass_decor.set(evtInfo, -1, sys);
69 m_maxw_res_4vect_decor.set(evtInfo, null4V, sys);
70 m_maxw_nu1_4vect_decor.set(evtInfo, null4V, sys);
71 m_maxw_nu2_4vect_decor.set(evtInfo, null4V, sys);
72 m_maxw_tau1_4vect_decor.set(evtInfo, null4V, sys);
73 m_maxw_tau2_4vect_decor.set(evtInfo, null4V, sys);
74 }
75 if (m_doMLNU3P) {
76 m_mlnu3p_mass_decor.set(evtInfo, -1, sys);
77 m_mlnu3p_res_4vect_decor.set(evtInfo, null4V, sys);
78 m_mlnu3p_nu1_4vect_decor.set(evtInfo, null4V, sys);
79 m_mlnu3p_nu2_4vect_decor.set(evtInfo, null4V, sys);
80 m_mlnu3p_tau1_4vect_decor.set(evtInfo, null4V, sys);
81 m_mlnu3p_tau2_4vect_decor.set(evtInfo, null4V, sys);
82 }
83 m_fitStatus_decor.set(evtInfo, 0, sys);
84 m_mlm_mass_decor.set(evtInfo, -1, sys);
86 m_coll_approx_mass_decor.set(evtInfo, -1234., sys);
87 m_coll_approx_x0_decor.set(evtInfo, -1234., sys);
88 m_coll_approx_x1_decor.set(evtInfo, -1234., sys);
89 }
90 };
91
92 for (const auto &sys : m_systematicsList.systematicsVector())
93 {
94 // retrieve the EventInfo
95 const xAOD::EventInfo *evtInfo = nullptr;
96 ANA_CHECK(m_eventInfoHandle.retrieve(evtInfo, sys, ctx));
97
98 // check the preselection
99 if (m_preselection && !m_preselection.getBool(*evtInfo, sys))
100 {
101 decorateDefaults(*evtInfo, sys);
102 continue;
103 }
104
105 // retrieve objects
106 const xAOD::ElectronContainer *electrons = nullptr;
107 ANA_CHECK(m_electronsHandle.retrieve(electrons, sys, ctx));
108 const xAOD::MuonContainer *muons = nullptr;
109 ANA_CHECK(m_muonsHandle.retrieve(muons, sys, ctx));
110 const xAOD::TauJetContainer *taus = nullptr;
111 ANA_CHECK(m_tausHandle.retrieve(taus, sys, ctx));
112 const xAOD::JetContainer *jets = nullptr;
113 ANA_CHECK(m_jetsHandle.retrieve(jets, sys, ctx));
114 const xAOD::MissingETContainer *met = nullptr;
115 ANA_CHECK(m_metHandle.retrieve(met, sys, ctx));
116
117 // apply object-wise selection
122
123 for (const xAOD::Electron *el : *electrons)
124 {
125 if (m_electronSelection.getBool(*el, sys))
126 selected_electrons.push_back(el);
127 }
128
129 for (const xAOD::Muon *mu : *muons)
130 {
131 if (m_muonSelection.getBool(*mu, sys))
132 selected_muons.push_back(mu);
133 }
134
135 for (const xAOD::TauJet *tau : *taus)
136 {
137 if (m_tauSelection.getBool(*tau, sys))
138 selected_taus.push_back(tau);
139 }
140
141 for (const xAOD::Jet *jet : *jets)
142 {
143 if (m_jetSelection.getBool(*jet, sys))
144 selected_jets.push_back(jet);
145 }
146
147 int nJets = selected_jets.size();
148
149 const xAOD::IParticle *vis1 = nullptr, *vis2 = nullptr;
150 // to assign the visible particles on which to run the MMC, we assume that the user would prefer
151 // 1) tau_had + tau_had
152 // 2) tau_had + e
153 // 3) tau_had + mu
154 // 4) e + mu
155 // 5) mu + mu
156 // 6) e + e
157 // To force a custom ordering, simply decorate your desired selection onto the particles before running this algorithm.
158 // e.g. you could "book" an OSSF pair of light leptons as originating from a Z boson, and remove them from consideration here.
159
160 if (selected_taus.size() >= 2)
161 {
162 vis1 = selected_taus.at(0);
163 vis2 = selected_taus.at(1);
164 }
165 else if (selected_taus.size() == 1 && selected_electrons.size() >= 1)
166 {
167 vis1 = selected_taus.at(0);
168 vis2 = selected_electrons.at(0);
169 }
170 else if (selected_taus.size() == 1 && selected_muons.size() >= 1)
171 {
172 vis1 = selected_taus.at(0);
173 vis2 = selected_muons.at(0);
174 }
175 else if (selected_electrons.size() >= 1 && selected_muons.size() >= 1)
176 {
177 vis1 = selected_electrons.at(0);
178 vis2 = selected_muons.at(0);
179 }
180 else if (selected_muons.size() >= 2)
181 {
182 vis1 = selected_muons.at(0);
183 vis2 = selected_muons.at(1);
184 }
185 else if (selected_electrons.size() >= 2)
186 {
187 vis1 = selected_electrons.at(0);
188 vis2 = selected_electrons.at(1);
189 }
190 else
191 {
192 ANA_MSG_WARNING("Not enough charged leptons in the event to run the MMC!");
193 decorateDefaults(*evtInfo, sys);
194 continue;
195 }
196
197 const xAOD::MissingET *metTerm = (*met)[m_metTerm.value()];
198 if (metTerm == nullptr)
199 {
200 ANA_MSG_ERROR("The MET term " << m_metTerm.value() << " doesn't exist! Aborting.");
201 return StatusCode::FAILURE;
202 }
203
204 ANA_CHECK(m_mmc->apply(*evtInfo, vis1, vis2, metTerm, nJets));
205
206 // retrieve the output variables and decorate them
207 PtEtaPhiMVector null4V(0.0, 0.0, 0.0, 0.0);
208 int fitStatus = m_mmc->GetFitStatus(0);
209 double mlm_mass = fitStatus == 1 ? m_mmc->GetFittedMass(DiTauMassTools::MMCFitMethod::MLM) : -1;
210 if (m_doMAXW) {
211 double maxw_mass = fitStatus == 1 ? m_mmc->GetFittedMass(DiTauMassTools::MMCFitMethod::MAXW) : -1;
212 PtEtaPhiMVector maxw_res_4vect = fitStatus == 1 ? m_mmc->GetResonanceVec(DiTauMassTools::MMCFitMethod::MAXW) : null4V;
213 PtEtaPhiMVector maxw_nu1_4vect = fitStatus == 1 ? m_mmc->GetNeutrino4vec(DiTauMassTools::MMCFitMethod::MAXW, 0) : null4V;
214 PtEtaPhiMVector maxw_nu2_4vect = fitStatus == 1 ? m_mmc->GetNeutrino4vec(DiTauMassTools::MMCFitMethod::MAXW, 1) : null4V;
215 PtEtaPhiMVector maxw_tau1_4vect = fitStatus == 1 ? m_mmc->GetTau4vec(DiTauMassTools::MMCFitMethod::MAXW, 0) : null4V;
216 PtEtaPhiMVector maxw_tau2_4vect = fitStatus == 1 ? m_mmc->GetTau4vec(DiTauMassTools::MMCFitMethod::MAXW, 1) : null4V;
217 m_maxw_mass_decor.set(*evtInfo, maxw_mass, sys);
218 m_maxw_res_4vect_decor.set(*evtInfo, maxw_res_4vect, sys);
219 m_maxw_nu1_4vect_decor.set(*evtInfo, maxw_nu1_4vect, sys);
220 m_maxw_nu2_4vect_decor.set(*evtInfo, maxw_nu2_4vect, sys);
221 m_maxw_tau1_4vect_decor.set(*evtInfo, maxw_tau1_4vect, sys);
222 m_maxw_tau2_4vect_decor.set(*evtInfo, maxw_tau2_4vect, sys);
223 }
224 if (m_doMLNU3P) {
225 double mlnu3p_mass = fitStatus == 1 ? m_mmc->GetFittedMass(DiTauMassTools::MMCFitMethod::MLNU3P) : -1;
226 PtEtaPhiMVector mlnu3p_res_4vect = fitStatus == 1 ? m_mmc->GetResonanceVec(DiTauMassTools::MMCFitMethod::MLNU3P) : null4V;
227 PtEtaPhiMVector mlnu3p_nu1_4vect = fitStatus == 1 ? m_mmc->GetNeutrino4vec(DiTauMassTools::MMCFitMethod::MLNU3P, 0) : null4V;
228 PtEtaPhiMVector mlnu3p_nu2_4vect = fitStatus == 1 ? m_mmc->GetNeutrino4vec(DiTauMassTools::MMCFitMethod::MLNU3P, 1) : null4V;
229 PtEtaPhiMVector mlnu3p_tau1_4vect = fitStatus == 1 ? m_mmc->GetTau4vec(DiTauMassTools::MMCFitMethod::MLNU3P, 0) : null4V;
230 PtEtaPhiMVector mlnu3p_tau2_4vect = fitStatus == 1 ? m_mmc->GetTau4vec(DiTauMassTools::MMCFitMethod::MLNU3P, 1) : null4V;
231 m_mlnu3p_mass_decor.set(*evtInfo, mlnu3p_mass, sys);
232 m_mlnu3p_res_4vect_decor.set(*evtInfo, mlnu3p_res_4vect, sys);
233 m_mlnu3p_nu1_4vect_decor.set(*evtInfo, mlnu3p_nu1_4vect, sys);
234 m_mlnu3p_nu2_4vect_decor.set(*evtInfo, mlnu3p_nu2_4vect, sys);
235 m_mlnu3p_tau1_4vect_decor.set(*evtInfo, mlnu3p_tau1_4vect, sys);
236 m_mlnu3p_tau2_4vect_decor.set(*evtInfo, mlnu3p_tau2_4vect, sys);
237 }
238 m_fitStatus_decor.set(*evtInfo, fitStatus, sys);
239 m_mlm_mass_decor.set(*evtInfo, mlm_mass, sys);
240
241 // retrieve results for collinear approximation
243 double coll_mass = -1234.;
244 double coll_x0 = -1234.;
245 double coll_x1 = -1234.;
246
247 ANA_CHECK(m_mmc->doCollinearApprox(vis1, vis2, metTerm, true, coll_mass, coll_x0, coll_x1));
248
249 m_coll_approx_mass_decor.set(*evtInfo, coll_mass, sys);
250 m_coll_approx_x0_decor.set(*evtInfo, coll_x0, sys);
251 m_coll_approx_x1_decor.set(*evtInfo, coll_x1, sys);
252 }
253
254 }
255
256 return StatusCode::SUCCESS;
257 }
258
259} // namespace
DataVector adapter that acts like it holds const pointers.
#define ANA_MSG_ERROR(xmsg,...)
Macro printing error messages.
#define ANA_CHECK(EXP)
check whether the given expression was successful
#define ANA_MSG_WARNING(xmsg,...)
Macro printing warning messages.
static Double_t taus
SysWriteDecorHandle< PtEtaPhiMVector > m_maxw_res_4vect_decor
Gaudi::Property< std::string > m_metTerm
SysWriteDecorHandle< double > m_coll_approx_x1_decor
SysWriteDecorHandle< int > m_fitStatus_decor
SysReadSelectionHandle m_preselection
Gaudi::Property< bool > m_doCollinearApprox
SysWriteDecorHandle< double > m_coll_approx_x0_decor
SysWriteDecorHandle< PtEtaPhiMVector > m_mlnu3p_tau2_4vect_decor
SysWriteDecorHandle< PtEtaPhiMVector > m_mlnu3p_nu2_4vect_decor
SysWriteDecorHandle< PtEtaPhiMVector > m_maxw_tau1_4vect_decor
SysWriteDecorHandle< PtEtaPhiMVector > m_maxw_tau2_4vect_decor
SysReadSelectionHandle m_muonSelection
SysWriteDecorHandle< PtEtaPhiMVector > m_mlnu3p_tau1_4vect_decor
Gaudi::Property< bool > m_doMAXW
SysWriteDecorHandle< double > m_mlnu3p_mass_decor
SysWriteDecorHandle< PtEtaPhiMVector > m_mlnu3p_nu1_4vect_decor
SysWriteDecorHandle< double > m_coll_approx_mass_decor
SysReadHandle< xAOD::MuonContainer > m_muonsHandle
ToolHandle< IMissingMassTool > m_mmc
Gaudi::Property< bool > m_doMLNU3P
SysReadHandle< xAOD::TauJetContainer > m_tausHandle
SysReadSelectionHandle m_electronSelection
SysWriteDecorHandle< PtEtaPhiMVector > m_maxw_nu1_4vect_decor
virtual StatusCode initialize() override
SysReadSelectionHandle m_tauSelection
SysWriteDecorHandle< double > m_maxw_mass_decor
SysReadHandle< xAOD::MissingETContainer > m_metHandle
SysReadHandle< xAOD::JetContainer > m_jetsHandle
SysReadHandle< xAOD::EventInfo > m_eventInfoHandle
SysWriteDecorHandle< double > m_mlm_mass_decor
SysWriteDecorHandle< PtEtaPhiMVector > m_maxw_nu2_4vect_decor
SysWriteDecorHandle< PtEtaPhiMVector > m_mlnu3p_res_4vect_decor
SysReadHandle< xAOD::ElectronContainer > m_electronsHandle
SysReadSelectionHandle m_jetSelection
Class to wrap a set of SystematicVariations.
DataVector adapter that acts like it holds const pointers.
value_type push_back(value_type pElem)
Add an element to the end of the collection.
ElementProxy at(size_type n)
Access an element, as an lvalue.
virtual::StatusCode execute()
execute this algorithm
Class providing the definition of the 4-vector interface.
Select isolated Photons, Electrons and Muons.
@ VIEW_ELEMENTS
this data object is a view, it does not own its elmts
Jet_v1 Jet
Definition of the current "jet version".
ElectronContainer_v1 ElectronContainer
Definition of the current "electron container version".
EventInfo_v1 EventInfo
Definition of the latest event info version.
MissingET_v1 MissingET
Version control by type defintion.
Definition MissingET.h:15
TauJet_v3 TauJet
Definition of the current "tau version".
Definition TauJet.h:17
MissingETContainer_v1 MissingETContainer
Muon_v1 Muon
Reference the current persistent version:
Definition Muon.h:13
JetContainer_v1 JetContainer
Definition of the current "jet container version".
TauJetContainer_v3 TauJetContainer
Definition of the current "taujet container version".
MuonContainer_v1 MuonContainer
Definition of the current "Muon container version".
Electron_v1 Electron
Definition of the current "egamma version".
Definition Electron.h:17