9 #include "Pythia8/DireTimes.h"
10 #include "Pythia8/DireSpace.h"
11 #include "Pythia8/DireHistory.h"
19 bool operator==(
const DireTimesEnd& dip1,
const DireTimesEnd& dip2) {
20 return dip1.iRadiator == dip2.iRadiator
21 && dip1.iRecoiler == dip2.iRecoiler
22 && dip1.colType == dip2.colType
23 && dip1.isrType == dip2.isrType
24 && dip1.allowedEmissions == dip2.allowedEmissions;
37 const double DireTimes::MCMIN = 1.2;
38 const double DireTimes::MBMIN = 4.0;
41 const double DireTimes::SIMPLIFYROOT = 1e-8;
46 const double DireTimes::XMARGIN = 1e-12;
47 const double DireTimes::XMARGINCOMB = 1e-4;
50 const double DireTimes::TINYPDF = 1e-5;
54 const int DireTimes::MAXLOOPTINYPDF = 10;
57 const double DireTimes::LARGEM2 = 1e20;
60 const double DireTimes::THRESHM2 = 4.004;
63 const double DireTimes::LAMBDA3MARGIN = 1.1;
66 const double DireTimes::TINYMASS = 1e-3;
69 const double DireTimes::TINYOVERESTIMATE = 1e-15;
72 const double DireTimes::PT2MIN_PDF_IN_OVERESTIMATE = 5.;
75 const double DireTimes::PT2_INCREASE_OVERESTIMATE = 2.;
77 const double DireTimes::KERNEL_HEADROOM = 10.;
81 const double DireTimes::LEPTONZMAX = 1. - 1e-4;
87 void DireTimes::init( BeamParticle* beamAPtrIn,
88 BeamParticle* beamBPtrIn) {
93 CA = settingsPtr->parm(
"DireColorQCD:CA") > 0.0
94 ? settingsPtr->parm(
"DireColorQCD:CA") : 3.0;
95 CF = settingsPtr->parm(
"DireColorQCD:CF") > 0.0
96 ? settingsPtr->parm(
"DireColorQCD:CF") : 4./3.;
97 TR = settingsPtr->parm(
"DireColorQCD:TR") > 0.
98 ? settingsPtr->parm(
"DireColorQCD:TR") : 0.5;
99 NC = settingsPtr->parm(
"DireColorQCD:NC") > 0.
100 ? settingsPtr->parm(
"DireColorQCD:NC") : 3.0;
103 processLevel.initInfoPtr(*infoPtr);
104 processLevel.initDecays(
nullptr);
107 beamAPtr = beamAPtrIn;
108 beamBPtr = beamBPtrIn;
111 doQCDshower = settingsPtr->flag(
"TimeShower:QCDshower");
112 doQEDshowerByQ = settingsPtr->flag(
"TimeShower:QEDshowerByQ");
113 doQEDshowerByL = settingsPtr->flag(
"TimeShower:QEDshowerByL");
114 doDecaysAsShower = settingsPtr->flag(
"DireTimes:DecaysAsShower");
116 doMEcorrections = settingsPtr->flag(
"Dire:doMECs")
117 || settingsPtr->flag(
"Dire:doMOPS");
118 doMEafterFirst = settingsPtr->flag(
"TimeShower:MEafterFirst");
119 doPhiPolAsym = settingsPtr->flag(
"TimeShower:phiPolAsym");
120 doInterleave = settingsPtr->flag(
"TimeShower:interleave");
121 allowBeamRecoil = settingsPtr->flag(
"TimeShower:allowBeamRecoil");
122 dampenBeamRecoil = settingsPtr->flag(
"TimeShower:dampenBeamRecoil");
123 recoilToColoured = settingsPtr->flag(
"TimeShower:recoilToColoured");
126 pTmaxMatch = settingsPtr->mode(
"TimeShower:pTmaxMatch");
127 pTdampMatch = settingsPtr->mode(
"TimeShower:pTdampMatch");
128 pTmaxFudge = settingsPtr->parm(
"TimeShower:pTmaxFudge");
129 pTmaxFudgeMPI = settingsPtr->parm(
"TimeShower:pTmaxFudgeMPI");
130 pTdampFudge = settingsPtr->parm(
"TimeShower:pTdampFudge");
131 pT2minVariations = pow2(max(0.,settingsPtr->parm(
"Variations:pTmin")));
132 pT2minEnhance = pow2(max(0.,settingsPtr->parm(
"Enhance:pTmin")));
133 pT2minMECs = pow2(max(0.,settingsPtr->parm(
"Dire:pTminMECs")));
134 Q2minMECs = pow2(max(0.,settingsPtr->parm(
"Dire:QminMECs")));
135 nFinalMaxMECs = settingsPtr->mode(
"Dire:nFinalMaxMECs");
136 suppressLargeMECs = settingsPtr->flag(
"Dire:suppressLargeMECs");
138 pow2(max(0.,settingsPtr->parm(
"DireTimes:pTrecombine")));
141 mc = max( MCMIN, particleDataPtr->m0(4));
142 mb = max( MBMIN, particleDataPtr->m0(5));
147 renormMultFac = settingsPtr->parm(
"TimeShower:renormMultFac");
148 factorMultFac = settingsPtr->parm(
"TimeShower:factorMultFac");
149 useFixedFacScale = settingsPtr->flag(
"TimeShower:useFixedFacScale");
150 fixedFacScale2 = pow2(settingsPtr->parm(
"TimeShower:fixedFacScale"));
153 alphaSvalue = settingsPtr->parm(
"TimeShower:alphaSvalue");
154 alphaSorder = settingsPtr->mode(
"TimeShower:alphaSorder");
155 alphaSnfmax = settingsPtr->mode(
"StandardModel:alphaSnfmax");
156 alphaSuseCMW = settingsPtr->flag(
"TimeShower:alphaSuseCMW");
157 alphaS2pi = 0.5 * alphaSvalue / M_PI;
158 asScheme = settingsPtr->mode(
"DireTimes:alphasScheme");
161 double mcpy = particleDataPtr->m0(4);
162 double mbpy = particleDataPtr->m0(5);
163 double mtpy = particleDataPtr->m0(6);
164 if (mcpy > 0.0 && mbpy > 0.0 && mtpy > 0.0)
165 alphaS.setThresholds(mcpy, mbpy, mtpy);
168 alphaS.init( alphaSvalue, alphaSorder, alphaSnfmax, alphaSuseCMW);
171 Lambda3flav = alphaS.Lambda3();
172 Lambda4flav = alphaS.Lambda4();
173 Lambda5flav = alphaS.Lambda5();
174 Lambda5flav2 = pow2(Lambda5flav);
175 Lambda4flav2 = pow2(Lambda4flav);
176 Lambda3flav2 = pow2(Lambda3flav);
179 nGluonToQuark = settingsPtr->mode(
"TimeShower:nGluonToQuark");
180 pTcolCutMin = settingsPtr->parm(
"TimeShower:pTmin");
181 if (pTcolCutMin > LAMBDA3MARGIN * Lambda3flav / sqrt(renormMultFac))
182 pTcolCut = pTcolCutMin;
184 pTcolCut = LAMBDA3MARGIN * Lambda3flav / sqrt(renormMultFac);
185 ostringstream newPTcolCut;
186 newPTcolCut << fixed << setprecision(3) << pTcolCut;
187 infoPtr->errorMsg(
"Warning in DireTimes::init: pTmin too low",
188 ", raised to " + newPTcolCut.str() );
189 infoPtr->setTooLowPTmin(
true);
191 pT2colCut = pow2(pTcolCut);
192 m2colCut = pT2colCut;
193 mTolErr = settingsPtr->parm(
"Check:mTolErr");
195 double pT2minQED = pow2(settingsPtr->parm(
"TimeShower:pTminChgQ"));
196 pT2minQED = min(pT2minQED, pow2(settingsPtr->parm(
"TimeShower:pTminChgL")));
197 pT2cutSave = create_unordered_map<int,double>
199 (1,pT2colCut)(-1,pT2colCut)(2,pT2colCut)(-2,pT2colCut)
200 (3,pT2colCut)(-3,pT2colCut)(4,pT2colCut)(-4,pT2colCut)
201 (5,pT2colCut)(-5,pT2colCut)(6,pT2colCut)(-6,pT2colCut)
203 (11,pT2minQED)(-11,pT2minQED)(13,pT2minQED)(-13,pT2minQED)
204 (15,pT2minQED)(-15,pT2minQED)
205 (900032,pT2minQED)(900012,pT2minQED)
209 pTchgQCut = settingsPtr->parm(
"TimeShower:pTminChgQ");
210 pT2chgQCut = pow2(pTchgQCut);
211 pTchgLCut = settingsPtr->parm(
"TimeShower:pTminChgL");
212 pT2chgLCut = pow2(pTchgLCut);
214 bool_settings = create_unordered_map<string,bool>
215 (
"doQEDshowerByL",doQEDshowerByL)
216 (
"doQEDshowerByQ",doQEDshowerByQ);
218 usePDFalphas = settingsPtr->flag(
"ShowerPDF:usePDFalphas");
219 useSummedPDF = settingsPtr->flag(
"ShowerPDF:useSummedPDF");
220 BeamParticle*
beam = NULL;
221 if (beamAPtr != NULL || beamBPtr != NULL) {
222 beam = (beamAPtr != NULL && particleDataPtr->isHadron(beamAPtr->id())) ?
224 : (beamBPtr != NULL && particleDataPtr->isHadron(beamBPtr->id())) ?
226 if (beam == NULL && beamAPtr != 0) beam = beamAPtr;
227 if (beam == NULL && beamBPtr != 0) beam = beamBPtr;
229 alphaS2piOverestimate = (usePDFalphas && beam != NULL)
230 ? beam->alphaS(pT2colCut) * 0.5/M_PI
231 : (alphaSorder > 0) ? alphaS.alphaS(pT2colCut)*0.5/M_PI
234 m2cPhys = (usePDFalphas) ? pow2(max(0.,beam->mQuarkPDF(4)))
235 : alphaS.muThres2(4);
236 m2bPhys = (usePDFalphas) ? pow2(max(0.,beam->mQuarkPDF(5)))
237 : alphaS.muThres2(5);
240 alphaEMorder = settingsPtr->mode(
"TimeShower:alphaEMorder");
243 alphaEM.init( alphaEMorder, settingsPtr);
246 nGammaToQuark = settingsPtr->mode(
"TimeShower:nGammaToQuark");
247 nGammaToLepton = settingsPtr->mode(
"TimeShower:nGammaToLepton");
248 sumCharge2L = max(0, min(3, nGammaToLepton));
250 if (nGammaToQuark > 4) sumCharge2Q = 11. / 9.;
251 else if (nGammaToQuark > 3) sumCharge2Q = 10. / 9.;
252 else if (nGammaToQuark > 2) sumCharge2Q = 6. / 9.;
253 else if (nGammaToQuark > 1) sumCharge2Q = 5. / 9.;
254 else if (nGammaToQuark > 0) sumCharge2Q = 1. / 9.;
255 sumCharge2Tot = sumCharge2L + 3. * sumCharge2Q;
259 useMassiveBeams =
false;
262 mZ = particleDataPtr->m0(23);
263 gammaZ = particleDataPtr->mWidth(23);
264 thetaW = 1. / (16. * coupSMPtr->sin2thetaW()
265 * coupSMPtr->cos2thetaW());
266 mW = particleDataPtr->m0(24);
267 gammaW = particleDataPtr->mWidth(24);
269 nFinalMax = settingsPtr->mode(
"DireTimes:nFinalMax");
270 usePDFmasses = settingsPtr->flag(
"ShowerPDF:usePDFmasses");
273 kernelOrder = settingsPtr->mode(
"DireTimes:kernelOrder");
274 kernelOrderMPI = settingsPtr->mode(
"DireTimes:kernelOrderMPI");
278 rejectProbability.insert( make_pair(key, multimap<double,double>() ));
279 acceptProbability.insert( make_pair(key, map<double,double>() ));
280 doVariations = settingsPtr->flag(
"Variations:doVariations");
288 if (splittingsPtr) splits = splittingsPtr->getSplittings();
291 for ( unordered_map<string,DireSplitting*>::iterator it = splits.begin();
292 it != splits.end(); ++it ) {
293 overhead.insert(make_pair(it->first,1.));
297 allowRescatter = settingsPtr->flag(
"PartonLevel:MPI")
298 && settingsPtr->flag(
"MultipartonInteractions:allowRescatter");
301 doSecondHard = settingsPtr->flag(
"SecondHard:generate");
304 hasUserHooks = (userHooksPtr != 0);
305 canVetoEmission = (userHooksPtr != 0)
306 ? userHooksPtr->canVetoFSREmission() :
false;
321 void DireTimes::initVariations() {
324 for (
int i=0; i < weights->sizeWeights(); ++i) {
325 string key = weights->weightName(i);
326 if ( key.compare(
"base") == 0)
continue;
327 if ( key.find(
"isr") != string::npos)
continue;
328 rejectProbability.insert( make_pair(key, multimap<double,double>() ));
329 acceptProbability.insert( make_pair(key, map<double,double>() ));
332 for ( unordered_map<
string, multimap<double,double> >::iterator
333 it = rejectProbability.begin(); it != rejectProbability.end(); ++it )
335 for ( unordered_map<
string, map<double,double> >::iterator
336 it = acceptProbability.begin(); it != acceptProbability.end(); ++it )
347 bool DireTimes::limitPTmax(
Event& event,
double,
double) {
350 bool dopTlimit =
false;
351 dopTlimit1 = dopTlimit2 =
false;
353 if (pTmaxMatch == 1) dopTlimit = dopTlimit1 = dopTlimit2 =
true;
354 else if (pTmaxMatch == 2) dopTlimit = dopTlimit1 = dopTlimit2 =
false;
357 else if (infoPtr->isNonDiffractive() || infoPtr->isDiffractiveA()
358 || infoPtr->isDiffractiveB() || infoPtr->isDiffractiveC() )
359 dopTlimit = dopTlimit1 = dopTlimit2 =
true;
365 for (
int i = 5; i <
event.size(); ++i) {
366 if (event[i].status() == -21) ++n21;
368 int idAbs =
event[i].idAbs();
369 if (idAbs <= 5 || idAbs == 21 || idAbs == 22) dopTlimit1 =
true;
370 if ( (event[i].col() != 0 || event[i].acol() != 0)
371 && idAbs > 5 && idAbs != 21 ) ++nHeavyCol;
372 }
else if (n21 == 2) {
373 int idAbs =
event[i].idAbs();
374 if (idAbs <= 5 || idAbs == 21 || idAbs == 22) dopTlimit2 =
true;
377 dopTlimit = (doSecondHard) ? (dopTlimit1 && dopTlimit2) : dopTlimit1;
391 void DireTimes::finalize(
Event& event ) {
395 int resSize = direInfoPtr->sizeResPos();
396 for (
int i=0; i < resSize; ++i){
397 int iRes = direInfoPtr->getResPos(i);
398 int sizeOld =
event.size();
401 decays.init(
"(decays)", particleDataPtr);
403 int iMother =
event[iRes].mother1();
404 decays.append(event[iMother]);
405 decays.append(event[iRes]);
406 decays[decays.size()-1].mother1(0);
407 processLevel.nextDecays(decays);
408 if (decays.size() < 3) {
409 infoPtr->errorMsg(
"Error in DireTimes::finalize: "
410 "Failed to decay shower-induced resonance");
414 int iDauMin = sizeOld;
415 int iDauMax = sizeOld + decays.size()-3;
416 event[direInfoPtr->getResPos(i)].statusNeg();
417 event[direInfoPtr->getResPos(i)].daughters(iDauMin,iDauMax);
418 int iBeg =
event.size()-1;
420 for (
int iDecay = 2; iDecay < decays.size(); ++iDecay) {
421 if (!decays[iDecay].isFinal())
continue;
422 event.append(decays[iDecay]);
423 event[
event.size()-1].mothers(direInfoPtr->getResPos(i),0);
428 int iSys = partonSystemsPtr->addSys();
431 for (
int ii = iBeg; ii <= iEnd; ++ii)
if (event[ii].isFinal()) {
432 partonSystemsPtr->addOut( iSys, ii);
433 pSum +=
event[ii].p();
435 partonSystemsPtr->setSHat( iSys, pSum.m2Calc() );
438 direInfoPtr->clearResPos();
450 int DireTimes::shower(
int iBeg,
int iEnd,
Event& event,
double pTmax,
454 int iSys = partonSystemsPtr->addSys();
458 for (
int i = iBeg; i <= iEnd; ++i)
if (event[i].isFinal()) {
459 partonSystemsPtr->addOut( iSys, i);
460 pSum +=
event[i].p();
462 partonSystemsPtr->setSHat( iSys, pSum.m2Calc() );
468 prepare( iSys, event,
true);
474 double pTtimes = pTnext( event, pTmax, 0.);
478 if (branch( event)) {
480 pTLastBranch = pTtimes;
487 }
while (pTmax > 0. && (nBranchMax <= 0 || nBranch < nBranchMax));
499 int DireTimes::showerQED(
int i1,
int i2,
Event& event,
double pTmax) {
502 int iSys = partonSystemsPtr->addSys();
503 partonSystemsPtr->addOut( iSys, i1);
504 partonSystemsPtr->addOut( iSys, i2);
505 partonSystemsPtr->setSHat( iSys, m2(event[i1], event[i2]) );
508 double scale1 =
event[i1].scale();
509 event[i1].scale(pTmax);
510 double scale2 =
event[i2].scale();
511 event[i2].scale(pTmax);
517 prepare( iSys, event,
false);
524 double pTsel = pTnext( event, pTmax, 0.,
false,
false);
531 pTLastBranch = pTsel;
536 }
while (pTmax > 0.);
539 event[i1].scale(scale1);
540 event[i2].scale(scale2);
551 void DireTimes::prepareGlobal(
Event& ) {
557 direInfoPtr->clearAll();
561 for ( unordered_map<
string, multimap<double,double> >::iterator
562 it = rejectProbability.begin(); it != rejectProbability.end(); ++it )
564 for ( unordered_map<
string, map<double,double> >::iterator
565 it = acceptProbability.begin(); it != acceptProbability.end(); ++it )
569 unordered_map<string,DireSplitting*> tmpSplits = splittingsPtr->
571 for ( unordered_map<string,DireSplitting*>::iterator it = tmpSplits.begin();
572 it != tmpSplits.end(); ++it ) {
573 if (it->second->isr) { it->second->isr->resetWeights();
break; }
583 void DireTimes::prepare(
int iSys,
Event& event,
bool limitPTmaxIn) {
586 if (nMPI < infoPtr->getCounter(23)
587 && iSys == infoPtr->getCounter(23) ) {
588 weights->calcWeight(pow2(infoPtr->pTnow()));
591 for ( unordered_map<
string, multimap<double,double> >::iterator
592 it = rejectProbability.begin(); it != rejectProbability.end(); ++it )
594 for ( unordered_map<
string, map<double,double> >::iterator
595 it = acceptProbability.begin(); it != acceptProbability.end(); ++it )
600 nMPI = infoPtr->getCounter(23);
603 int iInA = partonSystemsPtr->getInA(iSys);
604 int iInB = partonSystemsPtr->getInB(iSys);
605 if (iSys == 0 || iInA == 0) dipEnd.resize(0);
606 int dipEndSizeBeg = dipEnd.size();
609 splits = splittingsPtr->getSplittings();
611 for ( unordered_map<string,DireSplitting*>::iterator it = splits.begin();
612 it != splits.end(); ++it ) {
613 overhead.insert(make_pair(it->first,1.));
617 if (partonSystemsPtr->sizeOut(iSys) < 2) {
619 for (
int i = 0; i < partonSystemsPtr->sizeOut(iSys); ++i) {
620 int iRad = partonSystemsPtr->getOut( iSys, i);
621 if ( event[iRad].isFinal()
622 && event[iRad].scale() > 0.
623 && event[iRad].isResonance())
625 if (doDecaysAsShower) setupDecayDip( iSys, iRad, event, dipEnd);
631 if (doSecondHard && iSys == 0) limitPTmaxIn = dopTlimit1;
632 if (doSecondHard && iSys == 1) limitPTmaxIn = dopTlimit2;
637 for (
int i = 0; i < partonSystemsPtr->sizeOut(iSys); ++i) {
638 int iRad = partonSystemsPtr->getOut( iSys, i);
640 if (event[iRad].isFinal() && event[iRad].scale() > 0.) {
643 int colTag =
event[iRad].col();
644 if (doQCDshower && colTag > 0) setupQCDdip( iSys, i, colTag, 1, event,
645 false, limitPTmaxIn);
648 int acolTag =
event[iRad].acol();
649 if (doQCDshower && acolTag > 0) setupQCDdip( iSys, i, acolTag, -1, event,
650 false, limitPTmaxIn);
653 getGenDip( iSys, i, iRad, event, limitPTmaxIn, dipEnd);
659 if (doDecaysAsShower && event[iRad].isResonance())
660 setupDecayDip( iSys, iRad, event, dipEnd);
665 for (
int iDip = dipEndSizeBeg; iDip < int(dipEnd.size()); ++iDip)
666 dipEnd[iDip].MEtype = 0;
670 updateDipoles(event, iSys);
672 bornColors.resize(0);
673 for (
int iDip = 0; iDip < int(dipEnd.size()); ++iDip) {
674 int colRad =
event[dipEnd[iDip].iRadiator].col();
675 int acolRad =
event[dipEnd[iDip].iRadiator].acol();
676 if ( dipEnd[iDip].colType > 0
677 && find(bornColors.begin(), bornColors.end(), colRad) == bornColors.end())
678 bornColors.push_back(colRad);
679 if ( dipEnd[iDip].colType < 0
680 && find(bornColors.begin(), bornColors.end(), acolRad) ==
682 bornColors.push_back(acolRad);
686 if (iSys > 0 && ( (iInA > 0 && event[iInA].status() == -34)
687 || (iInB > 0 && event[iInB].status() == -34) ) )
688 rescatterUpdate( iSys, event);
692 if ( nProposedPT.find(iSys) == nProposedPT.end() )
693 nProposedPT.insert(make_pair(iSys,0));
699 for ( unordered_map<
string, multimap<double,double> >::iterator
700 it = rejectProbability.begin(); it != rejectProbability.end(); ++it )
702 for ( unordered_map<
string, map<double,double> >::iterator
703 it = acceptProbability.begin(); it != acceptProbability.end(); ++it )
710 void DireTimes::clear() {
720 for ( unordered_map<
string, multimap<double,double> >::iterator
721 it = rejectProbability.begin(); it != rejectProbability.end(); ++it )
723 for ( unordered_map<
string, map<double,double> >::iterator
724 it = acceptProbability.begin(); it != acceptProbability.end(); ++it )
733 void DireTimes::rescatterUpdate(
int iSys,
Event& event) {
737 for (
int iResc = 0; iResc < 2; ++iResc) {
738 int iIn = (iResc == 0) ? partonSystemsPtr->getInA(iSys)
739 : partonSystemsPtr->getInB(iSys);
740 if (iIn == 0 || event[iIn].status() != -34)
continue;
741 int iOut =
event[iIn].mother1();
744 int dipEndSize = dipEnd.size();
745 for (
int iDip = 0; iDip < dipEndSize; ++iDip) {
746 DireTimesEnd& dipNow = dipEnd[iDip];
749 if (dipNow.iRadiator == iOut) {
756 if (dipNow.iMEpartner == iOut) {
758 dipNow.iMEpartner = -1;
762 if (dipNow.iRecoiler == iOut) {
763 int iRad = dipNow.iRadiator;
766 if (dipNow.colType > 0) {
767 int colTag =
event[iRad].col();
769 for (
int i = 0; i < partonSystemsPtr->sizeOut(iSys); ++i) {
770 int iRecNow = partonSystemsPtr->getOut( iSys, i);
771 if (event[iRecNow].acol() == colTag) {
772 dipNow.iRecoiler = iRecNow;
773 dipNow.systemRec = iSys;
780 int iIn2 = (iResc == 0) ? partonSystemsPtr->getInB(iSys)
781 : partonSystemsPtr->getInA(iSys);
782 if (event[iIn2].col() == colTag) {
783 dipNow.iRecoiler = iIn2;
784 dipNow.systemRec = iSys;
786 int isrType =
event[iIn2].mother1();
788 while (isrType > 2 + beamOffset)
789 isrType =
event[isrType].mother1();
790 if (isrType > 2) isrType -= beamOffset;
791 dipNow.isrType = isrType;
797 int iRadNow = partonSystemsPtr->getIndexOfOut(dipNow.system, iRad);
799 setupQCDdip(dipNow.system, iRadNow, event[iRad].col(), 1,
800 event, dipNow.isOctetOnium,
true);
802 infoPtr->errorMsg(
"Warning in DireTimes::rescatterUpdate: "
803 "failed to locate radiator in system");
809 infoPtr->errorMsg(
"Warning in DireTimes::rescatterUpdate: "
810 "failed to locate new recoiling colour partner");
814 }
else if (dipNow.colType < 0) {
815 int acolTag =
event[iRad].acol();
817 for (
int i = 0; i < partonSystemsPtr->sizeOut(iSys); ++i) {
818 int iRecNow = partonSystemsPtr->getOut( iSys, i);
819 if (event[iRecNow].col() == acolTag) {
820 dipNow.iRecoiler = iRecNow;
821 dipNow.systemRec = iSys;
828 int iIn2 = (iResc == 0) ? partonSystemsPtr->getInB(iSys)
829 : partonSystemsPtr->getInA(iSys);
830 if (event[iIn2].acol() == acolTag) {
831 dipNow.iRecoiler = iIn2;
832 dipNow.systemRec = iSys;
834 int isrType =
event[iIn2].mother1();
836 while (isrType > 2 + beamOffset)
837 isrType =
event[isrType].mother1();
838 if (isrType > 2) isrType -= beamOffset;
839 dipNow.isrType = isrType;
845 int iRadNow = partonSystemsPtr->getIndexOfOut(dipNow.system, iRad);
847 setupQCDdip(dipNow.system, iRadNow, event[iRad].acol(), -1,
848 event, dipNow.isOctetOnium,
true);
850 infoPtr->errorMsg(
"Warning in DireTimes::rescatterUpdate: "
851 "failed to locate radiator in system");
857 infoPtr->errorMsg(
"Warning in DireTimes::rescatterUpdate: "
858 "failed to locate new recoiling colour partner");
873 void DireTimes::update(
int iSys,
Event& event,
bool) {
876 vector <DireTimesEnd> dipLT;
877 vector <DireTimesEnd> dipGT;
878 for (
int iDip = 0; iDip < int(dipEnd.size()); ++iDip) {
879 if (dipEnd[iDip].system < iSys) dipLT.push_back(dipEnd[iDip]);
880 if (dipEnd[iDip].system > iSys) dipGT.push_back(dipEnd[iDip]);
888 if (partonSystemsPtr->sizeOut(iSys) < 2)
return;
891 for (
int i = 0; i < partonSystemsPtr->sizeOut(iSys); ++i) {
892 int iRad = partonSystemsPtr->getOut( iSys, i);
894 if (event[iRad].isFinal() && event[iRad].scale() > 0.) {
897 int colTag =
event[iRad].col();
898 if (doQCDshower && colTag > 0) setupQCDdip( iSys, i, colTag, 1, event,
902 int acolTag =
event[iRad].acol();
903 if (doQCDshower && acolTag > 0) setupQCDdip( iSys, i, acolTag, -1, event,
907 getGenDip( iSys, i, iRad, event,
false, dipEnd);
913 if (doDecaysAsShower && event[iRad].isResonance())
914 setupDecayDip( iSys, iRad, event, dipEnd);
918 dipEnd.insert( dipEnd.begin(), dipLT.begin(), dipLT.end());
919 dipEnd.insert( dipEnd.end(), dipGT.begin(), dipGT.end());
922 updateDipoles(event, iSys);
930 void DireTimes::setupQCDdip(
int iSys,
int i,
int colTag,
int colSign,
931 Event& event,
bool isOctetOnium,
bool limitPTmaxIn) {
934 int iRad = partonSystemsPtr->getOut(iSys, i);
936 int sizeAllA = partonSystemsPtr->sizeAll(iSys);
937 int sizeOut = partonSystemsPtr->sizeOut(iSys);
938 int sizeAll = ( allowBeamRecoil ) ? sizeAllA : sizeOut;
939 int sizeIn = sizeAll - sizeOut;
940 int sizeInA = sizeAllA - sizeIn - sizeOut;
941 int iOffset = i + sizeAllA - sizeOut;
942 bool otherSystemRec =
false;
943 bool allowInitial = (partonSystemsPtr->hasInAB(iSys)) ?
true :
false;
944 vector<int> iRecVec(0);
949 for (
int j = 0; j < sizeAll; ++j)
if (j + sizeInA != iOffset) {
950 int iRecNow = partonSystemsPtr->getAll(iSys, j + sizeInA);
951 if ( ( j < sizeIn && event[iRecNow].col() == colTag
952 && !event[iRecNow].isRescatteredIncoming() )
953 || ( j >= sizeIn && event[iRecNow].acol() == colTag
954 && event[iRecNow].isFinal() ) ) {
963 for (
int j = 0; j < sizeAll; ++j)
if (j + sizeInA != iOffset) {
964 int iRecNow = partonSystemsPtr->getAll(iSys, j + sizeInA);
965 if ( ( j < sizeIn && event[iRecNow].acol() == colTag
966 && !event[iRecNow].isRescatteredIncoming() )
967 || ( j >= sizeIn && event[iRecNow].col() == colTag
968 && event[iRecNow].isFinal() ) ) {
978 bool hasJunction =
false;
979 if (iRec == 0 && !allowInitial) {
980 for (
int iJun = 0; iJun <
event.sizeJunction(); ++ iJun) {
984 int iBeg = (
event.kindJunction(iJun)-1)/2;
985 for (
int iLeg = iBeg; iLeg < 3; ++iLeg)
986 if (event.endColJunction( iJun, iLeg) == colTag) hasJunction =
true;
988 double ppMin = LARGEM2;
989 for (
int j = 0; j < sizeOut; ++j)
if (j != i) {
990 int iRecNow = partonSystemsPtr->getOut(iSys, j);
991 if (!event[iRecNow].isFinal())
continue;
992 double ppNow =
event[iRecNow].p() *
event[iRad].p()
993 -
event[iRecNow].m() *
event[iRad].m();
1003 for (
int j = 0; j <
event.size(); ++j)
if (event[j].isFinal()) {
1004 if ( (colSign > 0 && event[j].acol() == colTag)
1005 || (colSign < 0 &&
event[j].col() == colTag) ) {
1007 otherSystemRec =
true;
1013 if (iRec == 0 && allowInitial) {
1014 for (
int iSysR = 0; iSysR < partonSystemsPtr->sizeSys(); ++iSysR)
1015 if (iSysR != iSys) {
1016 int j = partonSystemsPtr->getInA(iSysR);
1017 if (j > 0 && event[j].isRescatteredIncoming()) j = 0;
1018 if (j > 0 && ( (colSign > 0 && event[j].col() == colTag)
1019 || (colSign < 0 && event[j].acol() == colTag) ) ) {
1021 otherSystemRec =
true;
1024 j = partonSystemsPtr->getInB(iSysR);
1025 if (j > 0 && event[j].isRescatteredIncoming()) j = 0;
1026 if (j > 0 && ( (colSign > 0 && event[j].col() == colTag)
1027 || (colSign < 0 && event[j].acol() == colTag) ) ) {
1029 otherSystemRec =
true;
1045 for (
int iJun = 0; iJun <
event.sizeJunction(); ++ iJun) {
1046 int kindJun =
event.kindJunction(iJun);
1047 int iBeg = (kindJun-1)/2;
1048 for (
int iLeg = iBeg; iLeg < 3; ++iLeg) {
1049 if (event.endColJunction( iJun, iLeg) == colTag) {
1057 if (sizeOut == 1)
return;
1062 else if (kindJun >= 3) {
1063 int iLegRec = 3-iLeg;
1064 int colTagRec =
event.endColJunction( iJun, iLegRec);
1065 for (
int j = 0; j < sizeOut; ++j)
if (j != i) {
1066 int iRecNow = partonSystemsPtr->getOut(iSys, j);
1067 if (!event[iRecNow].isFinal())
continue;
1068 if ( (colSign > 0 && event[iRecNow].col() == colTagRec)
1069 || (colSign < 0 && event[iRecNow].acol() == colTagRec) ) {
1080 for (
int jLeg = 1; jLeg <= 2; jLeg++) {
1081 int iLegRec = (iLeg + jLeg) % 3;
1082 int colTagRec =
event.endColJunction( iJun, iLegRec);
1083 for (
int j = 0; j < sizeOut; ++j)
if (j != i) {
1084 int iRecNow = partonSystemsPtr->getOut(iSys, j);
1085 if (!event[iRecNow].isFinal())
continue;
1086 if ( (colSign > 0 && event[iRecNow].col() == colTagRec)
1087 || (colSign < 0 && event[iRecNow].acol() == colTagRec) ) {
1089 iRecVec.push_back(iRecNow);
1107 double ppMin = LARGEM2;
1108 for (
int j = 0; j < sizeOut; ++j)
if (j != i) {
1109 int iRecNow = partonSystemsPtr->getOut(iSys, j);
1110 if (!event[iRecNow].isFinal())
continue;
1111 double ppNow =
event[iRecNow].p() *
event[iRad].p()
1112 -
event[iRecNow].m() *
event[iRad].m();
1113 if (ppNow < ppMin) {
1123 double ppMin = LARGEM2;
1124 for (
int iRecNow = 0; iRecNow <
event.size(); ++iRecNow)
1125 if (iRecNow != iRad && event[iRecNow].isFinal()) {
1126 double ppNow =
event[iRecNow].p() *
event[iRad].p()
1127 -
event[iRecNow].m() *
event[iRad].m();
1128 if (ppNow < ppMin) {
1130 otherSystemRec =
true;
1137 if (iRecVec.size() == 0 && iRec != 0) iRecVec.push_back(iRec);
1140 int nRec = iRecVec.size();
1141 for (
unsigned int mRec = 0; mRec < iRecVec.size(); ++mRec)
1142 if (iRecVec[mRec] <= 0) nRec--;
1146 infoPtr->errorMsg(
"Error in DireTimes::setupQCDdip: "
1147 "failed to locate any recoiling partner");
1152 for (
unsigned int mRec = 0; mRec < iRecVec.size(); ++mRec) {
1153 iRec = iRecVec[mRec];
1154 if (iRec <= 0)
continue;
1156 double pTmax =
event[iRad].scale();
1158 if (iSys == 0 || (iSys == 1 && doSecondHard)) pTmax *= pTmaxFudge;
1159 else if (sizeIn > 0) pTmax *= pTmaxFudgeMPI;
1161 }
else pTmax = m( event[iRad], event[iRec]);
1164 if ( abs(event[iRad].status()) > 20 && abs(event[iRad].status()) < 24
1165 && settingsPtr->flag(
"Beams:setProductionScalesFromLHEF")
1166 &&
event[iRad].scale() > 0.)
1167 pTmax =
event[iRad].scale();
1169 int colType = (
event[iRad].id() == 21) ? 2 * colSign : colSign;
1170 int isrType = (
event[iRec].isFinal()) ? 0 : event[iRec].mother1();
1172 while (isrType > 2 + beamOffset) isrType =
event[isrType].mother1();
1173 if (isrType > 2) isrType -= beamOffset;
1174 appendDipole( event, iRad, iRec, pTmax, colType, 0, 0, 0, isrType, iSys,
1175 -1, -1, 0, isOctetOnium, dipEnd);
1178 if (otherSystemRec) {
1179 int systemRec = partonSystemsPtr->getSystemOf(iRec,
true);
1180 if (systemRec >= 0) dipEnd.back().systemRec = systemRec;
1181 dipEnd.back().MEtype = 0;
1192 void DireTimes::setupDecayDip(
int iSys,
int iRad,
const Event& event,
1193 vector<DireTimesEnd>& dipEnds) {
1197 int sizeOut = partonSystemsPtr->sizeOut(iSys);
1198 bool allowInitial = (partonSystemsPtr->hasInAB(iSys)) ?
true :
false;
1202 double ppMin = LARGEM2;
1203 for (
int j = 0; j < sizeOut; ++j) {
1204 int iRecNow = partonSystemsPtr->getOut(iSys, j);
1205 if (iRecNow == iRad || !event[iRecNow].isFinal())
continue;
1206 double ppNow =
event[iRecNow].p() *
event[iRad].p()
1207 -
event[iRecNow].m() *
event[iRad].m();
1208 if (ppNow < ppMin) {
1216 if (iRec == 0 && allowInitial) {
1219 int iRecNow = partonSystemsPtr->getInA(iSys);
1220 double ppNow =
event[iRecNow].p() *
event[iRad].p()
1221 -
event[iRecNow].m() *
event[iRad].m();
1222 if (ppNow < ppMin) {
1228 iRecNow = partonSystemsPtr->getInB(iSys);
1229 ppNow =
event[iRecNow].p() *
event[iRad].p()
1230 -
event[iRecNow].m() *
event[iRad].m();
1231 if (ppNow < ppMin) {
1237 double pTmax = m( event[iRad], event[iRec]);
1238 int colType =
event[iRad].colType();
1239 int isrType = (
event[iRec].isFinal()) ? 0 : event[iRec].mother1();
1241 while (isrType > 2 + beamOffset) isrType =
event[isrType].mother1();
1242 if (isrType > 2) isrType -= beamOffset;
1244 appendDipole( event, iRad, iRec, pTmax, colType, 0, 0, 0, isrType, 0,
1245 -1, -1, 0,
false, dipEnds);
1254 void DireTimes::getGenDip(
int iSys,
int i,
int iRadIn,
1255 const Event& event,
bool limitPTmaxIn, vector<DireTimesEnd>& dipEnds) {
1258 int iRad = (iSys > -1) ? partonSystemsPtr->getOut(iSys, i) : iRadIn;
1259 int sizeAllA = (iSys > -1) ? partonSystemsPtr->sizeAll(iSys) :
event.size();
1260 int sizeOut = (iSys > -1) ? partonSystemsPtr->sizeOut(iSys) :
event.size();
1261 int sizeAll = (iSys > -1) ? (( allowBeamRecoil ) ? sizeAllA : sizeOut)
1263 int sizeIn = (iSys > -1) ? sizeAll - sizeOut : 0;
1264 int sizeInA = (iSys > -1) ? sizeAllA - sizeIn - sizeOut : 0;
1265 int iOffset = (iSys > -1) ? i + sizeAllA - sizeOut : 0;
1267 for (
int j = 0; j < sizeAll; ++j)
if (iSys < 0 || j + sizeInA != iOffset) {
1269 int iRecNow = (iSys > -1) ? partonSystemsPtr->getAll(iSys, j+sizeInA) : j;
1270 if ( !event[iRecNow].isFinal()
1271 && event[iRecNow].mother1() != 1
1272 && event[iRecNow].mother1() != 2)
continue;
1275 if ( iRecNow == iRad)
continue;
1280 for (
int k = 0; k < int(dipEnds.size()); ++k)
1281 if ( dipEnds[k].iRadiator == iRad && dipEnds[k].iRecoiler == iRecNow )
1283 if (
int(iDip.size()) > 0) {
1284 for (
int k = 0; k < int(iDip.size()); ++k)
1285 updateAllowedEmissions(event, &dipEnds[iDip[k]]);
1289 double pTmax =
event[iRad].scale();
1291 if (iSys == 0 || (iSys == 1 && doSecondHard)) pTmax *= pTmaxFudge;
1292 else if (sizeIn > 0) pTmax *= pTmaxFudgeMPI;
1293 }
else pTmax = m( event[iRad], event[iRecNow]);
1294 int isrType = (
event[iRecNow].isFinal()) ? 0 : event[iRecNow].mother1();
1296 while (isrType > 2 + beamOffset) isrType =
event[isrType].mother1();
1297 if (isrType > 2) isrType -= beamOffset;
1299 appendDipole( event, iRad, iRecNow, pTmax, 0, 0, 0, 0, isrType,
1300 (iSys > -1) ? iSys : 0, -1, -1, 0,
false, dipEnds);
1312 void DireTimes::getQCDdip(
int iRad,
int colTag,
int colSign,
1313 const Event& event, vector<DireTimesEnd>& dipEnds) {
1321 for (
int iRecNow = 0; iRecNow <
event.size(); ++iRecNow) {
1322 if (iRecNow == iRad)
continue;
1323 if ( ( event[iRecNow].col() == colTag
1324 && !event[iRecNow].isFinal() && !event[iRecNow].isRescatteredIncoming() )
1325 || (
event[iRecNow].acol() == colTag
1326 &&
event[iRecNow].isFinal() ) ) {
1335 for (
int iRecNow = 0; iRecNow <
event.size(); ++iRecNow) {
1336 if (iRecNow == iRad)
continue;
1337 if ( ( event[iRecNow].acol() == colTag
1338 && !event[iRecNow].isFinal() && !event[iRecNow].isRescatteredIncoming() )
1339 || (
event[iRecNow].col() == colTag
1340 &&
event[iRecNow].isFinal() ) ) {
1346 double pTmax =
event[iRad].scale();
1347 pTmax = m( event[iRad], event[iRec]);
1348 int colType = (
event[iRad].id() == 21) ? 2 * colSign : colSign;
1349 int isrType = (
event[iRec].isFinal()) ? 0 : event[iRec].mother1();
1351 while (isrType > 2 + beamOffset) isrType =
event[isrType].mother1();
1352 if (isrType > 2) isrType -= beamOffset;
1354 appendDipole( event, iRad, iRec, pTmax, colType, 0, 0, 0,
1355 isrType, 0, -1, -1, 0,
false, dipEnds);
1364 bool DireTimes::appendDipole(
const Event& state,
int iRad,
int iRec,
1365 double pTmax,
int colType,
int chgType,
int gamType,
int weakType,
1366 int isrType,
int iSys,
int MEtype,
int iMEpartner,
int weakPol,
1367 bool isOctetOnium, vector<DireTimesEnd>& dipEnds) {
1370 for (
int i = 0; i < int(dipEnds.size()); ++i)
1371 if (dipEnds[i].iRadiator == iRad
1372 && dipEnds[i].iRecoiler == iRec
1373 && dipEnds[i].colType == colType)
1377 if (colType == 0 && state[iRad].colType() != 0) {
1378 vector<int> shared = sharedColor(state[iRad], state[iRec]);
1382 for (
int i=0; i < int(shared.size()); ++i) {
1383 if ( state[iRad].colType() == 2 && state[iRad].col() == shared[i])
1385 if ( state[iRad].colType() == 2 && state[iRad].acol() == shared[i])
1387 if ( state[iRad].colType() == 1 && state[iRad].id() > 0
1388 && state[iRad].col() == shared[i])
1390 if ( state[iRad].colType() ==-1 && state[iRad].id() < 0
1391 && state[iRad].acol() == shared[i])
1394 for (
int j=0; j < int(dipEnds.size()); ++j) {
1395 if ( dipEnds[j].iRadiator == iRad && dipEnds[j].iRecoiler == iRec
1396 && dipEnds[j].colType == colTypeNow) { found =
true;
break; }
1401 colType = colTypeNow;
1405 if ( isrType == 0 && !state[iRec].isFinal() )
1406 isrType = state[iRec].mother1();
1410 vector<int> share = sharedColor(state[iRad], state[iRec]);
1411 if (colType > 0 && find(share.begin(), share.end(), state[iRad].col())
1412 == share.end())
return false;
1413 if (colType < 0 && find(share.begin(), share.end(), state[iRad].acol())
1414 == share.end())
return false;
1418 DireTimesEnd dipNow = DireTimesEnd( iRad, iRec, pTmax, colType, chgType,
1419 gamType, weakType, isrType, iSys, MEtype, iMEpartner, weakPol,
1421 dipNow.clearAllowedEmt();
1424 if (updateAllowedEmissions(state, &dipNow)) {
1425 dipEnds.push_back(dipNow);
1435 vector<int> DireTimes::sharedColor(
const Particle& rad,
const Particle& rec) {
1437 int radCol(rad.col()), radAcl(rad.acol()),
1438 recCol(rec.col()), recAcl(rec.acol());
1439 if ( rad.isFinal() && rec.isFinal() ) {
1440 if (radCol != 0 && radCol == recAcl) ret.push_back(radCol);
1441 if (radAcl != 0 && radAcl == recCol) ret.push_back(radAcl);
1442 }
else if ( rad.isFinal() && !rec.isFinal() ) {
1443 if (radCol != 0 && radCol == recCol) ret.push_back(radCol);
1444 if (radAcl != 0 && radAcl == recAcl) ret.push_back(radAcl);
1445 }
else if (!rad.isFinal() && rec.isFinal() ) {
1446 if (radCol != 0 && radCol == recCol) ret.push_back(radCol);
1447 if (radAcl != 0 && radAcl == recAcl) ret.push_back(radAcl);
1448 }
else if (!rad.isFinal() && !rec.isFinal() ) {
1449 if (radCol != 0 && radCol == recAcl) ret.push_back(radCol);
1450 if (radAcl != 0 && radAcl == recCol) ret.push_back(radAcl);
1459 void DireTimes::saveSiblings(
const Event& state,
int iSys) {
1461 int sizeAllSys = partonSystemsPtr->sizeSys();
1462 for (
int iSystem=0; iSystem < sizeAllSys; ++iSystem) {
1464 if (iSys > -1 && iSystem != iSys)
continue;
1467 int order = kernelOrder;
1469 bool hasInA = (partonSystemsPtr->getInA(iSystem) != 0);
1470 bool hasInB = (partonSystemsPtr->getInB(iSystem) != 0);
1471 if (iSystem != 0 && hasInA && hasInB) order = kernelOrderMPI;
1472 if (order != 4)
return;
1474 vector<int> q, qb, g;
1475 int sizeSystem(partonSystemsPtr->sizeAll(iSystem)), nFinal(0);
1476 for (
int i = 0; i < sizeSystem; ++i) {
1478 int iPos = partonSystemsPtr->getAll(iSystem, i);
1479 if ( state[iPos].isFinal()) nFinal++;
1481 if (!state[iPos].isFinal()
1482 && state[iPos].mother1() != 1
1483 && state[iPos].mother1() != 2)
continue;
1486 bool hasHadMother=
false;
1488 while (state[iPosNow].mother1() > 0) {
1489 hasHadMother = (state[iPosNow].statusAbs() > 60);
1490 if (hasHadMother)
break;
1491 iPosNow = state[iPosNow].mother1();
1493 if (hasHadMother)
continue;
1495 if ( state[iPos].isFinal() && state[iPos].colType() == 1
1496 && find(q.begin(),q.end(),iPos) == q.end())
1499 if (!state[iPos].isFinal() && state[iPos].colType() ==-1
1500 && find(q.begin(),q.end(),iPos) == q.end())
1503 if ( state[iPos].isFinal() && state[iPos].colType() ==-1
1504 && find(qb.begin(),qb.end(),iPos) == qb.end())
1507 if (!state[iPos].isFinal() && state[iPos].colType() == 1
1508 && find(qb.begin(),qb.end(),iPos) == qb.end())
1511 if ( abs(state[iPos].colType()) == 2
1512 && find(g.begin(),g.end(),iPos) == g.end())
1517 DireColChains chains;
1520 for (
int i = 0; i < int(q.size()); ++i) {
1521 if (chains.chainOf(q[i]).size() != 0)
continue;
1522 chains.addChain( DireSingleColChain(q[i],state, partonSystemsPtr));
1525 for (
int i = 0; i < int(qb.size()); ++i) {
1526 if (chains.chainOf(qb[i]).size() != 0)
continue;
1527 chains.addChain( DireSingleColChain(qb[i],state, partonSystemsPtr));
1530 for (
int i = 0; i < int(g.size()); ++i) {
1532 if (chains.chainOf(g[i]).size() != 0)
continue;
1533 chains.addChain( DireSingleColChain(g[i],state, partonSystemsPtr));
1538 for (
int iDip = 0; iDip < int(dipEnd.size()); ++iDip) {
1539 if (dipEnd[iDip].system != iSystem)
continue;
1540 if (dipEnd[iDip].colType == 0) dipEnd[iDip].clearSiblings();
1542 int col = dipEnd[iDip].colType > 0
1543 ? state[dipEnd[iDip].iRadiator].col()
1544 : state[dipEnd[iDip].iRadiator].acol();
1545 dipEnd[iDip].setSiblings(chains.chainFromCol( dipEnd[iDip].iRadiator,
1559 void DireTimes::updateDipoles(
const Event& state,
int iSys) {
1562 vector<int> iRemove;
1563 for (
int iDip = 0; iDip < int(dipEnd.size()); ++iDip) {
1564 if (!updateAllowedEmissions(state, &dipEnd[iDip])
1565 && find(iRemove.begin(), iRemove.end(), iDip) == iRemove.end())
1566 iRemove.push_back(iDip);
1567 dipEnd[iDip].init(state);
1571 sort (iRemove.begin(), iRemove.end());
1572 for (
int i = iRemove.size()-1; i >= 0; --i) {
1573 dipEnd[iRemove[i]] = dipEnd.back();
1578 checkDipoles(state);
1579 saveSiblings(state, iSys);
1587 void DireTimes::checkDipoles(
const Event& state) {
1590 vector<int> iRemove;
1591 for (
int iDip = 0; iDip < int(dipEnd.size()); ++iDip) {
1592 DireTimesEnd& dipi = dipEnd[iDip];
1593 for (
int jDip = iDip+1; jDip < int(dipEnd.size()); ++jDip) {
1594 DireTimesEnd& dipj = dipEnd[jDip];
1597 if (dipi == dipj && find(iRemove.begin(), iRemove.end(), iDip)
1598 == iRemove.end()) iRemove.push_back(iDip);
1601 if (dipi.iRadiator == dipj.iRadiator) {
1604 bool iEmtGlue = find(dipi.allowedEmissions.begin(),
1605 dipi.allowedEmissions.end(), 21) != dipi.allowedEmissions.end();
1606 bool jEmtGlue = find(dipj.allowedEmissions.begin(),
1607 dipj.allowedEmissions.end(), 21) != dipj.allowedEmissions.end();
1608 if (iEmtGlue && jEmtGlue) {
1609 bool connectI = int(sharedColor(state[dipi.iRadiator],
1610 state[dipi.iRecoiler]).size()) > 0;
1611 bool connectJ = int(sharedColor(state[dipj.iRadiator],
1612 state[dipj.iRecoiler]).size()) > 0;
1613 if ( connectI && !connectJ) dipj.removeAllowedEmt(21);
1614 if (!connectI && connectJ) dipi.removeAllowedEmt(21);
1619 bool iEmtQ = find(dipi.allowedEmissions.begin(),
1620 dipi.allowedEmissions.end(), 1) != dipi.allowedEmissions.end();
1621 bool jEmtQ = find(dipj.allowedEmissions.begin(),
1622 dipj.allowedEmissions.end(), 1) != dipj.allowedEmissions.end();
1623 if ( state[dipi.iRadiator].colType() != 0 && iEmtQ
1624 && state[dipj.iRadiator].colType() != 0 && jEmtQ) {
1625 bool connectI = int(sharedColor(state[dipi.iRadiator],
1626 state[dipi.iRecoiler]).size()) > 0;
1627 bool connectJ = int(sharedColor(state[dipj.iRadiator],
1628 state[dipj.iRecoiler]).size()) > 0;
1629 if ( connectI && !connectJ) dipj.removeAllowedEmt(1);
1630 if (!connectI && connectJ) dipi.removeAllowedEmt(1);
1635 bool iEmtA = find(dipi.allowedEmissions.begin(),
1636 dipi.allowedEmissions.end(), 22) != dipi.allowedEmissions.end();
1637 bool jEmtA = find(dipj.allowedEmissions.begin(),
1638 dipj.allowedEmissions.end(), 22) != dipj.allowedEmissions.end();
1639 if (iEmtA && jEmtA) {
1640 bool connectI = state[dipi.iRecoiler].isCharged();
1641 bool connectJ = state[dipj.iRecoiler].isCharged();
1642 if ( connectI && !connectJ) dipj.removeAllowedEmt(22);
1643 if (!connectI && connectJ) dipi.removeAllowedEmt(22);
1651 for (
int iDip = 0; iDip < int(dipEnd.size()); ++iDip) {
1652 if (!dipEnd[iDip].canEmit() && find(iRemove.begin(), iRemove.end(), iDip)
1653 == iRemove.end()) iRemove.push_back(iDip);
1657 sort (iRemove.begin(), iRemove.end());
1658 for (
int i = iRemove.size()-1; i >= 0; --i) {
1659 dipEnd[iRemove[i]] = dipEnd.back();
1664 for (
int iDip = 0; iDip < int(dipEnd.size()); ++iDip) {
1665 DireTimesEnd* dip = &dipEnd[iDip];
1666 int iRad = dip->iRadiator;
1667 int iRec = dip->iRecoiler;
1669 if (dip->colType == 0 && state[iRad].colType() != 0) {
1670 vector<int> shared = sharedColor(state[iRad], state[iRec]);
1674 for (
int i=0; i < int(shared.size()); ++i) {
1675 if ( state[iRad].colType() == 2 && state[iRad].col() == shared[i])
1677 if ( state[iRad].colType() == 2 && state[iRad].acol() == shared[i])
1679 if ( state[iRad].colType() == 1 && state[iRad].id() > 0
1680 && state[iRad].col() == shared[i])
1682 if ( state[iRad].colType() ==-1 && state[iRad].id() < 0
1683 && state[iRad].acol() == shared[i])
1686 dip->colType = colTypeNow;
1689 if ( dip->isrType == 0 && !state[iRec].isFinal() )
1690 dip->isrType = state[iRec].mother1();
1697 bool DireTimes::updateAllowedEmissions(
const Event& state, DireTimesEnd* dip) {
1699 dip->clearAllowedEmt();
1701 return appendAllowedEmissions(state, dip);
1708 bool DireTimes::appendAllowedEmissions(
const Event& state, DireTimesEnd* dip) {
1712 bool isAllowed =
false;
1713 int iRad(dip->iRadiator), iRec(dip->iRecoiler);
1714 pair<int,int> iRadRec(make_pair(iRad, iRec));
1715 pair<int,int> iRecRad(make_pair(iRec, iRad));
1717 for ( unordered_map<string,DireSplitting*>::iterator it = splits.begin();
1718 it != splits.end(); ++it ) {
1721 bool allowed = it->second->useFastFunctions()
1722 ? it->second->canRadiate(state,iRad,iRec)
1723 : it->second->canRadiate(state,iRadRec,bool_settings);
1724 if (!allowed)
continue;
1727 vector<int> re = it->second->radAndEmt( state[iRad].
id(), dip->colType);
1730 if ( particleDataPtr->isResonance(state[iRad].id())
1731 && !direInfoPtr->isRes(iRad) && state[iRad].id() != re[0])
1734 for (
int iEmtAft=1; iEmtAft < int(re.size()); ++iEmtAft) {
1735 int idEmtAft = re[iEmtAft];
1736 if (it->second->is_qcd) {
1737 idEmtAft = abs(idEmtAft);
1738 if (idEmtAft<10) idEmtAft = 1;
1741 if (!it->second->isPartial()) {
1742 dip->appendAllowedEmt(idEmtAft);
1746 bool isPartialFractioned =
false;
1747 for ( unordered_map<string,DireSplitting*>::iterator
1748 itRec = splits.begin(); itRec != splits.end(); ++itRec ) {
1750 if ( isPartialFractioned )
break;
1751 bool allowedRec = itRec->second->useFastFunctions()
1752 ? itRec->second->canRadiate(state,iRec,iRad)
1753 : itRec->second->canRadiate(state,iRecRad,bool_settings);
1755 if (!allowedRec)
continue;
1759 = state[iRec].isFinal() ? -dip->colType : dip->colType;
1761 = itRec->second->radAndEmt( state[iRec].
id(), colTypeRec);
1763 for (
int iEmtAftRec=1; iEmtAftRec<int(reRec.size()); ++iEmtAftRec) {
1764 int idEmtAftRec = reRec[iEmtAftRec];
1765 if (itRec->second->is_qcd) {
1766 idEmtAftRec = abs(idEmtAftRec);
1767 if (idEmtAftRec<10) idEmtAftRec = 1;
1769 if (idEmtAftRec == idEmtAft) { isPartialFractioned =
true;
break;}
1773 if (isPartialFractioned) {
1774 dip->appendAllowedEmt(idEmtAft);
1790 double DireTimes::pTnext(
Event& event,
double pTbegAll,
double pTendAll,
1791 bool,
bool doTrialIn ) {
1793 direInfoPtr->message(1) <<
"Next FSR starting from " << pTbegAll << endl;
1798 double pT2sel = pTendAll * pTendAll;
1799 splittingNowName=
"";
1800 splittingSelName=
"";
1801 splitInfoSel.clear();
1804 auxSel = overSel = auxNow = overNow = 0.;
1808 doTrialNow = doTrialIn;
1810 for (
int iDip = 0; iDip < int(dipEnd.size()); ++iDip) {
1811 DireTimesEnd& dip = dipEnd[iDip];
1814 int nfmax = settingsPtr->mode(
"DireTimes:nFinalMax");
1816 for (
int i=0; i <
event.size(); ++i)
1817 if (event[i].isFinal()) nFinal++;
1818 if (nfmax > -10 && nFinal > nfmax)
continue;
1821 dip.mRad =
event[dip.iRadiator].m();
1822 dip.mRec =
event[dip.iRecoiler].m();
1824 sqrt( abs(2. * event[dip.iRadiator].p() *
event[dip.iRecoiler].p()) );
1825 dip.m2Rad = pow2(dip.mRad);
1826 dip.m2Rec = pow2(dip.mRec);
1827 dip.m2Dip = pow2(dip.mDip);
1830 dip.m2DipCorr = dip.m2Dip;
1832 double pT2start = min( dip.m2Dip, pTbegAll*pTbegAll);
1833 double pT2stop = max( pT2cutMin(&dip), pTendAll*pTendAll);
1834 pT2stop = max( pT2stop, pT2sel);
1849 if (dip.m2DipCorr < 0.) {
1850 infoPtr->errorMsg(
"Warning in DireTimes::pTnext: "
1851 "negative dipole mass.");
1856 if (pT2start > pT2sel) {
1859 dip.pT2start = pT2start;
1860 dip.pT2stop = pT2stop;
1863 if ( dip.canEmit() ) pT2nextQCD(pT2start, pT2stop, dip, event);
1866 if (dip.pT2 > pT2sel) {
1870 splittingSelName = splittingNowName;
1871 splitInfoSel.store(splits[splittingSelName]->splitInfo);
1872 splittingSel = splits[splittingSelName];
1873 kernelSel = kernelNow;
1876 boostSel = boostNow;
1883 if (dipSel != 0 && nProposedPT.find(dipSel->system) != nProposedPT.end())
1884 ++nProposedPT[dipSel->system];
1887 for ( unordered_map<
string, multimap<double,double> >::iterator
1888 itR = rejectProbability.begin(); itR != rejectProbability.end(); ++itR)
1889 weights->insertWeights(acceptProbability[itR->first], itR->second,
1892 for ( unordered_map<
string, multimap<double,double> >::iterator
1893 it = rejectProbability.begin(); it != rejectProbability.end(); ++it )
1895 for ( unordered_map<
string, map<double,double> >::iterator
1896 it = acceptProbability.begin(); it != acceptProbability.end(); ++it )
1899 resetOverheadFactors();
1902 bool hasInAB =
false;
1903 for (
int iDip = 0; iDip < int(dipEnd.size()); ++iDip)
1904 if (partonSystemsPtr->hasInAB(dipEnd[iDip].system)) hasInAB =
true;
1905 if (dipSel == 0 && !hasInAB ) finalize(event);
1908 return (dipSel == 0) ? 0. : sqrt(pT2sel);
1914 double DireTimes::newPoint(
const Event& inevt) {
1916 int asOrderSave = alphaSorder;
1917 double pT2minMECsSave = pT2minMECs;
1920 double tFreeze = 1.;
1927 double pTendAll = 0.;
1928 double pT2sel = pTendAll * pTendAll;
1929 splittingNowName=
"";
1930 splittingSelName=
"";
1931 for ( unordered_map<string,DireSplitting*>::iterator it = splits.begin();
1932 it != splits.end(); ++it ) it->second->splitInfo.clear();
1933 splitInfoSel.clear();
1936 auxSel = overSel = auxNow = overNow = 0.;
1941 while (pT2sel==0.) {
1944 if (nTrials>=nTrialsMax)
break;
1946 for (
int iDip = 0; iDip < int(dipEnd.size()); ++iDip) {
1948 DireTimesEnd& dip = dipEnd[iDip];
1951 dip.mRad =
event[dip.iRadiator].m();
1952 dip.mRec =
event[dip.iRecoiler].m();
1954 sqrt( abs(2. * event[dip.iRadiator].p() *
event[dip.iRecoiler].p()) );
1955 dip.m2Rad = pow2(dip.mRad);
1956 dip.m2Rec = pow2(dip.mRec);
1957 dip.m2Dip = pow2(dip.mDip);
1960 dip.m2DipCorr = dip.m2Dip;
1962 double pT2start = m2Max(iDip, event);
1963 double pT2stop = pTendAll*pTendAll;
1978 dip.pT2start = pT2start;
1979 dip.pT2stop = pT2stop;
1982 if (dip.canEmit()) pT2nextQCD(pT2start,0.,dip,event,0.,tFreeze,
true);
1984 if (dip.pT2 > pT2sel) {
1988 splittingSelName = splittingNowName;
1989 splitInfoSel.store(splits[splittingSelName]->splitInfo);
1990 splittingSel = splits[splittingSelName];
1991 kernelSel = kernelNow;
1997 bool hasBranched =
false;
1998 if ( event[dipSel->iRecoiler].isFinal())
1999 hasBranched = branch_FF(event,
true, &splitInfoSel);
2000 else hasBranched = branch_FI(event,
true, &splitInfoSel);
2005 splitInfoSel.clear();
2012 alphaSorder = asOrderSave;
2013 pT2minMECs = pT2minMECsSave;
2016 if (dipSel == 0)
return 0.;
2019 return sqrt(pT2sel);
2025 double DireTimes::enhanceOverestimateFurther(
string name,
int,
double tOld) {
2027 if (tOld < pT2minEnhance)
return 1.;
2028 double enhance = weights->enhanceOverestimate(name);
2035 double DireTimes::overheadFactorsMEC(
const Event&, DireSplitInfo*,
string) {
2041 double DireTimes::overheadFactors( DireTimesEnd* dip,
const Event& state,
2042 string name,
double,
double tOld,
double xOld) {
2047 if (tOld < pT2colCut*1.25) MARGIN = 1.;
2051 if (tOld > PT2MIN_PDF_IN_OVERESTIMATE && tOld > pT2colCut
2052 && !state[dip->iRecoiler].isFinal()
2053 && particleDataPtr->colType(state[dip->iRecoiler].id()) != 0) {
2055 BeamParticle* beam = NULL;
2056 if (beamAPtr != NULL || beamBPtr != NULL) {
2057 if (dip->isrType == 1 && beamAPtr != NULL) beam = beamAPtr;
2058 if (dip->isrType != 1 && beamBPtr != NULL) beam = beamBPtr;
2063 double idRec = state[dip->iRecoiler].id();
2064 int iSysRec = dip->systemRec;
2065 double scale2 = max(tOld, pT2colCut);
2066 bool inOld = beam->insideBounds(xOld, scale2);
2067 double xPDFOld = getXPDF(idRec, xOld, scale2, iSysRec, beam);
2071 if (idRec == 21 && scale2 < PT2_INCREASE_OVERESTIMATE) {
2072 double xPDFmother = xPDFOld;
2073 int NTSTEPS(3), NXSTEPS(3);
2074 for (
int i=1; i <= NTSTEPS; ++i) {
2075 double tNew = pT2colCut + double(i)/double(NTSTEPS)*
2077 for (
int j=1; j <= NXSTEPS; ++j) {
2078 double xNew = xOld + double(j)/double(NXSTEPS)*(0.999999-xOld);
2079 double xPDFnew = getXPDF(21, xNew, tNew, iSysRec, beam);
2080 if ( beam->insideBounds(xNew, tNew) )
2081 xPDFmother = max(xPDFmother, xPDFnew);
2084 if ( inOld && abs(xPDFOld) > tinypdf(xOld) && xPDFmother/xPDFOld > 1.)
2085 factor *= xPDFmother / xPDFOld;
2088 double tNew1 = pT2colCut;
2089 double tNew2 = pT2colCut + 0.5 * ( scale2 - pT2colCut );
2090 double xNew1 = xOld;
2091 double xNew2 = xOld + 0.5 * ( 0.999999 - xOld );
2092 bool inNew = beam->insideBounds(xNew1, tNew1)
2093 || beam->insideBounds(xNew1, tNew2)
2094 || beam->insideBounds(xNew2, tNew1)
2095 || beam->insideBounds(xNew2, tNew2);
2096 double xPDFNew1 = getXPDF(idRec, xNew1, tNew1, iSysRec, beam);
2097 double xPDFNew2 = getXPDF(idRec, xNew1, tNew2, iSysRec, beam);
2098 double xPDFNew3 = getXPDF(idRec, xNew2, tNew1, iSysRec, beam);
2099 double xPDFNew4 = getXPDF(idRec, xNew2, tNew2, iSysRec, beam);
2100 double PDFNew = max( 1./xNew1 * max(xPDFNew1,xPDFNew2),
2101 1./xNew2 * max(xPDFNew3,xPDFNew4) );
2102 if ( inOld && inNew && xPDFOld > tinypdf(xOld)
2103 && abs((PDFNew)/(1./xOld*xPDFOld)) > 10)
2104 factor *= abs(PDFNew/(1./xOld*xPDFOld));
2110 if ( !state[dip->iRecoiler].isFinal()
2111 && max(tOld, pT2colCut) < PT2_INCREASE_OVERESTIMATE
2112 && ( name ==
"Dire_fsr_qcd_1->1&21" || name ==
"Dire_fsr_qcd_21->21&21a"
2113 || name ==
"Dire_fsr_qcd_21->1&1a")) factor *= 2.;
2115 if (!state[dip->iRecoiler].isFinal() && tOld > pT2minMECs && doMEcorrections)
2119 if ( overhead.find(name) != overhead.end() ) factor *= overhead[name];
2131 void DireTimes::getNewOverestimates( DireTimesEnd* dip,
const Event& state,
2132 double tOld,
double xOld,
double zMinAbs,
double zMaxAbs,
2133 multimap<double,string>& newOverestimates) {
2136 pair<int,int> iRadRec(make_pair(dip->iRadiator, dip->iRecoiler));
2139 for ( unordered_map<string,DireSplitting*>::iterator it = splits.begin();
2140 it != splits.end(); ++it ) {
2142 string name = it->first;
2144 it->second->splitInfo.clear();
2147 bool allowed = it->second->useFastFunctions()
2148 ? it->second->canRadiate(state,dip->iRadiator,dip->iRecoiler)
2149 : it->second->canRadiate(state,iRadRec,bool_settings);
2152 if (!allowed)
continue;
2155 vector<int> re = it->second->radAndEmt(state[dip->iRadiator].id(),
2157 if (
int(re.size()) < 2)
continue;
2159 for (
int iEmtAft=1; iEmtAft < int(re.size()); ++iEmtAft) {
2160 int idEmtAft = re[iEmtAft];
2161 if (it->second->is_qcd) {
2162 idEmtAft = abs(idEmtAft);
2163 if (idEmtAft<10) idEmtAft = 1;
2165 if (find(dip->allowedEmissions.begin(), dip->allowedEmissions.end(),
2166 idEmtAft) == dip->allowedEmissions.end() ) allowed =
false;
2168 if ( pT2cut(idEmtAft) > tOld) allowed =
false;
2171 if (!allowed)
continue;
2173 it->second->splitInfo.set_pT2Old ( tOld );
2174 it->second->splitInfo.storeRadBef(state[dip->iRadiator]);
2175 it->second->splitInfo.storeRecBef(state[dip->iRecoiler]);
2178 if (!it->second->aboveCutoff( tOld, state[dip->iRadiator],
2179 state[dip->iRecoiler], dip->system, partonSystemsPtr))
continue;
2182 int order = kernelOrder;
2184 bool hasInA = (partonSystemsPtr->getInA(dip->system) != 0);
2185 bool hasInB = (partonSystemsPtr->getInB(dip->system) != 0);
2186 if (dip->system != 0 && hasInA && hasInB) order = kernelOrderMPI;
2189 bool hasHadMother=
false;
2190 int iPos = dip->iRadiator;
2191 while (state[iPos].mother1() > 0) {
2192 hasHadMother = (state[iPos].statusAbs() > 60);
2193 if (hasHadMother)
break;
2194 iPos = state[iPos].mother1();
2196 if (hasHadMother) order = kernelOrderMPI;
2198 double wt = it->second->overestimateInt(zMinAbs, zMaxAbs, tOld,
2202 wt *= overheadFactors(dip, state, name, dip->m2Dip, tOld, xOld);
2205 double enhanceFurther
2206 = enhanceOverestimateFurther(name, state[dip->iRadiator].id(), tOld);
2207 wt *= enhanceFurther;
2211 if (!dryrun && it->second->hasMECBef(state, tOld)) wt *= KERNEL_HEADROOM;
2213 for (
int i=0; i < state.size(); ++i)
if (state[i].isFinal()) nFinal++;
2214 if (!dryrun) wt *= it->second->overhead
2215 (dip->m2Dip*xOld, state[dip->iRadiator].id(), nFinal);
2221 newOverestimates.insert(make_pair(sum,name));
2231 void DireTimes::getNewSplitting(
const Event& state, DireTimesEnd* dip,
2232 double tOld,
double xOld,
double t,
2233 double zMinAbs,
double zMaxAbs,
int idMother,
string name,
bool forceFixedAs,
2234 int& idDaughter,
int& idSister,
double& z,
double& wt,
2235 unordered_map<string,double>& full,
double& over) {
2238 DireSplitting* splitNow = splits[name];
2240 splitNow->splitInfo.storeRadBef ( state[dip->iRadiator]);
2241 splitNow->splitInfo.storeRecBef ( state[dip->iRecoiler]);
2244 vector<int> re = splitNow->radAndEmt(idMother, dip->colType);
2246 if (
int(re.size()) < 2) { wt = over = 0.; full.clear();
return; }
2249 int nEmissions = splitNow->nEmissions();
2253 if (idSister > 20) flavour = idSister;
2256 if ( pT2cut(idSister) > t) { wt = over = 0.; full.clear();
return; }
2259 if (z<0.) z = splitNow->zSplit(zMinAbs, zMaxAbs, dip->m2Dip);
2262 if (splitNow->is(splittingsPtr->fsrQED_11_to_11_and_22_notPartial)
2263 && z > LEPTONZMAX) { wt = over = 0.; full.clear();
return; }
2266 if (!splitNow->aboveCutoff( t, state[dip->iRadiator], state[dip->iRecoiler],
2267 dip->system, partonSystemsPtr)) { wt = over = 0.; full.clear();
return; }
2270 double RNflav = rndmPtr->flat();
2271 int sign = (idSister > 0) ? 1 : -1;
2272 if ( flavour == 0 && splitNow->is_dire && !splitNow->canUseForBranching()) {
2275 if ( splitNow->is(splittingsPtr->fsrQCD_21_to_1_and_1a)
2276 || splitNow->is(splittingsPtr->fsrQCD_21_to_1_and_1b))
2277 idSister = sign*min(5, 1 +
int(nGluonToQuark * RNflav));
2280 if ( splitNow->is(splittingsPtr->fsrQCD_21_to_1_and_1_notPartial)) {
2281 idSister = sign*min(5, 1 +
int(nGluonToQuark * RNflav));
2282 if (rndmPtr->flat() < 0.5) idSister *= -1;
2286 if (splitNow->is(splittingsPtr->fsrQCD_1_to_2_and_1_and_2)) {
2287 int index = int((2*nGluonToQuark - 2)*RNflav);
2289 for (
int i =-nGluonToQuark; i <=nGluonToQuark; ++i)
2290 if (abs(i) != state[dip->iRadiator].idAbs() && i != 0)
2291 quarks.push_back(i);
2292 idSister = quarks[index];
2296 if (splitNow->is(splittingsPtr->fsrQCD_1_to_1_and_1_and_1))
2297 idSister = -idMother;
2300 idDaughter = -idSister;
2303 if (nEmissions == 2) idDaughter = state[dip->iRadiator].id();
2309 dip->flavour = flavour;
2311 bool canUseSplitInfo = splitNow->canUseForBranching();
2312 if (canUseSplitInfo) {
2319 double m2Bef = particleDataPtr->isResonance(state[dip->iRadiator].id())
2320 ? getMass(state[dip->iRadiator].id(),3,
2321 state[dip->iRadiator].mCalc())
2322 : (state[dip->iRadiator].idAbs() < 6
2323 || state[dip->iRadiator].id() == 21
2324 || state[dip->iRadiator].id() == 22)
2325 ? getMass(state[dip->iRadiator].id(),2)
2326 : getMass(state[dip->iRadiator].id(),1);
2328 double m2r = particleDataPtr->isResonance(idDaughter)
2329 && idDaughter == state[dip->iRadiator].id()
2330 ? getMass(idDaughter,3,state[dip->iRadiator].mCalc())
2331 : (abs(idDaughter) < 6 || idDaughter == 21 || idDaughter == 22)
2332 ? getMass(idDaughter,2)
2333 : getMass(idDaughter,1);
2336 int type = (state[dip->iRecoiler].isFinal()) ? 1 : -1;
2338 m2s = particleDataPtr->isResonance(state[dip->iRecoiler].id())
2339 ? getMass(state[dip->iRecoiler].id(),3,
2340 state[dip->iRecoiler].mCalc())
2341 : (state[dip->iRecoiler].idAbs() < 6
2342 || state[dip->iRecoiler].id() == 21
2343 || state[dip->iRecoiler].id() == 22)
2344 ? getMass(state[dip->iRecoiler].id(),2)
2345 : getMass(state[dip->iRecoiler].id(),1);
2348 double m2e = (abs(flavour) < 6 || flavour == 21 || flavour == 22)
2349 ? getMass(flavour,2) : getMass(flavour,1);
2352 if ( particleDataPtr->isResonance(idDaughter)
2353 && idDaughter != state[dip->iRadiator].id() ) {
2355 m2r = pow2(particleDataPtr->mSel(idDaughter));
2357 if ( particleDataPtr->isResonance(flavour) ) {
2358 m2e = pow2(particleDataPtr->mSel(flavour));
2360 if (particleDataPtr->isResonance(state[dip->iRadiator].id())
2361 && sqrt(m2Bef) < sqrt(m2r) + sqrt(m2e) )
2362 m2e = pow2( sqrt(m2Bef) - sqrt(m2r));
2367 if ( type != 0 && (m2Bef > TINYMASS || m2r > TINYMASS || m2s > TINYMASS
2369 type = type/abs(type)*2;
2372 int massSign = (type > -1) ? 1 : -1;
2374 double q2 = ( state[dip->iRecoiler].p()
2375 + massSign*state[dip->iRadiator].p() ).m2Calc();
2377 double Q2 = dip->m2Dip + massSign*(m2Bef - m2r - m2e);
2382 int kinType = splitNow->kinMap();
2388 dip->phi = 2.*M_PI*rndmPtr->flat();
2391 double m2a = getMass(-idSister,2);
2392 double m2i = getMass( idSister,2);
2394 if (canUseSplitInfo) {
2395 m2a = getMass(re[0],2);
2398 m2i = getMass(re[1],2);
2399 if (
int(re.size()) > 2) {
2400 m2j = getMass(re[2],2);
2408 splitNow->splitInfo.clearRadAft();
2409 splitNow->splitInfo.clearEmtAft();
2410 splitNow->splitInfo.clearEmtAft2();
2413 if ( nEmissions == 2 ) {
2414 dip->mass.push_back(m2a);
2415 dip->mass.push_back(m2i);
2416 dip->mass.push_back(m2j);
2417 dip->mass.push_back(m2s);
2419 if (splitNow->allow_sai_endpoint_for_kinematics())
2420 splitNow->try_sai_endpoint();
2421 if (splitNow->allow_xa_endpoint_for_kinematics())
2422 splitNow->try_xa_endpoint();
2424 if (!splitNow->is_xa_endpoint()) zCollNextQCD( dip, dip->z, 1. );
2427 if (!splitNow->is_sai_endpoint()) virtNextQCD( dip, 0.0, dip->m2Dip);
2431 dip->phia1 = 2.*M_PI*rndmPtr->flat();
2435 vector <double> aux;
2436 if ( nEmissions == 2 ) {
2437 type = (state[dip->iRecoiler].isFinal()) ? 2 : -2;
2438 aux.push_back( dip->m2Dip );
2439 if (type > 0) aux.push_back( (state[dip->iRadiator].p()
2440 +state[dip->iRecoiler].p()).m2Calc() );
2441 else aux.push_back( (state[dip->iRadiator].p()
2442 -state[dip->iRecoiler].p()).m2Calc() );
2443 aux.push_back(dip->pT2);
2444 aux.push_back(dip->sa1);
2445 aux.push_back(dip->z);
2446 aux.push_back(dip->xa);
2447 aux.push_back(m2Bef);
2456 if (canUseSplitInfo) swap (m2i, m2j);
2459 double xBef = (type > 0) ? 0.0 : 2.*state[dip->iRecoiler].e()/state[0].m();
2460 splitNow->splitInfo.storeInfo(name, type, dip->system, dip->systemRec, 0,
2461 dip->iRadiator, dip->iRecoiler, state,
2462 dip->flavour, idDaughter, nEmissions, Q2, dip->pT2, dip->pT2Old,
2463 dip->z, dip->phi, m2Bef, m2s, (nEmissions == 1 ? m2r : m2a),
2464 (nEmissions == 1 ? m2e : m2i), dip->sa1, dip->xa, dip->phia1, m2j,
2466 splitNow->splitInfo.setSiblings(dip->iSiblings);
2467 if (canUseSplitInfo) {
2468 splitNow->splitInfo.setRadAft(re[0]);
2469 splitNow->splitInfo.setEmtAft(re[1]);
2470 if (nEmissions==2) splitNow->splitInfo.setEmtAft2(re[2]);
2471 splitNow->splitInfo.canUseForBranching(
true);
2473 splitNow->splitInfo.setRadAft(idDaughter);
2474 splitNow->splitInfo.setEmtAft(idSister);
2475 if (nEmissions==2) splitNow->splitInfo.setEmtAft2(-idSister);
2479 double zcheck(z), tcheck(t);
2482 ? splitNow->zdire_fi(z, t, Q2) : splitNow->zdire_ff(z, t, Q2);
2484 ? splitNow->tdire_fi(z, t, Q2) : splitNow->tdire_ff(z, t, Q2);
2486 if ( !inAllowedPhasespace( kinType, zcheck, tcheck, Q2, q2,
2487 xOld, type, m2Bef, m2r, m2s, m2e, aux ) )
2488 { wt = over = 0.; full.clear();
return; }
2491 int order = kernelOrder;
2493 bool hasInA = (partonSystemsPtr->getInA(dip->system) != 0);
2494 bool hasInB = (partonSystemsPtr->getInB(dip->system) != 0);
2495 if (dip->system != 0 && hasInA && hasInB) order = kernelOrderMPI;
2498 bool hasHadMother=
false;
2499 int iPos = dip->iRadiator;
2500 while (state[iPos].mother1() > 0) {
2501 hasHadMother = (state[iPos].statusAbs() > 60);
2502 if (hasHadMother)
break;
2503 iPos = state[iPos].mother1();
2505 if (hasHadMother) order = kernelOrderMPI;
2508 if (canUseSplitInfo) {
2509 vector< pair<int,int> > cols
2510 = splitNow->radAndEmtCols( dip->iRadiator, dip->colType, state);
2511 splitNow->splitInfo.setRadAft(re[0], cols[0].first, cols[0].second);
2512 splitNow->splitInfo.setEmtAft(re[1], cols[1].first, cols[1].second);
2513 if (nEmissions==2) splitNow->splitInfo.setEmtAft2(re[2], cols[2].first,
2517 dip->idRadAft = idDaughter;
2518 dip->idEmtAft = idSister;
2521 over = splitNow->overestimateDiff(z, dip->m2Dip, order);
2524 if (splitNow->calc( state, order) ) full = splitNow->getKernelVals();
2526 if (!dryrun && splitNow->hasMECBef(state, tOld)) over *= KERNEL_HEADROOM;
2527 if (!dryrun && splitNow->hasMECBef(state, dip->pT2))
2528 for (unordered_map<string,double>::iterator it=full.begin();
2529 it != full.end(); ++it) it->second *= KERNEL_HEADROOM;
2536 if ( max(tOld, pT2colCut) < pT2recombine ) {
2537 if ( splitNow->is(splittingsPtr->fsrQCD_1_to_21_and_1)
2538 || splitNow->is(splittingsPtr->fsrQCD_21_to_21_and_21b)
2539 || splitNow->is(splittingsPtr->fsrQCD_21_to_1_and_1b))
2540 for (unordered_map<string,double>::iterator it=full.begin();
2541 it != full.end(); ++it)
2543 string name_recombine=
"";
2544 if (splitNow->is(splittingsPtr->fsrQCD_1_to_1_and_21))
2545 name_recombine=
"Dire_fsr_qcd_1->21&1";
2546 if (splitNow->is(splittingsPtr->fsrQCD_21_to_21_and_21a))
2547 name_recombine=
"Dire_fsr_qcd_21->21&21b";
2548 if (splitNow->is(splittingsPtr->fsrQCD_21_to_1_and_1a))
2549 name_recombine=
"Dire_fsr_qcd_21->1&1b";
2551 if (name_recombine !=
"" && splits.find(name_recombine) != splits.end() ) {
2552 splits[name_recombine]->splitInfo.storeRadBef(state[dip->iRadiator]);
2553 splits[name_recombine]->splitInfo.storeRecBef(state[dip->iRecoiler]);
2554 splits[name_recombine]->splitInfo.storeInfo(name_recombine, type,
2555 dip->system, dip->systemRec, 0, dip->iRadiator,
2556 dip->iRecoiler, state, dip->flavour, idDaughter, nEmissions, Q2,
2557 dip->pT2, dip->pT2Old, dip->z,
2558 dip->phi, m2Bef, m2s, (nEmissions == 1 ? m2r : m2a),
2559 (nEmissions == 1 ? m2e : m2i), dip->sa1, dip->xa, dip->phia1, m2r,
2561 splits[name_recombine]->splitInfo.setRadAft(idDaughter);
2562 splits[name_recombine]->splitInfo.setEmtAft(idSister);
2563 splits[name_recombine]->splitInfo.setSiblings(dip->iSiblings);
2566 unordered_map<string,double> full_recombine;
2567 if (splits[name_recombine]->calc( state, order) )
2568 full_recombine = splits[name_recombine]->getKernelVals();
2569 for ( unordered_map<string,double>::iterator it = full_recombine.begin();
2570 it != full_recombine.end(); ++it ) full[it->first] += it->second;
2574 direInfoPtr->message(1) << __FILE__ <<
" " << __func__
2575 <<
" " << __LINE__ <<
" : New splitting "
2576 << setw(15) << name <<
" at pT="
2577 << setw(15) << sqrt(dip->pT2) <<
" z = "
2578 << setw(15) << dip->z <<
" prob = "
2579 << setw(15) << full[
"base"] << endl;
2582 double coupl = splitNow->coupling(dip->z, dip->pT2, Q2, -1.,
2583 make_pair(state[dip->iRadiator].id(), state[dip->iRadiator].isFinal()),
2584 make_pair(state[dip->iRecoiler].id(), state[dip->iRecoiler].isFinal()));
2586 double scale2 = splits[splittingNowName]->couplingScale2(
2587 dip->z, dip->pT2, Q2,
2588 make_pair(state[dip->iRadiator].id(), state[dip->iRadiator].isFinal()),
2589 make_pair(state[dip->iRecoiler].id(), state[dip->iRecoiler].isFinal()));
2590 if (scale2 < 0.) scale2 = dip->pT2;
2591 double talpha = max(scale2, pT2colCut);
2592 double renormMultFacNow = renormMultFac;
2593 if (forceFixedAs) renormMultFacNow = 1.0;
2596 full[
"base"] *= coupl / alphasNow(talpha, renormMultFacNow, dip->system);
2597 if (name.find(
"qcd") == string::npos) {
2598 for ( unordered_map<string,double>::iterator it = full.begin();
2599 it != full.end(); ++it ) {
2600 if (it->first ==
"base")
continue;
2601 it->second *= coupl / alphasNow(talpha, renormMultFacNow, dip->system);
2606 vector <int> in, out;
2607 for (
int i=0; i < state.size(); ++i) {
2608 if (i == dip->iRadiator)
continue;
2609 if (state[i].isFinal()) out.push_back(state[i].id());
2610 if (state[i].mother1() == 1 && state[i].mother2() == 0)
2611 in.push_back(state[i].id());
2612 if (state[i].mother1() == 2 && state[i].mother2() == 0)
2613 in.push_back(state[i].id());
2615 out.push_back(re[0]);
2616 for (
size_t i=1; i < re.size(); ++i) out.push_back(re[i]);
2617 bool hasME = dip->pT2 > pT2minMECs
2618 && doMEcorrections && weights->hasME(in,out);
2619 if (hasME)
for (unordered_map<string,double>::iterator it=full.begin();
2620 it != full.end(); ++it) it->second = abs(it->second);
2624 for (
int i=0; i < state.size(); ++i)
if (state[i].isFinal()) nFinal++;
2625 if (!dryrun) mecover = splitNow->overhead
2626 (dip->m2Dip*xOld, state[dip->iRadiator].id(), nFinal);
2627 for (unordered_map<string,double>::iterator it=full.begin();
2628 it != full.end(); ++it) it->second *= mecover;
2632 wt = full[
"base"]/over;
2635 double headRoom = overheadFactors(dip, state, name, dip->m2Dip, tOld, xOld);
2646 pair<bool, pair<double,double> > DireTimes::getMEC (
const Event& state,
2647 DireSplitInfo* splitInfo) {
2649 double MECnum(1.0), MECden(1.0);
2652 = weights->hasME(makeHardEvent(max(0,splitInfo->system), state,
false));
2657 mergingHooksPtr->init();
2660 mergingHooksPtr->orderHistories(
false);
2663 if ( mergingHooksPtr->getProcessString().compare(
"pp>h") == 0)
2664 mergingHooksPtr->allowCutOnRecState(
true);
2669 Event newProcess( mergingHooksPtr->bareEvent(
2670 makeHardEvent(max(0,splitInfo->system), state,
false),
true) );
2672 mergingHooksPtr->storeHardProcessCandidates( newProcess );
2675 int nSteps = mergingHooksPtr->
2676 getNumberOfClusteringSteps( newProcess,
true);
2679 newProcess.scale(0.0);
2681 DireHistory myHistory( nSteps, 0.0, newProcess, DireClustering(),
2682 mergingHooksPtr, (*beamAPtr), (*beamBPtr), particleDataPtr, infoPtr,
2683 NULL, splits.begin()->second->fsr, splits.begin()->second->isr, weights,
2684 coupSMPtr,
true,
true, 1.0, 1.0, 1.0, 1.0, 0);
2686 myHistory.projectOntoDesiredHistories();
2688 MECnum = myHistory.MECnum;
2689 MECden = myHistory.MECden;
2692 mergingHooksPtr->init();
2697 if (abs(MECden) < 1e-15) direInfoPtr->message(1)
2698 << __FILE__ <<
" " << __func__
2699 <<
" " << __LINE__ <<
" : Small MEC denominator="
2700 << MECden <<
" for numerator=" << MECnum << endl;
2701 if (abs(MECnum/MECden) > 1e2) { direInfoPtr->message(1)
2702 << __FILE__ <<
" " << __func__
2703 <<
" " << __LINE__ <<
" : Large MEC. Denominator="
2704 << MECden <<
" Numerator=" << MECnum <<
" at pT="
2705 << sqrt(splitInfo->kinematics()->pT2) <<
" "
2709 return make_pair(hasME, make_pair(MECnum,MECden));
2715 bool DireTimes::applyMEC (
const Event& state, DireSplitInfo* splitInfo,
2716 vector<Event> auxState) {
2719 pair<bool, pair<double, double> > mec = getMEC ( state, splitInfo);
2720 bool hasME = mec.first;
2721 double MECnum = mec.second.first;
2722 double MECden = mec.second.second;
2723 double MECnumX = mec.second.first;
2724 double MECdenX = mec.second.second;
2726 if (!hasME)
return false;
2728 if (abs(MECnum/MECden) > 5e0 && auxState.size()>0) {
2729 pair<bool, pair<double, double> > mec1 = getMEC ( auxState[0], splitInfo);
2730 pair<bool, pair<double, double> > mec2 = getMEC ( auxState[1], splitInfo);
2731 double MECnum1 = mec1.second.first;
2732 double MECden1 = mec1.second.second;
2733 double MECnum2 = mec2.second.first;
2734 double MECden2 = mec2.second.second;
2735 if (MECnum/MECden > MECnum1/MECden1) {MECnum = MECnum1; MECden = MECden1;}
2736 if (MECnum/MECden > MECnum2/MECden2) {MECnum = MECnum2; MECden = MECden2;}
2737 direInfoPtr->message(1) << __FILE__ <<
" " << __func__
2738 <<
" " << __LINE__ <<
" : Large MEC weight=" << MECnumX/MECdenX
2739 <<
" " << MECnum/MECden
2740 <<
"\t\t" << splitInfo->kinematics()->pT2/splitInfo->kinematics()->m2Dip
2741 <<
" " << splitInfo->kinematics()->z << endl;
2742 if (MECnum/MECden > (MECnum+MECnum1)/(MECden+MECden1))
2743 { MECnum += MECnum1; MECden += MECden1; }
2744 if (MECnum/MECden > (MECnum+MECnum2)/(MECden+MECden2))
2745 { MECnum += MECnum2; MECden += MECden2; }
2749 double kernel = kernelSel[
"base"];
2750 bool reject =
false;
2754 if (kernelSel.find(
"base_order_as2") != kernelSel.end() ) {
2755 oas2 = kernelSel[
"base_order_as2"];
2756 kernelSel.erase(kernelSel.find(
"base_order_as2"));
2758 double baseNew = ((kernel - oas2) * MECnum/MECden + oas2);
2763 double auxNew = kernel;
2764 double overNew = kernel;
2767 for (
int i=0; i < state.size(); ++i)
2768 if (state[i].isFinal()) nFinal++;
2770 if (dryrun) splittingSel->storeOverhead(
2771 splitInfo->kinematics()->m2Dip*splitInfo->kinematics()->xBef,
2772 splitInfo->kinematics()->xBef, state[splitInfo->iRadBef].id(), nFinal-1,
2773 max(baseNew/overNew,1.1));
2776 if (baseNew/auxNew < 0.) auxNew *= -1.;
2777 if (suppressLargeMECs)
while (baseNew/auxNew < 5e-2) auxNew /= 5.;
2780 if (baseNew/auxNew > 1.) {
2781 double rescale = baseNew/auxNew * 1.5;
2784 double wt = baseNew/auxNew;
2787 double wvNow = auxNew/overNew * (overNew - baseNew)
2788 / (auxNew - baseNew);
2791 double waNow = auxNew/overNew;
2792 if (wt < rndmPtr->flat()) {
2794 if (abs(wvNow) > 1e0) {
2795 direInfoPtr->message(1) << __FILE__ <<
" " << __func__
2796 <<
" " << __LINE__ <<
" : Large reject weight=" << wvNow
2797 <<
"\t for kernel=" << baseNew <<
" overestimate=" << overNew
2798 <<
"\t aux. overestimate=" << auxNew <<
" at pT2="
2799 << splitInfo->kinematics()->pT2
2800 <<
" for " << splittingSelName << endl;
2804 for (unordered_map<string,double>::iterator it= kernelSel.begin();
2805 it != kernelSel.end(); ++it) {
2807 double waOld = weights->getAcceptWeight( splitInfo->kinematics()->pT2,
2810 weights->eraseAcceptWeight(splitInfo->kinematics()->pT2, it->first);
2811 weights->resetRejectWeight(splitInfo->kinematics()->pT2, wvNow*waOld,
2817 if (abs(waNow) > 1e0) {
2818 direInfoPtr->message(1) << __FILE__ <<
" " << __func__
2819 <<
" " << __LINE__ <<
" : Large accept weight=" << waNow
2820 <<
"\t for kernel=" << baseNew <<
" overestimate=" << overNew
2821 <<
"\t aux. overestimate=" << auxNew <<
" at pT2="
2822 << splitInfo->kinematics()->pT2
2823 <<
" for " << splittingSelName << endl;
2827 for (unordered_map<string,double>::iterator it= kernelSel.begin();
2828 it != kernelSel.end(); ++it) {
2830 double waOld = weights->getAcceptWeight( splitInfo->kinematics()->pT2,
2833 weights->eraseRejectWeight(splitInfo->kinematics()->pT2, it->first);
2834 weights->resetAcceptWeight(splitInfo->kinematics()->pT2, waNow*waOld,
2852 bool DireTimes::inAllowedPhasespace(
int kinType,
double z,
double pT2,
2853 double m2dip,
double q2,
double xOld,
int splitType,
double m2RadBef,
2854 double m2r,
double m2s,
double m2e, vector<double> aux) {
2857 if (splitType == 0) {
2860 double yCS = (m2RadBef - m2e - m2r)
2861 / (m2RadBef - m2e - m2r + q2 - m2RadBef - m2s);
2863 double sij = yCS * (q2 - m2s) + (1.-yCS)*(m2r+m2e);
2864 double zbar = (q2-sij-m2s) / bABC(q2,sij,m2s)
2865 * (zCS - m2s/gABC(q2,sij,m2s)
2866 *(sij + m2r - m2e)/(q2-sij-m2s));
2867 double kT2 = zbar*(1.-zbar)*sij - (1.-zbar)*m2r - zbar*m2e;
2868 if (kT2 < 0.0)
return false;
2871 }
else if (splitType == 1) {
2874 double yCS = pT2/m2dip / (1.-z);
2875 double zCS = ( 1. - z - pT2/m2dip - pow2(1.-z) )
2876 / ( 1. - z - pT2/m2dip);
2881 yCS = pT2 / (m2dip*z*(1.-z)) ;
2885 if ( zCS < 0. || zCS > 1. || yCS < 0. || yCS > 1.)
return false;
2888 }
else if (splitType == 2 && aux.size() == 0) {
2892 double yCS = pT2/m2dip / (1.-z);
2893 double zCS = ( 1. - z - pT2/m2dip - pow2(1.-z) )
2894 / ( 1. - z - pT2/m2dip);
2899 yCS = pT2 / (m2dip*z*(1.-z)) ;
2903 double sij = yCS * (q2 - m2s) + (1.-yCS)*(m2r+m2e);
2904 double zbar = (q2-sij-m2s) / bABC(q2,sij,m2s)
2905 * (zCS - m2s/gABC(q2,sij,m2s)
2906 *(sij + m2r - m2e)/(q2-sij-m2s));
2907 double kT2 = zbar*(1.-zbar)*sij - (1.-zbar)*m2r - zbar*m2e;
2910 if (kT2 < 0. || isnan(kT2))
return false;
2913 double mu2Rad = m2r/q2;
2914 double mu2Emt = m2e/q2;
2915 double mu2Rec = m2s/q2;
2916 double yCSminMassive = 2.*sqrt(mu2Rad)*sqrt(mu2Emt)
2917 / ( 1 - mu2Rad - mu2Emt - mu2Rec);
2918 double yCSmaxMassive = 1.
2919 - 2.*sqrt(mu2Rec)*( 1 - sqrt(mu2Rec) )
2920 / ( 1 - mu2Rad - mu2Emt - mu2Rec);
2923 if ( yCS < yCSminMassive || yCS > yCSmaxMassive)
return false;
2926 double nu2Rad = m2r/m2dip;
2927 double nu2Emt = m2e/m2dip;
2928 double nu2Rec = m2s/m2dip;
2929 double vijk = pow2(1.-yCS) - 4.*(yCS + nu2Rad + nu2Emt)*nu2Rec;
2930 double viji = pow2(yCS) - 4.*nu2Rad*nu2Emt;
2931 if (vijk < 0. || viji < 0.)
return false;
2932 vijk = sqrt(vijk) / (1-yCS);
2933 viji = sqrt(viji) / (yCS + 2.*nu2Rad);
2934 double prefac = (m2dip*yCS + 2.*m2r) / (2.*m2dip*yCS + 2.*m2r + 2.*m2e);
2935 double zCSminMassive = ( 1 - vijk*viji) * prefac;
2936 double zCSmaxMassive = ( 1 + vijk*viji) * prefac;
2939 if ( zCS < zCSminMassive || zCS > zCSmaxMassive)
return false;
2942 }
else if (splitType == 2 && aux.size() > 0) {
2945 if (
int(aux.size()) < 11)
return false;
2948 double q2_1 = aux[1];
2950 double sai = aux[3];
2953 double m2aij = aux[6];
2954 double m2a = aux[7];
2955 double m2i = aux[8];
2956 double m2j = aux[9];
2957 double m2k = aux[10];
2958 double m2ai = sai + m2a + m2i;
2961 double yCS = t / (q2_1 - m2ai - m2j - m2k) * xa / za;
2962 double zCS = za / (xa *(1. - yCS))
2963 * (q2_1 - m2aij - m2k) / (q2_1 - m2ai - m2j - m2k);
2966 double sij = yCS * (q2_1 - m2k) + (1.-yCS)*(m2ai+m2j);
2967 double zbar = (q2_1-sij-m2k) / bABC(q2_1,sij,m2k)
2968 * (zCS - m2k/gABC(q2_1,sij,m2k)
2969 *(sij + m2ai - m2j)/(q2_1-sij-m2k));
2970 double kT2 = zbar*(1.-zbar)*sij - (1.-zbar)*m2ai - zbar*m2j;
2973 if (kT2 < 0. || isnan(kT2))
return false;
2976 double mu2Rad = m2ai/q2_1;
2977 double mu2Emt = m2j/q2_1;
2978 double mu2Rec = m2k/q2_1;
2979 double yCSminMassive = 2.*sqrt(mu2Rad)*sqrt(mu2Emt)
2980 / ( 1 - mu2Rad - mu2Emt - mu2Rec);
2981 double yCSmaxMassive = 1.
2982 - 2.*sqrt(mu2Rec)*( 1 - sqrt(mu2Rec) )
2983 / ( 1 - mu2Rad - mu2Emt - mu2Rec);
2986 if ( yCS < yCSminMassive || yCS > yCSmaxMassive)
return false;
2989 double nu2Rad = m2ai/(q2_1 - m2ai - m2j - m2k + m2aij + m2k);
2990 double nu2Emt = m2j/(q2_1 - m2ai - m2j - m2k + m2aij + m2k);
2991 double nu2Rec = m2k/(q2_1 - m2ai - m2j - m2k + m2aij + m2k);
2992 double vijk = pow2(1.-yCS) - 4.*(yCS + nu2Rad + nu2Emt)*nu2Rec;
2993 double viji = pow2(yCS) - 4.*nu2Rad*nu2Emt;
2994 if (vijk < 0. || viji < 0.)
return false;
2995 vijk = sqrt(vijk) / (1-yCS);
2996 viji = sqrt(viji) / (yCS + 2.*nu2Rad);
2997 double prefac = ((q2_1 - m2ai - m2j - m2k + m2aij + m2k)*yCS + 2.*m2ai)
2998 / (2.*(q2_1 - m2ai - m2j - m2k + m2aij + m2k)*yCS
2999 + 2.*m2ai + 2.*m2j);
3000 double zCSminMassive = ( 1 - vijk*viji) * prefac;
3001 double zCSmaxMassive = ( 1 + vijk*viji) * prefac;
3004 if ( zCS < zCSminMassive || zCS > zCSmaxMassive)
return false;
3007 double q2_2 = za/xa*(q2_1 - m2aij - m2k) + m2ai + m2k;
3009 double yCS_2 = (m2ai - m2a - m2i)
3010 / (m2ai - m2a - m2i + q2_2 - m2ai - m2k);
3013 sij = yCS_2 * (q2_2 - m2k) + (1.-yCS_2)*(m2a+m2i);
3014 zbar = (q2_2-sij-m2k) / bABC(q2_2,sij,m2k)
3015 * (zCS_2 - m2k/gABC(q2_2,sij,m2k)
3016 *(sij + m2a - m2i)/(q2_2-sij-m2k));
3017 kT2 = zbar*(1.-zbar)*sij - (1.-zbar)*m2a - zbar*m2i;
3019 if (kT2 < 0. || isnan(kT2))
return false;
3022 }
else if (splitType == 3) {
3025 if (pT2 > m2dip)
return false;
3027 double kappa2 = pow2(pTcolCutMin/10.)
3028 / pow2(0.5*(beamAPtr->e() + beamBPtr->e()));
3030 double yCS = kappa2 / (1.-z);
3031 double zCS = ( 1. - z - kappa2 - pow2(1.-z) )
3032 / ( 1. - z - kappa2);
3033 if ( zCS < 0. || zCS > 1. || yCS < 0. || yCS > 1.)
return false;
3036 }
else if (splitType ==-1) {
3039 double kappa2 = pT2/m2dip;
3041 double xCS = 1 - kappa2/(1.-z);
3046 xCS = m2dip*zCS*(1.-zCS) / ( pT2 + m2dip*zCS*(1.-zCS) ) ;
3050 if ( zCS < 0. || zCS > 1. || xCS < xOld || xCS > 1.)
return false;
3053 }
else if (splitType == -2 && aux.size() == 0) {
3057 double kappa2 = pT2/m2dip;
3059 double xCS = 1 - kappa2/(1.-z);
3064 xCS = m2dip*zCS*(1.-zCS) / ( pT2 + m2dip*zCS*(1.-zCS) ) ;
3068 double xCDST = xCS / m2dip * (m2dip + m2RadBef-m2r-m2e);
3069 double pijpa_tilde = m2dip - m2r - m2e + m2RadBef;
3070 double pijpa = pijpa_tilde/xCDST;
3071 double mu2RadBef = m2RadBef/pijpa;
3072 double muRad = sqrt(m2r/pijpa);
3073 double muEmt = sqrt(m2e/pijpa);
3074 double xCSmaxMassive = 1. + mu2RadBef - pow2(muRad + muEmt);
3077 if ( xCDST < xOld || xCDST > xCSmaxMassive)
return false;
3080 double nu2Rad = m2r/m2dip;
3081 double nu2Emt = m2e/m2dip;
3082 double viji = pow2(1.-xCS) - 4. * xCS*nu2Rad * xCS*nu2Emt;
3083 if (viji < 0.)
return false;
3084 viji = sqrt( viji ) / (1.-xCS+2.*nu2Rad*xCS);
3086 double prefac = 0.5 * ( 1.-xCS + 2.*xCS*nu2Rad )
3087 / ( 1.-xCS + xCS*nu2Rad + xCS*nu2Emt);
3088 double zCSminMassive = prefac * ( 1. - viji*vijk );
3089 double zCSmaxMassive = prefac * ( 1. + viji*vijk );
3092 if ( zCS < zCSminMassive || zCS > zCSmaxMassive)
return false;
3095 }
else if (splitType == -2 && aux.size() > 0) {
3098 if (
int(aux.size()) < 11)
return false;
3101 double q2_1 = aux[1];
3103 double sai = aux[3];
3106 double m2aij = aux[6];
3107 double m2a = aux[7];
3108 double m2i = aux[8];
3109 double m2j = aux[9];
3110 double m2k = aux[10];
3111 double m2ai = sai + m2a + m2i;
3116 double zCS = za / xa;
3117 double xCS = (q2_1 - m2ai - m2j - m2k)
3118 / (q2_1 - m2ai - m2j - m2k - t * xa/za );
3121 double xCDST = xCS * ( 1. - (m2aij-m2ai-m2j)/ (q2_1-m2ai-m2j-m2k) );
3124 double pijpa_tilde = -q2_1 + m2aij + m2k;
3125 double pijpa = pijpa_tilde/xCDST;
3126 double mu2RadBef = m2aij/pijpa;
3127 double muRad = sqrt(m2j/pijpa);
3128 double muEmt = sqrt(m2ai/pijpa);
3129 double xCSmaxMassive = 1. + mu2RadBef - pow2(muRad + muEmt);
3132 if ( xCDST < xOld || xCDST > xCSmaxMassive)
return false;
3135 double root = pow2(1. - xCDST + mu2RadBef - muRad*muRad - muEmt*muEmt)
3136 - 4.*pow2(muRad*muEmt);
3137 if (root < 0.)
return false;
3138 double zCSminMassive = (1. - xCDST + mu2RadBef + muRad*muRad - muEmt*muEmt
3139 - sqrt(root)) / ( 2.*(1. - xCDST + mu2RadBef) );
3140 double zCSmaxMassive = (1. - xCDST + mu2RadBef + muRad*muRad - muEmt*muEmt
3141 + sqrt(root)) / ( 2.*(1. - xCDST + mu2RadBef) );
3144 if ( zCS < zCSminMassive || zCS > zCSmaxMassive)
return false;
3150 double q2_2 = m2ai + m2k - za/xa * ( q2_1 - m2k - m2ai - m2j - t*xa/za);
3151 double yCS = (m2ai - m2a - m2i) / (m2ai - m2a - m2i + q2_2 - m2ai - m2k);
3154 double sij = yCS * (q2_2 - m2k) + (1.-yCS)*(m2a+m2i);
3155 double zbar = (q2_2-sij-m2k) / bABC(q2_2,sij,m2k)
3156 * (zCS - m2k/gABC(q2_2,sij,m2k)
3157 *(sij + m2a - m2i)/(q2_2-sij-m2k));
3158 double kT2 = zbar*(1.-zbar)*sij - (1.-zbar)*m2a - zbar*m2i;
3161 if (kT2 < 0. || isnan(kT2))
return false;
3164 }
else if (splitType ==-3) {
3167 if (pT2 > m2dip)
return false;
3169 double kappa2 = pow2(pTcolCutMin/10.)
3170 / pow2(0.5*(beamAPtr->e() + beamBPtr->e()));
3173 double xCS = 1 - kappa2/(1.-z);
3175 if ( zCS < 0. || zCS > 1. || xCS < xOld/1000. || xCS > 1.)
return false;
3187 void DireTimes::addNewOverestimates( multimap<double,string> newOverestimates,
3188 double& oldOverestimate) {
3191 if (!newOverestimates.empty())
3192 oldOverestimate += newOverestimates.rbegin()->first;
3202 void DireTimes::alphasReweight(
double,
double talpha,
int iSys,
3203 bool forceFixedAs,
double& weight,
double& fullWeight,
double& overWeight,
3204 double renormMultFacNow) {
3206 if (forceFixedAs) renormMultFacNow = 1.0;
3207 talpha = max(talpha, pT2colCut);
3209 double scale = talpha*renormMultFacNow;
3212 scale = max(scale, pT2colCut);
3215 double asPT2piCorr = alphasNow(talpha, renormMultFacNow, iSys);
3219 if (usePDFalphas) asOver = alphaS2piOverestimate;
3220 else if (alphaSorder==0) asOver = alphaS2pi;
3221 else asOver = alphaS.alphaS(scale) / (2.*M_PI);
3224 if (alphaSorder == 0) asFull = alphaS2pi;
3225 else asFull = asPT2piCorr;
3227 fullWeight *= asFull;
3228 overWeight *= asOver;
3229 weight *= asFull/asOver;
3239 void DireTimes::pT2nextQCD(
double pT2begDip,
double pT2sel,
3240 DireTimesEnd& dip,
Event& event,
double pT2endForce,
double pT2freeze,
3241 bool forceBranching) {
3243 if (event[dip.iRecoiler].isFinal())
3244 pT2nextQCD_FF(pT2begDip, pT2sel, dip, event, pT2endForce, pT2freeze,
3247 pT2nextQCD_FI(pT2begDip, pT2sel, dip, event, pT2endForce, pT2freeze,
3259 bool DireTimes::pT2nextQCD_FF(
double pT2begDip,
double pT2sel,
3260 DireTimesEnd& dip,
const Event& event,
double pT2endForce,
double pT2freeze,
3261 bool forceBranching) {
3264 double pT2endDip = max( pT2sel, pT2cutMin(&dip));
3265 if (pT2endForce >= 0.) pT2endDip = pT2endForce;
3266 if (pT2begDip < pT2endDip)
return false;
3269 dip.pT2 = pT2begDip;
3270 double zMinAbs = 0.0;
3271 double zMaxAbs = 1.0;
3272 double teval = pT2begDip;
3273 double Lambda2 = Lambda3flav2;
3274 double emitCoefTot = 0.;
3276 bool mustFindRange =
true;
3278 int idRadiator =
event[dip.iRadiator].id();
3279 multimap<double,string> newOverestimates;
3281 unordered_map<string,double> fullWeightsNow;
3282 int nContinue(0), nContinueMax(10000);
3283 double fullWeightNow(0.), overWeightNow(0.), auxWeightNow(0.), daux(0.);
3289 double tnow = (!forceBranching) ? dip.pT2 : pT2begDip;
3301 if (forceBranching && nContinue >= nContinueMax) {
3302 wt = 0.0; dip.pT2 = tnow = 0.;
3307 if ( fullWeightNow != 0. && overWeightNow != 0. ) {
3308 double enhanceFurther
3309 = enhanceOverestimateFurther(splittingNowName, idRadiator, teval);
3310 if (doTrialNow) enhanceFurther = 1.;
3311 kernelNow = fullWeightsNow;
3312 auxNow = auxWeightNow;
3313 overNow = overWeightNow;
3314 boostNow = enhanceFurther;
3315 for ( unordered_map<string,double>::iterator it = fullWeightsNow.begin();
3316 it != fullWeightsNow.end(); ++it ) {
3319 if (it->first ==
"base_order_as2")
continue;
3321 double wv = auxWeightNow/overWeightNow
3322 * (overWeightNow- it->second/enhanceFurther)
3323 / (auxWeightNow - fullWeightNow);
3324 if (abs(wv) > 1e0) {
3325 direInfoPtr->message(1) << __FILE__ <<
" " << __func__
3326 <<
" " << __LINE__ <<
" : Large reject weight=" << wv
3327 <<
"\t for kernel=" << it->second <<
" overestimate=" << overNow
3328 <<
"\t aux. overestimate=" << auxNow <<
" enhance=" << enhanceFurther
3329 <<
" at pT2=" << tnow
3330 <<
" for " << splittingNowName <<
" " << it->first << endl;
3333 rejectProbability[it->first].insert( make_pair(tnow,wv));
3337 splittingNowName =
"";
3338 fullWeightsNow.clear();
3339 fullWeightNow = overWeightNow = auxWeightNow = 0.;
3341 if (mustFindRange) {
3343 newOverestimates.clear();
3349 Lambda2 = Lambda5flav2;
3350 }
else if (tnow > m2c) {
3351 Lambda2 = Lambda4flav2;
3353 Lambda2 = Lambda3flav2;
3356 Lambda2 /= renormMultFac;
3359 getNewOverestimates( &dip, event, tnow, 1., zMinAbs, zMaxAbs,
3361 addNewOverestimates(newOverestimates, emitCoefTot);
3367 mustFindRange =
false;
3370 if (emitCoefTot < TINYOVERESTIMATE) { dip.pT2 = 0.0;
return false; }
3371 if (newOverestimates.empty()) { dip.pT2 = 0.0;
return false; }
3374 bool forceFixedAs = (tnow < pT2colCut);
3375 tnow = tNextQCD( &dip, emitCoefTot, tnow, pT2endDip, pT2freeze,
3376 (forceBranching ? -1 : 1));
3378 wt = 0.0; dip.pT2 = tnow = 0.;
3379 double R0 = emitCoefTot*rndmPtr->flat();
3380 if (!newOverestimates.empty()) {
3381 if (newOverestimates.lower_bound(R0) == newOverestimates.end())
3382 splittingNowName = newOverestimates.rbegin()->second;
3384 splittingNowName = newOverestimates.lower_bound(R0)->second;
3393 if ( tnow < pT2endDip ) { dip.pT2 = tnow = 0.;
break; }
3396 double R = emitCoefTot*rndmPtr->flat();
3398 int idDaughter, idSister;
3399 idDaughter = idSister = 0;
3400 if (!newOverestimates.empty()) {
3403 if (newOverestimates.lower_bound(R) == newOverestimates.end())
3404 splittingNowName = newOverestimates.rbegin()->second;
3406 splittingNowName = newOverestimates.lower_bound(R)->second;
3409 getNewSplitting( event, &dip, teval, 0., tnow, zMinAbs,
3410 zMaxAbs, idRadiator, splittingNowName, forceFixedAs, idDaughter,
3411 idSister, z, wt, fullWeightsNow, overWeightNow);
3417 if ( wt == 0. || z < 0.) {
3419 fullWeightsNow.clear();
3420 wt = fullWeightNow = overWeightNow = auxWeightNow = 0.;
3421 nContinue++;
continue;
3424 fullWeightNow = fullWeightsNow[
"base"];
3428 double m2Bef = particleDataPtr->isResonance(event[dip.iRadiator].id())
3429 ? getMass(event[dip.iRadiator].id(),3,
3430 event[dip.iRadiator].mCalc())
3431 : (abs(event[dip.iRadiator].id()) < 6
3432 || event[dip.iRadiator].id() == 21
3433 ||
event[dip.iRadiator].id() == 22)
3434 ? getMass(event[dip.iRadiator].id(),2)
3435 : getMass(event[dip.iRadiator].id(),1);
3437 double m2r = particleDataPtr->isResonance(idDaughter)
3438 && idDaughter ==
event[dip.iRadiator].id()
3439 ? getMass(idDaughter,3,event[dip.iRadiator].mCalc())
3440 : (abs(idDaughter) < 6 || idDaughter == 21
3441 || idDaughter == 22)
3442 ? getMass(idDaughter,2)
3443 : getMass(idDaughter,1);
3445 double m2s = particleDataPtr->isResonance(event[dip.iRecoiler].id())
3446 ? getMass(event[dip.iRecoiler].id(),3,
3447 event[dip.iRecoiler].mCalc())
3448 : (event[dip.iRecoiler].idAbs() < 6
3449 ||
event[dip.iRecoiler].id() == 21
3450 ||
event[dip.iRecoiler].id() == 22)
3451 ? getMass(event[dip.iRecoiler].id(),2)
3452 : getMass(event[dip.iRecoiler].id(),1);
3454 double m2e = (abs(dip.flavour) < 6 || dip.flavour == 21
3455 || dip.flavour == 22)
3456 ? getMass(dip.flavour,2) : getMass(dip.flavour,1);
3458 bool canUseSplitInfo = splits[splittingNowName]->canUseForBranching();
3459 if (canUseSplitInfo) {
3460 m2r = splits[splittingNowName]->splitInfo.kinematics()->m2RadAft;
3461 m2e = splits[splittingNowName]->splitInfo.kinematics()->m2EmtAft;
3463 int nEmissions = splits[splittingNowName]->nEmissions();
3466 double Q2 = dip.m2Dip + m2Bef - m2r - m2e;
3467 double q2 = (
event[dip.iRadiator].p() +
event[dip.iRecoiler].p()).m2Calc();
3473 if ( nEmissions == 2
3474 && ( (abs(dip.flavour) == 4 && tnow < m2cPhys)
3475 || (abs(dip.flavour) == 5 && tnow < m2bPhys))) {
3476 mustFindRange =
true;
3477 fullWeightsNow.clear();
3478 wt = fullWeightNow = overWeightNow = auxWeightNow = 0.;
3479 nContinue++;
continue;
3483 double m2aij(m2Bef), m2a(m2e), m2i(m2e), m2j(m2r), m2k(m2s);
3484 if (canUseSplitInfo)
3485 m2j = splits[splittingNowName]->splitInfo.kinematics()->m2EmtAft2;
3487 double jacobian(1.);
3488 if (canUseSplitInfo) {
3489 jacobian = splits[splittingNowName]->getJacobian(event,partonSystemsPtr);
3492 double yCS = tnow/Q2 / (1. - z);
3493 double mu2RadBef = m2Bef/ q2;
3494 double mu2Rad = m2r/ q2;
3495 double mu2Rec = m2s/ q2;
3496 double mu2Emt = m2e/ q2;
3498 double jac1 = ( 1. - mu2Rad - mu2Rec - mu2Emt)
3499 / sqrt(lABC(1.,mu2RadBef,mu2Rec));
3500 double jac2 = 1. + ( mu2Rad + mu2Emt - mu2RadBef)
3501 /( yCS*(1. - mu2Rad - mu2Rec - mu2Emt));
3504 if (nEmissions == 2) {
3505 double sai = dip.sa1;
3506 double m2ai = sai + m2a + m2i;
3509 jac1 = (q2 - m2aij - m2k) / sqrt( lABC(q2, m2aij, m2k) );
3511 double m2aik = (dip.sa1 + m2a + m2i) + m2k
3512 + dip.z/dip.xa * (q2 - m2Bef - m2k);
3513 jac1 *= (m2aik - m2ai - m2k) / sqrt( lABC(m2aik, m2ai, m2k) );
3515 jac2 = 1 + (m2ai + m2j - m2aij) / (dip.pT2*dip.xa/dip.z);
3517 jacobian = jac1/jac2;
3521 fullWeightNow *= jacobian;
3522 for ( unordered_map<string,double>::iterator it = fullWeightsNow.begin();
3523 it != fullWeightsNow.end(); ++it )
3524 it->second *= jacobian;
3528 if ( nEmissions == 2
3529 && splits[splittingNowName]->splitInfo.kinematics()->sai == 0.)
3532 if (fullWeightNow == 0. ) {
3534 fullWeightsNow.clear();
3535 wt = fullWeightNow = overWeightNow = auxWeightNow = 0.;
3536 nContinue++;
continue;
3540 double scale2 = splits[splittingNowName]->couplingScale2 ( z, tnow, Q2,
3541 make_pair (event[dip.iRadiator].id(),
event[dip.iRadiator].isFinal()),
3542 make_pair (event[dip.iRecoiler].id(),
event[dip.iRecoiler].isFinal()));
3543 if (scale2 < 0.) scale2 = tnow;
3544 double talpha = max(scale2, pT2colCut);
3548 alphasReweight( tnow, talpha, dip.system, forceFixedAs, wt, fullWeightNow,
3549 overWeightNow, renormMultFac);
3550 auxWeightNow = overWeightNow;
3554 alphasReweight(tnow, talpha, dip.system, forceFixedAs, daux, asw, daux,
3556 fullWeightsNow[
"base"] *= asw;
3557 if (fullWeightsNow.find(
"base_order_as2") != fullWeightsNow.end())
3558 fullWeightsNow[
"base_order_as2"] *= asw;
3560 if ( splittingNowName.find(
"qcd") != string::npos
3561 && settingsPtr->parm(
"Variations:muRfsrDown") != 1.) {
3563 alphasReweight(tnow, talpha, dip.system, forceFixedAs, daux, asw, daux,
3564 (tnow > pT2minVariations) ? settingsPtr->
3565 parm(
"Variations:muRfsrDown") : renormMultFac);
3566 fullWeightsNow[
"Variations:muRfsrDown"] *= asw;
3567 }
else if ( splittingNowName.find(
"qcd") == string::npos )
3568 fullWeightsNow[
"Variations:muRfsrDown"] *= asw;
3569 if ( splittingNowName.find(
"qcd") != string::npos
3570 && settingsPtr->parm(
"Variations:muRfsrUp") != 1.) {
3572 alphasReweight(tnow, talpha, dip.system, forceFixedAs, daux, asw, daux,
3573 (tnow > pT2minVariations) ? settingsPtr->parm(
"Variations:muRfsrUp")
3575 fullWeightsNow[
"Variations:muRfsrUp"] *= asw;
3576 }
else if ( splittingNowName.find(
"qcd") == string::npos )
3577 fullWeightsNow[
"Variations:muRfsrUp"] *= asw;
3581 if (fullWeightNow < 0.) {
3582 auxWeightNow *= -1.;
3586 if (fullWeightNow > 0. && fullWeightNow/auxWeightNow > 1.) {
3587 direInfoPtr->message(1) << __FILE__ <<
" " << __func__
3588 <<
" " << __LINE__ <<
" : Large acceptance weight="
3589 << fullWeightNow/auxWeightNow
3590 <<
" for splitting " << splittingNowName <<
" at pT2=" << tnow
3591 <<
" and z=" << z << endl;
3593 if (fullWeightNow/auxWeightNow > 2.)
3594 scaleOverheadFactor(splittingNowName, 2.);
3595 double rescale = fullWeightNow/auxWeightNow * 1.15;
3596 auxWeightNow *= rescale;
3597 infoPtr->errorMsg(
"Info in DireTimes::pT2nextQCD_FF: Found large "
3598 "acceptance weight for " + splittingNowName);
3601 wt = fullWeightNow/auxWeightNow;
3604 }
while (wt < rndmPtr->flat());
3607 if ( wt == 0.)
return false;
3611 if ( fullWeightNow != 0. && overWeightNow != 0. ) {
3612 double enhanceFurther
3613 = enhanceOverestimateFurther(splittingNowName, idRadiator, teval);
3614 double tnow = dip.pT2;
3616 weights->addTrialEnhancement(tnow, enhanceFurther);
3617 enhanceFurther = 1.;
3619 kernelNow = fullWeightsNow;
3620 auxNow = auxWeightNow;
3621 overNow = overWeightNow;
3622 boostNow = enhanceFurther;
3623 for ( unordered_map<string,double>::iterator it = fullWeightsNow.begin();
3624 it != fullWeightsNow.end(); ++it ) {
3627 if (it->first ==
"base_order_as2")
continue;
3629 acceptProbability[it->first].insert(make_pair(tnow,
3630 auxWeightNow/overWeightNow * 1./enhanceFurther
3631 * it->second/fullWeightNow ) );
3632 if (auxWeightNow == fullWeightNow && overWeightNow == fullWeightNow)
3633 rejectProbability[it->first].insert( make_pair(tnow, 1.0));
3635 double wv = auxWeightNow/overWeightNow
3636 * (overWeightNow- it->second/enhanceFurther)
3637 / (auxWeightNow - fullWeightNow);
3638 if (abs(wv) > 1e0) {
3639 direInfoPtr->message(1) << __FILE__ <<
" " << __func__
3640 <<
" " << __LINE__ <<
" : Large reject weight=" << wv
3641 <<
"\t for kernel=" << it->second <<
" " << fullWeightNow
3642 <<
" overestimate=" << overNow
3643 <<
"\t aux. overestimate=" << auxNow <<
" enhance=" << enhanceFurther
3646 <<
" for " << splittingNowName <<
" " << it->first << endl;
3648 rejectProbability[it->first].insert( make_pair(tnow, wv));
3662 bool DireTimes::pT2nextQCD_FI(
double pT2begDip,
double pT2sel,
3663 DireTimesEnd& dip,
const Event& event,
double pT2endForce,
double pT2freeze,
3664 bool forceBranching) {
3668 double pT2endDip = max( pT2sel, pT2cutMin(&dip));
3669 if (pT2endForce >= 0.) pT2endDip = pT2endForce;
3670 if (pT2begDip < pT2endDip) { dip.pT2 = 0.;
return false; }
3672 BeamParticle& beam = (dip.isrType == 1) ? *beamAPtr : *beamBPtr;
3679 dip.pT2 = pT2begDip;
3681 double zMinAbs = 0.0;
3682 double zMaxAbs = 1.0;
3683 double teval = pT2begDip;
3684 double Lambda2 = Lambda3flav2;
3685 double xPDFrecoiler = 0.;
3686 double emitCoefTot = 0.;
3688 bool mustFindRange =
true;
3689 int idRadiator =
event[dip.iRadiator].id();
3690 int idRecoiler =
event[dip.iRecoiler].id();
3691 int iSysRec = dip.systemRec;
3692 double xRecoiler = beam[iSysRec].x();
3693 bool hasPDFrec = hasPDF(idRecoiler);
3697 int iOther = (dip.isrType == 1) ? partonSystemsPtr->getInB(iSysRec)
3698 : partonSystemsPtr->getInA(iSysRec);
3699 Vec4 pOther(event[iOther].p());
3701 multimap<double,string> newOverestimates;
3702 unordered_map<string,double> fullWeightsNow;
3703 double fullWeightNow(0.), overWeightNow(0.), auxWeightNow(0.), daux(0.);
3706 int loopTinyPDFdau = 0;
3707 int nContinue(0), nContinueMax(10000);
3708 bool hasTinyPDFdau =
false;
3713 double tnow = (!forceBranching) ? dip.pT2 : pT2begDip;
3721 if (forceBranching && nContinue >= nContinueMax) {
3722 wt = 0.0; dip.pT2 = tnow = 0.;
3727 if ( fullWeightNow != 0. && overWeightNow != 0. ) {
3728 double enhanceFurther
3729 = enhanceOverestimateFurther(splittingNowName, idRadiator, teval);
3730 if (doTrialNow) enhanceFurther = 1.;
3731 kernelNow = fullWeightsNow;
3732 auxNow = auxWeightNow;
3733 overNow = overWeightNow;
3734 boostNow = enhanceFurther;
3735 for ( unordered_map<string,double>::iterator it = fullWeightsNow.begin();
3736 it != fullWeightsNow.end(); ++it ) {
3739 if (it->first ==
"base_order_as2")
continue;
3741 double wv = auxWeightNow/overWeightNow
3742 * (overWeightNow- it->second/enhanceFurther)
3743 / (auxWeightNow - fullWeightNow);
3744 if (abs(wv) > 1e0) {
3745 direInfoPtr->message(1) << __FILE__ <<
" " << __func__
3746 <<
" " << __LINE__ <<
" : Large reject weight=" << wv
3747 <<
"\t for kernel=" << it->second <<
" overestimate=" << overNow
3748 <<
"\t aux. overestimate=" << auxNow <<
" at pT2="
3750 <<
" for " << splittingNowName << endl;
3752 rejectProbability[it->first].insert( make_pair(tnow,wv));
3756 splittingNowName =
"";
3757 fullWeightsNow.clear();
3758 fullWeightNow = overWeightNow = auxWeightNow = 0.;
3761 if ( event[dip.iRecoiler].idAbs() == 4 && tnow <= m2cPhys) {
3762 dip.pT2 = 0.;
return false;
3764 if ( event[dip.iRecoiler].idAbs() == 5 && tnow <= m2bPhys) {
3765 dip.pT2 = 0.;
return false;
3769 double tnew = (useFixedFacScale) ? fixedFacScale2 : factorMultFac*tnow;
3770 bool inNew = (hasPDFrec)
3771 ? beam.insideBounds(xRecoiler, max(tnew, pT2colCut) ) : 1.0;
3772 if (hasPDFrec && !inNew) { dip.pT2 = 0.0;
return false; }
3776 if (hasTinyPDFdau) ++loopTinyPDFdau;
3777 if (hasPDFrec && loopTinyPDFdau > MAXLOOPTINYPDF) {
3778 infoPtr->errorMsg(
"Warning in DireTimes::pT2nextQCD_FI: "
3779 "small daughter PDF");
3787 || tnow < evalpdfstep(event[dip.iRecoiler].id(), tnow, m2cPhys, m2bPhys)*
3790 newOverestimates.clear();
3797 Lambda2 = Lambda5flav2;
3798 }
else if (tnow > m2c) {
3800 Lambda2 = Lambda4flav2;
3803 Lambda2 = Lambda3flav2;
3806 Lambda2 /= renormMultFac;
3809 pdfScale2 = (useFixedFacScale) ? fixedFacScale2 : factorMultFac*tnow;
3810 pdfScale2 = max(pdfScale2, pT2colCut);
3811 xPDFrecoiler = getXPDF(idRecoiler, xRecoiler, pdfScale2, iSysRec, &beam);
3812 if ( hasPDFrec && xPDFrecoiler != 0.
3813 && abs(xPDFrecoiler) < 1e-15) {
3814 int sign = (xPDFrecoiler > 0.) ? 1 : -1;
3815 xPDFrecoiler = sign*tinypdf(xRecoiler);
3816 hasTinyPDFdau =
true;
3819 double xMin = (hasPDFrec) ? xRecoiler : 0.;
3822 getNewOverestimates( &dip, event, tnow, xMin, zMinAbs, zMaxAbs,
3824 addNewOverestimates(newOverestimates, emitCoefTot);
3830 mustFindRange =
false;
3833 if (emitCoefTot < TINYOVERESTIMATE) { dip.pT2 = 0.0;
return false; }
3834 if (newOverestimates.empty()) { dip.pT2 = 0.0;
return false; }
3837 bool forceFixedAs = (tnow < pT2colCut);
3838 tnow = tNextQCD( &dip, emitCoefTot, tnow, pT2endDip, pT2freeze,
3839 (forceBranching ? -1 : 1));
3841 wt = 0.0; dip.pT2 = tnow = 0.;
3842 double R0 = emitCoefTot*rndmPtr->flat();
3843 if (!newOverestimates.empty()) {
3844 if (newOverestimates.lower_bound(R0) == newOverestimates.end())
3845 splittingNowName = newOverestimates.rbegin()->second;
3847 splittingNowName = newOverestimates.lower_bound(R0)->second;
3856 if ( nFlavour == 5 && tnow < m2bPhys ) {
3857 mustFindRange =
true;
3859 }
else if ( nFlavour == 4 && tnow < m2cPhys ) {
3860 mustFindRange =
true;
3864 if ( event[dip.iRecoiler].idAbs() == 4 && tnow <= m2cPhys) {
3865 dip.pT2 = 0.;
return false;
3867 if ( event[dip.iRecoiler].idAbs() == 5 && tnow <= m2bPhys) {
3868 dip.pT2 = 0.;
return false;
3872 if ( tnow < pT2endDip ) { dip.pT2 = tnow = 0.;
break; }
3875 double R = emitCoefTot*rndmPtr->flat();
3877 int idDaughter, idSister;
3878 idDaughter = idSister = 0;
3880 if (!newOverestimates.empty()) {
3882 if (newOverestimates.lower_bound(R) == newOverestimates.end())
3883 splittingNowName = newOverestimates.rbegin()->second;
3885 splittingNowName = newOverestimates.lower_bound(R)->second;
3888 double xMin = (hasPDFrec) ? xRecoiler : 0.;
3889 getNewSplitting( event, &dip, teval, xMin, tnow, zMinAbs,
3890 zMaxAbs, idRadiator, splittingNowName, forceFixedAs, idDaughter,
3891 idSister, z, wt, fullWeightsNow, overWeightNow);
3899 fullWeightsNow.clear();
3900 wt = fullWeightNow = overWeightNow = auxWeightNow = 0.;
3901 nContinue++;
continue;
3904 fullWeightNow = fullWeightsNow[
"base"];
3908 double m2Bef = particleDataPtr->isResonance(event[dip.iRadiator].id())
3909 ? getMass(event[dip.iRadiator].id(),3,
3910 event[dip.iRadiator].mCalc())
3911 : (event[dip.iRadiator].idAbs() < 6
3912 ||
event[dip.iRadiator].id() == 21
3913 ||
event[dip.iRadiator].id() == 22)
3914 ? getMass(event[dip.iRadiator].id(),2)
3915 : getMass(event[dip.iRadiator].id(),1);
3917 double m2r = particleDataPtr->isResonance(idDaughter)
3918 && idDaughter ==
event[dip.iRadiator].id()
3919 ? getMass(idDaughter,3,event[dip.iRadiator].mCalc())
3920 : (abs(idDaughter) < 6
3922 ||
event[dip.iRadiator].id() == 22)
3923 ? getMass(idDaughter,2)
3924 : getMass(idDaughter,1);
3926 double m2e = (abs(dip.flavour) < 6
3927 || dip.flavour == 21
3928 || dip.flavour == 22)
3929 ? getMass(dip.flavour,2)
3930 : getMass(dip.flavour,1);
3932 bool canUseSplitInfo = splits[splittingNowName]->canUseForBranching();
3933 if (canUseSplitInfo) {
3934 m2Bef = splits[splittingNowName]->splitInfo.kinematics()->m2RadBef;
3935 m2r = splits[splittingNowName]->splitInfo.kinematics()->m2RadAft;
3936 m2e = splits[splittingNowName]->splitInfo.kinematics()->m2EmtAft;
3938 int nEmissions = splits[splittingNowName]->nEmissions();
3940 double q2 = (
event[dip.iRecoiler].p()
3941 -
event[dip.iRadiator].p()).m2Calc();
3943 double Q2 = dip.m2Dip - m2Bef + m2r + m2e;
3946 if ( event[dip.iRecoiler].idAbs() == 5 && nEmissions == 2
3947 && tnow <= 4.*m2bPhys) {
3948 fullWeightsNow.clear();
3949 wt = fullWeightNow = overWeightNow = auxWeightNow = 0.;
3950 nContinue++;
continue;
3951 }
else if ( event[dip.iRecoiler].idAbs() == 4 && nEmissions == 2
3952 && tnow <= 4.*m2cPhys) {
3953 fullWeightsNow.clear();
3954 wt = fullWeightNow = overWeightNow = auxWeightNow = 0.;
3955 nContinue++;
continue;
3962 if ( nEmissions == 2
3963 && ( (abs(dip.flavour) == 4 && tnow < m2cPhys)
3964 || (abs(dip.flavour) == 5 && tnow < m2bPhys))) {
3965 mustFindRange =
true;
3966 fullWeightsNow.clear();
3967 wt = fullWeightNow = overWeightNow = auxWeightNow = 0.;
3968 nContinue++;
continue;
3971 double m2a(m2e), m2i(m2e), m2j(m2Bef), m2aij(m2Bef), m2k(0.0);
3972 if (canUseSplitInfo)
3973 m2j = splits[splittingNowName]->splitInfo.kinematics()->m2EmtAft2;
3977 double kappa2 = tnow/Q2;
3978 double xCS = 1 - kappa2/(1.-z);
3979 double xCDST = xCS*( 1. + (m2Bef-m2r-m2e)/Q2 );
3980 double xNew = xRecoiler / xCDST;
3983 double jacobian = 1.;
3984 if (canUseSplitInfo) {
3986 = splits[splittingNowName]->getJacobian(event,partonSystemsPtr);
3987 unordered_map<string,double> psvars
3988 = splits[splittingNowName]->getPhasespaceVars(event, partonSystemsPtr);
3989 xNew = psvars[
"xInAft"];
3993 double pdfRatio = 1.;
3994 pdfScale2 = (useFixedFacScale) ? fixedFacScale2
3995 : factorMultFac * tnow;
3996 pdfScale2 = max(pdfScale2, pT2colCut);
3997 double pdfScale2Old = pdfScale2;
3998 double pdfScale2New = pdfScale2;
3999 if (forceBranching) pdfScale2New = pdfScale2Old = infoPtr->Q2Fac();
4000 bool inD = hasPDFrec ? beam.insideBounds(xRecoiler, pdfScale2Old) :
true;
4001 bool inM = hasPDFrec ? beam.insideBounds(xNew, pdfScale2New) :
true;
4002 double pdfOld = getXPDF(idRecoiler, xRecoiler, pdfScale2Old, iSysRec,
4003 &beam,
false, z, dip.m2Dip);
4004 double pdfNew = getXPDF(idRecoiler, xNew, pdfScale2New, iSysRec,
4005 &beam,
false, z, dip.m2Dip);
4007 if ( hasPDFrec && pdfOld != 0.
4008 && abs(pdfOld) < tinypdf(xRecoiler) ) {
4009 fullWeightsNow.clear();
4010 wt = fullWeightNow = overWeightNow = auxWeightNow = 0.;
4011 nContinue++;
continue;
4018 double xPDFrecoilerLow = getXPDF(idRecoiler, xRecoiler,
4019 pdfScale2Old*pdfScale2Old/max(teval, pT2colCut), iSysRec, &beam);
4020 if ( idRecoiler == 21
4021 && ( abs(pdfOld/xPDFrecoiler) < 1e-4
4022 || abs(xPDFrecoilerLow/pdfOld) < 1e-4) ) {
4023 hasTinyPDFdau =
true;
4024 fullWeightsNow.clear();
4025 wt = fullWeightNow = overWeightNow = auxWeightNow = 0.;
4026 nContinue++;
continue;
4030 pdfRatio = (inD && inM) ? pdfNew/pdfOld : 0.;
4032 if (!canUseSplitInfo) {
4034 if ( nEmissions!= 2 ) jacobian = ( 1.- xCS) / ( 1. - xCDST);
4037 if ( nEmissions == 2 ) {
4038 double m2ai = dip.sa1 + m2a + m2i;
4039 xCS = (q2 - m2ai - m2a - m2i)
4040 / (q2 - m2ai - m2a - m2i - dip.pT2 * dip.xa/dip.z);
4044 double saij = (xCS - 1.)/xCS * (q2 - m2a) + (m2ai + m2j)/xCS;
4045 double xbar = (q2 - m2aij - m2k) / (q2 - saij - m2k);
4048 double sHatBefore = (
event[dip.iRecoiler].p() + pOther).m2Calc();
4049 double m2OtherBeam = 0.;
4052 Vec4 q(event[dip.iRecoiler].p()-
event[dip.iRadiator].p());
4053 Vec4 pRadBef(event[dip.iRadiator].p());
4054 Vec4 pRecBef(event[dip.iRecoiler].p());
4055 Vec4 qpar(q.px()+pRadBef.px(), q.py()+pRadBef.py(), q.pz(), q.e());
4056 double qpar2 = qpar.m2Calc();
4057 double pT2ijt = pow2(pRadBef.px()) + pow2(pRadBef.py());
4058 Vec4 pRec( (pRecBef - (qpar*pRecBef)/qpar2 * qpar)
4059 * sqrt( (lABC(q2,saij,m2k) - 4.*m2k*pT2ijt)
4060 /(lABC(q2,m2aij,m2k) - 4.*m2k*pT2ijt))
4061 + qpar * (q2+m2k-saij)/(2.*qpar2) );
4063 double sHatAfter = (pOther + pRec).m2Calc();
4066 double rho_bai = sqrt( lABC(sHatBefore, m2k, m2OtherBeam)
4067 / lABC(sHatAfter, m2k, m2OtherBeam) );
4068 jacobian = rho_bai/xbar
4069 * (saij + m2k - q2) / sqrt( lABC(saij, m2k, q2) );
4072 double saib = m2ai + m2k
4073 + dip.z/dip.xa * (q2 - m2k - m2ai - m2j - dip.pT2*dip.xa/dip.z);
4074 jacobian *= (m2ai + m2k - saib) / sqrt( lABC(m2ai, m2k, saib) );
4076 xCDST = xCS * ( 1. - (m2aij-m2ai-m2j)/ (q2-m2ai-m2j-m2k) );
4078 jacobian *= ( 1.- xCS) / ( 1. - xCDST);
4081 xNew = xRecoiler / xCDST;
4082 inM = (!hasPDFrec) ?
true : beam.insideBounds(xNew, pdfScale2);
4083 pdfNew = getXPDF(idRecoiler, xNew, pdfScale2, iSysRec, &beam);
4084 pdfRatio = (inD && inM) ? pdfNew/pdfOld : 0.;
4089 if ( idRecoiler == 21 && pdfScale2 == pT2colCut
4090 && pdfRatio > 50.) pdfRatio = 0.;
4092 fullWeightNow *= pdfRatio*jacobian;
4094 for ( unordered_map<string,double>::iterator it = fullWeightsNow.begin();
4095 it != fullWeightsNow.end(); ++it )
4096 it->second *= pdfRatio*jacobian;
4100 if ( nEmissions == 2
4101 && splits[splittingNowName]->splitInfo.kinematics()->sai == 0.)
4104 if (fullWeightNow == 0. ) {
4105 fullWeightsNow.clear();
4106 wt = fullWeightNow = overWeightNow = auxWeightNow = 0.;
4107 nContinue++;
continue;
4111 double scale2 = splits[splittingNowName]->couplingScale2 ( z, tnow, Q2,
4112 make_pair (event[dip.iRadiator].id(),
event[dip.iRadiator].isFinal()),
4113 make_pair (event[dip.iRecoiler].id(),
event[dip.iRecoiler].isFinal()));
4114 if (scale2 < 0.) scale2 = tnow;
4115 double talpha = max(scale2, pT2colCut);
4120 alphasReweight(tnow, talpha, dip.system, forceFixedAs, wt, fullWeightNow,
4121 overWeightNow, renormMultFac);
4122 auxWeightNow = overWeightNow;
4126 alphasReweight(tnow, talpha, dip.system, forceFixedAs, daux, asw, daux,
4128 fullWeightsNow[
"base"] *= asw;
4129 if (fullWeightsNow.find(
"base_order_as2") != fullWeightsNow.end())
4130 fullWeightsNow[
"base_order_as2"] *= asw;
4132 if ( splittingNowName.find(
"qcd") != string::npos
4133 && settingsPtr->parm(
"Variations:muRfsrDown") != 1.) {
4135 alphasReweight(tnow, talpha, dip.system, forceFixedAs, daux, asw, daux,
4136 (tnow > pT2minVariations) ? settingsPtr->
4137 parm(
"Variations:muRfsrDown") : renormMultFac);
4138 fullWeightsNow[
"Variations:muRfsrDown"] *= asw;
4139 }
else if ( splittingNowName.find(
"qcd") == string::npos )
4140 fullWeightsNow[
"Variations:muRfsrDown"] *= asw;
4141 if ( splittingNowName.find(
"qcd") != string::npos
4142 && settingsPtr->parm(
"Variations:muRfsrUp") != 1.) {
4144 alphasReweight(tnow, talpha, dip.system, forceFixedAs, daux, asw, daux,
4145 (tnow > pT2minVariations) ? settingsPtr->parm(
"Variations:muRfsrUp")
4147 fullWeightsNow[
"Variations:muRfsrUp"] *= asw;
4148 }
else if ( splittingNowName.find(
"qcd") == string::npos )
4149 fullWeightsNow[
"Variations:muRfsrUp"] *= asw;
4152 if (hasPDFrec && settingsPtr->flag(
"Variations:PDFup") ) {
4153 int valSea = (beam[iSysRec].isValence()) ? 1 : 0;
4154 if( beam[iSysRec].isUnmatched() ) valSea = 2;
4155 beam.calcPDFEnvelope( make_pair(idRecoiler, idRecoiler),
4156 make_pair(xNew,xRecoiler), pdfScale2, valSea);
4157 PDF::PDFEnvelope ratioPDFEnv = beam.getPDFEnvelope();
4159 = min(ratioPDFEnv.errplusPDF / ratioPDFEnv.centralPDF, 10.);
4160 double deltaPDFminus
4161 = min(ratioPDFEnv.errminusPDF / ratioPDFEnv.centralPDF, 10.);
4162 fullWeightsNow[
"Variations:PDFup"] = fullWeightsNow[
"base"]
4163 * ((tnow > pT2minVariations) ? (1.0 + deltaPDFplus) : 1.0);
4164 fullWeightsNow[
"Variations:PDFdown"] = fullWeightsNow[
"base"]
4165 * ((tnow > pT2minVariations) ? (1.0 - deltaPDFminus) : 1.0);
4170 if (fullWeightNow < 0.) {
4171 auxWeightNow *= -1.;
4175 if ( fullWeightNow/auxWeightNow > 1.) {
4176 direInfoPtr->message(1) << __FILE__ <<
" " << __func__
4177 <<
" " << __LINE__ <<
" : Large acceptance weight="
4178 << fullWeightNow/auxWeightNow
4179 <<
" for splitting " << splittingNowName <<
" at pT2=" << tnow
4180 <<
" and z=" << z <<
"\t(PDF ratio=" << pdfRatio <<
")" << endl;
4182 double rescale = fullWeightNow/auxWeightNow * 1.15;
4183 auxWeightNow *= rescale;
4184 infoPtr->errorMsg(
"Info in DireTimes::pT2nextQCD_FI: Found large "
4185 "acceptance weight for " + splittingNowName);
4188 wt = fullWeightNow/auxWeightNow;
4191 }
while (wt < rndmPtr->flat());
4194 if ( wt == 0.)
return false;
4198 if ( fullWeightNow != 0. && overWeightNow != 0. ) {
4199 double enhanceFurther
4200 = enhanceOverestimateFurther(splittingNowName, idRadiator, teval);
4201 double tnow = dip.pT2;
4203 weights->addTrialEnhancement(tnow, enhanceFurther);
4204 enhanceFurther = 1.;
4206 kernelNow = fullWeightsNow;
4207 auxNow = auxWeightNow;
4208 overNow = overWeightNow;
4209 boostNow = enhanceFurther;
4210 for ( unordered_map<string,double>::iterator it = fullWeightsNow.begin();
4211 it != fullWeightsNow.end(); ++it ) {
4214 if (it->first ==
"base_order_as2")
continue;
4216 acceptProbability[it->first].insert(make_pair(tnow,
4217 auxWeightNow/overWeightNow * 1./enhanceFurther
4218 * it->second/fullWeightNow ) );
4219 if (auxWeightNow == fullWeightNow && overWeightNow == fullWeightNow)
4220 rejectProbability[it->first].insert( make_pair(tnow, 1.0));
4222 double wv = auxWeightNow/overWeightNow
4223 * (overWeightNow- it->second/enhanceFurther)
4224 / (auxWeightNow - fullWeightNow);
4225 if (abs(wv) > 1e0) {
4226 direInfoPtr->message(1) << __FILE__ <<
" " << __func__
4227 <<
" " << __LINE__ <<
" : Large reject weight=" << wv
4228 <<
"\t for kernel=" << it->second <<
" overestimate=" << overNow
4229 <<
"\t aux. overestimate=" << auxNow <<
" at pT2="
4231 <<
" for " << splittingNowName << endl;
4233 rejectProbability[it->first].insert( make_pair(tnow, wv));
4245 double DireTimes::tNextQCD( DireTimesEnd*,
double overestimateInt,
4246 double tOld,
double tMin,
double tFreeze,
int algoType) {
4249 bool forceFixedAs = (tOld < pT2colCut);
4250 double asOver = (usePDFalphas || forceFixedAs)
4251 ? alphaS2piOverestimate : alphaS2pi;
4252 double rnd = rndmPtr->flat();
4256 if (usePDFalphas || alphaSorder == 0) {
4257 double rndMin = pow( tMin/tOld, asOver * overestimateInt);
4258 if (rnd < rndMin)
return -1.*tMin;
4263 double Lambda2 = Lambda3flav2;
4266 Lambda2 = Lambda5flav2;
4267 }
else if (tOld > m2c) {
4269 Lambda2 = Lambda4flav2;
4272 Lambda2 = Lambda3flav2;
4275 Lambda2 /= renormMultFac;
4278 double tForAlphaS=tOld;
4282 return pow(tMin+tFreeze,rnd) / pow(tnow+tFreeze,rnd-1) - tFreeze;
4284 if (usePDFalphas || forceFixedAs)
4285 tnow = (tnow+tFreeze) * pow( rnd,
4286 1. / (alphaS2piOverestimate * overestimateInt)) - tFreeze;
4288 else if (alphaSorder == 0)
4289 tnow = (tnow+tFreeze) * pow( rnd,
4290 1. / (alphaS2pi * overestimateInt) ) - tFreeze;
4292 else if (alphaSorder == 1)
4293 tnow = Lambda2 * pow( (tnow+tFreeze) / Lambda2,
4294 pow( rnd, b0 / overestimateInt) ) - tFreeze;
4298 tnow = Lambda2 * pow( (tnow+tFreeze) / Lambda2,
4299 pow(rndmPtr->flat(), b0 / overestimateInt) ) - tFreeze;
4300 tForAlphaS = renormMultFac * max( tnow+tFreeze,
4301 pow2(LAMBDA3MARGIN) * Lambda3flav2);
4302 }
while (alphaS.alphaS2OrdCorr(tForAlphaS) < rndmPtr->flat()
4315 bool DireTimes::zCollNextQCD( DireTimesEnd* dip,
double zMin,
double zMax,
4319 dip->xa = zMax * pow( zMax/zMin, -rndmPtr->flat());
4328 bool DireTimes::virtNextQCD( DireTimesEnd* dip,
double,
double,
4331 double v = rndmPtr->flat();
4332 double m2j = dip->mass[2];
4333 dip->sa1 = v / (1.-v) * ( dip->pT2*dip->xa/dip->z + m2j);
4342 bool DireTimes::branch(
Event& event,
bool ) {
4344 if (abs(dipSel->pT2 - pT2cutMin(dipSel)) < 1e-10)
return false;
4348 bool hasBranched =
false;
4349 if ( event[dipSel->iRecoiler].isFinal())
4350 hasBranched = branch_FF(event,
false, &splitInfoSel);
4351 else hasBranched = branch_FI(event,
false, &splitInfoSel);
4365 bool DireTimes::branch_FF(
Event& event,
bool trial,
4366 DireSplitInfo* split ) {
4368 Event auxevent1 = event;
4369 Event auxevent2 = event;
4372 bool physical =
true;
4373 bool canMergeFirst = (mergingHooksPtr != 0)
4374 ? mergingHooksPtr->canVetoEmission() :
false;
4377 int iRadBef = (!trial) ? dipSel->iRadiator : split->iRadBef;
4378 int iRecBef = (!trial) ? dipSel->iRecoiler : split->iRecBef;
4381 Vec4 pRadBef(event[iRadBef].p());
4382 Vec4 pRecBef(event[iRecBef].p());
4385 string name = (!trial) ? splittingSelName : split->splittingSelName;
4386 if (!trial) splits[name]->splitInfo.store(*split);
4388 unordered_map<string,double> psp(splits[name]->
4389 getPhasespaceVars(event, partonSystemsPtr));
4390 double pT2 = (!trial) ? dipSel->pT2 : split->kinematics()->pT2;
4391 double z = (!trial) ? dipSel->z : split->kinematics()->z ;
4393 if (split->useForBranching) { pT2 = psp[
"pT2"]; z = psp[
"z"]; }
4395 double m2Dip = (!trial) ? dipSel->m2Dip : split->kinematics()->m2Dip;
4397 double yCS = pT2/m2Dip / (1.-z);
4398 double zCS = ( 1. - z - pT2/m2Dip - pow2(1.-z) )
4399 / ( 1. - z - pT2/m2Dip);
4402 int flavour = (!trial) ? dipSel->flavour : split->emtAft()->id;
4404 int nEmissions = splits[name]->nEmissions();
4406 if ( nEmissions == 2 && !split->useForBranching) flavour = 21;
4409 int idRad =
event[iRadBef].id();
4410 int idEmt = abs(flavour);
4411 int colRad =
event[iRadBef].col();
4412 int acolRad =
event[iRadBef].acol();
4415 iSysSel = (!trial) ? dipSel->system : split->system;
4416 int iSysSelRec = (!trial) ? dipSel->systemRec : split->system;
4418 if (!trial && dipSel->colType > 0) colType = 2;
4419 if ( trial && idRad > 0) colType = 2;
4420 if (!trial && (dipSel->gamType == 1 || abs(dipSel->weakType) > 0)) colType=0;
4421 if ( trial && (idRad==22 || idRad==23 || idRad==24 || idRad==25)) colType=0;
4423 if ( split->useForBranching
4424 && (particleDataPtr->colType(split->emtAft()->id) == 0
4425 || (particleDataPtr->colType(split->emtAft2()->id) == 0
4426 && nEmissions == 2)))
4429 if (flavour == 22 || flavour == 23 || flavour == 25) ;
4432 else if (flavour == 21 && colType > 0) {
4434 colRad =
event.nextColTag();
4436 }
else if (flavour == 21) {
4438 acolRad =
event.nextColTag();
4441 }
else if (colType > 0) {
4442 idEmt = abs(flavour);
4446 }
else if (colType < 0) {
4447 idEmt = -abs(flavour);
4453 if (split->useForBranching) {
4454 idRad =
event[iRadBef].id();
4455 colRad =
event[iRadBef].col();
4456 acolRad =
event[iRadBef].acol();
4460 if (split->radAft()->id != 0) idRad = split->radAft()->id;
4461 if (split->emtAft()->id != 0) idEmt = split->emtAft()->id;
4462 if (split->radAft()->col > -1) colRad = split->radAft()->col;
4463 if (split->radAft()->acol > -1) acolRad = split->radAft()->acol;
4464 if (split->emtAft()->col > -1) colEmt = split->emtAft()->col;
4465 if (split->emtAft()->acol > -1) acolEmt = split->emtAft()->acol;
4467 if (nEmissions == 2) {
4468 if ( split->extras.find(
"idRadInt") != split->extras.end() )
4469 idRad =
int(split->extras[
"idRadInt"]);
4470 if ( split->extras.find(
"idEmtInt") != split->extras.end() )
4471 idEmt =
int(split->extras[
"idEmtInt"]);
4472 if ( split->extras.find(
"colRadInt") != split->extras.end() )
4473 colRad =
int(split->extras[
"colRadInt"]);
4474 if ( split->extras.find(
"acolRadInt") != split->extras.end() )
4475 acolRad =
int(split->extras[
"acolRadInt"]);
4476 if ( split->extras.find(
"colEmtInt") != split->extras.end() )
4477 colEmt =
int(split->extras[
"colEmtInt"]);
4478 if ( split->extras.find(
"acolEmtInt") != split->extras.end() )
4479 acolEmt =
int(split->extras[
"acolEmtInt"]);
4485 double m2Bef = particleDataPtr->isResonance(event[iRadBef].
id())
4486 ? getMass(event[iRadBef].
id(),3,event[iRadBef].mCalc())
4487 : (event[iRadBef].idAbs() < 6 || event[iRadBef].id() == 21
4488 || event[iRadBef].id() == 22)
4489 ? getMass(event[iRadBef].id(),2)
4490 : getMass(event[iRadBef].id(),1);
4492 double m2r = particleDataPtr->isResonance(idRad)
4493 && idRad ==
event[iRadBef].id()
4494 ? getMass(idRad,3,event[iRadBef].mCalc())
4495 : (abs(idRad) < 6 || idRad == 21 || idRad == 22)
4499 double m2s = particleDataPtr->isResonance(event[iRecBef].
id())
4500 ? getMass(event[iRecBef].
id(),3,event[iRecBef].mCalc())
4501 : (event[iRecBef].idAbs() < 6 || event[iRecBef].id() == 21
4502 || event[iRecBef].id() == 22)
4503 ? getMass(event[iRecBef].id(),2)
4504 : getMass(event[iRecBef].id(),1);
4506 double m2ex = (abs(idEmt) < 6 || idEmt == 21 || idEmt == 22)
4507 ? getMass(idEmt,2) : getMass(idEmt,1);
4508 double m2e = (!trial) ? m2ex
4509 : ( (split->kinematics()->m2EmtAft > 0.) ? split->kinematics()->m2EmtAft
4511 if (split->useForBranching) {
4512 m2r = split->kinematics()->m2RadAft;
4513 m2e = split->kinematics()->m2EmtAft;
4517 double Q2 = m2Dip + m2Bef - m2r - m2e;
4519 if (trial) Q2 = m2Dip;
4522 double kappa2 = pT2/Q2;
4523 yCS = kappa2 / (1.-z);
4524 zCS = ( 1. - z - kappa2 - pow2(1.-z) ) / ( 1. - z - kappa2);
4527 double sai = (!trial) ? dipSel->sa1 : split->kinematics()->sai;
4528 double xa = (!trial) ? dipSel->xa : split->kinematics()->xa;
4530 if (split->useForBranching) { sai = psp[
"sai"]; xa = psp[
"xa"]; }
4533 double phi_kt = (!trial)
4534 ? ((dipSel->phi >= 0.) ? dipSel->phi
4535 : 2.*M_PI*rndmPtr->flat())
4536 : ((split->kinematics()->phi >= 0.) ? split->kinematics()->phi
4537 : 2.*M_PI*rndmPtr->flat());
4539 double phi_kt1 = phi_kt+2./3.*M_PI;
4540 if (phi_kt1>2.*M_PI) phi_kt1 -= 2.*M_PI;
4541 double phi_kt2 = phi_kt-2./3.*M_PI;
4542 if (phi_kt2<0.) phi_kt2 += 2.*M_PI;
4543 if (phi_kt1<phi_kt2) swap(phi_kt1, phi_kt2);
4547 if (nEmissions == 2)
4549 ? ((dipSel->phia1 >= 0.) ? dipSel->phia1
4550 : 2.*M_PI*rndmPtr->flat())
4551 : ((split->kinematics()->phi2 >= 0.) ? split->kinematics()->phi2
4552 : 2.*M_PI*rndmPtr->flat());
4555 if (split->useForBranching) { phi_kt = psp[
"phi"]; phiX = psp[
"phi2"]; }
4557 Vec4 pRad, pEmt, pRec;
4558 Vec4 auxpRad1, auxpEmt1;
4559 Vec4 auxpRad2, auxpEmt2;
4561 Vec4 q(pRadBef + pRecBef);
4562 double q2 = q.m2Calc();
4565 double m2a(0.), m2i(0.), m2j(0.), m2ai(0.), m2k(0.), m2aij(0.);
4566 if (nEmissions == 2) {
4567 m2a = getMass((!trial) ? dipSel->flavour : split->emtAft()->id,2);
4568 m2i = getMass((!trial) ? dipSel->flavour : split->emtAft()->id,2);
4571 if (split->useForBranching) {
4572 m2a = split->kinematics()->m2RadAft;
4573 m2i = split->kinematics()->m2EmtAft;
4574 m2j = split->kinematics()->m2EmtAft2;
4577 m2ai = sai + m2a + m2i;
4578 Q2 = m2Dip + m2aij + m2k - m2ai - m2j - m2k;
4579 yCS = pT2/(q2 - m2ai - m2j - m2k) * xa / z;
4580 zCS = z / (xa*(1-yCS)) * (q2 - m2aij - m2k) / (q2 - m2ai - m2j - m2k);
4583 if (split->useForBranching) {
4584 m2Emt = split->kinematics()->m2EmtAft;
4585 m2Rad = sai + m2a + m2j;
4586 m2ai = sai + m2a + m2j;
4591 double sij = yCS * (q2 - m2s) + (1.-yCS)*(m2Rad+m2Emt);
4593 double zbar = (q2-sij-m2s) / bABC(q2,sij,m2s)
4594 * (zCS - m2s/gABC(q2,sij,m2s)
4595 *(sij + m2Rad - m2Emt)/(q2-sij-m2s));
4596 double kT2 = zbar*(1.-zbar)*sij - (1.-zbar)*m2Rad - zbar*m2Emt;
4600 infoPtr->errorMsg(
"Warning in DireTimes::branch_FF: Reject state "
4601 "with kinematically forbidden kT^2.");
4607 if (kT2!=kT2 || abs(kT2-kT2) > 1e5) {
4608 infoPtr->errorMsg(
"Warning in DireTimes::branch_FF: Reject state "
4609 "with not-a-number kT^2 for branching " + name);
4614 pRec.p( (pRecBef - (q*pRecBef)/q2 * q)
4615 * sqrt(lABC(q2,sij,m2s)/lABC(q2,m2Bef,m2s))
4616 + q * (q2+m2s-sij)/(2.*q2) );
4622 pair<Vec4, Vec4> pTvecs = getTwoPerpendicular(pRec, pij);
4623 Vec4 kTmom( sqrt(kT2)*sin(phi_kt)*pTvecs.first
4624 + sqrt(kT2)*cos(phi_kt)*pTvecs.second);
4627 pRad.p( zbar * (gABC(q2,sij,m2s)*pij - sij*pRec) / bABC(q2,sij,m2s)
4628 + (m2Rad+kT2) / (zbar*bABC(q2,sij,m2s))
4629 * (pRec - m2s/gABC(q2,sij,m2s)*pij)
4633 pEmt.p(q-pRad-pRec);
4635 kTmom.p( sqrt(kT2)*sin(phi_kt1)*pTvecs.first
4636 + sqrt(kT2)*cos(phi_kt1)*pTvecs.second);
4637 auxpRad1.p( zbar * (gABC(q2,sij,m2s)*pij - sij*pRec) / bABC(q2,sij,m2s)
4638 + (m2Rad+kT2) / (zbar*bABC(q2,sij,m2s))
4639 * (pRec - m2s/gABC(q2,sij,m2s)*pij)
4641 auxpEmt1.p(q-auxpRad1-pRec);
4643 kTmom.p( sqrt(kT2)*sin(phi_kt2)*pTvecs.first
4644 + sqrt(kT2)*cos(phi_kt2)*pTvecs.second);
4645 auxpRad2.p( zbar * (gABC(q2,sij,m2s)*pij - sij*pRec) / bABC(q2,sij,m2s)
4646 + (m2Rad+kT2) / (zbar*bABC(q2,sij,m2s))
4647 * (pRec - m2s/gABC(q2,sij,m2s)*pij)
4649 auxpEmt2.p(q-auxpRad2-pRec);
4652 double errMass = abs(pRad.mCalc() - sqrt(m2Rad)) / max( 1.0, pRad.e());
4653 if ( errMass > mTolErr*1e-2 ) {
4654 double deltam2 = pRad.m2Calc() - m2Rad;
4655 pRad.e(sqrtpos(pow2(pRad.e()) - deltam2));
4658 errMass = abs(pEmt.mCalc() - sqrt(m2Emt)) / max( 1.0, pEmt.e());
4659 if ( errMass > mTolErr*1e-2 ) {
4660 double deltam2 = pEmt.m2Calc() - m2Emt;
4661 pEmt.e(sqrtpos(pow2(pEmt.e()) - deltam2));
4664 errMass = abs(pRec.mCalc() - sqrt(m2s)) / max( 1.0, pRec.e());
4665 if ( errMass > mTolErr*1e-2 ) {
4666 double deltam2 = pRec.m2Calc() - m2s;
4667 pRec.e(sqrtpos(pow2(pRec.e()) - deltam2));
4672 if ( nEmissions == 2 && !split->useForBranching) {
4674 swap(colRad,colEmt);
4675 swap(acolRad,acolEmt);
4679 if ( nEmissions == 2 && split->useForBranching
4680 && particleDataPtr->colType(split->emtAft()->id) == 0)
4681 { colRad =
event[iRadBef].col(); acolRad =
event[iRadBef].acol(); }
4684 double pTsel = sqrt(pT2);
4685 Particle rad = Particle(idRad, 51, iRadBef, 0, 0, 0,
4686 colRad, acolRad, pRad, sqrt(m2Rad), pTsel);
4687 Particle auxrad1 = Particle(idRad, 51, iRadBef, 0, 0, 0,
4688 colRad, acolRad, auxpRad1, sqrt(m2Rad), pTsel);
4689 Particle auxrad2 = Particle(idRad, 51, iRadBef, 0, 0, 0,
4690 colRad, acolRad, auxpRad2, sqrt(m2Rad), pTsel);
4693 if ( nEmissions == 2) rad.status(59);
4695 Particle emt = Particle(idEmt, 51, iRadBef, 0, 0, 0,
4696 colEmt, acolEmt, pEmt, sqrt(m2Emt), pTsel);
4697 Particle auxemt1 = Particle(idEmt, 51, iRadBef, 0, 0, 0,
4698 colEmt, acolEmt, auxpEmt1, sqrt(m2Emt), pTsel);
4699 Particle auxemt2 = Particle(idEmt, 51, iRadBef, 0, 0, 0,
4700 colEmt, acolEmt, auxpEmt2, sqrt(m2Emt), pTsel);
4703 if ( nEmissions == 2 && split->useForBranching ) {
4704 if ( split->extras.find(
"colRadInt") != split->extras.end() )
4705 rad.col(
int(split->extras[
"colRadInt"]));
4706 if ( split->extras.find(
"acolRadInt") != split->extras.end() )
4707 rad.acol(
int(split->extras[
"acolRadInt"]));
4708 if ( split->extras.find(
"colEmtInt") != split->extras.end() )
4709 emt.col(
int(split->extras[
"colEmtInt"]));
4710 if ( split->extras.find(
"acolEmtInt") != split->extras.end() )
4711 emt.acol(
int(split->extras[
"acolEmtInt"]));
4714 Particle rec = Particle(event[iRecBef].
id(), 52, iRecBef, iRecBef, 0, 0,
4715 event[iRecBef].col(), event[iRecBef].acol(), pRec, sqrt(m2s), pTsel);
4719 if (emt.idAbs() == 23 || emt.idAbs() == 24) {
4722 event[iRadBef].pol(dipSel->weakPol);
4723 rad.pol(dipSel->weakPol);
4728 int evSizeOld =
event.size();
4729 int iRadStatusV =
event[iRadBef].status();
4730 int iRadDau1V =
event[iRadBef].daughter1();
4731 int iRadDau2V =
event[iRadBef].daughter2();
4732 int iRecStatusV =
event[iRecBef].status();
4733 int iRecDau1V =
event[iRecBef].daughter1();
4734 int iRecDau2V =
event[iRecBef].daughter2();
4737 if (event[iRadBef].hasVertex()) {
4738 rad.vProd( event[iRadBef].vProd() );
4739 emt.vProd( event[iRadBef].vProd() );
4741 if (event[iRecBef].hasVertex()) rec.vProd( event[iRecBef].vProd() );
4745 int iRad(event.append(rad));
4746 int iEmt(event.append(emt));
4748 event[iRadBef].statusNeg();
4749 event[iRadBef].daughters( iRad, iEmt);
4750 int iRec(event.append(rec));
4751 event[iRecBef].statusNeg();
4752 event[iRecBef].daughters( iRec, iRec);
4754 int auxiRad1(auxevent1.append(auxrad1));
4755 int auxiEmt1(auxevent1.append(auxemt1));
4756 auxevent1[iRadBef].statusNeg();
4757 auxevent1[iRadBef].daughters( auxiRad1, auxiEmt1);
4758 int auxiRec1(auxevent1.append(rec));
4759 auxevent1[iRecBef].statusNeg();
4760 auxevent1[iRecBef].daughters( auxiRec1, auxiRec1);
4762 int auxiRad2(auxevent2.append(auxrad2));
4763 int auxiEmt2(auxevent2.append(auxemt2));
4764 auxevent2[iRadBef].statusNeg();
4765 auxevent2[iRadBef].daughters( auxiRad2, auxiEmt2);
4766 int auxiRec2(auxevent2.append(rec));
4767 auxevent2[iRecBef].statusNeg();
4768 auxevent2[iRecBef].daughters( auxiRec2, auxiRec2);
4770 if ( nEmissions == 2 && !split->useForBranching) swap(iRad,iEmt);
4773 int flavourNow = (!trial) ? dipSel->flavour : split->emtAft()->id;
4776 bool inResonance = (partonSystemsPtr->getInA(iSysSel) == 0) ?
true :
false;
4777 bool doVeto =
false;
4778 if (nEmissions != 2)
4779 doVeto = (( canVetoEmission && userHooksPtr->doVetoFSREmission(
4780 evSizeOld,event,iSysSel,inResonance) )
4781 || ( canMergeFirst && mergingHooksPtr->doVetoEmission(
4783 bool doMECreject =
false;
4785 if ( nEmissions != 2) {
4788 if ( !validMomentum( rad.p(), idRad, 1)
4789 || !validMomentum( emt.p(), idEmt, 1)
4790 || !validMomentum( rec.p(),
event[iRecBef].id(), 1))
4794 bool isHardSystem = partonSystemsPtr->getSystemOf(iRadBef,
true) == 0
4795 && partonSystemsPtr->getSystemOf(iRecBef,
true) == 0;
4799 bool sys = partonSystemsPtr->getSystemOf(iRadBef,
true);
4800 int sizeSys = partonSystemsPtr->sizeSys();
4801 int in1 = partonSystemsPtr->getInA(sys);
4802 int in2 = partonSystemsPtr->getInB(sys);
4803 if ( in1 == 0 && in2 == 0 ) {
4804 int iParentInOther = 0;
4805 int nSys = partonSystemsPtr->sizeAll(sys);
4806 for (
int iInSys = 0; iInSys < nSys; ++iInSys){
4807 int iNow = partonSystemsPtr->getAll(sys,iInSys);
4808 for (
int iOtherSys = 0; iOtherSys < sizeSys; ++iOtherSys){
4809 if (iOtherSys == sys)
continue;
4810 int nOtherSys = partonSystemsPtr->sizeAll(iOtherSys);
4811 for (
int iInOtherSys = 0; iInOtherSys < nOtherSys; ++iInOtherSys){
4812 int iOtherNow = partonSystemsPtr->getAll(iOtherSys,iInOtherSys);
4813 if (event[iNow].isAncestor(iOtherNow)) {
4814 iParentInOther = iOtherNow;
4819 if (iParentInOther) isHardSystem =
true;
4822 if ( isHardSystem && physical && doMEcorrections
4824 && pT2 > pT2minMECs && checkSIJ(event,Q2minMECs)) {
4827 partonSystemsPtr->replace(iSysSel, iRadBef, iRad);
4828 partonSystemsPtr->addOut(iSysSel, iEmt);
4829 partonSystemsPtr->replace(iSysSelRec, iRecBef, iRec);
4831 if ( nFinalMaxMECs < 0
4832 || nFinalMaxMECs > partonSystemsPtr->sizeOut(iSysSel))
4833 doMECreject = applyMEC (event, split,
4834 createvector<Event>(auxevent1)(auxevent2));
4836 partonSystemsPtr->replace(iSysSel, iRad, iRadBef);
4837 partonSystemsPtr->replace(iSysSelRec, iRec, iRecBef);
4838 partonSystemsPtr->popBackOut(iSysSel);
4842 if (physical && !doVeto && !trial && !doMECreject) updateAfterFF( iSysSel,
4843 iSysSelRec, event, iRadBef, iRecBef, iRad, iEmt, iRec, flavour, colType,
4850 if ( !validMomentum( emt.p(), idEmt, 1)
4851 || !validMomentum( rec.p(),
event[iRecBef].id(), 1))
4854 int iRadOld = int(event.size())-3;
4855 int iEmtOld = int(event.size())-2;
4856 int iRecOld = int(event.size())-1;
4859 swap(iRadOld,iEmtOld);
4861 if (!split->useForBranching) {
4863 idEmt = -flavourNow;
4868 acolEmt =
event[iEmtOld].acol();
4869 colRad =
event[iEmtOld].col();
4872 colEmt =
event[iEmtOld].col();
4875 acolRad =
event[iEmtOld].acol();
4879 idRad = split->radAft()->id;
4880 idEmt = split->emtAft2()->id;
4881 colRad = split->radAft()->col;
4882 acolRad = split->radAft()->acol;
4883 colEmt = split->emtAft2()->col;
4884 acolEmt = split->emtAft2()->acol;
4886 if (
int(split->extras[
"swapped"]) == 1) {
4887 idRad = split->emtAft()->id;
4888 idEmt = split->emtAft2()->id;
4889 colRad = split->emtAft()->col;
4890 acolRad = split->emtAft()->acol;
4891 colEmt = split->emtAft2()->col;
4892 acolEmt = split->emtAft2()->acol;
4900 m2r = particleDataPtr->isResonance(idRad)
4901 && idRad ==
event[iRadBef].id()
4902 ? getMass(idRad,3,event[iRadBef].mCalc())
4903 : (abs(idRad) < 6 || idRad == 21 || idRad == 22)
4907 m2s = particleDataPtr->isResonance(event[iRecBef].
id())
4908 ? getMass(event[iRecBef].
id(),3,event[iRecBef].mCalc())
4909 : (event[iRecBef].idAbs() < 6 || event[iRecBef].id() == 21
4910 || event[iRecBef].id() == 22)
4911 ? getMass(event[iRecBef].id(),2)
4912 : getMass(event[iRecBef].id(),1);
4914 m2e = (abs(idEmt) < 6 || idEmt == 21 || idEmt == 22)
4915 ? getMass(idEmt,2) : getMass(idEmt,1);
4917 if (split->useForBranching) {
4918 m2r = split->kinematics()->m2RadAft;
4919 m2e = split->kinematics()->m2EmtAft2;
4923 Vec4 pa1(event[iEmtOld].p());
4930 if (split->useForBranching) {
4931 m2Rad = split->kinematics()->m2RadAft;
4932 m2Emt = split->kinematics()->m2EmtAft2;
4935 yCS = (m2ai-m2Emt-m2Rad) / (m2ai-m2Emt-m2Rad + 2.*pa1*pRec);
4938 sij = yCS * (q2 - m2s) + (1.-yCS)*(m2Rad+m2Emt);
4939 zbar = (q2-sij-m2s) / bABC(q2,sij,m2s)
4940 * (zCS - m2s/gABC(q2,sij,m2s)
4941 *(sij + m2Rad - m2Emt)/(q2-sij-m2s));
4942 kT2 = zbar*(1.-zbar)*sij - (1.-zbar)*m2Rad - zbar*m2Emt;
4944 if(kT2 < 0.) physical =
false;
4950 pTvecs = getTwoPerpendicular(pRec, pij);
4951 kTmom.p( sqrt(kT2)*sin(phiX)*pTvecs.first
4952 + sqrt(kT2)*cos(phiX)*pTvecs.second);
4955 pRad.p( zbar * (gABC(q2,sij,m2s)*pij - sij*pRec) / bABC(q2,sij,m2s)
4956 + (m2Rad+kT2) / (zbar*bABC(q2,sij,m2s))
4957 * (pRec - m2s/gABC(q2,sij,m2s)*pij)
4961 pEmt.p(q-pRad-pRec);
4964 pRec.p(event[iRecOld].p());
4967 Particle rad2 = Particle(idRad, 51, iEmtOld, 0, 0, 0,
4968 colRad, acolRad, pRad, sqrt(m2r), pTsel);
4969 Particle emt2 = Particle(idEmt, 51, iEmtOld, 0, 0, 0,
4970 colEmt, acolEmt, pEmt, sqrt(m2e), pTsel);
4971 Particle rec2 = Particle(event[iRecOld].
id(), 52, iRecOld, iRecOld, 0, 0,
4972 event[iRecOld].col(), event[iRecOld].acol(), pRec, sqrt(m2s), pTsel);
4975 if ( !validMomentum( rad2.p(), idRad, 1)
4976 || !validMomentum( emt2.p(), idEmt, 1)
4977 || !validMomentum( rec2.p(),
event[iRecOld].id(), 1) )
4982 Vec4 pa(pRad), pk(pRec), pj(emt.p()), pi(pEmt);
4983 double saix(2.*pa*pi), sakx(2.*pa*pk), sajx(2.*pa*pj), sikx(2.*pi*pk),
4984 sjkx(2.*pj*pk), sijx(2.*pi*pj);
4985 double pptt = (sajx+sijx)*(sakx+sikx)
4986 / ( (
event[iRadBef].p()+
event[iRecBef].p()).m2Calc()
4987 -
event[iRadBef].m2Calc() -
event[iRecBef].m2Calc() );
4988 double ssaaii = saix;
4990 / ( (
event[iRadBef].p()+
event[iRecBef].p()).m2Calc()
4991 -
event[iRadBef].m2Calc() -
event[iRecBef].m2Calc() );
4992 double xxaa = sakx / ( sakx + sikx );
4994 (abs(pptt-pT2) > 1e-5 || abs(ssaaii-sai) > 1e-5 ||
4995 abs(zzaa-z) > 1e-5 || abs(xxaa-xa) > 1e-5) ){
4996 cout << scientific << setprecision(8);
4997 cout <<
"Error in branch_FF: Invariant masses after branching do not "
4998 <<
"match chosen values." << endl;
5000 <<
" Q2 " << (
event[iRadBef].p()+
event[iRecBef].p()).m2Calc()
5004 <<
" xa " << xa << endl;
5005 cout <<
"Generated: "
5006 <<
" Q2 " << sakx+saix+sajx+sijx+sikx+sjkx
5008 <<
" sai " << ssaaii
5010 <<
" xa " << xxaa << endl;
5020 updateAfterFF( iSysSel, iSysSelRec, event,
5021 iRadBef, iRecBef, iRad, iEmt, iRec, flavour, colType, pTsel);
5024 if (event[iEmtOld].hasVertex()) {
5025 rad2.vProd( event[iEmtOld].vProd() );
5026 emt2.vProd( event[iEmtOld].vProd() );
5028 if (event[iRecOld].hasVertex()) rec2.vProd( event[iRecOld].vProd() );
5033 iRad =
event.append(rad2);
5034 iEmt =
event.append(emt2);
5035 event[iEmtOld].statusNeg();
5036 event[iEmtOld].daughters( iRad, iEmt);
5037 iRec =
event.append(rec2);
5038 event[iRecOld].statusNeg();
5039 event[iRecOld].daughters( iRec, iRec);
5043 int colTypeNow = colType;
5044 updateAfterFF( iSysSel, iSysSelRec, event, iEmtOld, iRecOld, iRad,
5045 iEmt,iRec, flavourNow, colTypeNow, pTsel);
5050 physical = physical && !doVeto;
5052 if ( physical && !trial && !doMECreject
5053 && !validMotherDaughter(event)) {
5054 infoPtr->errorMsg(
"Error in DireTimes::branch_FF: Mother-daughter "
5055 "relations after branching not valid.");
5060 if ( !physical || doMECreject ) {
5061 event.popBack( event.size() - evSizeOld);
5062 event[iRadBef].status( iRadStatusV);
5063 event[iRadBef].daughters( iRadDau1V, iRadDau2V);
5064 event[iRecBef].status( iRecStatusV);
5065 event[iRecBef].daughters( iRecDau1V, iRecDau2V);
5072 for ( unordered_map<
string, multimap<double,double> >::iterator
5073 it = rejectProbability.begin(); it != rejectProbability.end(); ++it){
5074 weights->eraseAcceptWeight(pT2, it->first);
5075 weights->eraseRejectWeight(pT2, it->first);
5079 if (!trial && doMECreject) {
5080 weights->calcWeight(pT2,
false,
true);
5083 for ( unordered_map<
string, multimap<double,double> >::iterator
5084 it = rejectProbability.begin(); it != rejectProbability.end(); ++it )
5086 for ( unordered_map<
string, map<double,double> >::iterator
5087 it = acceptProbability.begin(); it != acceptProbability.end(); ++it )
5095 if (trial && !split->useForBranching) split->storePosAfter(iRad, iRec, iEmt,
5096 (nEmissions < 2) ? 0 : iEmt2);
5097 if (trial && split->useForBranching) split->storePosAfter(iRad, iRec, iEmt2,
5098 (nEmissions < 2) ? 0 : iEmt);
5103 weights->calcWeight(pT2);
5106 if (nEmissions == 1) {
5107 direInfoPtr->updateSoftPos( iRadBef, iEmt );
5108 direInfoPtr->updateSoftPosIfMatch( iRecBef, iRec );
5111 direInfoPtr->updateSoftPos( iRadBef, iRad );
5114 updateDipoles(event, iSysSel);
5118 for ( unordered_map<
string, multimap<double,double> >::iterator
5119 it = rejectProbability.begin(); it != rejectProbability.end(); ++it )
5121 for ( unordered_map<
string, map<double,double> >::iterator
5122 it = acceptProbability.begin(); it != acceptProbability.end(); ++it )
5133 void DireTimes::updateAfterFF(
int iSysSelNow,
int iSysSelRec,
5134 Event& event,
int iRadBef,
int iRecBef,
int iRad,
int iEmt,
int iRec,
5135 int,
int colType,
double pTsel) {
5137 vector<int> iDipEndCorr, iDipEndRem;
5138 bool inResonance = (partonSystemsPtr->getInA(iSysSelNow)==0) ?
true :
false;
5139 int idEmt =
event[iEmt].id();
5140 bool hasDipSel = (dipSel != 0);
5143 if (particleDataPtr->colType(idEmt) == 2) {
5146 dipSel->iRadiator = iRad;
5147 dipSel->iRecoiler = iEmt;
5148 dipSel->systemRec = iSysSelNow;
5149 dipSel->isrType = 0;
5150 dipSel->pTmax = pTsel;
5154 for (
int i = 0; i < int(dipEnd.size()); ++i) {
5155 DireTimesEnd& dip = dipEnd[i];
5156 if (dip.iRadiator == iRecBef && dip.iRecoiler == iRadBef
5157 && dip.colType != 0) {
5158 dip.iRadiator = iRec;
5159 dip.iRecoiler = iEmt;
5162 if ( dip.colType * colType > 0) dip.iRecoiler = iRad;
5164 iDipEndCorr.push_back(i);
5168 int colTypeNow = (colType > 0) ? 2 : -2 ;
5172 if (recoilToColoured && inResonance && event[iRec].col() == 0
5173 &&
event[iRec].acol() == 0) iRecMod = iRad;
5174 if (appendDipole( event, iEmt, iRecMod, pTsel, colTypeNow, 0, 0, 0, 0,
5175 iSysSelNow, 0, -1, 0,
false, dipEnd)) {
5176 iDipEndCorr.push_back(dipEnd.size()-1);
5178 DireTimesEnd& dip1 = dipEnd.back();
5179 dip1.systemRec = iSysSelRec;
5182 if (appendDipole( event, iEmt, iRad, pTsel,-colTypeNow, 0, 0, 0, 0,
5183 iSysSelNow, 0, -1, 0,
false, dipEnd)) {
5184 iDipEndCorr.push_back(dipEnd.size()-1);
5188 }
else if (particleDataPtr->colType(idEmt) != 0) {
5191 if ( splittingsPtr->nEmissions(splittingSelName) == 2 ){
5192 for (
int i = 0; i < int(dipEnd.size()); ++i) {
5194 DireTimesEnd& dip = dipEnd[i];
5196 if ( dip.iRadiator == iRecBef ) {
5197 dip.iRadiator = iRec;
5199 if ( dip.iRecoiler == iRecBef ) {
5200 dip.iRecoiler = iRec;
5203 if ( dip.iRadiator == iRadBef ) {
5204 if (dip.colType > 0)
5205 dip.iRadiator = (
event[iEmt].id() > 0) ? iEmt : iRad;
5206 if (dip.colType < 0)
5207 dip.iRadiator = (
event[iEmt].id() < 0) ? iEmt : iRad;
5209 if (abs(dip.colType) == 2
5210 &&
event[dip.iRadiator].id() > 0
5211 &&
event[dip.iRadiator].idAbs() < 10)
5212 dip.colType = abs(dip.colType)/2;
5213 if (abs(dip.colType) == 2
5214 &&
event[dip.iRadiator].id() < 0
5215 &&
event[dip.iRadiator].idAbs() < 10)
5216 dip.colType = -abs(dip.colType)/2;
5218 iDipEndCorr.push_back(i);
5221 if ( dip.iRecoiler == iRadBef ) {
5222 if (dip.colType > 0)
5223 dip.iRecoiler = (
event[iEmt].id() < 0) ? iEmt : iRad;
5224 if (dip.colType < 0)
5225 dip.iRecoiler = (
event[iEmt].id() > 0) ? iEmt : iRad;
5227 if (abs(dip.colType) == 2) dipEnd[i].colType /= 2;
5229 if (abs(dip.colType) == 1
5230 &&
event[dip.iRadiator].id() > 0
5231 &&
event[dip.iRadiator].idAbs() < 10)
5234 if (abs(dip.colType) == 1
5235 &&
event[dip.iRadiator].id() < 0
5236 &&
event[dip.iRadiator].idAbs() < 10)
5239 iDipEndCorr.push_back(i);
5244 for (
int i = 0; i < int(dipEnd.size()); ++i) {
5246 if ( find(iDipEndCorr.begin(), iDipEndCorr.end(), i)
5247 != iDipEndCorr.end() )
continue;
5248 DireTimesEnd& dip = dipEnd[i];
5250 if ( dip.iRecoiler == iRadBef && dip.colType * colType < 0 ) {
5251 dip.iRecoiler = iEmt;
5253 if (dip.iRadiator == iRadBef && abs(dip.colType) == 2) {
5256 if (hasDipSel && &dipEnd[i] == dipSel) dip.iRadiator = iEmt;
5257 else dip.iRadiator = iRad;
5258 if (hasDipSel && &dipEnd[i] == dipSel) dip.iRecoiler = iRec;
5260 dip.colType = (
event[dip.iRadiator].id() > 0)
5261 ? abs(dip.colType) : -abs(dip.colType);
5263 iDipEndCorr.push_back(i);
5265 if (dip.system != dip.systemRec)
continue;
5267 if (hasDipSel && &dipEnd[i] == dipSel) dip.iMEpartner = iRad;
5268 else dip.iMEpartner = iEmt;
5274 bool updateSel=
true;
5275 for (
int j = 0; j < int(iDipEndCorr.size()); ++j)
5276 if ( hasDipSel && &dipEnd[iDipEndCorr[j]] == dipSel) updateSel =
false;
5280 dipSel->iRadiator = iEmt;
5281 dipSel->iRecoiler = iRec;
5284 dipSel->pTmax = pTsel;
5289 int iRadOld = (hasDipSel) ? dipSel->iRadiator : iRadBef;
5290 int iRecOld = (hasDipSel) ? dipSel->iRecoiler : iRecBef;
5292 for (
int i = 0; i < int(dipEnd.size()); ++i) {
5293 DireTimesEnd& dip = dipEnd[i];
5295 if ( dip.iRecoiler == iRecOld && dip.iRadiator == iRadOld ) {
5296 dip.iRadiator = iRad;
5297 dip.iRecoiler = iRec;
5299 iDipEndCorr.push_back(i);
5302 if ( dip.iRecoiler == iRadOld && dip.iRadiator == iRecOld ) {
5303 dip.iRadiator = iRec;
5304 dip.iRecoiler = iRad;
5306 iDipEndCorr.push_back(i);
5312 for (
int i = 0; i < int(dipEnd.size()); ++i) {
5314 if ( find(iDipEndCorr.begin(), iDipEndCorr.end(), i)
5315 != iDipEndCorr.end() )
continue;
5316 DireTimesEnd& dip = dipEnd[i];
5317 if (dip.iRadiator == iRadBef) dip.iRadiator = iRad;
5318 if (dip.iRecoiler == iRadBef) dip.iRecoiler = iRad;
5319 if (dip.iMEpartner == iRadBef) dip.iMEpartner = iRad;
5320 if (dip.iRadiator == iRecBef) dip.iRadiator = iRec;
5321 if (dip.iRecoiler == iRecBef) dip.iRecoiler = iRec;
5322 if (dip.iMEpartner == iRecBef) dip.iMEpartner = iRec;
5327 vector<pair<int, int> > rad_rec (createvector< pair<int,int> >
5328 (make_pair(iRad,iEmt))
5329 (make_pair(iEmt,iRec))
5330 (make_pair(iRec,iEmt))
5331 (make_pair(iEmt,iRad))
5332 (make_pair(iRad,iRec))
5333 (make_pair(iRec,iRad)));
5334 for (
int i=0; i < int(rad_rec.size()); ++i) {
5335 int iRadNow = rad_rec[i].first;
5336 int iRecNow = rad_rec[i].second;
5340 for (
int j = 0; j < int(dipEnd.size()); ++j)
5341 if ( dipEnd[j].iRadiator == iRadNow
5342 && dipEnd[j].iRecoiler == iRecNow )
5346 if (
int(iDip.size()) > 0)
for (
int j = 0; j < int(iDip.size()); ++j)
5347 updateAllowedEmissions(event, &dipEnd[iDip[j]]);
5349 else appendDipole( event, iRadNow, iRecNow, pTsel, 0, 0, 0, 0, 0,
5350 iSysSelNow, -1, -1, 0,
false, dipEnd);
5354 if (event[iRad].
id() == event[iRadBef].
id())
5355 event[iRad].tau( event[iRadBef].tau() );
5357 event[iRad].tau( event[iRad].tau0() * rndmPtr->exp() );
5358 event[iEmt].tau( event[iEmt].tau0() * rndmPtr->exp() );
5360 event[iRec].tau( event[iRecBef].tau() );
5363 partonSystemsPtr->replace(iSysSelNow, iRadBef, iRad);
5364 partonSystemsPtr->addOut(iSysSelNow, iEmt);
5365 partonSystemsPtr->replace(iSysSelRec, iRecBef, iRec);
5368 for (
int i = 0; i < partonSystemsPtr->sizeOut(iSysSelNow); ++i) {
5369 int iNow = partonSystemsPtr->getOut( iSysSelNow, i);
5370 if (event[iNow].isFinal() && event[iNow].scale() > 0.) {
5372 int colTag =
event[iNow].col();
5373 if (doQCDshower && colTag > 0) setupQCDdip( iSysSelNow, i, colTag, 1,
5374 event,
false,
true);
5376 int acolTag =
event[iNow].acol();
5377 if (doQCDshower && acolTag > 0) setupQCDdip( iSysSelNow, i, acolTag, -1,
5378 event,
false,
true);
5380 getGenDip( iSysSelNow, i, iNow, event,
false, dipEnd);
5383 if (doDecaysAsShower && event[iNow].isResonance())
5384 setupDecayDip( iSysSelNow, iNow, event, dipEnd);
5388 sort (iDipEndRem.begin(), iDipEndRem.end());
5389 for (
int i = iDipEndRem.size()-1; i >= 0; --i) {
5390 dipEnd[iDipEndRem[i]] = dipEnd.back();
5396 updateDipoles(event, iSysSelNow);
5399 if ( direInfoPtr->isRes(iRadBef) &&
5400 event[iRadBef].id() !=
event[iRad].id() )
5401 direInfoPtr->removeResPos(iRadBef);
5402 if ( particleDataPtr->isResonance(event[iRad].id()) ) {
5403 if ( direInfoPtr->isRes(iRadBef) )
5404 direInfoPtr->updateResPos(iRadBef,iRad);
5407 if ( direInfoPtr->isRes(iRecBef) )
5408 direInfoPtr->updateResPos(iRecBef,iRec);
5409 if ( particleDataPtr->isResonance(event[iEmt].id()) )
5410 direInfoPtr->addResPos(iEmt);
5413 for (
int i=0; i <
event.size(); ++i)
if (event[i].isFinal()) nFinal++;
5415 int col = (colType> 0) ? event[iRadBef].col() :
event[iRadBef].acol();
5416 vector<int>::iterator iRem =
5417 find(bornColors.begin(), bornColors.end(), col);
5418 if (iRem != bornColors.end()) bornColors.erase(iRem++);
5431 bool DireTimes::branch_FI(
Event& event,
bool trial,
5432 DireSplitInfo* split ) {
5434 Event auxevent1 = event;
5435 Event auxevent2 = event;
5438 bool physical =
true;
5439 bool canMergeFirst = (mergingHooksPtr != 0)
5440 ? mergingHooksPtr->canVetoEmission() :
false;
5443 int iRadBef = (!trial) ? dipSel->iRadiator : split->iRadBef;
5444 int iRecBef = (!trial) ? dipSel->iRecoiler : split->iRecBef;
5445 int isrType =
event[iRecBef].mother1();
5448 Vec4 pRadBef =
event[iRadBef].p();
5449 Vec4 pRecBef =
event[iRecBef].p();
5452 string name = (!trial) ? splittingSelName : split->splittingSelName;
5453 double pT2 = (!trial) ? dipSel->pT2 : split->kinematics()->pT2;
5454 double z = (!trial) ? dipSel->z : split->kinematics()->z;
5455 splits[name]->splitInfo.store(*split);
5456 unordered_map<string,double> psp(splits[name]->
5457 getPhasespaceVars(event, partonSystemsPtr));
5459 if (split->useForBranching) { pT2 = psp[
"pT2"]; z = psp[
"z"]; }
5460 double m2Dip = (!trial) ? dipSel->m2Dip : split->kinematics()->m2Dip;
5463 double kappa2 = pT2/m2Dip;
5465 double xCS = 1 - kappa2/(1.-z);
5468 int flavour = (!trial) ? dipSel->flavour : split->emtAft()->id;
5470 int flavourSave = flavour;
5472 int nEmissions = splits[name]->nEmissions();
5474 if ( nEmissions == 2 && !split->useForBranching) flavour = 21;
5477 int idRad =
event[iRadBef].id();
5478 int idEmt = abs(flavour);
5479 int colRad =
event[iRadBef].col();
5480 int acolRad =
event[iRadBef].acol();
5483 iSysSel = (!trial) ? dipSel->system : split->system;
5484 int iSysSelRec = (!trial) ? dipSel->systemRec : split->system;
5487 if (!trial && dipSel->colType > 0) colType = 2;
5488 if ( trial && idRad > 0) colType = 2;
5489 if (!trial && (dipSel->gamType == 1 || abs(dipSel->weakType) > 0)) colType=0;
5490 if ( trial && (idRad==22 || idRad==23 || idRad==24 || idRad==25)) colType=0;
5492 if ( split->useForBranching
5493 && (particleDataPtr->colType(split->emtAft()->id) == 0
5494 || (particleDataPtr->colType(split->emtAft2()->id) == 0
5495 && nEmissions == 2)))
5498 if (flavour == 22 || flavour == 23 || flavour == 25) ;
5501 else if (flavour == 21 && colType > 0) {
5503 colRad =
event.nextColTag();
5505 }
else if (flavour == 21) {
5507 acolRad =
event.nextColTag();
5510 }
else if (colType > 0) {
5511 idEmt = abs(flavour);
5515 }
else if (colType < 0) {
5516 idEmt = -abs(flavour);
5522 if (split->useForBranching) {
5523 idRad =
event[iRadBef].id();
5524 colRad =
event[iRadBef].col();
5525 acolRad =
event[iRadBef].acol();
5529 if (split->radAft()->id != 0) idRad = split->radAft()->id;
5530 if (split->emtAft()->id != 0) idEmt = split->emtAft()->id;
5531 if (split->radAft()->col > -1) colRad = split->radAft()->col;
5532 if (split->radAft()->acol > -1) acolRad = split->radAft()->acol;
5533 if (split->emtAft()->col > -1) colEmt = split->emtAft()->col;
5534 if (split->emtAft()->acol > -1) acolEmt = split->emtAft()->acol;
5539 double m2Bef = particleDataPtr->isResonance(event[iRadBef].
id())
5540 ? getMass(event[iRadBef].
id(),3,event[iRadBef].mCalc())
5541 : (event[iRadBef].idAbs() < 6 || event[iRadBef].id() == 21
5542 || event[iRadBef].id() == 22)
5543 ? getMass(event[iRadBef].id(),2)
5544 : getMass(event[iRadBef].id(),1);
5546 double m2r = particleDataPtr->isResonance(idRad)
5547 && idRad ==
event[iRadBef].id()
5548 ? getMass(idRad,3,event[iRadBef].mCalc())
5549 : (abs(idRad) < 6 || idRad == 21 || idRad == 22)
5553 double m2ex = (abs(idEmt) < 6 || idEmt == 21 || idEmt == 22)
5554 ? getMass(idEmt,2) : getMass(idEmt,1);
5555 double m2e = (!trial) ? m2ex
5556 : ( (split->kinematics()->m2EmtAft > 0.) ? split->kinematics()->m2EmtAft
5559 if (split->useForBranching) {
5560 m2r = split->kinematics()->m2RadAft;
5561 m2e = split->kinematics()->m2EmtAft;
5567 if ( useMassiveBeams && (event[iRecBef].idAbs() == 11
5568 || event[iRecBef].idAbs() == 13
5569 || event[iRecBef].idAbs() > 900000))
5570 m2s = getMass(event[iRecBef].
id(),1);
5573 double Q2 = m2Dip - m2Bef + m2r + m2e;
5577 xCS = 1 - kappa2/(1.-z);
5580 double sai = (!trial) ? dipSel->sa1 : split->kinematics()->sai;
5581 double xa = (!trial) ? dipSel->xa : split->kinematics()->xa;
5584 if (split->useForBranching) { sai = psp[
"sai"]; xa = psp[
"xa"]; }
5587 double phi_kt = (!trial)
5588 ? ((dipSel->phi >= 0.) ? dipSel->phi
5589 : 2.*M_PI*rndmPtr->flat())
5590 : ((split->kinematics()->phi >= 0.) ? split->kinematics()->phi
5591 : 2.*M_PI*rndmPtr->flat());
5592 double phi_kt1 = phi_kt+2./3.*M_PI;
5593 if (phi_kt1>2.*M_PI) phi_kt1 -= 2.*M_PI;
5594 double phi_kt2 = phi_kt-2./3.*M_PI;
5595 if (phi_kt2<0.) phi_kt2 += 2.*M_PI;
5596 if (phi_kt1<phi_kt2) swap(phi_kt1, phi_kt2);
5600 if (nEmissions == 2)
5602 ? ((dipSel->phia1 >= 0.) ? dipSel->phia1
5603 : 2.*M_PI*rndmPtr->flat())
5604 : ((split->kinematics()->phi2 >= 0.) ? split->kinematics()->phi2
5605 : 2.*M_PI*rndmPtr->flat());
5608 if (split->useForBranching) { phi_kt = psp[
"phi"]; phiX = psp[
"phi2"]; }
5610 Vec4 pRad, pEmt, pRec;
5611 Vec4 auxpRad1, auxpEmt1;
5612 Vec4 auxpRad2, auxpEmt2;
5615 Vec4 q(pRecBef-pRadBef);
5616 double q2 = q.m2Calc();
5619 double m2a(0.), m2i(0.), m2j(0.), m2ai(0.);
5620 if (nEmissions == 2) {
5621 m2a = (abs(flavourSave) < 6
5622 || flavourSave == 21
5623 || flavourSave == 22)
5624 ? getMass(flavourSave,2)
5625 : getMass(flavourSave,1);
5628 if (split->useForBranching) {
5629 m2a = split->kinematics()->m2RadAft;
5630 m2i = split->kinematics()->m2EmtAft;
5631 m2j = split->kinematics()->m2EmtAft2;
5633 m2ai = sai + m2a + m2i;
5634 Q2 = m2Dip - m2Bef + m2ai + m2j + m2s;
5636 xCS = (q2 - m2ai - m2j - m2s)
5637 / (q2 - m2ai - m2j - m2s - pT2 * xa/z);
5640 if (split->useForBranching) {
5641 m2Emt = split->kinematics()->m2EmtAft;
5642 m2Rad = sai + m2a + m2j;
5643 m2ai = sai + m2a + m2j;
5647 Vec4 qpar(q.px()+pRadBef.px(), q.py()+pRadBef.py(), q.pz(), q.e());
5648 double qpar2 = qpar.m2Calc();
5649 double pT2ijt = pow2(pRadBef.px()) + pow2(pRadBef.py());
5652 double sij = (1.-1./xCS) * (q2 - m2s) + (m2Rad+m2Emt) / xCS;
5653 double zbar = (q2-sij-m2s) / bABC(q2,sij,m2s)
5654 * (zCS - m2s/gABC(q2,sij,m2s)
5655 *(sij + m2Rad - m2Emt)/(q2-sij-m2s));
5656 double kT2 = zbar*(1.-zbar)*sij - (1.-zbar)*m2Rad - zbar*m2Emt;
5661 infoPtr->errorMsg(
"Warning in DireTimes::branch_FI: Reject state "
5662 "with kinematically forbidden kT^2.");
5668 if (physical && (kT2!=kT2 || abs(kT2-kT2) > 1e5) ) {
5669 infoPtr->errorMsg(
"Warning in DireTimes::branch_FI: Reject state "
5670 "with not-a-number kT^2 for branching " + name);
5675 pRec.p( (pRecBef - (q*pRecBef)/qpar2 * qpar)
5676 * sqrt( (lABC(q2,sij,m2s) - 4.*m2s*pT2ijt)
5677 /(lABC(q2,m2Bef,m2s) - 4.*m2s*pT2ijt))
5678 + qpar * (q2+m2s-sij)/(2.*qpar2) );
5684 pair<Vec4, Vec4> pTvecs = getTwoPerpendicular(pRec, pij);
5685 Vec4 kTmom( sqrt(kT2)*sin(phi_kt)*pTvecs.first
5686 + sqrt(kT2)*cos(phi_kt)*pTvecs.second);
5689 pRad.p( zbar * (gABC(q2,sij,m2s)*pij + sij*pRec) / bABC(q2,sij,m2s)
5690 + (m2Rad+kT2) / (zbar*bABC(q2,sij,m2s))
5691 * (-pRec - m2s/gABC(q2,sij,m2s)*pij)
5695 pEmt.p(-q-pRad+pRec);
5697 kTmom.p( sqrt(kT2)*sin(phi_kt1)*pTvecs.first
5698 + sqrt(kT2)*cos(phi_kt1)*pTvecs.second);
5699 auxpRad1.p( zbar * (gABC(q2,sij,m2s)*pij + sij*pRec) / bABC(q2,sij,m2s)
5700 + (m2Rad+kT2) / (zbar*bABC(q2,sij,m2s))
5701 * (-pRec - m2s/gABC(q2,sij,m2s)*pij)
5703 auxpEmt1.p(-q-auxpRad1+pRec);
5705 kTmom.p( sqrt(kT2)*sin(phi_kt2)*pTvecs.first
5706 + sqrt(kT2)*cos(phi_kt2)*pTvecs.second);
5707 auxpRad2.p( zbar * (gABC(q2,sij,m2s)*pij + sij*pRec) / bABC(q2,sij,m2s)
5708 + (m2Rad+kT2) / (zbar*bABC(q2,sij,m2s))
5709 * (-pRec - m2s/gABC(q2,sij,m2s)*pij)
5711 auxpEmt2.p(-q-auxpRad2+pRec);
5713 if ( abs(q.m2Calc()) < 1e-5 && pRadBef.m2Calc() > 0.) {
5714 double yCS = (m2Bef - m2Emt - m2Rad)
5715 / (m2Bef - m2Emt - m2Rad + 2.*pRadBef*pRecBef);
5717 q.p(pRadBef + pRecBef);
5720 sij = yCS * (q2 - m2s) + (1.-yCS)*(m2Rad+m2Emt);
5721 zbar = (q2-sij-m2s) / bABC(q2,sij,m2s)
5722 * (zCS - m2s/gABC(q2,sij,m2s)
5723 *(sij + m2Rad - m2Emt)/(q2-sij-m2s));
5724 kT2 = zbar*(1.-zbar)*sij - (1.-zbar)*m2Rad - zbar*m2Emt;
5727 if (!trial) infoPtr->errorMsg(
"Info in DireTimes::branch_FI: "
5728 "Recued state with previously forbidden kT^2.");
5732 pair < Vec4, Vec4 > momsAfter = decayWithOnshellRec( zCS, yCS,
5733 phi_kt, m2s, m2Rad, m2Emt, pRadBef, pRecBef );
5734 pRad.p(momsAfter.first);
5735 pEmt.p(momsAfter.second);
5738 if (isnan(pRad)) physical =
false;
5740 }
else if (isnan(pRad)) physical =
false;
5743 double errMass = abs(pRad.mCalc() - sqrt(m2Rad)) / max( 1.0, pRad.e());
5744 if ( errMass > mTolErr*1e-2 ) {
5745 double deltam2 = pRad.m2Calc() - m2Rad;
5746 pRad.e(sqrtpos(pow2(pRad.e()) - deltam2));
5749 errMass = abs(pEmt.mCalc() - sqrt(m2Emt)) / max( 1.0, pEmt.e());
5750 if ( errMass > mTolErr*1e-2 ) {
5751 double deltam2 = pEmt.m2Calc() - m2Emt;
5752 pEmt.e(sqrtpos(pow2(pEmt.e()) - deltam2));
5755 errMass = abs(pRec.mCalc() - sqrt(m2s)) / max( 1.0, pRec.e());
5756 if ( errMass > mTolErr*1e-2 ) {
5757 double deltam2 = pRec.m2Calc() - m2s;
5758 pRec.e(sqrtpos(pow2(pRec.e()) - deltam2));
5762 if ( physical && particleDataPtr->colType(event[iRecBef].id()) != 0
5763 && 2.*pRec.e()/
event[0].m() > 1. ) {
5764 infoPtr->errorMsg(
"Error in DireTimes::branch_FI: "
5765 "Larger than unity Bjorken x value");
5771 if ( nEmissions == 2 && !split->useForBranching) {
5773 swap(colRad,colEmt);
5774 swap(acolRad,acolEmt);
5778 if ( nEmissions == 2 && split->useForBranching
5779 && particleDataPtr->colType(split->emtAft()->id) == 0)
5780 { colRad =
event[iRadBef].col(); acolRad =
event[iRadBef].acol(); }
5783 double pTsel = sqrt(pT2);
5784 Particle rad = Particle(idRad, 51, iRadBef, 0, 0, 0,
5785 colRad, acolRad, pRad, sqrt(m2Rad), pTsel);
5786 Particle auxrad1 = Particle(idRad, 51, iRadBef, 0, 0, 0,
5787 colRad, acolRad, auxpRad1, sqrt(m2Rad), pTsel);
5788 Particle auxrad2 = Particle(idRad, 51, iRadBef, 0, 0, 0,
5789 colRad, acolRad, auxpRad2, sqrt(m2Rad), pTsel);
5792 if ( nEmissions == 2 ) rad.status(59);
5794 Particle emt = Particle(idEmt, 51, iRadBef, 0, 0, 0,
5795 colEmt, acolEmt, pEmt, sqrt(m2Emt), pTsel);
5796 Particle auxemt1 = Particle(idEmt, 51, iRadBef, 0, 0, 0,
5797 colEmt, acolEmt, auxpEmt1, sqrt(m2Emt), pTsel);
5798 Particle auxemt2 = Particle(idEmt, 51, iRadBef, 0, 0, 0,
5799 colEmt, acolEmt, auxpEmt2, sqrt(m2Emt), pTsel);
5801 Particle rec = Particle(event[iRecBef].
id(), -53, 0, 0, iRecBef, iRecBef,
5802 event[iRecBef].col(), event[iRecBef].acol(), pRec, 0., pTsel);
5806 if (emt.idAbs() == 23 || emt.idAbs() == 24) {
5809 event[iRadBef].pol( dipSel->weakPol );
5810 rad.pol( dipSel->weakPol );
5815 if ( nEmissions == 2 && split->useForBranching ) {
5816 if ( split->extras.find(
"colRadInt") != split->extras.end() )
5817 rad.col(
int(split->extras[
"colRadInt"]));
5818 if ( split->extras.find(
"acolRadInt") != split->extras.end() )
5819 rad.acol(
int(split->extras[
"acolRadInt"]));
5820 if ( split->extras.find(
"colEmtInt") != split->extras.end() )
5821 emt.col(
int(split->extras[
"colEmtInt"]));
5822 if ( split->extras.find(
"acolEmtInt") != split->extras.end() )
5823 emt.acol(
int(split->extras[
"acolEmtInt"]));
5827 int evSizeOld =
event.size();
5828 int iRadStatusV =
event[iRadBef].status();
5829 int iRadDau1V =
event[iRadBef].daughter1();
5830 int iRadDau2V =
event[iRadBef].daughter2();
5831 int iRecMot1V =
event[iRecBef].mother1();
5832 int iRecMot2V =
event[iRecBef].mother2();
5833 int beamOff1 = 1 + beamOffset;
5834 int beamOff2 = 2 + beamOffset;
5835 int ev1Dau1V =
event[beamOff1].daughter1();
5836 int ev2Dau1V =
event[beamOff2].daughter1();
5839 if (event[iRadBef].hasVertex()) {
5840 rad.vProd( event[iRadBef].vProd() );
5841 emt.vProd( event[iRadBef].vProd() );
5843 if (event[iRecBef].hasVertex()) rec.vProd( event[iRecBef].vProd() );
5847 int iRad = int(event.append(rad));
5848 int iEmt = int(event.append(emt));
5850 event[iRadBef].statusNeg();
5851 event[iRadBef].daughters( iRad, iEmt);
5852 int iRec =
event.append(rec);
5853 event[iRecBef].mothers( iRec, iRec);
5854 event[iRec].mothers( iRecMot1V, iRecMot2V);
5855 int iBeam1Dau1 =
event[beamOff1].daughter1();
5856 int iBeam2Dau1 =
event[beamOff2].daughter1();
5857 if (iSysSelRec == 0 && iRecMot1V == beamOff1)
5858 event[beamOff1].daughter1( iRec);
5859 if (iSysSelRec == 0 && iRecMot1V == beamOff2)
5860 event[beamOff2].daughter1( iRec);
5862 int auxiRad1 = int(auxevent1.append(auxrad1));
5863 int auxiEmt1 = int(auxevent1.append(auxemt1));
5864 auxevent1[iRadBef].statusNeg();
5865 auxevent1[iRadBef].daughters( auxiRad1, auxiEmt1);
5866 int auxiRec1 = auxevent1.append(rec);
5867 auxevent1[iRecBef].mothers( auxiRec1, auxiRec1);
5868 auxevent1[auxiRec1].mothers( iRecMot1V, iRecMot2V);
5870 int auxiRad2 = int(auxevent2.append(auxrad2));
5871 int auxiEmt2 = int(auxevent2.append(auxemt2));
5872 auxevent2[iRadBef].statusNeg();
5873 auxevent2[iRadBef].daughters( auxiRad2, auxiEmt2);
5874 int auxiRec2 = auxevent2.append(rec);
5875 auxevent2[iRecBef].mothers( auxiRec2, auxiRec2);
5876 auxevent2[auxiRec1].mothers( iRecMot1V, iRecMot2V);
5878 if ( nEmissions == 2 && !split->useForBranching) swap(iRad,iEmt);
5880 bool doVeto =
false;
5881 bool doMECreject =
false;
5882 if ( nEmissions != 2) {
5885 if ( !validMomentum( rad.p(), idRad, 1)
5886 || !validMomentum( emt.p(), idEmt, 1)
5887 || !validMomentum( rec.p(),
event[iRecBef].id(), -1) )
5890 bool inResonance = (partonSystemsPtr->getInA(iSysSel) == 0) ?
true :
false;
5891 doVeto = (( canVetoEmission && userHooksPtr->doVetoFSREmission(
5892 evSizeOld,event,iSysSel,inResonance) )
5893 || ( canMergeFirst && mergingHooksPtr->doVetoEmission(
5896 double xm = 2. * pRec.e() / (beamAPtr->e() + beamBPtr->e());
5898 BeamParticle& beamRec = (isrType == 1) ? *beamAPtr : *beamBPtr;
5899 if ( particleDataPtr->colType(event[iRecBef].id()) != 0
5900 && beamRec.size() > 0) {
5901 double xOld = beamRec[iSysSelRec].x();
5902 beamRec[iSysSelRec].iPos(iRec);
5903 beamRec[iSysSelRec].x(xm);
5904 if (beamRec.xMax(-1) < 0.0) {
5905 if (!trial) infoPtr->errorMsg(
"Warning in DireTimes::branch_FI: "
5906 "used up beam momentum; discard splitting.");
5910 beamRec[iSysSelRec].iPos(iRecBef);
5911 beamRec[iSysSelRec].x(xOld);
5915 bool isHardSystem = partonSystemsPtr->getSystemOf(iRadBef,
true) == 0
5916 && partonSystemsPtr->getSystemOf(iRecBef,
true) == 0;
5917 if ( isHardSystem && physical && doMEcorrections
5919 && pT2 > pT2minMECs && checkSIJ(event,Q2minMECs)) {
5921 partonSystemsPtr->replace(iSysSel, iRadBef, iRad);
5922 partonSystemsPtr->addOut(iSysSel, iEmt);
5923 partonSystemsPtr->replace(iSysSelRec, iRecBef, iRec);
5925 if ( nFinalMaxMECs < 0
5926 || nFinalMaxMECs > partonSystemsPtr->sizeOut(iSysSel))
5927 doMECreject = applyMEC (event, split,
5928 createvector<Event>(auxevent1)(auxevent2));
5931 partonSystemsPtr->replace(iSysSel, iRad, iRadBef);
5932 partonSystemsPtr->replace(iSysSelRec, iRec, iRecBef);
5933 partonSystemsPtr->popBackOut(iSysSel);
5938 if ( physical && !doVeto && !trial && !doMECreject) updateAfterFI(
5939 iSysSel, iSysSelRec,
5940 event, iRadBef, iRecBef, iRad, iEmt, iRec, flavour, colType, pTsel, xm);
5946 if ( !validMomentum( emt.p(), idEmt, 1)
5947 || !validMomentum( rec.p(),
event[iRecBef].id(), -1))
5950 int iRadOld = int(event.size())-3;
5951 int iEmtOld = int(event.size())-2;
5952 int iRecOld = int(event.size())-1;
5955 swap(iRadOld,iEmtOld);
5957 if (!split->useForBranching) {
5959 idEmt = -flavourSave;
5960 idRad = flavourSave;
5964 acolEmt =
event[iEmtOld].acol();
5965 colRad =
event[iEmtOld].col();
5968 colEmt =
event[iEmtOld].col();
5971 acolRad =
event[iEmtOld].acol();
5975 idRad = split->radAft()->id;
5976 idEmt = split->emtAft2()->id;
5977 colRad = split->radAft()->col;
5978 acolRad = split->radAft()->acol;
5979 colEmt = split->emtAft2()->col;
5980 acolEmt = split->emtAft2()->acol;
5985 m2r = particleDataPtr->isResonance(idRad)
5986 && idRad ==
event[iRadBef].id()
5987 ? getMass(idRad,3,event[iRadBef].mCalc())
5988 : (abs(idRad) < 6 || idRad == 21 || idRad == 22)
5991 m2e = (abs(idEmt) < 6 || idEmt == 21 || idEmt == 22)
5992 ? getMass(idEmt,2) : getMass(idEmt,1);
5994 if (split->useForBranching) {
5995 m2r = split->kinematics()->m2RadAft;
5996 m2e = split->kinematics()->m2EmtAft2;
6000 Vec4 pa1(event[iEmtOld].p());
6001 Vec4 pb(event[iRecOld].p());
6009 if (split->useForBranching) {
6010 m2Rad = split->kinematics()->m2RadAft;
6011 m2Emt = split->kinematics()->m2EmtAft2;
6015 double yCS = (m2ai - m2Emt - m2Rad) / (m2ai - m2Emt - m2Rad + 2.*pa1*pb);
6018 sij = yCS * (q2 - m2s) + (1.-yCS)*(m2Rad+m2Emt);
6019 zbar = (q2-sij-m2s) / bABC(q2,sij,m2s)
6020 * (zCS - m2s/gABC(q2,sij,m2s)
6021 *(sij + m2Rad - m2Emt)/(q2-sij-m2s));
6022 kT2 = zbar*(1.-zbar)*sij - (1.-zbar)*m2Rad - zbar*m2Emt;
6026 infoPtr->errorMsg(
"Warning in DireTimes::branch_FI: Reject state "
6027 "with kinematically forbidden kT^2.");
6033 if (physical && (kT2!=kT2 || abs(kT2-kT2) > 1e5) ) {
6034 infoPtr->errorMsg(
"Warning in DireTimes::branch_FI: Reject state "
6035 "with not-a-number kT^2 for branching " + name);
6040 double xm = 2. *
event[iRecOld].e() / (beamAPtr->e() + beamBPtr->e());
6043 BeamParticle& beamRec = (isrType == 1) ? *beamAPtr : *beamBPtr;
6044 if ( particleDataPtr->colType(event[iRecOld].id()) != 0
6045 && beamRec.size() > 0) {
6046 double xOld = beamRec[iSysSelRec].x();
6047 beamRec[iSysSelRec].iPos(iRec);
6048 beamRec[iSysSelRec].x(xm);
6049 if (beamRec.xMax(-1) < 0.0) {
6050 if (!trial) infoPtr->errorMsg(
"Warning in DireTimes::branch_FI: "
6051 "used up beam momentum; discard splitting.");
6055 beamRec[iSysSelRec].iPos(iRecBef);
6056 beamRec[iSysSelRec].x(xOld);
6059 if ( physical && !trial ) updateAfterFI( iSysSel, iSysSelRec, event,
6060 iRadBef, iRecBef, iRad, iEmt, iRec, flavour, colType, pTsel, xm);
6068 pTvecs = getTwoPerpendicular(pb, pij);
6069 kTmom.p( sqrt(kT2)*sin(phiX)*pTvecs.first
6070 + sqrt(kT2)*cos(phiX)*pTvecs.second);
6073 pRad.p( zbar * (gABC(q2,sij,m2s)*pij - sij*pb) / bABC(q2,sij,m2s)
6074 + (m2Rad+kT2) / (zbar*bABC(q2,sij,m2s))
6075 * (pb - m2s/gABC(q2,sij,m2s)*pij)
6082 pRec.p(event[iRecOld].p());
6086 Vec4 pa(pRad), pk(pRec), pj(emt.p()), pi(pEmt);
6087 double saix(2.*pa*pi), sakx(2.*pa*pk), sajx(2.*pa*pj), sikx(2.*pi*pk),
6088 sjkx(2.*pj*pk), sijx(2.*pi*pj);
6089 double pptt = (sajx+sijx)*(sakx+sikx)/( sakx + sikx + sjkx);
6090 double ssaaii = saix;
6091 double zzaa = sakx / ( sakx + sikx + sjkx );
6092 double xxaa = sakx / ( sakx + sikx );
6095 (abs(pptt-pT2) > 1e-5 || abs(ssaaii-sai) > 1e-5 ||
6096 abs(zzaa-z) > 1e-5 || abs(xxaa-xa) > 1e-5) ){
6098 cout << scientific << setprecision(8);
6099 cout <<
"Error in branch_FI: Invariant masses after branching do not "
6100 <<
"match chosen values." << endl;
6102 <<
" Q2 " << (
event[iRadBef].p()-
event[iRecBef].p()).m2Calc()
6106 <<
" xa " << xa << endl;
6107 cout <<
"Generated: "
6108 <<
" Q2 " << -sakx + saix + sajx +sijx -sikx - sjkx
6110 <<
" sai " << ssaaii
6112 <<
" xa " << xxaa << endl;
6118 if ( !validMomentum( pRad, idRad, 1)
6119 || !validMomentum( pEmt, idEmt, 1)
6120 || !validMomentum( pRec, event[iRecOld].
id(), -1) )
6124 if ( particleDataPtr->colType(event[iRecOld].id()) != 0
6125 && beamRec.size() > 0) {
6126 double xOld = beamRec[iSysSelRec].x();
6127 int iOld = beamRec[iSysSelRec].iPos();
6128 double xNew = 2.*pRec.e() / (beamAPtr->e() + beamBPtr->e());
6129 int iNew =
event.append(Particle(event[iRecOld].
id(), -53, 0, 0,
6130 iRecOld, iRecOld, event[iRecOld].col(), event[iRecOld].acol(), pRec,
6132 beamRec[iSysSelRec].iPos(iNew);
6133 beamRec[iSysSelRec].x(xNew);
6134 if (beamRec.xMax(-1) < 0.0) {
6135 if (!trial) infoPtr->errorMsg(
"Warning in DireTimes::branch_FI: "
6136 "used up beam momentum; discard splitting.");
6141 beamRec[iSysSelRec].iPos(iOld);
6142 beamRec[iSysSelRec].x(xOld);
6149 Particle rad2 = Particle(idRad, 51, iEmtOld, 0, 0, 0,
6151 colRad, acolRad, pRad, sqrt(m2Rad), pTsel);
6152 Particle emt2 = Particle(idEmt, 51, iEmtOld, 0, 0, 0,
6154 colEmt, acolEmt, pEmt, sqrt(m2Emt), pTsel);
6155 Particle rec2 = Particle(event[iRecOld].
id(), -53, 0, 0, iRecOld,
6156 iRecOld, event[iRecOld].col(), event[iRecOld].acol(), pRec, 0., pTsel);
6160 if (event[iEmtOld].hasVertex()) {
6161 rad2.vProd( event[iEmtOld].vProd() );
6162 emt2.vProd( event[iEmtOld].vProd() );
6164 if (event[iRecOld].hasVertex()) rec2.vProd( event[iRecOld].vProd() );
6169 iRad =
event.append(rad2);
6170 iEmt =
event.append(emt2);
6171 event[iEmtOld].statusNeg();
6172 event[iEmtOld].daughters( iRad, iEmt);
6174 iRecMot1V =
event[iRecOld].mother1();
6175 iRecMot2V =
event[iRecOld].mother2();
6176 iRec =
event.append(rec2);
6177 event[iRecOld].statusNeg();
6178 event[iRecOld].mothers( iRec, iRec);
6179 event[iRec].mothers( iRecMot1V, iRecMot2V);
6180 if (iRecMot1V == beamOff1)
event[beamOff1].daughter1( iRec);
6181 if (iRecMot1V == beamOff2)
event[beamOff2].daughter1( iRec);
6185 int colTypeNow = colType;
6186 xm = 2. *
event[iRec].e() / (beamAPtr->e() + beamBPtr->e());
6187 updateAfterFI( iSysSel, iSysSelRec, event, iEmtOld, iRecOld,
6188 iRad, iEmt, iRec, flavourSave, colTypeNow, pTsel, xm);
6193 physical = physical && !doVeto;
6197 if (iSysSelRec > 0) {
6198 if (iRecMot1V == beamOff1)
event[beamOff1].daughter1( iRec);
6199 if (iRecMot1V == beamOff2)
event[beamOff2].daughter1( iRec);
6204 if ( physical && !trial && !doMECreject && !validMotherDaughter(event)) {
6205 infoPtr->errorMsg(
"Error in DireTimes::branch_FI: Mother-daughter "
6206 "relations after branching not valid.");
6211 if (iSysSelRec > 0) {
6212 if (iRecMot1V == beamOff1)
event[beamOff1].daughter1(iBeam1Dau1);
6213 if (iRecMot1V == beamOff2)
event[beamOff2].daughter1(iBeam2Dau1);
6217 if ( !physical || doMECreject) {
6219 event.popBack( event.size() - evSizeOld);
6220 event[iRadBef].status( iRadStatusV);
6221 event[iRadBef].daughters( iRadDau1V, iRadDau2V);
6222 event[iRecBef].mothers( iRecMot1V, iRecMot2V);
6223 if (iSysSelRec == 0 && iRecMot1V == beamOff1)
6224 event[beamOff1].daughter1( ev1Dau1V);
6225 if (iSysSelRec == 0 && iRecMot1V == beamOff2)
6226 event[beamOff2].daughter1( ev2Dau1V);
6233 for ( unordered_map<
string, multimap<double,double> >::iterator
6234 it = rejectProbability.begin(); it != rejectProbability.end(); ++it){
6235 weights->eraseAcceptWeight(pT2, it->first);
6236 weights->eraseRejectWeight(pT2, it->first);
6240 if (!trial && doMECreject) {
6241 weights->calcWeight(pT2,
false,
true);
6244 for ( unordered_map<
string, multimap<double,double> >::iterator
6245 it = rejectProbability.begin(); it != rejectProbability.end(); ++it )
6247 for ( unordered_map<
string, map<double,double> >::iterator
6248 it = acceptProbability.begin(); it != acceptProbability.end(); ++it )
6256 if (trial) split->storePosAfter( iRad, iRec, iEmt,
6257 (nEmissions < 2) ? 0 : iEmt2);
6262 weights->calcWeight(pT2);
6266 direInfoPtr->updateSoftPos( iRadBef, iEmt );
6267 direInfoPtr->updateSoftPosIfMatch( iRecBef, iRec );
6268 if (nEmissions > 1) direInfoPtr->addSoftPos( iEmt2 );
6269 updateDipoles(event, iSysSel);
6273 for ( unordered_map<
string, multimap<double,double> >::iterator
6274 it = rejectProbability.begin(); it != rejectProbability.end(); ++it )
6276 for ( unordered_map<
string, map<double,double> >::iterator
6277 it = acceptProbability.begin(); it != acceptProbability.end(); ++it )
6288 void DireTimes::updateAfterFI(
int iSysSelNow,
int iSysSelRec,
6289 Event& event,
int iRadBef,
int iRecBef,
int iRad,
int iEmt,
int iRec,
6290 int,
int colType,
double pTsel,
double xNew) {
6292 bool hasDipSel = (dipSel != 0);
6293 int isrType = (hasDipSel) ? dipSel->isrType : event[iRec].mother1();
6294 bool inResonance = (partonSystemsPtr->getInA(iSysSelNow)==0) ?
true :
false;
6295 int idEmt =
event[iEmt].id();
6296 vector<int> iDipEndCorr;
6299 BeamParticle& beamRec = (isrType == 1) ? *beamAPtr : *beamBPtr;
6300 double xOld = beamRec[iSysSelRec].x();
6301 beamRec[iSysSelRec].iPos( iRec);
6302 beamRec[iSysSelRec].x( xNew);
6303 partonSystemsPtr->setSHat( iSysSelRec,
6304 partonSystemsPtr->getSHat(iSysSelRec) * xNew / xOld);
6306 if (particleDataPtr->colType(idEmt) == 2) {
6309 dipSel->iRadiator = iRad;
6310 dipSel->iRecoiler = iEmt;
6311 dipSel->systemRec = iSysSel;
6312 dipSel->pTmax = pTsel;
6316 for (
int i = 0; i < int(dipEnd.size()); ++i) {
6317 if (dipEnd[i].iRadiator == iRecBef && dipEnd[i].iRecoiler == iRadBef
6318 && dipEnd[i].colType != 0) {
6319 dipEnd[i].iRadiator = iRec;
6320 dipEnd[i].iRecoiler = iEmt;
6321 dipEnd[i].MEtype = 0;
6323 if ( dipEnd[i].colType * colType > 0)
6324 dipEnd[i].iRecoiler = iRad;
6325 dipEnd[i].pTmax = pTsel;
6326 iDipEndCorr.push_back(i);
6329 int colTypeNow = (colType > 0) ? 2 : -2 ;
6333 if (recoilToColoured && inResonance && event[iRec].col() == 0
6334 &&
event[iRec].acol() == 0) iRecMod = iRad;
6336 if (appendDipole(event, iEmt, iRecMod, pTsel, colTypeNow, 0, 0, 0, isrType,
6337 iSysSelNow, 0, -1, 0,
false, dipEnd)) {
6338 iDipEndCorr.push_back(dipEnd.size()-1);
6340 DireTimesEnd& dip1 = dipEnd.back();
6341 dip1.systemRec = iSysSelRec;
6343 if (appendDipole(event, iEmt, iRad, pTsel, -colTypeNow, 0, 0, 0, 0,
6344 iSysSelNow, 0, -1, 0,
false, dipEnd)) {
6345 iDipEndCorr.push_back(dipEnd.size()-1);
6347 DireTimesEnd& dip2 = dipEnd.back();
6348 dip2.systemRec = iSysSelRec;
6352 }
else if (particleDataPtr->colType(idEmt) != 0) {
6355 if ( splittingsPtr->nEmissions(splittingSelName) == 2 ){
6356 for (
int i = 0; i < int(dipEnd.size()); ++i) {
6358 DireTimesEnd& dip = dipEnd[i];
6360 if ( dip.iRadiator == iRecBef ) dip.iRadiator = iRec;
6361 if ( dip.iRecoiler == iRecBef ) dip.iRecoiler = iRec;
6362 if ( dip.iRadiator == iRadBef ) {
6363 if (dip.colType > 0)
6364 dip.iRadiator = (
event[iEmt].id() > 0) ? iEmt : iRad;
6365 if (dip.colType < 0)
6366 dip.iRadiator = (
event[iEmt].id() < 0) ? iEmt : iRad;
6368 if (abs(dip.colType) == 2
6369 &&
event[dip.iRadiator].id() > 0
6370 &&
event[dip.iRadiator].idAbs() < 10)
6371 dip.colType = abs(dip.colType)/2;
6372 if (abs(dip.colType) == 2
6373 &&
event[dip.iRadiator].id() < 0
6374 &&
event[dip.iRadiator].idAbs() < 10)
6375 dip.colType = -abs(dip.colType)/2;
6376 iDipEndCorr.push_back(i);
6379 if ( dip.iRecoiler == iRadBef ) {
6380 if (dip.colType > 0)
6381 dip.iRecoiler = (
event[iEmt].id() < 0) ? iEmt : iRad;
6382 if (dip.colType < 0)
6383 dip.iRecoiler = (
event[iEmt].id() > 0) ? iEmt : iRad;
6385 if (abs(dip.colType) == 2) dipEnd[i].colType /= 2;
6387 if (abs(dip.colType) == 1
6388 &&
event[dip.iRadiator].id() > 0
6389 &&
event[dip.iRadiator].idAbs() < 10)
6392 if (abs(dip.colType) == 1
6393 &&
event[dip.iRadiator].id() < 0
6394 &&
event[dip.iRadiator].idAbs() < 10)
6396 iDipEndCorr.push_back(i);
6401 for (
int i = 0; i < int(dipEnd.size()); ++i) {
6403 if ( find(iDipEndCorr.begin(), iDipEndCorr.end(), i)
6404 != iDipEndCorr.end() )
continue;
6406 if ( dipEnd[i].iRecoiler == iRadBef
6407 && dipEnd[i].colType * colType < 0 ) {
6408 dipEnd[i].iRecoiler = iEmt;
6410 if (dipEnd[i].iRadiator == iRadBef && abs(dipEnd[i].colType) == 2) {
6411 dipEnd[i].colType /= 2;
6413 if (hasDipSel && &dipEnd[i] == dipSel) dipEnd[i].iRadiator = iEmt;
6414 else dipEnd[i].iRadiator = iRad;
6415 if (hasDipSel && &dipEnd[i] == dipSel) dipEnd[i].iRecoiler = iRec;
6417 dipEnd[i].colType = (
event[dipEnd[i].iRadiator].id() > 0)
6418 ? abs(dipEnd[i].colType) : -abs(dipEnd[i].colType);
6420 iDipEndCorr.push_back(i);
6422 if (dipEnd[i].system != dipEnd[i].systemRec)
continue;
6423 dipEnd[i].MEtype = 0;
6424 if (hasDipSel && &dipEnd[i] == dipSel) dipEnd[i].iMEpartner = iRad;
6425 else dipEnd[i].iMEpartner = iEmt;
6430 bool updateSel=
true;
6431 for (
int j = 0; j < int(iDipEndCorr.size()); ++j)
6432 if ( hasDipSel && &dipEnd[iDipEndCorr[j]] == dipSel) updateSel =
false;
6436 dipSel->iRadiator = iEmt;
6437 dipSel->iRecoiler = iRec;
6440 dipSel->pTmax = pTsel;
6445 int iRadOld = (hasDipSel) ? dipSel->iRadiator : iRadBef;
6446 int iRecOld = (hasDipSel) ? dipSel->iRecoiler : iRecBef;
6449 for (
int i = 0; i < int(dipEnd.size()); ++i) {
6450 DireTimesEnd& dip = dipEnd[i];
6452 if ( dip.iRecoiler == iRecOld && dip.iRadiator == iRadOld ) {
6453 dip.iRadiator = iRad;
6454 dip.iRecoiler = iRec;
6456 iDipEndCorr.push_back(i);
6459 if ( dip.iRecoiler == iRadOld && dip.iRadiator == iRecOld ) {
6460 dip.iRadiator = iRec;
6461 dip.iRecoiler = iRad;
6463 iDipEndCorr.push_back(i);
6470 for (
int i = 0; i < int(dipEnd.size()); ++i) {
6472 if ( find(iDipEndCorr.begin(), iDipEndCorr.end(), i)
6473 != iDipEndCorr.end() )
continue;
6474 if (dipEnd[i].iRadiator == iRadBef) dipEnd[i].iRadiator = iRad;
6475 if (dipEnd[i].iRecoiler == iRadBef) dipEnd[i].iRecoiler = iRad;
6476 if (dipEnd[i].iMEpartner == iRadBef) dipEnd[i].iMEpartner = iRad;
6477 if (dipEnd[i].iRadiator == iRecBef) dipEnd[i].iRadiator = iRec;
6478 if (dipEnd[i].iRecoiler == iRecBef) dipEnd[i].iRecoiler = iRec;
6479 if (dipEnd[i].iMEpartner == iRecBef) dipEnd[i].iMEpartner = iRec;
6485 vector<pair<int, int> > rad_rec (createvector< pair<int,int> >
6486 (make_pair(iRad,iEmt))
6487 (make_pair(iEmt,iRec))
6488 (make_pair(iEmt,iRad))
6489 (make_pair(iRad,iRec)));
6490 for (
int i=0; i < int(rad_rec.size()); ++i) {
6491 int iRadNow = rad_rec[i].first;
6492 int iRecNow = rad_rec[i].second;
6496 for (
int j = 0; j < int(dipEnd.size()); ++j)
6497 if ( dipEnd[j].iRadiator == iRadNow
6498 && dipEnd[j].iRecoiler == iRecNow )
6502 if (
int(iDip.size()) > 0)
for (
int j = 0; j < int(iDip.size()); ++j)
6503 updateAllowedEmissions(event, &dipEnd[iDip[j]]);
6505 else appendDipole( event, iRadNow, iRecNow, pTsel, 0, 0, 0, 0, 0,
6506 iSysSelNow, -1, -1, 0,
false, dipEnd);
6510 if (event[iRad].
id() == event[iRadBef].
id()) {
6511 event[iRad].tau( event[iRadBef].tau() );
6513 event[iRad].tau( event[iRad].tau0() * rndmPtr->exp() );
6514 event[iEmt].tau( event[iEmt].tau0() * rndmPtr->exp() );
6516 event[iRec].tau( event[iRecBef].tau() );
6519 partonSystemsPtr->replace(iSysSel, iRadBef, iRad);
6520 partonSystemsPtr->addOut(iSysSel, iEmt);
6521 partonSystemsPtr->replace(iSysSelRec, iRecBef, iRec);
6524 for (
int i = 0; i < partonSystemsPtr->sizeOut(iSysSelNow); ++i) {
6525 int iNow = partonSystemsPtr->getOut( iSysSelNow, i);
6526 if (event[iNow].isFinal() && event[iNow].scale() > 0.) {
6528 int colTag =
event[iNow].col();
6529 if (doQCDshower && colTag > 0) setupQCDdip( iSysSelNow, i, colTag, 1,
6530 event,
false,
true);
6532 int acolTag =
event[iNow].acol();
6533 if (doQCDshower && acolTag > 0) setupQCDdip( iSysSelNow, i, acolTag, -1,
6534 event,
false,
true);
6536 getGenDip( iSysSelNow, i, iNow, event,
false, dipEnd);
6539 if (doDecaysAsShower && event[iNow].isResonance())
6540 setupDecayDip( iSysSelNow, iNow, event, dipEnd);
6545 updateDipoles(event, iSysSel);
6548 if ( direInfoPtr->isRes(iRadBef) &&
6549 event[iRadBef].id() !=
event[iRad].id() )
6550 direInfoPtr->removeResPos(iRadBef);
6551 if ( particleDataPtr->isResonance(event[iRad].id()) ) {
6552 if ( direInfoPtr->isRes(iRadBef) )
6553 direInfoPtr->updateResPos(iRadBef,iRad);
6555 if ( direInfoPtr->isRes(iRecBef) )
6556 direInfoPtr->updateResPos(iRecBef,iRec);
6557 if ( particleDataPtr->isResonance(event[iEmt].id()) )
6558 direInfoPtr->addResPos(iEmt);
6566 pair < Vec4, Vec4 > DireTimes::decayWithOnshellRec(
double zCS,
double yCS,
6567 double phi,
double m2Rec,
double m2RadAft,
double m2EmtAft,
6568 Vec4 pRadBef, Vec4 pRecBef ) {
6571 Vec4 q(pRadBef + pRecBef);
6572 double q2 = q.m2Calc();
6575 double sij = yCS * (q2 - m2Rec) + (1.-yCS)*(m2RadAft+m2EmtAft);
6576 double zbar = (q2-sij-m2Rec) / bABC(q2,sij,m2Rec)
6577 * (zCS - m2Rec/gABC(q2,sij,m2Rec)
6578 *(sij + m2RadAft - m2EmtAft)/(q2-sij-m2Rec));
6579 double kT2 = zbar*(1.-zbar)*sij - (1.-zbar)*m2RadAft - zbar*m2EmtAft;
6581 bool physical =
true;
6582 if (kT2 < 0. || isnan(kT2)) physical =
false;
6583 if (abs(kT2) < 1e-9) kT2 = 0.0;
6586 Vec4 pij(q-pRecBef);
6589 pair <Vec4, Vec4> pTvecs = getTwoPerpendicular(pRecBef, pij);
6590 Vec4 kTmom( sqrt(kT2)*sin(phi)*pTvecs.first
6591 + sqrt(kT2)*cos(phi)*pTvecs.second);
6594 Vec4 pRad( zbar * (gABC(q2,sij,m2Rec)*pij - sij*pRecBef)/bABC(q2,sij,m2Rec)
6595 + (m2RadAft+kT2) / (zbar*bABC(q2,sij,m2Rec))
6596 * (pRecBef - m2Rec/gABC(q2,sij,m2Rec)*pij)
6600 Vec4 pEmt(q-pRad-pRecBef);
6605 pair < Vec4, Vec4 > ret;
6606 if (physical) ret = make_pair(pRad,pEmt);
6613 pair <Vec4, Vec4> DireTimes::decayWithOffshellRec(
double zCS,
double yCS,
6614 double phi,
double m2RadBef,
double m2RadAft,
double m2EmtAft,
6615 Vec4 pRadBef, Vec4 pRecBef ) {
6617 Vec4 q(pRadBef + pRecBef);
6618 double q2 = q.m2Calc();
6620 double sij = yCS * (q2 - m2RadBef) + (1.-yCS)*(m2RadAft+m2EmtAft);
6621 double zbar = (q2-sij-m2RadBef) / bABC(q2,sij,m2RadBef)
6622 * (zCS - m2RadBef/gABC(q2,sij,m2RadBef)
6623 *(sij + m2RadAft - m2EmtAft)/(q2-sij-m2RadBef));
6624 double kT2 = zbar*(1.-zbar)*sij - (1.-zbar)*m2RadAft - zbar*m2EmtAft;
6627 bool physical =
true;
6628 if (kT2 < 0. || isnan(kT2)) physical =
false;
6631 Vec4 pij(q-pRadBef);
6634 pair < Vec4, Vec4> pTvecs = getTwoPerpendicular(pRadBef, pij);
6635 Vec4 kTmom( sqrt(kT2)*sin(phi)*pTvecs.first
6636 + sqrt(kT2)*cos(phi)*pTvecs.second);
6639 Vec4 pRec2( zbar * (gABC(q2,sij,m2RadBef)*pij - sij*pRadBef)
6640 / bABC(q2,sij,m2RadBef)
6641 + (m2RadAft+kT2) / (zbar*bABC(q2,sij,m2RadBef))
6642 * (pRadBef - m2RadBef/gABC(q2,sij,m2RadBef)*pij)
6646 Vec4 pRec1(q-pRec2-pRadBef);
6649 pair < Vec4, Vec4 > ret;
6650 if (physical) ret = make_pair(pRec1,pRec2);
6657 pair <Event, pair<int,int> > DireTimes::clustered_internal(
const Event& state,
6658 int iRad,
int iEmt,
int iRec,
string name ) {
6660 if (name.compare(
"Dire_fsr_qcd_1->21&1") == 0 && state[iRad].id() == 21)
6662 if (name.compare(
"Dire_fsr_qed_1->22&1") == 0 && state[iRad].id() == 22)
6664 if (name.compare(
"Dire_fsr_qed_11->22&11") == 0 && state[iRad].id() == 22)
6668 int radType = state[iRad].isFinal() ? 1 : -1;
6669 int recType = state[iRec].isFinal() ? 1 : -1;
6673 NewEvent.init(
"(hard process-modified)", particleDataPtr);
6676 for (
int i = 0; i < state.size(); ++i)
6677 if ( i != iRad && i != iRec && i != iEmt )
6678 NewEvent.append( state[i] );
6681 for (
int i = 0; i < state.sizeJunction(); ++i)
6682 NewEvent.appendJunction( state.getJunction(i) );
6684 double mu = infoPtr->QFac();
6686 NewEvent.saveSize();
6687 NewEvent.saveJunctionSize();
6689 NewEvent.scaleSecond(mu);
6693 Particle RecBefore = Particle( state[iRec] );
6694 RecBefore.setEvtPtr(&NewEvent);
6695 RecBefore.daughters(0,0);
6698 int radID = splits[name]->radBefID(state[iRad].
id(), state[iEmt].
id());
6699 int recID = state[iRec].id();
6700 Particle RadBefore = Particle( state[iRad] );
6701 RadBefore.setEvtPtr(&NewEvent);
6702 RadBefore.id(radID);
6703 RadBefore.daughters(0,0);
6705 RadBefore.cols(RecBefore.acol(),RecBefore.col());
6708 if ( particleDataPtr->isResonance(radID) && radType == 1)
6709 RadBefore.status(22);
6712 double radMass = particleDataPtr->m0(radID);
6713 double recMass = particleDataPtr->m0(recID);
6714 if (radType == 1 ) RadBefore.m(radMass);
6715 else RadBefore.m(0.0);
6716 if (recType == 1 ) RecBefore.m(recMass);
6717 else RecBefore.m(0.0);
6719 if ( particleDataPtr->isResonance(radID) && radType == 1 )
6720 RadBefore.m( (state[iRad].p()+state[iEmt].p()).mCalc() );
6721 if ( particleDataPtr->isResonance(recID) && radType == 1 )
6722 RadBefore.m( state[iRec].mCalc() );
6725 bool validState =
false;
6726 if ( state[iRec].isFinal())
6727 validState = cluster_FF(state,iRad,iEmt,iRec,radID,RadBefore,RecBefore);
6729 validState = cluster_FI(state,iRad,iEmt,iRec,radID,RadBefore,RecBefore);
6732 RecBefore.scale(mu);
6733 RadBefore.scale(mu);
6736 NewEvent.append(RecBefore);
6739 pair<int,int> cols = splits[name]->radBefCols( state[iRad].col(),
6740 state[iRad].acol(), state[iEmt].col(), state[iEmt].acol());
6741 RadBefore.cols( cols.first, cols.second );
6745 outState.init(
"(hard process-modified)", particleDataPtr);
6749 if (!validState) {
return make_pair(outState, make_pair(0,0)); }
6752 for (
int i = 0; i < 3; ++i)
6753 outState.append( NewEvent[i] );
6755 for (
int i = 0; i < state.sizeJunction(); ++i)
6756 outState.appendJunction( state.getJunction(i) );
6758 outState.saveSize();
6759 outState.saveJunctionSize();
6761 outState.scaleSecond(mu);
6762 bool radAppended =
false;
6763 bool recAppended =
false;
6764 int size = int(outState.size());
6766 int radPos(0), recPos(0);
6769 if ( RecBefore.mother1() == 1) {
6770 recPos = outState.append( RecBefore );
6772 }
else if ( RadBefore.mother1() == 1 ) {
6773 radPos = outState.append( RadBefore );
6778 for(
int i=0; i < int(state.size()); ++i)
6779 if (state[i].mother1() == 1) in1 =i;
6780 outState.append( state[in1] );
6784 if ( RecBefore.mother1() == 2) {
6785 recPos = outState.append( RecBefore );
6787 }
else if ( RadBefore.mother1() == 2 ) {
6788 radPos = outState.append( RadBefore );
6793 for(
int i=0; i < int(state.size()); ++i)
6794 if (state[i].mother1() == 2) in2 =i;
6796 outState.append( state[in2] );
6801 if (!recAppended && !RecBefore.isFinal()) {
6803 recPos = outState.append( RecBefore);
6806 if (!radAppended && !RadBefore.isFinal()) {
6808 radPos = outState.append( RadBefore);
6813 for (
int i = 0; i < int(NewEvent.size()-1); ++i) {
6814 if (NewEvent[i].status() != -22)
continue;
6815 if ( NewEvent[i].daughter1() == NewEvent[i].daughter2()
6816 && NewEvent[i].daughter1() > 0)
continue;
6817 outState.append( NewEvent[i] );
6821 for (
int i = 0; i < int(NewEvent.size()-1); ++i)
6822 if (NewEvent[i].status() == 22) {
6823 outState.append( NewEvent[i] );
6826 if (!radAppended && RadBefore.statusAbs() == 22)
6827 radPos = outState.append(RadBefore);
6829 recPos= outState.append(RecBefore);
6830 if (!radAppended && RadBefore.statusAbs() != 22)
6831 radPos = outState.append(RadBefore);
6833 for(
int i = 0; i < int(NewEvent.size()-1); ++i)
6834 if ( NewEvent[i].status() != 22
6835 && NewEvent[i].colType() != 0
6836 && NewEvent[i].isFinal())
6837 outState.append( NewEvent[i] );
6839 for(
int i = 0; i < int(NewEvent.size()-1); ++i)
6840 if ( NewEvent[i].status() != 22
6841 && NewEvent[i].colType() == 0
6842 && NewEvent[i].isFinal() )
6843 outState.append( NewEvent[i]);
6846 vector<int> PosIntermediate;
6847 vector<int> PosDaughter1;
6848 vector<int> PosDaughter2;
6849 for(
int i=0; i < int(outState.size()); ++i) {
6850 if (outState[i].status() == -22) {
6851 PosIntermediate.push_back(i);
6852 int d1 = outState[i].daughter1();
6853 int d2 = outState[i].daughter2();
6855 int daughter1 = FindParticle( state[d1], outState);
6856 int daughter2 = FindParticle( state[d2], outState);
6862 PosDaughter1.push_back( daughter1);
6865 while(!outState[daughter1].isFinal() ) daughter1++;
6866 PosDaughter1.push_back( daughter1);
6869 PosDaughter2.push_back( daughter2);
6871 daughter2 = outState.size()-1;
6872 while(!outState[daughter2].isFinal() ) daughter2--;
6873 PosDaughter2.push_back( daughter2);
6879 while(!outState[iOut1].isFinal() ) iOut1++;
6880 int iOut2 = outState.size()-1;
6881 while(!outState[iOut2].isFinal() ) iOut2--;
6884 for(
int i=0; i < int(PosIntermediate.size()); ++i) {
6885 outState[PosIntermediate[i]].daughters(PosDaughter1[i],PosDaughter2[i]);
6886 outState[PosDaughter1[i]].mother1(PosIntermediate[i]);
6887 outState[PosDaughter2[i]].mother1(PosIntermediate[i]);
6888 outState[PosDaughter1[i]].mother2(0);
6889 outState[PosDaughter2[i]].mother2(0);
6893 for (
int i=0; i < int(outState.size()); ++i) {
6894 if (outState[i].isFinal()) outState[i].status(23);
6898 int minParFinal = int(outState.size());
6899 int maxParFinal = 0;
6900 for(
int i=0; i < int(outState.size()); ++i)
6901 if (outState[i].mother1() == 3 && outState[i].mother2() == 4) {
6902 minParFinal = min(i,minParFinal);
6903 maxParFinal = max(i,maxParFinal);
6906 if (minParFinal == maxParFinal) maxParFinal = 0;
6907 outState[3].daughters(minParFinal,maxParFinal);
6908 outState[4].daughters(minParFinal,maxParFinal);
6911 outState.saveSize();
6912 outState.saveJunctionSize();
6926 if ( radType == -1 && state[iRad].colType() == 1) {
6928 for(
int i=0; i < int(state.size()); ++i)
6929 if ( i != iRad && i != iEmt && i != iRec
6930 && state[i].status() == -22
6931 && state[i].col() == state[iRad].col() )
6933 }
else if ( radType == -1 && state[iRad].colType() == -1) {
6935 for(
int i=0; i < int(state.size()); ++i)
6936 if ( i != iRad && i != iEmt && i != iRec
6937 && state[i].status() == -22
6938 && state[i].acol() == state[iRad].acol() )
6940 }
else if ( radType == 1 && state[iRad].colType() == 1) {
6942 for(
int i=0; i < int(state.size()); ++i)
6943 if ( i != iRad && i != iEmt && i != iRec
6944 && state[i].status() == -22
6945 && state[i].col() == state[iRad].col() )
6947 }
else if ( radType == 1 && state[iRad].colType() == -1) {
6949 for(
int i=0; i < int(state.size()); ++i)
6950 if ( i != iRad && i != iEmt && i != iRec
6951 && state[i].status() == -22
6952 && state[i].acol() == state[iRad].acol() )
6958 int iColResNow = FindParticle( state[iColRes], outState);
6961 int radCol = outState[radPos].col();
6962 int radAcl = outState[radPos].acol();
6964 int resCol = outState[iColResNow].col();
6965 int resAcl = outState[iColResNow].acol();
6967 bool matchesRes = (radCol > 0
6968 && ( radCol == resCol || radCol == resAcl))
6970 && ( radAcl == resCol || radAcl == resAcl));
6974 if (!matchesRes && iColResNow > 0) {
6975 if ( radType == -1 && outState[radPos].colType() == 1)
6976 outState[iColResNow].col(radCol);
6977 else if ( radType ==-1 && outState[radPos].colType() ==-1)
6978 outState[iColResNow].acol(radAcl);
6979 else if ( radType == 1 && outState[radPos].colType() == 1)
6980 outState[iColResNow].col(radCol);
6981 else if ( radType == 1 && outState[radPos].colType() ==-1)
6982 outState[iColResNow].acol(radAcl);
6988 if (!matchesRes && iColResNow > 0 && iColRes != iColResNow)
6989 outState[radPos].mother1(iColResNow);
6994 for (
int i=0; i < int(outState.size()); ++i) {
6995 if (outState[i].isFinal()) outState[i].status(23);
6999 outState[3].status(-21);
7000 outState[4].status(-21);
7003 for (
int i = 0; i < outState.size(); ++i) {
7004 if ( outState[i].status() == 23 && particleDataPtr->
7005 isResonance(outState[i].
id())) outState[i].status(22);
7009 if (!validEvent( outState,
true )) { outState.clear(); }
7012 return make_pair(outState, make_pair(radPos,recPos));
7016 bool DireTimes::cluster_FF(
const Event& state,
7017 int iRad,
int iEmt,
int iRec,
int idRadBef, Particle& radBef,
7018 Particle& recBef ) {
7021 double pT2 = pT2_FF(state[iRad], state[iEmt], state[iRec]);
7022 double z = z_FF(state[iRad], state[iEmt], state[iRec]);
7025 double m2Bef = ( abs(idRadBef) < 6 || idRadBef == 21 || idRadBef == 22)
7026 ? getMass(idRadBef,2)
7027 : (idRadBef == state[iRad].id())
7028 ? getMass(idRadBef,3,state[iRad].mCalc())
7029 : getMass(idRadBef,2);
7032 if ( particleDataPtr->isResonance(idRadBef)
7033 && !particleDataPtr->isResonance(state[iRad].
id())
7034 && !particleDataPtr->isResonance(state[iEmt].
id()) )
7035 m2Bef = (state[iRad].p()+state[iEmt].p()).m2Calc();
7037 double m2r = state[iRad].p().m2Calc();
7038 double m2e = state[iEmt].p().m2Calc();
7039 double m2s = state[iRec].p().m2Calc();
7041 double m2D = 2.*state[iRad].p()*state[iRec].p()
7042 + 2.*state[iRad].p()*state[iEmt].p()
7043 + 2.*state[iRec].p()*state[iEmt].p();
7044 double Q2 = m2D + (m2Bef - m2r - m2e);
7047 Vec4 q(state[iRad].p() + state[iEmt].p() + state[iRec].p());
7048 double q2 = q.m2Calc();
7052 if ( m2Bef > TINYMASS || m2r > TINYMASS || m2s > TINYMASS
7053 || m2e > TINYMASS ) type = 2;
7056 if ( !inAllowedPhasespace(1, z, pT2, Q2, q2, 0.0, type, m2Bef, m2r, m2s,
7057 m2e) )
return false;
7060 double sij = (state[iRad].p() + state[iEmt].p()).m2Calc();
7063 Vec4 pRec(state[iRec].p());
7064 Vec4 pRecBef( (pRec - (q*pRec)/q2 * q)
7065 * sqrt(lABC(q2,m2Bef,m2s)/lABC(q2,sij,m2s))
7066 + q * (q2+m2s-m2Bef)/(2.*q2) );
7069 Vec4 pRadBef(q-pRecBef);
7073 radBef.m(sqrtpos(m2Bef));
7074 recBef.m(sqrtpos(m2s));
7080 bool DireTimes::cluster_FI(
const Event& state,
7081 int iRad,
int iEmt,
int iRec,
int idRadBef, Particle& radBef,
7082 Particle& recBef ) {
7085 double pT2 = pT2_FI(state[iRad], state[iEmt], state[iRec]);
7086 double z = z_FI(state[iRad], state[iEmt], state[iRec]);
7089 double m2Bef = ( abs(idRadBef) < 6 || idRadBef == 21 || idRadBef == 22)
7090 ? getMass(idRadBef,2)
7091 : (idRadBef == state[iRad].id())
7092 ? getMass(idRadBef,3,state[iRad].mCalc())
7093 : getMass(idRadBef,2);
7096 if ( particleDataPtr->isResonance(idRadBef)
7097 && !particleDataPtr->isResonance(state[iRad].
id())
7098 && !particleDataPtr->isResonance(state[iEmt].
id()) )
7099 m2Bef = (state[iRad].p()+state[iEmt].p()).m2Calc();
7101 double m2r = state[iRad].p().m2Calc();
7102 double m2e = state[iEmt].p().m2Calc();
7103 double m2s = state[iRec].p().m2Calc();
7105 double m2D = -2.*state[iRad].p()*state[iEmt].p()
7106 + 2.*state[iRad].p()*state[iRec].p()
7107 + 2.*state[iRec].p()*state[iEmt].p();
7111 Vec4 q(-state[iRad].p() - state[iEmt].p() + state[iRec].p());
7112 double q2 = q.m2Calc();
7115 for (
int i=3; i < state.size(); ++i)
7116 if (i != iRad && i != iEmt && i != iRec) iOther.push_back(i);
7118 if ( (iOther.size() == 1 || abs(q.m2Calc()) < TINYMASS) && m2Bef > 0.) {
7121 Vec4 pRadBef( state[iRad].p() + state[iEmt].p() );
7124 double errMass = abs(pRadBef.mCalc() - sqrt(m2Bef))
7125 / max( 1.0, pRadBef.e());
7126 if ( errMass > mTolErr*1e-2 ) {
7127 double deltam2 = pRadBef.m2Calc() - m2Bef;
7128 pRadBef.e(sqrtpos(pow2(pRadBef.e()) - deltam2));
7130 Vec4 pRecBef( state[iRec].p() );
7132 errMass = abs(pRecBef.mCalc() - sqrt(m2s)) / max( 1.0, pRecBef.e());
7133 if ( errMass > mTolErr*1e-2 ) {
7134 double deltam2 = pRecBef.m2Calc() - m2s;
7135 pRecBef.e(sqrtpos(pow2(pRecBef.e()) - deltam2));
7139 radBef.m(sqrtpos(m2Bef));
7140 recBef.m(sqrtpos(m2s));
7146 double xNew = 2. * state[iRec].e() / state[0].m();
7149 double kappa2 = pT2/Q2;
7150 double xCS = 1 - kappa2/(1.-z);
7151 double xCDST = xCS*( 1. + (m2Bef-m2r-m2e)/Q2 );
7152 double xOld = xNew * xCDST;
7156 if ( m2Bef > TINYMASS || m2r > TINYMASS || m2s > TINYMASS
7157 || m2e > TINYMASS ) type = -2;
7159 bool hasPDFrec = (state[iRec].colType() != 0
7160 || (state[iRec].isLepton() && settingsPtr->flag(
"PDF:lepton")));
7161 double xMin = (hasPDFrec) ? xOld : 0.;
7162 if ( !inAllowedPhasespace( 1, z, pT2, Q2, q2, xMin, type, m2Bef, m2r, m2s,
7163 m2e) )
return false;
7165 Vec4 pRad(state[iRad].p());
7166 Vec4 pRec(state[iRec].p());
7167 Vec4 pEmt(state[iEmt].p());
7168 Vec4 qpar(q.px()+pRad.px()+pEmt.px(), q.py()+pRad.py()+pEmt.py(), q.pz(),
7170 double qpar2 = qpar.m2Calc();
7171 double pT2ijt = pow2(pRad.px()+pEmt.px()) + pow2(pRad.py()+pEmt.py());
7174 double sij = (state[iRad].p() + state[iEmt].p()).m2Calc();
7177 Vec4 pRecBef( (pRec - (q*pRec)/qpar2 * qpar)
7178 * sqrt( (lABC(q2,m2Bef,m2s) - 4.*m2s*pT2ijt)
7179 /(lABC(q2,sij,m2s) - 4.*m2s*pT2ijt))
7180 + qpar * (q2+m2s-m2Bef)/(2.*qpar2) );
7183 Vec4 pRadBef(-q+pRecBef);
7186 double errMass = abs(pRadBef.mCalc() - sqrt(m2Bef)) / max( 1.0, pRadBef.e());
7187 if ( errMass > mTolErr*1e-2 ) {
7188 double deltam2 = pRadBef.m2Calc() - m2Bef;
7189 pRadBef.e(sqrtpos(pow2(pRadBef.e()) - deltam2));
7192 errMass = abs(pRecBef.mCalc() - sqrt(m2s)) / max( 1.0, pRecBef.e());
7193 if ( errMass > mTolErr*1e-2 ) {
7194 double deltam2 = pRecBef.m2Calc() - m2s;
7195 pRecBef.e(sqrtpos(pow2(pRecBef.e()) - deltam2));
7200 radBef.m(sqrtpos(m2Bef));
7201 recBef.m(sqrtpos(m2s));
7216 int DireTimes::FindParticle(
const Particle& particle,
const Event& event,
7217 bool checkStatus ) {
7221 for (
int i =
int(event.size()) - 1; i > 0; --i )
7222 if ( event[i].
id() == particle.id()
7223 &&
event[i].colType() == particle.colType()
7224 &&
event[i].chargeType() == particle.chargeType()
7225 &&
event[i].col() == particle.col()
7226 &&
event[i].acol() == particle.acol()
7227 &&
event[i].charge() == particle.charge() ) {
7232 if ( checkStatus && event[index].status() != particle.status() )
7240 double DireTimes::pT2_FF (
const Particle& rad,
const Particle& emt,
7241 const Particle& rec) {
7242 double sij = 2.*rad.p()*emt.p();
7243 double sik = 2.*rad.p()*rec.p();
7244 double sjk = 2.*rec.p()*emt.p();
7245 return sij*sjk / (sij+sik+sjk);
7250 double DireTimes::pT2_FI (
const Particle& rad,
const Particle& emt,
7251 const Particle& rec) {
7252 double sij = 2.*rad.p()*emt.p();
7253 double sai = -2.*rec.p()*rad.p();
7254 double saj = -2.*rec.p()*emt.p();
7256 double t = sij*saj / (sai+saj) * (sij+saj+sai) / (sai+saj) ;
7257 if (sij+saj+sai < 1e-5 && abs(sij+saj+sai) < 1e-5) t = sij;
7264 double DireTimes::z_FF (
const Particle& rad,
const Particle& emt,
7265 const Particle& rec) {
7266 double sij = 2.*rad.p()*emt.p();
7267 double sik = 2.*rad.p()*rec.p();
7268 double sjk = 2.*rec.p()*emt.p();
7269 return (sij + sik) / (sij+sik+sjk);
7272 double DireTimes::z_FF_fromVec (
const Vec4& rad,
const Vec4& emt,
7274 double sij = 2.*rad*emt;
7275 double sik = 2.*rad*rec;
7276 double sjk = 2.*rec*emt;
7277 return (sij + sik) / (sij+sik+sjk);
7282 double DireTimes::z_FI (
const Particle& rad,
const Particle& emt,
7283 const Particle& rec) {
7284 double sai = -2.*rec.p()*rad.p();
7285 double saj = -2.*rec.p()*emt.p();
7286 return sai / (sai+saj);
7291 double DireTimes::m2dip_FF (
const Particle& rad,
const Particle& emt,
7292 const Particle& rec) {
7293 double sij = 2.*rad.p()*emt.p();
7294 double sik = 2.*rad.p()*rec.p();
7295 double sjk = 2.*rec.p()*emt.p();
7296 return (sij+sik+sjk);
7301 double DireTimes::m2dip_FI (
const Particle& rad,
const Particle& emt,
7302 const Particle& rec) {
7303 double sij = 2.*rad.p()*emt.p();
7304 double sai = -2.*rec.p()*rad.p();
7305 double saj = -2.*rec.p()*emt.p();
7306 return -1.*(sij+saj+sai);
7315 map<string, double> DireTimes::getStateVariables (
const Event& state,
7316 int rad,
int emt,
int rec,
string name) {
7317 map<string,double> ret;
7320 if (rad > 0 && emt > 0 && rec > 0) {
7322 double pT2 = pT2Times ( state[rad], state[emt], state[rec]);
7323 double z = zTimes ( state[rad], state[emt], state[rec]);
7324 ret.insert(make_pair(
"t",pT2));
7325 ret.insert(make_pair(
"tRS",pT2));
7326 ret.insert(make_pair(
"scaleAS",pT2));
7327 ret.insert(make_pair(
"scaleEM",pT2));
7328 ret.insert(make_pair(
"scalePDF",pT2));
7329 ret.insert(make_pair(
"z",z));
7334 ? (*splittingsPtr)[name]->radBefID(state[rad].
id(), state[emt].
id())
7336 pair<int,int> radBefCols
7338 ? (*splittingsPtr)[name]->radBefCols(state[rad].col(),
7339 state[rad].acol(), state[emt].col(), state[emt].acol())
7341 ret.insert(make_pair(
"radBefID", radBefID));
7342 ret.insert(make_pair(
"radBefCol", radBefCols.first));
7343 ret.insert(make_pair(
"radBefAcol", radBefCols.second));
7347 ? (*splittingsPtr)[name]->couplingType(state[rad].
id(), state[emt].
id())
7349 double couplingValue
7351 ? (*splittingsPtr)[name]->coupling(z,pT2)
7353 ret.insert(make_pair
7354 (
"scaleForCoupling " + std::to_string(couplingType), pT2));
7355 ret.insert(make_pair(
"couplingType",couplingType));
7356 ret.insert(make_pair(
"couplingValue",couplingValue));
7358 double m2dip = m2dipTimes ( state[rad], state[emt], state[rec]);
7359 ret.insert(make_pair(
"m2dip", m2dip));
7365 ret.insert(make_pair(
"t",0.));
7366 ret.insert(make_pair(
"tRS",0.));
7367 ret.insert(make_pair(
"scaleAS",0.));
7368 ret.insert(make_pair(
"scaleEM",0.));
7369 ret.insert(make_pair(
"z",0.));
7370 ret.insert(make_pair(
"radBefID", 0));
7371 ret.insert(make_pair(
"radBefCol", 0));
7372 ret.insert(make_pair(
"radBefAcol", 0));
7373 ret.insert(make_pair(
"scaleForCoupling "+std::to_string(-1),0.));
7374 ret.insert(make_pair(
"couplingType",-1));
7375 ret.insert(make_pair(
"couplingValue",-1.));
7378 vector<DireTimesEnd> dipEnds;
7381 for (
int iRad = 0; iRad < state.size(); ++iRad) {
7383 if ( !state[iRad].isFinal() )
continue;
7386 int colTag = state[iRad].col();
7387 if (colTag > 0) getQCDdip( iRad, colTag, 1, state, dipEnds);
7389 int acolTag = state[iRad].acol();
7390 if (acolTag > 0) getQCDdip( iRad, acolTag, -1, state, dipEnds);
7392 getGenDip( -1, 0, iRad, state,
false, dipEnds);
7398 double x1 = state[3].pPos() / state[0].m();
7399 double x2 = state[4].pNeg() / state[0].m();
7403 for (
int iDip = 0; iDip < int(dipEnds.size()); ++iDip) {
7404 double m2 = abs(2.*state[dipEnds[iDip].iRadiator].p()
7405 *state[dipEnds[iDip].iRecoiler].p());
7406 if ( dipEnds[iDip].iRecoiler == in1) m2 /= x1;
7407 if ( dipEnds[iDip].iRecoiler == in2) m2 /= x2;
7409 oss <<
"scalePDF-" << dipEnds[iDip].iRadiator
7410 <<
"-" << dipEnds[iDip].iRecoiler;
7411 ret.insert(make_pair(oss.str(),m2));
7424 double DireTimes::getSplittingProb(
const Event& state,
int iRad,
7425 int iEmt,
int iRec,
string name) {
7428 int order = atoi( (
char*)name.substr( name.find(
"-",0)+1,
7429 name.size() ).c_str() );
7430 name=name.substr( 0, name.size()-2);
7434 if ( splits[name]->splitInfo.extras.find(
"unitKernel")
7435 != splits[name]->splitInfo.extras.end() )
return 1.;
7437 double z = zTimes(state[iRad], state[iEmt], state[iRec]);
7438 double pT2 = pT2Times(state[iRad], state[iEmt], state[iRec]);
7439 double m2D = (state[iRec].isFinal())
7440 ? abs( 2.*state[iEmt].p()*state[iRad].p()
7441 + 2.*state[iRec].p()*state[iRad].p()
7442 + 2.*state[iEmt].p()*state[iRec].p())
7443 : abs( 2.*state[iEmt].p()*state[iRad].p()
7444 - 2.*state[iRec].p()*state[iRad].p()
7445 - 2.*state[iEmt].p()*state[iRec].p());
7448 if ( pT2cut(state[iEmt].
id()) > pT2)
return 0.;
7449 if ( !splits[name]->aboveCutoff( pT2, state[iRad], state[iRec], 0,
7450 partonSystemsPtr))
return 0.;
7452 int idRadBef = splits[name]->radBefID(state[iRad].
id(), state[iEmt].
id());
7454 double m2Bef = ( abs(idRadBef) < 6 || idRadBef == 21 || idRadBef == 22)
7455 ? getMass(idRadBef,2)
7456 : (idRadBef == state[iRad].id())
7457 ? getMass(idRadBef,3,state[iRad].mCalc())
7458 : getMass(idRadBef,2);
7459 double m2r = state[iRad].p().m2Calc();
7460 double m2e = state[iEmt].p().m2Calc();
7461 double m2s = state[iRec].p().m2Calc();
7462 int type = state[iRec].isFinal() ? 1 : -1;
7465 if (type == 1 && (m2Bef > TINYMASS || m2r > TINYMASS || m2s > TINYMASS
7466 || m2e > TINYMASS) ) type = 2;
7467 if (type ==-1 && (m2Bef > TINYMASS || m2r > TINYMASS || m2s > TINYMASS
7468 || m2e > TINYMASS) ) type =-2;
7471 int massSign = (type > 0) ? 1 : -1;
7472 double q2 = (state[iRec].p() + massSign*state[iRad].p()
7473 + massSign*state[iEmt].p()).m2Calc();
7476 double kappa2 = pT2/Q2;
7477 double xCS = 1 - kappa2/(1.-z);
7478 double xNew = (type > 0) ? 0.0 : 2.*state[iRec].e() / state[0].m();
7479 double xOld = (type > 0) ? 0.0 : xCS * xNew;
7482 bool hasPDFrec = type < 0 && (state[iRec].colType() != 0
7483 || (state[iRec].isLepton() && settingsPtr->flag(
"PDF:lepton")));
7484 double xMin = (hasPDFrec) ? xOld : 0.;
7486 if (abs(q2) < 1e-5) {
7487 q2 = Q2 = (state[iRad].p() + state[iEmt].p()).m2Calc();
7492 if (name.compare(
"Dire_fsr_qcd_1->21&1") == 0) swap(iRad,iEmt);
7493 if (name.compare(
"Dire_fsr_qed_1->22&1") == 0) swap(iRad,iEmt);
7494 if (name.compare(
"Dire_fsr_qed_11->22&11") == 0) swap(iRad,iEmt);
7499 if ( !inAllowedPhasespace( 1, z, pT2, Q2, q2, xMin, type, m2Bef, m2r, m2s,
7506 pair<Vec4, Vec4> pTdirection = getTwoPerpendicular(state[iRec].p(),
7507 state[iRad].p()+state[iEmt].p());
7508 double px= -pTdirection.first*state[iRad].p();
7509 double py= -pTdirection.second*state[iRad].p();
7510 double kT2 = pow2(px)+pow2(py);
7511 double phi1 = atan2(px/sqrt(kT2), py/sqrt(kT2));
7512 if (phi1 < 0.) phi1 = 2.*M_PI+phi1;
7514 pair <Event, pair<int,int> > born(clustered_internal(
7515 state, iRad, iEmt, iRec, name ));
7517 int nEmissions = splittingsPtr->nEmissions(name);
7518 double m2dipBef = abs(2.*born.first[born.second.first].p()
7519 *born.first[born.second.second].p());
7520 splits[name]->splitInfo.save();
7521 splits[name]->splitInfo.clear();
7522 splits[name]->splitInfo.storeInfo(name, type, 0, 0, 0,
7523 born.second.first, born.second.second, born.first,
7524 state[iEmt].id(), state[iRad].id(),
7525 nEmissions, m2dipBef, pT2, pT2, z, phi1, m2Bef, m2s,
7526 (nEmissions == 1 ? m2r : 0.0),(nEmissions == 1 ? m2e : 0.0),
7527 0.0, 0.0, 0.0, 0.0, xOld, xNew);
7528 splits[name]->splitInfo.setSiblings(DireSingleColChain());
7531 unordered_map < string, double > kernels;
7533 if (splits[name]->calc(born.first, order) )
7534 kernels = splits[name]->getKernelVals();
7535 if ( kernels.find(
"base") != kernels.end() ) p += kernels[
"base"];
7537 splits[name]->splitInfo.clear();
7538 splits[name]->splitInfo.restore();
7546 bool hasME = pT2 > pT2minMECs && doMEcorrections && weights->hasME(state);
7547 if (hasME) p = abs(p);
7549 if (!dryrun && splits[name]->hasMECAft(state, pT2)) p *= KERNEL_HEADROOM;
7553 for (
int i=0; i < state.size(); ++i)
if (state[i].isFinal()) nFinal++;
7554 double xDau = (type>0) ? 1. : xOld;
7556 mecover = splits[name]->
7557 overhead(m2dipBef*xDau, state[iRad].
id(), nFinal-1);
7568 bool DireTimes::allowedSplitting(
const Event& state,
int iRad,
int iEmt) {
7570 bool isAP = state[iRad].id() < 0;
7571 int idRad = state[iRad].id();
7572 int idEmt = state[iEmt].id();
7574 int colRad = state[iRad].col();
7575 int acolRad = state[iRad].acol();
7576 int colEmt = state[iEmt].col();
7577 int acolEmt = state[iEmt].acol();
7579 int colShared = (colRad > 0 && colRad == acolEmt) ? colRad
7580 : (acolRad > 0 && colEmt == acolRad) ? colEmt : 0;
7583 if ( state[iRad].status() < 0)
return false;
7586 if (idEmt == 21 && colShared > 0)
7590 if (idRad == 21 && colShared > 0)
7594 if ( idEmt == -idRad
7595 && state[iEmt].colType() != 0
7596 && ( (isAP && acolRad != colEmt) || (!isAP && acolEmt != colRad) ) )
7601 if ( idEmt == 22 && abs(idRad) < 10)
7603 if ( idRad == 22 && abs(idEmt) < 10)
7607 if ( idEmt == 22 && (abs(idRad) == 11 || abs(idRad) == 13
7608 || abs(idRad) == 15))
7610 if ( idRad == 22 && (abs(idEmt) == 11 || abs(idEmt) == 13
7611 || abs(idEmt) == 15))
7616 if ( idEmt == 23 && abs(idRad) < 10)
7618 if ( idRad == 23 && abs(idEmt) < 10)
7622 if ( idEmt == 22 && (abs(idRad) == 11 || abs(idRad) == 13
7623 || abs(idRad) == 15))
7625 if ( idRad == 22 && (abs(idEmt) == 11 || abs(idEmt) == 13
7626 || abs(idEmt) == 15))
7631 if ( idEmt == -idRad && state[iEmt].colType() != 0 && colShared > 0 )
7635 if ( idEmt == -idRad && state[iEmt].colType() == 0 )
7640 int emtSign = (idEmt>0) ? 1 : -1;
7641 int radSign = (idRad>0) ? 1 : -1;
7642 if ( emtSign*( abs(idEmt)+1 ) == -idRad
7643 && state[iEmt].colType() != 0 && colShared > 0 )
7645 if ( idEmt == -radSign*(abs(idRad)+1)
7646 && state[iEmt].colType() != 0 && colShared > 0 )
7651 if ( idEmt == idRad && idRad == 22 )
7660 vector<int> DireTimes::getRecoilers(
const Event& state,
int iRad,
int iEmt,
7663 return splits[name]->recPositions(state, iRad, iEmt);
7668 Event DireTimes::makeHardEvent(
int iSys,
const Event& state,
bool isProcess) {
7670 bool hasSystems = !isProcess && partonSystemsPtr->sizeSys() > 0;
7671 int sizeSys = (hasSystems) ? partonSystemsPtr->sizeSys() : 1;
7675 event.init(
"(hard process-modified)", particleDataPtr );
7678 for (
int i = state.size()-1; i > 0; --i)
7679 if ( state[i].mother1() == 1 && state[i].mother2() == 0
7680 && (!hasSystems || partonSystemsPtr->getSystemOf(i,
true) == iSys))
7682 if (in1 == 0) in1 = partonSystemsPtr->getInA(iSys);
7685 for (
int i = state.size()-1; i > 0; --i)
7686 if ( state[i].mother1() == 2 && state[i].mother2() == 0
7687 && (!hasSystems || partonSystemsPtr->getSystemOf(i,
true) == iSys))
7689 if (in2 == 0) in2 = partonSystemsPtr->getInB(iSys);
7693 bool resonantIncoming =
false;
7694 if ( in1 == 0 && in2 == 0 ) {
7695 int iParentInOther = 0;
7696 int nSys = partonSystemsPtr->sizeAll(iSys);
7697 for (
int iInSys = 0; iInSys < nSys; ++iInSys){
7698 int iNow = partonSystemsPtr->getAll(iSys,iInSys);
7699 for (
int iOtherSys = 0; iOtherSys < sizeSys; ++iOtherSys){
7700 if (iOtherSys == iSys)
continue;
7701 int nOtherSys = partonSystemsPtr->sizeAll(iOtherSys);
7702 for (
int iInOtherSys = 0; iInOtherSys < nOtherSys; ++iInOtherSys){
7703 int iOtherNow = partonSystemsPtr->getAll(iOtherSys,iInOtherSys);
7704 if (state[iNow].isAncestor(iOtherNow)) {
7705 iParentInOther = iOtherNow;
7710 in1 = iParentInOther;
7711 if (iParentInOther) resonantIncoming =
true;
7715 if ( !hasSystems || partonSystemsPtr->hasInAB(iSys) ) {
7716 event.append(state[0]);
7717 i1 =
event.append(state[1]);
7718 event[i1].mothers(0,0);
7719 i2 =
event.append(state[2]);
7720 event[i2].mothers(0,0);
7725 if (resonantIncoming) {
7726 event.append(state[0]);
7729 int beamA =
event.append(state[state[in1].mother1()]);
7730 event[beamA].mothers(0,0);
7731 event[beamA].status(-12);
7732 int beamB =
event.append(state[state[in1].mother2()]);
7733 event[beamB].mothers(0,0);
7734 event[beamB].status(-12);
7736 i1 =
event.append(state[in1]);
7737 event[i1].mothers(beamA,0);
7738 event[i1].daughters(0,0);
7739 event[i1].status(-21);
7740 event[beamA].daughters(i1,0);
7744 inNow =
event.append(state[in1]);
7745 event[inNow].mothers(i1,0);
7746 event[inNow].status(-21);
7747 event[i1].daughters(inNow,0);
7751 inNow =
event.append(state[in2]);
7752 event[inNow].mothers(i2,0);
7753 event[inNow].status(-21);
7754 event[i2].daughters(inNow,0);
7759 int sizeOld =
event.size();
7761 for (
int i = 0; i < state.size(); ++i) {
7766 bool isFin = state[i].isFinal();
7767 bool isInSys = (partonSystemsPtr->getSystemOf(i) == iSys);
7769 if (isFin && (!hasSystems || isInSys) ) {
7770 int iN =
event.append(state[i]);
7771 event[iN].daughters(0,0);
7772 event[iN].mothers(max(0,i1),max(0,i2));
7773 int status = (state[i].statusAbs() == 22) ? state[i].statusAbs() : 23;
7774 if ( particleDataPtr->isResonance(state[i].id()) ) status = 22;
7775 event[iN].status(status);
7779 int iDaughter2 = ((
unsigned int)event.size() > (
unsigned int)sizeOld + 1) ?
7783 if (i1 > -1 && event.size() > sizeOld)
7784 event[i1].daughters(sizeOld, iDaughter2);
7785 if (i2 > -1 && event.size() > sizeOld)
7786 event[i2].daughters(sizeOld, iDaughter2);
7795 bool DireTimes::validMomentum(
const Vec4& p,
int id,
int status) {
7798 if (isnan(p) || isinf(p))
return false;
7801 double mNow = (status < 0) ? 0.
7802 : ((abs(
id) < 6) ? getMass(
id,2) : getMass(id,1));
7804 if (status < 0 && useMassiveBeams
7805 && (abs(
id) == 11 || abs(
id) == 13 || abs(
id) > 900000))
7806 mNow = getMass(
id,1);
7811 if ( particleDataPtr->isResonance(
id) || abs(
id) > 22) mNow = p.mCalc();
7812 double errMass = abs(p.mCalc() - mNow) / max( 1.0, p.e());
7813 if ( errMass > mTolErr )
return false;
7816 if ( p.e() < 0. )
return false;
7826 bool DireTimes::validEvent(
const Event& state,
bool isProcess,
7829 bool validColour =
true;
7830 bool validCharge =
true;
7831 bool validMomenta =
true;
7833 bool hasSystems = !isProcess && partonSystemsPtr->sizeSys() > 0;
7834 int sizeSys = (hasSystems) ? partonSystemsPtr->sizeSys() : 1;
7837 for (
int i = 0; i < state.size(); ++i)
7838 if (isnan(state[i].p()) || isinf(state[i].p()))
return false;
7842 event.init(
"(hard process-modified)", particleDataPtr );
7844 for (
int iSys = 0; iSys < sizeSys; ++iSys) {
7846 if (iSysCheck >= 0 && iSys != iSysCheck)
continue;
7849 if (!validColour || !validCharge )
break;
7852 event.init(
"(hard process-modified)", particleDataPtr );
7855 event = makeHardEvent(iSys, state, isProcess);
7858 for (
int i = 0; i <
event.size(); ++i)
7860 if ( event[i].isFinal() &&
event[i].colType() == 1
7862 && ( FindCol(event[i].col(),vector<int>(1,i),event,1) == 0
7864 && FindCol(event[i].col(),vector<int>(1,i),event,2) == 0 )) {
7865 validColour =
false;
7868 }
else if ( event[i].isFinal() &&
event[i].colType() == -1
7870 && ( FindCol(event[i].acol(),vector<int>(1,i),event,2) == 0
7872 && FindCol(event[i].acol(),vector<int>(1,i),event,1) == 0 )) {
7873 validColour =
false;
7876 }
else if ( event[i].isFinal() &&
event[i].colType() == 2
7878 && ( FindCol(event[i].col(),vector<int>(1,i),event,1) == 0
7880 && FindCol(event[i].col(),vector<int>(1,i),event,2) == 0 )
7882 && ( FindCol(event[i].acol(),vector<int>(1,i),event,2) == 0
7884 && FindCol(event[i].acol(),vector<int>(1,i),event,1) == 0 )) {
7885 validColour =
false;
7889 for(
int i = 0; i <
event.size(); ++i) {
7890 if ( !event[i].isFinal()
7891 &&
event[i].status() != -11
7892 &&
event[i].status() != -12) {
7893 if ( event[i].colType() == 1 &&
event[i].acol()>0) validColour =
false;
7894 if ( event[i].colType() ==-1 &&
event[i].col() >0) validColour =
false;
7896 if ( event[i].isFinal() ) {
7897 if ( event[i].colType() == 1 &&
event[i].acol()>0) validColour =
false;
7898 if ( event[i].colType() ==-1 &&
event[i].col() >0) validColour =
false;
7903 double initCharge = 0.0;
7904 for(
int i = 0; i <
event.size(); ++i)
7905 if ( !event[i].isFinal()
7906 &&
event[i].status() != -11
7907 &&
event[i].status() != -12)
7908 initCharge += event[i].charge();
7909 double finalCharge = 0.0;
7910 for(
int i = 0; i <
event.size(); ++i)
7911 if (event[i].isFinal()) finalCharge += event[i].charge();
7912 if (abs(initCharge-finalCharge) > 1e-12) validCharge =
false;
7915 for (
int i = 0; i <
event.size(); ++i) {
7916 if (event[i].statusAbs() < 20)
continue;
7917 validMomenta = validMomenta && validMomentum(event[i].p(),
7918 event[i].
id(), (event[i].isFinal() ? 1 : -1));
7922 Vec4 pSum(0.,0.,0.,0.);
7923 for (
int i = 0; i <
event.size(); ++i) {
7925 if ( event[i].status() == -21
7926 ||
event[i].status() == -22 ) pSum -= event[i].p();
7927 if ( event[i].isFinal() ) pSum += event[i].p();
7929 if ( abs(pSum.px()) > mTolErr || abs(pSum.py()) > mTolErr)
7930 validMomenta =
false;
7931 if ( !particleDataPtr->isResonance(event[3].id())
7932 && event[3].status() == -21
7933 && (abs(event[3].px()) > mTolErr || abs(event[3].py()) > mTolErr))
7934 validMomenta =
false;
7935 if ( !particleDataPtr->isResonance(event[4].id())
7936 && event[4].status() == -21
7937 && (abs(event[4].px()) > mTolErr || abs(event[4].py()) > mTolErr))
7938 validMomenta =
false;
7941 for (
int i = 0; i <
event.size(); ++i)
7942 if ( (event[i].status() == -21 || event[i].status() == -22
7943 || event[i].isFinal() ) &&
event[i].e() < 0. ) validMomenta =
false;
7947 return (validColour && validCharge && validMomenta);
7952 bool DireTimes::validMotherDaughter(
const Event& event ) {
7956 vector< pair<int,int> > noMotDau;
7959 bool hasBeams =
false;
7960 for (
int i = 0; i <
event.size(); ++i) {
7961 int status =
event[i].status();
7962 if (abs(status) == 12) hasBeams =
true;
7965 vector<int> mList =
event[i].motherList();
7966 vector<int> dList =
event[i].daughterList();
7967 if (mList.size() == 0 && abs(status) != 11 && abs(status) != 12)
7969 if (dList.size() == 0 && status < 0 && status != -11)
7973 for (
int j = 0; j < int(mList.size()); ++j) {
7974 if ( event[mList[j]].daughter1() <= i
7975 &&
event[mList[j]].daughter2() >= i )
continue;
7976 vector<int> dmList =
event[mList[j]].daughterList();
7977 bool foundMatch =
false;
7978 for (
int k = 0; k < int(dmList.size()); ++k)
7979 if (dmList[k] == i) {
7983 if (!hasBeams && mList.size() == 1 && mList[0] == 0) foundMatch =
true;
7985 bool oldPair =
false;
7986 for (
int k = 0; k < int(noMotDau.size()); ++k)
7987 if (noMotDau[k].first == mList[j] && noMotDau[k].second == i) {
7991 if (!oldPair) noMotDau.push_back( make_pair( mList[j], i) );
7996 for (
int j = 0; j < int(dList.size()); ++j) {
7997 if ( event[dList[j]].statusAbs() > 80
7998 &&
event[dList[j]].statusAbs() < 90
7999 &&
event[dList[j]].mother1() <= i
8000 &&
event[dList[j]].mother2() >= i)
continue;
8001 vector<int> mdList =
event[dList[j]].motherList();
8002 bool foundMatch =
false;
8003 for (
int k = 0; k < int(mdList.size()); ++k)
8004 if (mdList[k] == i) {
8009 bool oldPair =
false;
8010 for (
int k = 0; k < int(noMotDau.size()); ++k)
8011 if (noMotDau[k].first == i && noMotDau[k].second == dList[j]) {
8015 if (!oldPair) noMotDau.push_back( make_pair( i, dList[j]) );
8022 if (noMot.size() > 0 || noDau.size() > 0 || noMotDau.size() > 0)
8034 int DireTimes::FindCol(
int col, vector<int> iExc,
const Event& event,
8035 int type,
int iSys) {
8039 int inA = 0, inB = 0;
8040 for (
int i=event.size()-1; i > 0; --i) {
8041 if ( event[i].mother1() == 1 &&
event[i].status() != -31
8042 &&
event[i].status() != -34) {
if (inA == 0) inA = i; }
8043 if ( event[i].mother1() == 2 &&
event[i].status() != -31
8044 &&
event[i].status() != -34) {
if (inB == 0) inB = i; }
8047 inA = partonSystemsPtr->getInA(iSys);
8048 inB = partonSystemsPtr->getInB(iSys);
8052 if (event[inA].status() > 0) {
8054 if (event[0].daughter1() > 0) inA =
event[0].daughter1();
8056 if (event[inB].status() > 0) {
8058 if (event[0].daughter2() > 0) inB =
event[0].daughter2();
8062 for(
int n = 0; n <
event.size(); ++n) {
8064 if ( find(iExc.begin(), iExc.end(), n) != iExc.end() )
continue;
8065 if ( event[n].colType() != 0 &&
event[n].status() > 0 ) {
8066 if ( event[n].acol() == col ) {
8070 if ( event[n].col() == col ) {
8077 for(
int n = event.size()-1; n > 0; --n) {
8079 if ( find(iExc.begin(), iExc.end(), n) != iExc.end() )
continue;
8080 if ( index == 0 && event[n].colType() != 0
8081 && ( n == inA || n == inB) ) {
8082 if ( event[n].acol() == col ) {
8086 if ( event[n].col() == col ) {
8093 if ( type == 1 && index < 0)
return abs(index);
8094 if ( type == 2 && index > 0)
return abs(index);
8113 typedef pair < int, int > pairInt;
8114 typedef vector < pairInt > vectorPairInt;
8133 inline vectorPairInt findParentSystems(
const int sys,
8134 Event& event, PartonSystems* partonSystemsPtr,
bool forwards) {
8136 vectorPairInt parentSystems;
8137 parentSystems.reserve(10);
8142 int iInA = partonSystemsPtr->getInA(iSysCur);
8143 int iInB = partonSystemsPtr->getInB(iSysCur);
8147 if (event[iInA].isRescatteredIncoming()) iIn = iInA;
8148 if (event[iInB].isRescatteredIncoming()) iIn = -iInB;
8151 parentSystems.push_back( pairInt(-iSysCur, iIn) );
8152 if (iIn == 0)
break;
8154 int iInAbs = abs(iIn);
8155 int iMother =
event[iInAbs].mother1();
8156 iSysCur = partonSystemsPtr->getSystemOf(iMother);
8157 if (iSysCur == -1) {
8158 parentSystems.clear();
8166 vectorPairInt::reverse_iterator rit;
8167 for (rit = parentSystems.rbegin(); rit < (parentSystems.rend() - 1);
8169 pairInt &cur = *rit;
8170 pairInt &next = *(rit + 1);
8171 cur.first = -cur.first;
8172 cur.second = (next.second < 0) ? -event[abs(next.second)].mother1() :
8173 event[abs(next.second)].mother1();
8177 return parentSystems;
8184 void DireTimes::list()
const {
8187 cout <<
"\n -------- DIRE DireTimes Dipole Listing ------------------"
8188 <<
"--------------------------------------------------------------"
8190 <<
" i rad rec pTmax col isr"
8191 <<
" sys sysR m2 siblings allowedIds\n"
8192 << fixed << setprecision(3);
8195 for (
int i = 0; i < int(dipEnd.size()); ++i) {
8196 cout << scientific << setprecision(4)
8197 << setw(4) << i <<
" | "
8198 << setw(4) << dipEnd[i].iRadiator <<
" | "
8199 << setw(4) << dipEnd[i].iRecoiler <<
" | "
8200 << setw(11) << dipEnd[i].pTmax <<
" | "
8201 << setw(3) << dipEnd[i].colType <<
" | "
8202 << setw(4) << dipEnd[i].isrType <<
" | "
8203 << setw(4) << dipEnd[i].system <<
" | "
8204 << setw(4) << dipEnd[i].systemRec <<
" | "
8205 << setw(11) << dipEnd[i].m2Dip <<
" | ";
8207 os << dipEnd[i].iSiblings.listPos();
8208 cout << setw(15) << os.str() <<
" | ";
8210 for (
int j = 0; j < int(dipEnd[i].allowedEmissions.size()); ++j)
8211 os << setw(4) << dipEnd[i].allowedEmissions[j];
8212 cout << setw(15) << os.str() << endl;
8216 for ( unordered_map<string,DireSplitting*>::const_iterator it
8217 = splits.begin(); it != splits.end(); ++it ) {
8218 multimap<double,OverheadInfo> bla = it->second->overhead_map;
8219 cout << it->first << endl;
8220 for ( multimap<double, OverheadInfo >::const_iterator itb = bla.begin();
8221 itb != bla.end(); ++itb )
8222 cout <<
" pT2=" << itb->first <<
" " << itb->second.list() << endl;
8227 cout <<
"\n -------- End DIRE DireTimes Dipole Listing --------------"
8228 <<
"--------------------------------------------------------------"
8229 <<
"----------" << endl;
8238 double DireTimes::alphasNow(
double pT2,
double renormMultFacNow,
int iSys ) {
8241 BeamParticle* beam = NULL;
8242 if (beamAPtr != NULL || beamBPtr != NULL) {
8243 beam = (beamAPtr != NULL && particleDataPtr->isHadron(beamAPtr->id()))
8245 : (beamBPtr != NULL && particleDataPtr->isHadron(beamBPtr->id()))
8247 if (beam == NULL && beamAPtr != 0) beam = beamAPtr;
8248 if (beam == NULL && beamBPtr != 0) beam = beamBPtr;
8250 double scale = pT2*renormMultFacNow;
8251 scale = max(scale, pT2colCut);
8254 double asPT2pi = (usePDFalphas && beam != NULL)
8255 ? beam->alphaS(scale) / (2.*M_PI)
8256 : alphaS.alphaS(scale) / (2.*M_PI);
8259 int order = kernelOrder-1;
8261 bool hasInA = (partonSystemsPtr->getInA(iSys) != 0);
8262 bool hasInB = (partonSystemsPtr->getInB(iSys) != 0);
8263 if (iSys != 0 && hasInA && hasInB) order = kernelOrderMPI-1;
8267 double m2cNow = m2cPhys;
8268 if ( !( (scale > m2cNow && pT2 < m2cNow)
8269 || (scale < m2cNow && pT2 > m2cNow) )) m2cNow = -1.;
8270 double m2bNow = m2bPhys;
8271 if ( !( (scale > m2bNow && pT2 < m2bNow)
8272 || (scale < m2bNow && pT2 > m2bNow) ) ) m2bNow = -1.;
8273 vector<double> scales;
8274 scales.push_back(scale);
8275 scales.push_back(pT2);
8276 if (m2cNow > 0.) scales.push_back(m2cNow);
8277 if (m2bNow > 0.) scales.push_back(m2bNow);
8278 sort( scales.begin(), scales.end());
8279 if (scale > pT2) reverse(scales.begin(), scales.end());
8281 double asPT2piCorr = asPT2pi;
8282 for (
int i = 1; i< int(scales.size()); ++i) {
8283 double NF = getNF( 0.5*(scales[i]+scales[i-1]) );
8284 double L = log( scales[i]/scales[i-1] );
8286 if (order > 0) subt += asPT2piCorr * beta0(NF) * L;
8287 if (order > 2) subt += pow2( asPT2piCorr ) * ( beta1(NF)*L
8288 - pow2(beta0(NF)*L) );
8289 if (order > 4) subt += pow( asPT2piCorr, 3) * ( beta2(NF)*L
8290 - 2.5 * beta0(NF)*beta1(NF)*L*L
8291 + pow( beta0(NF)*L, 3) );
8292 asPT2piCorr *= 1.0 - subt;
8305 double DireTimes::alphaemNow(
double pT2,
double renormMultFacNow,
int ) {
8307 double scale = pT2*renormMultFacNow;
8308 scale = max(scale, pT2colCut);
8311 double aemPT2pi = alphaEM.alphaEM(scale) / (2.*M_PI);
8322 double DireTimes::getNF(
double pT2) {
8326 BeamParticle* beam = NULL;
8327 if (beamAPtr != NULL || beamBPtr != NULL) {
8328 beam = (beamAPtr != NULL && particleDataPtr->isHadron(beamAPtr->id()))
8330 : (beamBPtr != NULL && particleDataPtr->isHadron(beamBPtr->id()))
8332 if (beam == NULL && beamAPtr != 0) beam = beamAPtr;
8333 if (beam == NULL && beamBPtr != 0) beam = beamBPtr;
8336 if ( !usePDFalphas || beam == NULL ) {
8337 if ( pT2 > pow2( max(0., particleDataPtr->m0(5) ) )
8338 && pT2 < pow2( particleDataPtr->m0(6)) ) NF = 5.;
8339 else if ( pT2 > pow2( max( 0., particleDataPtr->m0(4)) ) ) NF = 4.;
8340 else if ( pT2 > pow2( max( 0., particleDataPtr->m0(3)) ) ) NF = 3.;
8342 if ( pT2 > pow2( max(0., beam->mQuarkPDF(5) ) )
8343 && pT2 < pow2( particleDataPtr->m0(6)) ) NF = 5.;
8344 else if ( pT2 > pow2( max( 0., beam->mQuarkPDF(4)) ) ) NF = 4.;
8345 else if ( pT2 > pow2( max( 0., beam->mQuarkPDF(3)) ) ) NF = 3.;