8 #include "Pythia8/DireMerging.h"
9 #include "Pythia8/DireSpace.h"
10 #include "Pythia8/DireTimes.h"
24 bool validEvent(
const Event& event ) {
26 bool validColour =
true;
27 bool validCharge =
true;
28 bool validMomenta =
true;
32 double initCharge =
event[3].charge() +
event[4].charge();
33 double finalCharge = 0.0;
34 for(
int i = 0; i <
event.size(); ++i)
35 if (event[i].isFinal()) finalCharge += event[i].charge();
36 if (abs(initCharge-finalCharge) > 1e-12) validCharge =
false;
39 Vec4 pSum(0.,0.,0.,0.);
40 for (
int i = 0; i <
event.size(); ++i) {
41 if ( event[i].status() == -21 ) pSum -= event[i].p();
42 if ( event[i].isFinal() ) pSum += event[i].p();
44 if ( abs(pSum.px()) > mTolErr || abs(pSum.py()) > mTolErr) {
48 if ( event[3].status() == -21
49 && (abs(event[3].px()) > mTolErr || abs(event[3].py()) > mTolErr)){
52 if ( event[4].status() == -21
53 && (abs(event[4].px()) > mTolErr || abs(event[4].py()) > mTolErr)){
57 return (validColour && validCharge && validMomenta);
65 void DireMerging::init(){
67 tmsNowMin = infoPtr->eCM();
69 enforceCutOnLHE = settingsPtr->flag(
"Merging:enforceCutOnLHE");
70 doMOPS = settingsPtr->flag(
"Dire:doMOPS");
71 applyTMSCut = settingsPtr->flag(
"Merging:doXSectionEstimate");
72 doMerging = settingsPtr->flag(
"Dire:doMerging");
73 usePDF = settingsPtr->flag(
"ShowerPDF:usePDF");
74 allowReject = settingsPtr->flag(
"Merging:applyVeto");
75 doMECs = settingsPtr->flag(
"Dire:doMECs");
76 doMEM = settingsPtr->flag(
"Dire:doMEM");
77 doGenerateSubtractions
78 = settingsPtr->flag(
"Dire:doGenerateSubtractions");
79 doGenerateMergingWeights
80 = settingsPtr->flag(
"Dire:doGenerateMergingWeights");
82 = settingsPtr->flag(
"Dire:doExitAfterMerging");
84 = settingsPtr->flag(
"Merging:allowIncompleteHistoriesInReal");
85 nQuarksMerge = settingsPtr->mode(
"Merging:nQuarksMerge");
94 void DireMerging::statistics() {
97 double tmsval = mergingHooksPtr->tms();
98 bool printBanner = enforceCutOnLHE && tmsNowMin > TMSMISMATCH*tmsval
101 tmsNowMin = infoPtr->eCM();
103 if (doMOPS) printBanner =
false;
104 if (doMEM) printBanner =
false;
105 if (doMECs) printBanner =
false;
107 if (!printBanner)
return;
110 cout <<
"\n *------- PYTHIA Matrix Element Merging Information ------"
111 <<
"-------------------------------------------------------*\n"
116 cout <<
" | Warning in DireMerging::statistics: All Les Houches events"
117 <<
" significantly above Merging:TMS cut. Please check. |\n";
122 <<
" *------- End PYTHIA Matrix Element Merging Information -----"
123 <<
"-----------------------------------------------------*" << endl;
128 void DireMerging::storeInfos() {
134 for (
int i = 0 ; i < int(myHistory->children.size()); ++i) {
136 stoppingScalesSave.push_back(myHistory->children[i]->clusterIn.pT());
137 radSave.push_back(myHistory->children[i]->clusterIn.radPos());
138 emtSave.push_back(myHistory->children[i]->clusterIn.emtPos());
139 recSave.push_back(myHistory->children[i]->clusterIn.recPos());
140 mDipSave.push_back(myHistory->children[i]->clusterIn.mass());
147 void DireMerging::getStoppingInfo(
double scales [100][100],
148 double masses [100][100]) {
151 for (
unsigned int i=0; i < radSave.size(); ++i){
152 scales[radSave[i]-posOffest][recSave[i]-posOffest] = stoppingScalesSave[i];
153 masses[radSave[i]-posOffest][recSave[i]-posOffest] = mDipSave[i];
158 double DireMerging::generateSingleSudakov (
double pTbegAll,
159 double pTendAll,
double m2dip,
int idA,
int type,
double s,
double x) {
160 return isr->noEmissionProbability( pTbegAll, pTendAll, m2dip, idA,
166 void DireMerging::reset() {
167 partonSystemsPtr->clear();
176 bool DireMerging::generateUnorderedPoint(
Event& process){
178 cout <<
"generate new unordered point" << endl;
180 Event newProcess( mergingHooksPtr->bareEvent( process,
true) );
190 for (
int iii=0; iii<50; ++iii) {
192 int sizeOld = newProcess.size();
193 int sizeNew = newProcess.size();
196 while (sizeNew < sizeOld+nSplit) {
202 int sizeProcess = newProcess.size();
203 int sizeEvent = newProcess.size();
204 int nOffset = sizeEvent - sizeProcess;
205 int nHardDone = sizeProcess;
206 double scale = newProcess.scale();
208 partonSystemsPtr->addSys();
209 partonSystemsPtr->setInA(0, inP + nOffset);
210 partonSystemsPtr->setInB(0, inM + nOffset);
211 for (
int i = inM + 1; i < nHardDone; ++i)
212 partonSystemsPtr->addOut(0, i + nOffset);
213 partonSystemsPtr->setSHat( 0,
214 (newProcess[inP + nOffset].p() +
215 newProcess[inM + nOffset].p()).m2Calc() );
216 partonSystemsPtr->setPTHat( 0, scale);
219 double x1 = newProcess[inP].pPos() / newProcess[inS].m();
220 double x2 = newProcess[inM].pNeg() / newProcess[inS].m();
221 beamAPtr->append( inP + nOffset, newProcess[inP].
id(), x1);
222 beamBPtr->append( inM + nOffset, newProcess[inM].
id(), x2);
224 beamAPtr->xfISR( 0, newProcess[inP].
id(), x1, scale*scale);
225 int vsc1 = beamAPtr->pickValSeaComp();
226 beamBPtr->xfISR( 0, newProcess[inM].
id(), x2, scale*scale);
227 int vsc2 = beamBPtr->pickValSeaComp();
228 bool isVal1 = (vsc1 == -3);
229 bool isVal2 = (vsc2 == -3);
230 infoPtr->setValence( isVal1, isVal2);
232 isr->prepare(0, newProcess,
true);
233 fsr->prepare(0, newProcess,
true);
235 Event in(newProcess);
236 double pTnowFSR = fsr->newPoint(in);
237 double pTnowISR = isr->newPoint(in);
238 if (pTnowFSR==0. && pTnowISR==0.) { reset();
continue; }
240 if (pTnowFSR > pTnowISR) branched = fsr->branch(in);
241 else branched = isr->branch(in);
242 if (!branched) { reset();
continue; }
243 if (pTnowFSR > pTnowISR) isr->update(0, in,
false);
244 else fsr->update(0, in,
false);
246 pTnowISR = isr->newPoint(in);
247 pTnowFSR = fsr->newPoint(in);
248 if (pTnowFSR==0. && pTnowISR==0.) { reset();
continue; }
250 if (pTnowFSR > pTnowISR) branched = fsr->branch(in);
251 else branched = isr->branch(in);
252 if (!branched) { reset();
continue; }
253 if (pTnowFSR > pTnowISR) isr->update(0, in,
false);
254 else fsr->update(0, in,
false);
257 Event bla = fsr->makeHardEvent(0, in,
false);
258 sizeNew = bla.size();
259 partonSystemsPtr->clear();
270 int sizeOld = newProcess.size();
271 int sizeNew = newProcess.size();
274 while (sizeNew < sizeOld+nSplit) {
280 int sizeProcess = newProcess.size();
281 int sizeEvent = newProcess.size();
282 int nOffset = sizeEvent - sizeProcess;
283 int nHardDone = sizeProcess;
284 double scale = newProcess.scale();
286 partonSystemsPtr->addSys();
287 partonSystemsPtr->setInA(0, inP + nOffset);
288 partonSystemsPtr->setInB(0, inM + nOffset);
289 for (
int i = inM + 1; i < nHardDone; ++i)
290 partonSystemsPtr->addOut(0, i + nOffset);
291 partonSystemsPtr->setSHat( 0,
292 (newProcess[inP + nOffset].p() +
293 newProcess[inM + nOffset].p()).m2Calc() );
294 partonSystemsPtr->setPTHat( 0, scale);
297 double x1 = newProcess[inP].pPos() / newProcess[inS].m();
298 double x2 = newProcess[inM].pNeg() / newProcess[inS].m();
299 beamAPtr->append( inP + nOffset, newProcess[inP].
id(), x1);
300 beamBPtr->append( inM + nOffset, newProcess[inM].
id(), x2);
306 beamAPtr->xfISR( 0, newProcess[inP].
id(), x1, scale*scale);
307 int vsc1 = beamAPtr->pickValSeaComp();
308 beamBPtr->xfISR( 0, newProcess[inM].
id(), x2, scale*scale);
309 int vsc2 = beamBPtr->pickValSeaComp();
310 bool isVal1 = (vsc1 == -3);
311 bool isVal2 = (vsc2 == -3);
312 infoPtr->setValence( isVal1, isVal2);
314 isr->prepare(0, newProcess,
true);
315 fsr->prepare(0, newProcess,
true);
317 Event in(newProcess);
319 double pTnowFSR = fsr->newPoint(in);
320 double pTnowISR = isr->newPoint(in);
322 if (pTnowFSR==0. && pTnowISR==0.) { reset();
continue; }
324 if (pTnowFSR > pTnowISR) branched = fsr->branch(in);
325 else branched = isr->branch(in);
326 if (!branched) { reset();
continue; }
327 if (pTnowFSR > pTnowISR) isr->update(0, in,
false);
328 else fsr->update(0, in,
false);
330 pTnowISR = isr->newPoint(in);
331 pTnowFSR = fsr->newPoint(in);
332 if (pTnowFSR==0. && pTnowISR==0.) { reset();
continue; }
334 if (pTnowFSR > pTnowISR) branched = fsr->branch(in);
335 else branched = isr->branch(in);
336 if (!branched) { reset();
continue; }
337 if (pTnowFSR > pTnowISR) isr->update(0, in,
false);
338 else fsr->update(0, in,
false);
341 in = fsr->makeHardEvent(0, in,
false);
346 for(
int i=0; i < int(in.size()); ++i)
348 && in[i].colType()!= 0
349 && ( in[i].id() == 21 || in[i].idAbs() <= nQuarksMerge))
351 nPartons -= mergingHooksPtr->hardProcess->nQuarksOut();
354 settingsPtr->mode(
"Merging:nRequested", nPartons);
355 mergingHooksPtr->nRequestedSave
356 = settingsPtr->mode(
"Merging:nRequested");
357 mergingHooksPtr->reattachResonanceDecays(in);
359 generateHistories(in,
false);
361 if (myHistory->foundAnyOrderedPaths())
continue;
363 sizeNew = newProcess.size();
372 for(
int i=0; i < int(newProcess.size()); ++i)
373 if ( newProcess[i].isFinal()
374 && newProcess[i].colType()!= 0
375 && ( newProcess[i].id() == 21
376 || newProcess[i].idAbs() <= nQuarksMerge))
378 nPartons -= mergingHooksPtr->hardProcess->nQuarksOut();
381 settingsPtr->mode(
"Merging:nRequested", nPartons);
382 mergingHooksPtr->nRequestedSave
383 = settingsPtr->mode(
"Merging:nRequested");
384 mergingHooksPtr->reattachResonanceDecays(newProcess);
386 process = newProcess;
388 cout <<
"found unordered point" << endl;
402 int DireMerging::mergeProcess(
Event& process){
410 mergingHooksPtr->hardProcess->clear();
411 string processNow = settingsPtr->word(
"Merging:Process");
412 mergingHooksPtr->hardProcess->initOnProcess(processNow, particleDataPtr);
415 while(processNow.find(
" ", 0) != string::npos)
416 processNow.erase(processNow.begin()+processNow.find(
" ",0));
417 mergingHooksPtr->processSave = processNow;
419 mergingHooksPtr->doUserMergingSave
420 = settingsPtr->flag(
"Merging:doUserMerging");
421 mergingHooksPtr->doMGMergingSave
422 = settingsPtr->flag(
"Merging:doMGMerging");
423 mergingHooksPtr->doKTMergingSave
424 = settingsPtr->flag(
"Merging:doKTMerging");
425 mergingHooksPtr->doPTLundMergingSave
426 = settingsPtr->flag(
"Merging:doPTLundMerging");
427 mergingHooksPtr->doCutBasedMergingSave
428 = settingsPtr->flag(
"Merging:doCutBasedMerging");
429 mergingHooksPtr->doNL3TreeSave
430 = settingsPtr->flag(
"Merging:doNL3Tree");
431 mergingHooksPtr->doNL3LoopSave
432 = settingsPtr->flag(
"Merging:doNL3Loop");
433 mergingHooksPtr->doNL3SubtSave
434 = settingsPtr->flag(
"Merging:doNL3Subt");
435 mergingHooksPtr->doUNLOPSTreeSave
436 = settingsPtr->flag(
"Merging:doUNLOPSTree");
437 mergingHooksPtr->doUNLOPSLoopSave
438 = settingsPtr->flag(
"Merging:doUNLOPSLoop");
439 mergingHooksPtr->doUNLOPSSubtSave
440 = settingsPtr->flag(
"Merging:doUNLOPSSubt");
441 mergingHooksPtr->doUNLOPSSubtNLOSave
442 = settingsPtr->flag(
"Merging:doUNLOPSSubtNLO");
443 mergingHooksPtr->doUMEPSTreeSave
444 = settingsPtr->flag(
"Merging:doUMEPSTree");
445 mergingHooksPtr->doUMEPSSubtSave
446 = settingsPtr->flag(
"Merging:doUMEPSSubt");
447 mergingHooksPtr->nReclusterSave
448 = settingsPtr->mode(
"Merging:nRecluster");
450 mergingHooksPtr->hasJetMaxLocal =
false;
451 mergingHooksPtr->nJetMaxLocal
452 = mergingHooksPtr->nJetMaxSave;
453 mergingHooksPtr->nJetMaxNLOLocal
454 = mergingHooksPtr->nJetMaxNLOSave;
455 mergingHooksPtr->nRequestedSave
456 = settingsPtr->mode(
"Merging:nRequested");
459 mergingHooksPtr->tms(mergingHooksPtr->tmsCut());
462 bool includeWGT = mergingHooksPtr->includeWGTinXSEC();
468 if ( applyTMSCut && cutOnProcess(process) ) {
469 if (includeWGT) infoPtr->weightContainerPtr->setWeightNominal(0.);
474 if ( applyTMSCut )
return 1;
481 Event newp( mergingHooksPtr->bareEvent( process,
false) );
483 for(
int i=0; i < int(newp.size()); ++i)
484 if ( newp[i].isFinal()
485 && newp[i].colType()!= 0
486 && ( newp[i].id() == 21 || newp[i].idAbs() <= nQuarksMerge))
489 int nSteps = mergingHooksPtr->getNumberOfClusteringSteps( newp,
false);
491 nPartons -= mergingHooksPtr->hardProcess->nQuarksOut();
494 settingsPtr->mode(
"Merging:nRequested", nPartons);
496 mergingHooksPtr->hasJetMaxLocal =
false;
497 mergingHooksPtr->nJetMaxLocal
498 = mergingHooksPtr->nJetMaxSave;
499 mergingHooksPtr->nJetMaxNLOLocal
500 = mergingHooksPtr->nJetMaxNLOSave;
501 mergingHooksPtr->nRequestedSave
502 = settingsPtr->mode(
"Merging:nRequested");
505 int nFinal(0), nQuarks(0), nGammas(0);
506 for (
int i=0; i < newp.size(); ++i) {
507 if (newp[i].idAbs() < 7) nQuarks++;
508 if (newp[i].idAbs() == 22) nGammas++;
509 if (newp[i].isFinal()) nFinal++;
511 settingsPtr->mode(
"DireSpace:nFinalMax",nFinal-1);
512 settingsPtr->mode(
"DireTimes:nFinalMax",nFinal-1);
513 if (nQuarks > 4)
return 1;
517 mergingHooksPtr->tms(mergingHooksPtr->tmsCut());
521 if (doMECs)
return 1;
523 if (doMEM) mergingHooksPtr->orderHistories(
false);
525 clock_t begin = clock();
527 if (doMOPS) generateUnorderedPoint(process);
529 bool foundHistories = generateHistories(process,
false);
530 int returnCode = (foundHistories) ? 1 : 0;
532 if (doMOPS && myHistory->foundAnyOrderedPaths() && nSteps > 0)
535 std::clock_t end = std::clock();
536 double elapsed_secs_1 = double(end - begin) / CLOCKS_PER_SEC;
537 sum_paths += myHistory->goodBranches.size();
538 sum_time_1 += elapsed_secs_1;
546 if (doGenerateSubtractions) calculateSubtractions();
547 bool useAll = doMOPS;
549 double RNpath = getPathIndex(useAll);
550 if ((doMOPS && returnCode > 0) || doGenerateMergingWeights)
551 returnCode = calculateWeights(RNpath, useAll);
554 double elapsed_secs_2 = double(end - begin) / CLOCKS_PER_SEC;
555 sum_time_2 += elapsed_secs_2;
557 int tmp_code = getStartingConditions( RNpath, process);
558 if (returnCode > 0) returnCode = tmp_code;
561 if (returnCode == 0) {
562 mergingHooksPtr->setWeightCKKWL({0.});
563 if ( includeWGT) infoPtr->weightContainerPtr->setWeightNominal(0.);
566 if (!allowReject && returnCode < 1) returnCode=1;
569 if (foundHistories) storeInfos();
572 if (returnCode < 1) mergingHooksPtr->setWeightCKKWL({0.});
577 if (doExitAfterMerging)
return -1;
583 if ( mergingHooksPtr->doCKKWLMerging() )
584 vetoCode = mergeProcessCKKWL(process);
587 if ( mergingHooksPtr->doUMEPSMerging() )
588 vetoCode = mergeProcessUMEPS(process);
591 if ( mergingHooksPtr->doNL3Merging() )
592 vetoCode = mergeProcessNL3(process);
595 if ( mergingHooksPtr->doUNLOPSMerging() )
596 vetoCode = mergeProcessUNLOPS(process);
606 int DireMerging::mergeProcessCKKWL(
Event& process) {
609 mergingHooksPtr->doIgnoreStep(
true);
612 if ( mergingHooksPtr->getProcessString().compare(
"pp>h") == 0 )
613 mergingHooksPtr->allowCutOnRecState(
true);
618 mergingHooksPtr->orderHistories(
false);
621 bool includeWGT = mergingHooksPtr->includeWGTinXSEC();
625 mergingHooksPtr->setWeightCKKWL({1.});
626 mergingHooksPtr->muMI(-1.);
631 Event newProcess( mergingHooksPtr->bareEvent( process,
true) );
633 if (mergingHooksPtr->doWeakClustering())
634 for (
int i = 0;i < newProcess.size();++i)
635 newProcess[i].pol(9);
637 mergingHooksPtr->storeHardProcessCandidates( newProcess);
642 int nSteps = mergingHooksPtr->getNumberOfClusteringSteps( newProcess,
true);
644 double tmsnow = mergingHooksPtr->tmsNow( newProcess );
649 int nRequested = mergingHooksPtr->nRequested();
652 mergingHooksPtr->setHardProcessInfo(nSteps, tmsnow);
653 mergingHooksPtr->setEventVetoInfo(-1, -1.);
655 if (nSteps < nRequested && allowReject) {
656 if (!includeWGT) mergingHooksPtr->setWeightCKKWL({0.});
657 if ( includeWGT) infoPtr->weightContainerPtr->setWeightNominal(0.);
662 tmsNowMin = (nSteps == 0) ? 0. : min(tmsNowMin, tmsnow);
665 newProcess.scale(0.0);
667 DireHistory FullHistory( nSteps, 0.0, newProcess, DireClustering(),
668 mergingHooksPtr, (*beamAPtr), (*beamBPtr), particleDataPtr, infoPtr,
669 trialPartonLevelPtr, fsr, isr, psweights, coupSMPtr,
true,
true,
670 1.0, 1.0, 1.0, 1.0, 0);
673 FullHistory.projectOntoDesiredHistories();
676 double sumAll(0.), sumFullAll(0.);
677 for ( map<double, DireHistory*>::iterator
678 it = FullHistory.goodBranches.begin();
679 it != FullHistory.goodBranches.end(); ++it ) {
680 sumAll += it->second->prodOfProbs;
681 sumFullAll += it->second->prodOfProbsFull;
685 vector<double> path_index;
686 for ( map<double, DireHistory*>::iterator
687 it = FullHistory.goodBranches.begin();
688 it != FullHistory.goodBranches.end(); ++it ) {
690 double indexNow = (lastp + 0.5*(it->first - lastp))/sumAll;
691 path_index.push_back(indexNow);
695 int sizeBranches = FullHistory.goodBranches.size();
696 int iPosRN = (sizeBranches > 0)
698 vector<double>(sizeBranches, 1./
double(sizeBranches)) )
700 double RN = (sizeBranches > 0) ? path_index[iPosRN] : rndmPtr->flat();
703 FullHistory.select(RN)->setSelectedChild();
707 bool applyCut = allowReject
708 && nSteps > 0 && FullHistory.select(RN)->nClusterings() > 0;
710 Event core( FullHistory.lowestMultProc(RN) );
712 if ( mergingHooksPtr->getProcessString().compare(
"e+p>e+j") == 0
713 || mergingHooksPtr->getProcessString().compare(
"e-p>e-j") == 0 ) {
716 if (FullHistory.isDIS2to2(core)) {
717 int iInEl(0), iOutEl(0);
718 for (
int i=0; i < core.size(); ++i )
719 if ( core[i].idAbs() == 11 ) {
720 if ( core[i].status() == -21 ) iInEl = i;
721 if ( core[i].isFinal() ) iOutEl = i;
723 double Q = sqrt( -(core[iInEl].p() - core[iOutEl].p() ).m2Calc());
724 double tmsCut = mergingHooksPtr->tmsCut();
725 double tmsEvt = tmsCut / sqrt( 1. + pow( tmsCut/ ( 0.5*Q ), 2) );
726 mergingHooksPtr->tms(tmsEvt);
728 }
else if (FullHistory.isMassless2to2(core)) {
730 for (
int i=0; i < core.size(); ++i )
731 if ( core[i].isFinal() ) mT *= core[i].mT();
733 double tmsCut = mergingHooksPtr->tmsCut();
734 double tmsEvt = tmsCut / sqrt( 1. + pow( tmsCut/ ( 0.5*Q ), 2) );
735 mergingHooksPtr->tms(tmsEvt);
738 double tmsval = mergingHooksPtr->tms();
742 if ( enforceCutOnLHE && applyCut && tmsnow < tmsval ) {
743 string message=
"Warning in DireMerging::mergeProcessCKKWL: "
745 message+=
" fails merging scale cut. Reject event.";
746 infoPtr->errorMsg(message);
747 if (!includeWGT) mergingHooksPtr->setWeightCKKWL({0.});
748 if ( includeWGT) infoPtr->weightContainerPtr->setWeightNominal(0.);
753 int nFinalP(0), nFinalW(0), nFinalZ(0);
754 for (
int i = 0; i < core.size(); ++i )
755 if ( core[i].isFinal() ) {
756 if ( core[i].colType() != 0 ) nFinalP++;
757 if ( core[i].idAbs() == 24 ) nFinalW++;
758 if ( core[i].idAbs() == 23 ) nFinalZ++;
760 bool complete = (FullHistory.select(RN)->nClusterings() == nSteps) ||
761 ( mergingHooksPtr->doWeakClustering() && nFinalP == 2
762 && nFinalW+nFinalZ == 0);
764 string message=
"Warning in DireMerging::mergeProcessCKKWL: No clusterings";
765 message+=
" found. History incomplete.";
766 infoPtr->errorMsg(message);
772 for ( map<double, DireHistory*>::iterator it =
773 FullHistory.goodBranches.begin();
774 it != FullHistory.goodBranches.end(); ++it ) {
777 double indexNow = (lastp + 0.5*(it->first - lastp))/sumAll;
781 double probPath = it->second->prodOfProbsFull/sumFullAll;
783 FullHistory.select(indexNow)->setSelectedChild();
786 double w = FullHistory.weightTREE( trialPartonLevelPtr,
787 mergingHooksPtr->AlphaS_FSR(), mergingHooksPtr->AlphaS_ISR(),
788 mergingHooksPtr->AlphaEM_FSR(), mergingHooksPtr->AlphaEM_ISR(),
791 wgtsum += probPath*w;
798 FullHistory.getStartingConditions( RN, process );
800 mergingHooksPtr->reattachResonanceDecays(process);
804 double dampWeight = mergingHooksPtr->dampenIfFailCuts(
805 FullHistory.lowestMultProc(RN) );
812 if (!includeWGT) mergingHooksPtr->setWeightCKKWL({wgt});
815 if ( includeWGT) infoPtr->weightContainerPtr->
816 setWeightNominal(infoPtr->weight()*wgt);
819 mergingHooksPtr->doIgnoreStep(
false);
822 if ( allowReject && wgt == 0. )
return 0;
833 int DireMerging::mergeProcessUMEPS(
Event& process) {
836 bool doUMEPSTree = settingsPtr->flag(
"Merging:doUMEPSTree");
837 bool doUMEPSSubt = settingsPtr->flag(
"Merging:doUMEPSSubt");
839 mergingHooksPtr->nReclusterSave = settingsPtr->mode(
"Merging:nRecluster");
840 int nRecluster = settingsPtr->mode(
"Merging:nRecluster");
843 mergingHooksPtr->doIgnoreEmissions(
true);
846 if ( mergingHooksPtr->getProcessString().compare(
"pp>h") == 0 )
847 mergingHooksPtr->allowCutOnRecState(
true);
849 mergingHooksPtr->orderHistories(
true);
852 bool includeWGT = mergingHooksPtr->includeWGTinXSEC();
855 if (mergingHooksPtr->doWeakClustering())
856 for (
int i = 0;i < process.size();++i)
861 mergingHooksPtr->setWeightCKKWL({1.});
862 mergingHooksPtr->muMI(-1.);
867 Event newProcess( mergingHooksPtr->bareEvent( process,
true) );
869 mergingHooksPtr->storeHardProcessCandidates( newProcess );
872 double tmsval = mergingHooksPtr->tms();
874 double tmsnow = mergingHooksPtr->tmsNow( newProcess );
876 int nSteps = mergingHooksPtr->getNumberOfClusteringSteps( newProcess,
true);
877 int nRequested = mergingHooksPtr->nRequested();
882 if (nSteps < nRequested) {
883 if (!includeWGT) mergingHooksPtr->setWeightCKKWL({0.});
884 if ( includeWGT) infoPtr->weightContainerPtr->setWeightNominal(0.);
889 tmsNowMin = (nSteps == 0) ? 0. : min(tmsNowMin, tmsnow);
892 double RN = rndmPtr->flat();
894 newProcess.scale(0.0);
896 DireHistory FullHistory( nSteps, 0.0, newProcess, DireClustering(),
898 (*beamAPtr), (*beamBPtr), particleDataPtr, infoPtr,
899 trialPartonLevelPtr, fsr, isr, psweights, coupSMPtr,
true,
true,
900 1.0, 1.0, 1.0, 1.0, 0);
902 FullHistory.projectOntoDesiredHistories();
906 bool applyCut = nSteps > 0 && FullHistory.select(RN)->nClusterings() > 0;
910 if ( enforceCutOnLHE && applyCut && tmsnow < tmsval ) {
911 string message=
"Warning in DireMerging::mergeProcessUMEPS: "
913 message+=
" fails merging scale cut. Reject event.";
914 infoPtr->errorMsg(message);
915 if (!includeWGT) mergingHooksPtr->setWeightCKKWL({0.});
916 if ( includeWGT) infoPtr->weightContainerPtr->setWeightNominal(0.);
922 if ( nSteps > 0 && doUMEPSSubt
923 && !FullHistory.getFirstClusteredEventAboveTMS( RN, nRecluster,
924 newProcess, nPerformed,
false ) ) {
926 if (!includeWGT) mergingHooksPtr->setWeightCKKWL({0.});
927 if ( includeWGT) infoPtr->weightContainerPtr->setWeightNominal(0.);
931 mergingHooksPtr->nMinMPI(nSteps - nPerformed);
937 wgt = FullHistory.weight_UMEPS_TREE( trialPartonLevelPtr,
938 mergingHooksPtr->AlphaS_FSR(), mergingHooksPtr->AlphaS_ISR(),
939 mergingHooksPtr->AlphaEM_FSR(), mergingHooksPtr->AlphaEM_ISR(), RN);
941 wgt = FullHistory.weight_UMEPS_SUBT( trialPartonLevelPtr,
942 mergingHooksPtr->AlphaS_FSR(), mergingHooksPtr->AlphaS_ISR(),
943 mergingHooksPtr->AlphaEM_FSR(), mergingHooksPtr->AlphaEM_ISR(), RN);
948 if ( doUMEPSTree ) FullHistory.getStartingConditions( RN, process );
950 else FullHistory.getFirstClusteredEventAboveTMS( RN, nRecluster, process,
955 double dampWeight = mergingHooksPtr->dampenIfFailCuts(
956 FullHistory.lowestMultProc(RN) );
963 if (!includeWGT) mergingHooksPtr->setWeightCKKWL({wgt});
966 if ( includeWGT) infoPtr->weightContainerPtr->
967 setWeightNominal(infoPtr->weight()*wgt);
972 double muf = process[0].e();
973 for (
int i=0; i < process.size(); ++i )
974 if ( process[i].isFinal()
975 && (process[i].colType() != 0 || process[i].id() == 22 ) ) {
977 muf = min( muf, abs(process[i].mT()) );
983 int nStepsNew = mergingHooksPtr->getNumberOfClusteringSteps( process );
985 && ( mergingHooksPtr->getProcessString().compare(
"pp>jj") == 0
986 || mergingHooksPtr->getProcessString().compare(
"pp>aj") == 0) )
990 mergingHooksPtr->storeHardProcessCandidates( process );
992 mergingHooksPtr->reattachResonanceDecays(process);
995 mergingHooksPtr->doIgnoreEmissions(
false);
998 if ( wgt == 0. )
return 0;
1009 int DireMerging::mergeProcessNL3(
Event& process) {
1012 bool doNL3Tree = settingsPtr->flag(
"Merging:doNL3Tree");
1013 bool doNL3Loop = settingsPtr->flag(
"Merging:doNL3Loop");
1014 bool doNL3Subt = settingsPtr->flag(
"Merging:doNL3Subt");
1017 mergingHooksPtr->doIgnoreEmissions(
true);
1019 mergingHooksPtr->doIgnoreStep(
true);
1022 if ( mergingHooksPtr->getProcessString().compare(
"pp>h") == 0)
1023 mergingHooksPtr->allowCutOnRecState(
true);
1025 mergingHooksPtr->orderHistories(
true);
1029 mergingHooksPtr->setWeightCKKWL({1.});
1031 double wgtFIRST = 0.;
1032 mergingHooksPtr->setWeightFIRST({0.});
1033 mergingHooksPtr->muMI(-1.);
1038 Event newProcess( mergingHooksPtr->bareEvent( process,
true) );
1040 mergingHooksPtr->storeHardProcessCandidates( newProcess);
1043 double tmsval = mergingHooksPtr->tms();
1045 double tmsnow = mergingHooksPtr->tmsNow( newProcess );
1047 int nSteps = mergingHooksPtr->getNumberOfClusteringSteps( newProcess,
true);
1048 int nRequested = mergingHooksPtr->nRequested();
1053 if (nSteps < nRequested) {
1054 mergingHooksPtr->setWeightCKKWL({0.});
1055 mergingHooksPtr->setWeightFIRST({0.});
1060 tmsNowMin = (nSteps == 0) ? 0. : min(tmsNowMin, tmsnow);
1064 if ( enforceCutOnLHE && nSteps > 0 && nSteps == nRequested
1065 && tmsnow < tmsval ) {
1066 string message =
"Warning in DireMerging::mergeProcessNL3: Les Houches";
1067 message +=
" Event fails merging scale cut. Reject event.";
1068 infoPtr->errorMsg(message);
1069 mergingHooksPtr->setWeightCKKWL({0.});
1070 mergingHooksPtr->setWeightFIRST({0.});
1075 double RN = rndmPtr->flat();
1077 newProcess.scale(0.0);
1079 DireHistory FullHistory( nSteps, 0.0, newProcess, DireClustering(),
1081 (*beamAPtr), (*beamBPtr), particleDataPtr, infoPtr,
1082 trialPartonLevelPtr, fsr, isr, psweights, coupSMPtr,
true,
true,
1083 1.0, 1.0, 1.0, 1.0, 0);
1085 FullHistory.projectOntoDesiredHistories();
1088 if ( nSteps > 0 && doNL3Subt
1089 && FullHistory.select(RN)->nClusterings() == 0 ){
1090 mergingHooksPtr->setWeightCKKWL({0.});
1091 mergingHooksPtr->setWeightFIRST({0.});
1097 bool containsRealKin = nSteps > nRequested && nSteps > 0;
1101 if ( containsRealKin ) {
1105 dummy.init(
"(hard process-modified)", particleDataPtr );
1108 if ( !FullHistory.getClusteredEvent( RN, nSteps, dummy )) {
1109 mergingHooksPtr->setWeightCKKWL({0.});
1110 mergingHooksPtr->setWeightFIRST({0.});
1113 double tnowNew = mergingHooksPtr->tmsNow( dummy );
1115 if ( enforceCutOnLHE && nRequested > 0 && tnowNew < tmsval ) {
1116 mergingHooksPtr->setWeightCKKWL({0.});
1117 mergingHooksPtr->setWeightFIRST({0.});
1123 if ( doNL3Subt || containsRealKin ) mergingHooksPtr->nMinMPI(nSteps - 1);
1124 else mergingHooksPtr->nMinMPI(nSteps);
1131 wgt = FullHistory.weightTREE( trialPartonLevelPtr,
1132 mergingHooksPtr->AlphaS_FSR(), mergingHooksPtr->AlphaS_ISR(),
1133 mergingHooksPtr->AlphaEM_FSR(), mergingHooksPtr->AlphaEM_ISR(), RN);
1134 }
else if( doNL3Loop || doNL3Subt ) {
1137 wgt = FullHistory.weightLOOP( trialPartonLevelPtr, RN);
1142 if ( !doNL3Subt && !containsRealKin )
1143 FullHistory.getStartingConditions(RN, process);
1149 if ( !FullHistory.getClusteredEvent( RN, nSteps, process )) {
1150 mergingHooksPtr->setWeightCKKWL({0.});
1151 mergingHooksPtr->setWeightFIRST({0.});
1158 double dampWeight = mergingHooksPtr->dampenIfFailCuts(
1159 FullHistory.lowestMultProc(RN) );
1168 double kFactor = 1.;
1169 if( nSteps > mergingHooksPtr->nMaxJetsNLO() )
1170 kFactor = mergingHooksPtr->kFactor( mergingHooksPtr->nMaxJetsNLO() );
1171 else kFactor = mergingHooksPtr->kFactor(nSteps);
1177 mergingHooksPtr->setWeightCKKWL({wgt});
1182 bool doOASTree = doNL3Tree && nSteps <= mergingHooksPtr->nMaxJetsNLO();
1187 wgtFIRST = FullHistory.weightFIRST( trialPartonLevelPtr,
1188 mergingHooksPtr->AlphaS_FSR(), mergingHooksPtr->AlphaS_ISR(),
1189 mergingHooksPtr->AlphaEM_FSR(), mergingHooksPtr->AlphaEM_ISR(), RN,
1192 wgtFIRST *= dampWeight;
1194 mergingHooksPtr->setWeightFIRST({wgtFIRST});
1197 wgt = wgt - wgtFIRST;
1203 for(
int i=0; i < process.size(); ++i)
1204 if(process[i].isFinal() && process[i].colType() != 0) {
1205 pT = sqrt(pow(process[i].px(),2) + pow(process[i].py(),2));
1211 && mergingHooksPtr->getProcessString().compare(
"pp>jj") == 0)
1215 mergingHooksPtr->storeHardProcessCandidates( process );
1217 mergingHooksPtr->reattachResonanceDecays(process);
1220 mergingHooksPtr->doIgnoreEmissions(
false);
1222 mergingHooksPtr->doIgnoreStep(
false);
1233 int DireMerging::mergeProcessUNLOPS(
Event& process) {
1236 bool nloTilde = settingsPtr->flag(
"Merging:doUNLOPSTilde");
1237 bool doUNLOPSTree = settingsPtr->flag(
"Merging:doUNLOPSTree");
1238 bool doUNLOPSLoop = settingsPtr->flag(
"Merging:doUNLOPSLoop");
1239 bool doUNLOPSSubt = settingsPtr->flag(
"Merging:doUNLOPSSubt");
1240 bool doUNLOPSSubtNLO = settingsPtr->flag(
"Merging:doUNLOPSSubtNLO");
1242 mergingHooksPtr->nReclusterSave = settingsPtr->mode(
"Merging:nRecluster");
1243 int nRecluster = settingsPtr->mode(
"Merging:nRecluster");
1246 mergingHooksPtr->doIgnoreEmissions(
true);
1248 mergingHooksPtr->orderHistories(
true);
1251 if ( mergingHooksPtr->getProcessString().compare(
"pp>h") == 0)
1252 mergingHooksPtr->allowCutOnRecState(
true);
1256 mergingHooksPtr->setWeightCKKWL({1.});
1258 double wgtFIRST = 0.;
1259 mergingHooksPtr->setWeightFIRST({0.});
1260 mergingHooksPtr->muMI(-1.);
1265 Event newProcess( mergingHooksPtr->bareEvent( process,
true) );
1267 mergingHooksPtr->storeHardProcessCandidates( newProcess );
1270 double tmsval = mergingHooksPtr->tms();
1272 double tmsnow = mergingHooksPtr->tmsNow( newProcess );
1274 int nSteps = mergingHooksPtr->getNumberOfClusteringSteps( newProcess,
true);
1275 int nRequested = mergingHooksPtr->nRequested();
1280 if (nSteps < nRequested) {
1281 string message=
"Warning in DireMerging::mergeProcessUNLOPS: "
1282 "Les Houches Event";
1283 message+=
" after removing decay products does not contain enough partons.";
1284 infoPtr->errorMsg(message);
1285 mergingHooksPtr->setWeightCKKWL({0.});
1286 mergingHooksPtr->setWeightFIRST({0.});
1291 tmsNowMin = (nSteps == 0) ? 0. : min(tmsNowMin, tmsnow);
1294 double RN = rndmPtr->flat();
1296 newProcess.scale(0.0);
1298 DireHistory FullHistory( nSteps, 0.0, newProcess, DireClustering(),
1300 (*beamAPtr), (*beamBPtr), particleDataPtr, infoPtr,
1301 trialPartonLevelPtr, fsr, isr, psweights, coupSMPtr,
true,
true,
1302 1.0, 1.0, 1.0, 1.0, 0);
1304 FullHistory.projectOntoDesiredHistories();
1308 bool applyCut = nSteps > 0 && FullHistory.select(RN)->nClusterings() > 0;
1312 if ( enforceCutOnLHE && applyCut && nSteps == nRequested
1313 && tmsnow < tmsval && tmsval > 0.) {
1314 string message=
"Warning in DireMerging::mergeProcessUNLOPS: Les Houches";
1315 message+=
" Event fails merging scale cut. Reject event.";
1316 infoPtr->errorMsg(message);
1317 mergingHooksPtr->setWeightCKKWL({0.});
1318 mergingHooksPtr->setWeightFIRST({0.});
1324 bool containsRealKin = nSteps > nRequested && nSteps > 0;
1325 if ( containsRealKin ) nRecluster += nSteps - nRequested;
1330 if ( doUNLOPSLoop && containsRealKin && !allowIncompleteReal
1331 && FullHistory.select(RN)->nClusterings() == 0 ) {
1332 mergingHooksPtr->setWeightCKKWL({0.});
1333 mergingHooksPtr->setWeightFIRST({0.});
1339 if ( nSteps > 0 && !allowIncompleteReal
1340 && ( doUNLOPSSubt || doUNLOPSSubtNLO || containsRealKin )
1341 && !FullHistory.getFirstClusteredEventAboveTMS( RN, nRecluster,
1342 newProcess, nPerformed,
false ) ) {
1343 mergingHooksPtr->setWeightCKKWL({0.});
1344 mergingHooksPtr->setWeightFIRST({0.});
1349 mergingHooksPtr->nMinMPI(nSteps - nPerformed);
1353 if ( containsRealKin ) {
1357 dummy.init(
"(hard process-modified)", particleDataPtr );
1360 FullHistory.getClusteredEvent( RN, nSteps, dummy );
1361 double tnowNew = mergingHooksPtr->tmsNow( dummy );
1363 if (enforceCutOnLHE && nRequested > 0 && tnowNew < tmsval && tmsval > 0.) {
1364 string message=
"Warning in DireMerging::mergeProcessUNLOPS: Les Houches";
1365 message+=
" Event fails merging scale cut. Reject event.";
1366 infoPtr->errorMsg(message);
1367 mergingHooksPtr->setWeightCKKWL({0.});
1368 mergingHooksPtr->setWeightFIRST({0.});
1374 bool doUNLOPS2 =
false;
1379 if( doUNLOPSTree ) {
1382 wgt = FullHistory.weight_UNLOPS_TREE( trialPartonLevelPtr,
1383 mergingHooksPtr->AlphaS_FSR(), mergingHooksPtr->AlphaS_ISR(),
1384 mergingHooksPtr->AlphaEM_FSR(), mergingHooksPtr->AlphaEM_ISR(),
1386 }
else if( doUNLOPSLoop ) {
1388 wgt = FullHistory.weight_UNLOPS_LOOP( trialPartonLevelPtr,
1389 mergingHooksPtr->AlphaS_FSR(), mergingHooksPtr->AlphaS_ISR(),
1390 mergingHooksPtr->AlphaEM_FSR(), mergingHooksPtr->AlphaEM_ISR(),
1392 }
else if( doUNLOPSSubtNLO ) {
1394 wgt = FullHistory.weight_UNLOPS_SUBTNLO( trialPartonLevelPtr,
1395 mergingHooksPtr->AlphaS_FSR(), mergingHooksPtr->AlphaS_ISR(),
1396 mergingHooksPtr->AlphaEM_FSR(), mergingHooksPtr->AlphaEM_ISR(),
1398 }
else if( doUNLOPSSubt ) {
1401 wgt = FullHistory.weight_UNLOPS_SUBT( trialPartonLevelPtr,
1402 mergingHooksPtr->AlphaS_FSR(), mergingHooksPtr->AlphaS_ISR(),
1403 mergingHooksPtr->AlphaEM_FSR(), mergingHooksPtr->AlphaEM_ISR(),
1409 if (!doUNLOPSSubt && !doUNLOPSSubtNLO && !containsRealKin )
1410 FullHistory.getStartingConditions(RN, process);
1412 else FullHistory.getFirstClusteredEventAboveTMS( RN, nRecluster, process,
1417 double dampWeight = mergingHooksPtr->dampenIfFailCuts(
1418 FullHistory.lowestMultProc(RN) );
1425 if ( doUNLOPSTree || doUNLOPSSubt ){
1427 double kFactor = 1.;
1428 if ( nSteps > mergingHooksPtr->nMaxJetsNLO() )
1429 kFactor = mergingHooksPtr->kFactor( mergingHooksPtr->nMaxJetsNLO() );
1430 else kFactor = mergingHooksPtr->kFactor(nSteps);
1432 wgt *= (nRecluster == 2 && nloTilde) ? 1. : kFactor;
1436 mergingHooksPtr->setWeightCKKWL({wgt});
1441 int nMaxNLO = mergingHooksPtr->nMaxJetsNLO();
1442 bool doOASTree = doUNLOPSTree && nSteps <= nMaxNLO;
1443 bool doOASSubt = doUNLOPSSubt && nSteps <= nMaxNLO+1 && nSteps > 0;
1446 if ( doOASTree || doOASSubt ) {
1449 int order = ( nSteps > 0 && nSteps <= nMaxNLO) ? 1 : -1;
1454 if ( nloTilde && doUNLOPSSubt && nRecluster == 1
1455 && nSteps == nMaxNLO+1 ) order = 0;
1461 if (nloTilde && doUNLOPSSubt && ( nSteps > nMaxNLO+1
1462 || (nSteps == nMaxNLO+1 && nPerformed != nRecluster) ))
1466 wgtFIRST = FullHistory.weight_UNLOPS_CORRECTION( order,
1467 trialPartonLevelPtr, mergingHooksPtr->AlphaS_FSR(),
1468 mergingHooksPtr->AlphaS_ISR(), mergingHooksPtr->AlphaEM_FSR(),
1469 mergingHooksPtr->AlphaEM_ISR(), RN, rndmPtr );
1474 if ( nloTilde && doUNLOPSSubt && nRecluster == 1
1475 && nPerformed == nRecluster && nSteps <= nMaxNLO )
1479 wgtFIRST *= dampWeight;
1482 mergingHooksPtr->setWeightFIRST({wgtFIRST});
1486 if (doUNLOPS2 && order > -1) wgt = -wgt*(wgtFIRST-1.);
1487 else if (order > -1) wgt = wgt - wgtFIRST;
1494 double muf = process[0].e();
1495 for (
int i=0; i < process.size(); ++i )
1496 if ( process[i].isFinal()
1497 && (process[i].colType() != 0 || process[i].id() == 22 ) ) {
1499 muf = min( muf, abs(process[i].mT()) );
1503 if ( nSteps == 0 && nFinal == 2
1504 && ( mergingHooksPtr->getProcessString().compare(
"pp>jj") == 0
1505 || mergingHooksPtr->getProcessString().compare(
"pp>aj") == 0) )
1509 mergingHooksPtr->storeHardProcessCandidates( process );
1513 vector <int> oldResonance;
1514 for (
int i=0; i < newProcess.size(); ++i )
1515 if ( newProcess[i].status() == 22 )
1516 oldResonance.push_back(newProcess[i].id());
1517 vector <int> newResonance;
1518 for (
int i=0; i < process.size(); ++i )
1519 if ( process[i].status() == 22 )
1520 newResonance.push_back(process[i].id());
1522 for (
int i=0; i < int(oldResonance.size()); ++i )
1523 for (
int j=0; j < int(newResonance.size()); ++j )
1524 if ( newResonance[j] == oldResonance[i] ) {
1525 oldResonance[i] = 99;
1528 bool hasNewResonances = (newResonance.size() != oldResonance.size());
1529 for (
int i=0; i < int(oldResonance.size()); ++i )
1530 hasNewResonances = (oldResonance[i] != 99);
1533 if (!hasNewResonances) mergingHooksPtr->reattachResonanceDecays(process);
1536 mergingHooksPtr->doIgnoreEmissions(
false);
1539 if ( wgt == 0. )
return 0;
1543 if (hasNewResonances)
return 2;
1554 bool DireMerging::generateHistories(
const Event& process,
bool orderedOnly) {
1557 if (!validEvent(process)) {
1558 cout <<
"Warning in DireMerging::generateHistories: Input event "
1559 <<
"has invalid flavour or momentum structure, thus reject. " << endl;
1564 if (myHistory)
delete myHistory;
1567 mergingHooksPtr->orderHistories(orderedOnly);
1569 if (doMOPS) mergingHooksPtr->orderHistories(
false);
1573 if ( mergingHooksPtr->getProcessString().compare(
"pp>h") == 0)
1574 mergingHooksPtr->allowCutOnRecState(
true);
1579 Event newProcess( mergingHooksPtr->bareEvent( process,
true) );
1581 mergingHooksPtr->storeHardProcessCandidates( newProcess );
1584 int nSteps = mergingHooksPtr->getNumberOfClusteringSteps( newProcess,
true);
1589 newProcess.scale(0.0);
1591 myHistory =
new DireHistory( nSteps, 0.0, newProcess, DireClustering(),
1593 (*beamAPtr), (*beamBPtr), particleDataPtr, infoPtr,
1594 trialPartonLevelPtr, fsr, isr, psweights, coupSMPtr,
true,
true,
1595 1.0, 1.0, 1.0, 1.0, 0);
1597 bool foundHistories = myHistory->projectOntoDesiredHistories();
1600 return (doMOPS ? foundHistories :
true);
1606 void DireMerging::tagHistories() {
1609 for ( map<double, DireHistory*>::iterator it =
1610 myHistory->goodBranches.begin();
1611 it != myHistory->goodBranches.end(); ++it )
1612 it->second->tagPath(it->second);
1614 double sumAll(0.), sumFullAll(0.), lastp(0.);
1615 for ( map<double, DireHistory*>::iterator it =
1616 myHistory->goodBranches.begin();
1617 it != myHistory->goodBranches.end(); ++it ) {
1618 sumAll += it->second->prodOfProbs;
1619 sumFullAll += it->second->prodOfProbsFull;
1623 vector<double> sumSignalProb(createvector<double>(0.)(0.)(0.)),
1624 sumBkgrndProb(createvector<double>(0.)(0.)(0.));
1626 for ( map<double, DireHistory*>::iterator it =
1627 myHistory->goodBranches.begin();
1628 it != myHistory->goodBranches.end(); ++it ) {
1630 if (it->second == myHistory)
continue;
1633 double prob = it->second->prodOfProbsFull;
1635 double indexNow = (lastp + 0.5*(it->first - lastp))/sumAll;
1637 myHistory->select(indexNow)->setSelectedChild();
1638 vector<double> w = myHistory->weightMEM( trialPartonLevelPtr,
1639 mergingHooksPtr->AlphaS_FSR(), mergingHooksPtr->AlphaEM_FSR(), indexNow);
1640 for (
unsigned int i=0; i < w.size(); ++i) {
1641 totalProbSave[i] += prob*w[i];
1642 if (it->second->hasTag(
"higgs")) signalProbSave[
"higgs"][i] += prob*w[i];
1643 else bkgrndProbSave[
"higgs"][i] += prob*w[i];
1644 if (it->second->hasTag(
"qed")) signalProbSave[
"qed"][i] += prob*w[i];
1645 else bkgrndProbSave[
"qed"][i] += prob*w[i];
1646 if (it->second->hasTag(
"qcd")) signalProbSave[
"qcd"][i] += prob*w[i];
1647 else bkgrndProbSave[
"qcd"][i] += prob*w[i];
1649 if (it->second->hasTag(
"higgs") ) signalProbSave[
"higgs-subt"][i]
1651 else bkgrndProbSave[
"higgs-subt"][i]
1653 if (it->second->hasTag(
"higgs") ) signalProbSave[
"higgs-nosud"][i]
1655 else bkgrndProbSave[
"higgs-nosud"][i]
1664 double DireMerging::getPathIndex(
bool useAll) {
1666 if (!useAll)
return rndmPtr->flat();
1670 for ( map<double, DireHistory*>::iterator it =
1671 myHistory->goodBranches.begin();
1672 it != myHistory->goodBranches.end(); ++it ) {
1673 sumAll += it->second->prodOfProbs;
1677 vector<double> path_index;
1678 for ( map<double, DireHistory*>::iterator it =
1679 myHistory->goodBranches.begin();
1680 it != myHistory->goodBranches.end(); ++it ) {
1682 double indexNow = (lastp + 0.5*(it->first - lastp))/sumAll;
1683 path_index.push_back(indexNow);
1687 int sizeBranches = myHistory->goodBranches.size();
1688 int iPosRN = (sizeBranches > 0)
1690 vector<double>(sizeBranches, 1./
double(sizeBranches)) )
1692 double RN = (sizeBranches > 0) ? path_index[iPosRN] : rndmPtr->flat();
1700 bool DireMerging::calculateSubtractions() {
1703 clearSubtractions();
1704 for (
int i = 0 ; i < int(myHistory->children.size()); ++i) {
1707 Event psppoint = myHistory->children[i]->state;
1709 mergingHooksPtr->storeHardProcessCandidates( psppoint );
1713 vector <int> oldResonance;
1714 for (
int n=0; n < myHistory->state.size(); ++n )
1715 if ( myHistory->state[n].status() == 22 )
1716 oldResonance.push_back(myHistory->state[n].id());
1717 vector <int> newResonance;
1718 for (
int n=0; n < psppoint.size(); ++n )
1719 if ( psppoint[n].status() == 22 )
1720 newResonance.push_back(psppoint[n].id());
1722 for (
int n=0; n < int(oldResonance.size()); ++n )
1723 for (
int m=0; m < int(newResonance.size()); ++m )
1724 if ( newResonance[m] == oldResonance[n] ) {
1725 oldResonance[n] = 99;
1728 bool hasNewResonances = (newResonance.size() != oldResonance.size());
1729 for (
int n=0; n < int(oldResonance.size()); ++n )
1730 hasNewResonances = (oldResonance[n] != 99);
1733 if (!hasNewResonances) mergingHooksPtr->reattachResonanceDecays(psppoint);
1735 cout <<
"Warning in DireMerging::generateHistories: Resonance "
1736 <<
"structure changed due to clustering. Cannot attach decay "
1737 <<
"products correctly." << endl;
1740 double prob = myHistory->children[i]->clusterProb;
1746 map<string,double> stateVars;
1747 int rad = myHistory->children[i]->clusterIn.radPos();
1748 int emt = myHistory->children[i]->clusterIn.emtPos();
1749 int rec = myHistory->children[i]->clusterIn.recPos();
1751 bool isFSR = myHistory->showers->timesPtr->isTimelike(myHistory->state,
1754 stateVars = myHistory->showers->timesPtr->getStateVariables(
1755 myHistory->state,rad,emt,rec,
"");
1757 stateVars = myHistory->showers->spacePtr->getStateVariables(
1758 myHistory->state,rad,emt,rec,
"");
1760 double z = stateVars[
"z"];
1761 double t = stateVars[
"t"];
1764 (-2.*myHistory->state[emt].p()*myHistory->state[rad].p()
1765 -2.*myHistory->state[emt].p()*myHistory->state[rec].p()
1766 +2.*myHistory->state[rad].p()*myHistory->state[rec].p());
1767 double kappa2 = t/m2dip;
1768 double xCS = (z*(1-z) - kappa2) / (1 -z);
1774 prob *= myHistory->MECnum/myHistory->MECden;
1777 appendSubtraction( prob, psppoint);
1782 mergingHooksPtr->storeHardProcessCandidates( myHistory->state );
1793 int DireMerging::calculateWeights(
double RNpath,
bool useAll ) {
1796 bool nloTilde = settingsPtr->flag(
"Merging:doUNLOPSTilde");
1797 bool doUNLOPSTree = settingsPtr->flag(
"Merging:doUNLOPSTree");
1798 bool doUNLOPSLoop = settingsPtr->flag(
"Merging:doUNLOPSLoop");
1799 bool doUNLOPSSubt = settingsPtr->flag(
"Merging:doUNLOPSSubt");
1800 bool doUNLOPSSubtNLO = settingsPtr->flag(
"Merging:doUNLOPSSubtNLO");
1802 mergingHooksPtr->nReclusterSave = settingsPtr->mode(
"Merging:nRecluster");
1803 int nRecluster = settingsPtr->mode(
"Merging:nRecluster");
1806 mergingHooksPtr->doIgnoreEmissions(
true);
1807 mergingHooksPtr->setWeightCKKWL({1.});
1808 mergingHooksPtr->setWeightFIRST({0.});
1813 double wgtFIRST = 0.;
1814 mergingHooksPtr->muMI(-1.);
1817 double tmsval = mergingHooksPtr->tms();
1819 if (doMOPS) tmsval = 0.;
1822 double tmsnow = mergingHooksPtr->tmsNow( myHistory->state );
1824 int nSteps = mergingHooksPtr->getNumberOfClusteringSteps( myHistory->state,
1826 int nRequested = mergingHooksPtr->nRequested();
1828 if (doMOPS && nSteps == 0) {
return 1; }
1833 if (nSteps < nRequested) {
1834 string message=
"Warning in DireMerging::calculateWeights: "
1835 "Les Houches Event";
1836 message+=
" after removing decay products does not contain enough partons.";
1837 infoPtr->errorMsg(message);
1838 if (allowReject)
return -1;
1842 tmsNowMin = (nSteps == 0) ? 0. : min(tmsNowMin, tmsnow);
1846 bool applyCut = nSteps > 0 && myHistory->select(RNpath)->nClusterings() > 0;
1850 if ( enforceCutOnLHE && applyCut && nSteps == nRequested
1851 && tmsnow < tmsval && tmsval > 0.) {
1852 string message=
"Warning in DireMerging::calculateWeights: Les Houches";
1853 message+=
" Event fails merging scale cut. Reject event.";
1854 infoPtr->errorMsg(message);
1855 if (allowReject)
return -1;
1861 bool containsRealKin = nSteps > nRequested && nSteps > 0;
1862 if ( containsRealKin ) nRecluster += nSteps - nRequested;
1867 if ( doUNLOPSLoop && containsRealKin && !allowIncompleteReal
1868 && myHistory->select(RNpath)->nClusterings() == 0 ) {
1869 if (allowReject)
return -1;
1874 if ( nSteps > 0 && !allowIncompleteReal
1875 && ( doUNLOPSSubt || doUNLOPSSubtNLO || containsRealKin )
1876 && !myHistory->getFirstClusteredEventAboveTMS( RNpath, nRecluster,
1877 myHistory->state, nPerformed,
false ) ) {
1878 if (allowReject)
return -1;
1882 mergingHooksPtr->nMinMPI(nSteps - nPerformed);
1886 if ( containsRealKin ) {
1890 dummy.init(
"(hard process-modified)", particleDataPtr );
1893 myHistory->getClusteredEvent( RNpath, nSteps, dummy );
1894 double tnowNew = mergingHooksPtr->tmsNow( dummy );
1896 if (enforceCutOnLHE && nRequested > 0 && tnowNew < tmsval && tmsval > 0.) {
1897 string message=
"Warning in DireMerging::calculateWeights: Les Houches";
1898 message+=
" Event fails merging scale cut. Reject event.";
1899 infoPtr->errorMsg(message);
1900 if (allowReject)
return -1;
1906 double sumAll(0.), sumFullAll(0.);
1907 for ( map<double, DireHistory*>::iterator it =
1908 myHistory->goodBranches.begin();
1909 it != myHistory->goodBranches.end(); ++it ) {
1910 sumAll += it->second->prodOfProbs;
1911 sumFullAll += it->second->prodOfProbsFull;
1915 double sumSignalProb(0.), sumBkgrndProb(0.);
1918 bool doUNLOPS2 =
false;
1925 wgt = myHistory->weightMOPS( trialPartonLevelPtr,
1926 mergingHooksPtr->AlphaS_FSR(), mergingHooksPtr->AlphaEM_FSR(),
1928 else if ( mergingHooksPtr->doCKKWLMerging() )
1929 wgt = myHistory->weightTREE( trialPartonLevelPtr,
1930 mergingHooksPtr->AlphaS_FSR(), mergingHooksPtr->AlphaS_ISR(),
1931 mergingHooksPtr->AlphaEM_FSR(), mergingHooksPtr->AlphaEM_ISR(),
1933 else if ( mergingHooksPtr->doUMEPSTreeSave )
1934 wgt = myHistory->weight_UMEPS_TREE( trialPartonLevelPtr,
1935 mergingHooksPtr->AlphaS_FSR(), mergingHooksPtr->AlphaS_ISR(),
1936 mergingHooksPtr->AlphaEM_FSR(), mergingHooksPtr->AlphaEM_ISR(),
1938 else if ( mergingHooksPtr->doUMEPSSubtSave )
1939 wgt = myHistory->weight_UMEPS_SUBT( trialPartonLevelPtr,
1940 mergingHooksPtr->AlphaS_FSR(), mergingHooksPtr->AlphaS_ISR(),
1941 mergingHooksPtr->AlphaEM_FSR(), mergingHooksPtr->AlphaEM_ISR(),
1943 else if ( mergingHooksPtr->doUNLOPSTreeSave )
1944 wgt = myHistory->weight_UNLOPS_TREE( trialPartonLevelPtr,
1945 mergingHooksPtr->AlphaS_FSR(), mergingHooksPtr->AlphaS_ISR(),
1946 mergingHooksPtr->AlphaEM_FSR(), mergingHooksPtr->AlphaEM_ISR(),
1948 else if ( mergingHooksPtr->doUNLOPSLoopSave )
1949 wgt = myHistory->weight_UNLOPS_LOOP( trialPartonLevelPtr,
1950 mergingHooksPtr->AlphaS_FSR(), mergingHooksPtr->AlphaS_ISR(),
1951 mergingHooksPtr->AlphaEM_FSR(), mergingHooksPtr->AlphaEM_ISR(),
1953 else if ( mergingHooksPtr->doUNLOPSSubtNLOSave )
1954 wgt = myHistory->weight_UNLOPS_SUBTNLO( trialPartonLevelPtr,
1955 mergingHooksPtr->AlphaS_FSR(), mergingHooksPtr->AlphaS_ISR(),
1956 mergingHooksPtr->AlphaEM_FSR(), mergingHooksPtr->AlphaEM_ISR(),
1958 else if ( mergingHooksPtr->doUNLOPSSubtSave )
1959 wgt = myHistory->weight_UNLOPS_SUBT( trialPartonLevelPtr,
1960 mergingHooksPtr->AlphaS_FSR(), mergingHooksPtr->AlphaS_ISR(),
1961 mergingHooksPtr->AlphaEM_FSR(), mergingHooksPtr->AlphaEM_ISR(),
1965 if ( doUNLOPSTree || doUNLOPSSubt ){
1967 double kFactor = 1.;
1968 if ( nSteps > mergingHooksPtr->nMaxJetsNLO() )
1969 kFactor = mergingHooksPtr->kFactor( mergingHooksPtr->nMaxJetsNLO() );
1970 else kFactor = mergingHooksPtr->kFactor(nSteps);
1972 wgt *= (nRecluster == 2 && nloTilde) ? 1. : kFactor;
1975 }
else if (doMOPS) {
1980 for ( map<double, DireHistory*>::iterator it =
1981 myHistory->goodBranches.begin();
1982 it != myHistory->goodBranches.end(); ++it ) {
1985 double indexNow = (lastp + 0.5*(it->first - lastp))/sumAll;
1989 double probPath = it->second->prodOfProbsFull/sumFullAll;
1991 myHistory->select(indexNow)->setSelectedChild();
1994 double w = myHistory->weightMOPS( trialPartonLevelPtr,
1995 mergingHooksPtr->AlphaS_FSR(), mergingHooksPtr->AlphaEM_FSR(),
1998 wgtsum += probPath*w;
2001 if (it->second->hasTag(
"higgs"))
2002 sumSignalProb += it->second->prodOfProbsFull*w;
2004 sumBkgrndProb += it->second->prodOfProbsFull*w;
2011 mergingHooksPtr->setWeightCKKWL({wgt});
2016 int nMaxNLO = mergingHooksPtr->nMaxJetsNLO();
2017 bool doOASTree = doUNLOPSTree && nSteps <= nMaxNLO;
2018 bool doOASSubt = doUNLOPSSubt && nSteps <= nMaxNLO+1 && nSteps > 0;
2021 if ( doOASTree || doOASSubt ) {
2024 int order = ( nSteps > 0 && nSteps <= nMaxNLO) ? 1 : -1;
2029 if ( nloTilde && doUNLOPSSubt && nRecluster == 1
2030 && nSteps == nMaxNLO+1 ) order = 0;
2036 if (nloTilde && doUNLOPSSubt && ( nSteps > nMaxNLO+1
2037 || (nSteps == nMaxNLO+1 && nPerformed != nRecluster) ))
2041 wgtFIRST = myHistory->weight_UNLOPS_CORRECTION( order,
2042 trialPartonLevelPtr, mergingHooksPtr->AlphaS_FSR(),
2043 mergingHooksPtr->AlphaS_ISR(), mergingHooksPtr->AlphaEM_FSR(),
2044 mergingHooksPtr->AlphaEM_ISR(), RNpath, rndmPtr );
2049 if ( nloTilde && doUNLOPSSubt && nRecluster == 1
2050 && nPerformed == nRecluster && nSteps <= nMaxNLO )
2056 if (doUNLOPS2 && order > -1) wgt = -wgt*(wgtFIRST-1.);
2057 else if (order > -1) wgt = wgt - wgtFIRST;
2062 if ( allowReject && wgt == 0. )
return 0;
2074 int DireMerging::getStartingConditions(
double RNpath,
Event& process) {
2077 bool doUNLOPSSubt = settingsPtr->flag(
"Merging:doUNLOPSSubt");
2078 bool doUNLOPSSubtNLO = settingsPtr->flag(
"Merging:doUNLOPSSubtNLO");
2080 mergingHooksPtr->nReclusterSave = settingsPtr->mode(
"Merging:nRecluster");
2081 int nRecluster = settingsPtr->mode(
"Merging:nRecluster");
2084 int nSteps = mergingHooksPtr->getNumberOfClusteringSteps( myHistory->state,
2086 int nRequested = mergingHooksPtr->nRequested();
2090 bool containsRealKin = nSteps > nRequested && nSteps > 0;
2091 if ( containsRealKin ) nRecluster += nSteps - nRequested;
2096 if (!doUNLOPSSubt && !doUNLOPSSubtNLO && !containsRealKin )
2097 myHistory->getStartingConditions(RNpath, process);
2099 else myHistory->getFirstClusteredEventAboveTMS( RNpath, nRecluster, process,
2105 double muf = process[0].e();
2106 for (
int i=0; i < process.size(); ++i )
2107 if ( process[i].isFinal()
2108 && (process[i].colType() != 0 || process[i].id() == 22 ) ) {
2110 muf = min( muf, abs(process[i].mT()) );
2114 if ( nSteps == 0 && nFinal == 2
2115 && ( mergingHooksPtr->getProcessString().compare(
"pp>jj") == 0
2116 || mergingHooksPtr->getProcessString().compare(
"pp>aj") == 0) )
2120 mergingHooksPtr->storeHardProcessCandidates( process );
2124 vector <int> oldResonance;
2125 for (
int i=0; i < myHistory->state.size(); ++i )
2126 if ( myHistory->state[i].status() == 22 )
2127 oldResonance.push_back(myHistory->state[i].id());
2128 vector <int> newResonance;
2129 for (
int i=0; i < process.size(); ++i )
2130 if ( process[i].status() == 22 )
2131 newResonance.push_back(process[i].id());
2133 for (
int i=0; i < int(oldResonance.size()); ++i )
2134 for (
int j=0; j < int(newResonance.size()); ++j )
2135 if ( newResonance[j] == oldResonance[i] ) {
2136 oldResonance[i] = 99;
2139 bool hasNewResonances = (newResonance.size() != oldResonance.size());
2140 for (
int i=0; i < int(oldResonance.size()); ++i )
2141 hasNewResonances = (oldResonance[i] != 99);
2144 if (!hasNewResonances) mergingHooksPtr->reattachResonanceDecays(process);
2147 mergingHooksPtr->doIgnoreEmissions(
false);
2151 if (hasNewResonances)
return 2;
2162 bool DireMerging::cutOnProcess(
Event& process) {
2165 mergingHooksPtr->nReclusterSave = settingsPtr->mode(
"Merging:nRecluster");
2168 mergingHooksPtr->orderHistories(
true);
2171 if ( mergingHooksPtr->getProcessString().compare(
"pp>h") == 0)
2172 mergingHooksPtr->allowCutOnRecState(
true);
2175 if (mergingHooksPtr->doWeakClustering())
2176 for (
int i = 0;i < process.size();++i)
2182 Event newProcess( mergingHooksPtr->bareEvent( process,
true) );
2184 mergingHooksPtr->storeHardProcessCandidates( newProcess );
2187 double tmsval = mergingHooksPtr->tms();
2189 double tmsnow = mergingHooksPtr->tmsNow( newProcess );
2191 int nSteps = mergingHooksPtr->getNumberOfClusteringSteps( newProcess,
true);
2196 int nRequested = mergingHooksPtr->nRequested();
2197 if (nSteps < nRequested)
return true;
2200 tmsNowMin = (nSteps == 0) ? 0. : min(tmsNowMin, tmsnow);
2204 bool containsRealKin = nSteps > nRequested && nSteps > 0;
2207 double RN = rndmPtr->flat();
2209 newProcess.scale(0.0);
2211 DireHistory FullHistory( nSteps, 0.0, newProcess, DireClustering(),
2213 (*beamAPtr), (*beamBPtr), particleDataPtr, infoPtr,
2214 trialPartonLevelPtr, fsr, isr, psweights, coupSMPtr,
true,
true,
2215 1.0, 1.0, 1.0, 1.0, 0);
2217 FullHistory.projectOntoDesiredHistories();
2222 if ( containsRealKin && !allowIncompleteReal
2223 && FullHistory.select(RN)->nClusterings() == 0 )
2227 double dampWeight = mergingHooksPtr->dampenIfFailCuts(
2228 FullHistory.lowestMultProc(RN) );
2229 if ( dampWeight == 0. )
return true;
2233 if ( nSteps > 0 && FullHistory.select(RN)->nClusterings() == 0 )
2238 if ( nSteps > 0 && nSteps == nRequested && tmsnow < tmsval && tmsval > 0.) {
2239 string message=
"Warning in DireMerging::cutOnProcess: Les Houches Event";
2240 message+=
" fails merging scale cut. Reject event.";
2241 infoPtr->errorMsg(message);
2249 coreProcess.clear();
2250 coreProcess.init(
"(hard process-modified)", particleDataPtr );
2251 coreProcess.clear();
2252 coreProcess = FullHistory.lowestMultProc(RN);
2253 for (
int i = 0; i < coreProcess.size(); ++i )
2254 if ( coreProcess[i].isFinal() ) {
2255 if ( coreProcess[i].colType() != 0 )
2257 if ( coreProcess[i].idAbs() == 24 )
2261 bool complete = (FullHistory.select(RN)->nClusterings() == nSteps) ||
2262 ( mergingHooksPtr->doWeakClustering() && nFinalP == 2 && nFinalW == 0 );
2265 string message=
"Warning in DireMerging::cutOnProcess: No clusterings";
2266 message+=
" found. History incomplete.";
2267 infoPtr->errorMsg(message);
2271 if ( !containsRealKin )
return false;
2279 dummy.init(
"(hard process-modified)", particleDataPtr );
2282 FullHistory.getClusteredEvent( RN, nSteps, dummy );
2283 double tnowNew = mergingHooksPtr->tmsNow( dummy );
2285 if ( nRequested > 0 && tnowNew < tmsval && tmsval > 0.) {
2286 string message=
"Warning in DireMerging::cutOnProcess: Les Houches Event";
2287 message+=
" fails merging scale cut. Reject event.";
2288 infoPtr->errorMsg(message);