9 #include "Pythia8/LowEnergyProcess.h"
24 static constexpr
int MAXLOOP = 100;
27 static constexpr
double MASSREDUCERATE = 0.025;
30 static constexpr
double MDIFFMIN = 0.28;
31 static constexpr
double CRES = 2.0;
32 static constexpr
double MRES0 = 1.062;
35 static constexpr
double MPI = 0.14;
38 static constexpr
double MK = 0.498;
41 static constexpr
double MEXTRADIQDIQ = 0.5;
44 static constexpr
double ALPHAPRIME = 0.25;
50 void LowEnergyProcess::init( StringFlav* flavSelPtrIn,
51 StringFragmentation* stringFragPtrIn,
52 MiniStringFragmentation* ministringFragPtrIn,
53 LowEnergySigma* lowEnergySigmaPtrIn,
54 NucleonExcitations* nucleonExcitationsPtrIn) {
57 flavSelPtr = flavSelPtrIn;
58 stringFragPtr = stringFragPtrIn;
59 ministringFragPtr = ministringFragPtrIn;
60 lowEnergySigmaPtr = lowEnergySigmaPtrIn,
61 nucleonExcitationsPtr = nucleonExcitationsPtrIn;
64 probStoUD = parm(
"StringFlav:probStoUD");
67 double theta = parm(
"StringFlav:thetaPS");
68 double alpha = (theta + 54.7) * M_PI / 180.;
69 fracEtass = pow2(sin(alpha));
70 fracEtaPss = 1. - fracEtass;
73 xPowMes = parm(
"BeamRemnants:valencePowerMeson");
74 xPowBar = 0.5 * ( parm(
"BeamRemnants:valencePowerUinP")
75 + parm(
"BeamRemnants:valencePowerDinP") );
76 xDiqEnhance = parm(
"BeamRemnants:valenceDiqEnhance");
79 sigmaQ = parm(
"StringPT:sigma") / sqrt(2.);
82 mStringMin = parm(
"HadronLevel:mStringMin");
85 sProton = pow2(particleDataPtr->m0(2212));
88 probDoubleAnn = parm(
"LowEnergyQCD:probDoubleAnnihilation");
91 leEvent.init(
"(low energy event)", particleDataPtr);
105 bool LowEnergyProcess::collide(
int i1,
int i2,
int typeIn,
Event& event,
106 Vec4 vtx, Vec4 vtx1, Vec4 vtx2) {
110 infoPtr->errorMsg(
"Error in LowEnergyProcess::collide: "
114 if (!event[i1].isHadron() || !event[i2].isHadron())
return false;
115 sizeOld =
event.size();
119 id1 =
event[i1].id();
120 id2 =
event[i2].id();
121 isBaryon1 = ( (abs(id1)/1000)%10 > 0 );
122 isBaryon2 = ( (abs(id2)/1000)%10 > 0 );
125 eCM = (
event[i1].p() +
event[i2].p()).mCalc();
129 if ((id1 == 310 || id1 == 130) && (id2 == 310 || id2 == 130)) {
130 double sigmaSame = lowEnergySigmaPtr->sigmaPartial(311, 311, eCM,
132 double sigmaMix = lowEnergySigmaPtr->sigmaPartial(311, -311, eCM,
134 int choice = rndmPtr->pick({ 0.25 * sigmaSame, 0.25 * sigmaSame,
136 if (choice == 0) id1 = id2 = 311;
137 else if (choice == 1) id1 = id2 = -311;
138 else { id1 = 311; id2 = -311; }
142 if (id1 == 310 || id1 == 130) {
143 double sigmaK = lowEnergySigmaPtr->sigmaPartial( 311, id2, eCM,
145 double sigmaKbar = lowEnergySigmaPtr->sigmaPartial(-311, id2, eCM,
147 id1 = (rndmPtr->pick({ sigmaK, sigmaKbar }) == 0) ? 311 : -311;
149 else if (id2 == 310 || id2 == 130) {
150 double sigmaK = lowEnergySigmaPtr->sigmaPartial(id1, 311, eCM,
152 double sigmaKbar = lowEnergySigmaPtr->sigmaPartial(id1, -311, eCM,
154 id2 = (rndmPtr->pick({ sigmaK, sigmaKbar }) == 0) ? 311 : -311;
159 leEvent.append( event[i1]);
160 leEvent.append( event[i2]);
161 leEvent[1].status( -12);
162 leEvent[2].status( -12);
163 RotBstMatrix MtoCM = toCMframe( leEvent[1].p(), leEvent[2].p());
164 leEvent.rotbst( MtoCM);
168 if (type >= 1 && type <= 8 && type != 6) code = type;
169 else if (abs(type) > 100) code = 9;
171 infoPtr->errorMsg(
"Error in LowEnergyProcess::collide: "
172 "invalid process type", std::to_string(type));
177 if (code == 1) {
if (!nondiff())
return false; }
178 else if (code >= 2 && code <= 5) {
if (!eldiff())
return false; }
179 else if (code == 7) {
if (!excitation())
return false; }
180 else if (code == 8) {
if (!annihilation())
return false; }
181 else if (code == 9) {
if (!resonance())
return false; }
184 int nPrimaryProds = leEvent.size() - 3;
186 nHadron = (code == 3 || code == 5) ? 0 : 1;
189 if (code == 1 || code == 3 || code == 4 || code == 5 || code == 8) {
190 if (!simpleHadronization()) {
191 infoPtr->errorMsg(
"Error in LowEnergyProcess::collide: "
192 "hadronization failed");
198 int mother1 = max(i1, i2), mother2 = min(i1, i2);
201 int indexOffset = sizeOld - 3;
204 for (
int i = 3; i < leEvent.size(); ++i) {
205 int iNew =
event.append(leEvent[i]);
208 if ( leEvent[i].mother1() == 1 || leEvent[i].mother1() == 2
209 || leEvent[i].mother2() == 1 || leEvent[i].mother2() == 2 ) {
210 event[iNew].mothers(mother1, mother2);
214 event[iNew].mother1(indexOffset + leEvent[i].mother1());
215 event[iNew].mother2(indexOffset + leEvent[i].mother2());
219 if (event[iNew].isFinal()) {
220 event[iNew].status(150 + code);
221 if (event[iNew].isHadron())
222 event[iNew].tau( event[iNew].tau0() * rndmPtr->exp() );
224 event[iNew].status(-(150 + code));
225 event[iNew].daughter1(indexOffset + leEvent[i].daughter1());
226 event[iNew].daughter2(indexOffset + leEvent[i].daughter2());
231 event[i1].daughters(sizeOld, sizeOld + nPrimaryProds - 1);
232 event[i2].daughters(sizeOld, sizeOld + nPrimaryProds - 1);
235 RotBstMatrix MfromCM = fromCMframe( event[i1].p(), event[i2].p());
236 if (code == 1 || code == 6 || code > 7) {
237 for (
int i = sizeOld; i <
event.size(); ++i) {
238 event[i].rotbst( MfromCM);
239 event[i].vProdAdd( vtx);
246 int nParton = (code == 3 || code == 5) ? 2 : 0;
248 for (
int i = sizeOld; i <
event.size(); ++i) {
249 event[i].rotbst( MfromCM);
250 if (event[i].status() > 0)
251 event[i].vProdAdd( (++iHadron <= nHadron) ? vtx1 : vtx2 );
252 else event[i].vProdAdd( (++iParton <= nParton) ? vtx1 : vtx2 );
257 event[i1].statusNeg();
258 event[i2].statusNeg();
269 bool LowEnergyProcess::nondiff() {
272 pair< int, int> paircac1 = splitFlav( id1 );
273 idc1 = paircac1.first;
274 idac1 = paircac1.second;
275 pair< int, int> paircac2 = splitFlav( id2 );
276 idc2 = paircac2.first;
277 idac2 = paircac2.second;
278 mThr1 = mThreshold( idc1, idac2);
279 mThr2 = mThreshold( idc2, idac1);
282 if (eCM < mThr1 + mThr2 + MPI)
return twoBody();
285 if (eCM < mThr1 + mThr2 + 2. * MPI)
return threeBody();
289 double e1, pz1, epz1, pzc1, ec1, epz2, pzc2, ec2, mAbove1, mAbove2;
290 Vec4 pc1, pac1, pc2, pac2;
293 if (++loop == MAXLOOP)
return threeBody();
294 double redStep = (loop < 10) ? 1. : exp( -MASSREDUCERATE * (loop - 9));
297 splitA( eCM, redStep);
298 splitB( eCM, redStep);
301 z1 = splitZ( idc1, idac1, mTc1 / eCM, mTac1 / eCM);
302 z2 = splitZ( idc2, idac2, mTc2 / eCM, mTac2 / eCM);
303 mT1 = sqrt( mTsc1 / z1 + mTsac1 / (1. - z1));
304 mT2 = sqrt( mTsc2 / z2 + mTsac2 / (1. - z2));
307 }
while (mT1 + mT2 > eCM);
310 e1 = 0.5 * (sCM + mT1 * mT1 - mT2 * mT2) / eCM;
311 pz1 = sqrtpos(e1 * e1 - mT1 * mT1);
312 epz1 = z1 * (e1 + pz1);
313 pzc1 = 0.5 * (epz1 - mTsc1 / epz1 );
314 ec1 = 0.5 * (epz1 + mTsc1 / epz1 );
315 pc1.p( px1, py1, pzc1, ec1 );
316 pac1.p( -px1, -py1, pz1 - pzc1, e1 - ec1 );
317 epz2 = z2 * (eCM - e1 + pz1);
318 pzc2 = -0.5 * (epz2 - mTsc2 / epz2 );
319 ec2 = 0.5 * (epz2 + mTsc2 / epz2 );
320 pc2.p( px2, py2, pzc2, ec2 );
321 pac2.p( -px2, -py2, -pz1 - pzc2, eCM - e1 - ec2 );
324 mAbove1 = (pc1 + pac2).mCalc() - mThreshold( idc1, idac2);
325 mAbove2 = (pc2 + pac1).mCalc() - mThreshold( idc2, idac1);
326 }
while ( max( mAbove1, mAbove2) < MPI || min( mAbove1, mAbove2) < 0. );
329 if (mAbove1 < mAbove2) {
330 leEvent.append( idc1, 63, 1, 0, 0, 0, 101, 0, pc1, mc1);
331 leEvent.append( idac2, 63, 2, 0, 0, 0, 0, 101, pac2, mac2);
332 leEvent.append( idc2, 63, 2, 0, 0, 0, 102, 0, pc2, mc2);
333 leEvent.append( idac1, 63, 1, 0, 0, 0, 0, 102, pac1, mac1);
335 leEvent.append( idc2, 63, 2, 0, 0, 0, 102, 0, pc2, mc2);
336 leEvent.append( idac1, 63, 1, 0, 0, 0, 0, 102, pac1, mac1);
337 leEvent.append( idc1, 63, 1, 0, 0, 0, 101, 0, pc1, mc1);
338 leEvent.append( idac2, 63, 2, 0, 0, 0, 0, 101, pac2, mac2);
350 bool LowEnergyProcess::eldiff() {
353 bool excite1 = (type == 3 || type == 5);
354 bool excite2 = (type == 4 || type == 5);
357 bool hasExcitation = lowEnergySigmaPtr->hasExcitation( id1, id2);
362 double mAmin = (excite1) ? mDiffThr(id1, m1) : m1;
363 double mBmin = (excite2) ? mDiffThr(id2, m2) : m2;
364 double mAmax = eCM - mBmin;
365 double mBmax = eCM - mAmin;
366 if (mAmin + mBmin > eCM) {
367 infoPtr->errorMsg(
"Error in LowEnergyProcess::eldiff: "
368 "too low invariant mass for diffraction",
369 "for " + to_string(id1) +
" " + to_string(id2)
370 +
" with type=" + to_string(type) +
" @ " + to_string(eCM) +
" GeV");
379 double lam12 = sqrtpos(pow2( sCM - s1 - s2) - 4. * s1 * s2);
380 double sResXB = pow2(mA + MRES0);
381 double sResAX = pow2(mB + MRES0);
384 double sAmin = mAmin * mAmin;
385 double sBmin = mBmin * mBmin;
386 double lamAB = sqrtpos(pow2( sCM - sAmin - sBmin) - 4. * sAmin * sBmin);
387 double tempA = sCM - (s1 + s2 + sAmin + sBmin) + (s1 - s2) * (sAmin - sBmin)
389 double tempB = lam12 * lamAB / sCM;
390 double tLowX = -0.5 * (tempA + tempB);
391 double wtA, wtB, tempC, tLow, tUpp, tNow;
392 double bNow = (type == 2) ? bSlope() : 2.;
399 if (++loopT == MAXLOOP) {
400 infoPtr->errorMsg(
"Error in LowEnergyProcess::eldiff: "
401 "failed to construct valid kinematics (t)");
411 if (++loopM == MAXLOOP) {
412 infoPtr->errorMsg(
"Error in LowEnergyProcess::eldiff: "
413 "failed to construct valid kinematics (m)");
416 double redStep = (loopM < 10) ? 1. : exp( -MASSREDUCERATE * (loopM - 9));
421 mA = mAmin * pow( mAmax / mAmin, rndmPtr->flat() );
423 wtA = (hasExcitation) ? 1.
424 : (1. + CRES * sResXB / (sResXB + sA)) / (1. + CRES);
425 }
while (wtA < rndmPtr->flat());
426 splitA( mA, redStep);
427 if (mTc1 + mTac1 > mA) failM =
true;
432 if (excite2 && !failM) {
434 mB = mBmin * pow( mBmax / mBmin, rndmPtr->flat() );
436 wtB = (hasExcitation) ? 1.
437 : (1. + CRES * sResAX / (sResAX + sB)) / (1. + CRES);
438 }
while (wtB < rndmPtr->flat());
439 splitB( mB, redStep);
440 if (mTc2 + mTac2 > mB) failM =
true;
444 if (mA + mB > eCM) failM =
true;
447 if (type == 3) wtM = 1. - sA / sCM;
448 else if (type == 4) wtM = 1. - sB / sCM;
449 else if (type == 5) wtM = (1. - pow2(mA + mB) / sCM)
450 * sCM * sProton / (sCM * sProton + sA * sB);
451 if (wtM < rndmPtr->flat()) failM =
true;
456 lamAB = sqrtpos(pow2( sCM - sA - sB) - 4. * sA * sB);
457 tempA = sCM - (s1 + s2 + sA + sB) + (s1 - s2) * (sA - sB) / sCM;
458 tempB = lam12 * lamAB / sCM;
459 tempC = (sA - s1) * (sB - s2) + (s1 + sB - s2 - sA)
460 * (s1 * sB - s2 * sA) / sCM;
461 tLow = -0.5 * (tempA + tempB);
465 if (type != 2) bNow = bSlope();
466 tNow = log(1. - rndmPtr->flat() * (1. - exp(bNow * tLowX))) / bNow;
467 if (tNow < tLow || tNow > tUpp) failT =
true;
471 double eA = 0.5 * (sCM + sA - sB) / eCM;
472 double pzA = sqrtpos(eA * eA - sA);
473 Vec4 pA( 0., 0., pzA, eA);
474 Vec4 pB( 0., 0., -pzA, eCM - eA);
478 double ec1 = 0.5 * (sA + mTsc1 - mTsac1) / mA;
479 double pzc1 = sqrtpos(ec1 * ec1 - mTsc1);
481 if ( abs(idac1) > 10 || (abs(idc1) < 10 && abs(idac1) < 10
482 && rndmPtr->flat() > 0.5) ) pzc1 = -pzc1;
483 Vec4 pc1( px1, py1, pzc1, ec1);
484 Vec4 pac1( -px1, -py1, -pzc1, mA - ec1);
487 leEvent.append( idc1, 63, 1, 0, 0, 0, 101, 0, pc1, mc1);
488 leEvent.append( idac1, 63, 1, 0, 0, 0, 0, 101, pac1, mac1);
492 int iNew = leEvent.copy( 1, 63);
493 leEvent[iNew].p( pA);
494 leEvent[iNew].vProd( 0., 0., 0., 0.);
499 double ec2 = 0.5 * (sB + mTsc2 - mTsac2) / mB;
500 double pzc2 = -sqrtpos(ec2 * ec2 - mTsc2);
502 if ( abs(idac2) > 10 || (abs(idc2) < 10 && abs(idac2) < 10
503 && rndmPtr->flat() > 0.5) ) pzc2 = -pzc2;
504 Vec4 pc2( px2, py2, pzc2, ec2);
505 Vec4 pac2( -px2, -py2, -pzc2, mB - ec2);
508 leEvent.append( idc2, 63, 2, 0, 0, 0, 102, 0, pc2, mc2);
509 leEvent.append( idac2, 63, 2, 0, 0, 0, 0, 102, pac2, mac2);
513 int iNew = leEvent.copy( 2, 63);
514 leEvent[iNew].p( pB);
515 leEvent[iNew].vProd( 0., 0., 0., 0.);
519 double cosTheta = min(1., max(-1., (tempA + 2. * tNow) / tempB));
520 double sinTheta = 2. * sqrtpos( -(tempC + tempA * tNow + tNow * tNow) )
522 double theta = asin( min(1., sinTheta));
523 if (cosTheta < 0.) theta = M_PI - theta;
524 if (!std::isfinite(theta)) {
525 infoPtr->errorMsg(
"Error in LowEnergyProcess::eldiff: "
529 double phi = 2. * M_PI * rndmPtr->flat();
530 for (
int i = 3; i < leEvent.size(); ++i) leEvent[i].rot( theta, phi);
541 bool LowEnergyProcess::excitation() {
545 if (!nucleonExcitationsPtr->pickExcitation(id1, id2, eCM, idA, mA, idB, mB))
553 double lam12 = sqrtpos(pow2( sCM - s1 - s2) - 4. * s1 * s2);
554 double lamAB = sqrtpos(pow2( sCM - sA - sB) - 4. * sA * sB);
555 double tempA = sCM - (s1 + s2 + sA + sB) + (s1 - s2) * (sA - sB) / sCM;
556 double tempB = lam12 * lamAB / sCM;
557 double tempC = (sA - s1) * (sB - s2) + (s1 + sB - s2 - sA)
558 * (s1 * sB - s2 * sA) / sCM;
559 double tLow = -0.5 * (tempA + tempB);
560 double tUpp = tempC / tLow;
564 if (idA == id1 && idB == id2) type = 2;
565 else if (idB == id2) type = 3;
566 else if (idA == id1) type = 4;
568 double bNow = bSlope();
570 double tNow = tUpp + log(1. - rndmPtr->flat()
571 * (1. - exp(bNow * (tLow - tUpp)))) / bNow;
574 double eA = 0.5 * (sCM + sA - sB) / eCM;
575 double pzA = sqrtpos(eA * eA - sA);
576 Vec4 pA( 0., 0., pzA, eA);
577 Vec4 pB( 0., 0., -pzA, eCM - eA);
578 int iA = leEvent.append(idA, 157, 1,2, 0,0, 0,0, pA, mA);
579 int iB = leEvent.append(idB, 157, 1,2, 0,0, 0,0, pB, mB);
582 double cosTheta = min(1., max(-1., (tempA + 2. * tNow) / tempB));
583 double sinTheta = 2. * sqrtpos( -(tempC + tempA * tNow + tNow * tNow) )
585 double theta = asin( min(1., sinTheta));
586 if (cosTheta < 0.) theta = M_PI - theta;
587 double phi = 2. * M_PI * rndmPtr->flat();
588 leEvent[iA].rot( theta, phi);
589 leEvent[iB].rot( theta, phi);
599 bool LowEnergyProcess::annihilation() {
602 if (!isBaryon1 || !isBaryon2
603 || (id1 > 0 ? 1 : -1) * (id2 > 0 ? 1 : -1) > 0) {
604 infoPtr->errorMsg(
"Error in LowEnergyProcess::annihilation: "
605 "not a baryon-antibaryon incoming pair",
606 std::to_string(id1) +
" + " + std::to_string(id2));
615 for (
int iHad = 0; iHad < 2; ++iHad) {
616 int idAbs = (iHad == 0) ? abs(id1) : abs(id2);
617 iqAll[iHad][0] = (idAbs/1000)%10;
618 iqAll[iHad][1] = (idAbs/100)%10;
619 iqAll[iHad][2] = (idAbs/10)%10;
623 for (
int i1 = 0; i1 < 3; ++i1)
624 for (
int i2 = 0; i2 < 3; ++i2)
625 if (iqAll[1][i2] == iqAll[0][i1]) iqPair.push_back(10 * i1 + i2);
628 if (iqPair.size() == 0) {
629 infoPtr->errorMsg(
"Error in LowEnergyProcess::annihilation: "
630 "flavour content does not allow annihilation");
635 int iAnn = max( 0, min(
int(iqPair.size()) - 1,
636 int(iqPair.size() * rndmPtr->flat()) ));
637 iqAll[0][iqPair[iAnn]/10] = iqAll[0][2];
638 iqAll[1][iqPair[iAnn]%10] = iqAll[1][2];
642 for (
int i1 = 0; i1 < 2; ++i1)
643 for (
int i2 = 0; i2 < 2; ++i2)
644 if (iqAll[1][i2] == iqAll[0][i1]) iqPair.push_back(10 * i1 + i2);
647 if ( (iqPair.size() > 0) && (rndmPtr->flat() < probDoubleAnn) ) {
648 iAnn = max( 0, min(
int(iqPair.size()) - 1,
649 int(iqPair.size() * rndmPtr->flat()) ));
650 iqAll[0][iqPair[iAnn]/10] = iqAll[0][1];
651 iqAll[1][iqPair[iAnn]%10] = iqAll[1][1];
654 int id1Ann = (id1 > 0) ? iqAll[0][0] : -iqAll[0][0];
655 int id2Ann = (id2 > 0) ? iqAll[1][0] : -iqAll[1][0];
656 double m1Ann = particleDataPtr->m0( id1Ann);
657 double m2Ann = particleDataPtr->m0( id2Ann);
658 if (m1Ann + m2Ann > 0.8 * eCM) {
659 double scaledown = 0.8 * eCM / (m1Ann + m2Ann);
665 double e1Ann = 0.5 * (sCM + m1Ann*m1Ann - m2Ann*m2Ann) / eCM;
666 double pzAnn = sqrtpos(e1Ann*e1Ann - m1Ann*m1Ann);
667 Vec4 p1Ann( 0., 0., pzAnn, e1Ann );
668 Vec4 p2Ann( 0., 0., -pzAnn, eCM - e1Ann );
669 int col1 = (id1 > 0) ? 101 : 0;
670 int acol1 = (id1 > 0) ? 0 : 101;
671 leEvent.append( id1Ann, 63, 1, 2, 0, 0, col1, acol1, p1Ann, m1Ann);
672 leEvent.append( id2Ann, 63, 1, 2, 0, 0, acol1, col1, p2Ann, m2Ann);
678 idc1 = (id1 > 0) ? iqAll[0][0] : -iqAll[0][0];
679 idac1 = (id1 > 0) ? iqAll[0][1] : -iqAll[0][1] ;
680 idc2 = (id2 > 0) ? iqAll[1][0] : -iqAll[1][0];
681 idac2 = (id2 > 0) ? iqAll[1][1] : -iqAll[1][1] ;
682 if (rndmPtr->flat() < 0.5) swap(idc2, idac2);
686 double e1, pz1, epz1, pzc1, ec1, epz2, pzc2, ec2, mAbove1, mAbove2;
687 Vec4 pc1, pac1, pc2, pac2;
690 if (++loop == MAXLOOP) {
691 infoPtr->errorMsg(
"Error in LowEnergyProcess::annihilation: "
692 "failed to find working kinematics configuration");
695 double redStep = (loop < 10) ? 1. : exp( -MASSREDUCERATE * (loop - 9));
698 splitA( eCM, redStep,
false);
699 splitB( eCM, redStep,
false);
702 z1 = splitZ( idc1, idac1, mTc1 / eCM, mTac1 / eCM);
703 z2 = splitZ( idc2, idac2, mTc2 / eCM, mTac2 / eCM);
704 mT1 = sqrt( mTsc1 / z1 + mTsac1 / (1. - z1));
705 mT2 = sqrt( mTsc2 / z2 + mTsac2 / (1. - z2));
708 }
while (mT1 + mT2 > eCM);
711 e1 = 0.5 * (sCM + mT1 * mT1 - mT2 * mT2) / eCM;
712 pz1 = sqrtpos(e1 * e1 - mT1 * mT1);
713 epz1 = z1 * (e1 + pz1);
714 pzc1 = 0.5 * (epz1 - mTsc1 / epz1 );
715 ec1 = 0.5 * (epz1 + mTsc1 / epz1 );
716 pc1.p( px1, py1, pzc1, ec1 );
717 pac1.p( -px1, -py1, pz1 - pzc1, e1 - ec1 );
718 epz2 = z2 * (eCM - e1 + pz1);
719 pzc2 = -0.5 * (epz2 - mTsc2 / epz2 );
720 ec2 = 0.5 * (epz2 + mTsc2 / epz2 );
721 pc2.p( px2, py2, pzc2, ec2 );
722 pac2.p( -px2, -py2, -pz1 - pzc2, eCM - e1 - ec2 );
725 mAbove1 = (pc1 + pac2).mCalc() - mThreshold( idc1, idac2);
726 mAbove2 = (pc2 + pac1).mCalc() - mThreshold( idc2, idac1);
727 }
while ( max( mAbove1, mAbove2) < MPI || min( mAbove1, mAbove2) < 0. );
730 int col1 = (id1 > 0) ? 101 : 0;
731 int acol1 = (id1 > 0) ? 0 : 101;
732 int col2 = (id1 > 0) ? 102 : 0;
733 int acol2 = (id1 > 0) ? 0 : 102;
734 if (mAbove1 < mAbove2) {
735 leEvent.append( idc1, 63, 1, 0, 0, 0, col1, acol1, pc1, mc1);
736 leEvent.append( idac2, 63, 2, 0, 0, 0, acol1, col1, pac2, mac2);
737 leEvent.append( idac1, 63, 1, 0, 0, 0, col2, acol2, pac1, mac1);
738 leEvent.append( idc2, 63, 2, 0, 0, 0, acol2, col2, pc2, mc2);
740 leEvent.append( idac1, 63, 1, 0, 0, 0, col2, acol2, pac1, mac1);
741 leEvent.append( idc2, 63, 2, 0, 0, 0, acol2, col2, pc2, mc2);
742 leEvent.append( idc1, 63, 1, 0, 0, 0, col1, acol1, pc1, mc1);
743 leEvent.append( idac2, 63, 2, 0, 0, 0, acol1, col1, pac2, mac2);
755 bool LowEnergyProcess::resonance() {
758 int iNew = leEvent.append(type, 919, 1,2,0,0, 0,0, Vec4(0,0,0,eCM), eCM);
760 leEvent[1].statusNeg(); leEvent[1].daughters(iNew, 0);
761 leEvent[2].statusNeg(); leEvent[2].daughters(iNew, 0);
771 bool LowEnergyProcess::simpleHadronization() {
774 simpleColConfig.clear();
775 bool fixOrder = (type == 1);
776 for (
int i = 0; i < leEvent.size(); ++i)
777 if (leEvent[i].isQuark() || leEvent[i].isDiquark()) {
779 qqPair.push_back( i);
780 qqPair.push_back( ++i);
781 simpleColConfig.simpleInsert( qqPair, leEvent, fixOrder);
785 if (simpleColConfig.size() == 0)
return true;
789 int nHadronBeg = leEvent.size();
790 for (
int iSub = 0; iSub < simpleColConfig.size(); ++iSub) {
791 if (iSub == 1) nHadron = leEvent.size() - nHadronBeg;
794 double mExcess = simpleColConfig[iSub].massExcess;
795 double mDiqDiq = ( leEvent[simpleColConfig[iSub].iParton[0]].isDiquark()
796 && leEvent[simpleColConfig[iSub].iParton[1]].isDiquark() )
798 bool fragDone =
false;
801 if ( mExcess > mStringMin + mDiqDiq) {
802 fragDone = stringFragPtr->fragment( iSub, simpleColConfig, leEvent);
803 if (!fragDone && mExcess > mStringMin + mDiqDiq + 4. * MPI)
return false;
808 bool isDiff = (type >= 3 && type <= 5);
809 if ( !ministringFragPtr->fragment( iSub, simpleColConfig, leEvent,
810 isDiff,
false) )
return false;
815 int nHad = 0, id3 = 0, id4 = 0;
816 for (
int i = 1; i < leEvent.size(); ++i)
if (leEvent[i].isFinal()) {
818 if (nHad == 1) id3 = leEvent[i].id();
819 if (nHad == 2) id4 = leEvent[i].id();
821 if (type == 1 && nHad == 2 && ( (id3 == id1 && id4 == id2)
822 || (id3 == id2 && id4 == id1) )) {
823 leEvent.restoreSize();
836 bool LowEnergyProcess::twoBody() {
839 if ( (abs(idc1) > 10 && abs(idac2) > 10)
840 || (abs(idc2) > 10 && abs(idac1) > 10) ) swap(idac1, idac2);
843 int idH1 = flavSelPtr->combineToLightest( idc1, idac2);
844 int idH2 = flavSelPtr->combineToLightest( idc2, idac1);
848 if ( (particleDataPtr->mMin(idH1) + particleDataPtr->mMin(idH2) >= eCM)
849 || !hadronWidthsPtr->pickMasses(idH1, idH2, eCM, mH1, mH2)) {
850 infoPtr->errorMsg(
"Warning in LowEnergyProcess::twoBody: "
851 "below mass threshold, defaulting to elastic collision");
854 mH1 = leEvent[1].m();
855 mH2 = leEvent[2].m();
859 pair<Vec4, Vec4> ps12 = rndmPtr->phaseSpace2(eCM, mH1, mH2);
860 for (
int i = 3; i < leEvent.size(); ++i) leEvent[i].statusNeg();
861 leEvent.append( idH1, 111, 2, 1, 0, 0, 0, 0, ps12.first, mH1);
862 leEvent.append( idH2, 111, 2, 1, 0, 0, 0, 0, ps12.second, mH2);
873 bool LowEnergyProcess::threeBody() {
876 if ( (abs(idc1) > 10 && abs(idac2) > 10)
877 || (abs(idc2) > 10 && abs(idac1) > 10) ) swap(idac1, idac2);
880 int idc3, idH1, idH2, idH3;
881 double mH1, mH2, mH3;
882 for (
int iTry = 0; iTry < 10; ++iTry) {
883 idc3 = (rndmPtr->flat() < 0.5) ? 1 : 2;
884 if (iTry < 8 && rndmPtr->flat() < 0.5) {
885 idH1 = flavSelPtr->combineToLightest( idc1, -idc3);
886 idH2 = flavSelPtr->combineToLightest( idc3, idac2);
887 idH3 = flavSelPtr->combineToLightest( idc2, idac1);
888 }
else if (iTry < 8) {
889 idH1 = flavSelPtr->combineToLightest( idc1, idac2);
890 idH2 = flavSelPtr->combineToLightest( idc2, -idc3);
891 idH3 = flavSelPtr->combineToLightest( idc3, idac1);
893 idH1 = flavSelPtr->combineToLightest( idc1, idac2);
894 idH2 = flavSelPtr->combineToLightest( idc2, idac1);
899 mH1 = particleDataPtr->mSel( idH1);
900 mH2 = particleDataPtr->mSel( idH2);
901 mH3 = particleDataPtr->mSel( idH3);
902 if (mH1 + mH2 + mH3 < eCM)
break;
903 else if (iTry == 9)
return twoBody();
907 double m23Min = mH2 + mH3;
908 double m23Max = eCM - mH1;
909 double p1Max = 0.5 * sqrtpos( (eCM - mH1 - m23Min) * (eCM + mH1 + m23Min)
910 * (eCM + mH1 - m23Min) * (eCM - mH1 + m23Min) ) / eCM;
911 double p23Max = 0.5 * sqrtpos( (m23Max - mH2 - mH3) * (m23Max + mH2 + mH3)
912 * (m23Max + mH2 - mH3) * (m23Max - mH2 + mH3) ) / m23Max;
913 double wtPSmax = 0.5 * p1Max * p23Max;
916 double wtPS, m23, p1Abs, p23Abs;
918 m23 = m23Min + rndmPtr->flat() * (m23Max - m23Min);
921 p1Abs = 0.5 * sqrtpos( (eCM - mH1 - m23) * (eCM + mH1 + m23)
922 * (eCM + mH1 - m23) * (eCM - mH1 + m23) ) / eCM;
923 p23Abs = 0.5 * sqrtpos( (m23 - mH2 - mH3) * (m23 + mH2 + mH3)
924 * (m23 + mH2 - mH3) * (m23 - mH2 + mH3) ) / m23;
925 wtPS = p1Abs * p23Abs;
928 }
while ( wtPS < rndmPtr->flat() * wtPSmax );
931 pair<Vec4, Vec4> ps123 = rndmPtr->phaseSpace2(eCM, mH1, m23);
932 Vec4 p1 = ps123.first;
933 pair<Vec4, Vec4> ps23 = rndmPtr->phaseSpace2(m23, mH2, mH3);
934 Vec4 p2 = ps23.first;
935 Vec4 p3 = ps23.second;
936 p2.bst( ps123.second, m23 );
937 p3.bst( ps123.second, m23 );
940 for (
int i = 3; i < leEvent.size(); ++i) leEvent[i].statusNeg();
941 leEvent.append( idH1, 111, 2, 1, 0, 0, 0, 0, p1, mH1);
942 leEvent.append( idH2, 111, 2, 1, 0, 0, 0, 0, p2, mH2);
943 leEvent.append( idH3, 111, 2, 1, 0, 0, 0, 0, p3, mH3);
954 bool LowEnergyProcess::splitA(
double mMax,
double redMpT,
bool splitFlavour) {
958 pair< int, int> paircac = splitFlav( id1 );
959 idc1 = paircac.first;
960 idac1 = paircac.second;
962 if (idc1 == 0 || idac1 == 0)
return false;
965 for (
int i = 0; i < 10; ++i) {
968 mc1 = particleDataPtr->m0( idc1);
969 mac1 = particleDataPtr->m0( idac1);
970 double redNow = redMpT * min( 1., m1 / (mc1 + mac1));
975 pair<double, double> gauss2 = rndmPtr->gauss2();
976 px1 = redMpT * sigmaQ * gauss2.first;
977 py1 = redMpT * sigmaQ * gauss2.second;
978 pTs1 = px1 * px1 + py1 * py1;
981 mTsc1 = pow2(mc1) + pTs1;
982 mTsac1 = pow2(mac1) + pTs1;
984 mTac1 = sqrt(mTsac1);
987 if (mTc1 + mTac1 < mMax)
return true;
997 bool LowEnergyProcess::splitB(
double mMax,
double redMpT,
bool splitFlavour) {
1001 pair< int, int> paircac = splitFlav( id2 );
1002 idc2 = paircac.first;
1003 idac2 = paircac.second;
1005 if (idc2 == 0 || idac2 == 0)
return false;
1008 for (
int i = 0; i < 10; ++i) {
1011 mc2 = particleDataPtr->m0( idc2);
1012 mac2 = particleDataPtr->m0( idac2);
1013 double redNow = redMpT * min( 1., m2 / (mc2 + mac2));
1018 pair<double, double> gauss2 = rndmPtr->gauss2();
1019 px2 = redMpT * sigmaQ * gauss2.first;
1020 py2 = redMpT * sigmaQ * gauss2.second;
1021 pTs2 = px2 * px2 + py2 * py2;
1024 mTsc2 = pow2(mc2) + pTs2;
1025 mTsac2 = pow2(mac2) + pTs2;
1027 mTac2 = sqrt(mTsac2);
1030 if (mTc2 + mTac2 < mMax)
return true;
1040 pair< int, int> LowEnergyProcess::splitFlav(
int id) {
1043 int idAbs = abs(
id);
1044 int iq1 = (idAbs/1000)%10;
1045 int iq2 = (idAbs/100)%10;
1046 int iq3 = (idAbs/10)%10;
1050 if (iq1 == 0 && iq2 != iq3) {
1051 if (
id != 130 &&
id != 310) {
1052 if (iq2%2 == 1) swap( iq2, iq3);
1053 if (
id > 0)
return make_pair( iq2, -iq3);
1054 else return make_pair( iq3, -iq2);
1058 if (rndmPtr->flat() < 0.5)
return make_pair( 3, -1);
1059 else return make_pair( 1, -3);
1063 }
else if (iq1 == 0) {
1066 if (iq2 < 3 ||
id == 331) {
1067 iq4 = (rndmPtr->flat() < 0.5) ? 1 : 2;
1069 if (
id == 221 && eCM > 2 * MK && rndmPtr->flat() < fracEtass) iq4 = 3;
1070 if (
id == 331 && eCM > 2 * MK && rndmPtr->flat() < fracEtaPss) iq4 = 3;
1072 return make_pair( iq4, -iq4);
1075 }
else if (idAbs%10 == 2) {
1077 if (iq1 == iq2 && iq2 == iq3) {iq4 = iq1; iq5 = 1100 * iq1 + 3;}
1079 else if (iq1 == iq2 || iq2 == iq3) {
1080 double rr6 = 6. * rndmPtr->flat();
1081 if (iq1 == iq2 && rr6 < 2.) { iq4 = iq3; iq5 = 1100 * iq1 + 3;}
1082 else if (rr6 < 2.) { iq4 = iq1; iq5 = 1100 * iq3 + 3;}
1083 else if (rr6 < 3.) { iq4 = iq2; iq5 = 1000 * iq1 + 100 * iq3 + 3;}
1084 else { iq4 = iq2; iq5 = 1000 * iq1 + 100 * iq3 + 1;}
1087 int isp = (iq2 > iq3) ? 3 : 1;
1088 if (iq3 > iq1) swap( iq1, iq3);
1089 if (iq3 > iq2) swap( iq2, iq3);
1090 double rr12 = 12. * rndmPtr->flat();
1091 if (rr12 < 4.) { iq4 = iq1; iq5 = 1000 * iq2 + 100 * iq3 + isp;}
1092 else if (rr12 < 5.) { iq4 = iq2; iq5 = 1000 * iq1 + 100 * iq3 + isp;}
1093 else if (rr12 < 6.) { iq4 = iq3; iq5 = 1000 * iq1 + 100 * iq2 + isp;}
1094 else if (rr12 < 9.) { iq4 = iq2; iq5 = 1000 * iq1 + 100 * iq3 + 4 - isp;}
1095 else { iq4 = iq3; iq5 = 1000 * iq1 + 100 * iq2 + 4 - isp;}
1097 return (
id > 0) ? make_pair(iq4, iq5) : make_pair(-iq5, -iq4);
1101 double rr3 = 3. * rndmPtr->flat();
1103 if (iq3 > iq1) swap( iq1, iq3);
1104 if (iq3 > iq2) swap( iq2, iq3);
1105 if (rr3 < 1.) { iq4 = iq1; iq5 = 1000 * iq2 + 100 * iq3 + 3;}
1106 else if (rr3 < 2.) { iq4 = iq2; iq5 = 1000 * iq1 + 100 * iq3 + 3;}
1107 else { iq4 = iq3; iq5 = 1000 * iq1 + 100 * iq2 + 3;}
1108 return (
id > 0) ? make_pair(iq4, iq5) : make_pair(-iq5, -iq4);
1112 return make_pair( 0, 0);
1119 double LowEnergyProcess::splitZ(
int iq1,
int iq2,
double mRat1,
double mRat2) {
1122 int iq1Abs = abs(iq1);
1123 int iq2Abs = abs(iq2);
1124 if (iq2Abs > 10) swap( mRat1, mRat2);
1125 double x1, x2, x1a, x1b;
1128 if (iq1Abs < 10 && iq2Abs < 10) {
1129 do x1 = pow2( mRat1 + (1. - mRat1) * rndmPtr->flat() );
1130 while ( pow(1. - x1, xPowMes) < rndmPtr->flat() );
1131 do x2 = pow2( mRat2 + (1. - mRat2) * rndmPtr->flat() );
1132 while ( pow(1. - x2, xPowMes) < rndmPtr->flat() );
1136 double mRat1ab = 0.5 * mRat1 / xDiqEnhance;
1137 do x1a = pow2( mRat1ab + (1. - mRat1ab) * rndmPtr->flat() );
1138 while ( pow(1. - x1a, xPowBar) < rndmPtr->flat() );
1139 do x1b = pow2( mRat1ab + (1. - mRat1ab) * rndmPtr->flat() );
1140 while ( pow(1. - x1b, xPowBar) < rndmPtr->flat() );
1141 x1 = xDiqEnhance * ( x1a + x1b);
1142 do x2 = pow2( mRat2 + (1. - mRat2) * rndmPtr->flat() );
1143 while ( pow(1. - x2, xPowBar) < rndmPtr->flat() );
1144 if (iq2Abs > 10) swap( x1, x2);
1148 return x1 / (x1 + x2);
1156 double LowEnergyProcess::mThreshold(
int iq1,
int iq2) {
1159 int iq1Abs = abs(iq1);
1160 int iq2Abs = abs(iq2);
1161 if (iq2Abs > 10) swap( iq1Abs, iq2Abs);
1165 if (iq2Abs < 10) mThr
1166 = particleDataPtr->m0( flavSelPtr->combineToLightest ( iq1, iq2) );
1170 particleDataPtr->m0( flavSelPtr->combineToLightest ( iq1Abs, 1) )
1171 + particleDataPtr->m0( flavSelPtr->combineToLightest ( iq2Abs, 1) ),
1172 particleDataPtr->m0( flavSelPtr->combineToLightest ( iq1Abs, 2) )
1173 + particleDataPtr->m0( flavSelPtr->combineToLightest ( iq2Abs, 2) ) );
1185 double LowEnergyProcess::mDiffThr(
int idNow,
double mNow) {
1188 double mThr = mNow + MDIFFMIN;
1191 pair< int, int> paircac = splitFlav( idNow );
1192 int idcNow = paircac.first;
1193 int idacNow = paircac.second;
1194 if (idcNow == 0 || idacNow == 0)
return mThr;
1195 if (idNow == 221 || idNow == 331) {idcNow = 3; idacNow = -3;}
1198 double mThr2body = min(
1199 particleDataPtr->m0( flavSelPtr->combineToLightest ( idcNow, -1) )
1200 + particleDataPtr->m0( flavSelPtr->combineToLightest ( 1, idacNow) ),
1201 particleDataPtr->m0( flavSelPtr->combineToLightest ( idcNow, -2) )
1202 + particleDataPtr->m0( flavSelPtr->combineToLightest ( 2, idacNow) ) );
1205 return max(mThr, mThr2body);
1213 double LowEnergyProcess::bSlope() {
1218 bA = lowEnergySigmaPtr->nqEffAQM(id1) * ((isBaryon1) ? 2.3/3. : 1.4/2.);
1222 bB = lowEnergySigmaPtr->nqEffAQM(id2) * ((isBaryon1) ? 2.3/3. : 1.4/2.);
1228 return 2. * bA + 2. * bB + 2. * ALPHAPRIME * log(ALPHAPRIME * sCM);
1231 if (type == 3)
return 2. * bB + 2. * ALPHAPRIME * log(sCM / (mA * mA));
1232 if (type == 4)
return 2. * bA + 2. * ALPHAPRIME * log(sCM / (mB * mB));
1235 return 2. * ALPHAPRIME * log(exp(4.) + sCM / (ALPHAPRIME * pow2(mA * mB)) );