StRoot  1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
ParticleDecays.cc
1 // ParticleDecays.cc is a part of the PYTHIA event generator.
2 // Copyright (C) 2020 Torbjorn Sjostrand.
3 // PYTHIA is licenced under the GNU GPL v2 or later, 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
7 // ParticleDecays class.
8 
9 #include "Pythia8/ParticleDecays.h"
10 #include "Pythia8/HadronWidths.h"
11 
12 namespace Pythia8 {
13 
14 //==========================================================================
15 
16 // The ParticleDecays class.
17 
18 //--------------------------------------------------------------------------
19 
20 // Constants: could be changed here if desired, but normally should not.
21 // These are of technical nature, as described for each.
22 
23 // Number of times one tries to let decay happen (for 2 nested loops).
24 const int ParticleDecays::NTRYDECAY = 10;
25 
26 // Number of times one tries to pick valid hadronic content in decay.
27 const int ParticleDecays::NTRYPICK = 100;
28 
29 // Number of times one tries to pick decay topology.
30 const int ParticleDecays::NTRYMEWT = 1000;
31 
32 // Maximal loop count in Dalitz decay treatment.
33 const int ParticleDecays::NTRYDALITZ = 1000;
34 
35 // Minimal Dalitz pair mass this factor above threshold.
36 const double ParticleDecays::MSAFEDALITZ = 1.000001;
37 
38 // These numbers are hardwired empirical parameters,
39 // intended to speed up the M-generator.
40 const double ParticleDecays::WTCORRECTION[11] = { 1., 1., 1.,
41  2., 5., 15., 60., 250., 1250., 7000., 50000. };
42 
43 //--------------------------------------------------------------------------
44 
45 // Initialize and save pointers.
46 
47 void ParticleDecays::init(TimeShowerPtr timesDecPtrIn,
48  StringFlav* flavSelPtrIn, DecayHandlerPtr decayHandlePtrIn,
49  vector<int> handledParticles) {
50 
51  // Save pointers to error messages handling and flavour generation.
52  flavSelPtr = flavSelPtrIn;
53 
54  // Save pointer to timelike shower, as needed in some few decays.
55  timesDecPtr = timesDecPtrIn;
56 
57  // Save pointer for external handling of some decays.
58  decayHandlePtr = decayHandlePtrIn;
59 
60  // Set which particles should be handled externally.
61  if (decayHandlePtr != 0)
62  for (int i = 0; i < int(handledParticles.size()); ++i)
63  particleDataPtr->doExternalDecay(handledParticles[i], true);
64 
65  // Safety margin in mass to avoid troubles.
66  mSafety = parm("ParticleDecays:mSafety");
67 
68  // Lifetime and vertex rules for determining whether decay allowed.
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;
79 
80  // B-Bbar mixing parameters.
81  mixB = flag("ParticleDecays:mixB");
82  xBdMix = parm("ParticleDecays:xBdMix");
83  xBsMix = parm("ParticleDecays:xBsMix");
84 
85  // Suppression of extra-hadron momenta in semileptonic decays.
86  sigmaSoft = parm("ParticleDecays:sigmaSoft");
87 
88  // Selection of multiplicity and colours in "phase space" model.
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");
94 
95  // Minimum energy in system (+ m_q) from StringFragmentation.
96  stopMass = parm("StringFragmentation:stopMass");
97 
98  // Parameters for Dalitz decay virtual gamma mass spectrum.
99  sRhoDal = pow2(particleDataPtr->m0(113));
100  wRhoDal = pow2(particleDataPtr->mWidth(113));
101 
102  // Allow showers in decays to qqbar/gg/ggg/gammagg.
103  doFSRinDecays = flag("ParticleDecays:FSRinDecays");
104  doGammaRad = flag("ParticleDecays:allowPhotonRadiation");
105 
106  // Use standard decays or dedicated tau decay package
107  tauMode = mode("TauDecays:mode");
108 
109  // Initialize the dedicated tau decay handler.
110  if (tauMode) tauDecayer.init();
111 
112 }
113 
114 //--------------------------------------------------------------------------
115 
116 // Decay a particle; main method.
117 
118 bool ParticleDecays::decay( int iDec, Event& event) {
119 
120  // Check whether a decay is allowed, given the upcoming decay vertex.
121  Particle& decayer = event[iDec];
122  hasPartons = false;
123  keepPartons = false;
124  if (limitDecay && !checkVertex(decayer)) return true;
125 
126  // Do not allow resonance decays (beyond handling capability).
127  if (decayer.isResonance()) {
128  infoPtr->errorMsg("Warning in ParticleDecays::decay: "
129  "resonance left undecayed");
130  return true;
131  }
132 
133  // Fill the decaying particle in slot 0 of arrays.
134  idDec = decayer.id();
135  iProd.resize(0);
136  idProd.resize(0);
137  mProd.resize(0);
138  iProd.push_back( iDec );
139  idProd.push_back( idDec );
140  mProd.push_back( decayer.m() );
141 
142  // Check for oscillations B0 <-> B0bar or B_s0 <-> B_s0bar.
143  bool hasOscillated = (abs(idDec) == 511 || abs(idDec) == 531)
144  ? oscillateB(decayer) : false;
145  if (hasOscillated) {idDec = - idDec; idProd[0] = idDec;}
146 
147  // Particle data for decaying particle.
148  decDataPtr = &decayer.particleDataEntry();
149 
150  // Optionally send on to external decay program.
151  bool doneExternally = false;
152  if (decDataPtr->doExternalDecay()) {
153  motherProd.resize(0);
154  motherProd.push_back( 0 );
155  pProd.resize(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);
161 
162  // If it worked, then store the decay products in the event record.
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);
173 
174  // Also mark mother(s) decayed and store daughters.
175  event[iMo].statusNeg();
176  if ( event[iMo].daughter1() == 0) event[iMo].daughter1( iPos);
177  else event[iMo].daughter2( iPos);
178  }
179  }
180  }
181 
182  // Check if the particle is tau and let the special tau decayer handle it.
183  if (decayer.idAbs() == 15 && !doneExternally && tauMode) {
184  doneExternally = tauDecayer.decay(iDec, event);
185  if (doneExternally) return true;
186  }
187 
188  // Perform decay using mass dependent widths if possible.
189  if (!doneExternally && decDataPtr->varWidth()
190  && (idDec != 113 && abs(idDec) != 213 && idDec != 225)) {
191  double mDec = decayer.m();
192  int id1, id2;
193  double m1, m2;
194  if (hadronWidthsPtr->pickDecay(idDec, mDec, id1, id2, m1, m2)) {
195 
196  // Calculate four-momenta and boost to lab frame.
197  auto ps = rndmPtr->phaseSpace2(mDec, m1, m2);
198  ps.first.bst( decayer.p(), decayer.m() );
199  ps.second.bst(decayer.p(), decayer.m() );
200 
201  // Insert new particles into event record.
202  mult = 2;
203  int statOut = ( decayer.statusAbs() == 157
204  || decayer.statusAbs() == 159 ) ? 97 : 91;
205  iProd.resize(3);
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);
208 
209  // Mark original particle as decayed and set daughters.
210  event[iDec].statusNeg();
211  event[iDec].daughters(iProd[1], iProd[2]);
212 
213  // Mark as done externally.
214  doneExternally = true;
215  }
216  }
217 
218  // Now begin normal internal decay treatment.
219  if (!doneExternally) {
220 
221  // Allow up to ten tries to pick a channel.
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) {
226 
227  // Remove previous failed channel.
228  if (hasStored) event.popBack(mult);
229  hasStored = false;
230 
231  // Pick new channel. Read out basics.
232  DecayChannel& channel = decDataPtr->pickChannel();
233  meMode = channel.meMode();
234  keepPartons = (meMode > 90 && meMode <= 100);
235  mult = channel.multiplicity();
236 
237  // Allow up to ten tries for each channel (e.g with different masses).
238  bool foundMode = false;
239  iProd.resize(1);
240  for (int iTryMode = 0; iTryMode < NTRYDECAY; ++iTryMode) {
241  idProd.resize(1);
242  mProd.resize(1);
243  scale = 0.;
244 
245  // Extract and store the decay products in local arrays.
246  hasPartons = false;
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);
257  }
258 
259  // Decays into partons usually translate into hadrons.
260  if (hasPartons && !keepPartons && !pickHadrons()) continue;
261 
262  // Need to set colour flow if explicit decay to partons.
263  cols.resize(0);
264  acols.resize(0);
265  for (int i = 0; i <= mult; ++i) {
266  cols.push_back(0);
267  acols.push_back(0);
268  }
269  if (hasPartons && keepPartons && !setColours(event)) continue;
270 
271  // Check that enough phase space for decay.
272  if (mult > 1) {
273  double mDiff = mProd[0];
274  for (int i = 1; i <= mult; ++i) mDiff -= mProd[i];
275  if (mDiff < mSafety) continue;
276  }
277 
278  // End of inner trial loops. Check if succeeded or not.
279  foundMode = true;
280  break;
281  }
282  if (!foundMode) continue;
283 
284  // Store decay products in the event record.
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);
290  }
291  hasStored = true;
292 
293  // Pick mass of Dalitz decay. Temporarily change multiplicity.
294  if ( (meMode == 11 || meMode == 12 || meMode == 13)
295  && !dalitzMass() ) continue;
296 
297  // Do a decay, split by multiplicity.
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;
304 
305  // Kinematics of gamma* -> l- l+ in Dalitz decay. Restore multiplicity.
306  if (meMode == 11 || meMode == 12 || meMode == 13)
307  dalitzKinematics(event);
308 
309  // End of outer trial loops.
310  foundChannel = true;
311  break;
312  }
313 
314  // If the decay worked, then mark mother decayed and store daughters.
315  if (foundChannel) {
316  event[iDec].statusNeg();
317  event[iDec].daughters( iProd[1], iProd[mult]);
318 
319  // Else remove unused daughters and return failure.
320  } else {
321  if (hasStored) event.popBack(mult);
322  infoPtr->errorMsg("Error in ParticleDecays::decay: "
323  "failed to find workable decay channel");
324 
325  return false;
326  }
327 
328  // Now finished normal internal decay treatment.
329  }
330 
331  // Set decay vertex when this is displaced.
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 );
336  }
337 
338  // Set lifetime of daughters. Check if they decayed in their turn.
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 );
345  }
346  }
347 
348  // In a decay explicitly to partons then optionally do a shower,
349  // and always flag that partonic system should be fragmented.
350  if (hasPartons && keepPartons && doFSRinDecays)
351  timesDecPtr->shower( iProd[1], iProd.back(), event, mProd[0]);
352 
353  // Photon radiation implemented only for two-body decay to leptons.
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]);
357 
358  // For Hidden Valley particles also allow leptons to shower.
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]);
364  }
365 
366  // Done.
367  return true;
368 
369 }
370 
371 //--------------------------------------------------------------------------
372 
373 // Perform decays on all particles in the event.
374 
375 bool ParticleDecays::decayAll(Event& event, double minWidth) {
376 
377  // Loop through all entries to find those that should decay.
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) ) {
383  decay(iDec, event);
384  if (moreToDo()) gotMoreToDo = true;
385  }
386  }
387 
388  return gotMoreToDo;
389 }
390 
391 //--------------------------------------------------------------------------
392 
393 // Check whether a decay is allowed, given the upcoming decay vertex.
394 
395 bool ParticleDecays::checkVertex(Particle& decayer) {
396 
397  // Check whether any of the conditions are not fulfilled.
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;
404 
405  // Done.
406  return true;
407 
408 }
409 
410 //--------------------------------------------------------------------------
411 
412 // Check for oscillations B0 <-> B0bar or B_s0 <-> B_s0bar.
413 
414 bool ParticleDecays::oscillateB(Particle& decayer) {
415 
416  // Extract relevant information and decide.
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());
423 
424 }
425 
426 //--------------------------------------------------------------------------
427 
428 // Do a one-body decay. (Rare; e.g. for K0 -> K0_short.)
429 
430 bool ParticleDecays::oneBody(Event& event) {
431 
432  // References to the particles involved.
433  Particle& decayer = event[iProd[0]];
434  Particle& prod = event[iProd[1]];
435 
436  // Set momentum and expand mother information.
437  prod.p( decayer.p() );
438  prod.m( decayer.m() );
439  prod.mother2( iProd[0] );
440 
441  // Done.
442  return true;
443 
444 }
445 
446 //--------------------------------------------------------------------------
447 
448 // Do a two-body decay.
449 
450 bool ParticleDecays::twoBody(Event& event) {
451 
452  // References to the particles involved.
453  Particle& decayer = event[iProd[0]];
454  Particle& prod1 = event[iProd[1]];
455  Particle& prod2 = event[iProd[2]];
456 
457  // Masses.
458  double m0 = mProd[0];
459  double m1 = mProd[1];
460  double m2 = mProd[2];
461 
462  // Energies and absolute momentum in the rest frame.
463  if (m1 + m2 + mSafety > m0) return false;
464 
465  // When meMode = 2, for V -> PS2 + PS3 (V = vector, pseudoscalar),
466  // need to check if production is PS0 -> PS1/gamma + V.
467  int iMother = event[iProd[0]].mother1();
468  int idSister = 0;
469  if (meMode == 2) {
470  if (iMother <= 0 || iMother >= iProd[0]) meMode = 0;
471  else {
472  int iDaughter1 = event[iMother].daughter1();
473  int iDaughter2 = event[iMother].daughter2();
474  if (iDaughter2 != iDaughter1 + 1) meMode = 0;
475  else {
476  int idMother = abs( event[iMother].id() );
477  if (idMother <= 100 || idMother%10 !=1
478  || (idMother/1000)%10 != 0) meMode = 0;
479  else {
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;
484  }
485  }
486  }
487  }
488 
489  // Begin loop over matrix-element corrections.
490  double wtME, wtMEmax;
491  int loop = 0;
492  do {
493  wtME = 1.;
494  wtMEmax = 1.;
495  ++loop;
496 
497  // Fill four-momenta in mother rest frame and then boost to lab frame.
498  pair<Vec4, Vec4> ps = rndmPtr->phaseSpace2(m0, m1, m2);
499  prod1.p(ps.first);
500  prod2.p(ps.second);
501  prod1.bst( decayer.p(), decayer.m() );
502  prod2.bst( decayer.p(), decayer.m() );
503 
504  // Matrix element for PS0 -> PS1 + V1 -> PS1 + PS2 + PS3 of form
505  // cos**2(theta02) in V1 rest frame, and for PS0 -> gamma + V1
506  // -> gamma + PS2 + PS3 of form sin**2(theta02).
507  if (meMode == 2) {
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);
519  }
520 
521  // Break out of loop if no sensible ME weight.
522  if(loop > NTRYMEWT) {
523  infoPtr->errorMsg("ParticleDecays::twoBody: "
524  "caught in infinite ME weight loop");
525  wtME = abs(wtMEmax);
526  }
527 
528  // If rejected, try again with new invariant masses.
529  } while ( wtME < rndmPtr->flat() * wtMEmax );
530 
531  // Done.
532  return true;
533 
534 }
535 
536 //--------------------------------------------------------------------------
537 
538 // Do a three-body decay (except Dalitz decays).
539 
540 bool ParticleDecays::threeBody(Event& event) {
541 
542  // References to the particles involved.
543  Particle& decayer = event[iProd[0]];
544  Particle& prod1 = event[iProd[1]];
545  Particle& prod2 = event[iProd[2]];
546  Particle& prod3 = event[iProd[3]];
547 
548  // Mother and sum daughter masses. Fail if too close.
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;
556 
557  // Kinematical limits for 2+3 mass. Maximum phase-space weight.
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;
565 
566  // Begin loop over matrix-element corrections.
567  double wtME, wtMEmax, wtPS, m23, p1Abs, p23Abs;
568  do {
569  wtME = 1.;
570  wtMEmax = 1.;
571 
572  // Pick an intermediate mass m23 flat in the allowed range.
573  do {
574  m23 = m23Min + rndmPtr->flat() * mDiff;
575 
576  // Translate into relative momenta and find phase-space weight.
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;
582 
583  // If rejected, try again with new invariant masses.
584  } while ( wtPS < rndmPtr->flat() * wtPSmax );
585 
586  // Set up m23 -> m2 + m3 isotropic in its rest frame.
587  pair<Vec4, Vec4> ps23 = rndmPtr->phaseSpace2(m23, m2, m3);
588  prod2.p(ps23.first);
589  prod3.p(ps23.second);
590 
591  // Set up m0 -> m1 + m23 isotropic in its rest frame.
592  pair<Vec4, Vec4> ps123 = rndmPtr->phaseSpace2(m0, m1, m23);
593  prod1.p(ps123.first);
594 
595  // Boost 2 + 3 to the 0 rest frame.
596  prod2.bst( ps123.second, m23 );
597  prod3.bst( ps123.second, m23 );
598 
599  // Matrix-element weight for omega/phi -> pi+ pi- pi0.
600  if (meMode == 1) {
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.;
607 
608  // Effective matrix element for nu spectrum in tau -> nu + hadrons.
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);
614 
615  // Matrix element for weak decay (only semileptonic for c and b).
616  } else if ( ((meMode == 22 || meMode == 23) && prod1.isLepton())
617  || meMode == 94) {
618  wtME = m0 * prod1.e() * (prod2.p() * prod3.p());
619  wtMEmax = min( pow4(m0) / 16., m0 * (m0 - m1 - m2) * (m0 - m1 - m3)
620  * (m0 - m2 - m3) );
621 
622  // Effective matrix element for weak decay to hadrons (B -> D, D -> K).
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);
628 
629  // Effective matrix element for gamma spectrum in B -> gamma + hadrons.
630  } else if (meMode == 31) {
631  double x1 = 2. * prod1.e() / m0;
632  wtME = pow3(x1);
633  double x1Max = 1. - pow2(mSum / m0);
634  wtMEmax = pow3(x1Max);
635 
636  // Matrix-element weight for "onium" -> g + g + g or gamma + g + g.
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) );
643  wtMEmax = 2.;
644  // For gamma + g + g require minimum mass for g + g system.
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.;
648  }
649 
650  // If rejected, try again with new invariant masses.
651  } while ( wtME < rndmPtr->flat() * wtMEmax );
652 
653  // Boost 1 + 2 + 3 to the current frame.
654  prod1.bst( decayer.p(), decayer.m() );
655  prod2.bst( decayer.p(), decayer.m() );
656  prod3.bst( decayer.p(), decayer.m() );
657 
658  // Done.
659  return true;
660 
661 }
662 
663 //--------------------------------------------------------------------------
664 
665 // Do a multibody decay using the M-generator algorithm.
666 
667 bool ParticleDecays::mGenerator(Event& event) {
668 
669  // Mother and sum daughter masses. Fail if too close or inconsistent.
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;
675 
676  // Begin setup of intermediate invariant masses.
677  mInv.resize(0);
678  for (int i = 0; i <= mult; ++i) mInv.push_back( mProd[i]);
679 
680  // Calculate the maximum weight in the decay.
681  double wtPS, wtME, wtMEmax;
682  double wtPSmax = 1. / WTCORRECTION[mult];
683  double mMax = mDiff + mProd[mult];
684  double mMin = 0.;
685  for (int i = mult - 1; i > 0; --i) {
686  mMax += mProd[i];
687  mMin += mProd[i+1];
688  double mNow = mProd[i];
689  wtPSmax *= 0.5 * sqrtpos( (mMax - mMin - mNow) * (mMax + mMin + mNow)
690  * (mMax + mMin - mNow) * (mMax - mMin + mNow) ) / mMax;
691  }
692 
693  // Begin loop over matrix-element corrections.
694  do {
695  wtME = 1.;
696  wtMEmax = 1.;
697 
698  // Begin loop to find the set of intermediate invariant masses.
699  do {
700  wtPS = 1.;
701 
702  // Find and order random numbers in descending order.
703  rndmOrd.resize(0);
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] );
710  else break;
711  }
712  }
713  rndmOrd.push_back(0.);
714 
715  // Translate into intermediate masses and find weight.
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];
721  }
722 
723  // If rejected, try again with new invariant masses.
724  } while ( wtPS < rndmPtr->flat() * wtPSmax );
725 
726  // Perform two-particle decays in the respective rest frame.
727  pInv.resize(mult + 1);
728  for (int i = 1; i < mult; ++i) {
729  // Fill four-momenta
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);
733  }
734 
735  // Boost decay products to the mother rest frame.
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]);
740 
741  // Effective matrix element for nu spectrum in tau -> nu + hadrons.
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);
747 
748  // Effective matrix element for weak decay (only semileptonic for c and b).
749  // Particles 4 onwards should be made softer explicitly?
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.;
757 
758  // Effective matrix element for weak decay to hadrons (B -> D, D -> K).
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);
764 
765  // Effective matrix element for gamma spectrum in B -> gamma + hadrons.
766  } else if (meMode == 31) {
767  double x1 = 2. * event[iProd[1]].e() / m0;
768  wtME = pow3(x1);
769  double x1Max = 1. - pow2(mSum / m0);
770  wtMEmax = pow3(x1Max);
771  }
772 
773  // If rejected, try again with new invariant masses.
774  } while ( wtME < rndmPtr->flat() * wtMEmax );
775 
776  // Boost decay products to the current frame.
777  pInv[1].p( event[iProd[0]].p() );
778  for (int i = 1; i <= mult; ++i) event[iProd[i]].bst( pInv[1], mInv[1] );
779 
780  // Done.
781  return true;
782 
783 }
784 
785 //--------------------------------------------------------------------------
786 
787 // Select mass of lepton pair in a Dalitz decay.
788 
789 bool ParticleDecays::dalitzMass() {
790 
791  // Mother and sum daughter masses.
792  double mSum1 = 0;
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;
797 
798  // Fail if too close or inconsistent.
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");
804  return false;
805  }
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");
810  return false;
811  }
812 
813  // Case 1: one Dalitz pair.
814  if (meMode == 11 || meMode == 12) {
815 
816  // Kinematical limits for gamma* squared mass.
817  double sGamMin = pow2(mSum2);
818  double sGamMax = pow2(mProd[0] - mSum1);
819  // Select virtual gamma squared mass. Guessed form for meMode == 12.
820  double sGam, wtGam;
821  int loop = 0;
822  do {
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() );
829 
830  // Store results in preparation for doing a one-less-body decay.
831  --mult;
832  mProd[mult] = sqrt(sGam);
833 
834  // Case 2: two Dalitz pairs.
835  } else {
836 
837  // Kinematical limits for 1 + 2 and 3 + 4 gamma* masses.
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);
843 
844  // Select virtual gamma squared masses. Guessed form for meMode == 13.
845  double s12, s34, wt12, wt34, wtPAbs, wtAll;
846  int loop = 0;
847  do {
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());
863 
864  // Store results in preparation for doing a two-body decay.
865  mult = 2;
866  mProd[1] = sqrt(s12);
867  mProd[2] = sqrt(s34);
868  }
869 
870  // Done.
871  return true;
872 
873 }
874 
875 //--------------------------------------------------------------------------
876 
877 // Do kinematics of gamma* -> l- l+ in Dalitz decay.
878 
879 bool ParticleDecays::dalitzKinematics(Event& event) {
880 
881  // Restore multiplicity.
882  int nDal = (meMode < 13) ? 1 : 2;
883  mult += nDal;
884 
885  // Loop over one or two lepton pairs.
886  for (int iDal = 0; iDal < nDal; ++iDal) {
887 
888  // References to the particles involved.
889  Particle& decayer = event[iProd[0]];
890  Particle& prodA = (iDal == 0) ? event[iProd[mult - 1]]
891  : event[iProd[1]];
892  Particle& prodB = (iDal == 0) ? event[iProd[mult]]
893  : event[iProd[2]];
894 
895  // Reconstruct required rotations and boosts backwards.
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.);
904 
905  // Masses and phase space in gamma* rest frame.
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) );
912 
913  // Set up decay in gamma* rest frame, reference along +z axis.
914  double cosTheta, cos2Theta;
915  do {
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);
929 
930  // Boost to lab frame.
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() );
937  }
938 
939  // Done.
940  return true;
941 
942 }
943 
944 //--------------------------------------------------------------------------
945 
946 // Translate a partonic content into a set of actual hadrons.
947 
948 bool ParticleDecays::pickHadrons() {
949 
950  // Find partonic decay products. Rest are known id's, mainly hadrons,
951  // when necessary shuffled to beginning of idProd list.
952  idPartons.resize(0);
953  int nPartons = 0;
954  int nKnown = 0;
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) {
960  ++nPartons;
961  idPartons.push_back(idProd[i]);
962  if (idAbs == 83) closedGLoop = true;
963  } else {
964  ++nKnown;
965  if (nPartons > 0) {
966  idProd[nKnown] = idProd[i];
967  mProd[nKnown] = mProd[i];
968  }
969  }
970  }
971 
972  // Replace generic spectator flavour code by the actual one.
973  for (int i = 0; i < nPartons; ++i) {
974  int idPart = idPartons[i];
975  int idNew = idPart;
976  if (idPart == 81) {
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;
985 
986  // Replace generic random flavour by a randomly selected one.
987  } else if (idPart == 82 || idPart == 83) {
988  double mFlav;
989  do {
990  int idDummy = -flavSelPtr->pickLightQ();
991  FlavContainer flavDummy(idDummy, idPart - 82);
992  do idNew = flavSelPtr->pick(flavDummy).id;
993  while (idNew == 0);
994  mFlav = particleDataPtr->constituentMass(idNew);
995  } while (2. * mFlav + stopMass > mProd[0]);
996  } else if (idPart == -82 || idPart == -83) {
997  idNew = -idPartons[i-1];
998  }
999  idPartons[i] = idNew;
1000  }
1001 
1002  // Determine whether fixed multiplicity or to be selected at random.
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;
1007  int nFix = 0;
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;
1014 
1015  // Initial values for loop to set new hadronic content.
1016  int nFilled, nTotal, nNew, nSpec, nLeft;
1017  double mDiff;
1018  int nTry = 0;
1019  bool diquarkClash = false;
1020  bool usedChannel = false;
1021 
1022  // Begin loop; interrupt if multiple tries fail.
1023  do {
1024  ++nTry;
1025  if (nTry > NTRYPICK) return false;
1026 
1027  // Initialize variables inside new try.
1028  nFilled = nKnown + 1;
1029  idProd.resize(nFilled);
1030  mProd.resize(nFilled);
1031  nTotal = nKnown;
1032  nSpec = 0;
1033  nLeft = nPartons;
1034  mDiff = mProd[0];
1035  for (int i = 1; i < nFilled; ++i) mDiff -= mProd[i];
1036  diquarkClash = false;
1037  usedChannel = false;
1038 
1039  // For weak decays collapse spectators to one particle.
1040  if ( (meMode == 22 || meMode == 23) && nLeft > 1) {
1041  FlavContainer flav1( idPartons[nPartons - 2] );
1042  FlavContainer flav2( idPartons[nPartons - 1] );
1043  int idHad;
1044  do idHad = flavSelPtr->combine( flav1, flav2);
1045  while (idHad == 0);
1046  double mHad = particleDataPtr->mSel(idHad);
1047  mDiff -= mHad;
1048  idProd.push_back( idHad);
1049  mProd.push_back( mHad);
1050  ++nFilled;
1051  nSpec = 1;
1052  nLeft -= 2;
1053  }
1054 
1055  // If there are partons left, then determine how many hadrons to pick.
1056  if (nLeft > 0) {
1057 
1058  // For B -> gamma + X use geometrical distribution.
1059  if (meMode == 31) {
1060  double geom = rndmPtr->flat();
1061  nTotal = 1;
1062  do {
1063  ++nTotal;
1064  geom *= 2.;
1065  } while (geom < 1. && nTotal < 10);
1066 
1067  // Calculate mass excess and from there average multiplicity.
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;
1077 
1078  // Pick multiplicity according to Poissonian.
1079  double value = 1.;
1080  double sum = 1.;
1081  for (int nNow = nMin + 1; nNow <= 10; ++nNow) {
1082  value *= average / nNow;
1083  sum += value;
1084  }
1085  nTotal = nMin;
1086  value = 1.;
1087  sum *= rndmPtr->flat();
1088  sum -= value;
1089  if (sum > 0.) do {
1090  ++nTotal;
1091  value *= average / nTotal;
1092  sum -= value;
1093  } while (sum > 0. && nTotal < 10);
1094 
1095  // Alternatively predetermined multiplicity.
1096  } else {
1097  nTotal = nFix;
1098  }
1099  nNew = nTotal - nKnown - nSpec;
1100 
1101  // Set up ends of fragmented system, as copy of idPartons.
1102  flavEnds.resize(0);
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] );
1106  }
1107 
1108  // Fragment off at random, but save nLeft/2 for final recombination.
1109  if (nNew > nLeft/2) {
1110  FlavContainer flavNew;
1111  int idHad;
1112  for (int i = 0; i < nNew - nLeft/2; ++i) {
1113  // When four quarks consider last one to be spectator.
1114  int iEnd = int( (nLeft - 1.) * rndmPtr->flat() );
1115  // Pick new flavour and form a new hadron.
1116  do {
1117  flavNew = flavSelPtr->pick( flavEnds[iEnd] );
1118  idHad = flavSelPtr->combine( flavEnds[iEnd], flavNew);
1119  } while (idHad == 0);
1120  // Store new hadron and endpoint flavour.
1121  idProd.push_back( idHad);
1122  flavEnds[iEnd].anti(flavNew);
1123  }
1124  }
1125 
1126  // When only two quarks left, combine to form final hadron.
1127  if (nLeft == 2) {
1128  int idHad;
1129  if ( abs(flavEnds[0].id) > 8 && abs(flavEnds[1].id) > 8)
1130  diquarkClash = true;
1131  else {
1132  do idHad = flavSelPtr->combine( flavEnds[0], flavEnds[1]);
1133  while (idHad == 0);
1134  idProd.push_back( idHad);
1135  }
1136 
1137  // If four quarks, decide how to pair them up.
1138  } else {
1139  int iEnd1 = 0;
1140  int iEnd2 = 1;
1141  int iEnd3 = 2;
1142  int iEnd4 = 3;
1143  if ( rndmPtr->flat() < colRearrange) iEnd2 = 3;
1144  int relColSign =
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;
1152 
1153  // Then combine to get final two hadrons.
1154  int idHad;
1155  if ( abs(flavEnds[iEnd1].id) > 8 && abs(flavEnds[iEnd2].id) > 8)
1156  diquarkClash = true;
1157  else {
1158  do idHad = flavSelPtr->combine( flavEnds[iEnd1], flavEnds[iEnd2]);
1159  while (idHad == 0);
1160  idProd.push_back( idHad);
1161  }
1162  if ( abs(flavEnds[iEnd3].id) > 8 && abs(flavEnds[iEnd4].id) > 8)
1163  diquarkClash = true;
1164  else {
1165  do idHad = flavSelPtr->combine( flavEnds[iEnd3], flavEnds[iEnd4]);
1166  while (idHad == 0);
1167  idProd.push_back( idHad);
1168  }
1169  }
1170 
1171  // Find masses of the new hadrons.
1172  for (int i = nFilled; i < int(idProd.size()) ; ++i) {
1173  double mHad = particleDataPtr->mSel(idProd[i]);
1174  mProd.push_back( mHad);
1175  mDiff -= mHad;
1176  }
1177  }
1178 
1179  // Optional: check that this decay mode is not explicitly defined.
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;
1185  // Loop through all channels. Done if not same multiplicity.
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);
1190  // Match particles one by one until fail.
1191  // Do not distinguish K0/K0bar/K0short/K0long at this stage.
1192  for (int j = 0; j < nTotal; ++j) {
1193  matched = false;
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)) {
1198  // Compress list of unmatched when matching worked.
1199  idMatch[k] = idMatch[nTotal - 1 - j];
1200  matched = true;
1201  break;
1202  }
1203  if (!matched) break;
1204  }
1205  // If matching worked, then chosen channel to be rejected.
1206  if (matched) {usedChannel = true; break;}
1207  }
1208  }
1209 
1210  // Keep on trying until enough phase space and no clash.
1211  } while (mDiff < mSafety || diquarkClash || usedChannel);
1212 
1213  // Update particle multiplicity.
1214  mult = idProd.size() - 1;
1215 
1216  // For Dalitz decays shuffle Dalitz pair to the end of the list.
1217  if (meMode == 11 || meMode == 12) {
1218  int iL1 = 0;
1219  int iL2 = 0;
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;
1223  }
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];
1229  int iMove = 0;
1230  for (int i = 1; i <= mult; ++i) if (i != iL1 && i != iL2) {
1231  ++iMove;
1232  idProd[iMove] = idProd[i];
1233  mProd[iMove] = mProd[i];
1234  }
1235  idProd[mult - 1] = idL1;
1236  idProd[mult] = idL2;
1237  mProd[mult - 1] = mL1;
1238  mProd[mult] = mL2;
1239  }
1240  }
1241 
1242  // Done.
1243  return true;
1244 
1245 }
1246 
1247 //--------------------------------------------------------------------------
1248 
1249 // Set colour flow and scale in a decay explicitly to partons.
1250 
1251 bool ParticleDecays::setColours(Event& event) {
1252 
1253  // Decay to q qbar (or qbar q).
1254  if (meMode == 91 && idProd[1] > 0 && idProd[1] < 9) {
1255  int newCol = event.nextColTag();
1256  cols[1] = newCol;
1257  acols[2] = newCol;
1258  } else if (meMode == 91 && idProd[1] < 0 && idProd[1] > -9) {
1259  int newCol = event.nextColTag();
1260  cols[2] = newCol;
1261  acols[1] = newCol;
1262 
1263  // Decay to g g.
1264  } else if (meMode == 91 && idProd[1] == 21) {
1265  int newCol1 = event.nextColTag();
1266  int newCol2 = event.nextColTag();
1267  cols[1] = newCol1;
1268  acols[1] = newCol2;
1269  cols[2] = newCol2;
1270  acols[2] = newCol1;
1271 
1272  // Decay to g g g.
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();
1278  cols[1] = newCol1;
1279  acols[1] = newCol2;
1280  cols[2] = newCol2;
1281  acols[2] = newCol3;
1282  cols[3] = newCol3;
1283  acols[3] = newCol1;
1284 
1285  // Decay to g g gamma: locate which is gamma.
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;
1295 
1296  // Decay to q qbar singlet, in whichever order.
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;
1305 
1306  // Unknown decay mode means failure.
1307  } else return false;
1308 
1309  // Set maximum scale to be mass of decaying particle.
1310  scale = mProd[0];
1311 
1312  // Done.
1313  return true;
1314 
1315 }
1316 
1317 //==========================================================================
1318 
1319 } // end namespace Pythia8
Definition: AgUStep.h:26