ATLAS Offline Software
Loading...
Searching...
No Matches
DiTauTruthMatchingTool.cxx
Go to the documentation of this file.
1
9
10// Local include(s)
12
13using namespace TauAnalysisTools;
14using namespace ADD_CMODE(TauAnalysisTools);
15
16//=================================PUBLIC-PART==================================
17//______________________________________________________________________________
18DiTauTruthMatchingTool::DiTauTruthMatchingTool( const std::string& name )
19 : BuildTruthTaus(name)
20 , m_accPtVis("pt_vis")
21 , m_accEtaVis("eta_vis")
22 , m_accPhiVis("phi_vis")
23 , m_accMVis("m_vis")
24{
25}
26
27//______________________________________________________________________________
28DiTauTruthMatchingTool::~DiTauTruthMatchingTool( )
29{
30
31}
32
33//______________________________________________________________________________
34StatusCode DiTauTruthMatchingTool::initialize()
35{
36 ATH_MSG_INFO( "Initializing DiTauTruthMatchingTool" );
37
38 // configure BuildTruthTaus in truth matching mode, not truth tau building mode
39 DiTauTruthMatchingTool::BuildTruthTaus::setTruthMatchingMode();
40
41 if (DiTauTruthMatchingTool::BuildTruthTaus::initialize().isFailure())
42 {
43 ATH_MSG_FATAL("Failed initializing BuildTruthTaus");
44 return StatusCode::FAILURE;
45 }
46 return StatusCode::SUCCESS;
47}
48
49//______________________________________________________________________________
50void DiTauTruthMatchingTool::getTruth(const xAOD::DiTauJet& xDiTau)
51{
52 if (retrieveTruthTaus().isFailure())
53 return;
54
55 if (findTruthTau(xDiTau).isFailure())
56 ATH_MSG_WARNING("There was a failure in finding the matched truth tau");
57
58 return;
59}
60
61//______________________________________________________________________________
62void DiTauTruthMatchingTool::getTruth(const std::vector<const xAOD::DiTauJet*>& vDiTaus)
63{
64 for (auto xDiTau : vDiTaus)
65 getTruth(*xDiTau);
66 return;
67}
68
69
71// Private Part //
73
74//______________________________________________________________________________
75StatusCode DiTauTruthMatchingTool::findTruthTau(const xAOD::DiTauJet& xDiTau)
76{
77 // check if decorations were already added to the first passed tau
78 if (!m_bIsTruthMatchedAvailable.isValid()) {
79 static const SG::ConstAccessor<char> accIsTruthMatched("IsTruthMatched");
80 m_bIsTruthMatchedAvailable.set (accIsTruthMatched.isAvailable(xDiTau));
81 }
82 if (*m_bIsTruthMatchedAvailable.ptr())
83 return StatusCode::SUCCESS;
84
85 if (m_bTruthTauAvailable)
86 return checkTruthMatch(xDiTau, *m_truthTausEvent.m_xTruthTauContainerConst);
87 else
88 return checkTruthMatch(xDiTau, *m_truthTausEvent.m_xTruthTauContainer);
89}
90
91//______________________________________________________________________________
92StatusCode DiTauTruthMatchingTool::checkTruthMatch (const xAOD::DiTauJet& xDiTau, const xAOD::TruthParticleContainer& xTruthTauContainer) const
93{
94 std::vector<const xAOD::TruthParticle*> vTruthMatch;
95 std::vector<TruthMatchedParticleType> vTruthMatchedParticleType;
96 std::vector<const xAOD::Jet*> vTruthJetMatch;
97
98
99 xAOD::TruthParticleContainer xRemainingTruthTaus = xTruthTauContainer;
100
101 static const SG::Decorator<char> decIsTruthMatched("IsTruthMatched");
102 static const SG::Decorator<char> decIsTruthHadronic("IsTruthHadronic");
103 static const SG::ConstAccessor<int> accNSubjets("n_subjets");
104 static const SG::ConstAccessor<char> accIsTruthHadronic("IsTruthHadronic");
105
106 int n_subjets = 0;
107 if(!(accNSubjets.isAvailable(xDiTau))){
108 // n_subjets decoration is not available, recalculation on the fly
109 while (xDiTau.subjetPt(n_subjets) > 0. )
110 {
111 n_subjets++;
112 }
113 } else {
114 n_subjets = accNSubjets(xDiTau);
115 }
116
117 // set default values for each subjet
118 for (int i = 0; i < n_subjets; ++i)
119 {
120 const xAOD::TruthParticle* xTruthMatch = nullptr;
121 TruthMatchedParticleType eTruthMatchedParticleType = Unknown;
122
123 vTruthMatch.push_back(xTruthMatch);
124 vTruthMatchedParticleType.push_back(eTruthMatchedParticleType);
125
126 const xAOD::Jet* xTruthJetMatch = nullptr;
127 vTruthJetMatch.push_back(xTruthJetMatch);
128 }
129
130 // truthmatching for subjets:
131 for (int i = 0; i < n_subjets; ++i)
132 {
133 TLorentzVector vSubjetTLV;
134 vSubjetTLV.SetPtEtaPhiE(xDiTau.subjetPt(i),
135 xDiTau.subjetEta(i),
136 xDiTau.subjetPhi(i),
137 xDiTau.subjetE(i));
138 if ( truthMatch(vSubjetTLV,
139 xRemainingTruthTaus,
140 vTruthMatch.at(i),
141 vTruthJetMatch.at(i),
142 vTruthMatchedParticleType.at(i)).isFailure() )
143 {
144 ATH_MSG_WARNING("There was a failure in matching truth taus with subjet " << i);
145 return StatusCode::FAILURE;
146 }
147 if (vTruthMatch.at(i) && vTruthMatchedParticleType.at(i) == TruthHadronicTau)
148 {
149 xRemainingTruthTaus.erase( std::find(xRemainingTruthTaus.begin(),
150 xRemainingTruthTaus.end(),
151 vTruthMatch.at(i)) );
152 }
153 }
154
155 // create links for jets
156 std::vector< ElementLink < xAOD::JetContainer > > vTruthJetLinks;
157 for (int i = 0; i < n_subjets; ++i)
158 {
159 const xAOD::Jet* xTruthJetMatch = vTruthJetMatch.at(i);
160 if(xTruthJetMatch){
161 ElementLink < xAOD::JetContainer > lTruthParticleLink(xTruthJetMatch, *m_truthTausEvent.m_xTruthJetContainerConst);
162 vTruthJetLinks.push_back(lTruthParticleLink);
163 }
164 else
165 {
166 ElementLink < xAOD::JetContainer > lTruthParticleLink;
167 vTruthJetLinks.push_back(lTruthParticleLink);
168 }
169 }
171 decTruthJetLinks ("truthJetLinks");
172 decTruthJetLinks(xDiTau) = std::move(vTruthJetLinks);
173
174
175 bool bTruthMatched = true;
176
177 // create link to the original TruthParticle
178 std::vector< ElementLink < xAOD::TruthParticleContainer > > vTruthLinks;
179 for (int i = 0; i < n_subjets; ++i)
180 {
181 const xAOD::TruthParticle* xTruthMatch = vTruthMatch.at(i);
182 TruthMatchedParticleType eTruthMatchedParticleType = vTruthMatchedParticleType.at(i);
183 if (xTruthMatch)
184 {
185 if (eTruthMatchedParticleType == TruthHadronicTau)
186 {
187 ElementLink < xAOD::TruthParticleContainer > lTruthParticleLink(xTruthMatch, xTruthTauContainer);
188 vTruthLinks.push_back(lTruthParticleLink);
189 }
190 else if (eTruthMatchedParticleType == TruthMuon)
191 {
192 ElementLink <xAOD::TruthParticleContainer> lTruthParticleLink(xTruthMatch, *m_truthTausEvent.m_xTruthMuonContainerConst);
193 vTruthLinks.push_back(lTruthParticleLink);
194 }
195 else if (eTruthMatchedParticleType == TruthElectron)
196 {
197 ElementLink <xAOD::TruthParticleContainer> lTruthParticleLink(xTruthMatch, *m_truthTausEvent.m_xTruthElectronContainerConst);
198 vTruthLinks.push_back(lTruthParticleLink);
199 }
200 }
201 else
202 {
203 ElementLink < xAOD::TruthParticleContainer > lTruthParticleLink;
204 vTruthLinks.push_back(lTruthParticleLink);
205
206 // ditau is not truth matched if one of the two leading subjets is not truth matched
207 if (i == 0 || i == 1) bTruthMatched = false;
208 }
209 }
210
212 decTruthParticleLinks ("truthParticleLinks");
213 decTruthParticleLinks(xDiTau) = vTruthLinks;
214 if (!m_bTruthTauAvailable)
215 {
217 decTruthTaus ("TruthTaus");
218 decTruthTaus(xDiTau) = vTruthLinks;
219 }
220
221 static const SG::Decorator<float> decTruthLeadPt("TruthVisLeadPt");
222 static const SG::Decorator<float> decTruthLeadEta("TruthVisLeadEta");
223 static const SG::Decorator<float> decTruthLeadPhi("TruthVisLeadPhi");
224 static const SG::Decorator<float> decTruthLeadM("TruthVisLeadM");
225 static const SG::Decorator<int> decTruthLeadPdgID("TruthLeadPdgID");
226 static const SG::Decorator<float> decTruthSubleadPt("TruthVisSubleadPt");
227 static const SG::Decorator<float> decTruthSubleadEta("TruthVisSubleadEta");
228 static const SG::Decorator<float> decTruthSubleadPhi("TruthVisSubleadPhi");
229 static const SG::Decorator<float> decTruthSubleadM("TruthVisSubleadM");
230 static const SG::Decorator<int> decTruthSubleadPdgID("TruthSubleadPdgID");
231 static const SG::Decorator<float> decTruthDeltaR("TruthVisDeltaR");
232 static const SG::Decorator<float> decTruthMass("TruthVisMass");
233
234 // the ditau candidate should have at least 2 subjets to be truth matched
235 if ( n_subjets < 2) {
236 decIsTruthMatched(xDiTau) = (char)false;
237 decIsTruthHadronic(xDiTau) = (char)false;
238 decTruthLeadPt(xDiTau) = -1234.;
239 decTruthLeadEta(xDiTau) = -1234.;
240 decTruthLeadPhi(xDiTau) = -1234.;
241 decTruthLeadM(xDiTau) = -1234.;
242 decTruthLeadPdgID(xDiTau) = -1234.;
243 decTruthSubleadPt(xDiTau) = -1234.;
244 decTruthSubleadEta(xDiTau) = -1234.;
245 decTruthSubleadPhi(xDiTau) = -1234.;
246 decTruthSubleadM(xDiTau) = -1234.;
247 decTruthSubleadPdgID(xDiTau) = -1234.;
248 decTruthDeltaR(xDiTau) = -1234.;
249 decTruthMass(xDiTau) = -1234.;
250 return StatusCode::SUCCESS;
251 }
252
253 decIsTruthMatched(xDiTau) = (char)bTruthMatched;
254 if (bTruthMatched)
255 {
256 // ditau is hadronic if two leading subjets are truth matched with hadronic decay
257 decIsTruthHadronic(xDiTau) = (char)(vTruthMatchedParticleType[0]==TruthHadronicTau
258 && vTruthMatchedParticleType[1]==TruthHadronicTau );
259 }
260 else
261 decIsTruthHadronic(xDiTau) = (char)false;
262
263 if (accIsTruthHadronic(xDiTau))
264 {
265 TLorentzVector tlvTruthTau1;
266 TLorentzVector tlvTruthTau2;
267 tlvTruthTau1.SetPtEtaPhiM(m_accPtVis(*(*vTruthLinks.at(0))),
268 m_accEtaVis(*(*vTruthLinks.at(0))),
269 m_accPhiVis(*(*vTruthLinks.at(0))),
270 m_accMVis(*(*vTruthLinks.at(0))));
271 tlvTruthTau2.SetPtEtaPhiM(m_accPtVis(*(*vTruthLinks.at(1))),
272 m_accEtaVis(*(*vTruthLinks.at(1))),
273 m_accPhiVis(*(*vTruthLinks.at(1))),
274 m_accMVis(*(*vTruthLinks.at(1))));
275
276 decTruthLeadPt(xDiTau) = std::max(tlvTruthTau1.Pt(), tlvTruthTau2.Pt());
277 decTruthLeadEta(xDiTau) = (tlvTruthTau1.Pt() > tlvTruthTau2.Pt()) ? tlvTruthTau1.Eta() : tlvTruthTau2.Eta();
278 decTruthLeadPhi(xDiTau) = (tlvTruthTau1.Pt() > tlvTruthTau2.Pt()) ? tlvTruthTau1.Phi() : tlvTruthTau2.Phi();
279 decTruthLeadM(xDiTau) = (tlvTruthTau1.Pt() > tlvTruthTau2.Pt()) ? tlvTruthTau1.M() : tlvTruthTau2.M();
280 decTruthLeadPdgID(xDiTau) = (*vTruthLinks.at(0))->pdgId();
281 decTruthSubleadPt(xDiTau) = std::min(tlvTruthTau1.Pt(), tlvTruthTau2.Pt());
282 decTruthSubleadEta(xDiTau) = (tlvTruthTau1.Pt() > tlvTruthTau2.Pt()) ? tlvTruthTau2.Eta() : tlvTruthTau1.Eta();
283 decTruthSubleadPhi(xDiTau) = (tlvTruthTau1.Pt() > tlvTruthTau2.Pt()) ? tlvTruthTau2.Phi() : tlvTruthTau1.Phi();
284 decTruthSubleadM(xDiTau) = (tlvTruthTau1.Pt() > tlvTruthTau2.Pt()) ? tlvTruthTau2.M() : tlvTruthTau1.M();
285 decTruthSubleadPdgID(xDiTau) = (*vTruthLinks.at(1))->pdgId();
286 decTruthDeltaR(xDiTau) = tlvTruthTau1.DeltaR(tlvTruthTau2);
287 decTruthMass(xDiTau) = (tlvTruthTau1 + tlvTruthTau2).M();
288 }
289 else {
290 // set to a default value
291 decTruthLeadPt(xDiTau) = -1234.;
292 decTruthLeadEta(xDiTau) = -1234.;
293 decTruthLeadPhi(xDiTau) = -1234.;
294 decTruthLeadM(xDiTau) = -1234.;
295 decTruthLeadPdgID(xDiTau) = -1234.;
296 decTruthSubleadPt(xDiTau) = -1234.;
297 decTruthSubleadEta(xDiTau) = -1234.;
298 decTruthSubleadPhi(xDiTau) = -1234.;
299 decTruthSubleadM(xDiTau) = -1234.;
300 decTruthSubleadPdgID(xDiTau) = -1234.;
301 decTruthDeltaR(xDiTau) = -1234.;
302 decTruthMass(xDiTau) = -1234.;
303 }
304
305 return StatusCode::SUCCESS;
306}
307//______________________________________________________________________________
308StatusCode DiTauTruthMatchingTool::truthMatch(const TLorentzVector& vSubjetTLV,
309 const xAOD::TruthParticleContainer& xTruthTauContainer,
310 const xAOD::TruthParticle* &xTruthMatch,
311 const xAOD::Jet* &xTruthJetMatch,
312 TruthMatchedParticleType &eTruthMatchedParticleType) const
313{
314 for (auto xTruthTauIt : xTruthTauContainer)
315 {
316 TLorentzVector vTruthVisTLV;
317 vTruthVisTLV.SetPtEtaPhiM(m_accPtVis(*xTruthTauIt),
318 m_accEtaVis(*xTruthTauIt),
319 m_accPhiVis(*xTruthTauIt),
320 m_accMVis(*xTruthTauIt));
321 if (vSubjetTLV.DeltaR(vTruthVisTLV) <= m_dMaxDeltaR)
322 {
323 static const SG::ConstAccessor<char> accIsHadronicTau("IsHadronicTau");
324 if (static_cast<bool>(accIsHadronicTau(*xTruthTauIt)))
325 eTruthMatchedParticleType = TruthHadronicTau;
326 else
327 continue; // don't let leptonic taus steal truthmatch just by chance
328
329 xTruthMatch = xTruthTauIt;
330 break;
331 }
332 }
333
334 if (!xTruthMatch and m_truthTausEvent.m_xTruthMuonContainerConst)
335 {
336 double dPtMax = 0.;
337 for (auto xTruthMuonIt : *m_truthTausEvent.m_xTruthMuonContainerConst)
338 {
339 if (vSubjetTLV.DeltaR(xTruthMuonIt->p4()) <= m_dMaxDeltaR)
340 {
341 if (xTruthMuonIt->pt()<dPtMax)
342 continue;
343 eTruthMatchedParticleType = TruthMuon;
344
345 xTruthMatch = xTruthMuonIt;
346 dPtMax = xTruthMuonIt->pt();
347 }
348 }
349 }
350
351 if (!xTruthMatch and m_truthTausEvent.m_xTruthElectronContainerConst)
352 {
353 double dPtMax = 0.;
354 for (auto xTruthElectronIt : *m_truthTausEvent.m_xTruthElectronContainerConst)
355 {
356 if (vSubjetTLV.DeltaR(xTruthElectronIt->p4()) <= m_dMaxDeltaR)
357 {
358 if (xTruthElectronIt->pt()<dPtMax)
359 continue;
360 eTruthMatchedParticleType = TruthElectron;
361 xTruthMatch = xTruthElectronIt;
362 dPtMax = xTruthElectronIt->pt();
363 }
364 }
365 }
366
367 if (m_truthTausEvent.m_xTruthJetContainerConst)
368 {
369 double dPtMax = 0.;
370 for (auto xTruthJetIt : *m_truthTausEvent.m_xTruthJetContainerConst)
371 {
372 if (vSubjetTLV.DeltaR(xTruthJetIt->p4()) <= m_dMaxDeltaR)
373 {
374 if (xTruthJetIt->pt()<dPtMax)
375 continue;
376 xTruthJetMatch = xTruthJetIt;
377 dPtMax = xTruthJetIt->pt();
378 }
379 }
380 }
381
382 return StatusCode::SUCCESS;
383}
#define ATH_MSG_WARNING(x,...)
#define ATH_MSG_INFO(x,...)
#define ATH_MSG_FATAL(x,...)
#define ADD_CMODE(name)
Tau, lepton and jet truth matching for ditau jets.
const_iterator end() const noexcept
Return a const_iterator pointing past the end of the collection.
iterator erase(iterator position)
Remove element at a given position.
const_iterator begin() const noexcept
Return a const_iterator pointing at the beginning of the collection.
Helper class to provide constant type-safe access to aux data.
float subjetEta(unsigned int numSubjet) const
float subjetE(unsigned int numSubjet) const
float subjetPt(unsigned int numSubjet) const
float subjetPhi(unsigned int numSubjet) const
virtual double pt() const
The transverse momentum ( ) of the particle.
Definition Jet_v1.cxx:44
virtual double pt() const override final
The transverse momentum ( ) of the particle.
SG::Decorator< T, ALLOC > Decorator
Helper class to provide type-safe access to aux data, specialized for JaggedVecElt.
Definition AuxElement.h:576
Jet_v1 Jet
Definition of the current "jet version".
TruthParticle_v1 TruthParticle
Typedef to implementation.
DiTauJet_v1 DiTauJet
Definition of the current version.
Definition DiTauJet.h:17
TruthParticleContainer_v1 TruthParticleContainer
Declare the latest version of the truth particle container.