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) 2014 Torbjorn Sjostrand.
3 // PYTHIA is licenced under the GNU GPL version 2, 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( Settings* settingsPtrIn, Info* infoPtrIn,
28  ParticleData* particleDataPtrIn, Rndm* rndmPtrIn,
29  BeamParticle* beamAPtrIn, BeamParticle* beamBPtrIn,
30  MergingHooks* mergingHooksPtrIn, PartonLevel* trialPartonLevelPtrIn ){
31 
32  // Save pointers.
33  settingsPtr = settingsPtrIn;
34  infoPtr = infoPtrIn;
35  particleDataPtr = particleDataPtrIn;
36  rndmPtr = rndmPtrIn;
37  mergingHooksPtr = mergingHooksPtrIn;
38  trialPartonLevelPtr = trialPartonLevelPtrIn;
39  beamAPtr = beamAPtrIn;
40  beamBPtr = beamBPtrIn;
41  // Reset minimal tms value.
42  tmsNowMin = infoPtr->eCM();
43 
44 }
45 
46 //--------------------------------------------------------------------------
47 
48 // Function to print information.
49 void Merging::statistics( ostream& os ) {
50 
51  // Recall switch to enfore merging scale cut.
52  bool enforceCutOnLHE = settingsPtr->flag("Merging:enforceCutOnLHE");
53  // Recall merging scale value.
54  double tmsval = mergingHooksPtr->tms();
55  bool printBanner = enforceCutOnLHE && tmsNowMin > TMSMISMATCH*tmsval;
56  // Reset minimal tms value.
57  tmsNowMin = infoPtr->eCM();
58 
59  if (!printBanner) return;
60 
61  // Header.
62  os << "\n *------- PYTHIA Matrix Element Merging Information ------"
63  << "-------------------------------------------------------*\n"
64  << " | "
65  << " |\n";
66  // Print warning if the minimal tms value of any event was significantly
67  // above the desired merging scale value.
68  os << " | Warning in Merging::statistics: All Les Houches events"
69  << " significantly above Merging:TMS cut. Please check. |\n";
70 
71  // Listing finished.
72  os << " | "
73  << " |\n"
74  << " *------- End PYTHIA Matrix Element Merging Information -----"
75  << "-----------------------------------------------------*" << endl;
76 }
77 
78 //--------------------------------------------------------------------------
79 
80 // Function to steer different merging prescriptions.
81 
82 int Merging::mergeProcess(Event& process){
83 
84  int vetoCode = 1;
85 
86  // Reinitialise hard process.
87  mergingHooksPtr->hardProcess.clear();
88  mergingHooksPtr->processSave = settingsPtr->word("Merging:Process");
89  mergingHooksPtr->hardProcess.initOnProcess(
90  settingsPtr->word("Merging:Process"), particleDataPtr);
91 
92  // Possibility to apply merging scale to an input event.
93  bool applyTMSCut = settingsPtr->flag("Merging:doXSectionEstimate");
94  if ( applyTMSCut && cutOnProcess(process) ) return -1;
95  // Done if only a cut should be applied.
96  if ( applyTMSCut ) return 1;
97 
98  // Possibility to perform CKKW-L merging on this event.
99  if ( mergingHooksPtr->doCKKWLMerging() )
100  vetoCode = mergeProcessCKKWL(process);
101 
102  // Possibility to perform UMEPS merging on this event.
103  if ( mergingHooksPtr->doUMEPSMerging() )
104  vetoCode = mergeProcessUMEPS(process);
105 
106  // Possibility to perform NL3 NLO merging on this event.
107  if ( mergingHooksPtr->doNL3Merging() )
108  vetoCode = mergeProcessNL3(process);
109 
110  // Possibility to perform UNLOPS merging on this event.
111  if ( mergingHooksPtr->doUNLOPSMerging() )
112  vetoCode = mergeProcessUNLOPS(process);
113 
114  return vetoCode;
115 
116 }
117 
118 //--------------------------------------------------------------------------
119 
120 // Function to perform CKKW-L merging on this event.
121 
122 int Merging::mergeProcessCKKWL( Event& process) {
123 
124  // Ensure that merging hooks to not veto events in the trial showers.
125  mergingHooksPtr->doIgnoreStep(true);
126  // For pp > h, allow cut on state, so that underlying processes
127  // can be clustered to gg > h
128  if ( mergingHooksPtr->getProcessString().compare("pp>h") == 0 )
129  mergingHooksPtr->allowCutOnRecState(true);
130  // For now, prefer construction of ordered histories.
131  mergingHooksPtr->orderHistories(true);
132 
133  // Reset weight of the event.
134  double wgt = 1.0;
135  mergingHooksPtr->setWeightCKKWL(1.);
136  mergingHooksPtr->muMI(-1.);
137 
138  // Prepare process record for merging. If Pythia has already decayed
139  // resonances used to define the hard process, remove resonance decay
140  // products.
141  Event newProcess( mergingHooksPtr->bareEvent( process, true) );
142  // Store candidates for the splitting V -> qqbar'.
143  mergingHooksPtr->storeHardProcessCandidates( newProcess);
144 
145  // Check if event passes the merging scale cut.
146  double tmsval = mergingHooksPtr->tms();
147  // Get merging scale in current event.
148  double tmsnow = mergingHooksPtr->tmsNow( newProcess );
149  // Calculate number of clustering steps.
150  int nSteps = mergingHooksPtr->getNumberOfClusteringSteps( newProcess);
151 
152  // Too few steps can be possible if a chain of resonance decays has been
153  // removed. In this case, reject this event, since it will be handled in
154  // lower-multiplicity samples.
155  int nRequested = settingsPtr->mode("Merging:nRequested");
156  if (nSteps < nRequested) {
157  mergingHooksPtr->setWeightCKKWL(0.);
158  return -1;
159  }
160 
161  // Reset the minimal tms value, if necessary.
162  tmsNowMin = (nSteps == 0) ? 0. : min(tmsNowMin, tmsnow);
163 
164  // Get random number to choose a path.
165  double RN = rndmPtr->flat();
166  // Set dummy process scale.
167  newProcess.scale(0.0);
168  // Generate all histories.
169  History FullHistory( nSteps, 0.0, newProcess, Clustering(), mergingHooksPtr,
170  (*beamAPtr), (*beamBPtr), particleDataPtr, infoPtr, true, true,
171  true, true, 1.0, 0);
172  // Project histories onto desired branches, e.g. only ordered paths.
173  FullHistory.projectOntoDesiredHistories();
174 
175  // Do not apply cut if the configuration could not be projected onto an
176  // underlying born configuration.
177  bool applyCut = nSteps > 0 && FullHistory.select(RN)->nClusterings() > 0;
178 
179  // Enfore merging scale cut if the event did not pass the merging scale
180  // criterion.
181  bool enforceCutOnLHE = settingsPtr->flag("Merging:enforceCutOnLHE");
182  if ( enforceCutOnLHE && applyCut && tmsnow < tmsval ) {
183  string message="Warning in Merging::mergeProcessCKKWL: Les Houches Event";
184  message+=" fails merging scale cut. Reject event.";
185  infoPtr->errorMsg(message);
186  mergingHooksPtr->setWeightCKKWL(0.);
187  return -1;
188  }
189 
190  if ( FullHistory.select(RN)->nClusterings() < nSteps) {
191  string message="Warning in Merging::mergeProcessCKKWL: No clusterings";
192  message+=" found. History incomplete.";
193  infoPtr->errorMsg(message);
194  }
195 
196  // Calculate CKKWL weight:
197  // Perform reweighting with Sudakov factors, save alpha_s ratios and
198  // PDF ratio weights.
199  wgt = FullHistory.weightTREE( trialPartonLevelPtr,
200  mergingHooksPtr->AlphaS_FSR(), mergingHooksPtr->AlphaS_ISR(), RN);
201 
202  // Event with production scales set for further (trial) showering
203  // and starting conditions for the shower.
204  FullHistory.getStartingConditions( RN, process );
205  // If necessary, reattach resonance decay products.
206  mergingHooksPtr->reattachResonanceDecays(process);
207 
208  // Allow to dampen histories in which the lowest multiplicity reclustered
209  // state does not pass the lowest multiplicity cut of the matrix element.
210  double dampWeight = mergingHooksPtr->dampenIfFailCuts(
211  FullHistory.lowestMultProc(RN) );
212  // Save the weight of the event for histogramming. Only change the
213  // event weight after trial shower on the matrix element
214  // multiplicity event (= in doVetoStep).
215  wgt *= dampWeight;
216 
217  // Set QCD 2->2 starting scale different from arbitrary scale in LHEF!
218  // --> Set to minimal mT of partons.
219  int nFinal = 0;
220  double muf = process[0].e();
221  for ( int i=0; i < process.size(); ++i )
222  if ( process[i].isFinal()
223  && (process[i].colType() != 0 || process[i].id() == 22 ) ) {
224  nFinal++;
225  muf = min( muf, abs(process[i].mT()) );
226  }
227  // For pure QCD dijet events (only!), set the process scale to the
228  // transverse momentum of the outgoing partons.
229  if ( nSteps == 0 && nFinal == 2
230  && ( mergingHooksPtr->getProcessString().compare("pp>jj") == 0
231  || mergingHooksPtr->getProcessString().compare("pp>aj") == 0) )
232  process.scale(muf);
233 
234  // Save the weight of the event for histogramming.
235  mergingHooksPtr->setWeightCKKWL(wgt);
236 
237  // Allow merging hooks to veto events from now on.
238  mergingHooksPtr->doIgnoreStep(false);
239 
240  // If no-emission probability is zero.
241  if ( wgt == 0. ) return 0;
242 
243  // Done
244  return 1;
245 
246 }
247 
248 //--------------------------------------------------------------------------
249 
250 // Function to perform UMEPS merging on this event.
251 
252 int Merging::mergeProcessUMEPS( Event& process) {
253 
254  // Initialise which part of UMEPS merging is applied.
255  bool doUMEPSTree = settingsPtr->flag("Merging:doUMEPSTree");
256  bool doUMEPSSubt = settingsPtr->flag("Merging:doUMEPSSubt");
257  // Save number of looping steps
258  mergingHooksPtr->nReclusterSave = settingsPtr->mode("Merging:nRecluster");
259  int nRecluster = settingsPtr->mode("Merging:nRecluster");
260 
261  // Ensure that merging hooks does not remove emissions.
262  mergingHooksPtr->doIgnoreEmissions(true);
263  // For pp > h, allow cut on state, so that underlying processes
264  // can be clustered to gg > h
265  if ( mergingHooksPtr->getProcessString().compare("pp>h") == 0 )
266  mergingHooksPtr->allowCutOnRecState(true);
267  // For now, prefer construction of ordered histories.
268  mergingHooksPtr->orderHistories(true);
269 
270  // Reset weights of the event.
271  double wgt = 1.;
272  mergingHooksPtr->setWeightCKKWL(1.);
273  mergingHooksPtr->muMI(-1.);
274 
275  // Prepare process record for merging. If Pythia has already decayed
276  // resonances used to define the hard process, remove resonance decay
277  // products.
278  Event newProcess( mergingHooksPtr->bareEvent( process, true) );
279  // Store candidates for the splitting V -> qqbar'.
280  mergingHooksPtr->storeHardProcessCandidates( newProcess );
281 
282  // Check if event passes the merging scale cut.
283  double tmsval = mergingHooksPtr->tms();
284  // Get merging scale in current event.
285  double tmsnow = mergingHooksPtr->tmsNow( newProcess );
286  // Calculate number of clustering steps.
287  int nSteps = mergingHooksPtr->getNumberOfClusteringSteps( newProcess );
288 
289  // Too few steps can be possible if a chain of resonance decays has been
290  // removed. In this case, reject this event, since it will be handled in
291  // lower-multiplicity samples.
292  int nRequested = settingsPtr->mode("Merging:nRequested");
293  if (nSteps < nRequested) {
294  mergingHooksPtr->setWeightCKKWL(0.);
295  return -1;
296  }
297 
298  // Reset the minimal tms value, if necessary.
299  tmsNowMin = (nSteps == 0) ? 0. : min(tmsNowMin, tmsnow);
300 
301  // Get random number to choose a path.
302  double RN = rndmPtr->flat();
303  // Set dummy process scale.
304  newProcess.scale(0.0);
305  // Generate all histories.
306  History FullHistory( nSteps, 0.0, newProcess, Clustering(), mergingHooksPtr,
307  (*beamAPtr), (*beamBPtr), particleDataPtr, infoPtr, true, true,
308  true, true, 1.0, 0);
309  // Project histories onto desired branches, e.g. only ordered paths.
310  FullHistory.projectOntoDesiredHistories();
311 
312  // Do not apply cut if the configuration could not be projected onto an
313  // underlying born configuration.
314  bool applyCut = nSteps > 0 && FullHistory.select(RN)->nClusterings() > 0;
315 
316  // Enfore merging scale cut if the event did not pass the merging scale
317  // criterion.
318  bool enforceCutOnLHE = settingsPtr->flag("Merging:enforceCutOnLHE");
319  if ( enforceCutOnLHE && applyCut && tmsnow < tmsval ) {
320  string message="Warning in Merging::mergeProcessUMEPS: Les Houches Event";
321  message+=" fails merging scale cut. Reject event.";
322  infoPtr->errorMsg(message);
323  mergingHooksPtr->setWeightCKKWL(0.);
324  return -1;
325  }
326 
327  // Check reclustering steps to correctly apply MPI.
328  int nPerformed = 0;
329  if ( nSteps > 0 && doUMEPSSubt
330  && !FullHistory.getFirstClusteredEventAboveTMS( RN, nRecluster,
331  newProcess, nPerformed, false ) ) {
332  // Discard if the state could not be reclustered to a state above TMS.
333  mergingHooksPtr->setWeightCKKWL(0.);
334  return -1;
335  }
336 
337  mergingHooksPtr->nMinMPI(nSteps - nPerformed);
338 
339  // Calculate CKKWL weight:
340  // Perform reweighting with Sudakov factors, save alpha_s ratios and
341  // PDF ratio weights.
342  if ( doUMEPSTree ) {
343  wgt = FullHistory.weight_UMEPS_TREE( trialPartonLevelPtr,
344  mergingHooksPtr->AlphaS_FSR(), mergingHooksPtr->AlphaS_ISR(), RN );
345  } else {
346  wgt = FullHistory.weight_UMEPS_SUBT( trialPartonLevelPtr,
347  mergingHooksPtr->AlphaS_FSR(), mergingHooksPtr->AlphaS_ISR(), RN );
348  }
349 
350  // Event with production scales set for further (trial) showering
351  // and starting conditions for the shower.
352  if ( doUMEPSTree ) FullHistory.getStartingConditions( RN, process );
353  // Do reclustering (looping) steps.
354  else FullHistory.getFirstClusteredEventAboveTMS( RN, nRecluster, process,
355  nPerformed, true );
356 
357  // Allow to dampen histories in which the lowest multiplicity reclustered
358  // state does not pass the lowest multiplicity cut of the matrix element
359  double dampWeight = mergingHooksPtr->dampenIfFailCuts(
360  FullHistory.lowestMultProc(RN) );
361  // Save the weight of the event for histogramming. Only change the
362  // event weight after trial shower on the matrix element
363  // multiplicity event (= in doVetoStep)
364  wgt *= dampWeight;
365 
366  // Save the weight of the event for histogramming.
367  mergingHooksPtr->setWeightCKKWL(wgt);
368 
369  // Set QCD 2->2 starting scale different from arbitrary scale in LHEF!
370  // --> Set to minimal mT of partons.
371  int nFinal = 0;
372  double muf = process[0].e();
373  for ( int i=0; i < process.size(); ++i )
374  if ( process[i].isFinal()
375  && (process[i].colType() != 0 || process[i].id() == 22 ) ) {
376  nFinal++;
377  muf = min( muf, abs(process[i].mT()) );
378  }
379 
380  // For pure QCD dijet events (only!), set the process scale to the
381  // transverse momentum of the outgoing partons.
382  // Calculate number of clustering steps.
383  int nStepsNew = mergingHooksPtr->getNumberOfClusteringSteps( process );
384  if ( nStepsNew == 0
385  && ( mergingHooksPtr->getProcessString().compare("pp>jj") == 0
386  || mergingHooksPtr->getProcessString().compare("pp>aj") == 0) )
387  process.scale(muf);
388 
389  // Reset hard process candidates (changed after clustering a parton).
390  mergingHooksPtr->storeHardProcessCandidates( process );
391  // If necessary, reattach resonance decay products.
392  mergingHooksPtr->reattachResonanceDecays(process);
393 
394  // Allow merging hooks to remove emissions from now on.
395  mergingHooksPtr->doIgnoreEmissions(false);
396 
397  // If no-emission probability is zero.
398  if ( wgt == 0. ) return 0;
399 
400  // Done
401  return 1;
402 
403 }
404 
405 //--------------------------------------------------------------------------
406 
407 // Function to perform NL3 NLO merging on this event.
408 
409 int Merging::mergeProcessNL3( Event& process) {
410 
411  // Initialise which part of NL3 merging is applied.
412  bool doNL3Tree = settingsPtr->flag("Merging:doNL3Tree");
413  bool doNL3Loop = settingsPtr->flag("Merging:doNL3Loop");
414  bool doNL3Subt = settingsPtr->flag("Merging:doNL3Subt");
415  // Save number of looping steps.
416  int nRequested = settingsPtr->mode("Merging:nRequested");
417 
418  // Ensure that hooks (NL3 part) to not remove emissions.
419  mergingHooksPtr->doIgnoreEmissions(true);
420  // Ensure that hooks (CKKWL part) to not veto events in trial showers.
421  mergingHooksPtr->doIgnoreStep(true);
422  // For pp > h, allow cut on state, so that underlying processes
423  // can be clustered to gg > h
424  if ( mergingHooksPtr->getProcessString().compare("pp>h") == 0)
425  mergingHooksPtr->allowCutOnRecState(true);
426  // For now, prefer construction of ordered histories.
427  mergingHooksPtr->orderHistories(true);
428 
429  // Reset weight of the event
430  double wgt = 1.;
431  mergingHooksPtr->setWeightCKKWL(1.);
432  // Reset the O(alphaS)-term of the CKKW-L weight.
433  double wgtFIRST = 0.;
434  mergingHooksPtr->setWeightFIRST(0.);
435  mergingHooksPtr->muMI(-1.);
436 
437  // Prepare process record for merging. If Pythia has already decayed
438  // resonances used to define the hard process, remove resonance decay
439  // products.
440  Event newProcess( mergingHooksPtr->bareEvent( process, true) );
441  // Store candidates for the splitting V -> qqbar'
442  mergingHooksPtr->storeHardProcessCandidates( newProcess);
443 
444  // Check if event passes the merging scale cut.
445  double tmsval = mergingHooksPtr->tms();
446  // Get merging scale in current event.
447  double tmsnow = mergingHooksPtr->tmsNow( newProcess );
448  // Calculate number of clustering steps
449  int nSteps = mergingHooksPtr->getNumberOfClusteringSteps( newProcess);
450 
451  // Too few steps can be possible if a chain of resonance decays has been
452  // removed. In this case, reject this event, since it will be handled in
453  // lower-multiplicity samples.
454  if (nSteps < nRequested) {
455  mergingHooksPtr->setWeightCKKWL(0.);
456  mergingHooksPtr->setWeightFIRST(0.);
457  return -1;
458  }
459 
460  // Reset the minimal tms value, if necessary.
461  tmsNowMin = (nSteps == 0) ? 0. : min(tmsNowMin, tmsnow);
462 
463  // Enfore merging scale cut if the event did not pass the merging scale
464  // criterion.
465  bool enforceCutOnLHE = settingsPtr->flag("Merging:enforceCutOnLHE");
466  if ( enforceCutOnLHE && nSteps > 0 && nSteps == nRequested
467  && tmsnow < tmsval ) {
468  string message="Warning in Merging::mergeProcessNL3: Les Houches Event";
469  message+=" fails merging scale cut. Reject event.";
470  infoPtr->errorMsg(message);
471  mergingHooksPtr->setWeightCKKWL(0.);
472  mergingHooksPtr->setWeightFIRST(0.);
473  return -1;
474  }
475 
476  // Get random number to choose a path.
477  double RN = rndmPtr->flat();
478  // Set dummy process scale.
479  newProcess.scale(0.0);
480  // Generate all histories
481  History FullHistory( nSteps, 0.0, newProcess, Clustering(), mergingHooksPtr,
482  (*beamAPtr), (*beamBPtr), particleDataPtr, infoPtr, true, true,
483  true, true, 1.0, 0);
484  // Project histories onto desired branches, e.g. only ordered paths.
485  FullHistory.projectOntoDesiredHistories();
486 
487  // Discard states that cannot be projected unto a state with one less jet.
488  if ( nSteps > 0 && doNL3Subt
489  && FullHistory.select(RN)->nClusterings() == 0 ){
490  mergingHooksPtr->setWeightCKKWL(0.);
491  mergingHooksPtr->setWeightFIRST(0.);
492  return -1;
493  }
494 
495  // Potentially recluster real emission jets for powheg input containing
496  // "too many" jets, i.e. real-emission kinematics.
497  bool containsRealKin = nSteps > nRequested && nSteps > 0;
498 
499  // Perform one reclustering for real emission kinematics, then apply merging
500  // scale cut on underlying Born kinematics.
501  if ( containsRealKin ) {
502  Event dummy = Event();
503  // Initialise temporary output of reclustering.
504  dummy.clear();
505  dummy.init( "(hard process-modified)", particleDataPtr );
506  dummy.clear();
507  // Recluster once.
508  if ( !FullHistory.getClusteredEvent( RN, nSteps, dummy )) {
509  mergingHooksPtr->setWeightCKKWL(0.);
510  mergingHooksPtr->setWeightFIRST(0.);
511  return -1;
512  }
513  double tnowNew = mergingHooksPtr->tmsNow( dummy );
514  // Veto if underlying Born kinematics do not pass merging scale cut.
515  if ( enforceCutOnLHE && nSteps > 0 && nRequested > 0
516  && tnowNew < tmsval ) {
517  mergingHooksPtr->setWeightCKKWL(0.);
518  mergingHooksPtr->setWeightFIRST(0.);
519  return -1;
520  }
521  }
522 
523  // Remember number of jets, to include correct MPI no-emission probabilities.
524  if ( doNL3Subt || containsRealKin ) mergingHooksPtr->nMinMPI(nSteps - 1);
525  else mergingHooksPtr->nMinMPI(nSteps);
526 
527  // Calculate weight
528  // Do LO or first part of NLO tree-level reweighting
529  if( doNL3Tree ) {
530  // Perform reweighting with Sudakov factors, save as ratios and
531  // PDF ratio weights
532  wgt = FullHistory.weightTREE( trialPartonLevelPtr,
533  mergingHooksPtr->AlphaS_FSR(), mergingHooksPtr->AlphaS_ISR(), RN);
534  } else if( doNL3Loop || doNL3Subt ) {
535  // No reweighting, just set event scales properly and incorporate MPI
536  // no-emission probabilities.
537  wgt = FullHistory.weightLOOP( trialPartonLevelPtr, RN);
538  }
539 
540  // Event with production scales set for further (trial) showering
541  // and starting conditions for the shower
542  if ( !doNL3Subt && !containsRealKin )
543  FullHistory.getStartingConditions(RN, process);
544  // For sutraction of nSteps-additional resolved partons from
545  // the nSteps-1 parton phase space, recluster the last parton
546  // in nSteps-parton events, and sutract later
547  else {
548  // Function to return the reclustered event
549  if ( !FullHistory.getClusteredEvent( RN, nSteps, process )) {
550  mergingHooksPtr->setWeightCKKWL(0.);
551  mergingHooksPtr->setWeightFIRST(0.);
552  return -1;
553  }
554  }
555 
556  // Allow to dampen histories in which the lowest multiplicity reclustered
557  // state does not pass the lowest multiplicity cut of the matrix element
558  double dampWeight = mergingHooksPtr->dampenIfFailCuts(
559  FullHistory.lowestMultProc(RN) );
560  // Save the weight of the event for histogramming. Only change the
561  // event weight after trial shower on the matrix element
562  // multiplicity event (= in doVetoStep)
563  wgt *= dampWeight;
564 
565  // For tree level samples in NL3, rescale with k-Factor
566  if (doNL3Tree ){
567  // Find k-factor
568  double kFactor = 1.;
569  if( nSteps > mergingHooksPtr->nMaxJetsNLO() )
570  kFactor = mergingHooksPtr->kFactor( mergingHooksPtr->nMaxJetsNLO() );
571  else kFactor = mergingHooksPtr->kFactor(nSteps);
572  // For NLO merging, rescale CKKW-L weight with k-factor
573  wgt *= kFactor;
574  }
575 
576  // Save the weight of the event for histogramming
577  mergingHooksPtr->setWeightCKKWL(wgt);
578 
579  // Check if we need to subtract the O(\alpha_s)-term. If the number
580  // of additional partons is larger than the number of jets for
581  // which loop matrix elements are available, do standard CKKW-L
582  bool doOASTree = doNL3Tree && nSteps <= mergingHooksPtr->nMaxJetsNLO();
583 
584  // Now begin NLO part for tree-level events
585  if ( doOASTree ) {
586  // Calculate the O(\alpha_s)-term of the CKKWL weight
587  wgtFIRST = FullHistory.weightFIRST( trialPartonLevelPtr,
588  mergingHooksPtr->AlphaS_FSR(), mergingHooksPtr->AlphaS_ISR(), RN,
589  rndmPtr );
590  // If necessary, also dampen the O(\alpha_s)-term
591  wgtFIRST *= dampWeight;
592  // Set the subtractive weight to the value calculated so far
593  mergingHooksPtr->setWeightFIRST(wgtFIRST);
594  // Subtract the O(\alpha_s)-term from the CKKW-L weight
595  // If PDF contributions have not been included, subtract these later
596  wgt = wgt - wgtFIRST;
597  }
598 
599  // Set qcd 2->2 starting scale different from arbirtrary scale in LHEF!
600  // --> Set to pT of partons
601  double pT = 0.;
602  for( int i=0; i < process.size(); ++i)
603  if(process[i].isFinal() && process[i].colType() != 0) {
604  pT = sqrt(pow(process[i].px(),2) + pow(process[i].py(),2));
605  break;
606  }
607  // For pure QCD dijet events (only!), set the process scale to the
608  // transverse momentum of the outgoing partons.
609  if ( nSteps == 0
610  && mergingHooksPtr->getProcessString().compare("pp>jj") == 0)
611  process.scale(pT);
612 
613  // Reset hard process candidates (changed after clustering a parton).
614  mergingHooksPtr->storeHardProcessCandidates( process );
615  // If necessary, reattach resonance decay products.
616  mergingHooksPtr->reattachResonanceDecays(process);
617 
618  // Allow merging hooks (NL3 part) to remove emissions from now on.
619  mergingHooksPtr->doIgnoreEmissions(false);
620  // Allow merging hooks (CKKWL part) to veto events from now on.
621  mergingHooksPtr->doIgnoreStep(false);
622 
623  // Done
624  return 1;
625 
626 }
627 
628 //--------------------------------------------------------------------------
629 
630 // Function to perform UNLOPS merging on this event.
631 
632 int Merging::mergeProcessUNLOPS( Event& process) {
633 
634  // Initialise which part of UNLOPS merging is applied.
635  bool nloTilde = settingsPtr->flag("Merging:doUNLOPSTilde");
636  bool doUNLOPSTree = settingsPtr->flag("Merging:doUNLOPSTree");
637  bool doUNLOPSLoop = settingsPtr->flag("Merging:doUNLOPSLoop");
638  bool doUNLOPSSubt = settingsPtr->flag("Merging:doUNLOPSSubt");
639  bool doUNLOPSSubtNLO = settingsPtr->flag("Merging:doUNLOPSSubtNLO");
640  // Save number of looping steps
641  mergingHooksPtr->nReclusterSave = settingsPtr->mode("Merging:nRecluster");
642  int nRecluster = settingsPtr->mode("Merging:nRecluster");
643  int nRequested = settingsPtr->mode("Merging:nRequested");
644 
645  // Ensure that merging hooks to not remove emissions
646  mergingHooksPtr->doIgnoreEmissions(true);
647  // For now, prefer construction of ordered histories.
648  mergingHooksPtr->orderHistories(true);
649  // For pp > h, allow cut on state, so that underlying processes
650  // can be clustered to gg > h
651  if ( mergingHooksPtr->getProcessString().compare("pp>h") == 0)
652  mergingHooksPtr->allowCutOnRecState(true);
653 
654  // Reset weight of the event.
655  double wgt = 1.;
656  mergingHooksPtr->setWeightCKKWL(1.);
657  // Reset the O(alphaS)-term of the UMEPS weight.
658  double wgtFIRST = 0.;
659  mergingHooksPtr->setWeightFIRST(0.);
660  mergingHooksPtr->muMI(-1.);
661 
662  // Prepare process record for merging. If Pythia has already decayed
663  // resonances used to define the hard process, remove resonance decay
664  // products.
665  Event newProcess( mergingHooksPtr->bareEvent( process, true) );
666  // Store candidates for the splitting V -> qqbar'
667  mergingHooksPtr->storeHardProcessCandidates( newProcess );
668 
669  // Check if event passes the merging scale cut.
670  double tmsval = mergingHooksPtr->tms();
671  // Get merging scale in current event.
672  double tmsnow = mergingHooksPtr->tmsNow( newProcess );
673  // Calculate number of clustering steps
674  int nSteps = mergingHooksPtr->getNumberOfClusteringSteps( newProcess);
675 
676  // Too few steps can be possible if a chain of resonance decays has been
677  // removed. In this case, reject this event, since it will be handled in
678  // lower-multiplicity samples.
679  if (nSteps < nRequested) {
680  mergingHooksPtr->setWeightCKKWL(0.);
681  mergingHooksPtr->setWeightFIRST(0.);
682  return -1;
683  }
684 
685  // Reset the minimal tms value, if necessary.
686  tmsNowMin = (nSteps == 0) ? 0. : min(tmsNowMin, tmsnow);
687 
688  // Get random number to choose a path.
689  double RN = rndmPtr->flat();
690  // Set dummy process scale.
691  newProcess.scale(0.0);
692  // Generate all histories
693  History FullHistory( nSteps, 0.0, newProcess, Clustering(), mergingHooksPtr,
694  (*beamAPtr), (*beamBPtr), particleDataPtr, infoPtr, true, true,
695  true, true, 1.0, 0);
696  // Project histories onto desired branches, e.g. only ordered paths.
697  FullHistory.projectOntoDesiredHistories();
698 
699  // Do not apply cut if the configuration could not be projected onto an
700  // underlying born configuration.
701  bool applyCut = nSteps > 0 && FullHistory.select(RN)->nClusterings() > 0;
702 
703  // Enfore merging scale cut if the event did not pass the merging scale
704  // criterion.
705  bool enforceCutOnLHE = settingsPtr->flag("Merging:enforceCutOnLHE");
706  if ( enforceCutOnLHE && applyCut && nSteps == nRequested
707  && tmsnow < tmsval ) {
708  string message="Warning in Merging::mergeProcessUNLOPS: Les Houches Event";
709  message+=" fails merging scale cut. Reject event.";
710  infoPtr->errorMsg(message);
711  mergingHooksPtr->setWeightCKKWL(0.);
712  mergingHooksPtr->setWeightFIRST(0.);
713  return -1;
714  }
715 
716  // Potentially recluster real emission jets for powheg input containing
717  // "too many" jets, i.e. real-emission kinematics.
718  bool containsRealKin = nSteps > nRequested && nSteps > 0;
719  if ( containsRealKin ) nRecluster += nSteps - nRequested;
720 
721  // Remove real emission events without underlying Born configuration from
722  // the loop sample, since such states will be taken care of by tree-level
723  // samples.
724  bool allowIncompleteReal =
725  settingsPtr->flag("Merging:allowIncompleteHistoriesInReal");
726  if ( doUNLOPSLoop && containsRealKin && !allowIncompleteReal
727  && FullHistory.select(RN)->nClusterings() == 0 ) {
728  mergingHooksPtr->setWeightCKKWL(0.);
729  mergingHooksPtr->setWeightFIRST(0.);
730  return -1;
731  }
732 
733  // Discard if the state could not be reclustered to any state above TMS.
734  int nPerformed = 0;
735  if ( nSteps > 0
736  && ( doUNLOPSSubt || doUNLOPSSubtNLO || containsRealKin )
737  && !FullHistory.getFirstClusteredEventAboveTMS( RN, nRecluster,
738  newProcess, nPerformed, false ) ) {
739  mergingHooksPtr->setWeightCKKWL(0.);
740  mergingHooksPtr->setWeightFIRST(0.);
741  return -1;
742  }
743  // Check reclustering steps to correctly apply MPI.
744  mergingHooksPtr->nMinMPI(nSteps - nPerformed);
745 
746  // Perform one reclustering for real emission kinematics, then apply
747  // merging scale cut on underlying Born kinematics.
748  if ( containsRealKin ) {
749  Event dummy = Event();
750  // Initialise temporary output of reclustering.
751  dummy.clear();
752  dummy.init( "(hard process-modified)", particleDataPtr );
753  dummy.clear();
754  // Recluster once.
755  FullHistory.getClusteredEvent( RN, nSteps, dummy );
756  double tnowNew = mergingHooksPtr->tmsNow( dummy );
757  // Veto if underlying Born kinematics do not pass merging scale cut.
758  if ( enforceCutOnLHE && nSteps > 0 && nRequested > 0
759  && tnowNew < tmsval ) {
760  mergingHooksPtr->setWeightCKKWL(0.);
761  mergingHooksPtr->setWeightFIRST(0.);
762  return -1;
763  }
764  }
765 
766  // Calculate weights.
767  // Do LO or first part of NLO tree-level reweighting
768  if( doUNLOPSTree ) {
769  // Perform reweighting with Sudakov factors, save as ratios and
770  // PDF ratio weights
771  wgt = FullHistory.weight_UNLOPS_TREE( trialPartonLevelPtr,
772  mergingHooksPtr->AlphaS_FSR(), mergingHooksPtr->AlphaS_ISR(), RN);
773  } else if( doUNLOPSLoop ) {
774  // No reweighting, just set event scales properly
775  wgt = FullHistory.weight_UNLOPS_LOOP( trialPartonLevelPtr, RN);
776  } else if( doUNLOPSSubtNLO ) {
777  // The standard prescripition contains no real-emission parts
778  // No reweighting, just set event scales properly
779  wgt = FullHistory.weight_UNLOPS_SUBTNLO( trialPartonLevelPtr, RN);
780  } else if( doUNLOPSSubt ) {
781  // The standard prescripition contains no subtraction parts
782  // No reweighting, just set event scales properly
783  wgt = FullHistory.weight_UNLOPS_SUBT( trialPartonLevelPtr,
784  mergingHooksPtr->AlphaS_FSR(), mergingHooksPtr->AlphaS_ISR(), RN);
785  }
786 
787  // Event with production scales set for further (trial) showering
788  // and starting conditions for the shower.
789  if (!doUNLOPSSubt && !doUNLOPSSubtNLO && !containsRealKin )
790  FullHistory.getStartingConditions(RN, process);
791  // Do reclustering (looping) steps.
792  else FullHistory.getFirstClusteredEventAboveTMS( RN, nRecluster, process,
793  nPerformed, true );
794 
795  // Allow to dampen histories in which the lowest multiplicity reclustered
796  // state does not pass the lowest multiplicity cut of the matrix element
797  double dampWeight = mergingHooksPtr->dampenIfFailCuts(
798  FullHistory.lowestMultProc(RN) );
799  // Save the weight of the event for histogramming. Only change the
800  // event weight after trial shower on the matrix element
801  // multiplicity event (= in doVetoStep)
802  wgt *= dampWeight;
803 
804  // For tree-level or subtractive sammples, rescale with k-Factor
805  if ( doUNLOPSTree || doUNLOPSSubt ){
806  // Find k-factor
807  double kFactor = 1.;
808  if ( nSteps > mergingHooksPtr->nMaxJetsNLO() )
809  kFactor = mergingHooksPtr->kFactor( mergingHooksPtr->nMaxJetsNLO() );
810  else kFactor = mergingHooksPtr->kFactor(nSteps);
811  // For NLO merging, rescale CKKW-L weight with k-factor
812  wgt *= (nRecluster == 2 && nloTilde) ? 1. : kFactor;
813  }
814 
815  // Save the weight of the event for histogramming
816  mergingHooksPtr->setWeightCKKWL(wgt);
817 
818  // Check if we need to subtract the O(\alpha_s)-term. If the number
819  // of additional partons is larger than the number of jets for
820  // which loop matrix elements are available, do standard UMEPS.
821  int nMaxNLO = mergingHooksPtr->nMaxJetsNLO();
822  bool doOASTree = doUNLOPSTree && nSteps <= nMaxNLO;
823  bool doOASSubt = doUNLOPSSubt && nSteps <= nMaxNLO+1 && nSteps > 0;
824 
825  // Now begin NLO part for tree-level events
826  if ( doOASTree || doOASSubt ) {
827 
828  // Decide on which order to expand to.
829  int order = ( nSteps > 0 && nSteps <= nMaxNLO) ? 1 : -1;
830 
831  // Exclusive inputs:
832  // Subtract only the O(\alpha_s^{n+0})-term from the tree-level
833  // subtraction, if we're at the highest NLO multiplicity (nMaxNLO).
834  if ( nloTilde && doUNLOPSSubt && nRecluster == 1
835  && nSteps == nMaxNLO+1 ) order = 0;
836 
837  // Exclusive inputs:
838  // Do not remove the O(as)-term if the number of reclusterings
839  // exceeds the number of NLO jets, or if more clusterings have
840  // been performed.
841  if (nloTilde && doUNLOPSSubt && ( nSteps > nMaxNLO+1
842  || (nSteps == nMaxNLO+1 && nPerformed != nRecluster) ))
843  order = -1;
844 
845  // Calculate terms in expansion of the CKKW-L weight.
846  wgtFIRST = FullHistory.weight_UNLOPS_CORRECTION( order,
847  trialPartonLevelPtr, mergingHooksPtr->AlphaS_FSR(),
848  mergingHooksPtr->AlphaS_ISR(), RN, rndmPtr );
849 
850  // Exclusive inputs:
851  // Subtract the O(\alpha_s^{n+1})-term from the tree-level
852  // subtraction, not the O(\alpha_s^{n+0})-terms.
853  if ( nloTilde && doUNLOPSSubt && nRecluster == 1
854  && nPerformed == nRecluster && nSteps <= nMaxNLO )
855  wgtFIRST += 1.;
856 
857  // If necessary, also dampen the O(\alpha_s)-term
858  wgtFIRST *= dampWeight;
859  // Set the subtractive weight to the value calculated so far
860  mergingHooksPtr->setWeightFIRST(wgtFIRST);
861  // Subtract the O(\alpha_s)-term from the CKKW-L weight
862  // If PDF contributions have not been included, subtract these later
863  wgt = wgt - wgtFIRST;
864  }
865 
866  // Set QCD 2->2 starting scale different from arbitrary scale in LHEF!
867  // --> Set to minimal mT of partons.
868  int nFinal = 0;
869  double muf = process[0].e();
870  for ( int i=0; i < process.size(); ++i )
871  if ( process[i].isFinal()
872  && (process[i].colType() != 0 || process[i].id() == 22 ) ) {
873  nFinal++;
874  muf = min( muf, abs(process[i].mT()) );
875  }
876  // For pure QCD dijet events (only!), set the process scale to the
877  // transverse momentum of the outgoing partons.
878  if ( nSteps == 0 && nFinal == 2
879  && ( mergingHooksPtr->getProcessString().compare("pp>jj") == 0
880  || mergingHooksPtr->getProcessString().compare("pp>aj") == 0) )
881  process.scale(muf);
882 
883  // Reset hard process candidates (changed after clustering a parton).
884  mergingHooksPtr->storeHardProcessCandidates( process );
885 
886  // Check if resonance structure has been changed
887  // (e.g. because of clustering W/Z/gluino)
888  vector <int> oldResonance;
889  for ( int i=0; i < newProcess.size(); ++i )
890  if ( newProcess[i].status() == 22 )
891  oldResonance.push_back(newProcess[i].id());
892  vector <int> newResonance;
893  for ( int i=0; i < process.size(); ++i )
894  if ( process[i].status() == 22 )
895  newResonance.push_back(process[i].id());
896  // Compare old and new resonances
897  for ( int i=0; i < int(oldResonance.size()); ++i )
898  for ( int j=0; j < int(newResonance.size()); ++j )
899  if ( newResonance[j] == oldResonance[i] ) {
900  oldResonance[i] = 99;
901  break;
902  }
903  bool hasNewResonances = (newResonance.size() != oldResonance.size());
904  for ( int i=0; i < int(oldResonance.size()); ++i )
905  hasNewResonances = (oldResonance[i] != 99);
906 
907  // If necessary, reattach resonance decay products.
908  if (!hasNewResonances) mergingHooksPtr->reattachResonanceDecays(process);
909 
910  // Allow merging hooks to remove emissions from now on.
911  mergingHooksPtr->doIgnoreEmissions(false);
912 
913  // If no-emission probability is zero.
914  if ( wgt == 0. ) return 0;
915 
916  // If the resonance structure of the process has changed due to reclustering,
917  // redo the resonance decays in Pythia::next()
918  if (hasNewResonances) return 2;
919 
920  // Done
921  return 1;
922 
923 }
924 
925 //--------------------------------------------------------------------------
926 
927 // Function to apply the merging scale cut on an input event.
928 
929 bool Merging::cutOnProcess( Event& process) {
930 
931  // Save number of looping steps
932  mergingHooksPtr->nReclusterSave = settingsPtr->mode("Merging:nRecluster");
933  int nRequested = settingsPtr->mode("Merging:nRequested");
934 
935  // For now, prefer construction of ordered histories.
936  mergingHooksPtr->orderHistories(true);
937  // For pp > h, allow cut on state, so that underlying processes
938  // can be clustered to gg > h
939  if ( mergingHooksPtr->getProcessString().compare("pp>h") == 0)
940  mergingHooksPtr->allowCutOnRecState(true);
941 
942  // Prepare process record for merging. If Pythia has already decayed
943  // resonances used to define the hard process, remove resonance decay
944  // products.
945  Event newProcess( mergingHooksPtr->bareEvent( process, true) );
946  // Store candidates for the splitting V -> qqbar'
947  mergingHooksPtr->storeHardProcessCandidates( newProcess );
948 
949  // Check if event passes the merging scale cut.
950  double tmsval = mergingHooksPtr->tms();
951  // Get merging scale in current event.
952  double tmsnow = mergingHooksPtr->tmsNow( newProcess );
953  // Calculate number of clustering steps
954  int nSteps = mergingHooksPtr->getNumberOfClusteringSteps( newProcess);
955 
956  // Too few steps can be possible if a chain of resonance decays has been
957  // removed. In this case, reject this event, since it will be handled in
958  // lower-multiplicity samples.
959  if (nSteps < nRequested) return true;
960 
961  // Reset the minimal tms value, if necessary.
962  tmsNowMin = (nSteps == 0) ? 0. : min(tmsNowMin, tmsnow);
963 
964  // Potentially recluster real emission jets for powheg input containing
965  // "too many" jets, i.e. real-emission kinematics.
966  bool containsRealKin = nSteps > nRequested && nSteps > 0;
967 
968  // Get random number to choose a path.
969  double RN = rndmPtr->flat();
970  // Set dummy process scale.
971  newProcess.scale(0.0);
972  // Generate all histories
973  History FullHistory( nSteps, 0.0, newProcess, Clustering(), mergingHooksPtr,
974  (*beamAPtr), (*beamBPtr), particleDataPtr, infoPtr, true, true,
975  true, true, 1.0, 0);
976  // Project histories onto desired branches, e.g. only ordered paths.
977  FullHistory.projectOntoDesiredHistories();
978 
979  // Remove real emission events without underlying Born configuration from
980  // the loop sample, since such states will be taken care of by tree-level
981  // samples.
982  bool allowIncompleteReal =
983  settingsPtr->flag("Merging:allowIncompleteHistoriesInReal");
984  if ( containsRealKin && !allowIncompleteReal
985  && FullHistory.select(RN)->nClusterings() == 0 )
986  return true;
987 
988  // Cut if no history passes the cut on the lowest-multiplicity state.
989  double dampWeight = mergingHooksPtr->dampenIfFailCuts(
990  FullHistory.lowestMultProc(RN) );
991  if ( dampWeight == 0. ) return true;
992 
993  // Do not apply cut if the configuration could not be projected onto an
994  // underlying born configuration.
995  if ( nSteps > 0 && FullHistory.select(RN)->nClusterings() == 0 )
996  return false;
997 
998  // Now enfore merging scale cut if the event did not pass the merging scale
999  // criterion.
1000  if ( nSteps > 0 && nSteps == nRequested && tmsnow < tmsval ) {
1001  string message="Warning in Merging::cutOnProcess: Les Houches Event";
1002  message+=" fails merging scale cut. Reject event.";
1003  infoPtr->errorMsg(message);
1004  return true;
1005  }
1006 
1007  if ( FullHistory.select(RN)->nClusterings() < nSteps) {
1008  string message="Warning in Merging::cutOnProcess: No clusterings";
1009  message+=" found. History incomplete.";
1010  infoPtr->errorMsg(message);
1011  }
1012 
1013  // Done if no real-emission jets are present.
1014  if ( !containsRealKin ) return false;
1015 
1016  // Now cut on events that contain an additional real-emission jet.
1017  // Perform one reclustering for real emission kinematics, then apply merging
1018  // scale cut on underlying Born kinematics.
1019  if ( containsRealKin ) {
1020  Event dummy = Event();
1021  // Initialise temporary output of reclustering.
1022  dummy.clear();
1023  dummy.init( "(hard process-modified)", particleDataPtr );
1024  dummy.clear();
1025  // Recluster once.
1026  FullHistory.getClusteredEvent( RN, nSteps, dummy );
1027  double tnowNew = mergingHooksPtr->tmsNow( dummy );
1028  // Veto if underlying Born kinematics do not pass merging scale cut.
1029  if ( nSteps > 0 && nRequested > 0 && tnowNew < tmsval ) return true;
1030  }
1031 
1032  // Done if only interested in cross section estimate after cuts.
1033  return false;
1034 
1035 }
1036 
1037 //==========================================================================
1038 
1039 } // end namespace Pythia8
Definition: AgUStep.h:26