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,
89 Info* infoPtrIn, Settings* settingsPtrIn, ParticleData* particleDataPtrIn,
90 Rndm* rndmPtrIn, BeamParticle* beamAPtrIn, BeamParticle* beamBPtrIn,
91 Couplings* couplingsPtrIn, SigmaTotal* sigmaTotPtrIn,
92 UserHooks* userHooksPtrIn) {
95 sigmaProcessPtr = sigmaProcessPtrIn;
97 settingsPtr = settingsPtrIn;
98 particleDataPtr = particleDataPtrIn;
100 beamAPtr = beamAPtrIn;
101 beamBPtr = beamBPtrIn;
102 couplingsPtr = couplingsPtrIn;
103 sigmaTotPtr = sigmaTotPtrIn;
104 userHooksPtr = userHooksPtrIn;
107 idA = beamAPtr->id();
108 idB = beamBPtr->id();
111 eCM = infoPtr->eCM();
115 hasLeptonBeamA = beamAPtr->isLepton();
116 hasLeptonBeamB = beamBPtr->isLepton();
117 hasTwoLeptonBeams = hasLeptonBeamA && hasLeptonBeamB;
118 hasOneLeptonBeam = (hasLeptonBeamA || hasLeptonBeamB) && !hasTwoLeptonBeams;
119 bool hasPointLepton = (hasLeptonBeamA && beamAPtr->isUnresolved())
120 || (hasLeptonBeamB && beamBPtr->isUnresolved());
123 hasPointGammaA = beamAPtr->isGamma() && beamAPtr->isUnresolved();
124 hasPointGammaB = beamBPtr->isGamma() && beamBPtr->isUnresolved();
125 hasOnePointParticle = (hasOneLeptonBeam && hasPointLepton)
126 || ( hasPointGammaA && !hasPointGammaB)
127 || (!hasPointGammaA && hasPointGammaB);
128 hasTwoPointParticles = (hasTwoLeptonBeams && hasPointLepton)
129 || ( hasPointGammaA && hasPointGammaB);
132 bool beamHasResGamma = beamAPtr->hasResGamma() && beamBPtr->hasResGamma();
135 if ( beamAPtr->isGamma() && beamBPtr->isGamma() ) {
137 int beamAGammaMode = beamAPtr->getGammaMode();
138 int beamBGammaMode = beamBPtr->getGammaMode();
140 if ( beamAGammaMode == 2 && beamBGammaMode != 2 ) {
141 hasOnePointParticle =
true;
142 hasPointGammaA =
true;
144 if ( beamBGammaMode == 2 && beamAGammaMode != 2 ) {
145 hasOnePointParticle =
true;
146 hasPointGammaB =
true;
148 if ( beamAGammaMode == 2 && beamBGammaMode == 2 ) {
149 hasTwoPointParticles =
true;
150 hasPointGammaA =
true;
151 hasPointGammaB =
true;
156 if (isFirst || settingsPtr->flag(
"PhaseSpace:sameForSecond")) {
157 mHatGlobalMin = settingsPtr->parm(
"PhaseSpace:mHatMin");
158 mHatGlobalMax = settingsPtr->parm(
"PhaseSpace:mHatMax");
159 pTHatGlobalMin = settingsPtr->parm(
"PhaseSpace:pTHatMin");
160 pTHatGlobalMax = settingsPtr->parm(
"PhaseSpace:pTHatMax");
164 mHatGlobalMin = settingsPtr->parm(
"PhaseSpace:mHatMinSecond");
165 mHatGlobalMax = settingsPtr->parm(
"PhaseSpace:mHatMaxSecond");
166 pTHatGlobalMin = settingsPtr->parm(
"PhaseSpace:pTHatMinSecond");
167 pTHatGlobalMax = settingsPtr->parm(
"PhaseSpace:pTHatMaxSecond");
171 pTHatMinDiverge = settingsPtr->parm(
"PhaseSpace:pTHatMinDiverge");
174 Q2GlobalMin = settingsPtr->parm(
"PhaseSpace:Q2Min");
175 hasQ2Min = ( Q2GlobalMin >= pow2(pTHatMinDiverge) );
178 if ( beamHasResGamma ) {
179 double Wmax = settingsPtr->parm(
"Photon:Wmax");
180 if ( (mHatGlobalMax > Wmax) || mHatGlobalMax < 0.) mHatGlobalMax = Wmax;
184 useBreitWigners = settingsPtr->flag(
"PhaseSpace:useBreitWigners");
185 minWidthBreitWigners = settingsPtr->parm(
"PhaseSpace:minWidthBreitWigners");
188 doEnergySpread = settingsPtr->flag(
"Beams:allowMomentumSpread");
191 showSearch = settingsPtr->flag(
"PhaseSpace:showSearch");
192 showViolation = settingsPtr->flag(
"PhaseSpace:showViolation");
193 increaseMaximum = settingsPtr->flag(
"PhaseSpace:increaseMaximum");
196 gmZmodeGlobal = settingsPtr->mode(
"WeakZ0:gmZmode");
199 canModifySigma = (userHooksPtr != 0)
200 ? userHooksPtr->canModifySigma() :
false;
201 canBiasSelection = (userHooksPtr != 0)
202 ? userHooksPtr->canBiasSelection() :
false;
205 canBias2Sel = settingsPtr->flag(
"PhaseSpace:bias2Selection");
206 bias2SelPow = settingsPtr->parm(
"PhaseSpace:bias2SelectionPow");
207 bias2SelRef = settingsPtr->parm(
"PhaseSpace:bias2SelectionRef");
208 if (canBias2Sel) pTHatGlobalMin = max( pTHatGlobalMin, pTHatMinDiverge);
244 void PhaseSpace::decayKinematics(
Event& process) {
248 for (
int iResBeg = 5; iResBeg < process.size(); ++iResBeg) {
249 if (iResBeg <= iResEnd)
continue;
251 while ( iResEnd < process.size() - 1
252 && process[iResEnd + 1].mother1() == process[iResBeg].mother1()
253 && process[iResEnd + 1].mother2() == process[iResBeg].mother2() )
258 for (
int iRes = iResBeg; iRes <= iResEnd; ++iRes)
259 if ( !process[iRes].isFinal() ) hasRes =
true;
260 if ( !hasRes )
continue;
263 double decWt = sigmaProcessPtr->weightDecay( process, iResBeg, iResEnd);
264 if (decWt < 0.) infoPtr->errorMsg(
"Warning in PhaseSpace::decay"
265 "Kinematics: negative angular weight");
266 if (decWt > 1.) infoPtr->errorMsg(
"Warning in PhaseSpace::decay"
267 "Kinematics: angular weight above unity");
268 while (decWt < rndmPtr->flat() ) {
271 for (
int iRes = iResBeg; iRes < process.size(); ++iRes) {
272 if ( process[iRes].isFinal() )
continue;
273 int iResMother = iRes;
274 while (iResMother > iResEnd)
275 iResMother = process[iResMother].mother1();
276 if (iResMother < iResBeg)
continue;
279 decayKinematicsStep( process, iRes);
285 decWt = sigmaProcessPtr->weightDecay( process, iResBeg, iResEnd);
286 if (decWt < 0.) infoPtr->errorMsg(
"Warning in PhaseSpace::decay"
287 "Kinematics: negative angular weight");
288 if (decWt > 1.) infoPtr->errorMsg(
"Warning in PhaseSpace::decay"
289 "Kinematics: angular weight above unity");
302 void PhaseSpace::decayKinematicsStep(
Event& process,
int iRes) {
305 int i1 = process[iRes].daughter1();
306 int mult = process[iRes].daughter2() + 1 - i1;
307 double m0 = process[iRes].m();
308 Vec4 pRes = process[iRes].p();
315 double m1t = process[i1].m();
316 double m2t = process[i2].m();
319 double e1 = 0.5 * (m0*m0 + m1t*m1t - m2t*m2t) / m0;
320 double e2 = 0.5 * (m0*m0 + m2t*m2t - m1t*m1t) / m0;
321 double p12 = 0.5 * sqrtpos( (m0 - m1t - m2t) * (m0 + m1t + m2t)
322 * (m0 + m1t - m2t) * (m0 - m1t + m2t) ) / m0;
325 double cosTheta = 2. * rndmPtr->flat() - 1.;
326 double sinTheta = sqrt(1. - cosTheta*cosTheta);
327 double phi12 = 2. * M_PI * rndmPtr->flat();
328 double pX = p12 * sinTheta * cos(phi12);
329 double pY = p12 * sinTheta * sin(phi12);
330 double pZ = p12 * cosTheta;
333 Vec4 p1( pX, pY, pZ, e1);
334 Vec4 p2( -pX, -pY, -pZ, e2);
350 double m1t = process[i1].m();
351 double m2t = process[i2].m();
352 double m3t = process[i3].m();
353 double mDiff = m0 - (m1t + m2t + m3t);
356 double m23Min = m2t + m3t;
357 double m23Max = m0 - m1t;
358 double p1Max = 0.5 * sqrtpos( (m0 - m1t - m23Min)
359 * (m0 + m1t + m23Min) * (m0 + m1t - m23Min)
360 * (m0 - m1t + m23Min) ) / m0;
361 double p23Max = 0.5 * sqrtpos( (m23Max - m2t - m3t)
362 * (m23Max + m2t + m3t) * (m23Max + m2t - m3t)
363 * (m23Max - m2t + m3t) ) / m23Max;
364 double wtPSmax = 0.5 * p1Max * p23Max;
367 double wtPS, m23, p1Abs, p23Abs;
369 m23 = m23Min + rndmPtr->flat() * mDiff;
372 p1Abs = 0.5 * sqrtpos( (m0 - m1t - m23) * (m0 + m1t + m23)
373 * (m0 + m1t - m23) * (m0 - m1t + m23) ) / m0;
374 p23Abs = 0.5 * sqrtpos( (m23 - m2t - m3t) * (m23 + m2t + m3t)
375 * (m23 + m2t - m3t) * (m23 - m2t + m3t) ) / m23;
376 wtPS = p1Abs * p23Abs;
379 }
while ( wtPS < rndmPtr->flat() * wtPSmax );
382 double cosTheta = 2. * rndmPtr->flat() - 1.;
383 double sinTheta = sqrt(1. - cosTheta*cosTheta);
384 double phi23 = 2. * M_PI * rndmPtr->flat();
385 double pX = p23Abs * sinTheta * cos(phi23);
386 double pY = p23Abs * sinTheta * sin(phi23);
387 double pZ = p23Abs * cosTheta;
388 double e2 = sqrt( m2t*m2t + p23Abs*p23Abs);
389 double e3 = sqrt( m3t*m3t + p23Abs*p23Abs);
390 Vec4 p2( pX, pY, pZ, e2);
391 Vec4 p3( -pX, -pY, -pZ, e3);
394 cosTheta = 2. * rndmPtr->flat() - 1.;
395 sinTheta = sqrt(1. - cosTheta*cosTheta);
396 phi23 = 2. * M_PI * rndmPtr->flat();
397 pX = p1Abs * sinTheta * cos(phi23);
398 pY = p1Abs * sinTheta * sin(phi23);
399 pZ = p1Abs * cosTheta;
400 double e1 = sqrt( m1t*m1t + p1Abs*p1Abs);
401 double e23 = sqrt( m23*m23 + p1Abs*p1Abs);
402 Vec4 p1( pX, pY, pZ, e1);
405 Vec4 p23( -pX, -pY, -pZ, e23);
422 vector<double> mProd;
423 mProd.push_back( m0);
424 for (
int i = i1; i <= process[iRes].daughter2(); ++i)
425 mProd.push_back( process[i].m() );
427 pProd.push_back( pRes);
430 double mSum = mProd[1];
431 for (
int i = 2; i <= mult; ++i) mSum += mProd[i];
432 double mDiff = m0 - mSum;
436 for (
int i = 0; i <= mult; ++i) mInv.push_back( mProd[i]);
439 double wtPSmax = 1. / WTCORRECTION[mult];
440 double mMaxWT = mDiff + mProd[mult];
442 for (
int i = mult - 1; i > 0; --i) {
444 mMinWT += mProd[i+1];
445 double mNow = mProd[i];
446 wtPSmax *= 0.5 * sqrtpos( (mMaxWT - mMinWT - mNow)
447 * (mMaxWT + mMinWT + mNow) * (mMaxWT + mMinWT - mNow)
448 * (mMaxWT - mMinWT + mNow) ) / mMaxWT;
452 vector<double> rndmOrd;
459 rndmOrd.push_back(1.);
460 for (
int i = 1; i < mult - 1; ++i) {
461 double rndm = rndmPtr->flat();
462 rndmOrd.push_back(rndm);
463 for (
int j = i - 1; j > 0; --j) {
464 if (rndm > rndmOrd[j]) swap( rndmOrd[j], rndmOrd[j+1] );
468 rndmOrd.push_back(0.);
471 for (
int i = mult - 1; i > 0; --i) {
472 mInv[i] = mInv[i+1] + mProd[i] + (rndmOrd[i-1] - rndmOrd[i]) * mDiff;
473 wtPS *= 0.5 * sqrtpos( (mInv[i] - mInv[i+1] - mProd[i])
474 * (mInv[i] + mInv[i+1] + mProd[i]) * (mInv[i] + mInv[i+1] - mProd[i])
475 * (mInv[i] - mInv[i+1] + mProd[i]) ) / mInv[i];
479 }
while ( wtPS < rndmPtr->flat() * wtPSmax );
483 pInv.resize(mult + 1);
484 for (
int i = 1; i < mult; ++i) {
485 double p12 = 0.5 * sqrtpos( (mInv[i] - mInv[i+1] - mProd[i])
486 * (mInv[i] + mInv[i+1] + mProd[i]) * (mInv[i] + mInv[i+1] - mProd[i])
487 * (mInv[i] - mInv[i+1] + mProd[i]) ) / mInv[i];
490 double cosTheta = 2. * rndmPtr->flat() - 1.;
491 double sinTheta = sqrt(1. - cosTheta*cosTheta);
492 double phiLoc = 2. * M_PI * rndmPtr->flat();
493 double pX = p12 * sinTheta * cos(phiLoc);
494 double pY = p12 * sinTheta * sin(phiLoc);
495 double pZ = p12 * cosTheta;
498 double eHad = sqrt( mProd[i]*mProd[i] + p12*p12);
499 double eInv = sqrt( mInv[i+1]*mInv[i+1] + p12*p12);
500 pProd.push_back( Vec4( pX, pY, pZ, eHad) );
501 pInv[i+1].p( -pX, -pY, -pZ, eInv);
503 pProd.push_back( pInv[mult] );
507 for (
int iFrame = mult - 1; iFrame > 0; --iFrame)
508 for (
int i = iFrame; i <= mult; ++i) pProd[i].bst(pInv[iFrame]);
511 for (
int i = 1; i <= mult; ++i)
512 process[i1 + i - 1].p( pProd[i] );
521 void PhaseSpace::setup3Body() {
524 int idTchan1 = abs( sigmaProcessPtr->idTchan1() );
525 int idTchan2 = abs( sigmaProcessPtr->idTchan2() );
526 mTchan1 = (idTchan1 == 0) ? pTHatMinDiverge
527 : particleDataPtr->m0(idTchan1);
528 mTchan2 = (idTchan2 == 0) ? pTHatMinDiverge
529 : particleDataPtr->m0(idTchan2);
530 sTchan1 = mTchan1 * mTchan1;
531 sTchan2 = mTchan2 * mTchan2;
534 frac3Pow1 = sigmaProcessPtr->tChanFracPow1();
535 frac3Pow2 = sigmaProcessPtr->tChanFracPow2();
536 frac3Flat = 1. - frac3Pow1 - frac3Pow2;
537 useMirrorWeight = sigmaProcessPtr->useMirrorWeight();
545 bool PhaseSpace::setupSampling123(
bool is2,
bool is3) {
548 if (showSearch) cout <<
"\n PYTHIA Optimization printout for "
549 << sigmaProcessPtr->name() <<
"\n \n" << scientific << setprecision(3);
552 if (!limitTau(is2, is3))
return false;
555 int binTau[8], binY[8], binZ[8];
556 double vecTau[8], matTau[8][8], vecY[8], matY[8][8], vecZ[8], matZ[8][8];
557 for (
int i = 0; i < 8; ++i) {
567 for (
int j = 0; j < 8; ++j) {
577 nTau = (hasTwoPointParticles) ? 1 : 2;
578 nY = (hasOnePointParticle || hasTwoPointParticles) ? 1 : 5;
582 idResA = sigmaProcessPtr->resonanceA();
584 mResA = particleDataPtr->m0(idResA);
585 GammaResA = particleDataPtr->mWidth(idResA);
586 if (mHatMin > mResA + WIDTHMARGIN * GammaResA || (mHatMax > 0.
587 && mHatMax < mResA - WIDTHMARGIN * GammaResA) ) idResA = 0;
589 idResB = sigmaProcessPtr->resonanceB();
591 mResB = particleDataPtr->m0(idResB);
592 GammaResB = particleDataPtr->mWidth(idResB);
593 if (mHatMin > mResB + WIDTHMARGIN * GammaResB || (mHatMax > 0.
594 && mHatMax < mResB - WIDTHMARGIN * GammaResB) ) idResB = 0;
596 if (idResA == 0 && idResB != 0) {
599 GammaResA = GammaResB;
604 if (idResA !=0 && !hasTwoPointParticles) {
606 tauResA = mResA * mResA / s;
607 widResA = mResA * GammaResA / s;
609 if (idResB != 0 && !hasTwoPointParticles) {
611 tauResB = mResB * mResB / s;
612 widResB = mResB * GammaResB / s;
616 if (hasTwoLeptonBeams && !hasTwoPointParticles) ++nTau;
620 if (idResB != 0 && abs(mResA - mResB) < SAMEMASS * (GammaResA + GammaResB))
626 int nVar = (is2) ? 3 : 2;
635 for (
int iTau = 0; iTau < nTau; ++iTau) {
637 if (sameResMass && iTau > 1 && iTau < 6) posTau = (iTau < 4) ? 0.4 : 0.6;
638 selectTau( iTau, posTau, is2);
639 if (!limitY())
continue;
640 if (is2 && !limitZ())
continue;
643 for (
int iY = 0; iY < nY; ++iY) {
645 for (
int iZ = 0; iZ < nZ; ++iZ) {
646 if (is2) selectZ( iZ, 0.5);
647 double sigmaTmp = 0.;
651 sigmaProcessPtr->set1Kin( x1H, x2H, sH);
652 sigmaTmp = sigmaProcessPtr->sigmaPDF(
true);
653 sigmaTmp *= wtTau * wtY;
658 sigmaProcessPtr->set2Kin( x1H, x2H, sH, tH, m3, m4,
660 sigmaTmp = sigmaProcessPtr->sigmaPDF(
true);
661 sigmaTmp *= wtTau * wtY * wtZ * wtBW;
667 for (
int iTry3 = 0; iTry3 < NTRY3BODY; ++iTry3) {
668 if (!select3Body())
continue;
669 sigmaProcessPtr->set3Kin( x1H, x2H, sH, p3cm, p4cm, p5cm,
670 m3, m4, m5, runBW3H, runBW4H, runBW5H);
671 double sigmaTry = sigmaProcessPtr->sigmaPDF(
true);
672 sigmaTry *= wtTau * wtY * wt3Body * wtBW;
673 if (sigmaTry > sigmaTmp) sigmaTmp = sigmaTry;
678 if (canModifySigma) sigmaTmp
679 *= userHooksPtr->multiplySigmaBy( sigmaProcessPtr,
this,
false);
680 if (canBiasSelection) sigmaTmp
681 *= userHooksPtr->biasSelectionBy( sigmaProcessPtr,
this,
false);
682 if (canBias2Sel) sigmaTmp *= pow( pTH / bias2SelRef, bias2SelPow);
685 if (sigmaTmp > sigmaMx) sigmaMx = sigmaTmp;
688 if (showSearch) cout <<
" tau =" << setw(11) << tau <<
" y ="
689 << setw(11) << y <<
" z =" << setw(11) << z
690 <<
" sigma =" << setw(11) << sigmaTmp <<
"\n";
691 if (sigmaTmp < 0.) sigmaTmp = 0.;
694 if (!hasTwoPointParticles) {
696 vecTau[iTau] += sigmaTmp;
697 matTau[iTau][0] += 1. / intTau0;
698 matTau[iTau][1] += (1. / intTau1) / tau;
700 matTau[iTau][2] += (1. / intTau2) / (tau + tauResA);
701 matTau[iTau][3] += (1. / intTau3)
702 * tau / ( pow2(tau - tauResA) + pow2(widResA) );
705 matTau[iTau][4] += (1. / intTau4) / (tau + tauResB);
706 matTau[iTau][5] += (1. / intTau5)
707 * tau / ( pow2(tau - tauResB) + pow2(widResB) );
709 if (hasTwoLeptonBeams) matTau[iTau][nTau - 1] += (1. / intTau6)
710 * tau / max( LEPTONTAUMIN, 1. - tau);
714 if (!hasOnePointParticle && !hasTwoPointParticles) {
716 vecY[iY] += sigmaTmp;
717 matY[iY][0] += (yMax / intY0) / cosh(y);
718 matY[iY][1] += (yMax / intY12) * (y + yMax);
719 matY[iY][2] += (yMax / intY12) * (yMax - y);
720 if (!hasTwoLeptonBeams) {
721 matY[iY][3] += (yMax / intY34) * exp(y);
722 matY[iY][4] += (yMax / intY34) * exp(-y);
724 matY[iY][3] += (yMax / intY56)
725 / max( LEPTONXMIN, 1. - exp( y - yMax) );
726 matY[iY][4] += (yMax / intY56)
727 / max( LEPTONXMIN, 1. - exp(-y - yMax) );
733 double p2AbsMax = 0.25 * (pow2(tauMax * s - s3 - s4)
734 - 4. * s3 * s4) / (tauMax * s);
735 double zMaxMax = sqrtpos( 1. - pT2HatMin / p2AbsMax );
736 double zPosMaxMax = max(ratio34, unity34 + zMaxMax);
737 double zNegMaxMax = max(ratio34, unity34 - zMaxMax);
738 double intZ0Max = 2. * zMaxMax;
739 double intZ12Max = log( zPosMaxMax / zNegMaxMax);
740 double intZ34Max = 1. / zNegMaxMax - 1. / zPosMaxMax;
744 vecZ[iZ] += sigmaTmp;
746 matZ[iZ][1] += (intZ0Max / intZ12Max) / zNeg;
747 matZ[iZ][2] += (intZ0Max / intZ12Max) / zPos;
748 matZ[iZ][3] += (intZ0Max / intZ34Max) / pow2(zNeg);
749 matZ[iZ][4] += (intZ0Max / intZ34Max) / pow2(zPos);
765 if (!hasTwoPointParticles) solveSys( nTau, binTau, vecTau, matTau, tauCoef);
766 if (!hasOnePointParticle && !hasTwoPointParticles)
767 solveSys( nY, binY, vecY, matY, yCoef);
768 if (is2) solveSys( nZ, binZ, vecZ, matZ, zCoef);
769 if (showSearch) cout <<
"\n";
772 tauCoefSum[0] = tauCoef[0];
773 yCoefSum[0] = yCoef[0];
774 zCoefSum[0] = zCoef[0];
775 for (
int i = 1; i < 8; ++ i) {
776 tauCoefSum[i] = tauCoefSum[i - 1] + tauCoef[i];
777 yCoefSum[i] = yCoefSum[i - 1] + yCoef[i];
778 zCoefSum[i] = zCoefSum[i - 1] + zCoef[i];
781 tauCoefSum[nTau - 1] = 2.;
782 yCoefSum[nY - 1] = 2.;
783 zCoefSum[nZ - 1] = 2.;
787 int iMaxTau[NMAXTRY + 2], iMaxY[NMAXTRY + 2], iMaxZ[NMAXTRY + 2];
788 double sigMax[NMAXTRY + 2];
792 for (
int iTau = 0; iTau < nTau; ++iTau) {
794 if (sameResMass && iTau > 1 && iTau < 6) posTau = (iTau < 4) ? 0.4 : 0.6;
795 selectTau( iTau, posTau, is2);
796 if (!limitY())
continue;
797 if (is2 && !limitZ())
continue;
798 for (
int iY = 0; iY < nY; ++iY) {
800 for (
int iZ = 0; iZ < nZ; ++iZ) {
801 if (is2) selectZ( iZ, 0.5);
802 double sigmaTmp = 0.;
806 sigmaProcessPtr->set1Kin( x1H, x2H, sH);
807 sigmaTmp = sigmaProcessPtr->sigmaPDF(
true);
808 sigmaTmp *= wtTau * wtY;
813 sigmaProcessPtr->set2Kin( x1H, x2H, sH, tH, m3, m4,
815 sigmaTmp = sigmaProcessPtr->sigmaPDF(
true);
816 sigmaTmp *= wtTau * wtY * wtZ * wtBW;
822 for (
int iTry3 = 0; iTry3 < NTRY3BODY; ++iTry3) {
823 if (!select3Body())
continue;
824 sigmaProcessPtr->set3Kin( x1H, x2H, sH, p3cm, p4cm, p5cm,
825 m3, m4, m5, runBW3H, runBW4H, runBW5H);
826 double sigmaTry = sigmaProcessPtr->sigmaPDF(
true);
827 sigmaTry *= wtTau * wtY * wt3Body * wtBW;
828 if (sigmaTry > sigmaTmp) sigmaTmp = sigmaTry;
833 if (canModifySigma) sigmaTmp
834 *= userHooksPtr->multiplySigmaBy( sigmaProcessPtr,
this,
false);
835 if (canBiasSelection) sigmaTmp
836 *= userHooksPtr->biasSelectionBy( sigmaProcessPtr,
this,
false);
837 if (canBias2Sel) sigmaTmp *= pow( pTH / bias2SelRef, bias2SelPow);
840 if (showSearch) cout <<
" tau =" << setw(11) << tau <<
" y ="
841 << setw(11) << y <<
" z =" << setw(11) << z
842 <<
" sigma =" << setw(11) << sigmaTmp <<
"\n";
843 if (sigmaTmp < 0.) sigmaTmp = 0.;
846 bool mirrorPoint =
false;
847 for (
int iMove = 0; iMove < nMax; ++iMove)
848 if (abs(sigmaTmp - sigMax[iMove]) < SAMESIGMA
849 * (sigmaTmp + sigMax[iMove])) mirrorPoint =
true;
854 for (
int iMove = nMax - 1; iMove >= -1; --iMove) {
856 if (iInsert == 0 || sigmaTmp < sigMax[iMove])
break;
857 iMaxTau[iMove + 1] = iMaxTau[iMove];
858 iMaxY[iMove + 1] = iMaxY[iMove];
859 iMaxZ[iMove + 1] = iMaxZ[iMove];
860 sigMax[iMove + 1] = sigMax[iMove];
862 iMaxTau[iInsert] = iTau;
865 sigMax[iInsert] = sigmaTmp;
866 if (nMax < NMAXTRY) ++nMax;
873 if (showSearch) cout <<
"\n";
877 int beginVar = (hasTwoPointParticles) ? 2 : 0;
878 if (hasOnePointParticle) beginVar = 1;
879 for (
int iMax = 0; iMax < nMax; ++iMax) {
880 int iTau = iMaxTau[iMax];
881 int iY = iMaxY[iMax];
882 int iZ = iMaxZ[iMax];
887 double varVal, varNew, deltaVar, marginVar, sigGrid[3];
890 for (
int iRepeat = 0; iRepeat < 2; ++iRepeat) {
892 for (
int iVar = beginVar; iVar < nVar; ++iVar) {
893 bool isTauVar = iVar == 0 || (beginVar == 1 && iVar == 1);
894 if (isTauVar) varVal = tauVal;
895 else if (iVar == 1) varVal = yVal;
897 deltaVar = (iRepeat == 0) ? 0.1
898 : max( 0.01, min( 0.05, min( varVal - 0.02, 0.98 - varVal) ) );
899 marginVar = (iRepeat == 0) ? 0.02 : 0.002;
900 int moveStart = (iRepeat == 0 && isTauVar) ? 0 : 1;
901 for (
int move = moveStart; move < 9; ++move) {
907 }
else if (move == 1) {
909 varNew = varVal + deltaVar;
910 }
else if (move == 2) {
912 varNew = varVal - deltaVar;
913 }
else if (sigGrid[2] >= max( sigGrid[0], sigGrid[1])
914 && varVal + 2. * deltaVar < 1. - marginVar) {
916 sigGrid[0] = sigGrid[1];
917 sigGrid[1] = sigGrid[2];
919 varNew = varVal + deltaVar;
920 }
else if (sigGrid[0] >= max( sigGrid[1], sigGrid[2])
921 && varVal - 2. * deltaVar > marginVar) {
923 sigGrid[2] = sigGrid[1];
924 sigGrid[1] = sigGrid[0];
926 varNew = varVal - deltaVar;
927 }
else if (sigGrid[2] >= sigGrid[0]) {
930 sigGrid[0] = sigGrid[1];
936 sigGrid[2] = sigGrid[1];
942 bool insideLimits =
true;
945 selectTau( iTau, tauVal, is2);
946 if (!limitY()) insideLimits =
false;
947 if (is2 && !limitZ()) insideLimits =
false;
950 if (is2) selectZ( iZ, zVal);
952 }
else if (iVar == 1) {
955 }
else if (iVar == 2) {
961 double sigmaTmp = 0.;
966 sigmaProcessPtr->set1Kin( x1H, x2H, sH);
967 sigmaTmp = sigmaProcessPtr->sigmaPDF(
true);
968 sigmaTmp *= wtTau * wtY;
973 sigmaProcessPtr->set2Kin( x1H, x2H, sH, tH, m3, m4,
975 sigmaTmp = sigmaProcessPtr->sigmaPDF(
true);
976 sigmaTmp *= wtTau * wtY * wtZ * wtBW;
982 for (
int iTry3 = 0; iTry3 < NTRY3BODY; ++iTry3) {
983 if (!select3Body())
continue;
984 sigmaProcessPtr->set3Kin( x1H, x2H, sH, p3cm, p4cm, p5cm,
985 m3, m4, m5, runBW3H, runBW4H, runBW5H);
986 double sigmaTry = sigmaProcessPtr->sigmaPDF(
true);
987 sigmaTry *= wtTau * wtY * wt3Body * wtBW;
988 if (sigmaTry > sigmaTmp) sigmaTmp = sigmaTry;
993 if (canModifySigma) sigmaTmp
994 *= userHooksPtr->multiplySigmaBy( sigmaProcessPtr,
this,
false);
995 if (canBiasSelection) sigmaTmp
996 *= userHooksPtr->biasSelectionBy( sigmaProcessPtr,
this,
false);
997 if (canBias2Sel) sigmaTmp *= pow( pTH / bias2SelRef, bias2SelPow);
1000 if (showSearch) cout <<
" tau =" << setw(11) << tau <<
" y ="
1001 << setw(11) << y <<
" z =" << setw(11) << z
1002 <<
" sigma =" << setw(11) << sigmaTmp <<
"\n";
1003 if (sigmaTmp < 0.) sigmaTmp = 0.;
1007 sigGrid[iGrid] = sigmaTmp;
1008 if (sigmaTmp > sigmaMx) sigmaMx = sigmaTmp;
1013 sigmaMx *= SAFETYMARGIN;
1017 if (showSearch) cout <<
"\n Final maximum = " << setw(11) << sigmaMx
1030 bool PhaseSpace::trialKin123(
bool is2,
bool is3,
bool inEvent) {
1033 if (doEnergySpread) {
1034 eCM = infoPtr->eCM();
1038 if (idResA !=0 && !hasTwoPointParticles) {
1039 tauResA = mResA * mResA / s;
1040 widResA = mResA * GammaResA / s;
1042 if (idResB != 0 && !hasTwoPointParticles) {
1043 tauResB = mResB * mResB / s;
1044 widResB = mResB * GammaResB / s;
1055 if (!limitTau(is2, is3))
return false;
1057 if (!hasTwoPointParticles) {
1058 double rTau = rndmPtr->flat();
1059 while (rTau > tauCoefSum[iTau]) ++iTau;
1061 selectTau( iTau, rndmPtr->flat(), is2);
1068 if (!limitY())
return false;
1070 if (!hasOnePointParticle && !hasTwoPointParticles) {
1071 double rY = rndmPtr->flat();
1072 while (rY > yCoefSum[iY]) ++iY;
1074 selectY( iY, rndmPtr->flat());
1081 if (!limitZ())
return false;
1083 double rZ = rndmPtr->flat();
1084 while (rZ > zCoefSum[iZ]) ++iZ;
1085 selectZ( iZ, rndmPtr->flat());
1090 sigmaProcessPtr->set1Kin( x1H, x2H, sH);
1091 sigmaNw = sigmaProcessPtr->sigmaPDF();
1092 sigmaNw *= wtTau * wtY;
1097 sigmaProcessPtr->set2Kin( x1H, x2H, sH, tH, m3, m4, runBW3H, runBW4H);
1098 sigmaNw = sigmaProcessPtr->sigmaPDF();
1099 sigmaNw *= wtTau * wtY * wtZ * wtBW;
1104 if (!select3Body()) sigmaNw = 0.;
1106 sigmaProcessPtr->set3Kin( x1H, x2H, sH, p3cm, p4cm, p5cm,
1107 m3, m4, m5, runBW3H, runBW4H, runBW5H);
1108 sigmaNw = sigmaProcessPtr->sigmaPDF();
1109 sigmaNw *= wtTau * wtY * wt3Body * wtBW;
1114 if (canModifySigma) sigmaNw
1115 *= userHooksPtr->multiplySigmaBy( sigmaProcessPtr,
this, inEvent);
1116 if (canBiasSelection) sigmaNw
1117 *= userHooksPtr->biasSelectionBy( sigmaProcessPtr,
this, inEvent);
1118 if (canBias2Sel) sigmaNw *= pow( pTH / bias2SelRef, bias2SelPow);
1122 if (sigmaNw > sigmaMx) {
1123 infoPtr->errorMsg(
"Warning in PhaseSpace2to2tauyz::trialKin: "
1124 "maximum for cross section violated");
1127 if (increaseMaximum || !inEvent) {
1128 double violFact = SAFETYMARGIN * sigmaNw / sigmaMx;
1129 sigmaMx = SAFETYMARGIN * sigmaNw;
1131 if (showViolation) {
1132 if (violFact < 9.99) cout << fixed;
1133 else cout << scientific;
1134 cout <<
" PYTHIA Maximum for " << sigmaProcessPtr->name()
1135 <<
" increased by factor " << setprecision(3) << violFact
1136 <<
" to " << scientific << sigmaMx << endl;
1140 }
else if (showViolation && sigmaNw > sigmaPos) {
1141 double violFact = sigmaNw / sigmaMx;
1142 if (violFact < 9.99) cout << fixed;
1143 else cout << scientific;
1144 cout <<
" PYTHIA Maximum for " << sigmaProcessPtr->name()
1145 <<
" exceeded by factor " << setprecision(3) << violFact << endl;
1151 if (sigmaNw < sigmaNeg) {
1152 infoPtr->errorMsg(
"Warning in PhaseSpace2to2tauyz::trialKin:"
1153 " negative cross section set 0",
"for " + sigmaProcessPtr->name() );
1157 if (showViolation) cout <<
" PYTHIA Negative minimum for "
1158 << sigmaProcessPtr->name() <<
" changed to " << scientific
1159 << setprecision(3) << sigmaNeg << endl;
1161 if (sigmaNw < 0.) sigmaNw = 0.;
1164 biasWt = (canBiasSelection) ? userHooksPtr->biasedSelectionWeight() : 1.;
1165 if (canBias2Sel) biasWt /= pow( pTH / bias2SelRef, bias2SelPow);
1175 bool PhaseSpace::limitTau(
bool is2,
bool is3) {
1178 if (hasTwoPointParticles) {
1185 tauMin = sHatMin / s;
1186 if (is2 && hasQ2Min && Q2GlobalMin + s3 + s4 > sHatMin)
1187 tauMin = (Q2GlobalMin + s3 + s4) / s;
1188 tauMax = (mHatMax < mHatMin) ? 1. : min( 1., sHatMax / s);
1192 double mT3Min = sqrt(s3 + pT2HatMin);
1193 double mT4Min = sqrt(s4 + pT2HatMin);
1194 double mT5Min = (is3) ? sqrt(s5 + pT2HatMin) : 0.;
1195 tauMin = max( tauMin, pow2(mT3Min + mT4Min + mT5Min) / s);
1199 return (tauMax > tauMin);
1206 bool PhaseSpace::limitY() {
1209 if (hasTwoPointParticles) {
1215 yMax = -0.5 * log(tau);
1216 if (hasOnePointParticle)
return true;
1219 double yMaxMargin = (hasTwoLeptonBeams) ? yMax + LEPTONXLOGMAX : yMax;
1222 return (yMaxMargin > 0.);
1229 bool PhaseSpace::limitZ() {
1236 zMax = sqrtpos( 1. - pT2HatMin / p2Abs );
1237 if (pTHatMax > pTHatMin) zMin = sqrtpos( 1. - pT2HatMax / p2Abs );
1242 if (zMax < zMin)
return false;
1254 double zMaxQ2 = (sH - s3 - s4 - 2. * Q2GlobalMin) / (2. * pAbs * mHat);
1255 if (zMaxQ2 > zPosMin) {
1256 if (zMaxQ2 < zPosMax) zPosMax = zMaxQ2;
1260 if (zMaxQ2 > zNegMin) {
1261 if (zMaxQ2 < zNegMax) zNegMax = zMaxQ2;
1277 void PhaseSpace::selectTau(
int iTau,
double tauVal,
bool is2) {
1280 if (hasTwoPointParticles) {
1286 p2Abs = 0.25 * (pow2(sH - s3 - s4) - 4. * s3 * s4) / sH;
1287 pAbs = sqrtpos( p2Abs );
1297 tRatA = ((tauResA + tauMax) / (tauResA + tauMin)) * (tauMin / tauMax);
1298 aLowA = atan( (tauMin - tauResA) / widResA);
1299 aUppA = atan( (tauMax - tauResA) / widResA);
1305 tRatB = ((tauResB + tauMax) / (tauResB + tauMin)) * (tauMin / tauMax);
1306 aLowB = atan( (tauMin - tauResB) / widResB);
1307 aUppB = atan( (tauMax - tauResB) / widResB);
1313 if (hasTwoLeptonBeams) {
1314 aLowT = log( max( LEPTONTAUMIN, 1. - tauMin) );
1315 aUppT = log( max( LEPTONTAUMIN, 1. - tauMax) );
1316 intTau6 = aLowT - aUppT;
1320 if (iTau == 0) tau = tauMin * pow( tauMax / tauMin, tauVal);
1321 else if (iTau == 1) tau = tauMax * tauMin
1322 / (tauMin + (tauMax - tauMin) * tauVal);
1325 else if (hasTwoLeptonBeams && iTau == nTau - 1)
1326 tau = 1. - exp( aUppT + intTau6 * tauVal );
1330 else if (iTau == 2) tau = tauResA * tauMin
1331 / ((tauResA + tauMin) * pow( tRatA, tauVal) - tauMin);
1332 else if (iTau == 3) tau = tauResA + widResA
1333 * tan( aLowA + (aUppA - aLowA) * tauVal);
1334 else if (iTau == 4) tau = tauResB * tauMin
1335 / ((tauResB + tauMin) * pow( tRatB, tauVal) - tauMin);
1336 else if (iTau == 5) tau = tauResB + widResB
1337 * tan( aLowB + (aUppB - aLowB) * tauVal);
1340 intTau0 = log( tauMax / tauMin);
1341 intTau1 = (tauMax - tauMin) / (tauMax * tauMin);
1342 double invWtTau = (tauCoef[0] / intTau0) + (tauCoef[1] / intTau1) / tau;
1344 intTau2 = -log(tRatA) / tauResA;
1345 intTau3 = (aUppA - aLowA) / widResA;
1346 invWtTau += (tauCoef[2] / intTau2) / (tau + tauResA)
1347 + (tauCoef[3] / intTau3) * tau / ( pow2(tau - tauResA) + pow2(widResA) );
1350 intTau4 = -log(tRatB) / tauResB;
1351 intTau5 = (aUppB - aLowB) / widResB;
1352 invWtTau += (tauCoef[4] / intTau4) / (tau + tauResB)
1353 + (tauCoef[5] / intTau5) * tau / ( pow2(tau - tauResB) + pow2(widResB) );
1355 if (hasTwoLeptonBeams)
1356 invWtTau += (tauCoef[nTau - 1] / intTau6)
1357 * tau / max( LEPTONTAUMIN, 1. - tau);
1358 wtTau = 1. / invWtTau;
1364 p2Abs = 0.25 * (pow2(sH - s3 - s4) - 4. * s3 * s4) / sH;
1365 pAbs = sqrtpos( p2Abs );
1374 void PhaseSpace::selectY(
int iY,
double yVal) {
1377 if (hasTwoPointParticles) {
1386 if (hasOnePointParticle) {
1387 if (hasLeptonBeamA || hasPointGammaA) {
1401 if (hasTwoLeptonBeams && iY > 2) iY += 2;
1404 double expYMax = exp( yMax );
1405 double expYMin = exp(-yMax );
1406 double atanMax = atan( expYMax );
1407 double atanMin = atan( expYMin );
1408 double aUppY = (hasTwoLeptonBeams)
1409 ? log( max( LEPTONXMIN, LEPTONXMAX / tau - 1. ) ) : 0.;
1410 double aLowY = LEPTONXLOGMIN;
1413 if (iY == 0) y = log( tan( atanMin + (atanMax - atanMin) * yVal ) );
1416 else if (iY <= 2) y = yMax * (2. * sqrt(yVal) - 1.);
1419 else if (iY <= 4) y = log( expYMin + (expYMax - expYMin) * yVal );
1422 else y = yMax - log( 1. + exp(aLowY + (aUppY - aLowY) * yVal) );
1425 if (iY == 2 || iY == 4 || iY == 6) y = -y;
1428 intY0 = 2. * (atanMax - atanMin);
1429 intY12 = 0.5 * pow2(2. * yMax);
1430 intY34 = expYMax - expYMin;
1431 intY56 = aUppY - aLowY;
1432 double invWtY = (yCoef[0] / intY0) / cosh(y)
1433 + (yCoef[1] / intY12) * (y + yMax) + (yCoef[2] / intY12) * (yMax - y);
1434 if (!hasTwoLeptonBeams) invWtY
1435 += (yCoef[3] / intY34) * exp(y) + (yCoef[4] / intY34) * exp(-y);
1437 += (yCoef[3] / intY56) / max( LEPTONXMIN, 1. - exp( y - yMax) )
1438 + (yCoef[4] / intY56) / max( LEPTONXMIN, 1. - exp(-y - yMax) );
1442 x1H = sqrt(tau) * exp(y);
1443 x2H = sqrt(tau) * exp(-y);
1453 void PhaseSpace::selectZ(
int iZ,
double zVal) {
1456 ratio34 = max(TINY, 2. * s3 * s4 / pow2(sH));
1457 unity34 = 1. + ratio34;
1458 double ratiopT2 = 2. * pT2HatMin / max( SHATMINZ, sH);
1459 if (ratiopT2 < PT2RATMINZ) ratio34 = max( ratio34, ratiopT2);
1462 double zNegMinM = max(ratio34, unity34 - zNegMin);
1463 double zNegMaxM = max(ratio34, unity34 - zNegMax);
1464 double zPosMinM = max(ratio34, unity34 - zPosMin);
1465 double zPosMaxM = max(ratio34, unity34 - zPosMax);
1466 double zNegMinP = max(ratio34, unity34 + zNegMin);
1467 double zNegMaxP = max(ratio34, unity34 + zNegMax);
1468 double zPosMinP = max(ratio34, unity34 + zPosMin);
1469 double zPosMaxP = max(ratio34, unity34 + zPosMax);
1473 double area0Neg = zNegMax - zNegMin;
1474 double area0Pos = zPosMax - zPosMin;
1475 double area0 = area0Neg + area0Pos;
1477 double area1Neg = log(zNegMinM / zNegMaxM);
1478 double area1Pos = log(zPosMinM / zPosMaxM);
1479 double area1 = area1Neg + area1Pos;
1481 double area2Neg = log(zNegMaxP / zNegMinP);
1482 double area2Pos = log(zPosMaxP / zPosMinP);
1483 double area2 = area2Neg + area2Pos;
1485 double area3Neg = 1. / zNegMaxM - 1. / zNegMinM;
1486 double area3Pos = 1. / zPosMaxM - 1. / zPosMinM;
1487 double area3 = area3Neg + area3Pos;
1489 double area4Neg = 1. / zNegMinP - 1. / zNegMaxP;
1490 double area4Pos = 1. / zPosMinP - 1. / zPosMaxP;
1491 double area4 = area4Neg + area4Pos;
1496 if (!hasPosZ || zVal * area0 < area0Neg) {
1497 double zValMod = zVal * area0 / area0Neg;
1498 z = zNegMin + zValMod * area0Neg;
1500 double zValMod = (zVal * area0 - area0Neg) / area0Pos;
1501 z = zPosMin + zValMod * area0Pos;
1505 }
else if (iZ == 1) {
1506 if (!hasPosZ || zVal * area1 < area1Neg) {
1507 double zValMod = zVal * area1 / area1Neg;
1508 z = unity34 - zNegMinM * pow(zNegMaxM / zNegMinM, zValMod);
1510 double zValMod = (zVal * area1 - area1Neg)/ area1Pos;
1511 z = unity34 - zPosMinM * pow(zPosMaxM / zPosMinM, zValMod);
1515 }
else if (iZ == 2) {
1516 if (!hasPosZ || zVal * area2 < area2Neg) {
1517 double zValMod = zVal * area2 / area2Neg;
1518 z = zNegMinP * pow(zNegMaxP / zNegMinP, zValMod) - unity34;
1520 double zValMod = (zVal * area2 - area2Neg)/ area2Pos;
1521 z = zPosMinP * pow(zPosMaxP / zPosMinP, zValMod) - unity34;
1525 }
else if (iZ == 3) {
1526 if (!hasPosZ || zVal * area3 < area3Neg) {
1527 double zValMod = zVal * area3 / area3Neg;
1528 z = unity34 - 1. / (1./zNegMinM + area3Neg * zValMod);
1530 double zValMod = (zVal * area3 - area3Neg)/ area3Pos;
1531 z = unity34 - 1. / (1./zPosMinM + area3Pos * zValMod);
1535 }
else if (iZ == 4) {
1536 if (!hasPosZ || zVal * area4 < area4Neg) {
1537 double zValMod = zVal * area4 / area4Neg;
1538 z = 1. / (1./zNegMinP - area4Neg * zValMod) - unity34;
1540 double zValMod = (zVal * area4 - area4Neg)/ area4Pos;
1541 z = 1. / (1./zPosMinP - area4Pos * zValMod) - unity34;
1546 if (z < 0.) z = min( zNegMax, max( zNegMin, z));
1547 else z = min( zPosMax, max( zPosMin, z) );
1548 zNeg = max(ratio34, unity34 - z);
1549 zPos = max(ratio34, unity34 + z);
1552 wtZ = mHat * pAbs / ( (zCoef[0] / area0) + (zCoef[1] / area1) / zNeg
1553 + (zCoef[2] / area2) / zPos + (zCoef[3] / area3) / pow2(zNeg)
1554 + (zCoef[4] / area4) / pow2(zPos) );
1557 double sH34 = -0.5 * (sH - s3 - s4);
1558 double tHuH = pow2(sH34) * (1. - z) * (1. + z) + s3 * s4 * pow2(z);
1560 tH = sH34 + mHat * pAbs * z;
1563 uH = sH34 - mHat * pAbs * z;
1566 pTH = sqrtpos( (tH * uH - s3 * s4) / sH);
1575 bool PhaseSpace::select3Body() {
1578 double m35S = pow2(m3 + m5);
1579 double pT4Smax = 0.25 * ( pow2(sH - s4 - m35S) - 4. * s4 * m35S ) / sH;
1580 if (pTHatMax > pTHatMin) pT4Smax = min( pT2HatMax, pT4Smax);
1581 double pT4Smin = pT2HatMin;
1582 double m34S = pow2(m3 + m4);
1583 double pT5Smax = 0.25 * ( pow2(sH - s5 - m34S) - 4. * s5 * m34S ) / sH;
1584 if (pTHatMax > pTHatMin) pT5Smax = min( pT2HatMax, pT5Smax);
1585 double pT5Smin = pT2HatMin;
1588 if ( pT4Smax < pow2(pTHatMin + MASSMARGIN) )
return false;
1589 if ( pT5Smax < pow2(pTHatMin + MASSMARGIN) )
return false;
1592 double pTSmaxProp = pT4Smax + sTchan1;
1593 double pTSminProp = pT4Smin + sTchan1;
1594 double pTSratProp = pTSmaxProp / pTSminProp;
1595 double pTSdiff = pT4Smax - pT4Smin;
1596 double rShape = rndmPtr->flat();
1598 if (rShape < frac3Flat) pT4S = pT4Smin + rndmPtr->flat() * pTSdiff;
1599 else if (rShape < frac3Flat + frac3Pow1) pT4S = max( pT2HatMin,
1600 pTSminProp * pow( pTSratProp, rndmPtr->flat() ) - sTchan1 );
1601 else pT4S = max( pT2HatMin, pTSminProp * pTSmaxProp
1602 / (pTSminProp + rndmPtr->flat()* pTSdiff) - sTchan1 );
1603 double wt4 = pTSdiff / ( frac3Flat
1604 + frac3Pow1 * pTSdiff / (log(pTSratProp) * (pT4S + sTchan1))
1605 + frac3Pow2 * pTSminProp * pTSmaxProp / pow2(pT4S + sTchan1) );
1608 pTSmaxProp = pT5Smax + sTchan2;
1609 pTSminProp = pT5Smin + sTchan2;
1610 pTSratProp = pTSmaxProp / pTSminProp;
1611 pTSdiff = pT5Smax - pT5Smin;
1612 rShape = rndmPtr->flat();
1614 if (rShape < frac3Flat) pT5S = pT5Smin + rndmPtr->flat() * pTSdiff;
1615 else if (rShape < frac3Flat + frac3Pow1) pT5S = max( pT2HatMin,
1616 pTSminProp * pow( pTSratProp, rndmPtr->flat() ) - sTchan2 );
1617 else pT5S = max( pT2HatMin, pTSminProp * pTSmaxProp
1618 / (pTSminProp + rndmPtr->flat()* pTSdiff) - sTchan2 );
1619 double wt5 = pTSdiff / ( frac3Flat
1620 + frac3Pow1 * pTSdiff / (log(pTSratProp) * (pT5S + sTchan2))
1621 + frac3Pow2 * pTSminProp * pTSmaxProp / pow2(pT5S + sTchan2) );
1624 double phi4 = 2. * M_PI * rndmPtr->flat();
1625 double phi5 = 2. * M_PI * rndmPtr->flat();
1626 double pT3S = max( 0., pT4S + pT5S + 2. * sqrt(pT4S * pT5S)
1627 * cos(phi4 - phi5) );
1628 if ( pT3S < pT2HatMin || (pTHatMax > pTHatMin && pT3S > pT2HatMax) )
1632 double sT3 = s3 + pT3S;
1633 double sT4 = s4 + pT4S;
1634 double sT5 = s5 + pT5S;
1635 double mT3 = sqrt(sT3);
1636 double mT4 = sqrt(sT4);
1637 double mT5 = sqrt(sT5);
1638 if ( mT3 + mT4 + mT5 + MASSMARGIN > mHat )
return false;
1641 double m45S = pow2(mT4 + mT5);
1642 double y3max = log( ( sH + sT3 - m45S + sqrtpos( pow2(sH - sT3 - m45S)
1643 - 4 * sT3 * m45S ) ) / (2. * mHat * mT3) );
1644 if (y3max < YRANGEMARGIN)
return false;
1645 double y3 = (2. * rndmPtr->flat() - 1.) * (1. - YRANGEMARGIN) * y3max;
1646 double pz3 = mT3 * sinh(y3);
1647 double e3 = mT3 * cosh(y3);
1651 double e45 = mHat - e3;
1652 double sT45 = e45 * e45 - pz45 * pz45;
1653 double lam45 = sqrtpos( pow2(sT45 - sT4 - sT5) - 4. * sT4 * sT5 );
1654 if (lam45 < YRANGEMARGIN * sH)
return false;
1655 double lam4e = sT45 + sT4 - sT5;
1656 double lam5e = sT45 + sT5 - sT4;
1657 double tFac = -0.5 * mHat / sT45;
1658 double t1Pos = tFac * (e45 - pz45) * (lam4e - lam45);
1659 double t1Neg = tFac * (e45 - pz45) * (lam4e + lam45);
1660 double t2Pos = tFac * (e45 + pz45) * (lam5e - lam45);
1661 double t2Neg = tFac * (e45 + pz45) * (lam5e + lam45);
1664 double wtPosUnnorm = 1.;
1665 double wtNegUnnorm = 1.;
1666 if (useMirrorWeight) {
1667 wtPosUnnorm = 1./ pow2( (t1Pos - sTchan1) * (t2Pos - sTchan2) );
1668 wtNegUnnorm = 1./ pow2( (t1Neg - sTchan1) * (t2Neg - sTchan2) );
1670 double wtPos = wtPosUnnorm / (wtPosUnnorm + wtNegUnnorm);
1671 double wtNeg = wtNegUnnorm / (wtPosUnnorm + wtNegUnnorm);
1672 double epsilon = (rndmPtr->flat() < wtPos) ? 1. : -1.;
1675 double px4 = sqrt(pT4S) * cos(phi4);
1676 double py4 = sqrt(pT4S) * sin(phi4);
1677 double px5 = sqrt(pT5S) * cos(phi5);
1678 double py5 = sqrt(pT5S) * sin(phi5);
1679 double pz4 = 0.5 * (pz45 * lam4e + epsilon * e45 * lam45) / sT45;
1680 double pz5 = pz45 - pz4;
1681 double e4 = sqrt(sT4 + pz4 * pz4);
1682 double e5 = sqrt(sT5 + pz5 * pz5);
1683 p3cm = Vec4( -(px4 + px5), -(py4 + py5), pz3, e3);
1684 p4cm = Vec4( px4, py4, pz4, e4);
1685 p5cm = Vec4( px5, py5, pz5, e5);
1688 wt3Body = wt4 * wt5 * (2. * y3max) / (128. * pow3(M_PI) * lam45);
1689 wt3Body *= (epsilon > 0.) ? 1. / wtPos : 1. / wtNeg;
1692 wt3Body /= (2. * sH);
1703 void PhaseSpace::solveSys(
int n,
int bin[8],
double vec[8],
1704 double mat[8][8],
double coef[8]) {
1708 cout <<
"\n Equation system: " << setw(5) << bin[0];
1709 for (
int j = 0; j < n; ++j) cout << setw(12) << mat[0][j];
1710 cout << setw(12) << vec[0] <<
"\n";
1711 for (
int i = 1; i < n; ++i) {
1712 cout <<
" " << setw(5) << bin[i];
1713 for (
int j = 0; j < n; ++j) cout << setw(12) << mat[i][j];
1714 cout << setw(12) << vec[i] <<
"\n";
1719 double vecNor[8], coefTmp[8];
1720 for (
int i = 0; i < n; ++i) coefTmp[i] = 0.;
1723 bool canSolve =
true;
1724 for (
int i = 0; i < n; ++i)
if (bin[i] == 0) canSolve =
false;
1726 for (
int i = 0; i < n; ++i) vecSum += vec[i];
1727 if (abs(vecSum) < TINY) canSolve =
false;
1731 for (
int i = 0; i < n; ++i) vecNor[i] = max( 0.1, vec[i] / vecSum);
1732 for (
int k = 0; k < n - 1; ++k) {
1733 for (
int i = k + 1; i < n; ++i) {
1734 if (abs(mat[k][k]) < TINY) {canSolve =
false;
break;}
1735 double ratio = mat[i][k] / mat[k][k];
1736 vec[i] -= ratio * vec[k];
1737 for (
int j = k; j < n; ++j) mat[i][j] -= ratio * mat[k][j];
1739 if (!canSolve)
break;
1742 for (
int k = n - 1; k >= 0; --k) {
1743 for (
int j = k + 1; j < n; ++j) vec[k] -= mat[k][j] * coefTmp[j];
1744 coefTmp[k] = vec[k] / mat[k][k];
1750 if (!canSolve)
for (
int i = 0; i < n; ++i) {
1753 if (vecSum > TINY) vecNor[i] = max(0.1, vec[i] / vecSum);
1757 double coefSum = 0.;
1759 for (
int i = 0; i < n; ++i) {
1760 coefTmp[i] = max( 0., coefTmp[i]);
1761 coefSum += coefTmp[i];
1762 vecSum += vecNor[i];
1764 if (coefSum > 0.)
for (
int i = 0; i < n; ++i) coef[i] = EVENFRAC / n
1765 + (1. - EVENFRAC) * 0.5 * (coefTmp[i] / coefSum + vecNor[i] / vecSum);
1766 else for (
int i = 0; i < n; ++i) coef[i] = 1. / n;
1770 cout <<
" Solution: ";
1771 for (
int i = 0; i < n; ++i) cout << setw(12) << coef[i];
1780 void PhaseSpace::setupMass1(
int iM) {
1783 if (iM == 3) idMass[iM] = abs(sigmaProcessPtr->id3Mass());
1784 if (iM == 4) idMass[iM] = abs(sigmaProcessPtr->id4Mass());
1785 if (iM == 5) idMass[iM] = abs(sigmaProcessPtr->id5Mass());
1788 if (idMass[iM] == 0) {
1794 mPeak[iM] = particleDataPtr->m0(idMass[iM]);
1795 mWidth[iM] = particleDataPtr->mWidth(idMass[iM]);
1796 mMin[iM] = max( MRESMINABS, particleDataPtr->mMin(idMass[iM]) );
1797 mMax[iM] = particleDataPtr->mMax(idMass[iM]);
1799 if (idMass[iM] == 23 && gmZmode == 1) mPeak[iM] = mMin[iM];
1803 sPeak[iM] = mPeak[iM] * mPeak[iM];
1804 useBW[iM] = useBreitWigners && (mWidth[iM] > minWidthBreitWigners);
1805 if (!useBW[iM]) mWidth[iM] = 0.;
1806 mw[iM] = mPeak[iM] * mWidth[iM];
1807 wmRat[iM] = (idMass[iM] == 0 || mPeak[iM] == 0.)
1808 ? 0. : mWidth[iM] / mPeak[iM];
1812 mLower[iM] = mMin[iM];
1813 mUpper[iM] = mHatMax;
1822 void PhaseSpace::setupMass2(
int iM,
double distToThresh) {
1825 if (mMax[iM] > mMin[iM]) mUpper[iM] = min( mUpper[iM], mMax[iM]);
1826 sLower[iM] = mLower[iM] * mLower[iM];
1827 sUpper[iM] = mUpper[iM] * mUpper[iM];
1831 if (distToThresh > THRESHOLDSIZE) {
1832 fracFlatS[iM] = 0.1;
1833 fracFlatM[iM] = 0.1;
1835 }
else if (distToThresh > - THRESHOLDSIZE) {
1836 fracFlatS[iM] = 0.25 - 0.15 * distToThresh / THRESHOLDSIZE;
1837 fracInv [iM] = 0.15 - 0.05 * distToThresh / THRESHOLDSIZE;
1839 fracFlatS[iM] = 0.3;
1840 fracFlatM[iM] = 0.1;
1846 if (idMass[iM] == 23 && gmZmode == 0) {
1847 fracFlatS[iM] *= 0.5;
1848 fracFlatM[iM] *= 0.5;
1849 fracInv[iM] = 0.5 * fracInv[iM] + 0.25;
1850 fracInv2[iM] = 0.25;
1851 }
else if (idMass[iM] == 23 && gmZmode == 1) {
1852 fracFlatS[iM] = 0.1;
1853 fracFlatM[iM] = 0.1;
1855 fracInv2[iM] = 0.35;
1859 atanLower[iM] = atan( (sLower[iM] - sPeak[iM])/ mw[iM] );
1860 atanUpper[iM] = atan( (sUpper[iM] - sPeak[iM])/ mw[iM] );
1861 intBW[iM] = atanUpper[iM] - atanLower[iM];
1862 intFlatS[iM] = sUpper[iM] - sLower[iM];
1863 intFlatM[iM] = mUpper[iM] - mLower[iM];
1864 intInv[iM] = log( sUpper[iM] / sLower[iM] );
1865 intInv2[iM] = 1./sLower[iM] - 1./sUpper[iM];
1873 void PhaseSpace::trialMass(
int iM) {
1876 double& mSet = (iM == 3) ? m3 : ( (iM == 4) ? m4 : m5 );
1877 double& sSet = (iM == 3) ? s3 : ( (iM == 4) ? s4 : s5 );
1881 double pickForm = rndmPtr->flat();
1882 if (pickForm > fracFlatS[iM] + fracFlatM[iM] + fracInv[iM] + fracInv2[iM])
1883 sSet = sPeak[iM] + mw[iM] * tan( atanLower[iM]
1884 + rndmPtr->flat() * intBW[iM] );
1885 else if (pickForm > fracFlatM[iM] + fracInv[iM] + fracInv2[iM])
1886 sSet = sLower[iM] + rndmPtr->flat() * (sUpper[iM] - sLower[iM]);
1887 else if (pickForm > fracInv[iM] + fracInv2[iM])
1888 sSet = pow2(mLower[iM] + rndmPtr->flat() * (mUpper[iM] - mLower[iM]));
1889 else if (pickForm > fracInv2[iM])
1890 sSet = sLower[iM] * pow( sUpper[iM] / sLower[iM], rndmPtr->flat() );
1891 else sSet = sLower[iM] * sUpper[iM]
1892 / (sLower[iM] + rndmPtr->flat() * (sUpper[iM] - sLower[iM]));
1912 double PhaseSpace::weightMass(
int iM) {
1915 double& mSet = (iM == 3) ? m3 : ( (iM == 4) ? m4 : m5 );
1916 double& sSet = (iM == 3) ? s3 : ( (iM == 4) ? s4 : s5 );
1917 double& runBWH = (iM == 3) ? runBW3H : ( (iM == 4) ? runBW4H : runBW5H );
1921 if (!useBW[iM])
return 1.;
1925 = (1. - fracFlatS[iM] - fracFlatM[iM] - fracInv[iM] - fracInv2[iM])
1926 * mw[iM] / ( (pow2(sSet - sPeak[iM]) + pow2(mw[iM])) * intBW[iM])
1927 + fracFlatS[iM] / intFlatS[iM]
1928 + fracFlatM[iM] / (2. * mSet * intFlatM[iM])
1929 + fracInv[iM] / (sSet * intInv[iM])
1930 + fracInv2[iM] / (sSet*sSet * intInv2[iM]);
1933 double mwRun = sSet * wmRat[iM];
1938 runBWH = mwRun / (pow2(sSet - sPeak[iM]) + pow2(mwRun)) / M_PI;
1941 return (runBWH / genBW);
1954 bool PhaseSpace2to1tauy::setupMass() {
1957 gmZmode = gmZmodeGlobal;
1958 int gmZmodeProc = sigmaProcessPtr->gmZmode();
1959 if (gmZmodeProc >= 0) gmZmode = gmZmodeProc;
1962 int idRes = abs(sigmaProcessPtr->resonanceA());
1963 int idTmp = abs(sigmaProcessPtr->resonanceB());
1964 if (idTmp > 0) idRes = idTmp;
1965 double mResMin = (idRes == 0) ? 0. : particleDataPtr->mMin(idRes);
1966 double mResMax = (idRes == 0) ? 0. : particleDataPtr->mMax(idRes);
1969 mHatMin = max( mResMin, mHatGlobalMin);
1970 sHatMin = mHatMin*mHatMin;
1972 if (mResMax > mResMin) mHatMax = min( mHatMax, mResMax);
1973 if (mHatGlobalMax > mHatGlobalMin) mHatMax = min( mHatMax, mHatGlobalMax);
1974 sHatMax = mHatMax*mHatMax;
1980 return (mHatMax > mHatMin + MASSMARGIN);
1988 bool PhaseSpace2to1tauy::finalKin() {
1996 pH[1] = Vec4( 0., 0., 0.5 * eCM * x1H, 0.5 * eCM * x1H);
1997 pH[2] = Vec4( 0., 0., -0.5 * eCM * x2H, 0.5 * eCM * x2H);
1998 pH[3] = pH[1] + pH[2];
2013 bool PhaseSpace2to2tauyz::setupMasses() {
2016 gmZmode = gmZmodeGlobal;
2017 int gmZmodeProc = sigmaProcessPtr->gmZmode();
2018 if (gmZmodeProc >= 0) gmZmode = gmZmodeProc;
2021 mHatMin = mHatGlobalMin;
2022 sHatMin = mHatMin*mHatMin;
2024 if (mHatGlobalMax > mHatGlobalMin) mHatMax = min( eCM, mHatGlobalMax);
2025 sHatMax = mHatMax*mHatMax;
2032 if (useBW[3]) mUpper[3] -= (useBW[4]) ? mMin[4] : mPeak[4];
2033 if (useBW[4]) mUpper[4] -= (useBW[3]) ? mMin[3] : mPeak[3];
2036 bool physical =
true;
2037 if (useBW[3] && mUpper[3] < mLower[3] + MASSMARGIN) physical =
false;
2038 if (useBW[4] && mUpper[4] < mLower[4] + MASSMARGIN) physical =
false;
2039 if (!useBW[3] && !useBW[4] && mHatMax < mPeak[3] + mPeak[4] + MASSMARGIN)
2041 if (!physical)
return false;
2044 pTHatMin = pTHatGlobalMin;
2045 if (mPeak[3] < pTHatMinDiverge || mPeak[4] < pTHatMinDiverge)
2046 pTHatMin = max( pTHatMin, pTHatMinDiverge);
2047 pT2HatMin = pTHatMin * pTHatMin;
2048 pTHatMax = pTHatGlobalMax;
2049 pT2HatMax = pTHatMax * pTHatMax;
2053 double distToThreshA = (mHatMax - mPeak[3] - mPeak[4]) * mWidth[3]
2054 / (pow2(mWidth[3]) + pow2(mWidth[4]));
2055 double distToThreshB = (mHatMax - mPeak[3] - mMin[4]) / mWidth[3];
2056 double distToThresh = min( distToThreshA, distToThreshB);
2057 setupMass2(3, distToThresh);
2062 double distToThreshA = (mHatMax - mPeak[3] - mPeak[4]) * mWidth[4]
2063 / (pow2(mWidth[3]) + pow2(mWidth[4]));
2064 double distToThreshB = (mHatMax - mMin[3] - mPeak[4]) / mWidth[4];
2065 double distToThresh = min( distToThreshA, distToThreshB);
2066 setupMass2(4, distToThresh);
2070 m3 = (useBW[3]) ? min(mPeak[3], mUpper[3]) : mPeak[3];
2071 m4 = (useBW[4]) ? min(mPeak[4], mUpper[4]) : mPeak[4];
2072 if (m3 + m4 + THRESHOLDSIZE * (mWidth[3] + mWidth[4]) + MASSMARGIN
2074 if (useBW[3] && useBW[4]) physical = constrainedM3M4();
2075 else if (useBW[3]) physical = constrainedM3();
2076 else if (useBW[4]) physical = constrainedM4();
2084 if (useBW[3]) wtBW *= weightMass(3) * EXTRABWWTMAX;
2085 if (useBW[4]) wtBW *= weightMass(4) * EXTRABWWTMAX;
2097 bool PhaseSpace2to2tauyz::trialMasses() {
2108 if (m3 + m4 + MASSMARGIN > mHatMax)
return false;
2111 if (useBW[3]) wtBW *= weightMass(3);
2112 if (useBW[4]) wtBW *= weightMass(4);
2122 bool PhaseSpace2to2tauyz::finalKin() {
2125 int id3 = sigmaProcessPtr->id(3);
2126 int id4 = sigmaProcessPtr->id(4);
2127 if (idMass[3] == 0) { m3 = particleDataPtr->m0(id3); s3 = m3*m3; }
2128 if (idMass[4] == 0) { m4 = particleDataPtr->m0(id4); s4 = m4*m4; }
2131 if (sigmaProcessPtr->swappedTU()) {
2137 if (m3 + m4 + MASSMARGIN > mHat) {
2138 infoPtr->errorMsg(
"Warning in PhaseSpace2to2tauyz::finalKin: "
2139 "failed after mass assignment");
2142 p2Abs = 0.25 * (pow2(sH - s3 - s4) - 4. * s3 * s4) / sH;
2143 pAbs = sqrtpos( p2Abs );
2153 if ( hasPointGammaA && beamBPtr->isHadron() ) {
2154 double eCM1 = 0.5 * ( s + pow2(mA) - pow2(mB) ) / eCM;
2155 double eCM2 = 0.25 * x2H * s / eCM1;
2156 pH[1] = Vec4( 0., 0., eCM1, eCM1);
2157 pH[2] = Vec4( 0., 0., -eCM2, eCM2);
2158 }
else if ( hasPointGammaB && beamAPtr->isHadron() ) {
2159 double eCM2 = 0.5 * ( s - pow2(mA) + pow2(mB) ) / eCM;
2160 double eCM1 = 0.25 * x1H * s / eCM2;
2161 pH[1] = Vec4( 0., 0., eCM1, eCM1);
2162 pH[2] = Vec4( 0., 0., -eCM2, eCM2);
2165 }
else if ( ( (beamAPtr->isLepton() && beamBPtr->isHadron())
2166 || (beamBPtr->isLepton() && beamAPtr->isHadron()) )
2167 && !settingsPtr->flag(
"PDF:lepton2gamma") ) {
2170 double pzAcm = 0.5 * sqrtpos( (eCM + mA + mB) * (eCM - mA - mB)
2171 * (eCM - mA + mB) * (eCM + mA - mB) ) / eCM;
2172 double eAcm = sqrt( mH[1]*mH[1] + pzAcm*pzAcm);
2173 double pzBcm = -pzAcm;
2174 double eBcm = sqrt( mH[2]*mH[2] + pzBcm*pzBcm);
2175 pH[1] = Vec4( 0., 0., pzAcm * x1H, eAcm * x1H);
2176 pH[2] = Vec4( 0., 0., pzBcm * x2H, eBcm * x2H);
2180 pH[1] = Vec4( 0., 0., 0.5 * eCM * x1H, 0.5 * eCM * x1H);
2181 pH[2] = Vec4( 0., 0., -0.5 * eCM * x2H, 0.5 * eCM * x2H);
2185 pH[3] = Vec4( 0., 0., pAbs, 0.5 * (sH + s3 - s4) / mHat);
2186 pH[4] = Vec4( 0., 0., -pAbs, 0.5 * (sH + s4 - s3) / mHat);
2190 phi = 2. * M_PI * rndmPtr->flat();
2191 betaZ = (x1H - x2H)/(x1H + x2H);
2192 pH[3].rot( theta, phi);
2193 pH[4].rot( theta, phi);
2194 pH[3].bst( 0., 0., betaZ);
2195 pH[4].bst( 0., 0., betaZ);
2196 pTH = pAbs * sin(theta);
2209 bool PhaseSpace2to2tauyz::constrainedM3M4() {
2212 bool foundNonZero =
false;
2213 double wtMassMax = 0.;
2214 double m3WtMax = 0.;
2215 double m4WtMax = 0.;
2216 double xMax = (mHatMax - mLower[3] - mLower[4]) / (mWidth[3] + mWidth[4]);
2217 double xStep = THRESHOLDSTEP * min(1., xMax);
2219 double wtMassXbin, wtMassMaxOld, m34, mT34Min, wtMassNow,
2220 wtBW3Now, wtBW4Now, beta34Now;
2226 wtMassMaxOld = wtMassMax;
2227 m34 = mHatMax - xNow * (mWidth[3] + mWidth[4]);
2230 m3 = min( mUpper[3], m34 - mLower[4]);
2231 if (m3 > mPeak[3]) m3 = max( mLower[3], mPeak[3]);
2233 if (m4 < mLower[4]) {m4 = mLower[4]; m3 = m34 - m4;}
2236 mT34Min = sqrt(m3*m3 + pT2HatMin) + sqrt(m4*m4 + pT2HatMin);
2237 if (mT34Min < mHatMax) {
2241 if (m3 > mLower[3] && m3 < mUpper[3] && m4 > mLower[4]
2242 && m4 < mUpper[4]) {
2243 wtBW3Now = mw[3] / ( pow2(m3*m3 - sPeak[3]) + pow2(mw[3]) );
2244 wtBW4Now = mw[4] / ( pow2(m4*m4 - sPeak[4]) + pow2(mw[4]) );
2245 beta34Now = sqrt( pow2(mHatMax*mHatMax - m3*m3 - m4*m4)
2246 - pow2(2. * m3 * m4) ) / (mHatMax*mHatMax);
2247 wtMassNow = wtBW3Now * wtBW4Now * beta34Now;
2251 if (wtMassNow > wtMassXbin) wtMassXbin = wtMassNow;
2252 if (wtMassNow > wtMassMax) {
2253 foundNonZero =
true;
2254 wtMassMax = wtMassNow;
2261 m4 = min( mUpper[4], m34 - mLower[3]);
2262 if (m4 > mPeak[4]) m4 = max( mLower[4], mPeak[4]);
2264 if (m3 < mLower[3]) {m3 = mLower[3]; m4 = m34 - m3;}
2267 mT34Min = sqrt(m3*m3 + pT2HatMin) + sqrt(m4*m4 + pT2HatMin);
2268 if (mT34Min < mHatMax) {
2272 if (m3 > mLower[3] && m3 < mUpper[3] && m4 > mLower[4]
2273 && m4 < mUpper[4]) {
2274 wtBW3Now = mw[3] / ( pow2(m3*m3 - sPeak[3]) + pow2(mw[3]) );
2275 wtBW4Now = mw[4] / ( pow2(m4*m4 - sPeak[4]) + pow2(mw[4]) );
2276 beta34Now = sqrt( pow2(mHatMax*mHatMax - m3*m3 - m4*m4)
2277 - pow2(2. * m3 * m4) ) / (mHatMax*mHatMax);
2278 wtMassNow = wtBW3Now * wtBW4Now * beta34Now;
2282 if (wtMassNow > wtMassXbin) wtMassXbin = wtMassNow;
2283 if (wtMassNow > wtMassMax) {
2284 foundNonZero =
true;
2285 wtMassMax = wtMassNow;
2292 }
while ( (!foundNonZero || wtMassXbin > wtMassMaxOld)
2293 && xNow < xMax - xStep);
2298 return foundNonZero;
2308 bool PhaseSpace2to2tauyz::constrainedM3() {
2311 bool foundNonZero =
false;
2312 double wtMassMax = 0.;
2313 double m3WtMax = 0.;
2314 double mT4Min = sqrt(m4*m4 + pT2HatMin);
2315 double xMax = (mHatMax - mLower[3] - m4) / mWidth[3];
2316 double xStep = THRESHOLDSTEP * min(1., xMax);
2318 double wtMassNow, mT34Min, wtBW3Now, beta34Now;
2324 m3 = mHatMax - m4 - xNow * mWidth[3];
2327 mT34Min = sqrt(m3*m3 + pT2HatMin) + mT4Min;
2328 if (mT34Min < mHatMax) {
2331 wtBW3Now = mw[3] / ( pow2(m3*m3 - sPeak[3]) + pow2(mw[3]) );
2332 beta34Now = sqrt( pow2(mHatMax*mHatMax - m3*m3 - m4*m4)
2333 - pow2(2. * m3 * m4) ) / (mHatMax*mHatMax);
2334 wtMassNow = wtBW3Now * beta34Now;
2337 if (wtMassNow > wtMassMax) {
2338 foundNonZero =
true;
2339 wtMassMax = wtMassNow;
2345 }
while ( (!foundNonZero || wtMassNow > wtMassMax)
2346 && xNow < xMax - xStep);
2350 return foundNonZero;
2360 bool PhaseSpace2to2tauyz::constrainedM4() {
2363 bool foundNonZero =
false;
2364 double wtMassMax = 0.;
2365 double m4WtMax = 0.;
2366 double mT3Min = sqrt(m3*m3 + pT2HatMin);
2367 double xMax = (mHatMax - mLower[4] - m3) / mWidth[4];
2368 double xStep = THRESHOLDSTEP * min(1., xMax);
2370 double wtMassNow, mT34Min, wtBW4Now, beta34Now;
2376 m4 = mHatMax - m3 - xNow * mWidth[4];
2379 mT34Min = mT3Min + sqrt(m4*m4 + pT2HatMin);
2380 if (mT34Min < mHatMax) {
2383 wtBW4Now = mw[4] / ( pow2(m4*m4 - sPeak[4]) + pow2(mw[4]) );
2384 beta34Now = sqrt( pow2(mHatMax*mHatMax - m3*m3 - m4*m4)
2385 - pow2(2. * m3 * m4) ) / (mHatMax*mHatMax);
2386 wtMassNow = wtBW4Now * beta34Now;
2389 if (wtMassNow > wtMassMax) {
2390 foundNonZero =
true;
2391 wtMassMax = wtMassNow;
2397 }
while ( (!foundNonZero || wtMassNow > wtMassMax)
2398 && xNow < xMax - xStep);
2402 return foundNonZero;
2410 void PhaseSpace2to2tauyz::rescaleSigma(
double sHatNew){
2413 if ( idMass[3] == 0 ) s3 = 0.;
2414 if ( idMass[4] == 0 ) s4 = 0.;
2418 double sH34 = -0.5 * (sH - s3 - s4);
2419 p2Abs = 0.25 * (pow2(sH - s3 - s4) - 4. * s3 * s4) / sH;
2420 pAbs = sqrtpos( p2Abs );
2422 tH = sH34 + mHat * pAbs * z;
2423 uH = sH34 - mHat * pAbs * z;
2424 pTH = sqrtpos( (tH * uH - s3 * s4) / sH);
2428 if (sigmaNw > TINY) {
2429 sigmaProcessPtr->set2Kin( x1H, x2H, sH, tH, m3, m4, runBW3H, runBW4H);
2430 sigmaNw = sigmaProcessPtr->sigmaPDF(
false,
true);
2431 sigmaNw *= wtTau * wtY * wtZ * wtBW;
2432 if (canBias2Sel) sigmaNw *= pow( pTH / bias2SelRef, bias2SelPow);
2442 void PhaseSpace2to2tauyz::rescaleMomenta(
double sHatNew){
2445 for (
int i = 0; i <= 1; ++i){
2448 int iPartonA = (i == 0) ? 1 : 3;
2449 int iPartonB = (i == 0) ? 2 : 4;
2452 Vec4 pA = p( iPartonA);
2453 Vec4 pB = p( iPartonB);
2456 double m2A = pow2( m( iPartonA) );
2457 double m2B = pow2( m( iPartonB) );
2458 double eA = 0.5 * ( sHatNew + m2A - m2B) / sqrt( sHatNew);
2459 double eB = 0.5 * ( sHatNew + m2B - m2A) / sqrt( sHatNew);
2460 double pz = 0.5 * sqrtpos( pow2(sHatNew - m2A - m2B) - 4.0 * m2A * m2B )
2462 Vec4 pANew( 0, 0, pz, eA );
2463 Vec4 pBNew( 0, 0, -pz, eB );
2466 RotBstMatrix MtoCMinc;
2467 MtoCMinc.toCMframe( pA, pB);
2471 pANew.rotbst( MtoCMinc);
2472 pBNew.rotbst( MtoCMinc);
2473 setP( iPartonA, pANew);
2474 setP( iPartonB, pBNew);
2482 double PhaseSpace2to2tauyz::weightGammaPDFApprox(){
2485 if (beamAPtr->getGammaMode() == 2 && beamBPtr->getGammaMode() == 2)
2487 if ( (beamAPtr->getGammaMode() == 2 && beamBPtr->isHadron())
2488 || (beamBPtr->getGammaMode() == 2 && beamAPtr->isHadron()) )
2492 double x1GammaHadr = beamAPtr->xGammaHadr();
2493 double x2GammaHadr = beamBPtr->xGammaHadr();
2494 double x1Gamma = beamAPtr->xGamma();
2495 double x2Gamma = beamBPtr->xGamma();
2496 double x1Hadr = x1GammaHadr / x1Gamma;
2497 double x2Hadr = x2GammaHadr / x2Gamma;
2500 if ( beamAPtr->isHadron() || beamAPtr->getGammaMode() == 2 ) {
2504 if ( beamBPtr->isHadron() || beamBPtr->getGammaMode() == 2 ) {
2510 double sigmaOver = sigmaProcessPtr->sigmaPDF(
false,
false,
true,
2511 x1GammaHadr, x2GammaHadr);
2512 double sigmaCorr = sigmaProcessPtr->sigmaPDF(
false,
false,
true,
2516 if (sigmaOver < TINY)
return 0.;
2519 return sigmaCorr / sigmaOver;
2534 const int PhaseSpace2to2elastic::NTRY = 1000;
2537 const double PhaseSpace2to2elastic::HBARC2 = 0.38938;
2540 const double PhaseSpace2to2elastic::BNARROW = 10.;
2541 const double PhaseSpace2to2elastic::BWIDE = 1.;
2542 const double PhaseSpace2to2elastic::WIDEFRAC = 0.1;
2543 const double PhaseSpace2to2elastic::TOFFSET = -0.2;
2550 bool PhaseSpace2to2elastic::setupSampling() {
2553 sigmaNw = sigmaProcessPtr->sigmaHatWrap();
2563 isOneExp = sigmaTotPtr->bElIsExp();
2564 useCoulomb = sigmaTotPtr->hasCoulomb();
2565 alphaEM0 = settingsPtr->parm(
"StandardModel:alphaEM0");
2568 lambda12S = pow2(s - s1 - s2) - 4. * s1 * s2 ;
2569 tLow = - lambda12S / s;
2570 tUpp = (useCoulomb) ? -settingsPtr->parm(
"SigmaElastic:tAbsMin") : 0.;
2573 bSlope1 = (isOneExp) ? sigmaTotPtr->bSlopeEl() : BNARROW;
2575 sigRef1 = sigmaTotPtr->dsigmaEl( tUpp,
false);
2577 sigNorm1 = sigRef1 / bSlope1;
2578 if (useCoulomb) sigNorm1 *= 2.;
2581 sigRef2 = sigmaTotPtr->dsigmaEl( tUpp + TOFFSET,
false);
2582 sigRef = (sigRef1 > 2. * sigRef2) ? 2. * sigRef1 : 5. * sigRef2;
2583 rel2 = exp((bSlope2 - bSlope1) * tUpp) * WIDEFRAC / (1. - WIDEFRAC);
2584 sigNorm1 = sigRef / (bSlope1 + rel2 * bSlope2);
2585 sigNorm2 = sigNorm1 * rel2;
2587 sigNorm3 = (useCoulomb) ? -2. * HBARC2 * 4. * M_PI * pow2(alphaEM0)
2589 sigNormSum = sigNorm1 + sigNorm2 + sigNorm3;
2601 bool PhaseSpace2to2elastic::trialKin(
bool,
bool ) {
2604 if (doEnergySpread) {
2605 eCM = infoPtr->eCM();
2607 lambda12S = pow2(s - s1 - s2) - 4. * s1 * s2 ;
2608 tLow = - lambda12S / s;
2612 double rNow, bNow, sigNow, sigEst;
2617 infoPtr->errorMsg(
"Error in PhaseSpace2to2elastic::trialKin: "
2618 " quit after repeated tries");
2621 rNow = rndmPtr->flat() * sigNormSum;
2622 if (useCoulomb && rNow > sigNorm1 + sigNorm2) tH = tUpp / rndmPtr->flat();
2624 bNow = (rNow < sigNorm1) ? bSlope1 : bSlope2;
2625 tH = tUpp + log( rndmPtr->flat() ) / bNow;
2627 sigNow = sigmaTotPtr->dsigmaEl( tH, useCoulomb);
2628 sigEst = sigNorm1 * bSlope1 * exp( bSlope1 * (tH - tUpp))
2629 + sigNorm2 * bSlope2 * exp( bSlope2 * (tH - tUpp));
2630 if (useCoulomb) sigEst += sigNorm3 * (-tUpp) / pow2(tH);
2631 }
while (tH < tLow || sigNow < sigEst * rndmPtr->flat());
2632 if (sigNow > 1.01 * sigEst) infoPtr->errorMsg(
"Warning in "
2633 "PhaseSpace2to2elastic::trialKin: cross section maximum violated");
2636 double tRat = s * tH / lambda12S;
2637 double cosTheta = min(1., max(-1., 1. + 2. * tRat ) );
2638 double sinTheta = 2. * sqrtpos( -tRat * (1. + tRat) );
2639 theta = asin( min(1., sinTheta));
2640 if (cosTheta < 0.) theta = M_PI - theta;
2651 bool PhaseSpace2to2elastic::finalKin() {
2660 pAbs = 0.5 * sqrtpos(lambda12S) / eCM;
2661 pH[1] = Vec4( 0., 0., pAbs, 0.5 * (s + s1 - s2) / eCM);
2662 pH[2] = Vec4( 0., 0., -pAbs, 0.5 * (s + s2 - s1) / eCM);
2665 pH[3] = Vec4( 0., 0., pAbs, 0.5 * (s + s1 - s2) / eCM);
2666 pH[4] = Vec4( 0., 0., -pAbs, 0.5 * (s + s2 - s1) / eCM);
2669 phi = 2. * M_PI * rndmPtr->flat();
2670 pH[3].rot( theta, phi);
2671 pH[4].rot( theta, phi);
2677 uH = 2. * (s1 + s2) - sH - tH;
2679 p2Abs = pAbs * pAbs;
2681 pTH = pAbs * sin(theta);
2699 const int PhaseSpace2to2diffractive::NTRY = 2500;
2702 const double PhaseSpace2to2diffractive::BWID1 = 8.;
2703 const double PhaseSpace2to2diffractive::BWID2 = 2.;
2704 const double PhaseSpace2to2diffractive::BWID3 = 0.5;
2705 const double PhaseSpace2to2diffractive::BWID4 = 0.2;
2706 const double PhaseSpace2to2diffractive::FWID1SD = 1.;
2707 const double PhaseSpace2to2diffractive::FWID2SD = 0.2;
2708 const double PhaseSpace2to2diffractive::FWID3SD = 0.1;
2709 const double PhaseSpace2to2diffractive::FWID4SD = 0.1;
2710 const double PhaseSpace2to2diffractive::FWID1DD = 0.1;
2711 const double PhaseSpace2to2diffractive::FWID2DD = 1.;
2712 const double PhaseSpace2to2diffractive::FWID3DD = 0.5;
2713 const double PhaseSpace2to2diffractive::FWID4DD = 0.2;
2716 const double PhaseSpace2to2diffractive::MAXFUDGESD = 2.;
2717 const double PhaseSpace2to2diffractive::MAXFUDGEDD = 2.;
2718 const double PhaseSpace2to2diffractive::MAXFUDGET = 4.;
2721 const double PhaseSpace2to2diffractive::DIFFMASSMARGIN = 0.2;
2724 const double PhaseSpace2to2diffractive::SPROTON = 0.8803544;
2731 bool PhaseSpace2to2diffractive::setupSampling() {
2734 sigmaNw = sigmaProcessPtr->sigmaHatWrap();
2738 double mPi = particleDataPtr->m0(211);
2739 m3ElDiff = (isDiffA) ? mA + mPi : mA;
2740 m4ElDiff = (isDiffB) ? mB + mPi : mB;
2743 s3 = pow2( m3ElDiff);
2744 s4 = pow2( m4ElDiff);
2747 lambda12 = sqrtpos( pow2( s - s1 - s2) - 4. * s1 * s2 );
2751 splitxit = sigmaTotPtr->splitDiff();
2752 int step = (splitxit) ? 1 : 0;
2757 xiMin = (isDiffA) ? s3 / s : s4 / s;
2758 for (
int i = 0; i < 100; ++i) {
2759 xiNow = pow( xiMin, 0.01 * i + 0.005);
2760 sigNow = sigmaTotPtr->dsigmaSD( xiNow, 0., isDiffA, step);
2761 if (sigNow > sigMax) sigMax = sigNow;
2766 xiMin = max( s3, s4) / s;
2767 xiMax = sqrt( SPROTON / s);
2768 for (
int i = 0; i < 100; ++i) {
2769 xiNow = xiMin * pow( xiMax / xiMin, 0.01 * i + 0.005);
2770 sigNow = sigmaTotPtr->dsigmaDD( xiNow, xiNow, 0., step);
2771 if (sigNow > sigMax) sigMax = sigNow;
2774 sigMax *= (isSD ? MAXFUDGESD : MAXFUDGEDD);
2777 fWid1 = (isSD ? FWID1SD : FWID1DD);
2778 fWid2 = (isSD ? FWID2SD : FWID2DD);
2779 fWid3 = (isSD ? FWID3SD : FWID3DD);
2780 fWid4 = (isSD ? FWID4SD : FWID4DD);
2781 fbWid1 = fWid1 * BWID1;
2782 fbWid2 = fWid2 * BWID2;
2783 fbWid3 = fWid3 * BWID3;
2784 fbWid4 = fWid4 * BWID4;
2785 fbWid1234 = fbWid1 + fbWid2 + fbWid3 + fbWid4;
2797 bool PhaseSpace2to2diffractive::trialKin(
bool,
bool ) {
2800 if (doEnergySpread) {
2801 eCM = infoPtr->eCM();
2803 lambda12 = sqrtpos( pow2( s - s1 - s2) - 4. * s1 * s2 );
2807 int nStep = (splitxit) ? 2 : 1;
2808 for (
int iStep = 0; iStep < nStep; ++iStep) {
2809 int step = (splitxit) ? iStep + 1 : 0;
2812 for (
int loop = 0; ; ++loop) {
2814 infoPtr->errorMsg(
"Error in PhaseSpace2to2diffractive::trialKin: "
2815 " quit after repeated tries");
2821 m3 = (isDiffA) ? m3ElDiff * pow( max(mA, eCM - m4ElDiff) / m3ElDiff,
2822 rndmPtr->flat()) : m3ElDiff;
2823 m4 = (isDiffB) ? m4ElDiff * pow( max(mB, eCM - m3ElDiff) / m4ElDiff,
2824 rndmPtr->flat()) : m4ElDiff;
2825 if (m3 + m4 + DIFFMASSMARGIN >= eCM)
continue;
2832 double pickb = rndmPtr->flat() * (fWid1 + fWid2 + fWid3 + fWid4);
2833 bNow = (pickb < fWid1) ? BWID1
2834 : ( (pickb < fWid1 + fWid2) ? BWID2
2835 : ( (pickb < fWid1 + fWid2 + fWid3) ? BWID3 : BWID4 ) );
2836 tH = log(rndmPtr->flat()) / bNow;
2839 lambda34 = sqrtpos( pow2( s - s3 - s4) - 4. * s3 * s4 );
2840 tempA = s - (s1 + s2 + s3 + s4) + (s1 - s2) * (s3 - s4) / s;
2841 tempB = lambda12 * lambda34 / s;
2842 tempC = (s3 - s1) * (s4 - s2) + (s1 + s4 - s2 - s3)
2843 * (s1 * s4 - s2 * s3) / s;
2844 tLow = -0.5 * (tempA + tempB);
2845 tUpp = tempC / tLow;
2846 if (tH < tLow || tH > tUpp)
continue;
2851 xiNow = (isDiffA) ? s3 / s : s4 / s;
2852 sigNow = sigmaTotPtr->dsigmaSD( xiNow, tH, isDiffA, step);
2854 sigNow = sigmaTotPtr->dsigmaDD( s3 / s, s4 / s, tH, step);
2858 tWeight = ( fbWid1 * exp( BWID1 * tH) + fbWid2 * exp(BWID2 * tH)
2859 + fbWid3 * exp(BWID3 * tH) + fbWid4 * exp(BWID4 * tH) ) / fbWid1234;
2860 sigMaxNow = (step == 0) ? sigMax * tWeight
2861 : ( (step == 1) ? sigMax : MAXFUDGET * tWeight );
2864 if (sigNow > sigMaxNow) infoPtr->errorMsg(
"Error in PhaseSpace2to2"
2865 "diffractive::trialKin: maximum cross section violated");
2866 if (sigNow > rndmPtr->flat() * sigMaxNow)
break;
2873 double cosTheta = min(1., max(-1., (tempA + 2. * tH) / tempB));
2874 double sinTheta = 2. * sqrtpos( -(tempC + tempA * tH + tH * tH) ) / tempB;
2875 theta = asin( min(1., sinTheta));
2876 if (cosTheta < 0.) theta = M_PI - theta;
2887 bool PhaseSpace2to2diffractive::finalKin() {
2896 pAbs = 0.5 * lambda12 / eCM;
2897 pH[1] = Vec4( 0., 0., pAbs, 0.5 * (s + s1 - s2) / eCM);
2898 pH[2] = Vec4( 0., 0., -pAbs, 0.5 * (s + s2 - s1) / eCM);
2901 pAbs = 0.5 * lambda34 / eCM;
2902 pH[3] = Vec4( 0., 0., pAbs, 0.5 * (s + s3 - s4) / eCM);
2903 pH[4] = Vec4( 0., 0., -pAbs, 0.5 * (s + s4 - s3) / eCM);
2906 phi = 2. * M_PI * rndmPtr->flat();
2907 pH[3].rot( theta, phi);
2908 pH[4].rot( theta, phi);
2914 uH = s1 + s2 + s3 + s4 - sH - tH;
2916 p2Abs = pAbs * pAbs;
2918 pTH = pAbs * sin(theta);
2936 const int PhaseSpace2to3diffractive::NTRY = 2500;
2939 const double PhaseSpace2to3diffractive::BWID1 = 8.;
2940 const double PhaseSpace2to3diffractive::BWID2 = 4.;
2941 const double PhaseSpace2to3diffractive::BWID3 = 1.;
2942 const double PhaseSpace2to3diffractive::FWID1 = 1.;
2943 const double PhaseSpace2to3diffractive::FWID2 = 0.4;
2944 const double PhaseSpace2to3diffractive::FWID3 = 0.1;
2947 const double PhaseSpace2to3diffractive::MAXFUDGECD = 2.5;
2948 const double PhaseSpace2to3diffractive::MAXFUDGET = 10.0;
2951 const double PhaseSpace2to3diffractive::DIFFMASSMARGIN = 0.2;
2957 bool PhaseSpace2to3diffractive::setupSampling() {
2960 sigmaNw = sigmaProcessPtr->sigmaHatWrap();
2968 m5min = sigmaTotPtr->mMinCD();
2969 s5min = m5min * m5min;
2973 splitxit = sigmaTotPtr->splitDiff();
2974 int step = (splitxit) ? 1 : 0;
2980 for (
int i = 0; i < 100; ++i)
2981 for (
int j = 0; j <= i; ++j) {
2982 xi1 = pow( xiMin, 0.01 * i + 0.005);
2983 xi2 = pow( xiMin, 0.01 * j + 0.005);
2984 if (xi1 * xi2 > xiMin) {
2985 sigNow = sigmaTotPtr->dsigmaCD( xi1, xi2, 0., 0., step);
2986 if (sigNow > sigMax) sigMax = sigNow;
2989 sigMax *= MAXFUDGECD;
2995 fbWid1 = fWid1 * BWID1;
2996 fbWid2 = fWid2 * BWID2;
2997 fbWid3 = fWid3 * BWID3;
2998 fbWid123 = fbWid1 + fbWid2 + fbWid3;
3010 bool PhaseSpace2to3diffractive::trialKin(
bool,
bool ) {
3013 if (doEnergySpread) {
3014 eCM = infoPtr->eCM();
3019 pAbs = 0.5 * sqrtpos( pow2( s - s1 - s2) - 4. * s1 * s2 ) / 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 double pickb, bNow, tNow, sx1, sx2, sx3, sx4, t1, t2, tWeight1, tWeight2,
3025 lambda12, lambda34, tempA, tempB, tempC, cosTheta, sinTheta, pz, pT,
3026 deltaE, p2Esum, facP;
3027 xi1 = xi2 = t1 = t2 = 0.;
3030 int nStep = (splitxit) ? 2 : 1;
3031 for (
int iStep = 0; iStep < nStep; ++iStep) {
3032 int step = (splitxit) ? iStep + 1 : 0;
3035 for (
int loop = 0; ; ++loop) {
3037 infoPtr->errorMsg(
"Error in PhaseSpace2to3diffractive::trialKin: "
3038 " quit after repeated tries");
3045 xi1 = pow( s5min / s, rndmPtr->flat());
3046 xi2 = pow( s5min / s, rndmPtr->flat());
3049 }
while (m5 < m5min || mA + mB + m5 + DIFFMASSMARGIN > eCM);
3054 bool tryAgain =
false;
3055 for (
int i = 0; i < 2; ++i) {
3056 pickb = rndmPtr->flat() * (fWid1 + fWid2 + fWid3);
3057 bNow = (pickb < fWid1) ? BWID1
3058 : ( (pickb < fWid1 + fWid2) ? BWID2 : BWID3 );
3059 tNow = log(rndmPtr->flat()) / bNow;
3062 sx1 = (i == 0) ? s1 : s2;
3063 sx2 = (i == 0) ? s2 : s1;
3065 sx4 = (i == 0) ? s2 + xi1 * s : s1 + xi2 * s;
3066 if (sqrt(sx3) + sqrt(sx4) + DIFFMASSMARGIN > eCM) tryAgain =
true;
3067 if (!tInRange(tNow, s, sx1, sx2, sx3, sx4)) tryAgain =
true;
3068 if (tryAgain)
break;
3069 if (i == 0) t1 = tNow;
3072 if (tryAgain)
continue;
3076 sigNow = sigmaTotPtr->dsigmaCD( xi1, xi2, t1, t2, step);
3079 tWeight1 = ( fbWid1 * exp( BWID1 * t1) + fbWid2 * exp(BWID2 * t1)
3080 + fbWid3 * exp(BWID3 * t1) ) / fbWid123;
3081 tWeight2 = ( fbWid1 * exp( BWID1 * t2) + fbWid2 * exp(BWID2 * t2)
3082 + fbWid3 * exp(BWID3 * t2) ) / fbWid123;
3083 sigMaxNow = (step == 0) ? sigMax * tWeight1 * tWeight2
3084 : ( (step == 1) ? sigMax : MAXFUDGET * tWeight1 * tWeight2 );
3087 if (sigNow > sigMaxNow) infoPtr->errorMsg(
"Error in PhaseSpace2to3"
3088 "diffractive::trialKin: maximum cross section violated");
3089 if (sigNow > rndmPtr->flat() * sigMaxNow)
break;
3096 for (
int i = 0; i < 2; ++i) {
3097 tNow = (i == 0) ? t1 : t2;
3098 sx1 = (i == 0) ? s1 : s2;
3099 sx2 = (i == 0) ? s2 : s1;
3101 sx4 = (i == 0) ? s2 + xi1 * s : s1 + xi2 * s;
3102 lambda12 = sqrtpos( pow2( s - sx1 - sx2) - 4. * sx1 * sx2 );
3103 lambda34 = sqrtpos( pow2( s - sx3 - sx4) - 4. * sx3 * sx4 );
3104 tempA = s - (sx1 + sx2 + sx3 + sx4) + (sx1 - sx2) * (sx3 - sx4) / s;
3105 tempB = lambda12 * lambda34 / s;
3106 tempC = (sx3 - sx1) * (sx4 - sx2) + (sx1 + sx4 - sx2 - sx3)
3107 * (sx1 * sx4 - sx2 * sx3) / s;
3108 cosTheta = min(1., max(-1., (tempA + 2. * tNow) / tempB));
3109 sinTheta = 2. * sqrtpos( -(tempC + tempA * tNow + tNow * tNow) ) / tempB;
3110 theta = asin( min(1., sinTheta));
3111 if (cosTheta < 0.) theta = M_PI - theta;
3114 pAbs = 0.5 * lambda34 / eCM;
3115 pz = (i == 0) ? pAbs * cos(theta) : -pAbs * cos(theta);
3116 pT = pAbs * sin(theta);
3117 phi = 2. * M_PI * rndmPtr->flat();
3118 Vec4& pNow = (i == 0) ? p3 : p4;
3119 pNow.p( pT * cos(phi), pT * sin(phi), pz, sqrt(pAbs * pAbs + sx1) );
3123 p5 = (p1 - p3) + (p2 - p4);
3124 p5.e( sqrt(s5 + p5.pAbs2()) );
3125 for (
int iter = 0; iter < 5; ++iter) {
3126 deltaE = eCM - p3.e() - p4.e() - p5.e();
3127 if (abs(deltaE) < 1e-10 * eCM)
break;
3128 p2Esum = p3.pAbs2() / p3.e() + p4.pAbs2() / p4.e() + p5.pAbs2() / p5.e();
3129 facP = 1. + deltaE / p2Esum;
3133 p3.e( sqrt(s1 + p3.pAbs2()) );
3134 p4.e( sqrt(s2 + p4.pAbs2()) );
3135 p5.e( sqrt(s5 + p5.pAbs2()) );
3145 bool PhaseSpace2to3diffractive::finalKin() {
3163 tH = (p1 - p3).m2Calc();
3164 uH = (p2 - p4).m2Calc();
3166 p2Abs = pAbs * pAbs;
3169 pTH = (p3.pT() + p4.pT() + p5.pT()) / 3.;
3186 bool PhaseSpace2to2nondiffractiveGamma::setupSampling() {
3189 Q2maxGamma = settingsPtr->parm(
"Photon:Q2max");
3190 Wmin = settingsPtr->parm(
"Photon:Wmin");
3191 bool hasGamma = settingsPtr->flag(
"PDF:lepton2gamma");
3192 externalFlux = settingsPtr->mode(
"PDF:lepton2gammaSet") == 2;
3193 sampleQ2 = settingsPtr->flag(
"Photon:sampleQ2");
3196 alphaEM = couplingsPtr->alphaEM(Q2maxGamma);
3198 gammaA = beamAPtr->isGamma() || (beamAPtr->isLepton() && hasGamma);
3199 gammaB = beamBPtr->isGamma() || (beamBPtr->isLepton() && hasGamma);
3200 idAin = gammaA ? 22 : beamAPtr->id();
3201 idBin = gammaB ? 22 : beamBPtr->id();
3202 sigmaTotPtr->calc( idAin, idBin, eCM);
3203 sigmaNDmax = sigmaTotPtr->sigmaND();
3206 m2BeamA = pow2( mA );
3207 m2BeamB = pow2( mB );
3208 m2sA = 4. * m2BeamA / sCM;
3209 m2sB = 4. * m2BeamB / sCM;
3212 double m2GmGmMin = pow2(Wmin);
3213 double xGamAMax = 1.;
3214 double xGamBMax = 1.;
3215 double xGamAMin = m2GmGmMin / sCM ;
3216 double xGamBMin = m2GmGmMin / sCM ;
3225 xGamAMax = Q2maxGamma / (2. * m2BeamA)
3226 * (sqrt( (1. + 4. * m2BeamA / Q2maxGamma) * (1. - m2sA) ) - 1.);
3227 if ( !externalFlux) {
3228 log2xMinA = pow2( log( Q2maxGamma/ ( m2BeamA * pow2(xGamAMin) ) ) );
3229 log2xMaxA = pow2( log( Q2maxGamma/ ( m2BeamA * pow2(xGamAMax) ) ) );
3235 xGamBMax = Q2maxGamma / (2. * m2BeamB)
3236 * (sqrt( (1. + 4. * m2BeamB / Q2maxGamma) * (1. - m2sB) ) - 1.);
3237 if ( !externalFlux) {
3238 log2xMinB = pow2( log( Q2maxGamma/ ( m2BeamB * pow2(xGamBMin) ) ) );
3239 log2xMaxB = pow2( log( Q2maxGamma/ ( m2BeamB * pow2(xGamBMax) ) ) );
3244 if ( !externalFlux) {
3245 if ( gammaA && gammaB) {
3246 sigmaNDestimate = pow2( 0.5 * alphaEM / M_PI ) * 0.25
3247 * (log2xMinA - log2xMaxA) * (log2xMinB - log2xMaxB) * sigmaNDmax;
3248 }
else if (gammaA) {
3249 sigmaNDestimate = 0.5 * alphaEM / M_PI
3250 * 0.5 * (log2xMinA - log2xMaxA) * sigmaNDmax;
3251 }
else if (gammaB) {
3252 sigmaNDestimate = 0.5 * alphaEM / M_PI
3253 * 0.5 * (log2xMinB - log2xMaxB) * sigmaNDmax;
3260 double Q2minA = beamAPtr->Q2minPDF();
3261 double Q2minB = beamBPtr->Q2minPDF();
3262 double rescaleA = beamAPtr->gammaFluxNorm();
3263 double rescaleB = beamBPtr->gammaFluxNorm();
3266 if ( gammaA && gammaB) {
3267 sigmaNDestimate = pow2( alphaEM / M_PI ) * sigmaNDmax
3268 * rescaleA * log(xGamAMax / xGamAMin) * log(Q2maxGamma / Q2minA)
3269 * rescaleB * log(xGamBMax / xGamBMin) * log(Q2maxGamma / Q2minB);
3270 }
else if (gammaA) {
3271 sigmaNDestimate = alphaEM / M_PI * sigmaNDmax
3272 * rescaleA * log(xGamAMax / xGamAMin) * log(Q2maxGamma / Q2minA);
3273 }
else if (gammaB) {
3274 sigmaNDestimate = alphaEM / M_PI * sigmaNDmax
3275 * rescaleB * log(xGamBMax / xGamBMin) * log(Q2maxGamma / Q2minB);
3280 sigmaNw = sigmaNDestimate;
3281 sigmaMx = sigmaNDestimate;
3292 bool PhaseSpace2to2nondiffractiveGamma::trialKin(
bool ,
bool) {
3298 if ( !externalFlux) {
3299 if (gammaA) xGamma1 = sqrt( (Q2maxGamma / m2BeamA) * exp( -sqrt( log2xMinA
3300 + rndmPtr->flat() * (log2xMaxA - log2xMinA) ) ) );
3301 if (gammaB) xGamma2 = sqrt( (Q2maxGamma / m2BeamB) * exp( -sqrt( log2xMinB
3302 + rndmPtr->flat() * (log2xMaxB - log2xMinB) ) ) );
3305 beamAPtr->xGamma(xGamma1);
3306 beamBPtr->xGamma(xGamma2);
3310 if ( !(gammaKinPtr->sampleKTgamma(
true) ) )
return false;
3314 xGamma1 = beamAPtr->xGamma();
3315 xGamma2 = beamBPtr->xGamma();
3319 Q2gamma1 = gammaKinPtr->getQ2gamma1();
3320 Q2gamma2 = gammaKinPtr->getQ2gamma2();
3321 Q2min1 = gammaKinPtr->getQ2min1();
3322 Q2min2 = gammaKinPtr->getQ2min2();
3323 mGmGm = gammaKinPtr->eCMsub();
3331 if ( !externalFlux) {
3332 wt1 = ( 0.5 * ( 1. + pow2(1 - xGamma1) ) ) * log( Q2maxGamma/Q2min1 )
3333 / log( Q2maxGamma / ( m2BeamA * pow2( xGamma1 ) ) );
3337 wt1 = sampleQ2 ? beamAPtr->xfFlux(22, xGamma1, Q2gamma1)
3338 / beamAPtr->xfApprox(22, xGamma1, Q2gamma1) :
3339 beamAPtr->xfFlux(22, xGamma1, Q2gamma1)
3340 / beamAPtr->xf(22, xGamma1, Q2gamma1);
3346 if ( !externalFlux) {
3347 wt2 = ( 0.5 * ( 1. + pow2(1 - xGamma2) ) ) * log( Q2maxGamma/Q2min2 )
3348 / log( Q2maxGamma / ( m2BeamB * pow2( xGamma2 ) ) );
3352 wt2 = sampleQ2 ? beamBPtr->xfFlux(22, xGamma2, Q2gamma2)
3353 / beamBPtr->xfApprox(22, xGamma2, Q2gamma2) :
3354 beamBPtr->xfFlux(22, xGamma2, Q2gamma2)
3355 / beamBPtr->xf(22, xGamma2, Q2gamma2);
3360 sigmaTotPtr->calc( idAin, idBin, mGmGm );
3361 double sigmaNDnow = sigmaTotPtr->sigmaND();
3362 double wtSigma = sigmaNDnow/sigmaNDmax;
3365 double wtAlphaEM1 = gammaA ? couplingsPtr->alphaEM(Q2gamma1) / alphaEM : 1.;
3366 double wtAlphaEM2 = gammaB ? couplingsPtr->alphaEM(Q2gamma2) / alphaEM : 1.;
3367 double wtAlphaEM = wtAlphaEM1 * wtAlphaEM2;
3370 wt *= wt1 * wt2 * wtSigma * wtAlphaEM;
3372 infoPtr->errorMsg(
"Warning in PhaseSpace2to2nondiffractiveGamma::trialKin:"
3373 " weight above unity");
3377 if ( wt < rndmPtr->flat() )
return false;
3395 const int PhaseSpace2to3tauycyl::NITERNR = 5;
3401 bool PhaseSpace2to3tauycyl::setupMasses() {
3404 gmZmode = gmZmodeGlobal;
3405 int gmZmodeProc = sigmaProcessPtr->gmZmode();
3406 if (gmZmodeProc >= 0) gmZmode = gmZmodeProc;
3409 mHatMin = mHatGlobalMin;
3410 sHatMin = mHatMin*mHatMin;
3412 if (mHatGlobalMax > mHatGlobalMin) mHatMax = min( eCM, mHatGlobalMax);
3413 sHatMax = mHatMax*mHatMax;
3421 if (useBW[3]) mUpper[3] -= (mPeak[4] + mPeak[5]);
3422 if (useBW[4]) mUpper[4] -= (mPeak[3] + mPeak[5]);
3423 if (useBW[5]) mUpper[5] -= (mPeak[3] + mPeak[4]);
3426 bool physical =
true;
3427 if (useBW[3] && mUpper[3] < mLower[3] + MASSMARGIN) physical =
false;
3428 if (useBW[4] && mUpper[4] < mLower[4] + MASSMARGIN) physical =
false;
3429 if (useBW[5] && mUpper[5] < mLower[5] + MASSMARGIN) physical =
false;
3430 if (!useBW[3] && !useBW[4] && !useBW[5] && mHatMax < mPeak[3]
3431 + mPeak[4] + mPeak[5] + MASSMARGIN) physical =
false;
3432 if (!physical)
return false;
3435 pTHatMin = pTHatGlobalMin;
3436 pT2HatMin = pTHatMin * pTHatMin;
3437 pTHatMax = pTHatGlobalMax;
3438 pT2HatMax = pTHatMax * pTHatMax;
3442 double distToThreshA = (mHatMax - mPeak[3] - mPeak[4] - mPeak[5])
3443 * mWidth[3] / (pow2(mWidth[3]) + pow2(mWidth[4]) + pow2(mWidth[5]));
3444 double distToThreshB = (mHatMax - mPeak[3] - mMin[4] - mMin[5])
3446 double distToThresh = min( distToThreshA, distToThreshB);
3447 setupMass2(3, distToThresh);
3452 double distToThreshA = (mHatMax - mPeak[3] - mPeak[4] - mPeak[5])
3453 * mWidth[4] / (pow2(mWidth[3]) + pow2(mWidth[4]) + pow2(mWidth[5]));
3454 double distToThreshB = (mHatMax - mPeak[4] - mMin[3] - mMin[5])
3456 double distToThresh = min( distToThreshA, distToThreshB);
3457 setupMass2(4, distToThresh);
3462 double distToThreshA = (mHatMax - mPeak[3] - mPeak[4] - mPeak[5])
3463 * mWidth[5] / (pow2(mWidth[3]) + pow2(mWidth[4]) + pow2(mWidth[5]));
3464 double distToThreshB = (mHatMax - mPeak[5] - mMin[3] - mMin[4])
3466 double distToThresh = min( distToThreshA, distToThreshB);
3467 setupMass2(5, distToThresh);
3471 m3 = (useBW[3]) ? min(mPeak[3], mUpper[3]) : mPeak[3];
3472 m4 = (useBW[4]) ? min(mPeak[4], mUpper[4]) : mPeak[4];
3473 m5 = (useBW[5]) ? min(mPeak[5], mUpper[5]) : mPeak[5];
3474 if (m3 + m4 + m5 + MASSMARGIN > mHatMax) physical =
false;
3482 if (useBW[3]) wtBW *= weightMass(3) * EXTRABWWTMAX;
3483 if (useBW[4]) wtBW *= weightMass(4) * EXTRABWWTMAX;
3484 if (useBW[5]) wtBW *= weightMass(5) * EXTRABWWTMAX;
3495 bool PhaseSpace2to3tauycyl::trialMasses() {
3507 if (m3 + m4 + m5 + MASSMARGIN > mHatMax)
return false;
3510 if (useBW[3]) wtBW *= weightMass(3);
3511 if (useBW[4]) wtBW *= weightMass(4);
3512 if (useBW[5]) wtBW *= weightMass(5);
3523 bool PhaseSpace2to3tauycyl::finalKin() {
3526 int id3 = sigmaProcessPtr->id(3);
3527 int id4 = sigmaProcessPtr->id(4);
3528 int id5 = sigmaProcessPtr->id(5);
3529 if (idMass[3] == 0) { m3 = particleDataPtr->m0(id3); s3 = m3*m3; }
3530 if (idMass[4] == 0) { m4 = particleDataPtr->m0(id4); s4 = m4*m4; }
3531 if (idMass[5] == 0) { m5 = particleDataPtr->m0(id5); s5 = m5*m5; }
3534 if (m3 + m4 + m5 + MASSMARGIN > mHat) {
3535 infoPtr->errorMsg(
"Warning in PhaseSpace2to3tauycyl::finalKin: "
3536 "failed after mass assignment");
3548 pH[1] = Vec4( 0., 0., 0.5 * eCM * x1H, 0.5 * eCM * x1H);
3549 pH[2] = Vec4( 0., 0., -0.5 * eCM * x2H, 0.5 * eCM * x2H);
3552 if (idMass[3] == 0 || idMass[4] == 0 || idMass[5] == 0) {
3553 double p3S = p3cm.pAbs2();
3554 double p4S = p4cm.pAbs2();
3555 double p5S = p5cm.pAbs2();
3557 double e3, e4, e5, value, deriv;
3560 for (
int i = 0; i < NITERNR; ++i) {
3561 e3 = sqrt(s3 + fac * p3S);
3562 e4 = sqrt(s4 + fac * p4S);
3563 e5 = sqrt(s5 + fac * p5S);
3564 value = e3 + e4 + e5 - mHat;
3565 deriv = 0.5 * (p3S / e3 + p4S / e4 + p5S / e5);
3566 fac -= value / deriv;
3570 double facRoot = sqrt(fac);
3571 p3cm.rescale3( facRoot );
3572 p4cm.rescale3( facRoot );
3573 p5cm.rescale3( facRoot );
3574 p3cm.e( sqrt(s3 + fac * p3S) );
3575 p4cm.e( sqrt(s4 + fac * p4S) );
3576 p5cm.e( sqrt(s5 + fac * p5S) );
3585 betaZ = (x1H - x2H)/(x1H + x2H);
3586 pH[3].rot( theta, phi);
3587 pH[4].rot( theta, phi);
3588 pH[3].bst( 0., 0., betaZ);
3589 pH[4].bst( 0., 0., betaZ);
3590 pH[5].bst( 0., 0., betaZ);
3593 pTH = (p3cm.pT() + p4cm.pT() + p5cm.pT()) / 3.;
3609 bool PhaseSpace2to3yyycyl::setupSampling() {
3612 pTHat3Min = settingsPtr->parm(
"PhaseSpace:pTHat3Min");
3613 pTHat3Max = settingsPtr->parm(
"PhaseSpace:pTHat3Max");
3614 pTHat5Min = settingsPtr->parm(
"PhaseSpace:pTHat5Min");
3615 pTHat5Max = settingsPtr->parm(
"PhaseSpace:pTHat5Max");
3616 RsepMin = settingsPtr->parm(
"PhaseSpace:RsepMin");
3617 R2sepMin = pow2(RsepMin);
3620 hasBaryonBeams = ( beamAPtr->isBaryon() && beamBPtr->isBaryon() );
3623 for (
int i = 0; i < 6; ++i) mH[i] = 0.;
3628 if (pT3Max < pT3Min) pT3Max = 0.5 * eCM;
3631 if (pT5Max < pT5Min) pT5Max = 0.5 * eCM;
3632 if (pT5Max > pT3Max || pT5Min > pT3Min || pT3Min + 2. * pT5Min > eCM) {
3633 infoPtr->errorMsg(
"Error in PhaseSpace2to3yyycyl::setupSampling: "
3634 "inconsistent pT limits in 3-body phase space");
3642 double pT5EffMax = min( pT5Max, 0.5 * pT3Min / cos(0.5 * RsepMin) );
3643 double pT3EffMin = max( pT3Min, 2.0 * pT5Min * cos(0.5 * RsepMin) ) ;
3644 double sinhR = sinh(0.5 * RsepMin);
3645 double coshR = cosh(0.5 * RsepMin);
3646 for (
int iStep = 0; iStep < 120; ++iStep) {
3651 pT5 = pT5Min * pow( pT5EffMax / pT5Min, iStep / 9.);
3652 double pTRat = pT5 / pT3;
3653 double sin2Rsep = pow2( sin(RsepMin) );
3654 double cosPhi35 = - cos(RsepMin) * sqrtpos(1. - sin2Rsep
3655 * pow2(pTRat)) - sin2Rsep * pTRat;
3656 cosPhi35 = max( cosPhi35, cos(M_PI - 0.5 * RsepMin) );
3657 double sinPhi35 = sqrt(1. - pow2(cosPhi35));
3658 pT4 = sqrt( pow2(pT3) + pow2(pT5) + 2. * pT3 * pT5 * cosPhi35);
3659 p3cm = pT3 * Vec4( 1., 0., 0., 1.);
3660 p4cm = Vec4(-pT3 - pT5 * cosPhi35, -pT5 * sinPhi35, 0., pT4);
3661 p5cm = pT5 * Vec4( cosPhi35, sinPhi35, 0., 1.);
3665 pT5 = pT5Min * pow( pT5Max / pT5Min, iStep%10 / 9. );
3666 pT3 = max( pT3Min, 2. * pT5);
3668 p4cm = pT4 * Vec4( -1., 0., sinhR, coshR );
3669 p5cm = pT5 * Vec4( -1., 0., -sinhR, coshR );
3670 y3 = -1.2 + 0.2 * (iStep/10);
3671 p3cm = pT3 * Vec4( 1., 0., sinh(y3), cosh(y3));
3672 betaZ = (p3cm.pz() + p4cm.pz() + p5cm.pz())
3673 / (p3cm.e() + p4cm.e() + p5cm.e());
3674 p3cm.bst( 0., 0., -betaZ);
3675 p4cm.bst( 0., 0., -betaZ);
3676 p5cm.bst( 0., 0., -betaZ);
3680 pInSum = p3cm + p4cm + p5cm;
3681 x1H = pInSum.e() / eCM;
3683 sH = pInSum.m2Calc();
3684 sigmaProcessPtr->set3Kin( x1H, x2H, sH, p3cm, p4cm, p5cm,
3685 0., 0., 0., 1., 1., 1.);
3686 sigmaNw = sigmaProcessPtr->sigmaPDF();
3689 double flux = 1. /(8. * pow2(sH) * pow5(2. * M_PI));
3690 double pTRng = pow2(M_PI)
3691 * pow4(pT3) * (1./pow2(pT3Min) - 1./pow2(pT3Max))
3692 * pow2(pT5) * 2.* log(pT5Max/pT5Min);
3693 double yRng = 8. * log(eCM / pT3) * log(eCM / pT4) * log(eCM / pT5);
3694 sigmaNw *= SAFETYMARGIN * flux * pTRng * yRng;
3697 if (showSearch && sigmaNw > sigmaMx) cout <<
"\n New sigmamax is "
3698 << scientific << setprecision(3) << sigmaNw <<
" for x1 = " << x1H
3699 <<
" x2 = " << x2H <<
" sH = " << sH << endl <<
" p3 = " << p3cm
3700 <<
" p4 = " << p4cm <<
" p5 = " << p5cm;
3701 if (sigmaNw > sigmaMx) sigmaMx = sigmaNw;
3713 bool PhaseSpace2to3yyycyl::trialKin(
bool inEvent,
bool) {
3716 if (doEnergySpread) {
3717 eCM = infoPtr->eCM();
3725 if (pT3Max < pT3Min) pT3Max = 0.5 * eCM;
3728 if (pT5Max < pT5Min) pT5Max = 0.5 * eCM;
3729 if (pT5Max > pT3Max || pT5Min > pT3Min || pT3Min + 2. * pT5Min > eCM) {
3730 infoPtr->errorMsg(
"Error in PhaseSpace2to3yyycyl::trialKin: "
3731 "inconsistent pT limits in 3-body phase space");
3736 pT3 = pT3Min * pT3Max / sqrt( pow2(pT3Min) +
3737 rndmPtr->flat() * (pow2(pT3Max) - pow2(pT3Min)) );
3738 pT5Max = min(pT5Max, pT3);
3739 if (pT5Max < pT5Min)
return false;
3740 pT5 = pT5Min * pow( pT5Max / pT5Min, rndmPtr->flat() );
3743 phi3 = 2. * M_PI * rndmPtr->flat();
3744 phi5 = 2. * M_PI * rndmPtr->flat();
3745 pT4 = sqrt( pow2(pT3) + pow2(pT5) + 2. * pT3 * pT5 * cos(phi3 - phi5) );
3746 if (pT4 > pT3 || pT4 < pT5)
return false;
3747 phi4 = atan2( -(pT3 * sin(phi3) + pT5 * sin(phi5)),
3748 -(pT3 * cos(phi3) + pT5 * cos(phi5)) );
3751 y3Max = log(eCM / pT3);
3752 y4Max = log(eCM / pT4);
3753 y5Max = log(eCM / pT5);
3754 y3 = y3Max * (2. * rndmPtr->flat() - 1.);
3755 y4 = y4Max * (2. * rndmPtr->flat() - 1.);
3756 y5 = y5Max * (2. * rndmPtr->flat() - 1.);
3760 double WTy = (hasBaryonBeams) ? (1. - pow2(y3/y3Max))
3761 * (1. - pow2(y4/y4Max)) * (1. - pow2(y5/y5Max)) : 1.;
3762 if (WTy < rndmPtr->flat())
return false;
3765 dphi = abs(phi3 - phi4);
3766 if (dphi > M_PI) dphi = 2. * M_PI - dphi;
3767 if (pow2(y3 - y4) + pow2(dphi) < R2sepMin)
return false;
3768 dphi = abs(phi3 - phi5);
3769 if (dphi > M_PI) dphi = 2. * M_PI - dphi;
3770 if (pow2(y3 - y5) + pow2(dphi) < R2sepMin)
return false;
3771 dphi = abs(phi4 - phi5);
3772 if (dphi > M_PI) dphi = 2. * M_PI - dphi;
3773 if (pow2(y4 - y5) + pow2(dphi) < R2sepMin)
return false;
3776 pH[3] = pT3 * Vec4( cos(phi3), sin(phi3), sinh(y3), cosh(y3) );
3777 pH[4] = pT4 * Vec4( cos(phi4), sin(phi4), sinh(y4), cosh(y4) );
3778 pH[5] = pT5 * Vec4( cos(phi5), sin(phi5), sinh(y5), cosh(y5) );
3779 pInSum = pH[3] + pH[4] + pH[5];
3782 x1H = (pInSum.e() + pInSum.pz()) / eCM;
3783 x2H = (pInSum.e() - pInSum.pz()) / eCM;
3784 if (x1H >= 1. || x2H >= 1.)
return false;
3785 sH = pInSum.m2Calc();
3786 if ( sH < pow2(mHatGlobalMin) ||
3787 (mHatGlobalMax > mHatGlobalMin && sH > pow2(mHatGlobalMax)) )
3791 betaZ = (x1H - x2H)/(x1H + x2H);
3792 p3cm = pH[3]; p3cm.bst( 0., 0., -betaZ);
3793 p4cm = pH[4]; p4cm.bst( 0., 0., -betaZ);
3794 p5cm = pH[5]; p5cm.bst( 0., 0., -betaZ);
3797 sigmaProcessPtr->set3Kin( x1H, x2H, sH, p3cm, p4cm, p5cm,
3798 0., 0., 0., 1., 1., 1.);
3799 sigmaNw = sigmaProcessPtr->sigmaPDF();
3802 double flux = 1. /(8. * pow2(sH) * pow5(2. * M_PI));
3803 double yRng = 8. * y3Max * y4Max * y5Max;
3804 double pTRng = pow2(M_PI)
3805 * pow4(pT3) * (1./pow2(pT3Min) - 1./pow2(pT3Max))
3806 * pow2(pT5) * 2.* log(pT5Max/pT5Min);
3807 sigmaNw *= flux * yRng * pTRng / WTy;
3810 if (canModifySigma) sigmaNw
3811 *= userHooksPtr->multiplySigmaBy( sigmaProcessPtr,
this, inEvent);
3812 if (canBiasSelection) sigmaNw
3813 *= userHooksPtr->biasSelectionBy( sigmaProcessPtr,
this, inEvent);
3814 if (canBias2Sel) sigmaNw *= pow( pTH / bias2SelRef, bias2SelPow);
3818 if (sigmaNw > sigmaMx) {
3819 infoPtr->errorMsg(
"Warning in PhaseSpace2to3yyycyl::trialKin: "
3820 "maximum for cross section violated");
3823 if (increaseMaximum || !inEvent) {
3824 double violFact = SAFETYMARGIN * sigmaNw / sigmaMx;
3825 sigmaMx = SAFETYMARGIN * sigmaNw;
3827 if (showViolation) {
3828 if (violFact < 9.99) cout << fixed;
3829 else cout << scientific;
3830 cout <<
" PYTHIA Maximum for " << sigmaProcessPtr->name()
3831 <<
" increased by factor " << setprecision(3) << violFact
3832 <<
" to " << scientific << sigmaMx << endl;
3836 }
else if (showViolation && sigmaNw > sigmaPos) {
3837 double violFact = sigmaNw / sigmaMx;
3838 if (violFact < 9.99) cout << fixed;
3839 else cout << scientific;
3840 cout <<
" PYTHIA Maximum for " << sigmaProcessPtr->name()
3841 <<
" exceeded by factor " << setprecision(3) << violFact << endl;
3847 if (sigmaNw < sigmaNeg) {
3848 infoPtr->errorMsg(
"Warning in PhaseSpace2to3yyycyl::trialKin:"
3849 " negative cross section set 0",
"for " + sigmaProcessPtr->name() );
3853 if (showViolation) cout <<
" PYTHIA Negative minimum for "
3854 << sigmaProcessPtr->name() <<
" changed to " << scientific
3855 << setprecision(3) << sigmaNeg << endl;
3857 if (sigmaNw < 0.) sigmaNw = 0.;
3868 bool PhaseSpace2to3yyycyl::finalKin() {
3871 for (
int i = 0; i < 6; ++i) mH[i] = 0.;
3874 pH[1] = 0.5 * (pInSum.e() + pInSum.pz()) * Vec4( 0., 0., 1., 1.);
3875 pH[2] = 0.5 * (pInSum.e() - pInSum.pz()) * Vec4( 0., 0., -1., 1.);
3880 pTH = (pH[3].pT() + pH[4].pT() + pH[5].pT()) / 3.;
3900 const double PhaseSpaceLHA::CONVERTPB2MB = 1e-9;
3906 bool PhaseSpaceLHA::setupSampling() {
3909 strategy = lhaUpPtr->strategy();
3910 stratAbs = abs(strategy);
3911 if (strategy == 0 || stratAbs > 4) {
3912 ostringstream stratCode;
3913 stratCode << strategy;
3914 infoPtr->errorMsg(
"Error in PhaseSpaceLHA::setupSampling: unknown "
3915 "Les Houches Accord weighting stategy", stratCode.str());
3920 nProc = lhaUpPtr->sizeProc();
3926 double xMax, xSec, xMaxAbs;
3927 for (
int iProc = 0 ; iProc < nProc; ++iProc) {
3928 idPr = lhaUpPtr->idProcess(iProc);
3929 xMax = lhaUpPtr->xMax(iProc);
3930 xSec = lhaUpPtr->xSec(iProc);
3933 if ( (strategy == 1 || strategy == 2) && xMax < 0.) {
3934 infoPtr->errorMsg(
"Error in PhaseSpaceLHA::setupSampling: "
3935 "negative maximum not allowed");
3938 if ( ( strategy == 2 || strategy == 3) && xSec < 0.) {
3939 infoPtr->errorMsg(
"Error in PhaseSpaceLHA::setupSampling: "
3940 "negative cross section not allowed");
3945 if (stratAbs == 1) xMaxAbs = abs(xMax);
3946 else if (stratAbs < 4) xMaxAbs = abs(xSec);
3948 idProc.push_back( idPr );
3949 xMaxAbsProc.push_back( xMaxAbs );
3952 xMaxAbsSum += xMaxAbs;
3955 sigmaMx = xMaxAbsSum * CONVERTPB2MB;
3956 sigmaSgn = xSecSgnSum * CONVERTPB2MB;
3967 bool PhaseSpaceLHA::trialKin(
bool,
bool repeatSame ) {
3971 if (repeatSame) idProcNow = idProcSave;
3972 else if (stratAbs <= 2) {
3973 double xMaxAbsRndm = xMaxAbsSum * rndmPtr->flat();
3975 do xMaxAbsRndm -= xMaxAbsProc[++iProc];
3976 while (xMaxAbsRndm > 0. && iProc < nProc - 1);
3977 idProcNow = idProc[iProc];
3981 bool physical = lhaUpPtr->setEvent(idProcNow);
3982 if (!physical)
return false;
3985 int idPr = lhaUpPtr->idProcess();
3987 for (
int iP = 0; iP < int(idProc.size()); ++iP)
3988 if (idProc[iP] == idPr) iProc = iP;
3992 double wtPr = lhaUpPtr->weight();
3993 if (stratAbs == 1) sigmaNw = wtPr * CONVERTPB2MB
3994 * xMaxAbsSum / xMaxAbsProc[iProc];
3995 else if (stratAbs == 2) sigmaNw = (wtPr / abs(lhaUpPtr->xMax(iProc)))
3997 else if (strategy == 3) sigmaNw = sigmaMx;
3998 else if (strategy == -3 && wtPr > 0.) sigmaNw = sigmaMx;
3999 else if (strategy == -3) sigmaNw = -sigmaMx;
4000 else if (stratAbs == 4) sigmaNw = wtPr * CONVERTPB2MB;
4003 x1H = lhaUpPtr->x1();
4004 x2H = lhaUpPtr->x2();