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);
57 for (
const auto *
const entry : *truthParticleLinkVecReadHandle) {
61 if (!theGenPart || !truthParticle ||
63 theGenPart->status() != truthParticle->
status() ||
66 "HepMC::GenParticle and xAOD::TruthParticle do not match");
67 return std::make_pair(partType, partOrig);
69 return particleTruthClassifier(truthParticle,
info);
72 return std::make_pair(partType, partOrig);
76 std::pair<ParticleType, ParticleOrigin>
84 return std::make_pair(partType, partOrig);
87 const EventContext& ctx =
info ?
info->eventContext : Gaudi::Hive::currentContext();
90 info->genPart = thePart;
94 if (!truthParticleContainerReadHandle.
isValid()) {
95 ATH_MSG_WARNING(
" Invalid ReadHandle for xAOD::TruthParticleContainer with key: " << truthParticleContainerReadHandle.
key());
96 return std::make_pair(partType, partOrig);
99 ATH_MSG_DEBUG(
"xAODTruthParticleContainer with key " << truthParticleContainerReadHandle.
key() <<
" has valid ReadHandle ");
111 if (endVert !=
nullptr) {
129 if (abs(thePart->
pdg_id()) > 1000000000)
return std::make_pair(
NuclFrag, partOrig);
137 if (partOriVert !=
nullptr) {
140 int motherStatus = theMoth?theMoth->status():0;
141 int motherPDG = theMoth?theMoth->pdg_id():0;
142 info->setMotherProperties(theMoth);
150 partOrig = defOrigOfElectron(truthParticleContainerReadHandle.
ptr(), thePart,
isPrompt,
info);
156 partOrig = defOrigOfMuon(truthParticleContainerReadHandle.
ptr(), thePart,
isPrompt,
info);
159 if (!partOriVert &&
MC::isTau(thePart)) {
161 partOrig = defOrigOfTau(truthParticleContainerReadHandle.
ptr(), thePart, motherPDG,
info);
167 partOrig = defOrigOfPhoton(truthParticleContainerReadHandle.
ptr(), thePart,
isPrompt,
info);
173 return std::make_pair(
Neutrino, partOrig);
179 if (isPartHadr)
return std::make_pair(
Hadron, partOrig);
205 partOrig = defOrigOfElectron(truthParticleContainerReadHandle.
ptr(), thePart,
isPrompt,
info);
209 partOrig = defOrigOfMuon(truthParticleContainerReadHandle.
ptr(), thePart,
isPrompt,
info);
212 partOrig = defOrigOfTau(truthParticleContainerReadHandle.
ptr(), thePart, motherPDG,
info);
216 partOrig = defOrigOfPhoton(truthParticleContainerReadHandle.
ptr(), thePart,
isPrompt,
info);
220 partOrig = defOrigOfNeutrino(truthParticleContainerReadHandle.
ptr(), thePart,
isPrompt,
info);
225 return std::make_pair(partType, partOrig);
251 int numOfParents = -1;
253 if (numOfParents > 1)
ATH_MSG_DEBUG(
"DefOrigOfElectron:: electron has more than one mother ");
256 if (
info)
info->setMotherProperties(mother);
260 int motherPDG = mother->
pdgId();
261 if (
info)
info->setMotherProperties(mother);
264 bool samePart =
false;
266 if (!theDaug)
continue;
275 if ((abs(motherPDG) == 13 || abs(motherPDG) == 15 || abs(motherPDG) == 24) && mothOriVert !=
nullptr && !samePart) {
292 parent_endVtx = MotherParent->
decayVtx();
294 if (mother_endVtx == parent_prdVtx && mother_prdVtx == parent_endVtx) {
295 MotherParent = mother;
299 if (MotherParent) pPDG = MotherParent->
pdgId();
301 if (mother == MotherParent)
break;
302 if (abs(pPDG) == 13 || abs(pPDG) == 15 || abs(pPDG) == 24) mother = MotherParent;
304 }
while ((abs(pPDG) == 13 || abs(pPDG) == 15 || abs(pPDG) == 24));
306 if (abs(pPDG) == 13 || abs(pPDG) == 15 || abs(pPDG) == 24 || abs(pPDG) == 23 || abs(pPDG) == 25 ||
307 abs(pPDG) == 35 || abs(pPDG) == 36 || abs(pPDG) == 37 || abs(pPDG) == 32 || abs(pPDG) == 33 ||
308 abs(pPDG) == 34 || abs(pPDG) == 6 || abs(pPDG) == 9900024 || abs(pPDG) == 9900012 || abs(pPDG) == 9900014 ||
309 abs(pPDG) == 9900016 || (abs(pPDG) < 2000040 && abs(pPDG) > 1000001))
310 mother = MotherParent;
313 motherPDG = mother->
pdgId();
319 if (
info)
info->setMotherProperties(mother);
337 if (!theDaug)
continue;
338 int DaugType = theDaug->pdgId();
339 if (abs(DaugType) < 7) NumOfquark++;
340 if (abs(DaugType) == 21) NumOfgluon++;
341 if (abs(DaugType) == 12) NumOfElNeut++;
342 if (abs(DaugType) == 14) NumOfMuNeut++;
343 if (DaugType == 22) NumOfPhot++;
344 if (DaugType == 11) NumOfEl++;
345 if (DaugType == -11) NumOfPos++;
346 if (DaugType == 13) NumOfMuMin++;
347 if (DaugType == -13) NumOfMuPl++;
348 if (abs(DaugType) == 15) NumOfTau++;
349 if (abs(DaugType) == 16) NumOfTauNeut++;
350 if (abs(DaugType) == 42) NumOfLQ++;
352 if (numOfParents == 1 &&
353 (motherPDG == 22 || abs(motherPDG) == 11 || abs(motherPDG) == 13 || abs(motherPDG) == 211) &&
354 (DaugType > 1000000000 || DaugType == 0 || DaugType == 2212 || DaugType == 2112 || abs(DaugType) == 211 ||
355 abs(DaugType) == 111))
359 if (motherPDG == 22 && mothOriVert !=
nullptr) {
360 for (
const auto& theMother: mothOriVert->
particles_in()) {
361 if (!theMother)
continue;
363 info->photonMother = theMother;
364 info->photonMotherStatus = theMother->status();
366 info->photonMotherPDG = theMother->pdgId();
370 if ((motherPDG == 22 && numOfDaug == 2 && NumOfEl == 1 && NumOfPos == 1) || (motherPDG == 22 && numOfDaug == 1 && (NumOfEl == 1 || NumOfPos == 1)))
return PhotonConv;
373 if ((numOfParents == 1 && (abs(motherPDG) == 22 || abs(motherPDG) == 11 || abs(motherPDG) == 15)) && numOfDaug > 1 && NumOfNucFr != 0)
return ElMagProc;
375 if (numOfParents == 1 && abs(motherPDG) == 211 && numOfDaug > 2 && NumOfNucFr != 0)
return ElMagProc;
378 if (motherPDG == 22 && numOfDaug > 4 && NumOfNucFr != 0)
return ElMagProc;
381 if (abs(motherPDG) == 11 && numOfDaug == 2 && NumOfEl == 1 && NumOfPos == 1)
return ElMagProc;
384 if (motherPDG == 11 && numOfDaug == 2 && NumOfEl == 2 && NumOfPos == 0)
return ElMagProc;
387 if (motherPDG == -11 && numOfDaug == 2 && NumOfEl == 0 && NumOfPos == 2)
return ElMagProc;
390 if (abs(motherPDG) == 11 && !
MC::isDecayed(mother) && motherPDG == thePriPart->
pdgId() && numOfDaug == 1 && !samePart)
return ElMagProc;
394 if (numOfDaug == 2 && (NumOfEl == 1 || NumOfPos == 1) && abs(motherPDG) != 11 && samePart)
return ElMagProc;
396 if ((motherPDG == 111 && numOfDaug == 3 && NumOfPhot == 1 && NumOfEl == 1 && NumOfPos == 1) ||
397 (motherPDG == 111 && numOfDaug == 4 && NumOfPhot == 0 && NumOfEl == 2 && NumOfPos == 2))
401 if (abs(motherPDG) < 7 && numOfParents == 1 && numOfDaug == 3 && NumOfquark == 1 && NumOfElNeut == 1)
return QuarkWeakDec;
403 if (abs(motherPDG) == 13 && NumOfNucFr != 0)
return ElMagProc;
405 if (abs(motherPDG) == 6)
return top;
414 }
while (
MC::isW(ptrPart) && prodVert !=
nullptr);
417 if (abs(ptrPart->
pdgId()) == 9900012)
return NuREle;
418 if (abs(ptrPart->
pdgId()) == 9900014)
return NuRMu;
419 if (abs(ptrPart->
pdgId()) == 9900016)
return NuRTau;
427 if (numOfParents == 1 && numOfDaug > 4 && (abs(motherPDG) < 7 || motherPDG == 21)) {
431 if (theMother !=
nullptr && abs(theMother->
pdgId()) == 11 &&
MC::isDecayed(theMother)) thePartToCheck = theMother;
433 bool isZboson =
false;
434 bool isWboson =
false;
435 bool skipnext =
false;
437 for (
unsigned int ipOut = 0; ipOut + 1 < partOriVert->
nOutgoingParticles(); ++ipOut) {
439 if (!theDaug)
continue;
441 for (
unsigned int ipOut1 = ipOut + 1; ipOut1 < partOriVert->
nOutgoingParticles(); ipOut1++) {
443 if (theNextDaug !=
nullptr)
break;
445 if (!theNextDaug)
continue;
451 if (abs(theDaug->
pdgId()) == 11 && abs(theNextDaug->
pdgId()) == 11) {
453 if (thePartToCheck == theDaug || thePartToCheck == theNextDaug) {
458 }
else if (abs(theDaug->
pdgId()) == 11 && abs(theNextDaug->
pdgId()) == 12) {
460 if (thePartToCheck == theDaug || thePartToCheck == theNextDaug) {
467 if (isWboson)
return WBoson;
468 if (isZboson)
return ZBoson;
470 if (numOfParents == 2) {
474 if ((numOfDaug - NumOfquark - NumOfgluon) == 2 && NumOfEl == 1 && NumOfPos == 1)
return ZBoson;
477 if ((numOfDaug - NumOfquark - NumOfgluon) == 2 && (NumOfEl == 1 || NumOfPos == 1) && NumOfElNeut == 1)
return WBoson;
480 if ((numOfDaug - NumOfquark - NumOfgluon) == 4 && (NumOfEl + NumOfPos + NumOfMuPl + NumOfMuMin + NumOfTau + NumOfElNeut + NumOfMuNeut + NumOfTauNeut == 4) &&
484 if ((numOfDaug - NumOfquark - NumOfgluon - NumOfPhot) == 6 && (NumOfEl + NumOfPos + NumOfMuPl + NumOfMuMin + NumOfTau + NumOfElNeut + NumOfMuNeut + NumOfTauNeut == 6) &&
489 if (partOriVert == mothOriVert && partOriVert !=
nullptr) {
490 int NumOfEleLoop = 0;
491 int NumOfLepLoop = 0;
492 int NumOfEleNeuLoop = 0;
495 for (
const auto *
const pin: partOriVert->
particles_in()) {
499 if (std::abs(pin->pdgId()) == 12) NumOfEleNeuLoop++;
503 if (NumOfEleLoop == 2 && NumOfEleNeuLoop == 0)
return ZBoson;
504 if (NumOfEleLoop == 1 && NumOfEleNeuLoop == 1)
return WBoson;
505 if ((NumOfEleLoop == 4 && NumOfEleNeuLoop == 0) || (NumOfEleLoop == 3 && NumOfEleNeuLoop == 1) ||
506 (NumOfEleLoop == 2 && NumOfEleNeuLoop == 2))
508 if (NumOfLepLoop == 4)
return DiBoson;
513 if (abs(motherPDG) == 25)
return Higgs;
515 if (abs(motherPDG) == 35 || abs(motherPDG) == 36 || abs(motherPDG) == 37)
return HiggsMSSM;
517 if (abs(motherPDG) == 32 || abs(motherPDG) == 33 || abs(motherPDG) == 34)
return HeavyBoson;
519 if (abs(motherPDG) == 13)
return Mu;
520 if (abs(motherPDG) == 15) {
526 if (abs(motherPDG) == 9900024)
return WBosonLRSM;
527 if (abs(motherPDG) == 9900012)
return NuREle;
528 if (abs(motherPDG) == 9900014)
return NuRMu;
529 if (abs(motherPDG) == 9900016)
return NuRTau;
530 if (abs(motherPDG) == 42 || NumOfLQ != 0)
return LQ;
561 if (numOfParents > 1)
ATH_MSG_DEBUG(
"DefOrigOfMuon:: muon has more than one mother ");
564 if (
info)
info->setMotherProperties(mother);
570 int motherPDG = mother->
pdgId();
572 if ((
MC::isTau(motherPDG)||
MC::isW(motherPDG)) && mothOriVert !=
nullptr) {
590 parent_endVtx = MotherParent->
decayVtx();
593 if (mother_endVtx == parent_prdVtx && mother_prdVtx == parent_endVtx) {
594 MotherParent = mother;
599 if (mother == MotherParent) {
604 pPDG = MotherParent->
pdgId();
605 if (abs(pPDG) == 13 || abs(pPDG) == 15 || abs(pPDG) == 24) {
606 mother = MotherParent;
607 if (
info)
info->setMotherProperties(mother);
610 }
while ((abs(pPDG) == 13 || abs(pPDG) == 15 || abs(pPDG) == 24));
612 if (abs(pPDG) == 15 || abs(pPDG) == 24 || abs(pPDG) == 23 || abs(pPDG) == 25 || abs(pPDG) == 35 ||
613 abs(pPDG) == 36 || abs(pPDG) == 37 || abs(pPDG) == 32 || abs(pPDG) == 33 || abs(pPDG) == 34 || abs(pPDG) == 6 ||
614 abs(pPDG) == 9900024 || abs(pPDG) == 9900012 || abs(pPDG) == 9900014 || abs(pPDG) == 9900016 ||
615 (abs(pPDG) < 2000040 && abs(pPDG) > 1000001)) {
616 if (
info)
info->setMotherProperties(mother);
620 motherPDG = mother->
pdgId();
626 if (
info)
info->setMotherProperties(mother);
627 auto DP = DecayProducts(partOriVert);
628 int NumOfPhot = DP.pd(22);
629 int NumOfEl = DP.pd(11);
630 int NumOfPos = DP.pd(-11);
631 int NumOfElNeut = DP.apd(12);
632 int NumOfMuNeut = DP.apd(14);
633 int NumOfLQ = DP.apd(42);
634 int NumOfquark = DP.apd({1,2,3,4,5,6});
635 int NumOfgluon = DP.apd(21);
636 int NumOfMuPl = DP.pd(-13);
637 int NumOfMuMin = DP.pd(13);
638 int NumOfTau = DP.apd(15);
639 int NumOfTauNeut = DP.apd(16);
640 if (std::abs(motherPDG) == 211 && numOfDaug == 2 && NumOfMuNeut == 1)
return PionDecay;
641 if (std::abs(motherPDG) == 321 && numOfDaug == 2 && NumOfMuNeut == 1)
return KaonDecay;
648 if (std::abs(motherPDG) == 6)
return top;
650 if (abs(motherPDG) < 7 && numOfParents == 1 && numOfDaug == 3 && NumOfquark == 1 && NumOfMuNeut == 1)
return QuarkWeakDec;
658 }
while (
MC::isW(itrP) && prodVert !=
nullptr);
662 if (abs(itrP->
pdgId()) == 9900014)
return NuRMu;
669 if (motherPDG == 22 && numOfDaug == 2 && NumOfMuMin == 1 && NumOfMuPl == 1)
return PhotonConv;
674 if (numOfParents == 1 && numOfDaug > 4 && (abs(motherPDG) < 7 || motherPDG == 21)) {
675 bool isZboson =
false;
676 bool isWboson =
false;
677 bool skipnext =
false;
678 for (
unsigned int ipOut = 0; ipOut + 1 < partOriVert->
nOutgoingParticles(); ipOut++) {
684 if (!theDaug)
continue;
686 for (
unsigned int ipOut1 = ipOut + 1; ipOut1 < partOriVert->
nOutgoingParticles(); ipOut1++) {
688 if (theNextDaug !=
nullptr)
break;
690 if (!theNextDaug)
continue;
691 if (abs(theDaug->
pdgId()) == 13 && abs(theNextDaug->
pdgId()) == 13) {
693 if (thePriPart == theDaug || thePriPart == theNextDaug) {
698 }
else if (abs(theDaug->
pdgId()) == 13 && abs(theNextDaug->
pdgId()) == 14) {
700 if (thePriPart == theDaug || thePriPart == theNextDaug) {
707 if (isWboson)
return WBoson;
708 if (isZboson)
return ZBoson;
710 if (numOfParents == 2 ) {
714 if ((numOfDaug - NumOfquark - NumOfgluon) == 2 && NumOfMuPl == 1 && NumOfMuMin == 1)
return ZBoson;
718 if ((numOfDaug - NumOfquark - NumOfgluon) == 2 && (NumOfMuPl == 1 || NumOfMuMin == 1) && NumOfMuNeut == 1)
return WBoson;
721 if ((numOfDaug - NumOfquark - NumOfgluon) == 4 &&
722 (NumOfEl + NumOfPos + NumOfMuPl + NumOfMuMin + NumOfTau + NumOfElNeut + NumOfMuNeut + NumOfTauNeut == 4) &&
726 if ((numOfDaug - NumOfquark - NumOfgluon - NumOfPhot) == 6 &&
727 (NumOfEl + NumOfPos + NumOfMuPl + NumOfMuMin + NumOfTau + NumOfElNeut + NumOfMuNeut + NumOfTauNeut == 6) &&
732 if (partOriVert == mothOriVert) {
734 int NumOfMuNeuLoop = 0;
735 int NumOfLepLoop = 0;
741 if (std::abs(
pout->pdg_id()) == 13) NumOfMuLoop++;
742 if (std::abs(
pout->pdg_id()) == 14) NumOfMuNeuLoop++;
747 if (NumOfMuLoop == 2 && NumOfMuNeuLoop == 0)
return ZBoson;
748 if (NumOfMuLoop == 1 && NumOfMuNeuLoop == 1)
return WBoson;
749 if ((NumOfMuLoop == 4 && NumOfMuNeuLoop == 0) || (NumOfMuLoop == 3 && NumOfMuNeuLoop == 1) || (NumOfMuLoop == 2 && NumOfMuNeuLoop == 2))
return DiBoson;
750 if (NumOfLepLoop == 4)
return DiBoson;
755 if (abs(motherPDG) == 25)
return Higgs;
757 if (abs(motherPDG) == 35 || abs(motherPDG) == 36 || abs(motherPDG) == 37)
return HiggsMSSM;
759 if (abs(motherPDG) == 32 || abs(motherPDG) == 33 || abs(motherPDG) == 34)
return HeavyBoson;
761 if (abs(motherPDG) == 9900024)
return WBosonLRSM;
762 if (abs(motherPDG) == 9900012)
return NuREle;
763 if (abs(motherPDG) == 9900014)
return NuRMu;
764 if (abs(motherPDG) == 9900016)
return NuRTau;
765 if (abs(motherPDG) == 42 || NumOfLQ != 0)
return LQ;
796 if (numOfParents > 1)
ATH_MSG_DEBUG(
"DefOrigOfTau:: tau has more than one mother ");
799 if (
info)
info->setMotherProperties(mother);
808 if (
MC::isW(motherPDG) && mothOriVert !=
nullptr) {
813 pPDG = MotherParent->
pdgId();
814 if (abs(pPDG) == 6) {
815 mother = MotherParent;
816 if (
info)
info->setMotherProperties(mother);
821 motherPDG = mother->
pdgId();
822 if (
info)
info->setMotherProperties(mother);
828 auto DP = DecayProducts(partOriVert);
829 int numOfDaug = DP.size();
830 int NumOfPhot = DP.pd(22);
831 int NumOfEl = DP.pd(11);
832 int NumOfPos = DP.pd(-11);
833 int NumOfElNeut = DP.apd(12);
834 int NumOfMuNeut = DP.apd(14);
836 int NumOfquark = DP.apd({1,2,3,4,5,6});
837 int NumOfgluon = DP.apd(21);
838 int NumOfMuPl = DP.pd(-13);
839 int NumOfMuMin = DP.pd(13);
840 int NumOfTau = DP.apd(15);
841 int NumOfTauNeut = DP.pd(16);
843 if (abs(motherPDG) == 6)
return top;
850 }
while (
MC::isW(itrP) && prodVert !=
nullptr);
854 if (abs(itrP->
pdgId()) == 9900014)
return NuRMu;
861 if (numOfParents == 1 && numOfDaug > 4 && (abs(motherPDG) < 7 || motherPDG == 21)) {
862 bool isZboson =
false;
863 bool isWboson =
false;
864 bool skipnext =
false;
865 for (
unsigned int ipOut = 0; ipOut + 1 < partOriVert->
nOutgoingParticles(); ipOut++) {
871 if (!theDaug)
continue;
873 for (
unsigned int ipOut1 = ipOut + 1; ipOut1 < partOriVert->
nOutgoingParticles(); ipOut1++) {
875 if (theNextDaug !=
nullptr)
break;
880 if (abs(theDaug->
pdgId()) == 15 && abs(theNextDaug->
pdgId()) == 15) {
882 if (thePriPart == theDaug || thePriPart == theNextDaug) {
887 }
else if (abs(theDaug->
pdgId()) == 15 && abs(theNextDaug->
pdgId()) == 16) {
889 if (thePriPart == theDaug || thePriPart == theNextDaug) {
896 if (isWboson)
return WBoson;
897 if (isZboson)
return ZBoson;
899 if (numOfParents == 2 ) {
906 if ((numOfDaug - NumOfquark - NumOfgluon) == 2 && NumOfTau == 1 && NumOfTauNeut == 1)
return WBoson;
909 if ((numOfDaug - NumOfquark - NumOfgluon) == 4 &&
910 (NumOfEl + NumOfPos + NumOfMuPl + NumOfMuMin + NumOfTau + NumOfElNeut + NumOfMuNeut + NumOfTauNeut == 4) &&
914 if ((numOfDaug - NumOfquark - NumOfgluon - NumOfPhot) == 6 &&
915 (NumOfEl + NumOfPos + NumOfMuPl + NumOfMuMin + NumOfTau + NumOfElNeut + NumOfMuNeut + NumOfTauNeut == 6) &&
919 if (partOriVert == mothOriVert) {
920 int NumOfTauLoop = 0;
921 int NumOfTauNeuLoop = 0;
922 int NumOfLepLoop = 0;
925 for (
const auto *
const pin: partOriVert->
particles_in()) {
928 if (std::abs(
pout->pdgId()) == 15) NumOfTauLoop++;
929 if (std::abs(
pout->pdgId()) == 16) NumOfTauNeuLoop++;
933 if (NumOfTauLoop == 2 && NumOfTauNeuLoop == 0)
return ZBoson;
934 if (NumOfTauLoop == 1 && NumOfTauNeuLoop == 1)
return WBoson;
935 if ((NumOfTauLoop == 4 && NumOfTauNeuLoop == 0) || (NumOfTauLoop == 3 && NumOfTauNeuLoop == 1) || (NumOfTauLoop == 2 && NumOfTauNeuLoop == 2))
return DiBoson;
936 if (NumOfLepLoop == 4)
return DiBoson;
939 if (abs(motherPDG) == 25)
return Higgs;
940 if (abs(motherPDG) == 35 || abs(motherPDG) == 36 || abs(motherPDG) == 37)
return HiggsMSSM;
941 if (abs(motherPDG) == 32 || abs(motherPDG) == 33 || abs(motherPDG) == 34)
return HeavyBoson;
942 if (abs(motherPDG) == 9900024)
return WBosonLRSM;
943 if (abs(motherPDG) == 9900016)
return NuRTau;
946 if (abs(motherPDG) == 443)
return JPsi;
965 info->resetMotherProperties();
966 info->photonMother =
nullptr;
967 info->photonMotherBarcode = 0;
968 info->photonMotherPDG = 0;
969 info->photonMotherStatus = 0;
987 if (
info)
info->setMotherProperties(mother);
989 int motherPDG = mother->
pdgId();
991 int motherStatus = mother->
status();
992 if (
info)
info->setMotherProperties(mother);
1006 long NumOfPartons(0);
1009 if (!
pout)
continue;
1010 DaugType =
pout->pdg_id();
1011 if (numOfParents == 1 && (motherPDG == 22 || abs(motherPDG) == 11 || abs(motherPDG) == 211) &&
1012 (DaugType > 1000000000 || DaugType == 0 || DaugType == 2212 || DaugType == 2112))
1014 if (DaugType == 22) NumOfPht++;
1015 if (DaugType == 11) NumOfEl++;
1016 if (DaugType == -11) NumOfPos++;
1017 if (abs(DaugType) == 13) NumOfMu++;
1018 if (abs(DaugType) == 15) NumOfTau++;
1019 if (abs(DaugType) == 42) NumOfLQ++;
1020 if (abs(DaugType) == 11 || abs(DaugType) == 13 || abs(DaugType) == 15) NumOfLep++;
1021 if (abs(DaugType) == 12 || abs(DaugType) == 14 || abs(DaugType) == 16) NumOfNeut++;
1022 if (abs(DaugType) < 11 || (abs(DaugType) > 16 && abs(DaugType) < 43 && abs(DaugType) != 22)) NumOfPartons++;
1023 if (DaugType == motherPDG) {
1028 bool foundISR =
false;
1029 bool foundFSR =
false;
1031 if (numOfParents == 1 && numOfDaug == 2 && abs(motherPDG) == 11 && NumOfPht == 2)
return ElMagProc;
1034 if (numOfParents == 1 && numOfDaug == 2 && (abs(motherPDG) == 11 || abs(motherPDG) == 13 || abs(motherPDG) == 15) &&
1045 PartPDG = abs(pin->pdgId());
1046 prodVert = pin->prodVtx();
1047 if (PartPDG == 23 || PartPDG == 24 || PartPDG == 25) foundFSR =
true;
1054 }
while (prodVert !=
nullptr && abs(motherPDG) == PartPDG);
1064 if ((numOfParents == 1 && (abs(motherPDG) == 22 || abs(motherPDG) == 11) && numOfDaug > 2 && NumOfNucFr != 0) ||
1065 (numOfParents == 1 && abs(motherPDG) == 211 && numOfDaug > 10 && NumOfNucFr != 0) ||
1066 (numOfParents == 1 && motherPDG == 22 && numOfDaug > 10 && motherStatus == 1) ||
1067 (numOfParents == 1 && motherPDG > 1000000000))
1073 if (numOfParents == 1 && motherStatus == 3)
return (foundISR)?
ISRPhot:
UndrPhot;
1077 if (numOfParents == 1 && (abs(motherPDG) < 7 || motherPDG == 21) &&
1078 (numOfDaug != NumOfPht + NumOfPartons ||
1079 (motherStatus != 62 && motherStatus != 52 && motherStatus != 21 && motherStatus != 22))) {
1081 if (!
pout)
continue;
1082 if (motherPDG !=
pout->pdgId())
continue;
1084 if (!Vrtx)
continue;
1097 if (numOfParents == 2 && ((abs(motherPDG) == 11 && NumOfEl == 1 && NumOfPos == 1) || (abs(motherPDG) == 13 && NumOfMu == 2) || (abs(motherPDG) == 15 && NumOfTau == 2))) {
1101 if (numOfParents == 2 && NumOfLep == 1 && NumOfNeut == 1 && (abs(motherPDG) == 11 || abs(motherPDG) == 12))
return FSRPhot;
1104 if (abs(motherPDG) == 11 && numOfParents == 1 && numOfDaug == 2 && (NumOfEl == 1 || NumOfPos == 1) && NumOfPht == 1 &&
1109 if (
MC::isZ(motherPDG) && ((NumOfEl + NumOfPos == 2 || NumOfEl + NumOfPos == 4) || (NumOfMu == 2 || NumOfMu == 4) || (NumOfTau == 2 || NumOfTau == 4)) && NumOfPht > 0)
return FSRPhot;
1111 if (NumOfPht > 0 && (abs(motherPDG) == 9900024 || abs(motherPDG) == 9900012 || abs(motherPDG) == 9900014 || abs(motherPDG) == 9900016))
return FSRPhot;
1113 if (numOfParents == 2 && NumOfLQ == 1)
return FSRPhot;
1120 if (NumOfLep == 1 && NumOfNeut == 1 && numOfDaug == NumOfLep + NumOfNeut + NumOfPht)
return FSRPhot;
1128 }
while (
MC::isW(itrP) && prodVert !=
nullptr);
1133 if ( abs(itrP->
pdgId()) == 9900012)
return NuREle;
1134 if ( abs(itrP->
pdgId()) == 9900014)
return NuRMu;
1135 if ( abs(itrP->
pdgId()) == 9900016)
return NuRTau;
1142 if (numOfParents == 1 && numOfDaug > 4 && (abs(motherPDG) < 7 || motherPDG == 21)) {
1143 bool isZboson =
false;
1144 bool isWboson =
false;
1145 bool skipnext =
false;
1146 for (
unsigned int ipOut = 0; ipOut + 1 < partOriVert->
nOutgoingParticles(); ipOut++) {
1152 if (!theDaug)
continue;
1154 for (
unsigned int ipOut1 = ipOut + 1; ipOut1 < partOriVert->
nOutgoingParticles(); ipOut1++) {
1156 if (theNextDaug !=
nullptr)
break;
1158 if (!theNextDaug)
continue;
1159 if (abs(theDaug->
pdgId()) == 15 && abs(theNextDaug->
pdgId()) == 15) {
1161 if (thePriPart == theDaug || thePriPart == theNextDaug) {
1166 }
else if (abs(theDaug->
pdgId()) == 15 && abs(theNextDaug->
pdgId()) == 16) {
1168 if (thePriPart == theDaug || thePriPart == theNextDaug) {
1175 if (isWboson)
return WBoson;
1176 if (isZboson)
return ZBoson;
1180 if (numOfParents == 4 && (numOfDaug - NumOfPht) == 4 && (NumOfLep + NumOfNeut == 4)) {
1187 if (partOriVert == mothOriVert && partOriVert !=
nullptr) {
1188 int NumOfPhtLoop = 0;
1190 if (!
pout)
continue;
1191 for (
const auto *
const pin: partOriVert->
particles_in()) {
1199 if (abs(motherPDG) == 25)
return Higgs;
1200 if (abs(motherPDG) == 111)
return PiZero;
1201 if (abs(motherPDG) == 35 || abs(motherPDG) == 36 || abs(motherPDG) == 37)
return HiggsMSSM;
1202 if (abs(motherPDG) == 32 || abs(motherPDG) == 33 || abs(motherPDG) == 34 || abs(motherPDG) == 5100039 )
return HeavyBoson;
1208 if ((motherStatus == 62 || motherStatus == 52 || motherStatus == 21 || motherStatus == 22) &&
MC::isStable(thePriPart) && NumOfPht == 1 && numOfDaug == (NumOfPht + NumOfPartons))
return PromptPhot;
1224 int nuFlav = abs(thePart->
pdgId());
1238 int numOfParents = -1;
1240 if (numOfParents > 1)
ATH_MSG_DEBUG(
"DefOrigOfNeutrino:: neutrino has more than one mother ");
1245 int motherPDG = mother->
pdgId();
1249 bool samePart =
false;
1252 if ((abs(motherPDG) == nuFlav || abs(motherPDG) == 15 ||
MC::isW(motherPDG)) && mothOriVert !=
nullptr &&
1264 mother_endVtx = mother->
decayVtx();
1270 parent_endVtx = MotherParent->
decayVtx();
1272 if (mother_endVtx == parent_prdVtx && mother_prdVtx == parent_endVtx) {
1273 MotherParent = mother;
1278 pPDG = MotherParent->
pdgId();
1281 if (mother == MotherParent) {
1284 if (abs(pPDG) == nuFlav || abs(pPDG) == 15 || abs(pPDG) == 24 ) {
1285 mother = MotherParent;
1286 if (
info)
info->setMotherProperties(mother);
1289 }
while ((std::abs(pPDG) == nuFlav || std::abs(pPDG) == 15 || std::abs(pPDG) == 24));
1291 if (std::abs(pPDG) == nuFlav || std::abs(pPDG) == 15 || std::abs(pPDG) == 24 || std::abs(pPDG) == 23 || std::abs(pPDG) == 25 ||
1292 std::abs(pPDG) == 35 || std::abs(pPDG) == 36 || std::abs(pPDG) == 37 || std::abs(pPDG) == 32 || std::abs(pPDG) == 33 ||
1293 std::abs(pPDG) == 34 || std::abs(pPDG) == 6 || std::abs(pPDG) == 9900024 || std::abs(pPDG) == 9900012 || std::abs(pPDG) == 9900014 ||
1294 std::abs(pPDG) == 9900016 || (std::abs(pPDG) < 2000040 && std::abs(pPDG) > 1000001)) {
1295 mother = MotherParent;
1296 if (
info)
info->setMotherProperties(mother);
1302 motherPDG = mother->
pdgId();
1308 if (
info)
info->setMotherProperties(mother);
1316 int NumOfTauNeut(0);
1323 if (!theDaug)
continue;
1324 int DaugType = theDaug->pdgId();
1325 if (abs(DaugType) < 7) NumOfquark++;
1326 if (abs(DaugType) == 21) NumOfgluon++;
1327 if (abs(DaugType) == 12) NumOfElNeut++;
1328 if (std::abs(DaugType) == 14) NumOfMuNeut++;
1329 if (std::abs(DaugType) == 16) NumOfTauNeut++;
1330 if (DaugType == 22) NumOfPhot++;
1331 if (std::abs(DaugType) == 11) NumOfEl++;
1332 if (std::abs(DaugType) == 13) NumOfMu++;
1333 if (std::abs(DaugType) == 15) NumOfTau++;
1334 if (std::abs(DaugType) == 42) NumOfLQ++;
1339 if (
MC::isQuark(motherPDG) && numOfParents == 1 && numOfDaug == 3 && NumOfquark == 1 && (NumOfEl == 1 || NumOfMu == 1 || NumOfTau == 1))
return QuarkWeakDec;
1340 if (std::abs(motherPDG) == 6)
return top;
1348 }
while (
MC::isW(ptrPart) && prodVert !=
nullptr);
1351 if (abs(ptrPart->
pdgId()) == 9900012)
return NuREle;
1352 if (abs(ptrPart->
pdgId()) == 9900014)
return NuRMu;
1353 if (abs(ptrPart->
pdgId()) == 9900016)
return NuRTau;
1363 if (numOfParents == 1 && numOfDaug > 4 && (abs(motherPDG) < 7 || motherPDG == 21)) {
1368 if (abs(theMother->
pdgId()) == 11 &&
MC::isDecayed(theMother)) thePartToCheck = theMother;
1369 bool isZboson =
false;
1370 bool isWboson =
false;
1371 bool skipnext =
false;
1373 for (
unsigned int ipOut = 0; ipOut + 1 < partOriVert->
nOutgoingParticles(); ++ipOut) {
1375 if (!theDaug)
continue;
1377 for (
unsigned int ipOut1 = ipOut + 1; ipOut1 < partOriVert->
nOutgoingParticles(); ipOut1++) {
1379 if (theNextDaug !=
nullptr)
break;
1381 if (!theNextDaug)
continue;
1388 int apdgID1 = abs(theDaug->
pdgId());
1389 int apdgID2 = abs(theNextDaug->
pdgId());
1390 if ((apdgID1 == 12 && apdgID2 == 12) || (apdgID1 == 14 && apdgID2 == 14) || (apdgID1 == 16 && apdgID2 == 16)) {
1392 if (thePartToCheck == theDaug || thePartToCheck == theNextDaug) {
1397 }
else if ((apdgID1 == 11 && apdgID2 == 12) || (apdgID1 == 14 && apdgID2 == 14) ||
1398 (apdgID1 == 16 && apdgID2 == 16)) {
1400 if (thePartToCheck == theDaug || thePartToCheck == theNextDaug) {
1407 if (isWboson)
return WBoson;
1408 if (isZboson)
return ZBoson;
1411 if (numOfParents == 2) {
1415 if ( (numOfDaug - NumOfquark - NumOfgluon) == 2 && (NumOfElNeut == 2 || NumOfMuNeut == 2 || NumOfTauNeut == 2))
return ZBoson;
1418 if ((numOfDaug - NumOfquark - NumOfgluon) == 2 && ((NumOfEl == 1 && NumOfElNeut == 1) || (NumOfMu == 1 && NumOfMuNeut == 1) || (NumOfTau == 1 && NumOfTauNeut == 1)))
return WBoson;
1421 if ( (numOfDaug - NumOfquark - NumOfgluon) == 4 && (NumOfEl + NumOfMu + NumOfTau + NumOfElNeut + NumOfMuNeut + NumOfTauNeut == 4) &&
1425 if ((numOfDaug - NumOfquark - NumOfgluon - NumOfPhot) == 6 && (NumOfEl + NumOfMu + NumOfTau + NumOfElNeut + NumOfMuNeut + NumOfTauNeut == 6) &&
1430 if (partOriVert == mothOriVert && partOriVert !=
nullptr) {
1431 int NumOfLepLoop = 0;
1432 int NumOfNeuLoop = 0;
1434 if (!
pout)
continue;
1435 for (
const auto *
const pin: partOriVert->
particles_in()) {
1438 int apdgid = abs(
pout->pdgId());
1439 if (apdgid == 12 || apdgid == 14 || apdgid == 16) NumOfNeuLoop++;
1440 if (apdgid == 11 || apdgid == 13 || apdgid == 15) NumOfLepLoop++;
1443 if (NumOfNeuLoop == 2 && NumOfLepLoop == 0)
return ZBoson;
1444 if (NumOfNeuLoop == 1 && NumOfLepLoop == 1)
return WBoson;
1445 if (NumOfNeuLoop + NumOfLepLoop == 4)
return DiBoson;
1450 if (abs(motherPDG) == 25)
return Higgs;
1451 if (abs(motherPDG) == 35 || abs(motherPDG) == 36 || abs(motherPDG) == 37)
return HiggsMSSM;
1452 if (abs(motherPDG) == 32 || abs(motherPDG) == 33 || abs(motherPDG) == 34)
return HeavyBoson;
1454 if (abs(motherPDG) == 15) {
1460 if (abs(motherPDG) == 9900024)
return WBosonLRSM;
1461 if (abs(motherPDG) == 9900012)
return NuREle;
1462 if (abs(motherPDG) == 9900014)
return NuRMu;
1463 if (abs(motherPDG) == 9900016)
return NuRTau;
1464 if (abs(motherPDG) == 42 || NumOfLQ != 0)
return LQ;
1475 std::pair<ParticleType, ParticleOrigin>
1480 std::pair<ParticleType, ParticleOrigin>
part;
1481 part.first = Unknown;
1483 if (theEle ==
nullptr)
return part;
1487 if (!truthParticleContainerReadHandle.
isValid()) {
1488 ATH_MSG_WARNING(
" Invalid ReadHandle for xAOD::TruthParticleContainer with key: " << truthParticleContainerReadHandle.
key());
1492 ATH_MSG_DEBUG(
"xAODTruthParticleContainer with key " << truthParticleContainerReadHandle.
key() <<
" has valid ReadHandle ");
1496 part = particleTruthClassifier(theEle,
info);
1505 if (theMotherPart ==
nullptr || theMotherPart == thePart)
break;
1506 thePart = theMotherPart;
1507 part.first = Unknown;
1509 part = particleTruthClassifier(thePart,
info);
1518 if (thePart !=
nullptr)
part = particleTruthClassifier(thePart,
info);
1528 if (thePart !=
nullptr)
part = particleTruthClassifier(thePart,
info);
1531 info->bkgElecMother = thePart;