13#include <unordered_map>
14#include <unordered_set>
20#define TDS() evtStore()->tds()
22#define TDS() evtStore()
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;
33constexpr const char* kBeforeFSR =
"_beforeFSR";
34constexpr const char* kAfterFSR =
"_afterFSR";
38using ROOT::Math::PtEtaPhiMVector;
41 const std::string&
name,
const std::vector<std::string>& truthCollection)
53 return std::find(v->begin(), v->end(), p) != v->end();
59 PtEtaPhiMVector& p4) {
66 if (!v || idx >= v->size())
78 for (
const auto* p : entry.second) {
79 if (p && p->pdgId() == 22 && (!bestPhoton || p->pt() > bestPhoton->
pt()))
91 while (parent && parent->pdgId() == 22)
92 parent = parent->nParents() > 0 ? parent->parent(0) :
nullptr;
93 parentpdgId = parent ? parent->pdgId() : 0;
102 std::vector<int>& pdgIds) {
106 pdgIds.reserve(pdgIds.size() + v->size());
107 for (
const auto* p : *v)
109 pdgIds.push_back(p->pdgId());
116 if (!v || idx >= v->size())
118 pdgId = v->at(idx)->pdgId();
123 const std::string& prefix, std::vector<const xAOD::TruthParticle*>& out) {
127 out.insert(out.end(), v->begin(), v->end());
132 const std::string& prefix, std::vector<PtEtaPhiMVector>& particles,
133 std::vector<int>& pdgIds) {
137 particles.reserve(particles.size() + v->size());
138 pdgIds.reserve(pdgIds.size() + v->size());
139 for (
const auto* p : *v) {
141 pdgIds.push_back(p->pdgId());
147 PtEtaPhiMVector& particle,
153 PtEtaPhiMVector& particle,
154 int& pdgId, std::size_t idx) {
159 const std::string& alt_prefix,
160 PtEtaPhiMVector& 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);
191 std::vector<std::vector<const xAOD::TruthParticle*>>& allPaths) {
214 p,
"CustomLinkedTruthBosonWithDecayParticles");
220 if (p->nChildren() == 0) {
221 allPaths.push_back(path);
228 if (std::abs(afterFSR->
pdgId()) == 24) {
230 afterFSR,
"CustomLinkedTruthBosonWithDecayParticles");
238 for (std::size_t i = 0; i < afterFSR->
nChildren(); ++i) {
239 if (
const auto* c = afterFSR->
child(i))
247 const std::string& key) {
253 const std::string& newKey, std::string& key) {
266 std::string& key,
int decayID) {
274 const std::string decayStr =
"Decay" + std::to_string(decayID);
283 std::vector<std::vector<const xAOD::TruthParticle*>>& allPaths) {
303 for (
const auto& path : allPaths) {
305 std::string key =
m_prefix +
"_" +
"MC";
307 for (
const auto* p : path) {
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;
332 if (beforeFSR && afterFSR)
343 std::vector<std::vector<const xAOD::TruthParticle*>> allPaths;
344 allPaths.reserve(truthParticles->
size());
348 std::vector<const xAOD::TruthParticle*> path;
358 return StatusCode::SUCCESS;
369 return StatusCode::SUCCESS;
373 const std::vector<std::string>& collections,
374 const std::string& out_contName) {
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;
393 for (
const std::string& collection : collections) {
398 p_candidates.push_back(p);
399 candidateUids.insert(p->uid());
406 std::unordered_set<int> descendantUids;
407 std::vector<const xAOD::TruthParticle*> stack;
411 stack.assign(1, ancestor);
412 while (!stack.empty()) {
415 for (std::size_t i = 0; i < p->nChildren(); ++i) {
419 if (candidateUids.count(child->
uid()))
420 descendantUids.insert(child->
uid());
421 stack.push_back(child);
428 std::unordered_set<int> rootUids;
431 !descendantUids.count(potential_parent->uid()) &&
432 rootUids.insert(potential_parent->uid()).second)
433 p_parents.push_back(potential_parent);
435 out_cont->insert(out_cont->end(), p_parents.begin(), p_parents.end());
436 StatusCode save =
TDS()->record(std::move(out_cont), out_contName);
438 return StatusCode::FAILURE;
439 return StatusCode::SUCCESS;
444 "TruthBoson",
"TruthBosonsWithDecayParticles",
445 "CustomLinkedTruthBosonWithDecayParticles");
449 const std::string& collectionToDecorate,
450 const std::string& collectionToLink,
const std::string& nameOfDecoration) {
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) {
462 auto it = byUid.find(p->uid());
463 if (it != byUid.end() && it->second->pdgId() == p->pdgId())
467 return StatusCode::SUCCESS;
474 if (!
acc.isAvailable(*part))
477 return link ? link : part;
482 const std::string key =
m_prefix +
"_TruthParticles";
484 const auto& collections =
489 return StatusCode::SUCCESS;
492 return StatusCode::SUCCESS;
504 for (
const auto& group :
m_config.decoratorGroups) {
557 for (
const auto& zw :
m_config.decoratorZWs) {
566 m_dec.initializeVectorPtEtaPhiMDecorator(
fill.decorationKey);
567 m_dec.initializeVectorIntDecorator(
fill.decorationKey +
"_pdgId");
569 m_dec.initializePtEtaPhiMDecorator(
fill.decorationKey);
570 m_dec.initializeIntDecorator(
fill.decorationKey +
"_pdgId");
575 m_dec.initializeIntDecorator(
fill.decorationKey);
584 m_dec.setEventInfo(partonHistory);
588 for (
const auto& op :
m_config.specialFills) {
630 }
else if (
fill.retrievalKeys.size() == 1) {
640 bool onShell =
false;
641 for (
const auto& key :
fill.retrievalKeys) {
647 m_dec.decorateCustom(
fill.decorationKey, onShell ? 1 : 0);
650 return StatusCode::SUCCESS;
DataVector adapter that acts like it holds const pointers.
ROOT::Math::PtEtaPhiMVector GetPtEtaPhiMfromTruth(const xAOD::TruthParticle *TruthParticle)
ServiceHandle< StoreGateSvc > & evtStore()
void InitializeVectorAntiCharmDecorators()
void InitializeVectorCharmDecorators()
void InitializeAntiCharmDecorators()
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)
void InitializeVectorAntiBottomDecorators()
void Initialize4TopDecorators()
void InitializeVectorBottomDecorators()
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 InitializeBottomDecorators()
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)
void InitializePhotonDecorators()
bool Retrievep4(const std::string &key, PtEtaPhiMVector &p4)
void FillGammaPartonHistory()
void handleFSR(const xAOD::TruthParticle *particle, const std::string &newKey, std::string &key)
void InitializeCharmDecorators()
void InitializeTtbarDecorators()
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 InitializeAntiBottomDecorators()
void InitializeAntiTopDecorators(bool fcnc=false)
void TraceParticle(const xAOD::TruthParticle *particle, std::vector< const xAOD::TruthParticle * > ¤tPath, std::vector< std::vector< const xAOD::TruthParticle * > > &allPaths)
virtual void initializeDecorators()
void TraceParticles(const xAOD::TruthParticleContainer *truthParticles)
void InitializeHiggsDecorators()
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...
void InitializeWDecorators(int nWs=1)
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.
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 ®x)
does a string contain the substring
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).
@ AntiTopFCNC
FillAntiTopPartonHistory(true).
@ Ttbar
FillTtbarPartonHistory.
@ 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.
@ 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)