9 #include "PhaseSpace.h"
24 const int PhaseSpace::NMAXTRY = 2;
27 const int PhaseSpace::NTRY3BODY = 20;
30 const double PhaseSpace::SAFETYMARGIN = 1.05;
33 const double PhaseSpace::TINY = 1e-20;
36 const double PhaseSpace::EVENFRAC = 0.4;
39 const double PhaseSpace::SAMESIGMA = 1e-6;
42 const double PhaseSpace::WIDTHMARGIN = 20.;
45 const double PhaseSpace::SAMEMASS = 0.01;
48 const double PhaseSpace::MASSMARGIN = 0.01;
51 const double PhaseSpace::EXTRABWWTMAX = 1.25;
54 const double PhaseSpace::THRESHOLDSIZE = 3.;
57 const double PhaseSpace::THRESHOLDSTEP = 0.2;
60 const double PhaseSpace::YRANGEMARGIN = 1e-6;
64 const double PhaseSpace::LEPTONXMIN = 1e-10;
65 const double PhaseSpace::LEPTONXMAX = 1. - 1e-10;
66 const double PhaseSpace::LEPTONXLOGMIN = log(1e-10);
67 const double PhaseSpace::LEPTONXLOGMAX = log(1. - 1e-10);
68 const double PhaseSpace::LEPTONTAUMIN = 2e-10;
71 const double PhaseSpace::SHATMINZ = 1.;
74 const double PhaseSpace::PT2RATMINZ = 0.0001;
78 const double PhaseSpace::WTCORRECTION[11] = { 1., 1., 1.,
79 2., 5., 15., 60., 250., 1250., 7000., 50000. };
85 void PhaseSpace::init(
bool isFirst, SigmaProcess* sigmaProcessPtrIn,
86 Info* infoPtrIn, Settings* settingsPtrIn, ParticleData* particleDataPtrIn,
87 Rndm* rndmPtrIn, BeamParticle* beamAPtrIn, BeamParticle* beamBPtrIn,
88 Couplings* couplingsPtrIn, SigmaTotal* sigmaTotPtrIn,
89 UserHooks* userHooksPtrIn) {
92 sigmaProcessPtr = sigmaProcessPtrIn;
94 settingsPtr = settingsPtrIn;
95 particleDataPtr = particleDataPtrIn;
97 beamAPtr = beamAPtrIn;
98 beamBPtr = beamBPtrIn;
99 couplingsPtr = couplingsPtrIn;
100 sigmaTotPtr = sigmaTotPtrIn;
101 userHooksPtr = userHooksPtrIn;
104 idA = beamAPtr->id();
105 idB = beamBPtr->id();
108 eCM = infoPtr->eCM();
112 hasLeptonBeams = ( beamAPtr->isLepton() || beamBPtr->isLepton() );
113 hasPointLeptons = ( hasLeptonBeams
114 && (beamAPtr->isUnresolved() || beamBPtr->isUnresolved() ) );
117 if (isFirst || settingsPtr->flag(
"PhaseSpace:sameForSecond")) {
118 mHatGlobalMin = settingsPtr->parm(
"PhaseSpace:mHatMin");
119 mHatGlobalMax = settingsPtr->parm(
"PhaseSpace:mHatMax");
120 pTHatGlobalMin = settingsPtr->parm(
"PhaseSpace:pTHatMin");
121 pTHatGlobalMax = settingsPtr->parm(
"PhaseSpace:pTHatMax");
125 mHatGlobalMin = settingsPtr->parm(
"PhaseSpace:mHatMinSecond");
126 mHatGlobalMax = settingsPtr->parm(
"PhaseSpace:mHatMaxSecond");
127 pTHatGlobalMin = settingsPtr->parm(
"PhaseSpace:pTHatMinSecond");
128 pTHatGlobalMax = settingsPtr->parm(
"PhaseSpace:pTHatMaxSecond");
132 pTHatMinDiverge = settingsPtr->parm(
"PhaseSpace:pTHatMinDiverge");
135 useBreitWigners = settingsPtr->flag(
"PhaseSpace:useBreitWigners");
136 minWidthBreitWigners = settingsPtr->parm(
"PhaseSpace:minWidthBreitWigners");
139 doEnergySpread = settingsPtr->flag(
"Beams:allowMomentumSpread");
142 showSearch = settingsPtr->flag(
"PhaseSpace:showSearch");
143 showViolation = settingsPtr->flag(
"PhaseSpace:showViolation");
144 increaseMaximum = settingsPtr->flag(
"PhaseSpace:increaseMaximum");
147 gmZmodeGlobal = settingsPtr->mode(
"WeakZ0:gmZmode");
178 canModifySigma = (userHooksPtr > 0)
179 ? userHooksPtr->canModifySigma() :
false;
180 canBiasSelection = (userHooksPtr > 0)
181 ? userHooksPtr->canBiasSelection() :
false;
189 void PhaseSpace::decayKinematics(
Event& process) {
193 for (
int iResBeg = 5; iResBeg < process.size(); ++iResBeg) {
194 if (iResBeg <= iResEnd)
continue;
196 while ( iResEnd < process.size() - 1
197 && process[iResEnd + 1].mother1() == process[iResBeg].mother1()
198 && process[iResEnd + 1].mother2() == process[iResBeg].mother2() )
203 for (
int iRes = iResBeg; iRes <= iResEnd; ++iRes)
204 if ( !process[iRes].isFinal() ) hasRes =
true;
205 if ( !hasRes )
continue;
208 double decWt = sigmaProcessPtr->weightDecay( process, iResBeg, iResEnd);
209 if (decWt < 0.) infoPtr->errorMsg(
"Warning in PhaseSpace::decay"
210 "Kinematics: negative angular weight");
211 if (decWt > 1.) infoPtr->errorMsg(
"Warning in PhaseSpace::decay"
212 "Kinematics: angular weight above unity");
213 while (decWt < rndmPtr->flat() ) {
216 for (
int iRes = iResBeg; iRes < process.size(); ++iRes) {
217 if ( process[iRes].isFinal() )
continue;
218 int iResMother = iRes;
219 while (iResMother > iResEnd)
220 iResMother = process[iResMother].mother1();
221 if (iResMother < iResBeg)
continue;
224 decayKinematicsStep( process, iRes);
230 decWt = sigmaProcessPtr->weightDecay( process, iResBeg, iResEnd);
231 if (decWt < 0.) infoPtr->errorMsg(
"Warning in PhaseSpace::decay"
232 "Kinematics: negative angular weight");
233 if (decWt > 1.) infoPtr->errorMsg(
"Warning in PhaseSpace::decay"
234 "Kinematics: angular weight above unity");
247 void PhaseSpace::decayKinematicsStep(
Event& process,
int iRes) {
250 int i1 = process[iRes].daughter1();
251 int mult = process[iRes].daughter2() + 1 - i1;
252 double m0 = process[iRes].m();
253 Vec4 pRes = process[iRes].p();
260 double m1t = process[i1].m();
261 double m2t = process[i2].m();
264 double e1 = 0.5 * (m0*m0 + m1t*m1t - m2t*m2t) / m0;
265 double e2 = 0.5 * (m0*m0 + m2t*m2t - m1t*m1t) / m0;
266 double p12 = 0.5 * sqrtpos( (m0 - m1t - m2t) * (m0 + m1t + m2t)
267 * (m0 + m1t - m2t) * (m0 - m1t + m2t) ) / m0;
270 double cosTheta = 2. * rndmPtr->flat() - 1.;
271 double sinTheta = sqrt(1. - cosTheta*cosTheta);
272 double phi12 = 2. * M_PI * rndmPtr->flat();
273 double pX = p12 * sinTheta * cos(phi12);
274 double pY = p12 * sinTheta * sin(phi12);
275 double pZ = p12 * cosTheta;
278 Vec4 p1( pX, pY, pZ, e1);
279 Vec4 p2( -pX, -pY, -pZ, e2);
295 double m1t = process[i1].m();
296 double m2t = process[i2].m();
297 double m3t = process[i3].m();
298 double mDiff = m0 - (m1t + m2t + m3t);
301 double m23Min = m2t + m3t;
302 double m23Max = m0 - m1t;
303 double p1Max = 0.5 * sqrtpos( (m0 - m1t - m23Min)
304 * (m0 + m1t + m23Min) * (m0 + m1t - m23Min)
305 * (m0 - m1t + m23Min) ) / m0;
306 double p23Max = 0.5 * sqrtpos( (m23Max - m2t - m3t)
307 * (m23Max + m2t + m3t) * (m23Max + m2t - m3t)
308 * (m23Max - m2t + m3t) ) / m23Max;
309 double wtPSmax = 0.5 * p1Max * p23Max;
312 double wtPS, m23, p1Abs, p23Abs;
314 m23 = m23Min + rndmPtr->flat() * mDiff;
317 p1Abs = 0.5 * sqrtpos( (m0 - m1t - m23) * (m0 + m1t + m23)
318 * (m0 + m1t - m23) * (m0 - m1t + m23) ) / m0;
319 p23Abs = 0.5 * sqrtpos( (m23 - m2t - m3t) * (m23 + m2t + m3t)
320 * (m23 + m2t - m3t) * (m23 - m2t + m3t) ) / m23;
321 wtPS = p1Abs * p23Abs;
324 }
while ( wtPS < rndmPtr->flat() * wtPSmax );
327 double cosTheta = 2. * rndmPtr->flat() - 1.;
328 double sinTheta = sqrt(1. - cosTheta*cosTheta);
329 double phi23 = 2. * M_PI * rndmPtr->flat();
330 double pX = p23Abs * sinTheta * cos(phi23);
331 double pY = p23Abs * sinTheta * sin(phi23);
332 double pZ = p23Abs * cosTheta;
333 double e2 = sqrt( m2t*m2t + p23Abs*p23Abs);
334 double e3 = sqrt( m3t*m3t + p23Abs*p23Abs);
335 Vec4 p2( pX, pY, pZ, e2);
336 Vec4 p3( -pX, -pY, -pZ, e3);
339 cosTheta = 2. * rndmPtr->flat() - 1.;
340 sinTheta = sqrt(1. - cosTheta*cosTheta);
341 phi23 = 2. * M_PI * rndmPtr->flat();
342 pX = p1Abs * sinTheta * cos(phi23);
343 pY = p1Abs * sinTheta * sin(phi23);
344 pZ = p1Abs * cosTheta;
345 double e1 = sqrt( m1t*m1t + p1Abs*p1Abs);
346 double e23 = sqrt( m23*m23 + p1Abs*p1Abs);
347 Vec4 p1( pX, pY, pZ, e1);
350 Vec4 p23( -pX, -pY, -pZ, e23);
367 vector<double> mProd;
368 mProd.push_back( m0);
369 for (
int i = i1; i <= process[iRes].daughter2(); ++i)
370 mProd.push_back( process[i].m() );
372 pProd.push_back( pRes);
375 double mSum = mProd[1];
376 for (
int i = 2; i <= mult; ++i) mSum += mProd[i];
377 double mDiff = m0 - mSum;
381 for (
int i = 0; i <= mult; ++i) mInv.push_back( mProd[i]);
384 double wtPSmax = 1. / WTCORRECTION[mult];
385 double mMaxWT = mDiff + mProd[mult];
387 for (
int i = mult - 1; i > 0; --i) {
389 mMinWT += mProd[i+1];
390 double mNow = mProd[i];
391 wtPSmax *= 0.5 * sqrtpos( (mMaxWT - mMinWT - mNow)
392 * (mMaxWT + mMinWT + mNow) * (mMaxWT + mMinWT - mNow)
393 * (mMaxWT - mMinWT + mNow) ) / mMaxWT;
397 vector<double> rndmOrd;
404 rndmOrd.push_back(1.);
405 for (
int i = 1; i < mult - 1; ++i) {
406 double rndm = rndmPtr->flat();
407 rndmOrd.push_back(rndm);
408 for (
int j = i - 1; j > 0; --j) {
409 if (rndm > rndmOrd[j]) swap( rndmOrd[j], rndmOrd[j+1] );
413 rndmOrd.push_back(0.);
416 for (
int i = mult - 1; i > 0; --i) {
417 mInv[i] = mInv[i+1] + mProd[i] + (rndmOrd[i-1] - rndmOrd[i]) * mDiff;
418 wtPS *= 0.5 * sqrtpos( (mInv[i] - mInv[i+1] - mProd[i])
419 * (mInv[i] + mInv[i+1] + mProd[i]) * (mInv[i] + mInv[i+1] - mProd[i])
420 * (mInv[i] - mInv[i+1] + mProd[i]) ) / mInv[i];
424 }
while ( wtPS < rndmPtr->flat() * wtPSmax );
428 pInv.resize(mult + 1);
429 for (
int i = 1; i < mult; ++i) {
430 double p12 = 0.5 * sqrtpos( (mInv[i] - mInv[i+1] - mProd[i])
431 * (mInv[i] + mInv[i+1] + mProd[i]) * (mInv[i] + mInv[i+1] - mProd[i])
432 * (mInv[i] - mInv[i+1] + mProd[i]) ) / mInv[i];
435 double cosTheta = 2. * rndmPtr->flat() - 1.;
436 double sinTheta = sqrt(1. - cosTheta*cosTheta);
437 double phiLoc = 2. * M_PI * rndmPtr->flat();
438 double pX = p12 * sinTheta * cos(phiLoc);
439 double pY = p12 * sinTheta * sin(phiLoc);
440 double pZ = p12 * cosTheta;
443 double eHad = sqrt( mProd[i]*mProd[i] + p12*p12);
444 double eInv = sqrt( mInv[i+1]*mInv[i+1] + p12*p12);
445 pProd.push_back( Vec4( pX, pY, pZ, eHad) );
446 pInv[i+1].p( -pX, -pY, -pZ, eInv);
448 pProd.push_back( pInv[mult] );
452 for (
int iFrame = mult - 1; iFrame > 0; --iFrame)
453 for (
int i = iFrame; i <= mult; ++i) pProd[i].bst(pInv[iFrame]);
456 for (
int i = 1; i < mult; ++i)
457 process[i1 + i - 1].p( pProd[i] );
466 void PhaseSpace::setup3Body() {
469 int idTchan1 = abs( sigmaProcessPtr->idTchan1() );
470 int idTchan2 = abs( sigmaProcessPtr->idTchan2() );
471 mTchan1 = (idTchan1 == 0) ? pTHatMinDiverge
472 : particleDataPtr->m0(idTchan1);
473 mTchan2 = (idTchan2 == 0) ? pTHatMinDiverge
474 : particleDataPtr->m0(idTchan2);
475 sTchan1 = mTchan1 * mTchan1;
476 sTchan2 = mTchan2 * mTchan2;
479 frac3Pow1 = sigmaProcessPtr->tChanFracPow1();
480 frac3Pow2 = sigmaProcessPtr->tChanFracPow2();
481 frac3Flat = 1. - frac3Pow1 - frac3Pow2;
482 useMirrorWeight = sigmaProcessPtr->useMirrorWeight();
490 bool PhaseSpace::setupSampling123(
bool is2,
bool is3, ostream& os) {
493 if (showSearch) os <<
"\n PYTHIA Optimization printout for "
494 << sigmaProcessPtr->name() <<
"\n \n" << scientific << setprecision(3);
497 if (!limitTau(is2, is3))
return false;
500 int binTau[8], binY[8], binZ[8];
501 double vecTau[8], matTau[8][8], vecY[8], matY[8][8], vecZ[8], matZ[8][8];
502 for (
int i = 0; i < 8; ++i) {
512 for (
int j = 0; j < 8; ++j) {
522 nTau = (hasPointLeptons) ? 1 : 2;
523 nY = (hasPointLeptons) ? 1 : 5;
527 idResA = sigmaProcessPtr->resonanceA();
529 mResA = particleDataPtr->m0(idResA);
530 GammaResA = particleDataPtr->mWidth(idResA);
531 if (mHatMin > mResA + WIDTHMARGIN * GammaResA || (mHatMax > 0.
532 && mHatMax < mResA - WIDTHMARGIN * GammaResA) ) idResA = 0;
534 idResB = sigmaProcessPtr->resonanceB();
536 mResB = particleDataPtr->m0(idResB);
537 GammaResB = particleDataPtr->mWidth(idResB);
538 if (mHatMin > mResB + WIDTHMARGIN * GammaResB || (mHatMax > 0.
539 && mHatMax < mResB - WIDTHMARGIN * GammaResB) ) idResB = 0;
541 if (idResA == 0 && idResB != 0) {
544 GammaResA = GammaResB;
549 if (idResA !=0 && !hasPointLeptons) {
551 tauResA = mResA * mResA / s;
552 widResA = mResA * GammaResA / s;
554 if (idResB != 0 && !hasPointLeptons) {
556 tauResB = mResB * mResB / s;
557 widResB = mResB * GammaResB / s;
561 if (hasLeptonBeams && !hasPointLeptons) ++nTau;
565 if (idResB != 0 && abs(mResA - mResB) < SAMEMASS * (GammaResA + GammaResB))
571 int nVar = (is2) ? 3 : 2;
580 for (
int iTau = 0; iTau < nTau; ++iTau) {
582 if (sameResMass && iTau > 1 && iTau < 6) posTau = (iTau < 4) ? 0.4 : 0.6;
583 selectTau( iTau, posTau, is2);
584 if (!limitY())
continue;
585 if (is2 && !limitZ())
continue;
588 for (
int iY = 0; iY < nY; ++iY) {
590 for (
int iZ = 0; iZ < nZ; ++iZ) {
591 if (is2) selectZ( iZ, 0.5);
592 double sigmaTmp = 0.;
596 sigmaProcessPtr->set1Kin( x1H, x2H, sH);
597 sigmaTmp = sigmaProcessPtr->sigmaPDF();
598 sigmaTmp *= wtTau * wtY;
603 sigmaProcessPtr->set2Kin( x1H, x2H, sH, tH, m3, m4,
605 sigmaTmp = sigmaProcessPtr->sigmaPDF();
606 sigmaTmp *= wtTau * wtY * wtZ * wtBW;
612 for (
int iTry3 = 0; iTry3 < NTRY3BODY; ++iTry3) {
613 if (!select3Body())
continue;
614 sigmaProcessPtr->set3Kin( x1H, x2H, sH, p3cm, p4cm, p5cm,
615 m3, m4, m5, runBW3H, runBW4H, runBW5H);
616 double sigmaTry = sigmaProcessPtr->sigmaPDF();
617 sigmaTry *= wtTau * wtY * wt3Body * wtBW;
618 if (sigmaTry > sigmaTmp) sigmaTmp = sigmaTry;
623 if (canModifySigma) sigmaTmp
624 *= userHooksPtr->multiplySigmaBy( sigmaProcessPtr,
this,
false);
625 if (canBiasSelection) sigmaTmp
626 *= userHooksPtr->biasSelectionBy( sigmaProcessPtr,
this,
false);
629 if (sigmaTmp > sigmaMx) sigmaMx = sigmaTmp;
632 if (showSearch) os <<
" tau =" << setw(11) << tau <<
" y ="
633 << setw(11) << y <<
" z =" << setw(11) << z
634 <<
" sigma =" << setw(11) << sigmaTmp <<
"\n";
635 if (sigmaTmp < 0.) sigmaTmp = 0.;
638 if (!hasPointLeptons) {
640 vecTau[iTau] += sigmaTmp;
641 matTau[iTau][0] += 1. / intTau0;
642 matTau[iTau][1] += (1. / intTau1) / tau;
644 matTau[iTau][2] += (1. / intTau2) / (tau + tauResA);
645 matTau[iTau][3] += (1. / intTau3)
646 * tau / ( pow2(tau - tauResA) + pow2(widResA) );
649 matTau[iTau][4] += (1. / intTau4) / (tau + tauResB);
650 matTau[iTau][5] += (1. / intTau5)
651 * tau / ( pow2(tau - tauResB) + pow2(widResB) );
653 if (hasLeptonBeams) matTau[iTau][nTau - 1] += (1. / intTau6)
654 * tau / max( LEPTONTAUMIN, 1. - tau);
658 if (!hasPointLeptons) {
660 vecY[iY] += sigmaTmp;
661 matY[iY][0] += (yMax / intY0) / cosh(y);
662 matY[iY][1] += (yMax / intY12) * (y + yMax);
663 matY[iY][2] += (yMax / intY12) * (yMax - y);
664 if (!hasLeptonBeams) {
665 matY[iY][3] += (yMax / intY34) * exp(y);
666 matY[iY][4] += (yMax / intY34) * exp(-y);
668 matY[iY][3] += (yMax / intY56)
669 / max( LEPTONXMIN, 1. - exp( y - yMax) );
670 matY[iY][4] += (yMax / intY56)
671 / max( LEPTONXMIN, 1. - exp(-y - yMax) );
677 double p2AbsMax = 0.25 * (pow2(tauMax * s - s3 - s4)
678 - 4. * s3 * s4) / (tauMax * s);
679 double zMaxMax = sqrtpos( 1. - pT2HatMin / p2AbsMax );
680 double zPosMaxMax = max(ratio34, unity34 + zMaxMax);
681 double zNegMaxMax = max(ratio34, unity34 - zMaxMax);
682 double intZ0Max = 2. * zMaxMax;
683 double intZ12Max = log( zPosMaxMax / zNegMaxMax);
684 double intZ34Max = 1. / zNegMaxMax - 1. / zPosMaxMax;
688 vecZ[iZ] += sigmaTmp;
690 matZ[iZ][1] += (intZ0Max / intZ12Max) / zNeg;
691 matZ[iZ][2] += (intZ0Max / intZ12Max) / zPos;
692 matZ[iZ][3] += (intZ0Max / intZ34Max) / pow2(zNeg);
693 matZ[iZ][4] += (intZ0Max / intZ34Max) / pow2(zPos);
708 if (!hasPointLeptons) solveSys( nTau, binTau, vecTau, matTau, tauCoef);
709 if (!hasPointLeptons) solveSys( nY, binY, vecY, matY, yCoef);
710 if (is2) solveSys( nZ, binZ, vecZ, matZ, zCoef);
711 if (showSearch) os <<
"\n";
714 tauCoefSum[0] = tauCoef[0];
715 yCoefSum[0] = yCoef[0];
716 zCoefSum[0] = zCoef[0];
717 for (
int i = 1; i < 8; ++ i) {
718 tauCoefSum[i] = tauCoefSum[i - 1] + tauCoef[i];
719 yCoefSum[i] = yCoefSum[i - 1] + yCoef[i];
720 zCoefSum[i] = zCoefSum[i - 1] + zCoef[i];
723 tauCoefSum[nTau - 1] = 2.;
724 yCoefSum[nY - 1] = 2.;
725 zCoefSum[nZ - 1] = 2.;
729 int iMaxTau[NMAXTRY + 2], iMaxY[NMAXTRY + 2], iMaxZ[NMAXTRY + 2];
730 double sigMax[NMAXTRY + 2];
734 for (
int iTau = 0; iTau < nTau; ++iTau) {
736 if (sameResMass && iTau > 1 && iTau < 6) posTau = (iTau < 4) ? 0.4 : 0.6;
737 selectTau( iTau, posTau, is2);
738 if (!limitY())
continue;
739 if (is2 && !limitZ())
continue;
740 for (
int iY = 0; iY < nY; ++iY) {
742 for (
int iZ = 0; iZ < nZ; ++iZ) {
743 if (is2) selectZ( iZ, 0.5);
744 double sigmaTmp = 0.;
748 sigmaProcessPtr->set1Kin( x1H, x2H, sH);
749 sigmaTmp = sigmaProcessPtr->sigmaPDF();
750 sigmaTmp *= wtTau * wtY;
755 sigmaProcessPtr->set2Kin( x1H, x2H, sH, tH, m3, m4,
757 sigmaTmp = sigmaProcessPtr->sigmaPDF();
758 sigmaTmp *= wtTau * wtY * wtZ * wtBW;
764 for (
int iTry3 = 0; iTry3 < NTRY3BODY; ++iTry3) {
765 if (!select3Body())
continue;
766 sigmaProcessPtr->set3Kin( x1H, x2H, sH, p3cm, p4cm, p5cm,
767 m3, m4, m5, runBW3H, runBW4H, runBW5H);
768 double sigmaTry = sigmaProcessPtr->sigmaPDF();
769 sigmaTry *= wtTau * wtY * wt3Body * wtBW;
770 if (sigmaTry > sigmaTmp) sigmaTmp = sigmaTry;
775 if (canModifySigma) sigmaTmp
776 *= userHooksPtr->multiplySigmaBy( sigmaProcessPtr,
this,
false);
777 if (canBiasSelection) sigmaTmp
778 *= userHooksPtr->biasSelectionBy( sigmaProcessPtr,
this,
false);
781 if (showSearch) os <<
" tau =" << setw(11) << tau <<
" y ="
782 << setw(11) << y <<
" z =" << setw(11) << z
783 <<
" sigma =" << setw(11) << sigmaTmp <<
"\n";
784 if (sigmaTmp < 0.) sigmaTmp = 0.;
787 bool mirrorPoint =
false;
788 for (
int iMove = 0; iMove < nMax; ++iMove)
789 if (abs(sigmaTmp - sigMax[iMove]) < SAMESIGMA
790 * (sigmaTmp + sigMax[iMove])) mirrorPoint =
true;
795 for (
int iMove = nMax - 1; iMove >= -1; --iMove) {
797 if (iInsert == 0 || sigmaTmp < sigMax[iMove])
break;
798 iMaxTau[iMove + 1] = iMaxTau[iMove];
799 iMaxY[iMove + 1] = iMaxY[iMove];
800 iMaxZ[iMove + 1] = iMaxZ[iMove];
801 sigMax[iMove + 1] = sigMax[iMove];
803 iMaxTau[iInsert] = iTau;
806 sigMax[iInsert] = sigmaTmp;
807 if (nMax < NMAXTRY) ++nMax;
814 if (showSearch) os <<
"\n";
818 int beginVar = (hasPointLeptons) ? 2 : 0;
819 for (
int iMax = 0; iMax < nMax; ++iMax) {
820 int iTau = iMaxTau[iMax];
821 int iY = iMaxY[iMax];
822 int iZ = iMaxZ[iMax];
827 double varVal, varNew, deltaVar, marginVar, sigGrid[3];
830 for (
int iRepeat = 0; iRepeat < 2; ++iRepeat) {
832 for (
int iVar = beginVar; iVar < nVar; ++iVar) {
833 if (iVar == 0) varVal = tauVal;
834 else if (iVar == 1) varVal = yVal;
836 deltaVar = (iRepeat == 0) ? 0.1
837 : max( 0.01, min( 0.05, min( varVal - 0.02, 0.98 - varVal) ) );
838 marginVar = (iRepeat == 0) ? 0.02 : 0.002;
839 int moveStart = (iRepeat == 0 && iVar == 0) ? 0 : 1;
840 for (
int move = moveStart; move < 9; ++move) {
846 }
else if (move == 1) {
848 varNew = varVal + deltaVar;
849 }
else if (move == 2) {
851 varNew = varVal - deltaVar;
852 }
else if (sigGrid[2] >= max( sigGrid[0], sigGrid[1])
853 && varVal + 2. * deltaVar < 1. - marginVar) {
855 sigGrid[0] = sigGrid[1];
856 sigGrid[1] = sigGrid[2];
858 varNew = varVal + deltaVar;
859 }
else if (sigGrid[0] >= max( sigGrid[1], sigGrid[2])
860 && varVal - 2. * deltaVar > marginVar) {
862 sigGrid[2] = sigGrid[1];
863 sigGrid[1] = sigGrid[0];
865 varNew = varVal - deltaVar;
866 }
else if (sigGrid[2] >= sigGrid[0]) {
869 sigGrid[0] = sigGrid[1];
875 sigGrid[2] = sigGrid[1];
881 bool insideLimits =
true;
884 selectTau( iTau, tauVal, is2);
885 if (!limitY()) insideLimits =
false;
886 if (is2 && !limitZ()) insideLimits =
false;
889 if (is2) selectZ( iZ, zVal);
891 }
else if (iVar == 1) {
894 }
else if (iVar == 2) {
900 double sigmaTmp = 0.;
905 sigmaProcessPtr->set1Kin( x1H, x2H, sH);
906 sigmaTmp = sigmaProcessPtr->sigmaPDF();
907 sigmaTmp *= wtTau * wtY;
912 sigmaProcessPtr->set2Kin( x1H, x2H, sH, tH, m3, m4,
914 sigmaTmp = sigmaProcessPtr->sigmaPDF();
915 sigmaTmp *= wtTau * wtY * wtZ * wtBW;
921 for (
int iTry3 = 0; iTry3 < NTRY3BODY; ++iTry3) {
922 if (!select3Body())
continue;
923 sigmaProcessPtr->set3Kin( x1H, x2H, sH, p3cm, p4cm, p5cm,
924 m3, m4, m5, runBW3H, runBW4H, runBW5H);
925 double sigmaTry = sigmaProcessPtr->sigmaPDF();
926 sigmaTry *= wtTau * wtY * wt3Body * wtBW;
927 if (sigmaTry > sigmaTmp) sigmaTmp = sigmaTry;
932 if (canModifySigma) sigmaTmp
933 *= userHooksPtr->multiplySigmaBy( sigmaProcessPtr,
this,
false);
934 if (canBiasSelection) sigmaTmp
935 *= userHooksPtr->biasSelectionBy( sigmaProcessPtr,
this,
false);
938 if (showSearch) os <<
" tau =" << setw(11) << tau <<
" y ="
939 << setw(11) << y <<
" z =" << setw(11) << z
940 <<
" sigma =" << setw(11) << sigmaTmp <<
"\n";
941 if (sigmaTmp < 0.) sigmaTmp = 0.;
945 sigGrid[iGrid] = sigmaTmp;
946 if (sigmaTmp > sigmaMx) sigmaMx = sigmaTmp;
951 sigmaMx *= SAFETYMARGIN;
955 if (showSearch) os <<
"\n Final maximum = " << setw(11) << sigmaMx << endl;
967 bool PhaseSpace::trialKin123(
bool is2,
bool is3,
bool inEvent, ostream& os) {
970 if (doEnergySpread) {
971 eCM = infoPtr->eCM();
975 if (idResA !=0 && !hasPointLeptons) {
976 tauResA = mResA * mResA / s;
977 widResA = mResA * GammaResA / s;
979 if (idResB != 0 && !hasPointLeptons) {
980 tauResB = mResB * mResB / s;
981 widResB = mResB * GammaResB / s;
992 if (!limitTau(is2, is3))
return false;
994 if (!hasPointLeptons) {
995 double rTau = rndmPtr->flat();
996 while (rTau > tauCoefSum[iTau]) ++iTau;
998 selectTau( iTau, rndmPtr->flat(), is2);
1005 if (!limitY())
return false;
1007 if (!hasPointLeptons) {
1008 double rY = rndmPtr->flat();
1009 while (rY > yCoefSum[iY]) ++iY;
1011 selectY( iY, rndmPtr->flat());
1018 if (!limitZ())
return false;
1020 double rZ = rndmPtr->flat();
1021 while (rZ > zCoefSum[iZ]) ++iZ;
1022 selectZ( iZ, rndmPtr->flat());
1027 sigmaProcessPtr->set1Kin( x1H, x2H, sH);
1028 sigmaNw = sigmaProcessPtr->sigmaPDF();
1029 sigmaNw *= wtTau * wtY;
1034 sigmaProcessPtr->set2Kin( x1H, x2H, sH, tH, m3, m4, runBW3H, runBW4H);
1035 sigmaNw = sigmaProcessPtr->sigmaPDF();
1036 sigmaNw *= wtTau * wtY * wtZ * wtBW;
1041 if (!select3Body()) sigmaNw = 0.;
1043 sigmaProcessPtr->set3Kin( x1H, x2H, sH, p3cm, p4cm, p5cm,
1044 m3, m4, m5, runBW3H, runBW4H, runBW5H);
1045 sigmaNw = sigmaProcessPtr->sigmaPDF();
1046 sigmaNw *= wtTau * wtY * wt3Body * wtBW;
1051 if (canModifySigma) sigmaNw
1052 *= userHooksPtr->multiplySigmaBy( sigmaProcessPtr,
this, inEvent);
1053 if (canBiasSelection) sigmaNw
1054 *= userHooksPtr->biasSelectionBy( sigmaProcessPtr,
this, inEvent);
1058 if (sigmaNw > sigmaMx) {
1059 infoPtr->errorMsg(
"Warning in PhaseSpace2to2tauyz::trialKin: "
1060 "maximum for cross section violated");
1063 if (increaseMaximum || !inEvent) {
1064 double violFact = SAFETYMARGIN * sigmaNw / sigmaMx;
1065 sigmaMx = SAFETYMARGIN * sigmaNw;
1067 if (showViolation) {
1068 if (violFact < 9.99) os << fixed;
1069 else os << scientific;
1070 os <<
" PYTHIA Maximum for " << sigmaProcessPtr->name()
1071 <<
" increased by factor " << setprecision(3) << violFact
1072 <<
" to " << scientific << sigmaMx << endl;
1076 }
else if (showViolation && sigmaNw > sigmaPos) {
1077 double violFact = sigmaNw / sigmaMx;
1078 if (violFact < 9.99) os << fixed;
1079 else os << scientific;
1080 os <<
" PYTHIA Maximum for " << sigmaProcessPtr->name()
1081 <<
" exceeded by factor " << setprecision(3) << violFact << endl;
1087 if (sigmaNw < sigmaNeg) {
1088 infoPtr->errorMsg(
"Warning in PhaseSpace2to2tauyz::trialKin:"
1089 " negative cross section set 0",
"for " + sigmaProcessPtr->name() );
1093 if (showViolation) os <<
" PYTHIA Negative minimum for "
1094 << sigmaProcessPtr->name() <<
" changed to " << scientific
1095 << setprecision(3) << sigmaNeg << endl;
1097 if (sigmaNw < 0.) sigmaNw = 0.;
1100 biasWt = (canBiasSelection) ? userHooksPtr->biasedSelectionWeight() : 1.;
1110 bool PhaseSpace::limitTau(
bool is2,
bool is3) {
1113 if (hasPointLeptons) {
1120 tauMin = sHatMin / s;
1121 tauMax = (mHatMax < mHatMin) ? 1. : min( 1., sHatMax / s);
1125 double mT3Min = sqrt(s3 + pT2HatMin);
1126 double mT4Min = sqrt(s4 + pT2HatMin);
1127 double mT5Min = (is3) ? sqrt(s5 + pT2HatMin) : 0.;
1128 tauMin = max( tauMin, pow2(mT3Min + mT4Min + mT5Min) / s);
1132 return (tauMax > tauMin);
1139 bool PhaseSpace::limitY() {
1142 if (hasPointLeptons) {
1148 yMax = -0.5 * log(tau);
1151 double yMaxMargin = (hasLeptonBeams) ? yMax + LEPTONXLOGMAX : yMax;
1154 return (yMaxMargin > 0.);
1161 bool PhaseSpace::limitZ() {
1168 zMax = sqrtpos( 1. - pT2HatMin / p2Abs );
1169 if (pTHatMax > pTHatMin) zMin = sqrtpos( 1. - pT2HatMax / p2Abs );
1172 return (zMax > zMin);
1179 void PhaseSpace::selectTau(
int iTau,
double tauVal,
bool is2) {
1182 if (hasPointLeptons) {
1188 p2Abs = 0.25 * (pow2(sH - s3 - s4) - 4. * s3 * s4) / sH;
1189 pAbs = sqrtpos( p2Abs );
1199 tRatA = ((tauResA + tauMax) / (tauResA + tauMin)) * (tauMin / tauMax);
1200 aLowA = atan( (tauMin - tauResA) / widResA);
1201 aUppA = atan( (tauMax - tauResA) / widResA);
1207 tRatB = ((tauResB + tauMax) / (tauResB + tauMin)) * (tauMin / tauMax);
1208 aLowB = atan( (tauMin - tauResB) / widResB);
1209 aUppB = atan( (tauMax - tauResB) / widResB);
1215 if (hasLeptonBeams) {
1216 aLowT = log( max( LEPTONTAUMIN, 1. - tauMin) );
1217 aUppT = log( max( LEPTONTAUMIN, 1. - tauMax) );
1218 intTau6 = aLowT - aUppT;
1222 if (iTau == 0) tau = tauMin * pow( tauMax / tauMin, tauVal);
1223 else if (iTau == 1) tau = tauMax * tauMin
1224 / (tauMin + (tauMax - tauMin) * tauVal);
1227 else if (hasLeptonBeams && iTau == nTau - 1)
1228 tau = 1. - exp( aUppT + intTau6 * tauVal );
1232 else if (iTau == 2) tau = tauResA * tauMin
1233 / ((tauResA + tauMin) * pow( tRatA, tauVal) - tauMin);
1234 else if (iTau == 3) tau = tauResA + widResA
1235 * tan( aLowA + (aUppA - aLowA) * tauVal);
1236 else if (iTau == 4) tau = tauResB * tauMin
1237 / ((tauResB + tauMin) * pow( tRatB, tauVal) - tauMin);
1238 else if (iTau == 5) tau = tauResB + widResB
1239 * tan( aLowB + (aUppB - aLowB) * tauVal);
1242 intTau0 = log( tauMax / tauMin);
1243 intTau1 = (tauMax - tauMin) / (tauMax * tauMin);
1244 double invWtTau = (tauCoef[0] / intTau0) + (tauCoef[1] / intTau1) / tau;
1246 intTau2 = -log(tRatA) / tauResA;
1247 intTau3 = (aUppA - aLowA) / widResA;
1248 invWtTau += (tauCoef[2] / intTau2) / (tau + tauResA)
1249 + (tauCoef[3] / intTau3) * tau / ( pow2(tau - tauResA) + pow2(widResA) );
1252 intTau4 = -log(tRatB) / tauResB;
1253 intTau5 = (aUppB - aLowB) / widResB;
1254 invWtTau += (tauCoef[4] / intTau4) / (tau + tauResB)
1255 + (tauCoef[5] / intTau5) * tau / ( pow2(tau - tauResB) + pow2(widResB) );
1258 invWtTau += (tauCoef[nTau - 1] / intTau6)
1259 * tau / max( LEPTONTAUMIN, 1. - tau);
1260 wtTau = 1. / invWtTau;
1266 p2Abs = 0.25 * (pow2(sH - s3 - s4) - 4. * s3 * s4) / sH;
1267 pAbs = sqrtpos( p2Abs );
1276 void PhaseSpace::selectY(
int iY,
double yVal) {
1279 if (hasPointLeptons) {
1288 if (hasLeptonBeams && iY > 2) iY += 2;
1291 double expYMax = exp( yMax );
1292 double expYMin = exp(-yMax );
1293 double atanMax = atan( expYMax );
1294 double atanMin = atan( expYMin );
1295 double aUppY = (hasLeptonBeams)
1296 ? log( max( LEPTONXMIN, LEPTONXMAX / tau - 1. ) ) : 0.;
1297 double aLowY = LEPTONXLOGMIN;
1300 if (iY == 0) y = log( tan( atanMin + (atanMax - atanMin) * yVal ) );
1303 else if (iY <= 2) y = yMax * (2. * sqrt(yVal) - 1.);
1306 else if (iY <= 4) y = log( expYMin + (expYMax - expYMin) * yVal );
1309 else y = yMax - log( 1. + exp(aLowY + (aUppY - aLowY) * yVal) );
1312 if (iY == 2 || iY == 4 || iY == 6) y = -y;
1315 intY0 = 2. * (atanMax - atanMin);
1316 intY12 = 0.5 * pow2(2. * yMax);
1317 intY34 = expYMax - expYMin;
1318 intY56 = aUppY - aLowY;
1319 double invWtY = (yCoef[0] / intY0) / cosh(y)
1320 + (yCoef[1] / intY12) * (y + yMax) + (yCoef[2] / intY12) * (yMax - y);
1321 if (!hasLeptonBeams) invWtY
1322 += (yCoef[3] / intY34) * exp(y) + (yCoef[4] / intY34) * exp(-y);
1324 += (yCoef[3] / intY56) / max( LEPTONXMIN, 1. - exp( y - yMax) )
1325 + (yCoef[4] / intY56) / max( LEPTONXMIN, 1. - exp(-y - yMax) );
1329 x1H = sqrt(tau) * exp(y);
1330 x2H = sqrt(tau) * exp(-y);
1339 void PhaseSpace::selectZ(
int iZ,
double zVal) {
1342 ratio34 = max(TINY, 2. * s3 * s4 / pow2(sH));
1343 unity34 = 1. + ratio34;
1344 double ratiopT2 = 2. * pT2HatMin / max( SHATMINZ, sH);
1345 if (ratiopT2 < PT2RATMINZ) ratio34 = max( ratio34, ratiopT2);
1348 double zPosMax = max(ratio34, unity34 + zMax);
1349 double zNegMax = max(ratio34, unity34 - zMax);
1350 double zPosMin = max(ratio34, unity34 + zMin);
1351 double zNegMin = max(ratio34, unity34 - zMin);
1355 if (zVal < 0.5) z = -(zMax + (zMin - zMax) * 2. * zVal);
1356 else z = zMin + (zMax - zMin) * (2. * zVal - 1.);
1359 }
else if (iZ == 1) {
1360 double areaNeg = log(zPosMax / zPosMin);
1361 double areaPos = log(zNegMin / zNegMax);
1362 double area = areaNeg + areaPos;
1363 if (zVal * area < areaNeg) {
1364 double zValMod = zVal * area / areaNeg;
1365 z = unity34 - zPosMax * pow(zPosMin / zPosMax, zValMod);
1367 double zValMod = (zVal * area - areaNeg)/ areaPos;
1368 z = unity34 - zNegMin * pow(zNegMax / zNegMin, zValMod);
1372 }
else if (iZ == 2) {
1373 double areaNeg = log(zNegMin / zNegMax);
1374 double areaPos = log(zPosMax / zPosMin);
1375 double area = areaNeg + areaPos;
1376 if (zVal * area < areaNeg) {
1377 double zValMod = zVal * area / areaNeg;
1378 z = zNegMax * pow(zNegMin / zNegMax, zValMod) - unity34;
1380 double zValMod = (zVal * area - areaNeg)/ areaPos;
1381 z = zPosMin * pow(zPosMax / zPosMin, zValMod) - unity34;
1385 }
else if (iZ == 3) {
1386 double areaNeg = 1. / zPosMin - 1. / zPosMax;
1387 double areaPos = 1. / zNegMax - 1. / zNegMin;
1388 double area = areaNeg + areaPos;
1389 if (zVal * area < areaNeg) {
1390 double zValMod = zVal * area / areaNeg;
1391 z = unity34 - 1. / (1./zPosMax + areaNeg * zValMod);
1393 double zValMod = (zVal * area - areaNeg)/ areaPos;
1394 z = unity34 - 1. / (1./zNegMin + areaPos * zValMod);
1398 }
else if (iZ == 4) {
1399 double areaNeg = 1. / zNegMax - 1. / zNegMin;
1400 double areaPos = 1. / zPosMin - 1. / zPosMax;
1401 double area = areaNeg + areaPos;
1402 if (zVal * area < areaNeg) {
1403 double zValMod = zVal * area / areaNeg;
1404 z = 1. / (1./zNegMax - areaNeg * zValMod) - unity34;
1406 double zValMod = (zVal * area - areaNeg)/ areaPos;
1407 z = 1. / (1./zPosMin - areaPos * zValMod) - unity34;
1412 if (z < 0.) z = min(-zMin, max(-zMax, z));
1413 else z = min(zMax, max(zMin, z));
1414 zNeg = max(ratio34, unity34 - z);
1415 zPos = max(ratio34, unity34 + z);
1418 double intZ0 = 2. * (zMax - zMin);
1419 double intZ12 = log( (zPosMax * zNegMin) / (zPosMin * zNegMax) );
1420 double intZ34 = 1. / zPosMin - 1. / zPosMax + 1. / zNegMax
1422 wtZ = mHat * pAbs / ( (zCoef[0] / intZ0) + (zCoef[1] / intZ12) / zNeg
1423 + (zCoef[2] / intZ12) / zPos + (zCoef[3] / intZ34) / pow2(zNeg)
1424 + (zCoef[4] / intZ34) / pow2(zPos) );
1427 double sH34 = -0.5 * (sH - s3 - s4);
1428 tH = sH34 + mHat * pAbs * z;
1429 uH = sH34 - mHat * pAbs * z;
1430 pTH = sqrtpos( (tH * uH - s3 * s4) / sH);
1439 bool PhaseSpace::select3Body() {
1442 double m35S = pow2(m3 + m5);
1443 double pT4Smax = 0.25 * ( pow2(sH - s4 - m35S) - 4. * s4 * m35S ) / sH;
1444 if (pTHatMax > pTHatMin) pT4Smax = min( pT2HatMax, pT4Smax);
1445 double pT4Smin = pT2HatMin;
1446 double m34S = pow2(m3 + m4);
1447 double pT5Smax = 0.25 * ( pow2(sH - s5 - m34S) - 4. * s5 * m34S ) / sH;
1448 if (pTHatMax > pTHatMin) pT5Smax = min( pT2HatMax, pT5Smax);
1449 double pT5Smin = pT2HatMin;
1452 if ( pT4Smax < pow2(pTHatMin + MASSMARGIN) )
return false;
1453 if ( pT5Smax < pow2(pTHatMin + MASSMARGIN) )
return false;
1456 double pTSmaxProp = pT4Smax + sTchan1;
1457 double pTSminProp = pT4Smin + sTchan1;
1458 double pTSratProp = pTSmaxProp / pTSminProp;
1459 double pTSdiff = pT4Smax - pT4Smin;
1460 double rShape = rndmPtr->flat();
1462 if (rShape < frac3Flat) pT4S = pT4Smin + rndmPtr->flat() * pTSdiff;
1463 else if (rShape < frac3Flat + frac3Pow1) pT4S = max( pT2HatMin,
1464 pTSminProp * pow( pTSratProp, rndmPtr->flat() ) - sTchan1 );
1465 else pT4S = max( pT2HatMin, pTSminProp * pTSmaxProp
1466 / (pTSminProp + rndmPtr->flat()* pTSdiff) - sTchan1 );
1467 double wt4 = pTSdiff / ( frac3Flat
1468 + frac3Pow1 * pTSdiff / (log(pTSratProp) * (pT4S + sTchan1))
1469 + frac3Pow2 * pTSminProp * pTSmaxProp / pow2(pT4S + sTchan1) );
1472 pTSmaxProp = pT5Smax + sTchan2;
1473 pTSminProp = pT5Smin + sTchan2;
1474 pTSratProp = pTSmaxProp / pTSminProp;
1475 pTSdiff = pT5Smax - pT5Smin;
1476 rShape = rndmPtr->flat();
1478 if (rShape < frac3Flat) pT5S = pT5Smin + rndmPtr->flat() * pTSdiff;
1479 else if (rShape < frac3Flat + frac3Pow1) pT5S = max( pT2HatMin,
1480 pTSminProp * pow( pTSratProp, rndmPtr->flat() ) - sTchan2 );
1481 else pT5S = max( pT2HatMin, pTSminProp * pTSmaxProp
1482 / (pTSminProp + rndmPtr->flat()* pTSdiff) - sTchan2 );
1483 double wt5 = pTSdiff / ( frac3Flat
1484 + frac3Pow1 * pTSdiff / (log(pTSratProp) * (pT5S + sTchan2))
1485 + frac3Pow2 * pTSminProp * pTSmaxProp / pow2(pT5S + sTchan2) );
1488 double phi4 = 2. * M_PI * rndmPtr->flat();
1489 double phi5 = 2. * M_PI * rndmPtr->flat();
1490 double pT3S = max( 0., pT4S + pT5S + 2. * sqrt(pT4S * pT5S)
1491 * cos(phi4 - phi5) );
1492 if ( pT3S < pT2HatMin || (pTHatMax > pTHatMin && pT3S > pT2HatMax) )
1496 double sT3 = s3 + pT3S;
1497 double sT4 = s4 + pT4S;
1498 double sT5 = s5 + pT5S;
1499 double mT3 = sqrt(sT3);
1500 double mT4 = sqrt(sT4);
1501 double mT5 = sqrt(sT5);
1502 if ( mT3 + mT4 + mT5 + MASSMARGIN > mHat )
return false;
1505 double m45S = pow2(mT4 + mT5);
1506 double y3max = log( ( sH + sT3 - m45S + sqrtpos( pow2(sH - sT3 - m45S)
1507 - 4 * sT3 * m45S ) ) / (2. * mHat * mT3) );
1508 if (y3max < YRANGEMARGIN)
return false;
1509 double y3 = (2. * rndmPtr->flat() - 1.) * (1. - YRANGEMARGIN) * y3max;
1510 double pz3 = mT3 * sinh(y3);
1511 double e3 = mT3 * cosh(y3);
1515 double e45 = mHat - e3;
1516 double sT45 = e45 * e45 - pz45 * pz45;
1517 double lam45 = sqrtpos( pow2(sT45 - sT4 - sT5) - 4. * sT4 * sT5 );
1518 if (lam45 < YRANGEMARGIN * sH)
return false;
1519 double lam4e = sT45 + sT4 - sT5;
1520 double lam5e = sT45 + sT5 - sT4;
1521 double tFac = -0.5 * mHat / sT45;
1522 double t1Pos = tFac * (e45 - pz45) * (lam4e - lam45);
1523 double t1Neg = tFac * (e45 - pz45) * (lam4e + lam45);
1524 double t2Pos = tFac * (e45 + pz45) * (lam5e - lam45);
1525 double t2Neg = tFac * (e45 + pz45) * (lam5e + lam45);
1528 double wtPosUnnorm = 1.;
1529 double wtNegUnnorm = 1.;
1530 if (useMirrorWeight) {
1531 wtPosUnnorm = 1./ pow2( (t1Pos - sTchan1) * (t2Pos - sTchan2) );
1532 wtNegUnnorm = 1./ pow2( (t1Neg - sTchan1) * (t2Neg - sTchan2) );
1534 double wtPos = wtPosUnnorm / (wtPosUnnorm + wtNegUnnorm);
1535 double wtNeg = wtNegUnnorm / (wtPosUnnorm + wtNegUnnorm);
1536 double epsilon = (rndmPtr->flat() < wtPos) ? 1. : -1.;
1539 double px4 = sqrt(pT4S) * cos(phi4);
1540 double py4 = sqrt(pT4S) * sin(phi4);
1541 double px5 = sqrt(pT5S) * cos(phi5);
1542 double py5 = sqrt(pT5S) * sin(phi5);
1543 double pz4 = 0.5 * (pz45 * lam4e + epsilon * e45 * lam45) / sT45;
1544 double pz5 = pz45 - pz4;
1545 double e4 = sqrt(sT4 + pz4 * pz4);
1546 double e5 = sqrt(sT5 + pz5 * pz5);
1547 p3cm = Vec4( -(px4 + px5), -(py4 + py5), pz3, e3);
1548 p4cm = Vec4( px4, py4, pz4, e4);
1549 p5cm = Vec4( px5, py5, pz5, e5);
1552 wt3Body = wt4 * wt5 * (2. * y3max) / (128. * pow3(M_PI) * lam45);
1553 wt3Body *= (epsilon > 0.) ? 1. / wtPos : 1. / wtNeg;
1556 wt3Body /= (2. * sH);
1567 void PhaseSpace::solveSys(
int n,
int bin[8],
double vec[8],
1568 double mat[8][8],
double coef[8], ostream& os) {
1572 os <<
"\n Equation system: " << setw(5) << bin[0];
1573 for (
int j = 0; j < n; ++j) os << setw(12) << mat[0][j];
1574 os << setw(12) << vec[0] <<
"\n";
1575 for (
int i = 1; i < n; ++i) {
1576 os <<
" " << setw(5) << bin[i];
1577 for (
int j = 0; j < n; ++j) os << setw(12) << mat[i][j];
1578 os << setw(12) << vec[i] <<
"\n";
1583 double vecNor[8], coefTmp[8];
1584 for (
int i = 0; i < n; ++i) coefTmp[i] = 0.;
1587 bool canSolve =
true;
1588 for (
int i = 0; i < n; ++i)
if (bin[i] == 0) canSolve =
false;
1590 for (
int i = 0; i < n; ++i) vecSum += vec[i];
1591 if (abs(vecSum) < TINY) canSolve =
false;
1595 for (
int i = 0; i < n; ++i) vecNor[i] = max( 0.1, vec[i] / vecSum);
1596 for (
int k = 0; k < n - 1; ++k) {
1597 for (
int i = k + 1; i < n; ++i) {
1598 if (abs(mat[k][k]) < TINY) {canSolve =
false;
break;}
1599 double ratio = mat[i][k] / mat[k][k];
1600 vec[i] -= ratio * vec[k];
1601 for (
int j = k; j < n; ++j) mat[i][j] -= ratio * mat[k][j];
1603 if (!canSolve)
break;
1606 for (
int k = n - 1; k >= 0; --k) {
1607 for (
int j = k + 1; j < n; ++j) vec[k] -= mat[k][j] * coefTmp[j];
1608 coefTmp[k] = vec[k] / mat[k][k];
1614 if (!canSolve)
for (
int i = 0; i < n; ++i) {
1617 if (vecSum > TINY) vecNor[i] = max(0.1, vec[i] / vecSum);
1621 double coefSum = 0.;
1623 for (
int i = 0; i < n; ++i) {
1624 coefTmp[i] = max( 0., coefTmp[i]);
1625 coefSum += coefTmp[i];
1626 vecSum += vecNor[i];
1628 if (coefSum > 0.)
for (
int i = 0; i < n; ++i) coef[i] = EVENFRAC / n
1629 + (1. - EVENFRAC) * 0.5 * (coefTmp[i] / coefSum + vecNor[i] / vecSum);
1630 else for (
int i = 0; i < n; ++i) coef[i] = 1. / n;
1634 os <<
" Solution: ";
1635 for (
int i = 0; i < n; ++i) os << setw(12) << coef[i];
1644 void PhaseSpace::setupMass1(
int iM) {
1647 if (iM == 3) idMass[iM] = abs(sigmaProcessPtr->id3Mass());
1648 if (iM == 4) idMass[iM] = abs(sigmaProcessPtr->id4Mass());
1649 if (iM == 5) idMass[iM] = abs(sigmaProcessPtr->id5Mass());
1652 if (idMass[iM] == 0) {
1658 mPeak[iM] = particleDataPtr->m0(idMass[iM]);
1659 mWidth[iM] = particleDataPtr->mWidth(idMass[iM]);
1660 mMin[iM] = particleDataPtr->mMin(idMass[iM]);
1661 mMax[iM] = particleDataPtr->mMax(idMass[iM]);
1663 if (idMass[iM] == 23 && gmZmode == 1) mPeak[iM] = mMin[iM];
1667 sPeak[iM] = mPeak[iM] * mPeak[iM];
1668 useBW[iM] = useBreitWigners && (mWidth[iM] > minWidthBreitWigners);
1669 if (!useBW[iM]) mWidth[iM] = 0.;
1670 mw[iM] = mPeak[iM] * mWidth[iM];
1671 wmRat[iM] = (idMass[iM] == 0 || mPeak[iM] == 0.)
1672 ? 0. : mWidth[iM] / mPeak[iM];
1676 mLower[iM] = mMin[iM];
1677 mUpper[iM] = mHatMax;
1686 void PhaseSpace::setupMass2(
int iM,
double distToThresh) {
1689 if (mMax[iM] > mMin[iM]) mUpper[iM] = min( mUpper[iM], mMax[iM]);
1690 sLower[iM] = mLower[iM] * mLower[iM];
1691 sUpper[iM] = mUpper[iM] * mUpper[iM];
1695 if (distToThresh > THRESHOLDSIZE) {
1698 }
else if (distToThresh > - THRESHOLDSIZE) {
1699 fracFlat[iM] = 0.25 - 0.15 * distToThresh / THRESHOLDSIZE;
1700 fracInv [iM] = 0.15 - 0.05 * distToThresh / THRESHOLDSIZE;
1708 if (idMass[iM] == 23 && gmZmode == 0) {
1709 fracFlat[iM] *= 0.5;
1710 fracInv[iM] = 0.5 * fracInv[iM] + 0.25;
1711 fracInv2[iM] = 0.25;
1712 }
else if (idMass[iM] == 23 && gmZmode == 1) {
1719 atanLower[iM] = atan( (sLower[iM] - sPeak[iM])/ mw[iM] );
1720 atanUpper[iM] = atan( (sUpper[iM] - sPeak[iM])/ mw[iM] );
1721 intBW[iM] = atanUpper[iM] - atanLower[iM];
1722 intFlat[iM] = sUpper[iM] - sLower[iM];
1723 intInv[iM] = log( sUpper[iM] / sLower[iM] );
1724 intInv2[iM] = 1./sLower[iM] - 1./sUpper[iM];
1732 void PhaseSpace::trialMass(
int iM) {
1735 double& mSet = (iM == 3) ? m3 : ( (iM == 4) ? m4 : m5 );
1736 double& sSet = (iM == 3) ? s3 : ( (iM == 4) ? s4 : s5 );
1740 double pickForm = rndmPtr->flat();
1741 if (pickForm > fracFlat[iM] + fracInv[iM] + fracInv2[iM])
1742 sSet = sPeak[iM] + mw[iM] * tan( atanLower[iM]
1743 + rndmPtr->flat() * intBW[iM] );
1744 else if (pickForm > fracInv[iM] + fracInv2[iM])
1745 sSet = sLower[iM] + rndmPtr->flat() * (sUpper[iM] - sLower[iM]);
1746 else if (pickForm > fracInv2[iM])
1747 sSet = sLower[iM] * pow( sUpper[iM] / sLower[iM], rndmPtr->flat() );
1748 else sSet = sLower[iM] * sUpper[iM]
1749 / (sLower[iM] + rndmPtr->flat() * (sUpper[iM] - sLower[iM]));
1769 double PhaseSpace::weightMass(
int iM) {
1772 double& sSet = (iM == 3) ? s3 : ( (iM == 4) ? s4 : s5 );
1773 double& runBWH = (iM == 3) ? runBW3H : ( (iM == 4) ? runBW4H : runBW5H );
1777 if (!useBW[iM])
return 1.;
1780 double genBW = (1. - fracFlat[iM] - fracInv[iM] - fracInv2[iM])
1781 * mw[iM] / ( (pow2(sSet - sPeak[iM]) + pow2(mw[iM])) * intBW[iM])
1782 + fracFlat[iM] / intFlat[iM] + fracInv[iM] / (sSet * intInv[iM])
1783 + fracInv2[iM] / (sSet*sSet * intInv2[iM]);
1786 double mwRun = sSet * wmRat[iM];
1787 runBWH = mwRun / (pow2(sSet - sPeak[iM]) + pow2(mwRun)) / M_PI;
1790 return (runBWH / genBW);
1803 bool PhaseSpace2to1tauy::setupMass() {
1806 gmZmode = gmZmodeGlobal;
1807 int gmZmodeProc = sigmaProcessPtr->gmZmode();
1808 if (gmZmodeProc >= 0) gmZmode = gmZmodeProc;
1811 int idRes = abs(sigmaProcessPtr->resonanceA());
1812 int idTmp = abs(sigmaProcessPtr->resonanceB());
1813 if (idTmp > 0) idRes = idTmp;
1814 double mResMin = (idRes == 0) ? 0. : particleDataPtr->mMin(idRes);
1815 double mResMax = (idRes == 0) ? 0. : particleDataPtr->mMax(idRes);
1818 mHatMin = max( mResMin, mHatGlobalMin);
1819 sHatMin = mHatMin*mHatMin;
1821 if (mResMax > mResMin) mHatMax = min( mHatMax, mResMax);
1822 if (mHatGlobalMax > mHatGlobalMin) mHatMax = min( mHatMax, mHatGlobalMax);
1823 sHatMax = mHatMax*mHatMax;
1829 return (mHatMax > mHatMin + MASSMARGIN);
1837 bool PhaseSpace2to1tauy::finalKin() {
1845 pH[1] = Vec4( 0., 0., 0.5 * eCM * x1H, 0.5 * eCM * x1H);
1846 pH[2] = Vec4( 0., 0., -0.5 * eCM * x2H, 0.5 * eCM * x2H);
1847 pH[3] = pH[1] + pH[2];
1862 bool PhaseSpace2to2tauyz::setupMasses() {
1865 gmZmode = gmZmodeGlobal;
1866 int gmZmodeProc = sigmaProcessPtr->gmZmode();
1867 if (gmZmodeProc >= 0) gmZmode = gmZmodeProc;
1870 mHatMin = mHatGlobalMin;
1871 sHatMin = mHatMin*mHatMin;
1873 if (mHatGlobalMax > mHatGlobalMin) mHatMax = min( eCM, mHatGlobalMax);
1874 sHatMax = mHatMax*mHatMax;
1881 if (useBW[3]) mUpper[3] -= (useBW[4]) ? mMin[4] : mPeak[4];
1882 if (useBW[4]) mUpper[4] -= (useBW[3]) ? mMin[3] : mPeak[3];
1885 bool physical =
true;
1886 if (useBW[3] && mUpper[3] < mLower[3] + MASSMARGIN) physical =
false;
1887 if (useBW[4] && mUpper[4] < mLower[4] + MASSMARGIN) physical =
false;
1888 if (!useBW[3] && !useBW[4] && mHatMax < mPeak[3] + mPeak[4] + MASSMARGIN)
1890 if (!physical)
return false;
1893 pTHatMin = pTHatGlobalMin;
1894 if (mPeak[3] < pTHatMinDiverge || mPeak[4] < pTHatMinDiverge)
1895 pTHatMin = max( pTHatMin, pTHatMinDiverge);
1896 pT2HatMin = pTHatMin * pTHatMin;
1897 pTHatMax = pTHatGlobalMax;
1898 pT2HatMax = pTHatMax * pTHatMax;
1902 double distToThreshA = (mHatMax - mPeak[3] - mPeak[4]) * mWidth[3]
1903 / (pow2(mWidth[3]) + pow2(mWidth[4]));
1904 double distToThreshB = (mHatMax - mPeak[3] - mMin[4]) / mWidth[3];
1905 double distToThresh = min( distToThreshA, distToThreshB);
1906 setupMass2(3, distToThresh);
1911 double distToThreshA = (mHatMax - mPeak[3] - mPeak[4]) * mWidth[4]
1912 / (pow2(mWidth[3]) + pow2(mWidth[4]));
1913 double distToThreshB = (mHatMax - mMin[3] - mPeak[4]) / mWidth[4];
1914 double distToThresh = min( distToThreshA, distToThreshB);
1915 setupMass2(4, distToThresh);
1919 m3 = (useBW[3]) ? min(mPeak[3], mUpper[3]) : mPeak[3];
1920 m4 = (useBW[4]) ? min(mPeak[4], mUpper[4]) : mPeak[4];
1921 if (m3 + m4 + THRESHOLDSIZE * (mWidth[3] + mWidth[4]) + MASSMARGIN
1923 if (useBW[3] && useBW[4]) physical = constrainedM3M4();
1924 else if (useBW[3]) physical = constrainedM3();
1925 else if (useBW[4]) physical = constrainedM4();
1933 if (useBW[3]) wtBW *= weightMass(3) * EXTRABWWTMAX;
1934 if (useBW[4]) wtBW *= weightMass(4) * EXTRABWWTMAX;
1946 bool PhaseSpace2to2tauyz::trialMasses() {
1957 if (m3 + m4 + MASSMARGIN > mHatMax)
return false;
1960 if (useBW[3]) wtBW *= weightMass(3);
1961 if (useBW[4]) wtBW *= weightMass(4);
1971 bool PhaseSpace2to2tauyz::finalKin() {
1974 int id3 = sigmaProcessPtr->id(3);
1975 int id4 = sigmaProcessPtr->id(4);
1976 if (idMass[3] == 0) { m3 = particleDataPtr->m0(id3); s3 = m3*m3; }
1977 if (idMass[4] == 0) { m4 = particleDataPtr->m0(id4); s4 = m4*m4; }
1980 if (sigmaProcessPtr->swappedTU()) {
1986 if (m3 + m4 + MASSMARGIN > mHat) {
1987 infoPtr->errorMsg(
"Warning in PhaseSpace2to2tauyz::finalKin: "
1988 "failed after mass assignment");
1991 p2Abs = 0.25 * (pow2(sH - s3 - s4) - 4. * s3 * s4) / sH;
1992 pAbs = sqrtpos( p2Abs );
2001 pH[1] = Vec4( 0., 0., 0.5 * eCM * x1H, 0.5 * eCM * x1H);
2002 pH[2] = Vec4( 0., 0., -0.5 * eCM * x2H, 0.5 * eCM * x2H);
2005 pH[3] = Vec4( 0., 0., pAbs, 0.5 * (sH + s3 - s4) / mHat);
2006 pH[4] = Vec4( 0., 0., -pAbs, 0.5 * (sH + s4 - s3) / mHat);
2010 phi = 2. * M_PI * rndmPtr->flat();
2011 betaZ = (x1H - x2H)/(x1H + x2H);
2012 pH[3].rot( theta, phi);
2013 pH[4].rot( theta, phi);
2014 pH[3].bst( 0., 0., betaZ);
2015 pH[4].bst( 0., 0., betaZ);
2016 pTH = pAbs * sin(theta);
2029 bool PhaseSpace2to2tauyz::constrainedM3M4() {
2032 bool foundNonZero =
false;
2033 double wtMassMax = 0.;
2034 double m3WtMax = 0.;
2035 double m4WtMax = 0.;
2036 double xMax = (mHatMax - mLower[3] - mLower[4]) / (mWidth[3] + mWidth[4]);
2037 double xStep = THRESHOLDSTEP * min(1., xMax);
2039 double wtMassXbin, wtMassMaxOld, m34, mT34Min, wtMassNow,
2040 wtBW3Now, wtBW4Now, beta34Now;
2046 wtMassMaxOld = wtMassMax;
2047 m34 = mHatMax - xNow * (mWidth[3] + mWidth[4]);
2050 m3 = min( mUpper[3], m34 - mLower[4]);
2051 if (m3 > mPeak[3]) m3 = max( mLower[3], mPeak[3]);
2053 if (m4 < mLower[4]) {m4 = mLower[4]; m3 = m34 - m4;}
2056 mT34Min = sqrt(m3*m3 + pT2HatMin) + sqrt(m4*m4 + pT2HatMin);
2057 if (mT34Min < mHatMax) {
2061 if (m3 > mLower[3] && m3 < mUpper[3] && m4 > mLower[4]
2062 && m4 < mUpper[4]) {
2063 wtBW3Now = mw[3] / ( pow2(m3*m3 - sPeak[3]) + pow2(mw[3]) );
2064 wtBW4Now = mw[4] / ( pow2(m4*m4 - sPeak[4]) + pow2(mw[4]) );
2065 beta34Now = sqrt( pow2(mHatMax*mHatMax - m3*m3 - m4*m4)
2066 - pow2(2. * m3 * m4) ) / (mHatMax*mHatMax);
2067 wtMassNow = wtBW3Now * wtBW4Now * beta34Now;
2071 if (wtMassNow > wtMassXbin) wtMassXbin = wtMassNow;
2072 if (wtMassNow > wtMassMax) {
2073 foundNonZero =
true;
2074 wtMassMax = wtMassNow;
2081 m4 = min( mUpper[4], m34 - mLower[3]);
2082 if (m4 > mPeak[4]) m4 = max( mLower[4], mPeak[4]);
2084 if (m3 < mLower[3]) {m3 = mLower[3]; m4 = m34 - m3;}
2087 mT34Min = sqrt(m3*m3 + pT2HatMin) + sqrt(m4*m4 + pT2HatMin);
2088 if (mT34Min < mHatMax) {
2092 if (m3 > mLower[3] && m3 < mUpper[3] && m4 > mLower[4]
2093 && m4 < mUpper[4]) {
2094 wtBW3Now = mw[3] / ( pow2(m3*m3 - sPeak[3]) + pow2(mw[3]) );
2095 wtBW4Now = mw[4] / ( pow2(m4*m4 - sPeak[4]) + pow2(mw[4]) );
2096 beta34Now = sqrt( pow2(mHatMax*mHatMax - m3*m3 - m4*m4)
2097 - pow2(2. * m3 * m4) ) / (mHatMax*mHatMax);
2098 wtMassNow = wtBW3Now * wtBW4Now * beta34Now;
2102 if (wtMassNow > wtMassXbin) wtMassXbin = wtMassNow;
2103 if (wtMassNow > wtMassMax) {
2104 foundNonZero =
true;
2105 wtMassMax = wtMassNow;
2112 }
while ( (!foundNonZero || wtMassXbin > wtMassMaxOld)
2113 && xNow < xMax - xStep);
2118 return foundNonZero;
2128 bool PhaseSpace2to2tauyz::constrainedM3() {
2131 bool foundNonZero =
false;
2132 double wtMassMax = 0.;
2133 double m3WtMax = 0.;
2134 double mT4Min = sqrt(m4*m4 + pT2HatMin);
2135 double xMax = (mHatMax - mLower[3] - m4) / mWidth[3];
2136 double xStep = THRESHOLDSTEP * min(1., xMax);
2138 double wtMassNow, mT34Min, wtBW3Now, beta34Now;
2144 m3 = mHatMax - m4 - xNow * mWidth[3];
2147 mT34Min = sqrt(m3*m3 + pT2HatMin) + mT4Min;
2148 if (mT34Min < mHatMax) {
2151 wtBW3Now = mw[3] / ( pow2(m3*m3 - sPeak[3]) + pow2(mw[3]) );
2152 beta34Now = sqrt( pow2(mHatMax*mHatMax - m3*m3 - m4*m4)
2153 - pow2(2. * m3 * m4) ) / (mHatMax*mHatMax);
2154 wtMassNow = wtBW3Now * beta34Now;
2157 if (wtMassNow > wtMassMax) {
2158 foundNonZero =
true;
2159 wtMassMax = wtMassNow;
2165 }
while ( (!foundNonZero || wtMassNow > wtMassMax)
2166 && xNow < xMax - xStep);
2170 return foundNonZero;
2180 bool PhaseSpace2to2tauyz::constrainedM4() {
2183 bool foundNonZero =
false;
2184 double wtMassMax = 0.;
2185 double m4WtMax = 0.;
2186 double mT3Min = sqrt(m3*m3 + pT2HatMin);
2187 double xMax = (mHatMax - mLower[4] - m3) / mWidth[4];
2188 double xStep = THRESHOLDSTEP * min(1., xMax);
2190 double wtMassNow, mT34Min, wtBW4Now, beta34Now;
2196 m4 = mHatMax - m3 - xNow * mWidth[4];
2199 mT34Min = mT3Min + sqrt(m4*m4 + pT2HatMin);
2200 if (mT34Min < mHatMax) {
2203 wtBW4Now = mw[4] / ( pow2(m4*m4 - sPeak[4]) + pow2(mw[4]) );
2204 beta34Now = sqrt( pow2(mHatMax*mHatMax - m3*m3 - m4*m4)
2205 - pow2(2. * m3 * m4) ) / (mHatMax*mHatMax);
2206 wtMassNow = wtBW4Now * beta34Now;
2209 if (wtMassNow > wtMassMax) {
2210 foundNonZero =
true;
2211 wtMassMax = wtMassNow;
2217 }
while ( (!foundNonZero || wtMassNow > wtMassMax)
2218 && xNow < xMax - xStep);
2222 return foundNonZero;
2237 const double PhaseSpace2to2elastic::EXPMAX = 50.;
2240 const double PhaseSpace2to2elastic::CONVERTEL = 0.0510925;
2247 bool PhaseSpace2to2elastic::setupSampling() {
2250 sigmaNw = sigmaProcessPtr->sigmaHatWrap();
2258 bSlope = sigmaTotPtr->bSlopeEl();
2261 lambda12S = pow2(s - s1 - s2) - 4. * s1 * s2 ;
2262 tLow = - lambda12S / s;
2266 useCoulomb = settingsPtr->flag(
"SigmaTotal:setOwn")
2267 && settingsPtr->flag(
"SigmaElastic:setOwn");
2269 sigmaTot = sigmaTotPtr->sigmaTot();
2270 rho = settingsPtr->parm(
"SigmaElastic:rho");
2271 lambda = settingsPtr->parm(
"SigmaElastic:lambda");
2272 tAbsMin = settingsPtr->parm(
"SigmaElastic:tAbsMin");
2273 phaseCst = settingsPtr->parm(
"SigmaElastic:phaseConst");
2274 alphaEM0 = settingsPtr->parm(
"StandardModel:alphaEM0");
2278 sigmaNuc = CONVERTEL * pow2(sigmaTot) * (1. + rho*rho) / bSlope
2279 * exp(-bSlope * tAbsMin);
2280 sigmaCou = (useCoulomb) ?
2281 pow2(alphaEM0) / (4. * CONVERTEL * tAbsMin) : 0.;
2282 signCou = (idA == idB) ? 1. : -1.;
2291 tAux = exp( max(-EXPMAX, bSlope * (tLow - tUpp)) ) - 1.;
2302 bool PhaseSpace2to2elastic::trialKin(
bool,
bool ) {
2305 if (!useCoulomb || sigmaNuc > rndmPtr->flat() * (sigmaNuc + sigmaCou))
2306 tH = tUpp + log(1. + tAux * rndmPtr->flat()) / bSlope;
2309 else tH = tLow * tUpp / (tUpp + rndmPtr->flat() * (tLow - tUpp));
2313 double sigmaN = CONVERTEL * pow2(sigmaTot) * (1. + rho*rho)
2315 double alpEM = couplingsPtr->alphaEM(-tH);
2316 double sigmaC = pow2(alpEM) / (4. * CONVERTEL * tH*tH);
2317 double sigmaGen = 2. * (sigmaN + sigmaC);
2318 double form2 = pow4(lambda/(lambda - tH));
2319 double phase = signCou * alpEM
2320 * (-phaseCst - log(-0.5 * bSlope * tH));
2321 double sigmaCor = sigmaN + pow2(form2) * sigmaC
2322 - signCou * alpEM * sigmaTot * (form2 / (-tH))
2323 * exp(0.5 * bSlope * tH) * (rho * cos(phase) + sin(phase));
2324 sigmaNw = sigmaMx * sigmaCor / sigmaGen;
2328 double tRat = s * tH / lambda12S;
2329 double cosTheta = min(1., max(-1., 1. + 2. * tRat ) );
2330 double sinTheta = 2. * sqrtpos( -tRat * (1. + tRat) );
2331 theta = asin( min(1., sinTheta));
2332 if (cosTheta < 0.) theta = M_PI - theta;
2342 bool PhaseSpace2to2elastic::finalKin() {
2351 pAbs = 0.5 * sqrtpos(lambda12S) / eCM;
2352 pH[1] = Vec4( 0., 0., pAbs, 0.5 * (s + s1 - s2) / eCM);
2353 pH[2] = Vec4( 0., 0., -pAbs, 0.5 * (s + s2 - s1) / eCM);
2356 pH[3] = Vec4( 0., 0., pAbs, 0.5 * (s + s1 - s2) / eCM);
2357 pH[4] = Vec4( 0., 0., -pAbs, 0.5 * (s + s2 - s1) / eCM);
2360 phi = 2. * M_PI * rndmPtr->flat();
2361 pH[3].rot( theta, phi);
2362 pH[4].rot( theta, phi);
2368 uH = 2. * (s1 + s2) - sH - tH;
2370 p2Abs = pAbs * pAbs;
2372 pTH = pAbs * sin(theta);
2390 const int PhaseSpace2to2diffractive::NTRY = 500;
2393 const double PhaseSpace2to2diffractive::EXPMAX = 50.;
2396 const double PhaseSpace2to2diffractive::DIFFMASSMAX = 1e-8;
2403 bool PhaseSpace2to2diffractive::setupSampling() {
2406 PomFlux = settingsPtr->mode(
"Diffraction:PomFlux");
2407 epsilonPF = settingsPtr->parm(
"Diffraction:PomFluxEpsilon");
2408 alphaPrimePF = settingsPtr->parm(
"Diffraction:PomFluxAlphaPrime");
2411 sigmaNw = sigmaProcessPtr->sigmaHatWrap();
2415 m3ElDiff = (isDiffA) ? sigmaTotPtr->mMinXB() : mA;
2416 m4ElDiff = (isDiffB) ? sigmaTotPtr->mMinAX() : mB;
2419 s3 = pow2( m3ElDiff);
2420 s4 = pow2( m4ElDiff);
2423 lambda12 = sqrtpos( pow2( s - s1 - s2) - 4. * s1 * s2 );
2424 lambda34 = sqrtpos( pow2( s - s3 - s4) - 4. * s3 * s4 );
2425 double tempA = s - (s1 + s2 + s3 + s4) + (s1 - s2) * (s3 - s4) / s;
2426 double tempB = lambda12 * lambda34 / s;
2427 double tempC = (s3 - s1) * (s4 - s2) + (s1 + s4 - s2 - s3)
2428 * (s1 * s4 - s2 * s3) / s;
2429 tLow = -0.5 * (tempA + tempB);
2430 tUpp = tempC / tLow;
2433 cRes = sResXB = sResAX = sProton = bMin = bSlope = bSlope1 = bSlope2
2434 = probSlope1 = xIntPF = xtCorPF = mp24DL = coefDL = tAux
2435 = tAux1 = tAux2 = 0.;
2439 cRes = sigmaTotPtr->cRes();
2440 sResXB = pow2( sigmaTotPtr->mResXB());
2441 sResAX = pow2( sigmaTotPtr->mResAX());
2442 sProton = sigmaTotPtr->sProton();
2445 if (!isDiffB) bMin = sigmaTotPtr->bMinSlopeXB();
2446 else if (!isDiffA) bMin = sigmaTotPtr->bMinSlopeAX();
2447 else bMin = sigmaTotPtr->bMinSlopeXX();
2448 tAux = exp( max(-EXPMAX, bMin * (tLow - tUpp)) ) - 1.;
2451 }
else if (PomFlux == 2) {
2453 probSlope1 = 6.38 * ( exp(max(-EXPMAX, bSlope1 * tUpp))
2454 - exp(max(-EXPMAX, bSlope1 * tLow)) ) / bSlope1;
2456 double pS2 = 0.424 * ( exp(max(-EXPMAX, bSlope2 * tUpp))
2457 - exp(max(-EXPMAX, bSlope2 * tLow)) ) / bSlope2;
2458 probSlope1 /= probSlope1 + pS2;
2459 tAux1 = exp( max(-EXPMAX, bSlope1 * (tLow - tUpp)) ) - 1.;
2460 tAux2 = exp( max(-EXPMAX, bSlope2 * (tLow - tUpp)) ) - 1.;
2463 }
else if (PomFlux == 3) {
2465 double xPowPF = 1. - 2. * (1. + epsilonPF);
2466 xIntPF = 2. * (1. + xPowPF);
2467 xtCorPF = 2. * alphaPrimePF;
2468 tAux = exp( max(-EXPMAX, bSlope * (tLow - tUpp)) ) - 1.;
2471 }
else if (PomFlux == 4) {
2472 mp24DL = 4. * pow2(particleDataPtr->m0(2212));
2473 double xPowPF = 1. - 2. * (1. + epsilonPF);
2474 xIntPF = 2. * (1. + xPowPF);
2475 xtCorPF = 2. * alphaPrimePF;
2478 tAux1 = 1. / pow3(1. - coefDL * tLow);
2479 tAux2 = 1. / pow3(1. - coefDL * tUpp);
2492 bool PhaseSpace2to2diffractive::trialKin(
bool,
bool ) {
2495 for (
int loop = 0; ; ++loop) {
2497 infoPtr->errorMsg(
"Error in PhaseSpace2to2diffractive::trialKin: "
2498 " quit after repeated tries");
2506 m3 = (isDiffA) ? m3ElDiff * pow( max(mA, eCM - m4ElDiff) / m3ElDiff,
2507 rndmPtr->flat()) : m3ElDiff;
2508 m4 = (isDiffB) ? m4ElDiff * pow( max(mB, eCM - m3ElDiff) / m4ElDiff,
2509 rndmPtr->flat()) : m4ElDiff;
2514 if (m3 + m4 >= eCM)
continue;
2515 if (isDiffA && !isDiffB) {
2516 double facXB = (1. - s3 / s)
2517 * (1. + cRes * sResXB / (sResXB + s3));
2518 if (facXB < rndmPtr->flat() * (1. + cRes))
continue;
2519 }
else if (isDiffB && !isDiffA) {
2520 double facAX = (1. - s4 / s)
2521 * (1. + cRes * sResAX / (sResAX + s4));
2522 if (facAX < rndmPtr->flat() * (1. + cRes))
continue;
2524 double facXX = (1. - pow2(m3 + m4) / s)
2525 * (s * sProton / (s * sProton + s3 * s4))
2526 * (1. + cRes * sResXB / (sResXB + s3))
2527 * (1. + cRes * sResAX / (sResAX + s4));
2528 if (facXX < rndmPtr->flat() * pow2(1. + cRes))
continue;
2532 tH = tUpp + log(1. + tAux * rndmPtr->flat()) / bMin;
2534 if (isDiffA && !isDiffB) bDiff = sigmaTotPtr->bSlopeXB(s3) - bMin;
2535 else if (!isDiffA) bDiff = sigmaTotPtr->bSlopeAX(s4) - bMin;
2536 else bDiff = sigmaTotPtr->bSlopeXX(s3, s4) - bMin;
2537 bDiff = max(0., bDiff);
2538 if (exp( max(-EXPMAX, bDiff * (tH - tUpp)) ) < rndmPtr->flat())
continue;
2541 }
else if (PomFlux == 2) {
2544 m3 = (isDiffA) ? m3ElDiff * pow( max(mA, eCM - m4ElDiff) / m3ElDiff,
2545 rndmPtr->flat()) : m3ElDiff;
2546 m4 = (isDiffB) ? m4ElDiff * pow( max(mB, eCM - m3ElDiff) / m4ElDiff,
2547 rndmPtr->flat()) : m4ElDiff;
2552 tH = (rndmPtr->flat() < probSlope1)
2553 ? tUpp + log(1. + tAux1 * rndmPtr->flat()) / bSlope1
2554 : tUpp + log(1. + tAux2 * rndmPtr->flat()) / bSlope2;
2557 }
else if (PomFlux == 3) {
2563 double s3MinPow = pow( m3ElDiff, xIntPF );
2564 double s3MaxPow = pow( max(mA, eCM - m4ElDiff), xIntPF );
2565 m3 = pow( s3MinPow + rndmPtr->flat() * (s3MaxPow - s3MinPow),
2569 double s4MinPow = pow( m4ElDiff, xIntPF );
2570 double s4MaxPow = pow( max(mB, eCM - m3ElDiff), xIntPF );
2571 m4 = pow( s4MinPow + rndmPtr->flat() * (s4MaxPow - s4MinPow),
2578 tH = tUpp + log(1. + tAux * rndmPtr->flat()) / bSlope;
2579 if ( isDiffA && pow( s3 / s, xtCorPF * abs(tH) ) < rndmPtr->flat() )
2581 if ( isDiffB && pow( s4 / s, xtCorPF * abs(tH) ) < rndmPtr->flat() )
2585 }
else if (PomFlux == 4) {
2591 double s3MinPow = pow( m3ElDiff, xIntPF );
2592 double s3MaxPow = pow( max(mA, eCM - m4ElDiff), xIntPF );
2593 m3 = pow( s3MinPow + rndmPtr->flat() * (s3MaxPow - s3MinPow),
2597 double s4MinPow = pow( m4ElDiff, xIntPF );
2598 double s4MaxPow = pow( max(mB, eCM - m3ElDiff), xIntPF );
2599 m4 = pow( s4MinPow + rndmPtr->flat() * (s4MaxPow - s4MinPow),
2606 tH = - (1. / pow( tAux1 + rndmPtr->flat() * (tAux2 - tAux1), 1./3.)
2608 double wDL = pow2( (mp24DL - 2.8 * tH) / (mp24DL - tH) )
2609 / pow4( 1. - tH / 0.7);
2610 double wMX = 1. / pow4( 1. - coefDL * tH);
2611 if (wDL < rndmPtr->flat() * wMX)
continue;
2612 if ( isDiffA && pow( s3 / s, xtCorPF * abs(tH) ) < rndmPtr->flat() )
2614 if ( isDiffB && pow( s4 / s, xtCorPF * abs(tH) ) < rndmPtr->flat() )
2619 lambda34 = sqrtpos( pow2( s - s3 - s4) - 4. * s3 * s4 );
2620 double tempA = s - (s1 + s2 + s3 + s4) + (s1 - s2) * (s3 - s4) / s;
2621 double tempB = lambda12 * lambda34 / s;
2622 if (tempB < DIFFMASSMAX)
continue;
2623 double tempC = (s3 - s1) * (s4 - s2) + (s1 + s4 - s2 - s3)
2624 * (s1 * s4 - s2 * s3) / s;
2625 double tLowNow = -0.5 * (tempA + tempB);
2626 double tUppNow = tempC / tLowNow;
2627 if (tH < tLowNow || tH > tUppNow)
continue;
2630 double cosTheta = min(1., max(-1., (tempA + 2. * tH) / tempB));
2631 double sinTheta = 2. * sqrtpos( -(tempC + tempA * tH + tH * tH) )
2633 theta = asin( min(1., sinTheta));
2634 if (cosTheta < 0.) theta = M_PI - theta;
2647 bool PhaseSpace2to2diffractive::finalKin() {
2656 pAbs = 0.5 * lambda12 / eCM;
2657 pH[1] = Vec4( 0., 0., pAbs, 0.5 * (s + s1 - s2) / eCM);
2658 pH[2] = Vec4( 0., 0., -pAbs, 0.5 * (s + s2 - s1) / eCM);
2661 pAbs = 0.5 * lambda34 / eCM;
2662 pH[3] = Vec4( 0., 0., pAbs, 0.5 * (s + s3 - s4) / eCM);
2663 pH[4] = Vec4( 0., 0., -pAbs, 0.5 * (s + s4 - s3) / eCM);
2666 phi = 2. * M_PI * rndmPtr->flat();
2667 pH[3].rot( theta, phi);
2668 pH[4].rot( theta, phi);
2674 uH = s1 + s2 + s3 + s4 - sH - tH;
2676 p2Abs = pAbs * pAbs;
2678 pTH = pAbs * sin(theta);
2696 const int PhaseSpace2to3tauycyl::NITERNR = 5;
2702 bool PhaseSpace2to3tauycyl::setupMasses() {
2705 gmZmode = gmZmodeGlobal;
2706 int gmZmodeProc = sigmaProcessPtr->gmZmode();
2707 if (gmZmodeProc >= 0) gmZmode = gmZmodeProc;
2710 mHatMin = mHatGlobalMin;
2711 sHatMin = mHatMin*mHatMin;
2713 if (mHatGlobalMax > mHatGlobalMin) mHatMax = min( eCM, mHatGlobalMax);
2714 sHatMax = mHatMax*mHatMax;
2722 if (useBW[3]) mUpper[3] -= (mPeak[4] + mPeak[5]);
2723 if (useBW[4]) mUpper[4] -= (mPeak[3] + mPeak[5]);
2724 if (useBW[5]) mUpper[5] -= (mPeak[3] + mPeak[4]);
2727 bool physical =
true;
2728 if (useBW[3] && mUpper[3] < mLower[3] + MASSMARGIN) physical =
false;
2729 if (useBW[4] && mUpper[4] < mLower[4] + MASSMARGIN) physical =
false;
2730 if (useBW[5] && mUpper[5] < mLower[5] + MASSMARGIN) physical =
false;
2731 if (!useBW[3] && !useBW[4] && !useBW[5] && mHatMax < mPeak[3]
2732 + mPeak[4] + mPeak[5] + MASSMARGIN) physical =
false;
2733 if (!physical)
return false;
2736 pTHatMin = pTHatGlobalMin;
2737 pT2HatMin = pTHatMin * pTHatMin;
2738 pTHatMax = pTHatGlobalMax;
2739 pT2HatMax = pTHatMax * pTHatMax;
2743 double distToThreshA = (mHatMax - mPeak[3] - mPeak[4] - mPeak[5])
2744 * mWidth[3] / (pow2(mWidth[3]) + pow2(mWidth[4]) + pow2(mWidth[5]));
2745 double distToThreshB = (mHatMax - mPeak[3] - mMin[4] - mMin[5])
2747 double distToThresh = min( distToThreshA, distToThreshB);
2748 setupMass2(3, distToThresh);
2753 double distToThreshA = (mHatMax - mPeak[3] - mPeak[4] - mPeak[5])
2754 * mWidth[4] / (pow2(mWidth[3]) + pow2(mWidth[4]) + pow2(mWidth[5]));
2755 double distToThreshB = (mHatMax - mPeak[4] - mMin[3] - mMin[5])
2757 double distToThresh = min( distToThreshA, distToThreshB);
2758 setupMass2(4, distToThresh);
2763 double distToThreshA = (mHatMax - mPeak[3] - mPeak[4] - mPeak[5])
2764 * mWidth[5] / (pow2(mWidth[3]) + pow2(mWidth[4]) + pow2(mWidth[5]));
2765 double distToThreshB = (mHatMax - mPeak[5] - mMin[3] - mMin[4])
2767 double distToThresh = min( distToThreshA, distToThreshB);
2768 setupMass2(5, distToThresh);
2772 m3 = (useBW[3]) ? min(mPeak[3], mUpper[3]) : mPeak[3];
2773 m4 = (useBW[4]) ? min(mPeak[4], mUpper[4]) : mPeak[4];
2774 m5 = (useBW[5]) ? min(mPeak[5], mUpper[5]) : mPeak[5];
2775 if (m3 + m4 + m5 + MASSMARGIN > mHatMax) physical =
false;
2783 if (useBW[3]) wtBW *= weightMass(3) * EXTRABWWTMAX;
2784 if (useBW[4]) wtBW *= weightMass(4) * EXTRABWWTMAX;
2785 if (useBW[5]) wtBW *= weightMass(5) * EXTRABWWTMAX;
2796 bool PhaseSpace2to3tauycyl::trialMasses() {
2808 if (m3 + m4 + m5 + MASSMARGIN > mHatMax)
return false;
2811 if (useBW[3]) wtBW *= weightMass(3);
2812 if (useBW[4]) wtBW *= weightMass(4);
2813 if (useBW[5]) wtBW *= weightMass(5);
2824 bool PhaseSpace2to3tauycyl::finalKin() {
2827 int id3 = sigmaProcessPtr->id(3);
2828 int id4 = sigmaProcessPtr->id(4);
2829 int id5 = sigmaProcessPtr->id(5);
2830 if (idMass[3] == 0) { m3 = particleDataPtr->m0(id3); s3 = m3*m3; }
2831 if (idMass[4] == 0) { m4 = particleDataPtr->m0(id4); s4 = m4*m4; }
2832 if (idMass[5] == 0) { m5 = particleDataPtr->m0(id5); s5 = m5*m5; }
2835 if (m3 + m4 + m5 + MASSMARGIN > mHat) {
2836 infoPtr->errorMsg(
"Warning in PhaseSpace2to3tauycyl::finalKin: "
2837 "failed after mass assignment");
2849 pH[1] = Vec4( 0., 0., 0.5 * eCM * x1H, 0.5 * eCM * x1H);
2850 pH[2] = Vec4( 0., 0., -0.5 * eCM * x2H, 0.5 * eCM * x2H);
2853 if (idMass[3] == 0 || idMass[4] == 0 || idMass[5] == 0) {
2854 double p3S = p3cm.pAbs2();
2855 double p4S = p4cm.pAbs2();
2856 double p5S = p5cm.pAbs2();
2858 double e3, e4, e5, value, deriv;
2861 for (
int i = 0; i < NITERNR; ++i) {
2862 e3 = sqrt(s3 + fac * p3S);
2863 e4 = sqrt(s4 + fac * p4S);
2864 e5 = sqrt(s5 + fac * p5S);
2865 value = e3 + e4 + e5 - mHat;
2866 deriv = 0.5 * (p3S / e3 + p4S / e4 + p5S / e5);
2867 fac -= value / deriv;
2871 double facRoot = sqrt(fac);
2872 p3cm.rescale3( facRoot );
2873 p4cm.rescale3( facRoot );
2874 p5cm.rescale3( facRoot );
2875 p3cm.e( sqrt(s3 + fac * p3S) );
2876 p4cm.e( sqrt(s4 + fac * p4S) );
2877 p5cm.e( sqrt(s5 + fac * p5S) );
2886 betaZ = (x1H - x2H)/(x1H + x2H);
2887 pH[3].rot( theta, phi);
2888 pH[4].rot( theta, phi);
2889 pH[3].bst( 0., 0., betaZ);
2890 pH[4].bst( 0., 0., betaZ);
2891 pH[5].bst( 0., 0., betaZ);
2894 pTH = (p3cm.pT() + p4cm.pT() + p5cm.pT()) / 3.;
2911 bool PhaseSpace2to3yyycyl::setupSampling() {
2914 pTHat3Min = settingsPtr->parm(
"PhaseSpace:pTHat3Min");
2915 pTHat3Max = settingsPtr->parm(
"PhaseSpace:pTHat3Max");
2916 pTHat5Min = settingsPtr->parm(
"PhaseSpace:pTHat5Min");
2917 pTHat5Max = settingsPtr->parm(
"PhaseSpace:pTHat5Max");
2918 RsepMin = settingsPtr->parm(
"PhaseSpace:RsepMin");
2919 R2sepMin = pow2(RsepMin);
2922 hasBaryonBeams = ( beamAPtr->isBaryon() && beamBPtr->isBaryon() );
2925 for (
int i = 0; i < 6; ++i) mH[i] = 0.;
2930 if (pT3Max < pT3Min) pT3Max = 0.5 * eCM;
2933 if (pT5Max < pT5Min) pT5Max = 0.5 * eCM;
2934 if (pT5Max > pT3Max || pT5Min > pT3Min || pT3Min + 2. * pT5Min > eCM) {
2935 infoPtr->errorMsg(
"Error in PhaseSpace2to3yyycyl::setupSampling: "
2936 "inconsistent pT limits in 3-body phase space");
2944 double pT5EffMax = min( pT5Max, 0.5 * pT3Min / cos(0.5 * RsepMin) );
2945 double pT3EffMin = max( pT3Min, 2.0 * pT5Min * cos(0.5 * RsepMin) ) ;
2946 double sinhR = sinh(0.5 * RsepMin);
2947 double coshR = cosh(0.5 * RsepMin);
2948 for (
int iStep = 0; iStep < 120; ++iStep) {
2953 pT5 = pT5Min * pow( pT5EffMax / pT5Min, iStep / 9.);
2954 double pTRat = pT5 / pT3;
2955 double sin2Rsep = pow2( sin(RsepMin) );
2956 double cosPhi35 = - cos(RsepMin) * sqrtpos(1. - sin2Rsep
2957 * pow2(pTRat)) - sin2Rsep * pTRat;
2958 cosPhi35 = max( cosPhi35, cos(M_PI - 0.5 * RsepMin) );
2959 double sinPhi35 = sqrt(1. - pow2(cosPhi35));
2960 pT4 = sqrt( pow2(pT3) + pow2(pT5) + 2. * pT3 * pT5 * cosPhi35);
2961 p3cm = pT3 * Vec4( 1., 0., 0., 1.);
2962 p4cm = Vec4(-pT3 - pT5 * cosPhi35, -pT5 * sinPhi35, 0., pT4);
2963 p5cm = pT5 * Vec4( cosPhi35, sinPhi35, 0., 1.);
2967 pT5 = pT5Min * pow( pT5Max / pT5Min, iStep%10 / 9. );
2968 pT3 = max( pT3Min, 2. * pT5);
2970 p4cm = pT4 * Vec4( -1., 0., sinhR, coshR );
2971 p5cm = pT5 * Vec4( -1., 0., -sinhR, coshR );
2972 y3 = -1.2 + 0.2 * (iStep/10);
2973 p3cm = pT3 * Vec4( 1., 0., sinh(y3), cosh(y3));
2974 betaZ = (p3cm.pz() + p4cm.pz() + p5cm.pz())
2975 / (p3cm.e() + p4cm.e() + p5cm.e());
2976 p3cm.bst( 0., 0., -betaZ);
2977 p4cm.bst( 0., 0., -betaZ);
2978 p5cm.bst( 0., 0., -betaZ);
2982 pInSum = p3cm + p4cm + p5cm;
2983 x1H = pInSum.e() / eCM;
2985 sH = pInSum.m2Calc();
2986 sigmaProcessPtr->set3Kin( x1H, x2H, sH, p3cm, p4cm, p5cm,
2987 0., 0., 0., 1., 1., 1.);
2988 sigmaNw = sigmaProcessPtr->sigmaPDF();
2991 double flux = 1. /(8. * pow2(sH) * pow5(2. * M_PI));
2992 double pTRng = pow2(M_PI)
2993 * pow4(pT3) * (1./pow2(pT3Min) - 1./pow2(pT3Max))
2994 * pow2(pT5) * 2.* log(pT5Max/pT5Min);
2995 double yRng = 8. * log(eCM / pT3) * log(eCM / pT4) * log(eCM / pT5);
2996 sigmaNw *= SAFETYMARGIN * flux * pTRng * yRng;
2999 if (showSearch && sigmaNw > sigmaMx) cout <<
"\n New sigmamax is "
3000 << scientific << setprecision(3) << sigmaNw <<
" for x1 = " << x1H
3001 <<
" x2 = " << x2H <<
" sH = " << sH << endl <<
" p3 = " << p3cm
3002 <<
" p4 = " << p4cm <<
" p5 = " << p5cm;
3003 if (sigmaNw > sigmaMx) sigmaMx = sigmaNw;
3015 bool PhaseSpace2to3yyycyl::trialKin(
bool inEvent,
bool) {
3018 if (doEnergySpread) {
3019 eCM = infoPtr->eCM();
3027 if (pT3Max < pT3Min) pT3Max = 0.5 * eCM;
3030 if (pT5Max < pT5Min) pT5Max = 0.5 * eCM;
3031 if (pT5Max > pT3Max || pT5Min > pT3Min || pT3Min + 2. * pT5Min > eCM) {
3032 infoPtr->errorMsg(
"Error in PhaseSpace2to3yyycyl::trialKin: "
3033 "inconsistent pT limits in 3-body phase space");
3038 pT3 = pT3Min * pT3Max / sqrt( pow2(pT3Min) +
3039 rndmPtr->flat() * (pow2(pT3Max) - pow2(pT3Min)) );
3040 pT5Max = min(pT5Max, pT3);
3041 if (pT5Max < pT5Min)
return false;
3042 pT5 = pT5Min * pow( pT5Max / pT5Min, rndmPtr->flat() );
3045 phi3 = 2. * M_PI * rndmPtr->flat();
3046 phi5 = 2. * M_PI * rndmPtr->flat();
3047 pT4 = sqrt( pow2(pT3) + pow2(pT5) + 2. * pT3 * pT5 * cos(phi3 - phi5) );
3048 if (pT4 > pT3 || pT4 < pT5)
return false;
3049 phi4 = atan2( -(pT3 * sin(phi3) + pT5 * sin(phi5)),
3050 -(pT3 * cos(phi3) + pT5 * cos(phi5)) );
3053 y3Max = log(eCM / pT3);
3054 y4Max = log(eCM / pT4);
3055 y5Max = log(eCM / pT5);
3056 y3 = y3Max * (2. * rndmPtr->flat() - 1.);
3057 y4 = y4Max * (2. * rndmPtr->flat() - 1.);
3058 y5 = y5Max * (2. * rndmPtr->flat() - 1.);
3062 double WTy = (hasBaryonBeams) ? (1. - pow2(y3/y3Max))
3063 * (1. - pow2(y4/y4Max)) * (1. - pow2(y5/y5Max)) : 1.;
3064 if (WTy < rndmPtr->flat())
return false;
3067 dphi = abs(phi3 - phi4);
3068 if (dphi > M_PI) dphi = 2. * M_PI - dphi;
3069 if (pow2(y3 - y4) + pow2(dphi) < R2sepMin)
return false;
3070 dphi = abs(phi3 - phi5);
3071 if (dphi > M_PI) dphi = 2. * M_PI - dphi;
3072 if (pow2(y3 - y5) + pow2(dphi) < R2sepMin)
return false;
3073 dphi = abs(phi4 - phi5);
3074 if (dphi > M_PI) dphi = 2. * M_PI - dphi;
3075 if (pow2(y4 - y5) + pow2(dphi) < R2sepMin)
return false;
3078 pH[3] = pT3 * Vec4( cos(phi3), sin(phi3), sinh(y3), cosh(y3) );
3079 pH[4] = pT4 * Vec4( cos(phi4), sin(phi4), sinh(y4), cosh(y4) );
3080 pH[5] = pT5 * Vec4( cos(phi5), sin(phi5), sinh(y5), cosh(y5) );
3081 pInSum = pH[3] + pH[4] + pH[5];
3084 x1H = (pInSum.e() + pInSum.pz()) / eCM;
3085 x2H = (pInSum.e() - pInSum.pz()) / eCM;
3086 if (x1H >= 1. || x2H >= 1.)
return false;
3087 sH = pInSum.m2Calc();
3088 if ( sH < pow2(mHatGlobalMin) ||
3089 (mHatGlobalMax > mHatGlobalMin && sH > pow2(mHatGlobalMax)) )
3093 betaZ = (x1H - x2H)/(x1H + x2H);
3094 p3cm = pH[3]; p3cm.bst( 0., 0., -betaZ);
3095 p4cm = pH[4]; p4cm.bst( 0., 0., -betaZ);
3096 p5cm = pH[5]; p5cm.bst( 0., 0., -betaZ);
3099 sigmaProcessPtr->set3Kin( x1H, x2H, sH, p3cm, p4cm, p5cm,
3100 0., 0., 0., 1., 1., 1.);
3101 sigmaNw = sigmaProcessPtr->sigmaPDF();
3104 double flux = 1. /(8. * pow2(sH) * pow5(2. * M_PI));
3105 double yRng = 8. * y3Max * y4Max * y5Max;
3106 double pTRng = pow2(M_PI)
3107 * pow4(pT3) * (1./pow2(pT3Min) - 1./pow2(pT3Max))
3108 * pow2(pT5) * 2.* log(pT5Max/pT5Min);
3109 sigmaNw *= flux * yRng * pTRng / WTy;
3112 if (canModifySigma) sigmaNw
3113 *= userHooksPtr->multiplySigmaBy( sigmaProcessPtr,
this, inEvent);
3114 if (canBiasSelection) sigmaNw
3115 *= userHooksPtr->biasSelectionBy( sigmaProcessPtr,
this, inEvent);
3119 if (sigmaNw > sigmaMx) {
3120 infoPtr->errorMsg(
"Warning in PhaseSpace2to3yyycyl::trialKin: "
3121 "maximum for cross section violated");
3124 if (increaseMaximum || !inEvent) {
3125 double violFact = SAFETYMARGIN * sigmaNw / sigmaMx;
3126 sigmaMx = SAFETYMARGIN * sigmaNw;
3128 if (showViolation) {
3129 if (violFact < 9.99) cout << fixed;
3130 else cout << scientific;
3131 cout <<
" PYTHIA Maximum for " << sigmaProcessPtr->name()
3132 <<
" increased by factor " << setprecision(3) << violFact
3133 <<
" to " << scientific << sigmaMx << endl;
3137 }
else if (showViolation && sigmaNw > sigmaPos) {
3138 double violFact = sigmaNw / sigmaMx;
3139 if (violFact < 9.99) cout << fixed;
3140 else cout << scientific;
3141 cout <<
" PYTHIA Maximum for " << sigmaProcessPtr->name()
3142 <<
" exceeded by factor " << setprecision(3) << violFact << endl;
3148 if (sigmaNw < sigmaNeg) {
3149 infoPtr->errorMsg(
"Warning in PhaseSpace2to3yyycyl::trialKin:"
3150 " negative cross section set 0",
"for " + sigmaProcessPtr->name() );
3154 if (showViolation) cout <<
" PYTHIA Negative minimum for "
3155 << sigmaProcessPtr->name() <<
" changed to " << scientific
3156 << setprecision(3) << sigmaNeg << endl;
3158 if (sigmaNw < 0.) sigmaNw = 0.;
3169 bool PhaseSpace2to3yyycyl::finalKin() {
3172 for (
int i = 0; i < 6; ++i) mH[i] = 0.;
3175 pH[1] = 0.5 * (pInSum.e() + pInSum.pz()) * Vec4( 0., 0., 1., 1.);
3176 pH[2] = 0.5 * (pInSum.e() - pInSum.pz()) * Vec4( 0., 0., -1., 1.);
3181 pTH = (pH[3].pT() + pH[4].pT() + pH[5].pT()) / 3.;
3201 const double PhaseSpaceLHA::CONVERTPB2MB = 1e-9;
3207 bool PhaseSpaceLHA::setupSampling() {
3210 strategy = lhaUpPtr->strategy();
3211 stratAbs = abs(strategy);
3212 if (strategy == 0 || stratAbs > 4) {
3213 ostringstream stratCode;
3214 stratCode << strategy;
3215 infoPtr->errorMsg(
"Error in PhaseSpaceLHA::setupSampling: unknown "
3216 "Les Houches Accord weighting stategy", stratCode.str());
3221 nProc = lhaUpPtr->sizeProc();
3227 double xMax, xSec, xMaxAbs;
3228 for (
int iProc = 0 ; iProc < nProc; ++iProc) {
3229 idPr = lhaUpPtr->idProcess(iProc);
3230 xMax = lhaUpPtr->xMax(iProc);
3231 xSec = lhaUpPtr->xSec(iProc);
3234 if ( (strategy == 1 || strategy == 2) && xMax < 0.) {
3235 infoPtr->errorMsg(
"Error in PhaseSpaceLHA::setupSampling: "
3236 "negative maximum not allowed");
3239 if ( ( strategy == 2 || strategy == 3) && xSec < 0.) {
3240 infoPtr->errorMsg(
"Error in PhaseSpaceLHA::setupSampling: "
3241 "negative cross section not allowed");
3246 if (stratAbs == 1) xMaxAbs = abs(xMax);
3247 else if (stratAbs < 4) xMaxAbs = abs(xSec);
3249 idProc.push_back( idPr );
3250 xMaxAbsProc.push_back( xMaxAbs );
3253 xMaxAbsSum += xMaxAbs;
3256 sigmaMx = xMaxAbsSum * CONVERTPB2MB;
3257 sigmaSgn = xSecSgnSum * CONVERTPB2MB;
3268 bool PhaseSpaceLHA::trialKin(
bool,
bool repeatSame ) {
3272 if (repeatSame) idProcNow = idProcSave;
3273 else if (stratAbs <= 2) {
3274 double xMaxAbsRndm = xMaxAbsSum * rndmPtr->flat();
3276 do xMaxAbsRndm -= xMaxAbsProc[++iProc];
3277 while (xMaxAbsRndm > 0. && iProc < nProc - 1);
3278 idProcNow = idProc[iProc];
3282 bool physical = lhaUpPtr->setEvent(idProcNow);
3283 if (!physical)
return false;
3286 int idPr = lhaUpPtr->idProcess();
3288 for (
int iP = 0; iP < int(idProc.size()); ++iP)
3289 if (idProc[iP] == idPr) iProc = iP;
3293 double wtPr = lhaUpPtr->weight();
3294 if (stratAbs == 1) sigmaNw = wtPr * CONVERTPB2MB
3295 * xMaxAbsSum / xMaxAbsProc[iProc];
3296 else if (stratAbs == 2) sigmaNw = (wtPr / abs(lhaUpPtr->xMax(iProc)))
3298 else if (strategy == 3) sigmaNw = sigmaMx;
3299 else if (strategy == -3 && wtPr > 0.) sigmaNw = sigmaMx;
3300 else if (strategy == -3) sigmaNw = -sigmaMx;
3301 else if (stratAbs == 4) sigmaNw = wtPr * CONVERTPB2MB;
3304 x1H = lhaUpPtr->x1();
3305 x2H = lhaUpPtr->x2();