8 #include "Pythia8/TauDecays.h"
22 const int TauDecays::NTRYCHANNEL = 10;
25 const int TauDecays::NTRYDECAY = 10000;
29 const double TauDecays::WTCORRECTION[11] = { 1., 1., 1.,
30 2., 5., 15., 60., 250., 1250., 7000., 50000. };
39 void TauDecays::init(Info* infoPtrIn, Settings* settingsPtrIn,
40 ParticleData* particleDataPtrIn, Rndm* rndmPtrIn,
41 Couplings* couplingsPtrIn) {
45 settingsPtr = settingsPtrIn;
46 particleDataPtr = particleDataPtrIn;
48 couplingsPtr = couplingsPtrIn;
51 hmeTwoFermions2W2TwoFermions
52 .initPointers(particleDataPtr, couplingsPtr, settingsPtr);
53 hmeTwoFermions2GammaZ2TwoFermions
54 .initPointers(particleDataPtr, couplingsPtr, settingsPtr);
56 .initPointers(particleDataPtr, couplingsPtr, settingsPtr);
58 .initPointers(particleDataPtr, couplingsPtr, settingsPtr);
60 .initPointers(particleDataPtr, couplingsPtr);
62 .initPointers(particleDataPtr, couplingsPtr, settingsPtr);
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 tauExt = settingsPtr->mode(
"TauDecays:externalMode");
79 tauMode = settingsPtr->mode(
"TauDecays:mode");
80 tauMother = settingsPtr->mode(
"TauDecays:tauMother");
81 tauPol = settingsPtr->parm(
"TauDecays:tauPolarization");
84 limitTau0 = settingsPtr->flag(
"ParticleDecays:limitTau0");
85 tau0Max = settingsPtr->parm(
"ParticleDecays:tau0Max");
86 limitTau = settingsPtr->flag(
"ParticleDecays:limitTau");
87 tauMax = settingsPtr->parm(
"ParticleDecays:tauMax");
88 limitRadius = settingsPtr->flag(
"ParticleDecays:limitRadius");
89 rMax = settingsPtr->parm(
"ParticleDecays:rMax");
90 limitCylinder = settingsPtr->flag(
"ParticleDecays:limitCylinder");
91 xyMax = settingsPtr->parm(
"ParticleDecays:xyMax");
92 zMax = settingsPtr->parm(
"ParticleDecays:zMax");
93 limitDecay = limitTau0 || limitTau || limitRadius || limitCylinder;
104 bool TauDecays::decay(
int idxOut1,
Event& event) {
107 out1 = HelicityParticle(event[idxOut1]);
108 int idxOut1Top = out1.iTopCopyId();
109 vector<int> sistersOut1 =
event[idxOut1Top].sisterList();
110 int idxOut2Top = idxOut1Top;
111 if (sistersOut1.size() == 1) idxOut2Top = sistersOut1[0];
114 int tau(-1), tnu(-1), lep(-1), lnu(-1);
115 for (
int i = 0; i < int(sistersOut1.size()); ++i) {
116 int sn = out1.id() == 15 ? -1 : 1;
117 int id =
event[sistersOut1[i]].id();
118 if (
id == sn * 15 && tau == -1) tau = sistersOut1[i];
119 else if (
id == sn * 16 && tnu == -1) tnu = sistersOut1[i];
120 else if ((
id == sn * 11 || (
id == sn * 13)) && lep == -1)
121 lep = sistersOut1[i];
122 else if ((
id == sn * 12 || (
id == sn * 14)) && lnu == -1)
123 lnu = sistersOut1[i];
125 if (tau > 0) idxOut2Top = tau;
126 else if (tnu > 0) idxOut2Top = tnu;
127 else if (lep > 0) idxOut2Top = lep;
128 else if (lnu > 0) idxOut2Top = lnu;
130 int idxOut2 =
event[idxOut2Top].iBotCopyId();
131 out2 = HelicityParticle(event[idxOut2]);
134 int idxMediator =
event[idxOut1Top].mother1();
135 mediator = HelicityParticle(event[idxMediator]);
136 mediator.direction = -1;
137 if (mediator.m() < out1.m() + out2.m()) {
138 Vec4 p = out1.p() + out2.p();
140 mediator.m(p.mCalc());
144 int idxMediatorTop = mediator.iTopCopyId();
145 int idxIn1 =
event[idxMediatorTop].mother1();
146 int idxIn2 =
event[idxMediatorTop].mother2();
147 in1 = HelicityParticle(event[idxIn1]);
149 in2 = HelicityParticle(event[idxIn2]);
154 particles.push_back(in1);
155 particles.push_back(in2);
156 particles.push_back(out1);
157 particles.push_back(out2);
161 if (idxOut1 != idxOut2 &&
162 (abs(out2.id()) == 11 || abs(out2.id()) == 13 || abs(out2.id()) == 15)) {
165 if (limitTau0 && out2.tau0() > tau0Max) correlated =
false;
166 else if (limitTau && out2.tau() > tauMax) correlated =
false;
167 else if (limitRadius && pow2(out2.xDec()) + pow2(out2.yDec())
168 + pow2(out2.zDec()) > pow2(rMax)) correlated =
false;
169 else if (limitCylinder && (pow2(out2.xDec()) + pow2(out2.yDec())
170 > pow2(xyMax) || abs(out2.zDec()) > zMax))
173 else if (!out2.canDecay()) correlated =
false;
174 else if (!out2.mayDecay()) correlated =
false;
180 if (tauMode == 4) known = internalMechanism(event);
181 else if (tauMode == 5) known = externalMechanism(event);
183 if ((tauMode == 2 && abs(mediator.id()) == tauMother) || tauMode == 3) {
186 double sign = out1.id() == -15 ? -1 : 1;
187 particles[2].rho[0][0] = (1 - sign * tauPol) / 2;
188 particles[2].rho[1][1] = (1 + sign * tauPol) / 2;
190 if (!externalMechanism(event)) known = internalMechanism(event);
197 particles[1] = mediator;
198 if (abs(mediator.id()) == 22)
199 hardME = hmeGamma2TwoFermions.initChannel(particles);
200 else if (abs(mediator.id()) == 23 || abs(mediator.id()) == 32)
201 hardME = hmeZ2TwoFermions.initChannel(particles);
202 else if (abs(mediator.id()) == 24 || abs(mediator.id()) == 34)
203 hardME = hmeW2TwoFermions.initChannel(particles);
204 else if (correlated) {
205 Vec4 p = out1.p() + out2.p();
206 particles[1] = HelicityParticle(22, -22, idxIn1, idxIn2, idxOut1,
207 idxOut2, 0, 0, p, p.mCalc(), 0, particleDataPtr);
208 hardME = hmeGamma2TwoFermions.initChannel(particles);
209 infoPtr->errorMsg(
"Warning in TauDecays::decay: unknown correlated "
210 "tau production, assuming from unpolarized photon");
212 infoPtr->errorMsg(
"Warning in TauDecays::decay: unknown uncorrelated "
213 "tau production, assuming unpolarized");
218 if (correlated && !out2.isFinal()) event[out2.index()].undoDecay();
221 HelicityParticle* tau;
223 if (correlated) idx = (rndmPtr->flat() < 0.5) ? 2 : 3;
224 tau = &particles[idx];
227 if (hardME) hardME->calculateRho(idx, particles);
228 vector<HelicityParticle> children = createChildren(*tau);
229 if (children.size() == 0)
return false;
232 bool accepted =
false;
235 isotropicDecay(children);
236 double decayWeight = decayME->decayWeight(children);
237 double decayWeightMax = decayME->decayWeightMax(children);
238 accepted = (rndmPtr->flat() < decayWeight / decayWeightMax);
239 if (decayWeight > decayWeightMax)
240 infoPtr->errorMsg(
"Warning in TauDecays::decay: maximum "
241 "decay weight exceeded in tau decay");
242 if (tries > NTRYDECAY) {
243 infoPtr->errorMsg(
"Warning in TauDecays::decay: maximum "
244 "number of decay attempts exceeded");
249 writeDecay(event,children);
253 idx = (idx == 2) ? 3 : 2;
255 decayME->calculateD(children);
257 tau->D = children[0].D;
259 tau = &particles[idx];
261 hardME->calculateRho(idx, particles);
265 children = createChildren(*tau);
266 if (children.size() == 0)
return false;
270 isotropicDecay(children);
271 double decayWeight = decayME->decayWeight(children);
272 double decayWeightMax = decayME->decayWeightMax(children);
273 accepted = (rndmPtr->flat() < decayWeight / decayWeightMax);
274 if (decayWeight > decayWeightMax)
275 infoPtr->errorMsg(
"Warning in TauDecays::decay: maximum "
276 "decay weight exceeded in correlated tau decay");
277 if (tries > NTRYDECAY) {
278 infoPtr->errorMsg(
"Warning in TauDecays::decay: maximum "
279 "number of decay attempts exceeded");
284 writeDecay(event,children);
297 bool TauDecays::internalMechanism(
Event&) {
303 if (abs(mediator.id()) == 22 || abs(mediator.id()) == 23 ||
304 abs(mediator.id()) == 32) {
306 if (abs(in1.id()) <= 18 && abs(in2.id()) <= 18 && in1.daughter2() == 0 &&
307 in2.daughter2() == 0 && in1.daughter1() == in2.daughter1()) {
308 particles.push_back(mediator);
309 hardME = hmeTwoFermions2GammaZ2TwoFermions.initChannel(particles);
311 }
else known =
false;
314 }
else if (abs(mediator.id()) == 24 || abs(mediator.id()) == 34) {
316 if (abs(in1.id()) <= 18 && abs(in2.id()) <= 18 && in1.daughter2() == 0 &&
317 in2.daughter2() == 0 && in1.daughter1() == in2.daughter1()) {
318 particles.push_back(mediator);
319 hardME = hmeTwoFermions2W2TwoFermions.initChannel(particles);
321 }
else known =
false;
324 }
else if (abs(mediator.id()) == 25 || abs(mediator.id()) == 35 ||
325 abs(mediator.id()) == 36 || abs(mediator.id()) == 37) {
326 particles[1] = mediator;
327 hardME = hmeHiggs2TwoFermions.initChannel(particles);
330 }
else if ((abs(mediator.id()) == 411 || abs(mediator.id()) == 431
331 || abs(mediator.id()) == 511 || abs(mediator.id()) == 521
332 || abs(mediator.id()) == 531 || abs(mediator.id()) == 541
333 || (abs(mediator.id()) > 5100 && abs(mediator.id()) < 5600) )
334 && abs(out2.id()) == 16) {
335 int idBmother = (mediator.id() > 0) ? -5 : 5;
336 if (abs(mediator.id()) > 5100) idBmother = -idBmother;
337 particles[0] = HelicityParticle( idBmother, 0, 0, 0, 0, 0, 0, 0,
338 0., 0., 0., 0., 0., 0., particleDataPtr);
339 particles[1] = HelicityParticle( -idBmother, 0, 0, 0, 0, 0, 0, 0,
340 0., 0., 0., 0., 0., 0., particleDataPtr);
341 particles[0].index(-1);
342 particles[1].index(-1);
345 if (mediator.daughter1() + 2 == mediator.daughter2()) {
346 particles[0].p(mediator.p());
347 particles[1].direction = 1;
348 particles[1].id(-particles[1].
id());
349 particles[1].p(particles[0].p() - particles[2].p() - particles[3].p());
354 particles[0].p(mediator.p()/2);
355 particles[1].p(mediator.p()/2);
357 hardME = hmeTwoFermions2W2TwoFermions.initChannel(particles);
360 }
else known =
false;
370 bool TauDecays::externalMechanism(
Event &event) {
376 if (tauExt == 0) correlated =
false;
378 double spinup = particles[2].pol();
379 if (abs(spinup) > 1.001) spinup =
event[particles[2].iTopCopyId()].pol();
380 if (abs(spinup) > 1.001) known =
false;
382 particles[2].rho[0][0] = (1 - spinup) / 2;
383 particles[2].rho[1][1] = (1 + spinup) / 2;
387 }
else if (tauExt == 1) {
388 double spinup = mediator.pol();
389 if (abs(spinup) > 1.001) spinup =
event[mediator.iTopCopyId()].pol();
390 if (abs(spinup) > 1.001) spinup = 0;
391 if (mediator.rho.size() > 1) {
392 mediator.rho[0][0] = (1 - spinup) / mediator.spinStates();
393 mediator.rho[1][1] = (1 + spinup) / mediator.spinStates();
395 particles[1] = mediator;
396 if (abs(mediator.id()) == 22)
397 hardME = hmeGamma2TwoFermions.initChannel(particles);
398 else if (abs(mediator.id()) == 23 || abs(mediator.id()) == 32)
399 hardME = hmeZ2TwoFermions.initChannel(particles);
400 else if (abs(mediator.id()) == 24 || abs(mediator.id()) == 34)
401 hardME = hmeZ2TwoFermions.initChannel(particles);
402 else if (abs(mediator.id()) == 25 || abs(mediator.id()) == 35 ||
403 abs(mediator.id()) == 36 || abs(mediator.id()) == 37)
404 hardME = hmeHiggs2TwoFermions.initChannel(particles);
408 }
else known =
false;
419 vector<HelicityParticle> TauDecays::createChildren(HelicityParticle parent) {
423 vector<HelicityParticle> children;
426 parent.direction = -1;
429 ParticleDataEntry decayData = parent.particleDataEntry();
432 if (!decayData.preparePick(parent.id()))
return children;
435 bool decayed =
false;
437 while (!decayed && decayTries < NTRYCHANNEL) {
440 DecayChannel decayChannel = decayData.pickChannel();
441 meMode = decayChannel.meMode();
442 int decayMult = decayChannel.multiplicity();
445 bool allowed =
false;
446 int channelTries = 0;
447 while (!allowed && channelTries < NTRYCHANNEL) {
449 children.push_back(parent);
450 for (
int i = 0; i < decayMult; ++i) {
452 int childId = decayChannel.product(i);
454 if (parent.id() < 0 && particleDataPtr->hasAnti(childId))
457 double childMass = particleDataPtr->mSel(childId);
459 children.push_back( HelicityParticle(childId, 91, parent.index(), 0, 0,
460 0, 0, 0, 0., 0., 0., 0.,childMass, 0., particleDataPtr) );
465 double massDiff = parent.m();
466 for (
int i = 0; i < decayMult; ++i) massDiff -= children[i].m();
481 if (parent.idAbs() == 13 && children.size() == 4 && meMode == 22)
482 swap(children[1], children[3]);
486 if (children.size() == 3) {
488 decayME = hmeTau2Meson.initChannel(children);
489 else decayME = hmeTau2PhaseSpace.initChannel(children);
493 else if (children.size() == 4) {
495 if (meMode == 1531 || (parent.idAbs() == 13 && meMode == 22))
496 decayME = hmeTau2TwoLeptons.initChannel(children);
498 else if (meMode == 1532)
499 decayME = hmeTau2TwoMesonsViaVector.initChannel(children);
501 else if (meMode == 1533)
502 decayME = hmeTau2TwoMesonsViaVectorScalar.initChannel(children);
504 else decayME = hmeTau2PhaseSpace.initChannel(children);
508 else if (children.size() == 5) {
511 decayME = hmeTau2ThreePions.initChannel(children);
513 else if (meMode == 1542)
514 decayME = hmeTau2ThreeMesonsWithKaons.initChannel(children);
516 else if (meMode == 1543)
517 decayME = hmeTau2ThreeMesonsGeneric.initChannel(children);
519 else if (meMode == 1544)
520 decayME = hmeTau2TwoPionsGamma.initChannel(children);
522 else decayME = hmeTau2PhaseSpace.initChannel(children);
526 else if (children.size() == 6) {
529 decayME = hmeTau2FourPions.initChannel(children);
531 else decayME = hmeTau2PhaseSpace.initChannel(children);
535 else if (children.size() == 7) {
538 decayME = hmeTau2FivePions.initChannel(children);
540 else decayME = hmeTau2PhaseSpace.initChannel(children);
544 else decayME = hmeTau2PhaseSpace.initChannel(children);
558 void TauDecays::isotropicDecay(vector<HelicityParticle>& children) {
561 int decayMult = children.size() - 1;
562 double m0 = children[0].m();
563 double mSum = children[1].m();
564 for (
int i = 2; i <= decayMult; ++i) mSum += children[i].m();
565 double mDiff = m0 - mSum;
569 for (
int i = 0; i <= decayMult; ++i) mInv.push_back( children[i].m());
573 double wtPSmax = 1. / WTCORRECTION[decayMult];
574 double mMax = mDiff + children[decayMult].m();
576 for (
int i = decayMult - 1; i > 0; --i) {
577 mMax += children[i].m();
578 mMin += children[i+1].m();
579 double mNow = children[i].m();
580 wtPSmax *= 0.5 * sqrtpos( (mMax - mMin - mNow) * (mMax + mMin + mNow)
581 * (mMax + mMin - mNow) * (mMax - mMin + mNow) ) / mMax;
585 vector<double> rndmOrd;
591 rndmOrd.push_back(1.);
592 for (
int i = 1; i < decayMult - 1; ++i) {
593 double random = rndmPtr->flat();
594 rndmOrd.push_back(random);
595 for (
int j = i - 1; j > 0; --j) {
596 if (random > rndmOrd[j]) swap( rndmOrd[j], rndmOrd[j+1] );
600 rndmOrd.push_back(0.);
603 for (
int i = decayMult - 1; i > 0; --i) {
604 mInv[i] = mInv[i+1] + children[i].m()
605 + (rndmOrd[i-1] - rndmOrd[i]) * mDiff;
606 wtPS *= 0.5 * sqrtpos( (mInv[i] - mInv[i+1] - children[i].m())
607 * (mInv[i] + mInv[i+1] + children[i].m())
608 * (mInv[i] + mInv[i+1] - children[i].m())
609 * (mInv[i] - mInv[i+1] + children[i].m()) ) / mInv[i];
613 }
while ( wtPS < rndmPtr->flat() * wtPSmax );
616 vector<Vec4> pInv(decayMult + 1);
617 for (
int i = 1; i < decayMult; ++i) {
618 double pAbs = 0.5 * sqrtpos( (mInv[i] - mInv[i+1] - children[i].m())
619 * (mInv[i] + mInv[i+1] + children[i].m())
620 * (mInv[i] + mInv[i+1] - children[i].m())
621 * (mInv[i] - mInv[i+1] + children[i].m()) ) / mInv[i];
624 double cosTheta = 2. * rndmPtr->flat() - 1.;
625 double sinTheta = sqrt(1. - cosTheta*cosTheta);
626 double phi = 2. * M_PI * rndmPtr->flat();
627 double pX = pAbs * sinTheta * cos(phi);
628 double pY = pAbs * sinTheta * sin(phi);
629 double pZ = pAbs * cosTheta;
632 double eHad = sqrt( children[i].m()*children[i].m() + pAbs*pAbs);
633 double eInv = sqrt( mInv[i+1]*mInv[i+1] + pAbs*pAbs);
634 children[i].p( pX, pY, pZ, eHad);
635 pInv[i+1].p( -pX, -pY, -pZ, eInv);
639 children[decayMult].p( pInv[decayMult] );
640 for (
int iFrame = decayMult - 1; iFrame > 1; --iFrame)
641 for (
int i = iFrame; i <= decayMult; ++i)
642 children[i].bst( pInv[iFrame], mInv[iFrame]);
645 pInv[1].p( children[0].p() );
646 for (
int i = 1; i <= decayMult; ++i) children[i].bst( pInv[1], mInv[1] );
658 void TauDecays::writeDecay(
Event& event, vector<HelicityParticle>& children) {
661 int decayMult = children.size() - 1;
662 Vec4 decayVertex = children[0].vDec();
663 for (
int i = 1; i <= decayMult; i++) {
665 children[i].tau(children[i].tau0() * rndmPtr->exp());
667 children[i].vProd(decayVertex);
669 children[i].index(event.append(children[i]));
673 event[children[0].index()].statusNeg();
674 event[children[0].index()].daughters(children[1].index(),
675 children[decayMult].index());