1 // ResonanceDecays.cc is a part of the PYTHIA event generator.
2 // Copyright (C) 2012 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.
6 // Function definitions (not found in the header) for
7 // the ResonanceDecays class.
9 #include "ResonanceDecays.h"
13 //==========================================================================
15 // The ResonanceDecays class.
16 // Do all resonance decays sequentially.
18 //--------------------------------------------------------------------------
20 // Constants: could be changed here if desired, but normally should not.
21 // These are of technical nature, as described for each.
23 // Number of tries to pick a decay channel.
24 const int ResonanceDecays::NTRYCHANNEL = 10;
26 // Number of tries to pick a set of daughter masses.
27 const int ResonanceDecays::NTRYMASSES = 10000;
29 // Mass above threshold for allowed decays.
30 const double ResonanceDecays::MSAFETY = 0.1;
32 // When constrainted kinematics cut high-mass tail of Breit-Wigner.
33 const double ResonanceDecays::WIDTHCUT = 5.;
35 // Small number (relative to 1) to protect against roundoff errors.
36 const double ResonanceDecays::TINY = 1e-10;
38 // Forbid small Breit-Wigner mass range, as mapped onto atan range.
39 const double ResonanceDecays::TINYBWRANGE = 1e-8;
41 // These numbers are hardwired empirical parameters,
42 // intended to speed up the M-generator.
43 const double ResonanceDecays::WTCORRECTION[11] = { 1., 1., 1.,
44 2., 5., 15., 60., 250., 1250., 7000., 50000. };
46 //--------------------------------------------------------------------------
48 bool ResonanceDecays::next( Event& process) {
50 // Loop over all entries to find resonances that should decay.
53 Particle& decayer = process[iDec];
54 if (decayer.isFinal() && decayer.canDecay() && decayer.mayDecay()
55 && decayer.isResonance() ) {
57 // Fill the decaying particle in slot 0 of arrays.
62 idProd.push_back( id0 );
63 mProd.push_back( m0 );
65 // Mother flavour - relevant for gamma*/Z0 mixing. (Not always??)
66 int idIn = process[decayer.mother1()].id();
68 // Prepare decay selection.
69 if (!decayer.particleDataEntry().preparePick(id0, m0, idIn)) {
71 osWarn << "for id = " << id0;
72 infoPtr->errorMsg("Error in ResonanceDecays::next:"
73 " no open decay channel", osWarn.str());
77 // Pick a decay channel; allow up to ten tries.
78 bool foundChannel = false;
79 for (int iTryChannel = 0; iTryChannel < NTRYCHANNEL; ++iTryChannel) {
81 // Pick decay channel. Find multiplicity.
82 DecayChannel& channel = decayer.particleDataEntry().pickChannel();
83 mult = channel.multiplicity();
88 for (int i = 1; i <= mult; ++i) {
89 idNow = channel.product(i - 1);
90 if (id0 < 0 && particleDataPtr->hasAnti(idNow)) idNow = -idNow;
91 idProd.push_back( idNow);
94 // Pick masses. Pick new channel if fail.
95 if (!pickMasses()) continue;
100 // Failed to find acceptable decays.
102 ostringstream osWarn;
103 osWarn << "for id = " << id0;
104 infoPtr->errorMsg("Error in ResonanceDecays::next:"
105 " failed to find workable decay channel", osWarn.str());
109 // Select colours in decay.
110 if (!pickColours(iDec, process)) return false;
112 // Select four-momenta in decay, boosted to lab frame.
114 pProd.push_back( decayer.p() );
115 if (!pickKinematics()) return false;
117 // Append decay products to the process event record. Set lifetimes.
118 int iFirst = process.size();
119 for (int i = 1; i <= mult; ++i) {
120 process.append( idProd[i], 23, iDec, 0, 0, 0, cols[i], acols[i],
121 pProd[i], mProd[i], m0);
123 int iLast = process.size() - 1;
125 // Set decay vertex when this is displaced.
126 if (process[iDec].hasVertex() || process[iDec].tau() > 0.) {
127 Vec4 vDec = process[iDec].vDec();
128 for (int i = iFirst; i <= iLast; ++i) process[i].vProd( vDec );
131 // Set lifetime of daughters.
132 for (int i = iFirst; i <= iLast; ++i)
133 process[i].tau( process[i].tau0() * rndmPtr->exp() );
135 // Modify mother status and daughters.
137 decayer.daughters(iFirst, iLast);
139 // End of loop over all entries.
141 } while (++iDec < process.size());
148 //--------------------------------------------------------------------------
150 // Select masses of decay products.
152 bool ResonanceDecays::pickMasses() {
154 // Arrays with properties of particles. Fill with dummy values for mother.
156 vector<double> m0BW, mMinBW, mMaxBW, widthBW;
157 double mMother = mProd[0];
158 double m2Mother = mMother * mMother;
159 useBW.push_back( false );
160 m0BW.push_back( mMother );
161 mMinBW.push_back( mMother );
162 mMaxBW.push_back( mMother );
163 widthBW.push_back( 0. );
165 // Loop throught products for masses and widths. Set nominal mass.
167 double m0Now, mMinNow, mMaxNow, widthNow;
168 for (int i = 1; i <= mult; ++i) {
169 useBWNow = particleDataPtr->useBreitWigner( idProd[i] );
170 m0Now = particleDataPtr->m0( idProd[i] );
171 mMinNow = particleDataPtr->m0Min( idProd[i] );
172 mMaxNow = particleDataPtr->m0Max( idProd[i] );
173 if (useBWNow && mMaxNow < mMinNow) mMaxNow = mMother;
174 widthNow = particleDataPtr->mWidth( idProd[i] );
175 useBW.push_back( useBWNow );
176 m0BW.push_back( m0Now );
177 mMinBW.push_back( mMinNow );
178 mMaxBW.push_back( mMaxNow );
179 widthBW.push_back( widthNow );
180 mProd.push_back( m0Now );
183 // Find number of Breit-Wigners and summed (minimal) masses.
187 for (int i = 1; i <= mult; ++i) {
189 mSum += max( m0BW[i], mMinBW[i]);
190 mSumMin += mMinBW[i];
193 // If sum of minimal masses above mother mass then give up.
194 if (mSumMin + MSAFETY > mMother) return false;
196 // If sum of masses below and no Breit-Wigners then done.
197 if (mSum + 0.5 * MSAFETY < mMother && nBW == 0) return true;
199 // Else if below then retry Breit-Wigners, with simple treshold.
200 if (mSum + MSAFETY < mMother) {
201 double wtMax = 2. * sqrtpos(1. - mSum*mSum / m2Mother);
203 for (int iTryMasses = 0; iTryMasses <= NTRYMASSES; ++ iTryMasses) {
204 if (iTryMasses == NTRYMASSES) return false;
206 for (int i = 1; i <= mult; ++i) {
207 if (useBW[i]) mProd[i] = particleDataPtr->mass( idProd[i] );
210 wt = (mSum + 0.5 * MSAFETY < mMother)
211 ? sqrtpos(1. - mSum*mSum / m2Mother) : 0.;
212 if (wt > rndmPtr->flat() * wtMax) break;
217 // From now on some particles will have to be forced off shell.
219 // Order Breit-Wigners in decreasing widths. Sum of other masses.
222 for (int i = 1; i <= mult; ++i) {
223 if (useBW[i]) iBW.push_back(i);
224 else mSum0 += mProd[i];
226 for (int i = 1; i < nBW; ++i) {
227 for (int j = i - 1; j >= 0; --j) {
228 if (widthBW[iBW[j+1]] > widthBW[iBW[j]]) swap (iBW[j+1], iBW[j]);
233 // Do all but broadest two in increasing-width order. Includes only one.
235 int iMin = (nBW == 1) ? 0 : 2;
236 for (int i = nBW - 1; i >= iMin; --i) {
239 // Find allowed mass range of current resonance.
240 double mMax = mMother - mSum0 - MSAFETY;
241 if (nBW != 1) for (int j = 0; j < i; ++j) mMax -= mMinBW[iBW[j]];
242 mMax = min( mMaxBW[iBWi], mMax );
243 double mMin = min( mMinBW[iBWi], mMax - MSAFETY);
244 if (mMin < 0.) return false;
246 // Parameters for Breit-Wigner choice, with constrained mass range.
247 double m2Nom = pow2( m0BW[iBWi] );
248 double m2Max = mMax * mMax;
249 double m2Min = mMin * mMin;
250 double mmWid = m0BW[iBWi] * widthBW[iBWi];
251 double atanMin = atan( (m2Min - m2Nom) / mmWid );
252 double atanMax = atan( (m2Max - m2Nom) / mmWid );
253 double atanDif = atanMax - atanMin;
255 // Fail if too narrow mass range; e.g. out in tail of Breit-Wigner.
256 if (atanDif < TINYBWRANGE) return false;
258 // Retry mass according to Breit-Wigner, with simple threshold factor.
259 double mr1 = mSum0*mSum0 / m2Mother;
260 double mr2 = m2Min / m2Mother;
261 double wtMax = sqrtpos( pow2(1. - mr1 - mr2) - 4. * mr1 * mr2 );
263 for (int iTryMasses = 0; iTryMasses <= NTRYMASSES; ++ iTryMasses) {
264 if (iTryMasses == NTRYMASSES) return false;
265 m2Now = m2Nom + mmWid * tan(atanMin + rndmPtr->flat() * atanDif);
266 mr2 = m2Now / m2Mother;
267 wt = sqrtpos( pow2(1. - mr1 - mr2) - 4. * mr1 * mr2 );
268 if (wt > rndmPtr->flat() * wtMax) break;
271 // Prepare to iterate for more. Done for one Breit-Wigner.
272 mProd[iBWi] = sqrt(m2Now);
273 mSum0 += mProd[iBWi];
275 if (nBW == 1) return true;
278 // Left to do two broadest Breit-Wigners correlated, i.e. more realistic.
281 int idMother = abs(idProd[0]);
282 int idDau1 = abs(idProd[iBW1]);
283 int idDau2 = abs(idProd[iBW2]);
285 // In some cases known phase-space behaviour; else simple beta factor.
287 if ( (idMother == 25 || idMother == 35) && idDau1 < 19
288 && idDau2 == idDau1 ) psMode = 3;
289 if ( (idMother == 25 || idMother == 35 )
290 && (idDau1 == 23 || idDau1 == 24) && idDau2 == idDau1 ) psMode = 5;
292 && (idDau1 == 23 || idDau1 == 24) && idDau2 == idDau1 ) psMode = 6;
294 // Find allowed mass ranges. Ensure that they are not closed.
295 double mRem = mMother - mSum0 - MSAFETY;
296 double mMax1 = min( mMaxBW[iBW1], mRem - mMinBW[iBW2] );
297 double mMin1 = min( mMinBW[iBW1], mMax1 - MSAFETY);
298 double mMax2 = min( mMaxBW[iBW2], mRem - mMinBW[iBW1] );
299 double mMin2 = min( mMinBW[iBW2], mMax2 - MSAFETY);
301 // At least one range must extend below half remaining mass.
302 if (mMin1 + mMin2 > mRem) return false;
303 double mMid = 0.5 * mRem;
304 bool hasMid1 = (mMin1 < mMid);
305 bool hasMid2 = (mMin2 < mMid);
306 if (!hasMid1 && !hasMid2) return false;
308 // Parameters for Breit-Wigner choice, with constrained mass range.
309 double m2Nom1 = pow2( m0BW[iBW1] );
310 double m2Max1 = mMax1 * mMax1;
311 double m2Min1 = mMin1 * mMin1;
312 double m2Mid1 = min( mMid * mMid, m2Max1);
313 double mmWid1 = m0BW[iBW1] * widthBW[iBW1];
314 double atanMin1 = atan( (m2Min1 - m2Nom1) / mmWid1 );
315 double atanMax1 = atan( (m2Max1 - m2Nom1) / mmWid1 );
316 double atanMid1 = (hasMid1) ? atan( (m2Mid1 - m2Nom1) / mmWid1 ) : 0.;
317 double m2Nom2 = pow2( m0BW[iBW2] );
318 double m2Max2 = mMax2 * mMax2;
319 double m2Min2 = mMin2 * mMin2;
320 double m2Mid2 = min( mMid * mMid, m2Max2);
321 double mmWid2 = m0BW[iBW2] * widthBW[iBW2];
322 double atanMin2 = atan( (m2Min2 - m2Nom2) / mmWid2 );
323 double atanMax2 = atan( (m2Max2 - m2Nom2) / mmWid2 );
324 double atanMid2 = (hasMid2) ? atan( (m2Mid2 - m2Nom2) / mmWid2 ) : 0.;
326 // Relative weight to pick either below half remaining mass.
327 double probLow1 = (hasMid1) ? 1. : 0.;
328 if (hasMid1 && hasMid2) {
329 double intLow1 = (atanMid1 - atanMin1) * (atanMax2 - atanMin2);
330 double intLow2 = (atanMax1 - atanMin1) * (atanMid2 - atanMin2);
331 probLow1 = intLow1 / (intLow1 + intLow2);
334 // Maximum matrix element times phase space weight.
335 double m2Rem = mRem * mRem;
336 double mr1 = m2Min1 / m2Rem;
337 double mr2 = m2Min2 / m2Rem;
338 double psMax = sqrtpos( pow2(1. - mr1 - mr2) - 4. * mr1 * mr2 );
340 if (psMode == 1) wtMax = psMax;
341 else if (psMode == 2) wtMax = psMax * psMax;
342 else if (psMode == 3) wtMax = pow3(psMax);
343 else if (psMode == 5) wtMax = psMax
344 * (pow2(1. - mr1 - mr2) + 8. * mr1 * mr2);
345 else if (psMode == 6) wtMax = pow3(psMax);
347 // Retry mass according to Breit-Wigners, with simple threshold factor.
348 double atanDif1, atanDif2, m2Now1, m2Now2, mNow1, mNow2, ps, wt;
349 for (int iTryMasses = 0; iTryMasses <= NTRYMASSES; ++ iTryMasses) {
350 if (iTryMasses == NTRYMASSES) return false;
352 // Pick either below half remaining mass.
353 bool pickLow1 = false;
354 if (rndmPtr->flat() < probLow1) {
355 atanDif1 = atanMid1 - atanMin1;
356 atanDif2 = atanMax2 - atanMin2;
359 atanDif1 = atanMax1 - atanMin1;
360 atanDif2 = atanMid2 - atanMin2;
362 m2Now1 = m2Nom1 + mmWid1 * tan(atanMin1 + rndmPtr->flat() * atanDif1);
363 m2Now2 = m2Nom2 + mmWid2 * tan(atanMin2 + rndmPtr->flat() * atanDif2);
364 mNow1 = sqrt(m2Now1);
365 mNow2 = sqrt(m2Now2);
367 // Check that intended mass ordering is fulfilled.
368 bool rejectRegion = (pickLow1) ? (mNow1 > mNow2) : (mNow2 > mNow1);
369 if (rejectRegion) continue;
372 mr1 = m2Now1 / m2Rem;
373 mr2 = m2Now2 / m2Rem;
375 if (mNow1 + mNow2 + MSAFETY < mMother) {
376 ps = sqrtpos( pow2(1. - mr1 - mr2) - 4. * mr1 * mr2 );
378 if (psMode == 1) wt = ps;
379 else if (psMode == 2) wt = ps * ps;
380 else if (psMode == 3) wt = pow3(ps);
381 else if (psMode == 5) wt = ps
382 * (pow2(1. - mr1 - mr2) + 8. * mr1 * mr2);
383 else if (psMode == 6) wt = pow3(ps)*mr1*mr2;
385 if (wt > rndmPtr->flat() * wtMax) break;
395 //--------------------------------------------------------------------------
397 // Select colours of decay products.
399 bool ResonanceDecays::pickColours(int iDec, Event& process) {
401 // Reset or create arrays with colour info.
404 vector<int> iTriplet, iAtriplet, iOctet, iDipCol, iDipAcol;
406 // Mother colours already known.
407 int col0 = process[iDec].col();
408 int acol0 = process[iDec].acol();
409 int colType0 = process[iDec].colType();
410 cols.push_back( col0);
411 acols.push_back(acol0);
413 // Loop through all daughters.
415 for (int i = 1; i <= mult; ++i) {
416 // Daughter colours initially empty, so that all is set for singlet.
419 // Find character (singlet, triplet, antitriplet, octet) of daughters.
420 colTypeNow = particleDataPtr->colType( idProd[i] );
421 if (colTypeNow == 0);
422 else if (colTypeNow == 1) iTriplet.push_back(i);
423 else if (colTypeNow == -1) iAtriplet.push_back(i);
424 else if (colTypeNow == 2) iOctet.push_back(i);
425 // Add two entries for sextets;
426 else if (colTypeNow == 3) {
427 iTriplet.push_back(i);
428 iTriplet.push_back(i);
429 } else if (colTypeNow == -3) {
430 iAtriplet.push_back(i);
431 iAtriplet.push_back(i);
433 infoPtr->errorMsg("Error in ResonanceDecays::pickColours:"
434 " unknown colour type encountered");
439 // Check excess of colours and anticolours in final over initial state.
440 int nCol = iTriplet.size();
441 if (colType0 == 1 || colType0 == 2) nCol -= 1;
442 else if (colType0 == 3) nCol -= 2;
443 int nAcol = iAtriplet.size();
444 if (colType0 == -1 || colType0 == 2) nAcol -= 1;
445 else if (colType0 == -3) nAcol -= 2;
447 // If net creation of three colours then find junction kind:
448 // mother is 1 = singlet, triplet, or sextet (no incoming RPV tags)
449 // 3 = antitriplet, octet, or anti-sextet (acol0 = incoming RPV tag)
450 // 5 = not applicable to decays (needs two incoming RPV tags)
451 if (nCol - nAcol == 3) {
452 int kindJun = (colType0 == 0 || colType0 == 1 || colType0 == 3) ? 1 : 3;
454 // Set colours in three junction legs and store junction.
456 colJun[0] = (kindJun == 1) ? process.nextColTag() : acol0;
457 colJun[1] = process.nextColTag();
458 colJun[2] = process.nextColTag();
459 process.appendJunction( kindJun, colJun[0], colJun[1], colJun[2]);
461 // Loop over three legs. Remove an incoming anticolour on first leg.
462 for (int leg = 0; leg < 3; ++leg) {
463 if (leg == 0 && kindJun != 1) acol0 = 0;
465 // Pick final-state triplets to carry these new colours.
467 int pickT = (iTriplet.size() == 1) ? 0
468 : int( TINY + rndmPtr->flat() * (iTriplet.size() - TINY) );
469 int iPickT = iTriplet[pickT];
470 cols[iPickT] = colJun[leg];
472 // Remove matched triplet and store new colour dipole ends.
473 iTriplet[pickT] = iTriplet.back();
475 iDipCol.push_back(iPickT);
476 iDipAcol.push_back(0);
480 // Update colour counter. Done with junction.
484 // If net creation of three anticolours then find antijunction kind:
485 // mother is 2 = singlet, antitriplet, or antisextet (no incoming RPV tags)
486 // 4 = triplet, octet, or sextet (col0 = incoming RPV tag)
487 // 6 = not applicable to decays (needs two incoming RPV tags)
488 if (nAcol - nCol == 3) {
489 int kindJun = (colType0 == 0 || colType0 == -1 || colType0 == -3) ? 2 : 4;
491 // Set anticolours in three antijunction legs and store antijunction.
493 acolJun[0] = (kindJun == 2) ? process.nextColTag() : col0;
494 acolJun[1] = process.nextColTag();
495 acolJun[2] = process.nextColTag();
496 process.appendJunction( kindJun, acolJun[0], acolJun[1], acolJun[2]);
498 // Loop over three legs. Remove an incoming colour on first leg.
499 for (int leg = 0; leg < 3; ++leg) {
500 if (leg == 0 && kindJun != 2) col0 = 0;
502 // Pick final-state antitriplets to carry these new anticolours.
504 int pickA = (iAtriplet.size() == 1) ? 0
505 : int( TINY + rndmPtr->flat() * (iAtriplet.size() - TINY) );
506 int iPickA = iAtriplet[pickA];
507 acols[iPickA] = acolJun[leg];
509 // Remove matched antitriplet and store new colour dipole ends.
510 iAtriplet[pickA] = iAtriplet.back();
511 iAtriplet.pop_back();
512 iDipCol.push_back(0);
513 iDipAcol.push_back(iPickA);
517 // Update anticolour counter. Done with antijunction.
521 // If colours and anticolours do not match now then unphysical.
523 infoPtr->errorMsg("Error in ResonanceDecays::pickColours:"
524 " inconsistent colour tags");
528 // Pick final-state triplet (if any) to carry initial colour.
529 if (col0 > 0 && iTriplet.size() > 0) {
530 int pickT = (iTriplet.size() == 1) ? 0
531 : int( TINY + rndmPtr->flat() * (iTriplet.size() - TINY) );
532 int iPickT = iTriplet[pickT];
535 // Remove matched triplet and store new colour dipole ends.
537 iTriplet[pickT] = iTriplet.back();
539 iDipCol.push_back(iPickT);
540 iDipAcol.push_back(0);
543 // Pick final-state antitriplet (if any) to carry initial anticolour.
544 if (acol0 > 0 && iAtriplet.size() > 0) {
545 int pickA = (iAtriplet.size() == 1) ? 0
546 : int( TINY + rndmPtr->flat() * (iAtriplet.size() - TINY) );
547 int iPickA = iAtriplet[pickA];
548 acols[iPickA] = acol0;
550 // Remove matched antitriplet and store new colour dipole ends.
552 iAtriplet[pickA] = iAtriplet.back();
553 iAtriplet.pop_back();
554 iDipCol.push_back(0);
555 iDipAcol.push_back(iPickA);
558 // Sextets: second final-state triplet (if any)
559 if (acol0 < 0 && iTriplet.size() > 0) {
560 int pickT = (iTriplet.size() == 1) ? 0
561 : int( TINY + rndmPtr->flat() * (iTriplet.size() - TINY) );
562 int iPickT = iTriplet[pickT];
563 cols[iPickT] = -acol0;
565 // Remove matched antitriplet and store new colour dipole ends.
567 iTriplet[pickT] = iTriplet.back();
569 iDipCol.push_back(iPickT);
570 iDipAcol.push_back(0);
573 // Sextets: second final-state antitriplet (if any)
574 if (col0 < 0 && iAtriplet.size() > 0) {
575 int pickA = (iAtriplet.size() == 1) ? 0
576 : int( TINY + rndmPtr->flat() * (iAtriplet.size() - TINY) );
577 int iPickA = iAtriplet[pickA];
578 acols[iPickA] = -col0;
580 // Remove matched triplet and store new colour dipole ends.
582 iAtriplet[pickA] = iAtriplet.back();
583 iAtriplet.pop_back();
584 iDipCol.push_back(0);
585 iDipAcol.push_back(iPickA);
588 // Error checks that amount of leftover colours and anticolours match.
589 if ( (iTriplet.size() != iAtriplet.size())
590 || (col0 != 0 && acol0 == 0) || (col0 == 0 && acol0 != 0) ) {
591 infoPtr->errorMsg("Error in ResonanceDecays::pickColours:"
592 " inconsistent colour tags");
596 // Match triplets to antitriplets in the final state.
597 for (int pickT = 0; pickT < int(iTriplet.size()); ++pickT) {
598 int iPickT = iTriplet[pickT];
599 int pickA = (iAtriplet.size() == 1) ? 0
600 : int( TINY + rndmPtr->flat() * (iAtriplet.size() - TINY) );
601 int iPickA = iAtriplet[pickA];
603 // Connect pair with new colour tag.
604 cols[iPickT] = process.nextColTag();
605 acols[iPickA] = cols[iPickT];
607 // Remove matched antitriplet and store new colour dipole ends.
608 iAtriplet[pickT] = iAtriplet.back();
609 iAtriplet.pop_back();
610 iDipCol.push_back(iPickT);
611 iDipAcol.push_back(iPickA);
614 // If no octets are around then matching is done.
615 if (col0 == 0 && acol0 == 0 && iOctet.size() == 0) return true;
617 // If initial-state octet remains then store as (first!) new dipole.
619 iDipCol.push_back(0);
620 iDipAcol.push_back(0);
623 // Now attach all final-state octets at random to existing dipoles.
624 for (int i = 0; i < int(iOctet.size()); ++i) {
625 int iOct = iOctet[i];
627 // If no dipole then start new one. (Happens for singlet -> octets.)
628 if (iDipCol.size() == 0) {
629 cols[iOct] = process.nextColTag();
630 acols[iOct] = cols[iOct] ;
631 iDipCol.push_back(iOct);
632 iDipAcol.push_back(iOct);
635 // Else attach to existing dipole picked at random.
637 int pickDip = (iDipCol.size() == 1) ? 0
638 : int( TINY + rndmPtr->flat() * (iDipCol.size() - TINY) );
640 // Case with dipole in initial state: reattach existing colours.
641 if (iDipCol[pickDip] == 0 && iDipAcol[pickDip] == 0) {
644 iDipAcol[pickDip] = iOct;
645 iDipCol.push_back(iOct);
646 iDipAcol.push_back(0);
648 // Case with dipole from colour in initial state: also new colour.
649 } else if (iDipAcol[pickDip] == 0) {
650 int iPickCol = iDipCol[pickDip];
651 cols[iOct] = cols[iPickCol];
652 acols[iOct] = process.nextColTag();
653 cols[iPickCol] = acols[iOct];
654 iDipCol[pickDip] = iOct;
655 iDipCol.push_back(iPickCol);
656 iDipAcol.push_back(iOct);
658 // Remaining cases with dipole from anticolour in initial state
659 // or dipole inside final state: also new colour.
661 int iPickAcol = iDipAcol[pickDip];
662 acols[iOct] = acols[iPickAcol];
663 cols[iOct] = process.nextColTag();
664 acols[iPickAcol] = cols[iOct];
665 iDipAcol[pickDip] = iOct;
666 iDipCol.push_back(iOct);
667 iDipAcol.push_back(iPickAcol);
672 // Must now have at least two dipoles (no 1 -> 8 or 8 -> 1).
673 if (iDipCol.size() < 2) {
674 infoPtr->errorMsg("Error in ResonanceDecays::pickColours:"
675 " inconsistent colour tags");
684 //--------------------------------------------------------------------------
686 // Select decay products momenta isotropically in phase space.
687 // Process-dependent angular distributions may be imposed in SigmaProcess.
689 bool ResonanceDecays::pickKinematics() {
691 // Description of two-body decays as simple special case.
696 double m1 = mProd[1];
697 double m2 = mProd[2];
699 // Energies and absolute momentum in the rest frame.
700 double e1 = 0.5 * (m0*m0 + m1*m1 - m2*m2) / m0;
701 double e2 = 0.5 * (m0*m0 + m2*m2 - m1*m1) / m0;
702 double pAbs = 0.5 * sqrtpos( (m0 - m1 - m2) * (m0 + m1 + m2)
703 * (m0 + m1 - m2) * (m0 - m1 + m2) ) / m0;
705 // Pick isotropic angles to give three-momentum.
706 double cosTheta = 2. * rndmPtr->flat() - 1.;
707 double sinTheta = sqrt(1. - cosTheta*cosTheta);
708 double phi = 2. * M_PI * rndmPtr->flat();
709 double pX = pAbs * sinTheta * cos(phi);
710 double pY = pAbs * sinTheta * sin(phi);
711 double pZ = pAbs * cosTheta;
713 // Fill four-momenta in mother rest frame and then boost to lab frame.
714 pProd.push_back( Vec4( pX, pY, pZ, e1) );
715 pProd.push_back( Vec4( -pX, -pY, -pZ, e2) );
716 pProd[1].bst( pProd[0] );
717 pProd[2].bst( pProd[0] );
719 // Done for two-body decay.
723 // Description of three-body decays as semi-simple special case.
728 double m1 = mProd[1];
729 double m2 = mProd[2];
730 double m3 = mProd[3];
731 double mDiff = m0 - (m1 + m2 + m3);
733 // Kinematical limits for 2+3 mass. Maximum phase-space weight.
734 double m23Min = m2 + m3;
735 double m23Max = m0 - m1;
736 double p1Max = 0.5 * sqrtpos( (m0 - m1 - m23Min) * (m0 + m1 + m23Min)
737 * (m0 + m1 - m23Min) * (m0 - m1 + m23Min) ) / m0;
738 double p23Max = 0.5 * sqrtpos( (m23Max - m2 - m3) * (m23Max + m2 + m3)
739 * (m23Max + m2 - m3) * (m23Max - m2 + m3) ) / m23Max;
740 double wtPSmax = 0.5 * p1Max * p23Max;
742 // Pick an intermediate mass m23 flat in the allowed range.
743 double wtPS, m23, p1Abs, p23Abs;
745 m23 = m23Min + rndmPtr->flat() * mDiff;
747 // Translate into relative momenta and find phase-space weight.
748 p1Abs = 0.5 * sqrtpos( (m0 - m1 - m23) * (m0 + m1 + m23)
749 * (m0 + m1 - m23) * (m0 - m1 + m23) ) / m0;
750 p23Abs = 0.5 * sqrtpos( (m23 - m2 - m3) * (m23 + m2 + m3)
751 * (m23 + m2 - m3) * (m23 - m2 + m3) ) / m23;
752 wtPS = p1Abs * p23Abs;
754 // If rejected, try again with new invariant masses.
755 } while ( wtPS < rndmPtr->flat() * wtPSmax );
757 // Set up m23 -> m2 + m3 isotropic in its rest frame.
758 double cosTheta = 2. * rndmPtr->flat() - 1.;
759 double sinTheta = sqrt(1. - cosTheta*cosTheta);
760 double phi = 2. * M_PI * rndmPtr->flat();
761 double pX = p23Abs * sinTheta * cos(phi);
762 double pY = p23Abs * sinTheta * sin(phi);
763 double pZ = p23Abs * cosTheta;
764 double e2 = sqrt( m2*m2 + p23Abs*p23Abs);
765 double e3 = sqrt( m3*m3 + p23Abs*p23Abs);
766 Vec4 p2( pX, pY, pZ, e2);
767 Vec4 p3( -pX, -pY, -pZ, e3);
769 // Set up 0 -> 1 + 23 isotropic in its rest frame.
770 cosTheta = 2. * rndmPtr->flat() - 1.;
771 sinTheta = sqrt(1. - cosTheta*cosTheta);
772 phi = 2. * M_PI * rndmPtr->flat();
773 pX = p1Abs * sinTheta * cos(phi);
774 pY = p1Abs * sinTheta * sin(phi);
775 pZ = p1Abs * cosTheta;
776 double e1 = sqrt( m1*m1 + p1Abs*p1Abs);
777 double e23 = sqrt( m23*m23 + p1Abs*p1Abs);
778 pProd.push_back( Vec4( pX, pY, pZ, e1) );
780 // Boost 2 + 3 to the 0 rest frame and then boost to lab frame.
781 Vec4 p23( -pX, -pY, -pZ, e23);
784 pProd.push_back( p2 );
785 pProd.push_back( p3 );
786 pProd[1].bst( pProd[0] );
787 pProd[2].bst( pProd[0] );
788 pProd[3].bst( pProd[0] );
790 // Done for three-body decay.
794 // Do a multibody decay using the M-generator algorithm.
796 // Mother and sum daughter masses.
798 double mSum = mProd[1];
799 for (int i = 2; i <= mult; ++i) mSum += mProd[i];
800 double mDiff = m0 - mSum;
802 // Begin setup of intermediate invariant masses.
804 for (int i = 0; i <= mult; ++i) mInv.push_back( mProd[i]);
806 // Calculate the maximum weight in the decay.
807 double wtPSmax = 1. / WTCORRECTION[mult];
808 double mMax = mDiff + mProd[mult];
810 for (int i = mult - 1; i > 0; --i) {
813 double mNow = mProd[i];
814 wtPSmax *= 0.5 * sqrtpos( (mMax - mMin - mNow) * (mMax + mMin + mNow)
815 * (mMax + mMin - mNow) * (mMax - mMin + mNow) ) / mMax;
818 // Begin loop to find the set of intermediate invariant masses.
819 vector<double> rndmOrd;
824 // Find and order random numbers in descending order.
826 rndmOrd.push_back(1.);
827 for (int i = 1; i < mult - 1; ++i) {
828 double rndm = rndmPtr->flat();
829 rndmOrd.push_back(rndm);
830 for (int j = i - 1; j > 0; --j) {
831 if (rndm > rndmOrd[j]) swap( rndmOrd[j], rndmOrd[j+1] );
835 rndmOrd.push_back(0.);
837 // Translate into intermediate masses and find weight.
838 for (int i = mult - 1; i > 0; --i) {
839 mInv[i] = mInv[i+1] + mProd[i] + (rndmOrd[i-1] - rndmOrd[i]) * mDiff;
840 wtPS *= 0.5 * sqrtpos( (mInv[i] - mInv[i+1] - mProd[i])
841 * (mInv[i] + mInv[i+1] + mProd[i]) * (mInv[i] + mInv[i+1] - mProd[i])
842 * (mInv[i] - mInv[i+1] + mProd[i]) ) / mInv[i];
845 // If rejected, try again with new invariant masses.
846 } while ( wtPS < rndmPtr->flat() * wtPSmax );
848 // Perform two-particle decays in the respective rest frame.
850 pInv.resize(mult + 1);
851 for (int i = 1; i < mult; ++i) {
852 double pAbs = 0.5 * sqrtpos( (mInv[i] - mInv[i+1] - mProd[i])
853 * (mInv[i] + mInv[i+1] + mProd[i]) * (mInv[i] + mInv[i+1] - mProd[i])
854 * (mInv[i] - mInv[i+1] + mProd[i]) ) / mInv[i];
856 // Isotropic angles give three-momentum.
857 double cosTheta = 2. * rndmPtr->flat() - 1.;
858 double sinTheta = sqrt(1. - cosTheta*cosTheta);
859 double phi = 2. * M_PI * rndmPtr->flat();
860 double pX = pAbs * sinTheta * cos(phi);
861 double pY = pAbs * sinTheta * sin(phi);
862 double pZ = pAbs * cosTheta;
864 // Calculate energies, fill four-momenta.
865 double eHad = sqrt( mProd[i]*mProd[i] + pAbs*pAbs);
866 double eInv = sqrt( mInv[i+1]*mInv[i+1] + pAbs*pAbs);
867 pProd.push_back( Vec4( pX, pY, pZ, eHad) );
868 pInv[i+1].p( -pX, -pY, -pZ, eInv);
870 pProd.push_back( pInv[mult] );
872 // Boost decay products to the mother rest frame and on to lab frame.
874 for (int iFrame = mult - 1; iFrame > 0; --iFrame)
875 for (int i = iFrame; i <= mult; ++i) pProd[i].bst(pInv[iFrame]);
877 // Done for multibody decay.
882 //==========================================================================
884 } // end namespace Pythia8