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;
270 if ((abs(motherPDG) == 13 || abs(motherPDG) == 15 || abs(motherPDG) == 24) && mothOriVert !=
nullptr && !samePart) {
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;
297 if (abs(pPDG) == 13 || abs(pPDG) == 15 || abs(pPDG) == 24) mother = MotherParent;
299 }
while ((abs(pPDG) == 13 || abs(pPDG) == 15 || abs(pPDG) == 24));
301 if (abs(pPDG) == 13 || abs(pPDG) == 15 || abs(pPDG) == 24 || abs(pPDG) == 23 || abs(pPDG) == 25 ||
302 abs(pPDG) == 35 || abs(pPDG) == 36 || abs(pPDG) == 37 || abs(pPDG) == 32 || abs(pPDG) == 33 ||
303 abs(pPDG) == 34 || abs(pPDG) == 6 || abs(pPDG) == 9900024 || abs(pPDG) == 9900012 || abs(pPDG) == 9900014 ||
304 abs(pPDG) == 9900016 || (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();
334 if (abs(DaugType) < 7) NumOfquark++;
335 if (abs(DaugType) == 21) NumOfgluon++;
336 if (abs(DaugType) == 12) NumOfElNeut++;
337 if (abs(DaugType) == 14) NumOfMuNeut++;
338 if (DaugType == 22) NumOfPhot++;
339 if (DaugType == 11) NumOfEl++;
340 if (DaugType == -11) NumOfPos++;
341 if (DaugType == 13) NumOfMuMin++;
342 if (DaugType == -13) NumOfMuPl++;
343 if (abs(DaugType) == 15) NumOfTau++;
344 if (abs(DaugType) == 16) NumOfTauNeut++;
345 if (abs(DaugType) == 42) NumOfLQ++;
347 if (numOfParents == 1 &&
348 (motherPDG == 22 || abs(motherPDG) == 11 || abs(motherPDG) == 13 || abs(motherPDG) == 211) &&
349 (DaugType > 1000000000 || DaugType == 0 || DaugType == 2212 || DaugType == 2112 || abs(DaugType) == 211 ||
350 abs(DaugType) == 111))
354 if (motherPDG == 22 && mothOriVert !=
nullptr) {
355 for (
const auto& theMother: mothOriVert->
particles_in()) {
356 if (!theMother)
continue;
358 info->photonMother = theMother;
362 if ((motherPDG == 22 && numOfDaug == 2 && NumOfEl == 1 && NumOfPos == 1) || (motherPDG == 22 && numOfDaug == 1 && (NumOfEl == 1 || NumOfPos == 1)))
return PhotonConv;
365 if ((numOfParents == 1 && (abs(motherPDG) == 22 || abs(motherPDG) == 11 || abs(motherPDG) == 15)) && numOfDaug > 1 && NumOfNucFr != 0)
return ElMagProc;
367 if (numOfParents == 1 && abs(motherPDG) == 211 && numOfDaug > 2 && NumOfNucFr != 0)
return ElMagProc;
370 if (motherPDG == 22 && numOfDaug > 4 && NumOfNucFr != 0)
return ElMagProc;
373 if (abs(motherPDG) == 11 && numOfDaug == 2 && NumOfEl == 1 && NumOfPos == 1)
return ElMagProc;
376 if (motherPDG == 11 && numOfDaug == 2 && NumOfEl == 2 && NumOfPos == 0)
return ElMagProc;
379 if (motherPDG == -11 && numOfDaug == 2 && NumOfEl == 0 && NumOfPos == 2)
return ElMagProc;
382 if (abs(motherPDG) == 11 && !
MC::isDecayed(mother) && motherPDG == thePriPart->
pdgId() && numOfDaug == 1 && !samePart)
return ElMagProc;
386 if (numOfDaug == 2 && (NumOfEl == 1 || NumOfPos == 1) && abs(motherPDG) != 11 && samePart)
return ElMagProc;
388 if ((motherPDG == 111 && numOfDaug == 3 && NumOfPhot == 1 && NumOfEl == 1 && NumOfPos == 1) ||
389 (motherPDG == 111 && numOfDaug == 4 && NumOfPhot == 0 && NumOfEl == 2 && NumOfPos == 2))
393 if (abs(motherPDG) < 7 && numOfParents == 1 && numOfDaug == 3 && NumOfquark == 1 && NumOfElNeut == 1)
return QuarkWeakDec;
395 if (abs(motherPDG) == 13 && NumOfNucFr != 0)
return ElMagProc;
397 if (abs(motherPDG) == 6)
return top;
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;
419 if (numOfParents == 1 && numOfDaug > 4 && (abs(motherPDG) < 7 || motherPDG == 21)) {
423 if (theMother !=
nullptr && abs(theMother->
pdgId()) == 11 &&
MC::isDecayed(theMother)) thePartToCheck = theMother;
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;
443 if (abs(theDaug->
pdgId()) == 11 && abs(theNextDaug->
pdgId()) == 11) {
445 if (thePartToCheck == theDaug || thePartToCheck == theNextDaug) {
450 }
else if (abs(theDaug->
pdgId()) == 11 && abs(theNextDaug->
pdgId()) == 12) {
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()) == 12) 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;
505 if (abs(motherPDG) == 25)
return Higgs;
507 if (abs(motherPDG) == 35 || abs(motherPDG) == 36 || abs(motherPDG) == 37)
return HiggsMSSM;
509 if (abs(motherPDG) == 32 || abs(motherPDG) == 33 || abs(motherPDG) == 34)
return HeavyBoson;
511 if (abs(motherPDG) == 13)
return Mu;
512 if (abs(motherPDG) == 15) {
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;
522 if (abs(motherPDG) == 42 || NumOfLQ != 0)
return LQ;
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();
597 if (abs(pPDG) == 13 || abs(pPDG) == 15 || abs(pPDG) == 24) {
598 mother = MotherParent;
599 if (
info)
info->setMotherProperties(mother);
602 }
while ((abs(pPDG) == 13 || abs(pPDG) == 15 || abs(pPDG) == 24));
604 if (abs(pPDG) == 15 || abs(pPDG) == 24 || abs(pPDG) == 23 || abs(pPDG) == 25 || abs(pPDG) == 35 ||
605 abs(pPDG) == 36 || abs(pPDG) == 37 || abs(pPDG) == 32 || abs(pPDG) == 33 || abs(pPDG) == 34 || abs(pPDG) == 6 ||
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 int NumOfPhot = DP.pd(22);
621 int NumOfEl = DP.pd(11);
622 int NumOfPos = DP.pd(-11);
623 int NumOfElNeut = DP.apd(12);
624 int NumOfMuNeut = DP.apd(14);
625 int NumOfLQ = DP.apd(42);
626 int NumOfquark = DP.apd({1,2,3,4,5,6});
627 int NumOfgluon = DP.apd(21);
628 int NumOfMuPl = DP.pd(-13);
629 int NumOfMuMin = DP.pd(13);
630 int NumOfTau = DP.apd(15);
631 int NumOfTauNeut = DP.apd(16);
632 if (std::abs(motherPDG) == 211 && numOfDaug == 2 && NumOfMuNeut == 1)
return PionDecay;
633 if (std::abs(motherPDG) == 321 && numOfDaug == 2 && NumOfMuNeut == 1)
return KaonDecay;
640 if (std::abs(motherPDG) == 6)
return top;
642 if (abs(motherPDG) < 7 && 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;
661 if (motherPDG == 22 && numOfDaug == 2 && NumOfMuMin == 1 && NumOfMuPl == 1)
return PhotonConv;
666 if (numOfParents == 1 && numOfDaug > 4 && (abs(motherPDG) < 7 || motherPDG == 21)) {
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;
683 if (abs(theDaug->
pdgId()) == 13 && abs(theNextDaug->
pdgId()) == 13) {
685 if (thePriPart == theDaug || thePriPart == theNextDaug) {
690 }
else if (abs(theDaug->
pdgId()) == 13 && abs(theNextDaug->
pdgId()) == 14) {
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;
733 if (std::abs(
pout->pdg_id()) == 13) NumOfMuLoop++;
734 if (std::abs(
pout->pdg_id()) == 14) 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;
747 if (abs(motherPDG) == 25)
return Higgs;
749 if (abs(motherPDG) == 35 || abs(motherPDG) == 36 || abs(motherPDG) == 37)
return HiggsMSSM;
751 if (abs(motherPDG) == 32 || abs(motherPDG) == 33 || abs(motherPDG) == 34)
return HeavyBoson;
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;
757 if (abs(motherPDG) == 42 || NumOfLQ != 0)
return LQ;
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();
806 if (abs(pPDG) == 6) {
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 int numOfDaug = DP.size();
822 int NumOfPhot = DP.pd(22);
823 int NumOfEl = DP.pd(11);
824 int NumOfPos = DP.pd(-11);
825 int NumOfElNeut = DP.apd(12);
826 int NumOfMuNeut = DP.apd(14);
828 int NumOfquark = DP.apd({1,2,3,4,5,6});
829 int NumOfgluon = DP.apd(21);
830 int NumOfMuPl = DP.pd(-13);
831 int NumOfMuMin = DP.pd(13);
832 int NumOfTau = DP.apd(15);
833 int NumOfTauNeut = DP.pd(16);
835 if (abs(motherPDG) == 6)
return top;
842 }
while (
MC::isW(itrP) && prodVert !=
nullptr);
846 if (abs(itrP->
pdgId()) == 9900014)
return NuRMu;
853 if (numOfParents == 1 && numOfDaug > 4 && (abs(motherPDG) < 7 || motherPDG == 21)) {
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;
872 if (abs(theDaug->
pdgId()) == 15 && abs(theNextDaug->
pdgId()) == 15) {
874 if (thePriPart == theDaug || thePriPart == theNextDaug) {
879 }
else if (abs(theDaug->
pdgId()) == 15 && abs(theNextDaug->
pdgId()) == 16) {
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()) {
920 if (std::abs(
pout->pdgId()) == 15) NumOfTauLoop++;
921 if (std::abs(
pout->pdgId()) == 16) 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;
931 if (abs(motherPDG) == 25)
return Higgs;
932 if (abs(motherPDG) == 35 || abs(motherPDG) == 36 || abs(motherPDG) == 37)
return HiggsMSSM;
933 if (abs(motherPDG) == 32 || abs(motherPDG) == 33 || abs(motherPDG) == 34)
return HeavyBoson;
934 if (abs(motherPDG) == 9900024)
return WBosonLRSM;
935 if (abs(motherPDG) == 9900016)
return NuRTau;
938 if (abs(motherPDG) == 443)
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();
999 if (numOfParents == 1 && (motherPDG == 22 || abs(motherPDG) == 11 || abs(motherPDG) == 211) &&
1000 (DaugType > 1000000000 || DaugType == 0 || DaugType == 2212 || DaugType == 2112))
1002 if (DaugType == 22) NumOfPht++;
1003 if (DaugType == 11) NumOfEl++;
1004 if (DaugType == -11) NumOfPos++;
1005 if (abs(DaugType) == 13) NumOfMu++;
1006 if (abs(DaugType) == 15) NumOfTau++;
1007 if (abs(DaugType) == 42) NumOfLQ++;
1008 if (abs(DaugType) == 11 || abs(DaugType) == 13 || abs(DaugType) == 15) NumOfLep++;
1009 if (abs(DaugType) == 12 || abs(DaugType) == 14 || abs(DaugType) == 16) NumOfNeut++;
1010 if (abs(DaugType) < 11 || (abs(DaugType) > 16 && abs(DaugType) < 43 && abs(DaugType) != 22)) NumOfPartons++;
1011 if (DaugType == motherPDG) {
1016 bool foundISR =
false;
1017 bool foundFSR =
false;
1019 if (numOfParents == 1 && numOfDaug == 2 && abs(motherPDG) == 11 && NumOfPht == 2)
return ElMagProc;
1022 if (numOfParents == 1 && numOfDaug == 2 && (abs(motherPDG) == 11 || abs(motherPDG) == 13 || abs(motherPDG) == 15) &&
1033 PartPDG = abs(pin->pdgId());
1034 prodVert = pin->prodVtx();
1035 if (PartPDG == 23 || PartPDG == 24 || PartPDG == 25) foundFSR =
true;
1042 }
while (prodVert !=
nullptr && abs(motherPDG) == PartPDG);
1052 if ((numOfParents == 1 && (abs(motherPDG) == 22 || abs(motherPDG) == 11) && numOfDaug > 2 && NumOfNucFr != 0) ||
1053 (numOfParents == 1 && abs(motherPDG) == 211 && numOfDaug > 10 && NumOfNucFr != 0) ||
1054 (numOfParents == 1 && motherPDG == 22 && numOfDaug > 10 &&
MC::isStable(mother)) ||
1055 (numOfParents == 1 && motherPDG > 1000000000))
1065 if (numOfParents == 1 && (abs(motherPDG) < 7 || motherPDG == 21) &&
1068 if (!
pout)
continue;
1069 if (motherPDG !=
pout->pdgId())
continue;
1071 if (!Vrtx)
continue;
1084 if (numOfParents == 2 && ((abs(motherPDG) == 11 && NumOfEl == 1 && NumOfPos == 1) || (abs(motherPDG) == 13 && NumOfMu == 2) || (abs(motherPDG) == 15 && NumOfTau == 2))) {
1088 if (numOfParents == 2 && NumOfLep == 1 && NumOfNeut == 1 && (abs(motherPDG) == 11 || abs(motherPDG) == 12))
return FSRPhot;
1091 if (abs(motherPDG) == 11 && 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;
1129 if (numOfParents == 1 && numOfDaug > 4 && (abs(motherPDG) < 7 || motherPDG == 21)) {
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;
1146 if (abs(theDaug->
pdgId()) == 15 && abs(theNextDaug->
pdgId()) == 15) {
1148 if (thePriPart == theDaug || thePriPart == theNextDaug) {
1153 }
else if (abs(theDaug->
pdgId()) == 15 && abs(theNextDaug->
pdgId()) == 16) {
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()) {
1186 if (abs(motherPDG) == 25)
return Higgs;
1187 if (abs(motherPDG) == 111)
return PiZero;
1188 if (abs(motherPDG) == 35 || abs(motherPDG) == 36 || abs(motherPDG) == 37)
return HiggsMSSM;
1189 if (abs(motherPDG) == 32 || abs(motherPDG) == 33 || abs(motherPDG) == 34 || abs(motherPDG) == 5100039 )
return HeavyBoson;
1211 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 || abs(motherPDG) == 15 ||
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) {
1271 if (abs(pPDG) == nuFlav || abs(pPDG) == 15 || abs(pPDG) == 24 ) {
1272 mother = MotherParent;
1273 if (
info)
info->setMotherProperties(mother);
1276 }
while ((std::abs(pPDG) == nuFlav || std::abs(pPDG) == 15 || std::abs(pPDG) == 24));
1278 if (std::abs(pPDG) == nuFlav || std::abs(pPDG) == 15 || std::abs(pPDG) == 24 || std::abs(pPDG) == 23 || std::abs(pPDG) == 25 ||
1279 std::abs(pPDG) == 35 || std::abs(pPDG) == 36 || std::abs(pPDG) == 37 || std::abs(pPDG) == 32 || std::abs(pPDG) == 33 ||
1280 std::abs(pPDG) == 34 || std::abs(pPDG) == 6 || std::abs(pPDG) == 9900024 || std::abs(pPDG) == 9900012 || std::abs(pPDG) == 9900014 ||
1281 std::abs(pPDG) == 9900016 || (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();
1312 if (abs(DaugType) < 7) NumOfquark++;
1313 if (abs(DaugType) == 21) NumOfgluon++;
1314 if (abs(DaugType) == 12) NumOfElNeut++;
1315 if (std::abs(DaugType) == 14) NumOfMuNeut++;
1316 if (std::abs(DaugType) == 16) NumOfTauNeut++;
1317 if (DaugType == 22) NumOfPhot++;
1318 if (std::abs(DaugType) == 11) NumOfEl++;
1319 if (std::abs(DaugType) == 13) NumOfMu++;
1320 if (std::abs(DaugType) == 15) NumOfTau++;
1321 if (std::abs(DaugType) == 42) NumOfLQ++;
1326 if (
MC::isQuark(motherPDG) && numOfParents == 1 && numOfDaug == 3 && NumOfquark == 1 && (NumOfEl == 1 || NumOfMu == 1 || NumOfTau == 1))
return QuarkWeakDec;
1327 if (std::abs(motherPDG) == 6)
return top;
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;
1350 if (numOfParents == 1 && numOfDaug > 4 && (abs(motherPDG) < 7 || motherPDG == 21)) {
1355 if (abs(theMother->
pdgId()) == 11 &&
MC::isDecayed(theMother)) thePartToCheck = theMother;
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 int apdgID1 = abs(theDaug->
pdgId());
1376 int apdgID2 = abs(theNextDaug->
pdgId());
1377 if ((apdgID1 == 12 && apdgID2 == 12) || (apdgID1 == 14 && apdgID2 == 14) || (apdgID1 == 16 && apdgID2 == 16)) {
1379 if (thePartToCheck == theDaug || thePartToCheck == theNextDaug) {
1384 }
else if ((apdgID1 == 11 && apdgID2 == 12) || (apdgID1 == 14 && apdgID2 == 14) ||
1385 (apdgID1 == 16 && apdgID2 == 16)) {
1387 if (thePartToCheck == theDaug || thePartToCheck == theNextDaug) {
1394 if (isWboson)
return WBoson;
1395 if (isZboson)
return ZBoson;
1398 if (numOfParents == 2) {
1402 if ( (numOfDaug - NumOfquark - NumOfgluon) == 2 && (NumOfElNeut == 2 || NumOfMuNeut == 2 || NumOfTauNeut == 2))
return ZBoson;
1405 if ((numOfDaug - NumOfquark - NumOfgluon) == 2 && ((NumOfEl == 1 && NumOfElNeut == 1) || (NumOfMu == 1 && NumOfMuNeut == 1) || (NumOfTau == 1 && NumOfTauNeut == 1)))
return WBoson;
1408 if ( (numOfDaug - NumOfquark - NumOfgluon) == 4 && (NumOfEl + NumOfMu + NumOfTau + NumOfElNeut + NumOfMuNeut + NumOfTauNeut == 4) &&
1412 if ((numOfDaug - NumOfquark - NumOfgluon - NumOfPhot) == 6 && (NumOfEl + NumOfMu + NumOfTau + NumOfElNeut + NumOfMuNeut + NumOfTauNeut == 6) &&
1417 if (partOriVert == mothOriVert && partOriVert !=
nullptr) {
1418 int NumOfLepLoop = 0;
1419 int NumOfNeuLoop = 0;
1421 if (!
pout)
continue;
1422 for (
const auto *
const pin: partOriVert->
particles_in()) {
1425 int apdgid = abs(
pout->pdgId());
1426 if (apdgid == 12 || apdgid == 14 || apdgid == 16) NumOfNeuLoop++;
1427 if (apdgid == 11 || apdgid == 13 || apdgid == 15) NumOfLepLoop++;
1430 if (NumOfNeuLoop == 2 && NumOfLepLoop == 0)
return ZBoson;
1431 if (NumOfNeuLoop == 1 && NumOfLepLoop == 1)
return WBoson;
1432 if (NumOfNeuLoop + NumOfLepLoop == 4)
return DiBoson;
1437 if (abs(motherPDG) == 25)
return Higgs;
1438 if (abs(motherPDG) == 35 || abs(motherPDG) == 36 || abs(motherPDG) == 37)
return HiggsMSSM;
1439 if (abs(motherPDG) == 32 || abs(motherPDG) == 33 || abs(motherPDG) == 34)
return HeavyBoson;
1441 if (abs(motherPDG) == 15) {
1447 if (abs(motherPDG) == 9900024)
return WBosonLRSM;
1448 if (abs(motherPDG) == 9900012)
return NuREle;
1449 if (abs(motherPDG) == 9900014)
return NuRMu;
1450 if (abs(motherPDG) == 9900016)
return NuRTau;
1451 if (abs(motherPDG) == 42 || NumOfLQ != 0)
return LQ;