LCOV - code coverage report
Current view: top level - PYTHIA8/pythia8210dev/src - Merging.cc (source / functions) Hit Total Coverage
Test: coverage.info Lines: 0 501 0.0 %
Date: 2016-06-14 17:26:59 Functions: 0 8 0.0 %

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

Generated by: LCOV version 1.11