9 #include "Pythia8/ParticleDecays.h"
10 #include "Pythia8/HadronWidths.h"
24 const int ParticleDecays::NTRYDECAY = 10;
27 const int ParticleDecays::NTRYPICK = 100;
30 const int ParticleDecays::NTRYMEWT = 1000;
33 const int ParticleDecays::NTRYDALITZ = 1000;
36 const double ParticleDecays::MSAFEDALITZ = 1.000001;
40 const double ParticleDecays::WTCORRECTION[11] = { 1., 1., 1.,
41 2., 5., 15., 60., 250., 1250., 7000., 50000. };
47 void ParticleDecays::init(TimeShowerPtr timesDecPtrIn,
48 StringFlav* flavSelPtrIn, DecayHandlerPtr decayHandlePtrIn,
49 vector<int> handledParticles) {
52 flavSelPtr = flavSelPtrIn;
55 timesDecPtr = timesDecPtrIn;
58 decayHandlePtr = decayHandlePtrIn;
61 if (decayHandlePtr != 0)
62 for (
int i = 0; i < int(handledParticles.size()); ++i)
63 particleDataPtr->doExternalDecay(handledParticles[i],
true);
66 mSafety = parm(
"ParticleDecays:mSafety");
69 limitTau0 = flag(
"ParticleDecays:limitTau0");
70 tau0Max = parm(
"ParticleDecays:tau0Max");
71 limitTau = flag(
"ParticleDecays:limitTau");
72 tauMax = parm(
"ParticleDecays:tauMax");
73 limitRadius = flag(
"ParticleDecays:limitRadius");
74 rMax = parm(
"ParticleDecays:rMax");
75 limitCylinder = flag(
"ParticleDecays:limitCylinder");
76 xyMax = parm(
"ParticleDecays:xyMax");
77 zMax = parm(
"ParticleDecays:zMax");
78 limitDecay = limitTau0 || limitTau || limitRadius || limitCylinder;
81 mixB = flag(
"ParticleDecays:mixB");
82 xBdMix = parm(
"ParticleDecays:xBdMix");
83 xBsMix = parm(
"ParticleDecays:xBsMix");
86 sigmaSoft = parm(
"ParticleDecays:sigmaSoft");
89 multIncrease = parm(
"ParticleDecays:multIncrease");
90 multIncreaseWeak = parm(
"ParticleDecays:multIncreaseWeak");
91 multRefMass = parm(
"ParticleDecays:multRefMass");
92 multGoffset = parm(
"ParticleDecays:multGoffset");
93 colRearrange = parm(
"ParticleDecays:colRearrange");
96 stopMass = parm(
"StringFragmentation:stopMass");
99 sRhoDal = pow2(particleDataPtr->m0(113));
100 wRhoDal = pow2(particleDataPtr->mWidth(113));
103 doFSRinDecays = flag(
"ParticleDecays:FSRinDecays");
104 doGammaRad = flag(
"ParticleDecays:allowPhotonRadiation");
107 tauMode = mode(
"TauDecays:mode");
110 if (tauMode) tauDecayer.init();
118 bool ParticleDecays::decay(
int iDec,
Event& event) {
121 Particle& decayer =
event[iDec];
124 if (limitDecay && !checkVertex(decayer))
return true;
127 if (decayer.isResonance()) {
128 infoPtr->errorMsg(
"Warning in ParticleDecays::decay: "
129 "resonance left undecayed");
134 idDec = decayer.id();
138 iProd.push_back( iDec );
139 idProd.push_back( idDec );
140 mProd.push_back( decayer.m() );
143 bool hasOscillated = (abs(idDec) == 511 || abs(idDec) == 531)
144 ? oscillateB(decayer) :
false;
145 if (hasOscillated) {idDec = - idDec; idProd[0] = idDec;}
148 decDataPtr = &decayer.particleDataEntry();
151 bool doneExternally =
false;
152 if (decDataPtr->doExternalDecay()) {
153 motherProd.resize(0);
154 motherProd.push_back( 0 );
156 pProd.push_back(decayer.p());
157 doneExternally = decayHandlePtr->chainDecay( idProd, motherProd,
158 mProd, pProd, iDec, event);
159 if (!doneExternally) doneExternally = decayHandlePtr->decay( idProd,
160 mProd, pProd, iDec, event);
163 if (doneExternally) {
164 int oldSize =
event.size();
165 mult = idProd.size() - 1;
166 while (
int(motherProd.size()) <= mult) motherProd.push_back( 0 );
167 int status = (hasOscillated) ? 94 : 93;
168 for (
int i = 1; i <= mult; ++i) {
169 int iMo = (motherProd[i] == 0) ? iDec : oldSize + motherProd[i] - 1;
170 int iPos =
event.append( idProd[i], status, iMo, 0, 0, 0,
171 0, 0, pProd[i], mProd[i]);
172 iProd.push_back( iPos);
175 event[iMo].statusNeg();
176 if ( event[iMo].daughter1() == 0)
event[iMo].daughter1( iPos);
177 else event[iMo].daughter2( iPos);
183 if (decayer.idAbs() == 15 && !doneExternally && tauMode) {
184 doneExternally = tauDecayer.decay(iDec, event);
185 if (doneExternally)
return true;
189 if (!doneExternally && decDataPtr->varWidth()
190 && (idDec != 113 && abs(idDec) != 213 && idDec != 225)) {
191 double mDec = decayer.m();
194 if (hadronWidthsPtr->pickDecay(idDec, mDec, id1, id2, m1, m2)) {
197 auto ps = rndmPtr->phaseSpace2(mDec, m1, m2);
198 ps.first.bst( decayer.p(), decayer.m() );
199 ps.second.bst(decayer.p(), decayer.m() );
203 int statOut = ( decayer.statusAbs() == 157
204 || decayer.statusAbs() == 159 ) ? 97 : 91;
206 iProd[1] =
event.append(id1, statOut, iDec,0, 0,0, 0,0, ps.first , m1);
207 iProd[2] =
event.append(id2, statOut, iDec,0, 0,0, 0,0, ps.second, m2);
210 event[iDec].statusNeg();
211 event[iDec].daughters(iProd[1], iProd[2]);
214 doneExternally =
true;
219 if (!doneExternally) {
222 if (!decDataPtr->preparePick(idDec, decayer.m()))
return false;
223 bool foundChannel =
false;
224 bool hasStored =
false;
225 for (
int iTryChannel = 0; iTryChannel < NTRYDECAY; ++iTryChannel) {
228 if (hasStored)
event.popBack(mult);
232 DecayChannel& channel = decDataPtr->pickChannel();
233 meMode = channel.meMode();
234 keepPartons = (meMode > 90 && meMode <= 100);
235 mult = channel.multiplicity();
238 bool foundMode =
false;
240 for (
int iTryMode = 0; iTryMode < NTRYDECAY; ++iTryMode) {
247 for (
int i = 0; i < mult; ++i) {
248 int idNow = channel.product(i);
249 int idAbs = abs(idNow);
250 if ( idAbs < 10 || idAbs == 21 || idAbs == 81 || idAbs == 82
251 || idAbs == 83 || (idAbs > 1000 && idAbs < 10000
252 && (idAbs/10)%10 == 0) ) hasPartons =
true;
253 if (idDec < 0 && particleDataPtr->hasAnti(idNow)) idNow = -idNow;
254 double mNow = particleDataPtr->mSel(idNow);
255 idProd.push_back( idNow);
256 mProd.push_back( mNow);
260 if (hasPartons && !keepPartons && !pickHadrons())
continue;
265 for (
int i = 0; i <= mult; ++i) {
269 if (hasPartons && keepPartons && !setColours(event))
continue;
273 double mDiff = mProd[0];
274 for (
int i = 1; i <= mult; ++i) mDiff -= mProd[i];
275 if (mDiff < mSafety)
continue;
282 if (!foundMode)
continue;
285 int status = (hasOscillated) ? 92 : 91;
286 for (
int i = 1; i <= mult; ++i) {
287 int iPos =
event.append( idProd[i], status, iDec, 0, 0, 0,
288 cols[i], acols[i], Vec4(0., 0., 0., 0.), mProd[i], scale);
289 iProd.push_back( iPos);
294 if ( (meMode == 11 || meMode == 12 || meMode == 13)
295 && !dalitzMass() )
continue;
298 bool decayed =
false;
299 if (mult == 1) decayed = oneBody(event);
300 else if (mult == 2) decayed = twoBody(event);
301 else if (mult == 3) decayed = threeBody(event);
302 else decayed = mGenerator(event);
303 if (!decayed)
continue;
306 if (meMode == 11 || meMode == 12 || meMode == 13)
307 dalitzKinematics(event);
316 event[iDec].statusNeg();
317 event[iDec].daughters( iProd[1], iProd[mult]);
321 if (hasStored)
event.popBack(mult);
322 infoPtr->errorMsg(
"Error in ParticleDecays::decay: "
323 "failed to find workable decay channel");
332 if (event[iDec].hasVertex() || event[iDec].tau() > 0.) {
333 Vec4 vDec =
event[iDec].vDec();
334 for (
int i = event[iDec].daughter1(); i <=
event[iDec].daughter2(); ++i)
335 event[i].vProd( vDec );
339 for (
int i = iProd[1]; i <= iProd[mult]; ++i) {
340 event[i].tau( event[i].tau0() * rndmPtr->exp() );
341 if (!event[i].isFinal() && (
event[i].hasVertex() ||
event[i].tau() > 0.)) {
342 Vec4 vDecR =
event[i].vDec();
343 for (
int iR = event[i].daughter1(); iR <=
event[i].daughter2(); ++iR)
344 event[iR].vProd( vDecR );
350 if (hasPartons && keepPartons && doFSRinDecays)
351 timesDecPtr->shower( iProd[1], iProd.back(), event, mProd[0]);
354 else if (doGammaRad && mult == 2 && event[iProd[1]].isLepton()
355 &&
event[iProd[2]].isLepton())
356 timesDecPtr->showerQED( iProd[1], iProd[2], event, mProd[0]);
359 else if (event[iDec].idAbs() > 4900000 && event[iDec].idAbs() < 5000000
360 && doFSRinDecays && mult == 2 && event[iProd[1]].isLepton()) {
361 event[iProd[1]].scale(mProd[0]);
362 event[iProd[2]].scale(mProd[0]);
363 timesDecPtr->shower( iProd[1], iProd.back(), event, mProd[0]);
375 bool ParticleDecays::decayAll(
Event& event,
double minWidth) {
378 bool gotMoreToDo =
false;
379 for (
int iDec = 0; iDec <
event.size(); ++iDec) {
380 Particle& decayer =
event[iDec];
381 if ( decayer.isFinal() && decayer.canDecay() && decayer.mayDecay()
382 && (decayer.mWidth() >= minWidth || decayer.idAbs() == 311) ) {
384 if (moreToDo()) gotMoreToDo =
true;
395 bool ParticleDecays::checkVertex(Particle& decayer) {
398 if (limitTau0 && decayer.tau0() > tau0Max)
return false;
399 if (limitTau && decayer.tau() > tauMax)
return false;
400 if (limitRadius && pow2(decayer.xDec()) + pow2(decayer.yDec())
401 + pow2(decayer.zDec()) > pow2(rMax))
return false;
402 if (limitCylinder && (pow2(decayer.xDec()) + pow2(decayer.yDec())
403 > pow2(xyMax) || abs(decayer.zDec()) > zMax) )
return false;
414 bool ParticleDecays::oscillateB(Particle& decayer) {
417 if (!mixB)
return false;
418 double xBmix = (abs(decayer.id()) == 511) ? xBdMix : xBsMix;
419 double tau = decayer.tau();
420 double tau0 = decayer.tau0();
421 double probosc = pow2(sin(0.5 * xBmix * tau / tau0));
422 return (probosc > rndmPtr->flat());
430 bool ParticleDecays::oneBody(
Event& event) {
433 Particle& decayer =
event[iProd[0]];
434 Particle& prod =
event[iProd[1]];
437 prod.p( decayer.p() );
438 prod.m( decayer.m() );
439 prod.mother2( iProd[0] );
450 bool ParticleDecays::twoBody(
Event& event) {
453 Particle& decayer =
event[iProd[0]];
454 Particle& prod1 =
event[iProd[1]];
455 Particle& prod2 =
event[iProd[2]];
458 double m0 = mProd[0];
459 double m1 = mProd[1];
460 double m2 = mProd[2];
463 if (m1 + m2 + mSafety > m0)
return false;
467 int iMother =
event[iProd[0]].mother1();
470 if (iMother <= 0 || iMother >= iProd[0]) meMode = 0;
472 int iDaughter1 =
event[iMother].daughter1();
473 int iDaughter2 =
event[iMother].daughter2();
474 if (iDaughter2 != iDaughter1 + 1) meMode = 0;
476 int idMother = abs( event[iMother].
id() );
477 if (idMother <= 100 || idMother%10 !=1
478 || (idMother/1000)%10 != 0) meMode = 0;
480 int iSister = (iProd[0] == iDaughter1) ? iDaughter2 : iDaughter1;
481 idSister = abs( event[iSister].
id() );
482 if ( (idSister <= 100 || idSister%10 !=1
483 || (idSister/1000)%10 != 0) && idSister != 22) meMode = 0;
490 double wtME, wtMEmax;
498 pair<Vec4, Vec4> ps = rndmPtr->phaseSpace2(m0, m1, m2);
501 prod1.bst( decayer.p(), decayer.m() );
502 prod2.bst( decayer.p(), decayer.m() );
508 double p10 = decayer.p() *
event[iMother].p();
509 double p12 = decayer.p() * prod1.p();
510 double p02 =
event[iMother].p() * prod1.p();
511 double s0 = pow2(event[iMother].m());
512 double s1 = pow2(decayer.m());
513 double s2 = pow2(prod1.m());
514 if (idSister != 22) wtME = pow2(p10 * p12 - s1 * p02);
515 else wtME = s1 * (2. * p10 * p12 * p02 - s1 * p02*p02
516 - s0 * p12*p12 - s2 * p10*p10 + s1 * s0 * s2);
517 wtME = max( wtME, 1e-6 * s1*s1 * s0 * s2);
518 wtMEmax = (p10*p10 - s1 * s0) * (p12*p12 - s1 * s2);
522 if(loop > NTRYMEWT) {
523 infoPtr->errorMsg(
"ParticleDecays::twoBody: "
524 "caught in infinite ME weight loop");
529 }
while ( wtME < rndmPtr->flat() * wtMEmax );
540 bool ParticleDecays::threeBody(
Event& event) {
543 Particle& decayer =
event[iProd[0]];
544 Particle& prod1 =
event[iProd[1]];
545 Particle& prod2 =
event[iProd[2]];
546 Particle& prod3 =
event[iProd[3]];
549 double m0 = mProd[0];
550 double m1 = mProd[1];
551 double m2 = mProd[2];
552 double m3 = mProd[3];
553 double mSum = m1 + m2 + m3;
554 double mDiff = m0 - mSum;
555 if (mDiff < mSafety)
return false;
558 double m23Min = m2 + m3;
559 double m23Max = m0 - m1;
560 double p1Max = 0.5 * sqrtpos( (m0 - m1 - m23Min) * (m0 + m1 + m23Min)
561 * (m0 + m1 - m23Min) * (m0 - m1 + m23Min) ) / m0;
562 double p23Max = 0.5 * sqrtpos( (m23Max - m2 - m3) * (m23Max + m2 + m3)
563 * (m23Max + m2 - m3) * (m23Max - m2 + m3) ) / m23Max;
564 double wtPSmax = 0.5 * p1Max * p23Max;
567 double wtME, wtMEmax, wtPS, m23, p1Abs, p23Abs;
574 m23 = m23Min + rndmPtr->flat() * mDiff;
577 p1Abs = 0.5 * sqrtpos( (m0 - m1 - m23) * (m0 + m1 + m23)
578 * (m0 + m1 - m23) * (m0 - m1 + m23) ) / m0;
579 p23Abs = 0.5 * sqrtpos( (m23 - m2 - m3) * (m23 + m2 + m3)
580 * (m23 + m2 - m3) * (m23 - m2 + m3) ) / m23;
581 wtPS = p1Abs * p23Abs;
584 }
while ( wtPS < rndmPtr->flat() * wtPSmax );
587 pair<Vec4, Vec4> ps23 = rndmPtr->phaseSpace2(m23, m2, m3);
589 prod3.p(ps23.second);
592 pair<Vec4, Vec4> ps123 = rndmPtr->phaseSpace2(m0, m1, m23);
593 prod1.p(ps123.first);
596 prod2.bst( ps123.second, m23 );
597 prod3.bst( ps123.second, m23 );
601 double p1p2 = prod1.p() * prod2.p();
602 double p1p3 = prod1.p() * prod3.p();
603 double p2p3 = prod2.p() * prod3.p();
604 wtME = pow2(m1 * m2 * m3) - pow2(m1 * p2p3) - pow2(m2 * p1p3)
605 - pow2(m3 * p1p2) + 2. * p1p2 * p1p3 * p2p3;
606 wtMEmax = pow3(m0 * m0) / 150.;
609 }
else if (meMode == 21) {
610 double x1 = 2. * prod1.e() / m0;
611 wtME = x1 * (3. - 2. * x1);
612 double xMax = min( 0.75, 2. * (1. - mSum / m0) );
613 wtMEmax = xMax * (3. - 2. * xMax);
616 }
else if ( ((meMode == 22 || meMode == 23) && prod1.isLepton())
618 wtME = m0 * prod1.e() * (prod2.p() * prod3.p());
619 wtMEmax = min( pow4(m0) / 16., m0 * (m0 - m1 - m2) * (m0 - m1 - m3)
623 }
else if (meMode == 22 || meMode == 23) {
624 double x1 = 2. * prod1.pAbs() / m0;
625 wtME = x1 * (3. - 2. * x1);
626 double xMax = min( 0.75, 2. * (1. - mSum / m0) );
627 wtMEmax = xMax * (3. - 2. * xMax);
630 }
else if (meMode == 31) {
631 double x1 = 2. * prod1.e() / m0;
633 double x1Max = 1. - pow2(mSum / m0);
634 wtMEmax = pow3(x1Max);
637 }
else if (meMode == 92) {
638 double x1 = 2. * prod1.e() / m0;
639 double x2 = 2. * prod2.e() / m0;
640 double x3 = 2. * prod3.e() / m0;
641 wtME = pow2( (1. - x1) / (x2 * x3) ) + pow2( (1. - x2) / (x1 * x3) )
642 + pow2( (1. - x3) / (x1 * x2) );
645 if (prod1.id() == 22 && sqrt(1. - x1) * m0 < 2. * stopMass) wtME = 0.;
646 if (prod2.id() == 22 && sqrt(1. - x2) * m0 < 2. * stopMass) wtME = 0.;
647 if (prod3.id() == 22 && sqrt(1. - x3) * m0 < 2. * stopMass) wtME = 0.;
651 }
while ( wtME < rndmPtr->flat() * wtMEmax );
654 prod1.bst( decayer.p(), decayer.m() );
655 prod2.bst( decayer.p(), decayer.m() );
656 prod3.bst( decayer.p(), decayer.m() );
667 bool ParticleDecays::mGenerator(
Event& event) {
670 double m0 = mProd[0];
671 double mSum = mProd[1];
672 for (
int i = 2; i <= mult; ++i) mSum += mProd[i];
673 double mDiff = m0 - mSum;
674 if (mDiff < mSafety)
return false;
678 for (
int i = 0; i <= mult; ++i) mInv.push_back( mProd[i]);
681 double wtPS, wtME, wtMEmax;
682 double wtPSmax = 1. / WTCORRECTION[mult];
683 double mMax = mDiff + mProd[mult];
685 for (
int i = mult - 1; i > 0; --i) {
688 double mNow = mProd[i];
689 wtPSmax *= 0.5 * sqrtpos( (mMax - mMin - mNow) * (mMax + mMin + mNow)
690 * (mMax + mMin - mNow) * (mMax - mMin + mNow) ) / mMax;
704 rndmOrd.push_back(1.);
705 for (
int i = 1; i < mult - 1; ++i) {
706 double rndm = rndmPtr->flat();
707 rndmOrd.push_back(rndm);
708 for (
int j = i - 1; j > 0; --j) {
709 if (rndm > rndmOrd[j]) swap( rndmOrd[j], rndmOrd[j+1] );
713 rndmOrd.push_back(0.);
716 for (
int i = mult - 1; i > 0; --i) {
717 mInv[i] = mInv[i+1] + mProd[i] + (rndmOrd[i-1] - rndmOrd[i]) * mDiff;
718 wtPS *= 0.5 * sqrtpos( (mInv[i] - mInv[i+1] - mProd[i])
719 * (mInv[i] + mInv[i+1] + mProd[i]) * (mInv[i] + mInv[i+1] - mProd[i])
720 * (mInv[i] - mInv[i+1] + mProd[i]) ) / mInv[i];
724 }
while ( wtPS < rndmPtr->flat() * wtPSmax );
727 pInv.resize(mult + 1);
728 for (
int i = 1; i < mult; ++i) {
730 pair<Vec4, Vec4> ps = rndmPtr->phaseSpace2(mInv[i], mInv[i+1], mProd[i]);
731 pInv[i+1].p(ps.first);
732 event[iProd[i]].p(ps.second);
736 event[iProd[mult]].p( pInv[mult] );
737 for (
int iFrame = mult - 1; iFrame > 1; --iFrame)
738 for (
int i = iFrame; i <= mult; ++i)
739 event[iProd[i]].bst( pInv[iFrame], mInv[iFrame]);
742 if (meMode == 21 && event[iProd[1]].isLepton()) {
743 double x1 = 2. *
event[iProd[1]].e() / m0;
744 wtME = x1 * (3. - 2. * x1);
745 double xMax = min( 0.75, 2. * (1. - mSum / m0) );
746 wtMEmax = xMax * (3. - 2. * xMax);
750 }
else if ((meMode == 22 || meMode == 23) &&
event[iProd[1]].isLepton()) {
751 Vec4 pRest =
event[iProd[3]].p();
752 for (
int i = 4; i <= mult; ++i) pRest += event[iProd[i]].p();
753 wtME = m0 *
event[iProd[1]].e() * (
event[iProd[2]].p() * pRest);
754 for (
int i = 4; i <= mult; ++i) wtME
755 *= exp(- event[iProd[i]].pAbs2() / pow2(sigmaSoft) );
756 wtMEmax = pow4(m0) / 16.;
759 }
else if (meMode == 22 || meMode == 23) {
760 double x1 = 2. *
event[iProd[1]].pAbs() / m0;
761 wtME = x1 * (3. - 2. * x1);
762 double xMax = min( 0.75, 2. * (1. - mSum / m0) );
763 wtMEmax = xMax * (3. - 2. * xMax);
766 }
else if (meMode == 31) {
767 double x1 = 2. *
event[iProd[1]].e() / m0;
769 double x1Max = 1. - pow2(mSum / m0);
770 wtMEmax = pow3(x1Max);
774 }
while ( wtME < rndmPtr->flat() * wtMEmax );
777 pInv[1].p( event[iProd[0]].p() );
778 for (
int i = 1; i <= mult; ++i) event[iProd[i]].bst( pInv[1], mInv[1] );
789 bool ParticleDecays::dalitzMass() {
793 for (
int i = 1; i <= mult - 2; ++i) mSum1 += mProd[i];
794 if (meMode == 13) mSum1 *= MSAFEDALITZ;
795 double mSum2 = MSAFEDALITZ * (mProd[mult -1] + mProd[mult]);
796 double mDiff = mProd[0] - mSum1 - mSum2;
799 if (mDiff < mSafety)
return false;
800 if (idProd[mult - 1] + idProd[mult] != 0
801 || mProd[mult - 1] != mProd[mult]) {
802 infoPtr->errorMsg(
"Error in ParticleDecays::dalitzMass:"
803 " inconsistent flavour/mass assignments");
806 if ( meMode == 13 && (idProd[1] + idProd[2] != 0
807 || mProd[1] != mProd[2]) ) {
808 infoPtr->errorMsg(
"Error in ParticleDecays::dalitzMass:"
809 " inconsistent flavour/mass assignments");
814 if (meMode == 11 || meMode == 12) {
817 double sGamMin = pow2(mSum2);
818 double sGamMax = pow2(mProd[0] - mSum1);
823 if (++loop > NTRYDALITZ)
return false;
824 sGam = sGamMin * pow( sGamMax / sGamMin, rndmPtr->flat() );
825 wtGam = (1. + 0.5 * sGamMin / sGam) * sqrt(1. - sGamMin / sGam)
826 * pow3(1. - sGam / sGamMax) * sRhoDal * (sRhoDal + wRhoDal)
827 / ( pow2(sGam - sRhoDal) + sRhoDal * wRhoDal );
828 }
while ( wtGam < rndmPtr->flat() );
832 mProd[mult] = sqrt(sGam);
838 double s0 = pow2(mProd[0]);
839 double s12Min = pow2(mSum1);
840 double s12Max = pow2(mProd[0] - mSum2);
841 double s34Min = pow2(mSum2);
842 double s34Max = pow2(mProd[0] - mSum1);
845 double s12, s34, wt12, wt34, wtPAbs, wtAll;
848 if (++loop > NTRYDALITZ)
return false;
849 s12 = s12Min * pow( s12Max / s12Min, rndmPtr->flat() );
850 wt12 = (1. + 0.5 * s12Min / s12) * sqrt(1. - s12Min / s12)
851 * sRhoDal * (sRhoDal + wRhoDal)
852 / ( pow2(s12 - sRhoDal) + sRhoDal * wRhoDal );
853 s34 = s34Min * pow( s34Max / s34Min, rndmPtr->flat() );
854 wt34 = (1. + 0.5 * s34Min / s34) * sqrt(1. - s34Min / s34)
855 * sRhoDal * (sRhoDal + wRhoDal)
856 / ( pow2(s34 - sRhoDal) + sRhoDal * wRhoDal );
857 wtPAbs = sqrtpos( pow2(1. - (s12 + s34)/ s0)
858 - 4. * s12 * s34 / (s0 * s0) );
859 wtAll = wt12 * wt34 * pow3(wtPAbs);
860 if (wtAll > 1.) infoPtr->errorMsg(
861 "Error in ParticleDecays::dalitzMass: weight > 1");
862 }
while (wtAll < rndmPtr->flat());
866 mProd[1] = sqrt(s12);
867 mProd[2] = sqrt(s34);
879 bool ParticleDecays::dalitzKinematics(
Event& event) {
882 int nDal = (meMode < 13) ? 1 : 2;
886 for (
int iDal = 0; iDal < nDal; ++iDal) {
889 Particle& decayer =
event[iProd[0]];
890 Particle& prodA = (iDal == 0) ? event[iProd[mult - 1]]
892 Particle& prodB = (iDal == 0) ? event[iProd[mult]]
896 Vec4 pDec = decayer.p();
897 int iGam = (meMode < 13) ? mult - 1 : 2 - iDal;
898 Vec4 pGam =
event[iProd[iGam]].p();
899 pGam.bstback( pDec, decayer.m() );
900 double phiGam = pGam.phi();
901 pGam.rot( 0., -phiGam);
902 double thetaGam = pGam.theta();
903 pGam.rot( -thetaGam, 0.);
906 double mGam = (meMode < 13) ? mProd[mult - 1] : mProd[2 - iDal];
907 double mA = prodA.m();
908 double mB = prodB.m();
909 double mGamMin = MSAFEDALITZ * (mA + mB);
910 double mGamRat = pow2(mGamMin / mGam);
911 double pGamAbs = 0.5 * sqrtpos( (mGam - mA - mB) * (mGam + mA + mB) );
914 double cosTheta, cos2Theta;
916 cosTheta = 2. * rndmPtr->flat() - 1.;
917 cos2Theta = cosTheta * cosTheta;
918 }
while ( 1. + cos2Theta + mGamRat * (1. - cos2Theta)
919 < 2. * rndmPtr->flat() );
920 double sinTheta = sqrt(1. - cosTheta*cosTheta);
921 double phi = 2. * M_PI * rndmPtr->flat();
922 double pX = pGamAbs * sinTheta * cos(phi);
923 double pY = pGamAbs * sinTheta * sin(phi);
924 double pZ = pGamAbs * cosTheta;
925 double eA = sqrt( mA*mA + pGamAbs*pGamAbs);
926 double eB = sqrt( mB*mB + pGamAbs*pGamAbs);
927 prodA.p( pX, pY, pZ, eA);
928 prodB.p( -pX, -pY, -pZ, eB);
931 prodA.bst( pGam, mGam);
932 prodB.bst( pGam, mGam);
933 prodA.rot( thetaGam, phiGam);
934 prodB.rot( thetaGam, phiGam);
935 prodA.bst( pDec, decayer.m() );
936 prodB.bst( pDec, decayer.m() );
948 bool ParticleDecays::pickHadrons() {
955 bool closedGLoop =
false;
956 for (
int i = 1; i <= mult; ++i) {
957 int idAbs = abs(idProd[i]);
958 if ( idAbs < 9 || (idAbs > 1000 && idAbs < 10000 && (idAbs/10)%10 == 0)
959 || idAbs == 81 || idAbs == 82 || idAbs == 83) {
961 idPartons.push_back(idProd[i]);
962 if (idAbs == 83) closedGLoop =
true;
966 idProd[nKnown] = idProd[i];
967 mProd[nKnown] = mProd[i];
973 for (
int i = 0; i < nPartons; ++i) {
974 int idPart = idPartons[i];
977 int idAbs = abs(idDec);
978 if ( (idAbs/1000)%10 == 0 ) {
979 idNew = -(idAbs/10)%10;
980 if ((idAbs/100)%2 == 1) idNew = -idNew;
981 }
else if ( (idAbs/100)%10 >= (idAbs/10)%10 )
982 idNew = 100 * ((idAbs/10)%100) + 3;
983 else idNew = 1000 * ((idAbs/10)%10) + 100 * ((idAbs/100)%10) + 1;
984 if (idDec < 0) idNew = -idNew;
987 }
else if (idPart == 82 || idPart == 83) {
990 int idDummy = -flavSelPtr->pickLightQ();
991 FlavContainer flavDummy(idDummy, idPart - 82);
992 do idNew = flavSelPtr->pick(flavDummy).id;
994 mFlav = particleDataPtr->constituentMass(idNew);
995 }
while (2. * mFlav + stopMass > mProd[0]);
996 }
else if (idPart == -82 || idPart == -83) {
997 idNew = -idPartons[i-1];
999 idPartons[i] = idNew;
1003 int nMin = max( 2, nKnown + nPartons / 2);
1004 if (meMode == 23) nMin = 3;
1005 if (meMode > 41 && meMode <= 50) nMin = meMode - 40;
1006 if (meMode > 51 && meMode <= 60) nMin = meMode - 50;
1008 if (meMode == 0) nFix = nMin;
1009 if (meMode == 11) nFix = 3;
1010 if (meMode == 12) nFix = 4;
1011 if (meMode > 61 && meMode <= 70) nFix = meMode - 60;
1012 if (meMode > 71 && meMode <= 80) nFix = meMode - 70;
1013 if (nFix > 0 && nKnown + nPartons/2 > nFix)
return false;
1016 int nFilled, nTotal, nNew, nSpec, nLeft;
1019 bool diquarkClash =
false;
1020 bool usedChannel =
false;
1025 if (nTry > NTRYPICK)
return false;
1028 nFilled = nKnown + 1;
1029 idProd.resize(nFilled);
1030 mProd.resize(nFilled);
1035 for (
int i = 1; i < nFilled; ++i) mDiff -= mProd[i];
1036 diquarkClash =
false;
1037 usedChannel =
false;
1040 if ( (meMode == 22 || meMode == 23) && nLeft > 1) {
1041 FlavContainer flav1( idPartons[nPartons - 2] );
1042 FlavContainer flav2( idPartons[nPartons - 1] );
1044 do idHad = flavSelPtr->combine( flav1, flav2);
1046 double mHad = particleDataPtr->mSel(idHad);
1048 idProd.push_back( idHad);
1049 mProd.push_back( mHad);
1060 double geom = rndmPtr->flat();
1065 }
while (geom < 1. && nTotal < 10);
1068 }
else if (nFix == 0) {
1069 double multIncreaseNow = (meMode == 23)
1070 ? multIncreaseWeak : multIncrease;
1071 double mDiffPS = mDiff;
1072 for (
int i = 0; i < nLeft; ++i)
1073 mDiffPS -= particleDataPtr->constituentMass( idPartons[i] );
1074 double average = 0.5 * (nKnown + nSpec) + 0.25 * nPartons
1075 + multIncreaseNow * log( max( 1.1, mDiffPS / multRefMass ) );
1076 if (closedGLoop) average += multGoffset;
1081 for (
int nNow = nMin + 1; nNow <= 10; ++nNow) {
1082 value *= average / nNow;
1087 sum *= rndmPtr->flat();
1091 value *= average / nTotal;
1093 }
while (sum > 0. && nTotal < 10);
1099 nNew = nTotal - nKnown - nSpec;
1103 for (
int i = 0; i < nLeft; ++i) {
1104 flavEnds.push_back( FlavContainer(idPartons[i]) );
1105 if (abs(idPartons[i]) > 100) flavSelPtr->assignPopQ( flavEnds[i] );
1109 if (nNew > nLeft/2) {
1110 FlavContainer flavNew;
1112 for (
int i = 0; i < nNew - nLeft/2; ++i) {
1114 int iEnd = int( (nLeft - 1.) * rndmPtr->flat() );
1117 flavNew = flavSelPtr->pick( flavEnds[iEnd] );
1118 idHad = flavSelPtr->combine( flavEnds[iEnd], flavNew);
1119 }
while (idHad == 0);
1121 idProd.push_back( idHad);
1122 flavEnds[iEnd].anti(flavNew);
1129 if ( abs(flavEnds[0].
id) > 8 && abs(flavEnds[1].
id) > 8)
1130 diquarkClash =
true;
1132 do idHad = flavSelPtr->combine( flavEnds[0], flavEnds[1]);
1134 idProd.push_back( idHad);
1143 if ( rndmPtr->flat() < colRearrange) iEnd2 = 3;
1145 ( (flavEnds[iEnd1].id > 0 && flavEnds[iEnd1].id < 9)
1146 || flavEnds[iEnd1].
id < -10 ) ? 1 : -1;
1147 if ( (flavEnds[iEnd2].
id < 0 && flavEnds[iEnd2].
id > -9)
1148 || flavEnds[iEnd2].id > 10 ) relColSign *= -1;
1149 if (relColSign == 1) iEnd2 = 2;
1150 if (iEnd2 == 2) iEnd3 = 1;
1151 if (iEnd2 == 3) iEnd4 = 1;
1155 if ( abs(flavEnds[iEnd1].
id) > 8 && abs(flavEnds[iEnd2].
id) > 8)
1156 diquarkClash =
true;
1158 do idHad = flavSelPtr->combine( flavEnds[iEnd1], flavEnds[iEnd2]);
1160 idProd.push_back( idHad);
1162 if ( abs(flavEnds[iEnd3].
id) > 8 && abs(flavEnds[iEnd4].
id) > 8)
1163 diquarkClash =
true;
1165 do idHad = flavSelPtr->combine( flavEnds[iEnd3], flavEnds[iEnd4]);
1167 idProd.push_back( idHad);
1172 for (
int i = nFilled; i < int(idProd.size()) ; ++i) {
1173 double mHad = particleDataPtr->mSel(idProd[i]);
1174 mProd.push_back( mHad);
1180 if ( ( (meMode > 51 && meMode <= 60) || (meMode > 71 && meMode <= 80) )
1181 && mDiff > mSafety && !diquarkClash ) {
1182 int idMatch[10], idPNow;
1183 usedChannel =
false;
1184 bool matched =
false;
1186 for (
int i = 0; i < decDataPtr->sizeChannels(); ++i) {
1187 DecayChannel& channel = decDataPtr->channel(i);
1188 if (channel.multiplicity() != nTotal)
continue;
1189 for (
int k = 0; k < nTotal; ++k) idMatch[k] = channel.product(k);
1192 for (
int j = 0; j < nTotal; ++j) {
1194 idPNow = idProd[j + 1];
1195 if (idPNow == -311 || idPNow == 130 || idPNow == 310) idPNow = 311;
1196 for (
int k = 0; k < nTotal - j; ++k)
1197 if (idMatch[k] == idPNow || (idMatch[k] == -311 && idPNow == 311)) {
1199 idMatch[k] = idMatch[nTotal - 1 - j];
1203 if (!matched)
break;
1206 if (matched) {usedChannel =
true;
break;}
1211 }
while (mDiff < mSafety || diquarkClash || usedChannel);
1214 mult = idProd.size() - 1;
1217 if (meMode == 11 || meMode == 12) {
1220 for (
int i = 1; i <= mult; ++i) {
1221 if (idProd[i] == 11 || idProd[i] == 13 || idProd[i] == 15) iL1 = i;
1222 if (idProd[i] == -11 || idProd[i] == -13 || idProd[i] == -15) iL2 = i;
1224 if (iL1 > 0 && iL2 > 0) {
1225 int idL1 = idProd[iL1];
1226 int idL2 = idProd[iL2];
1227 double mL1 = mProd[iL1];
1228 double mL2 = mProd[iL2];
1230 for (
int i = 1; i <= mult; ++i)
if (i != iL1 && i != iL2) {
1232 idProd[iMove] = idProd[i];
1233 mProd[iMove] = mProd[i];
1235 idProd[mult - 1] = idL1;
1236 idProd[mult] = idL2;
1237 mProd[mult - 1] = mL1;
1251 bool ParticleDecays::setColours(
Event& event) {
1254 if (meMode == 91 && idProd[1] > 0 && idProd[1] < 9) {
1255 int newCol =
event.nextColTag();
1258 }
else if (meMode == 91 && idProd[1] < 0 && idProd[1] > -9) {
1259 int newCol =
event.nextColTag();
1264 }
else if (meMode == 91 && idProd[1] == 21) {
1265 int newCol1 =
event.nextColTag();
1266 int newCol2 =
event.nextColTag();
1273 }
else if (meMode == 92 && idProd[1] == 21 && idProd[2] == 21
1274 && idProd[3] == 21) {
1275 int newCol1 =
event.nextColTag();
1276 int newCol2 =
event.nextColTag();
1277 int newCol3 =
event.nextColTag();
1286 }
else if (meMode == 92) {
1287 int iGlu1 = (idProd[1] == 21) ? 1 : 3;
1288 int iGlu2 = (idProd[2] == 21) ? 2 : 3;
1289 int newCol1 =
event.nextColTag();
1290 int newCol2 =
event.nextColTag();
1291 cols[iGlu1] = newCol1;
1292 acols[iGlu1] = newCol2;
1293 cols[iGlu2] = newCol2;
1294 acols[iGlu2] = newCol1;
1297 }
else if (meMode == 93 || meMode == 94) {
1298 int newCol =
event.nextColTag();
1299 if (idProd[1] > 0 && idProd[1] < 9) cols[1] = newCol;
1300 if (idProd[1] < 0 && idProd[1] > -9) acols[1] = newCol;
1301 if (idProd[2] > 0 && idProd[2] < 9) cols[2] = newCol;
1302 if (idProd[2] < 0 && idProd[2] > -9) acols[2] = newCol;
1303 if (idProd[3] > 0 && idProd[3] < 9) cols[3] = newCol;
1304 if (idProd[3] < 0 && idProd[3] > -9) acols[3] = newCol;
1307 }
else return false;