24std::pair<ParticleType, ParticleOrigin>
27 const EventContext& ctx = info ? info->eventContext : Gaudi::Hive::currentContext();
29 if (!truthParticleLinkVecReadHandle.
isValid()) {
30 ATH_MSG_WARNING(
" Invalid ReadHandle for xAODTruthParticleLinkVector with key: " << truthParticleLinkVecReadHandle.
key());
41std::pair<ParticleType, ParticleOrigin>
51 return std::make_pair(partType, partOrig);
53 info.genPart = thePart;
57 if (!truthParticleContainerReadHandle.
isValid()) {
58 ATH_MSG_WARNING(
" Invalid ReadHandle for xAOD::TruthParticleContainer with key: " << truthParticleContainerReadHandle.
key());
59 return std::make_pair(partType, partOrig);
62 ATH_MSG_DEBUG(
"xAODTruthParticleContainer with key " << truthParticleContainerReadHandle.
key() <<
" has valid ReadHandle ");
102 const int parentPDG = parent?parent->pdg_id():0;
103 info.setMotherProperties(parent);
120 if (!partProdVtx &&
MC::isTau(thePart)) {
122 partOrig =
defOrigOfTau(*truthParticleContainerReadHandle, thePart, parentPDG, info);
134 return std::make_pair(
Neutrino, partOrig);
140 if (isPartHadr)
return std::make_pair(
Hadron, partOrig);
173 partOrig =
defOrigOfTau(*truthParticleContainerReadHandle, thePart, parentPDG, info);
186 return std::make_pair(partType, partOrig);
193 const int parentPDG = parent->pdgId();
195 if (!aChild)
continue;
224 parent_prdVtx = parent->hasProdVtx() ? parent->prodVtx() :
nullptr;
225 parent_endVtx = parent->decayVtx();
229 return (child_endVtx == parent_prdVtx && child_prdVtx == parent_endVtx);
237 const xAOD::TruthVertex* parentOrigVtx = parent->hasProdVtx() ? parent->prodVtx() :
nullptr;
268 info.setMotherProperties(ancestor);
284 if (ancestor == ancestorParent) {
break; }
286 ancestorParent = ancestor;
291 if (ancestorParent) {
292 pPDG = ancestorParent->
pdgId();
294 ancestor = ancestorParent;
303 ancestor = ancestorParent;
307 info.setMotherProperties(ancestor);
308 const int ancestorPDG = ancestor->
pdgId();
315 auto DP = DecayProducts(partProdVtx);
320 const int NumOfgluon = DP.apd(
MC::GLUON);
321 const int NumOfElNeut = DP.apd(
MC::NU_E);
323 const int NumOfMuPl = DP.pd(-
MC::MUON);
324 const int NumOfMuMin = DP.pd(
MC::MUON);
325 const int NumOfMuNeut = DP.apd(
MC::NU_MU);
326 const int NumOfTau = DP.apd(
MC::TAU);
333 if (!aChild)
continue;
334 const int childPDG = aChild->pdgId();
336 if (possibleNuclearFragment &&
345 for (
const auto& photonParent: ancestorProdVtx->
particles_in()) {
346 if (!photonParent)
continue;
347 info.photonMother = photonParent;
351 if ((
MC::isPhoton(ancestorPDG) && numberOfChildren == 2 && NumOfEl == 1 && NumOfPos == 1) || (
MC::isPhoton(ancestorPDG) && numberOfChildren == 1 && (NumOfEl == 1 || NumOfPos == 1)))
return PhotonConv;
356 if (numOfParents == 1 && std::abs(ancestorPDG) ==
MC::PIPLUS && numberOfChildren > 2 && NumOfNucFr != 0)
return ElMagProc;
365 if (ancestorPDG ==
MC::ELECTRON && numberOfChildren == 2 && NumOfEl == 2 && NumOfPos == 0)
return ElMagProc;
368 if (ancestorPDG ==
MC::POSITRON && numberOfChildren == 2 && NumOfEl == 0 && NumOfPos == 2)
return ElMagProc;
375 if (numberOfChildren == 2 && (NumOfEl == 1 || NumOfPos == 1) && !
MC::isElectron(ancestorPDG) && samePart)
return ElMagProc;
377 if ((ancestorPDG ==
MC::PI0 && numberOfChildren == 3 && NumOfPhot == 1 && NumOfEl == 1 && NumOfPos == 1) ||
378 (ancestorPDG ==
MC::PI0 && numberOfChildren == 4 && NumOfPhot == 0 && NumOfEl == 2 && NumOfPos == 2))
382 if (
MC::isSMQuark(ancestorPDG) && numOfParents == 1 && numberOfChildren == 3 && NumOfquark == 1 && NumOfElNeut == 1)
return QuarkWeakDec;
395 }
while (
MC::isW(ptrPart) && prodVert);
414 bool isZboson =
false;
415 bool isWboson =
false;
416 bool skipnext =
false;
418 for (
unsigned int ipOut = 0; ipOut + 1 < partProdVtx->
nOutgoingParticles(); ++ipOut) {
420 if (!aChild)
continue;
422 for (
unsigned int ipOut1 = ipOut + 1; ipOut1 < partProdVtx->
nOutgoingParticles(); ipOut1++) {
424 if (theNextChild)
break;
426 if (!theNextChild)
continue;
434 if (thePartToCheck == aChild || thePartToCheck == theNextChild) {
441 if (thePartToCheck == aChild || thePartToCheck == theNextChild) {
448 if (isWboson)
return WBoson;
449 if (isZboson)
return ZBoson;
451 if (numOfParents == 2) {
453 if ((numberOfChildren - NumOfquark - NumOfgluon) == 2 && NumOfEl == 1 && NumOfPos == 1)
return ZBoson;
456 if ((numberOfChildren - NumOfquark - NumOfgluon) == 2 && (NumOfEl == 1 || NumOfPos == 1) && NumOfElNeut == 1)
return WBoson;
461 if ((numberOfChildren - NumOfquark - NumOfgluon) == 4 &&
462 (NumOfEl + NumOfPos + NumOfMuPl + NumOfMuMin + NumOfTau + NumOfElNeut + NumOfMuNeut + NumOfTauNeut == 4) &&
466 if ((numberOfChildren - NumOfquark - NumOfgluon - NumOfPhot) == 6 &&
467 (NumOfEl + NumOfPos + NumOfMuPl + NumOfMuMin + NumOfTau + NumOfElNeut + NumOfMuNeut + NumOfTauNeut == 6) &&
471 if ((numberOfChildren - NumOfquark - NumOfgluon) == 8 &&
472 (NumOfEl + NumOfPos + NumOfMuPl + NumOfMuMin + NumOfTau + NumOfElNeut + NumOfMuNeut + NumOfTauNeut == 8) &&
480 if (partProdVtx == ancestorProdVtx) {
481 int NumOfEleLoop = 0;
482 int NumOfLepLoop = 0;
483 int NumOfEleNeuLoop = 0;
486 for (
const auto *
const pin: partProdVtx->
particles_in()) {
490 if (std::abs(pout->pdgId()) ==
MC::NU_E) NumOfEleNeuLoop++;
495 if (NumOfEleLoop == 2 && NumOfEleNeuLoop == 0)
return ZBoson;
496 if (NumOfEleLoop == 1 && NumOfEleNeuLoop == 1)
return WBoson;
497 if ((NumOfEleLoop == 4 && NumOfEleNeuLoop == 0) || (NumOfEleLoop == 3 && NumOfEleNeuLoop == 1) ||
498 (NumOfEleLoop == 2 && NumOfEleNeuLoop == 2))
return DiBoson;
499 if (NumOfLepLoop == 4)
return DiBoson;
552 info.setMotherProperties(ancestor);
565 if (ancestor == ancestorParent) {
break; }
567 ancestorParent = ancestor;
572 if (ancestorParent) {
573 pPDG = ancestorParent->
pdgId();
576 ancestor = ancestorParent;
585 ancestor = ancestorParent;
589 info.setMotherProperties(ancestor);
590 const int ancestorPDG = ancestor->
pdgId();
597 auto DP = DecayProducts(partProdVtx);
601 const int NumOfElNeut = DP.apd(
MC::NU_E);
602 const int NumOfMuNeut = DP.apd(
MC::NU_MU);
605 const int NumOfgluon = DP.apd(
MC::GLUON);
606 const int NumOfMuPl = DP.pd(-
MC::MUON);
607 const int NumOfMuMin = DP.pd(
MC::MUON);
608 const int NumOfTau = DP.apd(
MC::TAU);
612 if (std::abs(ancestorPDG) ==
MC::PIPLUS && numberOfChildren == 2 && NumOfMuNeut == 1)
return PionDecay;
613 if (std::abs(ancestorPDG) ==
MC::KPLUS && numberOfChildren == 2 && NumOfMuNeut == 1)
return KaonDecay;
622 if (
MC::isSMQuark(ancestorPDG) && numOfParents == 1 && numberOfChildren == 3 && NumOfquark == 1 && NumOfMuNeut == 1)
return QuarkWeakDec;
630 }
while (
MC::isW(itrP) && prodVert);
641 if (
MC::isPhoton(ancestorPDG) && numberOfChildren == 2 && NumOfMuMin == 1 && NumOfMuPl == 1)
return PhotonConv;
646 bool isZboson =
false;
647 bool isWboson =
false;
648 bool skipnext =
false;
649 for (
unsigned int ipOut = 0; ipOut + 1 < partProdVtx->
nOutgoingParticles(); ipOut++) {
655 if (!aChild)
continue;
657 for (
unsigned int ipOut1 = ipOut + 1; ipOut1 < partProdVtx->
nOutgoingParticles(); ipOut1++) {
659 if (theNextChild)
break;
661 if (!theNextChild)
continue;
664 if (thePriPart == aChild || thePriPart == theNextChild) {
671 if (thePriPart == aChild || thePriPart == theNextChild) {
678 if (isWboson)
return WBoson;
679 if (isZboson)
return ZBoson;
681 if (numOfParents == 2 ) {
683 if ((numberOfChildren - NumOfquark - NumOfgluon) == 2 && NumOfMuPl == 1 && NumOfMuMin == 1)
return ZBoson;
687 if ((numberOfChildren - NumOfquark - NumOfgluon) == 2 && (NumOfMuPl == 1 || NumOfMuMin == 1) && NumOfMuNeut == 1)
return WBoson;
692 if ((numberOfChildren - NumOfquark - NumOfgluon) == 4 &&
693 (NumOfEl + NumOfPos + NumOfMuPl + NumOfMuMin + NumOfTau + NumOfElNeut + NumOfMuNeut + NumOfTauNeut == 4) &&
697 if ((numberOfChildren - NumOfquark - NumOfgluon - NumOfPhot) == 6 &&
698 (NumOfEl + NumOfPos + NumOfMuPl + NumOfMuMin + NumOfTau + NumOfElNeut + NumOfMuNeut + NumOfTauNeut == 6) &&
702 if ((numberOfChildren - NumOfquark - NumOfgluon) == 8 &&
703 (NumOfEl + NumOfPos + NumOfMuPl + NumOfMuMin + NumOfTau + NumOfElNeut + NumOfMuNeut + NumOfTauNeut == 8) &&
713 if (partProdVtx == ancestorProdVtx) {
715 int NumOfMuNeuLoop = 0;
716 int NumOfLepLoop = 0;
723 if (std::abs(pout->pdg_id()) ==
MC::NU_MU) NumOfMuNeuLoop++;
729 if (NumOfMuLoop == 2 && NumOfMuNeuLoop == 0)
return ZBoson;
730 if (NumOfMuLoop == 1 && NumOfMuNeuLoop == 1)
return WBoson;
731 if ((NumOfMuLoop == 4 && NumOfMuNeuLoop == 0) || (NumOfMuLoop == 3 && NumOfMuNeuLoop == 1) ||
732 (NumOfMuLoop == 2 && NumOfMuNeuLoop == 2))
return DiBoson;
733 if (NumOfLepLoop == 4)
return DiBoson;
780 info.setMotherProperties(ancestor);
790 ancestor = ancestorParent;
794 const int ancestorPDG = ancestor->
pdgId();
795 info.setMotherProperties(ancestor);
802 auto DP = DecayProducts(partProdVtx);
803 const int numberOfChildren = DP.size();
807 const int NumOfElNeut = DP.apd(
MC::NU_E);
808 const int NumOfMuNeut = DP.apd(
MC::NU_MU);
811 const int NumOfgluon = DP.apd(
MC::GLUON);
812 const int NumOfMuPl = DP.pd(-
MC::MUON);
813 const int NumOfMuMin = DP.pd(
MC::MUON);
814 const int NumOfTau = DP.apd(
MC::TAU);
825 }
while (
MC::isW(itrP) && prodVert);
837 bool isZboson =
false;
838 bool isWboson =
false;
839 bool skipnext =
false;
840 for (
unsigned int ipOut = 0; ipOut + 1 < partProdVtx->
nOutgoingParticles(); ipOut++) {
846 if (!aChild)
continue;
848 for (
unsigned int ipOut1 = ipOut + 1; ipOut1 < partProdVtx->
nOutgoingParticles(); ipOut1++) {
850 if (theNextChild)
break;
857 if (thePriPart == aChild || thePriPart == theNextChild) {
864 if (thePriPart == aChild || thePriPart == theNextChild) {
871 if (isWboson)
return WBoson;
872 if (isZboson)
return ZBoson;
874 if (numOfParents == 2 ) {
881 if ((numberOfChildren - NumOfquark - NumOfgluon) == 2 && NumOfTau == 1 && NumOfTauNeut == 1)
return WBoson;
884 if ((numberOfChildren - NumOfquark - NumOfgluon) == 4 &&
885 (NumOfEl + NumOfPos + NumOfMuPl + NumOfMuMin + NumOfTau + NumOfElNeut + NumOfMuNeut + NumOfTauNeut == 4) &&
889 if ((numberOfChildren - NumOfquark - NumOfgluon - NumOfPhot) == 6 &&
890 (NumOfEl + NumOfPos + NumOfMuPl + NumOfMuMin + NumOfTau + NumOfElNeut + NumOfMuNeut + NumOfTauNeut == 6) &&
894 if ((numberOfChildren - NumOfquark - NumOfgluon) == 8 &&
895 (NumOfEl + NumOfPos + NumOfMuPl + NumOfMuMin + NumOfTau + NumOfElNeut + NumOfMuNeut + NumOfTauNeut == 8) &&
903 if (partProdVtx == ancestorProdVtx) {
904 int NumOfTauLoop = 0;
905 int NumOfTauNeuLoop = 0;
906 int NumOfLepLoop = 0;
907 for (
const auto *
const pout: partProdVtx->
particles_out()) {
909 for (
const auto *
const pin: partProdVtx->
particles_in()) {
913 if (std::abs(pout->pdgId()) ==
MC::NU_TAU) NumOfTauNeuLoop++;
918 if (NumOfTauLoop == 2 && NumOfTauNeuLoop == 0)
return ZBoson;
919 if (NumOfTauLoop == 1 && NumOfTauNeuLoop == 1)
return WBoson;
920 if ((NumOfTauLoop == 4 && NumOfTauNeuLoop == 0) || (NumOfTauLoop == 3 && NumOfTauNeuLoop == 1) || (NumOfTauLoop == 2 && NumOfTauNeuLoop == 2))
return DiBoson;
921 if (NumOfLepLoop == 4)
return DiBoson;
948 info.resetMotherProperties();
949 info.photonMother =
nullptr;
967 info.setMotherProperties(ancestor);
970 int ancestorPDG = ancestor->
pdgId();
980 auto DP = DecayProducts(partProdVtx);
983 const int NumOfMu = DP.apd(
MC::MUON);
984 const int NumOfTau = DP.apd(
MC::TAU);
986 const int NumOfLep = NumOfEl + NumOfPos + NumOfMu + NumOfTau;
997 childPDG = pout->pdg_id();
998 if (possibleNuclearFragment &&
1010 if (childPDG == ancestorPDG) {
1016 bool foundISR =
false;
1017 bool foundFSR =
false;
1019 if (numOfParents == 1 && numberOfChildren == 2 &&
MC::isElectron(ancestorPDG) && NumOfPht == 2)
return ElMagProc;
1033 PartPDG = std::abs(pin->pdgId());
1034 prodVert = pin->prodVtx();
1042 }
while (prodVert && std::abs(ancestorPDG) == PartPDG);
1052 if ((numOfParents == 1 && (
MC::isPhoton(ancestorPDG) ||
MC::isElectron(ancestorPDG)) && numberOfChildren > 2 && NumOfNucFr != 0) ||
1053 (numOfParents == 1 && std::abs(ancestorPDG) ==
MC::PIPLUS && numberOfChildren > 10 && NumOfNucFr != 0) ||
1058 if (
MC::isMuon(ancestorPDG) && NumOfMu == 0)
return Mu;
1068 if (!pout)
continue;
1069 if (ancestorPDG != pout->pdgId())
continue;
1071 if (!Vrtx)
continue;
1084 if (numOfParents == 2 && ((
MC::isElectron(ancestorPDG) && NumOfEl == 1 && NumOfPos == 1) || (
MC::isMuon(ancestorPDG) && NumOfMu == 2) || (
MC::isTau(ancestorPDG) && NumOfTau == 2))) {
1088 if (numOfParents == 2 && NumOfLep == 1 && NumOfNeut == 1 && (
MC::isElectron(ancestorPDG) || std::abs(ancestorPDG) ==
MC::NU_E))
return FSRPhot;
1091 if (
MC::isElectron(ancestorPDG) && numOfParents == 1 && numberOfChildren == 2 && (NumOfEl == 1 || NumOfPos == 1) && NumOfPht == 1 &&
1096 if (
MC::isZ(ancestorPDG) && ((NumOfEl + NumOfPos == 2 || NumOfEl + NumOfPos == 4) || (NumOfMu == 2 || NumOfMu == 4) || (NumOfTau == 2 || NumOfTau == 4)) && NumOfPht > 0)
return FSRPhot;
1100 if (numOfParents == 2 && NumOfLQ == 1)
return FSRPhot;
1107 if (NumOfLep == 1 && NumOfNeut == 1 && numberOfChildren == NumOfLep + NumOfNeut + NumOfPht)
return FSRPhot;
1115 }
while (
MC::isW(itrP) && prodVert);
1130 bool isZboson =
false;
1131 bool isWboson =
false;
1132 bool skipnext =
false;
1133 for (
unsigned int ipOut = 0; ipOut + 1 < partProdVtx->
nOutgoingParticles(); ipOut++) {
1139 if (!aChild)
continue;
1141 for (
unsigned int ipOut1 = ipOut + 1; ipOut1 < partProdVtx->
nOutgoingParticles(); ipOut1++) {
1143 if (theNextChild)
break;
1145 if (!theNextChild)
continue;
1148 if (thePriPart == aChild || thePriPart == theNextChild) {
1155 if (thePriPart == aChild || thePriPart == theNextChild) {
1162 if (isWboson)
return WBoson;
1163 if (isZboson)
return ZBoson;
1167 if (numOfParents == 4 && (numberOfChildren - NumOfPht) == 4 && (NumOfLep + NumOfNeut == 4)) {
1174 if (partProdVtx == ancestorProdVtx) {
1175 for (
const auto *
const pout: partProdVtx->
particles_out()) {
1176 if (!pout)
continue;
1177 for (
const auto *
const pin: partProdVtx->
particles_in()) {
1210 const int nuFlav = std::abs(thePart->
pdgId());
1225 info.setMotherProperties(ancestor);
1242 ancestorParent = ancestor;
1246 if (ancestorParent) {
1247 pPDG = ancestorParent->
pdgId();
1250 if (ancestor == ancestorParent) {
break; }
1254 ancestor = ancestorParent;
1255 info.setMotherProperties(ancestor);
1264 ancestor = ancestorParent;
1265 info.setMotherProperties(ancestor);
1271 info.setMotherProperties(ancestor);
1272 const int ancestorPDG = ancestor->
pdgId();
1273 partProdVtx = ancestor->
decayVtx();
1279 auto DP = DecayProducts(partProdVtx);
1282 const int NumOfgluon = DP.apd(
MC::GLUON);
1284 const int NumOfElNeut = DP.apd(
MC::NU_E);
1285 const int NumOfMuNeut = DP.apd(
MC::NU_MU);
1288 const int NumOfMu = DP.apd(
MC::MUON);
1289 const int NumOfTau = DP.apd(
MC::TAU);
1293 if (!aChild)
continue;
1302 if (
MC::isQuark(ancestorPDG) && numOfParents == 1 && numberOfChildren == 3 && NumOfquark == 1 && (NumOfEl == 1 || NumOfMu == 1 || NumOfTau == 1))
return QuarkWeakDec;
1311 }
while (
MC::isW(ptrPart) && prodVert);
1332 bool isZboson =
false;
1333 bool isWboson =
false;
1334 bool skipnext =
false;
1336 for (
unsigned int ipOut = 0; ipOut + 1 < partProdVtx->
nOutgoingParticles(); ++ipOut) {
1338 if (!aChild)
continue;
1340 for (
unsigned int ipOut1 = ipOut + 1; ipOut1 < partProdVtx->
nOutgoingParticles(); ipOut1++) {
1342 if (theNextChild)
break;
1344 if (!theNextChild)
continue;
1351 const int apdgID1 = std::abs(aChild->
pdgId());
1352 const int apdgID2 = std::abs(theNextChild->
pdgId());
1355 if (thePartToCheck == aChild || thePartToCheck == theNextChild) {
1368 if (thePartToCheck == aChild || thePartToCheck == theNextChild) {
1375 if (isWboson)
return WBoson;
1376 if (isZboson)
return ZBoson;
1379 if (numOfParents == 2) {
1381 if ( (numberOfChildren - NumOfquark - NumOfgluon) == 2 && (NumOfElNeut == 2 || NumOfMuNeut == 2 || NumOfTauNeut == 2))
return ZBoson;
1384 if ((numberOfChildren - NumOfquark - NumOfgluon) == 2 && ((NumOfEl == 1 && NumOfElNeut == 1) || (NumOfMu == 1 && NumOfMuNeut == 1) || (NumOfTau == 1 && NumOfTauNeut == 1)))
return WBoson;
1389 if ( (numberOfChildren - NumOfquark - NumOfgluon) == 4 && (NumOfEl + NumOfMu + NumOfTau + NumOfElNeut + NumOfMuNeut + NumOfTauNeut == 4) &&
1393 if ((numberOfChildren - NumOfquark - NumOfgluon - NumOfPhot) == 6 && (NumOfEl + NumOfMu + NumOfTau + NumOfElNeut + NumOfMuNeut + NumOfTauNeut == 6) &&
1398 if (partProdVtx == ancestorProdVtx) {
1399 int NumOfLepLoop = 0;
1400 int NumOfNeuLoop = 0;
1401 for (
const auto *
const pout: partProdVtx->
particles_out()) {
1402 if (!pout)
continue;
1403 for (
const auto *
const pin: partProdVtx->
particles_in()) {
1406 const int apdgid = std::abs(pout->pdgId());
1409 else { NumOfLepLoop++; }
1414 if (NumOfNeuLoop == 2 && NumOfLepLoop == 0)
return ZBoson;
1415 if (NumOfNeuLoop == 1 && NumOfLepLoop == 1)
return WBoson;
1416 if (NumOfNeuLoop + NumOfLepLoop == 4)
return DiBoson;
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_WARNING(x)
ElementLink implementation for ROOT usage.
bool isValid() const
Check if the element can be found.
a link optimized in size for a GenParticle in a McEventCollection
bool TruthLoopDetectionMethod3(const xAOD::TruthVertex *childOrigVtx, const xAOD::TruthParticle *parent) const
virtual std::pair< MCTruthPartClassifier::ParticleType, MCTruthPartClassifier::ParticleOrigin > particleHepMCTruthClassifier(const HepMcParticleLink &theLink, MCTruthPartClassifier::Info *info=nullptr) const override final
MCTruthPartClassifier::ParticleOrigin defOrigOfElectron(const xAOD::TruthParticleContainer &xTruthParticleContainer, const xAOD::TruthParticle *, bool &isPrompt, MCTruthPartClassifier::Info &info) const
SG::ReadHandleKey< xAODTruthParticleLinkVector > m_truthLinkVecReadHandleKey
bool TruthLoopDetectionMethod1(const xAOD::TruthVertex *childOrigVtx, const xAOD::TruthParticle *parent) const
MCTruthPartClassifier::ParticleOrigin defOrigOfNeutrino(const xAOD::TruthParticleContainer &xTruthParticleContainer, const xAOD::TruthParticle *, bool &isPrompt, MCTruthPartClassifier::Info &info) const
MCTruthPartClassifier::ParticleOrigin defOrigOfMuon(const xAOD::TruthParticleContainer &xTruthParticleContainer, const xAOD::TruthParticle *, bool &isPrompt, MCTruthPartClassifier::Info &info) const
MCTruthPartClassifier::ParticleOrigin defOrigOfPhoton(const xAOD::TruthParticleContainer &xTruthParticleContainer, const xAOD::TruthParticle *, bool &isPrompt, MCTruthPartClassifier::Info &info) const
virtual std::pair< MCTruthPartClassifier::ParticleType, MCTruthPartClassifier::ParticleOrigin > particleTruthClassifier(const xAOD::TruthParticle *, MCTruthPartClassifier::Info *info=nullptr) const override final
bool TruthLoopDetectionMethod2(const xAOD::TruthParticle *child, const xAOD::TruthParticle *parent) const
SG::ReadHandleKey< xAOD::TruthParticleContainer > m_truthParticleContainerKey
MCTruthPartClassifier::ParticleOrigin defOrigOfTau(const xAOD::TruthParticleContainer &xTruthParticleContainer, const xAOD::TruthParticle *, int motherPDG, MCTruthPartClassifier::Info &info) const
virtual bool isValid() override final
Can the handle be successfully dereferenced?
virtual const std::string & key() const override final
Return the StoreGate ID for the referenced object.
int status() const
Status code.
int pdgId() const
PDG ID code.
const TruthVertex_v1 * decayVtx() const
The decay vertex of this particle.
int pdg_id() const
PDG ID code.
bool hasProdVtx() const
Check for a production vertex on this particle.
const TruthVertex_v1 * prodVtx() const
The production vertex of this particle.
const TruthParticle_v1 * outgoingParticle(size_t index) const
Get one of the outgoing particles.
const TruthParticle_v1 * incomingParticle(size_t index) const
Get one of the incoming particles.
std::vector< const TruthParticle * > particles_out() const
Get the outgoing particles.
size_t nOutgoingParticles() const
Get the number of outgoing particles.
size_t nIncomingParticles() const
Get the number of incoming particles.
std::vector< const TruthParticle * > particles_in() const
Get the incoming particles.
bool is_same_generator_particle(const T1 &p1, const T2 &p2)
Method to establish if two particles in the GenEvent actually represent the same generated particle.
bool is_same_particle(const T1 &p1, const T2 &p2)
Method to establish if two particles in the GenEvent actually represent the same particle.
bool is_simulation_particle(const T &p)
Method to establish if a particle (or barcode) was created during the simulation (TODO update to be s...
bool is_same_vertex(const T1 &p1, const T2 &p2)
Method to establish if two particles in the GenEvent actually represent the same vertex.
ParticleOutCome defOutComeOfElectron(T thePart)
ParticleOutCome defOutComeOfPhoton(T thePart)
ParticleType defTypeOfPhoton(ParticleOrigin PhotOrig)
ParticleOrigin convHadronTypeToOrig(ParticleType pType, int motherPDG)
ParticleOutCome defOutComeOfTau(T thePart)
ParticleType defTypeOfTau(ParticleOrigin TauOrig)
ParticleType defTypeOfMuon(ParticleOrigin MuOrig, bool isPrompt)
ParticleType defTypeOfHadron(int pdg)
int isPrompt(const unsigned int classify, bool allow_prompt_tau_decays=true)
ParticleOutCome defOutComeOfMuon(T thePart)
ParticleType defTypeOfElectron(ParticleOrigin EleOrig, bool isPrompt)
bool isConditionA(const T &p)
To be understood.
T findMatching(C TruthContainer, T p)
Function to find a particle in container.
bool isNeutrinoRH(const T &p)
PDG Rule 12: APID: Helper function for right-handed neutrino states These are generator defined PDG I...
bool isHardScatteringVertex(T pVert)
Function to classify the vertex as hard scattering vertex.
bool isSMLepton(const T &p)
APID: the fourth generation leptons are not standard model leptons.
bool isPhoton(const T &p)
static const int RH_NU_TAU
bool isSMNeutrino(const T &p)
static const int WBOSON_LRSM
bool isNeutrino(const T &p)
APID: the fourth generation neutrinos are neutrinos.
bool isElectron(const T &p)
static const int ELECTRON
bool isStable(const T &p)
Identify if the particle is stable, i.e. has not decayed.
bool isSMQuark(const T &p)
static const int POSITRON
bool isMSSMHiggs(const T &p)
APID: Additional Higgs bosons for MSSM (Used in MCTruthClassifier).
bool isDecayed(const T &p)
Identify if the particle decayed.
bool isQuark(const T &p)
PDG rule 2: Quarks and leptons are numbered consecutively starting from 1 and 11 respectively; to do ...
T findMother(T thePart)
Function to get a mother of particle. MCTruthClassifier legacy.
bool isHiggs(const T &p)
APID: HIGGS boson is only one particle.
static const int LEPTOQUARK
bool isBeam(const T &p)
Identify if the particle is beam particle.
bool isHadron(const T &p)
bool isNucleus(const T &p)
PDG rule 16 Nuclear codes are given as 10-digit numbers ±10LZZZAAAI.
static const int RH_NU_MU
bool isHeavyBoson(const T &p)
APID: Additional "Heavy"/"prime" versions of W and Z bosons (Used in MCTruthClassifier).
bool isLeptoQuark(const T &p)
PDG rule 11c: “One-of-a-kind” exotic particles are assigned numbers in the range 41–80.
static const int RH_NU_E
PDG Rule 12: Generator defined PDG ID values for right handed neutrinos and corresponding W+ boson fr...
bool isPhysical(const T &p)
Identify if the particle is physical, i.e. is stable or decayed.
bool isBSM(const T &p)
APID: graviton and all Higgs extensions are BSM.
TruthVertex_v1 TruthVertex
Typedef to implementation.
TruthParticle_v1 TruthParticle
Typedef to implementation.
TruthParticleContainer_v1 TruthParticleContainer
Declare the latest version of the truth particle container.