9 #include "Pythia8/GammaKinematics.h"
22 bool GammaKinematics::init() {
25 bool rejectTheta = mode(
"Beams:frameType") == 1;
28 Q2maxGamma = parm(
"Photon:Q2max");
29 Wmin = parm(
"Photon:Wmin");
30 Wmax = parm(
"Photon:Wmax");
31 theta1Max = rejectTheta ? parm(
"Photon:thetaAMax") : -1.0;
32 theta2Max = rejectTheta ? parm(
"Photon:thetaBMax") : -1.0;
36 gammaMode = mode(
"Photon:ProcessType");
37 hasApproxFluxA = beamAPtr->hasApproxGammaFlux();
38 hasApproxFluxB = beamBPtr->hasApproxGammaFlux();
41 sampleQ2 = flag(
"Photon:sampleQ2");
44 hasGammaA = flag(
"PDF:beamA2gamma");
45 hasGammaB = flag(
"PDF:beamB2gamma");
50 m2BeamA = pow2( beamAPtr->m() );
51 m2BeamB = pow2( beamBPtr->m() );
55 subInA = (beamAPtr->isGamma() || hasGammaA) ? 22 : beamAPtr->id();
56 subInB = (beamBPtr->isGamma() || hasGammaB) ? 22 : beamBPtr->id();
59 eCM2A = 0.25 * pow2( sCM + m2BeamA - m2BeamB ) / sCM;
60 eCM2B = 0.25 * pow2( sCM - m2BeamA + m2BeamB ) / sCM;
63 m2eA = m2BeamA / eCM2A;
64 m2eB = m2BeamB / eCM2B;
67 xGammaMax1 = 2. * ( 1. - 0.25 * Q2maxGamma / eCM2A - m2eA)
68 / ( 1. + sqrt((1. + 4. * m2BeamA / Q2maxGamma) * (1. - m2eA)) );
69 xGammaMax2 = 2. * ( 1. - 0.25 * Q2maxGamma / eCM2B - m2eB)
70 / ( 1. + sqrt((1. + 4. * m2BeamB / Q2maxGamma) * (1. - m2eB)) );
79 if ( Wmax < Wmin ) Wmax = eCM;
89 bool GammaKinematics::sampleKTgamma(
bool nonDiff) {
92 xGamma1 = beamAPtr->xGamma();
93 xGamma2 = beamBPtr->xGamma();
96 gammaMode = infoPtr->photonMode();
99 if ( hasGammaA && (!hasApproxFluxA || ( hasApproxFluxA
100 && (gammaMode == 3 || gammaMode == 4) ) ) && (xGamma1 > xGammaMax1) )
102 if ( hasGammaB && (!hasApproxFluxB || ( hasApproxFluxB
103 && (gammaMode == 2 || gammaMode == 4) ) ) && (xGamma2 > xGammaMax2) )
110 if ( hasApproxFluxA && (gammaMode == 1 || gammaMode == 2) ) {
111 double xMinA = nonDiff ? -1. : beamAPtr->xGammaHadr();
112 xGamma1 = beamAPtr->sampleXgamma(xMinA);
113 if ( xGamma1 > xGammaMax1 )
return false;
117 Q2min1 = 2. * m2BeamA * pow2(xGamma1) / ( 1. - xGamma1 - m2eA
118 + sqrt(1. - m2eA) * sqrt( pow2(1. - xGamma1) - m2eA ) );
121 if (sampleQ2) Q2gamma1 = beamAPtr->sampleQ2gamma(Q2min1);
125 if ( sampleQ2 && (Q2gamma1 < Q2min1) )
return false;
132 if ( hasApproxFluxB && (gammaMode == 1 || gammaMode == 3) ) {
133 double xMinB = nonDiff ? -1. : beamBPtr->xGammaHadr();
134 xGamma2 = beamBPtr->sampleXgamma(xMinB);
135 if ( xGamma2 > xGammaMax2 )
return false;
139 Q2min2 = 2. * m2BeamB * pow2(xGamma2) / ( 1. - xGamma2 - m2eB
140 + sqrt(1. - m2eB) * sqrt( pow2(1. - xGamma2) - m2eB ) );
143 if (sampleQ2) Q2gamma2 = beamBPtr->sampleQ2gamma(Q2min2);
147 if ( sampleQ2 && (Q2gamma2 < Q2min2) )
return false;
152 if ( !deriveKin(xGamma1, Q2gamma1, m2BeamA, eCM2A) )
return false;
159 if ( theta1Max > 0 && ( theta1 > theta1Max ) )
return false;
162 if ( !deriveKin(xGamma2, Q2gamma2, m2BeamB, eCM2B) )
return false;
169 if ( theta2Max > 0 && ( theta2 > theta2Max ) )
return false;
173 if ( hasGammaA && hasGammaB) {
176 double cosPhi12 = cos(phi1 - phi2);
177 m2GmGm = 2. * sqrt(eCM2A * eCM2B) * xGamma1 * xGamma2 - Q2gamma1 - Q2gamma2
178 + 2. * kz1 * kz2 - 2. * kT1 * kT2 * cosPhi12;
181 if ( ( m2GmGm < pow2(Wmin) ) || ( m2GmGm > pow2(Wmax) ) )
return false;
184 mGmGm = sqrt(m2GmGm);
189 }
else if (hasGammaA || hasGammaB) {
193 double pz2 = ( pow2(sCM - m2BeamA - m2BeamB) - 4. * m2BeamA * m2BeamB )
195 double pz = sqrtpos( pz2);
198 double m2Beam = hasGammaA ? m2BeamB : m2BeamA;
199 double xGamma = hasGammaA ? xGamma1 : xGamma2;
200 double Q2gamma = hasGammaA ? Q2gamma1 : Q2gamma2;
203 m2GmGm = m2Beam - Q2gamma + 2. * ( xGamma * sqrt(eCM2A) * sqrt(eCM2B)
205 if ( ( m2GmGm < pow2(Wmin) ) || ( m2GmGm > pow2(Wmax) ) )
return false;
206 mGmGm = sqrt(m2GmGm);
220 bool GammaKinematics::deriveKin(
double xGamma,
double Q2gamma,
221 double m2Beam,
double eCM2) {
224 phi = 2. * M_PI * rndmPtr->flat();
227 double kT2gamma = ( ( 1. - xGamma - 0.25 * Q2gamma / eCM2 ) * Q2gamma
228 - m2Beam * ( Q2gamma / eCM2 + pow2(xGamma) ) ) / (1.- m2Beam / eCM2);
231 if ( !sampleQ2 ) kT2gamma = 0.;
235 if ( kT2gamma < 0. ) {
236 infoPtr->errorMsg(
"Error in gammaKinematics::sampleKTgamma: "
237 "unphysical kT value.");
243 kT = sqrt( kT2gamma );
244 theta = atan( sqrt( eCM2 * ( Q2gamma * ( 1. - xGamma )
245 - m2Beam * pow2(xGamma) ) - m2Beam * Q2gamma - pow2( 0.5 * Q2gamma) )
246 / ( eCM2 * ( 1. - xGamma) - m2Beam - 0.5 * Q2gamma ) );
247 kz = (xGamma * eCM2 + 0.5 * Q2gamma) / ( sqrt(eCM2 - m2Beam) );
257 double GammaKinematics::calcNewSHat(
double sHatOld){
260 if ( hasGammaA && hasGammaB) {
263 gammaMode = infoPtr->photonMode();
264 if (gammaMode == 4) {
267 }
else if (gammaMode == 2 || gammaMode == 3) {
268 sHatNew = sHatOld * m2GmGm / ( xGamma1 * xGamma2 * sCM);
288 double GammaKinematics::fluxWeight() {
295 if (hasGammaA && hasApproxFluxA)
296 wtFlux *= beamAPtr->xfFlux(22, xGamma1, Q2gamma1)
297 / beamAPtr->xfApprox(22, xGamma1, Q2gamma1);
298 if (hasGammaB && hasApproxFluxB)
299 wtFlux *= beamBPtr->xfFlux(22, xGamma2, Q2gamma2)
300 / beamBPtr->xfApprox(22, xGamma2, Q2gamma2);
304 if (hasGammaA && hasApproxFluxA)
305 wtFlux *= beamAPtr->xfFlux(22, xGamma1, Q2gamma1)
306 / beamAPtr->xf(22, xGamma1, Q2gamma1);
307 if (hasGammaB && hasApproxFluxB)
308 wtFlux *= beamBPtr->xfFlux(22, xGamma2, Q2gamma2)
309 / beamBPtr->xf(22, xGamma2, Q2gamma2);
320 bool GammaKinematics::finalize(){
323 beamAPtr->newGammaKTPhi(kT1, phi1);
324 beamBPtr->newGammaKTPhi(kT2, phi2);
325 beamAPtr->Q2Gamma(Q2gamma1);
326 beamBPtr->Q2Gamma(Q2gamma2);
329 infoPtr->setQ2Gamma1(Q2gamma1);
330 infoPtr->setQ2Gamma2(Q2gamma2);
331 infoPtr->setX1Gamma(xGamma1);
332 infoPtr->setX2Gamma(xGamma2);
335 if ( (infoPtr->nFinal() > 1) || (gammaMode != 4)) {
336 infoPtr->setTheta1(theta1);
337 infoPtr->setTheta2(theta2);
338 infoPtr->setECMsub(mGmGm);
339 infoPtr->setsHatNew(sHatNew);
350 double GammaKinematics::setupSoftPhaseSpaceSampling(
double sigmaMax) {
353 sigmaEstimate = sigmaMax;
354 alphaEM = coupSMPtr->alphaEM(Q2maxGamma);
355 gammaA = beamAPtr->isGamma() || hasGammaA;
356 gammaB = beamBPtr->isGamma() || hasGammaB;
359 double m2sA = 4. * m2BeamA / sCM;
360 double m2sB = 4. * m2BeamB / sCM;
363 double m2GmGmMin = pow2(Wmin);
364 double xGamAMax = 1.;
365 double xGamBMax = 1.;
366 double xGamAMin = m2GmGmMin / sCM ;
367 double xGamBMin = m2GmGmMin / sCM ;
379 xGamAMax = 2. * ( 1. - 0.25 * Q2maxGamma / eCM2A - m2sA )
380 / ( 1. + sqrt( (1. + 4. * m2BeamA / Q2maxGamma) * (1. - m2sA) ) );
381 if ( !hasApproxFluxA) {
382 log2xMinA = pow2( log( Q2maxGamma/ ( m2BeamA * pow2(xGamAMin) ) ) );
383 log2xMaxA = pow2( log( Q2maxGamma/ ( m2BeamA * pow2(xGamAMax) ) ) );
389 xGamBMax = 2. * ( 1. - 0.25 * Q2maxGamma / eCM2B - m2sB )
390 / ( 1. + sqrt( (1. + 4. * m2BeamB / Q2maxGamma) * (1. - m2sB) ) );
391 if ( !hasApproxFluxB) {
392 log2xMinB = pow2( log( Q2maxGamma/ ( m2BeamB * pow2(xGamBMin) ) ) );
393 log2xMaxB = pow2( log( Q2maxGamma/ ( m2BeamB * pow2(xGamBMax) ) ) );
399 if (hasApproxFluxA) sigmaEstimate *= beamAPtr->gammaFluxIntApprox();
400 else sigmaEstimate *= 0.5 * alphaEM / M_PI
401 * 0.5 * (log2xMinA - log2xMaxA);
404 if (hasApproxFluxB) sigmaEstimate *= beamBPtr->gammaFluxIntApprox();
405 else sigmaEstimate *= 0.5 * alphaEM / M_PI
406 * 0.5 * (log2xMinB - log2xMaxB);
410 return sigmaEstimate;
417 bool GammaKinematics::trialKinSoftPhaseSpaceSampling(){
423 if ( !hasApproxFluxA) {
424 if (gammaA) xGamma1 = sqrt( (Q2maxGamma / m2BeamA) * exp( -sqrt(
425 log2xMinA + rndmPtr->flat() * (log2xMaxA - log2xMinA) ) ) );
428 beamAPtr->xGamma(xGamma1);
432 if ( !hasApproxFluxB) {
433 if (gammaB) xGamma2 = sqrt( (Q2maxGamma / m2BeamB) * exp( -sqrt(
434 log2xMinB + rndmPtr->flat() * (log2xMaxB - log2xMinB) ) ) );
437 beamBPtr->xGamma(xGamma2);
441 if ( !(sampleKTgamma(
true)) )
return false;
444 if (hasApproxFluxA) xGamma1 = beamAPtr->xGamma();
445 if (hasApproxFluxB) xGamma2 = beamBPtr->xGamma();
453 if ( !hasApproxFluxA ) {
454 wt1 = ( 0.5 * ( 1. + pow2(1 - xGamma1) ) ) * log( Q2maxGamma/Q2min1 )
455 / log( Q2maxGamma / ( m2BeamA * pow2( xGamma1 ) ) );
459 wt1 = sampleQ2 ? beamAPtr->xfFlux(22, xGamma1, Q2gamma1)
460 / beamAPtr->xfApprox(22, xGamma1, Q2gamma1)
461 : beamAPtr->xfFlux(22, xGamma1, Q2gamma1)
462 / beamAPtr->xf(22, xGamma1, Q2gamma1);
468 if ( !hasApproxFluxB ) {
469 wt2 = ( 0.5 * ( 1. + pow2(1 - xGamma2) ) ) * log( Q2maxGamma/Q2min2 )
470 / log( Q2maxGamma / ( m2BeamB * pow2( xGamma2 ) ) );
474 wt2 = sampleQ2 ? beamBPtr->xfFlux(22, xGamma2, Q2gamma2)
475 / beamBPtr->xfApprox(22, xGamma2, Q2gamma2)
476 : beamBPtr->xfFlux(22, xGamma2, Q2gamma2)
477 / beamBPtr->xf(22, xGamma2, Q2gamma2);
482 double wtAlphaEM1 = (gammaA && !hasApproxFluxA)
483 ? coupSMPtr->alphaEM(Q2gamma1) / alphaEM : 1.;
484 double wtAlphaEM2 = (gammaB && !hasApproxFluxB)
485 ? coupSMPtr->alphaEM(Q2gamma2) / alphaEM : 1.;
486 double wtAlphaEM = wtAlphaEM1 * wtAlphaEM2;
489 wt = wt1 * wt2 * wtAlphaEM;