9 #include "Pythia8/Event.h"
24 const double Particle::TINY = 1e-20;
30 void Particle::setPDEPtr(ParticleDataEntry* pdePtrIn) {
31 pdePtr = pdePtrIn;
if (pdePtrIn != 0 || evtPtr == 0)
return;
32 pdePtr = (*evtPtr).particleDataPtr->particleDataEntryPtr( idSave);}
38 int Particle::intPol()
const {
40 double smallDbls[6] = { 0., 1., -1., 2., -2., 9.};
41 int smallInts[6] = { 0, 1, -1, 2, -2, 9 };
42 for (
int iPol = 0; iPol < 6; ++ iPol)
43 if (abs(polSave - smallDbls[iPol]) < 1e-10)
return smallInts[iPol];
52 double Particle::y()
const {
53 double temp = log( ( pSave.e() + abs(pSave.pz()) ) / max( TINY, mT() ) );
54 return (pSave.pz() > 0.) ? temp : -temp;
57 double Particle::eta()
const {
58 double temp = log( ( pSave.pAbs() + abs(pSave.pz()) ) / max( TINY, pT() ) );
59 return (pSave.pz() > 0.) ? temp : -temp;
64 double Particle::y(
double mCut)
const {
65 double mTmin = max( mCut, mT() );
66 double eMin = sqrt( pow2(mTmin) + pow2(pSave.pz()) );
67 double temp = log( ( eMin + abs(pSave.pz()) ) / mTmin );
68 return (pSave.pz() > 0.) ? temp : -temp;
71 double Particle::y(
double mCut, RotBstMatrix& M)
const {
74 double mTmin = max( mCut, sqrt( m2() + pCopy.pT2()) );
75 double eMin = sqrt( pow2(mTmin) + pow2(pCopy.pz()) );
76 double temp = log( ( eMin + abs(pCopy.pz()) ) / mTmin );
77 return (pCopy.pz() > 0.) ? temp : -temp;
84 int Particle::index()
const {
if (evtPtr == 0)
return -1;
85 return (
long(
this) -
long(&((*evtPtr)[0]))) /
sizeof(Particle);
92 int Particle::iTopCopy()
const {
94 if (evtPtr == 0)
return -1;
96 while ( iUp > 0 && (*evtPtr)[iUp].mother2() == (*evtPtr)[iUp].mother1()
97 && (*evtPtr)[iUp].mother1() > 0) iUp = (*evtPtr)[iUp].mother1();
102 int Particle::iBotCopy()
const {
104 if (evtPtr == 0)
return -1;
106 while ( iDn > 0 && (*evtPtr)[iDn].daughter2() == (*evtPtr)[iDn].daughter1()
107 && (*evtPtr)[iDn].daughter1() > 0) iDn = (*evtPtr)[iDn].daughter1();
118 int Particle::iTopCopyId(
bool simplify)
const {
121 if (evtPtr == 0)
return -1;
125 if (simplify)
for ( ; ; ) {
126 int mother1up = (*evtPtr)[iUp].mother1();
127 int id1up = (mother1up > 0) ? (*evtPtr)[mother1up].id() : 0;
128 int mother2up = (*evtPtr)[iUp].mother2();
129 int id2up = (mother2up > 0) ? (*evtPtr)[mother2up].id() : 0;
130 if (mother2up != mother1up && id2up == id1up)
return iUp;
131 if (id1up != idSave && id2up != idSave)
return iUp;
132 iUp = (id1up == idSave) ? mother1up : mother2up;
138 vector<int> mothersTmp = (*evtPtr)[iUp].motherList();
139 for (
unsigned int i = 0; i < mothersTmp.size(); ++i)
140 if ( (*evtPtr)[mothersTmp[i]].id() == idSave) {
141 if (iUpTmp != 0)
return iUp;
142 iUpTmp = mothersTmp[i];
144 if (iUpTmp == 0)
return iUp;
150 int Particle::iBotCopyId(
bool simplify)
const {
153 if (evtPtr == 0)
return -1;
157 if (simplify)
for ( ; ; ) {
158 int daughter1dn = (*evtPtr)[iDn].daughter1();
159 int id1dn = (daughter1dn > 0) ? (*evtPtr)[daughter1dn].id() : 0;
160 int daughter2dn = (*evtPtr)[iDn].daughter2();
161 int id2dn = (daughter2dn > 0) ? (*evtPtr)[daughter2dn].id() : 0;
162 if (daughter2dn != daughter1dn && id2dn == id1dn)
return iDn;
163 if (id1dn != idSave && id2dn != idSave)
return iDn;
164 iDn = (id1dn == idSave) ? daughter1dn : daughter2dn;
170 vector<int> daughtersTmp = (*evtPtr)[iDn].daughterList();
171 for (
unsigned int i = 0; i < daughtersTmp.size(); ++i)
172 if ( (*evtPtr)[daughtersTmp[i]].id() == idSave) {
173 if (iDnTmp != 0)
return iDn;
174 iDnTmp = daughtersTmp[i];
176 if (iDnTmp == 0)
return iDn;
186 vector<int> Particle::motherList()
const {
189 vector<int> motherVec;
190 if (evtPtr == 0)
return motherVec;
193 int statusSaveAbs = abs(statusSave);
194 if (statusSaveAbs == 11 || statusSaveAbs == 12) ;
195 else if (mother1Save == 0 && mother2Save == 0) motherVec.push_back(0);
198 else if (mother2Save == 0 || mother2Save == mother1Save)
199 motherVec.push_back(mother1Save);
202 else if ( (statusSaveAbs > 80 && statusSaveAbs < 90)
203 || (statusSaveAbs > 100 && statusSaveAbs < 107) )
204 for (
int iRange = mother1Save; iRange <= mother2Save; ++iRange)
205 motherVec.push_back(iRange);
209 motherVec.push_back( min(mother1Save, mother2Save) );
210 motherVec.push_back( max(mother1Save, mother2Save) );
222 vector<int> Particle::daughterList()
const {
225 vector<int> daughterVec;
226 if (evtPtr == 0)
return daughterVec;
229 if (daughter1Save == 0 && daughter2Save == 0) ;
230 else if (daughter2Save == 0 || daughter2Save == daughter1Save)
231 daughterVec.push_back(daughter1Save);
234 else if (daughter2Save > daughter1Save)
235 for (
int iRange = daughter1Save; iRange <= daughter2Save; ++iRange)
236 daughterVec.push_back(iRange);
240 daughterVec.push_back(daughter2Save);
241 daughterVec.push_back(daughter1Save);
246 if (abs(statusSave) == 12 || abs(statusSave) == 13) {
248 for (
int iDau = i + 1; iDau < evtPtr->size(); ++iDau)
249 if ((*evtPtr)[iDau].mother1() == i) {
251 for (
int iIn = 0; iIn < int(daughterVec.size()); ++iIn)
252 if (iDau == daughterVec[iIn]) isIn =
true;
253 if (!isIn) daughterVec.push_back(iDau);
267 vector<int> Particle::daughterListRecursive()
const {
270 vector<int> daughterVec;
271 if (evtPtr == 0)
return daughterVec;
274 daughterVec = daughterList();
277 int size = daughterVec.size();
278 for (
int iDau = 0; iDau < size; ++iDau) {
279 Particle& partNow = (*evtPtr)[daughterVec[iDau]];
280 if (!partNow.isFinal()) {
281 vector<int> grandDauVec = partNow.daughterList();
282 for (
int i = 0; i < int(grandDauVec.size()); ++i)
283 daughterVec.push_back( grandDauVec[i] );
284 size += grandDauVec.size();
298 vector<int> Particle::sisterList(
bool traceTopBot)
const {
301 vector<int> sisterVec;
302 if (evtPtr == 0 || abs(statusSave) == 11)
return sisterVec;
305 int iUp = (traceTopBot) ? iTopCopy() : index();
306 int iMother = (*evtPtr)[iUp].mother1();
307 vector<int> daughterVec = (*evtPtr)[iMother].daughterList();
310 for (
int j = 0; j < int(daughterVec.size()); ++j) {
311 int iDau = daughterVec[j];
313 int iDn = (traceTopBot) ? (*evtPtr)[iDau].iBotCopy() : iDau;
314 sisterVec.push_back( iDn);
329 bool Particle::isAncestor(
int iAncestor)
const {
332 if (evtPtr == 0)
return false;
334 int sizeNow = (*evtPtr).size();
338 if (iUp == iAncestor)
return true;
341 if (iUp <= 0 || iUp > sizeNow)
return false;
344 int mother1up = (*evtPtr)[iUp].mother1();
345 int mother2up = (*evtPtr)[iUp].mother2();
346 if (mother2up == mother1up || mother2up == 0) {iUp = mother1up;
continue;}
349 int statusUp = (*evtPtr)[iUp].statusAbs();
350 if (statusUp < 81 || statusUp > 86)
return false;
353 if (statusUp == 82) {
354 iUp = (iUp + 1 < sizeNow && (*evtPtr)[iUp + 1].mother1() == mother1up)
355 ? mother1up : mother2up;
continue;
357 if (statusUp == 83) {
358 if ((*evtPtr)[iUp - 1].mother1() == mother1up)
return false;
359 iUp = mother1up;
continue;
361 if (statusUp == 84) {
362 if (iUp + 1 < sizeNow && (*evtPtr)[iUp + 1].mother1() == mother1up)
364 iUp = mother1up;
continue;
380 int Particle::statusHepMC()
const {
383 if (statusSave > 0)
return 1;
384 if (statusSave == -12)
return 4;
385 if (evtPtr == 0)
return 0;
388 if (isHadron() || abs(idSave) == 13 || abs(idSave) == 15) {
390 if ( (*evtPtr)[daughter1Save].
id() != idSave) {
391 int statusDau = (*evtPtr)[daughter1Save].statusAbs();
392 if (statusDau > 90 && statusDau < 95)
return 2;
397 if (statusSave <= -11 && statusSave >= -200)
return -statusSave;
408 bool Particle::isFinalPartonLevel()
const {
410 if (index() >= evtPtr->savedPartonLevelSize)
return false;
411 if (statusSave > 0)
return true;
412 if (daughter1Save >= evtPtr->savedPartonLevelSize)
return true;
423 bool Particle::undoDecay() {
426 if (evtPtr == 0)
return false;
428 if (i < 0 || i >=
int((*evtPtr).size()))
return false;
429 if (colSave != 0 || acolSave != 0)
return false;
432 int dau1 = daughter1Save;
433 if (dau1 == 0)
return false;
434 int dau2 = daughter2Save;
435 if (dau2 == 0) dau2 = dau1;
438 for (
int j = dau1; j <= dau2; ++j)
if ((*evtPtr)[j].mother1() != i
439 || ((*evtPtr)[j].mother2() != i && (*evtPtr)[j].mother2() != 0) )
443 vector<int> dauBeg, dauEnd;
444 dauBeg.push_back( dau1);
445 dauEnd.push_back( dau2);
450 for (
int j = dauBeg[iRange]; j <= dauEnd[iRange]; ++j)
451 if ((*evtPtr)[j].status() < 0) {
454 dau1 = (*evtPtr)[j].daughter1();
455 if (dau1 == 0)
return false;
456 dau2 = (*evtPtr)[j].daughter2();
457 if (dau2 == 0) dau2 = dau1;
461 for (
int iR = 0; iR < int(dauBeg.size()); ++iR) {
462 if (dau1 == dauBeg[iR] && dau2 == dauEnd[iR]) isNew =
false;
463 else if (dau1 >= dauBeg[iR] && dau1 <= dauEnd[iR])
return false;
464 else if (dau2 >= dauBeg[iR] && dau2 <= dauEnd[iR])
return false;
469 dauBeg.push_back( dau1);
470 dauEnd.push_back( dau2);
471 for (
int iR =
int(dauBeg.size()) - 1; iR > 0; --iR) {
472 if (dauBeg[iR] < dauBeg[iR - 1]) {
473 swap( dauBeg[iR], dauBeg[iR - 1]);
474 swap( dauEnd[iR], dauEnd[iR - 1]);
481 }
while (++iRange <
int(dauBeg.size()));
484 if (
int(dauBeg.size()) > 1) {
487 if (dauEnd[iRJ] + 1 == dauBeg[iRJ + 1]) {
488 for (
int iRB = iRJ + 1; iRB < int(dauBeg.size()) - 1; ++iRB)
489 dauBeg[iRB] = dauBeg[iRB + 1];
490 for (
int iRE = iRJ; iRE < int(dauEnd.size()) - 1; ++iRE)
491 dauEnd[iRE] = dauEnd[iRE + 1];
495 }
while (iRJ <
int(dauBeg.size()) - 1);
499 for (
int iR =
int(dauBeg.size()) - 1; iR >= 0; --iR) {
502 (*evtPtr).remove( dauBeg[iR], dauEnd[iR]);
506 statusSave = abs(statusSave);
519 string Particle::nameWithStatus(
int maxLen)
const {
521 if (pdePtr == 0)
return " ";
522 string temp = (statusSave > 0) ? pdePtr->name(idSave)
523 :
"(" + pdePtr->name(idSave) +
")";
524 while (
int(temp.length()) > maxLen) {
526 int iRem = temp.find_last_not_of(
")+-0");
536 void Particle::offsetHistory(
int minMother,
int addMother,
int minDaughter,
539 if (addMother < 0 || addDaughter < 0)
return;
540 if ( mother1Save > minMother ) mother1Save += addMother;
541 if ( mother2Save > minMother ) mother2Save += addMother;
542 if (daughter1Save > minDaughter) daughter1Save += addDaughter;
543 if (daughter2Save > minDaughter) daughter2Save += addDaughter;
551 void Particle::offsetCol(
int addCol) {
553 if (addCol < 0)
return;
554 if ( colSave > 0) colSave += addCol;
555 if (acolSave > 0) acolSave += addCol;
564 double m(
const Particle& pp1,
const Particle& pp2) {
565 double m2 = pow2(pp1.e() + pp2.e()) - pow2(pp1.px() + pp2.px())
566 - pow2(pp1.py() + pp2.py()) - pow2(pp1.pz() + pp2.pz());
567 return (m2 > 0. ? sqrt(m2) : 0.);
570 double m2(
const Particle& pp1,
const Particle& pp2) {
571 double m2 = pow2(pp1.e() + pp2.e()) - pow2(pp1.px() + pp2.px())
572 - pow2(pp1.py() + pp2.py()) - pow2(pp1.pz() + pp2.pz());
587 const int Event::IPERLINE = 20;
593 Event& Event::operator=(
const Event& oldEvent) {
596 if (
this != &oldEvent) {
602 particleDataPtr = oldEvent.particleDataPtr;
606 for (
int i = 0; i < oldEvent.size(); ++i) append( oldEvent[i] );
609 for (
int i = 0; i < oldEvent.sizeJunction(); ++i)
610 appendJunction( oldEvent.getJunction(i) );
613 startColTag = oldEvent.startColTag;
614 maxColTag = oldEvent.maxColTag;
615 savedSize = oldEvent.savedSize;
616 savedJunctionSize = oldEvent.savedJunctionSize;
617 scaleSave = oldEvent.scaleSave;
618 scaleSecondSave = oldEvent.scaleSecondSave;
619 headerList = oldEvent.headerList;
635 int Event::copy(
int iCopy,
int newStatus) {
639 if (iCopy < 0 || iCopy >= size())
return -1;
642 entry.push_back(entry[iCopy]);
643 int iNew = entry.size() - 1;
647 entry[iCopy].daughters(iNew,iNew);
648 entry[iCopy].statusNeg();
649 entry[iNew].mothers(iCopy, iCopy);
650 entry[iNew].status(newStatus);
653 }
else if (newStatus < 0) {
654 entry[iCopy].mothers(iNew,iNew);
655 entry[iNew].daughters(iCopy, iCopy);
656 entry[iNew].status(newStatus);
669 void Event::remove(
int iFirst,
int iLast,
bool shiftHistory) {
672 if (iFirst < 0 || iLast >=
int(entry.size()) || iLast < iFirst)
return;
673 int nRem = iLast + 1 - iFirst;
676 entry.erase( entry.begin() + iFirst, entry.begin() + iLast + 1);
679 if (shiftHistory)
for (
int i = 0; i < int(entry.size()); ++i) {
680 int iMot1 = entry[i].mother1();
681 int iMot2 = entry[i].mother2();
682 int iDau1 = entry[i].daughter1();
683 int iDau2 = entry[i].daughter2();
687 if (iMot1 > iLast) iMot1 -= nRem;
688 else if (iMot1 >= iFirst) iMot1 = 0;
689 if (iMot2 > iLast) iMot2 -= nRem;
690 else if (iMot2 >= iFirst) iMot2 = 0;
691 if (iDau1 > iLast) iDau1 -= nRem;
692 else if (iDau1 >= iFirst) iDau1 = 0;
693 if (iDau2 > iLast) iDau2 -= nRem;
694 else if (iDau2 >= iFirst) iDau2 = 0;
697 entry[i].mothers(iMot1, iMot2);
698 entry[i].daughters(iDau1, iDau2);
707 void Event::list(
bool showScaleAndVertex,
bool showMothersAndDaughters,
708 int precision)
const {
711 cout <<
"\n -------- PYTHIA Event Listing " << headerList <<
"----------"
712 <<
"-------------------------------------------------\n \n no "
713 <<
" id name status mothers daughters colou"
714 <<
"rs p_x p_y p_z e m \n";
715 if (showScaleAndVertex)
716 cout <<
" scale pol "
717 <<
" xProd yProd zProd tProd "
721 int prec = max( 3, precision);
722 bool useFixed = (entry.empty() || entry[0].e() < 1e5);
726 double chargeSum = 0.;
727 for (
int i = 0; i < int(entry.size()); ++i) {
728 const Particle& pt = entry[i];
731 cout << setw(6) << i << setw(11) << pt.id() <<
" " << left
732 << setw(18) << pt.nameWithStatus(18) << right << setw(4)
733 << pt.status() << setw(6) << pt.mother1() << setw(6)
734 << pt.mother2() << setw(6) << pt.daughter1() << setw(6)
735 << pt.daughter2() << setw(6) << pt.col() << setw(6) << pt.acol()
736 << ( (useFixed) ? fixed : scientific ) << setprecision(prec)
737 << setw(8+prec) << pt.px() << setw(8+prec) << pt.py()
738 << setw(8+prec) << pt.pz() << setw(8+prec) << pt.e()
739 << setw(8+prec) << pt.m() <<
"\n";
742 if (showScaleAndVertex)
743 cout <<
" " << setw(8+prec) << pt.scale()
744 <<
" " << fixed << setprecision(prec) << setw(8+prec) << pt.pol()
745 <<
" " << scientific << setprecision(prec)
746 << setw(8+prec) << pt.xProd() << setw(8+prec) << pt.yProd()
747 << setw(8+prec) << pt.zProd() << setw(8+prec) << pt.tProd()
748 << setw(8+prec) << pt.tau() <<
"\n";
751 if (showMothersAndDaughters) {
754 vector<int> allMothers = pt.motherList();
755 for (
int j = 0; j < int(allMothers.size()); ++j) {
756 cout <<
" " << allMothers[j];
757 if (++linefill == IPERLINE) {
762 cout <<
"; daughters:";
763 vector<int> allDaughters = pt.daughterList();
764 for (
int j = 0; j < int(allDaughters.size()); ++j) {
765 cout <<
" " << allDaughters[j];
766 if (++linefill == IPERLINE) {
771 if (linefill !=0) cout <<
"\n";
775 if (showScaleAndVertex || showMothersAndDaughters) cout <<
"\n";
778 if (entry[i].status() > 0) {
779 pSum += entry[i].p();
780 chargeSum += entry[i].charge();
785 cout << fixed << setprecision(3) <<
" "
786 <<
"Charge sum:" << setw(7) << chargeSum <<
" Momentum sum:"
787 << ( (useFixed) ? fixed : scientific ) << setprecision(prec)
788 << setw(8+prec) << pSum.px() << setw(8+prec) << pSum.py()
789 << setw(8+prec) << pSum.pz() << setw(8+prec) << pSum.e()
790 << setw(8+prec) << pSum.mCalc() <<
"\n";
793 cout <<
"\n -------- End PYTHIA Event Listing ----------------------------"
794 <<
"-------------------------------------------------------------------"
802 void Event::eraseJunction(
int i) {
804 for (
int j = i; j < int(junction.size()) - 1; ++j)
805 junction[j] = junction[j + 1];
814 void Event::listJunctions()
const {
817 cout <<
"\n -------- PYTHIA Junction Listing "
818 << headerList.substr(0,30) <<
"\n \n no kind col0 col1 col2 "
819 <<
"endc0 endc1 endc2 stat0 stat1 stat2\n";
822 for (
int i = 0; i < sizeJunction(); ++i)
823 cout << setw(6) << i << setw(6) << kindJunction(i) << setw(6)
824 << colJunction(i, 0) << setw(6) << colJunction(i, 1) << setw(6)
825 << colJunction(i, 2) << setw(6) << endColJunction(i, 0) << setw(6)
826 << endColJunction(i, 1) << setw(6) << endColJunction(i, 2) << setw(6)
827 << statusJunction(i, 0) << setw(6) << statusJunction(i, 1) << setw(6)
828 << statusJunction(i, 2) <<
"\n";
831 if (sizeJunction() == 0) cout <<
" no junctions present \n";
832 cout <<
"\n -------- End PYTHIA Junction Listing --------------------"
840 Event& Event::operator+=(
const Event& addEvent) {
843 int offsetIdx = entry.size() - 1;
844 int offsetCol = maxColTag;
847 entry[0].p( entry[0].p() + addEvent[0].p() );
848 entry[0].m( entry[0].mCalc() );
852 for (
int i = 1; i < addEvent.size(); ++i) {
856 if (temp.mother1() > 0) temp.mother1( temp.mother1() + offsetIdx );
857 if (temp.mother2() > 0) temp.mother2( temp.mother2() + offsetIdx );
858 if (temp.daughter1() > 0) temp.daughter1( temp.daughter1() + offsetIdx );
859 if (temp.daughter2() > 0) temp.daughter2( temp.daughter2() + offsetIdx );
860 if (temp.col() > 0) temp.col( temp.col() + offsetCol );
861 if (temp.acol() > 0) temp.acol( temp.acol() + offsetCol );
870 for (
int i = 0; i < addEvent.sizeJunction(); ++i) {
871 tempJ = addEvent.getJunction(i);
874 for (
int j = 0; j < 3; ++j) {
875 begCol = tempJ.col(j);
876 endCol = tempJ.endCol(j);
877 if (begCol > 0) begCol += offsetCol;
878 if (endCol > 0) endCol += offsetCol;
879 tempJ.cols( j, begCol, endCol);
883 appendJunction( tempJ );
887 headerList =
"(combination of several events) -------";