10 #include "Pythia8/Ropewalk.h"
23 OverlappingRopeDipole::OverlappingRopeDipole(RopeDipole* d,
double m0,
24 RotBstMatrix& r) : dipole(d), dir(1) {
27 b1 = d->d1Ptr()->getParticlePtr()->vProd();
29 b2 = d->d2Ptr()->getParticlePtr()->vProd();
31 y1 = d->d1Ptr()->rap(m0,r);
32 y2 = d->d2Ptr()->rap(m0,r);
33 if (y1 < y2) dir = -1;
41 bool OverlappingRopeDipole::overlap(
double y, Vec4 ba,
double r0) {
43 if (y < min(y1, y2) || y > max(y1, y2))
return false;
44 Vec4 bb = b1 + (b2 - b1) * (y - y1) / (y2 - y1);
46 return (tmp.pT() <= 2 * r0);
54 bool OverlappingRopeDipole::hadronized() {
56 return dipole->hadronized();
70 RopeDipole::RopeDipole(RopeDipoleEnd d1In, RopeDipoleEnd d2In,
int iSubIn,
72 : d1(d1In), d2(d2In), iSub(iSubIn), hasRotFrom(false), hasRotTo(false),
73 isHadronized(false), infoPtr(infoPtrIn) {
76 if (d1In.getParticlePtr()->col() == d2In.getParticlePtr()->acol()
77 && d1In.getParticlePtr()->col() != 0) { }
78 else { d2 = d1In, d1 = d2In; }
86 void RopeDipole::addExcitation(
double ylab, Particle* ex) {
88 pair<map<double, Particle*>::iterator, map<double, Particle*>::iterator>
89 ret = excitations.equal_range(ylab);
90 for (map<double, Particle*>::iterator itr = ret.first; itr != ret.second;
92 if (ex == itr->second)
return;
93 excitations.insert( make_pair(ylab,ex) );
101 void RopeDipole::propagateInit(
double deltat) {
104 Vec4 pcm = d1.getParticlePtr()->p();
105 Vec4 pam = d2.getParticlePtr()->p();
106 double mTc = sqrt(pcm.pT2() + pcm.m2Calc());
107 double mTa = sqrt(pam.pT2() + pam.m2Calc());
108 if (mTc == 0 || mTa == 0)
109 infoPtr->errorMsg(
"Error in RopeDipole::propagateInit: Tried to"
110 "propagate a RopeDipoleEnd with mT = 0");
113 Vec4 newv1 = Vec4(d1.getParticlePtr()->xProd() + deltat * pcm.px() / mTc,
114 d1.getParticlePtr()->yProd() + deltat * pcm.py() / mTc, 0, 0);
115 Vec4 newv2 = Vec4(d2.getParticlePtr()->xProd() + deltat * pam.px() / mTa,
116 d2.getParticlePtr()->yProd() + deltat * pam.py() / mTa, 0, 0);
118 d1.getParticlePtr()->vProd(newv1);
119 d2.getParticlePtr()->vProd(newv2);
127 void RopeDipole::propagate(
double deltat,
double m0) {
130 propagateInit(deltat);
131 for (map<double, Particle*>::iterator eItr = excitations.begin();
132 eItr != excitations.end(); ++eItr) {
134 Vec4 em = eItr->second->p();
135 em.rotbst(getDipoleLabFrame());
139 Vec4 newVert = Vec4(eItr->second->xProd() + deltat * em.px() / em.pT(),
140 eItr->second->yProd() + deltat * em.py() / em.pT(), 0, 0);
141 eItr->second->vProd(newVert);
143 else eItr->second->vProd(bInterpolateLab(eItr->first,m0));
152 void RopeDipole::excitationsToString(
double m0,
Event& event) {
155 map<double, Particle*>::iterator pItr = excitations.begin();
156 while (pItr != excitations.end() ) {
157 if (pItr->second->pAbs() < 1e-6) {
158 map<double, Particle*>::iterator eraseMe = pItr;
160 excitations.erase(eraseMe);
168 int oldcol = d1.getParticlePtr()->col();
169 if (oldcol != d2.getParticlePtr()->acol()) {
170 infoPtr->errorMsg(
"Error in Ropewalk::RopeDipole::excitationsToString: "
171 "color indices do not match.");
174 vector<int> daughters;
178 if (d1.rap(m0) == minRapidity(m0)) {
180 for (map<double, Particle*>::iterator itr = excitations.begin();
181 itr != excitations.end(); ++itr) {
182 int col =
event.nextColTag();
183 itr->second->status(51);
184 itr->second->mothers(d1.getNe(),d1.getNe());
185 itr->second->cols(col,acol);
186 daughters.push_back(event.append(Particle(*(itr->second))));
189 d2.getParticlePtr()->acol(acol);
190 event[d2.getNe()].acol(acol);
194 for (map<double, Particle*>::reverse_iterator itr = excitations.rbegin();
195 itr != excitations.rend(); ++itr) {
196 int col =
event.nextColTag();
197 itr->second->status(51);
198 itr->second->mothers(d1.getNe(),d1.getNe());
199 itr->second->cols(col,acol);
200 daughters.push_back(event.append(Particle(*(itr->second))));
203 d2.getParticlePtr()->acol(acol);
204 event[d2.getNe()].acol(acol);
206 bool stringEnd =
false;
207 if (d2.getParticlePtr()->col() == 0) stringEnd =
true;
210 event[d1.getNe()].statusNeg();
211 Particle cc1 = *d1.getParticlePtr();
213 cc1.mothers(d1.getNe(),d1.getNe());
214 daughters.push_back(event.append(cc1));
215 event[d1.getNe()].daughters( daughters[0], daughters[daughters.size() -1 ] );
217 event[d2.getNe()].statusNeg();
218 Particle cc2 = *d2.getParticlePtr();
220 cc2.mothers(d2.getNe(),d2.getNe());
221 int did =
event.append(cc2);
222 event[d2.getNe()].daughters(did,did);
231 void RopeDipole::splitMomentum(Vec4 mom, Particle* p1, Particle* p2,
234 Vec4 p1new = p1->p() + frac * mom;
235 Vec4 p2new = p2->p() + (1. - frac) * mom;
248 bool RopeDipole::recoil(Vec4& pg,
bool dummy) {
252 if (d1.rap(1.0) > d2.rap(1.0)) sign = -1;
255 Particle* epaPtr = d1.getParticlePtr();
256 Particle* epcPtr = d2.getParticlePtr();
257 double pplus = epcPtr->pPos() + epaPtr->pPos() - pg.pPos();
258 double pminus = epcPtr->pNeg() + epaPtr->pNeg() - pg.pNeg();
265 double mta2 = epaPtr->mT2();
266 double mtc2 = epcPtr->mT2();
267 double mta = sqrt(mta2);
268 double mtc = sqrt(mtc2);
269 if ( pplus * pminus <= pow2(mta + mtc)
270 || pplus <= 0.0 || pminus <= 0.0 )
return false;
273 double sqarg = pow2(pplus * pminus - mta2 - mtc2) - 4. * mta2 * mtc2;
274 if (sqarg <= 0.0 )
return false;
276 ppa = 0.5 * (pplus * pminus + mta2 - mtc2 + sqrt(sqarg)) / pminus;
281 if ( ppa * mtc < ppc * mta )
return false;
284 pma = 0.5 * (pplus * pminus + mta2 - mtc2 + sqrt(sqarg)) / pplus;
289 if ( ppa*mtc > ppc*mta )
return false;
293 Vec4 shifta = Vec4( epaPtr->px(), epaPtr->py(),
294 0.5 * (ppa - pma), 0.5 * (ppa + pma));
295 Vec4 shiftc = Vec4( epcPtr->px(), epcPtr->py(),
296 0.5 * (ppc - pmc), 0.5 * (ppc + pmc));
309 RotBstMatrix RopeDipole::getDipoleRestFrame() {
311 if (hasRotTo)
return rotTo;
314 r.toCMframe(d1.getParticlePtr()->p(),d2.getParticlePtr()->p());
325 RotBstMatrix RopeDipole::getDipoleLabFrame() {
327 if(hasRotFrom)
return rotFrom;
330 r.fromCMframe(d1.getParticlePtr()->p(),d2.getParticlePtr()->p());
340 Vec4 RopeDipole::dipoleMomentum() {
342 Vec4 ret = d1.getParticlePtr()->p() + d2.getParticlePtr()->p();
353 Vec4 RopeDipole::bInterpolateDip(
double y,
double m0) {
354 if(!hasRotTo) getDipoleRestFrame();
355 Vec4 bb1 = d1.getParticlePtr()->vProd();
357 Vec4 bb2 = d2.getParticlePtr()->vProd();
359 double y1 = d1.rap(m0,rotTo);
360 double y2 = d2.rap(m0,rotTo);
361 return bb1 + y * (bb2 - bb1) / (y2 - y1);
369 Vec4 RopeDipole::bInterpolateLab(
double y,
double m0) {
371 Vec4 bb1 = d1.getParticlePtr()->vProd();
372 Vec4 bb2 = d2.getParticlePtr()->vProd();
373 double y1 = d1.rap(m0);
374 double y2 = d2.rap(m0);
375 return bb1 + y * (bb2 - bb1) / (y2 - y1);
384 Vec4 RopeDipole::bInterpolate(
double y, RotBstMatrix
rb,
double m0) {
386 Vec4 bb1 = d1.getParticlePtr()->vProd();
387 Vec4 bb2 = d2.getParticlePtr()->vProd();
390 double y1 = d1.rap(m0);
391 double y2 = d2.rap(m0);
392 return bb1 + y * (bb2 - bb1) / (y2 - y1);
401 pair<int, int> RopeDipole::getOverlaps(
double yfrac,
double m0,
double r0) {
403 if (!hasRotTo) getDipoleRestFrame();
404 double yL = d1.rap(m0,rotTo);
405 double yS = d2.rap(m0,rotTo);
406 double yH = yS + (yL - yS) * yfrac;
408 for (
size_t i = 0; i < overlaps.size(); ++i) {
409 if (overlaps[i].overlap( yfrac, bInterpolateDip(yH,m0), r0)
410 && !overlaps[i].hadronized()) {
411 if (overlaps[i].dir > 0) ++m;
415 return make_pair(m,n);
431 Exc(
double yIn,
double m0In,
int iIn,
int jIn,
int kIn,
RopeDipole* dip1In,
432 RopeDipole* dip2In) : y(yIn), m0(m0In), i(iIn), j(jIn), k(kIn), pp1(NULL),
433 pp2(NULL), dip1(dip1In), dip2(dip2In) { }
440 dip1->addExcitation(y, pp1);
441 dip2->addExcitation(y, pp2);
445 void shove(
double dpx,
double dpy) {
450 double mt2new = sqrt(pow2(p2.px() - dpx) + pow2(p2.py() - dpy));
451 double e2new = mt2new * cosh(y);
452 double p2znew = mt2new * sinh(y);
453 Vec4 p2new(p2.px() - dpx, p2.py() - dpy, p2znew, e2new);
454 double mt1new = sqrt(pow2(p1.px() + dpx) + pow2(p1.py() + dpy));
455 double e1new = mt1new * cosh(y);
456 double p1znew = mt1new * sinh(y);
457 Vec4 p1new(p1.px() + dpx, p1.py() + dpy, p1znew, e1new);
459 Vec4 deltap1 = p1new - p1;
460 Vec4 deltap2 = p2new - p2;
462 if ( dip2->recoil(deltap2) ) {
463 if ( dip1->recoil(deltap1) ) {
475 return dip1->bInterpolateDip(y,m0) -
476 dip2->bInterpolateDip(y,m0);
508 doShoving = settings.flag(
"Ropewalk:doShoving");
509 shoveMiniStrings = settings.flag(
"Ropewalk:shoveMiniStrings");
510 shoveJunctionStrings = settings.flag(
"Ropewalk:shoveJunctionStrings");
511 shoveGluonLoops = settings.flag(
"Ropewalk:shoveGluonLoops");
512 limitMom = settings.flag(
"Ropewalk:limitMom");
513 mStringMin = settings.parm(
"HadronLevel:mStringMin");
514 r0 = settings.parm(
"Ropewalk:r0");
515 m0 = settings.parm(
"Ropewalk:m0");
516 pTcut = settings.parm(
"Ropewalk:pTcut");
517 rCutOff = settings.parm(
"Ropewalk:rCutOff");
518 gAmplitude = settings.parm(
"Ropewalk:gAmplitude");
519 gExponent = settings.parm(
"Ropewalk:gExponent");
520 deltay = settings.parm(
"Ropewalk:deltay");
521 deltat = settings.parm(
"Ropewalk:deltat");
522 tShove = settings.parm(
"Ropewalk:tShove");
523 tInit = settings.parm(
"Ropewalk:tInit");
524 showerCut = settings.parm(
"TimeShower:pTmin");
525 alwaysHighest = settings.flag(
"Ropewalk:alwaysHighest");
528 if (deltat > tShove) {
529 infoPtr->errorMsg(
"Error in Ropewalk::init: "
530 "deltat cannot be larger than tShove");
542 double Ropewalk::averageKappa() {
546 for (DMap::iterator itr = dipoles.begin(); itr != dipoles.end(); ++itr) {
549 pair<int,int> overlap = itr->second.getOverlaps( rndmPtr->flat(), m0, r0);
553 pair<double, double> pq = select( overlap.first + 1, overlap.second,
555 double enh = 0.25 * (2. + 2. * pq.first + pq.second);
556 kap += (enh > 1.0 ? enh : 1.0);
568 double Ropewalk::getKappaHere(
int e1,
int e2,
double yfrac) {
570 multimap< pair<int,int>, RopeDipole >::iterator
571 itr = dipoles.find( make_pair(e1,e2) );
572 if (itr == dipoles.end()) itr = dipoles.find( make_pair(e2,e1) );
573 if (itr == dipoles.end())
return 1.0;
574 RopeDipole* d = &(itr->second);
578 pair<int, int> overlap = d->getOverlaps(yfrac, m0, r0);
579 pair<double, double> pq;
583 pq = make_pair(overlap.first + 1, overlap.second);
587 pq = select(overlap.first + 1, overlap.second, rndmPtr);
590 double enh = 0.25 * (2. + 2. * pq.first + pq.second);
591 return (enh > 1.0 ? enh : 1.0);
599 bool Ropewalk::calculateOverlaps() {
602 for (multimap< pair<int,int>, RopeDipole>::iterator itr = dipoles.begin();
603 itr != dipoles.end(); ++itr ) {
604 RopeDipole* d1 = &(itr->second);
605 if (d1->dipoleMomentum().m2Calc() < pow2(m0))
continue;
608 RotBstMatrix dipoleRestFrame = d1->getDipoleRestFrame();
609 double yc1 = d1->d1Ptr()->rap(m0, dipoleRestFrame);
610 double ya1 = d1->d2Ptr()->rap(m0, dipoleRestFrame);
611 if (yc1 <= ya1)
continue;
614 for (multimap< pair<int,int>, RopeDipole>::iterator itr2 = dipoles.begin();
615 itr2 != dipoles.end(); ++itr2) {
616 RopeDipole* d2 = &(itr2->second);
619 if (d1 == d2)
continue;
620 if (d2->dipoleMomentum().m2Calc() < pow2(m0))
continue;
623 OverlappingRopeDipole od(d2, m0, dipoleRestFrame);
624 if (min(od.y1, od.y2) > yc1 || max(od.y1, od.y2) < ya1 || od.y1 == od.y2)
627 d1->addOverlappingDipole(od);
638 pair<int, int> Ropewalk::select(
int m,
int n, Rndm* rndm) {
645 while (mm + nn > 0) {
648 if (rndm->flat() < 0.5 && mm > 0) {
652 double p1 = multiplicity(p + 1, q);
653 double p2 = multiplicity(p, q - 1);
654 double p3 = multiplicity(p - 1, q + 1);
657 double sum = p1 + p2 + p3;
658 p1 /= sum, p2 /= sum, p3 /= sum;
661 double pick = rndm->flat();
663 else if (pick < p1 + p2) --q;
670 double p1 = multiplicity(p, q + 1);
671 double p2 = multiplicity(p -1, q);
672 double p3 = multiplicity(p + 1, q - 1);
673 double sum = p1 + p2 + p3;
674 p1 /= sum, p2 /= sum, p3 /= sum;
675 double pick = rndm->flat();
677 else if (pick < p1 + p2) --p;
683 return make_pair( (p < 0 ? 0 : p), (q < 0 ? 0 : q) );
691 void Ropewalk::shoveTheDipoles(
Event& event) {
695 for (DMap::iterator dItr = dipoles.begin(); dItr != dipoles.end(); ++dItr)
696 dItr->second.propagateInit(tInit);
700 multimap<double, RopeDipole *> rapDipoles;
705 for (DMap::iterator dItr = dipoles.begin(); dItr != dipoles.end(); ++dItr) {
706 RopeDipole* dip = &(dItr->second);
708 rapDipoles.insert( make_pair(dip->maxRapidity(m0), dip) );
710 if (dip->minRapidity(m0) < ymin) ymin = dip->minRapidity(m0);
711 if (dip->maxRapidity(m0) > ymax) ymax = dip->maxRapidity(m0);
715 vector<double> rapidities;
716 for (
double y = ymin; y < ymax; y += deltay) rapidities.push_back(y);
719 map<double, vector<Exc> > exPairs;
720 for (
int i = 0, N = eParticles.size(); i < N; ++i) eParticles[i].clear();
722 for (
int i = 0, N = rapidities.size(); i < N; ++i) {
724 eParticles.push_back( vector<Particle>() );
727 double ySample = rapidities[i];
728 vector<RopeDipole*> tmp;
729 for (multimap<double, RopeDipole*>::iterator
730 rItr = rapDipoles.lower_bound(ySample); rItr != rapDipoles.end(); ++rItr) {
731 if (rItr->second->minRapidity(m0) < ySample)
732 tmp.push_back(rItr->second);
736 vector<int> eraseDipoles;
738 for (
int j = 0, M = tmp.size(); j < M; ++j) {
741 if (!tmp[j]->recoil(ex,
true) ) {
742 eraseDipoles.push_back(j);
746 for (
int j = 0, M = eraseDipoles.size(); j < M; ++j) {
747 tmp.erase( tmp.begin() + (eraseDipoles[j]-j) );
750 if(
int(tmp.size()) > 1)
751 for (
int j = 0, M = tmp.size(); j < M; ++j) {
754 tmp[j]->recoil(ex,
false);
755 Particle pp = Particle(21, 22, 0, 0, 0, 0, 0, 0, ex);
756 pp.vProd( tmp[j]->bInterpolateLab(ySample,m0) );
757 eParticles[i].push_back(pp);
760 exPairs[ySample] = vector<Exc>();
761 for (
int j = 0, M = tmp.size(); j < M; ++j)
762 for (
int k = 0; k < M; ++k) {
764 if(j != k && tmp[j]->index() != tmp[k]->index() )
765 exPairs[ySample].push_back( Exc(ySample, m0, i, j, k, tmp[j],
771 for (map<
double, vector<Exc> >::iterator slItr = exPairs.begin();
772 slItr != exPairs.end(); ++slItr) {
773 for (
int i = 0, N = slItr->second.size(); i < N; ++i) {
774 Exc& ep = slItr->second[i];
775 ep.setParticlePtrs( &eParticles[ep.i][ep.j], &eParticles[ep.i][ep.k] );
780 for (
double t = tInit; t < tShove + tInit; t += deltat) {
782 for (map<
double, vector<Exc> >::iterator slItr = exPairs.begin();
783 slItr != exPairs.end(); ++slItr)
785 for (
int i = 0, N = slItr->second.size(); i < N; ++i) {
786 Exc& ep = slItr->second[i];
788 Vec4 direction = ep.direction();
793 double rt = max(t, 1. / showerCut / 5.068);
794 rt = min(rt, r0 * gExponent);
795 double dist = direction.pT();
797 if (dist < rCutOff * rt) {
799 double gain = 0.5 * deltay * deltat * gAmplitude * dist / rt / rt
800 * exp( -0.25 * dist * dist / rt / rt);
801 double dpx = dist > 0.0 ? gain * direction.px() / dist: 0.0;
802 double dpy = dist > 0.0 ? gain * direction.py() / dist: 0.0;
808 for (DMap::iterator dItr = dipoles.begin(); dItr != dipoles.end(); ++dItr)
809 dItr->second.propagate(deltat, m0);
813 for (DMap::iterator dItr = dipoles.begin(); dItr != dipoles.end(); ++dItr) {
814 RopeDipole* dip = &(dItr->second);
815 if (dip->nExcitations() > 0) dip->excitationsToString( m0, event);
823 bool Ropewalk::extractDipoles(
Event& event, ColConfig& colConfig) {
827 for (
int iSub = 0; iSub < colConfig.size(); ++iSub) {
830 if (colConfig[iSub].hasJunction && !shoveJunctionStrings)
continue;
831 if (colConfig[iSub].isClosed && !shoveGluonLoops)
continue;
832 if (colConfig[iSub].massExcess <= mStringMin && !shoveMiniStrings)
835 colConfig.collect(iSub,event);
836 vector<int> stringPartons = colConfig[iSub].iParton;
837 vector<RopeDipole> stringDipole;
838 bool stringStart =
true;
839 RopeDipoleEnd previous;
840 for (
int iPar =
int(stringPartons.size() - 1); iPar > -1; --iPar) {
841 if (stringPartons[iPar] > 0) {
843 RopeDipoleEnd next( &event, stringPartons[iPar]);
847 pair<int,int> dipoleER = make_pair( stringPartons[iPar + 1],
848 stringPartons[iPar] );
849 RopeDipole test(previous, next, iSub, infoPtr);
850 if ( limitMom && test.dipoleMomentum().pT() < pTcut)
851 dipoles.insert( pair< pair<int, int>, RopeDipole>(dipoleER,
852 RopeDipole( previous, next, iSub, infoPtr)) );
854 dipoles.insert( pair< pair<int, int>, RopeDipole>(dipoleER,
855 RopeDipole( previous, next, iSub, infoPtr)));
878 const double RopeFragPars::DELTAA = 0.1;
881 const double RopeFragPars::ACONV = 0.001;
884 const double RopeFragPars::ZCUT = 1.0e-4;
890 void RopeFragPars::init(Info* infoPtrIn, Settings& settings) {
896 beta = settings.parm(
"Ropewalk:beta");
900 string params [len] = {
"StringPT:sigma",
"StringZ:aLund",
901 "StringZ:aExtraDiquark",
"StringZ:bLund",
"StringFlav:probStoUD",
902 "StringFlav:probSQtoQQ",
"StringFlav:probQQ1toQQ0",
"StringFlav:probQQtoQ",
904 double* variables[len] = {&sigmaIn, &aIn, &adiqIn, &bIn, &rhoIn, &xIn,
905 &yIn, &xiIn, &kappaIn};
906 for (
int i = 0; i < len; ++i) *variables[i] = settings.parm(params[i]);
909 sigmaEff = sigmaIn, aEff = aIn, adiqEff = adiqIn, bEff = bIn,
910 rhoEff = rhoIn, xEff = xIn, yEff = yIn, xiEff = xiIn, kappaEff = kappaIn;
911 if (!insertEffectiveParameters(1.0)) infoPtr->errorMsg(
912 "Error in RopeFragPars::init: failed to insert defaults.");
921 map<string,double> RopeFragPars::getEffectiveParameters(
double h) {
923 map<double, map<string, double> >::iterator parItr = parameters.find(h);
926 if ( parItr != parameters.end())
return parItr->second;
929 if (!calculateEffectiveParameters(h))
930 infoPtr->errorMsg(
"Error in RopeFragPars::getEffectiveParameters:"
931 " calculating effective parameters.");
934 if (!insertEffectiveParameters(h))
935 infoPtr->errorMsg(
"Error in RopeFragPars::getEffectiveParameters:"
936 " inserting effective parameters.");
939 return getEffectiveParameters(h);
947 double RopeFragPars::getEffectiveA(
double thisb,
double mT2,
bool isDiquark) {
950 if (thisb == bIn)
return (isDiquark ? aIn + adiqIn : aIn);
953 map<double, double>* aMPtr = (isDiquark ? &aDiqMap : &aMap);
954 double bmT2 = mT2 * thisb;
957 map<double,double>::iterator aItr = aMPtr->find(bmT2);
958 if (aItr != aMPtr->end())
return aItr->second;
961 double ae = ( isDiquark ? aEffective(aIn + adiqIn, thisb, mT2)
962 : aEffective(aIn, thisb, mT2) );
964 double suba = getEffectiveA(thisb, mT2,
false);
965 aMPtr->insert( make_pair(bmT2,
ae - suba) );
967 else aMPtr->insert(make_pair(bmT2,
ae));
976 bool RopeFragPars::calculateEffectiveParameters(
double h) {
978 if (h <= 0)
return false;
979 double hinv = 1.0 / h;
983 kappaEff = kappaIn * h;
985 rhoEff = pow(rhoIn, hinv);
987 xEff = pow(xIn, hinv);
989 yEff = pow(yIn, hinv);
991 sigmaEff = sigmaIn * sqrt(h);
994 double alpha = (1 + 2. * xIn * rhoIn + 9. * yIn + 6. * xIn * rhoIn * yIn
995 + 3. * yIn * xIn * xIn * rhoIn * rhoIn) / (2. + rhoIn);
996 double alphaEff = (1. + 2. * xEff * rhoEff + 9. * yEff
997 + 6. * xEff * rhoEff * yEff + 3. * yEff * xEff * xEff * rhoEff * rhoEff)
1001 xiEff = alphaEff * beta * pow( xiIn / alpha / beta, hinv);
1002 if (xiEff > 1.0) xiEff = 1.0;
1003 if (xiEff < xiIn) xiEff = xiIn;
1006 bEff = (2. + rhoEff) / (2. + rhoIn) * bIn;
1007 if (bEff < bIn) bEff = bIn;
1008 if (bEff > 2.0) bEff = 2.0;
1011 aEff = getEffectiveA( bEff, 1.0,
false);
1012 adiqEff = getEffectiveA( bEff, 1.0,
true) - aEff;
1022 bool RopeFragPars::insertEffectiveParameters(
double h) {
1024 map<string,double> p;
1025 p[
"StringPT:sigma"] = sigmaEff;
1026 p[
"StringZ:bLund"] = bEff;
1027 p[
"StringFlav:probStoUD"] = rhoEff;
1028 p[
"StringFlav:probSQtoQQ"] = xEff;
1029 p[
"StringFlav:probQQ1toQQ0"] = yEff;
1030 p[
"StringFlav:probQQtoQ"] = xiEff;
1031 p[
"StringZ:aLund"] = aEff;
1032 p[
"StringZ:aExtraDiquark"] = adiqEff;
1033 p[
"StringFlav:kappa"] = kappaEff;
1035 return (parameters.insert( make_pair(h,p)).second );
1043 double RopeFragPars::aEffective(
double aOrig,
double thisb,
double mT2) {
1046 double N = integrateFragFun(aOrig, bIn, mT2);
1047 double NEff = integrateFragFun(aOrig, thisb, mT2);
1048 int s = (N < NEff) ? -1 : 1;
1050 double aNew = aOrig - s * da;
1055 NEff = integrateFragFun(aNew, thisb, mT2);
1056 if ( ((N < NEff) ? -1 : 1) != s ) {
1057 s = (N < NEff) ? -1 : 1;
1063 if (aNew < 0.0) {aNew = 0.1;
break;}
1064 if (aNew > 2.0) {aNew = 2.0;
break;}
1065 }
while (da > ACONV);
1074 double RopeFragPars::fragf(
double z,
double a,
double b,
double mT2) {
1076 if (z < ZCUT)
return 0.0;
1077 return pow(1 - z, a) * exp(-b * mT2 / z) / z;
1085 double RopeFragPars::integrateFragFun(
double a,
double b,
double mT2) {
1088 double nextIter, nextComb;
1089 double thisComb = 0.0, thisIter = 0.0;
1091 double error = 1.0e-2;
1094 for (
int i = 1; i < 20; ++i) {
1095 nextIter = trapIntegrate( a, b, mT2, thisIter, i);
1096 nextComb = (4.0 * nextIter - thisIter) / 3.0;
1097 if (i > 3 && abs(nextComb - thisComb) < error * abs(nextComb))
1099 thisIter = nextIter;
1100 thisComb = nextComb;
1102 infoPtr->errorMsg(
"RopeFragPars::integrateFragFun:"
1103 "No convergence of frag fun integral.");
1112 double RopeFragPars::trapIntegrate(
double a,
double b,
double mT2,
1113 double sOld,
int n) {
1117 if (n == 1)
return 0.5 * (fragf(0.0, a, b, mT2) + fragf(1.0, a, b, mT2));
1121 double deltaz = 1.0 / double(intp);
1122 double z = 0.5 * deltaz;
1125 for (
int i = 0; i < intp; ++i, z += deltaz) sum += fragf( z, a, b, mT2);
1126 return 0.5 * (sOld + sum / double(intp));
1139 bool FlavourRope::doChangeFragPar(StringFlav* flavPtr, StringZ* zPtr,
1140 StringPT * pTPtr,
double m2Had, vector<int> iParton,
int endId) {
1143 map<string, double> newPar;
1145 newPar = fetchParametersBuffon(m2Had, iParton, endId);
1147 newPar = fetchParameters(m2Had, iParton, endId);
1149 for (map<string, double>::iterator itr = newPar.begin(); itr!=newPar.end();
1150 ++itr) settingsPtr->parm( itr->first, itr->second);
1152 flavPtr->init( *settingsPtr, particleDataPtr, rndmPtr, infoPtr);
1153 zPtr->init( *settingsPtr, *particleDataPtr, rndmPtr, infoPtr);
1154 pTPtr->init( *settingsPtr, particleDataPtr, rndmPtr, infoPtr);
1163 map<string, double> FlavourRope::fetchParametersBuffon(
double m2Had,
1164 vector<int> iParton,
int endId) {
1166 if (fixedKappa)
return fp.getEffectiveParameters(h);
1168 infoPtr->errorMsg(
"Error in FlavourRope::fetchParametersBuffon:"
1169 " Event pointer not set in FlavourRope");
1170 return fp.getEffectiveParameters(1.0);
1172 if(find(hadronized.begin(),hadronized.end(),*iParton.begin()) ==
1174 hadronized.reserve(hadronized.size() + iParton.size());
1175 hadronized.insert(hadronized.end(),iParton.begin(),iParton.end());
1180 if(ePtr->at(*(iParton.begin())).id() != endId &&
1181 ePtr->at(*(iParton.end() - 1)).id() != endId) {
1182 infoPtr->errorMsg(
"Error in FlavourRope::fetchParametersBuffon:"
1183 " Quark end inconsistency.");
1184 return fp.getEffectiveParameters(1.0);
1188 if(ePtr->at(*(iParton.begin())).id() != endId)
1189 reverse(iParton.begin(),iParton.end());
1192 Vec4 hadronic4Momentum(0,0,0,0);
1195 vector<int>::iterator dipItr;
1197 for(dipItr = iParton.begin(); dipItr != iParton.end(); ++dipItr){
1198 double m2Big = hadronic4Momentum.m2Calc();
1199 if( m2Had <= m2Big){
1207 else if(dipItr - 1 == iParton.begin()){
1208 dipFrac = sqrt(m2Had/m2Big);
1211 if(ePtr->at(*(dipItr - 1)).id() != 21) {
1212 infoPtr->errorMsg(
"Error in FlavourRope::fetchParametersBuffon:"
1213 " Connecting partons should always be gluons.");
1214 return fp.getEffectiveParameters(1.0);
1217 hadronic4Momentum -= 0.5*ePtr->at(*(dipItr -1)).p();
1218 double m2Small = hadronic4Momentum.m2Calc();
1220 dipFrac = (sqrt(m2Had) - sqrt(m2Small)) /
1221 (sqrt(m2Big) - sqrt(m2Small));
1225 hadronic4Momentum += ePtr->at(*dipItr).id() == 21 ?
1226 0.5*ePtr->at(*dipItr).p() : ePtr->at(*dipItr).p();
1230 if(dipItr == iParton.end())
1231 return fp.getEffectiveParameters(1.0);
1233 if(dipFrac < 0 || dipFrac > 1) {
1234 infoPtr->errorMsg(
"Error in FlavourRope::fetchParametersBuffon:"
1235 " Dipole exceed with fraction less than 0 or greater than 1.");
1236 return fp.getEffectiveParameters(1.0);
1243 yBreak = ePtr->at(*dipItr).y();
1246 if(dipItr == iParton.begin()) {
1247 infoPtr->errorMsg(
"Error in FlavourRope::fetchParametersBuffon:"
1248 " We are somehow before the first dipole on a string.");
1249 return fp.getEffectiveParameters(1.0);
1251 double dy = ePtr->at(*dipItr).y() - ePtr->at(*(dipItr - 1)).y();
1252 yBreak = ePtr->at(*(dipItr - 1)).y() + dipFrac*dy;
1259 for(
int i = 0; i < ePtr->size(); ++i){
1262 if(find(iParton.begin(),iParton.end(), i) != iParton.end())
1265 if(find(hadronized.begin(),hadronized.end(),i) != hadronized.end())
1267 double pRap = ePtr->at(i).y();
1268 if(pRap > yBreak - rapiditySpan && pRap < yBreak + rapiditySpan ){
1272 double r1 = rndmPtr->flat();
1273 double r2 = rndmPtr->flat();
1274 double theta1 = 2*M_PI*rndmPtr->flat();
1275 double theta2 = 2*M_PI*rndmPtr->flat();
1277 if(4*pow2(stringProtonRatio) > pow2(sqrt(r1)*cos(theta1) -
1278 sqrt(r2)*cos(theta2)) + pow2(sqrt(r1)*sin(theta1) -
1279 sqrt(r2)*sin(theta2))) {
1280 if(rndmPtr->flat() < 0.5) p += 0.5;
1285 enh = 0.25*(2.0*p+q+2.0);
1287 return fp.getEffectiveParameters(enh);
1292 return fp.getEffectiveParameters(1.0);
1294 return fp.getEffectiveParameters(1.0);
1300 map<string, double> FlavourRope::fetchParameters(
double m2Had,
1301 vector<int> iParton,
int endId) {
1303 if (fixedKappa)
return fp.getEffectiveParameters(h);
1305 infoPtr->errorMsg(
"Error in FlavourRope::fetchParameters:"
1306 " Event pointer not set in FlavourRope");
1307 return fp.getEffectiveParameters(1.0);
1310 int eventIndex = -1;
1313 if( ePtr->at(iParton[0]).id() == endId) dirPos =
true;
1314 else if( ePtr->at(iParton[iParton.size() - 1]).
id() == endId) dirPos =
false;
1316 infoPtr->errorMsg(
"Error in FlavourRope::fetchParameters:"
1317 " Could not get string direction");
1318 return fp.getEffectiveParameters(1.0);
1321 for (
int i = 0, N = iParton.size(); i < N; ++i) {
1323 int j = (dirPos ? i : N - 1 - i);
1325 if ( iParton[j] < 0)
continue;
1326 mom += ePtr->at(iParton[j]).p();
1327 if ( mom.m2Calc() > m2Had) {
1335 double m2Here = mom.m2Calc();
1339 if (eventIndex == -1 || eventIndex == 0) {
1341 dipFrac = sqrt(m2Had / m2Here);
1344 mom -= ePtr->at(iParton[eventIndex]).p();
1345 double m2Small = mom.m2Calc();
1346 dipFrac = (sqrt(m2Had) - sqrt(m2Small)) / (sqrt(m2Here) - sqrt(m2Small));
1348 double enh = rwPtr->getKappaHere( iParton[eventIndex],
1349 iParton[eventIndex + 1], dipFrac);
1350 return fp.getEffectiveParameters(enh);
void ae(int tracks=-1, int hits=-1)
This function is to search for the next non-empty event and draw it by looping over StBFChain (readin...