9 #include "SpaceShower.h"
23 const bool SpaceShower::DEBUG =
false;
27 const int SpaceShower::MAXLOOPTINYPDF = 10;
31 const double SpaceShower::CTHRESHOLD = 2.0;
32 const double SpaceShower::BTHRESHOLD = 2.0;
36 const double SpaceShower::EVALPDFSTEP = 0.1;
39 const double SpaceShower::TINYPDF = 1e-10;
42 const double SpaceShower::TINYKERNELPDF = 1e-6;
45 const double SpaceShower::TINYPT2 = 0.25e-6;
49 const double SpaceShower::HEAVYPT2EVOL = 1.1;
54 const double SpaceShower::HEAVYXEVOL = 0.9;
59 const double SpaceShower::EXTRASPACEQ = 2.0;
62 const double SpaceShower::LAMBDA3MARGIN = 1.1;
66 const double SpaceShower::LEPTONXMIN = 1e-10;
67 const double SpaceShower::LEPTONXMAX = 1. - 1e-10;
70 const double SpaceShower::LEPTONPT2MIN = 1.2;
73 const double SpaceShower::LEPTONFUDGE = 10.;
79 void SpaceShower::init( BeamParticle* beamAPtrIn,
80 BeamParticle* beamBPtrIn) {
83 beamAPtr = beamAPtrIn;
84 beamBPtr = beamBPtrIn;
87 doQCDshower = settingsPtr->flag(
"SpaceShower:QCDshower");
88 doQEDshowerByQ = settingsPtr->flag(
"SpaceShower:QEDshowerByQ");
89 doQEDshowerByL = settingsPtr->flag(
"SpaceShower:QEDshowerByL");
92 pTmaxMatch = settingsPtr->mode(
"SpaceShower:pTmaxMatch");
93 pTdampMatch = settingsPtr->mode(
"SpaceShower:pTdampMatch");
94 pTmaxFudge = settingsPtr->parm(
"SpaceShower:pTmaxFudge");
95 pTmaxFudgeMPI = settingsPtr->parm(
"SpaceShower:pTmaxFudgeMPI");
96 pTdampFudge = settingsPtr->parm(
"SpaceShower:pTdampFudge");
99 doRapidityOrder = settingsPtr->flag(
"SpaceShower:rapidityOrder");
102 mc = particleDataPtr->m0(4);
103 mb = particleDataPtr->m0(5);
108 alphaSvalue = settingsPtr->parm(
"SpaceShower:alphaSvalue");
109 alphaSorder = settingsPtr->mode(
"SpaceShower:alphaSorder");
110 alphaS2pi = 0.5 * alphaSvalue / M_PI;
113 alphaS.init( alphaSvalue, alphaSorder);
116 Lambda5flav = alphaS.Lambda5();
117 Lambda4flav = alphaS.Lambda4();
118 Lambda3flav = alphaS.Lambda3();
119 Lambda5flav2 = pow2(Lambda5flav);
120 Lambda4flav2 = pow2(Lambda4flav);
121 Lambda3flav2 = pow2(Lambda3flav);
125 useSamePTasMPI = settingsPtr->flag(
"SpaceShower:samePTasMPI");
126 if (useSamePTasMPI) {
127 pT0Ref = settingsPtr->parm(
"MultipartonInteractions:pT0Ref");
128 ecmRef = settingsPtr->parm(
"MultipartonInteractions:ecmRef");
129 ecmPow = settingsPtr->parm(
"MultipartonInteractions:ecmPow");
130 pTmin = settingsPtr->parm(
"MultipartonInteractions:pTmin");
132 pT0Ref = settingsPtr->parm(
"SpaceShower:pT0Ref");
133 ecmRef = settingsPtr->parm(
"SpaceShower:ecmRef");
134 ecmPow = settingsPtr->parm(
"SpaceShower:ecmPow");
135 pTmin = settingsPtr->parm(
"SpaceShower:pTmin");
139 sCM = m2( beamAPtr->p(), beamBPtr->p());
141 pT0 = pT0Ref * pow(eCM / ecmRef, ecmPow);
144 double pTminAbs = sqrtpos(pow2(LAMBDA3MARGIN) * Lambda3flav2 - pT0*pT0);
145 if (pTmin < pTminAbs) {
147 ostringstream newPTmin;
148 newPTmin << fixed << setprecision(3) << pTmin;
149 infoPtr->errorMsg(
"Warning in SpaceShower::init: pTmin too low",
150 ", raised to " + newPTmin.str() );
151 infoPtr->setTooLowPTmin(
true);
155 alphaEMorder = settingsPtr->mode(
"SpaceShower:alphaEMorder");
158 alphaEM.init( alphaEMorder, settingsPtr);
161 pTminChgQ = settingsPtr->parm(
"SpaceShower:pTminchgQ");
162 pTminChgL = settingsPtr->parm(
"SpaceShower:pTminchgL");
166 pT2min = pow2(pTmin);
167 pT2minChgQ = pow2(pTminChgQ);
168 pT2minChgL = pow2(pTminChgL);
171 doMEcorrections = settingsPtr->flag(
"SpaceShower:MEcorrections");
172 doMEafterFirst = settingsPtr->flag(
"SpaceShower:MEafterFirst");
173 doPhiPolAsym = settingsPtr->flag(
"SpaceShower:phiPolAsym");
174 doPhiIntAsym = settingsPtr->flag(
"SpaceShower:phiIntAsym");
175 strengthIntAsym = settingsPtr->parm(
"SpaceShower:strengthIntAsym");
176 nQuarkIn = settingsPtr->mode(
"SpaceShower:nQuarkIn");
180 = settingsPtr->mode(
"MultipartonInteractions:enhanceScreening");
181 if (!useSamePTasMPI) enhanceScreening = 0;
184 canVetoEmission = (userHooksPtr > 0) ? userHooksPtr->canVetoISREmission()
194 bool SpaceShower::limitPTmax(
Event& event,
double Q2Fac,
double Q2Ren) {
197 bool dopTlimit =
false;
198 if (pTmaxMatch == 1) dopTlimit =
true;
199 else if (pTmaxMatch == 2) dopTlimit =
false;
203 for (
int i = 5; i <
event.size(); ++i)
204 if (event[i].status() != -21) {
205 int idAbs =
event[i].idAbs();
206 if (idAbs <= 5 || idAbs == 21 || idAbs == 22) dopTlimit =
true;
213 if ( !dopTlimit && (pTdampMatch == 1 || pTdampMatch == 2) ) {
215 pT2damp = pow2(pTdampFudge) * ((pTdampMatch == 1) ? Q2Fac : Q2Ren);
228 void SpaceShower::prepare(
int iSys,
Event& event,
bool limitPTmaxIn) {
231 int in1 = partonSystemsPtr->getInA(iSys);
232 int in2 = partonSystemsPtr->getInB(iSys);
235 bool canRadiate1 = !(
event[in1].isRescatteredIncoming());
236 bool canRadiate2 = !(
event[in2].isRescatteredIncoming());
239 if (iSys == 0) dipEnd.resize(0);
240 if (iSys == 0) idResFirst = 0;
241 if (iSys == 1) idResSecond = 0;
244 int MEtype = findMEtype( iSys, event);
247 double pTmax1 = (limitPTmaxIn) ? event[in1].scale() : eCM;
248 double pTmax2 = (limitPTmaxIn) ? event[in2].scale() : eCM;
249 if (iSys == 0 && limitPTmaxIn) {
250 pTmax1 *= pTmaxFudge;
251 pTmax2 *= pTmaxFudge;
252 }
else if (iSys > 0 && limitPTmaxIn) {
253 pTmax1 *= pTmaxFudgeMPI;
254 pTmax2 *= pTmaxFudgeMPI;
260 int colType1 =
event[in1].colType();
261 if (canRadiate1) dipEnd.push_back( SpaceDipoleEnd( iSys, 1,
262 in1, in2, pTmax1, colType1, 0, MEtype, canRadiate2) );
263 int colType2 =
event[in2].colType();
264 if (canRadiate2) dipEnd.push_back( SpaceDipoleEnd( iSys, 2,
265 in2, in1, pTmax2, colType2, 0, MEtype, canRadiate1) );
270 if (doQEDshowerByQ || doQEDshowerByL) {
271 int chgType1 = ( (
event[in1].isQuark() && doQEDshowerByQ)
272 || (event[in1].isLepton() && doQEDshowerByL) )
273 ?
event[in1].chargeType() : 0;
275 if (event[in1].
id() == 22 && doQEDshowerByQ) chgType1 = 22 ;
276 if (canRadiate1) dipEnd.push_back( SpaceDipoleEnd( iSys, -1,
277 in1, in2, pTmax1, 0, chgType1, MEtype, canRadiate2) );
278 int chgType2 = ( (
event[in2].isQuark() && doQEDshowerByQ)
279 || (event[in2].isLepton() && doQEDshowerByL) )
280 ?
event[in2].chargeType() : 0;
282 if (event[in2].
id() == 22 && doQEDshowerByQ) chgType2 = 22 ;
283 if (canRadiate2) dipEnd.push_back( SpaceDipoleEnd( iSys, -2,
284 in2, in1, pTmax2, 0, chgType2, MEtype, canRadiate1) );
289 if (iSys == 0 && infoPtr->hasHistory()) {
290 double zNow = infoPtr->zNowISR();
291 double pT2Now = infoPtr->pT2NowISR();
292 for (
int iDipEnd = 0; iDipEnd < int(dipEnd.size()); ++iDipEnd) {
293 dipEnd[iDipEnd].zOld = zNow;
294 dipEnd[iDipEnd].pT2Old = pT2Now;
295 ++dipEnd[iDipEnd].nBranch;
305 double SpaceShower::pTnext(
Event& event,
double pTbegAll,
double pTendAll,
309 sCM = m2( beamAPtr->p(), beamBPtr->p());
315 double pT2sel = pow2(pTendAll);
321 for (
int iDipEnd = 0; iDipEnd < int(dipEnd.size()); ++iDipEnd) {
323 dipEndNow = &dipEnd[iDipEnd];
324 iSysNow = dipEndNow->system;
328 double pT2begDip = pow2( min( pTbegAll, dipEndNow->pTmax ));
329 if (pT2begDip > pT2sel
330 && ( dipEndNow->colType != 0 || dipEndNow->chgType != 0 ) ) {
331 double pT2endDip = 0.;
334 if (dipEndNow->colType != 0) pT2endDip = max( pT2sel, pT2min );
335 else if (abs(dipEndNow->chgType) != 3) pT2endDip
336 = max( pT2sel, pT2minChgQ );
337 else pT2endDip = max( pT2sel, pT2minChgL );
340 sideA = ( abs(dipEndNow->side) == 1 );
341 BeamParticle& beamNow = (sideA) ? *beamAPtr : *beamBPtr;
342 BeamParticle& beamRec = (sideA) ? *beamBPtr : *beamAPtr;
343 iNow = beamNow[iSysNow].iPos();
344 iRec = beamRec[iSysNow].iPos();
345 idDaughter = beamNow[iSysNow].id();
346 xDaughter = beamNow[iSysNow].x();
347 x1Now = (sideA) ? xDaughter : beamRec[iSysNow].x();
348 x2Now = (sideA) ? beamRec[iSysNow].x() : xDaughter;
351 m2Rec = (dipEndNow->normalRecoil) ? 0. : event[iRec].m2();
352 m2Dip = x1Now * x2Now * sCM + m2Rec;
355 if (pT2begDip > pT2endDip) {
356 if (dipEndNow->colType != 0) pT2nextQCD( pT2begDip, pT2endDip);
357 else pT2nextQED( pT2begDip, pT2endDip);
361 if (dipEndNow->pT2 > pT2sel) {
362 pT2sel = dipEndNow->pT2;
365 dipEndSel = dipEndNow;
373 return (dipEndSel == 0) ? 0. : sqrt(pT2sel);
380 void SpaceShower::pT2nextQCD(
double pT2begDip,
double pT2endDip) {
383 BeamParticle&
beam = (sideA) ? *beamAPtr : *beamBPtr;
384 bool isGluon = (idDaughter == 21);
385 bool isValence = beam[iSysNow].isValence();
386 int MEtype = dipEndNow->MEtype;
387 double pT2 = pT2begDip;
388 double xMaxAbs = beam.xMax(iSysNow);
389 double zMinAbs = xDaughter / xMaxAbs;
391 infoPtr->errorMsg(
"Warning in SpaceShower::pT2nextQCD: "
397 double idMassive = 0;
398 if ( abs(idDaughter) == 4 ) idMassive = 4;
399 if ( abs(idDaughter) == 5 ) idMassive = 5;
400 bool isMassive = (idMassive > 0);
401 double m2Massive = 0.;
403 double zMaxMassive = 1.;
404 double m2Threshold = pT2;
408 m2Massive = (idMassive == 4) ? m2c : m2b;
409 if (pT2 < HEAVYPT2EVOL * m2Massive)
return;
410 mRatio = sqrt( m2Massive / m2Dip );
411 zMaxMassive = (1. - mRatio) / ( 1. + mRatio * (1. - mRatio) );
412 if (xDaughter > HEAVYXEVOL * zMaxMassive * xMaxAbs)
return;
415 m2Threshold = (idMassive == 4) ? min( pT2, CTHRESHOLD * m2c)
416 : min( pT2, BTHRESHOLD * m2b);
422 double Lambda2 = Lambda3flav2;
423 double pT2minNow = pT2endDip;
428 double zRootMax = 0.;
429 double zRootMin = 0.;
434 double g2Qenhance = 0.;
435 double xPDFdaughter = 0.;
436 double xPDFmother[21] = {0.};
437 double xPDFgMother = 0.;
438 double xPDFmotherSum = 0.;
439 double kernelPDF = 0.;
444 double m2Sister = 0.;
447 bool needNewPDF =
true;
450 int loopTinyPDFdau = 0;
451 bool hasTinyPDFdau =
false;
457 if (hasTinyPDFdau) ++loopTinyPDFdau;
458 if (loopTinyPDFdau > MAXLOOPTINYPDF) {
459 infoPtr->errorMsg(
"Warning in SpaceShower::pT2nextQCD: "
460 "small daughter PDF");
467 if (needNewPDF || pT2 < EVALPDFSTEP * pT2PDF) {
469 hasTinyPDFdau =
false;
474 pT2minNow = max( m2b, pT2endDip);
476 Lambda2 = Lambda5flav2;
477 }
else if (pT2 > m2c) {
479 pT2minNow = max( m2c, pT2endDip);
481 Lambda2 = Lambda4flav2;
484 pT2minNow = pT2endDip;
486 Lambda2 = Lambda3flav2;
488 zMaxAbs = 1. - 0.5 * (pT2minNow / m2Dip) *
489 ( sqrt( 1. + 4. * m2Dip / pT2minNow ) - 1. );
490 if (isMassive) zMaxAbs = min( zMaxAbs, zMaxMassive);
493 if (zMinAbs > zMaxAbs) {
494 if (nFlavour == 3 || (idMassive == 4 && nFlavour == 4)
495 || idMassive == 5)
return;
496 pT2 = (nFlavour == 4) ? m2c : m2b;
501 xPDFdaughter = beam.xfISR(iSysNow, idDaughter, xDaughter, pT2);
502 if (xPDFdaughter < TINYPDF) {
503 xPDFdaughter = TINYPDF;
504 hasTinyPDFdau =
true;
509 g2gInt = 6. * log(zMaxAbs * (1.-zMinAbs)
510 / (zMinAbs * (1.-zMaxAbs)));
511 if (doMEcorrections) g2gInt *= calcMEmax(MEtype, 21, 21);
512 q2gInt = (16./3.) * (1./sqrt(zMinAbs) - 1./sqrt(zMaxAbs));
513 if (doMEcorrections) q2gInt *= calcMEmax(MEtype, 1, 21);
517 for (
int i = -nQuarkIn; i <= nQuarkIn; ++i) {
521 xPDFmother[i+10] = beam.xfISR(iSysNow, i, xDaughter, pT2);
522 xPDFmotherSum += xPDFmother[i+10];
527 kernelPDF = g2gInt + q2gInt * xPDFmotherSum / xPDFdaughter;
531 }
else if (isValence) {
532 zRootMin = (1. + sqrt(zMinAbs)) / (1. - sqrt(zMinAbs));
533 zRootMax = (1. + sqrt(zMaxAbs)) / (1. - sqrt(zMaxAbs));
534 q2qInt = (8./3.) * log( zRootMax / zRootMin );
535 if (doMEcorrections) q2qInt *= calcMEmax(MEtype, 1, 1);
540 q2qInt = (8./3.) * log( (1. - zMinAbs) / (1. - zMaxAbs) );
541 if (doMEcorrections) q2qInt *= calcMEmax(MEtype, 1, 1);
542 g2qInt = 0.5 * (zMaxAbs - zMinAbs);
543 if (doMEcorrections) g2qInt *= calcMEmax(MEtype, 21, 1);
547 if (alphaSorder == 0) g2Qenhance = log(pT2/m2Massive)
548 / log(m2Threshold/m2Massive);
550 double m2log = log( m2Massive / Lambda2);
551 g2Qenhance = log( log(pT2/Lambda2) / m2log )
552 / log( log(m2Threshold/Lambda2) / m2log );
554 g2qInt *= g2Qenhance;
558 xPDFgMother = beam.xfISR(iSysNow, 21, xDaughter, pT2);
561 kernelPDF = q2qInt + g2qInt * xPDFgMother / xPDFdaughter;
567 if (kernelPDF < TINYKERNELPDF)
return;
574 if (alphaSorder == 0) {
575 pT2 = (pT2 + pT20) * pow( rndmPtr->flat(),
576 1. / (alphaS2pi * kernelPDF)) - pT20;
579 }
else if (alphaSorder == 1) {
580 pT2 = Lambda2 * pow( (pT2 + pT20) / Lambda2,
581 pow(rndmPtr->flat(), b0 / kernelPDF) ) - pT20;
586 pT2 = Lambda2 * pow( (pT2 + pT20) / Lambda2,
587 pow(rndmPtr->flat(), b0 / kernelPDF) ) - pT20;
588 Q2alphaS = max(pT2 + pT20, pow2(LAMBDA3MARGIN) * Lambda3flav2);
589 }
while (alphaS.alphaS2OrdCorr(Q2alphaS) < rndmPtr->flat()
596 if (idMassive == 5 && pT2 < m2Threshold) {
597 pT2nearQCDthreshold( beam, m2Massive, m2Threshold, xMaxAbs,
598 zMinAbs, zMaxMassive );
602 }
else if (nFlavour == 5 && pT2 < m2b) {
608 }
else if (idMassive == 4 && pT2 < m2Threshold) {
609 pT2nearQCDthreshold( beam, m2Massive, m2Threshold, xMaxAbs,
610 zMinAbs, zMaxMassive );
614 }
else if (nFlavour == 4 && pT2 < m2c) {
620 }
else if (pT2 < pT2endDip)
return;
625 if (rndmPtr->flat() * kernelPDF < g2gInt) {
628 z = 1. / ( 1. + ((1. - zMinAbs) / zMinAbs) * pow( (zMinAbs *
629 (1. - zMaxAbs)) / (zMaxAbs * (1. - zMinAbs)), rndmPtr->flat() ) );
630 wt = pow2( 1. - z * (1. - z));
633 double temp = xPDFmotherSum * rndmPtr->flat();
634 idMother = -nQuarkIn - 1;
635 do { temp -= xPDFmother[(++idMother) + 10]; }
636 while (temp > 0. && idMother < nQuarkIn);
638 z = (zMinAbs * zMaxAbs) / pow2( sqrt(zMinAbs) + rndmPtr->flat()
639 * ( sqrt(zMaxAbs)- sqrt(zMinAbs) ));
640 wt = 0.5 * (1. + pow2(1. - z)) * sqrt(z)
641 * xPDFdaughter / xPDFmother[idMother + 10];
648 if (isValence || rndmPtr->flat() * kernelPDF < q2qInt) {
649 idMother = idDaughter;
653 double zTmp = zRootMin * pow(zRootMax / zRootMin, rndmPtr->flat() );
654 z = pow2( (1. - zTmp) / (1. + zTmp) );
656 z = 1. - (1. - zMinAbs) * pow( (1. - zMaxAbs) / (1. - zMinAbs),
660 wt = 0.5 * (1. + pow2(z));
664 wt = 0.5 * (1. + pow2(z)) - z * pow2(1.-z) * m2Massive / pT2;
666 if (isValence) wt *= sqrt(z);
670 idSister = - idDaughter;
671 z = zMinAbs + rndmPtr->flat() * (zMaxAbs - zMinAbs);
673 wt = (pow2(z) + pow2(1.-z)) * xPDFdaughter / xPDFgMother ;
675 wt = (pow2(z) + pow2(1.-z) + 2. * z * (1.-z) * m2Massive / pT2)
676 * xPDFdaughter / (xPDFgMother * g2Qenhance) ;
683 xMother = xDaughter / z;
685 if (!dipEndNow->normalRecoil) {
686 if (sideA) xMother += (m2Rec / (x2Now * sCM)) * (1. / z - 1.);
687 else xMother += (m2Rec / (x1Now * sCM)) * (1. / z - 1.);
689 if(xMother > xMaxAbs) { wt = 0.;
continue; }
692 mSister = particleDataPtr->m0(idSister);
693 m2Sister = pow2(mSister);
694 pT2corr = Q2 - z * (m2Dip + Q2) * (Q2 + m2Sister) / m2Dip;
695 if(pT2corr < TINYPT2) { wt = 0.;
continue; }
698 if ( doRapidityOrder && dipEndNow->nBranch > 0
699 && pT2 > pow2( (1. - z) / (z * (1. - dipEndNow->zOld)) )
700 * dipEndNow->pT2Old ) { wt = 0.;
continue; }
704 if ( isGluon && ( abs(idMother) == 4 || abs(idMother) == 5 )) {
705 double m2QQsister = EXTRASPACEQ * 4. * m2Sister;
706 double pT2QQcorr = Q2 - z * (m2Dip + Q2) * (Q2 + m2QQsister) / m2Dip;
707 if(pT2QQcorr < TINYPT2) { wt = 0.;
continue; }
711 if (doMEcorrections) wt *= calcMEcorr(MEtype, idMother, idDaughter,
712 m2Dip, z, Q2) / calcMEmax(MEtype, idMother, idDaughter);
715 if (dopTdamp && iSysNow == 0 && MEtype == 0 && nRad == 0)
716 wt *= pT2damp / (pT2 + pT2damp);
720 if (enhanceScreening == 2) {
721 int nSysNow = infoPtr->nMPI() + infoPtr->nISR() + 1;
722 double WTscreen = pow2( (pT2 + pT20) / (pT2 + nSysNow * pT20) );
727 double xPDFdaughterNew = max ( TINYPDF,
728 beam.xfISR(iSysNow, idDaughter, xDaughter, pT2) );
729 double xPDFmotherNew = beam.xfISR(iSysNow, idMother, xMother, pT2);
730 wt *= xPDFmotherNew / xPDFdaughterNew;
733 if (wt > 1.) infoPtr->errorMsg(
"Warning in SpaceShower::"
734 "pT2nextQCD: weight above unity");
737 }
while (wt < rndmPtr->flat()) ;
740 dipEndNow->store( idDaughter,idMother, idSister, x1Now, x2Now, m2Dip,
741 pT2, z, xMother, Q2, mSister, m2Sister, pT2corr);
752 void SpaceShower::pT2nearQCDthreshold( BeamParticle& beam,
753 double m2Massive,
double m2Threshold,
double xMaxAbs,
754 double zMinAbs,
double zMaxMassive) {
757 double Lambda2 = (abs(idDaughter) == 4) ? Lambda4flav2 : Lambda5flav2;
758 double logM2Lambda2 = log( m2Massive / Lambda2 );
759 double xPDFmotherOld = beam.xfISR(iSysNow, 21, xDaughter, m2Threshold);
776 infoPtr->errorMsg(
"Error in SpaceShower::pT2nearQCDthreshold: "
782 pT2 = m2Massive * pow( m2Threshold / m2Massive, rndmPtr->flat() );
785 z = zMinAbs + rndmPtr->flat() * (zMaxMassive - zMinAbs);
788 Q2 = pT2 / (1.-z) - m2Massive;
789 pT2corr = Q2 - z * (m2Dip + Q2) * (Q2 + m2Massive) / m2Dip;
790 if(pT2corr < TINYPT2)
continue;
793 wt = logM2Lambda2 / log( pT2 / Lambda2 );
796 wt *= pow2(z) + pow2(1.-z) + 2. * z * (1.-z) * m2Massive / pT2;
799 xMother = xDaughter / z;
800 if (!dipEndNow->normalRecoil) {
801 if (sideA) xMother += (m2Rec / (x2Now * sCM)) * (1. / z - 1.);
802 else xMother += (m2Rec / (x1Now * sCM)) * (1. / z - 1.);
804 if (xMother > xMaxAbs) { wt = 0.;
continue; }
807 double xPDFmotherNew = beam.xfISR(iSysNow, 21, xMother, pT2);
808 wt *= xPDFmotherNew / xPDFmotherOld;
811 }
while (wt < rndmPtr->flat()) ;
814 double mSister = (abs(idDaughter) == 4) ? mc : mb;
815 dipEndNow->store( idDaughter, 21, -idDaughter, x1Now, x2Now, m2Dip,
816 pT2, z, xMother, Q2, mSister, pow2(mSister), pT2corr);
824 void SpaceShower::pT2nextQED(
double pT2begDip,
double pT2endDip) {
827 BeamParticle& beam = (sideA) ? *beamAPtr : *beamBPtr;
828 bool isLeptonBeam = beam.isLepton();
829 int MEtype = dipEndNow->MEtype;
830 bool isPhoton = (idDaughter == 22);
831 double pT2 = pT2begDip;
832 double m2Lepton = (isLeptonBeam) ? pow2(beam.m()) : 0.;
833 if (isLeptonBeam && pT2begDip < m2Lepton)
return;
836 if (isPhoton && isLeptonBeam)
return;
839 double alphaEMmax = alphaEM.alphaEM(pT2begDip);
840 double alphaEM2pi = alphaEMmax / (2. * M_PI);
843 double xMaxAbs = (isLeptonBeam) ? LEPTONXMAX : beam.xMax(iSysNow);
844 double zMinAbs = xDaughter / xMaxAbs;
846 infoPtr->errorMsg(
"Warning in SpaceShower::pT2nextQED: "
852 double zMaxAbs = 1. - 0.5 * (pT2endDip / m2Dip) *
853 ( sqrt( 1. + 4. * m2Dip / pT2endDip ) - 1. );
855 double zMaxLepton = xDaughter / (xDaughter + LEPTONXMIN);
856 if (zMaxLepton < zMaxAbs) zMaxAbs = zMaxLepton;
858 if (zMaxAbs < zMinAbs)
return;
868 double m2Sister = 0.;
877 double f2fIntA = 2. * log( (1. - zMinAbs) / (1. - zMaxAbs) );
880 f2fIntB = 2. * log( (zMaxAbs - xDaughter) / (zMinAbs - xDaughter) );
881 f2fInt = f2fIntA + f2fIntB;
882 }
else f2fInt = pow2(dipEndNow->chgType / 3.) * f2fIntA;
885 if (doMEcorrections) f2fInt *= calcMEmax(MEtype, 1, 1);
886 double kernelPDF = alphaEM2pi * f2fInt;
887 double fudge = (isLeptonBeam) ? LEPTONFUDGE * log(m2Dip/m2Lepton) : 1.;
889 if (kernelPDF < TINYKERNELPDF)
return;
896 double shift = pow(rndmPtr->flat(), 1. / kernelPDF);
897 if (isLeptonBeam) pT2 = m2Lepton * pow( pT2 / m2Lepton, shift);
898 else pT2 = pT2 * shift;
901 if (pT2 < pT2endDip)
return;
902 if (isLeptonBeam && pT2 < LEPTONPT2MIN * m2Lepton)
return;
905 idMother = idDaughter;
906 wt = 0.5 * (1. + pow2(z));
908 if (f2fIntA > rndmPtr->flat() * (f2fIntA + f2fIntB)) {
909 z = 1. - (1. - zMinAbs)
910 * pow( (1. - zMaxAbs) / (1. - zMinAbs), rndmPtr->flat() );
912 z = xDaughter + (zMinAbs - xDaughter)
913 * pow( (zMaxAbs - xDaughter) / (zMinAbs - xDaughter),
916 wt *= (z - xDaughter) / (1. - xDaughter);
918 z = 1. - (1. - zMinAbs)
919 * pow( (1. - zMaxAbs) / (1. - zMinAbs), rndmPtr->flat() );
924 xMother = xDaughter / z;
926 if (!dipEndNow->normalRecoil) {
927 if (sideA) xMother += (m2Rec / (x2Now * sCM)) * (1. / z - 1.);
928 else xMother += (m2Rec / (x1Now * sCM)) * (1. / z - 1.);
930 if(xMother > xMaxAbs) { wt = 0.;
continue; }
935 pT2corr = Q2 - z * (m2Dip + Q2) * (Q2 + m2Sister) / m2Dip;
936 if(pT2corr < TINYPT2) { wt = 0.;
continue; }
939 if (isLeptonBeam) wt *= log(pT2 / m2Lepton) / fudge;
942 if (doMEcorrections) wt *= calcMEcorr(MEtype, idMother, idDaughter,
943 m2Dip, z, Q2) / calcMEmax(MEtype, idMother, idDaughter);
946 if (doMEcorrections && MEtype == 1 && idDaughter == idMother
947 && ( (iSysNow == 0 && idResFirst == 24)
948 || (iSysNow == 1 && idResSecond == 24) ) ) {
950 double uHe = Q2 - m2Dip * (1. - z) / z;
951 double chg1 = abs(dipEndNow->chgType / 3.);
952 double chg2 = 1. - chg1;
953 wt *= pow2(chg1 * uHe - chg2 * tHe)
954 / ( (tHe + uHe) * (pow2(chg1) * uHe + pow2(chg2) * tHe) );
958 if (dopTdamp && iSysNow == 0 && MEtype == 0 && nRad == 0)
959 wt *= pT2damp / (pT2 + pT2damp);
962 double alphaEMnow = alphaEM.alphaEM(pT2);
963 wt *= (alphaEMnow / alphaEMmax);
966 double xPDFdaughterNew = max ( TINYPDF,
967 beam.xfISR(iSysNow, idDaughter, xDaughter, pT2) );
968 double xPDFmotherNew = beam.xfISR(iSysNow, idMother, xMother, pT2);
969 wt *= xPDFmotherNew / xPDFdaughterNew;
972 }
while (wt < rndmPtr->flat()) ;
980 double kernelPDF = 0.0;
981 double xPDFdaughter = 0.;
982 double xPDFmother[21] = {0.};
983 double xPDFmotherSum = 0.0;
985 double pT2minNow = pT2endDip;
986 bool needNewPDF =
true;
989 int loopTinyPDFdau = 0;
990 bool hasTinyPDFdau =
false;
995 if (hasTinyPDFdau) ++loopTinyPDFdau;
996 if (loopTinyPDFdau > MAXLOOPTINYPDF) {
997 infoPtr->errorMsg(
"Warning in SpaceShower::pT2nextQED: "
998 "small daughter PDF");
1005 if (needNewPDF || pT2 < EVALPDFSTEP * pT2PDF) {
1008 hasTinyPDFdau =
false;
1011 if (pT2 > m2b && nQuarkIn >= 5) {
1013 pT2minNow = max( m2b, pT2endDip);
1014 }
else if (pT2 > m2c && nQuarkIn >= 4) {
1016 pT2minNow = max( m2c, pT2endDip);
1019 pT2minNow = pT2endDip;
1023 zMaxAbs = 1. - 0.5 * (pT2minNow / m2Dip) *
1024 ( sqrt( 1. + 4. * m2Dip / pT2minNow ) - 1. );
1027 xPDFdaughter = beam.xfISR(iSysNow, idDaughter, xDaughter, pT2);
1028 if (xPDFdaughter < TINYPDF) {
1029 xPDFdaughter = TINYPDF;
1030 hasTinyPDFdau =
true;
1036 double q2gInt = 4. * (1./sqrt(zMinAbs) - 1./sqrt(zMaxAbs));
1040 for (
int i = -nFlavour; i <= nFlavour; ++i) {
1042 xPDFmother[10] = 0.;
1044 xPDFmother[i+10] = pow2((abs(i+1) % 2 + 1)/3.0)
1045 * beam.xfISR(iSysNow, i, xDaughter, pT2);
1046 xPDFmotherSum += xPDFmother[i+10];
1051 kernelPDF = q2gInt * xPDFmotherSum / xPDFdaughter;
1056 if (kernelPDF < TINYKERNELPDF)
return;
1059 pT2 *= pow( rndmPtr->flat(), 1. / (alphaEM2pi * kernelPDF));
1062 if (nFlavour == 5 && pT2 < m2b) {
1069 else if (nFlavour == 4 && pT2 < m2c) {
1076 else if (pT2 < pT2endDip)
return;
1079 double temp = xPDFmotherSum * rndmPtr->flat();
1080 idMother = -nQuarkIn - 1;
1082 temp -= xPDFmother[(++idMother) + 10];
1083 }
while (temp > 0. && idMother < nQuarkIn);
1086 idSister = idMother;
1087 mSister = particleDataPtr->m0(idSister);
1088 m2Sister = pow2(mSister);
1091 z = (zMinAbs * zMaxAbs) / pow2( sqrt(zMinAbs) + rndmPtr->flat()
1092 * ( sqrt(zMaxAbs)- sqrt(zMinAbs) ));
1095 wt = 0.5 * (1. + pow2(1. - z)) * sqrt(z);
1098 double alphaEMnow = alphaEM.alphaEM(pT2);
1099 wt *= (alphaEMnow / alphaEMmax);
1102 Q2 = pT2 / (1. - z);
1103 xMother = xDaughter / z;
1105 if (!dipEndNow->normalRecoil) {
1106 if (sideA) xMother += (m2Rec / (x2Now * sCM)) * (1. / z - 1.);
1107 else xMother += (m2Rec / (x1Now * sCM)) * (1. / z - 1.);
1111 pT2corr = Q2 - z * (m2Dip + Q2) * (Q2 + m2Sister) / m2Dip;
1112 if(pT2corr < TINYPT2) { wt = 0.;
continue; }
1116 if ( abs(idMother) == 4 || abs(idMother) == 5 ) {
1117 double m2QQsister = EXTRASPACEQ * 4. * m2Sister;
1118 double pT2QQcorr = Q2 - z * (m2Dip + Q2) * (Q2 + m2QQsister) / m2Dip;
1119 if(pT2QQcorr < TINYPT2) { wt = 0.;
continue; }
1123 if (dopTdamp && iSysNow == 0 && MEtype == 0 && nRad == 0)
1124 wt *= pT2damp / (pT2 + pT2damp);
1127 double xPDFdaughterNew = beam.xfISR(iSysNow, idDaughter, xDaughter, pT2);
1128 if (xPDFdaughterNew < TINYPDF) {
1129 xPDFdaughterNew = TINYPDF;
1133 double xPDFmotherNew = pow2( (abs(idMother+1) % 2 + 1)/3.0 )
1134 * beam.xfISR(iSysNow, idMother, xMother, pT2);
1137 wt *= xPDFdaughter / xPDFmother[idMother + 10];
1140 wt *= xPDFmotherNew / xPDFdaughterNew;
1143 if (DEBUG) cout <<
" Trial weight is : " << wt <<
"\n pT2 = "
1144 << pT2 <<
" z = " << z <<
" alpha/alphahat = " << alphaEMnow
1145 <<
"/" << alphaEMmax <<
" idMother = " << idMother
1146 <<
" xPDFd/xPDFm = " << xPDFdaughter <<
"/" << xPDFmother[idMother+10]
1147 <<
" xPDFmNew/xPDFdNew " << xPDFmotherNew <<
"/" << xPDFdaughterNew
1148 <<
" pT2damp = " << pT2damp <<
" Q2 = " << Q2 <<
" pT2corr = "
1152 }
while (wt < rndmPtr->flat()) ;
1156 dipEndNow->store( idDaughter, idMother, idSister, x1Now, x2Now, m2Dip,
1157 pT2, z, xMother, Q2, mSister, m2Sister, pT2corr);
1166 bool SpaceShower::branch(
Event& event) {
1169 int side = abs(dipEndSel->side);
1170 double sideSign = (side == 1) ? 1. : -1.;
1173 int iDaughter = partonSystemsPtr->getInA(iSysSel);
1174 int iRecoiler = partonSystemsPtr->getInB(iSysSel);
1175 if (side == 2) swap(iDaughter, iRecoiler);
1176 int idDaughterNow = dipEndSel->idDaughter;
1177 int idMother = dipEndSel->idMother;
1178 int idSister = dipEndSel->idSister;
1179 int colDaughter =
event[iDaughter].col();
1180 int acolDaughter =
event[iDaughter].acol();
1183 bool normalRecoil = dipEndSel->normalRecoil;
1184 int iRecoilMother =
event[iRecoiler].mother1();
1187 double x1 = dipEndSel->x1;
1188 double x2 = dipEndSel->x2;
1189 double xMo = dipEndSel->xMo;
1190 double m2 = dipEndSel->m2Dip;
1191 double m = sqrt(m2);
1192 double pT2 = dipEndSel->pT2;
1193 double z = dipEndSel->z;
1194 double Q2 = dipEndSel->Q2;
1195 double mSister = dipEndSel->mSister;
1196 double m2Sister = dipEndSel->m2Sister;
1197 double pT2corr = dipEndSel->pT2corr;
1198 double x1New = (side == 1) ? xMo : x1;
1199 double x2New = (side == 2) ? xMo : x2;
1203 rescatterFail =
false;
1207 double eNewRec, pzNewRec, pTbranch, pzMother;
1209 eNewRec = 0.5 * (m2 + Q2) / m;
1210 pzNewRec = -sideSign * eNewRec;
1211 pTbranch = sqrt(pT2corr) * m2 / ( z * (m2 + Q2) );
1212 pzMother = sideSign * 0.5 * m * ( (m2 - Q2) / ( z * (m2 + Q2) )
1213 + (Q2 + m2Sister) / m2 );
1216 m2Rec =
event[iRecoiler].m2();
1217 double s1Tmp = m2 + Q2 - m2Rec;
1218 double s3Tmp = m2 / z - m2Rec;
1219 double r1Tmp = sqrt(s1Tmp * s1Tmp + 4. * Q2 * m2Rec);
1220 eNewRec = 0.5 * (m2 + m2Rec + Q2) / m;
1221 pzNewRec = -sideSign * 0.5 * r1Tmp / m;
1222 double pT2br = Q2 * s3Tmp * (m2 / z - m2 - Q2)
1223 - m2Sister * s1Tmp * s3Tmp - m2Rec * pow2(Q2 + m2Sister);
1224 if (pT2br <= 0.)
return false;
1225 pTbranch = sqrt(pT2br) / r1Tmp;
1226 pzMother = sideSign * (m * s3Tmp
1227 - eNewRec * (m2 / z - Q2 - m2Rec - m2Sister)) / r1Tmp;
1230 double eMother = sqrt( pow2(pTbranch) + pow2(pzMother) );
1231 double pzSister = pzMother + pzNewRec;
1232 double eSister = sqrt( pow2(pTbranch) + pow2(pzSister) + m2Sister );
1233 Vec4 pMother( pTbranch, 0., pzMother, eMother );
1234 Vec4 pSister( pTbranch, 0., pzSister, eSister );
1235 Vec4 pNewRec( 0., 0., pzNewRec, eNewRec );
1238 int eventSizeOld =
event.size();
1239 int systemSizeOld = partonSystemsPtr->sizeAll(iSysSel);
1242 int ev1dau1V =
event[1].daughter1();
1243 int ev2dau1V =
event[2].daughter1();
1244 vector<int> statusV, mother1V, mother2V, daughter1V, daughter2V;
1245 if (canVetoEmission) {
1246 for (
int iCopy = 0; iCopy < systemSizeOld; ++iCopy) {
1247 int iOldCopy = partonSystemsPtr->getAll(iSysSel, iCopy);
1248 statusV.push_back( event[iOldCopy].status());
1249 mother1V.push_back( event[iOldCopy].mother1());
1250 mother2V.push_back( event[iOldCopy].mother2());
1251 daughter1V.push_back( event[iOldCopy].daughter1());
1252 daughter2V.push_back( event[iOldCopy].daughter2());
1258 for (
int iCopy = 0; iCopy < systemSizeOld; ++iCopy) {
1259 int iOldCopy = partonSystemsPtr->getAll(iSysSel, iCopy);
1260 int statusOld =
event[iOldCopy].status();
1261 int statusNew = (iOldCopy == iDaughter
1262 || iOldCopy == iRecoiler) ? statusOld : 44;
1263 int iNewCopy =
event.copy(iOldCopy, statusNew);
1264 if (statusOld < 0)
event[iNewCopy].statusNeg();
1269 int colMother = colDaughter;
1270 int acolMother = acolDaughter;
1273 if (idSister == 22) ;
1275 else if (idSister == 21 && ( (idMother > 0 && idMother < 9)
1276 || (idMother == 21 && rndmPtr->flat() < 0.5) ) ) {
1277 colMother =
event.nextColTag();
1278 colSister = colMother;
1279 acolSister = colDaughter;
1281 }
else if (idSister == 21) {
1282 acolMother =
event.nextColTag();
1283 acolSister = acolMother;
1284 colSister = acolDaughter;
1286 }
else if (idDaughterNow == 21 && idMother > 0) {
1287 colMother = colDaughter;
1289 colSister = acolDaughter;
1291 }
else if (idDaughterNow == 21) {
1292 acolMother = acolDaughter;
1294 acolSister = colDaughter;
1296 }
else if (idDaughterNow > 0 && idDaughterNow < 9) {
1297 acolMother =
event.nextColTag();
1298 acolSister = acolMother;
1300 }
else if (idDaughterNow < 0 && idDaughterNow > -9) {
1301 colMother =
event.nextColTag();
1302 colSister = colMother;
1304 }
else if (idDaughterNow == 22 && idMother > 0) {
1305 colMother =
event.nextColTag();
1306 colSister = colMother;
1308 }
else if (idDaughterNow == 22) {
1309 acolMother =
event.nextColTag();
1310 acolSister = acolMother;
1314 int iMother = eventSizeOld + side - 1;
1315 int iNewRecoiler = eventSizeOld + 2 - side;
1316 int iSister =
event.append( idSister, 43, iMother, 0, 0, 0,
1317 colSister, acolSister, pSister, mSister, sqrt(pT2) );
1320 Particle& daughter =
event[iDaughter];
1321 Particle& mother =
event[iMother];
1322 Particle& newRecoiler =
event[iNewRecoiler];
1323 Particle& sister =
event.back();
1326 mother.id( idMother );
1327 mother.status( -41);
1328 mother.cols( colMother, acolMother);
1330 newRecoiler.status( (normalRecoil) ? -42 : -46 );
1331 newRecoiler.p( pNewRec);
1332 if (!normalRecoil) newRecoiler.m( event[iRecoiler].m() );
1335 daughter.mothers( iMother, 0);
1336 mother.daughters( iSister, iDaughter);
1338 event[1].daughter1( (side == 1) ? iMother : iNewRecoiler );
1339 event[2].daughter1( (side == 2) ? iMother : iNewRecoiler );
1344 if (normalRecoil) Mtot.bst(0., 0., (x2 - x1) / (x1 + x2) );
1346 Mtot.toCMframe( event[iDaughter].p(), event[iRecoiler].p() );
1347 else Mtot.toCMframe( event[iRecoiler].p(), event[iDaughter].p() );
1350 double phi = 2. * M_PI * rndmPtr->flat();
1353 findAsymPol( event, dipEndSel);
1354 int iFinPol = dipEndSel->iFinPol;
1355 double cPol = dipEndSel->asymPol;
1356 double phiPol = (iFinPol == 0) ? 0. : event[iFinPol].phi();
1363 for (
int i = 0; i < partonSystemsPtr->sizeOut(iSysSel); ++ i) {
1364 int iOut = partonSystemsPtr->getOut(iSysSel, i);
1365 if ( (acolSister != 0 && event[iOut].col() == acolSister)
1366 || (colSister != 0 && event[iOut].acol() == colSister) )
1371 Vec4 pFinTmp =
event[iFinInt].p();
1372 pFinTmp.rotbst(Mtot);
1373 double theFin = pFinTmp.theta();
1374 if (side == 2) theFin = M_PI - theFin;
1375 double theSis = pSister.theta();
1376 if (side == 2) theSis = M_PI - theSis;
1377 cInt = strengthIntAsym * 2. * theSis * theFin
1378 / (pow2(theSis) + pow2(theFin));
1379 phiInt =
event[iFinInt].phi();
1384 if (iFinPol != 0 || iFinInt != 0) {
1385 double cPhiPol, cPhiInt, weight;
1387 phi = 2. * M_PI * rndmPtr->flat();
1390 cPhiPol = cos(phi - phiPol);
1391 weight *= ( 1. + cPol * (2. * pow2(cPhiPol) - 1.) )
1392 / ( 1. + abs(cPol) );
1395 cPhiInt = cos(phi - phiInt);
1396 weight *= (1. - cInt) * (1. - cInt * cPhiInt)
1397 / (1. + pow2(cInt) - 2. * cInt * cPhiInt);
1399 }
while (weight < rndmPtr->flat());
1406 RotBstMatrix MfromRest;
1408 Vec4 sumNew = pMother + pNewRec;
1409 double betaX = sumNew.px() / sumNew.e();
1410 double betaZ = sumNew.pz() / sumNew.e();
1411 MfromRest.bst( -betaX, 0., -betaZ);
1414 pMother.rotbst(MfromRest);
1415 double theta = pMother.theta();
1416 if (pMother.px() < 0.) theta = -theta;
1417 if (side == 2) theta += M_PI;
1418 MfromRest.rot(-theta, phi);
1421 MfromRest.bst( 0., 0., (x1New - x2New) / (x1New + x2New) );
1422 }
else if (side == 1) {
1423 Vec4 pMotherWanted( 0., 0., 0.5 * eCM * x1New, 0.5 * eCM * x1New);
1424 MfromRest.fromCMframe( pMotherWanted, event[iRecoiler].p() );
1427 Vec4 pMotherWanted( 0., 0., -0.5 * eCM * x2New, 0.5 * eCM * x2New);
1428 MfromRest.fromCMframe( event[iRecoiler].p(), pMotherWanted );
1430 Mtot.rotbst(MfromRest);
1434 mother.rotbst(MfromRest);
1435 newRecoiler.rotbst(MfromRest);
1436 sister.rotbst(MfromRest);
1438 for (
int i = eventSizeOld + 2; i < eventSizeOld + systemSizeOld; ++i)
1439 event[i].rotbst(Mtot);
1442 if ( canVetoEmission
1443 && userHooksPtr->doVetoISREmission(eventSizeOld, event, iSysSel) ) {
1444 event.popBack( event.size() - eventSizeOld);
1445 event[1].daughter1( ev1dau1V);
1446 event[2].daughter1( ev2dau1V);
1447 for (
int iCopy = 0; iCopy < systemSizeOld; ++iCopy) {
1448 int iOldCopy = partonSystemsPtr->getAll(iSysSel, iCopy);
1449 event[iOldCopy].status( statusV[iCopy]);
1450 event[iOldCopy].mothers( mother1V[iCopy], mother2V[iCopy]);
1451 event[iOldCopy].daughters( daughter1V[iCopy], daughter2V[iCopy]);
1457 partonSystemsPtr->setInA(iSysSel, eventSizeOld);
1458 partonSystemsPtr->setInB(iSysSel, eventSizeOld + 1);
1459 for (
int iCopy = 2; iCopy < systemSizeOld; ++iCopy)
1460 partonSystemsPtr->setOut(iSysSel, iCopy - 2, eventSizeOld + iCopy);
1461 partonSystemsPtr->addOut(iSysSel, eventSizeOld + systemSizeOld);
1462 partonSystemsPtr->setSHat(iSysSel, m2 / z);
1465 for (
int iDip = 0; iDip < int(dipEnd.size()); ++iDip)
1466 if ( dipEnd[iDip].system == iSysSel) {
1467 if (abs(dipEnd[iDip].side) == side) {
1468 dipEnd[iDip].iRadiator = iMother;
1469 dipEnd[iDip].iRecoiler = iNewRecoiler;
1470 if (dipEnd[iDip].side > 0)
1471 dipEnd[iDip].colType = mother.colType();
1473 dipEnd[iDip].chgType = 0;
1474 if ( (mother.isQuark() && doQEDshowerByQ)
1475 || (mother.isLepton() && doQEDshowerByL) )
1476 dipEnd[iDip].chgType = mother.chargeType();
1479 dipEnd[iDip].MEtype = 0;
1483 dipEnd[iDip].iRadiator = iNewRecoiler;
1484 dipEnd[iDip].iRecoiler = iMother;
1486 if (!doMEafterFirst) dipEnd[iDip].MEtype = 0;
1491 BeamParticle& beamNow = (side == 1) ? *beamAPtr : *beamBPtr;
1492 double xNew = (side == 1) ? x1New : x2New;
1493 beamNow[iSysSel].update( iMother, idMother, xNew);
1495 if (idMother != idDaughterNow) {
1496 beamNow.xfISR( iSysSel, idMother, xNew, pT2);
1497 beamNow.pickValSeaComp();
1499 BeamParticle& beamRec = (side == 1) ? *beamBPtr : *beamAPtr;
1500 beamRec[iSysSel].iPos( iNewRecoiler);
1503 ++dipEndSel->nBranch;
1504 dipEndSel->pT2Old = pT2;
1505 dipEndSel->zOld = z;
1509 event[iRecoilMother].daughters( iNewRecoiler, iNewRecoiler);
1512 vector<int> iRescatterer;
1513 for (
int i = 0; i < systemSizeOld - 2; ++i) {
1514 int iOutNew = partonSystemsPtr->getOut( iSysSel, i);
1515 if (!event[iOutNew].isFinal()) iRescatterer.push_back(iOutNew);
1520 while (++iRescNow <
int(iRescatterer.size())) {
1526 int iOutNew = iRescatterer[iRescNow];
1527 int iInOld =
event[iOutNew].daughter1();
1528 int iSysResc = partonSystemsPtr->getSystemOf(iInOld,
true);
1531 int iOldA = partonSystemsPtr->getInA(iSysResc);
1532 int iOldB = partonSystemsPtr->getInB(iSysResc);
1533 bool rescSideA =
event[iOldA].isRescatteredIncoming();
1534 int statusNewA = (rescSideA) ? -45 : -42;
1535 int statusNewB = (rescSideA) ? -42 : -45;
1536 int iNewA =
event.copy(iOldA, statusNewA);
1537 int iNewB =
event.copy(iOldB, statusNewB);
1540 int eventSize =
event.size();
1541 int sizeOutAB = partonSystemsPtr->sizeOut(iSysResc);
1542 int iOldAB, statusOldAB, iNewAB;
1543 for (
int iOutAB = 0; iOutAB < sizeOutAB; ++iOutAB) {
1544 iOldAB = partonSystemsPtr->getOut(iSysResc, iOutAB);
1545 statusOldAB =
event[iOldAB].status();
1546 iNewAB =
event.copy(iOldAB, 44);
1548 if (statusOldAB < 0) {
1549 event[iNewAB].statusNeg();
1550 iRescatterer.push_back(iNewAB);
1555 int iInNew = (rescSideA) ? iNewA : iNewB;
1556 event[iOutNew].daughters( iInNew, iInNew);
1557 event[iInNew].mothers( iOutNew, iOutNew);
1560 event[iInNew].p( event[iOutNew].p() );
1561 double momFac = (rescSideA)
1562 ? event[iInOld].pPos() /
event[iInNew].pPos()
1563 :
event[iInOld].pNeg() /
event[iInNew].pNeg();
1564 int iInRec = (rescSideA) ? iNewB : iNewA;
1570 infoPtr->errorMsg(
"Warning in SpaceShower::branch: "
1571 "change in lightcone momentum sign; retrying parton level");
1572 rescatterFail =
true;
1576 event[iInRec].rescale4( momFac);
1579 RotBstMatrix MmodResc;
1580 MmodResc.toCMframe( event[iOldA].p(), event[iOldB].p());
1581 MmodResc.fromCMframe(event[iNewA].p(), event[iNewB].p());
1582 for (
int iOutAB = 0; iOutAB < sizeOutAB; ++iOutAB)
1583 event[eventSize + iOutAB].rotbst(MmodResc);
1586 partonSystemsPtr->setInA(iSysResc, iNewA);
1587 partonSystemsPtr->setInB(iSysResc, iNewB);
1588 for (
int iCopy = 0; iCopy < sizeOutAB; ++iCopy)
1589 partonSystemsPtr->setOut(iSysResc, iCopy, eventSize + iCopy);
1592 for (
int iDip = 0; iDip < int(dipEnd.size()); ++iDip)
1593 if ( dipEnd[iDip].system == iSysResc) {
1594 bool sideAnow = (abs(dipEnd[iDip].side) == 1);
1595 dipEnd[iDip].iRadiator = (sideAnow) ? iNewA : iNewB;
1596 dipEnd[iDip].iRecoiler = (sideAnow) ? iNewB : iNewA;
1600 BeamParticle& beamResc = (rescSideA) ? *beamAPtr : *beamBPtr;
1601 beamResc[iSysResc].iPos( iInNew);
1602 beamResc[iSysResc].p( event[iInNew].p() );
1603 beamResc[iSysResc].scaleX( 1. / momFac );
1604 BeamParticle& beamReco = (rescSideA) ? *beamBPtr : *beamAPtr;
1605 beamReco[iSysResc].iPos( iInRec);
1606 beamReco[iSysResc].scaleX( momFac);
1612 if (beamAPtr->xMax(-1) < 0.0 || beamBPtr->xMax(-1) < 0.0) {
1613 infoPtr->errorMsg(
"Warning in SpaceShower::branch: "
1614 "used up beam momentum; retrying parton level");
1615 rescatterFail =
true;
1628 int SpaceShower::findMEtype(
int iSys,
Event& event) {
1632 if (!doMEcorrections) ;
1635 else if (partonSystemsPtr->sizeOut( iSys) == 1) {
1636 int idIn1 =
event[partonSystemsPtr->getInA(iSys)].id();
1637 int idIn2 =
event[partonSystemsPtr->getInA(iSys)].id();
1638 int idRes =
event[partonSystemsPtr->getOut(iSys, 0)].id();
1639 if (iSys == 0) idResFirst = abs(idRes);
1640 if (iSys == 1) idResSecond = abs(idRes);
1643 if ( (idRes == 23 || abs(idRes) == 24 || idRes == 32
1644 || idRes == 33 || abs(idRes) == 34 || abs(idRes) == 41)
1645 && abs(idIn1) < 20 && abs(idIn2) < 20 ) MEtype = 1;
1648 if ( (idRes == 25 || idRes == 35 || idRes == 36)
1649 && ( ( idIn1 == 21 && idIn2 == 21 )
1650 || ( idIn1 == 22 && idIn2 == 22 ) ) ) MEtype = 2;
1653 if ( (idRes == 25 || idRes == 35 || idRes == 36)
1654 && abs(idIn1) < 20 && abs(idIn2) < 20 ) MEtype = 3;
1666 double SpaceShower::calcMEmax(
int MEtype,
int idMother,
int idDaughterIn) {
1669 if (MEtype == 1 && idMother > 20 && idDaughterIn < 20)
return 3.;
1680 double SpaceShower::calcMEcorr(
int MEtype,
int idMother,
int idDaughterIn,
1681 double M2,
double z,
double Q2) {
1686 double uH = Q2 - M2 * (1. - z) / z;
1687 int idMabs = abs(idMother);
1688 int idDabs = abs(idDaughterIn);
1692 if (idMabs < 20 && idDabs < 20) {
1693 return (tH*tH + uH*uH + 2. * M2 * sH) / (sH*sH + M2*M2);
1694 }
else if (idDabs < 20) {
1698 return (sH*sH + uH*uH + 2. * M2 * tH) / (pow2(sH - M2) + M2*M2);
1702 }
else if (MEtype == 2) {
1703 if (idMabs < 20 && idDabs > 20) {
1704 return (sH*sH + uH*uH) / (sH*sH + pow2(sH - M2));
1705 }
else if (idDabs > 20) {
1706 return 0.5 * (pow4(sH) + pow4(tH) + pow4(uH) + pow4(M2))
1707 / pow2(sH*sH - M2 * (sH - M2));
1711 }
else if (MEtype == 3) {
1712 if (idMabs < 20 && idDabs < 20) {
1715 }
else if (idDabs < 20) {
1718 return (sH*sH + uH*uH + 2. * (M2 - uH) * (M2 - sH))
1719 / (pow2(sH - M2) + M2*M2);
1731 void SpaceShower::findAsymPol(
Event& event, SpaceDipoleEnd* dip) {
1736 int iRad = dip->iRadiator;
1737 if (!doPhiPolAsym || dip->idDaughter != 21)
return;
1742 int iGrandD1 =
event[iRad].daughter1();
1743 int iGrandD2 =
event[iRad].daughter2();
1744 bool traceCopy =
false;
1747 if (iGrandD1 > 0 && iGrandD2 == iGrandD1) {
1748 iGrandD1 =
event[iGrandD2].daughter1();
1749 iGrandD2 =
event[iGrandD2].daughter2();
1752 }
while (traceCopy);
1753 int statusGrandD1 =
event[ iGrandD1 ].statusAbs();
1754 bool isHardProc = (statusGrandD1 == 23 || statusGrandD1 == 33);
1756 if (iGrandD2 != iGrandD1 + 1)
return;
1757 if (event[iGrandD1].isGluon() &&
event[iGrandD2].isGluon());
1758 else if (event[iGrandD1].isQuark() &&
event[iGrandD2].isQuark());
1761 dip->iFinPol = iGrandD1;
1764 if (dip->idMother == 21) dip->asymPol = pow2( (1. - dip->z)
1765 / (1. - dip->z * (1. - dip->z) ) );
1766 else dip->asymPol = 2. * (1. - dip->z) / (1. + pow2(1. - dip->z) );
1769 double zDau = (isHardProc) ? 0.5 : dip->zOld;
1770 if (event[iGrandD1].isGluon()) dip->asymPol *= pow2( (1. - zDau)
1771 / (1. - zDau * (1. - zDau) ) );
1772 else dip->asymPol *= -2. * zDau *( 1. - zDau )
1773 / (1. - 2. * zDau * (1. - zDau) );
1781 void SpaceShower::list(ostream& os)
const {
1784 os <<
"\n -------- PYTHIA SpaceShower Dipole Listing -------------- \n"
1785 <<
"\n i syst side rad rec pTmax col chg ME rec \n"
1786 << fixed << setprecision(3);
1789 for (
int i = 0; i < int(dipEnd.size()); ++i)
1790 os << setw(5) << i << setw(6) << dipEnd[i].system
1791 << setw(6) << dipEnd[i].side << setw(6) << dipEnd[i].iRadiator
1792 << setw(6) << dipEnd[i].iRecoiler << setw(12) << dipEnd[i].pTmax
1793 << setw(5) << dipEnd[i].colType << setw(5) << dipEnd[i].chgType
1794 << setw(5) << dipEnd[i].MEtype << setw(4)
1795 << dipEnd[i].normalRecoil <<
"\n";
1798 os <<
"\n -------- End PYTHIA SpaceShower Dipole Listing ----------"