ATLAS Offline Software
Loading...
Searching...
No Matches
CalcPartonHistory.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
3*/
4
7
9
11
12#include <memory>
13#include <unordered_map>
14#include <unordered_set>
15
18
19#ifdef XAOD_STANDALONE
20#define TDS() evtStore()->tds()
21#else
22#define TDS() evtStore()
23#endif
24
25namespace {
26const std::vector<const xAOD::TruthParticle*>* findVector(
27 const std::map<std::string, std::vector<const xAOD::TruthParticle*>>& map,
28 const std::string& key) {
29 auto it = map.find(key);
30 return it == map.end() ? nullptr : &it->second;
31}
32
33constexpr const char* kBeforeFSR = "_beforeFSR";
34constexpr const char* kAfterFSR = "_afterFSR";
35} // namespace
36
37namespace CP {
38using ROOT::Math::PtEtaPhiMVector;
39
41 const std::string& name, const std::vector<std::string>& truthCollection)
42 : asg::AsgTool(name), m_truthCollections(truthCollection) {}
43
44bool CalcPartonHistory::ExistsInMap(const std::string& key) const {
45 // Checks whether a given key exists in the particle map.
46 return m_particleMap.find(key) != m_particleMap.end();
47}
48
49bool CalcPartonHistory::ExistsInKey(const std::string& key,
50 const xAOD::TruthParticle* p) const {
51 // Checks whether a given particle exists in the vector for the given key.
52 if (const auto* v = findVector(m_particleMap, key)) {
53 return std::find(v->begin(), v->end(), p) != v->end();
54 }
55 return false;
56}
57
58bool CalcPartonHistory::Retrievep4(const std::string& key,
59 PtEtaPhiMVector& p4) {
60 return Retrievep4(key, p4, 0);
61}
62
63bool CalcPartonHistory::Retrievep4(const std::string& key, PtEtaPhiMVector& p4,
64 std::size_t idx) {
65 const auto* v = findVector(m_particleMap, key);
66 if (!v || idx >= v->size())
67 return false;
68 p4 = GetPtEtaPhiMfromTruth(v->at(idx));
69 return true;
70}
71
72bool CalcPartonHistory::Retrievep4Gamma(PtEtaPhiMVector& p4, int& parentpdgId) {
73 // Finds the highest-pT photon among all m_particleMap entries. Photons are
74 // stored either under "..._gamma_<beforeFSR|afterFSR>" keys or, when they
75 // come from a W/Z/H decay vertex, under "...Decay<N>_<beforeFSR|afterFSR>".
76 const xAOD::TruthParticle* bestPhoton = nullptr;
77 for (const auto& entry : m_particleMap) {
78 for (const auto* p : entry.second) {
79 if (p && p->pdgId() == 22 && (!bestPhoton || p->pt() > bestPhoton->pt()))
80 bestPhoton = p;
81 }
82 }
83 if (!bestPhoton) {
84 parentpdgId = 0;
85 return false;
86 }
87 p4 = GetPtEtaPhiMfromTruth(bestPhoton);
88 // Skip identical-photon copies to find the particle that emitted it.
89 const xAOD::TruthParticle* parent =
90 bestPhoton->nParents() > 0 ? bestPhoton->parent(0) : nullptr;
91 while (parent && parent->pdgId() == 22)
92 parent = parent->nParents() > 0 ? parent->parent(0) : nullptr;
93 parentpdgId = parent ? parent->pdgId() : 0;
94 return true;
95}
96
97bool CalcPartonHistory::RetrievepdgId(const std::string& key, int& pdgId) {
98 return RetrievepdgId(key, pdgId, 0);
99}
100
101bool CalcPartonHistory::RetrievepdgId(const std::string& key,
102 std::vector<int>& pdgIds) {
103 const auto* v = findVector(m_particleMap, key);
104 if (!v)
105 return false;
106 pdgIds.reserve(pdgIds.size() + v->size());
107 for (const auto* p : *v)
108 if (p)
109 pdgIds.push_back(p->pdgId());
110 return true;
111}
112
113bool CalcPartonHistory::RetrievepdgId(const std::string& key, int& pdgId,
114 std::size_t idx) {
115 const auto* v = findVector(m_particleMap, key);
116 if (!v || idx >= v->size())
117 return false;
118 pdgId = v->at(idx)->pdgId();
119 return true;
120}
121
123 const std::string& prefix, std::vector<const xAOD::TruthParticle*>& out) {
124 const auto* v = findVector(m_particleMap, prefix);
125 if (!v)
126 return false;
127 out.insert(out.end(), v->begin(), v->end());
128 return true;
129}
130
132 const std::string& prefix, std::vector<PtEtaPhiMVector>& particles,
133 std::vector<int>& pdgIds) {
134 const auto* v = findVector(m_particleMap, prefix);
135 if (!v)
136 return false;
137 particles.reserve(particles.size() + v->size());
138 pdgIds.reserve(pdgIds.size() + v->size());
139 for (const auto* p : *v) {
140 particles.push_back(GetPtEtaPhiMfromTruth(p));
141 pdgIds.push_back(p->pdgId());
142 }
143 return true;
144}
145
146bool CalcPartonHistory::RetrieveParticleInfo(const std::string& prefix,
147 PtEtaPhiMVector& particle,
148 int& pdgId) {
149 return RetrieveParticleInfo(prefix, particle, pdgId, 0);
150}
151
152bool CalcPartonHistory::RetrieveParticleInfo(const std::string& prefix,
153 PtEtaPhiMVector& particle,
154 int& pdgId, std::size_t idx) {
155 return Retrievep4(prefix, particle, idx) && RetrievepdgId(prefix, pdgId, idx);
156}
157
158bool CalcPartonHistory::RetrieveParticleInfo(const std::string& prefix,
159 const std::string& alt_prefix,
160 PtEtaPhiMVector& particle,
161 int& pdgId) {
162 if (Retrievep4(prefix, particle) && RetrievepdgId(prefix, pdgId))
163 return true;
164 return Retrievep4(alt_prefix, particle) && RetrievepdgId(alt_prefix, pdgId);
165}
166
168 const xAOD::TruthParticle* particle) {
169 static const std::unordered_map<int, std::string> pdgMap = {
170 {1, "_q"}, {2, "_q"}, {3, "_q"}, {-1, "_qbar"},
171 {-2, "_qbar"}, {-3, "_qbar"}, {6, "_t"}, {-6, "_tbar"},
172 {5, "_b"}, {-5, "_bbar"}, {4, "_c"}, {-4, "_cbar"},
173 {25, "_H"}, {24, "_W"}, {-24, "_W"}, {23, "_Z"},
174 {22, "_gamma"}, {21, "_g"}, {11, "_l"}, {13, "_l"},
175 {15, "_l"}, {-11, "_lbar"}, {-13, "_lbar"}, {-15, "_lbar"},
176 {12, "_nu"}, {14, "_nu"}, {16, "_nu"}, {-12, "_nubar"},
177 {-14, "_nubar"}, {-16, "_nubar"}, {2212, "_p"}, {1103, "_dd"},
178 {2101, "_ud"}, {2103, "_ud"}, {2203, "_uu"}, {3101, "_sd"},
179 {3103, "_sd"}, {3201, "_su"}, {3203, "_su"}, {3303, "_ss"},
180 {4101, "_cd"}, {4103, "_cd"}, {4201, "_cu"}, {4203, "_cu"},
181 {4301, "_cs"}, {4303, "_cs"}, {4403, "_cc"}, {5101, "_bd"},
182 {5103, "_bd"}, {5201, "_bu"}, {5203, "_bu"}, {5301, "_bs"},
183 {5303, "_bs"}, {5401, "_bc"}, {5403, "_bc"}, {5503, "_bb"}};
184 int pdgId = particle->pdgId();
185 auto it = pdgMap.find(pdgId);
186 return it != pdgMap.end() ? it->second : "_" + std::to_string(pdgId);
187}
188
190 const xAOD::TruthParticle* p, std::vector<const xAOD::TruthParticle*>& path,
191 std::vector<std::vector<const xAOD::TruthParticle*>>& allPaths) {
192 // Recursively builds decay paths from p down to stable particles.
193 // Each completed root-to-leaf path is appended to allPaths and later
194 // processed by FillParticleMap to assign m_particleMap keys.
195 //
196 // FSR handling: a particle that radiates before decaying appears as a chain
197 // of identical PDG-ID nodes (e.g. t → t → t → W b). findAfterFSR() follows
198 // that chain to the last node before the actual decay vertex, so the path
199 // records the pre- and post-FSR instances rather than every intermediate.
200 //
201 // W linking (DAOD_PHYS only): TruthTop links to Ws in TruthBoson, which
202 // carry no decay products. When we encounter such a W (isAfterFSR &&
203 // |pdg|==24) we swap it for the corresponding entry in
204 // TruthBosonsWithDecayParticles via the
205 // "CustomLinkedTruthBosonWithDecayParticles" decoration so that the subsequent
206 // child traversal finds the W decay products.
208 return;
209
210 // If this W node has no identical child (i.e. it is the after-FSR instance)
211 // but lacks decay products, swap to the linked decay-product-bearing copy.
212 if (PartonHistoryUtils::isAfterFSR(*p) && std::abs(p->pdgId()) == 24) {
214 p, "CustomLinkedTruthBosonWithDecayParticles");
215 }
216
217 path.push_back(p);
218
219 // Leaf node: record the completed path.
220 if (p->nChildren() == 0) {
221 allPaths.push_back(path);
222 path.pop_back();
223 return;
224 }
225
227 // Same W-linking fix for the after-FSR node reached by findAfterFSR().
228 if (std::abs(afterFSR->pdgId()) == 24) {
230 afterFSR, "CustomLinkedTruthBosonWithDecayParticles");
231 }
232
233 if (afterFSR != p) {
234 // There was FSR: continue the path from the post-FSR node.
235 TraceParticle(afterFSR, path, allPaths);
236 } else {
237 // No FSR: branch into each child (e.g. W→lν gives two sub-paths).
238 for (std::size_t i = 0; i < afterFSR->nChildren(); ++i) {
239 if (const auto* c = afterFSR->child(i))
240 TraceParticle(c, path, allPaths);
241 }
242 }
243 path.pop_back();
244}
245
247 const std::string& key) {
248 if (!ExistsInKey(key, p))
249 m_particleMap[key].push_back(p);
250}
251
253 const std::string& newKey, std::string& key) {
254 // Last copy of an FSR chain: stored under the key of its first copy.
256 AddToParticleMap(p, key + kAfterFSR);
257 return;
258 }
259 key += newKey;
260 AddToParticleMap(p, key + kBeforeFSR);
262 AddToParticleMap(p, key + kAfterFSR);
263}
264
266 std::string& key, int decayID) {
267 // Only daughters of a W/Z/H (not FSR copies of the boson itself).
272 return false;
273
274 const std::string decayStr = "Decay" + std::to_string(decayID);
275 key += decayStr;
276 AddToParticleMap(p, key + kBeforeFSR);
278 AddToParticleMap(p, key + kAfterFSR);
279 return true;
280}
281
283 std::vector<std::vector<const xAOD::TruthParticle*>>& allPaths) {
284 // Converts the raw decay paths produced by TraceParticles into the
285 // m_particleMap used by all Retrieve* and Fill* methods.
286 //
287 // Key construction: each path is walked particle by particle, accumulating
288 // a string key of the form
289 // "<prefix>_MC_<type1>_<type2>_..._<beforeFSR|afterFSR>". For example, a b
290 // quark from a top gives "MySch_MC_t_b_beforeFSR". Decay products of W/Z/H
291 // get an additional "Decay<N>" segment to distinguish the two daughters, e.g.
292 // "MySch_MC_t_WDecay1_beforeFSR".
293 //
294 // Handlers (first match wins for each particle in the path):
295 // handleDecay — daughters of W/Z/H: appends "Decay<N>" and records
296 // beforeFSR/afterFSR
297 // handleFSR — all other particles: the first copy of an FSR chain
298 // appends the type suffix and records beforeFSR (and
299 // afterFSR if it does not radiate); the last copy (same PDG
300 // as parent) records afterFSR under the current key
301 m_particleMap.clear();
302
303 for (const auto& path : allPaths) {
304 // m_particleMap keys always include the prefix, built once here.
305 std::string key = m_prefix + "_" + "MC";
306
307 for (const auto* p : path) {
308 // beforeFSR: this node has an identical child (it will radiate).
309 // afterFSR: this node's parent has the same PDG ID (it was radiated
310 // from).
311 const bool beforeFSR = PartonHistoryUtils::hasIdenticalChild(*p);
312 const bool afterFSR = PartonHistoryUtils::hasParentPdgId(*p);
313
314 // Determine which child index this particle is under its parent; used to
315 // label W/Z/H decay daughters as Decay1, Decay2. Falls back to sign of
316 // pdgId (negative → 2) if parent navigation is unavailable.
317 int decayID = (p->pdgId() < 0) ? 2 : 1;
318 if (p->nParents() != 0 && p->parent(0)) {
319 const auto* par = p->parent(0);
320 for (std::size_t i = 0; i < par->nChildren(); ++i) {
321 if (par->child(i) == p) {
322 decayID = static_cast<int>(i) + 1;
323 break;
324 }
325 }
326 }
327
328 const std::string new_key = GetParticleType(p);
329
330 // Skip pure intermediate FSR nodes that are neither the first nor last
331 // in the FSR chain — they carry no additional physics information.
332 if (beforeFSR && afterFSR)
333 continue;
334 if (handleDecay(p, key, decayID))
335 continue;
336 handleFSR(p, new_key, key);
337 }
338 }
339}
340
342 const xAOD::TruthParticleContainer* truthParticles) {
343 std::vector<std::vector<const xAOD::TruthParticle*>> allPaths;
344 allPaths.reserve(truthParticles->size());
345 for (const xAOD::TruthParticle* p : *truthParticles) {
347 continue;
348 std::vector<const xAOD::TruthParticle*> path;
349 path.reserve(16);
350 TraceParticle(p, path, allPaths);
351 }
352 FillParticleMap(allPaths);
353}
354
356 m_dec.setPrefix(m_prefix);
358 return StatusCode::SUCCESS;
359}
360
362 const xAOD::TruthParticleContainer* truthParticles{nullptr};
363 ANA_CHECK(linkTruthContainers(truthParticles));
364
365 const xAOD::EventInfo* partonHistory = nullptr;
366 ANA_CHECK(evtStore()->retrieve(partonHistory, "EventInfo"));
367
368 ANA_CHECK(runHistorySaver(truthParticles, partonHistory));
369 return StatusCode::SUCCESS;
370}
371
373 const std::vector<std::string>& collections,
374 const std::string& out_contName) {
375 // In DAOD_PHYS there is no single TruthParticles collection, so we merge
376 // several dedicated collections (e.g. TruthTop,
377 // TruthBosonsWithDecayParticles) into one working container stored in the
378 // event store.
379 //
380 // The merge must avoid double-counting: the same particle can appear in
381 // multiple collections (e.g. the b from a top appears in both TruthTop and
382 // TruthBottom). We therefore keep only "root" particles — those that are not
383 // a descendant of any other candidate in the merged pool. TraceParticles then
384 // walks down from these roots, naturally visiting all descendants regardless
385 // of which original collection they came from.
386 auto out_cont =
387 std::make_unique<ConstDataVector<DataVector<xAOD::TruthParticle_v1>>>(
389 std::vector<const xAOD::TruthParticle*> p_candidates;
390 std::vector<const xAOD::TruthParticle*> p_parents;
391 std::unordered_set<int> candidateUids;
392
393 for (const std::string& collection : collections) {
394 const xAOD::TruthParticleContainer* cont = nullptr;
395 ANA_CHECK(evtStore()->retrieve(cont, collection));
396 for (const xAOD::TruthParticle* p : *cont) {
397 if (p) {
398 p_candidates.push_back(p);
399 candidateUids.insert(p->uid());
400 }
401 }
402 }
403 // Collect the uids of all candidates that descend from another (non-PDF)
404 // candidate, walking the decay tree of each candidate once. All copies of
405 // duplicated particles are walked, as their navigation links may differ.
406 std::unordered_set<int> descendantUids;
407 std::vector<const xAOD::TruthParticle*> stack;
408 for (const xAOD::TruthParticle* ancestor : p_candidates) {
410 continue;
411 stack.assign(1, ancestor);
412 while (!stack.empty()) {
413 const xAOD::TruthParticle* p = stack.back();
414 stack.pop_back();
415 for (std::size_t i = 0; i < p->nChildren(); ++i) {
416 const xAOD::TruthParticle* child = p->child(i);
417 if (!child)
418 continue;
419 if (candidateUids.count(child->uid()))
420 descendantUids.insert(child->uid());
421 stack.push_back(child);
422 }
423 }
424 }
425 // Retain only particles that have no ancestor among the other candidates.
426 // Particles present in several collections (same uid) are kept only once,
427 // using the copy from the first collection that contains them.
428 std::unordered_set<int> rootUids;
429 for (const xAOD::TruthParticle* potential_parent : p_candidates) {
430 if (!PartonHistoryUtils::isQuarkFromPDF(*potential_parent) &&
431 !descendantUids.count(potential_parent->uid()) &&
432 rootUids.insert(potential_parent->uid()).second)
433 p_parents.push_back(potential_parent);
434 }
435 out_cont->insert(out_cont->end(), p_parents.begin(), p_parents.end());
436 StatusCode save = TDS()->record(std::move(out_cont), out_contName);
437 if (!save)
438 return StatusCode::FAILURE;
439 return StatusCode::SUCCESS;
440}
441
444 "TruthBoson", "TruthBosonsWithDecayParticles",
445 "CustomLinkedTruthBosonWithDecayParticles");
446}
447
449 const std::string& collectionToDecorate,
450 const std::string& collectionToLink, const std::string& nameOfDecoration) {
451 const SG::Decorator<const xAOD::TruthParticle*> dec(nameOfDecoration);
452 const xAOD::TruthParticleContainer* cont1 = nullptr;
453 const xAOD::TruthParticleContainer* cont2 = nullptr;
454 ANA_CHECK(evtStore()->retrieve(cont1, collectionToDecorate));
455 ANA_CHECK(evtStore()->retrieve(cont2, collectionToLink));
456 std::unordered_map<int, const xAOD::TruthParticle*> byUid;
457 byUid.reserve(cont2->size());
458 for (const auto* q : *cont2)
459 byUid.emplace(q->uid(), q);
460 for (const auto* p : *cont1) {
461 const xAOD::TruthParticle* link = nullptr;
462 auto it = byUid.find(p->uid());
463 if (it != byUid.end() && it->second->pdgId() == p->pdgId())
464 link = it->second;
465 dec(*p) = link;
466 }
467 return StatusCode::SUCCESS;
468}
469
472 const xAOD::TruthParticle* part, const std::string& decorationName) {
474 if (!acc.isAvailable(*part))
475 return part;
476 const xAOD::TruthParticle* link = acc(*part);
477 return link ? link : part;
478}
479
481 const xAOD::TruthParticleContainer*& tp) {
482 const std::string key = m_prefix + "_TruthParticles";
484 const auto& collections =
485 m_configured ? m_config.truthCollections : m_truthCollections;
487 ANA_CHECK(evtStore()->retrieve(tp, key));
489 return StatusCode::SUCCESS;
490 }
491 ANA_CHECK(evtStore()->retrieve(tp, key));
492 return StatusCode::SUCCESS;
493}
494
496 m_config = config;
497 m_configured = true;
498}
499
501 if (!m_configured)
502 return;
503
504 for (const auto& group : m_config.decoratorGroups) {
505 switch (group) {
508 break;
511 break;
514 break;
517 break;
520 break;
523 break;
526 break;
529 break;
532 break;
535 break;
538 break;
541 break;
544 break;
547 break;
550 break;
553 break;
554 }
555 }
556
557 for (const auto& zw : m_config.decoratorZWs) {
558 if (zw.type == DecoratorZW::Z)
559 InitializeZDecorators(zw.count, zw.extended);
560 else
561 InitializeWDecorators(zw.count);
562 }
563
564 for (const auto& fill : m_config.genericFills) {
565 if (fill.isVector) {
566 m_dec.initializeVectorPtEtaPhiMDecorator(fill.decorationKey);
567 m_dec.initializeVectorIntDecorator(fill.decorationKey + "_pdgId");
568 } else {
569 m_dec.initializePtEtaPhiMDecorator(fill.decorationKey);
570 m_dec.initializeIntDecorator(fill.decorationKey + "_pdgId");
571 }
572 }
573
574 for (const auto& fill : m_config.isOnShellFills)
575 m_dec.initializeIntDecorator(fill.decorationKey);
576}
577
579 const xAOD::TruthParticleContainer* truthParticles,
580 const xAOD::EventInfo* partonHistory) {
581
582 // Register the EventInfo for this event; all m_dec.decorate*() calls
583 // will write to it automatically.
584 m_dec.setEventInfo(partonHistory);
585
586 TraceParticles(truthParticles);
587
588 for (const auto& op : m_config.specialFills) {
589 switch (op.type) {
592 break;
595 break;
598 break;
601 break;
604 break;
607 break;
609 FillZPartonHistory(op.parent, op.count, op.mode);
610 break;
612 FillZtautauPartonHistory(op.parent, op.count, op.mode);
613 break;
615 FillWPartonHistory(op.parent, op.count, op.mode);
616 break;
618 FillHiggsPartonHistory(op.mode);
619 break;
622 break;
623 }
624 }
625
626 for (const auto& fill : m_config.genericFills) {
627 if (fill.isVector) {
628 FillGenericVectorPartonHistory(fill.retrievalKeys.at(0),
629 fill.decorationKey);
630 } else if (fill.retrievalKeys.size() == 1) {
631 FillGenericPartonHistory(fill.retrievalKeys.at(0), fill.decorationKey,
632 fill.idx);
633 } else {
634 FillGenericPartonHistory(fill.retrievalKeys, fill.decorationKey,
635 fill.idx);
636 }
637 }
638
639 for (const auto& fill : m_config.isOnShellFills) {
640 bool onShell = false;
641 for (const auto& key : fill.retrievalKeys) {
642 if (ExistsInMap(m_prefix + "_" + key)) {
643 onShell = true;
644 break;
645 }
646 }
647 m_dec.decorateCustom(fill.decorationKey, onShell ? 1 : 0);
648 }
649
650 return StatusCode::SUCCESS;
651}
652
653} // namespace CP
#define TDS()
DataVector adapter that acts like it holds const pointers.
#define ANA_CHECK(EXP)
check whether the given expression was successful
ROOT::Math::PtEtaPhiMVector GetPtEtaPhiMfromTruth(const xAOD::TruthParticle *TruthParticle)
ServiceHandle< StoreGateSvc > & evtStore()
StatusCode buildContainerFromMultipleCollections(const std::vector< std::string > &collections, const std::string &out_contName)
used to build container from multiple collections in DAOD_PHYS we don't have the TruthParticles colle...
CalcPartonHistory(const std::string &name, const std::vector< std::string > &truthCollections={"TruthTop"})
void FillGenericVectorPartonHistory(const std::string &retrievalstring, const std::string &decorationstring)
bool ExistsInKey(const std::string &key, const xAOD::TruthParticle *particle) const
void configure(const PartonSchemeConfig &config)
const xAOD::TruthParticle * getTruthParticleLinkedFromDecoration(const xAOD::TruthParticle *part, const std::string &decorationName)
helper method to handle retriveing the truth particle linked in the decoration of another particle
virtual StatusCode runHistorySaver(const xAOD::TruthParticleContainer *truthParticles, const xAOD::EventInfo *ttbarPartonHistory)
void FillParticleMap(std::vector< std::vector< const xAOD::TruthParticle * > > &allPaths)
bool Retrievep4Gamma(PtEtaPhiMVector &p4, int &parentpdgId)
bool RetrieveParticleInfo(const std::string &prefix, std::vector< const xAOD::TruthParticle * > &particles)
const std::vector< std::string > m_truthCollections
Gaudi::Property< std::string > m_prefix
void FillHiggsPartonHistory(const std::string &mode)
std::map< std::string, std::vector< const xAOD::TruthParticle * > > m_particleMap
virtual StatusCode linkTruthContainers(const xAOD::TruthParticleContainer *&tp)
void FillWPartonHistory(const std::string &parent, int nWs=1, const std::string &mode="resonant")
std::string GetParticleType(const xAOD::TruthParticle *particle)
bool Retrievep4(const std::string &key, PtEtaPhiMVector &p4)
void handleFSR(const xAOD::TruthParticle *particle, const std::string &newKey, std::string &key)
void FillTopPartonHistory(bool fcnc=false)
bool ExistsInMap(const std::string &key) const
void InitializeZDecorators(int nZs=1, bool extend=false)
void FillZtautauPartonHistory(const std::string &parent, int nZs=1, const std::string &mode="resonant")
bool RetrievepdgId(const std::string &key, std::vector< int > &pdgIds)
bool handleDecay(const xAOD::TruthParticle *particle, std::string &key, int decayID)
bool m_configured
true after configure() has been called
void InitializeTopDecorators(bool fcnc=false)
void FillZPartonHistory(const std::string &parent, int nZs=1, const std::string &mode="resonant")
void InitializeAntiTopDecorators(bool fcnc=false)
void TraceParticle(const xAOD::TruthParticle *particle, std::vector< const xAOD::TruthParticle * > &currentPath, std::vector< std::vector< const xAOD::TruthParticle * > > &allPaths)
virtual void initializeDecorators()
void TraceParticles(const xAOD::TruthParticleContainer *truthParticles)
StatusCode linkBosonCollections()
currently in DAOD_PHYS TruthTop have links to Ws from the TruthBoson collection, which have no link t...
void FillGenericPartonHistory(const std::string &retrievalstring, const std::string &decorationstring, const int idx)
StatusCode decorateCollectionWithLinksToAnotherCollection(const std::string &collectionToDecorate, const std::string &collectionToLink, const std::string &nameOfDecoration)
helper method currently used in DAOD_PHYS to link particles from a given collection to the same parti...
PartonSchemeConfig m_config
scheme configuration set via configure()
void FillTtbarPartonHistory(bool fcnc=false)
void AddToParticleMap(const xAOD::TruthParticle *particle, const std::string &key)
void FillAntiTopPartonHistory(bool fcnc=false)
virtual StatusCode initialize() override
Dummy implementation of the initialisation function.
size_type size() const noexcept
Returns the number of elements in the collection.
Helper class to provide constant type-safe access to aux data.
AsgTool(const std::string &name)
Constructor specifying the tool instance's name.
Definition AsgTool.cxx:58
STL class.
const TruthParticle_v1 * child(size_t i) const
Retrieve the i-th mother (TruthParticle) of this TruthParticle.
int pdgId() const
PDG ID code.
const TruthParticle_v1 * parent(size_t i) const
Retrieve the i-th mother (TruthParticle) of this TruthParticle.
virtual double pt() const override final
The transverse momentum ( ) of the particle.
size_t nParents() const
Number of parents of this particle.
int uid() const
Unique ID.
size_t nChildren() const
Number of children of this particle.
bool contains(const std::string &s, const std::string &regx)
does a string contain the substring
Definition hcg.cxx:116
bool isQuarkFromPDF(const xAOD::TruthParticle &particle)
bool hasParentAbsPdgId(const xAOD::TruthParticle &particle, int absPdgId)
bool hasIdenticalChild(const xAOD::TruthParticle &particle)
bool isBrokenTop(const xAOD::TruthParticle &particle)
Looking for tops without children -> must be broken.
bool hasParentPdgId(const xAOD::TruthParticle &particle, int PdgId)
const xAOD::TruthParticle & findAfterFSR(const xAOD::TruthParticle &particle)
Return particle after FSR (before the decay vertex).
bool isAfterFSR(const xAOD::TruthParticle &particle)
Determine whether particle is afterFSR.
bool hasParticleIdenticalParent(const xAOD::TruthParticle &particle)
Return true when any parent of the particle has the same pdgId as the particle.
Select isolated Photons, Electrons and Muons.
@ TopFCNC
FillTopPartonHistory(true).
@ Z
FillZPartonHistory.
@ AntiTopFCNC
FillAntiTopPartonHistory(true).
@ Ttbar
FillTtbarPartonHistory.
@ W
FillWPartonHistory.
@ Ztautau
FillZtautauPartonHistory.
@ Higgs
FillHiggsPartonHistory.
@ Top
FillTopPartonHistory.
@ AntiTop
FillAntiTopPartonHistory.
@ Gamma
FillGammaPartonHistory.
@ TopFCNC
InitializeTopDecorators(true).
@ FourTop
Initialize4TopDecorators().
@ VectorAntiBottom
InitializeVectorAntiBottomDecorators().
@ VectorAntiCharm
InitializeVectorAntiCharmDecorators().
@ Bottom
InitializeBottomDecorators().
@ Charm
InitializeCharmDecorators().
@ AntiTopFCNC
InitializeAntiTopDecorators(true).
@ AntiCharm
InitializeAntiCharmDecorators().
@ VectorBottom
InitializeVectorBottomDecorators().
@ Ttbar
InitializeTtbarDecorators().
@ VectorCharm
InitializeVectorCharmDecorators().
@ Higgs
InitializeHiggsDecorators().
@ Top
InitializeTopDecorators().
@ AntiBottom
InitializeAntiBottomDecorators().
@ AntiTop
InitializeAntiTopDecorators().
@ Photon
InitializePhotonDecorators().
SG::Decorator< T, ALLOC > Decorator
Helper class to provide type-safe access to aux data, specialized for JaggedVecElt.
Definition AuxElement.h:576
@ VIEW_ELEMENTS
this data object is a view, it does not own its elmts
EventInfo_v1 EventInfo
Definition of the latest event info version.
TruthParticle_v1 TruthParticle
Typedef to implementation.
TruthParticleContainer_v1 TruthParticleContainer
Declare the latest version of the truth particle container.
static const SG::AuxElement::Accessor< ElementLink< IParticleContainer > > acc("originalObjectLink")
Object used for setting/getting the dynamic decoration in question.
enum CP::DecoratorZW::Type Z
Top-level configuration for a named parton history scheme.
void fill(H5::Group &out_file, size_t iterations)