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 ");
100 for (
const auto& temp: partProdVtx->
particles_in()) {
if (temp) parent = temp;}
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_DEBUG(x,...)
#define ATH_MSG_WARNING(x,...)
#define ATH_MSG_VERBOSE(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 was created during the simulation (based on the status value).
bool is_same_vertex(const T1 &p1, const T2 &p2)
Method to establish if two vertices in the GenEvent actually represent the same vertex.
ParticleOutCome defOutComeOfElectron(T thePart)
Determine the outcome of a simulated electron from its end vertex (NonInteract, ElectrMagInter,...
ParticleOutCome defOutComeOfPhoton(T thePart)
Determine the outcome of a simulated photon from its end vertex (UnConverted, Converted,...
ParticleType defTypeOfPhoton(ParticleOrigin PhotOrig)
Classify a photon (Unknown/Iso/NonIso/Bkg) from its origin.
ParticleOrigin convHadronTypeToOrig(ParticleType pType, int motherPDG)
Convert a hadron ParticleType to a ParticleOrigin (JPsi if a c-cbar meson has a J/psi mother).
ParticleOutCome defOutComeOfTau(T thePart)
Determine the outcome of a simulated tau from its decay products (NonInteract, NuclInteraction,...
ParticleType defTypeOfTau(ParticleOrigin TauOrig)
Classify a tau (Unknown/Iso/NonIso/Bkg) from its origin.
ParticleType defTypeOfMuon(ParticleOrigin MuOrig, bool isPrompt)
Classify a muon (Unknown/Iso/NonIso/Bkg) from its origin; prompt muons are always Iso.
ParticleType defTypeOfHadron(int pdg)
Classify a hadron by PDG ID into a ParticleType (Unknown if none applies).
int isPrompt(const unsigned int classify, bool allow_prompt_tau_decays=true)
Tell whether a particle is prompt, from the word returned by defOrigOfParticle().
ParticleOutCome defOutComeOfMuon(T thePart)
Determine the outcome of a simulated muon from its end vertex (NonInteract, DecaytoElectron,...
ParticleType defTypeOfElectron(ParticleOrigin EleOrig, bool isPrompt)
Classify an electron (Unknown/Iso/NonIso/Bkg) from its origin; prompt electrons are always Iso.
bool isConditionA(const T &p)
Match selected Pythia status codes for hardest-subprocess and later-stage particles: 21: incoming par...
T findMatching(C TruthContainer, T p)
Function to find in the container the particle that p descends from in the simulation (see HepMC::is_...
bool isNeutrinoRH(const T &p)
PDG rule 12: Occasionally program authors add their own states.
static const int DQUARK
PDG Rule 1: Particles are given positive numbers, antiparticles negative numbers.
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: Occasionally program authors add their own states.
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.