9 #include "Pythia8/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. };
82 const double PhaseSpace::FFA1 = 0.9;
83 const double PhaseSpace::FFA2 = 0.1;
84 const double PhaseSpace::FFB1 = 4.6;
85 const double PhaseSpace::FFB2 = 0.6;
91 void PhaseSpace::init(
bool isFirst, SigmaProcess* sigmaProcessPtrIn,
92 Info* infoPtrIn, Settings* settingsPtrIn, ParticleData* particleDataPtrIn,
93 Rndm* rndmPtrIn, BeamParticle* beamAPtrIn, BeamParticle* beamBPtrIn,
94 Couplings* couplingsPtrIn, SigmaTotal* sigmaTotPtrIn,
95 UserHooks* userHooksPtrIn) {
98 sigmaProcessPtr = sigmaProcessPtrIn;
100 settingsPtr = settingsPtrIn;
101 particleDataPtr = particleDataPtrIn;
103 beamAPtr = beamAPtrIn;
104 beamBPtr = beamBPtrIn;
105 couplingsPtr = couplingsPtrIn;
106 sigmaTotPtr = sigmaTotPtrIn;
107 userHooksPtr = userHooksPtrIn;
110 idA = beamAPtr->id();
111 idB = beamBPtr->id();
114 eCM = infoPtr->eCM();
118 hasLeptonBeams = ( beamAPtr->isLepton() || beamBPtr->isLepton() );
119 hasPointLeptons = ( hasLeptonBeams
120 && (beamAPtr->isUnresolved() || beamBPtr->isUnresolved() ) );
123 if (isFirst || settingsPtr->flag(
"PhaseSpace:sameForSecond")) {
124 mHatGlobalMin = settingsPtr->parm(
"PhaseSpace:mHatMin");
125 mHatGlobalMax = settingsPtr->parm(
"PhaseSpace:mHatMax");
126 pTHatGlobalMin = settingsPtr->parm(
"PhaseSpace:pTHatMin");
127 pTHatGlobalMax = settingsPtr->parm(
"PhaseSpace:pTHatMax");
131 mHatGlobalMin = settingsPtr->parm(
"PhaseSpace:mHatMinSecond");
132 mHatGlobalMax = settingsPtr->parm(
"PhaseSpace:mHatMaxSecond");
133 pTHatGlobalMin = settingsPtr->parm(
"PhaseSpace:pTHatMinSecond");
134 pTHatGlobalMax = settingsPtr->parm(
"PhaseSpace:pTHatMaxSecond");
138 pTHatMinDiverge = settingsPtr->parm(
"PhaseSpace:pTHatMinDiverge");
141 useBreitWigners = settingsPtr->flag(
"PhaseSpace:useBreitWigners");
142 minWidthBreitWigners = settingsPtr->parm(
"PhaseSpace:minWidthBreitWigners");
145 doEnergySpread = settingsPtr->flag(
"Beams:allowMomentumSpread");
148 showSearch = settingsPtr->flag(
"PhaseSpace:showSearch");
149 showViolation = settingsPtr->flag(
"PhaseSpace:showViolation");
150 increaseMaximum = settingsPtr->flag(
"PhaseSpace:increaseMaximum");
153 gmZmodeGlobal = settingsPtr->mode(
"WeakZ0:gmZmode");
156 canModifySigma = (userHooksPtr != 0)
157 ? userHooksPtr->canModifySigma() :
false;
158 canBiasSelection = (userHooksPtr != 0)
159 ? userHooksPtr->canBiasSelection() :
false;
162 canBias2Sel = settingsPtr->flag(
"PhaseSpace:bias2Selection");
163 bias2SelPow = settingsPtr->parm(
"PhaseSpace:bias2SelectionPow");
164 bias2SelRef = settingsPtr->parm(
"PhaseSpace:bias2SelectionRef");
167 mRecalculate = settingsPtr->parm(
"LesHouches:mRecalculate");
203 void PhaseSpace::decayKinematics(
Event& process) {
207 for (
int iResBeg = 5; iResBeg < process.size(); ++iResBeg) {
208 if (iResBeg <= iResEnd)
continue;
210 while ( iResEnd < process.size() - 1
211 && process[iResEnd + 1].mother1() == process[iResBeg].mother1()
212 && process[iResEnd + 1].mother2() == process[iResBeg].mother2() )
217 for (
int iRes = iResBeg; iRes <= iResEnd; ++iRes)
218 if ( !process[iRes].isFinal() ) hasRes =
true;
219 if ( !hasRes )
continue;
222 double decWt = sigmaProcessPtr->weightDecay( process, iResBeg, iResEnd);
223 if (decWt < 0.) infoPtr->errorMsg(
"Warning in PhaseSpace::decay"
224 "Kinematics: negative angular weight");
225 if (decWt > 1.) infoPtr->errorMsg(
"Warning in PhaseSpace::decay"
226 "Kinematics: angular weight above unity");
227 while (decWt < rndmPtr->flat() ) {
230 for (
int iRes = iResBeg; iRes < process.size(); ++iRes) {
231 if ( process[iRes].isFinal() )
continue;
232 int iResMother = iRes;
233 while (iResMother > iResEnd)
234 iResMother = process[iResMother].mother1();
235 if (iResMother < iResBeg)
continue;
238 decayKinematicsStep( process, iRes);
244 decWt = sigmaProcessPtr->weightDecay( process, iResBeg, iResEnd);
245 if (decWt < 0.) infoPtr->errorMsg(
"Warning in PhaseSpace::decay"
246 "Kinematics: negative angular weight");
247 if (decWt > 1.) infoPtr->errorMsg(
"Warning in PhaseSpace::decay"
248 "Kinematics: angular weight above unity");
261 void PhaseSpace::decayKinematicsStep(
Event& process,
int iRes) {
264 int i1 = process[iRes].daughter1();
265 int mult = process[iRes].daughter2() + 1 - i1;
266 double m0 = process[iRes].m();
267 Vec4 pRes = process[iRes].p();
274 double m1t = process[i1].m();
275 double m2t = process[i2].m();
278 double e1 = 0.5 * (m0*m0 + m1t*m1t - m2t*m2t) / m0;
279 double e2 = 0.5 * (m0*m0 + m2t*m2t - m1t*m1t) / m0;
280 double p12 = 0.5 * sqrtpos( (m0 - m1t - m2t) * (m0 + m1t + m2t)
281 * (m0 + m1t - m2t) * (m0 - m1t + m2t) ) / m0;
284 double cosTheta = 2. * rndmPtr->flat() - 1.;
285 double sinTheta = sqrt(1. - cosTheta*cosTheta);
286 double phi12 = 2. * M_PI * rndmPtr->flat();
287 double pX = p12 * sinTheta * cos(phi12);
288 double pY = p12 * sinTheta * sin(phi12);
289 double pZ = p12 * cosTheta;
292 Vec4 p1( pX, pY, pZ, e1);
293 Vec4 p2( -pX, -pY, -pZ, e2);
309 double m1t = process[i1].m();
310 double m2t = process[i2].m();
311 double m3t = process[i3].m();
312 double mDiff = m0 - (m1t + m2t + m3t);
315 double m23Min = m2t + m3t;
316 double m23Max = m0 - m1t;
317 double p1Max = 0.5 * sqrtpos( (m0 - m1t - m23Min)
318 * (m0 + m1t + m23Min) * (m0 + m1t - m23Min)
319 * (m0 - m1t + m23Min) ) / m0;
320 double p23Max = 0.5 * sqrtpos( (m23Max - m2t - m3t)
321 * (m23Max + m2t + m3t) * (m23Max + m2t - m3t)
322 * (m23Max - m2t + m3t) ) / m23Max;
323 double wtPSmax = 0.5 * p1Max * p23Max;
326 double wtPS, m23, p1Abs, p23Abs;
328 m23 = m23Min + rndmPtr->flat() * mDiff;
331 p1Abs = 0.5 * sqrtpos( (m0 - m1t - m23) * (m0 + m1t + m23)
332 * (m0 + m1t - m23) * (m0 - m1t + m23) ) / m0;
333 p23Abs = 0.5 * sqrtpos( (m23 - m2t - m3t) * (m23 + m2t + m3t)
334 * (m23 + m2t - m3t) * (m23 - m2t + m3t) ) / m23;
335 wtPS = p1Abs * p23Abs;
338 }
while ( wtPS < rndmPtr->flat() * wtPSmax );
341 double cosTheta = 2. * rndmPtr->flat() - 1.;
342 double sinTheta = sqrt(1. - cosTheta*cosTheta);
343 double phi23 = 2. * M_PI * rndmPtr->flat();
344 double pX = p23Abs * sinTheta * cos(phi23);
345 double pY = p23Abs * sinTheta * sin(phi23);
346 double pZ = p23Abs * cosTheta;
347 double e2 = sqrt( m2t*m2t + p23Abs*p23Abs);
348 double e3 = sqrt( m3t*m3t + p23Abs*p23Abs);
349 Vec4 p2( pX, pY, pZ, e2);
350 Vec4 p3( -pX, -pY, -pZ, e3);
353 cosTheta = 2. * rndmPtr->flat() - 1.;
354 sinTheta = sqrt(1. - cosTheta*cosTheta);
355 phi23 = 2. * M_PI * rndmPtr->flat();
356 pX = p1Abs * sinTheta * cos(phi23);
357 pY = p1Abs * sinTheta * sin(phi23);
358 pZ = p1Abs * cosTheta;
359 double e1 = sqrt( m1t*m1t + p1Abs*p1Abs);
360 double e23 = sqrt( m23*m23 + p1Abs*p1Abs);
361 Vec4 p1( pX, pY, pZ, e1);
364 Vec4 p23( -pX, -pY, -pZ, e23);
381 vector<double> mProd;
382 mProd.push_back( m0);
383 for (
int i = i1; i <= process[iRes].daughter2(); ++i)
384 mProd.push_back( process[i].m() );
386 pProd.push_back( pRes);
389 double mSum = mProd[1];
390 for (
int i = 2; i <= mult; ++i) mSum += mProd[i];
391 double mDiff = m0 - mSum;
395 for (
int i = 0; i <= mult; ++i) mInv.push_back( mProd[i]);
398 double wtPSmax = 1. / WTCORRECTION[mult];
399 double mMaxWT = mDiff + mProd[mult];
401 for (
int i = mult - 1; i > 0; --i) {
403 mMinWT += mProd[i+1];
404 double mNow = mProd[i];
405 wtPSmax *= 0.5 * sqrtpos( (mMaxWT - mMinWT - mNow)
406 * (mMaxWT + mMinWT + mNow) * (mMaxWT + mMinWT - mNow)
407 * (mMaxWT - mMinWT + mNow) ) / mMaxWT;
411 vector<double> rndmOrd;
418 rndmOrd.push_back(1.);
419 for (
int i = 1; i < mult - 1; ++i) {
420 double rndm = rndmPtr->flat();
421 rndmOrd.push_back(rndm);
422 for (
int j = i - 1; j > 0; --j) {
423 if (rndm > rndmOrd[j]) swap( rndmOrd[j], rndmOrd[j+1] );
427 rndmOrd.push_back(0.);
430 for (
int i = mult - 1; i > 0; --i) {
431 mInv[i] = mInv[i+1] + mProd[i] + (rndmOrd[i-1] - rndmOrd[i]) * mDiff;
432 wtPS *= 0.5 * sqrtpos( (mInv[i] - mInv[i+1] - mProd[i])
433 * (mInv[i] + mInv[i+1] + mProd[i]) * (mInv[i] + mInv[i+1] - mProd[i])
434 * (mInv[i] - mInv[i+1] + mProd[i]) ) / mInv[i];
438 }
while ( wtPS < rndmPtr->flat() * wtPSmax );
442 pInv.resize(mult + 1);
443 for (
int i = 1; i < mult; ++i) {
444 double p12 = 0.5 * sqrtpos( (mInv[i] - mInv[i+1] - mProd[i])
445 * (mInv[i] + mInv[i+1] + mProd[i]) * (mInv[i] + mInv[i+1] - mProd[i])
446 * (mInv[i] - mInv[i+1] + mProd[i]) ) / mInv[i];
449 double cosTheta = 2. * rndmPtr->flat() - 1.;
450 double sinTheta = sqrt(1. - cosTheta*cosTheta);
451 double phiLoc = 2. * M_PI * rndmPtr->flat();
452 double pX = p12 * sinTheta * cos(phiLoc);
453 double pY = p12 * sinTheta * sin(phiLoc);
454 double pZ = p12 * cosTheta;
457 double eHad = sqrt( mProd[i]*mProd[i] + p12*p12);
458 double eInv = sqrt( mInv[i+1]*mInv[i+1] + p12*p12);
459 pProd.push_back( Vec4( pX, pY, pZ, eHad) );
460 pInv[i+1].p( -pX, -pY, -pZ, eInv);
462 pProd.push_back( pInv[mult] );
466 for (
int iFrame = mult - 1; iFrame > 0; --iFrame)
467 for (
int i = iFrame; i <= mult; ++i) pProd[i].bst(pInv[iFrame]);
470 for (
int i = 1; i < mult; ++i)
471 process[i1 + i - 1].p( pProd[i] );
480 void PhaseSpace::setup3Body() {
483 int idTchan1 = abs( sigmaProcessPtr->idTchan1() );
484 int idTchan2 = abs( sigmaProcessPtr->idTchan2() );
485 mTchan1 = (idTchan1 == 0) ? pTHatMinDiverge
486 : particleDataPtr->m0(idTchan1);
487 mTchan2 = (idTchan2 == 0) ? pTHatMinDiverge
488 : particleDataPtr->m0(idTchan2);
489 sTchan1 = mTchan1 * mTchan1;
490 sTchan2 = mTchan2 * mTchan2;
493 frac3Pow1 = sigmaProcessPtr->tChanFracPow1();
494 frac3Pow2 = sigmaProcessPtr->tChanFracPow2();
495 frac3Flat = 1. - frac3Pow1 - frac3Pow2;
496 useMirrorWeight = sigmaProcessPtr->useMirrorWeight();
504 bool PhaseSpace::setupSampling123(
bool is2,
bool is3, ostream& os) {
507 if (showSearch) os <<
"\n PYTHIA Optimization printout for "
508 << sigmaProcessPtr->name() <<
"\n \n" << scientific << setprecision(3);
511 if (!limitTau(is2, is3))
return false;
514 int binTau[8], binY[8], binZ[8];
515 double vecTau[8], matTau[8][8], vecY[8], matY[8][8], vecZ[8], matZ[8][8];
516 for (
int i = 0; i < 8; ++i) {
526 for (
int j = 0; j < 8; ++j) {
536 nTau = (hasPointLeptons) ? 1 : 2;
537 nY = (hasPointLeptons) ? 1 : 5;
541 idResA = sigmaProcessPtr->resonanceA();
543 mResA = particleDataPtr->m0(idResA);
544 GammaResA = particleDataPtr->mWidth(idResA);
545 if (mHatMin > mResA + WIDTHMARGIN * GammaResA || (mHatMax > 0.
546 && mHatMax < mResA - WIDTHMARGIN * GammaResA) ) idResA = 0;
548 idResB = sigmaProcessPtr->resonanceB();
550 mResB = particleDataPtr->m0(idResB);
551 GammaResB = particleDataPtr->mWidth(idResB);
552 if (mHatMin > mResB + WIDTHMARGIN * GammaResB || (mHatMax > 0.
553 && mHatMax < mResB - WIDTHMARGIN * GammaResB) ) idResB = 0;
555 if (idResA == 0 && idResB != 0) {
558 GammaResA = GammaResB;
563 if (idResA !=0 && !hasPointLeptons) {
565 tauResA = mResA * mResA / s;
566 widResA = mResA * GammaResA / s;
568 if (idResB != 0 && !hasPointLeptons) {
570 tauResB = mResB * mResB / s;
571 widResB = mResB * GammaResB / s;
575 if (hasLeptonBeams && !hasPointLeptons) ++nTau;
579 if (idResB != 0 && abs(mResA - mResB) < SAMEMASS * (GammaResA + GammaResB))
585 int nVar = (is2) ? 3 : 2;
594 for (
int iTau = 0; iTau < nTau; ++iTau) {
596 if (sameResMass && iTau > 1 && iTau < 6) posTau = (iTau < 4) ? 0.4 : 0.6;
597 selectTau( iTau, posTau, is2);
598 if (!limitY())
continue;
599 if (is2 && !limitZ())
continue;
602 for (
int iY = 0; iY < nY; ++iY) {
604 for (
int iZ = 0; iZ < nZ; ++iZ) {
605 if (is2) selectZ( iZ, 0.5);
606 double sigmaTmp = 0.;
610 sigmaProcessPtr->set1Kin( x1H, x2H, sH);
611 sigmaTmp = sigmaProcessPtr->sigmaPDF();
612 sigmaTmp *= wtTau * wtY;
617 sigmaProcessPtr->set2Kin( x1H, x2H, sH, tH, m3, m4,
619 sigmaTmp = sigmaProcessPtr->sigmaPDF();
620 sigmaTmp *= wtTau * wtY * wtZ * wtBW;
626 for (
int iTry3 = 0; iTry3 < NTRY3BODY; ++iTry3) {
627 if (!select3Body())
continue;
628 sigmaProcessPtr->set3Kin( x1H, x2H, sH, p3cm, p4cm, p5cm,
629 m3, m4, m5, runBW3H, runBW4H, runBW5H);
630 double sigmaTry = sigmaProcessPtr->sigmaPDF();
631 sigmaTry *= wtTau * wtY * wt3Body * wtBW;
632 if (sigmaTry > sigmaTmp) sigmaTmp = sigmaTry;
637 if (canModifySigma) sigmaTmp
638 *= userHooksPtr->multiplySigmaBy( sigmaProcessPtr,
this,
false);
639 if (canBiasSelection) sigmaTmp
640 *= userHooksPtr->biasSelectionBy( sigmaProcessPtr,
this,
false);
641 if (canBias2Sel) sigmaTmp *= pow( pTH / bias2SelRef, bias2SelPow);
644 if (sigmaTmp > sigmaMx) sigmaMx = sigmaTmp;
647 if (showSearch) os <<
" tau =" << setw(11) << tau <<
" y ="
648 << setw(11) << y <<
" z =" << setw(11) << z
649 <<
" sigma =" << setw(11) << sigmaTmp <<
"\n";
650 if (sigmaTmp < 0.) sigmaTmp = 0.;
653 if (!hasPointLeptons) {
655 vecTau[iTau] += sigmaTmp;
656 matTau[iTau][0] += 1. / intTau0;
657 matTau[iTau][1] += (1. / intTau1) / tau;
659 matTau[iTau][2] += (1. / intTau2) / (tau + tauResA);
660 matTau[iTau][3] += (1. / intTau3)
661 * tau / ( pow2(tau - tauResA) + pow2(widResA) );
664 matTau[iTau][4] += (1. / intTau4) / (tau + tauResB);
665 matTau[iTau][5] += (1. / intTau5)
666 * tau / ( pow2(tau - tauResB) + pow2(widResB) );
668 if (hasLeptonBeams) matTau[iTau][nTau - 1] += (1. / intTau6)
669 * tau / max( LEPTONTAUMIN, 1. - tau);
673 if (!hasPointLeptons) {
675 vecY[iY] += sigmaTmp;
676 matY[iY][0] += (yMax / intY0) / cosh(y);
677 matY[iY][1] += (yMax / intY12) * (y + yMax);
678 matY[iY][2] += (yMax / intY12) * (yMax - y);
679 if (!hasLeptonBeams) {
680 matY[iY][3] += (yMax / intY34) * exp(y);
681 matY[iY][4] += (yMax / intY34) * exp(-y);
683 matY[iY][3] += (yMax / intY56)
684 / max( LEPTONXMIN, 1. - exp( y - yMax) );
685 matY[iY][4] += (yMax / intY56)
686 / max( LEPTONXMIN, 1. - exp(-y - yMax) );
692 double p2AbsMax = 0.25 * (pow2(tauMax * s - s3 - s4)
693 - 4. * s3 * s4) / (tauMax * s);
694 double zMaxMax = sqrtpos( 1. - pT2HatMin / p2AbsMax );
695 double zPosMaxMax = max(ratio34, unity34 + zMaxMax);
696 double zNegMaxMax = max(ratio34, unity34 - zMaxMax);
697 double intZ0Max = 2. * zMaxMax;
698 double intZ12Max = log( zPosMaxMax / zNegMaxMax);
699 double intZ34Max = 1. / zNegMaxMax - 1. / zPosMaxMax;
703 vecZ[iZ] += sigmaTmp;
705 matZ[iZ][1] += (intZ0Max / intZ12Max) / zNeg;
706 matZ[iZ][2] += (intZ0Max / intZ12Max) / zPos;
707 matZ[iZ][3] += (intZ0Max / intZ34Max) / pow2(zNeg);
708 matZ[iZ][4] += (intZ0Max / intZ34Max) / pow2(zPos);
723 if (!hasPointLeptons) solveSys( nTau, binTau, vecTau, matTau, tauCoef);
724 if (!hasPointLeptons) solveSys( nY, binY, vecY, matY, yCoef);
725 if (is2) solveSys( nZ, binZ, vecZ, matZ, zCoef);
726 if (showSearch) os <<
"\n";
729 tauCoefSum[0] = tauCoef[0];
730 yCoefSum[0] = yCoef[0];
731 zCoefSum[0] = zCoef[0];
732 for (
int i = 1; i < 8; ++ i) {
733 tauCoefSum[i] = tauCoefSum[i - 1] + tauCoef[i];
734 yCoefSum[i] = yCoefSum[i - 1] + yCoef[i];
735 zCoefSum[i] = zCoefSum[i - 1] + zCoef[i];
738 tauCoefSum[nTau - 1] = 2.;
739 yCoefSum[nY - 1] = 2.;
740 zCoefSum[nZ - 1] = 2.;
744 int iMaxTau[NMAXTRY + 2], iMaxY[NMAXTRY + 2], iMaxZ[NMAXTRY + 2];
745 double sigMax[NMAXTRY + 2];
749 for (
int iTau = 0; iTau < nTau; ++iTau) {
751 if (sameResMass && iTau > 1 && iTau < 6) posTau = (iTau < 4) ? 0.4 : 0.6;
752 selectTau( iTau, posTau, is2);
753 if (!limitY())
continue;
754 if (is2 && !limitZ())
continue;
755 for (
int iY = 0; iY < nY; ++iY) {
757 for (
int iZ = 0; iZ < nZ; ++iZ) {
758 if (is2) selectZ( iZ, 0.5);
759 double sigmaTmp = 0.;
763 sigmaProcessPtr->set1Kin( x1H, x2H, sH);
764 sigmaTmp = sigmaProcessPtr->sigmaPDF();
765 sigmaTmp *= wtTau * wtY;
770 sigmaProcessPtr->set2Kin( x1H, x2H, sH, tH, m3, m4,
772 sigmaTmp = sigmaProcessPtr->sigmaPDF();
773 sigmaTmp *= wtTau * wtY * wtZ * wtBW;
779 for (
int iTry3 = 0; iTry3 < NTRY3BODY; ++iTry3) {
780 if (!select3Body())
continue;
781 sigmaProcessPtr->set3Kin( x1H, x2H, sH, p3cm, p4cm, p5cm,
782 m3, m4, m5, runBW3H, runBW4H, runBW5H);
783 double sigmaTry = sigmaProcessPtr->sigmaPDF();
784 sigmaTry *= wtTau * wtY * wt3Body * wtBW;
785 if (sigmaTry > sigmaTmp) sigmaTmp = sigmaTry;
790 if (canModifySigma) sigmaTmp
791 *= userHooksPtr->multiplySigmaBy( sigmaProcessPtr,
this,
false);
792 if (canBiasSelection) sigmaTmp
793 *= userHooksPtr->biasSelectionBy( sigmaProcessPtr,
this,
false);
794 if (canBias2Sel) sigmaTmp *= pow( pTH / bias2SelRef, bias2SelPow);
797 if (showSearch) os <<
" tau =" << setw(11) << tau <<
" y ="
798 << setw(11) << y <<
" z =" << setw(11) << z
799 <<
" sigma =" << setw(11) << sigmaTmp <<
"\n";
800 if (sigmaTmp < 0.) sigmaTmp = 0.;
803 bool mirrorPoint =
false;
804 for (
int iMove = 0; iMove < nMax; ++iMove)
805 if (abs(sigmaTmp - sigMax[iMove]) < SAMESIGMA
806 * (sigmaTmp + sigMax[iMove])) mirrorPoint =
true;
811 for (
int iMove = nMax - 1; iMove >= -1; --iMove) {
813 if (iInsert == 0 || sigmaTmp < sigMax[iMove])
break;
814 iMaxTau[iMove + 1] = iMaxTau[iMove];
815 iMaxY[iMove + 1] = iMaxY[iMove];
816 iMaxZ[iMove + 1] = iMaxZ[iMove];
817 sigMax[iMove + 1] = sigMax[iMove];
819 iMaxTau[iInsert] = iTau;
822 sigMax[iInsert] = sigmaTmp;
823 if (nMax < NMAXTRY) ++nMax;
830 if (showSearch) os <<
"\n";
834 int beginVar = (hasPointLeptons) ? 2 : 0;
835 for (
int iMax = 0; iMax < nMax; ++iMax) {
836 int iTau = iMaxTau[iMax];
837 int iY = iMaxY[iMax];
838 int iZ = iMaxZ[iMax];
843 double varVal, varNew, deltaVar, marginVar, sigGrid[3];
846 for (
int iRepeat = 0; iRepeat < 2; ++iRepeat) {
848 for (
int iVar = beginVar; iVar < nVar; ++iVar) {
849 if (iVar == 0) varVal = tauVal;
850 else if (iVar == 1) varVal = yVal;
852 deltaVar = (iRepeat == 0) ? 0.1
853 : max( 0.01, min( 0.05, min( varVal - 0.02, 0.98 - varVal) ) );
854 marginVar = (iRepeat == 0) ? 0.02 : 0.002;
855 int moveStart = (iRepeat == 0 && iVar == 0) ? 0 : 1;
856 for (
int move = moveStart; move < 9; ++move) {
862 }
else if (move == 1) {
864 varNew = varVal + deltaVar;
865 }
else if (move == 2) {
867 varNew = varVal - deltaVar;
868 }
else if (sigGrid[2] >= max( sigGrid[0], sigGrid[1])
869 && varVal + 2. * deltaVar < 1. - marginVar) {
871 sigGrid[0] = sigGrid[1];
872 sigGrid[1] = sigGrid[2];
874 varNew = varVal + deltaVar;
875 }
else if (sigGrid[0] >= max( sigGrid[1], sigGrid[2])
876 && varVal - 2. * deltaVar > marginVar) {
878 sigGrid[2] = sigGrid[1];
879 sigGrid[1] = sigGrid[0];
881 varNew = varVal - deltaVar;
882 }
else if (sigGrid[2] >= sigGrid[0]) {
885 sigGrid[0] = sigGrid[1];
891 sigGrid[2] = sigGrid[1];
897 bool insideLimits =
true;
900 selectTau( iTau, tauVal, is2);
901 if (!limitY()) insideLimits =
false;
902 if (is2 && !limitZ()) insideLimits =
false;
905 if (is2) selectZ( iZ, zVal);
907 }
else if (iVar == 1) {
910 }
else if (iVar == 2) {
916 double sigmaTmp = 0.;
921 sigmaProcessPtr->set1Kin( x1H, x2H, sH);
922 sigmaTmp = sigmaProcessPtr->sigmaPDF();
923 sigmaTmp *= wtTau * wtY;
928 sigmaProcessPtr->set2Kin( x1H, x2H, sH, tH, m3, m4,
930 sigmaTmp = sigmaProcessPtr->sigmaPDF();
931 sigmaTmp *= wtTau * wtY * wtZ * wtBW;
937 for (
int iTry3 = 0; iTry3 < NTRY3BODY; ++iTry3) {
938 if (!select3Body())
continue;
939 sigmaProcessPtr->set3Kin( x1H, x2H, sH, p3cm, p4cm, p5cm,
940 m3, m4, m5, runBW3H, runBW4H, runBW5H);
941 double sigmaTry = sigmaProcessPtr->sigmaPDF();
942 sigmaTry *= wtTau * wtY * wt3Body * wtBW;
943 if (sigmaTry > sigmaTmp) sigmaTmp = sigmaTry;
948 if (canModifySigma) sigmaTmp
949 *= userHooksPtr->multiplySigmaBy( sigmaProcessPtr,
this,
false);
950 if (canBiasSelection) sigmaTmp
951 *= userHooksPtr->biasSelectionBy( sigmaProcessPtr,
this,
false);
952 if (canBias2Sel) sigmaTmp *= pow( pTH / bias2SelRef, bias2SelPow);
955 if (showSearch) os <<
" tau =" << setw(11) << tau <<
" y ="
956 << setw(11) << y <<
" z =" << setw(11) << z
957 <<
" sigma =" << setw(11) << sigmaTmp <<
"\n";
958 if (sigmaTmp < 0.) sigmaTmp = 0.;
962 sigGrid[iGrid] = sigmaTmp;
963 if (sigmaTmp > sigmaMx) sigmaMx = sigmaTmp;
968 sigmaMx *= SAFETYMARGIN;
972 if (showSearch) os <<
"\n Final maximum = " << setw(11) << sigmaMx << endl;
984 bool PhaseSpace::trialKin123(
bool is2,
bool is3,
bool inEvent, ostream& os) {
987 if (doEnergySpread) {
988 eCM = infoPtr->eCM();
992 if (idResA !=0 && !hasPointLeptons) {
993 tauResA = mResA * mResA / s;
994 widResA = mResA * GammaResA / s;
996 if (idResB != 0 && !hasPointLeptons) {
997 tauResB = mResB * mResB / s;
998 widResB = mResB * GammaResB / s;
1009 if (!limitTau(is2, is3))
return false;
1011 if (!hasPointLeptons) {
1012 double rTau = rndmPtr->flat();
1013 while (rTau > tauCoefSum[iTau]) ++iTau;
1015 selectTau( iTau, rndmPtr->flat(), is2);
1022 if (!limitY())
return false;
1024 if (!hasPointLeptons) {
1025 double rY = rndmPtr->flat();
1026 while (rY > yCoefSum[iY]) ++iY;
1028 selectY( iY, rndmPtr->flat());
1035 if (!limitZ())
return false;
1037 double rZ = rndmPtr->flat();
1038 while (rZ > zCoefSum[iZ]) ++iZ;
1039 selectZ( iZ, rndmPtr->flat());
1044 sigmaProcessPtr->set1Kin( x1H, x2H, sH);
1045 sigmaNw = sigmaProcessPtr->sigmaPDF();
1046 sigmaNw *= wtTau * wtY;
1051 sigmaProcessPtr->set2Kin( x1H, x2H, sH, tH, m3, m4, runBW3H, runBW4H);
1052 sigmaNw = sigmaProcessPtr->sigmaPDF();
1053 sigmaNw *= wtTau * wtY * wtZ * wtBW;
1058 if (!select3Body()) sigmaNw = 0.;
1060 sigmaProcessPtr->set3Kin( x1H, x2H, sH, p3cm, p4cm, p5cm,
1061 m3, m4, m5, runBW3H, runBW4H, runBW5H);
1062 sigmaNw = sigmaProcessPtr->sigmaPDF();
1063 sigmaNw *= wtTau * wtY * wt3Body * wtBW;
1068 if (canModifySigma) sigmaNw
1069 *= userHooksPtr->multiplySigmaBy( sigmaProcessPtr,
this, inEvent);
1070 if (canBiasSelection) sigmaNw
1071 *= userHooksPtr->biasSelectionBy( sigmaProcessPtr,
this, inEvent);
1072 if (canBias2Sel) sigmaNw *= pow( pTH / bias2SelRef, bias2SelPow);
1076 if (sigmaNw > sigmaMx) {
1077 infoPtr->errorMsg(
"Warning in PhaseSpace2to2tauyz::trialKin: "
1078 "maximum for cross section violated");
1081 if (increaseMaximum || !inEvent) {
1082 double violFact = SAFETYMARGIN * sigmaNw / sigmaMx;
1083 sigmaMx = SAFETYMARGIN * sigmaNw;
1085 if (showViolation) {
1086 if (violFact < 9.99) os << fixed;
1087 else os << scientific;
1088 os <<
" PYTHIA Maximum for " << sigmaProcessPtr->name()
1089 <<
" increased by factor " << setprecision(3) << violFact
1090 <<
" to " << scientific << sigmaMx << endl;
1094 }
else if (showViolation && sigmaNw > sigmaPos) {
1095 double violFact = sigmaNw / sigmaMx;
1096 if (violFact < 9.99) os << fixed;
1097 else os << scientific;
1098 os <<
" PYTHIA Maximum for " << sigmaProcessPtr->name()
1099 <<
" exceeded by factor " << setprecision(3) << violFact << endl;
1105 if (sigmaNw < sigmaNeg) {
1106 infoPtr->errorMsg(
"Warning in PhaseSpace2to2tauyz::trialKin:"
1107 " negative cross section set 0",
"for " + sigmaProcessPtr->name() );
1111 if (showViolation) os <<
" PYTHIA Negative minimum for "
1112 << sigmaProcessPtr->name() <<
" changed to " << scientific
1113 << setprecision(3) << sigmaNeg << endl;
1115 if (sigmaNw < 0.) sigmaNw = 0.;
1118 biasWt = (canBiasSelection) ? userHooksPtr->biasedSelectionWeight() : 1.;
1119 if (canBias2Sel) biasWt /= pow( pTH / bias2SelRef, bias2SelPow);
1129 bool PhaseSpace::limitTau(
bool is2,
bool is3) {
1132 if (hasPointLeptons) {
1139 tauMin = sHatMin / s;
1140 tauMax = (mHatMax < mHatMin) ? 1. : min( 1., sHatMax / s);
1144 double mT3Min = sqrt(s3 + pT2HatMin);
1145 double mT4Min = sqrt(s4 + pT2HatMin);
1146 double mT5Min = (is3) ? sqrt(s5 + pT2HatMin) : 0.;
1147 tauMin = max( tauMin, pow2(mT3Min + mT4Min + mT5Min) / s);
1151 return (tauMax > tauMin);
1158 bool PhaseSpace::limitY() {
1161 if (hasPointLeptons) {
1167 yMax = -0.5 * log(tau);
1170 double yMaxMargin = (hasLeptonBeams) ? yMax + LEPTONXLOGMAX : yMax;
1173 return (yMaxMargin > 0.);
1180 bool PhaseSpace::limitZ() {
1187 zMax = sqrtpos( 1. - pT2HatMin / p2Abs );
1188 if (pTHatMax > pTHatMin) zMin = sqrtpos( 1. - pT2HatMax / p2Abs );
1191 return (zMax > zMin);
1198 void PhaseSpace::selectTau(
int iTau,
double tauVal,
bool is2) {
1201 if (hasPointLeptons) {
1207 p2Abs = 0.25 * (pow2(sH - s3 - s4) - 4. * s3 * s4) / sH;
1208 pAbs = sqrtpos( p2Abs );
1218 tRatA = ((tauResA + tauMax) / (tauResA + tauMin)) * (tauMin / tauMax);
1219 aLowA = atan( (tauMin - tauResA) / widResA);
1220 aUppA = atan( (tauMax - tauResA) / widResA);
1226 tRatB = ((tauResB + tauMax) / (tauResB + tauMin)) * (tauMin / tauMax);
1227 aLowB = atan( (tauMin - tauResB) / widResB);
1228 aUppB = atan( (tauMax - tauResB) / widResB);
1234 if (hasLeptonBeams) {
1235 aLowT = log( max( LEPTONTAUMIN, 1. - tauMin) );
1236 aUppT = log( max( LEPTONTAUMIN, 1. - tauMax) );
1237 intTau6 = aLowT - aUppT;
1241 if (iTau == 0) tau = tauMin * pow( tauMax / tauMin, tauVal);
1242 else if (iTau == 1) tau = tauMax * tauMin
1243 / (tauMin + (tauMax - tauMin) * tauVal);
1246 else if (hasLeptonBeams && iTau == nTau - 1)
1247 tau = 1. - exp( aUppT + intTau6 * tauVal );
1251 else if (iTau == 2) tau = tauResA * tauMin
1252 / ((tauResA + tauMin) * pow( tRatA, tauVal) - tauMin);
1253 else if (iTau == 3) tau = tauResA + widResA
1254 * tan( aLowA + (aUppA - aLowA) * tauVal);
1255 else if (iTau == 4) tau = tauResB * tauMin
1256 / ((tauResB + tauMin) * pow( tRatB, tauVal) - tauMin);
1257 else if (iTau == 5) tau = tauResB + widResB
1258 * tan( aLowB + (aUppB - aLowB) * tauVal);
1261 intTau0 = log( tauMax / tauMin);
1262 intTau1 = (tauMax - tauMin) / (tauMax * tauMin);
1263 double invWtTau = (tauCoef[0] / intTau0) + (tauCoef[1] / intTau1) / tau;
1265 intTau2 = -log(tRatA) / tauResA;
1266 intTau3 = (aUppA - aLowA) / widResA;
1267 invWtTau += (tauCoef[2] / intTau2) / (tau + tauResA)
1268 + (tauCoef[3] / intTau3) * tau / ( pow2(tau - tauResA) + pow2(widResA) );
1271 intTau4 = -log(tRatB) / tauResB;
1272 intTau5 = (aUppB - aLowB) / widResB;
1273 invWtTau += (tauCoef[4] / intTau4) / (tau + tauResB)
1274 + (tauCoef[5] / intTau5) * tau / ( pow2(tau - tauResB) + pow2(widResB) );
1277 invWtTau += (tauCoef[nTau - 1] / intTau6)
1278 * tau / max( LEPTONTAUMIN, 1. - tau);
1279 wtTau = 1. / invWtTau;
1285 p2Abs = 0.25 * (pow2(sH - s3 - s4) - 4. * s3 * s4) / sH;
1286 pAbs = sqrtpos( p2Abs );
1295 void PhaseSpace::selectY(
int iY,
double yVal) {
1298 if (hasPointLeptons) {
1307 if (hasLeptonBeams && iY > 2) iY += 2;
1310 double expYMax = exp( yMax );
1311 double expYMin = exp(-yMax );
1312 double atanMax = atan( expYMax );
1313 double atanMin = atan( expYMin );
1314 double aUppY = (hasLeptonBeams)
1315 ? log( max( LEPTONXMIN, LEPTONXMAX / tau - 1. ) ) : 0.;
1316 double aLowY = LEPTONXLOGMIN;
1319 if (iY == 0) y = log( tan( atanMin + (atanMax - atanMin) * yVal ) );
1322 else if (iY <= 2) y = yMax * (2. * sqrt(yVal) - 1.);
1325 else if (iY <= 4) y = log( expYMin + (expYMax - expYMin) * yVal );
1328 else y = yMax - log( 1. + exp(aLowY + (aUppY - aLowY) * yVal) );
1331 if (iY == 2 || iY == 4 || iY == 6) y = -y;
1334 intY0 = 2. * (atanMax - atanMin);
1335 intY12 = 0.5 * pow2(2. * yMax);
1336 intY34 = expYMax - expYMin;
1337 intY56 = aUppY - aLowY;
1338 double invWtY = (yCoef[0] / intY0) / cosh(y)
1339 + (yCoef[1] / intY12) * (y + yMax) + (yCoef[2] / intY12) * (yMax - y);
1340 if (!hasLeptonBeams) invWtY
1341 += (yCoef[3] / intY34) * exp(y) + (yCoef[4] / intY34) * exp(-y);
1343 += (yCoef[3] / intY56) / max( LEPTONXMIN, 1. - exp( y - yMax) )
1344 + (yCoef[4] / intY56) / max( LEPTONXMIN, 1. - exp(-y - yMax) );
1348 x1H = sqrt(tau) * exp(y);
1349 x2H = sqrt(tau) * exp(-y);
1358 void PhaseSpace::selectZ(
int iZ,
double zVal) {
1361 ratio34 = max(TINY, 2. * s3 * s4 / pow2(sH));
1362 unity34 = 1. + ratio34;
1363 double ratiopT2 = 2. * pT2HatMin / max( SHATMINZ, sH);
1364 if (ratiopT2 < PT2RATMINZ) ratio34 = max( ratio34, ratiopT2);
1367 double zPosMax = max(ratio34, unity34 + zMax);
1368 double zNegMax = max(ratio34, unity34 - zMax);
1369 double zPosMin = max(ratio34, unity34 + zMin);
1370 double zNegMin = max(ratio34, unity34 - zMin);
1374 if (zVal < 0.5) z = -(zMax + (zMin - zMax) * 2. * zVal);
1375 else z = zMin + (zMax - zMin) * (2. * zVal - 1.);
1378 }
else if (iZ == 1) {
1379 double areaNeg = log(zPosMax / zPosMin);
1380 double areaPos = log(zNegMin / zNegMax);
1381 double area = areaNeg + areaPos;
1382 if (zVal * area < areaNeg) {
1383 double zValMod = zVal * area / areaNeg;
1384 z = unity34 - zPosMax * pow(zPosMin / zPosMax, zValMod);
1386 double zValMod = (zVal * area - areaNeg)/ areaPos;
1387 z = unity34 - zNegMin * pow(zNegMax / zNegMin, zValMod);
1391 }
else if (iZ == 2) {
1392 double areaNeg = log(zNegMin / zNegMax);
1393 double areaPos = log(zPosMax / zPosMin);
1394 double area = areaNeg + areaPos;
1395 if (zVal * area < areaNeg) {
1396 double zValMod = zVal * area / areaNeg;
1397 z = zNegMax * pow(zNegMin / zNegMax, zValMod) - unity34;
1399 double zValMod = (zVal * area - areaNeg)/ areaPos;
1400 z = zPosMin * pow(zPosMax / zPosMin, zValMod) - unity34;
1404 }
else if (iZ == 3) {
1405 double areaNeg = 1. / zPosMin - 1. / zPosMax;
1406 double areaPos = 1. / zNegMax - 1. / zNegMin;
1407 double area = areaNeg + areaPos;
1408 if (zVal * area < areaNeg) {
1409 double zValMod = zVal * area / areaNeg;
1410 z = unity34 - 1. / (1./zPosMax + areaNeg * zValMod);
1412 double zValMod = (zVal * area - areaNeg)/ areaPos;
1413 z = unity34 - 1. / (1./zNegMin + areaPos * zValMod);
1417 }
else if (iZ == 4) {
1418 double areaNeg = 1. / zNegMax - 1. / zNegMin;
1419 double areaPos = 1. / zPosMin - 1. / zPosMax;
1420 double area = areaNeg + areaPos;
1421 if (zVal * area < areaNeg) {
1422 double zValMod = zVal * area / areaNeg;
1423 z = 1. / (1./zNegMax - areaNeg * zValMod) - unity34;
1425 double zValMod = (zVal * area - areaNeg)/ areaPos;
1426 z = 1. / (1./zPosMin - areaPos * zValMod) - unity34;
1431 if (z < 0.) z = min(-zMin, max(-zMax, z));
1432 else z = min(zMax, max(zMin, z));
1433 zNeg = max(ratio34, unity34 - z);
1434 zPos = max(ratio34, unity34 + z);
1437 double intZ0 = 2. * (zMax - zMin);
1438 double intZ12 = log( (zPosMax * zNegMin) / (zPosMin * zNegMax) );
1439 double intZ34 = 1. / zPosMin - 1. / zPosMax + 1. / zNegMax
1441 wtZ = mHat * pAbs / ( (zCoef[0] / intZ0) + (zCoef[1] / intZ12) / zNeg
1442 + (zCoef[2] / intZ12) / zPos + (zCoef[3] / intZ34) / pow2(zNeg)
1443 + (zCoef[4] / intZ34) / pow2(zPos) );
1446 double sH34 = -0.5 * (sH - s3 - s4);
1447 tH = sH34 + mHat * pAbs * z;
1448 uH = sH34 - mHat * pAbs * z;
1449 pTH = sqrtpos( (tH * uH - s3 * s4) / sH);
1458 bool PhaseSpace::select3Body() {
1461 double m35S = pow2(m3 + m5);
1462 double pT4Smax = 0.25 * ( pow2(sH - s4 - m35S) - 4. * s4 * m35S ) / sH;
1463 if (pTHatMax > pTHatMin) pT4Smax = min( pT2HatMax, pT4Smax);
1464 double pT4Smin = pT2HatMin;
1465 double m34S = pow2(m3 + m4);
1466 double pT5Smax = 0.25 * ( pow2(sH - s5 - m34S) - 4. * s5 * m34S ) / sH;
1467 if (pTHatMax > pTHatMin) pT5Smax = min( pT2HatMax, pT5Smax);
1468 double pT5Smin = pT2HatMin;
1471 if ( pT4Smax < pow2(pTHatMin + MASSMARGIN) )
return false;
1472 if ( pT5Smax < pow2(pTHatMin + MASSMARGIN) )
return false;
1475 double pTSmaxProp = pT4Smax + sTchan1;
1476 double pTSminProp = pT4Smin + sTchan1;
1477 double pTSratProp = pTSmaxProp / pTSminProp;
1478 double pTSdiff = pT4Smax - pT4Smin;
1479 double rShape = rndmPtr->flat();
1481 if (rShape < frac3Flat) pT4S = pT4Smin + rndmPtr->flat() * pTSdiff;
1482 else if (rShape < frac3Flat + frac3Pow1) pT4S = max( pT2HatMin,
1483 pTSminProp * pow( pTSratProp, rndmPtr->flat() ) - sTchan1 );
1484 else pT4S = max( pT2HatMin, pTSminProp * pTSmaxProp
1485 / (pTSminProp + rndmPtr->flat()* pTSdiff) - sTchan1 );
1486 double wt4 = pTSdiff / ( frac3Flat
1487 + frac3Pow1 * pTSdiff / (log(pTSratProp) * (pT4S + sTchan1))
1488 + frac3Pow2 * pTSminProp * pTSmaxProp / pow2(pT4S + sTchan1) );
1491 pTSmaxProp = pT5Smax + sTchan2;
1492 pTSminProp = pT5Smin + sTchan2;
1493 pTSratProp = pTSmaxProp / pTSminProp;
1494 pTSdiff = pT5Smax - pT5Smin;
1495 rShape = rndmPtr->flat();
1497 if (rShape < frac3Flat) pT5S = pT5Smin + rndmPtr->flat() * pTSdiff;
1498 else if (rShape < frac3Flat + frac3Pow1) pT5S = max( pT2HatMin,
1499 pTSminProp * pow( pTSratProp, rndmPtr->flat() ) - sTchan2 );
1500 else pT5S = max( pT2HatMin, pTSminProp * pTSmaxProp
1501 / (pTSminProp + rndmPtr->flat()* pTSdiff) - sTchan2 );
1502 double wt5 = pTSdiff / ( frac3Flat
1503 + frac3Pow1 * pTSdiff / (log(pTSratProp) * (pT5S + sTchan2))
1504 + frac3Pow2 * pTSminProp * pTSmaxProp / pow2(pT5S + sTchan2) );
1507 double phi4 = 2. * M_PI * rndmPtr->flat();
1508 double phi5 = 2. * M_PI * rndmPtr->flat();
1509 double pT3S = max( 0., pT4S + pT5S + 2. * sqrt(pT4S * pT5S)
1510 * cos(phi4 - phi5) );
1511 if ( pT3S < pT2HatMin || (pTHatMax > pTHatMin && pT3S > pT2HatMax) )
1515 double sT3 = s3 + pT3S;
1516 double sT4 = s4 + pT4S;
1517 double sT5 = s5 + pT5S;
1518 double mT3 = sqrt(sT3);
1519 double mT4 = sqrt(sT4);
1520 double mT5 = sqrt(sT5);
1521 if ( mT3 + mT4 + mT5 + MASSMARGIN > mHat )
return false;
1524 double m45S = pow2(mT4 + mT5);
1525 double y3max = log( ( sH + sT3 - m45S + sqrtpos( pow2(sH - sT3 - m45S)
1526 - 4 * sT3 * m45S ) ) / (2. * mHat * mT3) );
1527 if (y3max < YRANGEMARGIN)
return false;
1528 double y3 = (2. * rndmPtr->flat() - 1.) * (1. - YRANGEMARGIN) * y3max;
1529 double pz3 = mT3 * sinh(y3);
1530 double e3 = mT3 * cosh(y3);
1534 double e45 = mHat - e3;
1535 double sT45 = e45 * e45 - pz45 * pz45;
1536 double lam45 = sqrtpos( pow2(sT45 - sT4 - sT5) - 4. * sT4 * sT5 );
1537 if (lam45 < YRANGEMARGIN * sH)
return false;
1538 double lam4e = sT45 + sT4 - sT5;
1539 double lam5e = sT45 + sT5 - sT4;
1540 double tFac = -0.5 * mHat / sT45;
1541 double t1Pos = tFac * (e45 - pz45) * (lam4e - lam45);
1542 double t1Neg = tFac * (e45 - pz45) * (lam4e + lam45);
1543 double t2Pos = tFac * (e45 + pz45) * (lam5e - lam45);
1544 double t2Neg = tFac * (e45 + pz45) * (lam5e + lam45);
1547 double wtPosUnnorm = 1.;
1548 double wtNegUnnorm = 1.;
1549 if (useMirrorWeight) {
1550 wtPosUnnorm = 1./ pow2( (t1Pos - sTchan1) * (t2Pos - sTchan2) );
1551 wtNegUnnorm = 1./ pow2( (t1Neg - sTchan1) * (t2Neg - sTchan2) );
1553 double wtPos = wtPosUnnorm / (wtPosUnnorm + wtNegUnnorm);
1554 double wtNeg = wtNegUnnorm / (wtPosUnnorm + wtNegUnnorm);
1555 double epsilon = (rndmPtr->flat() < wtPos) ? 1. : -1.;
1558 double px4 = sqrt(pT4S) * cos(phi4);
1559 double py4 = sqrt(pT4S) * sin(phi4);
1560 double px5 = sqrt(pT5S) * cos(phi5);
1561 double py5 = sqrt(pT5S) * sin(phi5);
1562 double pz4 = 0.5 * (pz45 * lam4e + epsilon * e45 * lam45) / sT45;
1563 double pz5 = pz45 - pz4;
1564 double e4 = sqrt(sT4 + pz4 * pz4);
1565 double e5 = sqrt(sT5 + pz5 * pz5);
1566 p3cm = Vec4( -(px4 + px5), -(py4 + py5), pz3, e3);
1567 p4cm = Vec4( px4, py4, pz4, e4);
1568 p5cm = Vec4( px5, py5, pz5, e5);
1571 wt3Body = wt4 * wt5 * (2. * y3max) / (128. * pow3(M_PI) * lam45);
1572 wt3Body *= (epsilon > 0.) ? 1. / wtPos : 1. / wtNeg;
1575 wt3Body /= (2. * sH);
1586 void PhaseSpace::solveSys(
int n,
int bin[8],
double vec[8],
1587 double mat[8][8],
double coef[8], ostream& os) {
1591 os <<
"\n Equation system: " << setw(5) << bin[0];
1592 for (
int j = 0; j < n; ++j) os << setw(12) << mat[0][j];
1593 os << setw(12) << vec[0] <<
"\n";
1594 for (
int i = 1; i < n; ++i) {
1595 os <<
" " << setw(5) << bin[i];
1596 for (
int j = 0; j < n; ++j) os << setw(12) << mat[i][j];
1597 os << setw(12) << vec[i] <<
"\n";
1602 double vecNor[8], coefTmp[8];
1603 for (
int i = 0; i < n; ++i) coefTmp[i] = 0.;
1606 bool canSolve =
true;
1607 for (
int i = 0; i < n; ++i)
if (bin[i] == 0) canSolve =
false;
1609 for (
int i = 0; i < n; ++i) vecSum += vec[i];
1610 if (abs(vecSum) < TINY) canSolve =
false;
1614 for (
int i = 0; i < n; ++i) vecNor[i] = max( 0.1, vec[i] / vecSum);
1615 for (
int k = 0; k < n - 1; ++k) {
1616 for (
int i = k + 1; i < n; ++i) {
1617 if (abs(mat[k][k]) < TINY) {canSolve =
false;
break;}
1618 double ratio = mat[i][k] / mat[k][k];
1619 vec[i] -= ratio * vec[k];
1620 for (
int j = k; j < n; ++j) mat[i][j] -= ratio * mat[k][j];
1622 if (!canSolve)
break;
1625 for (
int k = n - 1; k >= 0; --k) {
1626 for (
int j = k + 1; j < n; ++j) vec[k] -= mat[k][j] * coefTmp[j];
1627 coefTmp[k] = vec[k] / mat[k][k];
1633 if (!canSolve)
for (
int i = 0; i < n; ++i) {
1636 if (vecSum > TINY) vecNor[i] = max(0.1, vec[i] / vecSum);
1640 double coefSum = 0.;
1642 for (
int i = 0; i < n; ++i) {
1643 coefTmp[i] = max( 0., coefTmp[i]);
1644 coefSum += coefTmp[i];
1645 vecSum += vecNor[i];
1647 if (coefSum > 0.)
for (
int i = 0; i < n; ++i) coef[i] = EVENFRAC / n
1648 + (1. - EVENFRAC) * 0.5 * (coefTmp[i] / coefSum + vecNor[i] / vecSum);
1649 else for (
int i = 0; i < n; ++i) coef[i] = 1. / n;
1653 os <<
" Solution: ";
1654 for (
int i = 0; i < n; ++i) os << setw(12) << coef[i];
1663 void PhaseSpace::setupMass1(
int iM) {
1666 if (iM == 3) idMass[iM] = abs(sigmaProcessPtr->id3Mass());
1667 if (iM == 4) idMass[iM] = abs(sigmaProcessPtr->id4Mass());
1668 if (iM == 5) idMass[iM] = abs(sigmaProcessPtr->id5Mass());
1671 if (idMass[iM] == 0) {
1677 mPeak[iM] = particleDataPtr->m0(idMass[iM]);
1678 mWidth[iM] = particleDataPtr->mWidth(idMass[iM]);
1679 mMin[iM] = particleDataPtr->mMin(idMass[iM]);
1680 mMax[iM] = particleDataPtr->mMax(idMass[iM]);
1682 if (idMass[iM] == 23 && gmZmode == 1) mPeak[iM] = mMin[iM];
1686 sPeak[iM] = mPeak[iM] * mPeak[iM];
1687 useBW[iM] = useBreitWigners && (mWidth[iM] > minWidthBreitWigners);
1688 if (!useBW[iM]) mWidth[iM] = 0.;
1689 mw[iM] = mPeak[iM] * mWidth[iM];
1690 wmRat[iM] = (idMass[iM] == 0 || mPeak[iM] == 0.)
1691 ? 0. : mWidth[iM] / mPeak[iM];
1695 mLower[iM] = mMin[iM];
1696 mUpper[iM] = mHatMax;
1705 void PhaseSpace::setupMass2(
int iM,
double distToThresh) {
1708 if (mMax[iM] > mMin[iM]) mUpper[iM] = min( mUpper[iM], mMax[iM]);
1709 sLower[iM] = mLower[iM] * mLower[iM];
1710 sUpper[iM] = mUpper[iM] * mUpper[iM];
1714 if (distToThresh > THRESHOLDSIZE) {
1717 }
else if (distToThresh > - THRESHOLDSIZE) {
1718 fracFlat[iM] = 0.25 - 0.15 * distToThresh / THRESHOLDSIZE;
1719 fracInv [iM] = 0.15 - 0.05 * distToThresh / THRESHOLDSIZE;
1727 if (idMass[iM] == 23 && gmZmode == 0) {
1728 fracFlat[iM] *= 0.5;
1729 fracInv[iM] = 0.5 * fracInv[iM] + 0.25;
1730 fracInv2[iM] = 0.25;
1731 }
else if (idMass[iM] == 23 && gmZmode == 1) {
1738 atanLower[iM] = atan( (sLower[iM] - sPeak[iM])/ mw[iM] );
1739 atanUpper[iM] = atan( (sUpper[iM] - sPeak[iM])/ mw[iM] );
1740 intBW[iM] = atanUpper[iM] - atanLower[iM];
1741 intFlat[iM] = sUpper[iM] - sLower[iM];
1742 intInv[iM] = log( sUpper[iM] / sLower[iM] );
1743 intInv2[iM] = 1./sLower[iM] - 1./sUpper[iM];
1751 void PhaseSpace::trialMass(
int iM) {
1754 double& mSet = (iM == 3) ? m3 : ( (iM == 4) ? m4 : m5 );
1755 double& sSet = (iM == 3) ? s3 : ( (iM == 4) ? s4 : s5 );
1759 double pickForm = rndmPtr->flat();
1760 if (pickForm > fracFlat[iM] + fracInv[iM] + fracInv2[iM])
1761 sSet = sPeak[iM] + mw[iM] * tan( atanLower[iM]
1762 + rndmPtr->flat() * intBW[iM] );
1763 else if (pickForm > fracInv[iM] + fracInv2[iM])
1764 sSet = sLower[iM] + rndmPtr->flat() * (sUpper[iM] - sLower[iM]);
1765 else if (pickForm > fracInv2[iM])
1766 sSet = sLower[iM] * pow( sUpper[iM] / sLower[iM], rndmPtr->flat() );
1767 else sSet = sLower[iM] * sUpper[iM]
1768 / (sLower[iM] + rndmPtr->flat() * (sUpper[iM] - sLower[iM]));
1788 double PhaseSpace::weightMass(
int iM) {
1791 double& sSet = (iM == 3) ? s3 : ( (iM == 4) ? s4 : s5 );
1792 double& runBWH = (iM == 3) ? runBW3H : ( (iM == 4) ? runBW4H : runBW5H );
1796 if (!useBW[iM])
return 1.;
1799 double genBW = (1. - fracFlat[iM] - fracInv[iM] - fracInv2[iM])
1800 * mw[iM] / ( (pow2(sSet - sPeak[iM]) + pow2(mw[iM])) * intBW[iM])
1801 + fracFlat[iM] / intFlat[iM] + fracInv[iM] / (sSet * intInv[iM])
1802 + fracInv2[iM] / (sSet*sSet * intInv2[iM]);
1805 double mwRun = sSet * wmRat[iM];
1806 runBWH = mwRun / (pow2(sSet - sPeak[iM]) + pow2(mwRun)) / M_PI;
1809 return (runBWH / genBW);
1822 bool PhaseSpace2to1tauy::setupMass() {
1825 gmZmode = gmZmodeGlobal;
1826 int gmZmodeProc = sigmaProcessPtr->gmZmode();
1827 if (gmZmodeProc >= 0) gmZmode = gmZmodeProc;
1830 int idRes = abs(sigmaProcessPtr->resonanceA());
1831 int idTmp = abs(sigmaProcessPtr->resonanceB());
1832 if (idTmp > 0) idRes = idTmp;
1833 double mResMin = (idRes == 0) ? 0. : particleDataPtr->mMin(idRes);
1834 double mResMax = (idRes == 0) ? 0. : particleDataPtr->mMax(idRes);
1837 mHatMin = max( mResMin, mHatGlobalMin);
1838 sHatMin = mHatMin*mHatMin;
1840 if (mResMax > mResMin) mHatMax = min( mHatMax, mResMax);
1841 if (mHatGlobalMax > mHatGlobalMin) mHatMax = min( mHatMax, mHatGlobalMax);
1842 sHatMax = mHatMax*mHatMax;
1848 return (mHatMax > mHatMin + MASSMARGIN);
1856 bool PhaseSpace2to1tauy::finalKin() {
1864 pH[1] = Vec4( 0., 0., 0.5 * eCM * x1H, 0.5 * eCM * x1H);
1865 pH[2] = Vec4( 0., 0., -0.5 * eCM * x2H, 0.5 * eCM * x2H);
1866 pH[3] = pH[1] + pH[2];
1881 bool PhaseSpace2to2tauyz::setupMasses() {
1884 gmZmode = gmZmodeGlobal;
1885 int gmZmodeProc = sigmaProcessPtr->gmZmode();
1886 if (gmZmodeProc >= 0) gmZmode = gmZmodeProc;
1889 mHatMin = mHatGlobalMin;
1890 sHatMin = mHatMin*mHatMin;
1892 if (mHatGlobalMax > mHatGlobalMin) mHatMax = min( eCM, mHatGlobalMax);
1893 sHatMax = mHatMax*mHatMax;
1900 if (useBW[3]) mUpper[3] -= (useBW[4]) ? mMin[4] : mPeak[4];
1901 if (useBW[4]) mUpper[4] -= (useBW[3]) ? mMin[3] : mPeak[3];
1904 bool physical =
true;
1905 if (useBW[3] && mUpper[3] < mLower[3] + MASSMARGIN) physical =
false;
1906 if (useBW[4] && mUpper[4] < mLower[4] + MASSMARGIN) physical =
false;
1907 if (!useBW[3] && !useBW[4] && mHatMax < mPeak[3] + mPeak[4] + MASSMARGIN)
1909 if (!physical)
return false;
1912 pTHatMin = pTHatGlobalMin;
1913 if (mPeak[3] < pTHatMinDiverge || mPeak[4] < pTHatMinDiverge)
1914 pTHatMin = max( pTHatMin, pTHatMinDiverge);
1915 pT2HatMin = pTHatMin * pTHatMin;
1916 pTHatMax = pTHatGlobalMax;
1917 pT2HatMax = pTHatMax * pTHatMax;
1921 double distToThreshA = (mHatMax - mPeak[3] - mPeak[4]) * mWidth[3]
1922 / (pow2(mWidth[3]) + pow2(mWidth[4]));
1923 double distToThreshB = (mHatMax - mPeak[3] - mMin[4]) / mWidth[3];
1924 double distToThresh = min( distToThreshA, distToThreshB);
1925 setupMass2(3, distToThresh);
1930 double distToThreshA = (mHatMax - mPeak[3] - mPeak[4]) * mWidth[4]
1931 / (pow2(mWidth[3]) + pow2(mWidth[4]));
1932 double distToThreshB = (mHatMax - mMin[3] - mPeak[4]) / mWidth[4];
1933 double distToThresh = min( distToThreshA, distToThreshB);
1934 setupMass2(4, distToThresh);
1938 m3 = (useBW[3]) ? min(mPeak[3], mUpper[3]) : mPeak[3];
1939 m4 = (useBW[4]) ? min(mPeak[4], mUpper[4]) : mPeak[4];
1940 if (m3 + m4 + THRESHOLDSIZE * (mWidth[3] + mWidth[4]) + MASSMARGIN
1942 if (useBW[3] && useBW[4]) physical = constrainedM3M4();
1943 else if (useBW[3]) physical = constrainedM3();
1944 else if (useBW[4]) physical = constrainedM4();
1952 if (useBW[3]) wtBW *= weightMass(3) * EXTRABWWTMAX;
1953 if (useBW[4]) wtBW *= weightMass(4) * EXTRABWWTMAX;
1965 bool PhaseSpace2to2tauyz::trialMasses() {
1976 if (m3 + m4 + MASSMARGIN > mHatMax)
return false;
1979 if (useBW[3]) wtBW *= weightMass(3);
1980 if (useBW[4]) wtBW *= weightMass(4);
1990 bool PhaseSpace2to2tauyz::finalKin() {
1993 int id3 = sigmaProcessPtr->id(3);
1994 int id4 = sigmaProcessPtr->id(4);
1995 if (idMass[3] == 0) { m3 = particleDataPtr->m0(id3); s3 = m3*m3; }
1996 if (idMass[4] == 0) { m4 = particleDataPtr->m0(id4); s4 = m4*m4; }
1999 if (sigmaProcessPtr->swappedTU()) {
2005 if (m3 + m4 + MASSMARGIN > mHat) {
2006 infoPtr->errorMsg(
"Warning in PhaseSpace2to2tauyz::finalKin: "
2007 "failed after mass assignment");
2010 p2Abs = 0.25 * (pow2(sH - s3 - s4) - 4. * s3 * s4) / sH;
2011 pAbs = sqrtpos( p2Abs );
2020 pH[1] = Vec4( 0., 0., 0.5 * eCM * x1H, 0.5 * eCM * x1H);
2021 pH[2] = Vec4( 0., 0., -0.5 * eCM * x2H, 0.5 * eCM * x2H);
2024 pH[3] = Vec4( 0., 0., pAbs, 0.5 * (sH + s3 - s4) / mHat);
2025 pH[4] = Vec4( 0., 0., -pAbs, 0.5 * (sH + s4 - s3) / mHat);
2029 phi = 2. * M_PI * rndmPtr->flat();
2030 betaZ = (x1H - x2H)/(x1H + x2H);
2031 pH[3].rot( theta, phi);
2032 pH[4].rot( theta, phi);
2033 pH[3].bst( 0., 0., betaZ);
2034 pH[4].bst( 0., 0., betaZ);
2035 pTH = pAbs * sin(theta);
2048 bool PhaseSpace2to2tauyz::constrainedM3M4() {
2051 bool foundNonZero =
false;
2052 double wtMassMax = 0.;
2053 double m3WtMax = 0.;
2054 double m4WtMax = 0.;
2055 double xMax = (mHatMax - mLower[3] - mLower[4]) / (mWidth[3] + mWidth[4]);
2056 double xStep = THRESHOLDSTEP * min(1., xMax);
2058 double wtMassXbin, wtMassMaxOld, m34, mT34Min, wtMassNow,
2059 wtBW3Now, wtBW4Now, beta34Now;
2065 wtMassMaxOld = wtMassMax;
2066 m34 = mHatMax - xNow * (mWidth[3] + mWidth[4]);
2069 m3 = min( mUpper[3], m34 - mLower[4]);
2070 if (m3 > mPeak[3]) m3 = max( mLower[3], mPeak[3]);
2072 if (m4 < mLower[4]) {m4 = mLower[4]; m3 = m34 - m4;}
2075 mT34Min = sqrt(m3*m3 + pT2HatMin) + sqrt(m4*m4 + pT2HatMin);
2076 if (mT34Min < mHatMax) {
2080 if (m3 > mLower[3] && m3 < mUpper[3] && m4 > mLower[4]
2081 && m4 < mUpper[4]) {
2082 wtBW3Now = mw[3] / ( pow2(m3*m3 - sPeak[3]) + pow2(mw[3]) );
2083 wtBW4Now = mw[4] / ( pow2(m4*m4 - sPeak[4]) + pow2(mw[4]) );
2084 beta34Now = sqrt( pow2(mHatMax*mHatMax - m3*m3 - m4*m4)
2085 - pow2(2. * m3 * m4) ) / (mHatMax*mHatMax);
2086 wtMassNow = wtBW3Now * wtBW4Now * beta34Now;
2090 if (wtMassNow > wtMassXbin) wtMassXbin = wtMassNow;
2091 if (wtMassNow > wtMassMax) {
2092 foundNonZero =
true;
2093 wtMassMax = wtMassNow;
2100 m4 = min( mUpper[4], m34 - mLower[3]);
2101 if (m4 > mPeak[4]) m4 = max( mLower[4], mPeak[4]);
2103 if (m3 < mLower[3]) {m3 = mLower[3]; m4 = m34 - m3;}
2106 mT34Min = sqrt(m3*m3 + pT2HatMin) + sqrt(m4*m4 + pT2HatMin);
2107 if (mT34Min < mHatMax) {
2111 if (m3 > mLower[3] && m3 < mUpper[3] && m4 > mLower[4]
2112 && m4 < mUpper[4]) {
2113 wtBW3Now = mw[3] / ( pow2(m3*m3 - sPeak[3]) + pow2(mw[3]) );
2114 wtBW4Now = mw[4] / ( pow2(m4*m4 - sPeak[4]) + pow2(mw[4]) );
2115 beta34Now = sqrt( pow2(mHatMax*mHatMax - m3*m3 - m4*m4)
2116 - pow2(2. * m3 * m4) ) / (mHatMax*mHatMax);
2117 wtMassNow = wtBW3Now * wtBW4Now * beta34Now;
2121 if (wtMassNow > wtMassXbin) wtMassXbin = wtMassNow;
2122 if (wtMassNow > wtMassMax) {
2123 foundNonZero =
true;
2124 wtMassMax = wtMassNow;
2131 }
while ( (!foundNonZero || wtMassXbin > wtMassMaxOld)
2132 && xNow < xMax - xStep);
2137 return foundNonZero;
2147 bool PhaseSpace2to2tauyz::constrainedM3() {
2150 bool foundNonZero =
false;
2151 double wtMassMax = 0.;
2152 double m3WtMax = 0.;
2153 double mT4Min = sqrt(m4*m4 + pT2HatMin);
2154 double xMax = (mHatMax - mLower[3] - m4) / mWidth[3];
2155 double xStep = THRESHOLDSTEP * min(1., xMax);
2157 double wtMassNow, mT34Min, wtBW3Now, beta34Now;
2163 m3 = mHatMax - m4 - xNow * mWidth[3];
2166 mT34Min = sqrt(m3*m3 + pT2HatMin) + mT4Min;
2167 if (mT34Min < mHatMax) {
2170 wtBW3Now = mw[3] / ( pow2(m3*m3 - sPeak[3]) + pow2(mw[3]) );
2171 beta34Now = sqrt( pow2(mHatMax*mHatMax - m3*m3 - m4*m4)
2172 - pow2(2. * m3 * m4) ) / (mHatMax*mHatMax);
2173 wtMassNow = wtBW3Now * beta34Now;
2176 if (wtMassNow > wtMassMax) {
2177 foundNonZero =
true;
2178 wtMassMax = wtMassNow;
2184 }
while ( (!foundNonZero || wtMassNow > wtMassMax)
2185 && xNow < xMax - xStep);
2189 return foundNonZero;
2199 bool PhaseSpace2to2tauyz::constrainedM4() {
2202 bool foundNonZero =
false;
2203 double wtMassMax = 0.;
2204 double m4WtMax = 0.;
2205 double mT3Min = sqrt(m3*m3 + pT2HatMin);
2206 double xMax = (mHatMax - mLower[4] - m3) / mWidth[4];
2207 double xStep = THRESHOLDSTEP * min(1., xMax);
2209 double wtMassNow, mT34Min, wtBW4Now, beta34Now;
2215 m4 = mHatMax - m3 - xNow * mWidth[4];
2218 mT34Min = mT3Min + sqrt(m4*m4 + pT2HatMin);
2219 if (mT34Min < mHatMax) {
2222 wtBW4Now = mw[4] / ( pow2(m4*m4 - sPeak[4]) + pow2(mw[4]) );
2223 beta34Now = sqrt( pow2(mHatMax*mHatMax - m3*m3 - m4*m4)
2224 - pow2(2. * m3 * m4) ) / (mHatMax*mHatMax);
2225 wtMassNow = wtBW4Now * beta34Now;
2228 if (wtMassNow > wtMassMax) {
2229 foundNonZero =
true;
2230 wtMassMax = wtMassNow;
2236 }
while ( (!foundNonZero || wtMassNow > wtMassMax)
2237 && xNow < xMax - xStep);
2241 return foundNonZero;
2256 const double PhaseSpace2to2elastic::EXPMAX = 50.;
2259 const double PhaseSpace2to2elastic::CONVERTEL = 0.0510925;
2266 bool PhaseSpace2to2elastic::setupSampling() {
2269 sigmaNw = sigmaProcessPtr->sigmaHatWrap();
2279 bSlope = sigmaTotPtr->bSlopeEl();
2282 lambda12S = pow2(s - s1 - s2) - 4. * s1 * s2 ;
2283 tLow = - lambda12S / s;
2287 useCoulomb = settingsPtr->flag(
"SigmaTotal:setOwn")
2288 && settingsPtr->flag(
"SigmaElastic:setOwn");
2290 sigmaTot = sigmaTotPtr->sigmaTot();
2291 rho = settingsPtr->parm(
"SigmaElastic:rho");
2292 lambda = settingsPtr->parm(
"SigmaElastic:lambda");
2293 tAbsMin = settingsPtr->parm(
"SigmaElastic:tAbsMin");
2294 phaseCst = settingsPtr->parm(
"SigmaElastic:phaseConst");
2295 alphaEM0 = settingsPtr->parm(
"StandardModel:alphaEM0");
2299 sigmaNuc = CONVERTEL * pow2(sigmaTot) * (1. + rho*rho) / bSlope
2300 * exp(-bSlope * tAbsMin);
2301 sigmaCou = (useCoulomb) ?
2302 pow2(alphaEM0) / (4. * CONVERTEL * tAbsMin) : 0.;
2303 signCou = (idA == idB) ? 1. : -1.;
2312 tAux = exp( max(-EXPMAX, bSlope * (tLow - tUpp)) ) - 1.;
2323 bool PhaseSpace2to2elastic::trialKin(
bool,
bool ) {
2326 if (doEnergySpread) {
2327 eCM = infoPtr->eCM();
2329 lambda12S = pow2(s - s1 - s2) - 4. * s1 * s2 ;
2330 tLow = - lambda12S / s;
2331 tAux = exp( max(-EXPMAX, bSlope * (tLow - tUpp)) ) - 1.;
2335 if (!useCoulomb || sigmaNuc > rndmPtr->flat() * (sigmaNuc + sigmaCou))
2336 tH = tUpp + log(1. + tAux * rndmPtr->flat()) / bSlope;
2339 else tH = tLow * tUpp / (tUpp + rndmPtr->flat() * (tLow - tUpp));
2343 double sigmaN = CONVERTEL * pow2(sigmaTot) * (1. + rho*rho)
2345 double alpEM = couplingsPtr->alphaEM(-tH);
2346 double sigmaC = pow2(alpEM) / (4. * CONVERTEL * tH*tH);
2347 double sigmaGen = 2. * (sigmaN + sigmaC);
2348 double form2 = pow4(lambda/(lambda - tH));
2349 double phase = signCou * alpEM
2350 * (-phaseCst - log(-0.5 * bSlope * tH));
2351 double sigmaCor = sigmaN + pow2(form2) * sigmaC
2352 - signCou * alpEM * sigmaTot * (form2 / (-tH))
2353 * exp(0.5 * bSlope * tH) * (rho * cos(phase) + sin(phase));
2354 sigmaNw = sigmaMx * sigmaCor / sigmaGen;
2358 double tRat = s * tH / lambda12S;
2359 double cosTheta = min(1., max(-1., 1. + 2. * tRat ) );
2360 double sinTheta = 2. * sqrtpos( -tRat * (1. + tRat) );
2361 theta = asin( min(1., sinTheta));
2362 if (cosTheta < 0.) theta = M_PI - theta;
2372 bool PhaseSpace2to2elastic::finalKin() {
2381 pAbs = 0.5 * sqrtpos(lambda12S) / eCM;
2382 pH[1] = Vec4( 0., 0., pAbs, 0.5 * (s + s1 - s2) / eCM);
2383 pH[2] = Vec4( 0., 0., -pAbs, 0.5 * (s + s2 - s1) / eCM);
2386 pH[3] = Vec4( 0., 0., pAbs, 0.5 * (s + s1 - s2) / eCM);
2387 pH[4] = Vec4( 0., 0., -pAbs, 0.5 * (s + s2 - s1) / eCM);
2390 phi = 2. * M_PI * rndmPtr->flat();
2391 pH[3].rot( theta, phi);
2392 pH[4].rot( theta, phi);
2398 uH = 2. * (s1 + s2) - sH - tH;
2400 p2Abs = pAbs * pAbs;
2402 pTH = pAbs * sin(theta);
2420 const int PhaseSpace2to2diffractive::NTRY = 500;
2423 const double PhaseSpace2to2diffractive::EXPMAX = 50.;
2426 const double PhaseSpace2to2diffractive::DIFFMASSMARGIN = 0.2;
2433 bool PhaseSpace2to2diffractive::setupSampling() {
2436 PomFlux = settingsPtr->mode(
"Diffraction:PomFlux");
2437 epsilonPF = settingsPtr->parm(
"Diffraction:PomFluxEpsilon");
2438 alphaPrimePF = settingsPtr->parm(
"Diffraction:PomFluxAlphaPrime");
2441 sigmaNw = sigmaProcessPtr->sigmaHatWrap();
2445 m3ElDiff = (isDiffA) ? sigmaTotPtr->mMinXB() : mA;
2446 m4ElDiff = (isDiffB) ? sigmaTotPtr->mMinAX() : mB;
2449 s3 = pow2( m3ElDiff);
2450 s4 = pow2( m4ElDiff);
2453 lambda12 = sqrtpos( pow2( s - s1 - s2) - 4. * s1 * s2 );
2454 lambda34 = sqrtpos( pow2( s - s3 - s4) - 4. * s3 * s4 );
2455 double tempA = s - (s1 + s2 + s3 + s4) + (s1 - s2) * (s3 - s4) / s;
2456 double tempB = lambda12 * lambda34 / s;
2457 double tempC = (s3 - s1) * (s4 - s2) + (s1 + s4 - s2 - s3)
2458 * (s1 * s4 - s2 * s3) / s;
2459 tLow = -0.5 * (tempA + tempB);
2460 tUpp = tempC / tLow;
2463 cRes = sResXB = sResAX = sProton = bMin = bSlope = bSlope1 = bSlope2
2464 = probSlope1 = xIntPF = xtCorPF = mp24DL = coefDL = tAux
2465 = tAux1 = tAux2 = 0.;
2469 cRes = sigmaTotPtr->cRes();
2470 sResXB = pow2( sigmaTotPtr->mResXB());
2471 sResAX = pow2( sigmaTotPtr->mResAX());
2472 sProton = sigmaTotPtr->sProton();
2475 if (!isDiffB) bMin = sigmaTotPtr->bMinSlopeXB();
2476 else if (!isDiffA) bMin = sigmaTotPtr->bMinSlopeAX();
2477 else bMin = sigmaTotPtr->bMinSlopeXX();
2478 tAux = exp( max(-EXPMAX, bMin * (tLow - tUpp)) ) - 1.;
2481 }
else if (PomFlux == 2) {
2483 probSlope1 = 6.38 * ( exp(max(-EXPMAX, bSlope1 * tUpp))
2484 - exp(max(-EXPMAX, bSlope1 * tLow)) ) / bSlope1;
2486 double pS2 = 0.424 * ( exp(max(-EXPMAX, bSlope2 * tUpp))
2487 - exp(max(-EXPMAX, bSlope2 * tLow)) ) / bSlope2;
2488 probSlope1 /= probSlope1 + pS2;
2489 tAux1 = exp( max(-EXPMAX, bSlope1 * (tLow - tUpp)) ) - 1.;
2490 tAux2 = exp( max(-EXPMAX, bSlope2 * (tLow - tUpp)) ) - 1.;
2493 }
else if (PomFlux == 3) {
2495 double xPowPF = 1. - 2. * (1. + epsilonPF);
2496 xIntPF = 2. * (1. + xPowPF);
2497 xtCorPF = 2. * alphaPrimePF;
2498 tAux = exp( max(-EXPMAX, bSlope * (tLow - tUpp)) ) - 1.;
2501 }
else if (PomFlux == 4) {
2502 mp24DL = 4. * pow2(particleDataPtr->m0(2212));
2503 double xPowPF = 1. - 2. * (1. + epsilonPF);
2504 xIntPF = 2. * (1. + xPowPF);
2505 xtCorPF = 2. * alphaPrimePF;
2508 tAux1 = 1. / pow3(1. - coefDL * tLow);
2509 tAux2 = 1. / pow3(1. - coefDL * tUpp);
2512 }
else if (PomFlux == 5) {
2513 eps = settingsPtr->parm(
"Diffraction:MBRepsilon");
2514 alph = settingsPtr->parm(
"Diffraction:MBRalpha");
2515 alph2 = alph * alph;
2516 m2min = settingsPtr->parm(
"Diffraction:MBRm2Min");
2517 dyminSD = settingsPtr->parm(
"Diffraction:MBRdyminSD");
2518 dyminDD = settingsPtr->parm(
"Diffraction:MBRdyminDD");
2519 dyminSigSD = settingsPtr->parm(
"Diffraction:MBRdyminSigSD");
2520 dyminSigDD = settingsPtr->parm(
"Diffraction:MBRdyminSigDD");
2523 sdpmax= sigmaTotPtr->sdpMax();
2524 ddpmax= sigmaTotPtr->ddpMax();
2537 bool PhaseSpace2to2diffractive::trialKin(
bool,
bool ) {
2540 if (doEnergySpread) {
2541 eCM = infoPtr->eCM();
2543 lambda12 = sqrtpos( pow2( s - s1 - s2) - 4. * s1 * s2 );
2544 lambda34 = sqrtpos( pow2( s - s3 - s4) - 4. * s3 * s4 );
2545 double tempA = s - (s1 + s2 + s3 + s4) + (s1 - s2) * (s3 - s4) / s;
2546 double tempB = lambda12 * lambda34 / s;
2547 double tempC = (s3 - s1) * (s4 - s2) + (s1 + s4 - s2 - s3)
2548 * (s1 * s4 - s2 * s3) / s;
2549 tLow = -0.5 * (tempA + tempB);
2550 tUpp = tempC / tLow;
2552 tAux = exp( max(-EXPMAX, bMin * (tLow - tUpp)) ) - 1.;
2553 }
else if (PomFlux == 2) {
2554 tAux1 = exp( max(-EXPMAX, bSlope1 * (tLow - tUpp)) ) - 1.;
2555 tAux2 = exp( max(-EXPMAX, bSlope2 * (tLow - tUpp)) ) - 1.;
2556 }
else if (PomFlux == 3) {
2557 tAux = exp( max(-EXPMAX, bSlope * (tLow - tUpp)) ) - 1.;
2558 }
else if (PomFlux == 4) {
2559 tAux1 = 1. / pow3(1. - coefDL * tLow);
2560 tAux2 = 1. / pow3(1. - coefDL * tUpp);
2565 for (
int loop = 0; ; ++loop) {
2567 infoPtr->errorMsg(
"Error in PhaseSpace2to2diffractive::trialKin: "
2568 " quit after repeated tries");
2576 m3 = (isDiffA) ? m3ElDiff * pow( max(mA, eCM - m4ElDiff) / m3ElDiff,
2577 rndmPtr->flat()) : m3ElDiff;
2578 m4 = (isDiffB) ? m4ElDiff * pow( max(mB, eCM - m3ElDiff) / m4ElDiff,
2579 rndmPtr->flat()) : m4ElDiff;
2580 if (m3 + m4 + DIFFMASSMARGIN >= eCM)
continue;
2585 if (isDiffA && !isDiffB) {
2586 double facXB = (1. - s3 / s)
2587 * (1. + cRes * sResXB / (sResXB + s3));
2588 if (facXB < rndmPtr->flat() * (1. + cRes))
continue;
2589 }
else if (isDiffB && !isDiffA) {
2590 double facAX = (1. - s4 / s)
2591 * (1. + cRes * sResAX / (sResAX + s4));
2592 if (facAX < rndmPtr->flat() * (1. + cRes))
continue;
2594 double facXX = (1. - pow2(m3 + m4) / s)
2595 * (s * sProton / (s * sProton + s3 * s4))
2596 * (1. + cRes * sResXB / (sResXB + s3))
2597 * (1. + cRes * sResAX / (sResAX + s4));
2598 if (facXX < rndmPtr->flat() * pow2(1. + cRes))
continue;
2602 tH = tUpp + log(1. + tAux * rndmPtr->flat()) / bMin;
2604 if (isDiffA && !isDiffB) bDiff = sigmaTotPtr->bSlopeXB(s3) - bMin;
2605 else if (!isDiffA) bDiff = sigmaTotPtr->bSlopeAX(s4) - bMin;
2606 else bDiff = sigmaTotPtr->bSlopeXX(s3, s4) - bMin;
2607 bDiff = max(0., bDiff);
2608 if (exp( max(-EXPMAX, bDiff * (tH - tUpp)) ) < rndmPtr->flat())
continue;
2611 }
else if (PomFlux == 2) {
2614 m3 = (isDiffA) ? m3ElDiff * pow( max(mA, eCM - m4ElDiff) / m3ElDiff,
2615 rndmPtr->flat()) : m3ElDiff;
2616 m4 = (isDiffB) ? m4ElDiff * pow( max(mB, eCM - m3ElDiff) / m4ElDiff,
2617 rndmPtr->flat()) : m4ElDiff;
2618 if (m3 + m4 + DIFFMASSMARGIN >= eCM)
continue;
2623 tH = (rndmPtr->flat() < probSlope1)
2624 ? tUpp + log(1. + tAux1 * rndmPtr->flat()) / bSlope1
2625 : tUpp + log(1. + tAux2 * rndmPtr->flat()) / bSlope2;
2628 }
else if (PomFlux == 3) {
2634 double s3MinPow = pow( m3ElDiff, xIntPF );
2635 double s3MaxPow = pow( max(mA, eCM - m4ElDiff), xIntPF );
2636 m3 = pow( s3MinPow + rndmPtr->flat() * (s3MaxPow - s3MinPow),
2640 double s4MinPow = pow( m4ElDiff, xIntPF );
2641 double s4MaxPow = pow( max(mB, eCM - m3ElDiff), xIntPF );
2642 m4 = pow( s4MinPow + rndmPtr->flat() * (s4MaxPow - s4MinPow),
2645 if (m3 + m4 + DIFFMASSMARGIN >= eCM)
continue;
2650 tH = tUpp + log(1. + tAux * rndmPtr->flat()) / bSlope;
2651 if ( isDiffA && pow( s3 / s, xtCorPF * abs(tH) ) < rndmPtr->flat() )
2653 if ( isDiffB && pow( s4 / s, xtCorPF * abs(tH) ) < rndmPtr->flat() )
2657 }
else if (PomFlux == 4) {
2663 double s3MinPow = pow( m3ElDiff, xIntPF );
2664 double s3MaxPow = pow( max(mA, eCM - m4ElDiff), xIntPF );
2665 m3 = pow( s3MinPow + rndmPtr->flat() * (s3MaxPow - s3MinPow),
2669 double s4MinPow = pow( m4ElDiff, xIntPF );
2670 double s4MaxPow = pow( max(mB, eCM - m3ElDiff), xIntPF );
2671 m4 = pow( s4MinPow + rndmPtr->flat() * (s4MaxPow - s4MinPow),
2674 if (m3 + m4 + DIFFMASSMARGIN >= eCM)
continue;
2679 tH = - (1. / pow( tAux1 + rndmPtr->flat() * (tAux2 - tAux1), 1./3.)
2681 double wDL = pow2( (mp24DL - 2.8 * tH) / (mp24DL - tH) )
2682 / pow4( 1. - tH / 0.7);
2683 double wMX = 1. / pow4( 1. - coefDL * tH);
2684 if (wDL < rndmPtr->flat() * wMX)
continue;
2685 if ( isDiffA && pow( s3 / s, xtCorPF * abs(tH) ) < rndmPtr->flat() )
2687 if ( isDiffB && pow( s4 / s, xtCorPF * abs(tH) ) < rndmPtr->flat() )
2691 }
else if (PomFlux == 5) {
2694 double xi, P, yRnd, dy;
2697 if (isDiffA && isDiffB) {
2699 dymax = log(s/pow2(m2min));
2703 dy = dymin0 + (dymax - dymin0) * rndmPtr->flat();
2704 P = (dymax - dy) * exp(eps*dy) * ( exp(-2. * alph * dy * exp(-dy))
2705 - exp(-2. * alph * dy * exp(dy)) ) / dy;
2707 P *= 0.5 * (1 + erf( ( dy - dyminDD) / dyminSigDD ) );
2709 ostringstream osWarn;
2710 osWarn <<
"ddpmax = " << scientific << setprecision(3)
2711 << ddpmax <<
" " << P <<
" " << dy << endl;
2712 infoPtr->errorMsg(
"Warning in PhaseSpace2to2diffractive::"
2713 "trialKin for double diffraction:", osWarn.str());
2715 yRnd = ddpmax * rndmPtr->flat();
2718 double y0max = (dymax - dy)/2.;
2719 double y0min = -y0max;
2720 double y0 = y0min + (y0max - y0min) * rndmPtr->flat();
2721 am1 = sqrt( eCM * exp( -y0 - dy/2. ) );
2722 am2 = sqrt( eCM * exp( y0 - dy/2. ) );
2725 double b = 2. * alph * dy;
2728 tAux = exp( b * (tLow - tUpp) ) - 1.;
2729 t = tUpp + log(1. + tAux * rndmPtr->flat()) / b;
2735 }
else if (isDiffA || isDiffB) {
2737 dymax = log(s/m2min);
2741 dy = dymin0 + (dymax - dymin0) * rndmPtr->flat();
2742 P = exp(eps * dy) * ( (FFA1 / (FFB1 + 2. * alph * dy) )
2743 + (FFA2 / (FFB2 + 2. * alph * dy) ) );
2745 P *= 0.5 * (1. + erf( (dy - dyminSD) / dyminSigSD) );
2747 ostringstream osWarn;
2748 osWarn <<
"sdpmax = " << scientific << setprecision(3)
2749 << sdpmax <<
" " << P <<
" " << dy << endl;
2750 infoPtr->errorMsg(
"Warning in PhaseSpace2to2diffractive::"
2751 "trialKin for single diffraction:", osWarn.str());
2753 yRnd = sdpmax * rndmPtr->flat();
2756 amx = sqrt( xi * s );
2759 double tmin = -s1 * xi * xi / (1 - xi);
2761 t = tmin + log(1. - rndmPtr->flat());
2762 double pFF = (4. * s1 - 2.8 * t) / ( (4. * s1 - t)
2763 * pow2(1. - t / 0.71) );
2764 P = pow2(pFF) * exp(2. * alph * dy * t);
2765 yRnd = exp(t) * rndmPtr->flat();
2767 if(isDiffA) m3 = amx;
2768 if(isDiffB) m4 = amx;
2778 lambda34 = sqrtpos( pow2( s - s3 - s4) - 4. * s3 * s4 );
2779 double tempA = s - (s1 + s2 + s3 + s4) + (s1 - s2) * (s3 - s4) / s;
2780 double tempB = lambda12 * lambda34 / s;
2781 double tempC = (s3 - s1) * (s4 - s2) + (s1 + s4 - s2 - s3)
2782 * (s1 * s4 - s2 * s3) / s;
2783 double tLowNow = -0.5 * (tempA + tempB);
2784 double tUppNow = tempC / tLowNow;
2785 if (tH < tLowNow || tH > tUppNow)
continue;
2788 double cosTheta = min(1., max(-1., (tempA + 2. * tH) / tempB));
2789 double sinTheta = 2. * sqrtpos( -(tempC + tempA * tH + tH * tH) )
2791 theta = asin( min(1., sinTheta));
2792 if (cosTheta < 0.) theta = M_PI - theta;
2805 bool PhaseSpace2to2diffractive::finalKin() {
2814 pAbs = 0.5 * lambda12 / eCM;
2815 pH[1] = Vec4( 0., 0., pAbs, 0.5 * (s + s1 - s2) / eCM);
2816 pH[2] = Vec4( 0., 0., -pAbs, 0.5 * (s + s2 - s1) / eCM);
2819 pAbs = 0.5 * lambda34 / eCM;
2820 pH[3] = Vec4( 0., 0., pAbs, 0.5 * (s + s3 - s4) / eCM);
2821 pH[4] = Vec4( 0., 0., -pAbs, 0.5 * (s + s4 - s3) / eCM);
2824 phi = 2. * M_PI * rndmPtr->flat();
2825 pH[3].rot( theta, phi);
2826 pH[4].rot( theta, phi);
2832 uH = s1 + s2 + s3 + s4 - sH - tH;
2834 p2Abs = pAbs * pAbs;
2836 pTH = pAbs * sin(theta);
2854 const int PhaseSpace2to3diffractive::NTRY = 500;
2855 const int PhaseSpace2to3diffractive::NINTEG2 = 40;
2858 const double PhaseSpace2to3diffractive::EXPMAX = 50.;
2861 const double PhaseSpace2to3diffractive::DIFFMASSMIN = 0.8;
2864 const double PhaseSpace2to3diffractive::DIFFMASSMARGIN = 0.2;
2870 bool PhaseSpace2to3diffractive::setupSampling() {
2873 PomFlux = settingsPtr->mode(
"Diffraction:PomFlux");
2874 epsilonPF = settingsPtr->parm(
"Diffraction:PomFluxEpsilon");
2875 alphaPrimePF = settingsPtr->parm(
"Diffraction:PomFluxAlphaPrime");
2878 sigmaNw = sigmaProcessPtr->sigmaHatWrap();
2884 m5min = sigmaTotPtr->mMinAXB();
2885 s5min = m5min * m5min;
2888 for (
int i = 0; i < 2; ++i) {
2889 s3 = (i == 0) ? s1 : pow2(mA + m5min);
2890 s4 = (i == 0) ? pow2(mB + m5min) : s2;
2893 double lambda12 = sqrtpos( pow2( s - s1 - s2) - 4. * s1 * s2 );
2894 double lambda34 = sqrtpos( pow2( s - s3 - s4) - 4. * s3 * s4 );
2895 double tempA = s - (s1 + s2 + s3 + s4) + (s1 - s2) * (s3 - s4) / s;
2896 double tempB = lambda12 * lambda34 / s;
2897 double tempC = (s3 - s1) * (s4 - s2) + (s1 + s4 - s2 - s3)
2898 * (s1 * s4 - s2 * s3) / s;
2899 tLow[i] = -0.5 * (tempA + tempB);
2900 tUpp[i] = tempC / tLow[i];
2906 bSlope1 = bSlope2 = bSlope = xIntPF = xIntInvPF = xtCorPF = mp24DL
2908 for (
int i = 0; i < 2; ++i)
2909 bMin[i] = tAux[i] = probSlope1[i] = tAux1[i] = tAux2[i] = 0.;
2913 bMin[0] = sigmaTotPtr->bMinSlopeAX();
2914 tAux[0] = exp( max(-EXPMAX, bMin[0] * (tLow[0] - tUpp[0])) ) - 1.;
2915 bMin[1] = sigmaTotPtr->bMinSlopeXB();
2916 tAux[1] = exp( max(-EXPMAX, bMin[1] * (tLow[1] - tUpp[1])) ) - 1.;
2919 }
else if (PomFlux == 2) {
2922 for (
int i = 0; i < 2; ++i) {
2923 probSlope1[i] = 6.38 * ( exp(max(-EXPMAX, bSlope1 * tUpp[i]))
2924 - exp(max(-EXPMAX, bSlope1 * tLow[i])) ) / bSlope1;
2925 double pS2 = 0.424 * ( exp(max(-EXPMAX, bSlope2 * tUpp[i]))
2926 - exp(max(-EXPMAX, bSlope2 * tLow[i])) ) / bSlope2;
2927 probSlope1[i] /= probSlope1[i] + pS2;
2928 tAux1[i] = exp( max(-EXPMAX, bSlope1 * (tLow[i] - tUpp[i])) ) - 1.;
2929 tAux2[i] = exp( max(-EXPMAX, bSlope2 * (tLow[i] - tUpp[i])) ) - 1.;
2933 }
else if (PomFlux == 3) {
2935 double xPowPF = 1. - 2. * (1. + epsilonPF);
2936 xIntPF = 1. + xPowPF;
2937 xIntInvPF = 1. / xIntPF;
2938 xtCorPF = 2. * alphaPrimePF;
2939 tAux[0] = exp( max(-EXPMAX, bSlope * (tLow[0] - tUpp[0])) ) - 1.;
2940 tAux[1] = exp( max(-EXPMAX, bSlope * (tLow[1] - tUpp[1])) ) - 1.;
2943 }
else if (PomFlux == 4) {
2944 mp24DL = 4. * pow2(particleDataPtr->m0(2212));
2945 double xPowPF = 1. - 2. * (1. + epsilonPF);
2946 xIntPF = 1. + xPowPF;
2947 xIntInvPF = 1. / xIntPF;
2948 xtCorPF = 2. * alphaPrimePF;
2951 tAux1[0] = 1. / pow3(1. - coefDL * tLow[0]);
2952 tAux2[0] = 1. / pow3(1. - coefDL * tUpp[0]);
2953 tAux1[1] = 1. / pow3(1. - coefDL * tLow[1]);
2954 tAux2[1] = 1. / pow3(1. - coefDL * tUpp[1]);
2957 }
else if (PomFlux == 5) {
2958 epsMBR = settingsPtr->parm(
"Diffraction:MBRepsilon");
2959 alphMBR = settingsPtr->parm(
"Diffraction:MBRalpha");
2960 m2minMBR = settingsPtr->parm(
"Diffraction:MBRm2Min");
2961 dyminMBR = settingsPtr->parm(
"Diffraction:MBRdyminCD");
2962 dyminSigMBR = settingsPtr->parm(
"Diffraction:MBRdyminSigCD");
2963 dyminInvMBR = sqrt(2.) / dyminSigMBR;
2965 dpepmax = sigmaTotPtr->dpepMax();
2978 bool PhaseSpace2to3diffractive::trialKin(
bool,
bool ) {
2981 if (doEnergySpread) {
2982 eCM = infoPtr->eCM();
2984 for (
int i = 0; i < 2; ++i) {
2985 s3 = (i == 0) ? s1 : pow2(mA + m5min);
2986 s4 = (i == 0) ? pow2(mB + m5min) : s2;
2987 double lambda12 = sqrtpos( pow2( s - s1 - s2) - 4. * s1 * s2 );
2988 double lambda34 = sqrtpos( pow2( s - s3 - s4) - 4. * s3 * s4 );
2989 double tempA = s - (s1 + s2 + s3 + s4) + (s1 - s2) * (s3 - s4) / s;
2990 double tempB = lambda12 * lambda34 / s;
2991 double tempC = (s3 - s1) * (s4 - s2) + (s1 + s4 - s2 - s3)
2992 * (s1 * s4 - s2 * s3) / s;
2993 tLow[i] = -0.5 * (tempA + tempB);
2994 tUpp[i] = tempC / tLow[i];
2999 tAux[0] = exp( max(-EXPMAX, bMin[0] * (tLow[0] - tUpp[0])) ) - 1.;
3000 tAux[1] = exp( max(-EXPMAX, bMin[1] * (tLow[1] - tUpp[1])) ) - 1.;
3001 }
else if (PomFlux == 2) {
3002 for (
int i = 0; i < 2; ++i) {
3003 tAux1[i] = exp( max(-EXPMAX, bSlope1 * (tLow[i] - tUpp[i])) ) - 1.;
3004 tAux2[i] = exp( max(-EXPMAX, bSlope2 * (tLow[i] - tUpp[i])) ) - 1.;
3006 }
else if (PomFlux == 3) {
3007 tAux[0] = exp( max(-EXPMAX, bSlope * (tLow[0] - tUpp[0])) ) - 1.;
3008 tAux[1] = exp( max(-EXPMAX, bSlope * (tLow[1] - tUpp[1])) ) - 1.;
3009 }
else if (PomFlux == 4) {
3010 tAux1[0] = 1. / pow3(1. - coefDL * tLow[0]);
3011 tAux2[0] = 1. / pow3(1. - coefDL * tUpp[0]);
3012 tAux1[1] = 1. / pow3(1. - coefDL * tLow[1]);
3013 tAux2[1] = 1. / pow3(1. - coefDL * tUpp[1]);
3018 double lambda12 = sqrtpos( pow2( s - s1 - s2) - 4. * s1 * s2 );
3019 pAbs = 0.5 * lambda12 / eCM;
3020 p1.p( 0., 0., pAbs, 0.5 * (s + s1 - s2) / eCM);
3021 p2.p( 0., 0., -pAbs, 0.5 * (s + s2 - s1) / eCM);
3024 for (
int loop = 0; ; ++loop) {
3026 infoPtr->errorMsg(
"Error in PhaseSpace2to3diffractive::trialKin: "
3027 " quit after repeated tries");
3032 double tVal[2] = { 0., 0.};
3039 xi1 = pow( s5min / s, rndmPtr->flat());
3040 xi2 = pow( s5min / s, rndmPtr->flat());
3042 }
while (s5 < s5min || xi1 * xi2 > rndmPtr->flat());
3043 if (mA + mB + sqrt(s5) + DIFFMASSMARGIN >= eCM)
continue;
3046 bool tryAgain =
false;
3047 for (
int i = 0; i < 2; ++i) {
3048 tVal[i] = tUpp[i] + log(1. + tAux[i] * rndmPtr->flat()) / bMin[i];
3049 double bDiff = (i == 0) ? sigmaTotPtr->bSlopeAX(s2 + xi1 * s)
3050 : sigmaTotPtr->bSlopeXB(s1 + xi2 * s);
3051 bDiff = max(0., bDiff - bMin[i]);
3052 if (exp( max(-EXPMAX, bDiff * (tVal[i] - tUpp[i])) )
3053 < rndmPtr->flat()) tryAgain =
true;
3055 if (tryAgain)
continue;
3058 }
else if (PomFlux == 2) {
3062 xi1 = pow( s5min / s, rndmPtr->flat());
3063 xi2 = pow( s5min / s, rndmPtr->flat());
3065 }
while (s5 < s5min);
3066 if (mA + mB + sqrt(s5) + DIFFMASSMARGIN >= eCM)
continue;
3069 for (
int i = 0; i < 2; ++i)
3070 tVal[i] = (rndmPtr->flat() < probSlope1[i])
3071 ? tUpp[i] + log(1. + tAux1[i] * rndmPtr->flat()) / bSlope1
3072 : tUpp[i] + log(1. + tAux2[i] * rndmPtr->flat()) / bSlope2;
3075 }
else if (PomFlux == 3) {
3078 double sMinPow = pow( s5min / s, xIntPF);
3080 xi1 = pow( sMinPow + rndmPtr->flat() * (1. - sMinPow), xIntInvPF );
3081 xi2 = pow( sMinPow + rndmPtr->flat() * (1. - sMinPow), xIntInvPF );
3083 }
while (s5 < s5min);
3084 if (mA + mB + sqrt(s5) + DIFFMASSMARGIN >= eCM)
continue;
3087 bool tryAgain =
false;
3088 for (
int i = 0; i < 2; ++i) {
3089 tVal[i] = tUpp[i] + log(1. + tAux[i] * rndmPtr->flat()) / bSlope;
3090 double xi = (i == 0) ? xi1 : xi2;
3091 if ( pow( xi, xtCorPF * abs(tVal[i]) ) < rndmPtr->flat() )
3094 if (tryAgain)
continue;
3097 }
else if (PomFlux == 4) {
3100 double sMinPow = pow( s5min / s, xIntPF);
3102 xi1 = pow( sMinPow + rndmPtr->flat() * (1. - sMinPow), xIntInvPF );
3103 xi2 = pow( sMinPow + rndmPtr->flat() * (1. - sMinPow), xIntInvPF );
3105 }
while (s5 < s5min);
3106 if (mA + mB + sqrt(s5) + DIFFMASSMARGIN >= eCM)
continue;
3109 bool tryAgain =
false;
3110 for (
int i = 0; i < 2; ++i) {
3111 tVal[i] = - (1. / pow( tAux1[i] + rndmPtr->flat()
3112 * (tAux2[i] - tAux1[i]), 1./3.) - 1.) / coefDL;
3113 double wDL = pow2( (mp24DL - 2.8 * tVal[i]) / (mp24DL - tVal[i]) )
3114 / pow4( 1. - tVal[i] / 0.7);
3115 double wMX = 1. / pow4( 1. - coefDL * tVal[i]);
3116 if (wDL < rndmPtr->flat() * wMX) tryAgain =
true;
3117 double xi = (i == 0) ? xi1 : xi2;
3118 if ( pow( xi, xtCorPF * abs(tVal[i]) ) < rndmPtr->flat() )
3121 if (tryAgain)
continue;
3126 double dymax = log(s/m2minMBR);
3127 double f1, f2, step2, dy, yc, ycmin, ycmax, dy1, dy2,
3128 P, P1, P2, yRnd, yRnd1, yRnd2;
3132 dy = dymin0 + (dymax - dymin0) * rndmPtr->flat();
3134 step2 = (dy - dymin0) / NINTEG2;
3135 for (
int j = 0; j < NINTEG2 ; ++j) {
3136 yc = -(dy - dymin0) / 2. + (j + 0.5) * step2;
3137 dy1 = 0.5 * dy - yc;
3138 dy2 = 0.5 * dy + yc;
3139 f1 = exp(epsMBR * dy1) * ( (FFA1 / (FFB1 + 2. * alphMBR * dy1) )
3140 + (FFA2 / (FFB2 + 2. * alphMBR * dy1) ) );
3141 f2 = exp(epsMBR * dy2) * ( (FFA1 / (FFB1 + 2. * alphMBR * dy2) )
3142 + (FFA2 / (FFB2 + 2. * alphMBR * dy2) ) );
3143 f1 *= 0.5 * (1. + erf( (dy1 - 0.5 * dyminMBR) * dyminInvMBR ));
3144 f2 *= 0.5 * (1. + erf( (dy2 - 0.5 * dyminMBR) * dyminInvMBR ));
3145 P += f1 * f2 * step2;
3148 ostringstream osWarn;
3149 osWarn <<
"dpepmax = " << scientific << setprecision(3)
3150 << dpepmax <<
" " << P <<
" " << dy << endl;
3151 infoPtr->errorMsg(
"Warning in PhaseSpace2to2diffractive::"
3152 "trialKin for central diffraction:", osWarn.str());
3154 yRnd = dpepmax * rndmPtr->flat();
3157 ycmax = (dy - dymin0) / 2.;
3159 yc = ycmin + (ycmax - ycmin) * rndmPtr->flat();
3162 dy1 = 0.5 * dy + yc;
3163 dy2 = 0.5 * dy - yc;
3164 P1 = 0.5 * (1. + erf( (dy1 - 0.5 * dyminMBR) * dyminInvMBR ));
3165 P2 = 0.5 * (1. + erf( (dy2 - 0.5 * dyminMBR) * dyminInvMBR ));
3166 yRnd1 = rndmPtr->flat();
3167 yRnd2 = rndmPtr->flat();
3168 }
while( !(yRnd < P && yRnd1 < P1 && yRnd2 < P2) );
3173 double tmin = -s1 * xi1 * xi1 / (1. - xi1);
3175 t1 = tmin + log(1. - rndmPtr->flat());
3176 double pFF = (4. * s1 - 2.8 * t1) / ( (4. * s1 - t1)
3177 * pow2(1. - t1 / 0.71));
3178 P = pow2(pFF) * exp(2. * alphMBR * dy1 * t1);
3179 yRnd = exp(t1) * rndmPtr->flat();
3183 tmin = -s2 * xi2 * xi2 / (1. - xi2);
3185 t2 = tmin + log(1. - rndmPtr->flat());
3186 double pFF = (4. * s2 - 2.8 * t2) / ((4. * s2 - t2)
3187 * pow2(1. - t2 / 0.71));
3188 P = pow2(pFF) * exp(2. * alphMBR * dy2 * t2);
3189 yRnd = exp(t2) * rndmPtr->flat();
3201 bool tryAgain =
false;
3202 for (
int i = 0; i < 2; ++i) {
3203 double sx1 = (i == 0) ? s1 : s2;
3204 double sx2 = (i == 0) ? s2 : s1;
3206 double sx4 = (i == 0) ? s2 + xi1 * s : s1 + xi2 * s;
3207 if (sqrt(sx3) + sqrt(sx4) + DIFFMASSMARGIN > eCM) tryAgain =
true;
3208 double lambda34 = sqrtpos( pow2( s - sx3 - sx4) - 4. * sx3 * sx4 );
3209 double tempA = s - (sx1 + sx2 + sx3 + sx4)
3210 + (sx1 - sx2) * (sx3 - sx4) / s;
3211 double tempB = lambda12 * lambda34 / s;
3212 double tempC = (sx3 - sx1) * (sx4 - sx2) + (sx1 + sx4 - sx2 - sx3)
3213 * (sx1 * sx4 - sx2 * sx3) / s;
3214 double tLowNow = -0.5 * (tempA + tempB);
3215 double tUppNow = tempC / tLowNow;
3216 if (tVal[i] < tLowNow || tVal[i] > tUppNow) tryAgain =
true;
3217 if (tryAgain)
break;
3220 double cosTheta = min(1., max(-1., (tempA + 2. * tVal[i]) / tempB));
3221 double sinTheta = 2. * sqrtpos( -(tempC + tempA * tVal[i]
3222 + tVal[i] * tVal[i]) ) / tempB;
3223 theta = asin( min(1., sinTheta));
3224 if (cosTheta < 0.) theta = M_PI - theta;
3225 double pAbs34 = 0.5 * lambda34 / eCM;
3227 pz3 = pAbs34 * cos(theta);
3228 pT3 = pAbs34 * sin(theta);
3230 pz4 = -pAbs34 * cos(theta);
3231 pT4 = pAbs34 * sin(theta);
3234 if (tryAgain)
continue;
3240 pz3 = pAbs * (1. - xi1);
3241 pz4 = -pAbs * (1. - xi2);
3242 pT3 = sqrt( (1. - xi1) * abs(t1) - s1 * pow2(xi1) );
3243 pT4 = sqrt( (1. - xi2) * abs(t2) - s2 * pow2(xi2) );
3247 double phi3 = 2. * M_PI * rndmPtr->flat();
3248 double phi4 = 2. * M_PI * rndmPtr->flat();
3249 p3.p( pT3 * cos(phi3), pT3 * sin(phi3), pz3,
3250 sqrt(pz3 * pz3 + pT3 * pT3 + s1) );
3251 p4.p( pT4 * cos(phi4), pT4 * sin(phi4), pz4,
3252 sqrt(pz4 * pz4 + pT4 * pT4 + s2) );
3255 p5 = (p1 - p3) + (p2 - p4);
3259 if (mHat > DIFFMASSMIN)
break;
3269 bool PhaseSpace2to3diffractive::finalKin() {
3287 tH = (p1 - p3).m2Calc();
3288 uH = (p2 - p4).m2Calc();
3290 p2Abs = pAbs * pAbs;
3293 pTH = (p3.pT() + p4.pT() + p5.pT()) / 3.;
3311 const int PhaseSpace2to3tauycyl::NITERNR = 5;
3317 bool PhaseSpace2to3tauycyl::setupMasses() {
3320 gmZmode = gmZmodeGlobal;
3321 int gmZmodeProc = sigmaProcessPtr->gmZmode();
3322 if (gmZmodeProc >= 0) gmZmode = gmZmodeProc;
3325 mHatMin = mHatGlobalMin;
3326 sHatMin = mHatMin*mHatMin;
3328 if (mHatGlobalMax > mHatGlobalMin) mHatMax = min( eCM, mHatGlobalMax);
3329 sHatMax = mHatMax*mHatMax;
3337 if (useBW[3]) mUpper[3] -= (mPeak[4] + mPeak[5]);
3338 if (useBW[4]) mUpper[4] -= (mPeak[3] + mPeak[5]);
3339 if (useBW[5]) mUpper[5] -= (mPeak[3] + mPeak[4]);
3342 bool physical =
true;
3343 if (useBW[3] && mUpper[3] < mLower[3] + MASSMARGIN) physical =
false;
3344 if (useBW[4] && mUpper[4] < mLower[4] + MASSMARGIN) physical =
false;
3345 if (useBW[5] && mUpper[5] < mLower[5] + MASSMARGIN) physical =
false;
3346 if (!useBW[3] && !useBW[4] && !useBW[5] && mHatMax < mPeak[3]
3347 + mPeak[4] + mPeak[5] + MASSMARGIN) physical =
false;
3348 if (!physical)
return false;
3351 pTHatMin = pTHatGlobalMin;
3352 pT2HatMin = pTHatMin * pTHatMin;
3353 pTHatMax = pTHatGlobalMax;
3354 pT2HatMax = pTHatMax * pTHatMax;
3358 double distToThreshA = (mHatMax - mPeak[3] - mPeak[4] - mPeak[5])
3359 * mWidth[3] / (pow2(mWidth[3]) + pow2(mWidth[4]) + pow2(mWidth[5]));
3360 double distToThreshB = (mHatMax - mPeak[3] - mMin[4] - mMin[5])
3362 double distToThresh = min( distToThreshA, distToThreshB);
3363 setupMass2(3, distToThresh);
3368 double distToThreshA = (mHatMax - mPeak[3] - mPeak[4] - mPeak[5])
3369 * mWidth[4] / (pow2(mWidth[3]) + pow2(mWidth[4]) + pow2(mWidth[5]));
3370 double distToThreshB = (mHatMax - mPeak[4] - mMin[3] - mMin[5])
3372 double distToThresh = min( distToThreshA, distToThreshB);
3373 setupMass2(4, distToThresh);
3378 double distToThreshA = (mHatMax - mPeak[3] - mPeak[4] - mPeak[5])
3379 * mWidth[5] / (pow2(mWidth[3]) + pow2(mWidth[4]) + pow2(mWidth[5]));
3380 double distToThreshB = (mHatMax - mPeak[5] - mMin[3] - mMin[4])
3382 double distToThresh = min( distToThreshA, distToThreshB);
3383 setupMass2(5, distToThresh);
3387 m3 = (useBW[3]) ? min(mPeak[3], mUpper[3]) : mPeak[3];
3388 m4 = (useBW[4]) ? min(mPeak[4], mUpper[4]) : mPeak[4];
3389 m5 = (useBW[5]) ? min(mPeak[5], mUpper[5]) : mPeak[5];
3390 if (m3 + m4 + m5 + MASSMARGIN > mHatMax) physical =
false;
3398 if (useBW[3]) wtBW *= weightMass(3) * EXTRABWWTMAX;
3399 if (useBW[4]) wtBW *= weightMass(4) * EXTRABWWTMAX;
3400 if (useBW[5]) wtBW *= weightMass(5) * EXTRABWWTMAX;
3411 bool PhaseSpace2to3tauycyl::trialMasses() {
3423 if (m3 + m4 + m5 + MASSMARGIN > mHatMax)
return false;
3426 if (useBW[3]) wtBW *= weightMass(3);
3427 if (useBW[4]) wtBW *= weightMass(4);
3428 if (useBW[5]) wtBW *= weightMass(5);
3439 bool PhaseSpace2to3tauycyl::finalKin() {
3442 int id3 = sigmaProcessPtr->id(3);
3443 int id4 = sigmaProcessPtr->id(4);
3444 int id5 = sigmaProcessPtr->id(5);
3445 if (idMass[3] == 0) { m3 = particleDataPtr->m0(id3); s3 = m3*m3; }
3446 if (idMass[4] == 0) { m4 = particleDataPtr->m0(id4); s4 = m4*m4; }
3447 if (idMass[5] == 0) { m5 = particleDataPtr->m0(id5); s5 = m5*m5; }
3450 if (m3 + m4 + m5 + MASSMARGIN > mHat) {
3451 infoPtr->errorMsg(
"Warning in PhaseSpace2to3tauycyl::finalKin: "
3452 "failed after mass assignment");
3464 pH[1] = Vec4( 0., 0., 0.5 * eCM * x1H, 0.5 * eCM * x1H);
3465 pH[2] = Vec4( 0., 0., -0.5 * eCM * x2H, 0.5 * eCM * x2H);
3468 if (idMass[3] == 0 || idMass[4] == 0 || idMass[5] == 0) {
3469 double p3S = p3cm.pAbs2();
3470 double p4S = p4cm.pAbs2();
3471 double p5S = p5cm.pAbs2();
3473 double e3, e4, e5, value, deriv;
3476 for (
int i = 0; i < NITERNR; ++i) {
3477 e3 = sqrt(s3 + fac * p3S);
3478 e4 = sqrt(s4 + fac * p4S);
3479 e5 = sqrt(s5 + fac * p5S);
3480 value = e3 + e4 + e5 - mHat;
3481 deriv = 0.5 * (p3S / e3 + p4S / e4 + p5S / e5);
3482 fac -= value / deriv;
3486 double facRoot = sqrt(fac);
3487 p3cm.rescale3( facRoot );
3488 p4cm.rescale3( facRoot );
3489 p5cm.rescale3( facRoot );
3490 p3cm.e( sqrt(s3 + fac * p3S) );
3491 p4cm.e( sqrt(s4 + fac * p4S) );
3492 p5cm.e( sqrt(s5 + fac * p5S) );
3501 betaZ = (x1H - x2H)/(x1H + x2H);
3502 pH[3].rot( theta, phi);
3503 pH[4].rot( theta, phi);
3504 pH[3].bst( 0., 0., betaZ);
3505 pH[4].bst( 0., 0., betaZ);
3506 pH[5].bst( 0., 0., betaZ);
3509 pTH = (p3cm.pT() + p4cm.pT() + p5cm.pT()) / 3.;
3526 bool PhaseSpace2to3yyycyl::setupSampling() {
3529 pTHat3Min = settingsPtr->parm(
"PhaseSpace:pTHat3Min");
3530 pTHat3Max = settingsPtr->parm(
"PhaseSpace:pTHat3Max");
3531 pTHat5Min = settingsPtr->parm(
"PhaseSpace:pTHat5Min");
3532 pTHat5Max = settingsPtr->parm(
"PhaseSpace:pTHat5Max");
3533 RsepMin = settingsPtr->parm(
"PhaseSpace:RsepMin");
3534 R2sepMin = pow2(RsepMin);
3537 hasBaryonBeams = ( beamAPtr->isBaryon() && beamBPtr->isBaryon() );
3540 for (
int i = 0; i < 6; ++i) mH[i] = 0.;
3545 if (pT3Max < pT3Min) pT3Max = 0.5 * eCM;
3548 if (pT5Max < pT5Min) pT5Max = 0.5 * eCM;
3549 if (pT5Max > pT3Max || pT5Min > pT3Min || pT3Min + 2. * pT5Min > eCM) {
3550 infoPtr->errorMsg(
"Error in PhaseSpace2to3yyycyl::setupSampling: "
3551 "inconsistent pT limits in 3-body phase space");
3559 double pT5EffMax = min( pT5Max, 0.5 * pT3Min / cos(0.5 * RsepMin) );
3560 double pT3EffMin = max( pT3Min, 2.0 * pT5Min * cos(0.5 * RsepMin) ) ;
3561 double sinhR = sinh(0.5 * RsepMin);
3562 double coshR = cosh(0.5 * RsepMin);
3563 for (
int iStep = 0; iStep < 120; ++iStep) {
3568 pT5 = pT5Min * pow( pT5EffMax / pT5Min, iStep / 9.);
3569 double pTRat = pT5 / pT3;
3570 double sin2Rsep = pow2( sin(RsepMin) );
3571 double cosPhi35 = - cos(RsepMin) * sqrtpos(1. - sin2Rsep
3572 * pow2(pTRat)) - sin2Rsep * pTRat;
3573 cosPhi35 = max( cosPhi35, cos(M_PI - 0.5 * RsepMin) );
3574 double sinPhi35 = sqrt(1. - pow2(cosPhi35));
3575 pT4 = sqrt( pow2(pT3) + pow2(pT5) + 2. * pT3 * pT5 * cosPhi35);
3576 p3cm = pT3 * Vec4( 1., 0., 0., 1.);
3577 p4cm = Vec4(-pT3 - pT5 * cosPhi35, -pT5 * sinPhi35, 0., pT4);
3578 p5cm = pT5 * Vec4( cosPhi35, sinPhi35, 0., 1.);
3582 pT5 = pT5Min * pow( pT5Max / pT5Min, iStep%10 / 9. );
3583 pT3 = max( pT3Min, 2. * pT5);
3585 p4cm = pT4 * Vec4( -1., 0., sinhR, coshR );
3586 p5cm = pT5 * Vec4( -1., 0., -sinhR, coshR );
3587 y3 = -1.2 + 0.2 * (iStep/10);
3588 p3cm = pT3 * Vec4( 1., 0., sinh(y3), cosh(y3));
3589 betaZ = (p3cm.pz() + p4cm.pz() + p5cm.pz())
3590 / (p3cm.e() + p4cm.e() + p5cm.e());
3591 p3cm.bst( 0., 0., -betaZ);
3592 p4cm.bst( 0., 0., -betaZ);
3593 p5cm.bst( 0., 0., -betaZ);
3597 pInSum = p3cm + p4cm + p5cm;
3598 x1H = pInSum.e() / eCM;
3600 sH = pInSum.m2Calc();
3601 sigmaProcessPtr->set3Kin( x1H, x2H, sH, p3cm, p4cm, p5cm,
3602 0., 0., 0., 1., 1., 1.);
3603 sigmaNw = sigmaProcessPtr->sigmaPDF();
3606 double flux = 1. /(8. * pow2(sH) * pow5(2. * M_PI));
3607 double pTRng = pow2(M_PI)
3608 * pow4(pT3) * (1./pow2(pT3Min) - 1./pow2(pT3Max))
3609 * pow2(pT5) * 2.* log(pT5Max/pT5Min);
3610 double yRng = 8. * log(eCM / pT3) * log(eCM / pT4) * log(eCM / pT5);
3611 sigmaNw *= SAFETYMARGIN * flux * pTRng * yRng;
3614 if (showSearch && sigmaNw > sigmaMx) cout <<
"\n New sigmamax is "
3615 << scientific << setprecision(3) << sigmaNw <<
" for x1 = " << x1H
3616 <<
" x2 = " << x2H <<
" sH = " << sH << endl <<
" p3 = " << p3cm
3617 <<
" p4 = " << p4cm <<
" p5 = " << p5cm;
3618 if (sigmaNw > sigmaMx) sigmaMx = sigmaNw;
3630 bool PhaseSpace2to3yyycyl::trialKin(
bool inEvent,
bool) {
3633 if (doEnergySpread) {
3634 eCM = infoPtr->eCM();
3642 if (pT3Max < pT3Min) pT3Max = 0.5 * eCM;
3645 if (pT5Max < pT5Min) pT5Max = 0.5 * eCM;
3646 if (pT5Max > pT3Max || pT5Min > pT3Min || pT3Min + 2. * pT5Min > eCM) {
3647 infoPtr->errorMsg(
"Error in PhaseSpace2to3yyycyl::trialKin: "
3648 "inconsistent pT limits in 3-body phase space");
3653 pT3 = pT3Min * pT3Max / sqrt( pow2(pT3Min) +
3654 rndmPtr->flat() * (pow2(pT3Max) - pow2(pT3Min)) );
3655 pT5Max = min(pT5Max, pT3);
3656 if (pT5Max < pT5Min)
return false;
3657 pT5 = pT5Min * pow( pT5Max / pT5Min, rndmPtr->flat() );
3660 phi3 = 2. * M_PI * rndmPtr->flat();
3661 phi5 = 2. * M_PI * rndmPtr->flat();
3662 pT4 = sqrt( pow2(pT3) + pow2(pT5) + 2. * pT3 * pT5 * cos(phi3 - phi5) );
3663 if (pT4 > pT3 || pT4 < pT5)
return false;
3664 phi4 = atan2( -(pT3 * sin(phi3) + pT5 * sin(phi5)),
3665 -(pT3 * cos(phi3) + pT5 * cos(phi5)) );
3668 y3Max = log(eCM / pT3);
3669 y4Max = log(eCM / pT4);
3670 y5Max = log(eCM / pT5);
3671 y3 = y3Max * (2. * rndmPtr->flat() - 1.);
3672 y4 = y4Max * (2. * rndmPtr->flat() - 1.);
3673 y5 = y5Max * (2. * rndmPtr->flat() - 1.);
3677 double WTy = (hasBaryonBeams) ? (1. - pow2(y3/y3Max))
3678 * (1. - pow2(y4/y4Max)) * (1. - pow2(y5/y5Max)) : 1.;
3679 if (WTy < rndmPtr->flat())
return false;
3682 dphi = abs(phi3 - phi4);
3683 if (dphi > M_PI) dphi = 2. * M_PI - dphi;
3684 if (pow2(y3 - y4) + pow2(dphi) < R2sepMin)
return false;
3685 dphi = abs(phi3 - phi5);
3686 if (dphi > M_PI) dphi = 2. * M_PI - dphi;
3687 if (pow2(y3 - y5) + pow2(dphi) < R2sepMin)
return false;
3688 dphi = abs(phi4 - phi5);
3689 if (dphi > M_PI) dphi = 2. * M_PI - dphi;
3690 if (pow2(y4 - y5) + pow2(dphi) < R2sepMin)
return false;
3693 pH[3] = pT3 * Vec4( cos(phi3), sin(phi3), sinh(y3), cosh(y3) );
3694 pH[4] = pT4 * Vec4( cos(phi4), sin(phi4), sinh(y4), cosh(y4) );
3695 pH[5] = pT5 * Vec4( cos(phi5), sin(phi5), sinh(y5), cosh(y5) );
3696 pInSum = pH[3] + pH[4] + pH[5];
3699 x1H = (pInSum.e() + pInSum.pz()) / eCM;
3700 x2H = (pInSum.e() - pInSum.pz()) / eCM;
3701 if (x1H >= 1. || x2H >= 1.)
return false;
3702 sH = pInSum.m2Calc();
3703 if ( sH < pow2(mHatGlobalMin) ||
3704 (mHatGlobalMax > mHatGlobalMin && sH > pow2(mHatGlobalMax)) )
3708 betaZ = (x1H - x2H)/(x1H + x2H);
3709 p3cm = pH[3]; p3cm.bst( 0., 0., -betaZ);
3710 p4cm = pH[4]; p4cm.bst( 0., 0., -betaZ);
3711 p5cm = pH[5]; p5cm.bst( 0., 0., -betaZ);
3714 sigmaProcessPtr->set3Kin( x1H, x2H, sH, p3cm, p4cm, p5cm,
3715 0., 0., 0., 1., 1., 1.);
3716 sigmaNw = sigmaProcessPtr->sigmaPDF();
3719 double flux = 1. /(8. * pow2(sH) * pow5(2. * M_PI));
3720 double yRng = 8. * y3Max * y4Max * y5Max;
3721 double pTRng = pow2(M_PI)
3722 * pow4(pT3) * (1./pow2(pT3Min) - 1./pow2(pT3Max))
3723 * pow2(pT5) * 2.* log(pT5Max/pT5Min);
3724 sigmaNw *= flux * yRng * pTRng / WTy;
3727 if (canModifySigma) sigmaNw
3728 *= userHooksPtr->multiplySigmaBy( sigmaProcessPtr,
this, inEvent);
3729 if (canBiasSelection) sigmaNw
3730 *= userHooksPtr->biasSelectionBy( sigmaProcessPtr,
this, inEvent);
3731 if (canBias2Sel) sigmaNw *= pow( pTH / bias2SelRef, bias2SelPow);
3735 if (sigmaNw > sigmaMx) {
3736 infoPtr->errorMsg(
"Warning in PhaseSpace2to3yyycyl::trialKin: "
3737 "maximum for cross section violated");
3740 if (increaseMaximum || !inEvent) {
3741 double violFact = SAFETYMARGIN * sigmaNw / sigmaMx;
3742 sigmaMx = SAFETYMARGIN * sigmaNw;
3744 if (showViolation) {
3745 if (violFact < 9.99) cout << fixed;
3746 else cout << scientific;
3747 cout <<
" PYTHIA Maximum for " << sigmaProcessPtr->name()
3748 <<
" increased by factor " << setprecision(3) << violFact
3749 <<
" to " << scientific << sigmaMx << endl;
3753 }
else if (showViolation && sigmaNw > sigmaPos) {
3754 double violFact = sigmaNw / sigmaMx;
3755 if (violFact < 9.99) cout << fixed;
3756 else cout << scientific;
3757 cout <<
" PYTHIA Maximum for " << sigmaProcessPtr->name()
3758 <<
" exceeded by factor " << setprecision(3) << violFact << endl;
3764 if (sigmaNw < sigmaNeg) {
3765 infoPtr->errorMsg(
"Warning in PhaseSpace2to3yyycyl::trialKin:"
3766 " negative cross section set 0",
"for " + sigmaProcessPtr->name() );
3770 if (showViolation) cout <<
" PYTHIA Negative minimum for "
3771 << sigmaProcessPtr->name() <<
" changed to " << scientific
3772 << setprecision(3) << sigmaNeg << endl;
3774 if (sigmaNw < 0.) sigmaNw = 0.;
3785 bool PhaseSpace2to3yyycyl::finalKin() {
3788 for (
int i = 0; i < 6; ++i) mH[i] = 0.;
3791 pH[1] = 0.5 * (pInSum.e() + pInSum.pz()) * Vec4( 0., 0., 1., 1.);
3792 pH[2] = 0.5 * (pInSum.e() - pInSum.pz()) * Vec4( 0., 0., -1., 1.);
3797 pTH = (pH[3].pT() + pH[4].pT() + pH[5].pT()) / 3.;
3817 const double PhaseSpaceLHA::CONVERTPB2MB = 1e-9;
3823 bool PhaseSpaceLHA::setupSampling() {
3826 strategy = lhaUpPtr->strategy();
3827 stratAbs = abs(strategy);
3828 if (strategy == 0 || stratAbs > 4) {
3829 ostringstream stratCode;
3830 stratCode << strategy;
3831 infoPtr->errorMsg(
"Error in PhaseSpaceLHA::setupSampling: unknown "
3832 "Les Houches Accord weighting stategy", stratCode.str());
3837 nProc = lhaUpPtr->sizeProc();
3843 double xMax, xSec, xMaxAbs;
3844 for (
int iProc = 0 ; iProc < nProc; ++iProc) {
3845 idPr = lhaUpPtr->idProcess(iProc);
3846 xMax = lhaUpPtr->xMax(iProc);
3847 xSec = lhaUpPtr->xSec(iProc);
3850 if ( (strategy == 1 || strategy == 2) && xMax < 0.) {
3851 infoPtr->errorMsg(
"Error in PhaseSpaceLHA::setupSampling: "
3852 "negative maximum not allowed");
3855 if ( ( strategy == 2 || strategy == 3) && xSec < 0.) {
3856 infoPtr->errorMsg(
"Error in PhaseSpaceLHA::setupSampling: "
3857 "negative cross section not allowed");
3862 if (stratAbs == 1) xMaxAbs = abs(xMax);
3863 else if (stratAbs < 4) xMaxAbs = abs(xSec);
3865 idProc.push_back( idPr );
3866 xMaxAbsProc.push_back( xMaxAbs );
3869 xMaxAbsSum += xMaxAbs;
3872 sigmaMx = xMaxAbsSum * CONVERTPB2MB;
3873 sigmaSgn = xSecSgnSum * CONVERTPB2MB;
3884 bool PhaseSpaceLHA::trialKin(
bool,
bool repeatSame ) {
3888 if (repeatSame) idProcNow = idProcSave;
3889 else if (stratAbs <= 2) {
3890 double xMaxAbsRndm = xMaxAbsSum * rndmPtr->flat();
3892 do xMaxAbsRndm -= xMaxAbsProc[++iProc];
3893 while (xMaxAbsRndm > 0. && iProc < nProc - 1);
3894 idProcNow = idProc[iProc];
3898 bool physical = lhaUpPtr->setEvent(idProcNow, mRecalculate);
3899 if (!physical)
return false;
3902 int idPr = lhaUpPtr->idProcess();
3904 for (
int iP = 0; iP < int(idProc.size()); ++iP)
3905 if (idProc[iP] == idPr) iProc = iP;
3909 double wtPr = lhaUpPtr->weight();
3910 if (stratAbs == 1) sigmaNw = wtPr * CONVERTPB2MB
3911 * xMaxAbsSum / xMaxAbsProc[iProc];
3912 else if (stratAbs == 2) sigmaNw = (wtPr / abs(lhaUpPtr->xMax(iProc)))
3914 else if (strategy == 3) sigmaNw = sigmaMx;
3915 else if (strategy == -3 && wtPr > 0.) sigmaNw = sigmaMx;
3916 else if (strategy == -3) sigmaNw = -sigmaMx;
3917 else if (stratAbs == 4) sigmaNw = wtPr * CONVERTPB2MB;
3920 x1H = lhaUpPtr->x1();
3921 x2H = lhaUpPtr->x2();