24 const double Particle::TINY = 1e-20;
30 double Particle::y()
const {
31 double temp = log( ( pSave.e() + abs(pSave.pz()) ) / max( TINY, mT() ) );
32 return (pSave.pz() > 0) ? temp : -temp;
35 double Particle::eta()
const {
36 double temp = log( ( pSave.pAbs() + abs(pSave.pz()) ) / max( TINY, pT() ) );
37 return (pSave.pz() > 0) ? temp : -temp;
44 string Particle::nameWithStatus(
int maxLen)
const {
46 if (pdePtr == 0)
return " ";
47 string temp = (statusSave > 0) ? pdePtr->name(idSave)
48 :
"(" + pdePtr->name(idSave) +
")";
49 while (
int(temp.length()) > maxLen) {
51 int iRem = temp.find_last_not_of(
")+-0");
61 void Particle::offsetHistory(
int minMother,
int addMother,
int minDaughter,
64 if (addMother < 0 || addDaughter < 0)
return;
65 if ( mother1Save > minMother ) mother1Save += addMother;
66 if ( mother2Save > minMother ) mother2Save += addMother;
67 if (daughter1Save > minDaughter) daughter1Save += addDaughter;
68 if (daughter2Save > minDaughter) daughter2Save += addDaughter;
76 void Particle::offsetCol(
int addCol) {
78 if (addCol < 0)
return;
79 if ( colSave > 0) colSave += addCol;
80 if (acolSave > 0) acolSave += addCol;
89 double m(
const Particle& pp1,
const Particle& pp2) {
90 double m2 = pow2(pp1.e() + pp2.e()) - pow2(pp1.px() + pp2.px())
91 - pow2(pp1.py() + pp2.py()) - pow2(pp1.pz() + pp2.pz());
92 return (m2 > 0. ? sqrt(m2) : 0.);
95 double m2(
const Particle& pp1,
const Particle& pp2) {
96 double m2 = pow2(pp1.e() + pp2.e()) - pow2(pp1.px() + pp2.px())
97 - pow2(pp1.py() + pp2.py()) - pow2(pp1.pz() + pp2.pz());
112 const int Event::IPERLINE = 20;
118 Event& Event::operator=(
const Event& oldEvent) {
121 if (
this != &oldEvent) {
127 for (
int i = 0; i < oldEvent.size(); ++i) append( oldEvent[i] );
130 for (
int i = 0; i < oldEvent.sizeJunction(); ++i)
131 appendJunction( oldEvent.getJunction(i) );
134 startColTag = oldEvent.startColTag;
135 maxColTag = oldEvent.maxColTag;
136 savedSize = oldEvent.savedSize;
137 savedJunctionSize = oldEvent.savedJunctionSize;
138 scaleSave = oldEvent.scaleSave;
139 scaleSecondSave = oldEvent.scaleSecondSave;
140 headerList = oldEvent.headerList;
141 particleDataPtr = oldEvent.particleDataPtr;
157 int Event::copy(
int iCopy,
int newStatus) {
161 if (iCopy < 0 || iCopy >= size())
return -1;
164 entry.push_back(entry[iCopy]);
165 int iNew = entry.size() - 1;
169 entry[iCopy].daughters(iNew,iNew);
170 entry[iCopy].statusNeg();
171 entry[iNew].mothers(iCopy, iCopy);
172 entry[iNew].status(newStatus);
175 }
else if (newStatus < 0) {
176 entry[iCopy].mothers(iNew,iNew);
177 entry[iNew].daughters(iCopy, iCopy);
178 entry[iNew].status(newStatus);
191 void Event::list()
const {
192 list(
false,
false, cout);
195 void Event::list(ostream& os)
const {
196 list(
false,
false, os);
199 void Event::list(
bool showScaleAndVertex,
bool showMothersAndDaughters)
201 list(showScaleAndVertex, showMothersAndDaughters, cout);
208 void Event::list(
bool showScaleAndVertex,
bool showMothersAndDaughters,
212 os <<
"\n -------- PYTHIA Event Listing " << headerList <<
"----------"
213 <<
"-------------------------------------------------\n \n no "
214 <<
" id name status mothers daughters colou"
215 <<
"rs p_x p_y p_z e m \n";
216 if (showScaleAndVertex)
218 <<
" xProd yProd zProd tProd "
222 bool useFixed = (entry[0].e() < 1e5);
226 double chargeSum = 0.;
227 for (
int i = 0; i < int(entry.size()); ++i) {
228 const Particle& pt = entry[i];
231 os << setw(6) << i << setw(10) << pt.id() <<
" " << left
232 << setw(18) << pt.nameWithStatus(18) << right << setw(4)
233 << pt.status() << setw(6) << pt.mother1() << setw(6)
234 << pt.mother2() << setw(6) << pt.daughter1() << setw(6)
235 << pt.daughter2() << setw(6) << pt.col() << setw(6) << pt.acol()
236 << ( (useFixed) ? fixed : scientific ) << setprecision(3)
237 << setw(11) << pt.px() << setw(11) << pt.py() << setw(11)
238 << pt.pz() << setw(11) << pt.e() << setw(11) << pt.m() <<
"\n";
241 if (showScaleAndVertex)
242 os <<
" " << setw(11) << pt.scale()
243 <<
" " << fixed << setprecision(3) << setw(11) << pt.pol()
244 <<
" " << scientific << setprecision(3)
245 << setw(11) << pt.xProd() << setw(11) << pt.yProd()
246 << setw(11) << pt.zProd() << setw(11) << pt.tProd()
247 << setw(11) << pt.tau() <<
"\n";
250 if (showMothersAndDaughters) {
253 vector<int> allMothers = motherList(i);
254 for (
int j = 0; j < int(allMothers.size()); ++j) {
255 os <<
" " << allMothers[j];
256 if (++linefill == IPERLINE) {os <<
"\n "; linefill = 0;}
258 os <<
"; daughters:";
259 vector<int> allDaughters = daughterList(i);
260 for (
int j = 0; j < int(allDaughters.size()); ++j) {
261 os <<
" " << allDaughters[j];
262 if (++linefill == IPERLINE) {os <<
"\n "; linefill = 0;}
264 if (linefill !=0) os <<
"\n";
268 if (showScaleAndVertex || showMothersAndDaughters) os <<
"\n";
271 if (entry[i].status() > 0) {
272 pSum += entry[i].p();
273 chargeSum += entry[i].charge();
278 os << fixed << setprecision(3) <<
" "
279 <<
"Charge sum:" << setw(7) << chargeSum <<
" Momentum sum:"
280 << ( (useFixed) ? fixed : scientific ) << setprecision(3)
281 << setw(11) << pSum.px() << setw(11) << pSum.py() << setw(11)
282 << pSum.pz() << setw(11) << pSum.e() << setw(11) << pSum.mCalc()
286 os <<
"\n -------- End PYTHIA Event Listing ----------------------------"
287 <<
"-------------------------------------------------------------------"
295 vector<int> Event::motherList(
int i)
const {
301 int mother1 = entry[i].mother1();
302 int mother2 = entry[i].mother2();
303 int statusAbs = entry[i].statusAbs();
306 if (statusAbs == 11 || statusAbs == 12) ;
307 else if (mother1 == 0 && mother2 == 0) mothers.push_back(0);
310 else if (mother2 == 0 || mother2 == mother1) mothers.push_back(mother1);
313 else if ( statusAbs > 80 && statusAbs < 90)
314 for (
int iRange = mother1; iRange <= mother2; ++iRange)
315 mothers.push_back(iRange);
319 mothers.push_back( min(mother1, mother2) );
320 mothers.push_back( max(mother1, mother2) );
332 vector<int> Event::daughterList(
int i)
const {
335 vector<int> daughters;
338 int daughter1 = entry[i].daughter1();
339 int daughter2 = entry[i].daughter2();
342 if (daughter1 == 0 && daughter2 == 0) ;
343 else if (daughter2 == 0 || daughter2 == daughter1)
344 daughters.push_back(daughter1);
347 else if (daughter2 > daughter1)
348 for (
int iRange = daughter1; iRange <= daughter2; ++iRange)
349 daughters.push_back(iRange);
353 daughters.push_back(daughter2);
354 daughters.push_back(daughter1);
359 if (entry[i].statusAbs() == 12 || entry[i].statusAbs() == 13)
360 for (
int iDau = 3; iDau < size(); ++iDau)
361 if (entry[iDau].mother1() == i) {
363 for (
int iIn = 0; iIn < int(daughters.size()); ++iIn)
364 if (iDau == daughters[iIn]) isIn =
true;
365 if (!isIn) daughters.push_back(iDau);
377 int Event::statusHepMC(
int i)
const {
380 int statusNow = entry[i].status();
381 if (statusNow > 0)
return 1;
382 if (statusNow == -12)
return 4;
385 int idNow = entry[i].id();
386 if (entry[i].isHadron() || abs(idNow) == 13 || abs(idNow) == 15) {
387 int iDau = entry[i].daughter1();
389 if ( entry[iDau].
id() != idNow) {
390 int statusDau = entry[ iDau ].statusAbs();
391 if (statusDau > 90 && statusDau < 95)
return 2;
396 if (statusNow <= -11 && statusNow >= -200)
return -statusNow;
407 int Event::iTopCopy(
int i)
const {
410 while ( iUp > 0 && entry[iUp].mother2() == entry[iUp].mother1()
411 && entry[iUp].mother1() > 0) iUp = entry[iUp].mother1();
416 int Event::iBotCopy(
int i)
const {
419 while ( iDn > 0 && entry[iDn].daughter2() == entry[iDn].daughter1()
420 && entry[iDn].daughter1() > 0) iDn = entry[iDn].daughter1();
431 int Event::iTopCopyId(
int i)
const {
433 int id = entry[i].id();
436 int mother1 = entry[iUp].mother1();
437 int id1 = (mother1 > 0) ? entry[mother1].
id() : 0;
438 int mother2 = entry[iUp].mother2();
439 int id2 = (mother2 > 0) ? entry[mother2].
id() : 0;
440 if (mother2 != mother1 && id2 == id1)
break;
455 int Event::iBotCopyId(
int i)
const {
457 int id = entry[i].id();
460 int daughter1 = entry[iDn].daughter1();
461 int id1 = (daughter1 > 0) ? entry[daughter1].
id() : 0;
462 int daughter2 = entry[iDn].daughter2();
463 int id2 = (daughter2 > 0) ? entry[daughter2].
id() : 0;
464 if (daughter2 != daughter1 && id2 == id1)
break;
483 vector<int> Event::sisterList(
int i)
const {
487 if (entry[i].statusAbs() == 11)
return sisters;
490 int iMother = entry[i].mother1();
491 vector<int> daughters = daughterList(iMother);
494 for (
int j = 0; j < int(daughters.size()); ++j)
495 if (daughters[j] != i) sisters.push_back( daughters[j] );
508 vector<int> Event::sisterListTopBot(
int i,
bool widenSearch)
const {
512 if (entry[i].statusAbs() == 11)
return sisters;
515 int iUp = iTopCopy(i);
518 int iMother = entry[iUp].mother1();
519 vector<int> daughters = daughterList(iMother);
522 for (
int jD = 0; jD < int(daughters.size()); ++jD)
523 if (daughters[jD] != iUp)
524 sisters.push_back( iBotCopy( daughters[jD] ) );
528 while (jP <
int(sisters.size())) {
529 if (entry[sisters[jP]].status() > 0) ++jP;
531 sisters[jP] = sisters.back();
537 if (sisters.size() == 0 && widenSearch) {
538 for (
int jR = 0; jR < int(daughters.size()); ++jR)
539 if (daughters[jR] != iUp)
540 sisters.push_back( iBotCopy( daughters[jR] ) );
543 for (
int jT = 0; jT < int(sisters.size()); ++jT) {
544 daughters = daughterList( sisters[jT] );
545 for (
int k = 0; k < int(daughters.size()); ++k)
546 sisters.push_back( daughters[k] );
551 while (jN <
int(sisters.size())) {
552 if (entry[sisters[jN]].status() > 0) ++jN;
554 sisters[jN] = sisters.back();
571 bool Event::isAncestor(
int i,
int iAncestor)
const {
578 if (iUp == iAncestor)
return true;
581 if (iUp <= 0 || iUp > size())
return false;
584 int mother1 = entry[iUp].mother1();
585 int mother2 = entry[iUp].mother2();
586 if (mother2 == mother1 || mother2 == 0) {iUp = mother1;
continue;}
589 int status = entry[iUp].statusAbs();
590 if (status < 81 || status > 86)
return false;
594 iUp = (iUp + 1 < size() && entry[iUp + 1].mother1() == mother1)
595 ? mother1 : mother2;
continue;
598 if (entry[iUp - 1].mother1() == mother1)
return false;
599 iUp = mother1;
continue;
602 if (iUp + 1 < size() && entry[iUp + 1].mother1() == mother1)
604 iUp = mother1;
continue;
620 void Event::eraseJunction(
int i) {
622 for (
int j = i; j < int(junction.size()) - 1; ++j)
623 junction[j] = junction[j + 1];
632 void Event::listJunctions(ostream& os)
const {
635 os <<
"\n -------- PYTHIA Junction Listing "
636 << headerList.substr(0,30) <<
"\n \n no kind col0 col1 col2 "
637 <<
"endc0 endc1 endc2 stat0 stat1 stat2\n";
640 for (
int i = 0; i < sizeJunction(); ++i)
641 os << setw(6) << i << setw(6) << kindJunction(i) << setw(6)
642 << colJunction(i, 0) << setw(6) << colJunction(i, 1) << setw(6)
643 << colJunction(i, 2) << setw(6) << endColJunction(i, 0) << setw(6)
644 << endColJunction(i, 1) << setw(6) << endColJunction(i, 2) << setw(6)
645 << statusJunction(i, 0) << setw(6) << statusJunction(i, 1) << setw(6)
646 << statusJunction(i, 2) <<
"\n";
649 if (sizeJunction() == 0) os <<
" no junctions present \n";
650 os <<
"\n -------- End PYTHIA Junction Listing --------------------"
658 Event& Event::operator+=(
const Event& addEvent) {
661 int offsetIdx = entry.size() - 1;
662 int offsetCol = maxColTag;
665 entry[0].p( entry[0].p() + addEvent[0].p() );
666 entry[0].m( entry[0].mCalc() );
670 for (
int i = 1; i < addEvent.size(); ++i) {
674 if (temp.mother1() > 0) temp.mother1( temp.mother1() + offsetIdx );
675 if (temp.mother2() > 0) temp.mother2( temp.mother2() + offsetIdx );
676 if (temp.daughter1() > 0) temp.daughter1( temp.daughter1() + offsetIdx );
677 if (temp.daughter2() > 0) temp.daughter2( temp.daughter2() + offsetIdx );
678 if (temp.col() > 0) temp.col( temp.col() + offsetCol );
679 if (temp.acol() > 0) temp.acol( temp.acol() + offsetCol );
688 for (
int i = 0; i < addEvent.sizeJunction(); ++i) {
689 tempJ = addEvent.getJunction(i);
692 for (
int j = 0; j < 3; ++j) {
693 begCol = tempJ.col(j);
694 endCol = tempJ.endCol(j);
695 if (begCol > 0) begCol += offsetCol;
696 if (endCol > 0) endCol += offsetCol;
697 tempJ.cols( j, begCol, endCol);
701 appendJunction( tempJ );
705 headerList =
"(combination of several events) -------";