]> git.uio.no Git - u/mrichter/AliRoot.git/blobdiff - PYTHIA8/pythia8170/examples/MLMhooks.h
PYTHIA8: removing legacy pythia8170
[u/mrichter/AliRoot.git] / PYTHIA8 / pythia8170 / examples / MLMhooks.h
diff --git a/PYTHIA8/pythia8170/examples/MLMhooks.h b/PYTHIA8/pythia8170/examples/MLMhooks.h
deleted file mode 100644 (file)
index 2a778e3..0000000
+++ /dev/null
@@ -1,777 +0,0 @@
-// MLMhooks.h is a part of the PYTHIA event generator.
-// Copyright (C) 2012 Torbjorn Sjostrand.
-// PYTHIA is licenced under the GNU GPL version 2, see COPYING for details.
-// Please respect the MCnet Guidelines, see GUIDELINES for details.
-
-// Author: Richard Corke (richard.corke@thep.lu.se)
-// This file provides the MLMhooks class to perform MLM merging.
-// Example usage is shown in main32.cc, and further details
-// can be found in the 'Alpgen and MLM Merging' manual page.
-
-#ifndef MLMHOOKS_H
-#define MLMHOOKS_H
-
-// Includes
-#include "Pythia.h"
-using namespace Pythia8;
-
-//==========================================================================
-
-// Preprocessor settings
-
-// Debug flag to give verbose information at all stages of the merging.
-//#define MLMDEBUG
-// Debug flag to enable some extra checks in the code
-//#define MLMCHECK
-
-//==========================================================================
-
-// Declaration of main MLMhooks class to perform MLM matching.
-// Note that it is defined with virtual inheritance, so that it can
-// be combined with other UserHooks classes, see e.g. main32.cc.
-
-class MLMhooks : virtual public UserHooks {
-
-public:
-
-  // Constructor and destructor
-  MLMhooks() : cellJet(NULL), slowJet(NULL) {}
-  ~MLMhooks() {
-    if (cellJet) delete cellJet;
-    if (slowJet) delete slowJet; 
-  }
-
-  // Initialisation
-  virtual bool initAfterBeams();
-
-  // Process level vetos
-  virtual bool canVetoProcessLevel();
-  virtual bool doVetoProcessLevel(Event &);
-
-  // Parton level vetos (before beam remnants and resonance decays)
-  virtual bool canVetoPartonLevelEarly();
-  virtual bool doVetoPartonLevelEarly(const Event &);
-
-private:
-
-  // Different steps of the MLM matching algorithm
-  void sortIncomingProcess(const Event &);
-  void jetAlgorithmInput(const Event &, int);
-  void runJetAlgorithm();
-  bool matchPartonsToJets(int);
-  int  matchPartonsToJetsLight();
-  int  matchPartonsToJetsHeavy();
-
-  // DeltaR between two 4-vectors (eta and y variants)
-  inline double Vec4eta(const Vec4 &pIn) {
-    return -log(tan(pIn.theta() / 2.));
-  }
-  inline double Vec4y(const Vec4 &pIn) {
-    return 0.5 * log((pIn.e() + pIn.pz()) / (pIn.e() - pIn.pz()));
-  }
-  inline double deltaReta(const Vec4 &p1, const Vec4 &p2) {
-    double dEta = abs(Vec4eta(p1) - Vec4eta(p2));
-    double dPhi = abs(p1.phi() - p2.phi());
-    if (dPhi > M_PI) dPhi = 2. * M_PI - dPhi;
-    return sqrt(dEta*dEta + dPhi*dPhi);
-  }
-  inline double deltaRy(const Vec4 &p1, const Vec4 &p2) {
-    double dy   = abs(Vec4y(p1) - Vec4y(p2));
-    double dPhi = abs(p1.phi() - p2.phi());
-    if (dPhi > M_PI) dPhi = 2. * M_PI - dPhi;
-    return sqrt(dy*dy + dPhi*dPhi);
-  }
-
-  // Function to sort typeIdx vectors into descending eT/pT order.
-  // Uses a selection sort, as number of partons generally small
-  // and so efficiency not a worry.
-  void sortTypeIdx(vector < int > &vecIn) {
-    for (size_t i = 0; i < vecIn.size(); i++) {
-      size_t jMax = i;
-      double vMax = (jetAlgorithm == 1) ?
-                    eventProcess[vecIn[i]].eT() :
-                    eventProcess[vecIn[i]].pT();
-      for (size_t j = i + 1; j < vecIn.size(); j++) {
-        double vNow = (jetAlgorithm == 1) ?
-                      eventProcess[vecIn[j]].eT() :
-                      eventProcess[vecIn[j]].pT();
-        if (vNow > vMax) {
-          vMax = vNow;
-          jMax = j;
-        }
-      }
-      if (jMax != i) swap(vecIn[i], vecIn[jMax]);
-    }
-  }
-
-  // Master switch for merging
-  bool   doMerge;
-
-  // Maximum and current number of jets
-  int    nJetMax, nJet;
-
-  // Jet algorithm parameters
-  int    jetAlgorithm;
-  double eTjetMin, coneRadius, etaJetMax, etaJetMaxAlgo;
-
-  // CellJet specific
-  int    nEta, nPhi;
-  double eTseed, eTthreshold;
-
-  // SlowJet specific
-  int    slowJetPower;
-
-  // Merging procedure parameters
-  int    jetAllow, jetMatch, exclusiveMode;
-  double coneMatchLight, coneRadiusHeavy, coneMatchHeavy;
-  bool   exclusive;
-
-  // Event records to store original incoming process, final-state of the
-  // incoming process and what will be passed to the jet algorithm.
-  // Not completely necessary to store all steps, but makes tracking the
-  // steps of the algorithm a lot easier.
-  Event eventProcessOrig, eventProcess, workEventJet;
-
-  // Internal jet algorithms
-  CellJet *cellJet;
-  SlowJet *slowJet;
-
-  // Sort final-state of incoming process into light/heavy jets and 'other'
-  vector < int > typeIdx[3];
-  set    < int > typeSet[3];
-
-  // Momenta output of jet algorithm (to provide same output regardless of
-  // the selected jet algorithm)
-  vector < Vec4 > jetMomenta;
-
-  // Store the minimum eT/pT of matched light jets
-  double eTpTlightMin;
-
-  // Constants
-  static const double GHOSTENERGY, ZEROTHRESHOLD;
-};
-
-//--------------------------------------------------------------------------
-
-// Main implementation of MLMhooks class. This may be split out to a
-// separate C++ file if desired, but currently included here for ease
-// of use.
-
-// Constants: could be changed here if desired, but normally should not.
-// These are of technical nature, as described for each.
-
-// The energy of ghost particles. For technical reasons, this cannot be
-// set arbitrarily low, see 'Particle::TINY' in 'Event.cc' for details.
-const double MLMhooks::GHOSTENERGY   = 1e-15;
-
-// A zero threshold value for double comparisons.
-const double MLMhooks::ZEROTHRESHOLD = 1e-10;
-
-//--------------------------------------------------------------------------
-
-// Initialisation routine automatically called from Pythia::init().
-// Setup all parts needed for the merging.
-
-bool MLMhooks::initAfterBeams() {
-
-  // Read in parameters
-  doMerge         = settingsPtr->flag("MLM:merge");
-  nJet            = settingsPtr->mode("MLM:nJet");
-  nJetMax         = settingsPtr->mode("MLM:nJetMax");
-  jetAlgorithm    = settingsPtr->mode("MLM:jetAlgorithm");
-  eTjetMin        = settingsPtr->parm("MLM:eTjetMin");
-  coneRadius      = settingsPtr->parm("MLM:coneRadius");
-  etaJetMax       = settingsPtr->parm("MLM:etaJetMax");
-  // Use etaJetMax + coneRadius in input to jet algorithms
-  etaJetMaxAlgo   = etaJetMax + coneRadius;
-  // CellJet specific
-  nEta            = settingsPtr->mode("MLM:nEta");
-  nPhi            = settingsPtr->mode("MLM:nPhi");
-  eTseed          = settingsPtr->parm("MLM:eTseed");
-  eTthreshold     = settingsPtr->parm("MLM:eTthreshold");
-  // SlowJet specific
-  slowJetPower    = settingsPtr->mode("MLM:slowJetPower");
-  // Matching procedure
-  jetAllow        = settingsPtr->mode("MLM:jetAllow");
-  jetMatch        = settingsPtr->mode("MLM:jetMatch");
-  coneMatchLight  = settingsPtr->parm("MLM:coneMatchLight");
-  coneRadiusHeavy = settingsPtr->parm("MLM:coneRadiusHeavy");
-  if (coneRadiusHeavy < 0.) coneRadiusHeavy = coneRadius;
-  coneMatchHeavy  = settingsPtr->parm("MLM:coneMatchHeavy");
-  exclusiveMode   = settingsPtr->mode("MLM:exclusive");
-
-  // If not merging, then done
-  if (!doMerge) return true;
-
-  // Exclusive mode; if set to 2, then set based on nJet/nJetMax
-  if (exclusiveMode == 2) {
-
-    // No nJet or nJetMax, so default to exclusive mode
-    if (nJet < 0 || nJetMax < 0) {
-      infoPtr->errorMsg("Warning in MLMhooks:init: "
-          "missing jet multiplicity information; running in exclusive mode");
-      exclusive = true;
-
-    // Inclusive if nJet == nJetMax, exclusive otherwise
-    } else {
-      exclusive = (nJet == nJetMax) ? false : true;
-    }
-
-  // Otherwise, just set as given
-  } else {
-    exclusive = (exclusiveMode == 0) ? false : true;
-  }
-
-  // Initialise chosen jet algorithm. CellJet.
-  if (jetAlgorithm == 1) {
-
-    // Extra options for CellJet. nSel = 1 means that all final-state
-    // particles are taken and we retain control of what to select.
-    // smear/resolution/upperCut are not used and are set to default values.
-    int    nSel = 2, smear = 0;
-    double resolution = 0.5, upperCut = 2.;
-    cellJet = new CellJet(etaJetMaxAlgo, nEta, nPhi, nSel,
-                          smear, resolution, upperCut, eTthreshold);
-
-  // SlowJet
-  } else if (jetAlgorithm == 2) {
-    slowJet = new SlowJet(slowJetPower, coneRadius, eTjetMin, etaJetMaxAlgo);
-  }
-
-  // Check the jetMatch parameter; option 2 only works with SlowJet
-  if (jetAlgorithm == 1 && jetMatch == 2) {
-    infoPtr->errorMsg("Warning in MLMhooks:init: "
-        "jetMatch = 2 only valid with SlowJet algorithm. "
-        "Reverting to jetMatch = 1.");
-    jetMatch = 1;
-  }
-
-  // Setup local event records
-  eventProcessOrig.init("(eventProcessOrig)", particleDataPtr);
-  eventProcess.init("(eventProcess)", particleDataPtr);
-  workEventJet.init("(workEventJet)", particleDataPtr);
-
-  // Print information
-  string jetStr  = (jetAlgorithm ==  1) ? "CellJet" :
-                   (slowJetPower == -1) ? "anti-kT" :
-                   (slowJetPower ==  0) ? "C/A"     :
-                   (slowJetPower ==  1) ? "kT"      : "unknown";
-  string modeStr = (exclusive)         ? "exclusive" : "inclusive";
-  stringstream nJetStr, nJetMaxStr;
-  if (nJet >= 0)    nJetStr    << nJet;    else nJetStr    << "unknown";
-  if (nJetMax >= 0) nJetMaxStr << nJetMax; else nJetMaxStr << "unknown";
-  cout << endl
-       << " *-------  MLM matching parameters  -------*" << endl
-       << " |  nJet                |  " << setw(14)
-       << nJetStr.str() << "  |" << endl
-       << " |  nJetMax             |  " << setw(14)
-       << nJetMaxStr.str() << "  |" << endl
-       << " |  Jet algorithm       |  " << setw(14)
-       << jetStr << "  |" << endl
-       << " |  eTjetMin            |  " << setw(14)
-       << eTjetMin << "  |" << endl
-       << " |  coneRadius          |  " << setw(14)
-       << coneRadius << "  |" << endl
-       << " |  etaJetMax           |  " << setw(14)
-       << etaJetMax << "  |" << endl
-       << " |  jetAllow            |  " << setw(14)
-       << jetAllow << "  |" << endl
-       << " |  jetMatch            |  " << setw(14)
-       << jetMatch << "  |" << endl
-       << " |  coneMatchLight      |  " << setw(14)
-       << coneMatchLight << "  |" << endl
-       << " |  coneRadiusHeavy     |  " << setw(14)
-       << coneRadiusHeavy << "  |" << endl
-       << " |  coneMatchHeavy      |  " << setw(14)
-       << coneMatchHeavy << "  |" << endl
-       << " |  Mode                |  " << setw(14)
-       << modeStr << "  |" << endl
-       << " *-----------------------------------------*" << endl;
-
-  return true;
-}
-
-//--------------------------------------------------------------------------
-
-// Process level veto. Stores incoming event for later.
-
-bool MLMhooks::canVetoProcessLevel() { return doMerge; }
-
-bool MLMhooks::doVetoProcessLevel(Event& process) { 
-
-  // Copy incoming process
-  eventProcessOrig = process;
-  return false;
-}
-
-//--------------------------------------------------------------------------
-
-// Early parton level veto (before beam remnants and resonance showers)
-
-bool MLMhooks::canVetoPartonLevelEarly() { return doMerge; }
-
-bool MLMhooks::doVetoPartonLevelEarly(const Event& event) {
-
-  // 1) Sort the original incoming process. After this step is performed,
-  //    the following assignments have been made:
-  //      eventProcessOrig - the original incoming process
-  //      eventProcess     - the final-state of the incoming process with
-  //                         resonance decays removed (and resonances
-  //                         themselves now with positive status code)
-  //      typeIdx[0/1/2]   - indices into 'eventProcess' of
-  //                         light jets/heavy jets/other
-  //      typeSet[0/1/2]   - indices into 'event' of
-  //                         light jets/heavy jets/other
-  //      workEvent        - partons from the hardest subsystem
-  //                         + ISR + FSR only
-  sortIncomingProcess(event);
-
-  // Debug
-#ifdef MLMDEBUG
-  // Begin
-  cout << endl << "---------- Begin MLM Debug ----------" << endl;
-
-  // Original incoming process
-  cout << endl << "Original incoming process:";
-  eventProcessOrig.list();
-
-  // Final-state of original incoming process
-  cout << endl << "Final-state incoming process:";
-  eventProcess.list();
-
-  // List categories of sorted particles
-  for (size_t i = 0; i < typeIdx[0].size(); i++) 
-    cout << ((i == 0) ? "Light jets: " : ", ")
-         << setw(3) << typeIdx[0][i];
-  for (size_t i = 0; i < typeIdx[1].size(); i++) 
-    cout << ((i == 0) ? "\nHeavy jets: " : ", ")
-         << setw(3) << typeIdx[1][i];
-  for (size_t i = 0; i < typeIdx[2].size(); i++) 
-    cout << ((i == 0) ? "\nOther:      " : ", ")
-         << setw(3) << typeIdx[2][i];
-
-  // Full event at this stage
-  cout << endl << endl << "Event:";
-  event.list();
-
-  // Work event (partons from hardest subsystem + ISR + FSR)
-  cout << endl << "Work event:";
-  workEvent.list();
-#endif
-
-  // 2) Light/heavy jets: iType = 0 (light jets), 1 (heavy jets)
-  int iTypeEnd = (typeIdx[1].empty()) ? 1 : 2;
-  for (int iType = 0; iType < iTypeEnd; iType++) {
-
-    // 2a) Find particles which will be passed from the jet algorithm.
-    //     Input from 'workEvent' and output in 'workEventJet'.
-    jetAlgorithmInput(event, iType);
-
-    // Debug
-#ifdef MLMDEBUG
-    // Jet algorithm event
-    cout << endl << "Jet algorithm event (iType = " << iType << "):";
-    workEventJet.list();
-#endif
-
-    // 2b) Run jet algorithm on 'workEventJet'.
-    //     Output is stored in jetMomenta.
-    runJetAlgorithm();
-
-    // 2c) Match partons to jets and decide if veto is necessary
-    if (matchPartonsToJets(iType) == true) {
-      // Debug
-#ifdef MLMDEBUG
-      cout << endl << "Event vetoed" << endl
-           << "----------  End MLM Debug  ----------" << endl;
-#endif
-      return true;
-    }
-  }
-
-  // Debug
-#ifdef MLMDEBUG
-  cout << endl << "Event accepted" << endl
-       << "----------  End MLM Debug  ----------" << endl;
-#endif
-
-  // If we reached here, then no veto
-  return false;
-}
-
-//--------------------------------------------------------------------------
-
-// Step (1): sort the incoming particles
-
-void MLMhooks::sortIncomingProcess(const Event &event) {
-
-  // Remove resonance decays from original process and keep only final
-  // state. Resonances will have positive status code after this step.
-  omitResonanceDecays(eventProcessOrig, true);
-  eventProcess = workEvent;
-
-  // Sort original process final state into light/heavy jets and 'other'.
-  // Criteria:
-  //   1 <= ID <= 5 and massless, or ID == 21 --> light jet (typeIdx[0])
-  //   4 <= ID <= 6 and massive               --> heavy jet (typeIdx[1])
-  //   All else                               --> other     (typeIdx[2])
-  // Note that 'typeIdx' stores indices into 'eventProcess' (after resonance
-  // decays are omitted), while 'typeSet' stores indices into the original
-  // process record, 'eventProcessOrig', but these indices are also valid
-  // in 'event'.
-  for (int i = 0; i < 3; i++) {
-    typeIdx[i].clear();
-    typeSet[i].clear();
-  }
-  for (int i = 0; i < eventProcess.size(); i++) {
-    // Ignore nonfinal and default to 'other'
-    if (!eventProcess[i].isFinal()) continue;
-    int idx = 2;
-
-    // Light jets
-    if (eventProcess[i].id() == 21 || (eventProcess[i].idAbs() <= 5 &&
-        abs(eventProcess[i].m()) < ZEROTHRESHOLD))
-      idx = 0;
-
-    // Heavy jets
-    else if (eventProcess[i].idAbs() >= 4 && eventProcess[i].idAbs() <= 6)
-      idx = 1;
-
-    // Store
-    typeIdx[idx].push_back(i);
-    typeSet[idx].insert(eventProcess[i].daughter1());
-  }
-
-  // Extract partons from hardest subsystem + ISR + FSR only into
-  // workEvent. Note no resonance showers or MPIs.
-  subEvent(event);
-}
-
-//--------------------------------------------------------------------------
-
-// Step (2a): pick which particles to pass to the jet algorithm
-
-void MLMhooks::jetAlgorithmInput(const Event &event, int iType) {
-
-  // Take input from 'workEvent' and put output in 'workEventJet'
-  workEventJet = workEvent;
-
-  // Loop over particles and decide what to pass to the jet algorithm
-  for (int i = 0; i < workEventJet.size(); ++i) {
-    if (!workEventJet[i].isFinal()) continue;
-
-    // jetAllow option to disallow certain particle types
-    if (jetAllow == 1) {
-
-      // Original AG+Py6 algorithm explicitly excludes tops,
-      // leptons and photons.
-      int id = workEventJet[i].idAbs();
-      if ((id >= 11 && id <= 16) || id == 6 || id == 22) {
-        workEventJet[i].statusNeg();
-        continue;
-      }
-    }
-
-    // Get the index of this particle in original event
-    int idx = workEventJet[i].daughter1();
-
-    // Start with particle idx, and afterwards track mothers
-    while (true) {
-
-      // Light jets
-      if (iType == 0) {
-
-        // Do not include if originates from heavy jet or 'other'
-        if (typeSet[1].find(idx) != typeSet[1].end() ||
-            typeSet[2].find(idx) != typeSet[2].end()) {
-          workEventJet[i].statusNeg();
-          break;
-        }
-
-        // Made it to start of event record so done
-        if (idx == 0) break;
-        // Otherwise next mother and continue
-        idx = event[idx].mother1();
-
-      // Heavy jets
-      } else if (iType == 1) {
-
-        // Only include if originates from heavy jet
-        if (typeSet[1].find(idx) != typeSet[1].end()) break;
-
-        // Made it to start of event record with no heavy jet mother,
-        // so DO NOT include particle
-        if (idx == 0) {
-          workEventJet[i].statusNeg();
-          break;
-        }
-
-        // Otherwise next mother and continue
-        idx = event[idx].mother1();
-
-      } // if (iType)
-    } // while (true)
-  } // for (i)
-
-  // For jetMatch = 2, insert ghost particles corresponding to
-  // each hard parton in the original process
-  if (jetMatch == 2) {
-    for (int i = 0; i < int(typeIdx[iType].size()); i++) {
-      // Get y/phi of the parton
-      Vec4   pIn = eventProcess[typeIdx[iType][i]].p();
-      double y   = Vec4y(pIn);
-      double phi = pIn.phi();
-
-      // Create a ghost particle and add to the workEventJet
-      double e   = GHOSTENERGY;
-      double e2y = exp(2. * y);
-      double pz  = e * (e2y - 1.) / (e2y + 1.);
-      double pt  = sqrt(e*e - pz*pz);
-      double px  = pt * cos(phi);
-      double py  = pt * sin(phi);
-      workEventJet.append(Particle(21, 99, 0, 0, 0, 0, 0, 0,
-                                px, py, pz, e, 0., 0, 9.));
-
-      // Extra check on reconstructed y/phi values. If many warnings
-      // of this type, GHOSTENERGY may be set too low.
-#ifdef MLMCHECK
-      int lastIdx = workEventJet.size() - 1;
-      if (abs(y   - workEventJet[lastIdx].y())   > ZEROTHRESHOLD ||
-          abs(phi - workEventJet[lastIdx].phi()) > ZEROTHRESHOLD)
-        infoPtr->errorMsg("Warning in MLMhooks:jetAlgorithmInput: "
-            "ghost particle y/phi mismatch");
-#endif
-
-    } // for (i)
-  } // if (jetMatch == 2)
-}
-
-//--------------------------------------------------------------------------
-
-// Step (2b): run jet algorithm and provide common output
-
-void MLMhooks::runJetAlgorithm() {
-
-  // Run the jet clustering algorithm
-  if (jetAlgorithm == 1)
-    cellJet->analyze(workEventJet, eTjetMin, coneRadius, eTseed);
-  else
-    slowJet->analyze(workEventJet);
-
-  // Extract four-momenta of jets with |eta| < etaJetMax and
-  // put into jetMomenta. Note that this is done backwards as
-  // jets are removed with SlowJet.
-  jetMomenta.clear();
-  int iJet = (jetAlgorithm == 1) ? cellJet->size() - 1:
-                                   slowJet->sizeJet() - 1;
-  for (int i = iJet; i > -1; i--) {
-    Vec4 jetMom = (jetAlgorithm == 1) ? cellJet->pMassive(i) :
-                                        slowJet->p(i);
-    double eta = Vec4eta(jetMom);
-
-    if (abs(eta) > etaJetMax) {
-      if (jetAlgorithm == 2) slowJet->removeJet(i);
-      continue;
-    }
-    jetMomenta.push_back(jetMom);
-  }
-
-  // Reverse jetMomenta to restore eT/pT ordering
-  reverse(jetMomenta.begin(), jetMomenta.end());
-}
-
-//--------------------------------------------------------------------------
-
-// Step (2c): veto decision (returning true vetoes the event)
-
-bool MLMhooks::matchPartonsToJets(int iType) {
-
-  // Use two different routines for light/heavy jets as
-  // different veto conditions and for clarity
-  if (iType == 0) return (matchPartonsToJetsLight() > 0);
-  else            return (matchPartonsToJetsHeavy() > 0);
-}
-
-//--------------------------------------------------------------------------
-
-// Step(2c): light jets
-// Return codes are given indicating the reason for a veto.
-// Although not currently used, they are a useful debugging tool:
-//   0 = no veto
-//   1 = veto as number of jets less than number of partons
-//   2 = veto as exclusive mode and number of jets greater than
-//       number of partons
-//   3 = veto as inclusive mode and there would be an extra jet
-//       that is harder than any matched soft jet
-//   4 = veto as there is a parton which does not match a jet
-
-int MLMhooks::matchPartonsToJetsLight() {
-
-  // Always veto if number of jets is less than original number of jets
-  if (jetMomenta.size() < typeIdx[0].size()) return 1;
-  // Veto if in exclusive mode and number of jets bigger than original
-  if (exclusive && jetMomenta.size() > typeIdx[0].size()) return 2;
-
-  // Sort partons by eT/pT
-  sortTypeIdx(typeIdx[0]);
-
-  // Number of hard partons
-  int nParton = typeIdx[0].size();
-
-  // Keep track of which jets have been assigned a hard parton
-  vector < bool > jetAssigned;
-  jetAssigned.assign(jetMomenta.size(), false);
-
-  // Jet matching procedure: (1) deltaR between partons and jets
-  if (jetMatch == 1) {
-
-    // Loop over light hard partons and get 4-momentum
-    for (int i = 0; i < nParton; i++) {
-      Vec4 p1 = eventProcess[typeIdx[0][i]].p();
-
-      // Track which jet has the minimal dR measure with this parton
-      int    jMin  = -1;
-      double dRmin = 0.;
-
-      // Loop over all jets (skipping those already assigned).
-      for (int j = 0; j < int(jetMomenta.size()); j++) {
-        if (jetAssigned[j]) continue;
-
-        // DeltaR between parton/jet and store if minimum
-        double dR = (jetAlgorithm == 1) ?
-            deltaReta(p1, jetMomenta[j]) : deltaRy(p1, jetMomenta[j]);
-        if (jMin < 0 || dR < dRmin) {
-          dRmin = dR;
-          jMin  = j;
-        }
-      } // for (j)
-
-      // Check for jet-parton match
-      if (jMin >= 0 && dRmin < coneRadius * coneMatchLight) {
-
-        // If the matched jet is not one of the nParton hardest jets,
-        // the extra left over jet would be harder than some of the
-        // matched jets. This is disallowed, so veto.
-        if (jMin >= nParton) return 3;
-
-        // Mark jet as assigned.
-        jetAssigned[jMin] = true;
-
-      // If no match, then event will be vetoed in all cases
-      } else return 4;
-
-    } // for (i)
-
-  // Jet matching procedure: (2) ghost particles in SlowJet
-  } else {
-
-    // Loop over added 'ghost' particles and find if assigned to a jet
-    for (int i = workEventJet.size() - nParton;
-        i < workEventJet.size(); i++) {
-      int jMin = slowJet->jetAssignment(i);
-
-      // Veto if:
-      //  1) not one of nParton hardest jets
-      //  2) not assigned to a jet
-      //  3) jet has already been assigned
-      if (jMin >= nParton)               return 3;
-      if (jMin < 0 || jetAssigned[jMin]) return 4;
-
-      // Mark jet as assigned
-      jetAssigned[jMin] = true;
-
-    } // for (i)
-  } // if (jetMatch)
-
-  // Minimal eT/pT (CellJet/SlowJet) of matched light jets. Needed
-  // later for heavy jet vetos in inclusive mode.
-  if (nParton > 0)
-    eTpTlightMin = (jetAlgorithm == 1) ? jetMomenta[nParton - 1].eT()
-                                       : jetMomenta[nParton - 1].pT();
-  else
-    eTpTlightMin = -1.;
-
-  // No veto
-  return 0;
-}
-
-//--------------------------------------------------------------------------
-
-// Step(2c): heavy jets
-// Return codes are given indicating the reason for a veto.
-// Although not currently used, they are a useful debugging tool:
-//   0 = no veto as there are no extra jets present
-//   1 = veto as in exclusive mode and extra jets present
-//   2 = veto as in inclusive mode and extra jets were harder
-//       than any matched light jet
-
-int MLMhooks::matchPartonsToJetsHeavy() {
-
-  // If there are no extra jets, then accept
-  if (jetMomenta.empty()) return 0;
-
-  // Number of hard partons
-  int nParton = typeIdx[1].size();
-
-  // Remove jets that are close to heavy quarks
-  set < int > removeJets;
-
-  // Jet matching procedure: (1) deltaR between partons and jets
-  if (jetMatch == 1) {
-
-    // Loop over heavy hard partons and get 4-momentum
-    for (int i = 0; i < nParton; i++) {
-      Vec4 p1 = eventProcess[typeIdx[1][i]].p();
-
-      // Loop over all jets, find dR and mark for removal if match
-      for (int j = 0; j < int(jetMomenta.size()); j++) {
-        double dR = (jetAlgorithm == 1) ?
-            deltaReta(p1, jetMomenta[j]) : deltaRy(p1, jetMomenta[j]);
-        if (dR < coneRadiusHeavy * coneMatchHeavy)
-          removeJets.insert(j);
-
-      } // for (j)
-    } // for (i)
-
-  // Jet matching procedure: (2) ghost particles in SlowJet
-  } else {
-
-    // Loop over added 'ghost' particles and if assigned to a jet
-    // then mark this jet for removal
-    for (int i = workEventJet.size() - nParton;
-        i < workEventJet.size(); i++) {
-      int jMin = slowJet->jetAssignment(i);
-      if (jMin >= 0) removeJets.insert(jMin);
-    }
-      
-  }
-
-  // Remove jets (backwards order to not disturb indices)
-  for (set < int >::reverse_iterator it  = removeJets.rbegin();
-                                     it != removeJets.rend(); it++)
-    jetMomenta.erase(jetMomenta.begin() + *it);
-
-  // Handle case if there are still extra jets
-  if (!jetMomenta.empty()) {
-
-    // Exclusive mode, so immediate veto
-    if (exclusive) return 1;
-
-    // Inclusive mode; extra jets must be softer than any matched light jet
-    else if (eTpTlightMin >= 0.)
-      for (size_t j = 0; j < jetMomenta.size(); j++) {
-        // CellJet uses eT, SlowJet uses pT
-        if ( (jetAlgorithm == 1 && jetMomenta[j].eT() > eTpTlightMin) ||
-             (jetAlgorithm == 2 && jetMomenta[j].pT() > eTpTlightMin) )
-          return 2;
-      }
-
-  } // if (!jetMomenta.empty())
-
-  // No extra jets were present so no veto
-  return 0;
-}
-
-//==========================================================================
-
-#endif // MLMHOOKS_H