24 const int Sphericity::NSTUDYMIN = 2;
27 const int Sphericity::TIMESTOPRINT = 1;
30 const double Sphericity::P2MIN = 1e-20;
33 const double Sphericity::EIGENVALUEMIN = 1e-10;
39 bool Sphericity::analyze(
const Event& event, ostream& os) {
42 eVal1 = eVal2 = eVal3 = 0.;
43 eVec1 = eVec2 = eVec3 = 0.;
45 for (
int j = 1; j < 4; ++j)
46 for (
int k = j; k < 4; ++k) tt[j][k] = 0.;
51 for (
int i = 0; i <
event.size(); ++i)
52 if (event[i].isFinal()) {
53 if (select > 2 && event[i].isNeutral() )
continue;
54 if (select == 2 && !event[i].isVisible() )
continue;
59 pNow[1] =
event[i].px();
60 pNow[2] =
event[i].py();
61 pNow[3] =
event[i].pz();
62 double p2Now = pNow[1]*pNow[1] + pNow[2]*pNow[2] + pNow[3]*pNow[3];
64 if (powerInt == 1) pWeight = 1. / sqrt(max(P2MIN, p2Now));
65 else if (powerInt == 0) pWeight = pow( max(P2MIN, p2Now), powerMod);
66 for (
int j = 1; j < 4; ++j)
67 for (
int k = j; k < 4; ++k) tt[j][k] += pWeight * pNow[j] * pNow[k];
68 denom += pWeight * p2Now;
72 if (nStudy < NSTUDYMIN) {
73 if (nFew < TIMESTOPRINT) os <<
" PYTHIA Error in " <<
74 "Sphericity::analyze: too few particles" << endl;
80 for (
int j = 1; j < 4; ++j)
81 for (
int k = j; k < 4; ++k) tt[j][k] /= denom;
84 double qCoef = ( tt[1][1] * tt[2][2] + tt[1][1] * tt[3][3]
85 + tt[2][2] * tt[3][3] - pow2(tt[1][2]) - pow2(tt[1][3])
86 - pow2(tt[2][3]) ) / 3. - 1./9.;
87 double qCoefRt = sqrt( -qCoef);
88 double rCoef = -0.5 * ( qCoef + 1./9. + tt[1][1] * pow2(tt[2][3])
89 + tt[2][2] * pow2(tt[1][3]) + tt[3][3] * pow2(tt[1][2])
90 - tt[1][1] * tt[2][2] * tt[3][3] )
91 + tt[1][2] * tt[1][3] * tt[2][3] + 1./27.;
92 double pTemp = max( min( rCoef / pow3(qCoefRt), 1.), -1.);
93 double pCoef = cos( acos(pTemp) / 3.);
94 double pCoefRt = sqrt( 3. * (1. - pow2(pCoef)) );
95 eVal1 = 1./3. + qCoefRt * max( 2. * pCoef, pCoefRt - pCoef);
96 eVal3 = 1./3. + qCoefRt * min( 2. * pCoef, -pCoefRt - pCoef);
97 eVal2 = 1. - eVal1 - eVal3;
100 for (
int iVal = 0; iVal < 2; ++iVal) {
101 double eVal = (iVal == 0) ? eVal1 : eVal3;
104 if (iVal > 1 && eVal2 < EIGENVALUEMIN) {
105 if (nBack < TIMESTOPRINT) os <<
" PYTHIA Error in "
106 "Sphericity::analyze: particles too back-to-back" << endl;
113 for (
int j = 1; j < 4; ++j) {
114 dd[j][j] = tt[j][j] - eVal;
115 for (
int k = j + 1; k < 4; ++k) {
125 for (
int j = 1; j < 4; ++j)
126 for (
int k = 1; k < 4; ++k)
127 if (abs(dd[j][k]) > ddMax) {
130 ddMax = abs(dd[j][k]);
136 for (
int j = 1; j < 4; ++j)
138 double pivot = dd[j][kMax] / dd[jMax][kMax];
139 for (
int k = 1; k < 4; ++k) {
140 dd[j][k] -= pivot * dd[jMax][k];
141 if (abs(dd[j][k]) > ddMax) {
143 ddMax = abs(dd[j][k]);
149 int k1 = kMax + 1;
if (k1 > 3) k1 -= 3;
150 int k2 = kMax + 2;
if (k2 > 3) k2 -= 3;
152 eVec[k1] = -dd[jMax2][k2];
153 eVec[k2] = dd[jMax2][k1];
154 eVec[kMax] = (dd[jMax][k1] * dd[jMax2][k2]
155 - dd[jMax][k2] * dd[jMax2][k1]) / dd[jMax][kMax];
156 double length = sqrt( pow2(eVec[1]) + pow2(eVec[2])
160 if (iVal == 0) eVec1 = Vec4( eVec[1] / length,
161 eVec[2] / length, eVec[3] / length, 0.);
162 else eVec3 = Vec4( eVec[1] / length,
163 eVec[2] / length, eVec[3] / length, 0.);
167 eVec2 = cross3( eVec1, eVec3);
178 void Sphericity::list(ostream& os)
const {
181 os <<
"\n -------- PYTHIA Sphericity Listing -------- \n";
182 if (powerInt !=2) os <<
" Nonstandard momentum power = "
183 << fixed << setprecision(3) << setw(6) << power <<
"\n";
184 os <<
"\n no lambda e_x e_y e_z \n";
187 os << setprecision(5);
188 os <<
" 1" << setw(11) << eVal1 << setw(11) << eVec1.px()
189 << setw(10) << eVec1.py() << setw(10) << eVec1.pz() <<
"\n";
190 os <<
" 2" << setw(11) << eVal2 << setw(11) << eVec2.px()
191 << setw(10) << eVec2.py() << setw(10) << eVec2.pz() <<
"\n";
192 os <<
" 3" << setw(11) << eVal3 << setw(11) << eVec3.px()
193 << setw(10) << eVec3.py() << setw(10) << eVec3.pz() <<
"\n";
196 os <<
"\n -------- End PYTHIA Sphericity Listing ----" << endl;
212 const int Thrust::NSTUDYMIN = 2;
215 const int Thrust::TIMESTOPRINT = 1;
218 const double Thrust::MAJORMIN = 1e-10;
224 bool Thrust::analyze(
const Event& event, ostream& os) {
227 eVal1 = eVal2 = eVal3 = 0.;
228 eVec1 = eVec2 = eVec3 = 0.;
231 Vec4 pSum, nRef, pPart, pFull, pMax;
234 for (
int i = 0; i <
event.size(); ++i)
235 if (event[i].isFinal()) {
236 if (select > 2 && event[i].isNeutral() )
continue;
237 if (select == 2 && !event[i].isVisible() )
continue;
241 Vec4 pNow =
event[i].p();
244 pOrder.push_back(pNow);
248 if (nStudy < NSTUDYMIN) {
249 if (nFew < TIMESTOPRINT) os <<
" PYTHIA Error in " <<
250 "Thrust::analyze: too few particles" << endl;
256 for (
int i1 = 0; i1 < nStudy - 1; ++i1)
257 for (
int i2 = i1 + 1; i2 < nStudy; ++i2) {
258 nRef = cross3( pOrder[i1], pOrder[i2]);
263 for (
int i = 0; i < nStudy; ++i)
if (i != i1 && i != i2) {
264 if (dot3(pOrder[i], nRef) > 0.) pPart += pOrder[i];
265 else pPart -= pOrder[i];
267 for (
int j = 0; j < 4; ++j) {
268 if (j == 0) pFull = pPart + pOrder[i1] + pOrder[i2];
269 else if (j == 1) pFull = pPart + pOrder[i1] - pOrder[i2];
270 else if (j == 2) pFull = pPart - pOrder[i1] + pOrder[i2];
271 else pFull = pPart - pOrder[i1] - pOrder[i2];
272 pFull.e(pFull.pAbs());
273 if (pFull.e() > pMax.e()) pMax = pFull;
278 eVal1 = pMax.e() / pSum.e();
279 eVec1 = pMax / pMax.e();
284 for (
int i = 0; i < nStudy; ++i) {
285 pOrder[i] -= dot3( eVec1, pOrder[i]) * eVec1;
286 pOrder[i].e(pOrder[i].pAbs());
287 pAbsSum += pOrder[i].e();
291 if (pAbsSum < MAJORMIN * pSum.e()) {
292 if ( abs(eVec1.pz()) > 0.5) eVec2 = Vec4( 1., 0., 0., 0.);
293 else eVec2 = Vec4( 0., 0., 1., 0.);
294 eVec2 -= dot3( eVec1, eVec2) * eVec1;
295 eVec2 /= eVec2.pAbs();
296 eVec3 = cross3( eVec1, eVec2);
302 for (
int i1 = 0; i1 < nStudy; ++i1) {
303 nRef = cross3( pOrder[i1], eVec1);
308 for (
int i = 0; i < nStudy; ++i)
if (i != i1) {
309 if (dot3(pOrder[i], nRef) > 0.) pPart += pOrder[i];
310 else pPart -= pOrder[i];
312 pFull = pPart + pOrder[i1];
313 pFull.e(pFull.pAbs());
314 if (pFull.e() > pMax.e()) pMax = pFull;
315 pFull = pPart - pOrder[i1];
316 pFull.e(pFull.pAbs());
317 if (pFull.e() > pMax.e()) pMax = pFull;
321 eVal2 = pMax.e() / pSum.e();
322 eVec2 = pMax / pMax.e();
326 eVec3 = cross3( eVec1, eVec2);
328 for (
int i = 0; i < nStudy; ++i)
329 pAbsSum += abs( dot3(eVec3, pOrder[i]) );
330 eVal3 = pAbsSum / pSum.e();
341 void Thrust::list(ostream& os)
const {
344 os <<
"\n -------- PYTHIA Thrust Listing ------------ \n"
345 <<
"\n value e_x e_y e_z \n";
348 os << setprecision(5);
349 os <<
" Thr" << setw(11) << eVal1 << setw(11) << eVec1.px()
350 << setw(10) << eVec1.py() << setw(10) << eVec1.pz() <<
"\n";
351 os <<
" Maj" << setw(11) << eVal2 << setw(11) << eVec2.px()
352 << setw(10) << eVec2.py() << setw(10) << eVec2.pz() <<
"\n";
353 os <<
" Min" << setw(11) << eVal3 << setw(11) << eVec3.px()
354 << setw(10) << eVec3.py() << setw(10) << eVec3.pz() <<
"\n";
357 os <<
"\n -------- End PYTHIA Thrust Listing --------" << endl;
372 const double SingleClusterJet::PABSMIN = 1e-10;
378 double dist2Fun(
int measure,
const SingleClusterJet& j1,
379 const SingleClusterJet& j2) {
382 if (measure == 2)
return 2. * j1.pJet.e() * j2.pJet.e()
383 * (1. - dot3( j1.pJet, j2.pJet) / (j1.pAbs * j2.pAbs) );
386 if (measure == 3)
return 2. * pow2( min( j1.pJet.e(), j2.pJet.e() ) )
387 * (1. - dot3( j1.pJet, j2.pJet) / (j1.pAbs * j2.pAbs) );
390 return (j1.pAbs * j2.pAbs - dot3( j1.pJet, j2.pJet))
391 * 2. * j1.pAbs * j2.pAbs / pow2(j1.pAbs + j2.pAbs);
407 const int ClusterJet::TIMESTOPRINT = 1;
410 const double ClusterJet::PIMASS = 0.13957;
413 const double ClusterJet::PABSMIN = 1e-10;
416 const double ClusterJet::PRECLUSTERFRAC = 0.1;
419 const double ClusterJet::PRECLUSTERSTEP = 0.8;
425 bool ClusterJet::analyze(
const Event& event,
double yScaleIn,
426 double pTscaleIn,
int nJetMinIn,
int nJetMaxIn, ostream& os) {
439 for (
int i = 0; i <
event.size(); ++i)
440 if (event[i].isFinal()) {
441 if (select > 2 && event[i].isNeutral() )
continue;
442 if (select == 2 && !event[i].isVisible() )
continue;
445 Vec4 pTemp =
event[i].p();
446 if (massSet == 0 || massSet == 1) {
447 double mTemp = (massSet == 0 ||
event[i].id() == 22)
449 double eTemp = sqrt(pTemp.pAbs2() + pow2(mTemp));
452 particles.push_back( SingleClusterJet(pTemp, i) );
457 nParticles = particles.size();
458 if (nParticles < nJetMin) {
459 if (nFew < TIMESTOPRINT) os <<
" PYTHIA Error in " <<
460 "ClusterJet::analyze: too few particles" << endl;
466 double p2Sum = pSum.m2Calc();
467 dist2Join = max( yScale * p2Sum, pow2(pTscale));
468 dist2BigMin = 2. * max( dist2Join, p2Sum);
471 if (doPrecluster && nParticles > nJetMin + 2) {
473 if (doReassign) reassign();
477 else for (
int i = 0; i < nParticles; ++i) {
478 jets.push_back( SingleClusterJet(particles[i]) );
479 particles[i].daughter = i;
486 double dist2Min = dist2BigMin;
489 for (
int j = 0; j < int(jets.size()) - 1; ++j)
490 for (
int k = j + 1; k < int(jets.size()); ++k) {
491 double dist2 = dist2Fun( measure, jets[j], jets[k]);
492 if (dist2 < dist2Min) {
500 if ( dist2Min > dist2Join
501 && (nJetMax < nJetMin ||
int(jets.size()) <= nJetMax) )
break;
504 if (
int(jets.size()) <= nJetMin)
break;
507 jets[jMin].pJet += jets[kMin].pJet;
508 jets[jMin].pAbs = max( PABSMIN, jets[jMin].pJet.pAbs());
509 jets[jMin].multiplicity += jets[kMin].multiplicity;
510 for (
int i = 0; i < nParticles; ++i)
511 if (particles[i].daughter == kMin) particles[i].daughter = jMin;
514 distances.push_front(dist2Min);
515 if (distances.size() > 5) distances.pop_back();
518 jets[kMin] = jets.back();
520 int iEnd = jets.size();
521 for (
int i = 0; i < nParticles; ++i)
522 if (particles[i].daughter == iEnd) particles[i].daughter = kMin;
525 if (doReassign) reassign();
529 for (
int j = 0; j < int(jets.size()) - 1; ++j)
530 for (
int k =
int(jets.size()) - 1; k > j; --k)
531 if (jets[k].pJet.e() > jets[k-1].pJet.e()) {
532 swap( jets[k], jets[k-1]);
533 for (
int i = 0; i < nParticles; ++i) {
534 if (particles[i].daughter == k) particles[i].daughter = k-1;
535 else if (particles[i].daughter == k-1) particles[i].daughter = k;
547 void ClusterJet::precluster() {
550 distPre = PRECLUSTERFRAC * sqrt(dist2Join) / PRECLUSTERSTEP;
552 distPre *= PRECLUSTERSTEP;
553 dist2Pre = pow2(distPre);
554 for (
int i = 0; i < nParticles; ++i) {
555 particles[i].daughter = -1;
556 particles[i].isAssigned =
false;
562 for (
int i = 0; i < nParticles; ++i)
563 if (particles[i].pAbs < 2. * distPre) {
564 pCentral += particles[i].pJet;
565 multCentral += particles[i].multiplicity;
566 particles[i].isAssigned =
true;
568 if (pCentral.pAbs() > 2. * distPre) {
569 jets.push_back( SingleClusterJet(pCentral) );
570 jets.back().multiplicity = multCentral;
571 for (
int i = 0; i < nParticles; ++i)
572 if (particles[i].isAssigned) particles[i].daughter = 0;
579 for (
int i = 0; i < nParticles; ++i)
580 if ( !particles[i].isAssigned && particles[i].pAbs > pMax) {
582 pMax = particles[i].pAbs;
584 if (iMax == -1)
break;
590 for (
int i = 0; i < nParticles; ++i)
591 if ( !particles[i].isAssigned) {
592 double dist2 = dist2Fun( measure, particles[iMax],
594 if (dist2 < dist2Pre) {
595 pPre += particles[i].pJet;
597 particles[i].isAssigned =
true;
598 particles[i].daughter = jets.size();
601 jets.push_back( SingleClusterJet(pPre) );
602 jets.back().multiplicity = multPre;
605 if (
int(jets.size()) + nRemain < nJetMin)
break;
607 if (
int(jets.size()) >= nJetMin)
break;
616 void ClusterJet::reassign() {
619 for (
int j = 0; j < int(jets.size()); ++j) {
621 jets[j].multiplicity = 0;
625 for (
int i = 0; i < nParticles; ++i) {
626 particles[i].daughter = -1;
627 double dist2Min = dist2BigMin;
629 for (
int j = 0; j < int(jets.size()); ++j) {
630 double dist2 = dist2Fun( measure, particles[i], jets[j]);
631 if (dist2 < dist2Min) {
636 jets[jMin].pTemp += particles[i].pJet;
637 ++jets[jMin].multiplicity;
638 particles[i].daughter = jMin;
642 for (
int j = 0; j < int(jets.size()); ++j) {
643 jets[j].pJet = jets[j].pTemp;
644 jets[j].pAbs = max( PABSMIN, jets[j].pJet.pAbs());
652 for (
int j = 0; j < int(jets.size()); ++j)
653 if (jets[j].multiplicity == 0) jEmpty = j;
654 if (jEmpty == -1)
return;
658 double dist2Max = 0.;
659 for (
int i = 0; i < nParticles; ++i) {
660 int j = particles[i].daughter;
661 double dist2 = dist2Fun( measure, particles[i], jets[j]);
662 if (dist2 > dist2Max) {
669 int jSplit = particles[iSplit].daughter;
670 jets[jEmpty] = SingleClusterJet( particles[iSplit].pJet );
671 jets[jSplit].pJet -= particles[iSplit].pJet;
672 jets[jSplit].pAbs = max( PABSMIN,jets[jSplit].pJet.pAbs());
673 particles[iSplit].daughter = jEmpty;
674 --jets[jSplit].multiplicity;
683 void ClusterJet::list(ostream& os)
const {
686 string method = (measure == 1) ?
"Lund pT"
687 : ( (measure == 2) ?
"JADE m" :
"Durham kT" ) ;
688 os <<
"\n -------- PYTHIA ClusterJet Listing, " << setw(9) << method
689 <<
" =" << fixed << setprecision(3) << setw(7) << sqrt(dist2Join)
690 <<
" GeV --- \n \n no mult p_x p_y p_z "
694 for (
int i = 0; i < int(jets.size()); ++i) {
695 os << setw(4) << i << setw(6) << jets[i].multiplicity << setw(11)
696 << jets[i].pJet.px() << setw(11) << jets[i].pJet.py()
697 << setw(11) << jets[i].pJet.pz() << setw(11)
698 << jets[i].pJet.e() << setw(11) << jets[i].pJet.mCalc()
703 os <<
"\n -------- End PYTHIA ClusterJet Listing ---------------"
704 <<
"--------" << endl;
718 const int CellJet::TIMESTOPRINT = 1;
724 bool CellJet::analyze(
const Event& event,
double eTjetMinIn,
725 double coneRadiusIn,
double eTseedIn, ostream& ) {
728 eTjetMin = eTjetMinIn;
729 coneRadius = coneRadiusIn;
732 vector<SingleCell> cells;
735 for (
int i = 0; i <
event.size(); ++i)
736 if (event[i].isFinal()) {
737 if (select > 2 && event[i].isNeutral() )
continue;
738 if (select == 2 && !event[i].isVisible() )
continue;
741 double etaNow =
event[i].eta();
742 if (abs(etaNow) > etaMax)
continue;
743 double phiNow =
event[i].phi();
744 double pTnow =
event[i].pT();
745 int iEtaNow = max(1, min( nEta, 1 +
int(nEta * 0.5
746 * (1. + etaNow / etaMax) ) ) );
747 int iPhiNow = max(1, min( nPhi, 1 +
int(nPhi * 0.5
748 * (1. + phiNow / M_PI) ) ) );
749 int iCell = nPhi * iEtaNow + iPhiNow;
753 for (
int j = 0; j < int(cells.size()); ++j) {
754 if (iCell == cells[j].iCell) {
756 ++cells[j].multiplicity;
757 cells[j].eTcell += pTnow;
762 double etaCell = (etaMax / nEta) * (2 * iEtaNow - 1 - nEta);
763 double phiCell = (M_PI / nPhi) * (2 * iPhiNow - 1 - nPhi);
764 cells.push_back( SingleCell( iCell, etaCell, phiCell, pTnow, 1) );
769 if (smear > 0 && rndmPtr > 0)
770 for (
int j = 0; j < int(cells.size()); ++j) {
771 double eTeConv = (smear < 2) ? 1. : cosh( cells[j].etaCell );
772 double eBef = cells[j].eTcell * eTeConv;
774 do eAft = eBef + resolution * sqrt(eBef) * rndmPtr->gauss();
775 while (eAft < 0 || eAft > upperCut * eBef);
776 cells[j].eTcell = eAft / eTeConv;
780 for (
int j = 0; j < int(cells.size()); ++j) {
781 if (cells[j].eTcell < eTseed) cells[j].canBeSeed =
false;
782 if (cells[j].eTcell < threshold) cells[j].isUsed =
true;
789 for (
int j = 0; j < int(cells.size()); ++j)
790 if (cells[j].canBeSeed && cells[j].eTcell > eTmax) {
792 eTmax = cells[j].eTcell;
796 if (eTmax < eTseed)
break;
797 double etaCenterNow = cells[jMax].etaCell;
798 double phiCenterNow = cells[jMax].phiCell;
799 double eTjetNow = 0.;
802 for (
int j = 0; j < int(cells.size()); ++j) {
803 if (cells[j].isUsed)
continue;
804 double dEta = abs( cells[j].etaCell - etaCenterNow );
805 if (dEta > coneRadius)
continue;
806 double dPhi = abs( cells[j].phiCell - phiCenterNow );
807 if (dPhi > M_PI) dPhi = 2. * M_PI - dPhi;
808 if (dPhi > coneRadius)
continue;
809 if (pow2(dEta) + pow2(dPhi) > pow2(coneRadius))
continue;
810 cells[j].isAssigned =
true;
811 eTjetNow += cells[j].eTcell;
815 if (eTjetNow < eTjetMin) {
816 cells[jMax].canBeSeed =
false;
817 for (
int j = 0; j < int(cells.size()); ++j)
818 cells[j].isAssigned =
false;
822 double etaWeightedNow = 0.;
823 double phiWeightedNow = 0.;
824 int multiplicityNow = 0;
826 for (
int j = 0; j < int(cells.size()); ++j)
827 if (cells[j].isAssigned) {
828 cells[j].canBeSeed =
false;
829 cells[j].isUsed =
true;
830 cells[j].isAssigned =
false;
831 etaWeightedNow += cells[j].eTcell * cells[j].etaCell;
832 double phiCell = cells[j].phiCell;
833 if (abs(phiCell - phiCenterNow) > M_PI)
834 phiCell += (phiCenterNow > 0.) ? 2. * M_PI : -2. * M_PI;
835 phiWeightedNow += cells[j].eTcell * phiCell;
836 multiplicityNow += cells[j].multiplicity;
837 pMassiveNow += cells[j].eTcell * Vec4(
838 cos(cells[j].phiCell), sin(cells[j].phiCell),
839 sinh(cells[j].etaCell), cosh(cells[j].etaCell) );
841 etaWeightedNow /= eTjetNow;
842 phiWeightedNow /= eTjetNow;
845 jets.push_back( SingleCellJet( eTjetNow, etaCenterNow, phiCenterNow,
846 etaWeightedNow, phiWeightedNow, multiplicityNow, pMassiveNow) );
847 for (
int i =
int(jets.size()) - 1; i > 0; --i) {
848 if (jets[i-1].eTjet > jets[i].eTjet)
break;
849 swap( jets[i-1], jets[i]);
862 void CellJet::list(ostream& os)
const {
865 os <<
"\n -------- PYTHIA CellJet Listing, eTjetMin = "
866 << fixed << setprecision(3) << setw(8) << eTjetMin
867 <<
", coneRadius = " << setw(5) << coneRadius
868 <<
" ------------------------------ \n \n no "
869 <<
" eTjet etaCtr phiCtr etaWt phiWt mult p_x"
870 <<
" p_y p_z e m \n";
873 for (
int i = 0; i < int(jets.size()); ++i) {
874 os << setw(4) << i << setw(10) << jets[i].eTjet << setw(8)
875 << jets[i].etaCenter << setw(8) << jets[i].phiCenter << setw(8)
876 << jets[i].etaWeighted << setw(8) << jets[i].phiWeighted
877 << setw(5) << jets[i].multiplicity << setw(11)
878 << jets[i].pMassive.px() << setw(11) << jets[i].pMassive.py()
879 << setw(11) << jets[i].pMassive.pz() << setw(11)
880 << jets[i].pMassive.e() << setw(11)
881 << jets[i].pMassive.mCalc() <<
"\n";
885 os <<
"\n -------- End PYTHIA CellJet Listing ------------------"
886 <<
"-------------------------------------------------"
901 const int SlowJet::TIMESTOPRINT = 1;
904 const double SlowJet::PIMASS = 0.13957;
907 const double SlowJet::TINY = 1e-20;
913 bool SlowJet::setup(
const Event& event) {
922 double mTemp, pT2Temp, mTTemp, yTemp, phiTemp;
923 for (
int i = 0; i <
event.size(); ++i)
924 if (event[i].isFinal()) {
927 if (chargedOnly && event[i].isNeutral() )
continue;
928 else if (visibleOnly && !event[i].isVisible() )
continue;
934 if (cutInEta && abs(event[i].eta()) > etaMax)
continue;
937 pTemp =
event[i].p();
938 mTemp =
event[i].m();
940 mTemp = (massSet == 0 ||
event[i].id() == 22) ? 0. : PIMASS;
941 pTemp.e( sqrt(pTemp.pAbs2() + mTemp*mTemp) );
947 pTemp =
event[i].p();
948 mTemp =
event[i].m();
949 if ( !sjHookPtr->include( i, event, pTemp, mTemp) )
continue;
953 pT2Temp = max( TINY*TINY, pTemp.pT2());
954 mTTemp = sqrt( mTemp*mTemp + pT2Temp);
955 yTemp = (pTemp.pz() > 0)
956 ? log( max( TINY, pTemp.e() + pTemp.pz() ) / mTTemp )
957 : log( mTTemp / max( TINY, pTemp.e() - pTemp.pz() ) );
958 phiTemp = pTemp.phi();
959 clusters.push_back( SingleSlowJet(pTemp, pT2Temp, yTemp, phiTemp) );
963 origSize = clusters.size();
967 dij.resize(clSize * (clSize - 1) / 2);
970 for (
int i = 0; i < clSize; ++i) {
971 if (isAnti) diB[i] = 1. / clusters[i].pT2;
972 else if (isKT) diB[i] = clusters[i].pT2;
976 for (
int j = 0; j < i; ++j) {
977 dPhi = abs( clusters[i].phi - clusters[j].phi );
978 if (dPhi > M_PI) dPhi = 2. * M_PI - dPhi;
979 dijTemp = (pow2( clusters[i].y - clusters[j].y) + dPhi*dPhi) / R2;
980 if (isAnti) dijTemp /= max(clusters[i].pT2, clusters[j].pT2);
981 else if (isKT) dijTemp *= min(clusters[i].pT2, clusters[j].pT2);
982 dij[i*(i-1)/2 + j] = dijTemp;
1000 bool SlowJet::doStep() {
1003 if (clSize == 0)
return false;
1009 if (clusters[iMin].pT2 > pT2jetMin) {
1010 jets.push_back( SingleSlowJet(clusters[iMin]) );
1014 for (
int i = jtSize - 1; i > 0; --i) {
1015 if (jets[i].pT2 < jets[i-1].pT2)
break;
1016 swap( jets[i], jets[i-1]);
1025 clusters[jMin].p += clusters[iMin].p;
1026 clusters[jMin].pT2 = max( TINY*TINY, clusters[jMin].p.pT2());
1027 double mTTemp = sqrt(clusters[jMin].p.m2Calc() + clusters[jMin].pT2);
1028 clusters[jMin].y = (clusters[jMin].p.pz() > 0)
1029 ? log( max( TINY, clusters[jMin].p.e() + clusters[jMin].p.pz() )
1030 / mTTemp ) : log( mTTemp
1031 / max( TINY, clusters[jMin].p.e() - clusters[jMin].p.pz() ) );
1032 clusters[jMin].phi = clusters[jMin].p.phi();
1033 clusters[jMin].mult += clusters[iMin].mult;
1036 if (isAnti) diB[jMin] = 1. / clusters[jMin].pT2;
1037 else if (isKT) diB[jMin] = clusters[jMin].pT2;
1038 else diB[jMin] = 1.;
1039 for (
int i = 0; i < clSize; ++i)
if (i != jMin && i != iMin) {
1040 dPhi = abs( clusters[i].phi - clusters[jMin].phi );
1041 if (dPhi > M_PI) dPhi = 2. * M_PI - dPhi;
1042 dijTemp = (pow2( clusters[i].y - clusters[jMin].y) + dPhi*dPhi) / R2;
1043 if (isAnti) dijTemp /= max(clusters[i].pT2, clusters[jMin].pT2);
1044 else if (isKT) dijTemp *= min(clusters[i].pT2, clusters[jMin].pT2);
1045 if (i < jMin) dij[jMin*(jMin-1)/2 + i] = dijTemp;
1046 else dij[i*(i-1)/2 + jMin] = dijTemp;
1051 if (iMin < clLast) {
1052 clusters[iMin] = clusters[clLast];
1053 diB[iMin] = diB[clLast];
1054 for (
int j = 0; j < iMin; ++j)
1055 dij[iMin*(iMin-1)/2 + j] = dij[clLast*(clLast-1)/2 + j];
1056 for (
int j = iMin + 1; j < clLast; ++j)
1057 dij[j*(j-1)/2 + iMin] = dij[clLast*(clLast-1)/2 + j];
1061 clusters.pop_back();
1077 void SlowJet::list(
bool listAll, ostream& os)
const {
1080 os <<
"\n -------- PYTHIA SlowJet Listing, p = " << setw(2)
1081 << power <<
", R = " << fixed << setprecision(3) << setw(5) << R
1082 <<
", pTjetMin =" << setw(8) << pTjetMin <<
", etaMax = " << setw(6)
1083 << etaMax <<
" --- \n \n no pTjet y phi mult "
1084 <<
" p_x p_y p_z e m \n";
1087 for (
int i = 0; i < jtSize; ++i) {
1088 os << setw(4) << i << setw(11) << sqrt(jets[i].pT2) << setw(9)
1089 << jets[i].y << setw(9) << jets[i].phi << setw(6)
1090 << jets[i].mult << setw(11) << jets[i].p.px() << setw(11)
1091 << jets[i].p.py() << setw(11) << jets[i].p.pz() << setw(11)
1092 << jets[i].p.e() << setw(11) << jets[i].p.mCalc() <<
"\n";
1096 if (listAll && clSize > 0) {
1097 os <<
" -------- Below this line follows remaining clusters,"
1098 <<
" still pT-unordered -------------------\n";
1099 for (
int i = 0; i < clSize; ++i) {
1100 os << setw(4) << i + jtSize << setw(11) << sqrt(clusters[i].pT2)
1101 << setw(9) << clusters[i].y << setw(9) << clusters[i].phi
1102 << setw(6) << clusters[i].mult << setw(11) << clusters[i].p.px()
1103 << setw(11) << clusters[i].p.py() << setw(11) << clusters[i].p.pz()
1104 << setw(11) << clusters[i].p.e() << setw(11)
1105 << clusters[i].p.mCalc() <<
"\n";
1110 os <<
"\n -------- End PYTHIA SlowJet Listing ------------------"
1111 <<
"-------------------------------------" << endl;
1119 void SlowJet::findNext() {
1126 for (
int i = 1; i < clSize; ++i) {
1127 if (diB[i] < dMin) {
1132 for (
int j = 0; j < i; ++j) {
1133 if (dij[i*(i-1)/2 + j] < dMin) {
1136 dMin = dij[i*(i-1)/2 + j];