ATLAS Offline Software
Loading...
Searching...
No Matches
DecoratePromptLeptonRNN.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
4
5// Local
9
10// xAOD
15
16// ROOT
17#include "TH1.h"
18
19//=============================================================================
20Prompt::DecoratePromptLeptonRNN::DecoratePromptLeptonRNN(const std::string& name, ISvcLocator* pSvcLocator):
21 AthAlgorithm(name, pSvcLocator),
22 m_histSvc ("THistSvc/THistSvc", name),
24{}
25
26//=============================================================================
28{
29 ATH_MSG_DEBUG("Initializing DecoratePromptLeptonRNN...");
30
31 // Initialize read/write handles
36
37 ATH_CHECK(m_eventHandleKey.initialize());
38
39 //
40 // Initialize tools and services
41 //
42 ATH_CHECK( m_histSvc.retrieve() );
43
44 m_decorHandleKeys.clear();
45 for(const std::string &label: m_toolRNN->getOutputLabels()) {
46 const std::string key = m_decorationPrefixRNN + label;
47
48 ATH_MSG_DEBUG("Add output RNN label: \"" << key << "\"");
49
50 m_decorNameMap.try_emplace (label, m_decorHandleKeys.size());
52 }
53 ATH_CHECK(m_decorHandleKeys.initialize());
54
55 ATH_MSG_DEBUG("inputContainerMuon=\"" << m_inputContainerLeptonKey << "\"");
56
57 //
58 // Instantiate Muon quality accessors
59 //
60
61 m_timerEvent.Reset();
62
63 ATH_MSG_DEBUG("DecoratePromptLeptonRNN initialized successfully.");
64
65 return StatusCode::SUCCESS;
66
67}
68
69//=============================================================================
70StatusCode Prompt::DecoratePromptLeptonRNN::execute(const EventContext& ctx)
71{
72 //
73 // Process current event
74 //
76
77
78 ATH_MSG_DEBUG("execute() - begin...");
79
81
82 //
83 // Retrieve object containers and event info
84 //
89
91
92 ATH_MSG_DEBUG("Size of LeptonContainer: " << h_leptons->size());
93
94 std::vector<decoratorFloatH_t> decors;
95 decors.reserve (m_decorHandleKeys.size());
97 decors.emplace_back (k, ctx);
98 }
99
100 //
101 // Find default Primary Vertex
102 //
103 const xAOD::Vertex *primaryVertex = nullptr;
104
105 for(const xAOD::Vertex *vertex: *h_vertices) {
106 if(vertex->vertexType() == xAOD::VxType::PriVtx) {
107 primaryVertex = vertex;
108 break;
109 }
110 }
111
112 //
113 // Collect tracks
114 //
115 for(const xAOD::IParticle *lepton: *h_leptons) {
116 //
117 // Select lepton track
118 //
119 const xAOD::TrackParticle *trackLep = nullptr;
120 const xAOD::Electron *elec = dynamic_cast<const xAOD::Electron*>(lepton);
121 const xAOD::Muon *muon = dynamic_cast<const xAOD::Muon *>(lepton);
122
123 if(elec) {
124 const xAOD::TrackParticle *bestmatchedGSFElTrack = elec->trackParticle(0);
125 if(bestmatchedGSFElTrack) {
126 trackLep = xAOD::EgammaHelpers::getOriginalTrackParticleFromGSF(bestmatchedGSFElTrack);
127 }
128 }
129 else if (muon) {
130 trackLep = findMuonTrack(muon);
131 }
132 else {
133 ATH_MSG_WARNING("execute - failed to find electron or muon: should never happen!");
134 }
135
136 //
137 // Find closest track jet
138 //
139 const xAOD::Jet *trackJet = findClosestTrackJet(trackLep, *h_trackJets);
140
141 if(!trackLep || !trackJet) {
142 compDummy(*lepton, decors);
143 continue;
144 }
145
146 //
147 // Select tracks within cone around lepton track.
148 //
149 std::vector<Prompt::VarHolder > select_tracks;
150
151 Prompt::VarHolder lepton_obj;
152
153 if(!prepTrackObject(lepton_obj, *trackLep, *trackLep, *trackJet, *primaryVertex, *event_handle)) {
154 continue;
155 }
156
157 //
158 // Add lepton track as one of the cone tracks.
159 //
160 select_tracks.push_back(lepton_obj);
161
162 for(const xAOD::TrackParticle *track: *h_tracks) {
163
164 if(!track) {
165 ATH_MSG_WARNING("Prompt::DecoratePromptLeptonRNN::execute - skip null track pointer - should never happen");
166 continue;
167 }
168
169 Prompt::VarHolder track_obj;
170
171 if(!prepTrackObject(track_obj, *track, *trackLep, *trackJet, *primaryVertex, *event_handle)) {
172 continue;
173 }
174
175 if(passTrack(track_obj)) {
176 select_tracks.push_back(track_obj);
177
178 ATH_MSG_DEBUG("Prompt::DecoratePromptLeptonRNN::execute - passed track pT= " << track->pt());
179 }
180 }
181
182 //
183 // Sort tracks by DR distance to lepton
184 //
185 std::sort(select_tracks.begin(), select_tracks.end(), Prompt::SortObjectByVar(Def::LepTrackDR, msg()));
186
187 //
188 // Compute RNN
189 //
190 compScore(*lepton, select_tracks, decors);
191
192 ATH_MSG_DEBUG("DecoratePromptLeptonRNN::CompScore - " << std::endl
193 << "lepton pT= " << lepton->pt()
194 << ", number of tracks: " << select_tracks.size());
195 }
196
197 return StatusCode::SUCCESS;
198}
199
200//=============================================================================
202{
203 //
204 // Finalize output
205 //
206 if(m_printTime) {
207 //
208 // Print full time stopwatch
209 //
210 ATH_MSG_INFO("DecoratePromptLeptonRNN - total time: " << PrintResetStopWatch(m_timerEvent));
211 ATH_MSG_INFO("DecoratePromptLeptonRNN - processed " << m_countEvent << " events.");
212 }
213
214 return StatusCode::SUCCESS;
215}
216
217//=============================================================================
219 //
220 // Process muon - return true if all information present for RNN
221 //
222 ATH_MSG_DEBUG("muon pT=" << muon->pt() << " quality=" << muon->quality());
223
224 return muon->muonType() == xAOD::Muon::MuonType::Combined ?
225 muon->trackParticle(xAOD::Muon::TrackParticleType::InnerDetectorTrackParticle) : nullptr;
226 }
227
228//=============================================================================
230 const xAOD::JetContainer &trackJets)
231{
232 //
233 // Find track jet closest to IParticle and within fixed cone
234 //
235 if(!particle) {
236 return 0;
237 }
238
239 const xAOD::Jet *trackJet = 0;
240 double currTrackJetDR = -1.0;
241
242 //
243 // Select track jet within cone around muon
244 //
245 for(const xAOD::Jet *jet: trackJets) {
246 const double dr = particle->p4().DeltaR(jet->p4());
247
248 if(currTrackJetDR < 0.0 || dr < currTrackJetDR) {
249 trackJet = jet;
250 currTrackJetDR = dr;
251 }
252 }
253
254 if(trackJet && currTrackJetDR < m_maxLepTrackJetDR) {
255 return trackJet;
256 }
257
258 return 0;
259}
260
261//=============================================================================
264 const xAOD::TrackParticle &track,
265 const xAOD::TrackParticle &lepton,
266 const xAOD::Jet &trackJet,
267 const xAOD::Vertex &priVtx,
268 const xAOD::EventInfo event
269)
270{
271 //
272 // Add xAOD::TrackParticle variables to the track object VarHolder
273 //
274 uint8_t numberOfPixelHits = 0;
275 uint8_t numberOfSCTHits = 0;
276 uint8_t numberOfPixelHoles = 0;
277 uint8_t numberOfSCTHoles = 0;
278 uint8_t numberOfPixelSharedHits = 0;
279 uint8_t numberOfSCTSharedHits = 0;
280
281 if(!(track.summaryValue(numberOfPixelHits, xAOD::numberOfPixelHits))) return false;
282 if(!(track.summaryValue(numberOfSCTHits, xAOD::numberOfSCTHits))) return false;
283 if(!(track.summaryValue(numberOfPixelHoles, xAOD::numberOfPixelHoles))) return false;
284 if(!(track.summaryValue(numberOfSCTHoles, xAOD::numberOfSCTHoles))) return false;
285 if(!(track.summaryValue(numberOfPixelSharedHits, xAOD::numberOfPixelSharedHits))) return false;
286 if(!(track.summaryValue(numberOfSCTSharedHits, xAOD::numberOfSCTSharedHits))) return false;
287
288 const uint8_t NSiHits = numberOfPixelHits + numberOfSCTHits;
289 const uint8_t NSiHoles = numberOfPixelHoles + numberOfSCTHoles;
290 const float NSiShHits = float(numberOfPixelSharedHits) + float(numberOfSCTSharedHits)/2.0;
291
292 p.addVar(Def::Pt, track.pt());
293 p.addVar(Def::AbsEta, std::fabs(track.eta()));
294 p.addVar(Def::NumberOfPIXHits, numberOfPixelHits);
295 p.addVar(Def::NumberOfSCTHits, numberOfSCTHits);
296 p.addVar(Def::NumberOfSiHits, NSiHits);
297 p.addVar(Def::NumberOfSharedSiHits, NSiShHits);
298 p.addVar(Def::NumberOfSiHoles, NSiHoles);
299 p.addVar(Def::NumberOfPixelHoles, numberOfPixelHoles);
300
301 //
302 // Add lepton - jet variables to VarHolder
303 //
304 double PtFrac = -99.;
305
306 if(track.pt() > 0.0 && trackJet.pt() > 0.0) {
307 PtFrac = track.pt() / trackJet.pt();
308 }
309
310 p.addVar(Def::TrackPtOverTrackJetPt, PtFrac);
311 p.addVar(Def::TrackJetDR, track.p4().DeltaR(trackJet.p4()));
312 p.addVar(Def::LepTrackDR, track.p4().DeltaR(lepton.p4()));
313
314 //
315 // Add Impact Parameters
316 //
317 double d0_significance = -99.;
318 double Z0Sin = 0.0;
319
320 if(track.definingParametersCovMatrixVec().size() > 0 && track.definingParametersCovMatrixVec().at(0) > 0.0) {
321 d0_significance = xAOD::TrackingHelpers::d0significance(&track,
322 event.beamPosSigmaX(),
323 event.beamPosSigmaY(),
324 event.beamPosSigmaXY());
325 }
326
327 const double deltaZ0 = track.z0() + track.vz() - priVtx.z();
328 Z0Sin = deltaZ0*std::sin(track.theta());
329
330 p.addVar(Def::Z0Sin, Z0Sin);
331 p.addVar(Def::D0Sig, d0_significance);
332
333 return true;
334}
335
336//=============================================================================
338{
339 //
340 // Select cone tracks
341 //
342 if(p.getVar(Def::LepTrackDR) < m_minTrackLeptonDR) return false;
343 if(p.getVar(Def::LepTrackDR) > m_maxTrackLeptonDR) return false;
344
345 //
346 // Kinematic track selection
347 //
348 if(p.getVar(Def::Pt) < m_minTrackpT) return false;
349 if(p.getVar(Def::AbsEta) > m_maxTrackEta) return false;
350 if(std::fabs(p.getVar(Def::Z0Sin)) > m_maxTrackZ0Sin) return false;
351
352 //
353 // Hit quality track selection
354 //
355 if(p.getVar(Def::NumberOfSiHits) < m_minTrackSiHits) return false;
356 if(p.getVar(Def::NumberOfSharedSiHits) > m_maxTrackSharedSiHits) return false;
357 if(p.getVar(Def::NumberOfSiHoles) > m_maxTrackSiHoles) return false;
358 if(p.getVar(Def::NumberOfPixelHoles) > m_maxTrackPixHoles) return false;
359
360 return true;
361}
362
363//=============================================================================
365 const std::vector<Prompt::VarHolder> &tracks,
366 std::vector<decoratorFloatH_t>& decors)
367{
368 //
369 // Call the RNN tool to get the RNN prediction for the leptons and decorate the lepton with those RNN scores.
370 //
371 ATH_MSG_DEBUG("compScore - number of tracks: " << tracks.size());
372
373 for(const Prompt::VarHolder &o: tracks) {
374 ATH_MSG_DEBUG("compScore - track: LepTrackDR = " << o.getVar(Def::LepTrackDR)
375 << ", TrackJetDR = " << o.getVar(Def::TrackJetDR)
376 << ", D0Sig = " << o.getVar(Def::D0Sig)
377 << ", Z0Sin = " << o.getVar(Def::Z0Sin)
378 << ", NumberOfPIXHits = " << o.getVar(Def::NumberOfPIXHits)
379 << ", NumberOfSCTHits = " << o.getVar(Def::NumberOfSCTHits)
380 << ", PtFrac = " << o.getVar(Def::TrackPtOverTrackJetPt) );
381 }
382
383 const std::map<std::string, double> results = m_toolRNN->computeRNNOutput(tracks);
384
385 for(const std::pair<const std::string, double>& v: results) {
386 //
387 // Decorate muon
388 //
389
390 ATH_MSG_DEBUG("DecoratePromptLeptonRNN compScore - " << v.first << " = " << v.second );
391
392 auto dit = m_decorNameMap.find (v.first);
393
394 if(dit != m_decorNameMap.end()) {
395 decors.at(dit->second)(particle) = v.second;
396 }
397 else {
398 ATH_MSG_WARNING("CompScore - unknown output label=\"" << v.first << "\"");
399 }
400
401 if(m_debug) {
402 std::map<std::string, TH1*>::iterator hit = m_hists.find(v.first);
403
404 if(hit == m_hists.end()) {
405 TH1* h = 0;
406
407 StatusCode hist_status = makeHist(h, v.first, 100, 0.0, 1.0);
408 if (hist_status != StatusCode::SUCCESS){
409 ATH_MSG_WARNING("DecoratePromptLeptonRNN compScore - failed to make hist");
410 }
411
412 hit = m_hists.insert(std::map<std::string, TH1*>::value_type(v.first, h)).first;
413 }
414
415 if(hit->second) {
416 hit->second->Fill(v.second);
417 }
418 }
419 }
420
421 return true;
422}
423
424//=============================================================================
426 std::vector<decoratorFloatH_t>& decors) const
427{
428 //
429 // Fill dummy values for RNN outputs
430 //
431 for (auto& d : decors) {
432 d(particle) = -1.0;
433 }
434
435 return true;
436}
437
438//=============================================================================
439StatusCode Prompt::DecoratePromptLeptonRNN::makeHist(TH1 *&h, const std::string &key, int nbin, double xmin, double xmax)
440{
441 //
442 // Initiliase histogram pointer. If configured to run in validation mode, then create and register histogram
443 //
444 h = 0;
445
446 if(m_outputStream.empty() || key.empty()) {
447 return StatusCode::SUCCESS;
448 }
449
450 const std::string hname = name() + "_" + key;
451 const std::string hist_key = "/"+m_outputStream+"/"+hname;
452
453 h = new TH1D(hname.c_str(), hname.c_str(), nbin, xmin, xmax);
454 h->SetDirectory(0);
455
456 return m_histSvc->regHist(hist_key, h);
457}
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_INFO(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
Some common helper functions used by decoration handles.
AthAlgorithm(const std::string &name, ISvcLocator *pSvcLocator)
Constructor.
Header file for AthHistogramAlgorithm.
virtual StatusCode finalize() override
SG::ReadHandleKey< xAOD::JetContainer > m_inputContainerTrackJetKey
Gaudi::Property< double > m_maxTrackEta
const xAOD::TrackParticle * findMuonTrack(const xAOD::Muon *muon)
bool compDummy(const xAOD::IParticle &particle, std::vector< decoratorFloatH_t > &decors) const
Gaudi::Property< unsigned > m_minTrackSiHits
std::map< std::string, TH1 * > m_hists
DecoratePromptLeptonRNN(const std::string &name, ISvcLocator *pSvcLocator)
Gaudi::Property< unsigned > m_maxTrackSiHoles
StatusCode makeHist(TH1 *&h, const std::string &key, int nbin, double xmin, double xmax)
std::unordered_map< std::string, size_t > m_decorNameMap
virtual StatusCode execute(const EventContext &ctx) override
Execute method.
Gaudi::Property< double > m_maxTrackLeptonDR
const xAOD::Jet * findClosestTrackJet(const xAOD::TrackParticle *particle, const xAOD::JetContainer &trackJets)
SG::ReadHandleKey< xAOD::IParticleContainer > m_inputContainerLeptonKey
Gaudi::Property< double > m_maxLepTrackJetDR
Gaudi::Property< double > m_maxTrackZ0Sin
virtual StatusCode initialize() override
SG::WriteDecorHandleKeyArray< xAOD::IParticleContainer > m_decorHandleKeys
SG::ReadHandleKey< xAOD::VertexContainer > m_inputContainerPrimaryVerticesKey
Gaudi::Property< std::string > m_decorationPrefixRNN
Gaudi::Property< std::string > m_outputStream
SG::ReadHandleKey< xAOD::TrackParticleContainer > m_inputContainerTrackKey
bool compScore(const xAOD::IParticle &particle, const std::vector< Prompt::VarHolder > &tracks, std::vector< decoratorFloatH_t > &decors)
Gaudi::Property< double > m_maxTrackSharedSiHits
Gaudi::Property< unsigned > m_maxTrackPixHoles
SG::ReadHandleKey< xAOD::EventInfo > m_eventHandleKey
Gaudi::Property< double > m_minTrackLeptonDR
bool prepTrackObject(Prompt::VarHolder &p, const xAOD::TrackParticle &track, const xAOD::TrackParticle &lepton, const xAOD::Jet &trackJet, const xAOD::Vertex &priVtx, const xAOD::EventInfo event)
Gaudi::Property< double > m_minTrackpT
Property holding a SG store/key/clid/attr name from which a WriteDecorHandle is made.
const xAOD::TrackParticle * trackParticle(size_t index=0) const
Pointer to the xAOD::TrackParticle/s that match the electron candidate.
Class providing the definition of the 4-vector interface.
virtual FourMom_t p4() const
The full 4-momentum of the particle.
Definition Jet_v1.cxx:71
virtual double pt() const
The transverse momentum ( ) of the particle.
Definition Jet_v1.cxx:44
virtual FourMom_t p4() const override final
The full 4-momentum of the particle.
float z() const
Returns the z position.
std::string label(const std::string &format, int i)
Definition label.h:19
double xmax
Definition listroot.cxx:61
double xmin
Definition listroot.cxx:60
@ NumberOfPixelHoles
Definition VarHolder.h:53
@ NumberOfPIXHits
Definition VarHolder.h:48
@ NumberOfSCTHits
Definition VarHolder.h:49
@ NumberOfSharedSiHits
Definition VarHolder.h:51
@ TrackPtOverTrackJetPt
Definition VarHolder.h:55
@ NumberOfSiHoles
Definition VarHolder.h:52
std::string PrintResetStopWatch(TStopwatch &watch)
std::string makeContDecorKey(const std::string &cont, const std::string &decor)
Make a StoreGate key from container and decoration name.
void sort(typename DataModel_detail::iterator< DVL > beg, typename DataModel_detail::iterator< DVL > end)
Specialization of sort for DataVector/List.
const xAOD::TrackParticle * getOriginalTrackParticleFromGSF(const xAOD::TrackParticle *trkPar)
Helper function for getting the "Original" Track Particle (i.e before GSF) via the GSF Track Particle...
double d0significance(const xAOD::TrackParticle *tp, double d0_uncert_beam_spot_2)
@ PriVtx
Primary vertex.
Jet_v1 Jet
Definition of the current "jet version".
EventInfo_v1 EventInfo
Definition of the latest event info version.
TrackParticle_v1 TrackParticle
Reference the current persistent version:
Vertex_v1 Vertex
Define the latest version of the vertex class.
Muon_v1 Muon
Reference the current persistent version:
JetContainer_v1 JetContainer
Definition of the current "jet container version".
@ numberOfPixelHoles
number of pixel layers on track with absence of hits [unit8_t].
@ numberOfSCTHits
number of hits in SCT [unit8_t].
@ numberOfPixelHits
these are the pixel hits, including the b-layer [unit8_t].
@ numberOfPixelSharedHits
number of Pixel all-layer hits shared by several tracks [unit8_t].
@ numberOfSCTSharedHits
number of SCT hits shared by several tracks [unit8_t].
@ numberOfSCTHoles
number of SCT holes [unit8_t].
Electron_v1 Electron
Definition of the current "egamma version".