8 #include "Pythia8/PartonLevel.h"
22 const int PartonLevel::NTRY = 10;
28 bool PartonLevel::init( Info* infoPtrIn, Settings& settings,
29 ParticleData* particleDataPtrIn, Rndm* rndmPtrIn,
30 BeamParticle* beamAPtrIn, BeamParticle* beamBPtrIn,
31 BeamParticle* beamPomAPtrIn, BeamParticle* beamPomBPtrIn,
32 Couplings* couplingsPtrIn, PartonSystems* partonSystemsPtrIn,
33 SigmaTotal* sigmaTotPtr, TimeShower* timesDecPtrIn, TimeShower* timesPtrIn,
34 SpaceShower* spacePtrIn, RHadrons* rHadronsPtrIn, UserHooks* userHooksPtrIn,
35 MergingHooks* mergingHooksPtrIn,
bool useAsTrial ) {
39 particleDataPtr = particleDataPtrIn;
41 beamAPtr = beamAPtrIn;
42 beamBPtr = beamBPtrIn;
43 beamHadAPtr = beamAPtr;
44 beamHadBPtr = beamBPtr;
45 beamPomAPtr = beamPomAPtrIn;
46 beamPomBPtr = beamPomBPtrIn;
47 couplingsPtr = couplingsPtrIn;
48 partonSystemsPtr = partonSystemsPtrIn;
49 timesDecPtr = timesDecPtrIn;
50 timesPtr = timesPtrIn;
51 spacePtr = spacePtrIn;
52 rHadronsPtr = rHadronsPtrIn;
53 userHooksPtr = userHooksPtrIn;
54 mergingHooksPtr = mergingHooksPtrIn;
57 bool doSQ = settings.flag(
"SoftQCD:all")
58 || settings.flag(
"SoftQCD:inelastic");
59 bool doND = settings.flag(
"SoftQCD:nonDiffractive");
60 bool doSD = settings.flag(
"SoftQCD:singleDiffractive");
61 bool doDD = settings.flag(
"SoftQCD:doubleDiffractive");
62 bool doCD = settings.flag(
"SoftQCD:centralDiffractive");
63 doNonDiff = doSQ || doND;
64 doDiffraction = doSQ || doSD || doDD || doCD;
67 mMinDiff = settings.parm(
"Diffraction:mMinPert");
68 mWidthDiff = settings.parm(
"Diffraction:mWidthPert");
69 pMaxDiff = settings.parm(
"Diffraction:probMaxPert");
70 if (mMinDiff > infoPtr->eCM()) doDiffraction =
false;
74 doMPI = settings.flag(
"PartonLevel:MPI");
80 if (doNonDiff || doDiffraction) doMPIinit =
true;
81 if (!settings.flag(
"PartonLevel:all")) doMPIinit =
false;
86 bool hasMergingHooks = (mergingHooksPtr != 0);
87 canRemoveEvent = !doTrial && hasMergingHooks
88 && ( mergingHooksPtr->doCKKWLMerging() || mergingHooksPtr->doNL3Merging());
89 canRemoveEmission = !doTrial && hasMergingHooks
90 && ( mergingHooksPtr->doUMEPSMerging() || mergingHooksPtr->doNL3Merging()
91 || mergingHooksPtr->doUNLOPSMerging() );
97 doISR = settings.flag(
"PartonLevel:ISR");
98 bool FSR = settings.flag(
"PartonLevel:FSR");
99 bool FSRinProcess = settings.flag(
"PartonLevel:FSRinProcess");
100 bool interleaveFSR = settings.flag(
"TimeShower:interleave");
101 doFSRduringProcess = FSR && FSRinProcess && interleaveFSR;
102 doFSRafterProcess = FSR && FSRinProcess && !interleaveFSR;
103 doFSRinResonances = FSR && settings.flag(
"PartonLevel:FSRinResonances");
106 doRemnants = settings.flag(
"PartonLevel:Remnants");
107 doSecondHard = settings.flag(
"SecondHard:generate");
108 earlyResDec = settings.flag(
"PartonLevel:earlyResDec");
111 allowRH = settings.flag(
"RHadrons:allow");
114 canVetoPT = (userHooksPtr != 0)
115 ? userHooksPtr->canVetoPT() :
false;
116 pTvetoPT = (canVetoPT)
117 ? userHooksPtr->scaleVetoPT() : -1.;
118 canVetoStep = (userHooksPtr != 0)
119 ? userHooksPtr->canVetoStep() :
false;
120 nVetoStep = (canVetoStep)
121 ? userHooksPtr->numberVetoStep() : -1;
122 canVetoMPIStep = (userHooksPtr != 0)
123 ? userHooksPtr->canVetoMPIStep() :
false;
124 nVetoMPIStep = (canVetoMPIStep)
125 ? userHooksPtr->numberVetoMPIStep() : -1;
126 canVetoEarly = (userHooksPtr != 0)
127 ? userHooksPtr->canVetoPartonLevelEarly() :
false;
130 vetoWeakJets = settings.flag(
"WeakShower:vetoQCDjets");
131 vetoWeakDeltaR2 = pow2(settings.parm(
"WeakShower:vetoWeakDeltaR"));
134 canSetScale = (userHooksPtr != 0)
135 ? userHooksPtr->canSetResonanceScale() :
false;
138 canReconResSys = (userHooksPtr != 0)
139 ? userHooksPtr->canReconnectResonanceSystems() :
false;
142 if (beamAPtr == 0 || beamBPtr == 0)
return true;
145 hasLeptonBeams = ( beamAPtr->isLepton() || beamBPtr->isLepton() );
146 hasPointLeptons = ( hasLeptonBeams
147 && (beamAPtr->isUnresolved() || beamBPtr->isUnresolved() ) );
148 if (hasLeptonBeams) {
155 if (hasPointLeptons) {
161 timesPtr->init( beamAPtr, beamBPtr);
162 if (doISR) spacePtr->init( beamAPtr, beamBPtr);
163 doMPIMB = multiMB.init( doMPIinit, 0, infoPtr, settings, particleDataPtr,
164 rndmPtr, beamAPtr, beamBPtr, couplingsPtr, partonSystemsPtr, sigmaTotPtr,
166 if (doSD || doDD || doSQ) doMPISDA = multiSDA.init( doMPIinit, 1, infoPtr,
167 settings, particleDataPtr, rndmPtr, beamAPtr, beamPomBPtr, couplingsPtr,
168 partonSystemsPtr, sigmaTotPtr, userHooksPtr);
169 if (doSD || doDD || doSQ) doMPISDB = multiSDB.init( doMPIinit, 2, infoPtr,
170 settings, particleDataPtr, rndmPtr, beamPomAPtr, beamBPtr, couplingsPtr,
171 partonSystemsPtr, sigmaTotPtr, userHooksPtr);
172 if (doCD || doSQ) doMPICD = multiCD.init( doMPIinit, 3, infoPtr, settings,
173 particleDataPtr, rndmPtr, beamPomAPtr, beamPomBPtr, couplingsPtr,
174 partonSystemsPtr, sigmaTotPtr, userHooksPtr);
175 remnants.init( infoPtr, settings, rndmPtr, beamAPtr, beamBPtr,
177 resonanceDecays.init( infoPtr, particleDataPtr, rndmPtr);
181 if (doMPIinit && !doMPIMB)
return false;
182 if (doMPIinit && (doSD || doDD || doSQ) && (!doMPISDA || !doMPISDB))
184 if (doMPIinit && (doCD || doSQ) && !doMPICD)
return false;
185 if (!doMPIMB || !doMPISDA || !doMPISDB || !doMPICD) doMPI =
false;
193 void PartonLevel::resetTrial() {
196 partonSystemsPtr->clear();
199 beamHadAPtr->clear();
200 beamHadBPtr->clear();
201 beamPomAPtr->clear();
202 beamPomBPtr->clear();
214 bool PartonLevel::next(
Event& process,
Event& event) {
217 isResolved = infoPtr->isResolved();
218 isResolvedA = isResolved;
219 isResolvedB = isResolved;
220 isResolvedC = isResolved;
221 isDiffA = infoPtr->isDiffractiveA();
222 isDiffB = infoPtr->isDiffractiveB();
223 isDiffC = infoPtr->isDiffractiveC();
224 isDiff = isDiffA || isDiffB || isDiffC;
225 isCentralDiff = isDiffC;
226 isDoubleDiff = isDiffA && isDiffB;
227 isSingleDiff = isDiff && !isDoubleDiff && !isCentralDiff;
228 isNonDiff = infoPtr->isNonDiffractive();
235 if (!isResolved) nHardLoop = (isDiff) ? decideResolvedDiff( process) : 0;
240 if (!isResolvedA || !isResolvedB || !isResolvedC) {
241 bool physical = setupUnresolvedSys( process, event);
242 if (!physical || nHardLoop == 0)
return physical;
243 sizeProcess = process.size();
244 sizeEvent =
event.size();
250 int nBranchMax = (doTrial) ? nTrialEmissions : -1;
253 bool hasMergingHooks = (mergingHooksPtr != 0);
254 if ( hasMergingHooks && canRemoveEvent )
255 mergingHooksPtr->storeWeights(infoPtr->getWeightCKKWL());
259 for (
int iHardLoop = 1; iHardLoop <= nHardLoop; ++iHardLoop) {
260 infoPtr->setCounter(20, iHardLoop);
261 infoPtr->setCounter(21);
265 if (isDiffA || isDiffB) iDS = (iHardLoop == 2 || !isResolvedA) ? 2 : 1;
266 if (isDiffC) iDS = 3;
269 if (iHardLoop == 2) {
270 sizeProcess = process.size();
271 sizeEvent =
event.size();
272 partonSystemsPtr->clear();
273 if (event.lastColTag() > process.lastColTag())
274 process.initColTag(event.lastColTag());
280 event.saveJunctionSize();
283 setupResolvedDiff( process);
287 if (doMPIinit) multiPtr->reset();
290 if (isNonDiff || isDiff) {
292 multiPtr->setupFirstSys( process);
297 bool physical =
true;
299 for (
int iTry = 0; iTry < NTRY; ++ iTry) {
300 infoPtr->addCounter(21);
301 for (
int i = 22; i < 32; ++i) infoPtr->setCounter(i);
305 nMPI = (doSecondHard) ? 2 : 1;
316 setupHardSys( process, event);
319 if (canVetoMPIStep) {
320 doVeto = userHooksPtr->doVetoMPIStep( 1, event);
323 if (isDiff) leaveResolvedDiff( iHardLoop, process, event);
329 double Q2Fac = infoPtr->Q2Fac();
330 double Q2Ren = infoPtr->Q2Ren();
331 bool limitPTmaxISR = (doISR)
332 ? spacePtr->limitPTmax( event, Q2Fac, Q2Ren) :
false;
333 bool limitPTmaxFSR = (doFSRduringProcess)
334 ? timesPtr->limitPTmax( event, Q2Fac, Q2Ren) :
false;
335 bool limitPTmaxMPI = (doMPI) ? multiPtr->limitPTmax( event) :
false;
338 timesPtr->prepareGlobal( event);
339 bool isFirstTrial =
true;
342 double pTscaleRad = process.scale();
343 double pTscaleMPI = pTscaleRad;
345 pTscaleRad = max( pTscaleRad, process.scaleSecond() );
346 pTscaleMPI = min( pTscaleMPI, process.scaleSecond() );
348 double pTmaxMPI = (limitPTmaxMPI) ? pTscaleMPI : infoPtr->eCM();
349 double pTmaxISR = (limitPTmaxISR) ? spacePtr->enhancePTmax() * pTscaleRad
351 double pTmaxFSR = (limitPTmaxFSR) ? timesPtr->enhancePTmax() * pTscaleRad
355 if ( hasMergingHooks && (doTrial || canRemoveEvent || canRemoveEmission) )
356 mergingHooksPtr->setShowerStartingScales( doTrial,
357 (canRemoveEvent || canRemoveEmission), pTscaleRad, process, pTmaxFSR,
358 limitPTmaxFSR, pTmaxISR, limitPTmaxISR, pTmaxMPI, limitPTmaxMPI );
360 double pTmax = max( pTmaxMPI, max( pTmaxISR, pTmaxFSR) );
361 pTsaveMPI = pTmaxMPI;
362 pTsaveISR = pTmaxISR;
363 pTsaveFSR = pTmaxFSR;
365 if (doMPI) multiPtr->prepare( event, pTmaxMPI);
366 if (doISR) spacePtr->prepare( 0, event, limitPTmaxISR);
367 if (doFSRduringProcess) timesPtr->prepare( 0, event, limitPTmaxFSR);
368 if (doSecondHard && doISR) spacePtr->prepare( 1, event, limitPTmaxISR);
369 if (doSecondHard && doFSRduringProcess) timesPtr->prepare( 1, event,
373 if (!isDiff) infoPtr->setImpact( multiPtr->bMPI(),
374 multiPtr->enhanceMPI(),
true);
377 double pTveto = pTvetoPT;
382 infoPtr->addCounter(22);
384 nRad = nISR + nFSRinProc;
389 double pTtimes = (doFSRduringProcess)
390 ? timesPtr->pTnext( event, pTmaxFSR, pTgen, isFirstTrial) : -1.;
391 pTgen = max( pTgen, pTtimes);
392 double pTmulti = (doMPI)
393 ? multiPtr->pTnext( pTmaxMPI, pTgen, event) : -1.;
394 pTgen = max( pTgen, pTmulti);
395 double pTspace = (doISR)
396 ? spacePtr->pTnext( event, pTmaxISR, pTgen, nRad) : -1.;
397 double pTnow = max( pTtimes, max( pTmulti, pTspace));
400 infoPtr->setPTnow( pTnow);
401 isFirstTrial =
false;
404 if (pTveto > 0. && pTveto > pTnow) {
406 doVeto = userHooksPtr->doVetoPT( typeLatest, event);
409 if (isDiff) leaveResolvedDiff( iHardLoop, process, event);
415 if (pTmulti > 0. && pTmulti > pTspace && pTmulti > pTtimes) {
416 infoPtr->addCounter(23);
417 if (multiPtr->scatter( event)) {
420 if (canVetoMPIStep && nMPI <= nVetoMPIStep) typeVetoStep = 1;
423 if (doISR) spacePtr->prepare( nMPI - 1, event);
424 if (doFSRduringProcess) timesPtr->prepare( nMPI - 1, event);
429 pTmaxISR = min(pTmulti, pTmaxISR);
430 pTmaxFSR = min(pTmulti, pTmaxFSR);
433 pTLastBranch = pTmulti;
438 else if (pTspace > 0. && pTspace > pTtimes) {
439 infoPtr->addCounter(24);
440 if (spacePtr->branch( event)) {
442 iSysNow = spacePtr->system();
444 if (iSysNow == 0) ++nISRhard;
445 if (canVetoStep && iSysNow == 0 && nISRhard <= nVetoStep)
449 if (doFSRduringProcess) timesPtr->update( iSysNow, event,
450 spacePtr->getHasWeaklyRadiated());
452 pTLastBranch = pTspace;
457 }
else if (spacePtr->doRestart()) {
463 pTmaxMPI = min(pTspace, pTmaxMPI);
465 pTmaxFSR = min(pTspace, pTmaxFSR);
470 else if (pTtimes > 0.) {
471 infoPtr->addCounter(25);
472 if (timesPtr->branch( event,
true)) {
474 iSysNow = timesPtr->system();
476 if (iSysNow == 0) ++nFSRhard;
477 if (canVetoStep && iSysNow == 0 && nFSRhard <= nVetoStep)
481 if (doISR) spacePtr->update( iSysNow, event,
482 timesPtr->getHasWeaklyRadiated());
484 pTLastBranch = pTtimes;
490 pTmaxMPI = min(pTtimes, pTmaxMPI);
491 pTmaxISR = min(pTtimes, pTmaxISR);
501 if ( (infoPtr->code() == 221 || infoPtr->code() == 222) &&
502 nISRhard + nFSRhard == 2 && vetoWeakJets) {
503 int id1 =
event[partonSystemsPtr->getOut(0,0)].id();
504 int id2 =
event[partonSystemsPtr->getOut(0,1)].id();
505 int id3 =
event[partonSystemsPtr->getOut(0,2)].id();
506 Vec4 p1 =
event[partonSystemsPtr->getOut(0,0)].p();
507 Vec4 p2 =
event[partonSystemsPtr->getOut(0,1)].p();
508 Vec4 p3 =
event[partonSystemsPtr->getOut(0,2)].p();
512 bool doubleCountEvent =
true;
513 if (abs(id1) == 24 || abs(id1) == 23) {
514 if (abs(id2) > 21 || abs(id3) > 21)
515 doubleCountEvent =
false;
516 }
else if (abs(id2) == 24 || abs(id2) == 23) {
520 doubleCountEvent =
false;
521 }
else if ( abs(id3) == 24 || abs(id3) == 23) {
526 if (doubleCountEvent) {
529 if (p2.pT2() < d) {d = p2.pT2(); cut =
false;}
530 if (p3.pT2() < d) {d = p3.pT2(); cut =
false;}
535 double dij = min(p1.pT2(),p2.pT2())
536 * pow2(RRapPhi(p1,p2)) / vetoWeakDeltaR2;
544 double dij = min(p1.pT2(),p3.pT2())
545 * pow2(RRapPhi(p1,p3)) / vetoWeakDeltaR2;
555 if (abs(id2) == 21 || abs(id3) == 21 || id2 == - id3) {
556 double dij = min(p2.pT2(),p3.pT2())
557 * pow2(RRapPhi(p2,p3)) / vetoWeakDeltaR2;
565 if (cut)
return false;
571 if (typeVetoStep == 1) {
572 doVeto = userHooksPtr->doVetoMPIStep( nMPI, event);
573 }
else if (typeVetoStep > 1) {
574 doVeto = userHooksPtr->doVetoStep( typeVetoStep, nISRhard,
580 if (isDiff) leaveResolvedDiff( iHardLoop, process, event);
585 if (typeLatest > 0 && typeLatest < 4)
586 infoPtr->addCounter(25 + typeLatest);
587 if (!isDiff) infoPtr->setPartEvolved( nMPI, nISR);
590 if ( canRemoveEvent && nISRhard + nFSRhard == 1 ){
592 mergingHooksPtr->doVetoStep( process, event );
596 }
while (pTmax > 0. && (nBranchMax <= 0 || nBranch < nBranchMax) );
599 if (doFSRafterProcess && (nBranchMax <= 0 || nBranch < nBranchMax) ) {
603 for (
int i = 0; i <
event.size(); ++i)
604 if (event[i].isFinal() &&
event[i].scale() > pTmax)
605 pTmax = event[i].scale();
609 for (
int iSys = 0; iSys < partonSystemsPtr->sizeSys(); ++iSys)
610 timesPtr->prepare( iSys, event);
618 infoPtr->addCounter(29);
620 double pTtimes = timesPtr->pTnext( event, pTmax, 0.);
621 infoPtr->setPTnow( pTtimes);
624 if (pTveto > 0. && pTveto > pTtimes) {
626 doVeto = userHooksPtr->doVetoPT( 4, event);
629 if (isDiff) leaveResolvedDiff( iHardLoop, process, event);
636 infoPtr->addCounter(30);
637 if (timesPtr->branch( event,
true)) {
638 iSysNow = timesPtr->system();
640 if (iSysNow == 0) ++nFSRhard;
641 if (canVetoStep && iSysNow == 0 && nFSRhard <= nVetoStep)
645 pTLastBranch = pTtimes;
656 if (typeVetoStep > 0) {
657 doVeto = userHooksPtr->doVetoStep( typeVetoStep, nISRhard,
661 if (isDiff) leaveResolvedDiff( iHardLoop, process, event);
667 if ( canRemoveEvent && nISRhard + nFSRhard == 1 ){
669 mergingHooksPtr->doVetoStep( process, event );
673 infoPtr->addCounter(31);
675 }
while (pTmax > 0. && (nBranchMax <= 0 || nBranch < nBranchMax) );
680 if (canVetoEarly && userHooksPtr->doVetoPartonLevelEarly( event)) {
682 if (isDiff) leaveResolvedDiff( iHardLoop, process, event);
688 int oldSizeEvt =
event.size();
689 int oldSizeSys = partonSystemsPtr->sizeSys();
690 if (nBranchMax <= 0 || nBranch < nBranchMax)
691 doVeto = !resonanceShowers( process, event,
true);
693 if (doVeto)
return false;
696 for (
int iSys = oldSizeSys; iSys < partonSystemsPtr->sizeSys(); ++iSys)
697 for (
int iOut = 0; iOut < partonSystemsPtr->sizeOut(iSys); ++iOut)
698 partonSystemsPtr->addOut(0, partonSystemsPtr->getOut( iSys, iOut) );
699 partonSystemsPtr->setSizeSys( oldSizeSys);
703 if (!wzDecayShowers( event))
return false;
706 if (canReconResSys && !userHooksPtr->doReconnectResonanceSystems(
707 oldSizeEvt, event))
return false;
711 if (!doTrial && physical && doRemnants && !remnants.add( event))
718 if (!isDiff)
event.clear();
721 event.restoreJunctionSize();
725 partonSystemsPtr->clear();
729 if (isDiff) leaveResolvedDiff( iHardLoop, process, event);
730 if (!physical)
return false;
737 int oldSizeEvt =
event.size();
738 if (nBranchMax <= 0 || nBranch < nBranchMax)
739 doVeto = !resonanceShowers( process, event,
true);
741 if (doVeto)
return false;
745 if (!wzDecayShowers( event))
return false;
748 if (canReconResSys && !userHooksPtr->doReconnectResonanceSystems(
749 oldSizeEvt, event))
return false;
753 if (!isDiff) infoPtr->setEvolution( pTsaveMPI, pTsaveISR, pTsaveFSR,
754 nMPI, nISR, nFSRinProc, nFSRinRes);
756 multiPtr->setEmpty();
757 infoPtr->setImpact( multiPtr->bMPI(), multiPtr->enhanceMPI(),
false);
769 int PartonLevel::decideResolvedDiff(
Event& process) {
773 int iDSmin = (isDiffC) ? 3 : 1;
774 int iDSmax = (isDiffC) ? 3 : 2;
775 for (
int iDSnow = iDSmin; iDSnow <= iDSmax; ++iDSnow) {
776 int iDiffMot = iDSnow + 2;
779 double mDiff = process[iDiffMot].m();
780 bool isHighMass = ( mDiff > mMinDiff && rndmPtr->flat()
781 < pMaxDiff * ( 1. - exp( -(mDiff - mMinDiff) / mWidthDiff ) ) );
784 if (isHighMass) ++nHighMass;
785 if (iDSnow == 1) isResolvedA = isHighMass;
786 if (iDSnow == 2) isResolvedB = isHighMass;
787 if (iDSnow == 3) isResolvedC = isHighMass;
797 bool PartonLevel::setupUnresolvedSys(
Event& process,
Event& event) {
803 for (
int i = 0; i < process.size(); ++ i) event.append( process[i]);
806 for (iDS = 1; iDS < 4; ++iDS)
807 if ( (iDS == 1 && isDiffA && !isResolvedA)
808 || (iDS == 2 && isDiffB && !isResolvedB)
809 || (iDS == 3 && isDiffC && !isResolvedC) ) {
814 double mDiff = process[iBeam].m();
815 double m2Diff = mDiff * mDiff;
816 Vec4 pDiffA = (iDS == 1) ? process[1].p()
817 : process[1].p() - process[3].p();
818 Vec4 pDiffB = (iDS == 2) ? process[2].p()
819 : process[2].p() - process[4].p();
821 MtoCM.fromCMframe( pDiffA, pDiffB);
825 bool beamSideA = (iDS == 1 || (iDS == 3 && rndmPtr->flat() < 0.5));
826 BeamParticle* beamPtr = (beamSideA) ? beamAPtr : beamBPtr;
827 if (iDS == 3) beamPtr = (beamSideA) ? beamPomAPtr : beamPomBPtr;
830 beamPtr->newValenceContent();
831 bool gluonIsKicked = beamPtr->pickGluon(mDiff);
832 int id1 = beamPtr->pickValence();
833 int id2 = beamPtr->pickRemnant();
836 double m1 = particleDataPtr->constituentMass(id1);
837 double m2 = particleDataPtr->constituentMass(id2);
838 if (m1 + m2 > 0.5 * mDiff) {
839 double reduce = 0.5 * mDiff / (m1 + m2);
845 if (!gluonIsKicked) {
846 double pAbs = sqrt( pow2(m2Diff - m1*m1 - m2*m2)
847 - pow2(2. * m1 * m2) ) / (2. * mDiff);
848 if (!beamSideA) pAbs = -pAbs;
849 double e1 = (m2Diff + m1*m1 - m2*m2) / (2. * mDiff);
850 double e2 = (m2Diff + m2*m2 - m1*m1) / (2. * mDiff);
851 Vec4 p1( 0., 0., -pAbs, e1);
852 Vec4 p2( 0., 0., pAbs, e2);
859 int col1, acol1, col2, acol2;
860 if (particleDataPtr->colType(id1) == 1) {
861 col1 =
event.nextColTag();
867 acol1 =
event.nextColTag();
872 process.nextColTag();
875 int iDauBeg =
event.append( id1, 24, iBeam, 0, 0, 0, col1, acol1,
877 int iDauEnd =
event.append( id2, 63, iBeam, 0, 0, 0, col2, acol2,
879 event[iBeam].statusNeg();
880 event[iBeam].daughters(iDauBeg, iDauEnd);
884 double m2Sys, zSys, pxSys, pySys, mTS1, mTS2;
885 zSys = beamPtr->zShare(mDiff, m1, m2);
888 pxSys = beamPtr->pxShare();
889 pySys = beamPtr->pyShare();
890 mTS1 = m1*m1 + pxSys*pxSys + pySys*pySys;
891 mTS2 = m2*m2 + pxSys*pxSys + pySys*pySys;
892 m2Sys = mTS1 / zSys + mTS2 / (1. - zSys);
895 double pAbs = (m2Diff - m2Sys) / (2. * mDiff);
896 double pLRem = (beamSideA) ? pAbs : -pAbs;
897 Vec4 pG( 0., 0., -pLRem, pAbs);
898 Vec4 pRem(0., 0., pLRem, mDiff - pAbs);
901 double e1 = 0.5 * (zSys * mDiff + mTS1 / (zSys * mDiff));
902 double pL1 = 0.5 * (zSys * mDiff - mTS1 / (zSys * mDiff));
903 if (!beamSideA) pL1 = -pL1;
904 Vec4 p1(pxSys, pySys, pL1, e1);
914 int colG, acolG, col1, acol1, col2, acol2;
915 if (particleDataPtr->colType(id1) == 1) {
916 col1 =
event.nextColTag();
918 colG =
event.nextColTag();
924 acol1 =
event.nextColTag();
926 acolG =
event.nextColTag();
931 process.nextColTag();
932 process.nextColTag();
935 int iDauBeg =
event.append( 21, 24, iBeam, 0, 0, 0, colG, acolG, pG, 0.);
936 event.append( id1, 63, iBeam, 0, 0, 0, col1, acol1, p1, m1);
937 int iDauEnd =
event.append( id2, 63, iBeam, 0, 0, 0, col2, acol2,
939 event[iBeam].statusNeg();
940 event[iBeam].daughters(iDauBeg, iDauEnd);
953 void PartonLevel::setupHardSys(
Event& process,
Event& event) {
961 int iDiffMot = iDS + 2;
962 int iDiffDau = process.size() - 1;
963 int nOffset = sizeEvent - sizeProcess;
972 event[inS].statusNeg();
973 event[inS].daughters( inP - 2 + nOffset, inM - 2 + nOffset);
977 int iBeginSecond = process.size();
980 while (process[iBeginSecond].status() != -21) ++iBeginSecond;
984 if (process[inP].m() != 0. || process[inM].m() != 0.) {
985 double pPos = process[inP].pPos() + process[inM].pPos();
986 double pNeg = process[inP].pNeg() + process[inM].pNeg();
987 process[inP].pz( 0.5 * pPos);
988 process[inP].e( 0.5 * pPos);
990 process[inM].pz(-0.5 * pNeg);
991 process[inM].e( 0.5 * pNeg);
996 double x1 = process[inP].pPos() / process[inS].m();
997 beamAPtr->append( inP + nOffset, process[inP].
id(), x1);
998 double x2 = process[inM].pNeg() / process[inS].m();
999 beamBPtr->append( inM + nOffset, process[inM].
id(), x2);
1005 double scale = process.scale();
1007 beamAPtr->xfISR( 0, process[inP].
id(), x1, scale*scale);
1008 if (isNonDiff && (vsc1 = multiPtr->getVSC1()) != 0)
1009 (*beamAPtr)[0].companion(vsc1);
1010 else vsc1 = beamAPtr->pickValSeaComp();
1011 beamBPtr->xfISR( 0, process[inM].
id(), x2, scale*scale);
1012 if (isNonDiff && (vsc2 = multiPtr->getVSC2()) != 0)
1013 (*beamBPtr)[0].companion(vsc2);
1014 else vsc2 = beamBPtr->pickValSeaComp();
1015 bool isVal1 = (vsc1 == -3);
1016 bool isVal2 = (vsc2 == -3);
1017 infoPtr->setValence( isVal1, isVal2);
1020 nHardDone = sizeProcess;
1021 iPosBefShow.resize( process.size() );
1022 fill( iPosBefShow.begin(), iPosBefShow.end(), 0);
1025 for (
int i = sizeProcess; i < iBeginSecond; ++i) {
1026 if (process[i].mother1() > inM)
break;
1027 int j =
event.append(process[i]);
1032 int iOrd = i - iBeginSecond + 7;
1033 if (iOrd == 1 || iOrd == 2)
1034 event[j].offsetHistory( 0, 0, 0, nOffset);
1035 else if (iOrd == 3 || iOrd == 4)
1036 event[j].offsetHistory( 0, nOffset, 0, nOffset);
1037 else if (iOrd == 5 || iOrd == 6)
1038 event[j].offsetHistory( 0, nOffset, 0, 0);
1042 if (event[j].status() == -22) {
1043 event[j].statusPos();
1044 event[j].daughters(0, 0);
1052 partonSystemsPtr->addSys();
1053 partonSystemsPtr->setInA(0, inP + nOffset);
1054 partonSystemsPtr->setInB(0, inM + nOffset);
1055 for (
int i = inM + 1; i < nHardDone; ++i)
1056 partonSystemsPtr->addOut(0, i + nOffset);
1057 partonSystemsPtr->setSHat( 0,
1058 (event[inP + nOffset].p() + event[inM + nOffset].p()).m2Calc() );
1059 partonSystemsPtr->setPTHat( 0, scale);
1064 int inP2 = iBeginSecond;
1065 int inM2 = iBeginSecond + 1;
1069 x1 = process[inP2].pPos() / process[0].e();
1070 beamAPtr->append( inP2, process[inP2].
id(), x1);
1071 x2 = process[inM2].pNeg() / process[0].e();
1072 beamBPtr->append( inM2, process[inM2].
id(), x2);
1075 scale = process.scaleSecond();
1076 beamAPtr->xfISR( 1, process[inP2].
id(), x1, scale*scale);
1077 beamAPtr->pickValSeaComp();
1078 beamBPtr->xfISR( 1, process[inM2].
id(), x2, scale*scale);
1079 beamBPtr->pickValSeaComp();
1082 for (
int i = inP2; i < process.size(); ++ i) {
1083 int mother = process[i].mother1();
1084 if ( (mother > 2 && mother < inP2) || mother > inM2 )
break;
1085 event.append(process[i]);
1089 if (event[i].status() == -22) {
1090 event[i].statusPos();
1091 event[i].daughters(0, 0);
1099 partonSystemsPtr->addSys();
1100 partonSystemsPtr->setInA(1, inP2);
1101 partonSystemsPtr->setInB(1, inM2);
1102 for (
int i = inM2 + 1; i < nHardDone; ++i)
1103 partonSystemsPtr->addOut(1, i);
1104 partonSystemsPtr->setSHat( 1,
1105 (event[inP2].p() + event[inM2].p()).m2Calc() );
1106 partonSystemsPtr->setPTHat( 1, scale);
1113 for (
int i = 0; i < process.size(); ++ i) {
1114 if (process[i].col() > maxColTag) maxColTag = process[i].col();
1115 if (process[i].acol() > maxColTag) maxColTag = process[i].acol();
1117 event.initColTag(maxColTag);
1120 for (
int iJun = 0; iJun < process.sizeJunction(); ++iJun) {
1123 int kindJunction = process.kindJunction(iJun);
1126 if (kindJunction <= 4) {
1127 int iLegF1 = (kindJunction - 1) / 2;
1128 for (
int iLeg = iLegF1; iLeg <= 2; ++iLeg) {
1129 bool colFound =
false;
1130 for (
int i = inM + 1; i <
event.size(); ++i) {
1131 int col = (kindJunction % 2 == 1) ? event[i].col() :
event[i].acol();
1132 if (col == process.colJunction(iJun,iLeg)) colFound =
true;
1134 if (!colFound) doCopy =
false;
1137 if (doCopy)
event.appendJunction( process.getJunction(iJun));
1147 void PartonLevel::setupShowerSys(
Event& process,
Event& event) {
1151 event.append( process[0]);
1155 iPosBefShow.resize( process.size());
1156 fill( iPosBefShow.begin(), iPosBefShow.end(), 0);
1159 for (
int i = 1; i < process.size(); ++i) {
1160 if (process[i].mother1() > 0)
break;
1161 int j =
event.append(process[i]);
1165 if (event[j].status() == -22) {
1166 event[j].statusPos();
1167 event[j].daughters(0, 0);
1175 partonSystemsPtr->clear();
1176 partonSystemsPtr->addSys();
1177 for (
int i = 1; i < nHardDone; ++i) partonSystemsPtr->addOut(0, i);
1178 partonSystemsPtr->setSHat( 0, pow2(process[0].m()) );
1179 partonSystemsPtr->setPTHat( 0, 0.5 * process[0].m() );
1182 for (
int iJun = 0; iJun < process.sizeJunction(); ++iJun) {
1185 int kindJunction = process.kindJunction(iJun);
1188 if (kindJunction <= 4) {
1189 int iLegF1 = (kindJunction - 1) / 2;
1190 for (
int iLeg = iLegF1; iLeg <= 2; ++iLeg) {
1191 bool colFound =
false;
1192 for (
int i = 1; i <
event.size(); ++i) {
1193 int col = (kindJunction % 2 == 1) ? event[i].col() :
event[i].acol();
1194 if (col == process.colJunction(iJun,iLeg)) colFound =
true;
1196 if (!colFound) doCopy =
false;
1199 if (doCopy)
event.appendJunction( process.getJunction(iJun));
1209 void PartonLevel::setupResolvedDiff(
Event& process) {
1212 int iDiffMot = iDS + 2;
1213 int iDiffDau = process.size() - 1;
1217 process[iDiffMot].statusNeg();
1218 process[iDiffMot].daughters( iDiffDau + 1, iDiffDau + 2);
1221 double mDiff = process[iDiffMot].m();
1222 double m2Diff = mDiff * mDiff;
1226 int idDiffA = (iDS == 1) ? process[1].
id() : 990;
1227 int idDiffB = (iDS == 2) ? process[2].
id() : 990;
1228 double mDiffA = (iDS == 1) ? process[1].m() : 0.;
1229 double mDiffB = (iDS == 2) ? process[2].m() : 0.;
1230 double m2DiffA = mDiffA * mDiffA;
1231 double m2DiffB = mDiffB * mDiffB;
1232 double eDiffA = 0.5 * (m2Diff + m2DiffA - m2DiffB) / mDiff;
1233 double eDiffB = 0.5 * (m2Diff + m2DiffB - m2DiffA) / mDiff;
1234 double pzDiff = 0.5 * sqrtpos( pow2(m2Diff - m2DiffA - m2DiffB)
1235 - 4. * m2DiffA * m2DiffB ) / mDiff;
1236 process.append( idDiffA, 13, iDiffMot, 0, 0, 0, 0, 0,
1237 0., 0., pzDiff, eDiffA, mDiffA);
1238 process.append( idDiffB, 13, iDiffMot, 0, 0, 0, 0, 0,
1239 0., 0., -pzDiff, eDiffB, mDiffB);
1242 beamAPtr = (iDS == 1) ? beamHadAPtr : beamPomAPtr;
1243 beamBPtr = (iDS == 2) ? beamHadBPtr : beamPomBPtr;
1246 eCMsave = infoPtr->eCM();
1247 infoPtr->setECM( mDiff);
1248 beamAPtr->newPzE( pzDiff, eDiffA);
1249 beamBPtr->newPzE( -pzDiff, eDiffB);
1252 int beamOffset = (sizeEvent > 0) ? sizeEvent - 1 : 4;
1255 timesPtr->reassignBeamPtrs( beamAPtr, beamBPtr, beamOffset);
1256 spacePtr->reassignBeamPtrs( beamAPtr, beamBPtr, beamOffset);
1257 remnants.reassignBeamPtrs( beamAPtr, beamBPtr, iDS);
1260 if (iDS == 1) multiPtr = &multiSDA;
1261 else if (iDS == 2) multiPtr = &multiSDB;
1262 else multiPtr = &multiCD;
1270 void PartonLevel::leaveResolvedDiff(
int iHardLoop,
Event& process,
1274 Vec4 pDiffA = (iDS == 1) ? process[1].p()
1275 : process[1].p() - process[3].p();
1276 Vec4 pDiffB = (iDS == 2) ? process[2].p()
1277 : process[2].p() - process[4].p();
1279 MtoCM.fromCMframe( pDiffA, pDiffB);
1282 for (
int i = sizeProcess; i < process.size(); ++i)
1283 process[i].rotbst( MtoCM);
1284 int iFirst = (iHardLoop == 1) ? 5 + sizeEvent - sizeProcess : sizeEvent;
1285 if(isDiffC) iFirst = 6 + sizeEvent - sizeProcess;
1286 for (
int i = iFirst; i <
event.size(); ++i)
1287 event[i].rotbst( MtoCM);
1290 infoPtr->setECM( eCMsave);
1291 beamAPtr->newPzE( event[1].pz(), event[1].e());
1292 beamBPtr->newPzE( event[2].pz(), event[2].e());
1295 beamAPtr = beamHadAPtr;
1296 beamBPtr = beamHadBPtr;
1299 timesPtr->reassignBeamPtrs( beamAPtr, beamBPtr, 0);
1300 spacePtr->reassignBeamPtrs( beamAPtr, beamBPtr, 0);
1301 remnants.reassignBeamPtrs( beamAPtr, beamBPtr, 0);
1304 multiPtr = &multiMB;
1312 bool PartonLevel::resonanceShowers(
Event& process,
Event& event,
1318 nHardDoneRHad = nHardDone;
1319 inRHadDecay.resize(0);
1320 for (
int i = 0; i < process.size(); ++i)
1321 inRHadDecay.push_back(
false);
1322 }
else nHardDone = nHardDoneRHad;
1329 int nBranchMax = (doTrial) ? nTrialEmissions : -1;
1331 vector<int> iJunCopied;
1333 while (nHardDone < process.size()) {
1335 int iBegin = nHardDone;
1341 bool comesFromR =
false;
1342 int iTraceUp = iBegin;
1344 if ( rHadronsPtr->givesRHadron(process[iTraceUp].id()) )
1346 iTraceUp = process[iTraceUp].mother1();
1347 }
while (iTraceUp > 0 && !comesFromR);
1349 inRHadDecay[iBegin] =
true;
1356 }
else if (!inRHadDecay[iBegin]) {
1363 int iHardMother = process[iBegin].mother1();
1364 Particle& hardMother = process[iHardMother];
1365 int iBefMother = iPosBefShow[iHardMother];
1366 int iAftMother =
event.iBotCopyId(iBefMother);
1369 int iTraceRHadron = rHadronsPtr->trace( iAftMother);
1370 if (iTraceRHadron > 0) iAftMother = iTraceRHadron;
1372 Particle& aftMother =
event[iAftMother];
1375 aftMother.statusNeg();
1379 int colBef = hardMother.col();
1380 int acolBef = hardMother.acol();
1381 int colAft = aftMother.col();
1382 int acolAft = aftMother.acol();
1384 M.bst( hardMother.p(), aftMother.p());
1387 vector<bool> doCopyJun;
1388 for (
int i = iBegin; i < process.size(); ++i) {
1389 if (process[i].mother1() != iHardMother)
break;
1390 int iNow =
event.append( process[i] );
1391 iPosBefShow[i] = iNow;
1392 Particle& now =
event.back();
1395 if (now.status() == -22) {
1397 now.daughters(0, 0);
1401 if (i == iBegin)
event[iAftMother].daughter1( iNow);
1402 else event[iAftMother].daughter2( iNow);
1403 now.mother1(iAftMother);
1406 for (
int iJun = 0; iJun < process.sizeJunction(); ++iJun) {
1407 if (iJun >=
int(doCopyJun.size())) doCopyJun.push_back(
false);
1409 int kindJunction = process.kindJunction(iJun);
1410 if (kindJunction >= 5)
continue;
1411 int col = (kindJunction % 2 == 1) ? now.col() : now.acol();
1412 int iLegF1 = (kindJunction - 1) / 2;
1413 for (
int iLeg = iLegF1; iLeg <= 2; ++iLeg)
1414 if (col == process.colJunction(iJun,iLeg)) doCopyJun[iJun] =
true;
1418 if (now.col() == colBef) now.col( colAft);
1419 if (now.acol() == acolBef) now.acol( acolAft);
1423 if (now.hasVertex()) now.vProd( event[iAftMother].vDec() );
1428 int iEnd = nHardDone - 1;
1431 for (
int iJun = 0; iJun < int(doCopyJun.size()); ++iJun) {
1433 for (
int jJun = 0; jJun < int(iJunCopied.size()); ++jJun)
1434 if (iJunCopied[jJun] == iJun) doCopyJun[iJun] =
false;
1436 if (!doCopyJun[iJun])
continue;
1438 Junction junCopy = process.getJunction(iJun);
1439 for (
int iLeg = 0; iLeg <= 2; ++iLeg) {
1440 int colLeg = junCopy.col(iLeg);
1441 if (colLeg == colBef) junCopy.col(iLeg, colAft);
1442 if (colLeg == acolBef) junCopy.col(iLeg, acolAft);
1444 event.appendJunction(junCopy);
1446 iJunCopied.push_back(iJun);
1453 int iSys = partonSystemsPtr->addSys();
1454 partonSystemsPtr->setSHat(iSys, pow2(hardMother.m()) );
1455 partonSystemsPtr->setPTHat(iSys, 0.5 * hardMother.m() );
1458 for (
int i = iPosBefShow[iBegin]; i <= iPosBefShow[iEnd]; ++i)
1459 if (event[i].isFinal()) partonSystemsPtr->addOut( iSys, i);
1462 if (doFSRinResonances) {
1463 double pTmax = 0.5 * hardMother.m();
1464 if (canSetScale) pTmax
1465 = userHooksPtr->scaleResonance( iAftMother, event);
1469 if (doTrial) pTmax = process.scale();
1472 timesDecPtr->prepare( iSys, event);
1479 double pTveto = pTvetoPT;
1484 double pTtimes = timesDecPtr->pTnext( event, pTmax, 0.);
1487 if (pTveto > 0. && pTveto > pTtimes) {
1489 doVeto = userHooksPtr->doVetoPT( 5, event);
1491 if (doVeto)
return false;
1496 if (timesDecPtr->branch( event)) {
1499 if (canVetoStep && nFSRhard <= nVetoStep) typeVetoStep = 5;
1502 pTLastBranch = pTtimes;
1513 if (typeVetoStep > 0) {
1514 doVeto = userHooksPtr->doVetoStep( typeVetoStep, 0, nFSRhard,
1517 if (doVeto)
return false;
1521 if ( canRemoveEvent && nFSRhard == 1 ) {
1523 mergingHooksPtr->doVetoStep( process, event,
true );
1527 }
while (pTmax > 0. && (nBranchMax <= 0 || nBranch < nBranchMax) );
1533 if (skipForR) nFSRinRes = nFSRres;
1542 bool PartonLevel::wzDecayShowers(
Event& event) {
1545 for (
int iWZ = 0; iWZ <
event.size(); ++iWZ)
1546 if (event[iWZ].isFinal()
1547 && (
event[iWZ].id() == 23 ||
event[iWZ].idAbs() == 24) ) {
1548 int iWZtop =
event[iWZ].iTopCopy();
1550 if (event[iWZtop].statusAbs() == 56) typeWZ = 1;
1551 if (event[iWZtop].statusAbs() == 47) typeWZ = 2;
1552 int sizeSave =
event.size();
1557 int idSave =
event[iWZ].id();
1558 event[iWZ].id( (idSave > 0) ? idSave + 70 : idSave - 70);
1559 int statusSave =
event[iWZ].status();
1560 resonanceDecays.next( event, iWZ);
1561 event[iWZ].id( idSave);
1562 if (event.size() - sizeSave != 2)
return true;
1563 event[iWZ].status( -statusSave);
1570 vector<int> iSisters =
event[iWZtop].sisterList();
1571 if (iSisters.size() != 1) {
1572 infoPtr->errorMsg(
"Error in PartonLevel::wzDecayShowers: "
1573 "Not able to find a single sister particle");
1576 int iEmitter = iSisters[0];
1579 RotBstMatrix MtoNew, MtoRest, MtoCM;
1580 MtoNew.bst( event[iWZtop].p(), event[iWZ].p());
1581 MtoRest.bstback( event[iWZ].p());
1582 MtoCM.bst( event[iWZ].p());
1585 Vec4 pEmitter =
event[iEmitter].p();
1586 pEmitter.rotbst( MtoNew);
1587 pEmitter.rotbst( MtoRest);
1588 if (event[iWZtop + 1].statusAbs() != 52) {
1589 infoPtr->errorMsg(
"Error in PartonLevel::wzDecayShowers: "
1590 "Found wrong recoiler");
1593 Vec4 pRecoiler =
event[iWZtop + 1].p();
1594 pRecoiler.rotbst( MtoNew);
1595 pRecoiler.rotbst( MtoRest);
1596 Vec4 pWZRest =
event[iWZ].p();
1597 pWZRest.rotbst( MtoRest);
1601 Vec4 p5 = pRecoiler;
1602 if (event[iEmitter].
id() < 0) swap( p4, p5);
1606 Vec4 pDec1 =
event[sizeSave].p();
1607 Vec4 pDec2 =
event[sizeSave + 1].p();
1608 if (event[sizeSave].
id() < 0) swap( pDec1, pDec2);
1609 pDec1.rotbst( MtoRest);
1610 pDec2.rotbst( MtoRest);
1613 double li2, ri2, lf2, rf2;
1615 if (event[iWZ].
id() == 23) {
1616 li2 = pow2(couplingsPtr->lf( event[iEmitter].idAbs() ));
1617 ri2 = pow2(couplingsPtr->rf( event[iEmitter].idAbs() ));
1618 lf2 = pow2(couplingsPtr->lf( event[sizeSave].idAbs() ));
1619 rf2 = pow2(couplingsPtr->rf( event[sizeSave].idAbs() ));
1620 if ( abs( event[iEmitter].pol() + 1.) < 0.1) ri2 = 0.;
1621 if ( abs( event[iEmitter].pol() - 1.) < 0.1) li2 = 0.;
1631 double sWZER = (p4 + pWZRest + p5).m2Calc();
1632 double x1 = 2. * p4 * (p4 + pWZRest + p5) / sWZER;
1633 double x2 = 2. * p5 * (p4 + pWZRest + p5) / sWZER;
1634 double x1s = x1 * x1;
1635 double x2s = x2 * x2;
1636 double m2Sel = pWZRest.m2Calc();
1637 double rWZER = m2Sel / sWZER;
1641 con[0] = 2. * m2Sel * (1.-x1) * ((x2s+1.-x1-x2) - rWZER * (1.-x2))
1642 * (li2 * lf2 + ri2 * rf2);
1643 con[1] = 2. * m2Sel * (1.-x2) * ((x1s+1.-x1-x2) - rWZER * (1.-x1))
1644 * (li2 * rf2 + ri2 * lf2);
1645 con[2] = 2. * m2Sel * (1.-x1) * ((x2s+1.-x1-x2) - rWZER * (1.-x2))
1646 * (li2 * rf2 + ri2 * lf2);
1647 con[3] = 2. * m2Sel * (1.-x2) * ((x1s+1.-x1-x2) - rWZER * (1.-x1))
1648 * (li2 * lf2 + ri2 * rf2);
1649 con[4] = m2Sel * sWZER * (1.-x1) * (1.-x2) * ((x1+x2-1.) + rWZER)
1650 * (li2 + ri2) * (lf2 + rf2);
1651 con[5] = -4. * (1.-x1) * (1.-x2) * (li2 + ri2) * (lf2 + rf2);
1652 con[6] = -4. * (1.-x1) * (1.-x2) * (li2 + ri2) * (lf2 + rf2);
1653 con[7] = 4. * (1.-x1) * ((1.-x1) - rWZER * (1.-x2))
1654 * (li2 + ri2) * (lf2 + rf2);
1655 con[8] = 4. * (1.-x2) * ((1.-x2) - rWZER * (1.-x1))
1656 * (li2 + ri2) * (lf2 + rf2);
1660 double pAbs12 = pDec1.pAbs();
1661 for (
int j = 0; j < 6; ++j) {
1662 Vec4 pDec1Test( 0., 0., 0., pDec1.e());
1663 Vec4 pDec2Test( 0., 0., 0., pDec2.e());
1664 if (j == 0) { pDec1Test.px( pAbs12); pDec1Test.px( -pAbs12);}
1665 else if (j == 1) { pDec1Test.px( -pAbs12); pDec1Test.px( pAbs12);}
1666 else if (j == 2) { pDec1Test.py( pAbs12); pDec1Test.py( -pAbs12);}
1667 else if (j == 3) { pDec1Test.py( -pAbs12); pDec1Test.py( pAbs12);}
1668 else if (j == 4) { pDec1Test.pz( pAbs12); pDec1Test.pz( -pAbs12);}
1669 else if (j == 5) { pDec1Test.pz( -pAbs12); pDec1Test.pz( pAbs12);}
1672 double p2p4Test = p4 * pDec1Test;
1673 double p3p4Test = p4 * pDec2Test;
1674 double p2p5Test = p5 * pDec1Test;
1675 double p3p5Test = p5 * pDec2Test;
1676 double testValues[9] = { p2p4Test, p2p5Test, p3p4Test, p3p5Test, 1.,
1677 p2p5Test * p3p4Test, p2p4Test * p3p5Test, p2p4Test * p3p4Test,
1678 p2p5Test * p3p5Test};
1680 for (
int i = 0; i < 9; ++i) wtTest += con[i] * testValues[i];
1681 if (wtTest > wtMax) wtMax = wtTest;
1693 RotBstMatrix MrndmRot;
1694 MrndmRot.rot( acos(2. * rndmPtr->flat() - 1.),
1695 2. * M_PI * rndmPtr->flat());
1696 pDec1.rotbst(MrndmRot);
1697 pDec2.rotbst(MrndmRot);
1703 double p2p4 = p4 * pDec1;
1704 double p3p4 = p4 * pDec2;
1705 double p2p5 = p5 * pDec1;
1706 double p3p5 = p5 * pDec2;
1709 double wtValues[9] = { p2p4, p2p5, p3p4, p3p5, 1., p2p5 * p3p4,
1710 p2p4 * p3p5, p2p4 * p3p4, p2p5 * p3p5};
1712 for (
int i = 0; i < 9; ++i) wt += con[i] * wtValues[i];
1713 if (wt > wtMax || wt < 0.) {
1714 infoPtr->errorMsg(
"Error in PartonLevel::wzDecayShowers: "
1715 "wt bigger than wtMax or less than zero");
1718 }
while (wt < wtMax * rndmPtr->flat());
1722 pDec1.rotbst( MtoCM);
1723 pDec2.rotbst( MtoCM);
1724 if (event[sizeSave].
id() > 0) {
1725 event[sizeSave].p( pDec1);
1726 event[sizeSave + 1].p( pDec2);
1729 event[sizeSave].p( pDec2);
1730 event[sizeSave + 1].p( pDec1);
1739 double iMother =
event[iWZtop].mother1();
1742 RotBstMatrix MtoNew, MtoRest, MtoCM;
1743 MtoNew.bst( event[iWZtop].p(), event[iWZ].p());
1744 MtoRest.bstback( event[iWZ].p());
1745 MtoCM.bst( event[iWZ].p());
1749 if (event[iMother + 1].statusAbs() == 42) iRecoiler = iMother + 1;
1750 else if (event[iMother - 1].statusAbs() == 42) iRecoiler = iMother - 1;
1752 infoPtr->errorMsg(
"Error in PartonLevel::wzDecayShowers: "
1753 "Found wrong recoiler");
1758 Vec4 pMother =
event[iMother].p();
1759 pMother.rotbst( MtoNew);
1760 pMother.rotbst( MtoRest);
1761 Vec4 pRecoiler =
event[iRecoiler].p();
1762 pRecoiler.rotbst( MtoNew);
1763 pRecoiler.rotbst( MtoRest);
1764 Vec4 pWZRest =
event[iWZ].p();
1765 pWZRest.rotbst( MtoRest);
1770 Vec4 p2 = pRecoiler;
1771 if (event[iMother].
id() < 0) swap( p1, p2);
1775 Vec4 pDec1 =
event[sizeSave].p();
1776 Vec4 pDec2 =
event[sizeSave + 1].p();
1777 if (event[sizeSave].
id() < 0) swap( pDec1, pDec2);
1778 pDec1.rotbst( MtoRest);
1779 pDec2.rotbst( MtoRest);
1782 double li2, ri2, lf2, rf2;
1784 if (event[iWZ].
id() == 23) {
1785 li2 = pow2(couplingsPtr->lf( event[iMother].idAbs() ));
1786 ri2 = pow2(couplingsPtr->rf( event[iMother].idAbs() ));
1787 lf2 = pow2(couplingsPtr->lf( event[sizeSave].idAbs() ));
1788 rf2 = pow2(couplingsPtr->rf( event[sizeSave].idAbs() ));
1789 if ( abs( event[iMother].pol() + 1.) < 0.1) ri2 = 0.;
1790 if ( abs( event[iMother].pol() - 1.) < 0.1) li2 = 0.;
1800 double s = (p1 + p2).m2Calc();
1801 double t = (p1-pWZRest).m2Calc();
1802 double u = (p2-pWZRest).m2Calc();
1803 double m2Sel = pWZRest.m2Calc();
1804 double m2Final = t + u + s - m2Sel;
1808 con[0] = 2. * m2Sel * (u * (1. - m2Final / t) + s)
1809 * (li2 * rf2 + ri2 * lf2);
1810 con[1] = 2. * m2Sel * (u * (1. - m2Final / t) + s)
1811 * (li2 * lf2 + ri2 * rf2);
1812 con[2] = 2. * m2Sel * (t * (1. - m2Final / u) + s)
1813 * (li2 * lf2 + ri2 * rf2);
1814 con[3] = 2. * m2Sel * (t * (1. - m2Final / u) + s)
1815 * (li2 * rf2 + ri2 * lf2);
1816 con[4] = m2Sel * m2Final * s * (li2 + ri2) * (lf2 + rf2);
1817 con[5] = -4. * m2Final * (li2 + ri2) * (lf2 + rf2);
1818 con[6] = -4. * m2Final * (li2 + ri2) * (lf2 + rf2);
1819 con[7] = 4. * (m2Final * u / t - m2Sel) * (li2 + ri2) * (lf2 + rf2);
1820 con[8] = 4. * (m2Final * t / u - m2Sel) * (li2 + ri2) * (lf2 + rf2);
1824 double pAbs12 = pDec1.pAbs();
1825 for (
int j = 0; j < 6; ++j) {
1826 Vec4 pDec1Test( 0., 0., 0., pDec1.e());
1827 Vec4 pDec2Test( 0., 0., 0., pDec2.e());
1828 if (j == 0) { pDec1Test.px( pAbs12); pDec1Test.px( -pAbs12);}
1829 else if (j == 1) { pDec1Test.px( -pAbs12); pDec1Test.px( pAbs12);}
1830 else if (j == 2) { pDec1Test.py( pAbs12); pDec1Test.py( -pAbs12);}
1831 else if (j == 3) { pDec1Test.py( -pAbs12); pDec1Test.py( pAbs12);}
1832 else if (j == 4) { pDec1Test.pz( pAbs12); pDec1Test.pz( -pAbs12);}
1833 else if (j == 5) { pDec1Test.pz( -pAbs12); pDec1Test.pz( pAbs12);}
1836 double p1p4Test = p1 * pDec1Test;
1837 double p1p5Test = p1 * pDec2Test;
1838 double p2p4Test = p2 * pDec1Test;
1839 double p2p5Test = p2 * pDec2Test;
1840 double testValues[9] = { p1p4Test, p1p5Test, p2p4Test, p2p5Test, 1.,
1841 p1p4Test * p2p5Test, p1p5Test * p2p4Test, p1p4Test * p1p5Test,
1842 p2p4Test * p2p5Test};
1844 for (
int i = 0; i < 9; ++i) wtTest += con[i] * testValues[i];
1845 if (wtTest > wtMax) wtMax = wtTest;
1857 RotBstMatrix MrndmRot;
1858 MrndmRot.rot( acos(2. * rndmPtr->flat() - 1.),
1859 2. * M_PI * rndmPtr->flat());
1860 pDec1.rotbst(MrndmRot);
1861 pDec2.rotbst(MrndmRot);
1867 double p1p4 = p1 * pDec1;
1868 double p1p5 = p1 * pDec2;
1869 double p2p4 = p2 * pDec1;
1870 double p2p5 = p2 * pDec2;
1873 double wtValues[9] = { p1p4, p1p5, p2p4, p2p5, 1., p1p4 * p2p5,
1874 p1p5 * p2p4, p1p4 * p1p5, p2p4 * p2p5};
1876 for (
int i = 0; i < 9; ++i) wt += con[i] * wtValues[i];
1877 if (wt > wtMax || wt < 0.) {
1878 infoPtr->errorMsg(
"Error in PartonLevel::wzDecayShowers: "
1879 "wt bigger than wtMax or less than zero");
1882 }
while (wt < wtMax * rndmPtr->flat());
1886 pDec1.rotbst( MtoCM);
1887 pDec2.rotbst( MtoCM);
1888 if (event[sizeSave].
id() > 0) {
1889 event[sizeSave].p( pDec1);
1890 event[sizeSave + 1].p( pDec2);
1893 event[sizeSave].p( pDec2);
1894 event[sizeSave + 1].p( pDec1);
1902 double pTmax = 0.5 *
event[iWZ].m();
1903 int iSys = partonSystemsPtr->addSys();
1904 partonSystemsPtr->setSHat(iSys, pow2(event[iWZ].m()) );
1905 partonSystemsPtr->setPTHat(iSys, pTmax );
1906 for (
int i = sizeSave; i <
event.size(); ++i)
1907 partonSystemsPtr->addOut( iSys, i);
1910 if (doFSRinResonances) {
1913 timesDecPtr->prepare( iSys, event);
1917 double pTtimes = timesDecPtr->pTnext( event, pTmax, 0.);
1921 timesDecPtr->branch( event);
1929 }
while (pTmax > 0.);