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 .initPointers(particleDataPtr, couplingsPtr);
52 hmeTwoFermions2Z2TwoFermions .initPointers(particleDataPtr, couplingsPtr);
53 hmeTwoFermions2Gamma2TwoFermions .initPointers(particleDataPtr,
55 hmeTwoFermions2GammaZ2TwoFermions.initPointers(particleDataPtr,
57 hmeHiggsEven2TwoFermions .initPointers(particleDataPtr, couplingsPtr);
58 hmeHiggsOdd2TwoFermions .initPointers(particleDataPtr, couplingsPtr);
59 hmeHiggsCharged2TwoFermions .initPointers(particleDataPtr, couplingsPtr);
60 hmeUnpolarized .initPointers(particleDataPtr, couplingsPtr);
63 hmeTau2Meson .initPointers(particleDataPtr, couplingsPtr);
64 hmeTau2TwoLeptons .initPointers(particleDataPtr, couplingsPtr);
65 hmeTau2TwoMesonsViaVector .initPointers(particleDataPtr, couplingsPtr);
66 hmeTau2TwoMesonsViaVectorScalar.initPointers(particleDataPtr, couplingsPtr);
67 hmeTau2ThreePions .initPointers(particleDataPtr, couplingsPtr);
68 hmeTau2FourPions .initPointers(particleDataPtr, couplingsPtr);
69 hmeTau2PhaseSpace .initPointers(particleDataPtr, couplingsPtr);
72 tauMode = settingsPtr->mode(
"ParticleDecays:sophisticatedTau");
75 tauMother = settingsPtr->mode(
"ParticleDecays:tauMother");
78 polarization = settingsPtr->parm(
"ParticleDecays:tauPolarization");
89 bool TauDecays::decay(
int idxOut1,
Event& event) {
92 out1 = HelicityParticle(event[idxOut1]);
96 int idxMediator = out1.mother1();
97 int idxFirstOut1 = idxOut1;
98 while(idxMediator > 0 && event[idxMediator].
id() == out1.id()) {
99 idxFirstOut1 = idxMediator;
100 idxMediator =
event[idxMediator].mother1();
102 mediator = HelicityParticle(event[idxMediator]);
103 mediator.idx = idxMediator;
104 mediator.direction = -1;
107 int idxIn1 = mediator.mother1();
108 int idxIn2 = mediator.mother2();
109 while(idxIn1 > 0 && event[idxIn1].
id() == mediator.id()) {
110 idxIn1 =
event[idxIn1].mother1();
111 idxIn2 =
event[idxIn2].mother2();
113 in1 = HelicityParticle(event[idxIn1]);
116 in2 = HelicityParticle(event[idxIn2]);
121 int idxOut2 = (mediator.daughter1() == idxFirstOut1)
122 ? mediator.daughter2() : mediator.daughter1();
123 while (idxOut2 > 0 && event[idxOut2].daughter1() != 0) {
124 idxOut2 =
event[idxOut2].daughter1();
126 out2 = HelicityParticle(event[idxOut2]);
131 particles.push_back(in1);
132 particles.push_back(in2);
133 particles.push_back(out1);
134 particles.push_back(out2);
138 if (abs(mediator.id()) == 24 &&
139 (abs(in1.id()) <= 18 || abs(in2.id()) <= 18)) {
141 if (abs(in1.id()) <= 18 && abs(in2.id()) <= 18)
142 hardME = hmeTwoFermions2W2TwoFermions.initChannel(particles);
145 bool fermion = (abs(in1.id()) <= 18) ? 0 : 1;
147 = (
event[particles[fermion].daughter1()].id() == mediator.id())
148 ? HelicityParticle(event[particles[fermion].daughter2()])
149 : HelicityParticle(event[particles[fermion].daughter1()]);
150 particles[!fermion].direction = 1;
151 if (abs(particles[!fermion].
id()) <= 18)
152 hardME = hmeTwoFermions2W2TwoFermions.initChannel(particles);
154 infoPtr->errorMsg(
"Warning in TauDecays::decay: unknown "
155 "tau production, assuming unpolarized and uncorrelated");
156 hardME = hmeUnpolarized.initChannel(particles);
162 }
else if (abs(mediator.id()) == 22 && abs(in1.id()) <= 18) {
163 particles.push_back(mediator);
164 hardME = hmeTwoFermions2Gamma2TwoFermions.initChannel(particles);
168 }
else if (abs(mediator.id()) == 23 && abs(in1.id()) <= 18) {
169 particles.push_back(mediator);
170 if (settingsPtr->mode(
"WeakZ0:gmZmode") == 0)
171 hardME = hmeTwoFermions2GammaZ2TwoFermions.initChannel(particles);
172 else if (settingsPtr->mode(
"WeakZ0:gmZmode") == 1)
173 hardME = hmeTwoFermions2Gamma2TwoFermions.initChannel(particles);
174 else if (settingsPtr->mode(
"WeakZ0:gmZmode") == 2)
175 hardME = hmeTwoFermions2Z2TwoFermions.initChannel(particles);
179 }
else if (abs(mediator.id()) == 25 || abs(mediator.id()) == 35) {
180 hardME = hmeHiggsEven2TwoFermions.initChannel(particles);
184 }
else if (abs(mediator.id()) == 36) {
185 hardME = hmeHiggsOdd2TwoFermions.initChannel(particles);
189 }
else if (abs(mediator.id()) == 37) {
190 hardME = hmeHiggsCharged2TwoFermions.initChannel(particles);
195 }
else if ((abs(mediator.id()) == 411 || abs(mediator.id()) == 431
196 || abs(mediator.id()) == 511 || abs(mediator.id()) == 521
197 || abs(mediator.id()) == 531 || abs(mediator.id()) == 541)
198 && abs(out2.id()) == 16) {
199 particles[0] = HelicityParticle( (mediator.id() > 0) ? -5 : 5,
200 0, 0, 0, 0, 0, 0, 0, 0., 0., 0., 0., 0., 0., particleDataPtr);
201 particles[1] = HelicityParticle( (mediator.id() > 0) ? 5 : -5,
202 0, 0, 0, 0, 0, 0, 0, 0., 0., 0., 0., 0., 0., particleDataPtr);
203 particles[0].idx = 0;
204 particles[1].idx = 1;
207 if (mediator.daughter1() + 2 == mediator.daughter2()) {
208 particles[0].p(mediator.p());
209 particles[1].direction = 1;
210 particles[1].id(-particles[1].
id());
211 particles[1].p(particles[0].p() - particles[2].p() - particles[3].p());
216 particles[0].p(mediator.p()/2);
217 particles[1].p(mediator.p()/2);
219 hardME = hmeTwoFermions2W2TwoFermions.initChannel(particles);
223 }
else if (abs(out1.id()) == 15 && abs(out2.id()) == 15) {
224 particles.push_back(mediator);
225 particles[0] = HelicityParticle(-1, 0, 0, 0, 0, 0, 0, 0,
226 mediator.p()/2, 0., 0., particleDataPtr);
227 particles[1] = HelicityParticle(1, 0, 0, 0, 0, 0, 0, 0,
228 mediator.p()/2, 0., 0., particleDataPtr);
229 particles[0].direction = -1;
230 particles[1].direction = -1;
231 particles[0].idx = 0;
232 particles[1].idx = 0;
233 hardME = hmeTwoFermions2Gamma2TwoFermions.initChannel(particles);
239 infoPtr->errorMsg(
"Warning in TauDecays::decay: unknown "
240 "tau production, assuming unpolarized and uncorrelated");
241 hardME = hmeUnpolarized.initChannel(particles);
246 HelicityParticle* tau;
248 if (correlated) idx = (rndmPtr->flat() < 0.5) ? 2 : 3;
249 else idx = (abs(particles[2].
id()) == 15) ? 2 : 3;
250 tau = &particles[idx];
253 if ( (tauMode == 2 && abs(mediator.id()) == tauMother) || tauMode == 3) {
254 tau->rho[0][0] = (tau->id() > 0)
255 ? (1 - polarization) / 2 : (1 + polarization) / 2;
256 tau->rho[1][1] = (tau->id() > 0)
257 ? (1 + polarization) / 2 : (1 - polarization) / 2;
260 hardME->calculateRho(idx, particles);
261 vector<HelicityParticle> children = createChildren(*tau);
262 if (children.size() == 0)
return false;
265 bool accepted =
false;
268 isotropicDecay(children);
269 double decayWeight = decayME->decayWeight(children);
270 double decayWeightMax = decayME->decayWeightMax(children);
271 accepted = (rndmPtr->flat() < decayWeight / decayWeightMax);
272 if (decayWeight > decayWeightMax)
273 infoPtr->errorMsg(
"Warning in TauDecays::decay: maximum "
274 "decay weight exceeded in tau decay");
275 if (tries > NTRYDECAY) {
276 infoPtr->errorMsg(
"Warning in TauDecays::decay: maximum "
277 "number of decay attempts exceeded");
282 writeDecay(event,children);
286 idx = (idx == 2) ? 3 : 2;
288 decayME->calculateD(children);
290 (*tau).D = children[0].D;
292 tau = &particles[idx];
294 hardME->calculateRho(idx, particles);
298 children = createChildren(*tau);
299 if (children.size() == 0)
return false;
303 isotropicDecay(children);
304 double decayWeight = decayME->decayWeight(children);
305 double decayWeightMax = decayME->decayWeightMax(children);
306 accepted = (rndmPtr->flat() < decayWeight / decayWeightMax);
307 if (decayWeight > decayWeightMax)
308 infoPtr->errorMsg(
"Warning in TauDecays::decay: maximum "
309 "decay weight exceeded in correlated tau decay");
310 if (tries > NTRYDECAY) {
311 infoPtr->errorMsg(
"Warning in TauDecays::decay: maximum "
312 "number of decay attempts exceeded");
317 writeDecay(event,children);
331 vector<HelicityParticle> TauDecays::createChildren(HelicityParticle parent) {
335 vector<HelicityParticle> children;
338 parent.direction = -1;
341 ParticleDataEntry decayData = parent.particleDataEntry();
344 if (!decayData.preparePick(parent.id()))
return children;
347 bool decayed =
false;
349 while (!decayed && decayTries < NTRYCHANNEL) {
352 DecayChannel decayChannel = decayData.pickChannel();
353 meMode = decayChannel.meMode();
354 int decayMult = decayChannel.multiplicity();
357 bool allowed =
false;
358 int channelTries = 0;
359 while (!allowed && channelTries < NTRYCHANNEL) {
361 children.push_back(parent);
362 for (
int i = 0; i < decayMult; ++i) {
364 int childId = decayChannel.product(i);
366 if (parent.id() < 0 && particleDataPtr->hasAnti(childId))
369 double childMass = particleDataPtr->mass(childId);
371 children.push_back( HelicityParticle(childId, 91, parent.idx, 0, 0,
372 0, 0, 0, 0., 0., 0., 0.,childMass, 0., particleDataPtr) );
377 double massDiff = parent.m();
378 for (
int i = 0; i < decayMult; ++i) massDiff -= children[i].m();
394 if (children.size() == 3) {
396 decayME = hmeTau2Meson.initChannel(children);
397 else decayME = hmeTau2PhaseSpace.initChannel(children);
401 else if (children.size() == 4) {
404 decayME = hmeTau2TwoLeptons.initChannel(children);
406 else if (meMode == 1532)
407 decayME = hmeTau2TwoMesonsViaVector.initChannel(children);
409 else if (meMode == 1533)
410 decayME = hmeTau2TwoMesonsViaVectorScalar.initChannel(children);
412 else decayME = hmeTau2PhaseSpace.initChannel(children);
416 else if (children.size() == 5) {
419 decayME = hmeTau2ThreePions.initChannel(children);
421 else decayME = hmeTau2PhaseSpace.initChannel(children);
425 else if (children.size() == 6) {
428 decayME = hmeTau2FourPions.initChannel(children);
430 else decayME = hmeTau2PhaseSpace.initChannel(children);
434 else decayME = hmeTau2PhaseSpace.initChannel(children);
448 void TauDecays::isotropicDecay(vector<HelicityParticle>& children) {
451 int decayMult = children.size() - 1;
452 double m0 = children[0].m();
453 double mSum = children[1].m();
454 for (
int i = 2; i <= decayMult; ++i) mSum += children[i].m();
455 double mDiff = m0 - mSum;
459 for (
int i = 0; i <= decayMult; ++i) mInv.push_back( children[i].m());
463 double wtPSmax = 1. / WTCORRECTION[decayMult];
464 double mMax = mDiff + children[decayMult].m();
466 for (
int i = decayMult - 1; i > 0; --i) {
467 mMax += children[i].m();
468 mMin += children[i+1].m();
469 double mNow = children[i].m();
470 wtPSmax *= 0.5 * sqrtpos( (mMax - mMin - mNow) * (mMax + mMin + mNow)
471 * (mMax + mMin - mNow) * (mMax - mMin + mNow) ) / mMax;
475 vector<double> rndmOrd;
481 rndmOrd.push_back(1.);
482 for (
int i = 1; i < decayMult - 1; ++i) {
483 double random = rndmPtr->flat();
484 rndmOrd.push_back(random);
485 for (
int j = i - 1; j > 0; --j) {
486 if (random > rndmOrd[j]) swap( rndmOrd[j], rndmOrd[j+1] );
490 rndmOrd.push_back(0.);
493 for (
int i = decayMult - 1; i > 0; --i) {
494 mInv[i] = mInv[i+1] + children[i].m()
495 + (rndmOrd[i-1] - rndmOrd[i]) * mDiff;
496 wtPS *= 0.5 * sqrtpos( (mInv[i] - mInv[i+1] - children[i].m())
497 * (mInv[i] + mInv[i+1] + children[i].m())
498 * (mInv[i] + mInv[i+1] - children[i].m())
499 * (mInv[i] - mInv[i+1] + children[i].m()) ) / mInv[i];
503 }
while ( wtPS < rndmPtr->flat() * wtPSmax );
506 vector<Vec4> pInv(decayMult + 1);
507 for (
int i = 1; i < decayMult; ++i) {
508 double pAbs = 0.5 * sqrtpos( (mInv[i] - mInv[i+1] - children[i].m())
509 * (mInv[i] + mInv[i+1] + children[i].m())
510 * (mInv[i] + mInv[i+1] - children[i].m())
511 * (mInv[i] - mInv[i+1] + children[i].m()) ) / mInv[i];
514 double cosTheta = 2. * rndmPtr->flat() - 1.;
515 double sinTheta = sqrt(1. - cosTheta*cosTheta);
516 double phi = 2. * M_PI * rndmPtr->flat();
517 double pX = pAbs * sinTheta * cos(phi);
518 double pY = pAbs * sinTheta * sin(phi);
519 double pZ = pAbs * cosTheta;
522 double eHad = sqrt( children[i].m()*children[i].m() + pAbs*pAbs);
523 double eInv = sqrt( mInv[i+1]*mInv[i+1] + pAbs*pAbs);
524 children[i].p( pX, pY, pZ, eHad);
525 pInv[i+1].p( -pX, -pY, -pZ, eInv);
529 children[decayMult].p( pInv[decayMult] );
530 for (
int iFrame = decayMult - 1; iFrame > 1; --iFrame)
531 for (
int i = iFrame; i <= decayMult; ++i)
532 children[i].bst( pInv[iFrame], mInv[iFrame]);
535 pInv[1].p( children[0].p() );
536 for (
int i = 1; i <= decayMult; ++i) children[i].bst( pInv[1], mInv[1] );
548 void TauDecays::writeDecay(
Event& event, vector<HelicityParticle>& children) {
551 int decayMult = children.size() - 1;
552 Vec4 decayVertex = children[0].vDec();
553 for (
int i = 1; i <= decayMult; i++) {
555 children[i].tau(children[i].tau0() * rndmPtr->exp());
557 children[i].vProd(decayVertex);
559 children[i].idx =
event.append(children[i]);
563 event[children[0].idx].statusNeg();
564 event[children[0].idx].daughters(children[1].idx, children[decayMult].idx);