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);
210 const int parentPDG =
parent->pdgId();
212 if (!aChild)
continue;
223 return TruthLoopDetectionMethod3(childOrigVtx, parent);
243 parent_prdVtx =
parent->hasProdVtx() ?
parent->prodVtx() :
nullptr;
244 parent_endVtx =
parent->decayVtx();
248 return (child_endVtx == parent_prdVtx && child_prdVtx == parent_endVtx);
275 info.setMotherProperties(ancestor);
279 bool samePart = TruthLoopDetectionMethod1(partProdVtx, ancestor);
291 if (ancestor == ancestorParent) {
break; }
292 if (TruthLoopDetectionMethod2(ancestor,ancestorParent)) {
293 ancestorParent = ancestor;
298 if (ancestorParent) {
299 pPDG = ancestorParent->
pdgId();
301 ancestor = ancestorParent;
310 ancestor = ancestorParent;
314 info.setMotherProperties(ancestor);
315 const int ancestorPDG = ancestor->
pdgId();
322 auto DP = DecayProducts(partProdVtx);
327 const int NumOfgluon = DP.apd(
MC::GLUON);
328 const int NumOfElNeut = DP.apd(
MC::NU_E);
330 const int NumOfMuPl = DP.pd(-
MC::MUON);
331 const int NumOfMuMin = DP.pd(
MC::MUON);
332 const int NumOfMuNeut = DP.apd(
MC::NU_MU);
333 const int NumOfTau = DP.apd(
MC::TAU);
340 if (!aChild)
continue;
341 const int childPDG = aChild->pdgId();
343 if (possibleNuclearFragment &&
352 for (
const auto& photonParent: ancestorProdVtx->
particles_in()) {
353 if (!photonParent)
continue;
354 info.photonMother = photonParent;
358 if ((
MC::isPhoton(ancestorPDG) && numberOfChildren == 2 && NumOfEl == 1 && NumOfPos == 1) || (
MC::isPhoton(ancestorPDG) && numberOfChildren == 1 && (NumOfEl == 1 || NumOfPos == 1)))
return PhotonConv;
363 if (numOfParents == 1 && std::abs(ancestorPDG) ==
MC::PIPLUS && numberOfChildren > 2 && NumOfNucFr != 0)
return ElMagProc;
372 if (ancestorPDG ==
MC::ELECTRON && numberOfChildren == 2 && NumOfEl == 2 && NumOfPos == 0)
return ElMagProc;
375 if (ancestorPDG ==
MC::POSITRON && numberOfChildren == 2 && NumOfEl == 0 && NumOfPos == 2)
return ElMagProc;
382 if (numberOfChildren == 2 && (NumOfEl == 1 || NumOfPos == 1) && !
MC::isElectron(ancestorPDG) && samePart)
return ElMagProc;
384 if ((ancestorPDG ==
MC::PI0 && numberOfChildren == 3 && NumOfPhot == 1 && NumOfEl == 1 && NumOfPos == 1) ||
385 (ancestorPDG ==
MC::PI0 && numberOfChildren == 4 && NumOfPhot == 0 && NumOfEl == 2 && NumOfPos == 2))
389 if (
MC::isSMQuark(ancestorPDG) && numOfParents == 1 && numberOfChildren == 3 && NumOfquark == 1 && NumOfElNeut == 1)
return QuarkWeakDec;
402 }
while (
MC::isW(ptrPart) && prodVert);
421 bool isZboson =
false;
422 bool isWboson =
false;
423 bool skipnext =
false;
425 for (
unsigned int ipOut = 0; ipOut + 1 < partProdVtx->
nOutgoingParticles(); ++ipOut) {
427 if (!aChild)
continue;
429 for (
unsigned int ipOut1 = ipOut + 1; ipOut1 < partProdVtx->
nOutgoingParticles(); ipOut1++) {
431 if (theNextChild)
break;
433 if (!theNextChild)
continue;
441 if (thePartToCheck == aChild || thePartToCheck == theNextChild) {
448 if (thePartToCheck == aChild || thePartToCheck == theNextChild) {
455 if (isWboson)
return WBoson;
456 if (isZboson)
return ZBoson;
458 if (numOfParents == 2) {
460 if ((numberOfChildren - NumOfquark - NumOfgluon) == 2 && NumOfEl == 1 && NumOfPos == 1)
return ZBoson;
463 if ((numberOfChildren - NumOfquark - NumOfgluon) == 2 && (NumOfEl == 1 || NumOfPos == 1) && NumOfElNeut == 1)
return WBoson;
468 if ((numberOfChildren - NumOfquark - NumOfgluon) == 4 &&
469 (NumOfEl + NumOfPos + NumOfMuPl + NumOfMuMin + NumOfTau + NumOfElNeut + NumOfMuNeut + NumOfTauNeut == 4) &&
473 if ((numberOfChildren - NumOfquark - NumOfgluon - NumOfPhot) == 6 &&
474 (NumOfEl + NumOfPos + NumOfMuPl + NumOfMuMin + NumOfTau + NumOfElNeut + NumOfMuNeut + NumOfTauNeut == 6) &&
478 if ((numberOfChildren - NumOfquark - NumOfgluon) == 8 &&
479 (NumOfEl + NumOfPos + NumOfMuPl + NumOfMuMin + NumOfTau + NumOfElNeut + NumOfMuNeut + NumOfTauNeut == 8) &&
486 if ((numberOfChildren - NumOfquark - NumOfgluon) >= 3 && NumOfPhot >= 1 && NumOfEl == 1 && NumOfPos == 1) {
490 if ((numberOfChildren - NumOfquark - NumOfgluon) >= 3 && NumOfPhot >= 1 && (NumOfEl == 1 || NumOfPos == 1) && NumOfElNeut == 1) {
497 if (partProdVtx == ancestorProdVtx) {
498 int NumOfEleLoop = 0;
499 int NumOfLepLoop = 0;
500 int NumOfEleNeuLoop = 0;
503 for (
const auto *
const pin: partProdVtx->
particles_in()) {
507 if (std::abs(pout->pdgId()) ==
MC::NU_E) NumOfEleNeuLoop++;
512 if (NumOfEleLoop == 2 && NumOfEleNeuLoop == 0)
return ZBoson;
513 if (NumOfEleLoop == 1 && NumOfEleNeuLoop == 1)
return WBoson;
514 if ((NumOfEleLoop == 4 && NumOfEleNeuLoop == 0) || (NumOfEleLoop == 3 && NumOfEleNeuLoop == 1) ||
515 (NumOfEleLoop == 2 && NumOfEleNeuLoop == 2))
return DiBoson;
516 if (NumOfLepLoop == 4)
return DiBoson;
569 info.setMotherProperties(ancestor);
582 if (ancestor == ancestorParent) {
break; }
583 if (TruthLoopDetectionMethod2(ancestor,ancestorParent)) {
584 ancestorParent = ancestor;
589 if (ancestorParent) {
590 pPDG = ancestorParent->
pdgId();
593 ancestor = ancestorParent;
602 ancestor = ancestorParent;
606 info.setMotherProperties(ancestor);
607 const int ancestorPDG = ancestor->
pdgId();
614 auto DP = DecayProducts(partProdVtx);
618 const int NumOfElNeut = DP.apd(
MC::NU_E);
619 const int NumOfMuNeut = DP.apd(
MC::NU_MU);
622 const int NumOfgluon = DP.apd(
MC::GLUON);
623 const int NumOfMuPl = DP.pd(-
MC::MUON);
624 const int NumOfMuMin = DP.pd(
MC::MUON);
625 const int NumOfTau = DP.apd(
MC::TAU);
629 if (std::abs(ancestorPDG) ==
MC::PIPLUS && numberOfChildren == 2 && NumOfMuNeut == 1)
return PionDecay;
630 if (std::abs(ancestorPDG) ==
MC::KPLUS && numberOfChildren == 2 && NumOfMuNeut == 1)
return KaonDecay;
639 if (
MC::isSMQuark(ancestorPDG) && numOfParents == 1 && numberOfChildren == 3 && NumOfquark == 1 && NumOfMuNeut == 1)
return QuarkWeakDec;
647 }
while (
MC::isW(itrP) && prodVert);
658 if (
MC::isPhoton(ancestorPDG) && numberOfChildren == 2 && NumOfMuMin == 1 && NumOfMuPl == 1)
return PhotonConv;
663 bool isZboson =
false;
664 bool isWboson =
false;
665 bool skipnext =
false;
666 for (
unsigned int ipOut = 0; ipOut + 1 < partProdVtx->
nOutgoingParticles(); ipOut++) {
672 if (!aChild)
continue;
674 for (
unsigned int ipOut1 = ipOut + 1; ipOut1 < partProdVtx->
nOutgoingParticles(); ipOut1++) {
676 if (theNextChild)
break;
678 if (!theNextChild)
continue;
681 if (thePriPart == aChild || thePriPart == theNextChild) {
688 if (thePriPart == aChild || thePriPart == theNextChild) {
695 if (isWboson)
return WBoson;
696 if (isZboson)
return ZBoson;
698 if (numOfParents == 2 ) {
700 if ((numberOfChildren - NumOfquark - NumOfgluon) == 2 && NumOfMuPl == 1 && NumOfMuMin == 1)
return ZBoson;
704 if ((numberOfChildren - NumOfquark - NumOfgluon) == 2 && (NumOfMuPl == 1 || NumOfMuMin == 1) && NumOfMuNeut == 1)
return WBoson;
709 if ((numberOfChildren - NumOfquark - NumOfgluon) == 4 &&
710 (NumOfEl + NumOfPos + NumOfMuPl + NumOfMuMin + NumOfTau + NumOfElNeut + NumOfMuNeut + NumOfTauNeut == 4) &&
714 if ((numberOfChildren - NumOfquark - NumOfgluon - NumOfPhot) == 6 &&
715 (NumOfEl + NumOfPos + NumOfMuPl + NumOfMuMin + NumOfTau + NumOfElNeut + NumOfMuNeut + NumOfTauNeut == 6) &&
719 if ((numberOfChildren - NumOfquark - NumOfgluon) == 8 &&
720 (NumOfEl + NumOfPos + NumOfMuPl + NumOfMuMin + NumOfTau + NumOfElNeut + NumOfMuNeut + NumOfTauNeut == 8) &&
727 if ((numberOfChildren - NumOfquark - NumOfgluon) >= 3 && NumOfPhot >= 1 && NumOfMuPl == 1 && NumOfMuMin == 1) {
731 if ((numberOfChildren - NumOfquark - NumOfgluon) >= 3 && NumOfPhot >= 1 && (NumOfMuPl == 1 || NumOfMuMin == 1) && NumOfMuNeut == 1) {
739 if (partProdVtx == ancestorProdVtx) {
741 int NumOfMuNeuLoop = 0;
742 int NumOfLepLoop = 0;
749 if (std::abs(pout->pdg_id()) ==
MC::NU_MU) NumOfMuNeuLoop++;
755 if (NumOfMuLoop == 2 && NumOfMuNeuLoop == 0)
return ZBoson;
756 if (NumOfMuLoop == 1 && NumOfMuNeuLoop == 1)
return WBoson;
757 if ((NumOfMuLoop == 4 && NumOfMuNeuLoop == 0) || (NumOfMuLoop == 3 && NumOfMuNeuLoop == 1) ||
758 (NumOfMuLoop == 2 && NumOfMuNeuLoop == 2))
return DiBoson;
759 if (NumOfLepLoop == 4)
return DiBoson;
806 info.setMotherProperties(ancestor);
816 ancestor = ancestorParent;
820 const int ancestorPDG = ancestor->
pdgId();
821 info.setMotherProperties(ancestor);
828 auto DP = DecayProducts(partProdVtx);
829 const int numberOfChildren = DP.size();
833 const int NumOfElNeut = DP.apd(
MC::NU_E);
834 const int NumOfMuNeut = DP.apd(
MC::NU_MU);
837 const int NumOfgluon = DP.apd(
MC::GLUON);
838 const int NumOfMuPl = DP.pd(-
MC::MUON);
839 const int NumOfMuMin = DP.pd(
MC::MUON);
840 const int NumOfTau = DP.apd(
MC::TAU);
851 }
while (
MC::isW(itrP) && prodVert);
863 bool isZboson =
false;
864 bool isWboson =
false;
865 bool skipnext =
false;
866 for (
unsigned int ipOut = 0; ipOut + 1 < partProdVtx->
nOutgoingParticles(); ipOut++) {
872 if (!aChild)
continue;
874 for (
unsigned int ipOut1 = ipOut + 1; ipOut1 < partProdVtx->
nOutgoingParticles(); ipOut1++) {
876 if (theNextChild)
break;
883 if (thePriPart == aChild || thePriPart == theNextChild) {
890 if (thePriPart == aChild || thePriPart == theNextChild) {
897 if (isWboson)
return WBoson;
898 if (isZboson)
return ZBoson;
900 if (numOfParents == 2 ) {
907 if ((numberOfChildren - NumOfquark - NumOfgluon) == 2 && NumOfTau == 1 && NumOfTauNeut == 1)
return WBoson;
910 if ((numberOfChildren - NumOfquark - NumOfgluon) == 4 &&
911 (NumOfEl + NumOfPos + NumOfMuPl + NumOfMuMin + NumOfTau + NumOfElNeut + NumOfMuNeut + NumOfTauNeut == 4) &&
915 if ((numberOfChildren - NumOfquark - NumOfgluon - NumOfPhot) == 6 &&
916 (NumOfEl + NumOfPos + NumOfMuPl + NumOfMuMin + NumOfTau + NumOfElNeut + NumOfMuNeut + NumOfTauNeut == 6) &&
920 if ((numberOfChildren - NumOfquark - NumOfgluon) == 8 &&
921 (NumOfEl + NumOfPos + NumOfMuPl + NumOfMuMin + NumOfTau + NumOfElNeut + NumOfMuNeut + NumOfTauNeut == 8) &&
928 if ((numberOfChildren - NumOfquark - NumOfgluon) >= 3 && NumOfPhot >= 1 && NumOfTau == 2) {
932 if ((numberOfChildren - NumOfquark - NumOfgluon) >= 3 && NumOfPhot >= 1 && NumOfTau == 1 && NumOfTauNeut == 1) {
939 if (partProdVtx == ancestorProdVtx) {
940 int NumOfTauLoop = 0;
941 int NumOfTauNeuLoop = 0;
942 int NumOfLepLoop = 0;
943 for (
const auto *
const pout: partProdVtx->
particles_out()) {
945 for (
const auto *
const pin: partProdVtx->
particles_in()) {
949 if (std::abs(pout->pdgId()) ==
MC::NU_TAU) NumOfTauNeuLoop++;
954 if (NumOfTauLoop == 2 && NumOfTauNeuLoop == 0)
return ZBoson;
955 if (NumOfTauLoop == 1 && NumOfTauNeuLoop == 1)
return WBoson;
956 if ((NumOfTauLoop == 4 && NumOfTauNeuLoop == 0) || (NumOfTauLoop == 3 && NumOfTauNeuLoop == 1) || (NumOfTauLoop == 2 && NumOfTauNeuLoop == 2))
return DiBoson;
957 if (NumOfLepLoop == 4)
return DiBoson;
984 info.resetMotherProperties();
985 info.photonMother =
nullptr;
1003 info.setMotherProperties(ancestor);
1006 int ancestorPDG = ancestor->
pdgId();
1010 partProdVtx = ancestor->
decayVtx();
1016 auto DP = DecayProducts(partProdVtx);
1019 const int NumOfMu = DP.apd(
MC::MUON);
1020 const int NumOfTau = DP.apd(
MC::TAU);
1022 const int NumOfLep = NumOfEl + NumOfPos + NumOfMu + NumOfTau;
1027 int NumOfPartons(0);
1032 if (!pout)
continue;
1033 childPDG = pout->pdg_id();
1034 if (possibleNuclearFragment &&
1046 if (childPDG == ancestorPDG) {
1052 bool foundISR =
false;
1053 bool foundFSR =
false;
1055 if (numOfParents == 1 && numberOfChildren == 2 &&
MC::isElectron(ancestorPDG) && NumOfPht == 2)
return ElMagProc;
1069 PartPDG = std::abs(pin->pdgId());
1070 prodVert = pin->prodVtx();
1078 }
while (prodVert && std::abs(ancestorPDG) == PartPDG);
1088 if ((numOfParents == 1 && (
MC::isPhoton(ancestorPDG) ||
MC::isElectron(ancestorPDG)) && numberOfChildren > 2 && NumOfNucFr != 0) ||
1089 (numOfParents == 1 && std::abs(ancestorPDG) ==
MC::PIPLUS && numberOfChildren > 10 && NumOfNucFr != 0) ||
1094 if (
MC::isMuon(ancestorPDG) && NumOfMu == 0)
return Mu;
1104 if (!pout)
continue;
1105 if (ancestorPDG != pout->pdgId())
continue;
1107 if (!Vrtx)
continue;
1120 if (numOfParents == 2 && ((
MC::isElectron(ancestorPDG) && NumOfEl == 1 && NumOfPos == 1) || (
MC::isMuon(ancestorPDG) && NumOfMu == 2) || (
MC::isTau(ancestorPDG) && NumOfTau == 2))) {
1124 if (numOfParents == 2 && NumOfLep == 1 && NumOfNeut == 1 && (
MC::isElectron(ancestorPDG) || std::abs(ancestorPDG) ==
MC::NU_E))
return FSRPhot;
1127 if (
MC::isElectron(ancestorPDG) && numOfParents == 1 && numberOfChildren == 2 && (NumOfEl == 1 || NumOfPos == 1) && NumOfPht == 1 &&
1132 if (
MC::isZ(ancestorPDG) && ((NumOfEl + NumOfPos == 2 || NumOfEl + NumOfPos == 4) || (NumOfMu == 2 || NumOfMu == 4) || (NumOfTau == 2 || NumOfTau == 4)) && NumOfPht > 0)
return FSRPhot;
1136 if (numOfParents == 2 && NumOfLQ == 1)
return FSRPhot;
1143 if (NumOfLep == 1 && NumOfNeut == 1 && numberOfChildren == NumOfLep + NumOfNeut + NumOfPht)
return FSRPhot;
1151 }
while (
MC::isW(itrP) && prodVert);
1166 bool isZboson =
false;
1167 bool isWboson =
false;
1168 bool skipnext =
false;
1169 for (
unsigned int ipOut = 0; ipOut + 1 < partProdVtx->
nOutgoingParticles(); ipOut++) {
1175 if (!aChild)
continue;
1177 for (
unsigned int ipOut1 = ipOut + 1; ipOut1 < partProdVtx->
nOutgoingParticles(); ipOut1++) {
1179 if (theNextChild)
break;
1181 if (!theNextChild)
continue;
1184 if (thePriPart == aChild || thePriPart == theNextChild) {
1191 if (thePriPart == aChild || thePriPart == theNextChild) {
1198 if (isWboson)
return WBoson;
1199 if (isZboson)
return ZBoson;
1203 if (numOfParents == 4 && (numberOfChildren - NumOfPht) == 4 && (NumOfLep + NumOfNeut == 4)) {
1210 if (partProdVtx == ancestorProdVtx) {
1211 for (
const auto *
const pout: partProdVtx->
particles_out()) {
1212 if (!pout)
continue;
1213 for (
const auto *
const pin: partProdVtx->
particles_in()) {
1246 const int nuFlav = std::abs(thePart->
pdgId());
1261 info.setMotherProperties(ancestor);
1266 bool samePart = TruthLoopDetectionMethod1(partProdVtx, ancestor);
1277 if (TruthLoopDetectionMethod2(ancestor,ancestorParent)) {
1278 ancestorParent = ancestor;
1282 if (ancestorParent) {
1283 pPDG = ancestorParent->
pdgId();
1286 if (ancestor == ancestorParent) {
break; }
1290 ancestor = ancestorParent;
1291 info.setMotherProperties(ancestor);
1300 ancestor = ancestorParent;
1301 info.setMotherProperties(ancestor);
1307 info.setMotherProperties(ancestor);
1308 const int ancestorPDG = ancestor->
pdgId();
1309 partProdVtx = ancestor->
decayVtx();
1315 auto DP = DecayProducts(partProdVtx);
1318 const int NumOfgluon = DP.apd(
MC::GLUON);
1320 const int NumOfElNeut = DP.apd(
MC::NU_E);
1321 const int NumOfMuNeut = DP.apd(
MC::NU_MU);
1324 const int NumOfMu = DP.apd(
MC::MUON);
1325 const int NumOfTau = DP.apd(
MC::TAU);
1329 if (!aChild)
continue;
1338 if (
MC::isQuark(ancestorPDG) && numOfParents == 1 && numberOfChildren == 3 && NumOfquark == 1 && (NumOfEl == 1 || NumOfMu == 1 || NumOfTau == 1))
return QuarkWeakDec;
1347 }
while (
MC::isW(ptrPart) && prodVert);
1368 bool isZboson =
false;
1369 bool isWboson =
false;
1370 bool skipnext =
false;
1372 for (
unsigned int ipOut = 0; ipOut + 1 < partProdVtx->
nOutgoingParticles(); ++ipOut) {
1374 if (!aChild)
continue;
1376 for (
unsigned int ipOut1 = ipOut + 1; ipOut1 < partProdVtx->
nOutgoingParticles(); ipOut1++) {
1378 if (theNextChild)
break;
1380 if (!theNextChild)
continue;
1387 const int apdgID1 = std::abs(aChild->
pdgId());
1388 const int apdgID2 = std::abs(theNextChild->
pdgId());
1391 if (thePartToCheck == aChild || thePartToCheck == theNextChild) {
1404 if (thePartToCheck == aChild || thePartToCheck == theNextChild) {
1411 if (isWboson)
return WBoson;
1412 if (isZboson)
return ZBoson;
1415 if (numOfParents == 2) {
1417 if ( (numberOfChildren - NumOfquark - NumOfgluon) == 2 && (NumOfElNeut == 2 || NumOfMuNeut == 2 || NumOfTauNeut == 2))
return ZBoson;
1420 if ((numberOfChildren - NumOfquark - NumOfgluon) == 2 && ((NumOfEl == 1 && NumOfElNeut == 1) || (NumOfMu == 1 && NumOfMuNeut == 1) || (NumOfTau == 1 && NumOfTauNeut == 1)))
return WBoson;
1425 if ( (numberOfChildren - NumOfquark - NumOfgluon) == 4 && (NumOfEl + NumOfMu + NumOfTau + NumOfElNeut + NumOfMuNeut + NumOfTauNeut == 4) &&
1429 if ((numberOfChildren - NumOfquark - NumOfgluon - NumOfPhot) == 6 && (NumOfEl + NumOfMu + NumOfTau + NumOfElNeut + NumOfMuNeut + NumOfTauNeut == 6) &&
1433 if ((numberOfChildren - NumOfquark - NumOfgluon) >= 3 && NumOfPhot >= 1 && (NumOfElNeut == 2 || NumOfMuNeut == 2 || NumOfTauNeut == 2)) {
1440 if (partProdVtx == ancestorProdVtx) {
1441 int NumOfLepLoop = 0;
1442 int NumOfNeuLoop = 0;
1443 for (
const auto *
const pout: partProdVtx->
particles_out()) {
1444 if (!pout)
continue;
1445 for (
const auto *
const pin: partProdVtx->
particles_in()) {
1448 const int apdgid = std::abs(pout->pdgId());
1451 else { NumOfLepLoop++; }
1456 if (NumOfNeuLoop == 2 && NumOfLepLoop == 0)
return ZBoson;
1457 if (NumOfNeuLoop == 1 && NumOfLepLoop == 1)
return WBoson;
1458 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
MCTruthPartClassifier::ParticleOrigin defOrigOfPhoton(const xAOD::TruthParticleContainer &xTruthParticleContainer, const xAOD::TruthParticle *, bool &isPrompt, IMCTruthClassifier::Info &info) const
virtual std::pair< MCTruthPartClassifier::ParticleType, MCTruthPartClassifier::ParticleOrigin > particleTruthClassifier(const xAOD::TruthParticle *, IMCTruthClassifier::Info *info) const override final
MCTruthPartClassifier::ParticleOrigin defOrigOfMuon(const xAOD::TruthParticleContainer &xTruthParticleContainer, const xAOD::TruthParticle *, bool &isPrompt, IMCTruthClassifier::Info &info) const
MCTruthPartClassifier::ParticleOrigin defOrigOfTau(const xAOD::TruthParticleContainer &xTruthParticleContainer, const xAOD::TruthParticle *, int motherPDG, IMCTruthClassifier::Info &info) const
MCTruthPartClassifier::ParticleOrigin defOrigOfElectron(const xAOD::TruthParticleContainer &xTruthParticleContainer, const xAOD::TruthParticle *, bool &isPrompt, IMCTruthClassifier::Info &info) const
namespace
SG::ReadHandleKey< xAODTruthParticleLinkVector > m_truthLinkVecReadHandleKey
virtual std::pair< MCTruthPartClassifier::ParticleType, MCTruthPartClassifier::ParticleOrigin > particleHepMCTruthClassifier(const HepMcParticleLink &theLink, IMCTruthClassifier::Info *info) const override final
MCTruthPartClassifier::ParticleOrigin defOrigOfNeutrino(const xAOD::TruthParticleContainer &xTruthParticleContainer, const xAOD::TruthParticle *, bool &isPrompt, IMCTruthClassifier::Info &info) const
SG::ReadHandleKey< xAOD::TruthParticleContainer > m_truthParticleContainerKey
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.