StRoot  1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
Merging.cc
1 // MergingHooks.cc is a part of the PYTHIA event generator.
2 // Copyright (C) 2020 Torbjorn Sjostrand.
3 // PYTHIA is licenced under the GNU GPL v2 or later, see COPYING for details.
4 // Please respect the MCnet Guidelines, see GUIDELINES for details.
5 
6 // This file is written by Stefan Prestel.
7 // Function definitions (not found in the header) for the Merging class.
8 
9 #include "Pythia8/Merging.h"
10 
11 namespace Pythia8 {
12 
13 //==========================================================================
14 
15 // The Merging class.
16 
17 //--------------------------------------------------------------------------
18 
19 // Factor by which the maximal value of the merging scale can deviate before
20 // a warning is printed.
21 const double Merging::TMSMISMATCH = 1.5;
22 
23 //--------------------------------------------------------------------------
24 
25 // Initialise Merging class
26 
27 void Merging::init(){
28 
29  // Reset minimal tms value.
30  tmsNowMin = infoPtr->eCM();
31 
32 }
33 
34 //--------------------------------------------------------------------------
35 
36 // Function to print information.
37 void Merging::statistics() {
38 
39  // Recall switch to enfore merging scale cut.
40  bool enforceCutOnLHE = flag("Merging:enforceCutOnLHE");
41  // Recall merging scale value.
42  double tmsval = mergingHooksPtr ? mergingHooksPtr->tms() : 0;
43  bool printBanner = enforceCutOnLHE && tmsNowMin > TMSMISMATCH*tmsval;
44  // Reset minimal tms value.
45  tmsNowMin = infoPtr->eCM();
46 
47  if (!printBanner) return;
48 
49  // Header.
50  cout << "\n *------- PYTHIA Matrix Element Merging Information ------"
51  << "-------------------------------------------------------*\n"
52  << " | "
53  << " |\n";
54  // Print warning if the minimal tms value of any event was significantly
55  // above the desired merging scale value.
56  cout << " | Warning in Merging::statistics: All Les Houches events"
57  << " significantly above Merging:TMS cut. Please check. |\n";
58 
59  // Listing finished.
60  cout << " | "
61  << " |\n"
62  << " *------- End PYTHIA Matrix Element Merging Information -----"
63  << "-----------------------------------------------------*" << endl;
64 }
65 
66 //--------------------------------------------------------------------------
67 
68 // Function to steer different merging prescriptions.
69 
70 int Merging::mergeProcess(Event& process){
71 
72  int vetoCode = 1;
73 
74  // Reinitialise hard process.
75  mergingHooksPtr->hardProcess->clear();
76  mergingHooksPtr->processNow = word("Merging:Process");
77  mergingHooksPtr->hardProcess->initOnProcess(
78  mergingHooksPtr->processNow, particleDataPtr);
79 
80  settingsPtr->word("Merging:Process", mergingHooksPtr->processSave);
81 
82  mergingHooksPtr->doUserMergingSave = flag("Merging:doUserMerging");
83  mergingHooksPtr->doMGMergingSave = flag("Merging:doMGMerging");
84  mergingHooksPtr->doKTMergingSave = flag("Merging:doKTMerging");
85  mergingHooksPtr->doPTLundMergingSave = flag("Merging:doPTLundMerging");
86  mergingHooksPtr->doCutBasedMergingSave = flag("Merging:doCutBasedMerging");
87  mergingHooksPtr->doNL3TreeSave = flag("Merging:doNL3Tree");
88  mergingHooksPtr->doNL3LoopSave = flag("Merging:doNL3Loop");
89  mergingHooksPtr->doNL3SubtSave = flag("Merging:doNL3Subt");
90  mergingHooksPtr->doUNLOPSTreeSave = flag("Merging:doUNLOPSTree");
91  mergingHooksPtr->doUNLOPSLoopSave = flag("Merging:doUNLOPSLoop");
92  mergingHooksPtr->doUNLOPSSubtSave = flag("Merging:doUNLOPSSubt");
93  mergingHooksPtr->doUNLOPSSubtNLOSave = flag("Merging:doUNLOPSSubtNLO");
94  mergingHooksPtr->doUMEPSTreeSave = flag("Merging:doUMEPSTree");
95  mergingHooksPtr->doUMEPSSubtSave = flag("Merging:doUMEPSSubt");
96  mergingHooksPtr->nReclusterSave = mode("Merging:nRecluster");
97 
98  mergingHooksPtr->hasJetMaxLocal = false;
99  mergingHooksPtr->nJetMaxLocal = mergingHooksPtr->nJetMaxSave;
100  mergingHooksPtr->nJetMaxNLOLocal = mergingHooksPtr->nJetMaxNLOSave;
101  mergingHooksPtr->nRequestedSave = mode("Merging:nRequested");
102 
103  // Ensure that merging weight is not counted twice.
104  bool includeWGT = mergingHooksPtr->includeWGTinXSEC();
105 
106  // Possibility to apply merging scale to an input event.
107  bool applyTMSCut = flag("Merging:doXSectionEstimate");
108  if ( applyTMSCut && cutOnProcess(process) ) {
109  if (includeWGT) infoPtr->weightContainerPtr->setWeightNominal(0.);
110  return -1;
111  }
112  // Done if only a cut should be applied.
113  if ( applyTMSCut ) return 1;
114 
115  // Possibility to perform CKKW-L merging on this event.
116  if ( mergingHooksPtr->doCKKWLMerging() )
117  vetoCode = mergeProcessCKKWL(process);
118 
119  // Possibility to perform UMEPS merging on this event.
120  if ( mergingHooksPtr->doUMEPSMerging() )
121  vetoCode = mergeProcessUMEPS(process);
122 
123  // Possibility to perform NL3 NLO merging on this event.
124  if ( mergingHooksPtr->doNL3Merging() )
125  vetoCode = mergeProcessNL3(process);
126 
127  // Possibility to perform UNLOPS merging on this event.
128  if ( mergingHooksPtr->doUNLOPSMerging() )
129  vetoCode = mergeProcessUNLOPS(process);
130 
131  return vetoCode;
132 
133 }
134 
135 //--------------------------------------------------------------------------
136 
137 // Function to perform CKKW-L merging on this event.
138 
139 int Merging::mergeProcessCKKWL( Event& process) {
140 
141  // Ensure that merging hooks to not veto events in the trial showers.
142  mergingHooksPtr->doIgnoreStep(true);
143  // For pp > h, allow cut on state, so that underlying processes
144  // can be clustered to gg > h
145  if ( mergingHooksPtr->getProcessString().compare("pp>h") == 0 )
146  mergingHooksPtr->allowCutOnRecState(true);
147  // For now, prefer construction of ordered histories.
148  mergingHooksPtr->orderHistories(true);
149 
150  // Ensure that merging weight is not counted twice.
151  bool includeWGT = mergingHooksPtr->includeWGTinXSEC();
152 
153  // Reset weight of the event.
154  int nWgts = mergingHooksPtr->nWgts;
155  vector<double> wgt( nWgts, 1.0 );
156  mergingHooksPtr->setWeightCKKWL(wgt);
157  mergingHooksPtr->muMI(-1.);
158 
159  // Prepare process record for merging. If Pythia has already decayed
160  // resonances used to define the hard process, remove resonance decay
161  // products.
162  Event newProcess( mergingHooksPtr->bareEvent( process, true) );
163  // Reset any incoming spins for W+-.
164  if (mergingHooksPtr->doWeakClustering())
165  for (int i = 0;i < newProcess.size();++i)
166  newProcess[i].pol(9);
167  // Store candidates for the splitting V -> qqbar'.
168  mergingHooksPtr->storeHardProcessCandidates( newProcess);
169 
170  // Check if event passes the merging scale cut.
171  double tmsval = mergingHooksPtr->tms();
172  // Get merging scale in current event.
173  double tmsnow = mergingHooksPtr->tmsNow( newProcess );
174  // Calculate number of clustering steps.
175  int nSteps = mergingHooksPtr->getNumberOfClusteringSteps( newProcess, true);
176 
177  // Check if hard event cut should be applied later.
178  bool applyVeto = flag("Merging:applyVeto");
179 
180  // Too few steps can be possible if a chain of resonance decays has been
181  // removed. In this case, reject this event, since it will be handled in
182  // lower-multiplicity samples.
183  int nRequested = mergingHooksPtr->nRequested();
184 
185  // Store hard event cut information, reset veto information.
186  mergingHooksPtr->setHardProcessInfo(nSteps, tmsnow);
187  mergingHooksPtr->setEventVetoInfo(-1, -1.);
188  if (nSteps < nRequested ) {
189  if (!includeWGT) mergingHooksPtr->
190  setWeightCKKWL(vector<double>(nWgts, 0.));
191  if ( includeWGT) infoPtr->weightContainerPtr->setWeightNominal(0.);
192  if (applyVeto) return -1;
193  else return 1;
194  }
195 
196  // Reset the minimal tms value, if necessary.
197  tmsNowMin = (nSteps > 0 && tmsnow < infoPtr->eCM())
198  ? min(tmsNowMin, tmsnow) : 0.;
199 
200  // Get random number to choose a path.
201  double RN = rndmPtr->flat();
202 
203  // Set dummy process scale.
204  newProcess.scale(0.0);
205  // Generate all histories.
206  History FullHistory( nSteps, 0.0, newProcess, Clustering(), mergingHooksPtr,
207  (*beamAPtr), (*beamBPtr), particleDataPtr, infoPtr,
208  trialPartonLevelPtr, coupSMPtr, true, true, true, true, 1.0, 0);
209 
210  // Project histories onto desired branches, e.g. only ordered paths.
211  FullHistory.projectOntoDesiredHistories();
212 
213  // Setup the selected path. Needed for
214  FullHistory.select(RN)->setSelectedChild();
215 
216  // Do not apply cut if the configuration could not be projected onto an
217  // underlying born configuration.
218  bool applyCut = nSteps > 0 && FullHistory.select(RN)->nClusterings() > 0;
219 
220  // Enfore merging scale cut if the event did not pass the merging scale
221  // criterion.
222  bool enforceCutOnLHE = flag("Merging:enforceCutOnLHE");
223  if ( enforceCutOnLHE && applyCut && tmsnow < tmsval && tmsnow >= 0. ) {
224  string message="Warning in Merging::mergeProcessCKKWL: Les Houches Event";
225  message+=" fails merging scale cut. Reject event.";
226  infoPtr->errorMsg(message);
227  if (!includeWGT) mergingHooksPtr->
228  setWeightCKKWL(vector<double>(nWgts, 0.));
229  if ( includeWGT) infoPtr->weightContainerPtr->setWeightNominal(0.);
230  //return -1;
231  if (applyVeto) return -1;
232  else return 1;
233  }
234 
235  // Check if more steps should be taken.
236  int nFinalP = 0;
237  int nFinalW = 0;
238  Event coreProcess = Event();
239  coreProcess.clear();
240  coreProcess.init( "(hard process-modified)", particleDataPtr );
241  coreProcess.clear();
242  coreProcess = FullHistory.lowestMultProc(RN);
243  for ( int i = 0; i < coreProcess.size(); ++i )
244  if ( coreProcess[i].isFinal() ) {
245  if ( coreProcess[i].colType() != 0 )
246  nFinalP++;
247  if ( coreProcess[i].idAbs() == 24 )
248  nFinalW++;
249  }
250 
251  bool complete = (FullHistory.select(RN)->nClusterings() == nSteps) ||
252  ( mergingHooksPtr->doWeakClustering() && nFinalP == 2 && nFinalW == 0 );
253 
254  if ( !complete ) {
255  string message="Warning in Merging::mergeProcessCKKWL: No clusterings";
256  message+=" found. History incomplete.";
257  infoPtr->errorMsg(message);
258  }
259 
260  // Calculate CKKWL weight:
261  // Perform reweighting with Sudakov factors, save alpha_s ratios and
262  // PDF ratio weights.
263  wgt = FullHistory.weightCKKWL( trialPartonLevelPtr,
264  mergingHooksPtr->AlphaS_FSR(), mergingHooksPtr->AlphaS_ISR(),
265  mergingHooksPtr->AlphaEM_FSR(), mergingHooksPtr->AlphaEM_ISR(), RN);
266 
267  // Event with production scales set for further (trial) showering
268  // and starting conditions for the shower.
269  FullHistory.getStartingConditions( RN, process );
270  // If necessary, reattach resonance decay products.
271  mergingHooksPtr->reattachResonanceDecays(process);
272 
273  // Allow to dampen histories in which the lowest multiplicity reclustered
274  // state does not pass the lowest multiplicity cut of the matrix element.
275  double dampWeight = mergingHooksPtr->dampenIfFailCuts(
276  FullHistory.lowestMultProc(RN) );
277  // Save the weight of the event for histogramming. Only change the
278  // event weight after trial shower on the matrix element
279  // multiplicity event (= in doVetoStep).
280  for (double& wgti: wgt) wgti *= dampWeight;
281 
282  // Save the weight of the event for histogramming.
283  if (!includeWGT) mergingHooksPtr->setWeightCKKWL(wgt);
284 
285  // Update the event weight.
286  if ( includeWGT) {
287  // In this case, central merging weight goes into nominal weight, all
288  // variations are saved relative to central merging weight
289  vector<double> relWgt({1.});
290  for (int iVar = 1; iVar < nWgts; ++iVar)
291  relWgt.push_back(wgt[0] != 0 ? wgt[iVar]/wgt[0] :
292  std::numeric_limits<double>::infinity());
293  infoPtr->weightContainerPtr->
294  setWeightNominal(infoPtr->weight()*wgt[0]);
295  mergingHooksPtr->setWeightCKKWL(relWgt);
296  }
297 
298  // Allow merging hooks to veto events from now on.
299  mergingHooksPtr->doIgnoreStep(false);
300 
301  // If no-emission probability is zero.
302  if ( applyVeto && wgt[0] == 0. ) return 0;
303 
304  // Done
305  return 1;
306 
307 }
308 
309 //--------------------------------------------------------------------------
310 
311 // Function to perform UMEPS merging on this event.
312 
313 int Merging::mergeProcessUMEPS( Event& process) {
314 
315  // Initialise which part of UMEPS merging is applied.
316  bool doUMEPSTree = flag("Merging:doUMEPSTree");
317  bool doUMEPSSubt = flag("Merging:doUMEPSSubt");
318  // Save number of looping steps
319  mergingHooksPtr->nReclusterSave = mode("Merging:nRecluster");
320  int nRecluster = mode("Merging:nRecluster");
321 
322  // Ensure that merging hooks does not remove emissions.
323  mergingHooksPtr->doIgnoreEmissions(true);
324  // For pp > h, allow cut on state, so that underlying processes
325  // can be clustered to gg > h
326  if ( mergingHooksPtr->getProcessString().compare("pp>h") == 0 )
327  mergingHooksPtr->allowCutOnRecState(true);
328  // For now, prefer construction of ordered histories.
329  mergingHooksPtr->orderHistories(true);
330 
331  // Ensure that merging weight is not counted twice.
332  bool includeWGT = mergingHooksPtr->includeWGTinXSEC();
333 
334  // Reset any incoming spins for W+-.
335  if (mergingHooksPtr->doWeakClustering())
336  for (int i = 0;i < process.size();++i)
337  process[i].pol(9);
338 
339  // Reset weights of the event.
340  int nWgts = mergingHooksPtr->nWgts;
341  vector<double> wgt( nWgts, 1.);
342  mergingHooksPtr->setWeightCKKWL(wgt);
343  mergingHooksPtr->muMI(-1.);
344 
345  // Prepare process record for merging. If Pythia has already decayed
346  // resonances used to define the hard process, remove resonance decay
347  // products.
348  Event newProcess( mergingHooksPtr->bareEvent( process, true) );
349  // Store candidates for the splitting V -> qqbar'.
350  mergingHooksPtr->storeHardProcessCandidates( newProcess );
351 
352  // Check if event passes the merging scale cut.
353  double tmsval = mergingHooksPtr->tms();
354  // Get merging scale in current event.
355  double tmsnow = mergingHooksPtr->tmsNow( newProcess );
356  // Calculate number of clustering steps.
357  int nSteps = mergingHooksPtr->getNumberOfClusteringSteps( newProcess, true);
358  int nRequested = mergingHooksPtr->nRequested();
359 
360  // Check if hard event cut should be applied later.
361  bool applyVeto = flag("Merging:applyVeto");
362 
363  // Too few steps can be possible if a chain of resonance decays has been
364  // removed. In this case, reject this event, since it will be handled in
365  // lower-multiplicity samples.
366  if (nSteps < nRequested) {
367  if (!includeWGT) mergingHooksPtr->
368  setWeightCKKWL(vector<double>(nWgts, 0.));
369  if ( includeWGT) infoPtr->weightContainerPtr->setWeightNominal(0.);
370  if (applyVeto) return -1;
371  else return 1;
372  }
373 
374  // Reset the minimal tms value, if necessary.
375  tmsNowMin = (nSteps == 0) ? 0. : min(tmsNowMin, tmsnow);
376 
377  // Get random number to choose a path.
378  double RN = rndmPtr->flat();
379  // Set dummy process scale.
380  newProcess.scale(0.0);
381  // Generate all histories.
382  History FullHistory( nSteps, 0.0, newProcess, Clustering(), mergingHooksPtr,
383  (*beamAPtr), (*beamBPtr), particleDataPtr, infoPtr,
384  trialPartonLevelPtr, coupSMPtr, true, true, true, true, 1.0, 0);
385  // Project histories onto desired branches, e.g. only ordered paths.
386  FullHistory.projectOntoDesiredHistories();
387 
388  // Do not apply cut if the configuration could not be projected onto an
389  // underlying born configuration.
390  bool applyCut = nSteps > 0 && FullHistory.select(RN)->nClusterings() > 0;
391 
392  // Enfore merging scale cut if the event did not pass the merging scale
393  // criterion.
394  bool enforceCutOnLHE = flag("Merging:enforceCutOnLHE");
395  if ( enforceCutOnLHE && applyCut && tmsnow < tmsval ) {
396  string message="Warning in Merging::mergeProcessUMEPS: Les Houches Event";
397  message+=" fails merging scale cut. Reject event.";
398  infoPtr->errorMsg(message);
399  if (!includeWGT) mergingHooksPtr->setWeightCKKWL(vector<double>(nWgts,0.));
400  if ( includeWGT) infoPtr->weightContainerPtr->setWeightNominal(0.);
401  if (applyVeto) return -1;
402  else return 1;
403  }
404 
405  // Check reclustering steps to correctly apply MPI.
406  int nPerformed = 0;
407  if ( nSteps > 0 && doUMEPSSubt
408  && !FullHistory.getFirstClusteredEventAboveTMS( RN, nRecluster,
409  newProcess, nPerformed, false ) ) {
410  // Discard if the state could not be reclustered to a state above TMS.
411  if (!includeWGT) mergingHooksPtr->setWeightCKKWL(vector<double>(nWgts,0.));
412  if ( includeWGT) infoPtr->weightContainerPtr->setWeightNominal(0.);
413  if (applyVeto) return -1;
414  else return 1;
415  }
416 
417  mergingHooksPtr->nMinMPI(nSteps - nPerformed);
418 
419  // Calculate CKKWL weight:
420  // Perform reweighting with Sudakov factors, save alpha_s ratios and
421  // PDF ratio weights.
422  if ( doUMEPSTree ) {
423  wgt = FullHistory.weightUMEPSTree( trialPartonLevelPtr,
424  mergingHooksPtr->AlphaS_FSR(), mergingHooksPtr->AlphaS_ISR(),
425  mergingHooksPtr->AlphaEM_FSR(), mergingHooksPtr->AlphaEM_ISR(), RN);
426  } else {
427  wgt = FullHistory.weightUMEPSSubt( trialPartonLevelPtr,
428  mergingHooksPtr->AlphaS_FSR(), mergingHooksPtr->AlphaS_ISR(),
429  mergingHooksPtr->AlphaEM_FSR(), mergingHooksPtr->AlphaEM_ISR(), RN);
430  }
431 
432  // Event with production scales set for further (trial) showering
433  // and starting conditions for the shower.
434  if ( doUMEPSTree ) FullHistory.getStartingConditions( RN, process );
435  // Do reclustering (looping) steps.
436  else FullHistory.getFirstClusteredEventAboveTMS( RN, nRecluster, process,
437  nPerformed, true );
438 
439  // Allow to dampen histories in which the lowest multiplicity reclustered
440  // state does not pass the lowest multiplicity cut of the matrix element
441  double dampWeight = mergingHooksPtr->dampenIfFailCuts(
442  FullHistory.lowestMultProc(RN) );
443  // Save the weight of the event for histogramming. Only change the
444  // event weight after trial shower on the matrix element
445  // multiplicity event (= in doVetoStep)
446  for (double& wgti: wgt) wgti *= dampWeight;
447 
448  // Save the weight of the event for histogramming.
449  if (!includeWGT) mergingHooksPtr->setWeightCKKWL(wgt);
450 
451  // Update the event weight.
452  if ( includeWGT) {
453  // In this case, central merging weight goes into nominal weight, all
454  // variations are saved relative to central merging weight
455  vector<double> relWgt({1.});
456  for (int iVar = 1; iVar < nWgts; ++iVar)
457  relWgt.push_back(wgt[0] != 0 ? wgt[iVar]/wgt[0] :
458  std::numeric_limits<double>::infinity());
459  infoPtr->weightContainerPtr->
460  setWeightNominal(infoPtr->weight()*wgt[0]);
461  mergingHooksPtr->setWeightCKKWL(relWgt);
462  }
463 
464  // Set QCD 2->2 starting scale different from arbitrary scale in LHEF!
465  // --> Set to minimal mT of partons.
466  int nFinal = 0;
467  double muf = process[0].e();
468  for ( int i=0; i < process.size(); ++i )
469  if ( process[i].isFinal()
470  && (process[i].colType() != 0 || process[i].id() == 22 ) ) {
471  nFinal++;
472  muf = min( muf, abs(process[i].mT()) );
473  }
474 
475  // For pure QCD dijet events (only!), set the process scale to the
476  // transverse momentum of the outgoing partons.
477  // Calculate number of clustering steps.
478  int nStepsNew = mergingHooksPtr->getNumberOfClusteringSteps( process );
479  if ( nStepsNew == 0
480  && ( mergingHooksPtr->getProcessString().compare("pp>jj") == 0
481  || mergingHooksPtr->getProcessString().compare("pp>aj") == 0) )
482  process.scale(muf);
483 
484  // Reset hard process candidates (changed after clustering a parton).
485  mergingHooksPtr->storeHardProcessCandidates( process );
486  // If necessary, reattach resonance decay products.
487  mergingHooksPtr->reattachResonanceDecays(process);
488 
489  // Allow merging hooks to remove emissions from now on.
490  mergingHooksPtr->doIgnoreEmissions(false);
491 
492  // If no-emission probability is zero.
493  if ( applyVeto && wgt[0] == 0. ) return 0;
494 
495  // Done
496  return 1;
497 
498 }
499 
500 //--------------------------------------------------------------------------
501 
502 // Function to perform NL3 NLO merging on this event.
503 
504 int Merging::mergeProcessNL3( Event& process) {
505 
506  // Initialise which part of NL3 merging is applied.
507  bool doNL3Tree = flag("Merging:doNL3Tree");
508  bool doNL3Loop = flag("Merging:doNL3Loop");
509  bool doNL3Subt = flag("Merging:doNL3Subt");
510 
511  // Ensure that hooks (NL3 part) to not remove emissions.
512  mergingHooksPtr->doIgnoreEmissions(true);
513  // Ensure that hooks (CKKWL part) to not veto events in trial showers.
514  mergingHooksPtr->doIgnoreStep(true);
515  // For pp > h, allow cut on state, so that underlying processes
516  // can be clustered to gg > h
517  if ( mergingHooksPtr->getProcessString().compare("pp>h") == 0)
518  mergingHooksPtr->allowCutOnRecState(true);
519  // For now, prefer construction of ordered histories.
520  mergingHooksPtr->orderHistories(true);
521 
522  // Reset weight of the event
523  int nWgts = mergingHooksPtr->nWgts;
524  vector<double> wgt( nWgts, 1. );
525  mergingHooksPtr->setWeightCKKWL(wgt);
526  // Reset the O(alphaS)-term of the CKKW-L weight.
527  vector<double> wgtFIRST( nWgts, 0. );
528  mergingHooksPtr->setWeightFIRST(wgtFIRST);
529  mergingHooksPtr->muMI(-1.);
530 
531  // Prepare process record for merging. If Pythia has already decayed
532  // resonances used to define the hard process, remove resonance decay
533  // products.
534  Event newProcess( mergingHooksPtr->bareEvent( process, true) );
535  // Store candidates for the splitting V -> qqbar'
536  mergingHooksPtr->storeHardProcessCandidates( newProcess);
537 
538  // Check if event passes the merging scale cut.
539  double tmsval = mergingHooksPtr->tms();
540  // Get merging scale in current event.
541  double tmsnow = mergingHooksPtr->tmsNow( newProcess );
542  // Calculate number of clustering steps
543  int nSteps = mergingHooksPtr->getNumberOfClusteringSteps( newProcess, true);
544  int nRequested = mergingHooksPtr->nRequested();
545 
546  // Too few steps can be possible if a chain of resonance decays has been
547  // removed. In this case, reject this event, since it will be handled in
548  // lower-multiplicity samples.
549  if (nSteps < nRequested) {
550  mergingHooksPtr->setWeightCKKWL(vector<double>( nWgts, 0.));
551  mergingHooksPtr->setWeightFIRST(vector<double>( nWgts, 0.));
552  return -1;
553  }
554 
555  // Reset the minimal tms value, if necessary.
556  tmsNowMin = (nSteps == 0) ? 0. : min(tmsNowMin, tmsnow);
557 
558  // Enfore merging scale cut if the event did not pass the merging scale
559  // criterion.
560  bool enforceCutOnLHE = flag("Merging:enforceCutOnLHE");
561  if ( enforceCutOnLHE && nSteps > 0 && nSteps == nRequested
562  && tmsnow < tmsval ) {
563  string message="Warning in Merging::mergeProcessNL3: Les Houches Event";
564  message+=" fails merging scale cut. Reject event.";
565  infoPtr->errorMsg(message);
566  mergingHooksPtr->setWeightCKKWL(vector<double>(nWgts, 0.));
567  mergingHooksPtr->setWeightFIRST(vector<double>(nWgts, 0.));
568  return -1;
569  }
570 
571  // Get random number to choose a path.
572  double RN = rndmPtr->flat();
573  // Set dummy process scale.
574  newProcess.scale(0.0);
575  // Generate all histories
576  History FullHistory( nSteps, 0.0, newProcess, Clustering(), mergingHooksPtr,
577  (*beamAPtr), (*beamBPtr), particleDataPtr, infoPtr,
578  trialPartonLevelPtr, coupSMPtr, true, true, true, true, 1.0, 0);
579  // Project histories onto desired branches, e.g. only ordered paths.
580  FullHistory.projectOntoDesiredHistories();
581 
582  // Discard states that cannot be projected unto a state with one less jet.
583  if ( nSteps > 0 && doNL3Subt
584  && FullHistory.select(RN)->nClusterings() == 0 ){
585  mergingHooksPtr->setWeightCKKWL(vector<double>(nWgts, 0.));
586  mergingHooksPtr->setWeightFIRST(vector<double>(nWgts, 0.));
587  return -1;
588  }
589 
590  // Potentially recluster real emission jets for powheg input containing
591  // "too many" jets, i.e. real-emission kinematics.
592  bool containsRealKin = nSteps > nRequested && nSteps > 0;
593 
594  // Perform one reclustering for real emission kinematics, then apply merging
595  // scale cut on underlying Born kinematics.
596  if ( containsRealKin ) {
597  Event dummy = Event();
598  // Initialise temporary output of reclustering.
599  dummy.clear();
600  dummy.init( "(hard process-modified)", particleDataPtr );
601  dummy.clear();
602  // Recluster once.
603  if ( !FullHistory.getClusteredEvent( RN, nSteps, dummy )) {
604  mergingHooksPtr->setWeightCKKWL( vector<double>( nWgts, 0. ) );
605  mergingHooksPtr->setWeightFIRST( vector<double>( nWgts, 0. ) );
606  return -1;
607  }
608  double tnowNew = mergingHooksPtr->tmsNow( dummy );
609  // Veto if underlying Born kinematics do not pass merging scale cut.
610  if ( enforceCutOnLHE && nRequested > 0 && tnowNew < tmsval ) {
611  mergingHooksPtr->setWeightCKKWL(vector<double>( nWgts, 0. ) );
612  mergingHooksPtr->setWeightFIRST( vector<double>( nWgts, 0. ) );
613  return -1;
614  }
615  }
616 
617  // Remember number of jets, to include correct MPI no-emission probabilities.
618  if ( doNL3Subt || containsRealKin ) mergingHooksPtr->nMinMPI(nSteps - 1);
619  else mergingHooksPtr->nMinMPI(nSteps);
620 
621  // Calculate weight
622  // Do LO or first part of NLO tree-level reweighting
623  if( doNL3Tree ) {
624  // Perform reweighting with Sudakov factors, save as ratios and
625  // PDF ratio weights
626  wgt = FullHistory.weightNL3Tree( trialPartonLevelPtr,
627  mergingHooksPtr->AlphaS_FSR(), mergingHooksPtr->AlphaS_ISR(),
628  mergingHooksPtr->AlphaEM_FSR(), mergingHooksPtr->AlphaEM_ISR(), RN);
629  } else if( doNL3Loop || doNL3Subt ) {
630  // No reweighting, just set event scales properly and incorporate MPI
631  // no-emission probabilities.
632  wgt = FullHistory.weightNL3Loop( trialPartonLevelPtr, RN);
633  }
634 
635  // Event with production scales set for further (trial) showering
636  // and starting conditions for the shower
637  if ( !doNL3Subt && !containsRealKin )
638  FullHistory.getStartingConditions(RN, process);
639  // For sutraction of nSteps-additional resolved partons from
640  // the nSteps-1 parton phase space, recluster the last parton
641  // in nSteps-parton events, and sutract later
642  else {
643  // Function to return the reclustered event
644  if ( !FullHistory.getClusteredEvent( RN, nSteps, process )) {
645  mergingHooksPtr->setWeightCKKWL(vector<double> (nWgts, 0.));
646  mergingHooksPtr->setWeightFIRST(vector<double> (nWgts, 0.));
647  return -1;
648  }
649  }
650 
651  // Allow to dampen histories in which the lowest multiplicity reclustered
652  // state does not pass the lowest multiplicity cut of the matrix element
653  double dampWeight = mergingHooksPtr->dampenIfFailCuts(
654  FullHistory.lowestMultProc(RN) );
655  // Save the weight of the event for histogramming. Only change the
656  // event weight after trial shower on the matrix element
657  // multiplicity event (= in doVetoStep)
658  for (double& wgti: wgt) wgti *= dampWeight;
659 
660  // For tree level samples in NL3, rescale with k-Factor
661  if (doNL3Tree ){
662  // Find k-factor
663  double kFactor = 1.;
664  if( nSteps > mergingHooksPtr->nMaxJetsNLO() )
665  kFactor = mergingHooksPtr->kFactor( mergingHooksPtr->nMaxJetsNLO() );
666  else kFactor = mergingHooksPtr->kFactor(nSteps);
667  // For NLO merging, rescale CKKW-L weight with k-factor
668  for (double& wgti: wgt) wgti *= kFactor;
669  }
670 
671  // Save the weight of the event for histogramming
672  mergingHooksPtr->setWeightCKKWL(wgt);
673 
674  // Check if we need to subtract the O(\alpha_s)-term. If the number
675  // of additional partons is larger than the number of jets for
676  // which loop matrix elements are available, do standard CKKW-L
677  bool doOASTree = doNL3Tree && nSteps <= mergingHooksPtr->nMaxJetsNLO();
678 
679  // Now begin NLO part for tree-level events
680  if ( doOASTree ) {
681  // Calculate the O(\alpha_s)-term of the CKKWL weight
682  wgtFIRST = FullHistory.weightNL3First( trialPartonLevelPtr,
683  mergingHooksPtr->AlphaS_FSR(), mergingHooksPtr->AlphaS_ISR(),
684  mergingHooksPtr->AlphaEM_FSR(), mergingHooksPtr->AlphaEM_ISR(), RN,
685  rndmPtr );
686  // If necessary, also dampen the O(\alpha_s)-term
687  for (double& wFi: wgtFIRST) wFi *= dampWeight;
688  // Set the subtractive weight to the value calculated so far
689  mergingHooksPtr->setWeightFIRST(wgtFIRST);
690  // Subtract the O(\alpha_s)-term from the CKKW-L weight
691  // If PDF contributions have not been included, subtract these later
692  for (int iVar = 0; iVar < nWgts; ++iVar)
693  wgt[iVar] = wgt[iVar] - wgtFIRST[iVar];
694  }
695 
696  // Set qcd 2->2 starting scale different from arbirtrary scale in LHEF!
697  // --> Set to pT of partons
698  double pT = 0.;
699  for( int i=0; i < process.size(); ++i)
700  if(process[i].isFinal() && process[i].colType() != 0) {
701  pT = sqrt(pow(process[i].px(),2) + pow(process[i].py(),2));
702  break;
703  }
704  // For pure QCD dijet events (only!), set the process scale to the
705  // transverse momentum of the outgoing partons.
706  if ( nSteps == 0
707  && mergingHooksPtr->getProcessString().compare("pp>jj") == 0)
708  process.scale(pT);
709 
710  // Reset hard process candidates (changed after clustering a parton).
711  mergingHooksPtr->storeHardProcessCandidates( process );
712  // If necessary, reattach resonance decay products.
713  mergingHooksPtr->reattachResonanceDecays(process);
714 
715  // Allow merging hooks (NL3 part) to remove emissions from now on.
716  mergingHooksPtr->doIgnoreEmissions(false);
717  // Allow merging hooks (CKKWL part) to veto events from now on.
718  mergingHooksPtr->doIgnoreStep(false);
719 
720  // Done
721  return 1;
722 
723 }
724 
725 //--------------------------------------------------------------------------
726 
727 // Function to perform UNLOPS merging on this event.
728 
729 int Merging::mergeProcessUNLOPS( Event& process) {
730 
731  // Initialise which part of UNLOPS merging is applied.
732  bool nloTilde = flag("Merging:doUNLOPSTilde");
733  bool doUNLOPSTree = flag("Merging:doUNLOPSTree");
734  bool doUNLOPSLoop = flag("Merging:doUNLOPSLoop");
735  bool doUNLOPSSubt = flag("Merging:doUNLOPSSubt");
736  bool doUNLOPSSubtNLO = flag("Merging:doUNLOPSSubtNLO");
737  // Save number of looping steps
738  mergingHooksPtr->nReclusterSave = mode("Merging:nRecluster");
739  int nRecluster = mode("Merging:nRecluster");
740 
741  // Ensure that merging hooks to not remove emissions
742  mergingHooksPtr->doIgnoreEmissions(true);
743  // For now, prefer construction of ordered histories.
744  mergingHooksPtr->orderHistories(true);
745  // For pp > h, allow cut on state, so that underlying processes
746  // can be clustered to gg > h
747  if ( mergingHooksPtr->getProcessString().compare("pp>h") == 0)
748  mergingHooksPtr->allowCutOnRecState(true);
749 
750  // Reset weight of the event.
751  int nWgts = mergingHooksPtr->nWgts;
752  vector<double> wgt( nWgts, 1. );
753  mergingHooksPtr->setWeightCKKWL(wgt);
754  // Reset the O(alphaS)-term of the UMEPS weight.
755  vector<double> wgtFIRST( nWgts, 0. );
756  mergingHooksPtr->setWeightFIRST(wgtFIRST);
757  mergingHooksPtr->muMI(-1.);
758 
759  // Vectors for UNLOPS-P and UNLOPS-PC weights
760  vector<double> wgtP( nWgts, 1. );
761  vector<double> wgtPC( nWgts, 1. );
762  vector<double> wgtFIRSTP( nWgts, 0. );
763  vector<double> wgtFIRSTPC( nWgts, 0. );
764 
765  // Check if scheme variations activated, and if so, reset
766  bool doSchemeVariation = settingsPtr->flag("Merging:doSchemeVariation");
767  if (doSchemeVariation) {
768  infoPtr->weightContainerPtr->weightsMerging.weightValuesP = wgtP;
769  infoPtr->weightContainerPtr->weightsMerging.weightValuesPC = wgtPC;
770  infoPtr->weightContainerPtr->weightsMerging.weightValuesFirstP
771  = wgtFIRSTP;
772  infoPtr->weightContainerPtr->weightsMerging.weightValuesFirstPC
773  = wgtFIRSTPC;
774  }
775 
776 
777  // Prepare process record for merging. If Pythia has already decayed
778  // resonances used to define the hard process, remove resonance decay
779  // products.
780  Event newProcess( mergingHooksPtr->bareEvent( process, true) );
781  // Store candidates for the splitting V -> qqbar'
782  mergingHooksPtr->storeHardProcessCandidates( newProcess );
783 
784  // Check if event passes the merging scale cut.
785  double tmsval = mergingHooksPtr->tms();
786  // Get merging scale in current event.
787  double tmsnow = mergingHooksPtr->tmsNow( newProcess );
788  // Calculate number of clustering steps
789  int nSteps = mergingHooksPtr->getNumberOfClusteringSteps( newProcess, true);
790  int nRequested = mergingHooksPtr->nRequested();
791 
792  // Check if hard event cut should be applied later.
793  bool allowReject = flag("Merging:applyVeto");
794 
795  // Too few steps can be possible if a chain of resonance decays has been
796  // removed. In this case, reject this event, since it will be handled in
797  // lower-multiplicity samples.
798  if (nSteps < nRequested) {
799  string message="Warning in Merging::mergeProcessUNLOPS: Les Houches Event";
800  message+=" after removing decay products does not contain enough partons.";
801  infoPtr->errorMsg(message);
802  mergingHooksPtr->setWeightCKKWL(vector<double>(nWgts,0.));
803  mergingHooksPtr->setWeightFIRST(vector<double>(nWgts,0.));
804  if (doSchemeVariation) {
805  infoPtr->weightContainerPtr->weightsMerging.weightValuesP =
806  infoPtr->weightContainerPtr->weightsMerging.weightValuesPC =
807  infoPtr->weightContainerPtr->weightsMerging.weightValuesFirstP =
808  infoPtr->weightContainerPtr->weightsMerging.weightValuesFirstPC =
809  vector<double>(nWgts,0.);
810  }
811  return ((allowReject)? -1 : 1);
812  }
813 
814  // Reset the minimal tms value, if necessary.
815  tmsNowMin = (nSteps == 0) ? 0. : min(tmsNowMin, tmsnow);
816 
817  // Get random number to choose a path.
818  double RN = rndmPtr->flat();
819  // Set dummy process scale.
820  newProcess.scale(0.0);
821  // Generate all histories
822  History FullHistory( nSteps, 0.0, newProcess, Clustering(), mergingHooksPtr,
823  (*beamAPtr), (*beamBPtr), particleDataPtr, infoPtr,
824  trialPartonLevelPtr, coupSMPtr, true, true, true, true, 1.0, 0);
825  // Project histories onto desired branches, e.g. only ordered paths.
826  FullHistory.projectOntoDesiredHistories();
827 
828  // Do not apply cut if the configuration could not be projected onto an
829  // underlying born configuration.
830  bool applyCut = nSteps > 0 && FullHistory.select(RN)->nClusterings() > 0;
831 
832  // Enfore merging scale cut if the event did not pass the merging scale
833  // criterion.
834  bool enforceCutOnLHE = flag("Merging:enforceCutOnLHE");
835  if ( enforceCutOnLHE && applyCut && nSteps == nRequested
836  && tmsnow < tmsval ) {
837  string message="Warning in Merging::mergeProcessUNLOPS: Les Houches";
838  message+=" Event fails merging scale cut. Reject event.";
839  infoPtr->errorMsg(message);
840  mergingHooksPtr->setWeightCKKWL(vector<double>(nWgts,0.));
841  mergingHooksPtr->setWeightFIRST(vector<double>(nWgts,0.));
842  if (doSchemeVariation) {
843  infoPtr->weightContainerPtr->weightsMerging.weightValuesP =
844  infoPtr->weightContainerPtr->weightsMerging.weightValuesPC =
845  infoPtr->weightContainerPtr->weightsMerging.weightValuesFirstP =
846  infoPtr->weightContainerPtr->weightsMerging.weightValuesFirstPC =
847  vector<double>(nWgts,0.);
848  }
849  return ((allowReject)? -1 : 1);
850  }
851 
852  // Potentially recluster real emission jets for powheg input containing
853  // "too many" jets, i.e. real-emission kinematics.
854  bool containsRealKin = nSteps > nRequested && nSteps > 0;
855  if ( containsRealKin ) nRecluster += nSteps - nRequested;
856 
857  // Remove real emission events without underlying Born configuration from
858  // the loop sample, since such states will be taken care of by tree-level
859  // samples.
860  bool allowIncompleteReal = flag("Merging:allowIncompleteHistoriesInReal");
861  if ( doUNLOPSLoop && containsRealKin && !allowIncompleteReal
862  && FullHistory.select(RN)->nClusterings() == 0 ) {
863  mergingHooksPtr->setWeightCKKWL(vector<double>(nWgts,0.));
864  mergingHooksPtr->setWeightFIRST(vector<double>(nWgts,0.));
865  if (doSchemeVariation) {
866  infoPtr->weightContainerPtr->weightsMerging.weightValuesP =
867  infoPtr->weightContainerPtr->weightsMerging.weightValuesPC =
868  infoPtr->weightContainerPtr->weightsMerging.weightValuesFirstP =
869  infoPtr->weightContainerPtr->weightsMerging.weightValuesFirstPC =
870  vector<double>(nWgts,0.);
871  }
872  return ((allowReject)? -1 : 1);
873  }
874 
875  // Discard if the state could not be reclustered to any state above TMS.
876  int nPerformed = 0;
877  if ( nSteps > 0 && !allowIncompleteReal
878  && ( doUNLOPSSubt || doUNLOPSSubtNLO || containsRealKin )
879  && !FullHistory.getFirstClusteredEventAboveTMS( RN, nRecluster,
880  newProcess, nPerformed, false ) ) {
881  mergingHooksPtr->setWeightCKKWL(vector<double>(nWgts, 0.));
882  mergingHooksPtr->setWeightFIRST(vector<double>(nWgts, 0.));
883  if (doSchemeVariation) {
884  infoPtr->weightContainerPtr->weightsMerging.weightValuesP =
885  infoPtr->weightContainerPtr->weightsMerging.weightValuesPC =
886  infoPtr->weightContainerPtr->weightsMerging.weightValuesFirstP =
887  infoPtr->weightContainerPtr->weightsMerging.weightValuesFirstPC =
888  vector<double>(nWgts,0.);
889  }
890  return ((allowReject)? -1 : 1);
891  }
892 
893  // Check reclustering steps to correctly apply MPI.
894  mergingHooksPtr->nMinMPI(nSteps - nPerformed);
895 
896  // Perform one reclustering for real emission kinematics, then apply
897  // merging scale cut on underlying Born kinematics.
898  if ( containsRealKin ) {
899  Event dummy = Event();
900  // Initialise temporary output of reclustering.
901  dummy.clear();
902  dummy.init( "(hard process-modified)", particleDataPtr );
903  dummy.clear();
904  // Recluster once.
905  FullHistory.getClusteredEvent( RN, nSteps, dummy );
906  double tnowNew = mergingHooksPtr->tmsNow( dummy );
907  // Veto if underlying Born kinematics do not pass merging scale cut.
908  if ( enforceCutOnLHE && nRequested > 0 && tnowNew < tmsval ) {
909  string message="Warning in Merging::mergeProcessUNLOPS: Les Houches";
910  message+=" Event fails merging scale cut. Reject event.";
911  infoPtr->errorMsg(message);
912  mergingHooksPtr->setWeightCKKWL(vector<double>(nWgts,0.));
913  mergingHooksPtr->setWeightFIRST(vector<double>(nWgts,0.));
914  if (doSchemeVariation) {
915  infoPtr->weightContainerPtr->weightsMerging.weightValuesP =
916  infoPtr->weightContainerPtr->weightsMerging.weightValuesPC =
917  infoPtr->weightContainerPtr->weightsMerging.weightValuesFirstP =
918  infoPtr->weightContainerPtr->weightsMerging.weightValuesFirstPC =
919  vector<double>(nWgts,0.);
920  }
921  return ((allowReject)? -1 : 1);
922  }
923  }
924 
925  // New UNLOPS strategy based on UN2LOPS.
926  int depth = (!doSchemeVariation) ? -1 : ( (containsRealKin) ?
927  nSteps-1 : nSteps);
928 
929  // Calculate weights.
930  // Do LO or first part of NLO tree-level reweighting
931  if( doUNLOPSTree ) {
932  // Perform reweighting with Sudakov factors, save as ratios and
933  // PDF ratio weights
934  wgt = FullHistory.weightUNLOPSTree( trialPartonLevelPtr,
935  mergingHooksPtr->AlphaS_FSR(), mergingHooksPtr->AlphaS_ISR(),
936  mergingHooksPtr->AlphaEM_FSR(), mergingHooksPtr->AlphaEM_ISR(),
937  RN, depth);
938  } else if( doUNLOPSLoop ) {
939  // Set event scales properly, reweight for new UNLOPS
940  wgt = FullHistory.weightUNLOPSLoop( trialPartonLevelPtr,
941  mergingHooksPtr->AlphaS_FSR(), mergingHooksPtr->AlphaS_ISR(),
942  mergingHooksPtr->AlphaEM_FSR(), mergingHooksPtr->AlphaEM_ISR(),
943  RN, depth);
944  } else if( doUNLOPSSubtNLO ) {
945  // Set event scales properly, reweight for new UNLOPS
946  wgt = FullHistory.weightUNLOPSSubtNLO( trialPartonLevelPtr,
947  mergingHooksPtr->AlphaS_FSR(), mergingHooksPtr->AlphaS_ISR(),
948  mergingHooksPtr->AlphaEM_FSR(), mergingHooksPtr->AlphaEM_ISR(),
949  RN, depth);
950  } else if( doUNLOPSSubt ) {
951  // Perform reweighting with Sudakov factors, save as ratios and
952  // PDF ratio weights
953  wgt = FullHistory.weightUNLOPSSubt( trialPartonLevelPtr,
954  mergingHooksPtr->AlphaS_FSR(), mergingHooksPtr->AlphaS_ISR(),
955  mergingHooksPtr->AlphaEM_FSR(), mergingHooksPtr->AlphaEM_ISR(),
956  RN, depth);
957  }
958 
959  // Set weights for UNLOPS-P and UNLOPS-PC
960  if (doSchemeVariation && (doUNLOPSLoop || doUNLOPSSubtNLO)) {
961  wgtPC = wgt;
962  wgt = mergingHooksPtr->individualWeights.mpiWeightSave;
963  wgtP = mergingHooksPtr->getSudakovWeight();
964  }
965 
966  // Event with production scales set for further (trial) showering
967  // and starting conditions for the shower.
968  if (!doUNLOPSSubt && !doUNLOPSSubtNLO && !containsRealKin )
969  FullHistory.getStartingConditions(RN, process);
970  // Do reclustering (looping) steps.
971  else FullHistory.getFirstClusteredEventAboveTMS( RN, nRecluster, process,
972  nPerformed, true );
973 
974  // Allow to dampen histories in which the lowest multiplicity reclustered
975  // state does not pass the lowest multiplicity cut of the matrix element
976  double dampWeight = mergingHooksPtr->dampenIfFailCuts(
977  FullHistory.lowestMultProc(RN) );
978  // Save the weight of the event for histogramming. Only change the
979  // event weight after trial shower on the matrix element
980  // multiplicity event (= in doVetoStep)
981  for (double& wgti: wgt) wgti *= dampWeight;
982  if (doSchemeVariation && (doUNLOPSLoop || doUNLOPSSubtNLO)) {
983  for (double& wgti: wgtP) wgti *= dampWeight;
984  for (double& wgti: wgtPC) wgti *= dampWeight;
985  }
986 
987  // For tree-level or subtractive samples, rescale with k-Factor
988  if ( doUNLOPSTree || doUNLOPSSubt ){
989  // Find k-factor
990  double kFactor = 1.;
991  if ( nSteps > mergingHooksPtr->nMaxJetsNLO() )
992  kFactor = mergingHooksPtr->kFactor( mergingHooksPtr->nMaxJetsNLO() );
993  else kFactor = mergingHooksPtr->kFactor(nSteps);
994  // For NLO merging, rescale CKKW-L weight with k-factor
995  for (double& wgti: wgt) wgti *= (nRecluster == 2 && nloTilde) ?
996  1. : kFactor;
997  }
998 
999  // Save the weight of the event for histogramming
1000  mergingHooksPtr->setWeightCKKWL(wgt);
1001  if ( doSchemeVariation ) {
1002  if (doUNLOPSLoop || doUNLOPSSubtNLO) {
1003  infoPtr->weightContainerPtr->weightsMerging.weightValuesP = wgtP;
1004  infoPtr->weightContainerPtr->weightsMerging.weightValuesPC = wgtPC;
1005  } else {
1006  infoPtr->weightContainerPtr->weightsMerging.weightValuesP = wgtP = wgt;
1007  infoPtr->weightContainerPtr->weightsMerging.weightValuesPC = wgtPC = wgt;
1008  }
1009  }
1010 
1011  // Check if we need to subtract the O(\alpha_s)-term. If the number
1012  // of additional partons is larger than the number of jets for
1013  // which loop matrix elements are available, do standard UMEPS.
1014  int nMaxNLO = mergingHooksPtr->nMaxJetsNLO();
1015  bool doOASTree = doUNLOPSTree && nSteps <= nMaxNLO;
1016  bool doOASSubt = doUNLOPSSubt && nSteps <= nMaxNLO+1 && nSteps > 0;
1017 
1018  // Now begin NLO part for tree-level events
1019  if ( doOASTree || doOASSubt ) {
1020 
1021  // Decide on which order to expand to.
1022  int order = ( nSteps > 0 && nSteps <= nMaxNLO) ? 1 : -1;
1023 
1024  // Exclusive inputs:
1025  // Subtract only the O(\alpha_s^{n+0})-term from the tree-level
1026  // subtraction, if we're at the highest NLO multiplicity (nMaxNLO).
1027  if ( nloTilde && doUNLOPSSubt && nRecluster == 1
1028  && nSteps == nMaxNLO+1 ) order = 0;
1029 
1030  // Exclusive inputs:
1031  // Do not remove the O(as)-term if the number of reclusterings
1032  // exceeds the number of NLO jets, or if more clusterings have
1033  // been performed.
1034  if (nloTilde && doUNLOPSSubt && ( nSteps > nMaxNLO+1
1035  || (nSteps == nMaxNLO+1 && nPerformed != nRecluster) ))
1036  order = -1;
1037 
1038  // Calculate terms in expansion of the CKKW-L weight.
1039  wgtFIRST = FullHistory.weightUNLOPSFirst( order,
1040  trialPartonLevelPtr, mergingHooksPtr->AlphaS_FSR(),
1041  mergingHooksPtr->AlphaS_ISR(), mergingHooksPtr->AlphaEM_FSR(),
1042  mergingHooksPtr->AlphaEM_ISR(), RN, rndmPtr );
1043 
1044  // Exclusive inputs:
1045  // Subtract the O(\alpha_s^{n+1})-term from the tree-level
1046  // subtraction, not the O(\alpha_s^{n+0})-terms.
1047  if ( nloTilde && doUNLOPSSubt && nRecluster == 1
1048  && nPerformed == nRecluster && nSteps <= nMaxNLO )
1049  for (double& wFi: wgtFIRST) wFi += 1.;
1050 
1051  // If necessary, also dampen the O(\alpha_s)-term
1052  for (double& wFi: wgtFIRST) wFi *= dampWeight;
1053 
1054  // Set the subtractive weight to the value calculated so far
1055  mergingHooksPtr->setWeightFIRST(wgtFIRST);
1056  if (doSchemeVariation) {
1057  vector<double> sudFact = mergingHooksPtr->getSudakovWeight();
1058  vector<double> couplingFact = mergingHooksPtr->getCouplingWeight();
1059  for (int iWgt = 0; iWgt < nWgts; ++iWgt) {
1060  double wgtF = wgtFIRST[iWgt]*sudFact[iWgt];
1061  wgtFIRSTP[iWgt] = wgtF;
1062  wgtF *= couplingFact[iWgt];
1063  wgtFIRSTPC[iWgt] = wgtF;
1064  }
1065  infoPtr->weightContainerPtr->weightsMerging.weightValuesFirstP
1066  = wgtFIRSTP;
1067  infoPtr->weightContainerPtr->weightsMerging.weightValuesFirstPC
1068  = wgtFIRSTPC;
1069  }
1070 
1071  // Subtract the O(\alpha_s)-term from the CKKW-L weight
1072  // If PDF contributions have not been included, subtract these later
1073  // New UNLOPS based on UN2LOPS.
1074  //if (doUNLOPS2 && order > -1) wgt = -wgt*(wgtFIRST-1.);
1075  //else if (order > -1) wgt = wgt - wgtFIRST;
1076  if (order > -1) {
1077  for (int i = 0; i < nWgts; ++i) {
1078  wgt[i] = wgt[i] - wgtFIRST[i];
1079  if (doSchemeVariation) {
1080  wgtP[i] = wgtP[i] - wgtFIRSTP[i];
1081  wgtPC[i] = wgtPC[i] - wgtFIRSTPC[i];
1082  }
1083  }
1084  }
1085  }
1086  // If no first order weight needs to be subtracted, set it anyway
1087  else if (doSchemeVariation) {
1088  infoPtr->weightContainerPtr->weightsMerging.weightValuesFirstP
1089  = wgtFIRSTP;
1090  infoPtr->weightContainerPtr->weightsMerging.weightValuesFirstPC
1091  = wgtFIRSTPC;
1092  }
1093 
1094  // Set QCD 2->2 starting scale different from arbitrary scale in LHEF!
1095  // --> Set to minimal mT of partons.
1096  int nFinal = 0;
1097  double muf = process[0].e();
1098  for ( int i=0; i < process.size(); ++i )
1099  if ( process[i].isFinal()
1100  && (process[i].colType() != 0 || process[i].id() == 22 ) ) {
1101  nFinal++;
1102  muf = min( muf, abs(process[i].mT()) );
1103  }
1104  // For pure QCD dijet events (only!), set the process scale to the
1105  // transverse momentum of the outgoing partons.
1106  if ( nSteps == 0 && nFinal == 2
1107  && ( mergingHooksPtr->getProcessString().compare("pp>jj") == 0
1108  || mergingHooksPtr->getProcessString().compare("pp>aj") == 0) )
1109  process.scale(muf);
1110 
1111  // Reset hard process candidates (changed after clustering a parton).
1112  mergingHooksPtr->storeHardProcessCandidates( process );
1113 
1114  // Check if resonance structure has been changed
1115  // (e.g. because of clustering W/Z/gluino)
1116  vector <int> oldResonance;
1117  for ( int i=0; i < newProcess.size(); ++i )
1118  if ( newProcess[i].status() == 22 )
1119  oldResonance.push_back(newProcess[i].id());
1120  vector <int> newResonance;
1121  for ( int i=0; i < process.size(); ++i )
1122  if ( process[i].status() == 22 )
1123  newResonance.push_back(process[i].id());
1124  // Compare old and new resonances
1125  for ( int i=0; i < int(oldResonance.size()); ++i )
1126  for ( int j=0; j < int(newResonance.size()); ++j )
1127  if ( newResonance[j] == oldResonance[i] ) {
1128  oldResonance[i] = 99;
1129  break;
1130  }
1131  bool hasNewResonances = (newResonance.size() != oldResonance.size());
1132  for ( int i=0; i < int(oldResonance.size()); ++i )
1133  hasNewResonances = (oldResonance[i] != 99);
1134 
1135  // If necessary, reattach resonance decay products.
1136  if (!hasNewResonances) mergingHooksPtr->reattachResonanceDecays(process);
1137 
1138  // Allow merging hooks to remove emissions from now on.
1139  mergingHooksPtr->doIgnoreEmissions(false);
1140 
1141  // If no-emission probability is zero.
1142  if (allowReject) {
1143  if (!doSchemeVariation && wgt[0] == 0.) return 0;
1144  if (doSchemeVariation && wgt[0] == 0. && wgtP[0] == 0. && wgtPC[0] == 0.)
1145  return 0;
1146  }
1147 
1148  // If the resonance structure of the process has changed due to reclustering,
1149  // redo the resonance decays in Pythia::next()
1150  if (hasNewResonances) return 2;
1151 
1152  // Done
1153  return 1;
1154 
1155 }
1156 
1157 //--------------------------------------------------------------------------
1158 
1159 // Function to apply the merging scale cut on an input event.
1160 
1161 bool Merging::cutOnProcess( Event& process) {
1162 
1163  // Save number of looping steps
1164  mergingHooksPtr->nReclusterSave = mode("Merging:nRecluster");
1165 
1166  // For now, prefer construction of ordered histories.
1167  mergingHooksPtr->orderHistories(true);
1168  // For pp > h, allow cut on state, so that underlying processes
1169  // can be clustered to gg > h
1170  if ( mergingHooksPtr->getProcessString().compare("pp>h") == 0)
1171  mergingHooksPtr->allowCutOnRecState(true);
1172 
1173  // Reset any incoming spins for W+-.
1174  if (mergingHooksPtr->doWeakClustering())
1175  for (int i = 0;i < process.size();++i)
1176  process[i].pol(9);
1177 
1178  // Prepare process record for merging. If Pythia has already decayed
1179  // resonances used to define the hard process, remove resonance decay
1180  // products.
1181  Event newProcess( mergingHooksPtr->bareEvent( process, true) );
1182  // Store candidates for the splitting V -> qqbar'
1183  mergingHooksPtr->storeHardProcessCandidates( newProcess );
1184 
1185  // Check if event passes the merging scale cut.
1186  double tmsval = mergingHooksPtr->tms();
1187  // Get merging scale in current event.
1188  double tmsnow = mergingHooksPtr->tmsNow( newProcess );
1189  // Calculate number of clustering steps
1190  int nSteps = mergingHooksPtr->getNumberOfClusteringSteps( newProcess, true);
1191 
1192  // Too few steps can be possible if a chain of resonance decays has been
1193  // removed. In this case, reject this event, since it will be handled in
1194  // lower-multiplicity samples.
1195  int nRequested = mergingHooksPtr->nRequested();
1196  if (nSteps < nRequested) return true;
1197 
1198  // Reset the minimal tms value, if necessary.
1199  tmsNowMin = (nSteps == 0) ? 0. : min(tmsNowMin, tmsnow);
1200 
1201  // Potentially recluster real emission jets for powheg input containing
1202  // "too many" jets, i.e. real-emission kinematics.
1203  bool containsRealKin = nSteps > nRequested && nSteps > 0;
1204 
1205  // Get random number to choose a path.
1206  double RN = rndmPtr->flat();
1207  // Set dummy process scale.
1208  newProcess.scale(0.0);
1209  // Generate all histories
1210  History FullHistory( nSteps, 0.0, newProcess, Clustering(), mergingHooksPtr,
1211  (*beamAPtr), (*beamBPtr), particleDataPtr, infoPtr,
1212  trialPartonLevelPtr, coupSMPtr, true, true, true, true, 1.0, 0);
1213  // Project histories onto desired branches, e.g. only ordered paths.
1214  FullHistory.projectOntoDesiredHistories();
1215 
1216  // Remove real emission events without underlying Born configuration from
1217  // the loop sample, since such states will be taken care of by tree-level
1218  // samples.
1219  bool allowIncompleteReal = flag("Merging:allowIncompleteHistoriesInReal");
1220  if ( containsRealKin && !allowIncompleteReal
1221  && FullHistory.select(RN)->nClusterings() == 0 )
1222  return true;
1223 
1224  // Cut if no history passes the cut on the lowest-multiplicity state.
1225  double dampWeight = mergingHooksPtr->dampenIfFailCuts(
1226  FullHistory.lowestMultProc(RN) );
1227  if ( dampWeight == 0. ) return true;
1228 
1229  // Do not apply cut if the configuration could not be projected onto an
1230  // underlying born configuration.
1231  if ( nSteps > 0 && FullHistory.select(RN)->nClusterings() == 0 )
1232  return false;
1233 
1234  // Now enfore merging scale cut if the event did not pass the merging scale
1235  // criterion.
1236  if ( nSteps > 0 && nSteps == nRequested && tmsnow < tmsval ) {
1237  string message="Warning in Merging::cutOnProcess: Les Houches Event";
1238  message+=" fails merging scale cut. Reject event.";
1239  infoPtr->errorMsg(message);
1240  return true;
1241  }
1242 
1243  // Check if more steps should be taken.
1244  int nFinalP = 0;
1245  int nFinalW = 0;
1246  Event coreProcess = Event();
1247  coreProcess.clear();
1248  coreProcess.init( "(hard process-modified)", particleDataPtr );
1249  coreProcess.clear();
1250  coreProcess = FullHistory.lowestMultProc(RN);
1251  for ( int i = 0; i < coreProcess.size(); ++i )
1252  if ( coreProcess[i].isFinal() ) {
1253  if ( coreProcess[i].colType() != 0 )
1254  nFinalP++;
1255  if ( coreProcess[i].idAbs() == 24 )
1256  nFinalW++;
1257  }
1258 
1259  bool complete = (FullHistory.select(RN)->nClusterings() == nSteps) ||
1260  ( mergingHooksPtr->doWeakClustering() && nFinalP == 2 && nFinalW == 0 );
1261 
1262  if ( !complete ) {
1263  string message="Warning in Merging::cutOnProcess: No clusterings";
1264  message+=" found. History incomplete.";
1265  infoPtr->errorMsg(message);
1266  }
1267 
1268  // Done if no real-emission jets are present.
1269  if ( !containsRealKin ) return false;
1270 
1271  // Now cut on events that contain an additional real-emission jet.
1272  // Perform one reclustering for real emission kinematics, then apply merging
1273  // scale cut on underlying Born kinematics.
1274  Event dummy = Event();
1275  // Initialise temporary output of reclustering.
1276  dummy.clear();
1277  dummy.init( "(hard process-modified)", particleDataPtr );
1278  dummy.clear();
1279  // Recluster once.
1280  FullHistory.getClusteredEvent( RN, nSteps, dummy );
1281  double tnowNew = mergingHooksPtr->tmsNow( dummy );
1282  // Veto if underlying Born kinematics do not pass merging scale cut.
1283  if ( nRequested > 0 && tnowNew < tmsval ) {
1284  string message = "Warning in Merging::cutOnProcess: Les Houches Event";
1285  message += " fails merging scale cut. Reject event.";
1286  infoPtr->errorMsg(message);
1287  return true;
1288  }
1289 
1290  // Done if only interested in cross section estimate after cuts.
1291  return false;
1292 
1293 }
1294 
1295 //==========================================================================
1296 
1297 } // end namespace Pythia8
Definition: AgUStep.h:26