25 std::pair<ParticleType, ParticleOrigin>
28 const EventContext& ctx =
info ?
info->eventContext : Gaudi::Hive::currentContext();
30 if (!truthParticleLinkVecReadHandle.
isValid()) {
31 ATH_MSG_WARNING(
" Invalid ReadHandle for xAODTruthParticleLinkVector with key: " << truthParticleLinkVecReadHandle.
key());
36 return particleTruthClassifier (*tplink,
info);
41 std::pair<ParticleType, ParticleOrigin>
46 if (!theGenPart)
return std::make_pair(partType, partOrig);
49 const EventContext& ctx =
info ?
info->eventContext : Gaudi::Hive::currentContext();
52 if (!truthParticleLinkVecReadHandle.
isValid()) {
53 ATH_MSG_WARNING(
" Invalid ReadHandle for xAODTruthParticleLinkVector with key: " << truthParticleLinkVecReadHandle.
key());
54 return std::make_pair(partType, partOrig);
56 for (
const auto *
const entry : *truthParticleLinkVecReadHandle) {
59 if (!theGenPart || !truthParticle ||
61 theGenPart->status() != truthParticle->
status() ||
64 "HepMC::GenParticle and xAOD::TruthParticle do not match");
65 return std::make_pair(partType, partOrig);
67 return particleTruthClassifier(truthParticle,
info);
70 return std::make_pair(partType, partOrig);
74 std::pair<ParticleType, ParticleOrigin>
82 return std::make_pair(partType, partOrig);
85 const EventContext& ctx =
info ?
info->eventContext : Gaudi::Hive::currentContext();
88 info->genPart = thePart;
92 if (!truthParticleContainerReadHandle.
isValid()) {
93 ATH_MSG_WARNING(
" Invalid ReadHandle for xAOD::TruthParticleContainer with key: " << truthParticleContainerReadHandle.
key());
94 return std::make_pair(partType, partOrig);
97 ATH_MSG_DEBUG(
"xAODTruthParticleContainer with key " << truthParticleContainerReadHandle.
key() <<
" has valid ReadHandle ");
108 if (endVert !=
nullptr) {
126 if (abs(thePart->
pdg_id()) > 1000000000)
return std::make_pair(
NuclFrag, partOrig);
134 if (partOriVert !=
nullptr) {
137 int motherPDG = theMoth?theMoth->pdg_id():0;
138 info->setMotherProperties(theMoth);
146 partOrig = defOrigOfElectron(truthParticleContainerReadHandle.
ptr(), thePart,
isPrompt,
info);
152 partOrig = defOrigOfMuon(truthParticleContainerReadHandle.
ptr(), thePart,
isPrompt,
info);
155 if (!partOriVert &&
MC::isTau(thePart)) {
157 partOrig = defOrigOfTau(truthParticleContainerReadHandle.
ptr(), thePart, motherPDG,
info);
163 partOrig = defOrigOfPhoton(truthParticleContainerReadHandle.
ptr(), thePart,
isPrompt,
info);
169 return std::make_pair(
Neutrino, partOrig);
175 if (isPartHadr)
return std::make_pair(
Hadron, partOrig);
201 partOrig = defOrigOfElectron(truthParticleContainerReadHandle.
ptr(), thePart,
isPrompt,
info);
205 partOrig = defOrigOfMuon(truthParticleContainerReadHandle.
ptr(), thePart,
isPrompt,
info);
208 partOrig = defOrigOfTau(truthParticleContainerReadHandle.
ptr(), thePart, motherPDG,
info);
212 partOrig = defOrigOfPhoton(truthParticleContainerReadHandle.
ptr(), thePart,
isPrompt,
info);
216 partOrig = defOrigOfNeutrino(truthParticleContainerReadHandle.
ptr(), thePart,
isPrompt,
info);
221 return std::make_pair(partType, partOrig);
247 int numOfParents = -1;
249 if (numOfParents > 1)
ATH_MSG_DEBUG(
"DefOrigOfElectron:: electron has more than one mother ");
252 if (
info)
info->setMotherProperties(mother);
256 int motherPDG = mother->
pdgId();
257 if (
info)
info->setMotherProperties(mother);
260 bool samePart =
false;
262 if (!theDaug)
continue;
287 parent_endVtx = MotherParent->
decayVtx();
289 if (mother_endVtx == parent_prdVtx && mother_prdVtx == parent_endVtx) {
290 MotherParent = mother;
294 if (MotherParent) pPDG = MotherParent->
pdgId();
296 if (mother == MotherParent)
break;
303 abs(pPDG) == 9900024 || abs(pPDG) == 9900012 || abs(pPDG) == 9900014 || abs(pPDG) == 9900016 ||
304 (abs(pPDG) < 2000040 && abs(pPDG) > 1000001))
305 mother = MotherParent;
308 motherPDG = mother->
pdgId();
314 if (
info)
info->setMotherProperties(mother);
332 if (!theDaug)
continue;
333 int DaugType = theDaug->pdgId();
336 else if (abs(DaugType) == MC::NU_E) NumOfElNeut++;
337 else if (abs(DaugType) == MC::NU_MU) NumOfMuNeut++;
339 else if (DaugType == MC::ELECTRON) NumOfEl++;
340 else if (DaugType == MC::POSITRON) NumOfPos++;
341 else if (DaugType == MC::MUON) NumOfMuMin++;
342 else if (DaugType == -MC::MUON) NumOfMuPl++;
343 else if (
MC::isTau(DaugType)) NumOfTau++;
344 else if (abs(DaugType) == MC::NU_TAU) NumOfTauNeut++;
347 if (numOfParents == 1 &&
349 (DaugType > 1000000000 || DaugType == 0 || DaugType == MC::PROTON || DaugType == MC::NEUTRON ||
350 abs(DaugType) == MC::PIPLUS || abs(DaugType) == MC::PI0))
354 if (
MC::isPhoton(motherPDG) && mothOriVert !=
nullptr) {
355 for (
const auto& theMother: mothOriVert->
particles_in()) {
356 if (!theMother)
continue;
358 info->photonMother = theMother;
362 if ((
MC::isPhoton(motherPDG) && numOfDaug == 2 && NumOfEl == 1 && NumOfPos == 1) || (
MC::isPhoton(motherPDG) && numOfDaug == 1 && (NumOfEl == 1 || NumOfPos == 1)))
return PhotonConv;
367 if (numOfParents == 1 && abs(motherPDG) == MC::PIPLUS && numOfDaug > 2 && NumOfNucFr != 0)
return ElMagProc;
376 if (motherPDG == MC::ELECTRON && numOfDaug == 2 && NumOfEl == 2 && NumOfPos == 0)
return ElMagProc;
379 if (motherPDG == MC::POSITRON && numOfDaug == 2 && NumOfEl == 0 && NumOfPos == 2)
return ElMagProc;
386 if (numOfDaug == 2 && (NumOfEl == 1 || NumOfPos == 1) && !
MC::isElectron(motherPDG) && samePart)
return ElMagProc;
388 if ((motherPDG == MC::PI0 && numOfDaug == 3 && NumOfPhot == 1 && NumOfEl == 1 && NumOfPos == 1) ||
389 (motherPDG == MC::PI0 && numOfDaug == 4 && NumOfPhot == 0 && NumOfEl == 2 && NumOfPos == 2))
393 if (
MC::isSMQuark(motherPDG) && numOfParents == 1 && numOfDaug == 3 && NumOfquark == 1 && NumOfElNeut == 1)
return QuarkWeakDec;
406 }
while (
MC::isW(ptrPart) && prodVert !=
nullptr);
409 if (abs(ptrPart->
pdgId()) == 9900012)
return NuREle;
410 if (abs(ptrPart->
pdgId()) == 9900014)
return NuRMu;
411 if (abs(ptrPart->
pdgId()) == 9900016)
return NuRTau;
425 bool isZboson =
false;
426 bool isWboson =
false;
427 bool skipnext =
false;
429 for (
unsigned int ipOut = 0; ipOut + 1 < partOriVert->
nOutgoingParticles(); ++ipOut) {
431 if (!theDaug)
continue;
433 for (
unsigned int ipOut1 = ipOut + 1; ipOut1 < partOriVert->
nOutgoingParticles(); ipOut1++) {
435 if (theNextDaug !=
nullptr)
break;
437 if (!theNextDaug)
continue;
445 if (thePartToCheck == theDaug || thePartToCheck == theNextDaug) {
452 if (thePartToCheck == theDaug || thePartToCheck == theNextDaug) {
459 if (isWboson)
return WBoson;
460 if (isZboson)
return ZBoson;
462 if (numOfParents == 2) {
466 if ((numOfDaug - NumOfquark - NumOfgluon) == 2 && NumOfEl == 1 && NumOfPos == 1)
return ZBoson;
469 if ((numOfDaug - NumOfquark - NumOfgluon) == 2 && (NumOfEl == 1 || NumOfPos == 1) && NumOfElNeut == 1)
return WBoson;
472 if ((numOfDaug - NumOfquark - NumOfgluon) == 4 && (NumOfEl + NumOfPos + NumOfMuPl + NumOfMuMin + NumOfTau + NumOfElNeut + NumOfMuNeut + NumOfTauNeut == 4) &&
476 if ((numOfDaug - NumOfquark - NumOfgluon - NumOfPhot) == 6 && (NumOfEl + NumOfPos + NumOfMuPl + NumOfMuMin + NumOfTau + NumOfElNeut + NumOfMuNeut + NumOfTauNeut == 6) &&
481 if (partOriVert == mothOriVert && partOriVert !=
nullptr) {
482 int NumOfEleLoop = 0;
483 int NumOfLepLoop = 0;
484 int NumOfEleNeuLoop = 0;
487 for (
const auto *
const pin: partOriVert->
particles_in()) {
491 if (std::abs(pin->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))
500 if (NumOfLepLoop == 4)
return DiBoson;
518 if (abs(motherPDG) == 9900024)
return WBosonLRSM;
519 if (abs(motherPDG) == 9900012)
return NuREle;
520 if (abs(motherPDG) == 9900014)
return NuRMu;
521 if (abs(motherPDG) == 9900016)
return NuRTau;
553 if (numOfParents > 1)
ATH_MSG_DEBUG(
"DefOrigOfMuon:: muon has more than one mother ");
556 if (
info)
info->setMotherProperties(mother);
562 int motherPDG = mother->
pdgId();
564 if ((
MC::isTau(motherPDG)||
MC::isW(motherPDG)) && mothOriVert !=
nullptr) {
582 parent_endVtx = MotherParent->
decayVtx();
585 if (mother_endVtx == parent_prdVtx && mother_prdVtx == parent_endVtx) {
586 MotherParent = mother;
591 if (mother == MotherParent) {
596 pPDG = MotherParent->
pdgId();
598 mother = MotherParent;
599 if (
info)
info->setMotherProperties(mother);
606 abs(pPDG) == 9900024 || abs(pPDG) == 9900012 || abs(pPDG) == 9900014 || abs(pPDG) == 9900016 ||
607 (abs(pPDG) < 2000040 && abs(pPDG) > 1000001)) {
608 if (
info)
info->setMotherProperties(mother);
612 motherPDG = mother->
pdgId();
618 if (
info)
info->setMotherProperties(mother);
619 auto DP = DecayProducts(partOriVert);
620 const int NumOfPhot = DP.pd(MC::PHOTON);
621 const int NumOfEl = DP.pd(MC::ELECTRON);
622 const int NumOfPos = DP.pd(MC::POSITRON);
623 const int NumOfElNeut = DP.apd(MC::NU_E);
624 const int NumOfMuNeut = DP.apd(MC::NU_MU);
625 const int NumOfLQ = DP.apd(MC::LEPTOQUARK);
626 const int NumOfquark = DP.apd({MC::DQUARK,MC::UQUARK,MC::SQUARK,MC::CQUARK,MC::BQUARK,MC::TQUARK});
627 const int NumOfgluon = DP.apd(MC::GLUON);
628 const int NumOfMuPl = DP.pd(-MC::MUON);
629 const int NumOfMuMin = DP.pd(MC::MUON);
630 const int NumOfTau = DP.apd(MC::TAU);
631 const int NumOfTauNeut = DP.apd(MC::NU_TAU);
632 if (std::abs(motherPDG) == MC::PIPLUS && numOfDaug == 2 && NumOfMuNeut == 1)
return PionDecay;
633 if (std::abs(motherPDG) == MC::KPLUS && numOfDaug == 2 && NumOfMuNeut == 1)
return KaonDecay;
642 if (
MC::isSMQuark(motherPDG) && numOfParents == 1 && numOfDaug == 3 && NumOfquark == 1 && NumOfMuNeut == 1)
return QuarkWeakDec;
650 }
while (
MC::isW(itrP) && prodVert !=
nullptr);
654 if (abs(itrP->
pdgId()) == 9900014)
return NuRMu;
667 bool isZboson =
false;
668 bool isWboson =
false;
669 bool skipnext =
false;
670 for (
unsigned int ipOut = 0; ipOut + 1 < partOriVert->
nOutgoingParticles(); ipOut++) {
676 if (!theDaug)
continue;
678 for (
unsigned int ipOut1 = ipOut + 1; ipOut1 < partOriVert->
nOutgoingParticles(); ipOut1++) {
680 if (theNextDaug !=
nullptr)
break;
682 if (!theNextDaug)
continue;
685 if (thePriPart == theDaug || thePriPart == theNextDaug) {
690 }
else if (
MC::isMuon(theDaug) && abs(theNextDaug->
pdgId()) == MC::NU_MU) {
692 if (thePriPart == theDaug || thePriPart == theNextDaug) {
699 if (isWboson)
return WBoson;
700 if (isZboson)
return ZBoson;
702 if (numOfParents == 2 ) {
706 if ((numOfDaug - NumOfquark - NumOfgluon) == 2 && NumOfMuPl == 1 && NumOfMuMin == 1)
return ZBoson;
710 if ((numOfDaug - NumOfquark - NumOfgluon) == 2 && (NumOfMuPl == 1 || NumOfMuMin == 1) && NumOfMuNeut == 1)
return WBoson;
713 if ((numOfDaug - NumOfquark - NumOfgluon) == 4 &&
714 (NumOfEl + NumOfPos + NumOfMuPl + NumOfMuMin + NumOfTau + NumOfElNeut + NumOfMuNeut + NumOfTauNeut == 4) &&
718 if ((numOfDaug - NumOfquark - NumOfgluon - NumOfPhot) == 6 &&
719 (NumOfEl + NumOfPos + NumOfMuPl + NumOfMuMin + NumOfTau + NumOfElNeut + NumOfMuNeut + NumOfTauNeut == 6) &&
724 if (partOriVert == mothOriVert) {
726 int NumOfMuNeuLoop = 0;
727 int NumOfLepLoop = 0;
734 if (std::abs(
pout->pdg_id()) == MC::NU_MU) NumOfMuNeuLoop++;
739 if (NumOfMuLoop == 2 && NumOfMuNeuLoop == 0)
return ZBoson;
740 if (NumOfMuLoop == 1 && NumOfMuNeuLoop == 1)
return WBoson;
741 if ((NumOfMuLoop == 4 && NumOfMuNeuLoop == 0) || (NumOfMuLoop == 3 && NumOfMuNeuLoop == 1) || (NumOfMuLoop == 2 && NumOfMuNeuLoop == 2))
return DiBoson;
742 if (NumOfLepLoop == 4)
return DiBoson;
753 if (abs(motherPDG) == 9900024)
return WBosonLRSM;
754 if (abs(motherPDG) == 9900012)
return NuREle;
755 if (abs(motherPDG) == 9900014)
return NuRMu;
756 if (abs(motherPDG) == 9900016)
return NuRTau;
788 if (numOfParents > 1)
ATH_MSG_DEBUG(
"DefOrigOfTau:: tau has more than one mother ");
791 if (
info)
info->setMotherProperties(mother);
800 if (
MC::isW(motherPDG) && mothOriVert !=
nullptr) {
805 pPDG = MotherParent->
pdgId();
807 mother = MotherParent;
808 if (
info)
info->setMotherProperties(mother);
813 motherPDG = mother->
pdgId();
814 if (
info)
info->setMotherProperties(mother);
820 auto DP = DecayProducts(partOriVert);
821 const int numOfDaug = DP.size();
822 const int NumOfPhot = DP.pd(MC::PHOTON);
823 const int NumOfEl = DP.pd(MC::ELECTRON);
824 const int NumOfPos = DP.pd(MC::POSITRON);
825 const int NumOfElNeut = DP.apd(MC::NU_E);
826 const int NumOfMuNeut = DP.apd(MC::NU_MU);
828 const int NumOfquark = DP.apd({MC::DQUARK,MC::UQUARK,MC::SQUARK,MC::CQUARK,MC::BQUARK,MC::TQUARK});
829 const int NumOfgluon = DP.apd(MC::GLUON);
830 const int NumOfMuPl = DP.pd(-MC::MUON);
831 const int NumOfMuMin = DP.pd(MC::MUON);
832 const int NumOfTau = DP.apd(MC::TAU);
833 const int NumOfTauNeut = DP.apd(MC::NU_TAU);
842 }
while (
MC::isW(itrP) && prodVert !=
nullptr);
846 if (abs(itrP->
pdgId()) == 9900014)
return NuRMu;
854 bool isZboson =
false;
855 bool isWboson =
false;
856 bool skipnext =
false;
857 for (
unsigned int ipOut = 0; ipOut + 1 < partOriVert->
nOutgoingParticles(); ipOut++) {
863 if (!theDaug)
continue;
865 for (
unsigned int ipOut1 = ipOut + 1; ipOut1 < partOriVert->
nOutgoingParticles(); ipOut1++) {
867 if (theNextDaug !=
nullptr)
break;
874 if (thePriPart == theDaug || thePriPart == theNextDaug) {
879 }
else if (
MC::isTau(theDaug) && abs(theNextDaug->
pdgId()) == MC::NU_TAU) {
881 if (thePriPart == theDaug || thePriPart == theNextDaug) {
888 if (isWboson)
return WBoson;
889 if (isZboson)
return ZBoson;
891 if (numOfParents == 2 ) {
898 if ((numOfDaug - NumOfquark - NumOfgluon) == 2 && NumOfTau == 1 && NumOfTauNeut == 1)
return WBoson;
901 if ((numOfDaug - NumOfquark - NumOfgluon) == 4 &&
902 (NumOfEl + NumOfPos + NumOfMuPl + NumOfMuMin + NumOfTau + NumOfElNeut + NumOfMuNeut + NumOfTauNeut == 4) &&
906 if ((numOfDaug - NumOfquark - NumOfgluon - NumOfPhot) == 6 &&
907 (NumOfEl + NumOfPos + NumOfMuPl + NumOfMuMin + NumOfTau + NumOfElNeut + NumOfMuNeut + NumOfTauNeut == 6) &&
911 if (partOriVert == mothOriVert) {
912 int NumOfTauLoop = 0;
913 int NumOfTauNeuLoop = 0;
914 int NumOfLepLoop = 0;
917 for (
const auto *
const pin: partOriVert->
particles_in()) {
921 if (std::abs(
pout->pdgId()) == MC::NU_TAU) NumOfTauNeuLoop++;
925 if (NumOfTauLoop == 2 && NumOfTauNeuLoop == 0)
return ZBoson;
926 if (NumOfTauLoop == 1 && NumOfTauNeuLoop == 1)
return WBoson;
927 if ((NumOfTauLoop == 4 && NumOfTauNeuLoop == 0) || (NumOfTauLoop == 3 && NumOfTauNeuLoop == 1) || (NumOfTauLoop == 2 && NumOfTauNeuLoop == 2))
return DiBoson;
928 if (NumOfLepLoop == 4)
return DiBoson;
934 if (abs(motherPDG) == 9900024)
return WBosonLRSM;
935 if (abs(motherPDG) == 9900016)
return NuRTau;
938 if (abs(motherPDG) == MC::JPSI)
return JPsi;
957 info->resetMotherProperties();
958 info->photonMother =
nullptr;
976 if (
info)
info->setMotherProperties(mother);
978 int motherPDG = mother->
pdgId();
980 if (
info)
info->setMotherProperties(mother);
994 long NumOfPartons(0);
998 DaugType =
pout->pdg_id();
1000 (DaugType > 1000000000 || DaugType == 0 || DaugType == MC::PROTON || DaugType == MC::NEUTRON))
1002 if (DaugType == MC::PHOTON) NumOfPht++;
1003 else if (DaugType == MC::ELECTRON) NumOfEl++;
1004 else if (DaugType == MC::POSITRON) NumOfPos++;
1006 else if (
MC::isTau(DaugType)) NumOfTau++;
1009 else if (abs(DaugType) == MC::NU_E || abs(DaugType) == MC::NU_MU || abs(DaugType) == MC::NU_TAU) NumOfNeut++;
1010 if (abs(DaugType) < MC::ELECTRON || (abs(DaugType) > MC::NU_TAU && abs(DaugType) < 43 && !
MC::isPhoton(DaugType))) NumOfPartons++;
1011 if (DaugType == motherPDG) {
1016 bool foundISR =
false;
1017 bool foundFSR =
false;
1033 PartPDG = abs(pin->pdgId());
1034 prodVert = pin->prodVtx();
1042 }
while (prodVert !=
nullptr && abs(motherPDG) == PartPDG);
1053 (numOfParents == 1 && abs(motherPDG) == MC::PIPLUS && numOfDaug > 10 && NumOfNucFr != 0) ||
1055 (numOfParents == 1 && motherPDG > 1000000000))
1068 if (!
pout)
continue;
1069 if (motherPDG !=
pout->pdgId())
continue;
1071 if (!Vrtx)
continue;
1084 if (numOfParents == 2 && ((
MC::isElectron(motherPDG) && NumOfEl == 1 && NumOfPos == 1) || (
MC::isMuon(motherPDG) && NumOfMu == 2) || (
MC::isTau(motherPDG) && NumOfTau == 2))) {
1088 if (numOfParents == 2 && NumOfLep == 1 && NumOfNeut == 1 && (
MC::isElectron(motherPDG) || abs(motherPDG) == MC::NU_E))
return FSRPhot;
1091 if (
MC::isElectron(motherPDG) && numOfParents == 1 && numOfDaug == 2 && (NumOfEl == 1 || NumOfPos == 1) && NumOfPht == 1 &&
1096 if (
MC::isZ(motherPDG) && ((NumOfEl + NumOfPos == 2 || NumOfEl + NumOfPos == 4) || (NumOfMu == 2 || NumOfMu == 4) || (NumOfTau == 2 || NumOfTau == 4)) && NumOfPht > 0)
return FSRPhot;
1098 if (NumOfPht > 0 && (abs(motherPDG) == 9900024 || abs(motherPDG) == 9900012 || abs(motherPDG) == 9900014 || abs(motherPDG) == 9900016))
return FSRPhot;
1100 if (numOfParents == 2 && NumOfLQ == 1)
return FSRPhot;
1107 if (NumOfLep == 1 && NumOfNeut == 1 && numOfDaug == NumOfLep + NumOfNeut + NumOfPht)
return FSRPhot;
1115 }
while (
MC::isW(itrP) && prodVert !=
nullptr);
1120 if ( abs(itrP->
pdgId()) == 9900012)
return NuREle;
1121 if ( abs(itrP->
pdgId()) == 9900014)
return NuRMu;
1122 if ( abs(itrP->
pdgId()) == 9900016)
return NuRTau;
1130 bool isZboson =
false;
1131 bool isWboson =
false;
1132 bool skipnext =
false;
1133 for (
unsigned int ipOut = 0; ipOut + 1 < partOriVert->
nOutgoingParticles(); ipOut++) {
1139 if (!theDaug)
continue;
1141 for (
unsigned int ipOut1 = ipOut + 1; ipOut1 < partOriVert->
nOutgoingParticles(); ipOut1++) {
1143 if (theNextDaug !=
nullptr)
break;
1145 if (!theNextDaug)
continue;
1148 if (thePriPart == theDaug || thePriPart == theNextDaug) {
1153 }
else if (
MC::isTau(theDaug) && abs(theNextDaug->
pdgId()) == MC::NU_TAU) {
1155 if (thePriPart == theDaug || thePriPart == theNextDaug) {
1162 if (isWboson)
return WBoson;
1163 if (isZboson)
return ZBoson;
1167 if (numOfParents == 4 && (numOfDaug - NumOfPht) == 4 && (NumOfLep + NumOfNeut == 4)) {
1174 if (partOriVert == mothOriVert && partOriVert !=
nullptr) {
1175 int NumOfPhtLoop = 0;
1177 if (!
pout)
continue;
1178 for (
const auto *
const pin: partOriVert->
particles_in()) {
1187 if (abs(motherPDG) == MC::PI0)
return PiZero;
1211 const int nuFlav = abs(thePart->
pdgId());
1225 int numOfParents = -1;
1227 if (numOfParents > 1)
ATH_MSG_DEBUG(
"DefOrigOfNeutrino:: neutrino has more than one mother ");
1232 int motherPDG = mother->
pdgId();
1236 bool samePart =
false;
1239 if ((abs(motherPDG) == nuFlav ||
MC::isTau(motherPDG) ||
MC::isW(motherPDG)) && mothOriVert !=
nullptr &&
1251 mother_endVtx = mother->
decayVtx();
1257 parent_endVtx = MotherParent->
decayVtx();
1259 if (mother_endVtx == parent_prdVtx && mother_prdVtx == parent_endVtx) {
1260 MotherParent = mother;
1265 pPDG = MotherParent->
pdgId();
1268 if (mother == MotherParent) {
1272 mother = MotherParent;
1273 if (
info)
info->setMotherProperties(mother);
1280 std::abs(pPDG) == 9900024 || std::abs(pPDG) == 9900012 || std::abs(pPDG) == 9900014 || std::abs(pPDG) == 9900016 ||
1281 (std::abs(pPDG) < 2000040 && std::abs(pPDG) > 1000001)) {
1282 mother = MotherParent;
1283 if (
info)
info->setMotherProperties(mother);
1289 motherPDG = mother->
pdgId();
1295 if (
info)
info->setMotherProperties(mother);
1303 int NumOfTauNeut(0);
1310 if (!theDaug)
continue;
1311 int DaugType = theDaug->pdgId();
1314 else if (abs(DaugType) == MC::NU_E) NumOfElNeut++;
1315 else if (std::abs(DaugType) == MC::NU_MU) NumOfMuNeut++;
1316 else if (std::abs(DaugType) == MC::NU_TAU) NumOfTauNeut++;
1320 else if (
MC::isTau(DaugType)) NumOfTau++;
1326 if (
MC::isQuark(motherPDG) && numOfParents == 1 && numOfDaug == 3 && NumOfquark == 1 && (NumOfEl == 1 || NumOfMu == 1 || NumOfTau == 1))
return QuarkWeakDec;
1335 }
while (
MC::isW(ptrPart) && prodVert !=
nullptr);
1338 if (abs(ptrPart->
pdgId()) == 9900012)
return NuREle;
1339 if (abs(ptrPart->
pdgId()) == 9900014)
return NuRMu;
1340 if (abs(ptrPart->
pdgId()) == 9900016)
return NuRTau;
1356 bool isZboson =
false;
1357 bool isWboson =
false;
1358 bool skipnext =
false;
1360 for (
unsigned int ipOut = 0; ipOut + 1 < partOriVert->
nOutgoingParticles(); ++ipOut) {
1362 if (!theDaug)
continue;
1364 for (
unsigned int ipOut1 = ipOut + 1; ipOut1 < partOriVert->
nOutgoingParticles(); ipOut1++) {
1366 if (theNextDaug !=
nullptr)
break;
1368 if (!theNextDaug)
continue;
1375 const int apdgID1 = abs(theDaug->
pdgId());
1376 const int apdgID2 = abs(theNextDaug->
pdgId());
1379 if (thePartToCheck == theDaug || thePartToCheck == theNextDaug) {
1384 }
else if ((apdgID1 == MC::ELECTRON && apdgID2 == MC::NU_E) ||
1385 (apdgID1 == MC::NU_E && apdgID2 == MC::ELECTRON) ||
1386 (apdgID1 == MC::MUON && apdgID2 == MC::NU_MU) ||
1387 (apdgID1 == MC::NU_MU && apdgID2 == MC::MUON) ||
1388 (apdgID1 == MC::TAU && apdgID2 == MC::NU_TAU) ||
1389 (apdgID1 == MC::NU_TAU && apdgID2 == MC::TAU)
1392 if (thePartToCheck == theDaug || thePartToCheck == theNextDaug) {
1399 if (isWboson)
return WBoson;
1400 if (isZboson)
return ZBoson;
1403 if (numOfParents == 2) {
1407 if ( (numOfDaug - NumOfquark - NumOfgluon) == 2 && (NumOfElNeut == 2 || NumOfMuNeut == 2 || NumOfTauNeut == 2))
return ZBoson;
1410 if ((numOfDaug - NumOfquark - NumOfgluon) == 2 && ((NumOfEl == 1 && NumOfElNeut == 1) || (NumOfMu == 1 && NumOfMuNeut == 1) || (NumOfTau == 1 && NumOfTauNeut == 1)))
return WBoson;
1413 if ( (numOfDaug - NumOfquark - NumOfgluon) == 4 && (NumOfEl + NumOfMu + NumOfTau + NumOfElNeut + NumOfMuNeut + NumOfTauNeut == 4) &&
1417 if ((numOfDaug - NumOfquark - NumOfgluon - NumOfPhot) == 6 && (NumOfEl + NumOfMu + NumOfTau + NumOfElNeut + NumOfMuNeut + NumOfTauNeut == 6) &&
1422 if (partOriVert == mothOriVert && partOriVert !=
nullptr) {
1423 int NumOfLepLoop = 0;
1424 int NumOfNeuLoop = 0;
1426 if (!
pout)
continue;
1427 for (
const auto *
const pin: partOriVert->
particles_in()) {
1430 const int apdgid = abs(
pout->pdgId());
1433 else { NumOfLepLoop++; }
1437 if (NumOfNeuLoop == 2 && NumOfLepLoop == 0)
return ZBoson;
1438 if (NumOfNeuLoop == 1 && NumOfLepLoop == 1)
return WBoson;
1439 if (NumOfNeuLoop + NumOfLepLoop == 4)
return DiBoson;
1454 if (abs(motherPDG) == 9900024)
return WBosonLRSM;
1455 if (abs(motherPDG) == 9900012)
return NuREle;
1456 if (abs(motherPDG) == 9900014)
return NuRMu;
1457 if (abs(motherPDG) == 9900016)
return NuRTau;