StRoot  1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
TauDecays.cc
1 // TauDecays.cc is a part of the PYTHIA event generator.
2 // Copyright (C) 2014 Philip Ilten, Torbjorn Sjostrand.
3 // PYTHIA is licenced under the GNU GPL version 2, see COPYING for details.
4 // Please respect the MCnet Guidelines, see GUIDELINES for details.
5 
6 // Function definitions (not found in the header) for the TauDecays class.
7 
8 #include "Pythia8/TauDecays.h"
9 
10 namespace Pythia8 {
11 
12 //==========================================================================
13 
14 // The TauDecays class.
15 
16 //--------------------------------------------------------------------------
17 
18 // Constants: could be changed here if desired, but normally should not.
19 // These are of technical nature, as described for each.
20 
21 // Number of times to try a decay channel.
22 const int TauDecays::NTRYCHANNEL = 10;
23 
24 // Number of times to try a decay sampling.
25  const int TauDecays::NTRYDECAY = 10000;
26  //const int TauDecays::NTRYDECAY = 100000;
27 
28 // These numbers are hardwired empirical parameters,
29 // intended to speed up the M-generator.
30 const double TauDecays::WTCORRECTION[11] = { 1., 1., 1.,
31  2., 5., 15., 60., 250., 1250., 7000., 50000. };
32 
33 //--------------------------------------------------------------------------
34 
35 // Initialize the TauDecays class with the necessary pointers to info,
36 // particle data, random numbers, and Standard Model couplings.
37 // Additionally, the necessary matrix elements are initialized with the
38 // Standard Model couplings, and particle data pointers.
39 
40 void TauDecays::init(Info* infoPtrIn, Settings* settingsPtrIn,
41  ParticleData* particleDataPtrIn, Rndm* rndmPtrIn,
42  Couplings* couplingsPtrIn) {
43 
44  // Set the pointers.
45  infoPtr = infoPtrIn;
46  settingsPtr = settingsPtrIn;
47  particleDataPtr = particleDataPtrIn;
48  rndmPtr = rndmPtrIn;
49  couplingsPtr = couplingsPtrIn;
50 
51  // Initialize the hard matrix elements.
52  hmeTwoFermions2W2TwoFermions .initPointers(particleDataPtr, couplingsPtr);
53  hmeTwoFermions2Z2TwoFermions .initPointers(particleDataPtr, couplingsPtr);
54  hmeTwoFermions2Gamma2TwoFermions .initPointers(particleDataPtr,
55  couplingsPtr);
56  hmeTwoFermions2GammaZ2TwoFermions.initPointers(particleDataPtr,
57  couplingsPtr);
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);
63 
64  // Initialize the tau decay matrix elements.
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);
76 
77  // User selected tau decay mode.
78  tauModeSave = settingsPtr->mode("ParticleDecays:sophisticatedTau");
79 
80  // User selected tau decay mother.
81  tauMotherSave = settingsPtr->mode("ParticleDecays:tauMother");
82 
83  // User selected tau polarization.
84  polSave = settingsPtr->parm("ParticleDecays:tauPolarization");
85 
86  // Parameters to determine if correlated partner should decay.
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;
97 }
98 
99 //--------------------------------------------------------------------------
100 
101 // Main method of the TauDecays class. Pass the index of the tau requested
102 // to be decayed along with the event record in which the tau exists. The
103 // tau is then decayed with proper spin correlations as well any partner.
104 // The children of the decays are written to the event record, and if the
105 // decays were succesful, a return value of true is supplied.
106 
107 bool TauDecays::decay(int idxOut1, Event& event) {
108 
109  // User selected tau decay mode, mother, and polarization.
110  tauMode = tauModeSave;
111  tauMother = tauMotherSave;
112  polarization = polSave;
113 
114  // Set the first outgoing particle of the hard process.
115  out1 = HelicityParticle(event[idxOut1]);
116  out1.idx = idxOut1;
117 
118  // Begin PS April 2012.
119  // Check if this tau already has helicity information (eg from LHEF).
120  bool hasHelicity = false;
121  double helicityNow = 0.;
122  if (tauMode >= 1 && abs(out1.pol()) <= 1.001) {
123  hasHelicity = true;
124  helicityNow = out1.pol();
125  }
126  // End PS April 2012.
127 
128  // Find the mediator of the hard process. Create temporary copy.
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();
134  }
135  Particle medTmp = event[idxMediator];
136 
137  // Find and set up the incoming particles of the hard process.
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();
143  }
144  in1 = HelicityParticle(event[idxIn1]);
145  in1.idx = idxIn1;
146  in1.direction = -1;
147  in2 = HelicityParticle(event[idxIn2]);
148  in2.idx = idxIn2;
149  in2.direction = -1;
150 
151  // Find and set up the second outgoing particle of the hard process.
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();
157  }
158  out2 = HelicityParticle(event[idxOut2]);
159  out2.idx = idxOut2;
160 
161  // Set up the mediator. Special case for dipole shower,
162  // where a massless photon can branch to a tau pair.
163  if (medTmp.id() == 22 && out2.idAbs() == 15
164  && medTmp.m() < out1.m() + out2.m()) {
165  Vec4 pTmp = out1.p() + out2.p();
166  medTmp.p( pTmp);
167  medTmp.m( pTmp.mCalc() );
168  }
169  mediator = HelicityParticle(medTmp);
170  mediator.idx = idxMediator;
171  mediator.direction = -1;
172 
173  // Set the particles vector.
174  particles.clear();
175  particles.push_back(in1);
176  particles.push_back(in2);
177  particles.push_back(out1);
178  particles.push_back(out2);
179 
180  // Set the hard matrix element.
181  // Polarized tau (decayed one by one).
182  if (hasHelicity) {
183  correlated = false;
184 
185  // Produced from a W.
186  } else if (abs(mediator.id()) == 24) {
187  // Produced from quarks: s-channel.
188  if (abs(in1.id()) <= 18 && abs(in2.id()) <= 18)
189  hardME = hmeTwoFermions2W2TwoFermions.initChannel(particles);
190  // Produced from quarks: t-channel.
191  else if (abs(in1.id()) <= 18 || abs(in2.id()) <= 18) {
192  bool fermion = (abs(in1.id()) <= 18) ? 0 : 1;
193  particles[!fermion]
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);
200  else {
201  infoPtr->errorMsg("Warning in TauDecays::decay: unknown "
202  "tau production, assuming unpolarized and uncorrelated");
203  hardME = hmeUnpolarized.initChannel(particles);
204  }
205  // Unknown W production: assume negative helicity.
206  } else if (tauMode == 1) {
207  tauMode = 3;
208  polarization = -1;
209  }
210  correlated = false;
211 
212  // Produced from a photon.
213  } else if (abs(mediator.id()) == 22 && abs(in1.id()) <= 18) {
214  particles.push_back(mediator);
215  hardME = hmeTwoFermions2Gamma2TwoFermions.initChannel(particles);
216  correlated = true;
217 
218  // Produced from a photon/Z.
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);
227  correlated = true;
228 
229  // Unkown Z production: assume unpolarized Z.
230  } else if (abs(mediator.id()) == 23) {
231  particles[1] = mediator;
232  hardME = hmeZ2TwoFermions.initChannel(particles);
233  correlated = true;
234 
235  // Produced from a CP even Higgs.
236  } else if (abs(mediator.id()) == 25 || abs(mediator.id()) == 35) {
237  hardME = hmeHiggsEven2TwoFermions.initChannel(particles);
238  correlated = true;
239 
240  // Produced from a CP odd Higgs.
241  } else if (abs(mediator.id()) == 36) {
242  hardME = hmeHiggsOdd2TwoFermions.initChannel(particles);
243  correlated = true;
244 
245  // Produced from a charged Higgs.
246  } else if (abs(mediator.id()) == 37) {
247  hardME = hmeHiggsCharged2TwoFermions.initChannel(particles);
248  correlated = false;
249 
250  // Produced from a D or B hadron decay with a single tau.
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;
264 
265  // D or B meson decays into neutrino + tau + meson.
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());
271  }
272 
273  // D or B meson decays into neutrino + tau.
274  else {
275  particles[0].p(mediator.p()/2);
276  particles[1].p(mediator.p()/2);
277  }
278  hardME = hmeTwoFermions2W2TwoFermions.initChannel(particles);
279  correlated = false;
280 
281  // Produced from a virtual photon with correlated taus.
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);
293  correlated = true;
294 
295  // Produced from an unknown process, assume unpolarized and uncorrelated.
296  } else {
297  if (tauMode <= 1)
298  infoPtr->errorMsg("Warning in TauDecays::decay: unknown "
299  "tau production, assuming unpolarized and uncorrelated");
300  hardME = hmeUnpolarized.initChannel(particles);
301  correlated = false;
302  }
303 
304  // Check if correlated partner should decay.
305  if (correlated) {
306  // Check vertex is within limits.
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;
313  // Check partner can decay.
314  else if (!out2.canDecay()) correlated = false;
315  else if (!out2.mayDecay()) correlated = false;
316  // Check partner is compatible with hard matrix element (only leptons).
317  else if (out2.idAbs() < 11 || out2.idAbs() > 16) {
318  infoPtr->errorMsg("Warning in TauDecays::decay: incompatible "
319  "correlated partner in tau decay");
320  correlated = false;
321  }
322  // Undecay correlated partner if already decayed.
323  else if (!out2.isFinal()) event.undoDecay(out2.idx);
324  }
325 
326  // Pick the first tau to decay.
327  HelicityParticle* tau;
328  int idx;
329  if (correlated) idx = (rndmPtr->flat() < 0.5) ? 2 : 3;
330  else idx = (abs(particles[2].id()) == 15) ? 2 : 3;
331  tau = &particles[idx];
332 
333  // Calculate the density matrix and decay the tau.
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;
339  correlated = false;
340  }
341 
342  // Begin PS April 2012.
343  // Else use tau helicity provided by event record (LHEF).
344  else if (hasHelicity) {
345  tau->rho[0][0] = (1. - helicityNow) / 2.;
346  tau->rho[1][1] = (1. + helicityNow) / 2.;
347  }
348  // End PS April 2012.
349 
350  // Else compute density matrix according to matrix element.
351  else
352  hardME->calculateRho(idx, particles);
353  vector<HelicityParticle> children = createChildren(*tau);
354  if (children.size() == 0) return false;
355 
356  // Decay the first tau.
357  bool accepted = false;
358  int tries = 0;
359  while (!accepted) {
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");
370  break;
371  }
372  ++tries;
373  }
374  writeDecay(event,children);
375 
376  // If a correlated second tau exists, decay that tau as well.
377  if (correlated) {
378  idx = (idx == 2) ? 3 : 2;
379  // Calculate the first tau decay matrix.
380  decayME->calculateD(children);
381  // Update the decay matrix for the tau.
382  (*tau).D = children[0].D;
383  // Switch the taus.
384  tau = &particles[idx];
385  // Calculate second tau's density matrix.
386  hardME->calculateRho(idx, particles);
387 
388  // Decay the second tau.
389  children.clear();
390  children = createChildren(*tau);
391  if (children.size() == 0) return false;
392  accepted = false;
393  tries = 0;
394  while (!accepted) {
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");
405  break;
406  }
407  ++tries;
408  }
409  writeDecay(event,children);
410  }
411 
412  // Done.
413  return true;
414 
415 }
416 
417 //--------------------------------------------------------------------------
418 
419 // Given a HelicityParticle parent, select the decay channel and return
420 // a vector of HelicityParticles containing the children, with the parent
421 // particle duplicated in the first entry of the vector.
422 
423 vector<HelicityParticle> TauDecays::createChildren(HelicityParticle parent) {
424 
425  // Initial values.
426  int meMode = 0;
427  vector<HelicityParticle> children;
428 
429  // Set the parent as incoming.
430  parent.direction = -1;
431 
432  // Setup decay data for the decaying particle.
433  ParticleDataEntry decayData = parent.particleDataEntry();
434 
435  // Initialize the decay data.
436  if (!decayData.preparePick(parent.id())) return children;
437 
438  // Try to pick a decay channel.
439  bool decayed = false;
440  int decayTries = 0;
441  while (!decayed && decayTries < NTRYCHANNEL) {
442 
443  // Pick a decay channel.
444  DecayChannel decayChannel = decayData.pickChannel();
445  meMode = decayChannel.meMode();
446  int decayMult = decayChannel.multiplicity();
447 
448  // Select children masses.
449  bool allowed = false;
450  int channelTries = 0;
451  while (!allowed && channelTries < NTRYCHANNEL) {
452  children.resize(0);
453  children.push_back(parent);
454  for (int i = 0; i < decayMult; ++i) {
455  // Grab child ID.
456  int childId = decayChannel.product(i);
457  // Flip sign for anti-particle decay.
458  if (parent.id() < 0 && particleDataPtr->hasAnti(childId))
459  childId = -childId;
460  // Grab child mass.
461  double childMass = particleDataPtr->mSel(childId);
462  // Push back the child into the children vector.
463  children.push_back( HelicityParticle(childId, 91, parent.idx, 0, 0,
464  0, 0, 0, 0., 0., 0., 0.,childMass, 0., particleDataPtr) );
465  }
466 
467  // Check there is enough phase space for decay.
468  if (decayMult > 1) {
469  double massDiff = parent.m();
470  for (int i = 0; i < decayMult; ++i) massDiff -= children[i].m();
471  // For now we just check kinematically available.
472  if (massDiff > 0) {
473  allowed = true;
474  decayed = true;
475  }
476  }
477 
478  // End pick a channel.
479  ++channelTries;
480  }
481  ++decayTries;
482  }
483 
484  // Swap the children ordering for muons.
485  if (parent.idAbs() == 13 && children.size() == 4 && meMode == 22)
486  swap(children[1], children[3]);
487 
488  // Set the decay matrix element.
489  // Two body decays.
490  if (children.size() == 3) {
491  if (meMode == 1521)
492  decayME = hmeTau2Meson.initChannel(children);
493  else decayME = hmeTau2PhaseSpace.initChannel(children);
494  }
495 
496  // Three body decays.
497  else if (children.size() == 4) {
498  // Leptonic decay.
499  if (meMode == 1531 || (parent.idAbs() == 13 && meMode == 22))
500  decayME = hmeTau2TwoLeptons.initChannel(children);
501  // Two meson decay via vector meson.
502  else if (meMode == 1532)
503  decayME = hmeTau2TwoMesonsViaVector.initChannel(children);
504  // Two meson decay via vector or scalar meson.
505  else if (meMode == 1533)
506  decayME = hmeTau2TwoMesonsViaVectorScalar.initChannel(children);
507  // Flat phase space.
508  else decayME = hmeTau2PhaseSpace.initChannel(children);
509  }
510 
511  // Four body decays.
512  else if (children.size() == 5) {
513  // Three pion CLEO decay.
514  if (meMode == 1541)
515  decayME = hmeTau2ThreePions.initChannel(children);
516  // Three meson decay with one or more kaons decay.
517  else if (meMode == 1542)
518  decayME = hmeTau2ThreeMesonsWithKaons.initChannel(children);
519  // Generic three meson decay.
520  else if (meMode == 1543)
521  decayME = hmeTau2ThreeMesonsGeneric.initChannel(children);
522  // Two pions and photon decay.
523  else if (meMode == 1544)
524  decayME = hmeTau2TwoPionsGamma.initChannel(children);
525  // Flat phase space.
526  else decayME = hmeTau2PhaseSpace.initChannel(children);
527  }
528 
529  // Five body decays.
530  else if (children.size() == 6) {
531  // Four pion Novosibirsk current.
532  if (meMode == 1551)
533  decayME = hmeTau2FourPions.initChannel(children);
534  // Flat phase space.
535  else decayME = hmeTau2PhaseSpace.initChannel(children);
536  }
537 
538  // Six body decays.
539  else if (children.size() == 7) {
540  // Four pion Novosibirsk current.
541  if (meMode == 1561)
542  decayME = hmeTau2FivePions.initChannel(children);
543  // Flat phase space.
544  else decayME = hmeTau2PhaseSpace.initChannel(children);
545  }
546 
547  // Flat phase space.
548  else decayME = hmeTau2PhaseSpace.initChannel(children);
549 
550  // Done.
551  return children;
552 }
553 
554 //--------------------------------------------------------------------------
555 
556 // N-body decay using the M-generator algorithm described in
557 // "Monte Carlo Phase Space" by F. James in CERN 68-15, May 1968. Taken
558 // from ParticleDecays::mGenerator but modified to handle spin particles.
559 // Given a vector of HelicityParticles where the first particle is
560 // the mother, the remaining particles are decayed isotropically.
561 
562 void TauDecays::isotropicDecay(vector<HelicityParticle>& children) {
563 
564  // Mother and sum daughter masses.
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;
570 
571  // Begin setup of intermediate invariant masses.
572  vector<double> mInv;
573  for (int i = 0; i <= decayMult; ++i) mInv.push_back( children[i].m());
574 
575  // Calculate the maximum weight in the decay.
576  double wtPS;
577  double wtPSmax = 1. / WTCORRECTION[decayMult];
578  double mMax = mDiff + children[decayMult].m();
579  double mMin = 0.;
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;
586  }
587 
588  // Begin loop to find the set of intermediate invariant masses.
589  vector<double> rndmOrd;
590  do {
591  wtPS = 1.;
592 
593  // Find and order random numbers in descending order.
594  rndmOrd.clear();
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] );
601  else break;
602  }
603  }
604  rndmOrd.push_back(0.);
605 
606  // Translate into intermediate masses and find weight.
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];
614  }
615 
616  // If rejected, try again with new invariant masses.
617  } while ( wtPS < rndmPtr->flat() * wtPSmax );
618 
619  // Perform two-particle decays in the respective rest frame.
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];
626 
627  // Isotropic angles give three-momentum.
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;
634 
635  // Calculate energies, fill four-momenta.
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);
640  }
641 
642  // Boost decay products to the mother rest frame.
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]);
647 
648  // Boost decay products to the current frame.
649  pInv[1].p( children[0].p() );
650  for (int i = 1; i <= decayMult; ++i) children[i].bst( pInv[1], mInv[1] );
651 
652  // Done.
653  return;
654 }
655 
656 //--------------------------------------------------------------------------
657 
658 // Write the vector of HelicityParticles to the event record, excluding the
659 // first particle. Set the lifetime and production vertex of the particles
660 // and mark the first particle of the vector as decayed.
661 
662 void TauDecays::writeDecay(Event& event, vector<HelicityParticle>& children) {
663 
664  // Set additional information and append children to event.
665  int decayMult = children.size() - 1;
666  Vec4 decayVertex = children[0].vDec();
667  for (int i = 1; i <= decayMult; i++) {
668  // Set child lifetime.
669  children[i].tau(children[i].tau0() * rndmPtr->exp());
670  // Set child production vertex.
671  children[i].vProd(decayVertex);
672  // Append child to record.
673  children[i].idx = event.append(children[i]);
674  }
675 
676  // Mark the parent as decayed and set children.
677  event[children[0].idx].statusNeg();
678  event[children[0].idx].daughters(children[1].idx, children[decayMult].idx);
679 
680 }
681 
682 //==========================================================================
683 
684 } // end namespace Pythia8
Definition: AgUStep.h:26