8 #include "Pythia8/DireHistory.h"
9 #include "Pythia8/DireSpace.h"
10 #include "Pythia8/DireTimes.h"
16 string stringFlavs(
const Event& event) {
19 for (
int i=0; i <
event.size(); ++i)
20 if (event[i].status() == -21) os <<
" " << event[i].
id();
22 for (
int i=0; i <
event.size(); ++i) {
23 if (event[i].status() == 23) os <<
" " << event[i].
id();
24 if (event[i].status() == 22) os <<
" " << event[i].
id();
30 void listFlavs(
const Event& event,
bool includeEndl =
false) {
31 cout << std::left << setw(30) << stringFlavs(event);
32 if (includeEndl) cout << endl;
44 as(asIn), aem(
nullptr), asPow(1), aemPow(1) {};
46 as(
nullptr), aem(aemIn), asPow(1), aemPow(1) {};
48 AlphaEM* aemIn,
int aemPowIn) : as(asIn), aem(aemIn), asPow(asPowIn),
51 double ret = (as==
nullptr) ? 1. : pow(as->alphaS(x),asPow);
52 ret *= (aem==
nullptr) ? 1. : pow(aem->alphaEM(x),aemPow);
55 double f(
double x,
double) {
56 double ret = (as==
nullptr) ? 1. : pow(as->alphaS(x),asPow);
57 ret *= (aem==
nullptr) ? 1. : pow(aem->alphaEM(x),aemPow);
60 double f(
double x, vector<double>) {
61 double ret = (as==
nullptr) ? 1. : pow(as->alphaS(x),asPow);
62 ret *= (aem==
nullptr) ? 1. : pow(aem->alphaEM(x),aemPow);
83 void DireClustering::list()
const {
84 cout <<
" emt " << emitted
86 <<
" rec " << recoiler
87 <<
" partner " << partner
88 <<
" pTscale " << pTscale
89 <<
" name " << name() << endl;
111 const int DireHistory::NTRIAL = 1;
113 const double DireHistory::MCWINDOW = 0.1;
114 const double DireHistory::MBWINDOW = 0.1;
115 const double DireHistory::PROBMAXFAC = 0.0;
132 DireHistory::DireHistory(
int depthIn,
136 MergingHooksPtr mergingHooksPtrIn,
137 BeamParticle beamAIn,
138 BeamParticle beamBIn,
139 ParticleData* particleDataPtrIn,
141 PartonLevel* showersIn,
142 shared_ptr<DireTimes> fsrIn,
143 shared_ptr<DireSpace> isrIn,
144 DireWeightContainer* psweightsIn,
146 bool isOrdered =
true,
147 bool isAllowed =
true,
148 double clusterProbIn = 1.0,
149 double clusterCouplIn = 1.0,
150 double prodOfProbsIn = 1.0,
151 double prodOfProbsFullIn = 1.0,
152 DireHistory * mothin = 0)
158 sumGoodBranches(0.0),
160 foundOrderedPath(false),
161 foundAllowedPath(false),
162 foundCompletePath(false),
163 foundOrderedChildren(true),
167 clusterProb(clusterProbIn),
168 clusterCoupl(clusterCouplIn),
169 prodOfProbs(prodOfProbsIn),
170 prodOfProbsFull(prodOfProbsFullIn),
178 mergingHooksPtr(mergingHooksPtrIn),
181 particleDataPtr(particleDataPtrIn),
186 coupSMPtr(coupSMPtrIn),
187 psweights(psweightsIn),
189 infoPtr->settingsPtr->flag(
"Dire:doSingleLegSudakovs")),
194 fsr->direInfoPtr->message(1)
195 << scientific << setprecision(15)
196 << __FILE__ <<
" " << __func__
197 <<
" " << __LINE__ <<
" : New history node "
198 << stringFlavs(state) <<
" at "
199 << clusterIn.name() <<
" " << clusterIn.pT() <<
" "
200 << (clusterIn.radSave? clusterIn.radSave->id() : 0) <<
" "
201 << (clusterIn.emtSave? clusterIn.emtSave->id() : 0) <<
" "
202 << (clusterIn.recSave? clusterIn.recSave->id() : 0) <<
" "
203 << clusterProb <<
" "
204 << clusterCoupl <<
" "
205 << prodOfProbs <<
" "
206 <<
"\t\t bare prob = " << clusterProb*pow2(clusterIn.pT())
207 <<
" pT = " << clusterIn.pT()
211 goodBranches.clear();
216 if (!mother) nStepsMax = depth;
217 else nStepsMax = mother->nStepsMax;
223 if (mother && mergingHooksPtr->includeRedundant()) {
224 double pdfFac = pdfForSudakov();
225 clusterProb *= pdfFac;
226 prodOfProbs *= pdfFac;
227 prodOfProbsFull *= pdfFac;
231 if ( mother ) iReclusteredOld = mother->iReclusteredNew;
234 int nFinalHeavy = 0, nFinalLight = 0;
235 for (
int i = 0; i < int(state.size()); ++i )
236 if ( state[i].status() > 0) {
237 if ( state[i].idAbs() == 23
238 || state[i].idAbs() == 24
239 || state[i].idAbs() == 25)
241 if ( state[i].colType() != 0
242 || state[i].idAbs() == 22
243 || (state[i].idAbs() > 10 && state[i].idAbs() < 20) )
246 if (nFinalHeavy == 1 && nFinalLight == 0) depth = 0;
253 vector<DireClustering> clusterings;
254 if ( depth > 0 ) clusterings = getAllClusterings(state);
256 if (nFinalHeavy == 0 && nFinalLight == 2 && clusterings.empty()) depth = 0;
258 if ( clusterings.empty() ) {
259 hasMEweight = psweights->hasME(state);
260 if (hasMEweight) MECnum = psweights->getME(state);
261 else MECnum = hardProcessME(state);
262 fsr->direInfoPtr->message(1)
263 << scientific << setprecision(15)
264 << __FILE__ <<
" " << __func__
265 <<
" " << __LINE__ <<
" : Hard ME for "
266 << stringFlavs(state) <<
" found? " << hasMEweight <<
" ME "
270 hasMEweight = psweights->hasME(state);
272 if (hasMEweight) MECnum = psweights->getME(state);
273 fsr->direInfoPtr->message(1)
274 << scientific << setprecision(15)
275 << __FILE__ <<
" " << __func__
276 <<
" " << __LINE__ <<
" : Hard ME for "
277 << stringFlavs(state) <<
" found? " << hasMEweight <<
" ME "
282 for (
int i = 0; i < int(state.size()); ++i ) {
283 if ( state[i].status() > 0 ) nf++;
284 if ( state[i].status() > 0 && state[i].idAbs() == 22) na++;
288 int nfqq = 0, nfhh = 0, nfgg = 0;
289 for (
int i = 0; i < int(state.size()); ++i )
290 if ( state[i].status() > 0) {
291 if ( state[i].idAbs() < 10) nfqq++;
292 if ( state[i].idAbs() == 21) nfgg++;
293 if ( state[i].idAbs() == 25) nfhh++;
298 if ( clusterings.empty() ) {
301 prodOfProbs *= MECnum;
302 prodOfProbsFull *= MECnum;
305 double MECnumCoupl = hardProcessCouplings(state);
306 if (MECnumCoupl != 0.0) {
307 prodOfProbs /= MECnumCoupl;
308 prodOfProbsFull /= MECnumCoupl;
312 prodOfProbsFull = 0.0;
317 if ( mergingHooksPtr->orderHistories()
318 || ( infoPtr->settingsPtr->flag(
"Dire:doMOPS")
319 && infoPtr->settingsPtr->mode(
"Merging:nRequested") < 2) )
320 isOrdered = isOrdered && (scale < hardStartScale(state) );
322 if (registerPath( *
this, isOrdered, isAllowed, depth == 0 ))
323 updateMinDepth(depth);
330 multimap<double, DireClustering *> sorted;
331 for (
int i = 0, N = clusterings.size(); i < N; ++i ) {
332 sorted.insert(make_pair(clusterings[i].pT(), &clusterings[i]));
335 bool foundChild =
false;
336 for ( multimap<double, DireClustering *>::iterator it = sorted.begin();
337 it != sorted.end(); ++it ) {
340 bool ordered = isOrdered;
341 if ( mergingHooksPtr->orderHistories() ) {
345 if ( !ordered || ( mother && (it->first < scale) ) ) {
346 if ( depth >= minDepth() && onlyOrderedPaths() && onlyAllowedPaths() )
352 if ( !ordered || ( mother && (it->first < scale) ) ) ordered =
false;
354 Event newState(cluster(*it->second));
356 if ( newState.size() == 0)
continue;
359 bool doCut = mergingHooksPtr->canCutOnRecState()
360 || mergingHooksPtr->allowCutOnRecState();
361 bool allowed = isAllowed;
363 && mergingHooksPtr->doCutOnRecState(newState) ) {
364 if ( onlyAllowedPaths() )
continue;
368 pair <double,double> probs = getProb(*it->second);
371 if ( probs.second == 0. || hardProcessCouplings(newState) == 0.
372 || (psweights->hasME(newState) && psweights->getME(newState) < 1e-20))
375 if (abs(probs.second)*prodOfProbs < PROBMAXFAC*probMax())
380 children.push_back(
new DireHistory(depth - 1,it->first, newState,
381 *it->second, mergingHooksPtr, beamA, beamB, particleDataPtr,
382 infoPtr, showers, fsr, isr, psweights, coupSMPtr, ordered,
384 probs.second, probs.first, abs(probs.second)*prodOfProbs,
385 probs.second*prodOfProbsFull,
this ));
393 prodOfProbs *= MECnum;
394 prodOfProbsFull *= MECnum;
397 double MECnumCoupl = hardProcessCouplings(state);
398 if (MECnumCoupl != 0.0) {
399 prodOfProbs /= MECnumCoupl;
400 prodOfProbsFull /= MECnumCoupl;
404 prodOfProbsFull = 0.0;
407 if (registerPath( *
this, isOrdered, isAllowed, depth == 0 ))
408 updateMinDepth(depth);
417 bool DireHistory::projectOntoDesiredHistories() {
419 bool foundGoodMOPS=
true;
422 if ( infoPtr->settingsPtr->flag(
"Dire:doMOPS")) {
423 for ( map<double, DireHistory*>::iterator it = paths.begin();
424 it != paths.end(); ++it ) {
425 if (!it->second->hasScalesAboveCutoff()) { foundGoodMOPS=
false;
break; }
431 for ( map<double, DireHistory*>::iterator it = paths.begin();
432 it != paths.end(); ++it )
433 it->second->setGoodChildren();
439 for ( map<double, DireHistory*>::iterator it = paths.begin();
440 it != paths.end(); ++it ) {
441 it->second->setCouplingOrderCount(it->second);
446 if (paths.size() > 0) {
450 DireHistory* deepest =
nullptr;
454 int generationMin = 1000000000;
455 for ( map<double, DireHistory*>::iterator it = paths.begin();
456 it != paths.end(); ++it )
457 if (it->second->generation < generationMin) {
458 generationMin = it->second->generation;
459 deepest = it->second;
461 if (deepest->mother) deepest->mother->setProbabilities();
462 if (deepest->mother) deepest->mother->setEffectiveScales();
467 for ( map<double, DireHistory*>::iterator it = paths.begin();
468 it != paths.end(); ++it ) {
469 it->second->multiplyMEsToPath(it->second);
473 bool foundGood = trimHistories();
476 return (infoPtr->settingsPtr->flag(
"Dire:doMOPS")
477 ? foundGoodMOPS : foundGood);
493 double DireHistory::weightMOPS(PartonLevel* trial, AlphaStrong * ,
494 AlphaEM * ,
double RN) {
497 double maxScale = (foundCompletePath) ? infoPtr->eCM()
498 : mergingHooksPtr->muFinME();
501 DireHistory * selected = select(RN);
504 selected->setScalesInHistory();
508 if (foundOrderedPath) {
return 0.;}
512 vector<double> ret(createvector<double>(1.)(1.)(1.));
513 vector<double> noemwt = selected->weightEmissionsVec(trial,1,-1,-1,maxScale);
514 for (
size_t i=0; i < ret.size(); ++i) ret[i] *= noemwt[i];
515 for (
size_t i=0; i < ret.size(); ++i)
if (abs(ret[i]) > 1e-12) nZero =
true;
517 double sudakov = noemwt.front();
521 if (nZero) pdfwt = selected->weightPDFs( maxScale, selected->clusterIn.pT());
522 for (
size_t i=0; i < ret.size(); ++i) ret[i] *= pdfwt;
524 for (
size_t i=0; i < ret.size(); ++i)
if (abs(ret[i]) > 1e-12) nZero =
true;
527 vector<double> couplwt(createvector<double>(1.)(1.)(1.));
528 if (nZero) couplwt = selected->weightCouplingsDenominator();
529 for (
size_t i=0; i < ret.size(); ++i) ret[i] *= couplwt[i];
531 for (
size_t i=0; i < ret.size(); ++i)
if (abs(ret[i]) > 1e-12) nZero =
true;
533 double coupwt = couplEffective/couplwt.front();
536 int njetsMaxMPI = mergingHooksPtr->nMinMPI();
539 if (infoPtr->settingsPtr->flag(
"PartonLevel:MPI")) mpiwt
540 = selected->weightEmissions( trial, -1, 0, njetsMaxMPI, maxScale );
543 return (sudakov*coupwt*pdfwt*mpiwt);
549 vector<double> DireHistory::weightMEM(PartonLevel* trial, AlphaStrong * as,
550 AlphaEM * aem,
double RN) {
553 double maxScale = (foundCompletePath) ? infoPtr->eCM()
554 : mergingHooksPtr->muFinME();
557 DireHistory * selected = select(RN);
560 selected->setScalesInHistory();
564 vector<double> ret(createvector<double>(1.)(1.)(1.));
565 vector<double> noemwt = selected->weightEmissionsVec(trial,1,-1,-1,maxScale);
566 for (
size_t i=0; i < ret.size(); ++i) ret[i] *= noemwt[i];
567 for (
size_t i=0; i < ret.size(); ++i)
if (abs(ret[i]) > 1e-12) nZero =
true;
571 if (nZero) pdfwt = selected->weightPDFs( maxScale, selected->clusterIn.pT());
572 for (
size_t i=0; i < ret.size(); ++i) ret[i] *= pdfwt;
574 for (
size_t i=0; i < ret.size(); ++i)
if (abs(ret[i]) > 1e-12) nZero =
true;
577 vector<double> couplwt(createvector<double>(1.)(1.)(1.));
578 if (nZero) couplwt = selected->weightCouplings();
579 for (
size_t i=0; i < ret.size(); ++i) ret[i] *= couplwt[i];
581 for (
size_t i=0; i < ret.size(); ++i)
if (abs(ret[i]) > 1e-12) nZero =
true;
584 vector<double> vars(createvector<double>(1.)(0.25)(4.));
585 double QRen = selected->hardProcessScale(selected->state);
586 double coupl = selected->hardProcessCouplings(selected->state, 1,
588 for (
size_t i=0; i < vars.size(); ++i) {
589 double ratio = selected->hardProcessCouplings(selected->state, 1,
590 vars[i]*QRen*QRen, as, aem) / coupl;
610 double DireHistory::weightTREE(PartonLevel* trial, AlphaStrong * asFSR,
611 AlphaStrong * asISR, AlphaEM * aemFSR, AlphaEM * aemISR,
double RN) {
613 if ( mergingHooksPtr->canCutOnRecState() && !foundAllowedPath ) {
614 string message=
"Warning in DireHistory::weightTREE: No allowed history";
615 message+=
" found. Using disallowed history.";
616 infoPtr->errorMsg(message);
619 if ( mergingHooksPtr->orderHistories() && !foundOrderedPath ) {
620 string message=
"Warning in DireHistory::weightTREE: No ordered history";
621 message+=
" found. Using unordered history.";
622 infoPtr->errorMsg(message);
624 if ( mergingHooksPtr->canCutOnRecState()
625 && mergingHooksPtr->orderHistories()
626 && !foundAllowedPath && !foundOrderedPath ) {
627 string message=
"Warning in DireHistory::weightTREE: No allowed or ordered";
628 message+=
" history found.";
629 infoPtr->errorMsg(message);
633 double asME = infoPtr->alphaS();
634 double aemME = infoPtr->alphaEM();
635 double maxScale = (foundCompletePath) ? infoPtr->eCM()
636 : mergingHooksPtr->muFinME();
639 DireHistory * selected = select(RN);
642 selected->setScalesInHistory();
646 double asWeight = 1.;
647 double aemWeight = 1.;
648 double pdfWeight = 1.;
651 sudakov = selected->weight( trial, asME, aemME, maxScale,
652 selected->clusterIn.pT(), asFSR, asISR, aemFSR, aemISR, asWeight,
653 aemWeight, pdfWeight );
656 int njetsMaxMPI = mergingHooksPtr->nMinMPI();
661 if (infoPtr->settingsPtr->flag(
"PartonLevel:MPI")) mpiwt
662 = selected->weightEmissions( trial, -1, 0, njetsMaxMPI, maxScale );
665 bool resetScales = mergingHooksPtr->resetHardQRen();
671 && mergingHooksPtr->getProcessString().compare(
"pp>jj") == 0) {
673 double newQ2Ren = pow2( selected->hardRenScale(selected->state) );
674 double runningCoupling = (*asFSR).alphaS(newQ2Ren) / asME;
675 asWeight *= pow2(runningCoupling);
676 }
else if (mergingHooksPtr->doWeakClustering()
677 && isQCD2to2(selected->state)) {
679 double newQ2Ren = pow2( selected->hardRenScale(selected->state) );
680 double runningCoupling = (*asFSR).alphaS(newQ2Ren) / asME;
681 asWeight *= pow2(runningCoupling);
685 if (mergingHooksPtr->doWeakClustering() && isEW2to1(selected->state)) {
687 double newQ2Ren = pow2( selected->hardRenScale(selected->state) );
688 double runningCoupling = (*aemFSR).alphaEM(newQ2Ren) / aemME;
689 aemWeight *= runningCoupling;
696 && mergingHooksPtr->getProcessString().compare(
"pp>aj") == 0) {
698 double newQ2Ren = pow2( selected->hardRenScale(selected->state) );
699 double runningCoupling =
700 (*asISR).alphaS( newQ2Ren + pow(mergingHooksPtr->pT0ISR(),2) ) / asME;
701 asWeight *= runningCoupling;
706 && ( mergingHooksPtr->getProcessString().compare(
"e+p>e+j") == 0
707 || mergingHooksPtr->getProcessString().compare(
"e-p>e-j") == 0)) {
708 double newQ2Ren = pow2( selected->hardRenScale(selected->state) );
709 double pT20 = pow(mergingHooksPtr->pT0ISR(),2);
710 if ( isMassless2to2(selected->state) ) {
711 int nIncP(0), nOutP(0);
712 for (
int i=0; i < selected->state.size(); ++i ) {
713 if ( selected->state[i].isFinal()
714 && selected->state[i].colType() != 0)
716 if ( selected->state[i].status() == -21
717 && selected->state[i].colType() != 0)
720 if (nIncP == 2 && nOutP == 2)
721 asWeight *= pow2( (*asISR).alphaS(newQ2Ren+pT20) / asME );
722 if (nIncP == 1 && nOutP == 2)
723 asWeight *= (*asISR).alphaS(newQ2Ren+pT20) / asME
724 * (*aemFSR).alphaEM(newQ2Ren) / aemME;
729 return (sudakov*asWeight*aemWeight*pdfWeight*mpiwt);
738 double DireHistory::weightLOOP(PartonLevel* trial,
double RN ) {
740 if ( mergingHooksPtr->canCutOnRecState() && !foundAllowedPath ) {
741 string message=
"Warning in DireHistory::weightLOOP: No allowed history";
742 message+=
" found. Using disallowed history.";
743 infoPtr->errorMsg(message);
747 DireHistory * selected = select(RN);
749 selected->setScalesInHistory();
755 double maxScale = (foundCompletePath) ? infoPtr->eCM()
756 : mergingHooksPtr->muFinME();
757 int njetsMaxMPI = mergingHooksPtr->nMinMPI();
758 double mpiwt = selected->weightEmissions( trial, -1, 0, njetsMaxMPI,
769 double DireHistory::weightFIRST(PartonLevel* trial, AlphaStrong* asFSR,
770 AlphaStrong* asISR, AlphaEM * aemFSR, AlphaEM * aemISR,
double RN,
774 if (
false) cout << aemFSR << aemISR;
777 double asME = infoPtr->alphaS();
778 double muR = mergingHooksPtr->muRinME();
779 double maxScale = (foundCompletePath)
781 : mergingHooksPtr->muFinME();
784 DireHistory * selected = select(RN);
786 selected->setScalesInHistory();
788 int nSteps = mergingHooksPtr->getNumberOfClusteringSteps(state);
791 double kFactor = asME * mergingHooksPtr->k1Factor(nSteps);
795 double wt = 1. + kFactor;
798 wt += selected->weightFirst(trial,asME, muR, maxScale, asFSR, asISR,
802 double startingScale = (selected->mother) ? state.scale() : infoPtr->eCM();
806 double nWeight1 = 0.;
807 for(
int i=0; i < NTRIAL; ++i) {
809 vector<double> unresolvedEmissionTerm = countEmissions
810 ( trial, startingScale, mergingHooksPtr->tms(), 2, asME, asFSR, asISR, 3,
812 nWeight1 += unresolvedEmissionTerm[1];
815 wt += nWeight1/double(NTRIAL);
824 double DireHistory::weight_UMEPS_TREE(PartonLevel* trial, AlphaStrong * asFSR,
825 AlphaStrong * asISR, AlphaEM * aemFSR, AlphaEM * aemISR,
double RN) {
827 return weightTREE( trial, asFSR, asISR, aemFSR, aemISR, RN);
834 double DireHistory::weight_UMEPS_SUBT(PartonLevel* trial, AlphaStrong * asFSR,
835 AlphaStrong * asISR, AlphaEM * aemFSR, AlphaEM * aemISR,
double RN ) {
838 double asME = infoPtr->alphaS();
839 double aemME = infoPtr->alphaEM();
840 double maxScale = (foundCompletePath) ? infoPtr->eCM()
841 : mergingHooksPtr->muFinME();
843 DireHistory * selected = select(RN);
845 selected->setScalesInHistory();
849 double asWeight = 1.;
850 double aemWeight = 1.;
851 double pdfWeight = 1.;
854 sudakov = selected->weight(trial, asME, aemME, maxScale,
855 selected->clusterIn.pT(), asFSR, asISR, aemFSR, aemISR, asWeight,
856 aemWeight, pdfWeight);
859 int njetsMaxMPI = mergingHooksPtr->nMinMPI()+1;
860 double mpiwt = selected->weightEmissions( trial, -1, 0, njetsMaxMPI,
864 bool resetScales = mergingHooksPtr->resetHardQRen();
869 && mergingHooksPtr->getProcessString().compare(
"pp>jj") == 0) {
871 double newQ2Ren = pow2( selected->hardRenScale(selected->state) );
872 double runningCoupling = (*asFSR).alphaS(newQ2Ren) / asME;
873 asWeight *= pow(runningCoupling,2);
880 && mergingHooksPtr->getProcessString().compare(
"pp>aj") == 0) {
882 double newQ2Ren = pow2( selected->hardRenScale(selected->state) );
883 double runningCoupling =
884 (*asISR).alphaS( newQ2Ren + pow(mergingHooksPtr->pT0ISR(),2) ) / asME;
885 asWeight *= runningCoupling;
889 return (sudakov*asWeight*aemWeight*pdfWeight*mpiwt);
895 double DireHistory::weight_UNLOPS_TREE(PartonLevel* trial, AlphaStrong * asFSR,
896 AlphaStrong * asISR, AlphaEM * aemFSR, AlphaEM * aemISR,
double RN,
900 double asME = infoPtr->alphaS();
901 double aemME = infoPtr->alphaEM();
902 double maxScale = (foundCompletePath) ? infoPtr->eCM()
903 : mergingHooksPtr->muFinME();
905 DireHistory * selected = select(RN);
907 selected->setScalesInHistory();
910 double asWeight = 1.;
911 double aemWeight = 1.;
912 double pdfWeight = 1.;
916 if (depthIn < 0) wt = selected->weight(trial, asME, aemME, maxScale,
917 selected->clusterIn.pT(), asFSR, asISR, aemFSR, aemISR, asWeight,
918 aemWeight, pdfWeight);
920 wt = selected->weightEmissions( trial, 1, 0, depthIn, maxScale );
922 asWeight = selected->weightALPHAS( asME, asFSR, asISR, 0, depthIn);
923 aemWeight = selected->weightALPHAEM( aemME, aemFSR, aemISR, 0, depthIn);
924 pdfWeight = selected->weightPDFs
925 ( maxScale, selected->clusterIn.pT(), 0, depthIn);
930 int njetsMaxMPI = mergingHooksPtr->nMinMPI();
931 double mpiwt = selected->weightEmissions( trial, -1, 0, njetsMaxMPI,
935 bool resetScales = mergingHooksPtr->resetHardQRen();
940 && mergingHooksPtr->getProcessString().compare(
"pp>jj") == 0) {
942 double newQ2Ren = pow2( selected->hardRenScale(selected->state) );
943 double runningCoupling = (*asFSR).alphaS(newQ2Ren) / asME;
944 asWeight *= pow(runningCoupling,2);
951 && mergingHooksPtr->getProcessString().compare(
"pp>aj") == 0) {
953 double newQ2Ren = pow2( selected->hardRenScale(selected->state) );
954 double runningCoupling =
955 (*asISR).alphaS( newQ2Ren + pow(mergingHooksPtr->pT0ISR(),2) ) / asME;
956 asWeight *= runningCoupling;
960 return (wt*asWeight*aemWeight*pdfWeight*mpiwt);
966 double DireHistory::weight_UNLOPS_LOOP(PartonLevel* trial, AlphaStrong * asFSR,
967 AlphaStrong * asISR, AlphaEM * aemFSR, AlphaEM * aemISR,
double RN,
970 if (depthIn < 0)
return weightLOOP(trial, RN);
971 else return weight_UNLOPS_TREE(trial, asFSR,asISR, aemFSR,
972 aemISR, RN, depthIn);
977 double DireHistory::weight_UNLOPS_SUBT(PartonLevel* trial, AlphaStrong * asFSR,
978 AlphaStrong * asISR, AlphaEM * aemFSR, AlphaEM * aemISR,
double RN,
982 DireHistory * selected = select(RN);
984 selected->setScalesInHistory();
989 double asME = infoPtr->alphaS();
990 double aemME = infoPtr->alphaEM();
991 double maxScale = (foundCompletePath)
993 : mergingHooksPtr->muFinME();
997 double nSteps = mergingHooksPtr->getNumberOfClusteringSteps(state);
998 if ( nSteps == 2 && mergingHooksPtr->nRecluster() == 2
999 && ( !foundCompletePath
1000 || !selected->allIntermediateAboveRhoMS( mergingHooksPtr->tms() )) )
1004 double asWeight = 1.;
1005 double aemWeight = 1.;
1006 double pdfWeight = 1.;
1008 double sudakov = 1.;
1010 sudakov = selected->weight(trial, asME, aemME, maxScale,
1011 selected->clusterIn.pT(), asFSR, asISR, aemFSR, aemISR, asWeight,
1012 aemWeight, pdfWeight);
1014 sudakov = selected->weightEmissions( trial, 1, 0, depthIn, maxScale );
1016 asWeight = selected->weightALPHAS( asME, asFSR, asISR, 0, depthIn);
1017 aemWeight = selected->weightALPHAEM( aemME, aemFSR, aemISR, 0, depthIn);
1018 pdfWeight = selected->weightPDFs
1019 ( maxScale, selected->clusterIn.pT(), 0, depthIn);
1024 int njetsMaxMPI = mergingHooksPtr->nMinMPI()+1;
1025 double mpiwt = selected->weightEmissions( trial, -1, 0, njetsMaxMPI,
1029 wt = ( mergingHooksPtr->nRecluster() == 2 ) ? 1.
1030 : asWeight*aemWeight*pdfWeight*sudakov*mpiwt;
1039 double DireHistory::weight_UNLOPS_SUBTNLO(PartonLevel* trial,
1040 AlphaStrong * asFSR,
1041 AlphaStrong * asISR, AlphaEM * aemFSR, AlphaEM * aemISR,
double RN,
1047 DireHistory * selected = select(RN);
1049 selected->setScalesInHistory();
1053 double maxScale = (foundCompletePath) ? infoPtr->eCM()
1054 : mergingHooksPtr->muFinME();
1055 int njetsMaxMPI = mergingHooksPtr->nMinMPI()+1;
1056 double mpiwt = selected->weightEmissions( trial, -1, 0, njetsMaxMPI,
1062 }
else return weight_UNLOPS_SUBT(trial, asFSR, asISR, aemFSR, aemISR, RN,
1071 double DireHistory::weight_UNLOPS_CORRECTION(
int order, PartonLevel* trial,
1072 AlphaStrong* asFSR, AlphaStrong* asISR, AlphaEM * aemFSR, AlphaEM * aemISR,
1073 double RN, Rndm* rndmPtr ) {
1076 if (
false) cout << aemFSR << aemISR;
1079 if ( order < 0 )
return 0.;
1082 double asME = infoPtr->alphaS();
1084 double muR = mergingHooksPtr->muRinME();
1085 double maxScale = (foundCompletePath)
1087 : mergingHooksPtr->muFinME();
1090 DireHistory * selected = select(RN);
1092 selected->setScalesInHistory();
1094 double nSteps = mergingHooksPtr->getNumberOfClusteringSteps(state);
1097 double kFactor = asME * mergingHooksPtr->k1Factor(nSteps);
1104 if ( order == 0 )
return wt;
1112 double wA = selected->weightFirstALPHAS( asME, muR, asFSR, asISR );
1116 double nWeight = 0.;
1117 for (
int i = 0; i < NTRIAL; ++i ) {
1119 double wE = selected->weightFirstEmissions
1120 ( trial,asME, maxScale, asFSR, asISR,
true,
true );
1124 double pscale = selected->clusterIn.pT();
1125 double wP = selected->weightFirstPDFs(asME, maxScale, pscale, rndmPtr);
1129 wt += nWeight/double(NTRIAL);
1132 if ( order == 1 )
return wt;
1143 void DireHistory::getStartingConditions(
const double RN,
Event& outState ) {
1146 DireHistory * selected = select(RN);
1149 selected->setScalesInHistory();
1152 int nSteps = mergingHooksPtr->getNumberOfClusteringSteps(state);
1155 if (!selected->mother) {
1157 for(
int i=0; i < int(state.size()); ++i)
1158 if ( state[i].isFinal()) nFinal++;
1161 double startingScale = hardStartScale(state);
1162 state.scale(startingScale);
1163 for (
int i = 3;i < state.size();++i)
1164 state[i].scale(startingScale);
1171 infoPtr->zNowISR(0.5);
1172 infoPtr->pT2NowISR(pow(state[0].e(),2));
1173 infoPtr->hasHistory(
true);
1180 mergingHooksPtr->muMI(infoPtr->eCM());
1182 mergingHooksPtr->muMI(outState.scale());
1184 mergingHooksPtr->setShowerStoppingScale(0.0);
1192 void DireHistory::printHistory(
const double RN ) {
1193 DireHistory * selected = select(RN);
1194 selected->printStates();
1202 void DireHistory::printStates() {
1204 cout << scientific << setprecision(4) <<
"Probability="
1205 << prodOfProbs << endl;
1206 cout <<
"State:\t\t\t"; listFlavs(state,
true);
1211 double p = prodOfProbs/mother->prodOfProbs;
1212 cout << scientific << setprecision(4) <<
"Probabilities:"
1213 <<
"\n\t Product = "
1214 << prodOfProbs <<
" " << prodOfProbsFull
1215 <<
"\n\t Single with coupling = " << p
1216 <<
"\n\t Cluster probability = " << clusterProb <<
"\t\t"
1218 <<
"\nScale=" << clusterIn.pT() << endl;
1219 cout <<
"State:\t\t\t"; listFlavs(state,
true);
1220 cout <<
"rad=" << clusterIn.radPos()
1221 <<
" emt=" << clusterIn.emtPos()
1222 <<
" rec=" << clusterIn.recPos() << endl;
1224 mother->printStates();
1233 bool DireHistory::getClusteredEvent(
const double RN,
int nSteps,
1237 DireHistory * selected = select(RN);
1241 selected->setScalesInHistory();
1244 if (nSteps > selected->nClusterings())
return false;
1247 outState = selected->clusteredState(nSteps-1);
1255 bool DireHistory::getFirstClusteredEventAboveTMS(
const double RN,
1256 int nDesired,
Event& process,
int& nPerformed,
bool doUpdate ) {
1259 int nTried = nDesired - 1;
1261 int nSteps = select(RN)->nClusterings();
1263 select(RN)->setScalesInHistory();
1270 dummy.init(
"(hard process-modified)", particleDataPtr );
1275 if ( !getClusteredEvent( RN, nSteps-nTried+1, dummy ) )
return false;
1276 if ( nTried >= nSteps )
break;
1279 }
while ( mergingHooksPtr->getNumberOfClusteringSteps(dummy) > 0
1280 && mergingHooksPtr->tmsNow( dummy) < mergingHooksPtr->tms() );
1283 if ( doUpdate ) process = dummy;
1286 if ( nTried > nSteps )
return false;
1288 nPerformed = nTried;
1291 mergingHooksPtr->nReclusterSave = nPerformed;
1293 if (mergingHooksPtr->getNumberOfClusteringSteps(state) == 0)
1294 mergingHooksPtr->muMI(infoPtr->eCM());
1296 mergingHooksPtr->muMI(state.scale());
1308 double DireHistory::getPDFratio(
int side,
bool forSudakov,
bool useHardPDFs,
1309 int flavNum,
double xNum,
double muNum,
1310 int flavDen,
double xDen,
double muDen) {
1313 if ( particleDataPtr->colType(flavNum) == 0)
return 1.0;
1314 if ( particleDataPtr->colType(flavDen) == 0)
return 1.0;
1317 double pdfRatio = 1.0;
1320 double pdfNum = 0.0;
1321 double pdfDen = 0.0;
1324 if ( useHardPDFs ) {
1327 pdfNum = mother->beamA.xfHard( flavNum, xNum, muNum*muNum);
1328 else pdfNum = beamA.xfHard( flavNum, xNum, muNum*muNum);
1329 pdfDen = max(1e-10, beamA.xfHard( flavDen, xDen, muDen*muDen));
1332 pdfNum = mother->beamB.xfHard( flavNum, xNum, muNum*muNum);
1333 else pdfNum = beamB.xfHard( flavNum, xNum, muNum*muNum);
1334 pdfDen = max(1e-10,beamB.xfHard( flavDen, xDen, muDen*muDen));
1341 pdfNum = mother->beamA.xfISR(0, flavNum, xNum, muNum*muNum);
1342 else pdfNum = beamA.xfISR(0, flavNum, xNum, muNum*muNum);
1343 pdfDen = max(1e-10, beamA.xfISR(0, flavDen, xDen, muDen*muDen));
1346 pdfNum = mother->beamB.xfISR(0, flavNum, xNum, muNum*muNum);
1347 else pdfNum = beamB.xfISR(0, flavNum, xNum, muNum*muNum);
1348 pdfDen = max(1e-10,beamB.xfISR(0, flavDen, xDen, muDen*muDen));
1353 if ( forSudakov && abs(flavNum) ==4 && abs(flavDen) == 4 && muDen == muNum
1354 && muNum < particleDataPtr->m0(4))
1355 pdfDen = pdfNum = 1.0;
1358 if ( pdfNum > 1e-15 && pdfDen > 1e-10 ) {
1359 pdfRatio *= pdfNum / pdfDen;
1360 }
else if ( pdfNum < pdfDen ) {
1362 }
else if ( pdfNum > pdfDen ) {
1378 void DireHistory::setScalesInHistory() {
1386 setScales(ident,
true);
1403 void DireHistory::findPath(vector<int>& out) {
1406 if (!mother &&
int(children.size()) < 1)
return;
1412 int size = int(mother->children.size());
1414 for (
int i=0; i < size; ++i) {
1415 if ( mother->children[i]->scale == scale
1416 && mother->children[i]->prodOfProbs == prodOfProbs
1417 && equalClustering(mother->children[i]->clusterIn,clusterIn)) {
1424 out.push_back(iChild);
1425 mother->findPath(out);
1450 void DireHistory::setScales( vector<int> index,
bool forward) {
1455 if ( !infoPtr->settingsPtr->flag(
"Dire:doMOPS")) {
1458 if ( children.empty() && forward ) {
1461 double scaleNew = 1.;
1462 if (mergingHooksPtr->incompleteScalePrescip()==0) {
1463 scaleNew = mergingHooksPtr->muF();
1464 }
else if (mergingHooksPtr->incompleteScalePrescip()==1) {
1466 pOut.p(0.,0.,0.,0.);
1467 for(
int i=0; i<int(state.size()); ++i)
1468 if (state[i].isFinal())
1469 pOut += state[i].p();
1470 scaleNew = pOut.mCalc();
1471 }
else if (mergingHooksPtr->incompleteScalePrescip()==2) {
1472 scaleNew = state[0].e();
1475 scaleNew = max( mergingHooksPtr->pTcut(), scaleNew);
1477 state.scale(scaleNew);
1478 for(
int i=3; i < int(state.size());++i)
1479 if (state[i].colType() != 0)
1480 state[i].scale(scaleNew);
1483 state.scale( state[0].e() );
1485 bool isLEP = ( state[3].isLepton() && state[4].isLepton() );
1487 int nFinalPartons = 0;
1488 int nFinalPhotons = 0;
1489 for (
int i=0; i < int(state.size()); ++i ) {
1490 if ( state[i].isFinal() ) {
1492 if ( state[i].colType() != 0 ) nFinalPartons++;
1493 if ( state[i].
id() == 22 ) nFinalPhotons++;
1496 bool isQCD = ( nFinal == 2 && nFinal == nFinalPartons );
1497 bool isPPh = ( nFinal == 2 && nFinalPartons == 1 && nFinalPhotons == 1);
1499 if ( !isLEP && ( isQCD || isPPh ) ) {
1500 double scaleNew = hardFacScale(state);
1501 state.scale( scaleNew );
1505 if ( ( isDIS2to2(state) || isMassless2to2(state) )
1506 && ( mergingHooksPtr->getProcessString().compare(
"e+p>e+j") == 0
1507 || mergingHooksPtr->getProcessString().compare(
"e-p>e-j") == 0) )
1508 state.scale( hardFacScale(state) );
1514 if (mother && forward) {
1516 double scaleNew = 1.;
1517 if ( mergingHooksPtr->unorderedScalePrescip() == 0) {
1519 scaleNew = max( mergingHooksPtr->pTcut(), max(scale,mother->scale));
1520 }
else if ( mergingHooksPtr->unorderedScalePrescip() == 1) {
1522 if (scale < mother->scale)
1523 scaleNew = max( mergingHooksPtr->pTcut(), min(scale,mother->scale));
1525 scaleNew = max( mergingHooksPtr->pTcut(), max(scale,mother->scale));
1530 mother->state[clusterIn.emtPos()].scale(scaleNew);
1531 mother->state[clusterIn.radPos()].scale(scaleNew);
1532 mother->state[clusterIn.recPos()].scale(scaleNew);
1536 mother->scaleCopies(clusterIn.emtPos(), mother->state, scaleNew);
1537 mother->scaleCopies(clusterIn.radPos(), mother->state, scaleNew);
1538 mother->scaleCopies(clusterIn.recPos(), mother->state, scaleNew);
1541 mother->setScales(index,
true);
1546 if (!mother || !forward) {
1549 if (
int(index.size()) > 0 ) {
1550 iChild = index.back();
1556 scale = max(mergingHooksPtr->pTcut(), scale);
1559 if (iChild != -1 && !children.empty()) {
1560 if (scale > children[iChild]->scale ) {
1562 if ( mergingHooksPtr->unorderedScalePrescip() == 0) {
1564 double scaleNew = max( mergingHooksPtr->pTcut(),
1565 max(scale,children[iChild]->scale));
1567 for(
int i = 0; i < int(children[iChild]->state.size()); ++i)
1568 if (children[iChild]->state[i].scale() == children[iChild]->scale)
1569 children[iChild]->state[i].scale(scaleNew);
1571 children[iChild]->scale = scaleNew;
1573 }
else if ( mergingHooksPtr->unorderedScalePrescip() == 1) {
1575 double scaleNew = max(mergingHooksPtr->pTcut(),
1576 min(scale,children[iChild]->scale));
1578 for(
int i = 0; i < int(state.size()); ++i)
1579 if (state[i].scale() == scale)
1580 state[i].scale(scaleNew);
1588 double scalemin = state[0].e();
1589 for(
int i = 0; i < int(state.size()); ++i)
1590 if (state[i].colType() != 0)
1591 scalemin = max(mergingHooksPtr->pTcut(),
1592 min(scalemin,state[i].scale()));
1593 state.scale(scalemin);
1594 scale = max(mergingHooksPtr->pTcut(), scale);
1597 children[iChild]->setScales(index,
false);
1607 if ( children.empty() && forward ) {
1610 double scaleNew = 1.;
1611 if (mergingHooksPtr->incompleteScalePrescip()==0) {
1612 scaleNew = mergingHooksPtr->muF();
1613 }
else if (mergingHooksPtr->incompleteScalePrescip()==1) {
1615 pOut.p(0.,0.,0.,0.);
1616 for(
int i=0; i<int(state.size()); ++i)
1617 if (state[i].isFinal())
1618 pOut += state[i].p();
1619 scaleNew = pOut.mCalc();
1620 }
else if (mergingHooksPtr->incompleteScalePrescip()==2) {
1621 scaleNew = state[0].e();
1624 scaleNew = max( mergingHooksPtr->pTcut(), scaleNew);
1626 state.scale(scaleNew);
1627 for(
int i=3; i < int(state.size());++i)
1628 if (state[i].colType() != 0)
1629 state[i].scale(scaleNew);
1632 state.scale( state[0].e() );
1634 bool isLEP = ( state[3].isLepton() && state[4].isLepton() );
1636 int nFinalPartons = 0;
1637 int nFinalPhotons = 0;
1638 for (
int i=0; i < int(state.size()); ++i ) {
1639 if ( state[i].isFinal() ) {
1641 if ( state[i].colType() != 0 ) nFinalPartons++;
1642 if ( state[i].
id() == 22 ) nFinalPhotons++;
1645 bool isQCD = ( nFinal == 2 && nFinal == nFinalPartons );
1646 bool isPPh = ( nFinal == 2 && nFinalPartons == 1 && nFinalPhotons == 1);
1648 if ( !isLEP && ( isQCD || isPPh ) ) {
1649 double scaleNew = hardFacScale(state);
1650 state.scale( scaleNew );
1654 if ( ( isDIS2to2(state) || isMassless2to2(state) )
1655 && ( mergingHooksPtr->getProcessString().compare(
"e+p>e+j") == 0
1656 || mergingHooksPtr->getProcessString().compare(
"e-p>e-j") == 0) )
1657 state.scale( hardFacScale(state) );
1659 double hardScale = hardStartScale(state);
1660 state.scale(hardScale);
1668 if (mother && forward) {
1669 double scaleNew = (scaleEffective > 0.) ? scaleEffective : scale;
1670 scale = max(mergingHooksPtr->pTcut(), scaleNew);
1672 double scaleProduction = max( mergingHooksPtr->pTcut(),
1673 mother->scaleEffective);
1674 scaleProduction = max(scaleProduction,scaleNew);
1678 mother->state[clusterIn.emtPos()].scale(scaleProduction);
1679 mother->state[clusterIn.radPos()].scale(scaleProduction);
1680 mother->state[clusterIn.recPos()].scale(scaleProduction);
1684 mother->scaleCopies(clusterIn.emtPos(), mother->state, scaleProduction);
1685 mother->scaleCopies(clusterIn.radPos(), mother->state, scaleProduction);
1686 mother->scaleCopies(clusterIn.recPos(), mother->state, scaleProduction);
1689 mother->setScales(index,
true);
1694 if (!mother || !forward) {
1698 if (
int(index.size()) > 0 ) {
1699 iChild = index.back();
1705 scale = max(mergingHooksPtr->pTcut(), scale);
1706 if (infoPtr->settingsPtr->flag(
"Dire:doMOPS"))
1707 scale = max(scale,mother->scaleEffective);
1710 if (iChild != -1 && !children.empty()) {
1711 if (scale > children[iChild]->scale ) {
1713 double scaleNew = max( mergingHooksPtr->pTcut(),
1714 max(children[iChild]->scale, scaleEffective));
1715 if (mother) scaleNew = max(scaleNew, mother->scaleEffective);
1718 for(
int i = 0; i < int(children[iChild]->state.size()); ++i) {
1719 if (children[iChild]->state[i].scale() == children[iChild]->scale)
1720 children[iChild]->state[i].scale(scaleNew);
1723 children[iChild]->scale = scaleNew;
1726 double scalemin = state[0].e();
1727 for(
int i = 0; i < int(state.size()); ++i)
1728 if (state[i].colType() != 0)
1729 scalemin = max(mergingHooksPtr->pTcut(),
1730 min(scalemin,state[i].scale()));
1731 state.scale(scalemin);
1732 scale = max(mergingHooksPtr->pTcut(), scale);
1735 children[iChild]->setScales(index,
false);
1755 void DireHistory::scaleCopies(
int iPart,
const Event& refEvent,
double rho) {
1760 for(
int i=0; i < mother->state.size(); ++i) {
1761 if ( ( mother->state[i].id() == refEvent[iPart].id()
1762 && mother->state[i].colType() == refEvent[iPart].colType()
1763 && mother->state[i].chargeType() == refEvent[iPart].chargeType()
1764 && mother->state[i].col() == refEvent[iPart].col()
1765 && mother->state[i].acol() == refEvent[iPart].acol() )
1768 mother->state[i].scale(rho);
1771 mother->scaleCopies( iPart, refEvent, rho );
1784 void DireHistory::setEventScales() {
1788 mother->state.scale(scale);
1790 mother->setEventScales();
1801 int DireHistory::nClusterings() {
1802 if (!mother)
return 0;
1803 int w = mother->nClusterings();
1816 Event DireHistory::clusteredState(
int nSteps) {
1819 Event outState = state;
1821 if (mother && nSteps > 0)
1822 outState = mother->clusteredState(nSteps - 1);
1835 DireHistory * DireHistory::select(
double rnd) {
1838 if ( goodBranches.empty() && badBranches.empty() )
return this;
1842 map<double, DireHistory*> selectFrom;
1843 if ( !goodBranches.empty() ) {
1844 selectFrom = goodBranches;
1845 sum = sumGoodBranches;
1847 selectFrom = badBranches;
1848 sum = sumBadBranches;
1853 return selectFrom.upper_bound(sum*rnd)->second;
1855 return selectFrom.lower_bound(sum*rnd)->second;
1865 bool DireHistory::trimHistories() {
1867 if ( paths.empty() )
return false;
1869 for ( map<double, DireHistory*>::iterator it = paths.begin();
1870 it != paths.end(); ++it ) {
1872 if ( it->second->keep() && !it->second->keepHistory() )
1873 it->second->remove();
1877 double sumold(0.), sumnew(0.), mismatch(0.);
1880 for ( map<double, DireHistory*>::iterator it = paths.begin();
1881 it != paths.end(); ++it ) {
1883 sumnew = it->second->prodOfProbs;
1884 if ( it->second->keep() ) {
1886 goodBranches.insert( make_pair( sumnew - mismatch, it->second) );
1888 sumGoodBranches = sumnew - mismatch;
1892 double mismatchOld = mismatch;
1893 mismatch += sumnew - sumold;
1895 badBranches.insert( make_pair( mismatchOld + sumnew - sumold,
1898 sumBadBranches = mismatchOld + sumnew - sumold;
1902 sumold = it->second->prodOfProbs;
1906 return !goodBranches.empty();
1913 bool DireHistory::keepHistory() {
1914 bool keepPath =
true;
1916 double hardScale = hardStartScale(state);
1919 if ( mergingHooksPtr->getProcessString().compare(
"pp>jj") == 0
1920 || mergingHooksPtr->getProcessString().compare(
"pp>aj") == 0
1921 || isQCD2to2(state) ) {
1924 hardScale = hardStartScale(state);
1928 if (isEW2to1(state)) {
1930 for (
int i = 0;i < state.size(); ++i)
1931 if (state[i].isFinal()) pSum += state[i].p();
1932 hardScale = pSum.mCalc();
1936 if ( mergingHooksPtr->getProcessString().compare(
"e+p>e+j") == 0
1937 || mergingHooksPtr->getProcessString().compare(
"e-p>e-j") == 0 ) {
1940 hardScale = hardFacScale(state);
1943 keepPath = isOrderedPath( hardScale );
1945 if ( !mergingHooksPtr->orderHistories() ) keepPath =
true;
1955 bool DireHistory::isOrderedPath(
double maxscale ) {
1956 double newscale = clusterIn.pT();
1957 if ( !mother )
return true;
1958 bool ordered = mother->isOrderedPath(newscale);
1959 if ( !ordered || maxscale < newscale)
return false;
1968 bool DireHistory::allIntermediateAboveRhoMS(
double rhoms,
bool good ) {
1971 if ( !good )
return false;
1974 for (
int i = 0; i < state.size(); ++i )
1975 if ( state[i].isFinal() && state[i].colType() != 0 )
1977 double rhoNew = (nFinal > 0 ) ? mergingHooksPtr->tmsNow( state )
1980 if ( !mother )
return good;
1982 return mother->allIntermediateAboveRhoMS( rhoms, (rhoNew > rhoms) );
1989 bool DireHistory::foundAnyOrderedPaths() {
1991 if ( paths.empty() )
return false;
1992 double maxscale = hardStartScale(state);
1994 for ( map<double, DireHistory*>::iterator it = paths.begin();
1995 it != paths.end(); ++it )
1996 if ( it->second->isOrderedPath(maxscale) )
2007 bool DireHistory::hasScalesAboveCutoff() {
2008 if ( !mother )
return true;
2009 return ( clusterIn.pT() > mergingHooksPtr->pTcut()
2010 && mother->hasScalesAboveCutoff() );
2028 double DireHistory::weight(PartonLevel* trial,
double as0,
double aem0,
2029 double maxscale,
double pdfScale, AlphaStrong * asFSR, AlphaStrong * asISR,
2030 AlphaEM * aemFSR, AlphaEM * aemISR,
double& asWeight,
double& aemWeight,
2031 double& pdfWeight) {
2034 double newScale = scale;
2039 int sideRad = (state[3].pz() > 0) ? 1 :-1;
2040 int sideRec = (state[4].pz() > 0) ? 1 :-1;
2043 if (state[3].colType() != 0) {
2045 double x = 2.*state[3].e() / state[0].e();
2046 int flav = state[3].id();
2048 double scaleNum = (children.empty()) ? hardFacScale(state) : maxscale;
2049 double scaleDen = mergingHooksPtr->muFinME();
2051 double ratio = getPDFratio(sideRad,
false,
false, flav, x, scaleNum,
2057 if (state[4].colType() != 0) {
2059 double x = 2.*state[4].e() / state[0].e();
2060 int flav = state[4].id();
2062 double scaleNum = (children.empty()) ? hardFacScale(state) : maxscale;
2063 double scaleDen = mergingHooksPtr->muFinME();
2065 double ratio = getPDFratio(sideRec,
false,
false, flav, x, scaleNum,
2075 double newPDFscale = newScale;
2076 if ( !infoPtr->settingsPtr->flag(
"Dire:doMOPS")
2077 && mergingHooksPtr->unorderedPDFscalePrescip() == 1)
2078 newPDFscale = clusterIn.pT();
2081 double w = mother->weight(trial, as0, aem0, newScale, newPDFscale,
2082 asFSR, asISR, aemFSR, aemISR, asWeight, aemWeight, pdfWeight);
2085 if (state.size() < 3)
return 1.0;
2088 w *= doTrialShower(trial, 1, maxscale).front();
2090 int emtType = mother->state[clusterIn.emtPos()].colType();
2091 bool isQCD = emtType != 0;
2092 bool isQED = emtType == 0;
2094 pair<int,double> coup = getCoupling(mother->state, clusterIn.emittor,
2095 clusterIn.emtPos(), clusterIn.recoiler, clusterIn.name());
2097 if (coup.first > 0) {
2098 isQCD = isQED =
false;
2099 if (coup.first == 1)
2100 asWeight *= coup.second * 2.*M_PI / as0;
2101 if (coup.first == 2 || coup.first == 3)
2102 aemWeight *= coup.second * 2.*M_PI / aem0;
2106 if ( asFSR && asISR && isQCD) {
2107 double asScale = pow2( newScale );
2108 if ( !infoPtr->settingsPtr->flag(
"Dire:doMOPS")
2109 && mergingHooksPtr->unorderedASscalePrescip() == 1)
2110 asScale = pow2( clusterIn.pT() );
2113 bool FSR = mother->state[clusterIn.emittor].isFinal();
2114 if (!FSR) asScale += pow2(mergingHooksPtr->pT0ISR());
2117 asScale = getShowerPluginScale(mother->state, clusterIn.emittor,
2118 clusterIn.emtPos(), clusterIn.recoiler, clusterIn.name(),
2119 "scaleAS", asScale);
2121 if (infoPtr->settingsPtr->flag(
"Dire:doMOPS"))
2122 asScale = pow2(newScale);
2124 double alphaSinPS = (FSR) ? (*asFSR).alphaS(asScale)
2125 : (*asISR).alphaS(asScale);
2126 asWeight *= alphaSinPS / as0;
2130 if ( aemFSR && aemISR && isQED ) {
2131 double aemScale = pow2( newScale );
2132 if ( !infoPtr->settingsPtr->flag(
"Dire:doMOPS")
2133 && mergingHooksPtr->unorderedASscalePrescip() == 1)
2134 aemScale = pow2( clusterIn.pT() );
2137 bool FSR = mother->state[clusterIn.emittor].isFinal();
2138 if (!FSR) aemScale += pow2(mergingHooksPtr->pT0ISR());
2141 aemScale = getShowerPluginScale(mother->state, clusterIn.emittor,
2142 clusterIn.emtPos(), clusterIn.recoiler, clusterIn.name(),
2143 "scaleEM", aemScale);
2145 double alphaEMinPS = (FSR) ? (*aemFSR).alphaEM(aemScale)
2146 : (*aemISR).alphaEM(aemScale);
2147 aemWeight *= alphaEMinPS / aem0;
2153 int sideP = (mother->state[inP].pz() > 0) ? 1 :-1;
2154 int sideM = (mother->state[inM].pz() > 0) ? 1 :-1;
2156 if ( mother->state[inP].colType() != 0 ) {
2158 double x = getCurrentX(sideP);
2159 int flav = getCurrentFlav(sideP);
2161 double scaleNum = (children.empty())
2162 ? hardFacScale(state)
2163 : ( (!infoPtr->settingsPtr->flag(
"Dire:doMOPS")
2164 && mergingHooksPtr->unorderedPDFscalePrescip() == 1)
2165 ? pdfScale : maxscale );
2166 double scaleDen = ( !infoPtr->settingsPtr->flag(
"Dire:doMOPS")
2167 && mergingHooksPtr->unorderedPDFscalePrescip() == 1)
2168 ? clusterIn.pT() : newScale;
2170 double ratio = getPDFratio(sideP,
false,
false, flav, x, scaleNum,
2176 if ( mother->state[inM].colType() != 0 ) {
2178 double x = getCurrentX(sideM);
2179 int flav = getCurrentFlav(sideM);
2181 double scaleNum = (children.empty())
2182 ? hardFacScale(state)
2183 : ( (!infoPtr->settingsPtr->flag(
"Dire:doMOPS")
2184 && mergingHooksPtr->unorderedPDFscalePrescip() == 1)
2185 ? pdfScale : maxscale );
2186 double scaleDen = ( !infoPtr->settingsPtr->flag(
"Dire:doMOPS")
2187 && mergingHooksPtr->unorderedPDFscalePrescip() == 1)
2188 ? clusterIn.pT() : newScale;
2190 double ratio = getPDFratio(sideM,
false,
false, flav, x, scaleNum,
2204 double DireHistory::weightALPHAS(
double as0, AlphaStrong * asFSR,
2205 AlphaStrong * asISR,
int njetMin,
int njetMax ) {
2208 if ( !mother )
return 1.;
2210 double w = mother->weightALPHAS( as0, asFSR, asISR, njetMin, njetMax );
2212 if (state.size() < 3)
return w;
2215 int njetNow = mergingHooksPtr->getNumberOfClusteringSteps( state) ;
2216 if (njetNow >= njetMax)
return 1.0;
2219 bool FSR = mother->state[clusterIn.emittor].isFinal();
2220 int emtID = mother->state[clusterIn.emtPos()].id();
2223 if (abs(emtID) == 22 || abs(emtID) == 23 || abs(emtID) == 24)
return w;
2225 if (njetNow < njetMin ) w *= 1.0;
2228 if ( asFSR && asISR ) {
2229 double asScale = pow2( scale );
2230 if (!infoPtr->settingsPtr->flag(
"Dire:doMOPS")
2231 && mergingHooksPtr->unorderedASscalePrescip() == 1)
2232 asScale = pow2( clusterIn.pT() );
2235 if (!FSR) asScale += pow2(mergingHooksPtr->pT0ISR());
2238 asScale = getShowerPluginScale(mother->state, clusterIn.emittor,
2239 clusterIn.emtPos(), clusterIn.recoiler, clusterIn.name(),
2240 "scaleAS", asScale);
2242 double alphaSinPS = (FSR) ? (*asFSR).alphaS(asScale)
2243 : (*asISR).alphaS(asScale);
2244 w *= alphaSinPS / as0;
2256 vector<double> DireHistory::weightCouplings() {
2259 if ( !mother )
return createvector<double>(1.)(1.)(1.);
2261 vector<double> w = mother->weightCouplings();
2263 if (state.size() < 3)
return w;
2266 int rad = clusterIn.radPos();
2267 int rec = clusterIn.recPos();
2268 int emt = clusterIn.emtPos();
2269 string name = clusterIn.name();
2271 if (!(fsr && isr))
return createvector<double>(1.)(1.)(1.);
2272 bool isFSR = fsr->isTimelike(mother->state, rad, emt, rec,
"");
2273 bool isISR = isr->isSpacelike(mother->state, rad, emt, rec,
"");
2274 double mu2Ren = pow2(mergingHooksPtr->muR());
2275 double t = pow2(scale);
2276 double renormMultFacFSR
2277 = infoPtr->settingsPtr->parm(
"TimeShower:renormMultFac");
2278 double renormMultFacISR
2279 = infoPtr->settingsPtr->parm(
"SpaceShower:renormMultFac");
2280 if (isFSR) t *= renormMultFacFSR;
2281 else if (isISR) t *= renormMultFacISR;
2283 double couplingOld(1.), couplingNew(1.);
2284 if (isFSR) couplingOld = fsr->getCoupling( mu2Ren, name);
2285 if (isISR) couplingOld = isr->getCoupling( mu2Ren, name);
2286 vector<double> variations(createvector<double>(1.)(0.25)(4.));
2287 for (
size_t i=0; i<variations.size(); ++i) {
2288 if (isFSR) couplingNew = fsr->getCoupling( variations[i]*t, name);
2289 if (isISR) couplingNew = fsr->getCoupling( variations[i]*t, name);
2290 w[i] *= couplingNew / couplingOld;
2301 vector<double> DireHistory::weightCouplingsDenominator() {
2304 if ( !mother )
return createvector<double>(1.)(1.)(1.);
2306 vector<double> w = mother->weightCouplingsDenominator();
2308 if (state.size() < 3)
return w;
2310 if (!(fsr && isr))
return createvector<double>(1.)(1.)(1.);
2311 for (
size_t i=0; i<w.size(); ++i) {
2312 w[i] *= clusterCoupl*2.*M_PI;
2323 double DireHistory::weightALPHAEM(
double aem0, AlphaEM * aemFSR,
2324 AlphaEM * aemISR,
int njetMin,
int njetMax ) {
2327 if ( !mother )
return 1.;
2329 double w = mother->weightALPHAEM( aem0, aemFSR, aemISR, njetMin, njetMax);
2331 if (state.size() < 3)
return w;
2334 int njetNow = mergingHooksPtr->getNumberOfClusteringSteps( state) ;
2335 if (njetNow >= njetMax)
return 1.0;
2338 bool FSR = mother->state[clusterIn.emittor].isFinal();
2339 int emtID = mother->state[clusterIn.emtPos()].id();
2342 if (!(abs(emtID) == 22 || abs(emtID) == 23 || abs(emtID) == 24))
return w;
2344 if (njetNow < njetMin ) w *= 1.0;
2347 if ( aemFSR && aemISR ) {
2348 double aemScale = pow2( scale );
2349 if (!infoPtr->settingsPtr->flag(
"Dire:doMOPS")
2350 && mergingHooksPtr->unorderedASscalePrescip() == 1)
2351 aemScale = pow2( clusterIn.pT() );
2354 if (!FSR) aemScale += pow2(mergingHooksPtr->pT0ISR());
2357 aemScale = getShowerPluginScale(mother->state, clusterIn.emittor,
2358 clusterIn.emtPos(), clusterIn.recoiler, clusterIn.name(),
2359 "scaleEM", aemScale);
2361 double alphaEMinPS = (FSR) ? (*aemFSR).alphaEM(aemScale)
2362 : (*aemISR).alphaEM(aemScale);
2363 w *= alphaEMinPS / aem0;
2375 double DireHistory::weightPDFs(
double maxscale,
double pdfScale,
2376 int njetMin,
int njetMax ) {
2379 double newScale = scale;
2380 int njetNow = mergingHooksPtr->getNumberOfClusteringSteps( state);
2386 if (njetMax > -1 && njetNow > njetMax)
return 1.0;
2389 int sideRad = (state[3].pz() > 0) ? 1 :-1;
2390 int sideRec = (state[4].pz() > 0) ? 1 :-1;
2393 if (state[3].colType() != 0) {
2395 double x = 2.*state[3].e() / state[0].e();
2396 int flav = state[3].id();
2398 double scaleNum = (children.empty()) ? hardFacScale(state) : maxscale;
2399 double scaleDen = mergingHooksPtr->muFinME();
2401 if (njetMin > -1 && njetNow >= njetMin ) wt *= getPDFratio(sideRad,
2402 false,
false, flav, x, scaleNum, flav, x, scaleDen);
2403 else if (njetMin == -1) wt *= getPDFratio(sideRad,
2404 false,
false, flav, x, scaleNum, flav, x, scaleDen);
2408 if (state[4].colType() != 0) {
2410 double x = 2.*state[4].e() / state[0].e();
2411 int flav = state[4].id();
2413 double scaleNum = (children.empty()) ? hardFacScale(state) : maxscale;
2414 double scaleDen = mergingHooksPtr->muFinME();
2415 if (njetMin > -1 && njetNow >= njetMin ) wt *= getPDFratio(sideRec,
2416 false,
false, flav, x, scaleNum, flav, x, scaleDen);
2417 else if (njetMin == -1) wt *= getPDFratio(sideRec,
2418 false,
false, flav, x, scaleNum, flav, x, scaleDen);
2426 double newPDFscale = newScale;
2427 if ( !infoPtr->settingsPtr->flag(
"Dire:doMOPS")
2428 && mergingHooksPtr->unorderedPDFscalePrescip() == 1)
2429 newPDFscale = clusterIn.pT();
2432 double w = mother->weightPDFs( newScale, newPDFscale, njetMin, njetMax);
2435 if (state.size() < 3)
return w;
2440 int sideP = (mother->state[inP].pz() > 0) ? 1 :-1;
2441 int sideM = (mother->state[inM].pz() > 0) ? 1 :-1;
2443 if ( mother->state[inP].colType() != 0 ) {
2445 double x = getCurrentX(sideP);
2446 int flav = getCurrentFlav(sideP);
2448 double scaleNum = (children.empty())
2449 ? hardFacScale(state)
2450 : ( (!infoPtr->settingsPtr->flag(
"Dire:doMOPS")
2451 && mergingHooksPtr->unorderedPDFscalePrescip() == 1)
2452 ? pdfScale : maxscale );
2453 double scaleDen = ( !infoPtr->settingsPtr->flag(
"Dire:doMOPS")
2454 && mergingHooksPtr->unorderedPDFscalePrescip() == 1)
2455 ? clusterIn.pT() : newScale;
2456 double xDen = (njetMax > -1 && njetNow == njetMax)
2457 ? mother->getCurrentX(sideP) : x;
2458 int flavDen = (njetMax > -1 && njetNow == njetMax)
2459 ? mother->getCurrentFlav(sideP) : flav;
2460 double sDen = (njetMax > -1 && njetNow == njetMax)
2461 ? mergingHooksPtr->muFinME() : scaleDen;
2462 if (njetMin > -1 && njetNow >= njetMin ) w *= getPDFratio(sideP,
2463 false,
false, flav, x, scaleNum, flavDen, xDen, sDen);
2464 else if (njetMin == -1) w *= getPDFratio(sideP,
2465 false,
false, flav, x, scaleNum, flavDen, xDen, sDen);
2468 if ( mother->state[inM].colType() != 0 ) {
2470 double x = getCurrentX(sideM);
2471 int flav = getCurrentFlav(sideM);
2473 double scaleNum = (children.empty())
2474 ? hardFacScale(state)
2475 : ( (!infoPtr->settingsPtr->flag(
"Dire:doMOPS")
2476 && mergingHooksPtr->unorderedPDFscalePrescip() == 1)
2477 ? pdfScale : maxscale );
2478 double scaleDen = ( !infoPtr->settingsPtr->flag(
"Dire:doMOPS")
2479 && mergingHooksPtr->unorderedPDFscalePrescip() == 1)
2480 ? clusterIn.pT() : newScale;
2481 double xDen = (njetMax > -1 && njetNow == njetMax)
2482 ? mother->getCurrentX(sideM) : x;
2483 int flavDen = (njetMax > -1 && njetNow == njetMax)
2484 ? mother->getCurrentFlav(sideM) : flav;
2485 double sDen = (njetMax > -1 && njetNow == njetMax)
2486 ? mergingHooksPtr->muFinME() : scaleDen;
2487 if (njetMin > -1 && njetNow >= njetMin ) w *= getPDFratio(sideM,
2488 false,
false, flav, x, scaleNum, flavDen, xDen, sDen);
2489 else if (njetMin == -1) w *= getPDFratio(sideM,
2490 false,
false, flav, x, scaleNum, flavDen, xDen, sDen);
2501 double DireHistory::weightEmissions( PartonLevel* trial,
int type,
2502 int njetMin,
int njetMax,
double maxscale ) {
2505 double newScale = scale;
2508 if ( !mother )
return 1.0;
2510 double w = mother->weightEmissions(trial,type,njetMin,njetMax,newScale);
2512 if (state.size() < 3)
return 1.0;
2514 if ( w < 1e-12 )
return 0.0;
2516 int njetNow = mergingHooksPtr->getNumberOfClusteringSteps( state) ;
2517 if (njetMax > -1 && njetNow >= njetMax)
return 1.0;
2518 if (njetMin > -1 && njetNow < njetMin ) w *= 1.0;
2520 else w *= doTrialShower(trial, type, maxscale).front();
2522 if ( abs(w) < 1e-12 )
return 0.0;
2532 vector<double> DireHistory::weightEmissionsVec( PartonLevel* trial,
int type,
2533 int njetMin,
int njetMax,
double maxscale ) {
2536 double newScale = scale;
2539 if (!mother)
return createvector<double>(1.)(1.)(1.);
2542 vector<double> w = mother->weightEmissionsVec(trial, type, njetMin, njetMax,
2545 if (state.size() < 3)
return createvector<double>(1.)(1.)(1.);
2547 bool nonZero =
false;
2548 for (
size_t i=0; i < w.size(); ++i)
if (abs(w[i]) > 1e-12) nonZero =
true;
2549 if (!nonZero)
return createvector<double>(0.)(0.)(0.);
2551 int njetNow = mergingHooksPtr->getNumberOfClusteringSteps(state);
2552 if (njetMax > -1 && njetNow >= njetMax)
2553 return createvector<double>(1.)(1.)(1.);
2556 if (njetMin > -1 && njetNow < njetMin ) ;
2559 vector<double> wem = doTrialShower(trial, type, maxscale);
2560 for (
size_t i=0; i < w.size(); ++i) w[i] *= wem[i];
2564 for (
size_t i=0; i < w.size(); ++i)
if (abs(w[i]) > 1e-12) nonZero =
true;
2565 if (!nonZero)
return createvector<double>(0.)(0.)(0.);
2576 double DireHistory::weightFirst(PartonLevel* trial,
double as0,
double muR,
2577 double maxscale, AlphaStrong * asFSR, AlphaStrong * asISR, Rndm* rndmPtr ) {
2580 double newScale = scale;
2587 if (state[3].colType() != 0) {
2589 double x = 2.*state[3].e() / state[0].e();
2590 int flav = state[3].id();
2592 double scaleNum = (children.empty()) ? hardFacScale(state) : maxscale;
2593 double scaleDen = mergingHooksPtr->muFinME();
2595 double intPDF4 = monteCarloPDFratios(flav, x, scaleNum, scaleDen,
2596 mergingHooksPtr->muFinME(), as0, rndmPtr);
2601 if (state[4].colType() != 0) {
2603 double x = 2.*state[4].e() / state[0].e();
2604 int flav = state[4].id();
2606 double scaleNum = (children.empty()) ? hardFacScale(state) : maxscale;
2607 double scaleDen = mergingHooksPtr->muFinME();
2609 double intPDF4 = monteCarloPDFratios(flav, x, scaleNum, scaleDen,
2610 mergingHooksPtr->muFinME(), as0, rndmPtr);
2618 double w = mother->weightFirst(trial, as0, muR, newScale, asFSR, asISR,
2622 if (state.size() < 3)
return 0.0;
2626 double asScale2 = newScale*newScale;
2627 int showerType = (mother->state[clusterIn.emittor].isFinal() ) ? 1 : -1;
2628 if (showerType == -1) asScale2 += pow(mergingHooksPtr->pT0ISR(),2);
2631 asScale2 = getShowerPluginScale(mother->state, clusterIn.emittor,
2632 clusterIn.emtPos(), clusterIn.recoiler, clusterIn.name(),
2633 "scaleAS", asScale2);
2637 double BETA0 = 11. - 2./3.* NF;
2639 w += as0 / (2.*M_PI) * 0.5 * BETA0 * log( (muR*muR) / (b*asScale2) );
2645 double nWeight1 = 0.;
2646 double nWeight2 = 0.;
2648 for(
int i=0; i < NTRIAL; ++i) {
2650 vector<double> unresolvedEmissionTerm = countEmissions(trial, maxscale,
2651 newScale, 2, as0, asFSR, asISR, 3, fixpdf, fixas);
2652 nWeight1 += unresolvedEmissionTerm[1];
2654 w += nWeight1/double(NTRIAL) + nWeight2/double(NTRIAL);
2659 int sideP = (mother->state[inP].pz() > 0) ? 1 :-1;
2660 int sideM = (mother->state[inM].pz() > 0) ? 1 :-1;
2662 if ( mother->state[inP].colType() != 0 ) {
2664 double x = getCurrentX(sideP);
2665 int flav = getCurrentFlav(sideP);
2667 double scaleNum = (children.empty()) ? hardFacScale(state) : maxscale;
2669 double intPDF4 = monteCarloPDFratios(flav, x, scaleNum, newScale,
2670 mergingHooksPtr->muFinME(), as0, rndmPtr);
2675 if ( mother->state[inM].colType() != 0 ) {
2677 double x = getCurrentX(sideM);
2678 int flav = getCurrentFlav(sideM);
2680 double scaleNum = (children.empty()) ? hardFacScale(state) : maxscale;
2682 double intPDF4 = monteCarloPDFratios(flav, x, scaleNum, newScale,
2683 mergingHooksPtr->muFinME(), as0, rndmPtr);
2698 double DireHistory::weightFirstALPHAS(
double as0,
double muR,
2699 AlphaStrong * asFSR, AlphaStrong * asISR ) {
2702 double newScale = scale;
2704 if ( !mother )
return 0.;
2706 double w = mother->weightFirstALPHAS( as0, muR, asFSR, asISR );
2708 int showerType = (mother->state[clusterIn.emittor].isFinal() ) ? 1 : -1;
2710 double asScale = pow2( newScale );
2711 if ( mergingHooksPtr->unorderedASscalePrescip() == 1 )
2712 asScale = pow2( clusterIn.pT() );
2713 if (showerType == -1)
2714 asScale += pow2( mergingHooksPtr->pT0ISR() );
2717 asScale = getShowerPluginScale(mother->state, clusterIn.emittor,
2718 clusterIn.emtPos(), clusterIn.recoiler, clusterIn.name(),
2719 "scaleAS", asScale);
2723 double BETA0 = 11. - 2./3.* NF;
2725 w += as0 / (2.*M_PI) * 0.5 * BETA0 * log( (muR*muR) / (b*asScale) );
2737 double DireHistory::weightFirstPDFs(
double as0,
double maxscale,
2738 double pdfScale, Rndm* rndmPtr ) {
2741 double newScale = scale;
2748 if (state[3].colType() != 0) {
2750 double x = 2.*state[3].e() / state[0].e();
2751 int flav = state[3].id();
2753 double scaleNum = (children.empty()) ? hardFacScale(state) : maxscale;
2754 double scaleDen = mergingHooksPtr->muFinME();
2756 wt += monteCarloPDFratios(flav, x, scaleNum, scaleDen,
2757 mergingHooksPtr->muFinME(), as0, rndmPtr);
2760 if (state[4].colType() != 0) {
2762 double x = 2.*state[4].e() / state[0].e();
2763 int flav = state[4].id();
2765 double scaleNum = (children.empty()) ? hardFacScale(state) : maxscale;
2766 double scaleDen = mergingHooksPtr->muFinME();
2768 wt += monteCarloPDFratios(flav, x, scaleNum, scaleDen,
2769 mergingHooksPtr->muFinME(), as0, rndmPtr);
2778 double newPDFscale = newScale;
2779 if (mergingHooksPtr->unorderedPDFscalePrescip() == 1)
2780 newPDFscale = clusterIn.pT();
2783 double w = mother->weightFirstPDFs( as0, newScale, newPDFscale, rndmPtr);
2788 int sideP = (mother->state[inP].pz() > 0) ? 1 :-1;
2789 int sideM = (mother->state[inM].pz() > 0) ? 1 :-1;
2791 if ( mother->state[inP].colType() != 0 ) {
2793 double x = getCurrentX(sideP);
2794 int flav = getCurrentFlav(sideP);
2796 double scaleNum = (children.empty())
2797 ? hardFacScale(state)
2798 : ( (mergingHooksPtr->unorderedPDFscalePrescip() == 1)
2799 ? pdfScale : maxscale );
2800 double scaleDen = (mergingHooksPtr->unorderedPDFscalePrescip() == 1)
2801 ? clusterIn.pT() : newScale;
2803 w += monteCarloPDFratios(flav, x, scaleNum, scaleDen,
2804 mergingHooksPtr->muFinME(), as0, rndmPtr);
2807 if ( mother->state[inM].colType() != 0 ) {
2809 double x = getCurrentX(sideM);
2810 int flav = getCurrentFlav(sideM);
2812 double scaleNum = (children.empty())
2813 ? hardFacScale(state)
2814 : ( (mergingHooksPtr->unorderedPDFscalePrescip() == 1)
2815 ? pdfScale : maxscale );
2816 double scaleDen = (mergingHooksPtr->unorderedPDFscalePrescip() == 1)
2817 ? clusterIn.pT() : newScale;
2819 w += monteCarloPDFratios(flav, x, scaleNum, scaleDen,
2820 mergingHooksPtr->muFinME(), as0, rndmPtr);
2834 double DireHistory::weightFirstEmissions(PartonLevel* trial,
double as0,
2835 double maxscale, AlphaStrong * asFSR, AlphaStrong * asISR,
2836 bool fixpdf,
bool fixas ) {
2839 double newScale = scale;
2840 if ( !mother )
return 0.0;
2842 double w = mother->weightFirstEmissions(trial, as0, newScale, asFSR, asISR,
2845 if (state.size() < 3)
return 0.0;
2847 double nWeight1 = 0.;
2848 double nWeight2 = 0.;
2849 for(
int i=0; i < NTRIAL; ++i) {
2851 vector<double> unresolvedEmissionTerm = countEmissions(trial, maxscale,
2852 newScale, 2, as0, asFSR, asISR, 3, fixpdf, fixas);
2853 nWeight1 += unresolvedEmissionTerm[1];
2856 w += nWeight1/double(NTRIAL) + nWeight2/double(NTRIAL);
2867 double DireHistory::hardFacScale(
const Event& event) {
2870 double hardscale = 0.;
2872 if ( !mergingHooksPtr->resetHardQFac() )
return mergingHooksPtr->muF();
2877 if ( mergingHooksPtr->getProcessString().compare(
"pp>jj") == 0
2878 || mergingHooksPtr->getProcessString().compare(
"pp>aj") == 0
2879 || isQCD2to2(event)) {
2882 for (
int i=0; i <
event.size(); ++i)
2883 if ( event[i].isFinal() &&
event[i].colType() != 0 )
2884 mT.push_back( abs(event[i].mT2()) );
2885 if (
int(mT.size()) != 2 )
2886 hardscale = infoPtr->QFac();
2888 hardscale = sqrt( min( mT[0], mT[1] ) );
2891 }
else if ( mergingHooksPtr->getProcessString().compare(
"e+p>e+j") == 0
2892 || mergingHooksPtr->getProcessString().compare(
"e-p>e-j") == 0) {
2894 if ( isDIS2to2(event)) {
2895 int iInEl(0), iOutEl(0);
2896 for (
int i=0; i <
event.size(); ++i )
2897 if ( event[i].idAbs() == 11 ) {
2898 if ( event[i].status() == -21 ) iInEl = i;
2899 if ( event[i].isFinal() ) iOutEl = i;
2901 hardscale = sqrt( -(event[iInEl].p()-event[iOutEl].p()).m2Calc() );
2904 }
else if (isMassless2to2(event)) {
2908 for (
int i=0; i <
event.size(); ++i)
2909 if ( event[i].isFinal() &&
event[i].colType() != 0 )
2910 mT.push_back( abs(event[i].mT2()) );
2911 if (
int(mT.size()) != 2 )
2912 hardscale = infoPtr->QFac();
2914 hardscale = sqrt( min( mT[0], mT[1] ) );
2916 }
else hardscale = mergingHooksPtr->muF();
2919 hardscale = mergingHooksPtr->muF();
2929 double DireHistory::hardRenScale(
const Event& event) {
2931 double hardscale = 0.;
2933 if ( !mergingHooksPtr->resetHardQRen() )
return mergingHooksPtr->muR();
2937 if ( mergingHooksPtr->getProcessString().compare(
"pp>jj") == 0
2938 || mergingHooksPtr->getProcessString().compare(
"pp>aj") == 0
2939 || isQCD2to2(event)) {
2942 for (
int i=0; i <
event.size(); ++i)
2943 if ( event[i].isFinal()
2944 && (
event[i].colType() != 0 ||
event[i].id() == 22 ) )
2945 mT.push_back( abs(event[i].mT()) );
2946 if (
int(mT.size()) != 2 )
2947 hardscale = infoPtr->QRen();
2949 hardscale = sqrt( mT[0]*mT[1] );
2952 }
else if ( mergingHooksPtr->getProcessString().compare(
"e+p>e+j") == 0
2953 || mergingHooksPtr->getProcessString().compare(
"e-p>e-j") == 0) {
2955 if ( isDIS2to2(event)) {
2956 int iInEl(0), iOutEl(0);
2957 for (
int i=0; i < state.size(); ++i )
2958 if ( state[i].idAbs() == 11 ) {
2959 if ( state[i].status() == -21 ) iInEl = i;
2960 if ( state[i].isFinal() ) iOutEl = i;
2962 hardscale = sqrt( -(state[iInEl].p()-state[iOutEl].p()).m2Calc() );
2965 }
else if (isMassless2to2(event)) {
2969 for (
int i=0; i <
event.size(); ++i)
2970 if ( event[i].isFinal() &&
event[i].colType() != 0 )
2971 mT.push_back( abs(event[i].mT2()) );
2972 if (
int(mT.size()) != 2 )
2973 hardscale = infoPtr->QFac();
2975 hardscale = sqrt( min( mT[0], mT[1] ) );
2977 }
else hardscale = mergingHooksPtr->muF();
2980 hardscale = mergingHooksPtr->muR();
2990 double DireHistory::hardStartScale(
const Event& event) {
2993 map<string,double> stateVarsISR;
2995 if ( showers && showers->spacePtr) stateVarsISR
2996 = showers->spacePtr->getStateVariables(event,0,0,0,
"");
2997 if (!showers && isr) stateVarsISR
2998 = isr->getStateVariables(event,0,0,0,
"");
3001 map<string,double> stateVarsFSR;
3002 if ( showers && showers->timesPtr ) stateVarsFSR
3003 = showers->timesPtr->getStateVariables(event,0,0,0,
"");
3004 if (!showers && fsr) stateVarsFSR
3005 = fsr->getStateVariables(event,0,0,0,
"");
3008 double hardscale = 0.;
3009 for ( map<string,double>::iterator it = stateVarsISR.begin();
3010 it != stateVarsISR.end(); ++it )
3011 if ( it->first.find(
"scalePDF") != string::npos )
3012 hardscale = max( hardscale, sqrt(it->second) );
3013 for ( map<string,double>::iterator it = stateVarsFSR.begin();
3014 it != stateVarsFSR.end(); ++it )
3015 if ( it->first.find(
"scalePDF") != string::npos )
3016 hardscale = max( hardscale, sqrt(it->second) );
3033 vector<double> DireHistory::doTrialShower( PartonLevel* trial,
int type,
3034 double maxscaleIn,
double minscaleIn ) {
3037 Event process = state;
3039 double startingScale = maxscaleIn;
3042 if ( mergingHooksPtr->getNumberOfClusteringSteps(process) == 0
3043 && ( mergingHooksPtr->getProcessString().compare(
"pp>jj") == 0
3044 || mergingHooksPtr->getProcessString().compare(
"pp>aj") == 0
3045 || isQCD2to2(state) ) )
3046 startingScale = min( startingScale, hardFacScale(process) );
3049 if ( mergingHooksPtr->getNumberOfClusteringSteps(process) == 0
3050 && ( mergingHooksPtr->getProcessString().compare(
"e+p>e+j") == 0
3051 || mergingHooksPtr->getProcessString().compare(
"e-p>e-j") == 0))
3053 startingScale = hardFacScale(process);
3055 if ( mergingHooksPtr->getNumberOfClusteringSteps(process) == 0 )
3056 startingScale = hardStartScale(process);
3060 vector <double> wtv(createvector<double>(1.)(1.)(1.));
3061 int nFSRtry(0), nISRtry(0), nMPItry(0);
3067 trial->resetTrial();
3070 event.init(
"(hard process-modified)", particleDataPtr);
3074 process.scale(startingScale);
3078 double minScale = (minscaleIn > 0.) ? minscaleIn : scale;
3080 mergingHooksPtr->setShowerStoppingScale(minScale);
3084 if (type == -1 && nFSRtry+nISRtry > 500) {
break;}
3089 if (minScale >= startingScale)
break;
3095 double z = ( mergingHooksPtr->getNumberOfClusteringSteps(state) == 0
3098 : mother->getCurrentZ(clusterIn.emittor,clusterIn.recoiler,
3099 clusterIn.emtPos(), clusterIn.flavRadBef);
3101 infoPtr->zNowISR(z);
3102 infoPtr->pT2NowISR(pow(startingScale,2));
3103 infoPtr->hasHistory(
true);
3106 trial->next(process,event);
3108 double pTtrial = trial->pTLastInShower();
3109 int typeTrial = trial->typeLastInShower();
3111 if (typeTrial == 1) nMPItry++;
3112 else if (typeTrial == 2) nISRtry++;
3116 trial->resetTrial();
3118 double t = (pTtrial <= 0.) ? pow2(minScale) : pow2(pTtrial);
3119 pair<double,double> wtShower = psweights->getWeight(t);
3120 pair<double,double> wt_isr_1 = psweights->getWeight
3121 (t,
"Variations:muRisrDown");
3122 pair<double,double> wt_isr_2 = psweights->getWeight
3123 (t,
"Variations:muRisrUp");
3124 pair<double,double> wt_fsr_1 = psweights->getWeight
3125 (t,
"Variations:muRfsrDown");
3126 pair<double,double> wt_fsr_2 = psweights->getWeight
3127 (t,
"Variations:muRfsrUp");
3129 double enhancement = 1.;
3130 if ( pTtrial > minScale) enhancement
3131 = psweights->getTrialEnhancement( pow2(pTtrial));
3133 if (pTtrial>0.) psweights->init();
3134 psweights->clearTrialEnhancements();
3137 double vetoScale = (mother) ? 0. : mergingHooksPtr->tms();
3139 double tnow = mergingHooksPtr->tmsNow( event );
3142 if ( pTtrial < minScale ) {
3143 wt *= wtShower.second;
3144 wtv[0] *= wtShower.second;
3145 wtv[1] *= wt_isr_1.second*wt_fsr_1.second;
3146 wtv[2] *= wt_isr_2.second*wt_fsr_2.second;
3151 startingScale = pTtrial;
3154 if ( tnow < vetoScale && vetoScale > 0. )
continue;
3157 if ( mergingHooksPtr->canVetoTrialEmission()
3158 && mergingHooksPtr->doVetoTrialEmission( process, event) )
continue;
3160 int iRecAft =
event.size() - 1;
3161 int iEmt =
event.size() - 2;
3162 int iRadAft =
event.size() - 3;
3163 if ( (event[iRecAft].status() != 52 && event[iRecAft].status() != -53) ||
3164 event[iEmt].status() != 51 || event[iRadAft].status() != 51)
3165 iRecAft = iEmt = iRadAft = -1;
3166 for (
int i = event.size() - 1; i > 0; i--) {
3167 if (iRadAft == -1 && event[i].status() == -41) iRadAft = i;
3168 else if (iEmt == -1 && event[i].status() == 43) iEmt = i;
3169 else if (iRecAft == -1 && event[i].status() == -42) iRecAft = i;
3170 if (iRadAft != -1 && iEmt != -1 && iRecAft != -1)
break;
3175 bool onCthreshold(
false), onBthreshold(
false);
3176 if (process[3].colType() != 0 || process[4].colType() != 0 ) {
3178 = infoPtr->settingsPtr->flag(
"ShowerPDF:usePDFalphas");
3179 BeamParticle*
beam = (particleDataPtr->isHadron(beamA.id())) ? &beamA
3180 : (particleDataPtr->isHadron(beamB.id())) ? &beamB
3182 double m2cPhys = (usePDFalphas) ? pow2(max(0.,beam->mQuarkPDF(4)))
3183 : mergingHooksPtr->AlphaS_ISR()->muThres2(4);
3184 double m2bPhys = (usePDFalphas) ? pow2(max(0.,beam->mQuarkPDF(5)))
3185 : mergingHooksPtr->AlphaS_ISR()->muThres2(5);
3186 if ( event[iEmt].idAbs() == 4 && minScale < sqrt(m2cPhys)
3187 && pTtrial > (1. - MCWINDOW)*sqrt(m2cPhys)
3188 && pTtrial < (1. + MCWINDOW)*sqrt(m2cPhys)) onCthreshold =
true;
3189 if ( event[iEmt].idAbs() == 5 && minScale < sqrt(m2bPhys)
3190 && pTtrial > (1. - MBWINDOW)*sqrt(m2bPhys)
3191 && pTtrial < (1. + MBWINDOW)*sqrt(m2bPhys)) onBthreshold =
true;
3196 if ( type == -1 && typeTrial != 1 ) {
3201 if (onCthreshold || onBthreshold) {
break; }
3205 if ( type == 1 && !(typeTrial == 2 || typeTrial >= 3) )
continue;
3207 if (pTtrial > minScale) {
3208 wt *= wtShower.first*wtShower.second * (1.-1./enhancement);
3209 wtv[0] *= wtShower.first*wtShower.second * (1.-1./enhancement);
3210 wtv[1] *= wt_isr_1.first*wt_isr_1.second*wt_fsr_1.first*wt_fsr_1.second
3211 *(1.-1./enhancement);
3212 wtv[2] *= wt_isr_2.first*wt_isr_2.second*wt_fsr_2.first*wt_fsr_2.second
3213 *(1.-1./enhancement);
3215 if (wt == 0.)
break;
3217 if (pTtrial > minScale)
continue;
3223 && mergingHooksPtr->getNumberOfClusteringSteps(process) == 0
3224 && ( mergingHooksPtr->getProcessString().compare(
"pp>jj") == 0
3225 || mergingHooksPtr->getProcessString().compare(
"pp>aj") == 0
3226 || isQCD2to2(state))
3227 && pTtrial > hardFacScale(process) )
3228 return createvector<double>(0.)(0.)(0.);
3237 trial->resetTrial();
3251 bool DireHistory::updateind(vector<int> & ind,
int i,
int N) {
3252 if ( i < 0 )
return false;
3253 if ( ++ind[i] < N )
return true;
3254 if ( !updateind(ind, i - 1, N - 1) )
return false;
3255 ind[i] = ind[i - 1] + 1;
3266 DireHistory::countEmissions(PartonLevel* trial,
double maxscale,
3267 double minscale,
int showerType,
double as0,
3268 AlphaStrong * asFSR, AlphaStrong * asISR,
int N = 1,
3269 bool fixpdf =
true,
bool fixas =
true) {
3271 if ( N < 0 )
return vector<double>();
3272 vector<double> result(N+1);
3274 if ( N < 1 )
return result;
3277 Event process = state;
3279 double startingScale = maxscale;
3282 if ( mergingHooksPtr->getNumberOfClusteringSteps(process) == 0
3283 && ( mergingHooksPtr->getProcessString().compare(
"pp>jj") == 0
3284 || mergingHooksPtr->getProcessString().compare(
"pp>aj") == 0
3285 || isQCD2to2(state) ) )
3286 startingScale = min( startingScale, hardFacScale(process) );
3289 bool canEnhanceTrial = trial->canEnhanceTrial();
3295 trial->resetTrial();
3298 event.init(
"(hard process-modified)", particleDataPtr);
3302 process.scale(startingScale);
3307 if (minscale >= startingScale)
return result;
3313 double z = ( mergingHooksPtr->getNumberOfClusteringSteps(state) == 0)
3315 : mother->getCurrentZ(clusterIn.emittor,clusterIn.recoiler,
3316 clusterIn.emtPos());
3318 infoPtr->zNowISR(z);
3319 infoPtr->pT2NowISR(pow(startingScale,2));
3320 infoPtr->hasHistory(
true);
3324 trial->next(process,event);
3327 double pTtrial = trial->pTLastInShower();
3328 int typeTrial = trial->typeLastInShower();
3331 trial->resetTrial();
3334 double pTEnhanced = trial->getEnhancedTrialPT();
3335 double wtEnhanced = trial->getEnhancedTrialWeight();
3336 if ( canEnhanceTrial && pTEnhanced > 0.) pTtrial = pTEnhanced;
3339 double vetoScale = (mother) ? 0. : mergingHooksPtr->tms();
3341 double tnow = mergingHooksPtr->tmsNow( event );
3344 startingScale = pTtrial;
3346 if ( pTtrial < minscale )
break;
3348 if ( tnow < vetoScale && vetoScale > 0. )
continue;
3350 if ( mergingHooksPtr->canVetoTrialEmission()
3351 && mergingHooksPtr->doVetoTrialEmission( process, event) )
continue;
3354 double enhance = (canEnhanceTrial && pTtrial > minscale) ? wtEnhanced : 1.;
3359 double alphaSinPS = as0;
3362 double asScale2 = pTtrial*pTtrial;
3364 asScale2 = getShowerPluginScale(mother->state, clusterIn.emittor,
3365 clusterIn.emtPos(), clusterIn.recoiler, clusterIn.name(),
3366 "scaleAS", asScale2);
3369 if ( (showerType == -1 || showerType == 2) && typeTrial == 2 ) {
3371 if ( fixas ) alphaSinPS = (*asISR).alphaS(asScale2);
3376 pdfs = pdfFactor( process, event, typeTrial, pTtrial,
3377 mergingHooksPtr->muFinME() );
3379 }
else if ( (showerType == 1 || showerType == 2) && typeTrial >= 3 ) {
3381 if ( fixas ) alphaSinPS = (*asFSR).alphaS(asScale2);
3385 pdfs = pdfFactor( process, event, typeTrial, pTtrial,
3386 mergingHooksPtr->muFinME() );
3390 if ( typeTrial == 2 || typeTrial >= 3 )
3391 wts.push_back(as0/alphaSinPS * pdfs * 1./enhance);
3395 for (
int n = 1; n <= min(N,
int(wts.size())); ++n ) {
3397 for (
int i = 0; i < N; ++i ) ind[i] = i;
3400 for (
int j = 0; j < n; ++j ) x *= wts[ind[j]];
3402 }
while ( updateind(ind, n - 1, wts.size()) );
3403 if ( n%2 ) result[n] *= -1.0;
3408 trial->resetTrial();
3419 double DireHistory::monteCarloPDFratios(
int flav,
double x,
double maxScale,
3420 double minScale,
double pdfScale,
double asME, Rndm* rndmPtr) {
3424 double factor = asME / (2.*M_PI);
3426 factor *= log(maxScale/minScale);
3429 if (factor == 0.)
return 0.;
3437 double integral = 0.;
3438 double RN = rndmPtr->flat();
3441 double zTrial = pow(x,RN);
3442 integral = -log(x) * zTrial *
3443 integrand(flav, x, pdfScale, zTrial);
3444 integral += 1./6.*(11.*CA - 4.*NF*TR)
3447 double zTrial = x + RN*(1. - x);
3449 integrand(flav, x, pdfScale, zTrial);
3450 integral += 3./2.*CF
3455 return (factor*integral);
3466 bool DireHistory::onlyOrderedPaths() {
3467 if ( !mother || foundOrderedPath )
return foundOrderedPath;
3468 return foundOrderedPath = mother->onlyOrderedPaths();
3477 bool DireHistory::onlyAllowedPaths() {
3478 if ( !mother || foundAllowedPath )
return foundAllowedPath;
3479 return foundAllowedPath = mother->onlyAllowedPaths();
3491 bool DireHistory::registerPath(DireHistory & l,
bool isOrdered,
3492 bool isAllowed,
bool isComplete) {
3495 if ( l.prodOfProbs <= 0.0)
3498 if ( mother )
return mother->registerPath(l, isOrdered,
3499 isAllowed, isComplete);
3502 if ( sumpath == sumpath + l.prodOfProbs )
3504 if ( mergingHooksPtr->canCutOnRecState()
3505 && foundAllowedPath && !isAllowed )
3507 if ( mergingHooksPtr->orderHistories()
3508 && foundOrderedPath && !isOrdered ) {
3510 if ( (!foundCompletePath && isComplete)
3511 || (!foundAllowedPath && isAllowed) ) ;
3515 if ( foundCompletePath && !isComplete)
3517 if ( !mergingHooksPtr->canCutOnRecState()
3518 && !mergingHooksPtr->allowCutOnRecState() )
3519 foundAllowedPath =
true;
3521 if ( mergingHooksPtr->canCutOnRecState() && isAllowed && isComplete) {
3522 if ( !foundAllowedPath || !foundCompletePath ) {
3528 foundAllowedPath =
true;
3532 if ( mergingHooksPtr->orderHistories() && isOrdered && isComplete ) {
3533 if ( !foundOrderedPath || !foundCompletePath ) {
3539 foundOrderedPath =
true;
3540 foundCompletePath =
true;
3545 if ( !foundCompletePath ) {
3551 foundCompletePath =
true;
3554 if ( isOrdered ) foundOrderedPath =
true;
3557 sumpath += l.prodOfProbs;
3558 paths[sumpath] = &l;
3560 updateProbMax(l.prodOfProbs, isComplete);
3571 vector<DireClustering> DireHistory::getAllClusterings(
const Event& event) {
3573 vector<DireClustering> ret;
3574 vector<DireClustering> systems;
3576 for (
int i=0; i <
event.size(); ++i) {
3577 if ( event[i].isFinal() ) {
3578 for (
int j=0; j <
event.size(); ++j) {
3579 if ( i == j)
continue;
3580 bool isInitial = (
event[j].status() == -21
3581 ||
event[j].status() == -41 ||
event[j].status() == -42
3582 ||
event[j].status() == -53
3583 ||
event[j].status() == -31 ||
event[j].status() == -34);
3584 if (!isInitial && !event[j].isFinal() )
continue;
3585 systems = getClusterings( i, j, event);
3586 ret.insert(ret.end(), systems.begin(), systems.end());
3593 vector<int> iRemove;
3594 for (
unsigned int i=0; i < ret.size(); ++i) {
3595 for (
unsigned int j=i; j < ret.size(); ++j) {
3596 if (i == j)
continue;
3597 if (find(iRemove.begin(), iRemove.end(), j) != iRemove.end())
continue;
3598 if ( equalClustering(ret[i], ret[j])) iRemove.push_back(j);
3601 sort (iRemove.begin(), iRemove.end());
3602 for (
int i = iRemove.size()-1; i >= 0; --i) {
3603 ret[iRemove[i]] = ret.back();
3614 void DireHistory::attachClusterings (vector<DireClustering>& clus,
int iEmt,
3616 int iRec,
int iPartner,
double pT,
string name,
const Event& event) {
3619 if (pT <= 0.)
return;
3621 if ( !mergingHooksPtr->doWeakClustering() ) {
3623 clus.push_back( DireClustering(iEmt, iRad, iRec, iPartner, pT,
3624 &event[iRad], &event[iEmt], &event[iRec], name, 0, 0, 0, 0));
3629 map<string,double> stateVars;
3630 bool hasPartonLevel(showers && showers->timesPtr && showers->spacePtr),
3631 hasShowers(fsr && isr);
3632 if (hasPartonLevel) {
3633 bool isFSR = showers->timesPtr->isTimelike(event, iRad, iEmt, iRec,
"");
3634 if (isFSR) stateVars = showers->timesPtr->getStateVariables(event,iRad,
3636 else stateVars = showers->spacePtr->getStateVariables(event,iRad,
3638 }
else if (hasShowers) {
3639 bool isFSR = fsr->isTimelike(event, iRad, iEmt, iRec,
"");
3640 if (isFSR) stateVars = fsr->getStateVariables(event,iRad,iEmt,iRec,name);
3641 else stateVars = isr->getStateVariables(event,iRad,iEmt,iRec,name);
3645 int radBeforeFlav = int(stateVars[
"radBefID"]);
3647 clus.push_back( DireClustering(iEmt, iRad, iRec, iPartner, pT,
3648 &event[iRad], &event[iEmt], &event[iRec], name, radBeforeFlav, 0, 0, 0));
3669 vector<DireClustering> DireHistory::getClusterings (
int emt,
int rad,
3670 const Event& event ) {
3672 vector<DireClustering> clus;
3675 bool isFSR(
false), isISR(
false), hasShowers(fsr && isr),
3676 hasPartonLevel(showers && showers->timesPtr && showers->spacePtr);
3677 if (hasPartonLevel) {
3678 isFSR = showers->timesPtr->allowedSplitting(event, rad, emt);
3679 isISR = showers->spacePtr->allowedSplitting(event, rad, emt);
3680 }
else if (hasShowers) {
3681 isFSR = fsr->allowedSplitting(event, rad, emt);
3682 isISR = isr->allowedSplitting(event, rad, emt);
3686 vector<string> names = hasPartonLevel
3687 ? showers->timesPtr->getSplittingName(event,rad,emt,0)
3688 : hasShowers ? fsr->getSplittingName(event,rad,emt,0) : vector<string>();
3689 for (
int iName=0; iName < int(names.size()); ++iName) {
3690 vector<int> recsNow = hasPartonLevel
3691 ? showers->timesPtr->getRecoilers(event, rad, emt, names[iName])
3692 : (hasShowers ? fsr->getRecoilers(event, rad, emt, names[iName])
3694 for (
int i = 0; i < int(recsNow.size()); ++i ) {
3695 if ( allowedClustering( rad, emt, recsNow[i], recsNow[i],
3696 names[iName], event) ) {
3697 double pT = pTLund(event, rad, emt, recsNow[i], names[iName]);
3698 attachClusterings (clus, emt, rad, recsNow[i], recsNow[i], pT,
3699 names[iName], event);
3706 vector<string> names = hasPartonLevel
3707 ? showers->spacePtr->getSplittingName(event,rad,emt,0)
3708 : hasShowers ? isr->getSplittingName(event,rad,emt,0) : vector<string>();
3710 for (
int iName=0; iName < int(names.size()); ++iName) {
3711 vector<int> recsNow = hasPartonLevel
3712 ? showers->spacePtr->getRecoilers(event, rad, emt, names[iName])
3713 : (hasShowers ? isr->getRecoilers(event, rad, emt, names[iName])
3715 for (
int i = 0; i < int(recsNow.size()); ++i ) {
3716 if ( allowedClustering( rad, emt, recsNow[i], recsNow[i],
3717 names[iName], event) ) {
3718 attachClusterings (clus, emt, rad, recsNow[i], recsNow[i],
3719 pTLund(event, rad, emt, recsNow[i], names[iName]),
3720 names[iName], event);
3737 pair<double,double> DireHistory::getProb(
const DireClustering & SystemIn) {
3740 int rad = SystemIn.radPos();
3741 int rec = SystemIn.recPos();
3742 int emt = SystemIn.emtPos();
3743 string name = SystemIn.name();
3747 if (SystemIn.pT() <= 0.) {
return make_pair(1.,0.);}
3749 double pr(0.), coupling(1.);
3751 bool isFSR(
false), isISR(
false), hasShowers(fsr && isr),
3752 hasPartonLevel(showers && showers->timesPtr && showers->spacePtr);
3753 if (hasPartonLevel) {
3754 isFSR = showers->timesPtr->isTimelike(state, rad, emt, rec,
"");
3755 isISR = showers->spacePtr->isSpacelike(state, rad, emt, rec,
"");
3756 }
else if (hasShowers) {
3757 isFSR = fsr->isTimelike(state, rad, emt, rec,
"");
3758 isISR = isr->isSpacelike(state, rad, emt, rec,
"");
3766 pr += hasPartonLevel
3767 ? showers->timesPtr->getSplittingProb( state, rad, emt, rec, name)
3768 : hasShowers ? fsr->getSplittingProb( state, rad, emt, rec, name) : 0.;
3771 double mu2Ren = pow2(mergingHooksPtr->muR());
3772 name=name.substr( 0, name.size()-2);
3773 coupling = fsr->getCoupling( mu2Ren, name);
3780 pr += hasPartonLevel
3781 ? showers->spacePtr->getSplittingProb( state, rad, emt, rec, name)
3782 : hasShowers ? isr->getSplittingProb( state, rad, emt, rec, name) : 0.;
3785 double mu2Ren = pow2(mergingHooksPtr->muR());
3786 name=name.substr( 0, name.size()-2);
3787 coupling = isr->getCoupling( mu2Ren, name);
3792 return make_pair(coupling,pr);
3808 void DireHistory::setupBeams() {
3813 if (state.size() < 4)
return;
3816 if ( state[3].colType() == 0 && state[4].colType() == 0 )
return;
3822 for(
int i=0;i< int(state.size()); ++i) {
3823 if (state[i].mother1() == 1) inP = i;
3824 if (state[i].mother1() == 2) inM = i;
3829 int motherPcompRes = -1;
3830 int motherMcompRes = -1;
3832 bool sameFlavP =
false;
3833 bool sameFlavM =
false;
3838 for(
int i=0;i< int(mother->state.size()); ++i) {
3839 if (mother->state[i].mother1() == 1) inMotherP = i;
3840 if (mother->state[i].mother1() == 2) inMotherM = i;
3842 sameFlavP = (state[inP].id() == mother->state[inMotherP].id());
3843 sameFlavM = (state[inM].id() == mother->state[inMotherM].id());
3845 motherPcompRes = (sameFlavP) ? beamA[0].companion() : -2;
3846 motherMcompRes = (sameFlavM) ? beamB[0].companion() : -2;
3854 double Ep = 2. * state[inP].e();
3855 double Em = 2. * state[inM].e();
3858 if (state[inP].m() != 0. || state[inM].m() != 0.) {
3859 Ep = state[inP].pPos() + state[inM].pPos();
3860 Em = state[inP].pNeg() + state[inM].pNeg();
3864 double x1 = Ep / state[inS].m();
3865 beamA.append( inP, state[inP].
id(), x1);
3866 double x2 = Em / state[inS].m();
3867 beamB.append( inM, state[inM].
id(), x2);
3871 double scalePDF = (mother) ? scale : infoPtr->QFac();
3875 beamA.xfISR( 0, state[inP].
id(), x1, scalePDF*scalePDF);
3877 beamA.pickValSeaComp();
3879 beamA[0].companion(motherPcompRes);
3881 beamB.xfISR( 0, state[inM].
id(), x2, scalePDF*scalePDF);
3883 beamB.pickValSeaComp();
3885 beamB[0].companion(motherMcompRes);
3895 double DireHistory::pdfForSudakov() {
3898 if ( state[3].colType() == 0 )
return 1.0;
3899 if ( state[4].colType() == 0 )
return 1.0;
3902 bool FSR = ( mother->state[clusterIn.emittor].isFinal()
3903 && mother->state[clusterIn.recoiler].isFinal());
3904 bool FSRinRec = ( mother->state[clusterIn.emittor].isFinal()
3905 && !mother->state[clusterIn.recoiler].isFinal());
3908 if (FSR)
return 1.0;
3910 int iInMother = (FSRinRec)? clusterIn.recoiler : clusterIn.emittor;
3912 int side = ( mother->state[iInMother].pz() > 0 ) ? 1 : -1;
3916 for(
int i=0;i< int(state.size()); ++i) {
3917 if (state[i].mother1() == 1) inP = i;
3918 if (state[i].mother1() == 2) inM = i;
3922 int idMother = mother->state[iInMother].id();
3924 int iDau = (side == 1) ? inP : inM;
3925 int idDaughter = state[iDau].id();
3927 double xMother = 2. * mother->state[iInMother].e() / mother->state[0].e();
3929 double xDaughter = 2.*state[iDau].e() / state[0].e();
3932 double ratio = getPDFratio(side,
true,
false, idMother, xMother, scale,
3933 idDaughter, xDaughter, scale);
3938 return ( (FSRinRec)? min(1.,ratio) : ratio);
3946 double DireHistory::hardProcessME(
const Event& event ) {
3949 if (isEW2to1(event)) {
3952 if (event[5].idAbs() == 24) {
3953 int idIn1 =
event[3].id();
3954 int idIn2 =
event[4].id();
3955 double mW = particleDataPtr->m0(24);
3956 double gW = particleDataPtr->mWidth(24) / mW;
3957 double sH = (
event[3].p()+
event[4].p()).m2Calc();
3959 double thetaWRat = 1. / (12. * coupSMPtr->sin2thetaW());
3960 double ckmW = coupSMPtr->V2CKMid(abs(idIn1), abs(idIn2));
3962 double bwW = 12. * M_PI / ( pow2(sH - pow2(mW)) + pow2(sH * gW) );
3963 double preFac = thetaWRat * sqrt(sH) * particleDataPtr->mWidth(24);
3964 return ckmW * preFac * bwW;
3968 else if (event[5].idAbs() == 23) {
3969 double mZ = particleDataPtr->m0(23);
3970 double gZ = particleDataPtr->mWidth(23) / mZ;
3971 double sH = (
event[3].p()+
event[4].p()).m2Calc();
3972 int flav = (mother) ? abs(clusterIn.flavRadBef) :
event[3].idAbs();
3974 (pow2(coupSMPtr->rf( flav )) + pow2(coupSMPtr->lf( flav ))) /
3975 (24. * coupSMPtr->sin2thetaW() * coupSMPtr->cos2thetaW());
3976 double bwW = 12. * M_PI / ( pow2(sH - pow2(mZ)) + pow2(sH * gZ) );
3977 double preFac = thetaZRat * sqrt(sH) * particleDataPtr->mWidth(23);
3978 return preFac * bwW;
3982 string message=
"Warning in DireHistory::hardProcessME: Only Z/W are";
3983 message+=
" supported as 2->1 processes. Skipping history.";
3984 infoPtr->errorMsg(message);
3989 else if (isQCD2to2(event)) {
3990 int idIn1 =
event[3].id();
3991 int idIn2 =
event[4].id();
3992 int idOut1 =
event[5].id();
3993 int idOut2 =
event[6].id();
3995 double sH = (
event[3].p()+
event[4].p()).m2Calc();
3996 double tH = (
event[3].p()-
event[5].p()).m2Calc();
3997 double uH = (
event[3].p()-
event[6].p()).m2Calc();
4001 if (!(abs(idIn1) < 10 || abs(idIn1) == 21) ) isQCD =
false;
4002 if (!(abs(idIn2) < 10 || abs(idIn2) == 21) ) isQCD =
false;
4003 if (!(abs(idOut1) < 10 || abs(idOut1) == 21) ) isQCD =
false;
4004 if (!(abs(idOut2) < 10 || abs(idOut2) == 21) ) isQCD =
false;
4008 double cor = 1. / (9. * pow2(sH));
4011 double mu2Ren = pow2(mergingHooksPtr->muR());
4012 cor *= pow2( mergingHooksPtr->AlphaS_ISR()->alphaS(mu2Ren) );
4019 if (abs(idIn1) == 21 && abs(idIn2) == 21) {
4020 if (abs(idOut1) == 21 && abs(idOut2) == 21)
4021 return cor * weakShowerMEs.getMEgg2gg(sH, tH, uH);
4022 else return cor * weakShowerMEs.getMEgg2qqbar(sH, tH, uH);
4025 }
else if (abs(idIn1) == 21 || abs(idIn2) == 21) {
4026 if (idIn1 != idOut1) swap(uH, tH);
4027 return cor * weakShowerMEs.getMEqg2qg(sH, tH, uH);
4032 if (abs(idOut1) == 21 && abs(idOut2) == 21) {
4033 return cor * weakShowerMEs.getMEqqbar2gg(sH, tH, uH);
4036 if (idIn1 == -idIn2) {
4037 if (abs(idIn1) == abs(idOut1)) {
4038 if (idIn1 != idOut1) swap(uH, tH);
4039 return cor * weakShowerMEs.getMEqqbar2qqbar(sH, tH, uH,
true);
4042 return cor * weakShowerMEs.getMEqqbar2qqbar(sH, tH, uH,
false);
4045 else if (idIn1 == idIn2)
4046 return cor * weakShowerMEs.getMEqq2qq(sH, tH, uH,
true);
4048 if (idIn1 == idOut1) swap(uH,tH);
4049 return cor * weakShowerMEs.getMEqq2qq(sH, tH, uH,
false);
4056 if ( isDIS2to2(event) ) {
4059 int iIncEl(0), iOutEl(0), iIncP(0);
4060 for (
int i=0; i <
event.size(); ++i ) {
4061 if ( event[i].idAbs() == 11 ) {
4062 if ( event[i].status() == -21 ) iIncEl = i;
4063 if ( event[i].isFinal() ) iOutEl = i;
4065 if ( event[i].colType() != 0 ) {
4066 if ( event[i].status() == -21 ) iIncP = i;
4070 Vec4 pgam( event[iIncEl].p() - event[iOutEl].p() );
4071 Vec4 pprot( (event[iIncP].mother1() == 1) ? event[1].p() : event[2].p() );
4072 double s = pow2(event[0].m());
4073 double Q2 = -pgam.m2Calc();
4074 double y = (pprot*pgam) / (pprot*event[iIncEl].p());
4075 double x = Q2 / (2.*pprot*pgam);
4076 double res = 4.*M_PI / (s*pow2(x)*pow2(y))*(1. - y + 0.5*pow2(y));
4080 }
else if (isMassless2to2(event)) {
4081 int idIn1 =
event[3].id();
4082 int idIn2 =
event[4].id();
4083 int idOut1 =
event[5].id();
4084 int idOut2 =
event[6].id();
4086 double sH = (
event[3].p()+
event[4].p()).m2Calc();
4087 double tH = (
event[3].p()-
event[5].p()).m2Calc();
4088 double uH = (
event[3].p()-
event[6].p()).m2Calc();
4091 int inc1Type = particleDataPtr->colType(idIn1);
4092 int inc2Type = particleDataPtr->colType(idIn2);
4093 int out1Type = particleDataPtr->colType(idOut1);
4094 int out2Type = particleDataPtr->colType(idOut2);
4095 bool isQCD = (inc1Type*inc2Type*out1Type*out2Type != 0);
4098 double cor = M_PI / (9. * pow2(sH));
4105 if (abs(idIn1) == 21 && abs(idIn2) == 21) {
4106 if (abs(idOut1) == 21 && abs(idOut2) == 21)
4107 return cor * weakShowerMEs.getMEgg2gg(sH, tH, uH);
4108 else return cor * weakShowerMEs.getMEgg2qqbar(sH, tH, uH);
4111 }
else if (abs(idIn1) == 21 || abs(idIn2) == 21) {
4112 if (idIn1 != idOut1) swap(uH, tH);
4113 return cor * weakShowerMEs.getMEqg2qg(sH, tH, uH);
4118 if (abs(idOut1) == 21 && abs(idOut2) == 21)
4119 return cor * weakShowerMEs.getMEqqbar2gg(sH, tH, uH);
4120 if (idIn1 == -idIn2) {
4121 if (abs(idIn1) == abs(idOut1)) {
4122 if (idIn1 != idOut1) swap(uH, tH);
4123 return cor * weakShowerMEs.getMEqqbar2qqbar(sH, tH, uH,
true);
4126 return cor * weakShowerMEs.getMEqqbar2qqbar(sH, tH, uH,
false);
4129 else if (idIn1 == idIn2)
4130 return cor * weakShowerMEs.getMEqq2qq(sH, tH, uH,
true);
4132 if (idIn1 == idOut1) swap(uH,tH);
4133 return cor * weakShowerMEs.getMEqq2qq(sH, tH, uH,
false);
4139 if ( (idIn1 == 21 && idIn2 == 22) || (idIn1 == 22 && idIn2 == 21) )
4140 return cor * weakShowerMEs.getMEgg2qqbar(sH, tH, uH);
4143 if ( (abs(idIn1) < 10 && idIn2 == 22) || (idIn1 == 22 && abs(idIn2) < 10)){
4144 if (idIn1 != idOut1) swap(uH, tH);
4145 return cor * weakShowerMEs.getMEqg2qg(sH, tH, uH);
4151 string process = mergingHooksPtr->getProcessString();
4154 if ( process.compare(
"pp>e+ve") == 0
4155 || process.compare(
"pp>e-ve~") == 0
4156 || process.compare(
"pp>LEPTONS,NEUTRINOS") == 0 ) {
4159 for (
int i=0; i < int(event.size()); ++i )
4160 if ( event[i].isFinal() ) nFinal++;
4161 if ( nFinal != 2 )
return 1.;
4163 double mW = particleDataPtr->m0(24);
4164 double gW = particleDataPtr->mWidth(24) / mW;
4166 int inP = (
event[3].pz() > 0) ? 3 : 4;
4167 int inM = (
event[3].pz() > 0) ? 4 : 3;
4170 for (
int i=0; i < int(event.size()); ++i ) {
4171 if ( event[i].isFinal() &&
event[i].px() > 0 ) outP = i;
4174 double sH = (
event[inP].p() +
event[inM].p()).m2Calc();
4175 double tH = (
event[inP].p() -
event[outP].p()).m2Calc();
4176 double uH = - sH - tH;
4179 result = ( 1. + (tH - uH)/sH ) / ( pow2(sH - mW*mW) + pow2(sH*gW) );
4181 result = mergingHooksPtr->hardProcessME(event);
4193 double DireHistory::hardProcessCouplings(
const Event& event,
int order,
4194 double scale2, AlphaStrong* alphaS, AlphaEM* alphaEM,
4195 bool fillCouplCounters,
bool with2Pi) {
4197 vector<int> nwp, nwm, nz, nh, na, nl, nlq, ng, nq, nqb;
4199 for (
int i=0; i <
event.size(); ++i) {
4200 if (event[i].mother1() == 1 &&
event[i].mother2() == 0) in1 = i;
4201 if (event[i].mother1() == 2 &&
event[i].mother2() == 0) in2 = i;
4202 if (event[i].isFinal()) {
4203 if (event[i].
id() == 21) ng.push_back(i);
4204 if (event[i].
id() == 22) na.push_back(i);
4205 if (event[i].
id() == 23) nz.push_back(i);
4206 if (event[i].
id() == 24) nwp.push_back(i);
4207 if (event[i].
id() ==-24) nwm.push_back(i);
4208 if (event[i].
id() == 25) nh.push_back(i);
4209 if (event[i].isLepton()) nl.push_back(i);
4210 if (event[i].colType() == 1) nq.push_back(i);
4211 if (event[i].colType() ==-1) nqb.push_back(i);
4215 double twopi = (with2Pi) ? 2.*M_PI : 1.;
4216 double as2pi = (order == 0)
4217 ? infoPtr->settingsPtr->parm(
"SigmaProcess:alphaSvalue")/twopi
4218 : alphaS->alphaS(scale2)/twopi;
4219 double aem2pi = (order == 0)
4220 ? infoPtr->settingsPtr->parm(
"StandardModel:alphaEM0")/twopi
4221 : alphaEM->alphaEM(scale2)/twopi;
4225 result *= pow(aem2pi,na.size());
4226 if (fillCouplCounters) couplingPowCount[
"qed"]+=na.size();
4228 result *= pow(aem2pi,nwp.size()+nwm.size()+nz.size());
4229 if (fillCouplCounters) couplingPowCount[
"qed"]+=nwp.size()+nwm.size()+
4232 result *= pow(as2pi,ng.size());
4233 if (fillCouplCounters) couplingPowCount[
"qcd"]+=ng.size();
4237 (event[in1].colType() == 0 && event[in2].colType() == 0)
4238 && (nq.size() == 1 && nqb.size() == 1)
4239 && (event[nq[0]].
id() == -
event[nqb[0]].id()) ) {
4242 result *= pow(aem2pi,2.0);
4243 if (fillCouplCounters) couplingPowCount[
"qed"]+=2;
4245 (event[in1].colType() == 0 && event[in2].colType() == 1)
4246 && (nq.size() == 1 &&
event[in2].id() ==
event[nq[0]].id()) ) {
4248 result *= pow(aem2pi,2.0);
4249 if (fillCouplCounters) couplingPowCount[
"qed"]+=2;
4251 (event[in2].colType() == 0 && event[in1].colType() == 1)
4252 && (nq.size() == 1 &&
event[in1].id() ==
event[nq[0]].id()) ) {
4254 result *= pow(aem2pi,2.0);
4255 if (fillCouplCounters) couplingPowCount[
"qed"]+=2;
4257 (event[in1].colType() == 0 && event[in2].colType() ==-1)
4258 && (nqb.size() == 1 &&
event[in2].id() ==
event[nqb[0]].id()) ) {
4260 result *= pow(aem2pi,2.0);
4261 if (fillCouplCounters) couplingPowCount[
"qed"]+=2;
4263 (event[in2].colType() == 0 && event[in1].colType() ==-1)
4264 && (nqb.size() == 1 &&
event[in1].id() ==
event[nqb[0]].id()) ) {
4266 result *= pow(aem2pi,2.0);
4267 if (fillCouplCounters) couplingPowCount[
"qed"]+=2;
4270 result *= pow(as2pi,nq.size()+nqb.size());
4271 if (fillCouplCounters) couplingPowCount[
"qcd"]+=nq.size()+nqb.size();
4275 if ( nh.size() > 0 ) {
4277 double sH =
event[nh.front()].m2Calc();
4278 double mH = sqrt(sH);
4281 if (event[in1].
id() == event[in2].
id() && event[in1].
id() == 21)
4282 width = particleDataPtr->particleDataEntryPtr(25)->resWidthChan(
4284 else if (event[in1].
id() == -event[in2].
id() && event[in1].idAbs() < 9)
4285 width = particleDataPtr->particleDataEntryPtr(25)->resWidthChan(
4286 mH, event[in1].
id(), -event[in1].
id()) / 9.;
4287 else if (event[in1].
id() == 21 && event[in2].idAbs() < 9)
4288 width = max(particleDataPtr->particleDataEntryPtr(25)->resWidthChan(
4290 particleDataPtr->particleDataEntryPtr(25)->resWidthChan(
4291 mH, event[in1].
id(), -event[in1].
id()) / 9.);
4292 else if (event[in2].
id() == 21 && event[in1].idAbs() < 9)
4293 width = max(particleDataPtr->particleDataEntryPtr(25)->resWidthChan(
4295 particleDataPtr->particleDataEntryPtr(25)->resWidthChan(
4296 mH, event[in2].
id(), -event[in2].
id()) / 9.);
4298 double m2Res = pow2(particleDataPtr->m0(25));
4299 double widthTot = particleDataPtr->particleDataEntryPtr(25)->
4303 if (width/widthTot < 1e-4) {
4305 for (
int i=0; i <
event.size(); ++i) {
4306 if (i != nh.front() &&
event[i].isFinal()) {
4307 int sign = particleDataPtr->hasAnti(event[i].
id()) ? -1 : 1;
4308 double widthNew = particleDataPtr->particleDataEntryPtr(25)->
4309 resWidthChan( mH, event[i].
id(), sign*event[i].
id());
4310 if (event[i].
id() == 21) widthNew /= 64.;
4311 if (event[i].idAbs() < 9) widthNew /= 9.;
4312 if (widthNew/widthTot > 1e-4 && widthNew/widthTot > width/widthTot){
4313 width = widthNew;
break;
4321 double sigBW = 8. * M_PI/ ( pow2(sH - m2Res) + pow2(mH * widthTot) );
4324 if (width/widthTot < 1e-4) width = 0.;
4326 double asRatio = (order==0) ? 1.
4327 : pow2(alphaS->alphaS(scale2)/alphaS->alphaS(125.*125.));
4328 double res = pow(width*sigBW*asRatio,nh.size());
4331 if (fillCouplCounters) {
4332 couplingPowCount[
"qcd"]+=2;
4333 couplingPowCount[
"heft"]++;
4343 double DireHistory::hardProcessScale(
const Event& event) {
4346 double nFinal(0.), mTprod(1.);
4347 for (
int i=0; i <
event.size(); ++i)
4348 if ( event[i].isFinal() ) {
4350 mTprod *= abs(event[i].mT());
4352 double hardScale = (mTprod!=1.) ? pow(mTprod, 1./nFinal) : infoPtr->QRen();
4366 Event DireHistory::cluster( DireClustering & inSystem ) {
4369 int rad = inSystem.radPos();
4370 int rec = inSystem.recPos();
4371 int emt = inSystem.emtPos();
4372 string name = inSystem.name();
4376 newEvent.init(
"(hard process-modified)", particleDataPtr);
4379 bool isFSR(
false), hasShowers(fsr && isr),
4380 hasPartonLevel(showers && showers->timesPtr && showers->spacePtr);
4381 if (hasPartonLevel) {
4382 isFSR = showers->timesPtr->isTimelike(state, rad, emt, rec,
"");
4383 }
else if (hasShowers) {
4384 isFSR = fsr->isTimelike(state, rad, emt, rec,
"");
4388 newEvent = (hasPartonLevel
4389 ? showers->timesPtr->clustered( state, rad, emt, rec, name)
4390 : hasShowers ? fsr->clustered( state, rad, emt, rec, name)
4393 newEvent = (hasPartonLevel
4394 ? showers->spacePtr->clustered( state, rad, emt, rec, name)
4395 : hasShowers ? isr->clustered( state, rad, emt, rec, name)
4400 if (newEvent.size() > 0) {
4401 inSystem.recBef = newEvent[0].mother2();
4402 inSystem.radBef = newEvent[0].mother1();
4403 newEvent[0].mothers(0,0);
4418 int DireHistory::getRadBeforeFlav(
const int RadAfter,
const int EmtAfter,
4419 const Event& event) {
4421 int type =
event[RadAfter].isFinal() ? 1 :-1;
4422 int emtID =
event[EmtAfter].id();
4423 int radID =
event[RadAfter].id();
4424 int emtCOL =
event[EmtAfter].col();
4425 int radCOL =
event[RadAfter].col();
4426 int emtACL =
event[EmtAfter].acol();
4427 int radACL =
event[RadAfter].acol();
4429 bool colConnected = ((type == 1) && ( (emtCOL !=0 && (emtCOL ==radACL))
4430 || (emtACL !=0 && (emtACL ==radCOL)) ))
4431 ||((type ==-1) && ( (emtCOL !=0 && (emtCOL ==radCOL))
4432 || (emtACL !=0 && (emtACL ==radACL)) ));
4438 if ( type == 1 && emtID == -radID && !colConnected )
4441 if ( type ==-1 && radID == 21 )
4444 if ( type ==-1 && !colConnected && radID != 21 && abs(emtID) < 10
4449 int radSign = (radID < 0) ? -1 : 1;
4450 int offsetL = 1000000;
4451 int offsetR = 2000000;
4453 if ( emtID == 1000021 ) {
4455 if (abs(radID) < 10 ) {
4456 int offset = offsetL;
4459 for (
int i=0; i < int(event.size()); ++i)
4460 if ( event[i].isFinal()
4461 &&
event[i].idAbs() < offsetR+10 &&
event[i].idAbs() > offsetR)
4463 return radSign*(abs(radID)+offset);
4466 if (abs(radID) > offsetL && abs(radID) < offsetL+10 )
4467 return radSign*(abs(radID)-offsetL);
4468 if (abs(radID) > offsetR && abs(radID) < offsetR+10 )
4469 return radSign*(abs(radID)-offsetR);
4471 if (radID == 21 )
return emtID;
4474 int emtSign = (emtID < 0) ? -1 : 1;
4477 if ( abs(emtID) > offsetL && abs(emtID) < offsetL+10 )
4478 emtOffset = offsetL;
4479 if ( abs(emtID) > offsetR && abs(emtID) < offsetR+10 )
4480 emtOffset = offsetR;
4482 if ( abs(radID) > offsetL && abs(radID) < offsetL+10 )
4483 radOffset = offsetL;
4484 if ( abs(radID) > offsetR && abs(radID) < offsetR+10 )
4485 radOffset = offsetR;
4488 if ( type == 1 && !colConnected ) {
4490 if ( emtOffset > 0 && radOffset == 0
4491 && emtSign*(abs(emtID) - emtOffset) == -radID )
4494 if ( emtOffset == 0 && radOffset > 0
4495 && emtID == -radSign*(abs(radID) - radOffset) )
4500 if ( type ==-1 && radID == 1000021 ) {
4502 if ( emtOffset > 0 )
return -emtSign*(abs(emtID) - emtOffset);
4504 else return -emtSign*(abs(emtID) + emtOffset);
4509 && ( (abs(emtID) > offsetL && abs(emtID) < offsetL+10)
4510 || (abs(emtID) > offsetR && abs(emtID) < offsetR+10))
4511 && ( (abs(radID) > offsetL && abs(radID) < offsetL+10)
4512 || (abs(radID) > offsetR && abs(radID) < offsetR+10))
4513 && emtSign*(abs(emtID)+emtOffset) == radSign*(abs(radID) - radOffset)
4514 && !colConnected ) {
4520 double m2final = (
event[RadAfter].p()+
event[EmtAfter].p()).m2Calc();
4522 if ( emtID == 22 || emtID == 23 )
return radID;
4524 if ( type == 1 && emtID == -radID && colConnected && sqrt(m2final) <= 10. )
4527 if ( type == 1 && emtID == -radID && colConnected && sqrt(m2final) > 10. )
4530 if ( type ==-1 && (radID == 22 || radID == 23) )
4533 if ( type ==-1 && abs(emtID) < 10 && abs(radID) < 10 && colConnected )
4538 if ( emtID == 24 && radID < 0 )
return radID + 1;
4539 if ( emtID == 24 && radID > 0 )
return radID + 1;
4543 if ( emtID ==-24 && radID < 0 )
return radID - 1;
4544 if ( emtID ==-24 && radID > 0 )
return radID - 1;
4558 int DireHistory::getRadBeforeSpin(
const int radAfter,
const int emtAfter,
4559 const int spinRadAfter,
const int spinEmtAfter,
4560 const Event& event) {
4563 int radBeforeFlav = getRadBeforeFlav(radAfter, emtAfter, event);
4566 if ( event[radAfter].isFinal()
4567 && event[radAfter].
id() == -event[emtAfter].
id())
4568 return (spinRadAfter == 9) ? spinEmtAfter : spinRadAfter;
4571 if ( event[radAfter].isFinal() && abs(radBeforeFlav) < 10
4572 && event[radAfter].idAbs() < 10)
4574 return spinRadAfter;
4577 if ( event[radAfter].isFinal() && abs(radBeforeFlav) < 10
4578 && event[emtAfter].idAbs() < 10)
4580 return spinEmtAfter;
4583 if ( event[radAfter].isFinal() && radBeforeFlav == 21
4584 && event[radAfter].
id() == 21)
4586 return (spinRadAfter == 9) ? spinEmtAfter : spinRadAfter;
4589 if ( !event[radAfter].isFinal()
4590 && radBeforeFlav == -event[emtAfter].
id())
4591 return (spinRadAfter == 9) ? spinEmtAfter : spinRadAfter;
4594 if ( !event[radAfter].isFinal() && abs(radBeforeFlav) < 10
4595 && event[radAfter].idAbs() < 10)
4597 return spinRadAfter;
4600 if ( !event[radAfter].isFinal() && radBeforeFlav == 21
4601 && event[emtAfter].idAbs() < 10)
4603 return spinEmtAfter;
4622 bool DireHistory::connectRadiator( Particle& Radiator,
const int RadType,
4623 const Particle& Recoiler,
const int RecType,
4624 const Event& event ) {
4627 Radiator.cols( -1, -1 );
4631 if ( Radiator.colType() == -1 ) {
4634 if ( RadType + RecType == 2 )
4635 Radiator.cols( 0, Recoiler.col());
4636 else if ( RadType + RecType == 0 )
4637 Radiator.cols( 0, Recoiler.acol());
4645 for (
int i = 0; i <
event.size(); ++i) {
4646 int col =
event[i].col();
4647 int acl =
event[i].acol();
4649 if ( event[i].isFinal()) {
4651 if ( acl > 0 && FindCol(acl,i,0,event,1,
true) == 0
4652 && FindCol(acl,i,0,event,2,
true) == 0 )
4653 Radiator.acol(event[i].acol());
4656 if ( col > 0 && FindCol(col,i,0,event,1,
true) == 0
4657 && FindCol(col,i,0,event,2,
true) == 0 )
4658 Radiator.acol(event[i].col());
4663 }
else if ( Radiator.colType() == 1 ) {
4666 if ( RadType + RecType == 2 )
4667 Radiator.cols( Recoiler.acol(), 0);
4669 else if ( RadType + RecType == 0 )
4670 Radiator.cols( Recoiler.col(), 0);
4679 for (
int i = 0; i <
event.size(); ++i) {
4680 int col =
event[i].col();
4681 int acl =
event[i].acol();
4683 if ( event[i].isFinal()) {
4685 if ( col > 0 && FindCol(col,i,0,event,1,
true) == 0
4686 && FindCol(col,i,0,event,2,
true) == 0)
4687 Radiator.col(event[i].col());
4690 if ( acl > 0 && FindCol(acl,i,0,event,1,
true) == 0
4691 && FindCol(acl,i,0,event,2,
true) == 0)
4692 Radiator.col(event[i].acol());
4698 }
else if ( Radiator.colType() == 2 ) {
4704 for (
int i = 0; i <
event.size(); ++i) {
4705 int col =
event[i].col();
4706 int acl =
event[i].acol();
4709 if ( event[i].isFinal()) {
4710 if ( col > 0 && FindCol(col,iEx,0,event,1,
true) == 0
4711 && FindCol(col,iEx,0,event,2,
true) == 0) {
4712 if (Radiator.status() < 0 ) Radiator.col(event[i].col());
4713 else Radiator.acol(event[i].col());
4715 if ( acl > 0 && FindCol(acl,iEx,0,event,2,
true) == 0
4716 && FindCol(acl,iEx,0,event,1,
true) == 0 ) {
4717 if (Radiator.status() < 0 ) Radiator.acol(event[i].acol());
4718 else Radiator.col(event[i].acol());
4721 if ( col > 0 && FindCol(col,iEx,0,event,1,
true) == 0
4722 && FindCol(col,iEx,0,event,2,
true) == 0) {
4723 if (Radiator.status() < 0 ) Radiator.acol(event[i].col());
4724 else Radiator.col(event[i].col());
4726 if ( acl > 0 && (FindCol(acl,iEx,0,event,2,
true) == 0
4727 && FindCol(acl,iEx,0,event,1,
true) == 0)) {
4728 if (Radiator.status() < 0 ) Radiator.col(event[i].acol());
4729 else Radiator.acol(event[i].acol());
4736 if (Radiator.col() < 0 || Radiator.acol() < 0)
return false;
4758 int DireHistory::FindCol(
int col,
int iExclude1,
int iExclude2,
4759 const Event& event,
int type,
bool isHardIn) {
4761 bool isHard = isHardIn;
4766 for(
int n = 0; n <
event.size(); ++n) {
4767 if ( n != iExclude1 && n != iExclude2
4768 && event[n].colType() != 0
4769 &&(
event[n].status() > 0
4770 ||
event[n].status() == -21) ) {
4771 if ( event[n].acol() == col ) {
4775 if ( event[n].col() == col ) {
4784 for(
int n = 0; n <
event.size(); ++n) {
4785 if ( n != iExclude1 && n != iExclude2
4786 && event[n].colType() != 0
4787 &&(
event[n].status() == 43
4788 ||
event[n].status() == 51
4789 ||
event[n].status() == -41
4790 ||
event[n].status() == -42) ) {
4791 if ( event[n].acol() == col ) {
4795 if ( event[n].col() == col ) {
4803 if ( type == 1 && index < 0)
return abs(index);
4804 if ( type == 2 && index > 0)
return abs(index);
4818 int DireHistory::FindParticle(
const Particle& particle,
const Event& event,
4819 bool checkStatus ) {
4823 for (
int i =
int(event.size()) - 1; i > 0; --i )
4824 if ( event[i].
id() == particle.id()
4825 &&
event[i].colType() == particle.colType()
4826 &&
event[i].chargeType() == particle.chargeType()
4827 &&
event[i].col() == particle.col()
4828 &&
event[i].acol() == particle.acol()
4829 &&
event[i].charge() == particle.charge() ) {
4834 if ( checkStatus && event[index].status() != particle.status() )
4849 int DireHistory::getRadBeforeCol(
const int rad,
const int emt,
4850 const Event& event) {
4853 int type = (
event[rad].isFinal()) ? 1 :-1;
4855 int radBeforeFlav = getRadBeforeFlav(rad,emt,event);
4857 int radBeforeCol = -1;
4859 if (radBeforeFlav == 21) {
4862 if (type == 1 && event[emt].
id() != 21) {
4863 radBeforeCol = (
event[rad].col() > 0)
4864 ? event[rad].col() :
event[emt].col();
4866 }
else if (type == -1 && event[emt].
id() != 21) {
4867 radBeforeCol = (
event[rad].col() > 0)
4868 ? event[rad].col() :
event[emt].acol();
4870 }
else if (type == 1 && event[emt].
id() == 21) {
4873 int colRemove = (
event[rad].col() ==
event[emt].acol())
4874 ? event[rad].col() :
event[rad].acol();
4875 radBeforeCol = (
event[rad].col() == colRemove)
4876 ? event[emt].col() :
event[rad].col();
4878 }
else if (type == -1 && event[emt].
id() == 21) {
4881 int colRemove = (
event[rad].col() ==
event[emt].col())
4882 ? event[rad].col() :
event[rad].acol();
4883 radBeforeCol = (
event[rad].col() == colRemove)
4884 ? event[emt].acol() :
event[rad].col();
4888 }
else if ( radBeforeFlav > 0) {
4891 if (type == 1 && event[emt].
id() != 21) {
4894 int colRemove = (
event[rad].col() ==
event[emt].acol())
4895 ? event[rad].acol() : 0;
4896 radBeforeCol = (
event[rad].col() == colRemove)
4897 ? event[emt].col() :
event[rad].col();
4899 }
else if (type == 1 && event[emt].
id() == 21) {
4902 int colRemove = (
event[rad].col() ==
event[emt].acol())
4903 ? event[rad].col() : 0;
4904 radBeforeCol = (
event[rad].col() == colRemove)
4905 ? event[emt].col() :
event[rad].col();
4907 }
else if (type == -1 && event[emt].
id() != 21) {
4910 int colRemove = (
event[rad].col() ==
event[emt].col())
4911 ? event[rad].col() : 0;
4912 radBeforeCol = (
event[rad].col() == colRemove)
4913 ? event[emt].acol() :
event[rad].col();
4915 }
else if (type == -1 && event[emt].
id() == 21) {
4918 int colRemove = (
event[rad].col() ==
event[emt].col())
4919 ? event[rad].col() : 0;
4920 radBeforeCol = (
event[rad].col() == colRemove)
4921 ? event[emt].acol() :
event[rad].col();
4928 return radBeforeCol;
4941 int DireHistory::getRadBeforeAcol(
const int rad,
const int emt,
4942 const Event& event) {
4945 int type = (
event[rad].isFinal()) ? 1 :-1;
4948 int radBeforeFlav = getRadBeforeFlav(rad,emt,event);
4950 int radBeforeAcl = -1;
4952 if (radBeforeFlav == 21) {
4955 if (type == 1 && event[emt].
id() != 21) {
4956 radBeforeAcl = (
event[rad].acol() > 0)
4957 ? event[rad].acol() :
event[emt].acol();
4959 }
else if (type == -1 && event[emt].
id() != 21) {
4960 radBeforeAcl = (
event[rad].acol() > 0)
4961 ? event[rad].acol() :
event[emt].col();
4963 }
else if (type == 1 && event[emt].
id() == 21) {
4966 int colRemove = (
event[rad].col() ==
event[emt].acol())
4967 ? event[rad].col() :
event[rad].acol();
4968 radBeforeAcl = (
event[rad].acol() == colRemove)
4969 ? event[emt].acol() :
event[rad].acol();
4971 }
else if (type == -1 && event[emt].
id() == 21) {
4974 int colRemove = (
event[rad].col() ==
event[emt].col())
4975 ? event[rad].col() :
event[rad].acol();
4976 radBeforeAcl = (
event[rad].acol() == colRemove)
4977 ? event[emt].col() :
event[rad].acol();
4981 }
else if ( radBeforeFlav < 0) {
4984 if (type == 1 && event[emt].
id() != 21) {
4987 int colRemove = (
event[rad].col() ==
event[emt].acol())
4988 ? event[rad].acol() : 0;
4989 radBeforeAcl = (
event[rad].acol() == colRemove)
4990 ? event[emt].acol() :
event[rad].acol();
4992 }
else if (type == 1 && event[emt].
id() == 21) {
4995 int colRemove = (
event[rad].acol() ==
event[emt].col())
4996 ? event[rad].acol() : 0;
4997 radBeforeAcl = (
event[rad].acol() == colRemove)
4998 ? event[emt].acol() :
event[rad].acol();
5000 }
else if (type == -1 && event[emt].
id() != 21) {
5003 int colRemove = (
event[rad].acol() ==
event[emt].acol())
5004 ? event[rad].acol() : 0;
5005 radBeforeAcl = (
event[rad].acol() == colRemove)
5006 ? event[emt].col() :
event[rad].acol();
5008 }
else if (type == -1 && event[emt].
id() == 21) {
5011 int colRemove = (
event[rad].acol() ==
event[emt].acol())
5012 ? event[rad].acol() : 0;
5013 radBeforeAcl = (
event[rad].acol() == colRemove)
5014 ? event[emt].col() :
event[rad].acol();
5021 return radBeforeAcl;
5033 int DireHistory::getColPartner(
const int in,
const Event& event) {
5035 if (event[in].col() == 0)
return 0;
5039 partner = FindCol(event[in].col(),in,0,event,1,
true);
5042 partner = FindCol(event[in].col(),in,0,event,2,
true);
5057 int DireHistory::getAcolPartner(
const int in,
const Event& event) {
5059 if (event[in].acol() == 0)
return 0;
5063 partner = FindCol(event[in].acol(),in,0,event,2,
true);
5066 partner = FindCol(event[in].acol(),in,0,event,1,
true);
5083 vector<int> DireHistory::getReclusteredPartners(
const int rad,
const int emt,
5084 const Event& event) {
5087 int type =
event[rad].isFinal() ? 1 : -1;
5089 int radBeforeCol = getRadBeforeCol(rad, emt, event);
5090 int radBeforeAcl = getRadBeforeAcol(rad, emt, event);
5092 vector<int> partners;
5098 for(
int i=0; i < int(event.size()); ++i) {
5100 if ( i != emt && i != rad
5101 && event[i].status() == -21
5102 &&
event[i].col() > 0
5103 &&
event[i].col() == radBeforeCol)
5104 partners.push_back(i);
5106 if ( i != emt && i != rad
5107 && event[i].isFinal()
5108 && event[i].acol() > 0
5109 && event[i].acol() == radBeforeCol)
5110 partners.push_back(i);
5112 if ( i != emt && i != rad
5113 && event[i].status() == -21
5114 && event[i].acol() > 0
5115 && event[i].acol() == radBeforeAcl)
5116 partners.push_back(i);
5118 if ( i != emt && i != rad
5119 && event[i].isFinal()
5120 && event[i].col() > 0
5121 && event[i].col() == radBeforeAcl)
5122 partners.push_back(i);
5127 for(
int i=0; i < int(event.size()); ++i) {
5129 if ( i != emt && i != rad
5130 && event[i].status() == -21
5131 &&
event[i].acol() > 0
5132 &&
event[i].acol() == radBeforeCol)
5133 partners.push_back(i);
5135 if ( i != emt && i != rad
5136 && event[i].isFinal()
5137 && event[i].col() > 0
5138 && event[i].col() == radBeforeCol)
5139 partners.push_back(i);
5141 if ( i != emt && i != rad
5142 && event[i].status() == -21
5143 && event[i].col() > 0
5144 && event[i].col() == radBeforeAcl)
5145 partners.push_back(i);
5147 if ( i != emt && i != rad
5148 && event[i].isFinal()
5149 && event[i].acol() > 0
5150 && event[i].acol() == radBeforeAcl)
5151 partners.push_back(i);
5178 bool DireHistory::getColSinglet(
const int flavType,
const int iParton,
5179 const Event& event, vector<int>& exclude, vector<int>& colSinglet) {
5182 if (iParton < 0)
return false;
5190 for(
int i=0; i < int(event.size()); ++i)
5191 if ( event[i].isFinal() &&
event[i].colType() != 0)
5196 int nExclude = int(exclude.size());
5197 int nInitExclude = 0;
5198 if (!event[exclude[2]].isFinal())
5200 if (!event[exclude[3]].isFinal())
5204 if (nFinal == nExclude - nInitExclude)
5214 colSinglet.push_back(iParton);
5216 exclude.push_back(iParton);
5219 colP = getColPartner(iParton,event);
5222 colP = getAcolPartner(iParton,event);
5225 for(
int i = 0; i < int(exclude.size()); ++i)
5226 if (colP == exclude[i])
5230 return getColSinglet(flavType,colP,event,exclude,colSinglet);
5241 bool DireHistory::isColSinglet(
const Event& event,
5242 vector<int> system ) {
5245 for(
int i=0; i < int(system.size()); ++i ) {
5248 && (event[system[i]].colType() == 1
5249 ||
event[system[i]].colType() == 2) ) {
5250 for(
int j=0; j < int(system.size()); ++j)
5253 && event[system[i]].col() ==
event[system[j]].acol()) {
5262 && (event[system[i]].colType() == -1
5263 || event[system[i]].colType() == 2) ) {
5264 for(
int j=0; j < int(system.size()); ++j)
5267 && event[system[i]].acol() ==
event[system[j]].col()) {
5279 bool isColSing =
true;
5280 for(
int i=0; i < int(system.size()); ++i)
5281 if ( system[i] != 0 )
5299 bool DireHistory::isFlavSinglet(
const Event& event,
5300 vector<int> system,
int flav) {
5305 for(
int i=0; i < int(system.size()); ++i)
5306 if ( system[i] > 0 ) {
5307 for(
int j=0; j < int(system.size()); ++j) {
5311 if ( event[i].idAbs() != 21
5312 &&
event[i].idAbs() != 22
5313 &&
event[i].idAbs() != 23
5314 &&
event[i].idAbs() != 24
5316 &&
event[system[i]].isFinal()
5317 &&
event[system[j]].isFinal()
5318 &&
event[system[i]].id() == -1*
event[system[j]].id()) {
5321 if (abs(flav) > 0 &&
event[system[i]].idAbs() != flav)
5331 if ( event[i].idAbs() != 21
5332 &&
event[i].idAbs() != 22
5333 &&
event[i].idAbs() != 23
5334 &&
event[i].idAbs() != 24
5336 &&
event[system[i]].isFinal() !=
event[system[j]].isFinal()
5337 &&
event[system[i]].id() ==
event[system[j]].id()) {
5340 if (abs(flav) > 0 &&
event[system[i]].idAbs() != flav)
5353 bool isFlavSing =
true;
5354 for(
int i=0; i < int(system.size()); ++i)
5355 if ( system[i] != 0 )
5370 bool DireHistory::allowedClustering(
int rad,
int emt,
int rec,
int partner,
5371 string name,
const Event& event ) {
5374 bool allowed =
true;
5379 bool isSing = isSinglett(rad,emt,partner,event);
5380 bool hasColour =
event[rad].colType() != 0 ||
event[emt].colType() != 0;
5381 int type = (
event[rad].isFinal()) ? 1 :-1;
5384 map<string,double> stateVars;
5386 if (name.compare(
"Dire_fsr_qcd_1->21&1") == 0) swap(rad,emt);
5387 if (name.compare(
"Dire_fsr_qcd_1->22&1") == 0) swap(rad,emt);
5388 if (name.compare(
"Dire_fsr_qcd_11->22&11") == 0) swap(rad,emt);
5390 bool hasPartonLevel(showers && showers->timesPtr && showers->spacePtr),
5391 hasShowers(fsr && isr);
5392 if (hasPartonLevel) {
5393 bool isFSR = showers->timesPtr->isTimelike(event, rad, emt, rec,
"");
5394 if (isFSR) stateVars = showers->timesPtr->getStateVariables
5395 (event,rad,emt,rec,name);
5396 else stateVars = showers->spacePtr->getStateVariables
5397 (event,rad,emt,rec,name);
5398 }
else if (hasShowers) {
5399 bool isFSR = fsr->isTimelike(event, rad, emt, rec,
"");
5400 if (isFSR) stateVars = fsr->getStateVariables(event,rad,emt,rec,name);
5401 else stateVars = isr->getStateVariables(event,rad,emt,rec,name);
5405 int radBeforeFlav = int(stateVars[
"radBefID"]);
5407 int radBeforeCol = int(stateVars[
"radBefCol"]);
5408 int radBeforeAcl = int(stateVars[
"radBefAcol"]);
5411 vector<int> radBeforeColP = getReclusteredPartners(rad, emt, event);
5414 if ( stateVars[
"t"] < 0.0)
return false;
5417 int nPartonInHard = 0;
5418 for(
int i=0; i < int(event.size()); ++i)
5420 if ( event[i].isFinal()
5421 &&
event[i].colType() != 0
5422 && mergingHooksPtr->hardProcess->matchesAnyOutgoing(i, event) )
5428 for(
int i=0; i < int(event.size()); ++i)
5430 if ( i!=emt && i!=rad && i!=rec
5431 && event[i].isFinal()
5432 &&
event[i].colType() != 0
5433 && !mergingHooksPtr->hardProcess->matchesAnyOutgoing(i, event) )
5437 int nInitialPartons = 0;
5438 for(
int i=0; i < int(event.size()); ++i)
5439 if ( event[i].status() == -21
5440 &&
event[i].colType() != 0 )
5445 for(
int i=0; i < int(event.size()); ++i)
5446 if ( event[i].isFinal()
5447 &&(
event[i].id() == 22
5448 ||
event[i].id() == 23
5449 ||
event[i].idAbs() == 24
5450 ||(
event[i].idAbs() > 10 &&
event[i].idAbs() < 20)
5451 ||(event[i].idAbs() > 1000010 &&
event[i].idAbs() < 1000020)
5452 ||(event[i].idAbs() > 2000010 &&
event[i].idAbs() < 2000020) ))
5456 for(
int i=0; i < int(event.size()); ++i)
5457 if ( event[i].isFinal() &&
event[i].id() == 25)
5464 int nFinalQuark = 0;
5466 int nFinalQuarkExc = 0;
5467 for(
int i=0; i < int(event.size()); ++i) {
5468 if (i !=rad && i != emt && i != rec) {
5469 if (event[i].isFinal() && abs(event[i].colType()) == 1 ) {
5470 if ( !mergingHooksPtr->hardProcess->matchesAnyOutgoing(i,event) )
5479 if (event[rec].isFinal() &&
event[rec].isQuark()) nFinalQuark++;
5481 if (event[rad].isFinal() && abs(radBeforeFlav) < 10) nFinalQuark++;
5484 int nInitialQuark = 0;
5486 if (event[rec].isFinal()) {
5487 if (event[3].isQuark()) nInitialQuark++;
5488 if (event[4].isQuark()) nInitialQuark++;
5490 int iOtherIn = (rec == 3) ? 4 : 3;
5491 if (event[rec].isQuark()) nInitialQuark++;
5492 if (event[iOtherIn].isQuark()) nInitialQuark++;
5495 if (event[rec].isFinal()) {
5496 int iOtherIn = (rad == 3) ? 4 : 3;
5497 if (abs(radBeforeFlav) < 10) nInitialQuark++;
5498 if (event[iOtherIn].isQuark()) nInitialQuark++;
5500 if (abs(radBeforeFlav) < 10) nInitialQuark++;
5501 if (event[rec].isQuark()) nInitialQuark++;
5506 int nInitialLepton = 0;
5508 if (event[rec].isFinal()) {
5509 if (event[3].isLepton()) nInitialLepton++;
5510 if (event[4].isLepton()) nInitialLepton++;
5512 int iOtherIn = (rec == 3) ? 4 : 3;
5513 if (event[rec].isLepton()) nInitialLepton++;
5514 if (event[iOtherIn].isLepton()) nInitialLepton++;
5518 if (event[rec].isLepton()) nInitialLepton++;
5520 if (abs(radBeforeFlav) > 10 && abs(radBeforeFlav) < 20 ) nInitialLepton++;
5525 for(
int i=0; i < int(event.size()); ++i)
5526 if ( i!=emt && i!=rad && i!=rec
5527 && (event[i].mother1() == 1 ||
event[i].mother1() == 2))
5528 in.push_back(event[i].
id());
5529 if (!event[rad].isFinal()) in.push_back(radBeforeFlav);
5530 if (!event[rec].isFinal()) in.push_back(event[rec].
id());
5532 for(
int i=0; i < int(event.size()); ++i)
5533 if ( i!=emt && i!=rad && i!=rec && event[i].isFinal())
5534 out.push_back(event[i].id());
5535 if (event[rad].isFinal()) out.push_back(radBeforeFlav);
5536 if (event[rec].isFinal()) out.push_back(event[rec].
id());
5541 int proton[] = {1,2,3,4,5,21,22,23,24};
5542 bool isInProton =
false;
5543 for(
int i=0; i < 9; ++i)
5544 if (abs(radBeforeFlav) == proton[i]) isInProton =
true;
5545 if ( type == -1 && particleDataPtr->colType(radBeforeFlav) != 0
5546 && !isInProton)
return false;
5549 vector<int> unmatchedCol;
5550 vector<int> unmatchedAcl;
5552 for (
int i = 0; i <
event.size(); ++i)
5553 if ( i != emt && i != rad
5554 && (event[i].isFinal() || event[i].status() == -21)
5555 &&
event[i].colType() != 0 ) {
5557 int colP = getColPartner(i,event);
5558 int aclP = getAcolPartner(i,event);
5560 if (event[i].col() > 0
5561 && (colP == emt || colP == rad || colP == 0) )
5562 unmatchedCol.push_back(i);
5563 if (event[i].acol() > 0
5564 && (aclP == emt || aclP == rad || aclP == 0) )
5565 unmatchedAcl.push_back(i);
5571 if (
int(unmatchedCol.size()) +
int(unmatchedAcl.size()) > 2)
5576 if (hasColour && isSing)
5578 if (hasColour && isSing && (abs(radBeforeFlav)<10 &&
event[rec].isQuark()) )
5582 if (hasColour && isSing && abs(radBeforeFlav)<10 && nPartons == 0
5583 && nInitialPartons == 1)
5587 if ( mergingHooksPtr->hardProcess->matchesAnyOutgoing(emt,event) ) {
5591 bool canReplace = mergingHooksPtr->hardProcess->findOtherCandidates(emt,
5594 if (canReplace) allowed =
true;
5595 else allowed =
false;
5601 int nOutPartHardProc = mergingHooksPtr->hardProcess->nQuarksOut();
5603 int nOutPartNow(nPartons);
5605 for(
int i=0; i < int(event.size()); ++i)
5607 if ( i!=emt && i!=rad && i!=rec
5608 && event[i].isFinal()
5609 &&
event[i].colType() != 0
5610 && mergingHooksPtr->hardProcess->matchesAnyOutgoing(i, event) )
5612 if (event[rec].isFinal() &&
event[rec].colType() != 0) nOutPartNow++;
5614 if (event[rad].isFinal() && particleDataPtr->colType(radBeforeFlav) != 0)
5616 if (nOutPartNow < nOutPartHardProc) allowed =
false;
5620 if ( mergingHooksPtr->hardProcess->matchesAnyOutgoing(rad,event)
5621 &&
event[rad].id() != radBeforeFlav )
5626 if ( nFinalEW != 0 && nInitialQuark == 0 && nFinalQuark == 0
5627 && nFinalQuarkExc == 0 && nInitialLepton == 0
5628 && !mayHaveEffectiveVertex( mergingHooksPtr->getProcessString(), in, out))
5631 if ( (nInitialQuark + nFinalQuark + nFinalQuarkExc)%2 != 0 )
5634 map<int,int> nIncIDs, nOutIDs;
5635 for (
int i = 0; i <
event.size(); ++i) {
5636 if ( i != emt && i != rad && event[i].isFinal() ) {
5637 if (nOutIDs.find(event[i].id()) != nOutIDs.end() )
5638 nOutIDs[event[i].
id()]++;
5640 nOutIDs.insert(make_pair(event[i].
id(),1));
5642 if ( i != emt && i != rad && event[i].status() == -21 ){
5643 if (nIncIDs.find(event[i].id()) != nIncIDs.end() )
5644 nIncIDs[event[i].
id()]++;
5646 nIncIDs.insert(make_pair(event[i].
id(),1));
5650 if (nOutIDs.find(radBeforeFlav) != nOutIDs.end()) nOutIDs[radBeforeFlav]++;
5651 else nOutIDs.insert(make_pair(radBeforeFlav,1));
5654 if (nIncIDs.find(radBeforeFlav) != nIncIDs.end()) nIncIDs[radBeforeFlav]++;
5655 else nIncIDs.insert(make_pair(radBeforeFlav,1));
5658 if (!canConnectFlavs(nIncIDs,nOutIDs) ) allowed =
false;
5662 int nMassless(0), nOther(0);
5663 for ( map<int, int>::iterator it = nOutIDs.begin();
5664 it != nOutIDs.end(); ++it )
5665 if ( abs(it->first) < 20 || abs(it->first) == 21
5666 || abs(it->first) == 22) nMassless += it->second;
5668 if (nMassless == 1 && nOther == 0) allowed =
false;
5676 if (event[3].col() ==
event[4].acol()
5677 &&
event[3].acol() ==
event[4].col()
5678 && !mayHaveEffectiveVertex( mergingHooksPtr->getProcessString(), in, out)
5679 && nFinalQuark == 0){
5682 int nTripletts = abs(event[rec].colType())
5683 + abs(particleDataPtr->colType(radBeforeFlav));
5684 if (event[3].isGluon()) allowed =
false;
5685 else if (nTripletts != 2 && nFinalQuarkExc%2 == 0) allowed =
false;
5689 if ( event[rad].isFinal() &&
event[rec].isFinal()
5690 && abs( ( event[rad].p() + event[emt].p() + event[rec].p()).pz())
5691 > (
event[rad].p() +
event[emt].p() +
event[rec].p()).e() )
5694 if ( !event[rad].isFinal() && !
event[rec].isFinal()
5695 && abs( ( event[rad].p() - event[emt].p() + event[rec].p()).pz())
5696 > (
event[rad].p() -
event[emt].p() +
event[rec].p()).e() )
5699 if ( !event[rad].isFinal() &&
event[rec].isFinal()
5700 && -(-
event[rad].p() +
event[emt].p() +
event[rec].p()).m2Calc() < 0.)
5705 if ( !event[rad].isFinal() && !
event[rec].isFinal()
5706 && (
event[rad].p() -
event[emt].p() +
event[rec].p()).m2Calc() < 0.
5707 && abs((event[rad].p() - event[emt].p() + event[rec].p()).m2Calc()) > 1e-5)
5711 if ( !event[rad].isFinal() &&
event[rec].isFinal()
5712 && -(
event[rad].p() -
event[emt].p() -
event[rec].p()).m2Calc() < 0.
5713 && abs((event[rad].p() - event[emt].p() - event[rec].p()).m2Calc()) > 1e-5)
5717 if ( event[rad].isFinal() && !
event[rec].isFinal()
5718 && -(-
event[rad].p() -
event[emt].p() +
event[rec].p()).m2Calc() < 0.
5719 && abs((-event[rad].p() - event[emt].p() + event[rec].p()).m2Calc())
5724 if ( event[rad].isFinal() &&
event[rec].isFinal()
5725 && (
event[rad].p() +
event[emt].p() +
event[rec].p()).m2Calc() < 0.)
5729 if (event[emt].
id() == 21)
5733 if (event[emt].
id() == 22 ||
event[emt].id() == 23 ||
event[emt].id() == 25)
5737 if (event[emt].
id() == 1000021)
5747 vector<int> outgoingParticles;
5748 int nOut1 = int(mergingHooksPtr->hardProcess->PosOutgoing1.size());
5749 for (
int i=0; i < nOut1; ++i ) {
5750 int iPos = mergingHooksPtr->hardProcess->PosOutgoing1[i];
5751 outgoingParticles.push_back(
5752 mergingHooksPtr->hardProcess->state[iPos].id() );
5754 int nOut2 = int(mergingHooksPtr->hardProcess->PosOutgoing2.size());
5755 for (
int i=0; i < nOut2; ++i ) {
5756 int iPos = mergingHooksPtr->hardProcess->PosOutgoing2[i];
5757 outgoingParticles.push_back(
5758 mergingHooksPtr->hardProcess->state[iPos].id() );
5765 vector<int> iInQuarkFlav;
5766 for(
int i=0; i < int(event.size()); ++i)
5768 if ( i != emt && i != rad
5769 && event[i].status() == -21
5770 &&
event[i].idAbs() ==
event[emt].idAbs() )
5771 iInQuarkFlav.push_back(i);
5774 vector<int> iOutQuarkFlav;
5775 for(
int i=0; i < int(event.size()); ++i)
5777 if ( i != emt && i != rad
5778 && event[i].isFinal()
5779 &&
event[i].idAbs() ==
event[emt].idAbs() ) {
5783 bool matchOut =
false;
5784 for (
int j = 0; j < int(outgoingParticles.size()); ++j)
5785 if ( event[i].idAbs() == abs(outgoingParticles[j])) {
5787 outgoingParticles[j] = 99;
5789 if (!matchOut) iOutQuarkFlav.push_back(i);
5794 int nInQuarkFlav = int(iInQuarkFlav.size());
5795 int nOutQuarkFlav = int(iOutQuarkFlav.size());
5800 if ( event[partner].isFinal()
5801 &&
event[partner].id() == 21
5802 && radBeforeFlav == 21
5803 &&
event[partner].col() == radBeforeCol
5804 &&
event[partner].acol() == radBeforeAcl)
5808 if (nInQuarkFlav + nOutQuarkFlav == 0)
5815 vector<int> partons;
5816 for(
int i=0; i < int(event.size()); ++i)
5818 if ( i!=emt && i!=rad
5819 && event[i].colType() != 0
5820 && (
event[i].isFinal() ||
event[i].status() == -21) ) {
5822 partons.push_back(i);
5824 if (event[i].colType() == 2)
5826 else if (event[i].colType() == 1)
5828 else if (event[i].colType() == -1)
5834 bool isFSRg2qq = ( (type == 1) && radBeforeFlav == 21
5835 && (event[rad].
id() == -1*
event[emt].id()) );
5836 bool isISRg2qq = ( (type ==-1) && radBeforeFlav == 21
5837 && (event[rad].
id() ==
event[emt].id()) );
5842 if ( (isFSRg2qq || isISRg2qq)
5843 && int(quark.size()) +
int(antiq.size())
5844 +
int(gluon.size()) > nPartonInHard ) {
5846 vector<int> colours;
5847 vector<int> anticolours;
5852 colours.push_back(radBeforeCol);
5853 anticolours.push_back(radBeforeAcl);
5855 colours.push_back(radBeforeAcl);
5856 anticolours.push_back(radBeforeCol);
5859 for(
int i=0; i < int(gluon.size()); ++i)
5860 if (event[gluon[i]].isFinal()) {
5861 colours.push_back(event[gluon[i]].col());
5862 anticolours.push_back(event[gluon[i]].acol());
5864 colours.push_back(event[gluon[i]].acol());
5865 anticolours.push_back(event[gluon[i]].col());
5870 for(
int i=0; i < int(colours.size()); ++i)
5871 for(
int j=0; j < int(anticolours.size()); ++j)
5872 if (colours[i] > 0 && anticolours[j] > 0
5873 && colours[i] == anticolours[j]) {
5881 bool allMatched =
true;
5882 for(
int i=0; i < int(colours.size()); ++i)
5883 if (colours[i] != 0)
5885 for(
int i=0; i < int(anticolours.size()); ++i)
5886 if (anticolours[i] != 0)
5894 for(
int i=0; i < int(quark.size()); ++i)
5895 if ( event[quark[i]].isFinal()
5896 && mergingHooksPtr->hardProcess->matchesAnyOutgoing(quark[i], event) )
5897 colours.push_back(event[quark[i]].col());
5899 for(
int i=0; i < int(antiq.size()); ++i)
5900 if ( event[antiq[i]].isFinal()
5901 && mergingHooksPtr->hardProcess->matchesAnyOutgoing(antiq[i], event) )
5902 anticolours.push_back(event[antiq[i]].acol());
5906 for(
int i=0; i < int(colours.size()); ++i)
5908 for(
int j=0; j < int(anticolours.size()); ++j)
5909 if (colours[i] > 0 && anticolours[j] > 0
5910 && colours[i] == anticolours[j]) {
5917 for (
int i=0; i < int(quark.size()); ++i )
5918 if ( !mergingHooksPtr->hardProcess->matchesAnyOutgoing( quark[i],
5921 for (
int i=0; i < int(antiq.size()); ++i )
5922 if ( !mergingHooksPtr->hardProcess->matchesAnyOutgoing( antiq[i],
5925 for(
int i=0; i < int(gluon.size()); ++i)
5926 if ( event[gluon[i]].isFinal() )
5934 for(
int i=0; i < int(colours.size()); ++i)
5935 if (colours[i] != 0)
5937 for(
int i=0; i < int(anticolours.size()); ++i)
5938 if (anticolours[i] != 0)
5941 if (allMatched && nNotInHard > 0)
5948 if (isFSRg2qq && nInQuarkFlav + nOutQuarkFlav > 0) {
5952 for(
int i=0; i < int(gluon.size()); ++i) {
5953 if (!event[gluon[i]].isFinal()
5954 &&
event[gluon[i]].col() == radBeforeCol
5955 &&
event[gluon[i]].acol() == radBeforeAcl)
5961 for(
int i=0; i < int(gluon.size()); ++i) {
5962 if (event[gluon[i]].isFinal()
5963 &&
event[gluon[i]].col() == radBeforeAcl
5964 &&
event[gluon[i]].acol() == radBeforeCol)
5970 if (
int(radBeforeColP.size()) == 2
5971 && event[radBeforeColP[0]].isFinal()
5972 &&
event[radBeforeColP[1]].isFinal()
5973 &&
event[radBeforeColP[0]].id() == -1*
event[radBeforeColP[1]].id() ) {
5977 if (nInitialPartons > 0)
5984 if (
int(radBeforeColP.size()) == 2
5985 && (( event[radBeforeColP[0]].status() == -21
5986 && event[radBeforeColP[1]].isFinal())
5987 ||(
event[radBeforeColP[0]].isFinal()
5988 &&
event[radBeforeColP[1]].status() == -21))
5989 &&
event[radBeforeColP[0]].id() ==
event[radBeforeColP[1]].id() ) {
5996 int incoming = (
event[radBeforeColP[0]].isFinal())
5997 ? radBeforeColP[1] : radBeforeColP[0];
5998 int outgoing = (
event[radBeforeColP[0]].isFinal())
5999 ? radBeforeColP[0] : radBeforeColP[1];
6002 bool clusPossible =
false;
6003 for(
int i=0; i < int(event.size()); ++i)
6004 if ( i != emt && i != rad
6005 && i != incoming && i != outgoing
6006 && !mergingHooksPtr->hardProcess->matchesAnyOutgoing(i,event) ) {
6008 if ( event[i].status() == -21
6009 && (
event[i].id() ==
event[outgoing].id()
6010 ||
event[i].id() == -1*
event[incoming].id()) )
6011 clusPossible =
true;
6013 if ( event[i].isFinal()
6014 && (
event[i].id() == -1*
event[outgoing].id()
6015 ||
event[i].id() ==
event[incoming].id()) )
6016 clusPossible =
true;
6027 vector<int> excludeIn1;
6028 for(
int i=0; i < 4; ++i)
6029 excludeIn1.push_back(0);
6030 vector<int> colSingletIn1;
6031 int flavIn1Type = (
event[incoming].id() > 0) ? 1 : -1;
6033 bool isColSingIn1 = getColSinglet(flavIn1Type,incoming,event,
6034 excludeIn1,colSingletIn1);
6036 bool isFlavSingIn1 = isFlavSinglet(event,colSingletIn1);
6040 bool foundLepton =
false;
6041 for(
int i=0; i < int(event.size()); ++i)
6042 if ( i != emt && i != rad && i != incoming
6043 && event[i].isLepton() ) foundLepton =
true;
6044 if ( abs(radBeforeFlav)%10 == 1 ) foundLepton =
true;
6045 if ( foundLepton && event[incoming].isLepton() )
6046 isColSingIn1 = isFlavSingIn1 =
true;
6051 int incoming2 = (incoming == 3) ? 4 : 3;
6052 vector<int> excludeIn2;
6053 for(
int i=0; i < 4; ++i)
6054 excludeIn2.push_back(0);
6055 vector<int> colSingletIn2;
6056 int flavIn2Type = (
event[incoming2].id() > 0) ? 1 : -1;
6058 bool isColSingIn2 = getColSinglet(flavIn2Type,incoming2,event,
6059 excludeIn2,colSingletIn2);
6061 bool isFlavSingIn2 = isFlavSinglet(event,colSingletIn2);
6065 foundLepton =
false;
6066 for(
int i=0; i < int(event.size()); ++i)
6067 if ( i != emt && i != rad && i != incoming2
6068 && event[i].isLepton() ) foundLepton =
true;
6069 if ( abs(radBeforeFlav)%10 == 1 ) foundLepton =
true;
6070 if ( foundLepton && event[incoming2].isLepton() )
6071 isColSingIn2 = isFlavSingIn2 =
true;
6075 && (!isColSingIn1 || !isFlavSingIn1
6076 || !isColSingIn2 || !isFlavSingIn2))
6085 if (
int(radBeforeColP.size()) == 2 ) {
6090 int flav =
event[emt].id();
6091 vector<int> exclude;
6092 exclude.push_back(emt);
6093 exclude.push_back(rad);
6094 exclude.push_back(radBeforeColP[0]);
6095 exclude.push_back(radBeforeColP[1]);
6096 vector<int> colSinglet;
6101 for(
int i=0; i < int(event.size()); ++i)
6106 && i != radBeforeColP[0]
6107 && i != radBeforeColP[1]
6108 && event[i].isFinal() ) {
6110 if (event[i].
id() == flav) {
6116 int flavType = (iOther > 0 &&
event[iOther].id() > 0) ? 1
6117 : (iOther > 0) ? -1 : 0;
6119 bool isColSing = getColSinglet(flavType,iOther,event,exclude,colSinglet);
6121 bool isFlavSing = isFlavSinglet(event,colSinglet);
6125 bool isHardSys =
true;
6126 for(
int i=0; i < int(colSinglet.size()); ++i)
6128 mergingHooksPtr->hardProcess->matchesAnyOutgoing(colSinglet[i], event);
6133 if (isColSing && isFlavSing && !isHardSys) {
6139 vector<int> allFinal;
6140 for(
int i=0; i < int(event.size()); ++i)
6141 if ( event[i].isFinal() )
6142 allFinal.push_back(i);
6145 bool isFullColSing = isColSinglet(event,allFinal);
6147 bool isFullFlavSing = isFlavSinglet(event,allFinal,flav);
6152 if (!isFullColSing || !isFullFlavSing)
6162 if (isISRg2qq && nInQuarkFlav + nOutQuarkFlav > 0) {
6166 for(
int i=0; i < int(gluon.size()); ++i) {
6167 if (event[gluon[i]].isFinal()
6168 &&
event[gluon[i]].col() == radBeforeCol
6169 &&
event[gluon[i]].acol() == radBeforeAcl)
6175 for(
int i=0; i < int(gluon.size()); ++i) {
6176 if (event[gluon[i]].status() == -21
6177 &&
event[gluon[i]].acol() == radBeforeCol
6178 &&
event[gluon[i]].col() == radBeforeAcl)
6184 if (
int(radBeforeColP.size()) == 2
6185 && event[radBeforeColP[0]].isFinal()
6186 &&
event[radBeforeColP[1]].isFinal()
6187 &&
event[radBeforeColP[0]].id() == -1*
event[radBeforeColP[1]].id() ) {
6194 bool clusPossible =
false;
6195 for(
int i=0; i < int(event.size()); ++i)
6196 if ( i != emt && i != rad
6197 && i != radBeforeColP[0]
6198 && i != radBeforeColP[1]
6199 && !mergingHooksPtr->hardProcess->matchesAnyOutgoing(i,event) ) {
6200 if (event[i].status() == -21
6201 && (
event[radBeforeColP[0]].id() ==
event[i].id()
6202 ||
event[radBeforeColP[1]].id() ==
event[i].id() ))
6204 clusPossible =
true;
6205 if (event[i].isFinal()
6206 && (
event[radBeforeColP[0]].id() == -1*
event[i].id()
6207 ||
event[radBeforeColP[1]].id() == -1*
event[i].id() ))
6208 clusPossible =
true;
6220 vector<int> excludeIn1;
6221 for(
int i=0; i < 4; ++i)
6222 excludeIn1.push_back(0);
6223 vector<int> colSingletIn1;
6224 int flavIn1Type = (
event[incoming1].id() > 0) ? 1 : -1;
6226 bool isColSingIn1 = getColSinglet(flavIn1Type,incoming1,event,
6227 excludeIn1,colSingletIn1);
6229 bool isFlavSingIn1 = isFlavSinglet(event,colSingletIn1);
6233 bool foundLepton =
false;
6234 for(
int i=0; i < int(event.size()); ++i)
6235 if ( i != emt && i != rad && i != incoming1
6236 && event[i].isLepton() ) foundLepton =
true;
6237 if ( abs(radBeforeFlav)%10 == 1 ) foundLepton =
true;
6238 if ( foundLepton && event[incoming1].isLepton() )
6239 isColSingIn1 = isFlavSingIn1 =
true;
6245 vector<int> excludeIn2;
6246 for(
int i=0; i < 4; ++i)
6247 excludeIn2.push_back(0);
6248 vector<int> colSingletIn2;
6249 int flavIn2Type = (
event[incoming2].id() > 0) ? 1 : -1;
6251 bool isColSingIn2 = getColSinglet(flavIn2Type,incoming2,event,
6252 excludeIn2,colSingletIn2);
6254 bool isFlavSingIn2 = isFlavSinglet(event,colSingletIn2);
6258 foundLepton =
false;
6259 for(
int i=0; i < int(event.size()); ++i)
6260 if ( i != emt && i != rad && i != incoming2
6261 && event[i].isLepton() ) foundLepton =
true;
6262 if ( abs(radBeforeFlav)%10 == 1 ) foundLepton =
true;
6263 if ( foundLepton && event[incoming2].isLepton() )
6264 isColSingIn2 = isFlavSingIn2 =
true;
6268 && (!isColSingIn1 || !isFlavSingIn1
6269 || !isColSingIn2 || !isFlavSingIn2))
6282 bool DireHistory::hasConnections(
int,
int nIncIDs[],
int nOutIDs[]) {
6284 bool foundQuarks =
false;
6285 for (
int i=-6; i < 6; i++)
6286 if (nIncIDs[i] > 0 || nOutIDs[i] > 0) foundQuarks =
true;
6288 if ( nIncIDs[-11] == 1 && nOutIDs[-11] == 1 && !foundQuarks)
return false;
6294 bool DireHistory::canConnectFlavs(map<int,int> nIncIDs, map<int,int> nOutIDs) {
6296 bool foundIncQuarks(
false), foundOutQuarks(
false);
6297 for (
int i=-6; i < 6; i++) {
6298 if (nIncIDs[i] > 0) foundIncQuarks =
true;
6299 if (nOutIDs[i] > 0) foundOutQuarks =
true;
6302 int nIncEle = (nIncIDs.find(11) != nIncIDs.end()) ? nIncIDs[11] : 0;
6303 int nIncPos = (nIncIDs.find(-11) != nIncIDs.end()) ? nIncIDs[-11] : 0;
6304 int nOutEle = (nOutIDs.find(11) != nOutIDs.end()) ? nOutIDs[11] : 0;
6305 int nOutPos = (nOutIDs.find(-11) != nOutIDs.end()) ? nOutIDs[-11] : 0;
6308 if ( nIncPos == 1 && nOutPos == 1 && !foundOutQuarks && !foundIncQuarks)
6312 if ( nIncEle == 1 && nOutEle == 1 && !foundOutQuarks && !foundIncQuarks)
6326 bool DireHistory::isSinglett(
int rad,
int emt,
int rec,
const Event& event ) {
6328 int radCol =
event[rad].col();
6329 int emtCol =
event[emt].col();
6330 int recCol =
event[rec].col();
6331 int radAcl =
event[rad].acol();
6332 int emtAcl =
event[emt].acol();
6333 int recAcl =
event[rec].acol();
6334 int recType =
event[rec].isFinal() ? 1 : -1;
6336 bool isSing =
false;
6338 if ( ( recType == -1
6339 && radCol + emtCol == recCol && radAcl + emtAcl == recAcl)
6341 && radCol + emtCol == recAcl && radAcl + emtAcl == recCol) )
6357 bool DireHistory::validEvent(
const Event& event ) {
6360 bool validColour =
true;
6361 for (
int i = 0; i <
event.size(); ++i)
6363 if ( event[i].isFinal() &&
event[i].colType() == 1
6365 && ( FindCol(event[i].col(),i,0,event,1,
true) == 0
6367 && FindCol(event[i].col(),i,0,event,2,
true) == 0 )) {
6368 validColour =
false;
6371 }
else if ( event[i].isFinal() &&
event[i].colType() == -1
6373 && ( FindCol(event[i].acol(),i,0,event,2,
true) == 0
6375 && FindCol(event[i].acol(),i,0,event,1,
true) == 0 )) {
6376 validColour =
false;
6379 }
else if ( event[i].isFinal() &&
event[i].colType() == 2
6381 && ( FindCol(event[i].col(),i,0,event,1,
true) == 0
6383 && FindCol(event[i].col(),i,0,event,2,
true) == 0 )
6385 && ( FindCol(event[i].acol(),i,0,event,2,
true) == 0
6387 && FindCol(event[i].acol(),i,0,event,1,
true) == 0 )) {
6388 validColour =
false;
6393 bool validCharge =
true;
6394 double initCharge =
event[3].charge() +
event[4].charge();
6395 double finalCharge = 0.0;
6396 for(
int i = 0; i <
event.size(); ++i)
6397 if (event[i].isFinal()) finalCharge += event[i].charge();
6398 if (abs(initCharge-finalCharge) > 1e-12) validCharge =
false;
6400 return (validColour && validCharge);
6409 bool DireHistory::equalClustering( DireClustering c1 , DireClustering c2 ) {
6412 bool isIdenticalClustering
6413 = (c1.emittor == c2.emittor)
6414 && (c1.emitted == c2.emitted)
6415 && (c1.recoiler == c2.recoiler)
6416 && (c1.partner == c2.partner)
6417 && (c1.pT() == c2.pT())
6418 && (c1.spinRadBef == c2.spinRadBef)
6419 && (c1.flavRadBef == c2.flavRadBef)
6420 && (c1.splitName == c2.splitName);
6421 if (isIdenticalClustering)
return true;
6424 if (c1.recoiler != c2.recoiler)
return false;
6426 if (c1.name() != c2.name())
return false;
6430 if (c1.emittor != c2.emitted || c1.emitted != c2.emittor)
return false;
6432 bool isIdenticalSplitting =
false;
6433 if (fsr && c1.rad()->isFinal() && c2.rad()->isFinal())
6434 isIdenticalSplitting = fsr->isSymmetric(c1.name(),c1.rad(),c1.emt());
6435 else if (isr && !c1.rad()->isFinal() && !c2.rad()->isFinal())
6436 isIdenticalSplitting = isr->isSymmetric(c1.name(),c1.rad(),c1.emt());
6438 return isIdenticalSplitting;
6448 double DireHistory::choseHardScale(
const Event& event )
const {
6451 double mHat = (
event[3].p() +
event[4].p()).mCalc();
6458 for(
int i = 0; i <
event.size(); ++i)
6459 if ( event[i].isFinal() ) {
6462 if ( event[i].idAbs() == 23
6463 ||
event[i].idAbs() == 24 ) {
6466 mBos +=
event[i].m();
6468 }
else if ( abs(event[i].status()) == 22
6469 && ( event[i].idAbs() == 23
6470 || event[i].idAbs() == 24 )) {
6472 mBos +=
event[i].m();
6476 if ( nBosons > 0 && (nFinal + nFinBos*2) <= 3)
6477 return (mBos /
double(nBosons));
6488 int DireHistory::getCurrentFlav(
const int side)
const {
6489 int in = (side == 1) ? 3 : 4;
6490 return state[in].id();
6495 double DireHistory::getCurrentX(
const int side)
const {
6496 int in = (side == 1) ? 3 : 4;
6497 return ( 2.*state[in].e()/state[0].e() );
6502 double DireHistory::getCurrentZ(
const int rad,
6503 const int rec,
const int emt,
int idRadBef)
const {
6505 int type = state[rad].isFinal() ? 1 : -1;
6510 Vec4 radAfterBranch(state[rad].p());
6511 Vec4 recAfterBranch(state[rec].p());
6512 Vec4 emtAfterBranch(state[emt].p());
6515 double m2RadAft = radAfterBranch.m2Calc();
6516 double m2EmtAft = emtAfterBranch.m2Calc();
6517 double m2RadBef = 0.;
6518 if ( state[rad].idAbs() != 21 && state[rad].idAbs() != 22
6519 && state[emt].idAbs() != 24 && state[rad].idAbs() != state[emt].idAbs())
6520 m2RadBef = m2RadAft;
6521 else if ( state[emt].idAbs() == 24) {
6523 m2RadBef = pow2(particleDataPtr->m0(abs(idRadBef)));
6526 double Qsq = (radAfterBranch + emtAfterBranch).m2Calc();
6530 = (radAfterBranch + recAfterBranch + emtAfterBranch).m2Calc();
6532 if ( !state[rec].isFinal() ){
6533 double mar2 = m2final - 2. * Qsq + 2. * m2RadBef;
6534 recAfterBranch *= (1. - (Qsq - m2RadBef)/(mar2 - m2RadBef))
6535 /(1. + (Qsq - m2RadBef)/(mar2 - m2RadBef));
6538 if (Qsq > mar2)
return 0.5;
6541 Vec4 sum = radAfterBranch + recAfterBranch + emtAfterBranch;
6542 double m2Dip = sum.m2Calc();
6544 double x1 = 2. * (sum * radAfterBranch) / m2Dip;
6545 double x2 = 2. * (sum * recAfterBranch) / m2Dip;
6548 double lambda13 = sqrt( pow2(Qsq - m2RadAft - m2EmtAft )
6549 - 4.*m2RadAft*m2EmtAft);
6550 double k1 = ( Qsq - lambda13 + (m2EmtAft - m2RadAft ) ) / ( 2. * Qsq );
6551 double k3 = ( Qsq - lambda13 - (m2EmtAft - m2RadAft ) ) / ( 2. * Qsq );
6553 z = 1./ ( 1- k1 -k3) * ( x1 / (2.-x2) - k3);
6557 Vec4 qBR(state[rad].p() - state[emt].p() + state[rec].p());
6558 Vec4 qAR(state[rad].p() + state[rec].p());
6560 z = (qBR.m2Calc())/( qAR.m2Calc());
6571 double DireHistory::pTLund(
const Event& event,
int rad,
int emt,
int rec,
6575 map<string,double> stateVars;
6577 bool hasPartonLevel(showers && showers->timesPtr && showers->spacePtr),
6578 hasShowers(fsr && isr);
6579 if (hasPartonLevel) {
6580 bool isFSR = showers->timesPtr->isTimelike(event, rad, emt, rec,
"");
6581 if (isFSR) stateVars = showers->timesPtr->getStateVariables
6582 (event, rad,emt,rec, name);
6583 else stateVars = showers->spacePtr->getStateVariables
6584 (event, rad,emt,rec, name);
6585 }
else if (hasShowers) {
6586 bool isFSR = fsr->isTimelike(event, rad, emt, rec,
"");
6587 if (isFSR) stateVars = fsr->getStateVariables(event, rad,emt,rec, name);
6588 else stateVars = isr->getStateVariables(event, rad,emt,rec, name);
6591 return ( (stateVars.size() > 0 && stateVars.find(
"t") != stateVars.end())
6592 ? sqrt(stateVars[
"t"]) : -1.0 );
6600 int DireHistory::posChangedIncoming(
const Event& event,
bool before) {
6606 for (
int i =0; i <
event.size(); ++i)
6607 if (event[i].status() == 43) {
6613 if (iSister > 0) iMother =
event[iSister].mother1();
6616 if (iSister > 0 && iMother > 0) {
6619 int flavSister =
event[iSister].id();
6620 int flavMother =
event[iMother].id();
6623 int flavDaughter = 0;
6624 if ( abs(flavMother) < 21 && flavSister == 21)
6625 flavDaughter = flavMother;
6626 else if ( flavMother == 21 && flavSister == 21)
6627 flavDaughter = flavMother;
6628 else if ( flavMother == 21 && abs(flavSister) < 21)
6629 flavDaughter = -1*flavSister;
6630 else if ( abs(flavMother) < 21 && abs(flavSister) < 21)
6635 for (
int i =0; i <
event.size(); ++i)
6636 if ( !event[i].isFinal()
6637 &&
event[i].mother1() == iMother
6638 &&
event[i].id() == flavDaughter )
6642 if ( !before )
return iMother;
6643 else return iDaughter;
6651 for (
int i =0; i <
event.size(); ++i)
6652 if ( abs(event[i].status()) == 53 || abs(event[i].status()) == 54) {
6658 if (iMother > 0) iDaughter =
event[iMother].daughter1();
6661 if (iDaughter > 0 && iMother > 0) {
6664 if ( !before )
return iMother;
6665 else return iDaughter;
6676 vector<int> DireHistory::getSplittingPos(
const Event& e,
int type) {
6679 int iRadBef(-1), iRecBef(-1), iRadAft(-1), iEmt(-1), iRecAft(-1);
6683 for (
int i = e.size() - 1; i > 0; i--) {
6684 if ( iRadAft == -1 && e[i].status() == -41) iRadAft = i;
6685 else if ( iEmt == -1 && e[i].status() == 43) iEmt = i;
6686 else if ( iRecAft == -1
6687 && (e[i].status() == -42 || e[i].status() == 48) ) iRecAft = i;
6688 if (iRadAft != -1 && iEmt != -1 && iRecAft != -1)
break;
6691 iRadBef = (iRadAft > 0) ? e[iRadAft].daughter2() : -1;
6693 iRecBef = (iRecAft > 0) ? (e[iRecAft].isFinal()
6694 ? e[iRecAft].mother1() : e[iRecAft].daughter1()) : -1;
6697 }
else if (type >= 3) {
6700 if ( e[e.size() - 1].status() == 52
6701 || e[e.size() - 1].status() == -53
6702 || e[e.size() - 1].status() == -54) iRecAft = (e.size() - 1);
6704 if ( e[e.size() - 2].status() == 51) iEmt = (e.size() - 2);
6706 if ( e[e.size() - 3].status() == 51) iRadAft = (e.size() - 3);
6708 iRadBef = (iRadAft > 0) ? e[iRadAft].mother1() : -1;
6710 iRecBef = (iRecAft > 0) ? (e[iRecAft].isFinal()
6711 ? e[iRecAft].mother1() : e[iRecAft].daughter1()) : -1;
6720 ret = createvector<int>(iRadBef)(iRecBef)(iRadAft)(iRecAft)(iEmt);
6726 double DireHistory::pdfFactor(
const Event&,
const Event& e,
const int type,
6727 double pdfScale,
double mu ) {
6732 if (type < 2)
return 1.0;
6735 vector<int> splitPos = getSplittingPos(e, type);
6736 if (splitPos.size() < 5)
return 1.0;
6737 int iRadBef = splitPos[0];
6738 int iRecBef = splitPos[1];
6739 int iRadAft = splitPos[2];
6740 int iRecAft = splitPos[3];
6743 = infoPtr->settingsPtr->flag(
"ShowerPDF:useSummedPDF");
6746 if ( e[iRadAft].isFinal() && e[iRecAft].isFinal() ) {
6750 }
else if ( e[iRadAft].isFinal() && !e[iRecAft].isFinal() ) {
6753 int flavAft = e[iRecAft].id();
6754 int flavBef = e[iRecBef].id();
6755 double xAft = 2.*e[iRecAft].e() / e[0].e();
6756 double xBef = 2.*e[iRecBef].e() / e[0].e();
6757 bool hasPDFAft = (particleDataPtr->colType(flavAft) != 0);
6758 bool hasPDFBef = (particleDataPtr->colType(flavBef) != 0);
6763 int sideSplit = ( e[iRecAft].pz() > 0.) ? 1 : -1;
6764 double pdfDen1, pdfDen2, pdfNum1, pdfNum2;
6765 pdfDen1 = pdfDen2 = pdfNum1 = pdfNum2 = 1.;
6766 if ( sideSplit == 1 ) {
6767 pdfDen1 = (!hasPDFBef) ? 1.0 : (useSummedPDF)
6768 ? beamA.xf(flavBef, xBef, pow2(mu))
6769 : beamA.xfISR(0, flavBef, xBef, pow2(mu));
6770 pdfNum1 = (!hasPDFBef) ? 1.0 : (useSummedPDF)
6771 ? beamA.xf(flavBef, xBef, pow2(pdfScale))
6772 : beamA.xfISR(0, flavBef, xBef, pow2(pdfScale));
6773 pdfNum2 = (!hasPDFAft) ? 1.0 : (useSummedPDF)
6774 ? beamA.xf(flavAft, xAft, pow2(mu))
6775 : beamA.xfISR(0, flavAft, xAft, pow2(mu));
6776 pdfDen2 = (!hasPDFAft) ? 1.0 : (useSummedPDF)
6777 ? beamA.xf(flavAft, xAft, pow2(pdfScale))
6778 : beamA.xfISR(0, flavAft, xAft, pow2(pdfScale));
6780 pdfDen1 = (!hasPDFBef) ? 1.0 : (useSummedPDF)
6781 ? beamB.xf(flavBef, xBef, pow2(mu))
6782 : beamB.xfISR(0, flavBef, xBef, pow2(mu));
6783 pdfNum1 = (!hasPDFBef) ? 1.0 : (useSummedPDF)
6784 ? beamB.xf(flavBef, xBef, pow2(pdfScale))
6785 : beamB.xfISR(0, flavBef, xBef, pow2(pdfScale));
6786 pdfNum2 = (!hasPDFAft) ? 1.0 : (useSummedPDF)
6787 ? beamB.xf(flavAft, xAft, pow2(mu))
6788 : beamB.xfISR(0, flavAft, xAft, pow2(mu));
6789 pdfDen2 = (!hasPDFAft) ? 1.0 : (useSummedPDF)
6790 ? beamB.xf(flavAft, xAft, pow2(pdfScale))
6791 : beamB.xfISR(0, flavAft, xAft, pow2(pdfScale));
6793 wt = (pdfNum1/pdfDen1) * (pdfNum2)/(pdfDen2);
6796 }
else if ( !e[iRadAft].isFinal() && e[iRecAft].isFinal() ) {
6799 int flavAft = e[iRadAft].id();
6800 int flavBef = e[iRadBef].id();
6801 double xAft = 2.*e[iRadAft].e() / e[0].e();
6802 double xBef = 2.*e[iRadBef].e() / e[0].e();
6803 bool hasPDFAft = (particleDataPtr->colType(flavAft) != 0);
6804 bool hasPDFBef = (particleDataPtr->colType(flavBef) != 0);
6809 int sideSplit = ( e[iRadAft].pz() > 0.) ? 1 : -1;
6810 double pdfDen1, pdfDen2, pdfNum1, pdfNum2;
6811 pdfDen1 = pdfDen2 = pdfNum1 = pdfNum2 = 1.;
6812 if ( sideSplit == 1 ) {
6813 pdfDen1 = (!hasPDFBef) ? 1.0 : (useSummedPDF)
6814 ? beamA.xf(flavBef, xBef, pow2(mu))
6815 : beamA.xfISR(0, flavBef, xBef, pow2(mu));
6816 pdfNum1 = (!hasPDFBef) ? 1.0 : (useSummedPDF)
6817 ? beamA.xf(flavBef, xBef, pow2(pdfScale))
6818 : beamA.xfISR(0, flavBef, xBef, pow2(pdfScale));
6819 pdfNum2 = (!hasPDFAft) ? 1.0 : (useSummedPDF)
6820 ? beamA.xf(flavAft, xAft, pow2(mu))
6821 : beamA.xfISR(0, flavAft, xAft, pow2(mu));
6822 pdfDen2 = (!hasPDFAft) ? 1.0 : (useSummedPDF)
6823 ? beamA.xf(flavAft, xAft, pow2(pdfScale))
6824 : beamA.xfISR(0, flavAft, xAft, pow2(pdfScale));
6826 pdfDen1 = (!hasPDFBef) ? 1.0 : (useSummedPDF)
6827 ? beamB.xf(flavBef, xBef, pow2(mu))
6828 : beamB.xfISR(0, flavBef, xBef, pow2(mu));
6829 pdfNum1 = (!hasPDFBef) ? 1.0 : (useSummedPDF)
6830 ? beamB.xf(flavBef, xBef, pow2(pdfScale))
6831 : beamB.xfISR(0, flavBef, xBef, pow2(pdfScale));
6832 pdfNum2 = (!hasPDFAft) ? 1.0 : (useSummedPDF)
6833 ? beamB.xf(flavAft, xAft, pow2(mu))
6834 : beamB.xfISR(0, flavAft, xAft, pow2(mu));
6835 pdfDen2 = (!hasPDFAft) ? 1.0 : (useSummedPDF)
6836 ? beamB.xf(flavAft, xAft, pow2(pdfScale))
6837 : beamB.xfISR(0, flavAft, xAft, pow2(pdfScale));
6839 wt = (pdfNum1/pdfDen1) * (pdfNum2)/(pdfDen2);
6843 }
else if ( !e[iRadAft].isFinal() && !e[iRecAft].isFinal() ) {
6846 int flavAft = e[iRadAft].id();
6847 int flavBef = e[iRadBef].id();
6848 double xAft = 2.*e[iRadAft].e() / e[0].e();
6849 double xBef = 2.*e[iRadBef].e() / e[0].e();
6854 int sideSplit = ( e[iRadAft].pz() > 0.) ? 1 : -1;
6855 double ratio1 = getPDFratio( sideSplit,
false,
false, flavBef,
6856 xBef, pdfScale, flavBef, xBef, mu );
6857 double ratio2 = getPDFratio( sideSplit,
false,
false, flavAft,
6858 xAft, mu, flavAft, xAft, pdfScale );
6874 double DireHistory::integrand(
int flav,
double x,
double scaleInt,
double z) {
6877 double CA = infoPtr->settingsPtr->parm(
"DireColorQCD:CA") > 0.0
6878 ? infoPtr->settingsPtr->parm(
"DireColorQCD:CA") : 3.0;
6879 double CF = infoPtr->settingsPtr->parm(
"DireColorQCD:CF") > 0.0
6880 ? infoPtr->settingsPtr->parm(
"DireColorQCD:CF") : 4./3.;
6881 double TR = infoPtr->settingsPtr->parm(
"DireColorQCD:TR") > 0.
6882 ? infoPtr->settingsPtr->parm(
"DireColorQCD:TR") : 0.5;
6889 AlphaStrong* as = mergingHooksPtr->AlphaS_ISR();
6890 double asNow = (*as).alphaS(z);
6891 result = 1./z *asNow*asNow* ( log(scaleInt/z) -3./2. );
6895 }
else if (flav==21) {
6897 double measure1 = 1./(1. - z);
6898 double measure2 = 1.;
6902 * z * beamB.xf( 21,x/z,pow(scaleInt,2))
6903 / beamB.xf( 21,x, pow(scaleInt,2))
6908 2.*CA *((1. -z)/z + z*(1.-z))
6909 * beamB.xf( 21,x/z,pow(scaleInt,2))
6910 / beamB.xf( 21,x, pow(scaleInt,2))
6912 + CF * ((1+pow(1-z,2))/z)
6913 *( beamB.xf( 1, x/z,pow(scaleInt,2))
6914 / beamB.xf( 21, x, pow(scaleInt,2))
6915 + beamB.xf( -1, x/z,pow(scaleInt,2))
6916 / beamB.xf( 21, x, pow(scaleInt,2))
6917 + beamB.xf( 2, x/z,pow(scaleInt,2))
6918 / beamB.xf( 21, x, pow(scaleInt,2))
6919 + beamB.xf( -2, x/z,pow(scaleInt,2))
6920 / beamB.xf( 21, x, pow(scaleInt,2))
6921 + beamB.xf( 3, x/z,pow(scaleInt,2))
6922 / beamB.xf( 21, x, pow(scaleInt,2))
6923 + beamB.xf( -3, x/z,pow(scaleInt,2))
6924 / beamB.xf( 21, x, pow(scaleInt,2))
6925 + beamB.xf( 4, x/z,pow(scaleInt,2))
6926 / beamB.xf( 21, x, pow(scaleInt,2))
6927 + beamB.xf( -4, x/z,pow(scaleInt,2))
6928 / beamB.xf( 21, x, pow(scaleInt,2)) );
6931 result = integrand1*measure1 + integrand2*measure2;
6935 double measure1 = 1./(1. -z);
6936 double measure2 = 1.;
6941 * beamB.xf( flav, x/z, pow(scaleInt,2))
6942 / beamB.xf( flav, x, pow(scaleInt,2))
6947 + TR * (pow(z,2) + pow(1-z,2))
6948 * beamB.xf( 21, x/z, pow(scaleInt,2))
6949 / beamB.xf( flav, x, pow(scaleInt,2));
6952 result = measure1*integrand1 + measure2*integrand2;
6964 vector<int> DireHistory::posFlavCKM(
int flav) {
6967 int flavAbs = abs(flav);
6969 vector<int> flavRadBefs;
6971 if (flavAbs > 10 && flavAbs % 2 == 1)
6972 flavRadBefs.push_back(flavAbs + 1);
6974 else if (flavAbs > 10 && flavAbs % 2 == 0)
6975 flavRadBefs.push_back(flavAbs - 1);
6977 else if (flavAbs < 10 && flavAbs % 2 == 1) {
6978 flavRadBefs.push_back(2);
6979 flavRadBefs.push_back(4);
6980 flavRadBefs.push_back(6);
6982 else if (flavAbs < 10 && flavAbs % 2 == 0) {
6983 flavRadBefs.push_back(1);
6984 flavRadBefs.push_back(3);
6985 flavRadBefs.push_back(5);
6998 bool DireHistory::checkFlavour(vector<int>& flavCounts,
int flavRad,
6999 int flavRadBef,
int clusType) {
7002 for(
int k = 0; k < 20; ++k) {
7005 if (abs(flavRad) == k) {
7007 if (flavRad < 0) cor = 1;
7010 if (abs(flavRadBef) == k) {
7012 if (flavRadBef < 0) cor = -1;
7016 if (flavRadBef == flavRad) cor = 0;
7019 if (clusType == 1) {
7020 if (flavCounts[k] + cor != 0)
return false;
7023 if (flavCounts[k] - cor != 0)
return false;
7035 bool DireHistory::isQCD2to2(
const Event& event) {
7037 if (!mergingHooksPtr->doWeakClustering())
return false;
7038 int nFinalPartons = 0, nFinal = 0;
7039 for (
int i = 0;i <
event.size();++i)
7040 if (event[i].isFinal()) {
7042 if ( event[i].idAbs() < 10 ||
event[i].idAbs() == 21)
7045 if (nFinalPartons == 2 && nFinal == 2)
return true;
7054 bool DireHistory::isEW2to1(
const Event& event) {
7056 if (!mergingHooksPtr->doWeakClustering())
return false;
7058 for (
int i = 0;i <
event.size();++i) {
7059 if (event[i].isFinal()) {
7060 if (event[i].idAbs() == 23 ||
7061 event[i].idAbs() == 24 ||
7062 event[i].idAbs() == 22) nVector++;
7068 if (nVector == 1)
return true;
7079 bool DireHistory::isMassless2to2(
const Event& event) {
7081 int nFmassless(0), nFinal(0), nImassless(0);
7082 for (
int i = 0;i <
event.size();++i)
7083 if (event[i].isFinal()) {
7085 if ( event[i].idAbs() < 10
7086 ||
event[i].idAbs() == 21
7087 ||
event[i].idAbs() == 22) nFmassless++;
7088 }
else if ( event[i].status() == -21 ) {
7089 if ( event[i].idAbs() < 10
7090 ||
event[i].idAbs() == 21
7091 ||
event[i].idAbs() == 22) nImassless++;
7093 if (nFmassless == 2 && nFinal == 2 && nImassless == 2)
return true;
7103 bool DireHistory::isDIS2to2(
const Event& event) {
7105 int nFpartons(0), nFleptons(0), nIpartons(0), nIleptons(0), nFinal(0);
7106 for (
int i = 0;i <
event.size();++i)
7107 if (event[i].isFinal()) {
7108 if ( event[i].isLepton() ) nFleptons++;
7109 if ( event[i].colType() != 0 ) nFpartons++;
7111 }
else if ( event[i].status() == -21 ) {
7112 if ( event[i].isLepton() ) nIleptons++;
7113 if ( event[i].colType() != 0 ) nIpartons++;
7115 bool isDIS = nFinal == 2 && nFpartons == 1 && nFleptons == 1
7116 && nIpartons == 1 && nIleptons == 1;
7117 if (isDIS)
return true;
7124 bool DireHistory::mayHaveEffectiveVertex(
string process, vector<int> in,
7127 if ( process.compare(
"ta+ta->jj") == 0
7128 || process.compare(
"ta-ta+>jj") == 0 ) {
7129 int nInFermions(0), nOutFermions(0), nOutBosons(0);
7130 for (
int i=0; i < int(in.size()); ++i)
7131 if (abs(in[i])<20) nInFermions++;
7132 for (
int i=0; i < int(out.size()); ++i) {
7133 if (abs(out[i])<20) nOutFermions++;
7134 if (abs(out[i])>20) nOutBosons++;
7136 return (nInFermions%2==0 && nOutFermions%2==0);
7139 int nInG(0), nOutZ(0), nOutWp(0), nOutWm(0), nOutH(0), nOutA(0), nOutG(0);
7140 for (
int i=0; i < int(in.size()); ++i)
7141 if (in[i]==21) nInG++;
7142 for (
int i=0; i < int(out.size()); ++i) {
7143 if (out[i] == 21) nOutG++;
7144 if (out[i] == 22) nOutA++;
7145 if (out[i] == 23) nOutZ++;
7146 if (out[i] == 24) nOutWp++;
7147 if (out[i] ==-24) nOutWm++;
7148 if (out[i] == 25) nOutH++;
7151 if ( nInG==2 && nOutWp+nOutWm > 0 && nOutWp+nOutWm ==
int(out.size())
7152 && nOutWp-nOutWm == 0)
7154 if (nInG+nOutG>0 && nOutH > 0)
7157 if ( process.find(
"Hinc") != string::npos
7158 && process.find(
"Ainc") != string::npos
7159 && (nOutH > 0 || nOutA%2==0) )
7169 void DireHistory::setSelectedChild() {
7171 if (mother ==
nullptr)
return;
7172 for (
int i = 0;i < int(mother->children.size());++i)
7173 if (mother->children[i] ==
this) mother->selectedChild = i;
7174 mother->setSelectedChild();
7181 void DireHistory::setGoodChildren() {
7182 if (mother ==
nullptr)
return;
7183 for (
int i = 0;i < int(mother->children.size());++i)
7184 if (mother->children[i] ==
this) {
7186 if ( find(mother->goodChildren.begin(), mother->goodChildren.end(), i)
7187 != mother->goodChildren.end() )
continue;
7188 mother->goodChildren.push_back(i);
7190 mother->setGoodChildren();
7197 void DireHistory::setGoodSisters() {
7199 for (
int i = 0;i < int(goodChildren.size());++i) {
7200 for (
int j = 0;j < int(goodChildren.size());++j) {
7201 children[i]->goodSisters.push_back(children[j]);
7203 children[i]->setGoodSisters();
7205 if (!mother) goodSisters.push_back(
this);
7213 void DireHistory::printMECS() {
7215 if ( !mother && children.size() > 0 && (MECnum/MECden > 1e2 )) {
7216 cout << scientific << setprecision(6);
7218 cout <<
" " << goodChildren.size() <<
" num " << MECnum
7219 <<
" den " << MECden << endl;
7221 if (mother ) mother->printMECS();
7228 void DireHistory::setProbabilities() {
7230 for (
int i = 0;i < int(goodSisters.size());++i) {
7232 DireHistory* sisterNow = goodSisters[i];
7233 bool foundOrdered=
false;
7234 double denominator=0.;
7236 double denominator_unconstrained=0.;
7237 double contrib_unconstrained=0.;
7239 for (
int j = 0;j < int(sisterNow->goodChildren.size());++j) {
7241 DireHistory* childNow = sisterNow->children[j];
7243 double virtuality = 2.*(childNow->clusterIn.rad()->p()*
7244 childNow->clusterIn.emt()->p());
7247 map<string,double> stateVars;
7248 int rad = childNow->clusterIn.radPos();
7249 int emt = childNow->clusterIn.emtPos();
7250 int rec = childNow->clusterIn.recPos();
7252 bool hasPartonLevel(showers && showers->timesPtr && showers->spacePtr),
7253 hasShowers(fsr && isr), isFSR(
false);
7254 if (hasPartonLevel) {
7255 isFSR = showers->timesPtr->isTimelike
7256 (sisterNow->state, rad, emt, rec,
"");
7257 if (isFSR) stateVars = showers->timesPtr->getStateVariables
7258 (sisterNow->state,rad,emt,rec,
"");
7259 else stateVars = showers->spacePtr->getStateVariables
7260 (sisterNow->state,rad,emt,rec,
"");
7261 }
else if (hasShowers) {
7262 isFSR = fsr->isTimelike(sisterNow->state, rad, emt, rec,
"");
7263 if (isFSR) stateVars = fsr->getStateVariables
7264 (sisterNow->state,rad,emt,rec,
"");
7265 else stateVars = isr->getStateVariables
7266 (sisterNow->state,rad,emt,rec,
"");
7269 double z = stateVars[
"z"];
7270 double t = stateVars[
"t"];
7271 double Q2 = stateVars[
"m2dip"];
7275 if ( !isFSR && !sisterNow->state[rec].isFinal() ) {
7276 double kappa2 = t/Q2;
7277 xCS = (z*(1-z) - kappa2) / (1 -z);
7278 }
else if ( !isFSR && sisterNow->state[rec].isFinal() ) {
7280 }
else if ( isFSR && !sisterNow->state[rec].isFinal() ) {
7281 double kappa2 = t/Q2;
7282 xCS = 1 - kappa2/(1.-z);
7283 if (abs(Q2) < 1e-5) xCS = 1.;
7286 double dd = childNow->MECnum
7287 * childNow->clusterProb
7290 * pow2(childNow->clusterIn.pT()) / virtuality
7299 / childNow->MECden * childNow->MECcontrib;
7303 string name = childNow->clusterIn.name();
7304 if (hasPartonLevel) {
7305 if ( name.find(
"qcd") != string::npos
7306 || name.find(
"qed") != string::npos)
7307 coupl = childNow->clusterCoupl * 2. * M_PI * 8. * M_PI;
7309 coupl = childNow->clusterCoupl;
7310 }
else if (hasShowers) {
7311 if ( isFSR && ( fsr->splits[name]->is_qcd
7312 || fsr->splits[name]->is_qed))
7313 coupl = childNow->clusterCoupl * 2. * M_PI * 8. * M_PI;
7314 else if ( isr->splits[name]->is_qcd
7315 || isr->splits[name]->is_qed)
7316 coupl = childNow->clusterCoupl * 2. * M_PI * 8. * M_PI;
7318 coupl = childNow->clusterCoupl;
7323 denominator_unconstrained += dd;
7326 if (childNow->clusterIn.pT() > sisterNow->clusterIn.pT()) {
7327 contrib_unconstrained += dd;
7332 if (
int(childNow->goodChildren.size()) == 0
7333 && hardStartScale(childNow->state) > childNow->clusterIn.pT()) {
7335 if (childNow->clusterIn.pT() > sisterNow->clusterIn.pT())
7337 }
else if (
int(childNow->goodChildren.size()) > 0) {
7339 if (childNow->clusterIn.pT() > sisterNow->clusterIn.pT())
7346 if (sisterNow->children.size() > 0) {
7347 if (denominator != 0.0) goodSisters[i]->MECden = denominator;
7348 goodSisters[i]->MECcontrib = contrib;
7349 if (denominator == 0. && contrib == 0.) {
7350 if (denominator_unconstrained != 0.0)
7351 goodSisters[i]->MECden = denominator_unconstrained;
7352 goodSisters[i]->MECcontrib = contrib_unconstrained;
7355 if (!foundOrdered) goodSisters[i]->foundOrderedChildren =
false;
7361 if (mother) mother->setProbabilities();
7369 void DireHistory::setEffectiveScales() {
7371 for (
int i = 0;i < int(goodSisters.size());++i) {
7373 DireHistory* sisterNow = goodSisters[i];
7376 if (sisterNow->goodChildren.size()==0)
continue;
7378 double alphasOftEff_num(0.), alphasOftEff_den(0.), tmin(1e15), tmax(-1.0);
7380 for (
int j = 0;j < int(sisterNow->goodChildren.size());++j) {
7382 DireHistory* childNow = sisterNow->children[j];
7385 double t(pow2(childNow->clusterIn.pT()));
7394 double massSign = childNow->clusterIn.rad()->isFinal() ? 1. : -1.;
7395 double virtuality = massSign*(childNow->clusterIn.rad()->p()
7396 + massSign*childNow->clusterIn.emt()->p()).m2Calc();
7398 map<string,double> stateVars;
7399 int rad = childNow->clusterIn.radPos();
7400 int emt = childNow->clusterIn.emtPos();
7401 int rec = childNow->clusterIn.recPos();
7402 bool hasPartonLevel(showers && showers->timesPtr && showers->spacePtr),
7403 hasShowers(fsr && isr), isFSR(
false);
7404 if (hasPartonLevel) {
7405 isFSR = showers->timesPtr->isTimelike
7406 (sisterNow->state, rad, emt, rec,
"");
7407 if (isFSR) stateVars = showers->timesPtr->getStateVariables
7408 (sisterNow->state,rad,emt,rec,
"");
7409 else stateVars = showers->spacePtr->getStateVariables
7410 (sisterNow->state,rad,emt,rec,
"");
7411 }
else if (hasShowers) {
7412 isFSR = fsr->isTimelike(sisterNow->state, rad, emt, rec,
"");
7413 if (isFSR) stateVars = fsr->getStateVariables
7414 (sisterNow->state,rad,emt,rec,
"");
7415 else stateVars = isr->getStateVariables
7416 (sisterNow->state,rad,emt,rec,
"");
7419 double z = stateVars[
"z"];
7420 double Q2 = stateVars[
"m2dip"];
7424 if ( !isFSR && !sisterNow->state[rec].isFinal() ) {
7425 double kappa2 = t/Q2;
7426 xCS = (z*(1-z) - kappa2) / (1 -z);
7427 }
else if ( !isFSR && sisterNow->state[rec].isFinal() ) {
7429 }
else if ( isFSR && !sisterNow->state[rec].isFinal() ) {
7430 double kappa2 = t/Q2;
7431 xCS = 1 - kappa2/(1.-z);
7435 double coupling(1.);
7436 string name = childNow->clusterIn.name();
7437 int idRadBef = int(stateVars[
"radBefID"]);
7438 int idRec = sisterNow->state[rec].id();
7439 if (hasPartonLevel) {
7440 if ( name.find(
"qcd") != string::npos)
7441 coupling = mergingHooksPtr->AlphaS_FSR()->alphaS(t);
7442 else if ( name.find(
"qed") != string::npos)
7443 coupling = pow2(childNow->clusterIn.rad()->charge())
7444 * mergingHooksPtr->AlphaEM_FSR()->alphaEM(t);
7445 else if ( name.find(
"ew") != string::npos) {
7446 int flav = abs(childNow->clusterIn.flavRadBef);
7448 * (pow2(coupSMPtr->rf( flav )) + pow2(coupSMPtr->lf( flav )))
7449 / (coupSMPtr->sin2thetaW() * coupSMPtr->cos2thetaW());
7451 }
else if (hasShowers) {
7452 if (isFSR) coupling = 2.*M_PI*fsr->splits[name]->coupling(z,t,Q2,-1.,
7453 make_pair(idRadBef, sisterNow->state[rad].isFinal()),
7454 make_pair(idRec, sisterNow->state[rec].isFinal()) );
7455 else coupling = 2.*M_PI*isr->splits[name]->coupling(z,t,Q2,-1.,
7456 make_pair(idRadBef, sisterNow->state[rad].isFinal()),
7457 make_pair(idRec, sisterNow->state[rec].isFinal()) );
7461 double prob = abs(childNow->clusterProb)
7464 * pow2(childNow->clusterIn.pT()) / virtuality
7475 double alphasOftEffPrev(childNow->couplEffective);
7476 alphasOftEff_num += prob * childNow->MECnum * alphasOftEffPrev
7478 alphasOftEff_den += prob * childNow->MECnum;
7485 DireCouplFunction couplFunc( mergingHooksPtr->AlphaS_FSR(),
7486 couplingPowCount[
"qcd"], mergingHooksPtr->AlphaEM_FSR(),
7487 couplingPowCount[
"qed"]);
7488 double as_tmin = couplFunc.f(tmin,vector<double>());
7489 double as_tmax = couplFunc.f(tmax,vector<double>());
7490 double headroom = 1.;
7491 bool failed =
false;
7492 double alphasOftEffRatio = pow(alphasOftEff_num/alphasOftEff_den,1.);
7493 while ( tmin/headroom < tmax*headroom
7494 && ( ( as_tmin-alphasOftEffRatio > 0
7495 && as_tmax-alphasOftEffRatio > 0)
7496 || ( as_tmin-alphasOftEffRatio < 0
7497 && as_tmax-alphasOftEffRatio < 0))) {
7498 if (tmin/headroom < mergingHooksPtr->pTcut()) { failed =
true;
break;}
7500 as_tmin = couplFunc.f(tmin/headroom,vector<double>());
7501 as_tmax = couplFunc.f(tmax*headroom,vector<double>());
7505 DireRootFinder direRootFinder;
7506 double teff = mergingHooksPtr->pTcut();
7507 double tminNow(tmin/headroom), tmaxNow(tmax*headroom);
7509 if (abs(tmaxNow-tminNow)/tmaxNow < 1e-4) teff = tmaxNow;
7510 else teff = direRootFinder.findRoot1D( &couplFunc, tminNow, tmaxNow,
7511 alphasOftEffRatio, vector<double>(), 100);
7515 sisterNow->scaleEffective = sqrt(teff);
7516 sisterNow->couplEffective = alphasOftEffRatio;
7520 if (mother) mother->setEffectiveScales();
7530 double DireHistory::getShowerPluginScale(
const Event& event,
int rad,
int emt,
7531 int rec,
string name,
string key,
double) {
7533 map<string,double> stateVars;
7534 bool hasPartonLevel(showers && showers->timesPtr && showers->spacePtr),
7535 hasShowers(fsr && isr);
7536 if (hasPartonLevel) {
7537 bool isFSR = showers->timesPtr->isTimelike(event, rad, emt, rec,
"");
7538 if (isFSR) stateVars = showers->timesPtr->getStateVariables
7539 (event, rad, emt, rec, name);
7540 else stateVars = showers->spacePtr->getStateVariables
7541 (event, rad, emt, rec, name);
7542 }
else if (hasShowers) {
7543 bool isFSR = fsr->isTimelike(event, rad, emt, rec,
"");
7544 if (isFSR) stateVars = fsr->getStateVariables(event, rad, emt, rec, name);
7545 else stateVars = isr->getStateVariables(event, rad, emt, rec, name);
7548 return ( (stateVars.size() > 0 && stateVars.find(key) != stateVars.end())
7549 ? stateVars[key] : -1.0 );
7557 pair<int,double> DireHistory::getCoupling(
const Event& event,
int rad,
int emt,
7558 int rec,
string name) {
7561 map<string,double> stateVars;
7562 bool hasPartonLevel(showers && showers->timesPtr && showers->spacePtr),
7563 hasShowers(fsr && isr);
7564 if (hasPartonLevel) {
7565 bool isFSR = showers->timesPtr->isTimelike(event, rad, emt, rec,
"");
7566 if (isFSR) stateVars = showers->timesPtr->getStateVariables
7567 (event, rad, emt, rec, name);
7568 else stateVars = showers->spacePtr->getStateVariables
7569 (event, rad, emt, rec, name);
7570 }
else if (hasShowers) {
7571 bool isFSR = fsr->isTimelike(event, rad, emt, rec,
"");
7572 if (isFSR) stateVars = fsr->getStateVariables(event, rad, emt, rec, name);
7573 else stateVars = isr->getStateVariables(event, rad, emt, rec, name);
7578 int type = ( (stateVars.size() > 0
7579 && stateVars.find(
"couplingType") != stateVars.end())
7580 ? stateVars[
"couplingType"] : -1);
7581 double value = ( (stateVars.size() > 0
7582 && stateVars.find(
"couplingValue") != stateVars.end())
7583 ? stateVars[
"couplingValue"] : -1.0);
7586 return make_pair(type,value);
7595 void DireHistory::tagPath(DireHistory* leaf) {
7598 for (
int i=0; i < state.size(); ++i)
7599 if (state[i].isFinal() && state[i].id() == 25) nHiggs++;
7601 if (nHiggs > 0) leaf->tagSave.push_back(
"higgs");
7603 int nFinal(0), nFinalPartons(0), nFinalGamma(0);
7604 for (
int i = 0;i < state.size();++i) {
7605 if (state[i].isFinal()) {
7607 if ( state[i].idAbs() < 10
7608 || state[i].idAbs() == 21) nFinalPartons++;
7609 if ( state[i].idAbs() == 22) nFinalGamma++;
7613 if (nFinal == 2 && nFinalPartons == 2)
7614 leaf->tagSave.push_back(
"qcd");
7616 if (nFinal == 2 && nFinalGamma == 2)
7617 leaf->tagSave.push_back(
"qed");
7619 if (nFinal == 2 && nFinalGamma == 1 && nFinalPartons == 1) {
7620 leaf->tagSave.push_back(
"qed");
7621 leaf->tagSave.push_back(
"qcd");
7625 if (mother) mother->tagPath(leaf);
7634 void DireHistory::multiplyMEsToPath(DireHistory* leaf) {
7637 leaf->prodOfProbsFull *= hardProcessCouplings(state)*clusterCoupl;
7638 leaf->prodOfProbs *= abs(hardProcessCouplings(state)*clusterCoupl);
7640 leaf->prodOfProbsFull *= MECnum/MECden*clusterCoupl;
7641 leaf->prodOfProbs *= abs(MECnum/MECden*clusterCoupl);
7644 if (mother) mother->multiplyMEsToPath(leaf);
7653 void DireHistory::setCouplingOrderCount(DireHistory* leaf,
7654 map<string,int> count) {
7656 string name = clusterIn.name();
7659 hardProcessCouplings(state, 0, 1.,
nullptr,
nullptr,
true);
7661 count = couplingPowCount;
7663 }
else if (couplingPowCount.empty()) {
7664 couplingPowCount = count;
7667 if ( name.find(
"qcd") != string::npos) count[
"qcd"]++;
7668 if ( name.find(
"qed") != string::npos) count[
"qed"]++;
7670 if (mother) mother->setCouplingOrderCount(leaf, count);