8 #include "Pythia8/TauDecays.h"
22 const int TauDecays::NTRYCHANNEL = 10;
25 const int TauDecays::NTRYDECAY = 10000;
30 const double TauDecays::WTCORRECTION[11] = { 1., 1., 1.,
31 2., 5., 15., 60., 250., 1250., 7000., 50000. };
40 void TauDecays::init(Info* infoPtrIn, Settings* settingsPtrIn,
41 ParticleData* particleDataPtrIn, Rndm* rndmPtrIn,
42 Couplings* couplingsPtrIn) {
46 settingsPtr = settingsPtrIn;
47 particleDataPtr = particleDataPtrIn;
49 couplingsPtr = couplingsPtrIn;
52 hmeTwoFermions2W2TwoFermions .initPointers(particleDataPtr, couplingsPtr);
53 hmeTwoFermions2Z2TwoFermions .initPointers(particleDataPtr, couplingsPtr);
54 hmeTwoFermions2Gamma2TwoFermions .initPointers(particleDataPtr,
56 hmeTwoFermions2GammaZ2TwoFermions.initPointers(particleDataPtr,
58 hmeZ2TwoFermions .initPointers(particleDataPtr, couplingsPtr);
59 hmeHiggsEven2TwoFermions .initPointers(particleDataPtr, couplingsPtr);
60 hmeHiggsOdd2TwoFermions .initPointers(particleDataPtr, couplingsPtr);
61 hmeHiggsCharged2TwoFermions .initPointers(particleDataPtr, couplingsPtr);
62 hmeUnpolarized .initPointers(particleDataPtr, couplingsPtr);
65 hmeTau2Meson .initPointers(particleDataPtr, couplingsPtr);
66 hmeTau2TwoLeptons .initPointers(particleDataPtr, couplingsPtr);
67 hmeTau2TwoMesonsViaVector .initPointers(particleDataPtr, couplingsPtr);
68 hmeTau2TwoMesonsViaVectorScalar.initPointers(particleDataPtr, couplingsPtr);
69 hmeTau2ThreePions .initPointers(particleDataPtr, couplingsPtr);
70 hmeTau2ThreeMesonsWithKaons .initPointers(particleDataPtr, couplingsPtr);
71 hmeTau2ThreeMesonsGeneric .initPointers(particleDataPtr, couplingsPtr);
72 hmeTau2TwoPionsGamma .initPointers(particleDataPtr, couplingsPtr);
73 hmeTau2FourPions .initPointers(particleDataPtr, couplingsPtr);
74 hmeTau2FivePions .initPointers(particleDataPtr, couplingsPtr);
75 hmeTau2PhaseSpace .initPointers(particleDataPtr, couplingsPtr);
78 tauModeSave = settingsPtr->mode(
"ParticleDecays:sophisticatedTau");
81 tauMotherSave = settingsPtr->mode(
"ParticleDecays:tauMother");
84 polSave = settingsPtr->parm(
"ParticleDecays:tauPolarization");
87 limitTau0 = settingsPtr->flag(
"ParticleDecays:limitTau0");
88 tau0Max = settingsPtr->parm(
"ParticleDecays:tau0Max");
89 limitTau = settingsPtr->flag(
"ParticleDecays:limitTau");
90 tauMax = settingsPtr->parm(
"ParticleDecays:tauMax");
91 limitRadius = settingsPtr->flag(
"ParticleDecays:limitRadius");
92 rMax = settingsPtr->parm(
"ParticleDecays:rMax");
93 limitCylinder = settingsPtr->flag(
"ParticleDecays:limitCylinder");
94 xyMax = settingsPtr->parm(
"ParticleDecays:xyMax");
95 zMax = settingsPtr->parm(
"ParticleDecays:zMax");
96 limitDecay = limitTau0 || limitTau || limitRadius || limitCylinder;
107 bool TauDecays::decay(
int idxOut1,
Event& event) {
110 tauMode = tauModeSave;
111 tauMother = tauMotherSave;
112 polarization = polSave;
115 out1 = HelicityParticle(event[idxOut1]);
120 bool hasHelicity =
false;
121 double helicityNow = 0.;
122 if (tauMode >= 1 && abs(out1.pol()) <= 1.001) {
124 helicityNow = out1.pol();
129 int idxMediator = out1.mother1();
130 int idxFirstOut1 = idxOut1;
131 while(idxMediator > 0 && event[idxMediator].
id() == out1.id()) {
132 idxFirstOut1 = idxMediator;
133 idxMediator =
event[idxMediator].mother1();
135 Particle medTmp =
event[idxMediator];
138 int idxIn1 = medTmp.mother1();
139 int idxIn2 = medTmp.mother2();
140 while(idxIn1 > 0 && event[idxIn1].
id() == medTmp.id()) {
141 idxIn1 =
event[idxIn1].mother1();
142 idxIn2 =
event[idxIn2].mother2();
144 in1 = HelicityParticle(event[idxIn1]);
147 in2 = HelicityParticle(event[idxIn2]);
152 int idxOut2 = (medTmp.daughter1() == idxFirstOut1)
153 ? medTmp.daughter2() : medTmp.daughter1();
154 while (idxOut2 > 0 && event[idxOut2].daughter1() != 0
155 && event[event[idxOut2].daughter1()].
id() == event[idxOut2].
id()) {
156 idxOut2 =
event[idxOut2].daughter1();
158 out2 = HelicityParticle(event[idxOut2]);
163 if (medTmp.id() == 22 && out2.idAbs() == 15
164 && medTmp.m() < out1.m() + out2.m()) {
165 Vec4 pTmp = out1.p() + out2.p();
167 medTmp.m( pTmp.mCalc() );
169 mediator = HelicityParticle(medTmp);
170 mediator.idx = idxMediator;
171 mediator.direction = -1;
175 particles.push_back(in1);
176 particles.push_back(in2);
177 particles.push_back(out1);
178 particles.push_back(out2);
186 }
else if (abs(mediator.id()) == 24) {
188 if (abs(in1.id()) <= 18 && abs(in2.id()) <= 18)
189 hardME = hmeTwoFermions2W2TwoFermions.initChannel(particles);
191 else if (abs(in1.id()) <= 18 || abs(in2.id()) <= 18) {
192 bool fermion = (abs(in1.id()) <= 18) ? 0 : 1;
194 = (
event[particles[fermion].daughter1()].id() == mediator.id())
195 ? HelicityParticle(event[particles[fermion].daughter2()])
196 : HelicityParticle(event[particles[fermion].daughter1()]);
197 particles[!fermion].direction = 1;
198 if (abs(particles[!fermion].
id()) <= 18)
199 hardME = hmeTwoFermions2W2TwoFermions.initChannel(particles);
201 infoPtr->errorMsg(
"Warning in TauDecays::decay: unknown "
202 "tau production, assuming unpolarized and uncorrelated");
203 hardME = hmeUnpolarized.initChannel(particles);
206 }
else if (tauMode == 1) {
213 }
else if (abs(mediator.id()) == 22 && abs(in1.id()) <= 18) {
214 particles.push_back(mediator);
215 hardME = hmeTwoFermions2Gamma2TwoFermions.initChannel(particles);
219 }
else if (abs(mediator.id()) == 23 && abs(in1.id()) <= 18) {
220 particles.push_back(mediator);
221 if (settingsPtr->mode(
"WeakZ0:gmZmode") == 0)
222 hardME = hmeTwoFermions2GammaZ2TwoFermions.initChannel(particles);
223 else if (settingsPtr->mode(
"WeakZ0:gmZmode") == 1)
224 hardME = hmeTwoFermions2Gamma2TwoFermions.initChannel(particles);
225 else if (settingsPtr->mode(
"WeakZ0:gmZmode") == 2)
226 hardME = hmeTwoFermions2Z2TwoFermions.initChannel(particles);
230 }
else if (abs(mediator.id()) == 23) {
231 particles[1] = mediator;
232 hardME = hmeZ2TwoFermions.initChannel(particles);
236 }
else if (abs(mediator.id()) == 25 || abs(mediator.id()) == 35) {
237 hardME = hmeHiggsEven2TwoFermions.initChannel(particles);
241 }
else if (abs(mediator.id()) == 36) {
242 hardME = hmeHiggsOdd2TwoFermions.initChannel(particles);
246 }
else if (abs(mediator.id()) == 37) {
247 hardME = hmeHiggsCharged2TwoFermions.initChannel(particles);
251 }
else if ((abs(mediator.id()) == 411 || abs(mediator.id()) == 431
252 || abs(mediator.id()) == 511 || abs(mediator.id()) == 521
253 || abs(mediator.id()) == 531 || abs(mediator.id()) == 541
254 || (abs(mediator.id()) > 5100 && abs(mediator.id()) < 5600) )
255 && abs(out2.id()) == 16) {
256 int idBmother = (mediator.id() > 0) ? -5 : 5;
257 if (abs(mediator.id()) > 5100) idBmother = -idBmother;
258 particles[0] = HelicityParticle( idBmother, 0, 0, 0, 0, 0, 0, 0,
259 0., 0., 0., 0., 0., 0., particleDataPtr);
260 particles[1] = HelicityParticle( -idBmother, 0, 0, 0, 0, 0, 0, 0,
261 0., 0., 0., 0., 0., 0., particleDataPtr);
262 particles[0].idx = 0;
263 particles[1].idx = 1;
266 if (mediator.daughter1() + 2 == mediator.daughter2()) {
267 particles[0].p(mediator.p());
268 particles[1].direction = 1;
269 particles[1].id(-particles[1].
id());
270 particles[1].p(particles[0].p() - particles[2].p() - particles[3].p());
275 particles[0].p(mediator.p()/2);
276 particles[1].p(mediator.p()/2);
278 hardME = hmeTwoFermions2W2TwoFermions.initChannel(particles);
282 }
else if (abs(out1.id()) == 15 && abs(out2.id()) == 15) {
283 particles.push_back(mediator);
284 particles[0] = HelicityParticle(-1, 0, 0, 0, 0, 0, 0, 0,
285 mediator.p()/2, 0., 0., particleDataPtr);
286 particles[1] = HelicityParticle(1, 0, 0, 0, 0, 0, 0, 0,
287 mediator.p()/2, 0., 0., particleDataPtr);
288 particles[0].direction = -1;
289 particles[1].direction = -1;
290 particles[0].idx = 0;
291 particles[1].idx = 0;
292 hardME = hmeTwoFermions2Gamma2TwoFermions.initChannel(particles);
298 infoPtr->errorMsg(
"Warning in TauDecays::decay: unknown "
299 "tau production, assuming unpolarized and uncorrelated");
300 hardME = hmeUnpolarized.initChannel(particles);
307 if (limitTau0 && out2.tau0() > tau0Max) correlated =
false;
308 else if (limitTau && out2.tau() > tauMax) correlated =
false;
309 else if (limitRadius && pow2(out2.xDec()) + pow2(out2.yDec())
310 + pow2(out2.zDec()) > pow2(rMax)) correlated =
false;
311 else if (limitCylinder && (pow2(out2.xDec()) + pow2(out2.yDec())
312 > pow2(xyMax) || abs(out2.zDec()) > zMax)) correlated =
false;
314 else if (!out2.canDecay()) correlated =
false;
315 else if (!out2.mayDecay()) correlated =
false;
317 else if (out2.idAbs() < 11 || out2.idAbs() > 16) {
318 infoPtr->errorMsg(
"Warning in TauDecays::decay: incompatible "
319 "correlated partner in tau decay");
323 else if (!out2.isFinal()) event.undoDecay(out2.idx);
327 HelicityParticle* tau;
329 if (correlated) idx = (rndmPtr->flat() < 0.5) ? 2 : 3;
330 else idx = (abs(particles[2].
id()) == 15) ? 2 : 3;
331 tau = &particles[idx];
334 if ( (tauMode == 2 && abs(mediator.id()) == tauMother) || tauMode == 3 ) {
335 tau->rho[0][0] = (tau->id() > 0)
336 ? (1 - polarization) / 2 : (1 + polarization) / 2;
337 tau->rho[1][1] = (tau->id() > 0)
338 ? (1 + polarization) / 2 : (1 - polarization) / 2;
344 else if (hasHelicity) {
345 tau->rho[0][0] = (1. - helicityNow) / 2.;
346 tau->rho[1][1] = (1. + helicityNow) / 2.;
352 hardME->calculateRho(idx, particles);
353 vector<HelicityParticle> children = createChildren(*tau);
354 if (children.size() == 0)
return false;
357 bool accepted =
false;
360 isotropicDecay(children);
361 double decayWeight = decayME->decayWeight(children);
362 double decayWeightMax = decayME->decayWeightMax(children);
363 accepted = (rndmPtr->flat() < decayWeight / decayWeightMax);
364 if (decayWeight > decayWeightMax)
365 infoPtr->errorMsg(
"Warning in TauDecays::decay: maximum "
366 "decay weight exceeded in tau decay");
367 if (tries > NTRYDECAY) {
368 infoPtr->errorMsg(
"Warning in TauDecays::decay: maximum "
369 "number of decay attempts exceeded");
374 writeDecay(event,children);
378 idx = (idx == 2) ? 3 : 2;
380 decayME->calculateD(children);
382 (*tau).D = children[0].D;
384 tau = &particles[idx];
386 hardME->calculateRho(idx, particles);
390 children = createChildren(*tau);
391 if (children.size() == 0)
return false;
395 isotropicDecay(children);
396 double decayWeight = decayME->decayWeight(children);
397 double decayWeightMax = decayME->decayWeightMax(children);
398 accepted = (rndmPtr->flat() < decayWeight / decayWeightMax);
399 if (decayWeight > decayWeightMax)
400 infoPtr->errorMsg(
"Warning in TauDecays::decay: maximum "
401 "decay weight exceeded in correlated tau decay");
402 if (tries > NTRYDECAY) {
403 infoPtr->errorMsg(
"Warning in TauDecays::decay: maximum "
404 "number of decay attempts exceeded");
409 writeDecay(event,children);
423 vector<HelicityParticle> TauDecays::createChildren(HelicityParticle parent) {
427 vector<HelicityParticle> children;
430 parent.direction = -1;
433 ParticleDataEntry decayData = parent.particleDataEntry();
436 if (!decayData.preparePick(parent.id()))
return children;
439 bool decayed =
false;
441 while (!decayed && decayTries < NTRYCHANNEL) {
444 DecayChannel decayChannel = decayData.pickChannel();
445 meMode = decayChannel.meMode();
446 int decayMult = decayChannel.multiplicity();
449 bool allowed =
false;
450 int channelTries = 0;
451 while (!allowed && channelTries < NTRYCHANNEL) {
453 children.push_back(parent);
454 for (
int i = 0; i < decayMult; ++i) {
456 int childId = decayChannel.product(i);
458 if (parent.id() < 0 && particleDataPtr->hasAnti(childId))
461 double childMass = particleDataPtr->mSel(childId);
463 children.push_back( HelicityParticle(childId, 91, parent.idx, 0, 0,
464 0, 0, 0, 0., 0., 0., 0.,childMass, 0., particleDataPtr) );
469 double massDiff = parent.m();
470 for (
int i = 0; i < decayMult; ++i) massDiff -= children[i].m();
485 if (parent.idAbs() == 13 && children.size() == 4 && meMode == 22)
486 swap(children[1], children[3]);
490 if (children.size() == 3) {
492 decayME = hmeTau2Meson.initChannel(children);
493 else decayME = hmeTau2PhaseSpace.initChannel(children);
497 else if (children.size() == 4) {
499 if (meMode == 1531 || (parent.idAbs() == 13 && meMode == 22))
500 decayME = hmeTau2TwoLeptons.initChannel(children);
502 else if (meMode == 1532)
503 decayME = hmeTau2TwoMesonsViaVector.initChannel(children);
505 else if (meMode == 1533)
506 decayME = hmeTau2TwoMesonsViaVectorScalar.initChannel(children);
508 else decayME = hmeTau2PhaseSpace.initChannel(children);
512 else if (children.size() == 5) {
515 decayME = hmeTau2ThreePions.initChannel(children);
517 else if (meMode == 1542)
518 decayME = hmeTau2ThreeMesonsWithKaons.initChannel(children);
520 else if (meMode == 1543)
521 decayME = hmeTau2ThreeMesonsGeneric.initChannel(children);
523 else if (meMode == 1544)
524 decayME = hmeTau2TwoPionsGamma.initChannel(children);
526 else decayME = hmeTau2PhaseSpace.initChannel(children);
530 else if (children.size() == 6) {
533 decayME = hmeTau2FourPions.initChannel(children);
535 else decayME = hmeTau2PhaseSpace.initChannel(children);
539 else if (children.size() == 7) {
542 decayME = hmeTau2FivePions.initChannel(children);
544 else decayME = hmeTau2PhaseSpace.initChannel(children);
548 else decayME = hmeTau2PhaseSpace.initChannel(children);
562 void TauDecays::isotropicDecay(vector<HelicityParticle>& children) {
565 int decayMult = children.size() - 1;
566 double m0 = children[0].m();
567 double mSum = children[1].m();
568 for (
int i = 2; i <= decayMult; ++i) mSum += children[i].m();
569 double mDiff = m0 - mSum;
573 for (
int i = 0; i <= decayMult; ++i) mInv.push_back( children[i].m());
577 double wtPSmax = 1. / WTCORRECTION[decayMult];
578 double mMax = mDiff + children[decayMult].m();
580 for (
int i = decayMult - 1; i > 0; --i) {
581 mMax += children[i].m();
582 mMin += children[i+1].m();
583 double mNow = children[i].m();
584 wtPSmax *= 0.5 * sqrtpos( (mMax - mMin - mNow) * (mMax + mMin + mNow)
585 * (mMax + mMin - mNow) * (mMax - mMin + mNow) ) / mMax;
589 vector<double> rndmOrd;
595 rndmOrd.push_back(1.);
596 for (
int i = 1; i < decayMult - 1; ++i) {
597 double random = rndmPtr->flat();
598 rndmOrd.push_back(random);
599 for (
int j = i - 1; j > 0; --j) {
600 if (random > rndmOrd[j]) swap( rndmOrd[j], rndmOrd[j+1] );
604 rndmOrd.push_back(0.);
607 for (
int i = decayMult - 1; i > 0; --i) {
608 mInv[i] = mInv[i+1] + children[i].m()
609 + (rndmOrd[i-1] - rndmOrd[i]) * mDiff;
610 wtPS *= 0.5 * sqrtpos( (mInv[i] - mInv[i+1] - children[i].m())
611 * (mInv[i] + mInv[i+1] + children[i].m())
612 * (mInv[i] + mInv[i+1] - children[i].m())
613 * (mInv[i] - mInv[i+1] + children[i].m()) ) / mInv[i];
617 }
while ( wtPS < rndmPtr->flat() * wtPSmax );
620 vector<Vec4> pInv(decayMult + 1);
621 for (
int i = 1; i < decayMult; ++i) {
622 double pAbs = 0.5 * sqrtpos( (mInv[i] - mInv[i+1] - children[i].m())
623 * (mInv[i] + mInv[i+1] + children[i].m())
624 * (mInv[i] + mInv[i+1] - children[i].m())
625 * (mInv[i] - mInv[i+1] + children[i].m()) ) / mInv[i];
628 double cosTheta = 2. * rndmPtr->flat() - 1.;
629 double sinTheta = sqrt(1. - cosTheta*cosTheta);
630 double phi = 2. * M_PI * rndmPtr->flat();
631 double pX = pAbs * sinTheta * cos(phi);
632 double pY = pAbs * sinTheta * sin(phi);
633 double pZ = pAbs * cosTheta;
636 double eHad = sqrt( children[i].m()*children[i].m() + pAbs*pAbs);
637 double eInv = sqrt( mInv[i+1]*mInv[i+1] + pAbs*pAbs);
638 children[i].p( pX, pY, pZ, eHad);
639 pInv[i+1].p( -pX, -pY, -pZ, eInv);
643 children[decayMult].p( pInv[decayMult] );
644 for (
int iFrame = decayMult - 1; iFrame > 1; --iFrame)
645 for (
int i = iFrame; i <= decayMult; ++i)
646 children[i].bst( pInv[iFrame], mInv[iFrame]);
649 pInv[1].p( children[0].p() );
650 for (
int i = 1; i <= decayMult; ++i) children[i].bst( pInv[1], mInv[1] );
662 void TauDecays::writeDecay(
Event& event, vector<HelicityParticle>& children) {
665 int decayMult = children.size() - 1;
666 Vec4 decayVertex = children[0].vDec();
667 for (
int i = 1; i <= decayMult; i++) {
669 children[i].tau(children[i].tau0() * rndmPtr->exp());
671 children[i].vProd(decayVertex);
673 children[i].idx =
event.append(children[i]);
677 event[children[0].idx].statusNeg();
678 event[children[0].idx].daughters(children[1].idx, children[decayMult].idx);