11 #include "Pythia8/HardDiffraction.h"
20 const double HardDiffraction::TINYPDF = 1e-10;
23 const double HardDiffraction::POMERONMASS = 1.;
24 const double HardDiffraction::RHOMASS = 0.77549;
25 const double HardDiffraction::PROTONMASS = 0.93827;
28 const double HardDiffraction::DIFFMASSMARGIN = 0.2;
31 void HardDiffraction::init(Info* infoPtrIn, Settings& settingsPtrIn,
32 Rndm* rndmPtrIn, BeamParticle* beamAPtrIn, BeamParticle* beamBPtrIn,
33 BeamParticle* beamPomAPtrIn, BeamParticle* beamPomBPtrIn,
34 SigmaTotal* sigTotPtrIn) {
38 settings = settingsPtrIn;
40 beamAPtr = beamAPtrIn;
41 beamBPtr = beamBPtrIn;
42 beamPomAPtr = beamPomAPtrIn;
43 beamPomBPtr = beamPomBPtrIn;
44 sigTotPtr = sigTotPtrIn;
47 pomFlux = settings.mode(
"SigmaDiffractive:PomFlux");
50 idA = (beamAPtr != 0) ? beamAPtr->id() : 0;
51 idB = (beamBPtr != 0) ? beamBPtr->id() : 0;
52 mA = (beamAPtr != 0) ? beamAPtr->m() : 0.;
53 mB = (beamBPtr != 0) ? beamBPtr->m() : 0.;
54 isGammaA = (beamAPtr != 0) ? beamAPtr->isGamma() :
false;
55 isGammaB = (beamBPtr != 0) ? beamBPtr->isGamma() :
false;
56 isGammaGamma = (isGammaA && isGammaB);
59 rescale = settings.parm(
"Diffraction:PomFluxRescale");
60 a0 = 1. + settings.parm(
"SigmaDiffractive:PomFluxEpsilon");
61 ap = settings.parm(
"SigmaDiffractive:PomFluxAlphaPrime");
64 double sigmaRefPomP = settings.parm(
"Diffraction:sigmaRefPomP");
65 normPom = pow2(sigmaRefPomP) * 0.02;
67 }
else if (pomFlux == 2) {
73 }
else if (pomFlux == 3) {
75 normPom = pow2(beta)/(16.*M_PI);
77 }
else if (pomFlux == 4) {
79 normPom = 9. * pow2(beta) / (4. * pow2(M_PI));
86 }
else if (pomFlux == 5) {
91 a0 = 1. + settings.parm(
"SigmaDiffractive:MBRepsilon");
92 ap = settings.parm(
"SigmaDiffractive:MBRalpha");
93 bool renormalize = settings.flag(
"Diffraction:useMBRrenormalization");
95 double m2min = settings.parm(
"SigmaDiffractive:MBRm2Min");
96 double dyminSDflux = settings.parm(
"SigmaDiffractive:MBRdyminSDflux");
97 double dymaxSD = log(infoPtr->eCM()*infoPtr->eCM() / m2min);
100 double step = (dymaxSD - dyminSDflux) / 1000.;
103 for (
int i = 0; i < 1000; ++i) {
104 double dy = dyminSDflux + (i + 0.5) * step;
105 double f = exp(2.*(a0 - 1.)*dy) * ( (A1/(a1 + 2.*ap*dy))
106 + (A2/(a2 + 2. * ap*dy)) );
107 nGap += step * cflux * f;
110 if (nGap < 1.) nGap = 1.;
111 normPom = cflux/nGap;
112 }
else if (pomFlux == 6 || pomFlux == 7) {
116 if (pomFlux == 6) a0 = 1.1182;
118 double xNorm = 0.003;
119 double b = b0 + 2. * ap * log(1./xNorm);
120 double mMin = (isGammaA || isGammaB) ? RHOMASS : PROTONMASS;
121 double tmin = -pow(mMin * xNorm, 2.)/(1. - xNorm);
123 double fNorm = exp(log(1./xNorm) * ( 2.*a0 - 2.));
124 fNorm *= (exp(b*tmin) - exp(b*tcut))/b;
129 xPomA = tPomA = thetaPomA = 0.;
130 xPomB = tPomB = thetaPomB = 0.;
134 if (isGammaA || isGammaB) {
135 sigTotPtr->calc(22, 2212, infoPtr->eCM());
136 double sigGamP = sigTotPtr->sigmaTot();
137 sigTotPtr->calc(2212, 2212, infoPtr->eCM());
138 double sigPP = sigTotPtr->sigmaTot();
139 sigTotRatio = sigGamP / sigPP;
147 bool HardDiffraction::isDiffractive(
int iBeamIn,
int partonIn,
148 double xIn,
double Q2In,
double xfIncIn) {
155 int parton = partonIn;
158 double xfInc = xfIncIn;
159 tmpPomPtr = (iBeam == 1) ? beamPomAPtr : beamPomBPtr;
160 usePomInPhoton = ((iBeam == 1 && isGammaA) || (iBeam == 2 && isGammaB))
164 if (xfInc < TINYPDF) {
165 infoPtr->errorMsg(
"Warning in HardDiffraction::isDiffractive: "
166 "inclusive PDF is zero");
171 double xNow = pow(x, rndmPtr->flat());
176 double xfEst = log(1./x) * xfPom(xNow) * tmpPomPtr->xf(parton, x/xNow, Q2);
181 msg <<
", id = " << parton;
182 infoPtr->errorMsg(
"Warning in HardDiffraction::isDiffractive: "
183 "weight above unity", msg.str());
186 if (xfEst < rndmPtr->flat() * xfInc)
return false;
191 double mMin = (usePomInPhoton) ? RHOMASS : PROTONMASS;
192 double m2Diff = xNow * pow2( infoPtr->eCM());
193 double mDiff = sqrt(m2Diff);
194 double mDiffA = (iBeam == 1) ? 0. : mMin;
195 double mDiffB = (iBeam == 2) ? 0. : mMin;
196 double m2DiffA = mDiffA * mDiffA;
197 double m2DiffB = mDiffB * mDiffB;
198 double eDiff = (iBeam == 1)
199 ? 0.5 * (m2Diff + m2DiffA - m2DiffB) / mDiff
200 : 0.5 * (m2Diff + m2DiffB - m2DiffA) / mDiff;
201 if ( 1. - x / xNow < POMERONMASS / eDiff) {
202 infoPtr->errorMsg(
"Warning in HardDiffraction::isDiffractive: "
203 "No momentum left for beam remnant.");
208 double m3 = ((iBeam == 1 && isGammaA) || (iBeam == 2 && isGammaB))
209 ? RHOMASS : PROTONMASS;
211 if (m3 + m4 + DIFFMASSMARGIN >= infoPtr->eCM()) {
212 infoPtr->errorMsg(
"Warning in HardDiffraction::isDiffractive: "
213 "Too high diffractive mass.");
218 double tNow = pickTNow(xNow);
219 double thetaNow = getThetaNow(xNow, tNow);
225 thetaPomA = thetaNow;
229 thetaPomB = thetaNow;
241 double HardDiffraction::xfPom(
double xIn) {
244 pair<double, double> tLim = tRange(xIn);
245 double tMin = tLim.first;
246 double tMax = tLim.second;
254 double b = b0 + ap * log(1./x);
255 xFlux = normPom/(2.*b) * ( exp(2.*b*tMax) - exp(2.*b*tMin));
261 else if (pomFlux == 2) {
262 xFlux = normPom * (A1/a1 * (exp(a1*tMax) - exp(a1*tMin))
263 + A2/a2 * (exp(a2*tMax) - exp(a2*tMin)));
269 else if (pomFlux == 3) {
270 double b = (a1 + 2. * ap * log(1./x));
271 xFlux = normPom * exp(log(1./x) * (2.*a0 - 2.));
272 xFlux *= (exp(b*tMax) - exp(b*tMin))/b;
280 else if (pomFlux == 4) {
281 double Q = 2. * ap * log(1./x);
282 xFlux = normPom * exp(log(1./x) * (2.*a0 - 2.));
283 xFlux *= (A1/(Q + a1) * (exp((Q + a1)*tMax) - exp((Q + a1)*tMin))
284 + A2/(Q + a2) * (exp((Q + a2)*tMax) - exp((Q + a2)*tMin))
285 + A3/(Q + a3) * (exp((Q + a3)*tMax) - exp((Q + a3)*tMin)));
293 else if (pomFlux == 5) {
294 double Q = 2. * ap * log(1./x);
295 xFlux = normPom * exp(log(1./x) * ( 2.*a0 - 2.));
296 xFlux *= (A1/(Q + a1) * (exp((Q + a1)*tMax) - exp((Q + a1)*tMin))
297 + A2/(Q + a2) * (exp((Q + a2)*tMax) - exp((Q + a2)*tMin)));
303 else if (pomFlux == 6 || pomFlux == 7) {
304 double b = b0 + 2. * ap * log(1./x);
305 xFlux = normPom * exp(log(1./x) * ( 2.*a0 - 2.));
306 xFlux *= (exp(b*tMax) - exp(b*tMin))/b;
310 if (usePomInPhoton)
return xFlux * rescale * sigTotRatio;
311 else return xFlux * rescale;
319 double HardDiffraction::pickTNow(
double xIn) {
322 pair<double, double> tLim = HardDiffraction::tRange(xIn);
323 double tMin = tLim.first;
324 double tMax = tLim.second;
326 double rndm = rndmPtr->flat();
330 double b = b0 + ap * log(1./xIn);
331 tTmp = log( rndm*exp(2.*b*tMin) + (1. - rndm)*exp(2.*b*tMax))/(2.*b);
335 else if (pomFlux == 2) {
336 double prob1 = A1/a1 * (exp(a1*tMax) - exp(a1*tMin));
337 double prob2 = A2/a2 * (exp(a2*tMax) - exp(a2*tMin));
338 prob1 /= (prob1 + prob2);
339 tTmp = (prob1 > rndmPtr->flat())
340 ? log( rndm * exp(a1*tMin) + (1. - rndm) * exp(a1*tMax))/a1
341 : log( rndm * exp(a2*tMin) + (1. - rndm) * exp(a2*tMax))/a2;
345 else if (pomFlux == 3) {
346 double b = (2. * ap * log(1./xIn) + a1);
347 tTmp = log( rndm * exp(b*tMin) + (1. - rndm) * exp(b*tMax))/b;
351 else if (pomFlux == 4) {
352 double b1 = 2. * ap * log(1./xIn) + a1;
353 double b2 = 2. * ap * log(1./xIn) + a2;
354 double b3 = 2. * ap * log(1./xIn) + a3;
355 double prob1 = A1/b1 * ( exp(b1*tMax) - exp(b1*tMin));
356 double prob2 = A2/b2 * ( exp(b2*tMax) - exp(b2*tMin));
357 double prob3 = A3/b3 * ( exp(b3*tMax) - exp(b3*tMin));
358 double rndmProb = (prob1 + prob2 + prob3) * rndmPtr->flat() ;
359 if (rndmProb < prob1)
360 tTmp = log( rndm * exp(b1*tMin) + (1. - rndm) * exp(b1*tMax))/b1;
361 else if ( rndmProb < prob1 + prob2)
362 tTmp = log( rndm * exp(b2*tMin) + (1. - rndm) * exp(b2*tMax))/b2;
364 tTmp = log( rndm * exp(b3*tMin) + (1. - rndm) * exp(b3*tMax))/b3;
368 else if (pomFlux == 5) {
369 double b1 = a1 + 2. * ap * log(1./xIn);
370 double b2 = a2 + 2. * ap * log(1./xIn);
371 double prob1 = A1/b1 * (exp(b1*tMax) - exp(b1*tMin));
372 double prob2 = A2/b2 * (exp(b2*tMax) - exp(b2*tMin));
373 prob1 /= (prob1 + prob2);
374 tTmp = (prob1 > rndmPtr->flat())
375 ? log( rndm * exp(b1*tMin) + (1. - rndm) * exp(b1*tMax))/b1
376 : log( rndm * exp(b2*tMin) + (1. - rndm) * exp(b2*tMax))/b2;
380 else if (pomFlux == 6 || pomFlux == 7){
381 double b = b0 + 2. * ap * log(1./xIn);
382 tTmp = log( rndm * exp(b*tMin) + (1. - rndm) * exp(b*tMax))/b;
394 double HardDiffraction::xfPomWithT(
double xIn,
double tIn) {
403 double b = b0 + ap * log(1./x);
404 xFlux = normPom * exp( 2.*b*t);
408 else if (pomFlux == 2)
409 xFlux = normPom * (A1 * exp(a1*t) + A2 * exp(a2*t));
412 else if (pomFlux == 3) {
413 xFlux = normPom * exp(log(1./x) * (2.*a0 - 2.))
414 * exp(t * (a1 + 2.*ap*log(1./x)));
418 else if (pomFlux == 4){
419 double sqrF1 = A1 * exp(a1*t) + A2 * exp(a2*t) + A3 * exp(a3*t);
420 xFlux = normPom * pow(x, 2. + 2. * (a0 + ap*t)) * sqrF1;
424 else if (pomFlux == 5) {
425 double sqrF1 = A1 * exp(a1*t) + A2 * exp(a2*t);
426 xFlux = normPom * sqrF1 * exp(log(1./x) * (-2. + a0 + ap*t));
430 else if (pomFlux == 6 || pomFlux == 7)
431 xFlux = normPom * exp(b0*t)/pow(x, 2. * (a0 + ap*t) - 2.);
434 if (usePomInPhoton)
return xFlux * rescale * sigTotRatio;
435 else return xFlux * rescale;
443 pair<double, double> HardDiffraction::tRange(
double xIn) {
449 double eCM = infoPtr->eCM();
454 s3 = (iBeam == 1) ? s1 : M2;
455 s4 = (iBeam == 2) ? s2 : M2;
458 double lambda12 = sqrtpos(pow2(s - s1 - s2) - 4. * s1 * s2);
459 double lambda34 = sqrtpos(pow2(s - s3 - s4) - 4. * s3 * s4);
460 double tmp1 = s - (s1 + s2 + s3 + s4) + (s1 - s2) * (s3 - s4) / s;
461 double tmp2 = lambda12 * lambda34 / s;
462 double tmp3 = (s1 + s4 - s2 - s3) * (s1 * s4 - s2 * s3) / s
463 + (s3 - s1) * (s4 - s2);
464 double tMin = -0.5 * (tmp1 + tmp2);
465 double tMax = tmp3 / tMin;
468 return make_pair(tMin, tMax);
476 double HardDiffraction::getThetaNow(
double xIn,
double tIn) {
482 double eCM = infoPtr->eCM();
487 s3 = (iBeam == 1) ? s1 : M2;
488 s4 = (iBeam == 2) ? s2 : M2;
491 double lambda12 = sqrtpos(pow2(s - s1 - s2) - 4. * s1 * s2);
492 double lambda34 = sqrtpos(pow2(s - s3 - s4) - 4. * s3 * s4);
493 double tmp1 = s - (s1 + s2 + s3 + s4) + (s1 - s2) * (s3 - s4)/s;
494 double tmp2 = lambda12 * lambda34 / s;
495 double tmp3 = (s1 + s4 - s2 - s3) * (s1 * s4 - s2 * s3) / s
496 + (s3 - s1) * (s4 - s2);
497 double cosTheta = min(1., max(-1., (tmp1 + 2. * tIn) / tmp2));
498 double sinTheta = 2. * sqrtpos( -(tmp3 + tmp1 * tIn + tIn * tIn) ) / tmp2;
499 double theta = asin( min(1., sinTheta));
501 if (cosTheta < 0.) theta = M_PI - theta;