Matching and Merging

Starting from a Born-level leading-order (LO) process, higher orders can be included in various ways. The three basic approaches would be Given the pros and cons, much of the effort in recent years has involved the development of different prescriptions to combine the methods above in various ways.

The common traits of all combination methods are that matrix elements are used to describe the production of hard and well separated particles, and parton showers for the production of soft or collinear particles. What differs between the various approaches that have been proposed are which matrix elements are being used, how doublecounting is avoided, and how the transition from the hard to the soft regime is handled. These combination methods are typically referred to as "matching" or "merging" algorithms. There is some confusion about the distinction between the two terms, and so we leave it to the inventor/implementor of a particular scheme to choose and motivate the name given to that scheme.

PYTHIA comes with methods, to be described next, that implement or support several different kind of algorithms. The field is open-ended, however: any external program can feed in Les Houches events that PYTHIA subsequently showers, adds multiparton interactions to, and hadronizes. These events afterwards can be reweighted and combined in any desired way. The maximum pT of the shower evolution is set by the Les Houches scale, on the one hand, and by the values of the SpaceShower:pTmaxMatch, TimeShower:pTmaxMatch and other parton-shower settings, on the other. Typically it is not possible to achieve perfect matching this way, given that the PYTHIA pT evolution variables are not likely to agree with the variables used for cuts in the external program. Often one can get close enough with simple means but, for an improved matching, User Hooks can be inserted to control the steps taken on the way, e.g. to veto those parton shower branchings that would doublecount emissions included in the matrix elements.

Zooming in from the "anything goes" perspective, the list of relevent approaches actively supported is as follows.




MC@NLO, jet matching, multi-jet merging and NLO merging with main89.cc

A common Pythia main program for MC@NLO NLO+PS matching, MLM jet matching, FxFx (NLO) jet matching, CKKW-L merging, UMEPS merging and UNLOPS (NLO) merging is available through main89.cc, together with the input files main89mlm.cmnd, main89fxfx.cmnd, main89ckkwl.cmnd, main89umeps.cmnd and main89unlops.cmnd. The interface to MLM jet matching relies on MadGraph, while all other options of main89.cc use aMC@NLO input. main89.cc produces HepMC events [Dob01], that can be histogrammed (e.g. using RIVET [Buc10]), or used as input for a detector simulation. If the user is not familiar with HepMC analysis tools, it is possible to instead use Pythia's histogramming routines. For this, remove the lines referring to HepMC, and histogram events as illustrated (for CKKW-L) for the histogram histPTFirstSum in main84.cc, i.e. using weight*normhepmc as weight.

All settings can be transferred to main89.cc through an input file. The input file is part of the command line input of main89.cc, i.e. you can execute main89 with the command

./main89 myInputFile.cmnd myhepmc.hepmc

to read the input myInputFile.cmnd and produce the output file myhepmc.hepmc . Since main89.cc is currently a "front-end" for different types of matching/merging, we will briefly discuss the inputs for this sample program in the following.

Inputs

In its current form, main89.cc uses LHEF input to transfer (weighted) phase space points to Pythia. It is possible to include all parton multiplicities in one LHEF sample. If e.g. UMEPS merging for W-boson + up to two additional partons is to be performed, one LHE file containing W+zero, W+one and W+two parton events is required.

All input settings are handed to main89.cc in the form of an input file. We have included the input settings files

         main89mlm.cmnd, which illustrates the MLM jet matching interface,

         main89ckkwl.cmnd, which illustrates the CKKW-L multi-jet merging interface,

         main89umeps.cmnd, which illustrates the UMEPS multi-jet merging interface, and

         main89fxfx.cmnd, which illustrates the FxFx NLO jet matching interface,

         main89unlops.cmnd, which illustrates the UNLOPS multi-jet NLO merging interface.

Other settings (e.g. using main89.cc as simple LO+PS or as MC@NLO interface) are of course possible. In the following, we will briefly explain how input for the five choices above are generated and handled.

MLM jet matching with main89.cc

For MLM jet matching, main89.cc currently relies on LHEF input from MadGraph. Due to the particular unweighting strategy performed in the generation of these inputs, the sample program starts by estimating the cross section. After this estimate, MLM jet matching within the Madgraph approach is performed in a second Pythia run. Example MLM settings can be found in main89mlm.cmnd. Please consult Jet Matching for more details.

CKKW-L merging with main89.cc

For CKKW-L merging, main89.cc currently relies on LHEF inputs generated with the leading-order mode of aMC@NLO (i.e. events should be generated with ./bin/generate_events aMC@LO). No run to estimate the cross section estimate is needed. Example CKKW-L settings can be found in main89ckkwl.cmnd. Please consult CKKW-L merging for more details.

UMEPS merging with main89.cc

For UMEPS merging, main89.cc currently relies on LHEF inputs generated with the leading-order mode of aMC@NLO as well (see above). main89.cc automatically assigns if an event will be used as "standard" event or as "subtractive" contribution. Example UMEPS settings can be found in main89umeps.cmnd. Please consult UMEPS merging and CKKW-L merging for more details.

FxFx (NLO) jet matching with main89.cc

For FxFx jet matching, main89.cc relies on MC@NLO input LHE files generated with aMC@NLO. To produce FxFx outputs in aMC@NLO, the settings PYTHIA8 = parton_shower, 3 = ickkw and x = ptj are necessary in your aMC@NLO run card. Here, x is the value of the matching scale in FxFx, i.e. has be identical to JetMatching:qCutME in the Pythia inputs. Example FxFx settings for Pythia can be found in main89fxfx.cmnd. Please consult Jet Matching and aMC@NLO matching for more details.

UNLOPS (NLO) merging with main89.cc

For UNLOPS merging, main89.cc currently relies on LHEF inputs generated with the aMC@NLO. The UNLOPS interface in main89.cc requires a) leading-order inputs generated with the leading-order mode of aMC@NLO, using the UNLOPS prescription, and b) next-to-leading-order inputs generated with the NLO mode of aMC@NLO, using the UNLOPS prescription. To produce UNLOPS outputs in aMC@NLO, the settings PYTHIA8 = parton_shower, 4 = ickkw and x = ptj are necessary in your aMC@NLO run card. Here, x is the value of the merging scale in UNLOPS, i.e. has be identical to Merging:TMS in the Pythia inputs. main89.cc will then process NLO inputs and LO inputs consecutively, and will automatically assign if an event will be used as "standard" event or as "subtractive" contribution. Example UNLOPS settings can be found in main89umeps.cmnd. Please consult UMEPS merging and CKKW-L merging for more details.


Implementing an external ME+PS combination scheme and interfacing this plugin with Pythia

For experts and developers of new matching/merging schemes, Pythia also offers the possibility to completely replace its internal merging machinery with a user-defined plugin code (much in the same way that parton shower plugins (cf. Implement New Showers) are possible). This allows for maximum flexibility while still benefiting from the full Pythia event generation machinery. Note that the ME+PS merging with the VINCIA and DIRE shower plugins make use of this flexibility, and might thus provide helpful clarifications. Of course, implementing your own, new matching/merging scheme is a non-trivial task, and comprehensive guidelines on how to proceed are impossible to set. However, it is important that an external matching/merging plugin interfaces to Pythia in a simple and well-defined manner. Here, we will document which C++ functions are necessary to be able to use an external matching/merging (MM) plugin within Pythia.

To understand how to design a MM plugin for Pythia, it is useful to review how Pythia's internal merging machinery is structured. The interaction between the core Pythia and the merging code is governed by the Merging and MergingHooks classes. Note that for moderately complex requirements, it may be sufficient to only replace Pythia's instance of MergingHooks with a pointer to an external class (cf. CKKW-L merging). The latter two classes are supplemented with the helper classes History and HardProcess. The latter gathers information on the (user-supplied information about the) hard core scattering process to which hard jets are added by ME+PS merging. It is only used as a helper to the MergingHooks class. The History class contains the implementation of all internal (LO or NLO) merging schemes. The Merging class acts as a bridge between the implementation in the History class and the rest of the Pythia code.

To implement an external MM plugin, you will have to write classes that derive from the Merging, MergingHooks and HardProcess classes of Pythia. For special cases, it might also be permissible to only implement a replacement of the Merging class, while still using Pythia's implementation of the other two classes. The external MM plugin can then be transferred to and used by Pythia much in the same way as UserHooks classes or shower plugins. More concretely, an external MM code will be used if a pointer to an instance of the external classes is transferred to Pythia via the methods

Pythia::setMergingPtr( Merging* myMerging)  

Pythia::setMergingHooksPtr( MergingHooks* myMergingHooks)  

MergingHooks::setHardProcessPtr( HardProcess* myHardProcess)  

The option to only use a user-defined MergingHooks instance is already documented in the item CKKW-L merging and will not be discussed further. We will now focus on how to implement external Merging, MergingHooks and HardProcess classes that can be used as a complete replacement of the Pythia methods. Let us assume that you want to create a class of type MyMerging, and you call its instance myMerging. For this external ME+PS merging class to be interfaced to Pythia, the class needs to inherit from the Pythia8::Merging base class. It is further necessary to define the following functions that serve as interface to Pythia:

virtual ~MyMerging()  
A destructor for your ME+PS class. If not defined, the base class's empty destructor will be used.

virtual void MyMerging::init()  
A method that is used to initialize your merging class. Pythia will call this function during its initialization and after all pointers to internal classes (e.g. to instances of the Info and ParticleData classes) have been set up.

virtual void statistics()  
This function can be used to collect and print merging information at the end of the event generation. Pythia will call this function in the execution of a Pythia::stat() call.

virtual int MyMerging::mergeProcess( Event& process)  
This function should be the main interface of Pythia to the MM plugin. Pythia will execute this function once the partonic (fixed-order) scattering has been constructed (or read from LHEF). The partonic scattering is transferred via the process argument. The external MM plugin should then, based on the process, implement the matching/merging strategy. It is permissible that this function changes process. In this case, Pythia will continue the event generation with the changed process as starting point. The return value of the function steers how Pythia should proceed after the function execution. The following return values are supported:

  • -1 : Reject the event and exit the generation/processing of the current event
  • 0: Reject the event but continue with the generation/processing of the current event.
  • 1: Keep the event but continue with the generation/processing of the current event.
  • 2: Reject the event but continue with the generation/processing of the current event. However, re-evaluate resonance decays before any other event generation step. This option can be necessary if the merging code removes or changes resonant particles from process.
  • Note that because this function is the main interface between the MM plugin and Pythia, it is necessary to use this function to set up all the information that you might later need (merging weights, particle counters, etc) in this call already.

    For more details on how to design your MyMerging class, and to understand the interface to Pythia, studying Pythia's internal code is unavoidable. Each potential developer of a MM plugin should do so.

    The other main ingredient of the interface to MM plugins is a new implementation of the MergingHooks class. Let us assume that you want to create a class of type MyMergingHooks, and you call its instance myMergingHooks. For this class to be interfaced to Pythia, it will need to inherit from the Pythia8::MergingHooks base class.

    virtual ~MyMergingHooks()  
    A destructor for your MergingHooks class. If not defined, the base class's empty destructor will be used.

    virtual void MyMergingHooks::init()  
    A method that is used to initialize your MyMergingHooks class. Pythia will call this function during its initialization and after all pointers to internal classes (e.g. to instances of the Info and ParticleData classes) have been set up.

    virtual bool MyMergingHooks::canVetoStep()  
    This function will be used to tell Pythia if a CKKW-L-style event veto after the first parton shower emission should be checked. If so, the function should return true, and false otherwise.

    virtual bool MyMergingHooks::doVetoStep( const Event& process, const Event& event, bool doResonance = false )  
    This function will be used to implement the check of a CKKW-L-style event veto after the first parton shower emission, i.e. to check if the first parton shower emission is above the merging scale. If the input event event after emission should be kept, then false should be returned. If you want instead to veto the event and continue with a completely now hard scattering event, true should be returned.

    virtual bool MyMergingHooks::canVetoEmission()  
    This function will be used to tell Pythia if a veto of emissions should potentially be applied.

    virtual bool MyMergingHooks::doVetoStep( const Event& event)  
    This function will be used to implement the check if shower emissions should be discarded, as e.g. necessary in UMEPS or UNLOPS merging. You can study the input event event after emission, and return true if the emission is valid, and false if you want to reject the emission. Note that this veto does not lead to event rejections, only in potentially removing certain emissions during shower evolution.

    virtual bool MyMergingHooks::setShowerStartingScales( bool isTrial, bool doMergeFirstEmm, double& pTscaleIn, const Event& event, double& pTmaxFSRIn, bool& limitPTmaxFSRin, double& pTmaxISRIn, bool& limitPTmaxISRin, double& pTmaxMPIIn, bool& limitPTmaxMPIin )  
    This function allows to set the starting scales for timelike and spacelike showering as well as multiparton interactions. It is thus necessary to properly start trial showers (that generate necessary no-emission probabilities), and for setting the correct starting conditions for parton showering of accepted (non-zero weight) events. The input event gives the hard process before showers and MPI are attempted. If isTrial=true, this means that the function is currently called from within a trial shower object (to produce no-emission probabilities). If doMergeFirstEmm=true, then the function is called to set starting conditions for the shower evolution of an (accepted) event. The double arguments pTscaleIn, pTmaxFSRIn, pTmaxISRIn and pTmaxMPIIn are tentative values for the starting scales of FSR, ISR and MPI. The function may overwrite these with the desired values. Similarly, limitPTmaxFSRin, limitPTmaxFSRin and limitPTmaxMPIin inform Pythia if the phase space for FSR/ISR/MPI is restricted (true) or unrestricted (false). Again, the tentative values can be overwritten.

    The MergingHooks base class allows for further virtual functions that are not directly called by Pythia, and are hence not necessary to define. Th usage of these functions within Pythia's Merging and History classes is documented in CKKW-L merging. The additional (optional) virtual functions are:

    virtual double dampenIfFailCuts( const Event& inEvent )  

    virtual bool canCutOnRecState()  

    virtual bool doCutOnRecState( const Event& event )  

    virtual bool canVetoTrialEmission()  

    virtual bool doVetoTrialEmission( const Event&, const Event& )  

    virtual double hardProcessME( const Event& inEvent )  

    virtual double MyMergingHooks::tmsDefinition( const Event& event)  

    virtual int MyMergingHooks::getNumberOfClusteringSteps(const Event& event, bool resetNjetMax = false)  

    virtual bool useShowerPlugin()  

    The internal implementation of MergingHooks in Pythia heavily relies on the HardProcess helper class. It is in principle not necessary to follow the same strategy when implementing a derived MyMergingHooks class. However, to benefit from the Pythia implementation, and to allow for a structure similar to the internal code also for an external MM plugin, it is also possible to effectively replace (in the MergingHooks class) the pointer to an instance of HardProcess with a pointer to an external implementation. Let us assume that you want to create a class of type MyHardProcess, and you call its instance myHardProcess. For this class to be interfaced to MergingHooks (or the derived MyMergingHooks class), it will need to inherit from the Pythia8::HardProcess base class.

    virtual ~MyHardProcess()  
    A destructor for your HardProcess class. If not defined, the base class's empty destructor will be used.

    virtual void MyHardProcess::initOnProcess( string process, ParticleData* particleData)  
    This function can be used to initialize the instance of your HardProcess class. In the internal Pythia implementation, this acts as a wrapper around the next function.

    virtual void MyHardProcess::translateProcessString( string process)  
    This function will use the string argument to set up the hard process bookkeeping, e.g. how many incoming/outgoing particles of which flavour are contained in the core (lowest multiplicity) scattering process.

    virtual void MyHardProcess::storeCandidates( const Event& event, string process)  
    This function studies the input event and book-keeps the particles that may be considered as part of the core scattering process. For this, it may use the four next functions.

    virtual bool MyHardProcess::allowCandidates(int iPos, vector<int> Pos1, vector<int> Pos2, const Event& event)  
    This function uses the input vectors of positions of particles in the input event to decide if the particle with iPos could be member of the core scattering. If the particle with position iPos cannot be part of the core scattering (e.g. because it is a final state parton, while the core scattering contains final state leptons only), then the function should return false. Else, return true to allow this candidate. Note that it might be possible to find multiple equally good core scattering candidates. In this case, all candidates should be found (with the findOtherCandidates function), and can be potentially be replaced (with exchangeCandidates).

    virtual bool MyHardProcess::matchesAnyOutgoing(int iPos, const Event& event)  
    This function may be used to check if the particle with position iPos in the input event should be considered an outgoing particle of the core scattering.

    virtual bool MyHardProcess::findOtherCandidates(int iPos, const Event& event, bool doReplace)  
    The argument iPos specifies the position of a particle in the input event which is tagged as part of the core scattering. This function may be used to check the role of iPos as core scattering member may be filled by another particle in the event record. If so, and if doReplace=true, then iPos will no longer be book-kept as part of the core scattering. An example where this functionality is helpful is if the input event is g g -> b b~ b b~, and the core scattering is g g -> b b~. Not swapping the hard process candidates could in this case mean that not all parton shower histories can be found. The function should return false if no replacements can be found, and true otherwise.

    virtual bool MyHardProcess::exchangeCandidates( vector<int> candidates1, vector<int> candidates2, map<int, int> further1, map<int, int> further2)  
    This function implements the replacement of a list of core scattering candidates by another list of candidates.