9 #include "ResonanceDecays.h"
24 const int ResonanceDecays::NTRYCHANNEL = 10;
27 const int ResonanceDecays::NTRYMASSES = 10000;
30 const double ResonanceDecays::MSAFETY = 0.1;
33 const double ResonanceDecays::WIDTHCUT = 5.;
36 const double ResonanceDecays::TINY = 1e-10;
39 const double ResonanceDecays::TINYBWRANGE = 1e-8;
43 const double ResonanceDecays::WTCORRECTION[11] = { 1., 1., 1.,
44 2., 5., 15., 60., 250., 1250., 7000., 50000. };
48 bool ResonanceDecays::next(
Event& process) {
53 Particle& decayer = process[iDec];
54 if (decayer.isFinal() && decayer.canDecay() && decayer.mayDecay()
55 && decayer.isResonance() ) {
62 idProd.push_back( id0 );
63 mProd.push_back( m0 );
66 int idIn = process[decayer.mother1()].id();
69 decayer.particleDataEntry().preparePick(id0, m0, idIn);
72 bool foundChannel =
false;
73 for (
int iTryChannel = 0; iTryChannel < NTRYCHANNEL; ++iTryChannel) {
76 DecayChannel& channel = decayer.particleDataEntry().pickChannel();
77 mult = channel.multiplicity();
82 for (
int i = 1; i <= mult; ++i) {
83 idNow = channel.product(i - 1);
84 if (id0 < 0 && particleDataPtr->hasAnti(idNow)) idNow = -idNow;
85 idProd.push_back( idNow);
89 if (!pickMasses())
continue;
96 infoPtr->errorMsg(
"Error in ResonanceDecays::next:"
97 " failed to find workable decay channel");
102 if (!pickColours(iDec, process))
return false;
106 pProd.push_back( decayer.p() );
107 if (!pickKinematics())
return false;
110 int iFirst = process.size();
111 for (
int i = 1; i <= mult; ++i) {
112 process.append( idProd[i], 23, iDec, 0, 0, 0, cols[i], acols[i],
113 pProd[i], mProd[i], m0);
115 int iLast = process.size() - 1;
118 if (process[iDec].hasVertex() || process[iDec].tau() > 0.) {
119 Vec4 vDec = process[iDec].vDec();
120 for (
int i = iFirst; i <= iLast; ++i) process[i].vProd( vDec );
124 for (
int i = iFirst; i <= iLast; ++i)
125 process[i].tau( process[i].tau0() * rndmPtr->exp() );
129 decayer.daughters(iFirst, iLast);
133 }
while (++iDec < process.size());
144 bool ResonanceDecays::pickMasses() {
148 vector<double> m0BW, mMinBW, mMaxBW, widthBW;
149 double mMother = mProd[0];
150 double m2Mother = mMother * mMother;
151 useBW.push_back(
false );
152 m0BW.push_back( mMother );
153 mMinBW.push_back( mMother );
154 mMaxBW.push_back( mMother );
155 widthBW.push_back( 0. );
159 double m0Now, mMinNow, mMaxNow, widthNow;
160 for (
int i = 1; i <= mult; ++i) {
161 useBWNow = particleDataPtr->useBreitWigner( idProd[i] );
162 m0Now = particleDataPtr->m0( idProd[i] );
163 mMinNow = particleDataPtr->m0Min( idProd[i] );
164 mMaxNow = particleDataPtr->m0Max( idProd[i] );
165 if (useBWNow && mMaxNow < mMinNow) mMaxNow = mMother;
166 widthNow = particleDataPtr->mWidth( idProd[i] );
167 useBW.push_back( useBWNow );
168 m0BW.push_back( m0Now );
169 mMinBW.push_back( mMinNow );
170 mMaxBW.push_back( mMaxNow );
171 widthBW.push_back( widthNow );
172 mProd.push_back( m0Now );
179 for (
int i = 1; i <= mult; ++i) {
181 mSum += max( m0BW[i], mMinBW[i]);
182 mSumMin += mMinBW[i];
186 if (mSumMin + MSAFETY > mMother)
return false;
189 if (mSum + 0.5 * MSAFETY < mMother && nBW == 0)
return true;
192 if (mSum + MSAFETY < mMother) {
193 double wtMax = 2. * sqrtpos(1. - mSum*mSum / m2Mother);
195 for (
int iTryMasses = 0; iTryMasses <= NTRYMASSES; ++ iTryMasses) {
196 if (iTryMasses == NTRYMASSES)
return false;
198 for (
int i = 1; i <= mult; ++i) {
199 if (useBW[i]) mProd[i] = particleDataPtr->mass( idProd[i] );
202 wt = (mSum + 0.5 * MSAFETY < mMother)
203 ? sqrtpos(1. - mSum*mSum / m2Mother) : 0.;
204 if (wt > rndmPtr->flat() * wtMax)
break;
214 for (
int i = 1; i <= mult; ++i) {
215 if (useBW[i]) iBW.push_back(i);
216 else mSum0 += mProd[i];
218 for (
int i = 1; i < nBW; ++i) {
219 for (
int j = i - 1; j >= 0; --j) {
220 if (widthBW[iBW[j+1]] > widthBW[iBW[j]]) swap (iBW[j+1], iBW[j]);
227 int iMin = (nBW == 1) ? 0 : 2;
228 for (
int i = nBW - 1; i >= iMin; --i) {
232 double mMax = mMother - mSum0 - MSAFETY;
233 if (nBW != 1)
for (
int j = 0; j < i; ++j) mMax -= mMinBW[iBW[j]];
234 mMax = min( mMaxBW[iBWi], mMax );
235 double mMin = min( mMinBW[iBWi], mMax - MSAFETY);
236 if (mMin < 0.)
return false;
239 double m2Nom = pow2( m0BW[iBWi] );
240 double m2Max = mMax * mMax;
241 double m2Min = mMin * mMin;
242 double mmWid = m0BW[iBWi] * widthBW[iBWi];
243 double atanMin = atan( (m2Min - m2Nom) / mmWid );
244 double atanMax = atan( (m2Max - m2Nom) / mmWid );
245 double atanDif = atanMax - atanMin;
248 if (atanDif < TINYBWRANGE)
return false;
251 double mr1 = mSum0*mSum0 / m2Mother;
252 double mr2 = m2Min / m2Mother;
253 double wtMax = sqrtpos( pow2(1. - mr1 - mr2) - 4. * mr1 * mr2 );
255 for (
int iTryMasses = 0; iTryMasses <= NTRYMASSES; ++ iTryMasses) {
256 if (iTryMasses == NTRYMASSES)
return false;
257 m2Now = m2Nom + mmWid * tan(atanMin + rndmPtr->flat() * atanDif);
258 mr2 = m2Now / m2Mother;
259 wt = sqrtpos( pow2(1. - mr1 - mr2) - 4. * mr1 * mr2 );
260 if (wt > rndmPtr->flat() * wtMax)
break;
264 mProd[iBWi] = sqrt(m2Now);
265 mSum0 += mProd[iBWi];
267 if (nBW == 1)
return true;
273 int idMother = abs(idProd[0]);
274 int idDau1 = abs(idProd[iBW1]);
275 int idDau2 = abs(idProd[iBW2]);
279 if ( (idMother == 25 || idMother == 35) && idDau1 < 19
280 && idDau2 == idDau1 ) psMode = 3;
281 if ( (idMother == 25 || idMother == 35 )
282 && (idDau1 == 23 || idDau1 == 24) && idDau2 == idDau1 ) psMode = 5;
284 && (idDau1 == 23 || idDau1 == 24) && idDau2 == idDau1 ) psMode = 6;
287 double mRem = mMother - mSum0 - MSAFETY;
288 double mMax1 = min( mMaxBW[iBW1], mRem - mMinBW[iBW2] );
289 double mMin1 = min( mMinBW[iBW1], mMax1 - MSAFETY);
290 double mMax2 = min( mMaxBW[iBW2], mRem - mMinBW[iBW1] );
291 double mMin2 = min( mMinBW[iBW2], mMax2 - MSAFETY);
294 if (mMin1 + mMin2 > mRem)
return false;
295 double mMid = 0.5 * mRem;
296 bool hasMid1 = (mMin1 < mMid);
297 bool hasMid2 = (mMin2 < mMid);
298 if (!hasMid1 && !hasMid2)
return false;
301 double m2Nom1 = pow2( m0BW[iBW1] );
302 double m2Max1 = mMax1 * mMax1;
303 double m2Min1 = mMin1 * mMin1;
304 double m2Mid1 = min( mMid * mMid, m2Max1);
305 double mmWid1 = m0BW[iBW1] * widthBW[iBW1];
306 double atanMin1 = atan( (m2Min1 - m2Nom1) / mmWid1 );
307 double atanMax1 = atan( (m2Max1 - m2Nom1) / mmWid1 );
308 double atanMid1 = (hasMid1) ? atan( (m2Mid1 - m2Nom1) / mmWid1 ) : 0.;
309 double m2Nom2 = pow2( m0BW[iBW2] );
310 double m2Max2 = mMax2 * mMax2;
311 double m2Min2 = mMin2 * mMin2;
312 double m2Mid2 = min( mMid * mMid, m2Max2);
313 double mmWid2 = m0BW[iBW2] * widthBW[iBW2];
314 double atanMin2 = atan( (m2Min2 - m2Nom2) / mmWid2 );
315 double atanMax2 = atan( (m2Max2 - m2Nom2) / mmWid2 );
316 double atanMid2 = (hasMid2) ? atan( (m2Mid2 - m2Nom2) / mmWid2 ) : 0.;
319 double probLow1 = (hasMid1) ? 1. : 0.;
320 if (hasMid1 && hasMid2) {
321 double intLow1 = (atanMid1 - atanMin1) * (atanMax2 - atanMin2);
322 double intLow2 = (atanMax1 - atanMin1) * (atanMid2 - atanMin2);
323 probLow1 = intLow1 / (intLow1 + intLow2);
327 double m2Rem = mRem * mRem;
328 double mr1 = m2Min1 / m2Rem;
329 double mr2 = m2Min2 / m2Rem;
330 double psMax = sqrtpos( pow2(1. - mr1 - mr2) - 4. * mr1 * mr2 );
332 if (psMode == 1) wtMax = psMax;
333 else if (psMode == 2) wtMax = psMax * psMax;
334 else if (psMode == 3) wtMax = pow3(psMax);
335 else if (psMode == 5) wtMax = psMax
336 * (pow2(1. - mr1 - mr2) + 8. * mr1 * mr2);
337 else if (psMode == 6) wtMax = pow3(psMax);
340 double atanDif1, atanDif2, m2Now1, m2Now2, mNow1, mNow2, ps, wt;
341 for (
int iTryMasses = 0; iTryMasses <= NTRYMASSES; ++ iTryMasses) {
342 if (iTryMasses == NTRYMASSES)
return false;
345 bool pickLow1 =
false;
346 if (rndmPtr->flat() < probLow1) {
347 atanDif1 = atanMid1 - atanMin1;
348 atanDif2 = atanMax2 - atanMin2;
351 atanDif1 = atanMax1 - atanMin1;
352 atanDif2 = atanMid2 - atanMin2;
354 m2Now1 = m2Nom1 + mmWid1 * tan(atanMin1 + rndmPtr->flat() * atanDif1);
355 m2Now2 = m2Nom2 + mmWid2 * tan(atanMin2 + rndmPtr->flat() * atanDif2);
356 mNow1 = sqrt(m2Now1);
357 mNow2 = sqrt(m2Now2);
360 bool rejectRegion = (pickLow1) ? (mNow1 > mNow2) : (mNow2 > mNow1);
361 if (rejectRegion)
continue;
364 mr1 = m2Now1 / m2Rem;
365 mr2 = m2Now2 / m2Rem;
367 if (mNow1 + mNow2 + MSAFETY < mMother) {
368 ps = sqrtpos( pow2(1. - mr1 - mr2) - 4. * mr1 * mr2 );
370 if (psMode == 1) wt = ps;
371 else if (psMode == 2) wt = ps * ps;
372 else if (psMode == 3) wt = pow3(ps);
373 else if (psMode == 5) wt = ps
374 * (pow2(1. - mr1 - mr2) + 8. * mr1 * mr2);
375 else if (psMode == 6) wt = pow3(ps)*mr1*mr2;
377 if (wt > rndmPtr->flat() * wtMax)
break;
391 bool ResonanceDecays::pickColours(
int iDec,
Event& process) {
396 vector<int> iTriplet, iAtriplet, iOctet, iDipCol, iDipAcol;
399 int col0 = process[iDec].col();
400 int acol0 = process[iDec].acol();
401 int colType0 = process[iDec].colType();
402 cols.push_back( col0);
403 acols.push_back(acol0);
407 for (
int i = 1; i <= mult; ++i) {
412 colTypeNow = particleDataPtr->colType( idProd[i] );
413 if (colTypeNow == 0);
414 else if (colTypeNow == 1) iTriplet.push_back(i);
415 else if (colTypeNow == -1) iAtriplet.push_back(i);
416 else if (colTypeNow == 2) iOctet.push_back(i);
418 else if (colTypeNow == 3) {
419 iTriplet.push_back(i);
420 iTriplet.push_back(i);
421 }
else if (colTypeNow == -3) {
422 iAtriplet.push_back(i);
423 iAtriplet.push_back(i);
425 infoPtr->errorMsg(
"Error in ResonanceDecays::pickColours:"
426 " unknown colour type encountered");
432 int nCol = iTriplet.size();
433 if (colType0 == 1 || colType0 == 2) nCol -= 1;
434 else if (colType0 == 3) nCol -= 2;
435 int nAcol = iAtriplet.size();
436 if (colType0 == -1 || colType0 == 2) nAcol -= 1;
437 else if (colType0 == -3) nAcol -= 2;
441 if (nCol - nAcol == 3) {
442 int kindJun = (col0 == 0) ? ((acol0 == 0) ? 1 : 3) : 5;
446 colJun[0] = (kindJun == 1) ? process.nextColTag() : acol0;
447 colJun[1] = process.nextColTag();
448 colJun[2] = process.nextColTag();
449 process.appendJunction( kindJun, colJun[0], colJun[1], colJun[2]);
452 for (
int leg = 0; leg < 3; ++leg) {
453 if (leg == 0 && kindJun != 1) acol0 = 0;
457 int pickT = (iTriplet.size() == 1) ? 0
458 :
int( TINY + rndmPtr->flat() * (iTriplet.size() - TINY) );
459 int iPickT = iTriplet[pickT];
460 cols[iPickT] = colJun[leg];
463 iTriplet[pickT] = iTriplet.back();
465 iDipCol.push_back(iPickT);
466 iDipAcol.push_back(0);
476 if (nAcol - nCol == 3) {
477 int kindJun = (acol0 == 0) ? ((col0 == 0) ? 2 : 4) : 6;
481 acolJun[0] = (kindJun == 2) ? process.nextColTag() : col0;
482 acolJun[1] = process.nextColTag();
483 acolJun[2] = process.nextColTag();
484 process.appendJunction( kindJun, acolJun[0], acolJun[1], acolJun[2]);
487 for (
int leg = 0; leg < 3; ++leg) {
488 if (leg == 0 && kindJun != 2) col0 = 0;
492 int pickA = (iAtriplet.size() == 1) ? 0
493 :
int( TINY + rndmPtr->flat() * (iAtriplet.size() - TINY) );
494 int iPickA = iAtriplet[pickA];
495 acols[iPickA] = acolJun[leg];
498 iAtriplet[pickA] = iAtriplet.back();
499 iAtriplet.pop_back();
500 iDipCol.push_back(0);
501 iDipAcol.push_back(iPickA);
511 infoPtr->errorMsg(
"Error in ResonanceDecays::pickColours:"
512 " inconsistent colour tags");
517 if (col0 > 0 && iTriplet.size() > 0) {
518 int pickT = (iTriplet.size() == 1) ? 0
519 :
int( TINY + rndmPtr->flat() * (iTriplet.size() - TINY) );
520 int iPickT = iTriplet[pickT];
525 iTriplet[pickT] = iTriplet.back();
527 iDipCol.push_back(iPickT);
528 iDipAcol.push_back(0);
532 if (acol0 > 0 && iAtriplet.size() > 0) {
533 int pickA = (iAtriplet.size() == 1) ? 0
534 :
int( TINY + rndmPtr->flat() * (iAtriplet.size() - TINY) );
535 int iPickA = iAtriplet[pickA];
536 acols[iPickA] = acol0;
540 iAtriplet[pickA] = iAtriplet.back();
541 iAtriplet.pop_back();
542 iDipCol.push_back(0);
543 iDipAcol.push_back(iPickA);
547 if (acol0 < 0 && iTriplet.size() > 0) {
548 int pickT = (iTriplet.size() == 1) ? 0
549 :
int( TINY + rndmPtr->flat() * (iTriplet.size() - TINY) );
550 int iPickT = iTriplet[pickT];
551 cols[iPickT] = -acol0;
555 iTriplet[pickT] = iTriplet.back();
557 iDipCol.push_back(iPickT);
558 iDipAcol.push_back(0);
562 if (col0 < 0 && iAtriplet.size() > 0) {
563 int pickA = (iAtriplet.size() == 1) ? 0
564 :
int( TINY + rndmPtr->flat() * (iAtriplet.size() - TINY) );
565 int iPickA = iAtriplet[pickA];
566 acols[iPickA] = -col0;
570 iAtriplet[pickA] = iAtriplet.back();
571 iAtriplet.pop_back();
572 iDipCol.push_back(0);
573 iDipAcol.push_back(iPickA);
577 if ( (iTriplet.size() != iAtriplet.size())
578 || (col0 != 0 && acol0 == 0) || (col0 == 0 && acol0 != 0) ) {
579 infoPtr->errorMsg(
"Error in ResonanceDecays::pickColours:"
580 " inconsistent colour tags");
585 for (
int pickT = 0; pickT < int(iTriplet.size()); ++pickT) {
586 int iPickT = iTriplet[pickT];
587 int pickA = (iAtriplet.size() == 1) ? 0
588 :
int( TINY + rndmPtr->flat() * (iAtriplet.size() - TINY) );
589 int iPickA = iAtriplet[pickA];
592 cols[iPickT] = process.nextColTag();
593 acols[iPickA] = cols[iPickT];
596 iAtriplet[pickT] = iAtriplet.back();
597 iAtriplet.pop_back();
598 iDipCol.push_back(iPickT);
599 iDipAcol.push_back(iPickA);
603 if (col0 == 0 && acol0 == 0 && iOctet.size() == 0)
return true;
607 iDipCol.push_back(0);
608 iDipAcol.push_back(0);
612 for (
int i = 0; i < int(iOctet.size()); ++i) {
613 int iOct = iOctet[i];
616 if (iDipCol.size() == 0) {
617 cols[iOct] = process.nextColTag();
618 acols[iOct] = cols[iOct] ;
619 iDipCol.push_back(iOct);
620 iDipAcol.push_back(iOct);
625 int pickDip = (iDipCol.size() == 1) ? 0
626 :
int( TINY + rndmPtr->flat() * (iDipCol.size() - TINY) );
629 if (iDipCol[pickDip] == 0 && iDipAcol[pickDip] == 0) {
632 iDipAcol[pickDip] = iOct;
633 iDipCol.push_back(iOct);
634 iDipAcol.push_back(0);
637 }
else if (iDipAcol[pickDip] == 0) {
638 int iPickCol = iDipCol[pickDip];
639 cols[iOct] = cols[iPickCol];
640 acols[iOct] = process.nextColTag();
641 cols[iPickCol] = acols[iOct];
642 iDipCol[pickDip] = iOct;
643 iDipCol.push_back(iPickCol);
644 iDipAcol.push_back(iOct);
649 int iPickAcol = iDipAcol[pickDip];
650 acols[iOct] = acols[iPickAcol];
651 cols[iOct] = process.nextColTag();
652 acols[iPickAcol] = cols[iOct];
653 iDipAcol[pickDip] = iOct;
654 iDipCol.push_back(iOct);
655 iDipAcol.push_back(iPickAcol);
661 if (iDipCol.size() < 2) {
662 infoPtr->errorMsg(
"Error in ResonanceDecays::pickColours:"
663 " inconsistent colour tags");
677 bool ResonanceDecays::pickKinematics() {
684 double m1 = mProd[1];
685 double m2 = mProd[2];
688 double e1 = 0.5 * (m0*m0 + m1*m1 - m2*m2) / m0;
689 double e2 = 0.5 * (m0*m0 + m2*m2 - m1*m1) / m0;
690 double pAbs = 0.5 * sqrtpos( (m0 - m1 - m2) * (m0 + m1 + m2)
691 * (m0 + m1 - m2) * (m0 - m1 + m2) ) / m0;
694 double cosTheta = 2. * rndmPtr->flat() - 1.;
695 double sinTheta = sqrt(1. - cosTheta*cosTheta);
696 double phi = 2. * M_PI * rndmPtr->flat();
697 double pX = pAbs * sinTheta * cos(phi);
698 double pY = pAbs * sinTheta * sin(phi);
699 double pZ = pAbs * cosTheta;
702 pProd.push_back( Vec4( pX, pY, pZ, e1) );
703 pProd.push_back( Vec4( -pX, -pY, -pZ, e2) );
704 pProd[1].bst( pProd[0] );
705 pProd[2].bst( pProd[0] );
716 double m1 = mProd[1];
717 double m2 = mProd[2];
718 double m3 = mProd[3];
719 double mDiff = m0 - (m1 + m2 + m3);
722 double m23Min = m2 + m3;
723 double m23Max = m0 - m1;
724 double p1Max = 0.5 * sqrtpos( (m0 - m1 - m23Min) * (m0 + m1 + m23Min)
725 * (m0 + m1 - m23Min) * (m0 - m1 + m23Min) ) / m0;
726 double p23Max = 0.5 * sqrtpos( (m23Max - m2 - m3) * (m23Max + m2 + m3)
727 * (m23Max + m2 - m3) * (m23Max - m2 + m3) ) / m23Max;
728 double wtPSmax = 0.5 * p1Max * p23Max;
731 double wtPS, m23, p1Abs, p23Abs;
733 m23 = m23Min + rndmPtr->flat() * mDiff;
736 p1Abs = 0.5 * sqrtpos( (m0 - m1 - m23) * (m0 + m1 + m23)
737 * (m0 + m1 - m23) * (m0 - m1 + m23) ) / m0;
738 p23Abs = 0.5 * sqrtpos( (m23 - m2 - m3) * (m23 + m2 + m3)
739 * (m23 + m2 - m3) * (m23 - m2 + m3) ) / m23;
740 wtPS = p1Abs * p23Abs;
743 }
while ( wtPS < rndmPtr->flat() * wtPSmax );
746 double cosTheta = 2. * rndmPtr->flat() - 1.;
747 double sinTheta = sqrt(1. - cosTheta*cosTheta);
748 double phi = 2. * M_PI * rndmPtr->flat();
749 double pX = p23Abs * sinTheta * cos(phi);
750 double pY = p23Abs * sinTheta * sin(phi);
751 double pZ = p23Abs * cosTheta;
752 double e2 = sqrt( m2*m2 + p23Abs*p23Abs);
753 double e3 = sqrt( m3*m3 + p23Abs*p23Abs);
754 Vec4 p2( pX, pY, pZ, e2);
755 Vec4 p3( -pX, -pY, -pZ, e3);
758 cosTheta = 2. * rndmPtr->flat() - 1.;
759 sinTheta = sqrt(1. - cosTheta*cosTheta);
760 phi = 2. * M_PI * rndmPtr->flat();
761 pX = p1Abs * sinTheta * cos(phi);
762 pY = p1Abs * sinTheta * sin(phi);
763 pZ = p1Abs * cosTheta;
764 double e1 = sqrt( m1*m1 + p1Abs*p1Abs);
765 double e23 = sqrt( m23*m23 + p1Abs*p1Abs);
766 pProd.push_back( Vec4( pX, pY, pZ, e1) );
769 Vec4 p23( -pX, -pY, -pZ, e23);
772 pProd.push_back( p2 );
773 pProd.push_back( p3 );
774 pProd[1].bst( pProd[0] );
775 pProd[2].bst( pProd[0] );
776 pProd[3].bst( pProd[0] );
786 double mSum = mProd[1];
787 for (
int i = 2; i <= mult; ++i) mSum += mProd[i];
788 double mDiff = m0 - mSum;
792 for (
int i = 0; i <= mult; ++i) mInv.push_back( mProd[i]);
795 double wtPSmax = 1. / WTCORRECTION[mult];
796 double mMax = mDiff + mProd[mult];
798 for (
int i = mult - 1; i > 0; --i) {
801 double mNow = mProd[i];
802 wtPSmax *= 0.5 * sqrtpos( (mMax - mMin - mNow) * (mMax + mMin + mNow)
803 * (mMax + mMin - mNow) * (mMax - mMin + mNow) ) / mMax;
807 vector<double> rndmOrd;
814 rndmOrd.push_back(1.);
815 for (
int i = 1; i < mult - 1; ++i) {
816 double rndm = rndmPtr->flat();
817 rndmOrd.push_back(rndm);
818 for (
int j = i - 1; j > 0; --j) {
819 if (rndm > rndmOrd[j]) swap( rndmOrd[j], rndmOrd[j+1] );
823 rndmOrd.push_back(0.);
826 for (
int i = mult - 1; i > 0; --i) {
827 mInv[i] = mInv[i+1] + mProd[i] + (rndmOrd[i-1] - rndmOrd[i]) * mDiff;
828 wtPS *= 0.5 * sqrtpos( (mInv[i] - mInv[i+1] - mProd[i])
829 * (mInv[i] + mInv[i+1] + mProd[i]) * (mInv[i] + mInv[i+1] - mProd[i])
830 * (mInv[i] - mInv[i+1] + mProd[i]) ) / mInv[i];
834 }
while ( wtPS < rndmPtr->flat() * wtPSmax );
838 pInv.resize(mult + 1);
839 for (
int i = 1; i < mult; ++i) {
840 double pAbs = 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 double cosTheta = 2. * rndmPtr->flat() - 1.;
846 double sinTheta = sqrt(1. - cosTheta*cosTheta);
847 double phi = 2. * M_PI * rndmPtr->flat();
848 double pX = pAbs * sinTheta * cos(phi);
849 double pY = pAbs * sinTheta * sin(phi);
850 double pZ = pAbs * cosTheta;
853 double eHad = sqrt( mProd[i]*mProd[i] + pAbs*pAbs);
854 double eInv = sqrt( mInv[i+1]*mInv[i+1] + pAbs*pAbs);
855 pProd.push_back( Vec4( pX, pY, pZ, eHad) );
856 pInv[i+1].p( -pX, -pY, -pZ, eInv);
858 pProd.push_back( pInv[mult] );
862 for (
int iFrame = mult - 1; iFrame > 0; --iFrame)
863 for (
int i = iFrame; i <= mult; ++i) pProd[i].bst(pInv[iFrame]);