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::MRESMINABS = 0.001;
45 const double PhaseSpace::WIDTHMARGIN = 20.;
48 const double PhaseSpace::SAMEMASS = 0.01;
51 const double PhaseSpace::MASSMARGIN = 0.01;
54 const double PhaseSpace::EXTRABWWTMAX = 1.25;
57 const double PhaseSpace::THRESHOLDSIZE = 3.;
60 const double PhaseSpace::THRESHOLDSTEP = 0.2;
63 const double PhaseSpace::YRANGEMARGIN = 1e-6;
67 const double PhaseSpace::LEPTONXMIN = 1e-10;
68 const double PhaseSpace::LEPTONXMAX = 1. - 1e-10;
69 const double PhaseSpace::LEPTONXLOGMIN = log(1e-10);
70 const double PhaseSpace::LEPTONXLOGMAX = log(1. - 1e-10);
71 const double PhaseSpace::LEPTONTAUMIN = 2e-10;
74 const double PhaseSpace::SHATMINZ = 1.;
77 const double PhaseSpace::PT2RATMINZ = 0.0001;
81 const double PhaseSpace::WTCORRECTION[11] = { 1., 1., 1.,
82 2., 5., 15., 60., 250., 1250., 7000., 50000. };
88 void PhaseSpace::init(
bool isFirst, SigmaProcess* sigmaProcessPtrIn) {
91 sigmaProcessPtr = sigmaProcessPtrIn;
102 hasLeptonBeamA = beamAPtr->isLepton();
103 hasLeptonBeamB = beamBPtr->isLepton();
104 hasTwoLeptonBeams = hasLeptonBeamA && hasLeptonBeamB;
105 hasOneLeptonBeam = (hasLeptonBeamA || hasLeptonBeamB) && !hasTwoLeptonBeams;
106 bool hasPointLepton = (hasLeptonBeamA && beamAPtr->isUnresolved())
107 || (hasLeptonBeamB && beamBPtr->isUnresolved());
110 hasPointGammaA = beamAPtr->isGamma() && beamAPtr->isUnresolved();
111 hasPointGammaB = beamBPtr->isGamma() && beamBPtr->isUnresolved();
112 hasOnePointParticle = (hasOneLeptonBeam && hasPointLepton)
113 || ( hasPointGammaA && !hasPointGammaB)
114 || (!hasPointGammaA && hasPointGammaB);
115 hasTwoPointParticles = (hasTwoLeptonBeams && hasPointLepton)
116 || ( hasPointGammaA && hasPointGammaB);
119 bool beamHasResGamma = beamAPtr->hasResGamma() && beamBPtr->hasResGamma();
122 if ( beamAPtr->isGamma() && beamBPtr->isGamma() ) {
124 int beamAGammaMode = beamAPtr->getGammaMode();
125 int beamBGammaMode = beamBPtr->getGammaMode();
127 if ( beamAGammaMode == 2 && beamBGammaMode != 2 ) {
128 hasOnePointParticle =
true;
129 hasPointGammaA =
true;
131 if ( beamBGammaMode == 2 && beamAGammaMode != 2 ) {
132 hasOnePointParticle =
true;
133 hasPointGammaB =
true;
135 if ( beamAGammaMode == 2 && beamBGammaMode == 2 ) {
136 hasTwoPointParticles =
true;
137 hasPointGammaA =
true;
138 hasPointGammaB =
true;
143 if (isFirst || flag(
"PhaseSpace:sameForSecond")) {
144 mHatGlobalMin = parm(
"PhaseSpace:mHatMin");
145 mHatGlobalMax = parm(
"PhaseSpace:mHatMax");
146 pTHatGlobalMin = parm(
"PhaseSpace:pTHatMin");
147 pTHatGlobalMax = parm(
"PhaseSpace:pTHatMax");
151 mHatGlobalMin = parm(
"PhaseSpace:mHatMinSecond");
152 mHatGlobalMax = parm(
"PhaseSpace:mHatMaxSecond");
153 pTHatGlobalMin = parm(
"PhaseSpace:pTHatMinSecond");
154 pTHatGlobalMax = parm(
"PhaseSpace:pTHatMaxSecond");
158 pTHatMinDiverge = parm(
"PhaseSpace:pTHatMinDiverge");
161 Q2GlobalMin = parm(
"PhaseSpace:Q2Min");
162 hasQ2Min = ( Q2GlobalMin >= pow2(pTHatMinDiverge) );
165 if ( beamHasResGamma ) {
166 double Wmax = parm(
"Photon:Wmax");
167 if ( (mHatGlobalMax > Wmax) || mHatGlobalMax < 0.) mHatGlobalMax = Wmax;
171 useBreitWigners = flag(
"PhaseSpace:useBreitWigners");
172 minWidthBreitWigners = parm(
"PhaseSpace:minWidthBreitWigners");
173 minWidthNarrowBW = parm(
"PhaseSpace:minWidthNarrowBW");
176 doEnergySpread = flag(
"Beams:allowMomentumSpread")
177 || flag(
"Beams:allowVariableEnergy");
180 showSearch = flag(
"PhaseSpace:showSearch");
181 showViolation = flag(
"PhaseSpace:showViolation");
182 increaseMaximum = flag(
"PhaseSpace:increaseMaximum");
185 gmZmodeGlobal = mode(
"WeakZ0:gmZmode");
188 canModifySigma = (userHooksPtr != 0)
189 ? userHooksPtr->canModifySigma() :
false;
190 canBiasSelection = (userHooksPtr != 0)
191 ? userHooksPtr->canBiasSelection() :
false;
194 canBias2Sel = flag(
"PhaseSpace:bias2Selection");
195 bias2SelPow = parm(
"PhaseSpace:bias2SelectionPow");
196 bias2SelRef = parm(
"PhaseSpace:bias2SelectionRef");
197 if (canBias2Sel) pTHatGlobalMin = max( pTHatGlobalMin, pTHatMinDiverge);
233 void PhaseSpace::decayKinematics(
Event& process) {
237 for (
int iResBeg = 5; iResBeg < process.size(); ++iResBeg) {
238 if (iResBeg <= iResEnd)
continue;
240 while ( iResEnd < process.size() - 1
241 && process[iResEnd + 1].mother1() == process[iResBeg].mother1()
242 && process[iResEnd + 1].mother2() == process[iResBeg].mother2() )
247 for (
int iRes = iResBeg; iRes <= iResEnd; ++iRes)
248 if ( !process[iRes].isFinal() ) hasRes =
true;
249 if ( !hasRes )
continue;
252 double decWt = sigmaProcessPtr->weightDecay( process, iResBeg, iResEnd);
253 if (decWt < 0.) infoPtr->errorMsg(
"Warning in PhaseSpace::decay"
254 "Kinematics: negative angular weight");
255 if (decWt > 1.) infoPtr->errorMsg(
"Warning in PhaseSpace::decay"
256 "Kinematics: angular weight above unity");
257 while (decWt < rndmPtr->flat() ) {
260 for (
int iRes = iResBeg; iRes < process.size(); ++iRes) {
261 if ( process[iRes].isFinal() )
continue;
262 int iResMother = iRes;
263 while (iResMother > iResEnd)
264 iResMother = process[iResMother].mother1();
265 if (iResMother < iResBeg)
continue;
268 decayKinematicsStep( process, iRes);
274 decWt = sigmaProcessPtr->weightDecay( process, iResBeg, iResEnd);
275 if (decWt < 0.) infoPtr->errorMsg(
"Warning in PhaseSpace::decay"
276 "Kinematics: negative angular weight");
277 if (decWt > 1.) infoPtr->errorMsg(
"Warning in PhaseSpace::decay"
278 "Kinematics: angular weight above unity");
291 void PhaseSpace::decayKinematicsStep(
Event& process,
int iRes) {
294 int i1 = process[iRes].daughter1();
295 int mult = process[iRes].daughter2() + 1 - i1;
296 double m0 = process[iRes].m();
297 Vec4 pRes = process[iRes].p();
304 double m1t = process[i1].m();
305 double m2t = process[i2].m();
308 pair<Vec4, Vec4> ps = rndmPtr->phaseSpace2(m0, m1t, m2t);
326 double m1t = process[i1].m();
327 double m2t = process[i2].m();
328 double m3t = process[i3].m();
329 double mDiff = m0 - (m1t + m2t + m3t);
332 double m23Min = m2t + m3t;
333 double m23Max = m0 - m1t;
334 double p1Max = 0.5 * sqrtpos( (m0 - m1t - m23Min)
335 * (m0 + m1t + m23Min) * (m0 + m1t - m23Min)
336 * (m0 - m1t + m23Min) ) / m0;
337 double p23Max = 0.5 * sqrtpos( (m23Max - m2t - m3t)
338 * (m23Max + m2t + m3t) * (m23Max + m2t - m3t)
339 * (m23Max - m2t + m3t) ) / m23Max;
340 double wtPSmax = 0.5 * p1Max * p23Max;
343 double wtPS, m23, p1Abs, p23Abs;
345 m23 = m23Min + rndmPtr->flat() * mDiff;
348 p1Abs = 0.5 * sqrtpos( (m0 - m1t - m23) * (m0 + m1t + m23)
349 * (m0 + m1t - m23) * (m0 - m1t + m23) ) / m0;
350 p23Abs = 0.5 * sqrtpos( (m23 - m2t - m3t) * (m23 + m2t + m3t)
351 * (m23 + m2t - m3t) * (m23 - m2t + m3t) ) / m23;
352 wtPS = p1Abs * p23Abs;
355 }
while ( wtPS < rndmPtr->flat() * wtPSmax );
358 pair<Vec4, Vec4> ps23 = rndmPtr->phaseSpace2(m23, m2t, m3t);
360 Vec4 p3(ps23.second);
363 pair<Vec4, Vec4> ps123 = rndmPtr->phaseSpace2(m0, m1t, m23);
364 Vec4 p1(ps123.first);
367 p2.bst( ps123.second );
368 p3.bst( ps123.second );
385 vector<double> mProd;
386 mProd.push_back( m0);
387 for (
int i = i1; i <= process[iRes].daughter2(); ++i)
388 mProd.push_back( process[i].m() );
390 pProd.push_back( pRes);
393 double mSum = mProd[1];
394 for (
int i = 2; i <= mult; ++i) mSum += mProd[i];
395 double mDiff = m0 - mSum;
399 for (
int i = 0; i <= mult; ++i) mInv.push_back( mProd[i]);
402 double wtPSmax = 1. / WTCORRECTION[mult];
403 double mMaxWT = mDiff + mProd[mult];
405 for (
int i = mult - 1; i > 0; --i) {
407 mMinWT += mProd[i+1];
408 double mNow = mProd[i];
409 wtPSmax *= 0.5 * sqrtpos( (mMaxWT - mMinWT - mNow)
410 * (mMaxWT + mMinWT + mNow) * (mMaxWT + mMinWT - mNow)
411 * (mMaxWT - mMinWT + mNow) ) / mMaxWT;
415 vector<double> rndmOrd;
422 rndmOrd.push_back(1.);
423 for (
int i = 1; i < mult - 1; ++i) {
424 double rndm = rndmPtr->flat();
425 rndmOrd.push_back(rndm);
426 for (
int j = i - 1; j > 0; --j) {
427 if (rndm > rndmOrd[j]) swap( rndmOrd[j], rndmOrd[j+1] );
431 rndmOrd.push_back(0.);
434 for (
int i = mult - 1; i > 0; --i) {
435 mInv[i] = mInv[i+1] + mProd[i] + (rndmOrd[i-1] - rndmOrd[i]) * mDiff;
436 wtPS *= 0.5 * sqrtpos( (mInv[i] - mInv[i+1] - mProd[i])
437 * (mInv[i] + mInv[i+1] + mProd[i]) * (mInv[i] + mInv[i+1] - mProd[i])
438 * (mInv[i] - mInv[i+1] + mProd[i]) ) / mInv[i];
442 }
while ( wtPS < rndmPtr->flat() * wtPSmax );
446 pInv.resize(mult + 1);
447 for (
int i = 1; i < mult; ++i) {
448 pair<Vec4, Vec4> ps = rndmPtr->phaseSpace2(mInv[i], mInv[i+1], mProd[i]);
449 pInv[i+1].p(ps.first);
450 pProd.push_back(ps.second);
452 pProd.push_back( pInv[mult] );
456 for (
int iFrame = mult - 1; iFrame > 0; --iFrame)
457 for (
int i = iFrame; i <= mult; ++i) pProd[i].bst(pInv[iFrame]);
460 for (
int i = 1; i <= mult; ++i)
461 process[i1 + i - 1].p( pProd[i] );
470 void PhaseSpace::setup3Body() {
473 int idTchan1 = abs( sigmaProcessPtr->idTchan1() );
474 int idTchan2 = abs( sigmaProcessPtr->idTchan2() );
475 mTchan1 = (idTchan1 == 0) ? pTHatMinDiverge
476 : particleDataPtr->m0(idTchan1);
477 mTchan2 = (idTchan2 == 0) ? pTHatMinDiverge
478 : particleDataPtr->m0(idTchan2);
479 sTchan1 = mTchan1 * mTchan1;
480 sTchan2 = mTchan2 * mTchan2;
483 frac3Pow1 = sigmaProcessPtr->tChanFracPow1();
484 frac3Pow2 = sigmaProcessPtr->tChanFracPow2();
485 frac3Flat = 1. - frac3Pow1 - frac3Pow2;
486 useMirrorWeight = sigmaProcessPtr->useMirrorWeight();
494 bool PhaseSpace::setupSampling123(
bool is2,
bool is3) {
497 if (showSearch) cout <<
"\n PYTHIA Optimization printout for "
498 << sigmaProcessPtr->name() <<
"\n \n" << scientific << setprecision(3);
501 if (!limitTau(is2, is3))
return false;
504 int binTau[8], binY[8], binZ[8];
505 double vecTau[8], matTau[8][8], vecY[8], matY[8][8], vecZ[8], matZ[8][8];
506 for (
int i = 0; i < 8; ++i) {
516 for (
int j = 0; j < 8; ++j) {
526 nTau = (hasTwoPointParticles) ? 1 : 2;
527 nY = (hasOnePointParticle || hasTwoPointParticles) ? 1 : 5;
531 idResA = sigmaProcessPtr->resonanceA();
533 mResA = particleDataPtr->m0(idResA);
534 GammaResA = particleDataPtr->mWidth(idResA);
535 if (mHatMin > mResA + WIDTHMARGIN * GammaResA || (mHatMax > 0.
536 && mHatMax < mResA - WIDTHMARGIN * GammaResA) ) idResA = 0;
538 idResB = sigmaProcessPtr->resonanceB();
540 mResB = particleDataPtr->m0(idResB);
541 GammaResB = particleDataPtr->mWidth(idResB);
542 if (mHatMin > mResB + WIDTHMARGIN * GammaResB || (mHatMax > 0.
543 && mHatMax < mResB - WIDTHMARGIN * GammaResB) ) idResB = 0;
545 if (idResA == 0 && idResB != 0) {
548 GammaResA = GammaResB;
553 if (!is2 && !is3 && idResA != 0 && GammaResA == 0.) {
554 infoPtr->errorMsg(
"Error in PhaseSpace::setupSampling123: "
555 "zero-width resonance ", to_string(idResA),
true);
558 if (!is2 && !is3 && idResB != 0 && GammaResB == 0.) {
559 infoPtr->errorMsg(
"Error in PhaseSpace::setupSampling123: "
560 "zero-width resonance ", to_string(idResB),
true);
565 if (idResA !=0 && !hasTwoPointParticles) {
567 tauResA = mResA * mResA / s;
568 widResA = mResA * GammaResA / s;
570 if (idResB != 0 && !hasTwoPointParticles) {
572 tauResB = mResB * mResB / s;
573 widResB = mResB * GammaResB / s;
577 if (hasTwoLeptonBeams && !hasTwoPointParticles) ++nTau;
581 if (idResB != 0 && abs(mResA - mResB) < SAMEMASS * (GammaResA + GammaResB))
587 int nVar = (is2) ? 3 : 2;
596 for (
int iTau = 0; iTau < nTau; ++iTau) {
598 if (sameResMass && iTau > 1 && iTau < 6) posTau = (iTau < 4) ? 0.4 : 0.6;
599 selectTau( iTau, posTau, is2);
600 if (!limitY())
continue;
601 if (is2 && !limitZ())
continue;
604 for (
int iY = 0; iY < nY; ++iY) {
606 for (
int iZ = 0; iZ < nZ; ++iZ) {
607 if (is2) selectZ( iZ, 0.5);
608 double sigmaTmp = 0.;
612 sigmaProcessPtr->set1Kin( x1H, x2H, sH);
613 sigmaTmp = sigmaProcessPtr->sigmaPDF(
true);
614 sigmaTmp *= wtTau * wtY;
619 sigmaProcessPtr->set2Kin( x1H, x2H, sH, tH, m3, m4,
621 sigmaTmp = sigmaProcessPtr->sigmaPDF(
true);
622 sigmaTmp *= wtTau * wtY * wtZ * wtBW;
628 for (
int iTry3 = 0; iTry3 < NTRY3BODY; ++iTry3) {
629 if (!select3Body())
continue;
630 sigmaProcessPtr->set3Kin( x1H, x2H, sH, p3cm, p4cm, p5cm,
631 m3, m4, m5, runBW3H, runBW4H, runBW5H);
632 double sigmaTry = sigmaProcessPtr->sigmaPDF(
true);
633 sigmaTry *= wtTau * wtY * wt3Body * wtBW;
634 if (sigmaTry > sigmaTmp) sigmaTmp = sigmaTry;
639 if (canModifySigma) sigmaTmp
640 *= userHooksPtr->multiplySigmaBy( sigmaProcessPtr,
this,
false);
641 if (canBiasSelection) sigmaTmp
642 *= userHooksPtr->biasSelectionBy( sigmaProcessPtr,
this,
false);
643 if (canBias2Sel) sigmaTmp *= pow( pTH / bias2SelRef, bias2SelPow);
646 if (sigmaTmp > sigmaMx) sigmaMx = sigmaTmp;
649 if (showSearch) cout <<
" tau =" << setw(11) << tau <<
" y ="
650 << setw(11) << y <<
" z =" << setw(11) << z
651 <<
" sigma =" << setw(11) << sigmaTmp <<
"\n";
652 if (sigmaTmp < 0.) sigmaTmp = 0.;
655 if (!hasTwoPointParticles) {
657 vecTau[iTau] += sigmaTmp;
658 matTau[iTau][0] += 1. / intTau0;
659 matTau[iTau][1] += (1. / intTau1) / tau;
661 matTau[iTau][2] += (1. / intTau2) / (tau + tauResA);
662 matTau[iTau][3] += (1. / intTau3)
663 * tau / ( pow2(tau - tauResA) + pow2(widResA) );
666 matTau[iTau][4] += (1. / intTau4) / (tau + tauResB);
667 matTau[iTau][5] += (1. / intTau5)
668 * tau / ( pow2(tau - tauResB) + pow2(widResB) );
670 if (hasTwoLeptonBeams) matTau[iTau][nTau - 1] += (1. / intTau6)
671 * tau / max( LEPTONTAUMIN, 1. - tau);
675 if (!hasOnePointParticle && !hasTwoPointParticles) {
677 vecY[iY] += sigmaTmp;
678 matY[iY][0] += (yMax / intY0) / cosh(y);
679 matY[iY][1] += (yMax / intY12) * (y + yMax);
680 matY[iY][2] += (yMax / intY12) * (yMax - y);
681 if (!hasTwoLeptonBeams) {
682 matY[iY][3] += (yMax / intY34) * exp(y);
683 matY[iY][4] += (yMax / intY34) * exp(-y);
685 matY[iY][3] += (yMax / intY56)
686 / max( LEPTONXMIN, 1. - exp( y - yMax) );
687 matY[iY][4] += (yMax / intY56)
688 / max( LEPTONXMIN, 1. - exp(-y - yMax) );
694 double p2AbsMax = 0.25 * (pow2(tauMax * s - s3 - s4)
695 - 4. * s3 * s4) / (tauMax * s);
696 double zMaxMax = sqrtpos( 1. - pT2HatMin / p2AbsMax );
697 double zPosMaxMax = max(ratio34, unity34 + zMaxMax);
698 double zNegMaxMax = max(ratio34, unity34 - zMaxMax);
699 double intZ0Max = 2. * zMaxMax;
700 double intZ12Max = log( zPosMaxMax / zNegMaxMax);
701 double intZ34Max = 1. / zNegMaxMax - 1. / zPosMaxMax;
705 vecZ[iZ] += sigmaTmp;
707 matZ[iZ][1] += (intZ0Max / intZ12Max) / zNeg;
708 matZ[iZ][2] += (intZ0Max / intZ12Max) / zPos;
709 matZ[iZ][3] += (intZ0Max / intZ34Max) / pow2(zNeg);
710 matZ[iZ][4] += (intZ0Max / intZ34Max) / pow2(zPos);
726 if (!hasTwoPointParticles) solveSys( nTau, binTau, vecTau, matTau, tauCoef);
727 if (!hasOnePointParticle && !hasTwoPointParticles)
728 solveSys( nY, binY, vecY, matY, yCoef);
729 if (is2) solveSys( nZ, binZ, vecZ, matZ, zCoef);
730 if (showSearch) cout <<
"\n";
733 tauCoefSum[0] = tauCoef[0];
734 yCoefSum[0] = yCoef[0];
735 zCoefSum[0] = zCoef[0];
736 for (
int i = 1; i < 8; ++ i) {
737 tauCoefSum[i] = tauCoefSum[i - 1] + tauCoef[i];
738 yCoefSum[i] = yCoefSum[i - 1] + yCoef[i];
739 zCoefSum[i] = zCoefSum[i - 1] + zCoef[i];
742 tauCoefSum[nTau - 1] = 2.;
743 yCoefSum[nY - 1] = 2.;
744 zCoefSum[nZ - 1] = 2.;
748 int iMaxTau[NMAXTRY + 2], iMaxY[NMAXTRY + 2], iMaxZ[NMAXTRY + 2];
749 double sigMax[NMAXTRY + 2];
753 for (
int iTau = 0; iTau < nTau; ++iTau) {
755 if (sameResMass && iTau > 1 && iTau < 6) posTau = (iTau < 4) ? 0.4 : 0.6;
756 selectTau( iTau, posTau, is2);
757 if (!limitY())
continue;
758 if (is2 && !limitZ())
continue;
759 for (
int iY = 0; iY < nY; ++iY) {
761 for (
int iZ = 0; iZ < nZ; ++iZ) {
762 if (is2) selectZ( iZ, 0.5);
763 double sigmaTmp = 0.;
767 sigmaProcessPtr->set1Kin( x1H, x2H, sH);
768 sigmaTmp = sigmaProcessPtr->sigmaPDF(
true);
769 sigmaTmp *= wtTau * wtY;
774 sigmaProcessPtr->set2Kin( x1H, x2H, sH, tH, m3, m4,
776 sigmaTmp = sigmaProcessPtr->sigmaPDF(
true);
777 sigmaTmp *= wtTau * wtY * wtZ * wtBW;
783 for (
int iTry3 = 0; iTry3 < NTRY3BODY; ++iTry3) {
784 if (!select3Body())
continue;
785 sigmaProcessPtr->set3Kin( x1H, x2H, sH, p3cm, p4cm, p5cm,
786 m3, m4, m5, runBW3H, runBW4H, runBW5H);
787 double sigmaTry = sigmaProcessPtr->sigmaPDF(
true);
788 sigmaTry *= wtTau * wtY * wt3Body * wtBW;
789 if (sigmaTry > sigmaTmp) sigmaTmp = sigmaTry;
794 if (canModifySigma) sigmaTmp
795 *= userHooksPtr->multiplySigmaBy( sigmaProcessPtr,
this,
false);
796 if (canBiasSelection) sigmaTmp
797 *= userHooksPtr->biasSelectionBy( sigmaProcessPtr,
this,
false);
798 if (canBias2Sel) sigmaTmp *= pow( pTH / bias2SelRef, bias2SelPow);
801 if (showSearch) cout <<
" tau =" << setw(11) << tau <<
" y ="
802 << setw(11) << y <<
" z =" << setw(11) << z
803 <<
" sigma =" << setw(11) << sigmaTmp <<
"\n";
804 if (sigmaTmp < 0.) sigmaTmp = 0.;
807 bool mirrorPoint =
false;
808 for (
int iMove = 0; iMove < nMax; ++iMove)
809 if (abs(sigmaTmp - sigMax[iMove]) < SAMESIGMA
810 * (sigmaTmp + sigMax[iMove])) mirrorPoint =
true;
815 for (
int iMove = nMax - 1; iMove >= -1; --iMove) {
817 if (iInsert == 0 || sigmaTmp < sigMax[iMove])
break;
818 iMaxTau[iMove + 1] = iMaxTau[iMove];
819 iMaxY[iMove + 1] = iMaxY[iMove];
820 iMaxZ[iMove + 1] = iMaxZ[iMove];
821 sigMax[iMove + 1] = sigMax[iMove];
823 iMaxTau[iInsert] = iTau;
826 sigMax[iInsert] = sigmaTmp;
827 if (nMax < NMAXTRY) ++nMax;
834 if (showSearch) cout <<
"\n";
838 int beginVar = (hasTwoPointParticles) ? 2 : 0;
839 if (hasOnePointParticle) beginVar = 1;
840 for (
int iMax = 0; iMax < nMax; ++iMax) {
841 int iTau = iMaxTau[iMax];
842 int iY = iMaxY[iMax];
843 int iZ = iMaxZ[iMax];
848 double varVal, varNew, deltaVar, marginVar, sigGrid[3];
851 for (
int iRepeat = 0; iRepeat < 2; ++iRepeat) {
853 for (
int iVar = beginVar; iVar < nVar; ++iVar) {
854 bool isTauVar = iVar == 0 || (beginVar == 1 && iVar == 1);
855 if (isTauVar) varVal = tauVal;
856 else if (iVar == 1) varVal = yVal;
858 deltaVar = (iRepeat == 0) ? 0.1
859 : max( 0.01, min( 0.05, min( varVal - 0.02, 0.98 - varVal) ) );
860 marginVar = (iRepeat == 0) ? 0.02 : 0.002;
861 int moveStart = (iRepeat == 0 && isTauVar) ? 0 : 1;
862 for (
int move = moveStart; move < 9; ++move) {
868 }
else if (move == 1) {
870 varNew = varVal + deltaVar;
871 }
else if (move == 2) {
873 varNew = varVal - deltaVar;
874 }
else if (sigGrid[2] >= max( sigGrid[0], sigGrid[1])
875 && varVal + 2. * deltaVar < 1. - marginVar) {
877 sigGrid[0] = sigGrid[1];
878 sigGrid[1] = sigGrid[2];
880 varNew = varVal + deltaVar;
881 }
else if (sigGrid[0] >= max( sigGrid[1], sigGrid[2])
882 && varVal - 2. * deltaVar > marginVar) {
884 sigGrid[2] = sigGrid[1];
885 sigGrid[1] = sigGrid[0];
887 varNew = varVal - deltaVar;
888 }
else if (sigGrid[2] >= sigGrid[0]) {
891 sigGrid[0] = sigGrid[1];
897 sigGrid[2] = sigGrid[1];
903 bool insideLimits =
true;
906 selectTau( iTau, tauVal, is2);
907 if (!limitY()) insideLimits =
false;
908 if (is2 && !limitZ()) insideLimits =
false;
911 if (is2) selectZ( iZ, zVal);
913 }
else if (iVar == 1) {
916 }
else if (iVar == 2) {
922 double sigmaTmp = 0.;
927 sigmaProcessPtr->set1Kin( x1H, x2H, sH);
928 sigmaTmp = sigmaProcessPtr->sigmaPDF(
true);
929 sigmaTmp *= wtTau * wtY;
934 sigmaProcessPtr->set2Kin( x1H, x2H, sH, tH, m3, m4,
936 sigmaTmp = sigmaProcessPtr->sigmaPDF(
true);
937 sigmaTmp *= wtTau * wtY * wtZ * wtBW;
943 for (
int iTry3 = 0; iTry3 < NTRY3BODY; ++iTry3) {
944 if (!select3Body())
continue;
945 sigmaProcessPtr->set3Kin( x1H, x2H, sH, p3cm, p4cm, p5cm,
946 m3, m4, m5, runBW3H, runBW4H, runBW5H);
947 double sigmaTry = sigmaProcessPtr->sigmaPDF(
true);
948 sigmaTry *= wtTau * wtY * wt3Body * wtBW;
949 if (sigmaTry > sigmaTmp) sigmaTmp = sigmaTry;
954 if (canModifySigma) sigmaTmp
955 *= userHooksPtr->multiplySigmaBy( sigmaProcessPtr,
this,
false);
956 if (canBiasSelection) sigmaTmp
957 *= userHooksPtr->biasSelectionBy( sigmaProcessPtr,
this,
false);
958 if (canBias2Sel) sigmaTmp *= pow( pTH / bias2SelRef, bias2SelPow);
961 if (showSearch) cout <<
" tau =" << setw(11) << tau <<
" y ="
962 << setw(11) << y <<
" z =" << setw(11) << z
963 <<
" sigma =" << setw(11) << sigmaTmp <<
"\n";
964 if (sigmaTmp < 0.) sigmaTmp = 0.;
968 sigGrid[iGrid] = sigmaTmp;
969 if (sigmaTmp > sigmaMx) sigmaMx = sigmaTmp;
974 sigmaMx *= SAFETYMARGIN;
978 if (showSearch) cout <<
"\n Final maximum = " << setw(11) << sigmaMx
991 bool PhaseSpace::trialKin123(
bool is2,
bool is3,
bool inEvent) {
994 if (doEnergySpread) {
995 eCM = infoPtr->eCM();
999 if (idResA !=0 && !hasTwoPointParticles) {
1000 tauResA = mResA * mResA / s;
1001 widResA = mResA * GammaResA / s;
1002 if (widResA == 0)
return false;
1004 if (idResB != 0 && !hasTwoPointParticles) {
1005 tauResB = mResB * mResB / s;
1006 widResB = mResB * GammaResB / s;
1007 if (widResB == 0)
return false;
1018 if (!limitTau(is2, is3))
return false;
1020 if (!hasTwoPointParticles) {
1021 double rTau = rndmPtr->flat();
1022 while (rTau > tauCoefSum[iTau]) ++iTau;
1024 selectTau( iTau, rndmPtr->flat(), is2);
1031 if (!limitY())
return false;
1033 if (!hasOnePointParticle && !hasTwoPointParticles) {
1034 double rY = rndmPtr->flat();
1035 while (rY > yCoefSum[iY]) ++iY;
1037 selectY( iY, rndmPtr->flat());
1044 if (!limitZ())
return false;
1046 double rZ = rndmPtr->flat();
1047 while (rZ > zCoefSum[iZ]) ++iZ;
1048 selectZ( iZ, rndmPtr->flat());
1053 sigmaProcessPtr->set1Kin( x1H, x2H, sH);
1054 sigmaNw = sigmaProcessPtr->sigmaPDF();
1055 sigmaNw *= wtTau * wtY;
1060 sigmaProcessPtr->set2Kin( x1H, x2H, sH, tH, m3, m4, runBW3H, runBW4H);
1061 sigmaNw = sigmaProcessPtr->sigmaPDF();
1062 sigmaNw *= wtTau * wtY * wtZ * wtBW;
1067 if (!select3Body()) sigmaNw = 0.;
1069 sigmaProcessPtr->set3Kin( x1H, x2H, sH, p3cm, p4cm, p5cm,
1070 m3, m4, m5, runBW3H, runBW4H, runBW5H);
1071 sigmaNw = sigmaProcessPtr->sigmaPDF();
1072 sigmaNw *= wtTau * wtY * wt3Body * wtBW;
1077 if (canModifySigma) sigmaNw
1078 *= userHooksPtr->multiplySigmaBy( sigmaProcessPtr,
this, inEvent);
1079 if (canBiasSelection) sigmaNw
1080 *= userHooksPtr->biasSelectionBy( sigmaProcessPtr,
this, inEvent);
1081 if (canBias2Sel) sigmaNw *= pow( pTH / bias2SelRef, bias2SelPow);
1085 if (sigmaNw > sigmaMx) {
1086 infoPtr->errorMsg(
"Warning in PhaseSpace2to2tauyz::trialKin: "
1087 "maximum for cross section violated");
1090 if (increaseMaximum || !inEvent) {
1091 double violFact = SAFETYMARGIN * sigmaNw / sigmaMx;
1092 sigmaMx = SAFETYMARGIN * sigmaNw;
1094 if (showViolation) {
1095 if (violFact < 9.99) cout << fixed;
1096 else cout << scientific;
1097 cout <<
" PYTHIA Maximum for " << sigmaProcessPtr->name()
1098 <<
" increased by factor " << setprecision(3) << violFact
1099 <<
" to " << scientific << sigmaMx << endl;
1103 }
else if (showViolation && sigmaNw > sigmaPos) {
1104 double violFact = sigmaNw / sigmaMx;
1105 if (violFact < 9.99) cout << fixed;
1106 else cout << scientific;
1107 cout <<
" PYTHIA Maximum for " << sigmaProcessPtr->name()
1108 <<
" exceeded by factor " << setprecision(3) << violFact << endl;
1114 if (sigmaNw < sigmaNeg) {
1115 infoPtr->errorMsg(
"Warning in PhaseSpace2to2tauyz::trialKin:"
1116 " negative cross section set 0",
"for " + sigmaProcessPtr->name() );
1120 if (showViolation) cout <<
" PYTHIA Negative minimum for "
1121 << sigmaProcessPtr->name() <<
" changed to " << scientific
1122 << setprecision(3) << sigmaNeg << endl;
1124 if (sigmaNw < 0.) sigmaNw = 0.;
1127 biasWt = (canBiasSelection) ? userHooksPtr->biasedSelectionWeight() : 1.;
1128 if (canBias2Sel) biasWt /= pow( pTH / bias2SelRef, bias2SelPow);
1138 bool PhaseSpace::limitTau(
bool is2,
bool is3) {
1141 if (hasTwoPointParticles) {
1148 tauMin = sHatMin / s;
1149 if (is2 && hasQ2Min && Q2GlobalMin + s3 + s4 > sHatMin)
1150 tauMin = (Q2GlobalMin + s3 + s4) / s;
1151 tauMax = (mHatMax < mHatMin) ? 1. : min( 1., sHatMax / s);
1155 double mT3Min = sqrt(s3 + pT2HatMin);
1156 double mT4Min = sqrt(s4 + pT2HatMin);
1157 double mT5Min = (is3) ? sqrt(s5 + pT2HatMin) : 0.;
1158 tauMin = max( tauMin, pow2(mT3Min + mT4Min + mT5Min) / s);
1162 return (tauMax > tauMin);
1169 bool PhaseSpace::limitY() {
1172 if (hasTwoPointParticles) {
1178 yMax = -0.5 * log(tau);
1179 if (hasOnePointParticle)
return true;
1182 double yMaxMargin = (hasTwoLeptonBeams) ? yMax + LEPTONXLOGMAX : yMax;
1185 return (yMaxMargin > 0.);
1192 bool PhaseSpace::limitZ() {
1199 zMax = sqrtpos( 1. - pT2HatMin / p2Abs );
1200 if (pTHatMax > pTHatMin) zMin = sqrtpos( 1. - pT2HatMax / p2Abs );
1205 if (zMax < zMin)
return false;
1217 double zMaxQ2 = (sH - s3 - s4 - 2. * Q2GlobalMin) / (2. * pAbs * mHat);
1218 if (zMaxQ2 > zPosMin) {
1219 if (zMaxQ2 < zPosMax) zPosMax = zMaxQ2;
1223 if (zMaxQ2 > zNegMin) {
1224 if (zMaxQ2 < zNegMax) zNegMax = zMaxQ2;
1240 void PhaseSpace::selectTau(
int iTau,
double tauVal,
bool is2) {
1243 if (hasTwoPointParticles) {
1249 p2Abs = 0.25 * (pow2(sH - s3 - s4) - 4. * s3 * s4) / sH;
1250 pAbs = sqrtpos( p2Abs );
1260 tRatA = ((tauResA + tauMax) / (tauResA + tauMin)) * (tauMin / tauMax);
1261 aLowA = atan( (tauMin - tauResA) / widResA);
1262 aUppA = atan( (tauMax - tauResA) / widResA);
1268 tRatB = ((tauResB + tauMax) / (tauResB + tauMin)) * (tauMin / tauMax);
1269 aLowB = atan( (tauMin - tauResB) / widResB);
1270 aUppB = atan( (tauMax - tauResB) / widResB);
1276 if (hasTwoLeptonBeams) {
1277 aLowT = log( max( LEPTONTAUMIN, 1. - tauMin) );
1278 aUppT = log( max( LEPTONTAUMIN, 1. - tauMax) );
1279 intTau6 = aLowT - aUppT;
1283 if (iTau == 0) tau = tauMin * pow( tauMax / tauMin, tauVal);
1284 else if (iTau == 1) tau = tauMax * tauMin
1285 / (tauMin + (tauMax - tauMin) * tauVal);
1288 else if (hasTwoLeptonBeams && iTau == nTau - 1)
1289 tau = 1. - exp( aUppT + intTau6 * tauVal );
1293 else if (iTau == 2) tau = tauResA * tauMin
1294 / ((tauResA + tauMin) * pow( tRatA, tauVal) - tauMin);
1295 else if (iTau == 3) tau = tauResA + widResA
1296 * tan( aLowA + (aUppA - aLowA) * tauVal);
1297 else if (iTau == 4) tau = tauResB * tauMin
1298 / ((tauResB + tauMin) * pow( tRatB, tauVal) - tauMin);
1299 else if (iTau == 5) tau = tauResB + widResB
1300 * tan( aLowB + (aUppB - aLowB) * tauVal);
1303 intTau0 = log( tauMax / tauMin);
1304 intTau1 = (tauMax - tauMin) / (tauMax * tauMin);
1305 double invWtTau = (tauCoef[0] / intTau0) + (tauCoef[1] / intTau1) / tau;
1307 intTau2 = -log(tRatA) / tauResA;
1308 intTau3 = (aUppA - aLowA) / widResA;
1309 invWtTau += (tauCoef[2] / intTau2) / (tau + tauResA)
1310 + (tauCoef[3] / intTau3) * tau / ( pow2(tau - tauResA) + pow2(widResA) );
1313 intTau4 = -log(tRatB) / tauResB;
1314 intTau5 = (aUppB - aLowB) / widResB;
1315 invWtTau += (tauCoef[4] / intTau4) / (tau + tauResB)
1316 + (tauCoef[5] / intTau5) * tau / ( pow2(tau - tauResB) + pow2(widResB) );
1318 if (hasTwoLeptonBeams)
1319 invWtTau += (tauCoef[nTau - 1] / intTau6)
1320 * tau / max( LEPTONTAUMIN, 1. - tau);
1321 wtTau = 1. / invWtTau;
1327 p2Abs = 0.25 * (pow2(sH - s3 - s4) - 4. * s3 * s4) / sH;
1328 pAbs = sqrtpos( p2Abs );
1337 void PhaseSpace::selectY(
int iY,
double yVal) {
1340 if (hasTwoPointParticles) {
1349 if (hasOnePointParticle) {
1350 if (hasLeptonBeamA || hasPointGammaA) {
1364 if (hasTwoLeptonBeams && iY > 2) iY += 2;
1367 double expYMax = exp( yMax );
1368 double expYMin = exp(-yMax );
1369 double atanMax = atan( expYMax );
1370 double atanMin = atan( expYMin );
1371 double aUppY = (hasTwoLeptonBeams)
1372 ? log( max( LEPTONXMIN, LEPTONXMAX / tau - 1. ) ) : 0.;
1373 double aLowY = LEPTONXLOGMIN;
1376 if (iY == 0) y = log( tan( atanMin + (atanMax - atanMin) * yVal ) );
1379 else if (iY <= 2) y = yMax * (2. * sqrt(yVal) - 1.);
1382 else if (iY <= 4) y = log( expYMin + (expYMax - expYMin) * yVal );
1385 else y = yMax - log( 1. + exp(aLowY + (aUppY - aLowY) * yVal) );
1388 if (iY == 2 || iY == 4 || iY == 6) y = -y;
1391 intY0 = 2. * (atanMax - atanMin);
1392 intY12 = 0.5 * pow2(2. * yMax);
1393 intY34 = expYMax - expYMin;
1394 intY56 = aUppY - aLowY;
1395 double invWtY = (yCoef[0] / intY0) / cosh(y)
1396 + (yCoef[1] / intY12) * (y + yMax) + (yCoef[2] / intY12) * (yMax - y);
1397 if (!hasTwoLeptonBeams) invWtY
1398 += (yCoef[3] / intY34) * exp(y) + (yCoef[4] / intY34) * exp(-y);
1400 += (yCoef[3] / intY56) / max( LEPTONXMIN, 1. - exp( y - yMax) )
1401 + (yCoef[4] / intY56) / max( LEPTONXMIN, 1. - exp(-y - yMax) );
1405 x1H = sqrt(tau) * exp(y);
1406 x2H = sqrt(tau) * exp(-y);
1416 void PhaseSpace::selectZ(
int iZ,
double zVal) {
1419 ratio34 = max(TINY, 2. * s3 * s4 / pow2(sH));
1420 unity34 = 1. + ratio34;
1421 double ratiopT2 = 2. * pT2HatMin / max( SHATMINZ, sH);
1422 if (ratiopT2 < PT2RATMINZ) ratio34 = max( ratio34, ratiopT2);
1425 double zNegMinM = max(ratio34, unity34 - zNegMin);
1426 double zNegMaxM = max(ratio34, unity34 - zNegMax);
1427 double zPosMinM = max(ratio34, unity34 - zPosMin);
1428 double zPosMaxM = max(ratio34, unity34 - zPosMax);
1429 double zNegMinP = max(ratio34, unity34 + zNegMin);
1430 double zNegMaxP = max(ratio34, unity34 + zNegMax);
1431 double zPosMinP = max(ratio34, unity34 + zPosMin);
1432 double zPosMaxP = max(ratio34, unity34 + zPosMax);
1436 double area0Neg = zNegMax - zNegMin;
1437 double area0Pos = zPosMax - zPosMin;
1438 double area0 = area0Neg + area0Pos;
1440 double area1Neg = log(zNegMinM / zNegMaxM);
1441 double area1Pos = log(zPosMinM / zPosMaxM);
1442 double area1 = area1Neg + area1Pos;
1444 double area2Neg = log(zNegMaxP / zNegMinP);
1445 double area2Pos = log(zPosMaxP / zPosMinP);
1446 double area2 = area2Neg + area2Pos;
1448 double area3Neg = 1. / zNegMaxM - 1. / zNegMinM;
1449 double area3Pos = 1. / zPosMaxM - 1. / zPosMinM;
1450 double area3 = area3Neg + area3Pos;
1452 double area4Neg = 1. / zNegMinP - 1. / zNegMaxP;
1453 double area4Pos = 1. / zPosMinP - 1. / zPosMaxP;
1454 double area4 = area4Neg + area4Pos;
1459 if (!hasPosZ || zVal * area0 < area0Neg) {
1460 double zValMod = zVal * area0 / area0Neg;
1461 z = zNegMin + zValMod * area0Neg;
1463 double zValMod = (zVal * area0 - area0Neg) / area0Pos;
1464 z = zPosMin + zValMod * area0Pos;
1468 }
else if (iZ == 1) {
1469 if (!hasPosZ || zVal * area1 < area1Neg) {
1470 double zValMod = zVal * area1 / area1Neg;
1471 z = unity34 - zNegMinM * pow(zNegMaxM / zNegMinM, zValMod);
1473 double zValMod = (zVal * area1 - area1Neg)/ area1Pos;
1474 z = unity34 - zPosMinM * pow(zPosMaxM / zPosMinM, zValMod);
1478 }
else if (iZ == 2) {
1479 if (!hasPosZ || zVal * area2 < area2Neg) {
1480 double zValMod = zVal * area2 / area2Neg;
1481 z = zNegMinP * pow(zNegMaxP / zNegMinP, zValMod) - unity34;
1483 double zValMod = (zVal * area2 - area2Neg)/ area2Pos;
1484 z = zPosMinP * pow(zPosMaxP / zPosMinP, zValMod) - unity34;
1488 }
else if (iZ == 3) {
1489 if (!hasPosZ || zVal * area3 < area3Neg) {
1490 double zValMod = zVal * area3 / area3Neg;
1491 z = unity34 - 1. / (1./zNegMinM + area3Neg * zValMod);
1493 double zValMod = (zVal * area3 - area3Neg)/ area3Pos;
1494 z = unity34 - 1. / (1./zPosMinM + area3Pos * zValMod);
1498 }
else if (iZ == 4) {
1499 if (!hasPosZ || zVal * area4 < area4Neg) {
1500 double zValMod = zVal * area4 / area4Neg;
1501 z = 1. / (1./zNegMinP - area4Neg * zValMod) - unity34;
1503 double zValMod = (zVal * area4 - area4Neg)/ area4Pos;
1504 z = 1. / (1./zPosMinP - area4Pos * zValMod) - unity34;
1509 if (z < 0.) z = min( zNegMax, max( zNegMin, z));
1510 else z = min( zPosMax, max( zPosMin, z) );
1511 zNeg = max(ratio34, unity34 - z);
1512 zPos = max(ratio34, unity34 + z);
1515 wtZ = mHat * pAbs / ( (zCoef[0] / area0) + (zCoef[1] / area1) / zNeg
1516 + (zCoef[2] / area2) / zPos + (zCoef[3] / area3) / pow2(zNeg)
1517 + (zCoef[4] / area4) / pow2(zPos) );
1520 double sH34 = -0.5 * (sH - s3 - s4);
1521 double tHuH = pow2(sH34) * (1. - z) * (1. + z) + s3 * s4 * pow2(z);
1523 tH = sH34 + mHat * pAbs * z;
1526 uH = sH34 - mHat * pAbs * z;
1529 pTH = sqrtpos( (tH * uH - s3 * s4) / sH);
1538 bool PhaseSpace::select3Body() {
1541 double m35S = pow2(m3 + m5);
1542 double pT4Smax = 0.25 * ( pow2(sH - s4 - m35S) - 4. * s4 * m35S ) / sH;
1543 if (pTHatMax > pTHatMin) pT4Smax = min( pT2HatMax, pT4Smax);
1544 double pT4Smin = pT2HatMin;
1545 double m34S = pow2(m3 + m4);
1546 double pT5Smax = 0.25 * ( pow2(sH - s5 - m34S) - 4. * s5 * m34S ) / sH;
1547 if (pTHatMax > pTHatMin) pT5Smax = min( pT2HatMax, pT5Smax);
1548 double pT5Smin = pT2HatMin;
1551 if ( pT4Smax < pow2(pTHatMin + MASSMARGIN) )
return false;
1552 if ( pT5Smax < pow2(pTHatMin + MASSMARGIN) )
return false;
1555 double pTSmaxProp = pT4Smax + sTchan1;
1556 double pTSminProp = pT4Smin + sTchan1;
1557 double pTSratProp = pTSmaxProp / pTSminProp;
1558 double pTSdiff = pT4Smax - pT4Smin;
1559 double rShape = rndmPtr->flat();
1561 if (rShape < frac3Flat) pT4S = pT4Smin + rndmPtr->flat() * pTSdiff;
1562 else if (rShape < frac3Flat + frac3Pow1) pT4S = max( pT2HatMin,
1563 pTSminProp * pow( pTSratProp, rndmPtr->flat() ) - sTchan1 );
1564 else pT4S = max( pT2HatMin, pTSminProp * pTSmaxProp
1565 / (pTSminProp + rndmPtr->flat()* pTSdiff) - sTchan1 );
1566 double wt4 = pTSdiff / ( frac3Flat
1567 + frac3Pow1 * pTSdiff / (log(pTSratProp) * (pT4S + sTchan1))
1568 + frac3Pow2 * pTSminProp * pTSmaxProp / pow2(pT4S + sTchan1) );
1571 pTSmaxProp = pT5Smax + sTchan2;
1572 pTSminProp = pT5Smin + sTchan2;
1573 pTSratProp = pTSmaxProp / pTSminProp;
1574 pTSdiff = pT5Smax - pT5Smin;
1575 rShape = rndmPtr->flat();
1577 if (rShape < frac3Flat) pT5S = pT5Smin + rndmPtr->flat() * pTSdiff;
1578 else if (rShape < frac3Flat + frac3Pow1) pT5S = max( pT2HatMin,
1579 pTSminProp * pow( pTSratProp, rndmPtr->flat() ) - sTchan2 );
1580 else pT5S = max( pT2HatMin, pTSminProp * pTSmaxProp
1581 / (pTSminProp + rndmPtr->flat()* pTSdiff) - sTchan2 );
1582 double wt5 = pTSdiff / ( frac3Flat
1583 + frac3Pow1 * pTSdiff / (log(pTSratProp) * (pT5S + sTchan2))
1584 + frac3Pow2 * pTSminProp * pTSmaxProp / pow2(pT5S + sTchan2) );
1587 double phi4 = 2. * M_PI * rndmPtr->flat();
1588 double phi5 = 2. * M_PI * rndmPtr->flat();
1589 double pT3S = max( 0., pT4S + pT5S + 2. * sqrt(pT4S * pT5S)
1590 * cos(phi4 - phi5) );
1591 if ( pT3S < pT2HatMin || (pTHatMax > pTHatMin && pT3S > pT2HatMax) )
1595 double sT3 = s3 + pT3S;
1596 double sT4 = s4 + pT4S;
1597 double sT5 = s5 + pT5S;
1598 double mT3 = sqrt(sT3);
1599 double mT4 = sqrt(sT4);
1600 double mT5 = sqrt(sT5);
1601 if ( mT3 + mT4 + mT5 + MASSMARGIN > mHat )
return false;
1604 double m45S = pow2(mT4 + mT5);
1605 double y3max = log( ( sH + sT3 - m45S + sqrtpos( pow2(sH - sT3 - m45S)
1606 - 4 * sT3 * m45S ) ) / (2. * mHat * mT3) );
1607 if (y3max < YRANGEMARGIN)
return false;
1608 double y3 = (2. * rndmPtr->flat() - 1.) * (1. - YRANGEMARGIN) * y3max;
1609 double pz3 = mT3 * sinh(y3);
1610 double e3 = mT3 * cosh(y3);
1614 double e45 = mHat - e3;
1615 double sT45 = e45 * e45 - pz45 * pz45;
1616 double lam45 = sqrtpos( pow2(sT45 - sT4 - sT5) - 4. * sT4 * sT5 );
1617 if (lam45 < YRANGEMARGIN * sH)
return false;
1618 double lam4e = sT45 + sT4 - sT5;
1619 double lam5e = sT45 + sT5 - sT4;
1620 double tFac = -0.5 * mHat / sT45;
1621 double t1Pos = tFac * (e45 - pz45) * (lam4e - lam45);
1622 double t1Neg = tFac * (e45 - pz45) * (lam4e + lam45);
1623 double t2Pos = tFac * (e45 + pz45) * (lam5e - lam45);
1624 double t2Neg = tFac * (e45 + pz45) * (lam5e + lam45);
1627 double wtPosUnnorm = 1.;
1628 double wtNegUnnorm = 1.;
1629 if (useMirrorWeight) {
1630 wtPosUnnorm = 1./ pow2( (t1Pos - sTchan1) * (t2Pos - sTchan2) );
1631 wtNegUnnorm = 1./ pow2( (t1Neg - sTchan1) * (t2Neg - sTchan2) );
1633 double wtPos = wtPosUnnorm / (wtPosUnnorm + wtNegUnnorm);
1634 double wtNeg = wtNegUnnorm / (wtPosUnnorm + wtNegUnnorm);
1635 double epsilon = (rndmPtr->flat() < wtPos) ? 1. : -1.;
1638 double px4 = sqrt(pT4S) * cos(phi4);
1639 double py4 = sqrt(pT4S) * sin(phi4);
1640 double px5 = sqrt(pT5S) * cos(phi5);
1641 double py5 = sqrt(pT5S) * sin(phi5);
1642 double pz4 = 0.5 * (pz45 * lam4e + epsilon * e45 * lam45) / sT45;
1643 double pz5 = pz45 - pz4;
1644 double e4 = sqrt(sT4 + pz4 * pz4);
1645 double e5 = sqrt(sT5 + pz5 * pz5);
1646 p3cm = Vec4( -(px4 + px5), -(py4 + py5), pz3, e3);
1647 p4cm = Vec4( px4, py4, pz4, e4);
1648 p5cm = Vec4( px5, py5, pz5, e5);
1651 wt3Body = wt4 * wt5 * (2. * y3max) / (128. * pow3(M_PI) * lam45);
1652 wt3Body *= (epsilon > 0.) ? 1. / wtPos : 1. / wtNeg;
1655 wt3Body /= (2. * sH);
1666 void PhaseSpace::solveSys(
int n,
int bin[8],
double vec[8],
1667 double mat[8][8],
double coef[8]) {
1671 cout <<
"\n Equation system: " << setw(5) << bin[0];
1672 for (
int j = 0; j < n; ++j) cout << setw(12) << mat[0][j];
1673 cout << setw(12) << vec[0] <<
"\n";
1674 for (
int i = 1; i < n; ++i) {
1675 cout <<
" " << setw(5) << bin[i];
1676 for (
int j = 0; j < n; ++j) cout << setw(12) << mat[i][j];
1677 cout << setw(12) << vec[i] <<
"\n";
1682 double vecNor[8], coefTmp[8];
1683 for (
int i = 0; i < n; ++i) coefTmp[i] = 0.;
1686 bool canSolve =
true;
1687 for (
int i = 0; i < n; ++i)
if (bin[i] == 0) canSolve =
false;
1689 for (
int i = 0; i < n; ++i) vecSum += vec[i];
1690 if (abs(vecSum) < TINY) canSolve =
false;
1694 for (
int i = 0; i < n; ++i) vecNor[i] = max( 0.1, vec[i] / vecSum);
1695 for (
int k = 0; k < n - 1; ++k) {
1696 for (
int i = k + 1; i < n; ++i) {
1697 if (abs(mat[k][k]) < TINY) {canSolve =
false;
break;}
1698 double ratio = mat[i][k] / mat[k][k];
1699 vec[i] -= ratio * vec[k];
1700 for (
int j = k; j < n; ++j) mat[i][j] -= ratio * mat[k][j];
1702 if (!canSolve)
break;
1705 for (
int k = n - 1; k >= 0; --k) {
1706 for (
int j = k + 1; j < n; ++j) vec[k] -= mat[k][j] * coefTmp[j];
1707 coefTmp[k] = vec[k] / mat[k][k];
1713 if (!canSolve)
for (
int i = 0; i < n; ++i) {
1716 if (vecSum > TINY) vecNor[i] = max(0.1, vec[i] / vecSum);
1720 double coefSum = 0.;
1722 for (
int i = 0; i < n; ++i) {
1723 coefTmp[i] = max( 0., coefTmp[i]);
1724 coefSum += coefTmp[i];
1725 vecSum += vecNor[i];
1727 if (coefSum > 0.)
for (
int i = 0; i < n; ++i) coef[i] = EVENFRAC / n
1728 + (1. - EVENFRAC) * 0.5 * (coefTmp[i] / coefSum + vecNor[i] / vecSum);
1729 else for (
int i = 0; i < n; ++i) coef[i] = 1. / n;
1733 cout <<
" Solution: ";
1734 for (
int i = 0; i < n; ++i) cout << setw(12) << coef[i];
1743 void PhaseSpace::setupMass1(
int iM) {
1746 if (iM == 3) idMass[iM] = abs(sigmaProcessPtr->id3Mass());
1747 if (iM == 4) idMass[iM] = abs(sigmaProcessPtr->id4Mass());
1748 if (iM == 5) idMass[iM] = abs(sigmaProcessPtr->id5Mass());
1751 if (idMass[iM] == 0) {
1757 mPeak[iM] = particleDataPtr->m0(idMass[iM]);
1758 mWidth[iM] = particleDataPtr->mWidth(idMass[iM]);
1759 mMin[iM] = max( MRESMINABS, particleDataPtr->mMin(idMass[iM]) );
1760 mMax[iM] = particleDataPtr->mMax(idMass[iM]);
1762 if (idMass[iM] == 23 && gmZmode == 1) mPeak[iM] = mMin[iM];
1766 sPeak[iM] = mPeak[iM] * mPeak[iM];
1767 useBW[iM] = useBreitWigners && (mWidth[iM] > minWidthBreitWigners);
1768 useNarrowBW[iM] = useBreitWigners && !useBW[iM]
1769 && (mWidth[iM] > minWidthNarrowBW);
1770 if (!useBW[iM] && !useNarrowBW[iM]) mWidth[iM] = 0.;
1771 mw[iM] = mPeak[iM] * mWidth[iM];
1772 wmRat[iM] = (idMass[iM] == 0 || mPeak[iM] == 0.)
1773 ? 0. : mWidth[iM] / mPeak[iM];
1777 mLower[iM] = mMin[iM];
1778 mUpper[iM] = mHatMax;
1787 void PhaseSpace::setupMass2(
int iM,
double distToThresh) {
1790 if (mMax[iM] > mMin[iM]) mUpper[iM] = min( mUpper[iM], mMax[iM]);
1791 sLower[iM] = mLower[iM] * mLower[iM];
1792 sUpper[iM] = mUpper[iM] * mUpper[iM];
1796 if (distToThresh > THRESHOLDSIZE) {
1797 fracFlatS[iM] = 0.1;
1798 fracFlatM[iM] = 0.1;
1800 }
else if (distToThresh > - THRESHOLDSIZE) {
1801 fracFlatS[iM] = 0.25 - 0.15 * distToThresh / THRESHOLDSIZE;
1802 fracInv [iM] = 0.15 - 0.05 * distToThresh / THRESHOLDSIZE;
1804 fracFlatS[iM] = 0.3;
1805 fracFlatM[iM] = 0.1;
1811 if (idMass[iM] == 23 && gmZmode == 0) {
1812 fracFlatS[iM] *= 0.5;
1813 fracFlatM[iM] *= 0.5;
1814 fracInv[iM] = 0.5 * fracInv[iM] + 0.25;
1815 fracInv2[iM] = 0.25;
1816 }
else if (idMass[iM] == 23 && gmZmode == 1) {
1817 fracFlatS[iM] = 0.1;
1818 fracFlatM[iM] = 0.1;
1820 fracInv2[iM] = 0.35;
1824 atanLower[iM] = atan( (sLower[iM] - sPeak[iM])/ mw[iM] );
1825 atanUpper[iM] = atan( (sUpper[iM] - sPeak[iM])/ mw[iM] );
1826 intBW[iM] = atanUpper[iM] - atanLower[iM];
1827 intFlatS[iM] = sUpper[iM] - sLower[iM];
1828 intFlatM[iM] = mUpper[iM] - mLower[iM];
1829 intInv[iM] = log( sUpper[iM] / sLower[iM] );
1830 intInv2[iM] = 1./sLower[iM] - 1./sUpper[iM];
1838 void PhaseSpace::trialMass(
int iM) {
1841 double& mSet = (iM == 3) ? m3 : ( (iM == 4) ? m4 : m5 );
1842 double& sSet = (iM == 3) ? s3 : ( (iM == 4) ? s4 : s5 );
1846 double pickForm = rndmPtr->flat();
1847 if (pickForm > fracFlatS[iM] + fracFlatM[iM] + fracInv[iM] + fracInv2[iM])
1848 sSet = sPeak[iM] + mw[iM] * tan( atanLower[iM]
1849 + rndmPtr->flat() * intBW[iM] );
1850 else if (pickForm > fracFlatM[iM] + fracInv[iM] + fracInv2[iM])
1851 sSet = sLower[iM] + rndmPtr->flat() * (sUpper[iM] - sLower[iM]);
1852 else if (pickForm > fracInv[iM] + fracInv2[iM])
1853 sSet = pow2(mLower[iM] + rndmPtr->flat() * (mUpper[iM] - mLower[iM]));
1854 else if (pickForm > fracInv2[iM])
1855 sSet = sLower[iM] * pow( sUpper[iM] / sLower[iM], rndmPtr->flat() );
1856 else sSet = sLower[iM] * sUpper[iM]
1857 / (sLower[iM] + rndmPtr->flat() * (sUpper[iM] - sLower[iM]));
1861 }
else if (useNarrowBW[iM]) {
1862 mSet = particleDataPtr->mSel(idMass[iM]);
1882 double PhaseSpace::weightMass(
int iM) {
1885 double& mSet = (iM == 3) ? m3 : ( (iM == 4) ? m4 : m5 );
1886 double& sSet = (iM == 3) ? s3 : ( (iM == 4) ? s4 : s5 );
1887 double& runBWH = (iM == 3) ? runBW3H : ( (iM == 4) ? runBW4H : runBW5H );
1891 if (!useBW[iM])
return 1.;
1895 = (1. - fracFlatS[iM] - fracFlatM[iM] - fracInv[iM] - fracInv2[iM])
1896 * mw[iM] / ( (pow2(sSet - sPeak[iM]) + pow2(mw[iM])) * intBW[iM])
1897 + fracFlatS[iM] / intFlatS[iM]
1898 + fracFlatM[iM] / (2. * mSet * intFlatM[iM])
1899 + fracInv[iM] / (sSet * intInv[iM])
1900 + fracInv2[iM] / (sSet*sSet * intInv2[iM]);
1903 double mwRun = sSet * wmRat[iM];
1908 runBWH = mwRun / (pow2(sSet - sPeak[iM]) + pow2(mwRun)) / M_PI;
1911 return (runBWH / genBW);
1924 bool PhaseSpace2to1tauy::setupMass() {
1927 gmZmode = gmZmodeGlobal;
1928 int gmZmodeProc = sigmaProcessPtr->gmZmode();
1929 if (gmZmodeProc >= 0) gmZmode = gmZmodeProc;
1932 int idRes = abs(sigmaProcessPtr->resonanceA());
1933 int idTmp = abs(sigmaProcessPtr->resonanceB());
1934 if (idTmp > 0) idRes = idTmp;
1935 double mResMin = (idRes == 0) ? 0. : particleDataPtr->mMin(idRes);
1936 double mResMax = (idRes == 0) ? 0. : particleDataPtr->mMax(idRes);
1939 mHatMin = max( mResMin, mHatGlobalMin);
1940 sHatMin = mHatMin*mHatMin;
1942 if (mResMax > mResMin) mHatMax = min( mHatMax, mResMax);
1943 if (mHatGlobalMax > mHatGlobalMin) mHatMax = min( mHatMax, mHatGlobalMax);
1944 sHatMax = mHatMax*mHatMax;
1950 return (mHatMax > mHatMin + MASSMARGIN);
1958 bool PhaseSpace2to1tauy::finalKin() {
1966 pH[1] = Vec4( 0., 0., 0.5 * eCM * x1H, 0.5 * eCM * x1H);
1967 pH[2] = Vec4( 0., 0., -0.5 * eCM * x2H, 0.5 * eCM * x2H);
1968 pH[3] = pH[1] + pH[2];
1983 bool PhaseSpace2to2tauyz::setupMasses() {
1986 gmZmode = gmZmodeGlobal;
1987 int gmZmodeProc = sigmaProcessPtr->gmZmode();
1988 if (gmZmodeProc >= 0) gmZmode = gmZmodeProc;
1991 mHatMin = mHatGlobalMin;
1992 sHatMin = mHatMin*mHatMin;
1994 if (mHatGlobalMax > mHatGlobalMin) mHatMax = min( eCM, mHatGlobalMax);
1995 sHatMax = mHatMax*mHatMax;
2002 if (useBW[3]) mUpper[3] -= (useBW[4]) ? mMin[4] : mPeak[4];
2003 if (useBW[4]) mUpper[4] -= (useBW[3]) ? mMin[3] : mPeak[3];
2006 bool physical =
true;
2007 if (useBW[3] && mUpper[3] < mLower[3] + MASSMARGIN) physical =
false;
2008 if (useBW[4] && mUpper[4] < mLower[4] + MASSMARGIN) physical =
false;
2009 if (!useBW[3] && !useBW[4] && mHatMax < mPeak[3] + mPeak[4] + MASSMARGIN)
2011 if (!physical)
return false;
2014 pTHatMin = pTHatGlobalMin;
2015 if (mPeak[3] < pTHatMinDiverge || mPeak[4] < pTHatMinDiverge)
2016 pTHatMin = max( pTHatMin, pTHatMinDiverge);
2017 pT2HatMin = pTHatMin * pTHatMin;
2018 pTHatMax = pTHatGlobalMax;
2019 pT2HatMax = pTHatMax * pTHatMax;
2023 double distToThreshA = (mHatMax - mPeak[3] - mPeak[4]) * mWidth[3]
2024 / (pow2(mWidth[3]) + pow2(mWidth[4]));
2025 double distToThreshB = (mHatMax - mPeak[3] - mMin[4]) / mWidth[3];
2026 double distToThresh = min( distToThreshA, distToThreshB);
2027 setupMass2(3, distToThresh);
2032 double distToThreshA = (mHatMax - mPeak[3] - mPeak[4]) * mWidth[4]
2033 / (pow2(mWidth[3]) + pow2(mWidth[4]));
2034 double distToThreshB = (mHatMax - mMin[3] - mPeak[4]) / mWidth[4];
2035 double distToThresh = min( distToThreshA, distToThreshB);
2036 setupMass2(4, distToThresh);
2040 m3 = (useBW[3]) ? min(mPeak[3], mUpper[3]) : mPeak[3];
2041 m4 = (useBW[4]) ? min(mPeak[4], mUpper[4]) : mPeak[4];
2042 if (m3 + m4 + THRESHOLDSIZE * (mWidth[3] + mWidth[4]) + MASSMARGIN
2044 if (useBW[3] && useBW[4]) physical = constrainedM3M4();
2045 else if (useBW[3]) physical = constrainedM3();
2046 else if (useBW[4]) physical = constrainedM4();
2054 if (useBW[3]) wtBW *= weightMass(3) * EXTRABWWTMAX;
2055 if (useBW[4]) wtBW *= weightMass(4) * EXTRABWWTMAX;
2067 bool PhaseSpace2to2tauyz::trialMasses() {
2078 if (m3 + m4 + MASSMARGIN > mHatMax)
return false;
2081 if (useBW[3]) wtBW *= weightMass(3);
2082 if (useBW[4]) wtBW *= weightMass(4);
2092 bool PhaseSpace2to2tauyz::finalKin() {
2095 int id3 = sigmaProcessPtr->id(3);
2096 int id4 = sigmaProcessPtr->id(4);
2097 if (idMass[3] == 0) { m3 = particleDataPtr->m0(id3); s3 = m3*m3; }
2098 if (idMass[4] == 0) { m4 = particleDataPtr->m0(id4); s4 = m4*m4; }
2101 if (sigmaProcessPtr->swappedTU()) {
2107 if (m3 + m4 + MASSMARGIN > mHat) {
2108 infoPtr->errorMsg(
"Warning in PhaseSpace2to2tauyz::finalKin: "
2109 "failed after mass assignment");
2112 p2Abs = 0.25 * (pow2(sH - s3 - s4) - 4. * s3 * s4) / sH;
2113 pAbs = sqrtpos( p2Abs );
2123 if ( hasPointGammaA && (beamBPtr->isHadron()
2124 && !flag(
"PDF:beamB2gamma") ) ) {
2125 double eCM1 = 0.5 * ( s + pow2(mA) - pow2(mB) ) / eCM;
2126 double eCM2 = 0.25 * x2H * s / eCM1;
2127 pH[1] = Vec4( 0., 0., eCM1, eCM1);
2128 pH[2] = Vec4( 0., 0., -eCM2, eCM2);
2129 }
else if ( hasPointGammaB && (beamAPtr->isHadron()
2130 && !flag(
"PDF:beamA2gamma") ) ) {
2131 double eCM2 = 0.5 * ( s - pow2(mA) + pow2(mB) ) / eCM;
2132 double eCM1 = 0.25 * x1H * s / eCM2;
2133 pH[1] = Vec4( 0., 0., eCM1, eCM1);
2134 pH[2] = Vec4( 0., 0., -eCM2, eCM2);
2137 }
else if ( ( (beamAPtr->isLepton() && beamBPtr->isHadron())
2138 || (beamBPtr->isLepton() && beamAPtr->isHadron()) )
2139 && !(flag(
"PDF:beamA2gamma") || flag(
"PDF:beamB2gamma") ) ) {
2142 double pzAcm = 0.5 * sqrtpos( (eCM + mA + mB) * (eCM - mA - mB)
2143 * (eCM - mA + mB) * (eCM + mA - mB) ) / eCM;
2144 double eAcm = sqrt( mH[1]*mH[1] + pzAcm*pzAcm);
2145 double pzBcm = -pzAcm;
2146 double eBcm = sqrt( mH[2]*mH[2] + pzBcm*pzBcm);
2147 pH[1] = Vec4( 0., 0., pzAcm * x1H, eAcm * x1H);
2148 pH[2] = Vec4( 0., 0., pzBcm * x2H, eBcm * x2H);
2152 pH[1] = Vec4( 0., 0., 0.5 * eCM * x1H, 0.5 * eCM * x1H);
2153 pH[2] = Vec4( 0., 0., -0.5 * eCM * x2H, 0.5 * eCM * x2H);
2157 pH[3] = Vec4( 0., 0., pAbs, 0.5 * (sH + s3 - s4) / mHat);
2158 pH[4] = Vec4( 0., 0., -pAbs, 0.5 * (sH + s4 - s3) / mHat);
2162 phi = 2. * M_PI * rndmPtr->flat();
2163 betaZ = (x1H - x2H)/(x1H + x2H);
2164 pH[3].rot( theta, phi);
2165 pH[4].rot( theta, phi);
2166 pH[3].bst( 0., 0., betaZ);
2167 pH[4].bst( 0., 0., betaZ);
2168 pTH = pAbs * sin(theta);
2181 bool PhaseSpace2to2tauyz::constrainedM3M4() {
2184 bool foundNonZero =
false;
2185 double wtMassMax = 0.;
2186 double m3WtMax = 0.;
2187 double m4WtMax = 0.;
2188 double xMax = (mHatMax - mLower[3] - mLower[4]) / (mWidth[3] + mWidth[4]);
2189 double xStep = THRESHOLDSTEP * min(1., xMax);
2191 double wtMassXbin, wtMassMaxOld, m34, mT34Min, wtMassNow,
2192 wtBW3Now, wtBW4Now, beta34Now;
2198 wtMassMaxOld = wtMassMax;
2199 m34 = mHatMax - xNow * (mWidth[3] + mWidth[4]);
2202 m3 = min( mUpper[3], m34 - mLower[4]);
2203 if (m3 > mPeak[3]) m3 = max( mLower[3], mPeak[3]);
2205 if (m4 < mLower[4]) {m4 = mLower[4]; m3 = m34 - m4;}
2208 mT34Min = sqrt(m3*m3 + pT2HatMin) + sqrt(m4*m4 + pT2HatMin);
2209 if (mT34Min < mHatMax) {
2213 if (m3 > mLower[3] && m3 < mUpper[3] && m4 > mLower[4]
2214 && m4 < mUpper[4]) {
2215 wtBW3Now = mw[3] / ( pow2(m3*m3 - sPeak[3]) + pow2(mw[3]) );
2216 wtBW4Now = mw[4] / ( pow2(m4*m4 - sPeak[4]) + pow2(mw[4]) );
2217 beta34Now = sqrt( pow2(mHatMax*mHatMax - m3*m3 - m4*m4)
2218 - pow2(2. * m3 * m4) ) / (mHatMax*mHatMax);
2219 wtMassNow = wtBW3Now * wtBW4Now * beta34Now;
2223 if (wtMassNow > wtMassXbin) wtMassXbin = wtMassNow;
2224 if (wtMassNow > wtMassMax) {
2225 foundNonZero =
true;
2226 wtMassMax = wtMassNow;
2233 m4 = min( mUpper[4], m34 - mLower[3]);
2234 if (m4 > mPeak[4]) m4 = max( mLower[4], mPeak[4]);
2236 if (m3 < mLower[3]) {m3 = mLower[3]; m4 = m34 - m3;}
2239 mT34Min = sqrt(m3*m3 + pT2HatMin) + sqrt(m4*m4 + pT2HatMin);
2240 if (mT34Min < mHatMax) {
2244 if (m3 > mLower[3] && m3 < mUpper[3] && m4 > mLower[4]
2245 && m4 < mUpper[4]) {
2246 wtBW3Now = mw[3] / ( pow2(m3*m3 - sPeak[3]) + pow2(mw[3]) );
2247 wtBW4Now = mw[4] / ( pow2(m4*m4 - sPeak[4]) + pow2(mw[4]) );
2248 beta34Now = sqrt( pow2(mHatMax*mHatMax - m3*m3 - m4*m4)
2249 - pow2(2. * m3 * m4) ) / (mHatMax*mHatMax);
2250 wtMassNow = wtBW3Now * wtBW4Now * beta34Now;
2254 if (wtMassNow > wtMassXbin) wtMassXbin = wtMassNow;
2255 if (wtMassNow > wtMassMax) {
2256 foundNonZero =
true;
2257 wtMassMax = wtMassNow;
2264 }
while ( (!foundNonZero || wtMassXbin > wtMassMaxOld)
2265 && xNow < xMax - xStep);
2270 return foundNonZero;
2280 bool PhaseSpace2to2tauyz::constrainedM3() {
2283 bool foundNonZero =
false;
2284 double wtMassMax = 0.;
2285 double m3WtMax = 0.;
2286 double mT4Min = sqrt(m4*m4 + pT2HatMin);
2287 double xMax = (mHatMax - mLower[3] - m4) / mWidth[3];
2288 double xStep = THRESHOLDSTEP * min(1., xMax);
2290 double wtMassNow, mT34Min, wtBW3Now, beta34Now;
2296 m3 = mHatMax - m4 - xNow * mWidth[3];
2299 mT34Min = sqrt(m3*m3 + pT2HatMin) + mT4Min;
2300 if (mT34Min < mHatMax) {
2303 wtBW3Now = mw[3] / ( pow2(m3*m3 - sPeak[3]) + pow2(mw[3]) );
2304 beta34Now = sqrt( pow2(mHatMax*mHatMax - m3*m3 - m4*m4)
2305 - pow2(2. * m3 * m4) ) / (mHatMax*mHatMax);
2306 wtMassNow = wtBW3Now * beta34Now;
2309 if (wtMassNow > wtMassMax) {
2310 foundNonZero =
true;
2311 wtMassMax = wtMassNow;
2317 }
while ( (!foundNonZero || wtMassNow > wtMassMax)
2318 && xNow < xMax - xStep);
2322 return foundNonZero;
2332 bool PhaseSpace2to2tauyz::constrainedM4() {
2335 bool foundNonZero =
false;
2336 double wtMassMax = 0.;
2337 double m4WtMax = 0.;
2338 double mT3Min = sqrt(m3*m3 + pT2HatMin);
2339 double xMax = (mHatMax - mLower[4] - m3) / mWidth[4];
2340 double xStep = THRESHOLDSTEP * min(1., xMax);
2342 double wtMassNow, mT34Min, wtBW4Now, beta34Now;
2348 m4 = mHatMax - m3 - xNow * mWidth[4];
2351 mT34Min = mT3Min + sqrt(m4*m4 + pT2HatMin);
2352 if (mT34Min < mHatMax) {
2355 wtBW4Now = mw[4] / ( pow2(m4*m4 - sPeak[4]) + pow2(mw[4]) );
2356 beta34Now = sqrt( pow2(mHatMax*mHatMax - m3*m3 - m4*m4)
2357 - pow2(2. * m3 * m4) ) / (mHatMax*mHatMax);
2358 wtMassNow = wtBW4Now * beta34Now;
2361 if (wtMassNow > wtMassMax) {
2362 foundNonZero =
true;
2363 wtMassMax = wtMassNow;
2369 }
while ( (!foundNonZero || wtMassNow > wtMassMax)
2370 && xNow < xMax - xStep);
2374 return foundNonZero;
2382 void PhaseSpace2to2tauyz::rescaleSigma(
double sHatNew){
2385 if ( idMass[3] == 0 ) s3 = 0.;
2386 if ( idMass[4] == 0 ) s4 = 0.;
2390 double sH34 = -0.5 * (sH - s3 - s4);
2391 p2Abs = 0.25 * (pow2(sH - s3 - s4) - 4. * s3 * s4) / sH;
2392 pAbs = sqrtpos( p2Abs );
2394 tH = sH34 + mHat * pAbs * z;
2395 uH = sH34 - mHat * pAbs * z;
2396 pTH = sqrtpos( (tH * uH - s3 * s4) / sH);
2400 if (sigmaNw > TINY) {
2401 sigmaProcessPtr->set2Kin( x1H, x2H, sH, tH, m3, m4, runBW3H, runBW4H);
2402 sigmaNw = sigmaProcessPtr->sigmaPDF(
false,
true);
2403 sigmaNw *= wtTau * wtY * wtZ * wtBW;
2404 if (canBias2Sel) sigmaNw *= pow( pTH / bias2SelRef, bias2SelPow);
2414 void PhaseSpace2to2tauyz::rescaleMomenta(
double sHatNew){
2417 for (
int i = 0; i <= 1; ++i){
2420 int iPartonA = (i == 0) ? 1 : 3;
2421 int iPartonB = (i == 0) ? 2 : 4;
2424 Vec4 pA = p( iPartonA);
2425 Vec4 pB = p( iPartonB);
2428 double m2A = pow2( m( iPartonA) );
2429 double m2B = pow2( m( iPartonB) );
2430 double eA = 0.5 * ( sHatNew + m2A - m2B) / sqrt( sHatNew);
2431 double eB = 0.5 * ( sHatNew + m2B - m2A) / sqrt( sHatNew);
2432 double pz = 0.5 * sqrtpos( pow2(sHatNew - m2A - m2B) - 4.0 * m2A * m2B )
2434 Vec4 pANew( 0, 0, pz, eA );
2435 Vec4 pBNew( 0, 0, -pz, eB );
2438 RotBstMatrix MtoCMinc;
2439 MtoCMinc.toCMframe( pA, pB);
2443 pANew.rotbst( MtoCMinc);
2444 pBNew.rotbst( MtoCMinc);
2445 setP( iPartonA, pANew);
2446 setP( iPartonB, pBNew);
2454 double PhaseSpace2to2tauyz::weightGammaPDFApprox(){
2457 if (beamAPtr->getGammaMode() == 2 && beamBPtr->getGammaMode() == 2)
2459 if ( (beamAPtr->getGammaMode() == 2 && !(beamBPtr->gammaInBeam()) )
2460 || (beamBPtr->getGammaMode() == 2 && !(beamAPtr->gammaInBeam()) ) )
2465 double x1GammaHadr = -1.;
2466 double x2GammaHadr = -1.;
2467 double x1Gamma = -1.;
2468 double x2Gamma = -1.;
2469 double x1Hadr = -1.;
2470 double x2Hadr = -1.;
2473 if ( beamAPtr->hasApproxGammaFlux() ) {
2474 x1GammaHadr = beamAPtr->xGammaHadr();
2475 x1Gamma = beamAPtr->xGamma();
2476 x1Hadr = x1GammaHadr / x1Gamma;
2478 if ( beamBPtr->hasApproxGammaFlux() ) {
2479 x2GammaHadr = beamBPtr->xGammaHadr();
2480 x2Gamma = beamBPtr->xGamma();
2481 x2Hadr = x2GammaHadr / x2Gamma;
2485 if ( !(beamAPtr->gammaInBeam()) || beamAPtr->getGammaMode() == 2 ) {
2489 if ( !(beamBPtr->gammaInBeam()) || beamBPtr->getGammaMode() == 2 ) {
2495 double sigmaOver = sigmaProcessPtr->sigmaPDF(
false,
false,
true,
2496 x1GammaHadr, x2GammaHadr);
2497 double sigmaCorr = sigmaProcessPtr->sigmaPDF(
false,
false,
true,
2501 if (sigmaOver < TINY)
return 0.;
2504 return sigmaCorr / sigmaOver;
2519 const int PhaseSpace2to2elastic::NTRY = 1000;
2522 const double PhaseSpace2to2elastic::BNARROW = 10.;
2523 const double PhaseSpace2to2elastic::BWIDE = 1.;
2524 const double PhaseSpace2to2elastic::WIDEFRAC = 0.1;
2525 const double PhaseSpace2to2elastic::TOFFSET = -0.2;
2532 bool PhaseSpace2to2elastic::setupSampling() {
2535 hasGamma = flag(
"PDF:beamA2gamma") || flag(
"PDF:beamB2gamma");
2538 hasVMD = infoPtr->isVMDstateA() || infoPtr->isVMDstateB();
2544 sigmaNw = sigmaProcessPtr->sigmaHatWrap();
2550 idAgm = gammaKinPtr->idInA();
2551 idBgm = gammaKinPtr->idInB();
2552 sigmaTotPtr->calc( idAgm, idBgm, eCM);
2553 sigmaProcessPtr->setIdInDiff(idAgm, idBgm);
2556 if (idAgm == 22) mA = 0.;
2557 if (idBgm == 22) mB = 0.;
2560 sigmaMxGm = sigmaTotPtr->sigmaEl();
2561 sigmaNw = gammaKinPtr->setupSoftPhaseSpaceSampling(sigmaMxGm);
2568 isOneExp = sigmaTotPtr->bElIsExp();
2569 useCoulomb = sigmaTotPtr->hasCoulomb();
2570 alphaEM0 = parm(
"StandardModel:alphaEM0");
2580 lambda12S = pow2(s - s1 - s2) - 4. * s1 * s2 ;
2581 tLow = - lambda12S / s;
2582 tUpp = (useCoulomb) ? -parm(
"SigmaElastic:tAbsMin") : 0.;
2586 bSlope1 = (isOneExp && !hasVMD) ? sigmaTotPtr->bSlopeEl() : BNARROW;
2588 sigRef1 = sigmaTotPtr->dsigmaEl( tUpp,
false);
2590 sigNorm1 = sigRef1 / bSlope1;
2591 if (useCoulomb) sigNorm1 *= 2.;
2594 sigRef2 = sigmaTotPtr->dsigmaEl( tUpp + TOFFSET,
false);
2595 sigRef = (sigRef1 > 2. * sigRef2) ? 2. * sigRef1 : 5. * sigRef2;
2596 rel2 = exp((bSlope2 - bSlope1) * tUpp) * WIDEFRAC / (1. - WIDEFRAC);
2597 sigNorm1 = sigRef / (bSlope1 + rel2 * bSlope2);
2598 sigNorm2 = sigNorm1 * rel2;
2600 sigNorm3 = (useCoulomb) ? -2. * HBARCSQ * 4. * M_PI * pow2(alphaEM0)
2602 sigNormSum = sigNorm1 + sigNorm2 + sigNorm3;
2614 bool PhaseSpace2to2elastic::trialKin(
bool,
bool ) {
2617 if (doEnergySpread) {
2618 eCM = infoPtr->eCM();
2621 lambda12S = pow2(s - s1 - s2) - 4. * s1 * s2 ;
2622 tLow = - lambda12S / s;
2634 if (!gammaKinPtr->trialKinSoftPhaseSpaceSampling() )
return false;
2637 double eCMsub = gammaKinPtr->eCMsub();
2638 sigmaTotPtr->calc( idAgm, idBgm, eCMsub );
2641 double sigmaW = sigmaTotPtr->sigmaEl();
2642 double wtSigma = sigmaW/sigmaMxGm;
2645 wt *= wtSigma * gammaKinPtr->weight();
2646 if ( wt > 1. ) infoPtr->errorMsg(
"Warning in PhaseSpace2to2elastic::"
2647 "trialKin: weight above unity");
2650 if ( wt < rndmPtr->flat() )
return false;
2656 lambda12S = pow2( s - s1 - s2) - 4. * s1 * s2 ;
2657 tLow = - lambda12S / s;
2665 if (hasGamma) sigmaTotPtr->chooseVMDstates(idAgm, idBgm, eCM, 102);
2666 else sigmaTotPtr->chooseVMDstates(idA, idB, eCM, 102);
2667 m3 = (infoPtr->isVMDstateA()) ? infoPtr->mVMDA() : mA;
2668 m4 = (infoPtr->isVMDstateB()) ? infoPtr->mVMDB() : mB;
2673 lambda12 = sqrtpos( pow2( s - s1 - s2) - 4. * s1 * s2 );
2674 lambda34 = sqrtpos( pow2( s - s3 - s4) - 4. * s3 * s4 );
2675 tempA = s - (s1 + s2 + s3 + s4) + (s1 - s2) * (s3 - s4) / s;
2676 tempB = lambda12 * lambda34 / s;
2677 tempC = (s3 - s1) * (s4 - s2) + (s1 + s4 - s2 - s3)
2678 * (s1 * s4 - s2 * s3) / s;
2679 tLow = -0.5 * (tempA + tempB);
2680 tUpp = (useCoulomb) ? -parm(
"SigmaElastic:tAbsMin")
2685 int idAVMD = infoPtr->isVMDstateA() ? infoPtr->idVMDA() : idA;
2686 int idBVMD = infoPtr->isVMDstateB() ? infoPtr->idVMDB() : idB;
2687 sigmaTotPtr->calcTotEl(idAVMD, idBVMD, s, m3, m4);
2690 bSlope1 = (isOneExp) ? sigmaTotPtr->bSlopeEl() : BNARROW;
2692 sigRef1 = sigmaTotPtr->dsigmaEl( tUpp,
false);
2696 sigNorm1 = sigRef1 / bSlope1;
2697 if (useCoulomb) sigNorm1 *= 2.;
2700 sigRef2 = sigmaTotPtr->dsigmaEl( tUpp + TOFFSET,
false);
2701 sigRef = (sigRef1 > 2. * sigRef2) ? 2. * sigRef1 : 5. * sigRef2;
2702 rel2 = exp((bSlope2 - bSlope1) * tUpp) * WIDEFRAC / (1. - WIDEFRAC);
2703 sigNorm1 = sigRef / (bSlope1 + rel2 * bSlope2);
2704 sigNorm2 = sigNorm1 * rel2;
2706 sigNorm3 = (useCoulomb) ? -2. * HBARCSQ * 4. * M_PI * pow2(alphaEM0)
2708 sigNormSum = sigNorm1 + sigNorm2 + sigNorm3;
2712 double rNow, bNow, sigNow, sigEst;
2717 infoPtr->errorMsg(
"Error in PhaseSpace2to2elastic::trialKin: "
2718 " quit after repeated tries");
2721 rNow = rndmPtr->flat() * sigNormSum;
2722 if (useCoulomb && rNow > sigNorm1 + sigNorm2) tH = tUpp / rndmPtr->flat();
2724 bNow = (rNow < sigNorm1) ? bSlope1 : bSlope2;
2725 tH = tUpp + log( rndmPtr->flat() ) / bNow;
2727 sigNow = sigmaTotPtr->dsigmaEl( tH, useCoulomb);
2728 sigEst = sigNorm1 * bSlope1 * exp( bSlope1 * (tH - tUpp))
2729 + sigNorm2 * bSlope2 * exp( bSlope2 * (tH - tUpp));
2730 if (useCoulomb) sigEst += sigNorm3 * (-tUpp) / pow2(tH);
2731 }
while (tH < tLow || sigNow < sigEst * rndmPtr->flat());
2732 if (sigNow > 1.01 * sigEst) infoPtr->errorMsg(
"Warning in "
2733 "PhaseSpace2to2elastic::trialKin: cross section maximum violated");
2737 double tRat = s * tH / lambda12S;
2738 double cosTheta = min(1., max(-1., 1. + 2. * tRat ) );
2739 double sinTheta = 2. * sqrtpos( -tRat * (1. + tRat) );
2740 theta = asin( min(1., sinTheta));
2741 if (cosTheta < 0.) theta = M_PI - theta;
2744 double cosTheta = min(1., max(-1., (tempA + 2. * tH) / tempB));
2745 double sinTheta = 2. * sqrtpos( -(tempC + tempA * tH + tH * tH) ) / tempB;
2746 theta = asin( min(1., sinTheta));
2747 if (cosTheta < 0.) theta = M_PI - theta;
2759 bool PhaseSpace2to2elastic::finalKin() {
2771 pAbs = 0.5 * sqrtpos(lambda12S) / eCM;
2772 pH[1] = Vec4( 0., 0., pAbs, 0.5 * (s + s1 - s2) / eCM);
2773 pH[2] = Vec4( 0., 0., -pAbs, 0.5 * (s + s2 - s1) / eCM);
2776 pH[3] = Vec4( 0., 0., pAbs, 0.5 * (s + s1 - s2) / eCM);
2777 pH[4] = Vec4( 0., 0., -pAbs, 0.5 * (s + s2 - s1) / eCM);
2782 pAbs = 0.5 * lambda12 / eCM;
2783 pH[1] = Vec4( 0., 0., pAbs, 0.5 * (s + s1 - s2) / eCM);
2784 pH[2] = Vec4( 0., 0., -pAbs, 0.5 * (s + s2 - s1) / eCM);
2787 pAbs = 0.5 * lambda34 / eCM;
2788 pH[3] = Vec4( 0., 0., pAbs, 0.5 * (s + s3 - s4) / eCM);
2789 pH[4] = Vec4( 0., 0., -pAbs, 0.5 * (s + s4 - s3) / eCM);
2794 phi = 2. * M_PI * rndmPtr->flat();
2795 pH[3].rot( theta, phi);
2796 pH[4].rot( theta, phi);
2802 uH = 2. * (s1 + s2) - sH - tH;
2804 p2Abs = pAbs * pAbs;
2806 pTH = pAbs * sin(theta);
2809 if (hasGamma) gammaKinPtr->finalize();
2827 const int PhaseSpace2to2diffractive::NTRY = 2500;
2830 const double PhaseSpace2to2diffractive::BWID1 = 8.;
2831 const double PhaseSpace2to2diffractive::BWID2 = 2.;
2832 const double PhaseSpace2to2diffractive::BWID3 = 0.5;
2833 const double PhaseSpace2to2diffractive::BWID4 = 0.2;
2834 const double PhaseSpace2to2diffractive::FWID1SD = 1.;
2835 const double PhaseSpace2to2diffractive::FWID2SD = 0.2;
2836 const double PhaseSpace2to2diffractive::FWID3SD = 0.1;
2837 const double PhaseSpace2to2diffractive::FWID4SD = 0.1;
2838 const double PhaseSpace2to2diffractive::FWID1DD = 0.1;
2839 const double PhaseSpace2to2diffractive::FWID2DD = 1.;
2840 const double PhaseSpace2to2diffractive::FWID3DD = 0.5;
2841 const double PhaseSpace2to2diffractive::FWID4DD = 0.2;
2844 const double PhaseSpace2to2diffractive::MAXFUDGESD = 2.;
2845 const double PhaseSpace2to2diffractive::MAXFUDGEDD = 2.;
2846 const double PhaseSpace2to2diffractive::MAXFUDGET = 4.;
2849 const double PhaseSpace2to2diffractive::DIFFMASSMARGIN = 0.2;
2852 const double PhaseSpace2to2diffractive::SPROTON = 0.8803544;
2859 bool PhaseSpace2to2diffractive::setupSampling() {
2862 hasGamma = flag(
"PDF:beamA2gamma") || flag(
"PDF:beamB2gamma");
2865 hasVMD = infoPtr->isVMDstateA() || infoPtr->isVMDstateB();
2871 sigmaNw = sigmaProcessPtr->sigmaHatWrap();
2877 idAgm = gammaKinPtr->idInA();
2878 idBgm = gammaKinPtr->idInB();
2879 sigmaTotPtr->calc( idAgm, idBgm, eCM);
2880 sigmaProcessPtr->setIdInDiff(idAgm, idBgm);
2883 if (idAgm == 22) mA = 0.;
2884 if (idBgm == 22) mB = 0.;
2888 if (isDiffA && isSD) sigmaMxGm = sigmaTotPtr->sigmaAX();
2889 else if (isDiffB && isSD) sigmaMxGm = sigmaTotPtr->sigmaXB();
2890 else if (isDiffB && isDiffA) sigmaMxGm = sigmaTotPtr->sigmaXX();
2891 sigmaNw = gammaKinPtr->setupSoftPhaseSpaceSampling(sigmaMxGm);
2900 double mPi = particleDataPtr->m0(211);
2901 double mRho = particleDataPtr->m0(113);
2902 double mAtmp = (infoPtr->isVMDstateA()) ? mRho : mA;
2903 double mBtmp = (infoPtr->isVMDstateB()) ? mRho : mB;
2904 m3ElDiff = (isDiffA) ? mAtmp + mPi : mAtmp;
2905 m4ElDiff = (isDiffB) ? mBtmp + mPi : mBtmp;
2908 s3 = pow2( m3ElDiff);
2909 s4 = pow2( m4ElDiff);
2912 lambda12 = sqrtpos( pow2( s - s1 - s2) - 4. * s1 * s2 );
2916 splitxit = sigmaTotPtr->splitDiff();
2917 int step = (splitxit) ? 1 : 0;
2922 xiMin = (isDiffA) ? s3 / s : s4 / s;
2923 for (
int i = 0; i < 100; ++i) {
2924 xiNow = pow( xiMin, 0.01 * i + 0.005);
2925 sigNow = sigmaTotPtr->dsigmaSD( xiNow, 0., isDiffA, step);
2926 if (sigNow > sigMax) sigMax = sigNow;
2931 xiMin = max( s3, s4) / s;
2932 xiMax = sqrt( SPROTON / s);
2933 for (
int i = 0; i < 100; ++i) {
2934 xiNow = xiMin * pow( xiMax / xiMin, 0.01 * i + 0.005);
2935 sigNow = sigmaTotPtr->dsigmaDD( xiNow, xiNow, 0., step);
2936 if (sigNow > sigMax) sigMax = sigNow;
2939 sigMax *= (isSD ? MAXFUDGESD : MAXFUDGEDD);
2942 fWid1 = (isSD ? FWID1SD : FWID1DD);
2943 fWid2 = (isSD ? FWID2SD : FWID2DD);
2944 fWid3 = (isSD ? FWID3SD : FWID3DD);
2945 fWid4 = (isSD ? FWID4SD : FWID4DD);
2946 fbWid1 = fWid1 * BWID1;
2947 fbWid2 = fWid2 * BWID2;
2948 fbWid3 = fWid3 * BWID3;
2949 fbWid4 = fWid4 * BWID4;
2950 fbWid1234 = fbWid1 + fbWid2 + fbWid3 + fbWid4;
2962 bool PhaseSpace2to2diffractive::trialKin(
bool,
bool ) {
2965 if (doEnergySpread) {
2966 eCM = infoPtr->eCM();
2968 lambda12 = sqrtpos( pow2( s - s1 - s2) - 4. * s1 * s2 );
2979 if (!gammaKinPtr->trialKinSoftPhaseSpaceSampling() )
return false;
2982 double eCMsub = gammaKinPtr->eCMsub();
2983 sigmaTotPtr->calc( idAgm, idBgm, eCMsub );
2987 if (isDiffA && isSD) sigmaW = sigmaTotPtr->sigmaAX();
2988 else if (isDiffB && isSD) sigmaW = sigmaTotPtr->sigmaXB();
2989 else if (isDiffB && isDiffA) sigmaW = sigmaTotPtr->sigmaXX();
2990 double wtSigma = sigmaW/sigmaMxGm;
2993 wt *= wtSigma * gammaKinPtr->weight();
2994 if ( wt > 1. ) infoPtr->errorMsg(
"Warning in PhaseSpace2to2diffractive"
2995 "::trialKin: weight above unity");
2998 if ( wt < rndmPtr->flat() )
return false;
3003 lambda12 = sqrtpos( pow2( s - s1 - s2) - 4. * s1 * s2 );
3012 int processCode = 101;
3013 if (isDiffA && isSD) processCode = 104;
3014 else if (isDiffB && isSD) processCode = 103;
3015 else if (isDiffB && isDiffA) processCode = 105;
3018 if (hasGamma) sigmaTotPtr->chooseVMDstates(idAgm, idBgm, eCM, processCode);
3019 else sigmaTotPtr->chooseVMDstates(idA, idB, eCM, processCode);
3024 double mPi = particleDataPtr->m0(211);
3025 double mD = particleDataPtr->m0(411);
3026 mAtmp = (infoPtr->isVMDstateA()) ? infoPtr->mVMDA() : mA;
3027 mBtmp = (infoPtr->isVMDstateB()) ? infoPtr->mVMDB() : mB;
3028 m3ElDiff = (isDiffA) ? mAtmp + mPi : mAtmp;
3029 m4ElDiff = (isDiffB) ? mBtmp + mPi : mBtmp;
3030 if (isDiffA && infoPtr->idVMDA() == 443) m3ElDiff = 2. * mD;
3031 if (isDiffB && infoPtr->idVMDB() == 443) m4ElDiff = 2. * mD;
3032 s3 = pow2( m3ElDiff);
3033 s4 = pow2( m4ElDiff);
3038 int nStep = (splitxit) ? 2 : 1;
3039 for (
int iStep = 0; iStep < nStep; ++iStep) {
3040 int step = (splitxit) ? iStep + 1 : 0;
3043 for (
int loop = 0; ; ++loop) {
3045 infoPtr->errorMsg(
"Error in PhaseSpace2to2diffractive::trialKin: "
3046 " quit after repeated tries");
3053 m3 = (isDiffA) ? m3ElDiff * pow( max(mAtmp, eCM - m4ElDiff) / m3ElDiff,
3054 rndmPtr->flat()) : m3ElDiff;
3055 m4 = (isDiffB) ? m4ElDiff * pow( max(mBtmp, eCM - m3ElDiff) / m4ElDiff,
3056 rndmPtr->flat()) : m4ElDiff;
3057 if (m3 + m4 + DIFFMASSMARGIN >= eCM)
continue;
3064 double pickb = rndmPtr->flat() * (fWid1 + fWid2 + fWid3 + fWid4);
3065 bNow = (pickb < fWid1) ? BWID1
3066 : ( (pickb < fWid1 + fWid2) ? BWID2
3067 : ( (pickb < fWid1 + fWid2 + fWid3) ? BWID3 : BWID4 ) );
3068 tH = log(rndmPtr->flat()) / bNow;
3071 lambda34 = sqrtpos( pow2( s - s3 - s4) - 4. * s3 * s4 );
3072 tempA = s - (s1 + s2 + s3 + s4) + (s1 - s2) * (s3 - s4) / s;
3073 tempB = lambda12 * lambda34 / s;
3074 tempC = (s3 - s1) * (s4 - s2) + (s1 + s4 - s2 - s3)
3075 * (s1 * s4 - s2 * s3) / s;
3076 tLow = -0.5 * (tempA + tempB);
3077 tUpp = tempC / tLow;
3078 if (tH < tLow || tH > tUpp)
continue;
3083 xiNow = (isDiffA) ? s3 / s : s4 / s;
3084 sigNow = sigmaTotPtr->dsigmaSD( xiNow, tH, isDiffA, step);
3086 sigNow = sigmaTotPtr->dsigmaDD( s3 / s, s4 / s, tH, step);
3090 tWeight = ( fbWid1 * exp( BWID1 * tH) + fbWid2 * exp(BWID2 * tH)
3091 + fbWid3 * exp(BWID3 * tH) + fbWid4 * exp(BWID4 * tH) ) / fbWid1234;
3092 sigMaxNow = (step == 0) ? sigMax * tWeight
3093 : ( (step == 1) ? sigMax : MAXFUDGET * tWeight );
3096 if (sigNow > sigMaxNow) infoPtr->errorMsg(
"Error in PhaseSpace2to2"
3097 "diffractive::trialKin: maximum cross section violated");
3098 if (sigNow > rndmPtr->flat() * sigMaxNow)
break;
3105 double cosTheta = min(1., max(-1., (tempA + 2. * tH) / tempB));
3106 double sinTheta = 2. * sqrtpos( -(tempC + tempA * tH + tH * tH) ) / tempB;
3107 theta = asin( min(1., sinTheta));
3108 if (cosTheta < 0.) theta = M_PI - theta;
3119 bool PhaseSpace2to2diffractive::finalKin() {
3128 pAbs = 0.5 * lambda12 / eCM;
3129 pH[1] = Vec4( 0., 0., pAbs, 0.5 * (s + s1 - s2) / eCM);
3130 pH[2] = Vec4( 0., 0., -pAbs, 0.5 * (s + s2 - s1) / eCM);
3133 pAbs = 0.5 * lambda34 / eCM;
3134 pH[3] = Vec4( 0., 0., pAbs, 0.5 * (s + s3 - s4) / eCM);
3135 pH[4] = Vec4( 0., 0., -pAbs, 0.5 * (s + s4 - s3) / eCM);
3138 phi = 2. * M_PI * rndmPtr->flat();
3139 pH[3].rot( theta, phi);
3140 pH[4].rot( theta, phi);
3146 uH = s1 + s2 + s3 + s4 - sH - tH;
3148 p2Abs = pAbs * pAbs;
3150 pTH = pAbs * sin(theta);
3153 if (hasGamma) gammaKinPtr->finalize();
3171 const int PhaseSpace2to3diffractive::NTRY = 2500;
3174 const double PhaseSpace2to3diffractive::BWID1 = 8.;
3175 const double PhaseSpace2to3diffractive::BWID2 = 4.;
3176 const double PhaseSpace2to3diffractive::BWID3 = 1.;
3177 const double PhaseSpace2to3diffractive::FWID1 = 1.;
3178 const double PhaseSpace2to3diffractive::FWID2 = 0.4;
3179 const double PhaseSpace2to3diffractive::FWID3 = 0.1;
3182 const double PhaseSpace2to3diffractive::MAXFUDGECD = 2.5;
3183 const double PhaseSpace2to3diffractive::MAXFUDGET = 10.0;
3186 const double PhaseSpace2to3diffractive::DIFFMASSMARGIN = 0.2;
3192 bool PhaseSpace2to3diffractive::setupSampling() {
3195 sigmaNw = sigmaProcessPtr->sigmaHatWrap();
3203 m5min = sigmaTotPtr->mMinCD();
3204 s5min = m5min * m5min;
3208 splitxit = sigmaTotPtr->splitDiff();
3209 int step = (splitxit) ? 1 : 0;
3215 for (
int i = 0; i < 100; ++i)
3216 for (
int j = 0; j <= i; ++j) {
3217 xi1 = pow( xiMin, 0.01 * i + 0.005);
3218 xi2 = pow( xiMin, 0.01 * j + 0.005);
3219 if (xi1 * xi2 > xiMin) {
3220 sigNow = sigmaTotPtr->dsigmaCD( xi1, xi2, 0., 0., step);
3221 if (sigNow > sigMax) sigMax = sigNow;
3224 sigMax *= MAXFUDGECD;
3230 fbWid1 = fWid1 * BWID1;
3231 fbWid2 = fWid2 * BWID2;
3232 fbWid3 = fWid3 * BWID3;
3233 fbWid123 = fbWid1 + fbWid2 + fbWid3;
3245 bool PhaseSpace2to3diffractive::trialKin(
bool,
bool ) {
3248 if (doEnergySpread) {
3249 eCM = infoPtr->eCM();
3254 pAbs = 0.5 * sqrtpos( pow2( s - s1 - s2) - 4. * s1 * s2 ) / eCM;
3255 p1.p( 0., 0., pAbs, 0.5 * (s + s1 - s2) / eCM);
3256 p2.p( 0., 0., -pAbs, 0.5 * (s + s2 - s1) / eCM);
3259 double pickb, bNow, tNow, sx1, sx2, sx3, sx4, t1, t2, tWeight1, tWeight2,
3260 lambda12, lambda34, tempA, tempB, tempC, cosTheta, sinTheta, pz, pT,
3261 deltaE, p2Esum, facP;
3262 xi1 = xi2 = t1 = t2 = 0.;
3265 int nStep = (splitxit) ? 2 : 1;
3266 for (
int iStep = 0; iStep < nStep; ++iStep) {
3267 int step = (splitxit) ? iStep + 1 : 0;
3270 for (
int loop = 0; ; ++loop) {
3272 infoPtr->errorMsg(
"Error in PhaseSpace2to3diffractive::trialKin: "
3273 " quit after repeated tries");
3280 xi1 = pow( s5min / s, rndmPtr->flat());
3281 xi2 = pow( s5min / s, rndmPtr->flat());
3284 }
while (m5 < m5min || mA + mB + m5 + DIFFMASSMARGIN > eCM);
3289 bool tryAgain =
false;
3290 for (
int i = 0; i < 2; ++i) {
3291 pickb = rndmPtr->flat() * (fWid1 + fWid2 + fWid3);
3292 bNow = (pickb < fWid1) ? BWID1
3293 : ( (pickb < fWid1 + fWid2) ? BWID2 : BWID3 );
3294 tNow = log(rndmPtr->flat()) / bNow;
3297 sx1 = (i == 0) ? s1 : s2;
3298 sx2 = (i == 0) ? s2 : s1;
3300 sx4 = (i == 0) ? s2 + xi1 * s : s1 + xi2 * s;
3301 if (sqrt(sx3) + sqrt(sx4) + DIFFMASSMARGIN > eCM) tryAgain =
true;
3302 if (!tInRange(tNow, s, sx1, sx2, sx3, sx4)) tryAgain =
true;
3303 if (tryAgain)
break;
3304 if (i == 0) t1 = tNow;
3307 if (tryAgain)
continue;
3311 sigNow = sigmaTotPtr->dsigmaCD( xi1, xi2, t1, t2, step);
3314 tWeight1 = ( fbWid1 * exp( BWID1 * t1) + fbWid2 * exp(BWID2 * t1)
3315 + fbWid3 * exp(BWID3 * t1) ) / fbWid123;
3316 tWeight2 = ( fbWid1 * exp( BWID1 * t2) + fbWid2 * exp(BWID2 * t2)
3317 + fbWid3 * exp(BWID3 * t2) ) / fbWid123;
3318 sigMaxNow = (step == 0) ? sigMax * tWeight1 * tWeight2
3319 : ( (step == 1) ? sigMax : MAXFUDGET * tWeight1 * tWeight2 );
3322 if (sigNow > sigMaxNow) infoPtr->errorMsg(
"Error in PhaseSpace2to3"
3323 "diffractive::trialKin: maximum cross section violated");
3324 if (sigNow > rndmPtr->flat() * sigMaxNow)
break;
3331 for (
int i = 0; i < 2; ++i) {
3332 tNow = (i == 0) ? t1 : t2;
3333 sx1 = (i == 0) ? s1 : s2;
3334 sx2 = (i == 0) ? s2 : s1;
3336 sx4 = (i == 0) ? s2 + xi1 * s : s1 + xi2 * s;
3337 lambda12 = sqrtpos( pow2( s - sx1 - sx2) - 4. * sx1 * sx2 );
3338 lambda34 = sqrtpos( pow2( s - sx3 - sx4) - 4. * sx3 * sx4 );
3339 tempA = s - (sx1 + sx2 + sx3 + sx4) + (sx1 - sx2) * (sx3 - sx4) / s;
3340 tempB = lambda12 * lambda34 / s;
3341 tempC = (sx3 - sx1) * (sx4 - sx2) + (sx1 + sx4 - sx2 - sx3)
3342 * (sx1 * sx4 - sx2 * sx3) / s;
3343 cosTheta = min(1., max(-1., (tempA + 2. * tNow) / tempB));
3344 sinTheta = 2. * sqrtpos( -(tempC + tempA * tNow + tNow * tNow) ) / tempB;
3345 theta = asin( min(1., sinTheta));
3346 if (cosTheta < 0.) theta = M_PI - theta;
3349 pAbs = 0.5 * lambda34 / eCM;
3350 pz = (i == 0) ? pAbs * cos(theta) : -pAbs * cos(theta);
3351 pT = pAbs * sin(theta);
3352 phi = 2. * M_PI * rndmPtr->flat();
3353 Vec4& pNow = (i == 0) ? p3 : p4;
3354 pNow.p( pT * cos(phi), pT * sin(phi), pz, sqrt(pAbs * pAbs + sx1) );
3358 p5 = (p1 - p3) + (p2 - p4);
3359 p5.e( sqrt(s5 + p5.pAbs2()) );
3360 for (
int iter = 0; iter < 5; ++iter) {
3361 deltaE = eCM - p3.e() - p4.e() - p5.e();
3362 if (abs(deltaE) < 1e-10 * eCM)
break;
3363 p2Esum = p3.pAbs2() / p3.e() + p4.pAbs2() / p4.e() + p5.pAbs2() / p5.e();
3364 facP = 1. + deltaE / p2Esum;
3368 p3.e( sqrt(s1 + p3.pAbs2()) );
3369 p4.e( sqrt(s2 + p4.pAbs2()) );
3370 p5.e( sqrt(s5 + p5.pAbs2()) );
3380 bool PhaseSpace2to3diffractive::finalKin() {
3398 tH = (p1 - p3).m2Calc();
3399 uH = (p2 - p4).m2Calc();
3401 p2Abs = pAbs * pAbs;
3404 pTH = (p3.pT() + p4.pT() + p5.pT()) / 3.;
3420 bool PhaseSpace2to2nondiffractive::setupSampling(){
3423 hasGamma = flag(
"PDF:beamA2gamma") || flag(
"PDF:beamB2gamma");
3427 sigmaNw = sigmaProcessPtr->sigmaHat();
3432 idAgm = gammaKinPtr->idInA();
3433 idBgm = gammaKinPtr->idInB();
3434 sigmaTotPtr->calc( idAgm, idBgm, eCM);
3435 sigmaMxGm = sigmaTotPtr->sigmaND();
3436 sigmaNw = gammaKinPtr->setupSoftPhaseSpaceSampling(sigmaMxGm);
3449 bool PhaseSpace2to2nondiffractive::trialKin(
bool,
bool) {
3459 if (!gammaKinPtr->trialKinSoftPhaseSpaceSampling() )
return false;
3462 sigmaTotPtr->calc( idAgm, idBgm, gammaKinPtr->eCMsub() );
3463 double wtSigma = sigmaTotPtr->sigmaND()/sigmaMxGm;
3466 wt *= wtSigma * gammaKinPtr->weight();
3467 if ( wt > 1. ) infoPtr->errorMsg(
"Warning in "
3468 "PhaseSpace2to2nondiffractive::trialKin: weight above unity");
3471 if ( wt < rndmPtr->flat() )
return false;
3490 const int PhaseSpace2to3tauycyl::NITERNR = 5;
3496 bool PhaseSpace2to3tauycyl::setupMasses() {
3499 gmZmode = gmZmodeGlobal;
3500 int gmZmodeProc = sigmaProcessPtr->gmZmode();
3501 if (gmZmodeProc >= 0) gmZmode = gmZmodeProc;
3504 mHatMin = mHatGlobalMin;
3505 sHatMin = mHatMin*mHatMin;
3507 if (mHatGlobalMax > mHatGlobalMin) mHatMax = min( eCM, mHatGlobalMax);
3508 sHatMax = mHatMax*mHatMax;
3516 if (useBW[3]) mUpper[3] -= (mPeak[4] + mPeak[5]);
3517 if (useBW[4]) mUpper[4] -= (mPeak[3] + mPeak[5]);
3518 if (useBW[5]) mUpper[5] -= (mPeak[3] + mPeak[4]);
3521 bool physical =
true;
3522 if (useBW[3] && mUpper[3] < mLower[3] + MASSMARGIN) physical =
false;
3523 if (useBW[4] && mUpper[4] < mLower[4] + MASSMARGIN) physical =
false;
3524 if (useBW[5] && mUpper[5] < mLower[5] + MASSMARGIN) physical =
false;
3525 if (!useBW[3] && !useBW[4] && !useBW[5] && mHatMax < mPeak[3]
3526 + mPeak[4] + mPeak[5] + MASSMARGIN) physical =
false;
3527 if (!physical)
return false;
3530 pTHatMin = pTHatGlobalMin;
3531 pT2HatMin = pTHatMin * pTHatMin;
3532 pTHatMax = pTHatGlobalMax;
3533 pT2HatMax = pTHatMax * pTHatMax;
3537 double distToThreshA = (mHatMax - mPeak[3] - mPeak[4] - mPeak[5])
3538 * mWidth[3] / (pow2(mWidth[3]) + pow2(mWidth[4]) + pow2(mWidth[5]));
3539 double distToThreshB = (mHatMax - mPeak[3] - mMin[4] - mMin[5])
3541 double distToThresh = min( distToThreshA, distToThreshB);
3542 setupMass2(3, distToThresh);
3547 double distToThreshA = (mHatMax - mPeak[3] - mPeak[4] - mPeak[5])
3548 * mWidth[4] / (pow2(mWidth[3]) + pow2(mWidth[4]) + pow2(mWidth[5]));
3549 double distToThreshB = (mHatMax - mPeak[4] - mMin[3] - mMin[5])
3551 double distToThresh = min( distToThreshA, distToThreshB);
3552 setupMass2(4, distToThresh);
3557 double distToThreshA = (mHatMax - mPeak[3] - mPeak[4] - mPeak[5])
3558 * mWidth[5] / (pow2(mWidth[3]) + pow2(mWidth[4]) + pow2(mWidth[5]));
3559 double distToThreshB = (mHatMax - mPeak[5] - mMin[3] - mMin[4])
3561 double distToThresh = min( distToThreshA, distToThreshB);
3562 setupMass2(5, distToThresh);
3566 m3 = (useBW[3]) ? min(mPeak[3], mUpper[3]) : mPeak[3];
3567 m4 = (useBW[4]) ? min(mPeak[4], mUpper[4]) : mPeak[4];
3568 m5 = (useBW[5]) ? min(mPeak[5], mUpper[5]) : mPeak[5];
3569 if (m3 + m4 + m5 + MASSMARGIN > mHatMax) physical =
false;
3577 if (useBW[3]) wtBW *= weightMass(3) * EXTRABWWTMAX;
3578 if (useBW[4]) wtBW *= weightMass(4) * EXTRABWWTMAX;
3579 if (useBW[5]) wtBW *= weightMass(5) * EXTRABWWTMAX;
3590 bool PhaseSpace2to3tauycyl::trialMasses() {
3602 if (m3 + m4 + m5 + MASSMARGIN > mHatMax)
return false;
3605 if (useBW[3]) wtBW *= weightMass(3);
3606 if (useBW[4]) wtBW *= weightMass(4);
3607 if (useBW[5]) wtBW *= weightMass(5);
3618 bool PhaseSpace2to3tauycyl::finalKin() {
3621 int id3 = sigmaProcessPtr->id(3);
3622 int id4 = sigmaProcessPtr->id(4);
3623 int id5 = sigmaProcessPtr->id(5);
3624 if (idMass[3] == 0) { m3 = particleDataPtr->m0(id3); s3 = m3*m3; }
3625 if (idMass[4] == 0) { m4 = particleDataPtr->m0(id4); s4 = m4*m4; }
3626 if (idMass[5] == 0) { m5 = particleDataPtr->m0(id5); s5 = m5*m5; }
3629 if (m3 + m4 + m5 + MASSMARGIN > mHat) {
3630 infoPtr->errorMsg(
"Warning in PhaseSpace2to3tauycyl::finalKin: "
3631 "failed after mass assignment");
3643 pH[1] = Vec4( 0., 0., 0.5 * eCM * x1H, 0.5 * eCM * x1H);
3644 pH[2] = Vec4( 0., 0., -0.5 * eCM * x2H, 0.5 * eCM * x2H);
3647 if (idMass[3] == 0 || idMass[4] == 0 || idMass[5] == 0) {
3648 double p3S = p3cm.pAbs2();
3649 double p4S = p4cm.pAbs2();
3650 double p5S = p5cm.pAbs2();
3652 double e3, e4, e5, value, deriv;
3655 for (
int i = 0; i < NITERNR; ++i) {
3656 e3 = sqrt(s3 + fac * p3S);
3657 e4 = sqrt(s4 + fac * p4S);
3658 e5 = sqrt(s5 + fac * p5S);
3659 value = e3 + e4 + e5 - mHat;
3660 deriv = 0.5 * (p3S / e3 + p4S / e4 + p5S / e5);
3661 fac -= value / deriv;
3665 double facRoot = sqrt(fac);
3666 p3cm.rescale3( facRoot );
3667 p4cm.rescale3( facRoot );
3668 p5cm.rescale3( facRoot );
3669 p3cm.e( sqrt(s3 + fac * p3S) );
3670 p4cm.e( sqrt(s4 + fac * p4S) );
3671 p5cm.e( sqrt(s5 + fac * p5S) );
3680 betaZ = (x1H - x2H)/(x1H + x2H);
3681 pH[3].rot( theta, phi);
3682 pH[4].rot( theta, phi);
3683 pH[3].bst( 0., 0., betaZ);
3684 pH[4].bst( 0., 0., betaZ);
3685 pH[5].bst( 0., 0., betaZ);
3688 pTH = (p3cm.pT() + p4cm.pT() + p5cm.pT()) / 3.;
3704 bool PhaseSpace2to3yyycyl::setupSampling() {
3707 pTHat3Min = parm(
"PhaseSpace:pTHat3Min");
3708 pTHat3Max = parm(
"PhaseSpace:pTHat3Max");
3709 pTHat5Min = parm(
"PhaseSpace:pTHat5Min");
3710 pTHat5Max = parm(
"PhaseSpace:pTHat5Max");
3711 RsepMin = parm(
"PhaseSpace:RsepMin");
3712 R2sepMin = pow2(RsepMin);
3715 hasBaryonBeams = ( beamAPtr->isBaryon() && beamBPtr->isBaryon() );
3718 for (
int i = 0; i < 6; ++i) mH[i] = 0.;
3723 if (pT3Max < pT3Min) pT3Max = 0.5 * eCM;
3726 if (pT5Max < pT5Min) pT5Max = 0.5 * eCM;
3727 if (pT5Max > pT3Max || pT5Min > pT3Min || pT3Min + 2. * pT5Min > eCM) {
3728 infoPtr->errorMsg(
"Error in PhaseSpace2to3yyycyl::setupSampling: "
3729 "inconsistent pT limits in 3-body phase space");
3737 double pT5EffMax = min( pT5Max, 0.5 * pT3Min / cos(0.5 * RsepMin) );
3738 double pT3EffMin = max( pT3Min, 2.0 * pT5Min * cos(0.5 * RsepMin) ) ;
3739 double sinhR = sinh(0.5 * RsepMin);
3740 double coshR = cosh(0.5 * RsepMin);
3741 for (
int iStep = 0; iStep < 120; ++iStep) {
3746 pT5 = pT5Min * pow( pT5EffMax / pT5Min, iStep / 9.);
3747 double pTRat = pT5 / pT3;
3748 double sin2Rsep = pow2( sin(RsepMin) );
3749 double cosPhi35 = - cos(RsepMin) * sqrtpos(1. - sin2Rsep
3750 * pow2(pTRat)) - sin2Rsep * pTRat;
3751 cosPhi35 = max( cosPhi35, cos(M_PI - 0.5 * RsepMin) );
3752 double sinPhi35 = sqrt(1. - pow2(cosPhi35));
3753 pT4 = sqrt( pow2(pT3) + pow2(pT5) + 2. * pT3 * pT5 * cosPhi35);
3754 p3cm = pT3 * Vec4( 1., 0., 0., 1.);
3755 p4cm = Vec4(-pT3 - pT5 * cosPhi35, -pT5 * sinPhi35, 0., pT4);
3756 p5cm = pT5 * Vec4( cosPhi35, sinPhi35, 0., 1.);
3760 pT5 = pT5Min * pow( pT5Max / pT5Min, iStep%10 / 9. );
3761 pT3 = max( pT3Min, 2. * pT5);
3763 p4cm = pT4 * Vec4( -1., 0., sinhR, coshR );
3764 p5cm = pT5 * Vec4( -1., 0., -sinhR, coshR );
3765 y3 = -1.2 + 0.2 * int(iStep/10);
3766 p3cm = pT3 * Vec4( 1., 0., sinh(y3), cosh(y3));
3767 betaZ = (p3cm.pz() + p4cm.pz() + p5cm.pz())
3768 / (p3cm.e() + p4cm.e() + p5cm.e());
3769 p3cm.bst( 0., 0., -betaZ);
3770 p4cm.bst( 0., 0., -betaZ);
3771 p5cm.bst( 0., 0., -betaZ);
3775 pInSum = p3cm + p4cm + p5cm;
3776 x1H = pInSum.e() / eCM;
3778 sH = pInSum.m2Calc();
3779 sigmaProcessPtr->set3Kin( x1H, x2H, sH, p3cm, p4cm, p5cm,
3780 0., 0., 0., 1., 1., 1.);
3781 sigmaNw = sigmaProcessPtr->sigmaPDF();
3784 double flux = 1. /(8. * pow2(sH) * pow5(2. * M_PI));
3785 double pTRng = pow2(M_PI)
3786 * pow4(pT3) * (1./pow2(pT3Min) - 1./pow2(pT3Max))
3787 * pow2(pT5) * 2.* log(pT5Max/pT5Min);
3788 double yRng = 8. * log(eCM / pT3) * log(eCM / pT4) * log(eCM / pT5);
3789 sigmaNw *= SAFETYMARGIN * flux * pTRng * yRng;
3792 if (showSearch && sigmaNw > sigmaMx) cout <<
"\n New sigmamax is "
3793 << scientific << setprecision(3) << sigmaNw <<
" for x1 = " << x1H
3794 <<
" x2 = " << x2H <<
" sH = " << sH << endl <<
" p3 = " << p3cm
3795 <<
" p4 = " << p4cm <<
" p5 = " << p5cm;
3796 if (sigmaNw > sigmaMx) sigmaMx = sigmaNw;
3808 bool PhaseSpace2to3yyycyl::trialKin(
bool inEvent,
bool) {
3811 if (doEnergySpread) {
3812 eCM = infoPtr->eCM();
3820 if (pT3Max < pT3Min) pT3Max = 0.5 * eCM;
3823 if (pT5Max < pT5Min) pT5Max = 0.5 * eCM;
3824 if (pT5Max > pT3Max || pT5Min > pT3Min || pT3Min + 2. * pT5Min > eCM) {
3825 infoPtr->errorMsg(
"Error in PhaseSpace2to3yyycyl::trialKin: "
3826 "inconsistent pT limits in 3-body phase space");
3831 pT3 = pT3Min * pT3Max / sqrt( pow2(pT3Min) +
3832 rndmPtr->flat() * (pow2(pT3Max) - pow2(pT3Min)) );
3833 pT5Max = min(pT5Max, pT3);
3834 if (pT5Max < pT5Min)
return false;
3835 pT5 = pT5Min * pow( pT5Max / pT5Min, rndmPtr->flat() );
3838 phi3 = 2. * M_PI * rndmPtr->flat();
3839 phi5 = 2. * M_PI * rndmPtr->flat();
3840 pT4 = sqrt( pow2(pT3) + pow2(pT5) + 2. * pT3 * pT5 * cos(phi3 - phi5) );
3841 if (pT4 > pT3 || pT4 < pT5)
return false;
3842 phi4 = atan2( -(pT3 * sin(phi3) + pT5 * sin(phi5)),
3843 -(pT3 * cos(phi3) + pT5 * cos(phi5)) );
3846 y3Max = log(eCM / pT3);
3847 y4Max = log(eCM / pT4);
3848 y5Max = log(eCM / pT5);
3849 y3 = y3Max * (2. * rndmPtr->flat() - 1.);
3850 y4 = y4Max * (2. * rndmPtr->flat() - 1.);
3851 y5 = y5Max * (2. * rndmPtr->flat() - 1.);
3855 double WTy = (hasBaryonBeams) ? (1. - pow2(y3/y3Max))
3856 * (1. - pow2(y4/y4Max)) * (1. - pow2(y5/y5Max)) : 1.;
3857 if (WTy < rndmPtr->flat())
return false;
3860 dphi = abs(phi3 - phi4);
3861 if (dphi > M_PI) dphi = 2. * M_PI - dphi;
3862 if (pow2(y3 - y4) + pow2(dphi) < R2sepMin)
return false;
3863 dphi = abs(phi3 - phi5);
3864 if (dphi > M_PI) dphi = 2. * M_PI - dphi;
3865 if (pow2(y3 - y5) + pow2(dphi) < R2sepMin)
return false;
3866 dphi = abs(phi4 - phi5);
3867 if (dphi > M_PI) dphi = 2. * M_PI - dphi;
3868 if (pow2(y4 - y5) + pow2(dphi) < R2sepMin)
return false;
3871 pH[3] = pT3 * Vec4( cos(phi3), sin(phi3), sinh(y3), cosh(y3) );
3872 pH[4] = pT4 * Vec4( cos(phi4), sin(phi4), sinh(y4), cosh(y4) );
3873 pH[5] = pT5 * Vec4( cos(phi5), sin(phi5), sinh(y5), cosh(y5) );
3874 pInSum = pH[3] + pH[4] + pH[5];
3877 x1H = (pInSum.e() + pInSum.pz()) / eCM;
3878 x2H = (pInSum.e() - pInSum.pz()) / eCM;
3879 if (x1H >= 1. || x2H >= 1.)
return false;
3880 sH = pInSum.m2Calc();
3881 if ( sH < pow2(mHatGlobalMin) ||
3882 (mHatGlobalMax > mHatGlobalMin && sH > pow2(mHatGlobalMax)) )
3886 betaZ = (x1H - x2H)/(x1H + x2H);
3887 p3cm = pH[3]; p3cm.bst( 0., 0., -betaZ);
3888 p4cm = pH[4]; p4cm.bst( 0., 0., -betaZ);
3889 p5cm = pH[5]; p5cm.bst( 0., 0., -betaZ);
3892 sigmaProcessPtr->set3Kin( x1H, x2H, sH, p3cm, p4cm, p5cm,
3893 0., 0., 0., 1., 1., 1.);
3894 sigmaNw = sigmaProcessPtr->sigmaPDF();
3897 double flux = 1. /(8. * pow2(sH) * pow5(2. * M_PI));
3898 double yRng = 8. * y3Max * y4Max * y5Max;
3899 double pTRng = pow2(M_PI)
3900 * pow4(pT3) * (1./pow2(pT3Min) - 1./pow2(pT3Max))
3901 * pow2(pT5) * 2.* log(pT5Max/pT5Min);
3902 sigmaNw *= flux * yRng * pTRng / WTy;
3905 if (canModifySigma) sigmaNw
3906 *= userHooksPtr->multiplySigmaBy( sigmaProcessPtr,
this, inEvent);
3907 if (canBiasSelection) sigmaNw
3908 *= userHooksPtr->biasSelectionBy( sigmaProcessPtr,
this, inEvent);
3909 if (canBias2Sel) sigmaNw *= pow( pTH / bias2SelRef, bias2SelPow);
3913 if (sigmaNw > sigmaMx) {
3914 infoPtr->errorMsg(
"Warning in PhaseSpace2to3yyycyl::trialKin: "
3915 "maximum for cross section violated");
3918 if (increaseMaximum || !inEvent) {
3919 double violFact = SAFETYMARGIN * sigmaNw / sigmaMx;
3920 sigmaMx = SAFETYMARGIN * sigmaNw;
3922 if (showViolation) {
3923 if (violFact < 9.99) cout << fixed;
3924 else cout << scientific;
3925 cout <<
" PYTHIA Maximum for " << sigmaProcessPtr->name()
3926 <<
" increased by factor " << setprecision(3) << violFact
3927 <<
" to " << scientific << sigmaMx << endl;
3931 }
else if (showViolation && sigmaNw > sigmaPos) {
3932 double violFact = sigmaNw / sigmaMx;
3933 if (violFact < 9.99) cout << fixed;
3934 else cout << scientific;
3935 cout <<
" PYTHIA Maximum for " << sigmaProcessPtr->name()
3936 <<
" exceeded by factor " << setprecision(3) << violFact << endl;
3942 if (sigmaNw < sigmaNeg) {
3943 infoPtr->errorMsg(
"Warning in PhaseSpace2to3yyycyl::trialKin:"
3944 " negative cross section set 0",
"for " + sigmaProcessPtr->name() );
3948 if (showViolation) cout <<
" PYTHIA Negative minimum for "
3949 << sigmaProcessPtr->name() <<
" changed to " << scientific
3950 << setprecision(3) << sigmaNeg << endl;
3952 if (sigmaNw < 0.) sigmaNw = 0.;
3963 bool PhaseSpace2to3yyycyl::finalKin() {
3966 for (
int i = 0; i < 6; ++i) mH[i] = 0.;
3969 pH[1] = 0.5 * (pInSum.e() + pInSum.pz()) * Vec4( 0., 0., 1., 1.);
3970 pH[2] = 0.5 * (pInSum.e() - pInSum.pz()) * Vec4( 0., 0., -1., 1.);
3975 pTH = (pH[3].pT() + pH[4].pT() + pH[5].pT()) / 3.;
3995 const double PhaseSpaceLHA::CONVERTPB2MB = 1e-9;
4001 bool PhaseSpaceLHA::setupSampling() {
4004 strategy = lhaUpPtr->strategy();
4005 stratAbs = abs(strategy);
4006 if (strategy == 0 || stratAbs > 4) {
4007 ostringstream stratCode;
4008 stratCode << strategy;
4009 infoPtr->errorMsg(
"Error in PhaseSpaceLHA::setupSampling: unknown "
4010 "Les Houches Accord weighting stategy", stratCode.str());
4015 nProc = lhaUpPtr->sizeProc();
4021 double xMax, xSec, xMaxAbs;
4022 for (
int iProc = 0 ; iProc < nProc; ++iProc) {
4023 idPr = lhaUpPtr->idProcess(iProc);
4024 xMax = lhaUpPtr->xMax(iProc);
4025 xSec = lhaUpPtr->xSec(iProc);
4028 if ( (strategy == 1 || strategy == 2) && xMax < 0.) {
4029 infoPtr->errorMsg(
"Error in PhaseSpaceLHA::setupSampling: "
4030 "negative maximum not allowed");
4033 if ( ( strategy == 2 || strategy == 3) && xSec < 0.) {
4034 infoPtr->errorMsg(
"Error in PhaseSpaceLHA::setupSampling: "
4035 "negative cross section not allowed");
4040 if (stratAbs == 1) xMaxAbs = abs(xMax);
4041 else if (stratAbs < 4) xMaxAbs = abs(xSec);
4043 idProc.push_back( idPr );
4044 xMaxAbsProc.push_back( xMaxAbs );
4047 xMaxAbsSum += xMaxAbs;
4050 sigmaMx = xMaxAbsSum * CONVERTPB2MB;
4051 sigmaSgn = xSecSgnSum * CONVERTPB2MB;
4062 bool PhaseSpaceLHA::trialKin(
bool,
bool repeatSame ) {
4066 if (repeatSame) idProcNow = idProcSave;
4067 else if (stratAbs <= 2) {
4068 double xMaxAbsRndm = xMaxAbsSum * rndmPtr->flat();
4070 do xMaxAbsRndm -= xMaxAbsProc[++iProc];
4071 while (xMaxAbsRndm > 0. && iProc < nProc - 1);
4072 idProcNow = idProc[iProc];
4076 bool physical = lhaUpPtr->setEvent(idProcNow);
4077 if (!physical)
return false;
4080 int idPr = lhaUpPtr->idProcess();
4082 for (
int iP = 0; iP < int(idProc.size()); ++iP)
4083 if (idProc[iP] == idPr) iProc = iP;
4087 double wtPr = lhaUpPtr->weight();
4088 if (stratAbs == 1) sigmaNw = wtPr * CONVERTPB2MB
4089 * xMaxAbsSum / xMaxAbsProc[iProc];
4090 else if (stratAbs == 2) sigmaNw = (wtPr / abs(lhaUpPtr->xMax(iProc)))
4092 else if (strategy == 3) sigmaNw = sigmaMx;
4093 else if (strategy == -3 && wtPr > 0.) sigmaNw = sigmaMx;
4094 else if (strategy == -3) sigmaNw = -sigmaMx;
4095 else if (stratAbs == 4) sigmaNw = wtPr * CONVERTPB2MB;
4098 x1H = lhaUpPtr->x1();
4099 x2H = lhaUpPtr->x2();