main01.cc


// main01.cc is a part of the PYTHIA event generator.
// Copyright (C) 2016 Torbjorn Sjostrand.
// PYTHIA is licenced under the GNU GPL version 2, see COPYING for details.
// Please respect the MCnet Guidelines, see GUIDELINES for details.
// This is a simple test program. It fits on one slide in a talk.
// It studies the charged multiplicity distribution at the LHC.
#include "Pythia8/Pythia.h"
using namespace Pythia8;
int main() {
  // Generator. Process selection. LHC initialization. Histogram.
  Pythia pythia;
  pythia.readString("Beams:eCM = 8000.");
  pythia.readString("HardQCD:all = on");
  pythia.readString("PhaseSpace:pTHatMin = 20.");
  pythia.init();
  Hist mult("charged multiplicity", 100, -0.5, 799.5);
  // Begin event loop. Generate event. Skip if error. List first one.
  for (int iEvent = 0; iEvent < 100; ++iEvent) {
    if (!pythia.next()) continue;
    // Find number of all final charged particles and fill histogram.
    int nCharged = 0;
    for (int i = 0; i < pythia.event.size(); ++i)
      if (pythia.event[i].isFinal() && pythia.event[i].isCharged())
        ++nCharged;
    mult.fill( nCharged );
  // End of event loop. Statistics. Histogram. Done.
  }
  pythia.stat();
  cout << mult;
  return 0;
}

main02.cc


// main02.cc is a part of the PYTHIA event generator.
// Copyright (C) 2016 Torbjorn Sjostrand.
// PYTHIA is licenced under the GNU GPL version 2, see COPYING for details.
// Please respect the MCnet Guidelines, see GUIDELINES for details.
// This is a simple test program. It fits on one slide in a talk.
// It studies the pT_Z spectrum at the Tevatron.
#include "Pythia8/Pythia.h"
using namespace Pythia8;
int main() {
  // Generator. Process selection. Tevatron initialization. Histogram.
  Pythia pythia;
  pythia.readString("Beams:idB = -2212");
  pythia.readString("Beams:eCM = 1960.");
  pythia.readString("WeakSingleBoson:ffbar2gmZ = on");
  pythia.readString("PhaseSpace:mHatMin = 80.");
  pythia.readString("PhaseSpace:mHatMax = 120.");
  pythia.init();
  Hist pTZ("dN/dpTZ", 100, 0., 100.);
  // Begin event loop. Generate event. Skip if error. List first one.
  for (int iEvent = 0; iEvent < 1000; ++iEvent) {
    if (!pythia.next()) continue;
    // Loop over particles in event. Find last Z0 copy. Fill its pT.
    int iZ = 0;
    for (int i = 0; i < pythia.event.size(); ++i)
      if (pythia.event[i].id() == 23) iZ = i;
    pTZ.fill( pythia.event[iZ].pT() );
  // End of event loop. Statistics. Histogram. Done.
  }
  pythia.stat();
  cout << pTZ;
  return 0;
}

main03.cc


// main03.cc is a part of the PYTHIA event generator.
// Copyright (C) 2016 Torbjorn Sjostrand.
// PYTHIA is licenced under the GNU GPL version 2, see COPYING for details.
// Please respect the MCnet Guidelines, see GUIDELINES for details.
// This is a simple test program.
// It illustrates how different processes can be selected and studied.
// All input is specified in the main03.cmnd file.
#include "Pythia8/Pythia.h"
using namespace Pythia8;
int main() {
  // Generator.
  Pythia pythia;
  // Shorthand for the event record in pythia.
  Event& event = pythia.event;
  // Read in commands from external file.
  pythia.readFile("main03.cmnd");
  // Extract settings to be used in the main program.
  int nEvent = pythia.mode("Main:numberOfEvents");
  int nAbort = pythia.mode("Main:timesAllowErrors");
  // Initialize.
  pythia.init();
  // Book histograms.
  Hist pThard("process pT scale", 100, 0., 500.);
  Hist nFinal("final particle multiplicity", 100, -0.5, 1599.5);
  Hist nCharged("charged particle multiplicity", 100, -0.5, 799.5);
  Hist dndy("dn/dy for charged particles", 100, -10., 10.);
  Hist dndeta("dn/d(eta) for charged particles", 100, -10., 10.);
  Hist dndpT("dn/dpT for charged particles", 100, 0., 10.);
  Hist epCons("deviation from energy-momentum conservation", 100, 0., 1e-6);
  // Begin event loop.
  int iAbort = 0;
  for (int iEvent = 0; iEvent < nEvent; ++iEvent) {
    // Generate events. Quit if many failures.
    if (!pythia.next()) {
      if (++iAbort < nAbort) continue;
      cout << " Event generation aborted prematurely, owing to error!\n";
      break;
    }
    // Fill hard scale of event.
    pThard.fill( pythia.info.pTHat() );
    // Loop over final particles in the event.
    int  nFin = 0;
    int  nChg = 0;
    Vec4 pSum;
    for (int i = 0; i < event.size(); ++i) if (event[i].isFinal()) {
       // Analyze all particles.
      nFin++;
      pSum += event[i].p();
      // Analyze charged particles and fill histograms.
      if (event[i].isCharged()) {
        ++nChg;
        dndy.fill( event[i].y() );
        dndeta.fill( event[i].eta() );
        dndpT.fill( event[i].pT() );
      }
    // End of particle loop. Fill global properties.
    }
    nFinal.fill( nFin );
    nCharged.fill( nChg );
    pSum /= event[0].e();
    double epDev = abs(pSum.e() - 1.) + abs(pSum.px()) + abs(pSum.py())
      + abs(pSum.pz());
    epCons.fill(epDev);
  // End of event loop.
  }
  // Final statistics. Normalize and output histograms.
  pythia.stat();
  dndy   *=  5. / nEvent;
  dndeta *=  5. / nEvent;
  dndpT  *= 10. / nEvent;
  cout << pThard << nFinal << nCharged << dndy << dndeta << dndpT << epCons;
  // Done.
  return 0;
}

main04.cc


// main04.cc is a part of the PYTHIA event generator.
// Copyright (C) 2016 Torbjorn Sjostrand.
// PYTHIA is licenced under the GNU GPL version 2, see COPYING for details.
// Please respect the MCnet Guidelines, see GUIDELINES for details.
// This is a simple test program.
// It illustrates how to generate and study "total cross section" processes,
// i.e. elastic, single and double diffractive, and the "minimum-bias" rest.
// All input is specified in the main06.cmnd file.
// Note that the "total" cross section does NOT include
// the Coulomb contribution to elastic scattering, as switched on here.
#include "Pythia8/Pythia.h"
using namespace Pythia8;
//==========================================================================
int main() {
  // Generator. Shorthand for the event.
  Pythia pythia;
  Event& event = pythia.event;
  // Read in commands from external file.
  pythia.readFile("main04.cmnd");
  // Extract settings to be used in the main program.
  int    nEvent    = pythia.mode("Main:numberOfEvents");
  int    nAbort    = pythia.mode("Main:timesAllowErrors");
  // Initialize.
  pythia.init();
  // Book histograms: multiplicities and mean transverse momenta.
  Hist yChg("rapidity of charged particles; all",      100, -10., 10.);
  Hist nChg("number of charged particles; all",        100, -0.5, 799.5);
  Hist nChgSD("number of charged particles; single diffraction",
                                                       100, -0.5, 799.5);
  Hist nChgDD("number of charged particles, double diffractive",
                                                       100, -0.5, 799.5);
  Hist nChgCD("number of charged particles, central diffractive",
                                                       100, -0.5, 799.5);
  Hist nChgND("number of charged particles, non-diffractive",
                                                       100, -0.5, 799.5);
  Hist pTnChg("<pt>(n_charged) all",                   100, -0.5, 799.5);
  Hist pTnChgSD("<pt>(n_charged) single diffraction",  100, -0.5, 799.5);
  Hist pTnChgDD("<pt>(n_charged) double diffraction",  100, -0.5, 799.5);
  Hist pTnChgCD("<pt>(n_charged) central diffraction", 100, -0.5, 799.5);
  Hist pTnChgND("<pt>(n_charged) non-diffractive   ",  100, -0.5, 799.5);
  // Book histograms: ditto as function of separate subsystem mass.
  Hist mLogInel("log10(mass), by diffractive system",  100, 0., 5.);
  Hist nChgmLog("<n_charged>(log10(mass))",            100, 0., 5.);
  Hist pTmLog("<pT>_charged>(log10(mass))",            100, 0., 5.);
  // Book histograms: elastic/diffractive.
  Hist tSpecEl("elastic |t| spectrum",              100, 0., 1.);
  Hist tSpecElLog("elastic log10(|t|) spectrum",    100, -5., 0.);
  Hist tSpecSD("single diffractive |t| spectrum",   100, 0., 2.);
  Hist tSpecDD("double diffractive |t| spectrum",   100, 0., 5.);
  Hist tSpecCD("central diffractive |t| spectrum",  100, 0., 5.);
  Hist mSpec("diffractive mass spectrum",           100, 0., 100.);
  Hist mLogSpec("log10(diffractive mass spectrum)", 100, 0., 4.);
  // Book histograms: inelastic nondiffractive.
  double pTmax = 20.;
  double bMax  = 4.;
  Hist pTspec("total pT_hard spectrum",             100, 0., pTmax);
  Hist pTspecND("nondiffractive pT_hard spectrum",  100, 0., pTmax);
  Hist bSpec("b impact parameter spectrum",         100, 0., bMax);
  Hist enhanceSpec("b enhancement spectrum",        100, 0., 10.);
  Hist number("number of interactions",             100, -0.5, 99.5);
  Hist pTb1("pT spectrum for b < 0.5",              100, 0., pTmax);
  Hist pTb2("pT spectrum for 0.5 < b < 1",          100, 0., pTmax);
  Hist pTb3("pT spectrum for 1 < b < 1.5",          100, 0., pTmax);
  Hist pTb4("pT spectrum for 1.5 < b",              100, 0., pTmax);
  Hist bpT1("b spectrum for pT < 2",                100, 0., bMax);
  Hist bpT2("b spectrum for 2 < pT < 5",            100, 0., bMax);
  Hist bpT3("b spectrum for 5 < pT < 15",           100, 0., bMax);
  Hist bpT4("b spectrum for 15 < pT",               100, 0., bMax);
  // Begin event loop.
  int iAbort = 0;
  for (int iEvent = 0; iEvent < nEvent; ++iEvent) {
    // Generate events. Quit if too many failures.
    if (!pythia.next()) {
      if (++iAbort < nAbort) continue;
      cout << " Event generation aborted prematurely, owing to error!\n";
      break;
    }
    // Extract event classification.
    int code = pythia.info.code();
    // Charged multiplicity and mean pT: all and by event class.
    int nch = 0;
    double pTsum = 0.;
    for (int i = 1; i < event.size(); ++i)
    if (event[i].isFinal() && event[i].isCharged()) {
      yChg.fill( event[i].y() );
      ++nch;
      pTsum += event[i].pT();
    }
    nChg.fill( nch );
    if (nch > 0) pTnChg.fill( nch, pTsum/nch);
    if (code == 103 || code == 104) {
      nChgSD.fill( nch );
      if (nch > 0) pTnChgSD.fill( nch, pTsum/nch);
    } else if (code == 105) {
      nChgDD.fill( nch );
      if (nch > 0) pTnChgDD.fill( nch, pTsum/nch);
    } else if (code == 106) {
      nChgCD.fill( nch );
      if (nch > 0) pTnChgCD.fill( nch, pTsum/nch);
    } else if (code == 101) {
      nChgND.fill( nch );
      if (nch > 0) pTnChgND.fill( nch, pTsum/nch);
      double mLog = log10( event[0].m() );
      mLogInel.fill( mLog );
      nChgmLog.fill( mLog, nch );
      if (nch > 0) pTmLog.fill( mLog, pTsum / nch );
    }
    // Charged multiplicity and mean pT: per diffractive system.
    for (int iDiff = 0; iDiff < 3; ++iDiff)
    if ( (iDiff == 0 && pythia.info.isDiffractiveA())
      || (iDiff == 1 && pythia.info.isDiffractiveB())
      || (iDiff == 2 && pythia.info.isDiffractiveC()) ) {
      int ndiff = 0;
      double pTdiff = 0.;
      int nDoc = (iDiff < 2) ? 4 : 5;
      for (int i = nDoc + 1; i < event.size(); ++i)
      if (event[i].isFinal() && event[i].isCharged()) {
        // Trace back final particle to see which system it comes from.
        int k = i;
        do k = event[k].mother1();
        while (k > nDoc);
        if (k == iDiff + 3) {
          ++ndiff;
          pTdiff += event[i].pT();
        }
      }
      // Study diffractive mass spectrum.
      double mDiff = event[iDiff+3].m();
      double mLog  = log10( mDiff);
      mLogInel.fill( mLog );
      nChgmLog.fill( mLog, ndiff );
      if (ndiff > 0) pTmLog.fill( mLog, pTdiff / ndiff );
      mSpec.fill( mDiff );
      mLogSpec.fill( mLog );
    }
    // Study pT spectrum of all hard collisions, no distinction.
    double pT = pythia.info.pTHat();
    pTspec.fill( pT );
    // Study t distribution of elastic/diffractive events.
    if (code > 101) {
      double tAbs = abs(pythia.info.tHat());
      if (code == 102) {
        tSpecEl.fill(tAbs);
        tSpecElLog.fill(log10(tAbs));
      }
      else if (code == 103 || code == 104) tSpecSD.fill(tAbs);
      else if (code == 105) tSpecDD.fill(tAbs);
      else if (code == 106) {
        double t1Abs = abs( (event[3].p() - event[1].p()).m2Calc() );
        double t2Abs = abs( (event[4].p() - event[2].p()).m2Calc() );
        tSpecCD.fill(t1Abs);
        tSpecCD.fill(t2Abs);
      }
    // Study nondiffractive inelastic events in (pT, b) space.
    } else {
      double b = pythia.info.bMPI();
      double enhance = pythia.info.enhanceMPI();
      int nMPI = pythia.info.nMPI();
      pTspecND.fill( pT );
      bSpec.fill( b );
      enhanceSpec.fill( enhance );
      number.fill( nMPI );
      if (b < 0.5) pTb1.fill( pT );
      else if (b < 1.0) pTb2.fill( pT );
      else if (b < 1.5) pTb3.fill( pT );
      else pTb4.fill( pT );
      if (pT < 2.) bpT1.fill( b );
      else if (pT < 5.) bpT2.fill( b );
      else if (pT < 15.) bpT3.fill( b );
      else bpT4.fill( b );
    }
  // End of event loop.
  }
  // Final statistics and histograms.
  pythia.stat();
  pTnChg   /= nChg;
  pTnChgSD /= nChgSD;
  pTnChgDD /= nChgDD;
  pTnChgCD /= nChgCD;
  pTnChgND /= nChgND;
  nChgmLog /= mLogInel;
  pTmLog   /= mLogInel;
  cout << yChg << nChg << nChgSD << nChgDD << nChgCD << nChgND
       << pTnChg << pTnChgSD << pTnChgDD << pTnChgCD << pTnChgND
       << mLogInel << nChgmLog << pTmLog
       << tSpecEl << tSpecElLog << tSpecSD << tSpecDD << tSpecCD
       << mSpec << mLogSpec
       << pTspec << pTspecND << bSpec << enhanceSpec << number
       << pTb1 << pTb2 << pTb3 << pTb4 << bpT1 << bpT2 << bpT3 << bpT4;
  // Done.
  return 0;
}

main05.cc


// main05.cc is a part of the PYTHIA event generator.
// Copyright (C) 2016 Torbjorn Sjostrand.
// PYTHIA is licenced under the GNU GPL version 2, see COPYING for details.
// Please respect the MCnet Guidelines, see GUIDELINES for details.
// This is a simple test program.
// It studies jet production at the LHC, using SlowJet and CellJet.
// Note: the two finders are intended to construct approximately the same
// jet properties, but provides output in slightly different format,
// and have here not been optimized to show maximum possible agreement.
#include "Pythia8/Pythia.h"
using namespace Pythia8;
int main() {
  // Number of events, generated and listed ones.
  int nEvent    = 500;
  int nListJets = 5;
  // Generator. LHC process and output selection. Initialization.
  Pythia pythia;
  pythia.readString("Beams:eCM = 14000.");
  pythia.readString("HardQCD:all = on");
  pythia.readString("PhaseSpace:pTHatMin = 200.");
  pythia.readString("Next:numberShowInfo = 0");
  pythia.readString("Next:numberShowProcess = 0");
  pythia.readString("Next:numberShowEvent = 0");
  pythia.init();
  // Common parameters for the two jet finders.
  double etaMax   = 4.;
  double radius   = 0.7;
  double pTjetMin = 10.;
  // Exclude neutrinos (and other invisible) from study.
  int    nSel     = 2;
  // Range and granularity of CellJet jet finder.
  int    nEta     = 80;
  int    nPhi     = 64;
  // Set up SlowJet jet finder, with anti-kT clustering
  // and pion mass assumed for non-photons..
  SlowJet slowJet( -1, radius, pTjetMin, etaMax, nSel, 1);
  // Set up CellJet jet finder.
  CellJet cellJet( etaMax, nEta, nPhi, nSel);
  // Histograms. Note similarity in names, even when the two jet finders
  // do not calculate identically the same property (pT vs. ET, y vs. eta).
  Hist nJetsS("number of jets, SlowJet", 50, -0.5, 49.5);
  Hist nJetsC("number of jets, CellJet", 50, -0.5, 49.5);
  Hist nJetsD("number of jets, CellJet - SlowJet", 45, -22.5, 22.5);
  Hist eTjetsS("pT for jets, SlowJet", 100, 0., 500.);
  Hist eTjetsC("eT for jets, CellJet", 100, 0., 500.);
  Hist etaJetsS("y for jets, SlowJet", 100, -5., 5.);
  Hist etaJetsC("eta for jets, CellJet", 100, -5., 5.);
  Hist phiJetsS("phi for jets, SlowJwt", 100, -M_PI, M_PI);
  Hist phiJetsC("phi for jets, CellJet", 100, -M_PI, M_PI);
  Hist distJetsS("R distance between jets, SlowJet", 100, 0., 10.);
  Hist distJetsC("R distance between jets, CellJet", 100, 0., 10.);
  Hist eTdiffS("pT difference, SlowJet", 100, -100., 400.);
  Hist eTdiffC("eT difference, CellJet", 100, -100., 400.);
  // Begin event loop. Generate event. Skip if error.
  for (int iEvent = 0; iEvent < nEvent; ++iEvent) {
    if (!pythia.next()) continue;
    // Analyze Slowet jet properties. List first few.
    slowJet. analyze( pythia.event );
    if (iEvent < nListJets) slowJet.list();
    // Fill SlowJet inclusive jet distributions.
    nJetsS.fill( slowJet.sizeJet() );
    for (int i = 0; i < slowJet.sizeJet(); ++i) {
      eTjetsS.fill( slowJet.pT(i) );
      etaJetsS.fill( slowJet.y(i) );
      phiJetsS.fill( slowJet.phi(i) );
    }
    // Fill SlowJet distance between jets.
    for (int i = 0; i < slowJet.sizeJet() - 1; ++i)
    for (int j = i +1; j < slowJet.sizeJet(); ++j) {
      double dEta = slowJet.y(i) - slowJet.y(j);
      double dPhi = abs( slowJet.phi(i) - slowJet.phi(j) );
      if (dPhi > M_PI) dPhi = 2. * M_PI - dPhi;
      double dR = sqrt( pow2(dEta) + pow2(dPhi) );
      distJetsS.fill( dR );
    }
    // Fill SlowJet pT-difference between jets (to check ordering of list).
    for (int i = 1; i < slowJet.sizeJet(); ++i)
      eTdiffS.fill( slowJet.pT(i-1) - slowJet.pT(i) );
    // Analyze CellJet jet properties. List first few.
    cellJet. analyze( pythia.event, pTjetMin, radius );
    if (iEvent < nListJets) cellJet.list();
    // Fill CellJet inclusive jet distributions.
    nJetsC.fill( cellJet.size() );
    for (int i = 0; i < cellJet.size(); ++i) {
      eTjetsC.fill( cellJet.eT(i) );
      etaJetsC.fill( cellJet.etaWeighted(i) );
      phiJetsC.fill( cellJet.phiWeighted(i) );
    }
    // Fill CellJet distance between jets.
    for (int i = 0; i < cellJet.size() - 1; ++i)
    for (int j = i +1; j < cellJet.size(); ++j) {
      double dEta = cellJet.etaWeighted(i)
        - cellJet.etaWeighted(j);
      double dPhi = abs( cellJet.phiWeighted(i)
        - cellJet.phiWeighted(j) );
      if (dPhi > M_PI) dPhi = 2. * M_PI - dPhi;
      double dR = sqrt( pow2(dEta) + pow2(dPhi) );
      distJetsC.fill( dR );
    }
    // Fill CellJet ET-difference between jets (to check ordering of list).
    for (int i = 1; i < cellJet.size(); ++i)
      eTdiffC.fill( cellJet.eT(i-1) - cellJet.eT(i) );
    // Compare number of jets for the two finders.
    nJetsD.fill( cellJet.size() - slowJet.sizeJet() );
  // End of event loop. Statistics. Histograms.
  }
  pythia.stat();
  cout << nJetsS << nJetsC << nJetsD << eTjetsS << eTjetsC
       << etaJetsS << etaJetsC << phiJetsS << phiJetsC
       << distJetsS << distJetsC << eTdiffS << eTdiffC;
  // Done.
  return 0;
}

main06.cc


// main06.cc is a part of the PYTHIA event generator.
// Copyright (C) 2016 Torbjorn Sjostrand.
// PYTHIA is licenced under the GNU GPL version 2, see COPYING for details.
// Please respect the MCnet Guidelines, see GUIDELINES for details.
// This is a simple test program.
// It studies event properties of LEP1 events.
#include "Pythia8/Pythia.h"
using namespace Pythia8;
int main() {
  // Generator.
  Pythia pythia;
  // Allow no substructure in e+- beams: normal for corrected LEP data.
  pythia.readString("PDF:lepton = off");
  // Process selection.
  pythia.readString("WeakSingleBoson:ffbar2gmZ = on");
  // Switch off all Z0 decays and then switch back on those to quarks.
  pythia.readString("23:onMode = off");
  pythia.readString("23:onIfAny = 1 2 3 4 5");
  // LEP1 initialization at Z0 mass.
  pythia.readString("Beams:idA =  11");
  pythia.readString("Beams:idB = -11");
  double mZ = pythia.particleData.m0(23);
  pythia.settings.parm("Beams:eCM", mZ);
  pythia.init();
  // Histograms.
  Hist nCharge("charged multiplicity", 100, -0.5, 99.5);
  Hist spheri("Sphericity", 100, 0., 1.);
  Hist linea("Linearity", 100, 0., 1.);
  Hist thrust("thrust", 100, 0.5, 1.);
  Hist oblateness("oblateness", 100, 0., 1.);
  Hist sAxis("cos(theta_Sphericity)", 100, -1., 1.);
  Hist lAxis("cos(theta_Linearity)", 100, -1., 1.);
  Hist tAxis("cos(theta_Thrust)", 100, -1., 1.);
  Hist nLund("Lund jet multiplicity", 40, -0.5, 39.5);
  Hist nJade("Jade jet multiplicity", 40, -0.5, 39.5);
  Hist nDurham("Durham jet multiplicity", 40, -0.5, 39.5);
  Hist eDifLund("Lund e_i - e_{i+1}", 100, -5.,45.);
  Hist eDifJade("Jade e_i - e_{i+1}", 100, -5.,45.);
  Hist eDifDurham("Durham e_i - e_{i+1}", 100, -5.,45.);
  // Set up Sphericity, "Linearity", Thrust and cluster jet analyses.
  Sphericity sph;
  Sphericity lin(1.);
  Thrust thr;
  ClusterJet lund("Lund");
  ClusterJet jade("Jade");
  ClusterJet durham("Durham");
  // Begin event loop. Generate event. Skip if error. List first few.
  for (int iEvent = 0; iEvent < 10000; ++iEvent) {
    if (!pythia.next()) continue;
    // Find and histogram charged multiplicity.
    int nCh = 0;
    for (int i = 0; i < pythia.event.size(); ++i)
      if (pythia.event[i].isFinal() && pythia.event[i].isCharged()) ++nCh;
    nCharge.fill( nCh );
    // Find and histogram sphericity.
    if (sph.analyze( pythia.event )) {
      if (iEvent < 3) sph.list();
      spheri.fill( sph.sphericity() );
      sAxis.fill( sph.eventAxis(1).pz() );
      double e1 = sph.eigenValue(1);
      double e2 = sph.eigenValue(2);
      double e3 = sph.eigenValue(3);
      if (e2 > e1 || e3 > e2) cout << "eigenvalues out of order: "
      << e1 << "  " << e2 << "  " << e3 << endl;
    }
    // Find and histogram linearized sphericity.
    if (lin.analyze( pythia.event )) {
      if (iEvent < 3) lin.list();
      linea.fill( lin.sphericity() );
      lAxis.fill( lin.eventAxis(1).pz() );
      double e1 = lin.eigenValue(1);
      double e2 = lin.eigenValue(2);
      double e3 = lin.eigenValue(3);
      if (e2 > e1 || e3 > e2) cout << "eigenvalues out of order: "
      << e1 << "  " << e2 << "  " << e3 << endl;
    }
    // Find and histogram thrust.
    if (thr.analyze( pythia.event )) {
      if (iEvent < 3) thr.list();
      thrust.fill( thr.thrust() );
      oblateness.fill( thr.oblateness() );
      tAxis.fill( thr.eventAxis(1).pz() );
      if ( abs(thr.eventAxis(1).pAbs() - 1.) > 1e-8
        || abs(thr.eventAxis(2).pAbs() - 1.) > 1e-8
        || abs(thr.eventAxis(3).pAbs() - 1.) > 1e-8
        || abs(thr.eventAxis(1) * thr.eventAxis(2)) > 1e-8
        || abs(thr.eventAxis(1) * thr.eventAxis(3)) > 1e-8
        || abs(thr.eventAxis(2) * thr.eventAxis(3)) > 1e-8 ) {
        cout << " suspicious Thrust eigenvectors " << endl;
        thr.list();
      }
    }
    // Find and histogram cluster jets: Lund, Jade and Durham distance.
    if (lund.analyze( pythia.event, 0.01, 0.)) {
      if (iEvent < 3) lund.list();
      nLund.fill( lund.size() );
      for (int j = 0; j < lund.size() - 1; ++j)
        eDifLund.fill( lund.p(j).e() - lund.p(j+1).e() );
    }
    if (jade.analyze( pythia.event, 0.01, 0.)) {
      if (iEvent < 3) jade.list();
      nJade.fill( jade.size() );
      for (int j = 0; j < jade.size() - 1; ++j)
        eDifJade.fill( jade.p(j).e() - jade.p(j+1).e() );
    }
    if (durham.analyze( pythia.event, 0.01, 0.)) {
      if (iEvent < 3) durham.list();
      nDurham.fill( durham.size() );
      for (int j = 0; j < durham.size() - 1; ++j)
        eDifDurham.fill( durham.p(j).e() - durham.p(j+1).e() );
    }
  // End of event loop. Statistics. Output histograms.
  }
  pythia.stat();
  cout << nCharge << spheri << linea << thrust << oblateness
       << sAxis << lAxis << tAxis
       << nLund << nJade << nDurham
       << eDifLund << eDifJade << eDifDurham;
  // Done.
  return 0;
}

main07.cc


// main07.cc is a part of the PYTHIA event generator.
// Copyright (C) 2016 Torbjorn Sjostrand.
// PYTHIA is licenced under the GNU GPL version 2, see COPYING for details.
// Please respect the MCnet Guidelines, see GUIDELINES for details.
// Illustration how to generate various two-body channels from
// astroparticle processes, e.g. neutralino annihilation or decay.
// To this end a "blob" of energy is created with unit cross section,
// from the fictitious collision of two non-radiating incoming e+e-.
// In the accompanying main29.cmnd file the decay channels of this
// blob can be set up. Furthermore, only gamma, e+-, p/pbar and
// neutrinos are stable, everything else is set to decay.
// (The "single-particle gun" of main21.cc offers another possible
// approach to the same problem.)
#include "Pythia8/Pythia.h"
using namespace Pythia8;
//==========================================================================
// A derived class for (e+ e- ->) GenericResonance -> various final states.
class Sigma1GenRes : public Sigma1Process {
public:
  // Constructor.
  Sigma1GenRes() {}
  // Evaluate sigmaHat(sHat): dummy unit cross section.
  virtual double sigmaHat() {return 1.;}
  // Select flavour. No colour or anticolour.
  virtual void setIdColAcol() {setId( -11, 11, 999999);
    setColAcol( 0, 0, 0, 0, 0, 0);}
  // Info on the subprocess.
  virtual string name()    const {return "GenericResonance";}
  virtual int    code()    const {return 9001;}
  virtual string inFlux()  const {return "ffbarSame";}
};
//==========================================================================
int main() {
  // Pythia generator.
  Pythia pythia;
  // A class to generate the fictitious resonance initial state.
  SigmaProcess* sigma1GenRes = new Sigma1GenRes();
  // Hand pointer to Pythia.
  pythia.setSigmaPtr( sigma1GenRes);
  // Read in the rest of the settings and data from a separate file.
  pythia.readFile("main07.cmnd");
  // Initialization.
  pythia.init();
  // Extract settings to be used in the main program.
  int nEvent  = pythia.mode("Main:numberOfEvents");
  int nAbort  = pythia.mode("Main:timesAllowErrors");
  // Histogram particle spectra.
  Hist eGamma("energy spectrum of photons",        100, 0., 250.);
  Hist eE(    "energy spectrum of e+ and e-",      100, 0., 250.);
  Hist eP(    "energy spectrum of p and pbar",     100, 0., 250.);
  Hist eNu(   "energy spectrum of neutrinos",      100, 0., 250.);
  Hist eRest( "energy spectrum of rest particles", 100, 0., 250.);
  // Begin event loop.
  int iAbort = 0;
  for (int iEvent = 0; iEvent < nEvent; ++iEvent) {
    // Generate events. Quit if many failures.
    if (!pythia.next()) {
      if (++iAbort < nAbort) continue;
      cout << " Event generation aborted prematurely, owing to error!\n";
      break;
    }
    // Loop over all particles and analyze the final-state ones.
    for (int i = 0; i < pythia.event.size(); ++i)
    if (pythia.event[i].isFinal()) {
      int idAbs = pythia.event[i].idAbs();
      double eI = pythia.event[i].e();
      if (idAbs == 22) eGamma.fill(eI);
      else if (idAbs == 11) eE.fill(eI);
      else if (idAbs == 2212) eP.fill(eI);
      else if (idAbs == 12 || idAbs == 14 || idAbs == 16) eNu.fill(eI);
      else {
        eRest.fill(eI);
        cout << " Error: stable id = " << pythia.event[i].id() << endl;
      }
    }
  // End of event loop.
  }
  // Final statistics and histograms.
  pythia.stat();
  cout << eGamma << eE << eP << eNu << eRest;
  // Done.
  delete sigma1GenRes;
  return 0;
}

main08.cc


// main08.cc is a part of the PYTHIA event generator.
// Copyright (C) 2016 Torbjorn Sjostrand.
// PYTHIA is licenced under the GNU GPL version 2, see COPYING for details.
// Please respect the MCnet Guidelines, see GUIDELINES for details.
// This is a simple test program.
// It illustrates methods to emphasize generation at high pT.
#include "Pythia8/Pythia.h"
using namespace Pythia8;
int main() {
  // Different modes are illustrated for setting the pT ranges.
  // 1 : Hardcoded in the main program.
  // 2 : Using the Main:subrun keyword in a separate command file.
  // A third method instead biases selection continuously.
  // 3 : Bias high-pT selection by a pT^4 factor.
  // Matching also to low-pT processes is more complicated.
  // 4 : Matching between low- and high-pT. (No diffraction.)
  // 5: As 4, but bias high-pT selection by a pT^4 factor.
  int mode = 5;
  // Number of events to generate per bin.
  int nEvent = 10000;
  // One does not need complete events to study pThard spectrum only.
  bool completeEvents = false;
  // Optionally minimize output (almost) to final results.
  bool smallOutput = true;
  // Book histograms.
  int nRange = 100;
  double pTrange = (mode < 4) ? 1000. : 100.;
  Hist pTraw("pTHat distribution, unweighted", nRange, 0., pTrange);
  Hist pTnorm("pTHat distribution, weighted", nRange, 0., pTrange);
  Hist pTpow3("pTHat distribution, pT3*weighted", nRange, 0., pTrange);
  Hist pTpow5("pTHat distribution, pT5*weighted", nRange, 0., pTrange);
  Hist pTnormPart("pTHat distribution, weighted", nRange, 0., pTrange);
  Hist pTpow3Part("pTHat distribution, pT3*weighted", nRange, 0., pTrange);
  Hist pTpow5Part("pTHat distribution, pT5*weighted", nRange, 0., pTrange);
  // Generator.
  Pythia pythia;
  // Shorthand for some public members of pythia (also static ones).
  Settings& settings = pythia.settings;
  Info& info = pythia.info;
  // Optionally limit output to minimal one.
  if (smallOutput) {
    pythia.readString("Init:showProcesses = off");
    pythia.readString("Init:showMultipartonInteractions = off");
    pythia.readString("Init:showChangedSettings = off");
    pythia.readString("Init:showChangedParticleData = off");
    pythia.readString("Next:numberCount = 1000000000");
    pythia.readString("Next:numberShowInfo = 0");
    pythia.readString("Next:numberShowProcess = 0");
    pythia.readString("Next:numberShowEvent = 0");
  }
  // Number of bins to use. In mode 2 read from main08.cmnd file.
  int nBin = 5;
  if (mode == 2) {
    pythia.readFile("main08.cmnd");
    nBin = pythia.mode("Main:numberOfSubruns");
  }
  else if (mode == 3) nBin = 1;
  else if (mode == 4) nBin = 4;
  else if (mode == 5) nBin = 2;
  // Mode 1: set up five pT bins - last one open-ended.
  double pTlimit[6] = {100., 150., 250., 400., 600., 0.};
  // Modes 4 & 5: set up pT bins for range [0, 100]. The lowest bin
  // is generated with soft processes, to regularize pT -> 0 blowup.
  // Warning: if pTlimitLow[1] is picked too low there will be a
  // visible discontinuity, since soft processes are generated with
  // dampening and "Sudakov" for pT -> 0, while hard processes are not.
  double pTlimitLow[6] = {0., 20., 40., 70., 100.};
  double pTlimitTwo[3] = {0., 20., 100.};
  // Loop over number of bins, i.e. number of subruns.
  for (int iBin = 0; iBin < nBin; ++iBin) {
    // Normally HardQCD, but in two cases nonDiffractive.
    // Need MPI on in nonDiffractive to get first interaction, but not else.
    if (mode > 3 && iBin == 0) {
      pythia.readString("HardQCD:all = off");
      pythia.readString("SoftQCD:nonDiffractive = on");
      if (!completeEvents) {
      pythia.readString("PartonLevel:all = on");
        pythia.readString("PartonLevel:ISR = off");
        pythia.readString("PartonLevel:FSR = off");
        pythia.readString("HadronLevel:all = off");
      }
    } else {
      pythia.readString("HardQCD:all = on");
      pythia.readString("SoftQCD:nonDiffractive = off");
      if (!completeEvents) pythia.readString("PartonLevel:all = off");
    }
    // Mode 1: hardcoded here. Use settings.parm for non-string input.
    if (mode == 1) {
      settings.parm("PhaseSpace:pTHatMin", pTlimit[iBin]);
      settings.parm("PhaseSpace:pTHatMax", pTlimit[iBin + 1]);
    }
    // Mode 2: subruns stored in the main08.cmnd file.
    else if (mode == 2) pythia.readFile("main08.cmnd", iBin);
    // Mode 3: The whole range in one step, but pT-weighted.
    else if (mode == 3) {
      settings.parm("PhaseSpace:pTHatMin", pTlimit[0]);
      settings.parm("PhaseSpace:pTHatMax", 0.);
      pythia.readString("PhaseSpace:bias2Selection = on");
      pythia.readString("PhaseSpace:bias2SelectionPow = 4.");
      pythia.readString("PhaseSpace:bias2SelectionRef = 100.");
    }
    // Mode 4: hardcoded here. Use settings.parm for non-string input.
    else if (mode == 4) {
      settings.parm("PhaseSpace:pTHatMin", pTlimitLow[iBin]);
      settings.parm("PhaseSpace:pTHatMax", pTlimitLow[iBin + 1]);
    }
    // Mode 5: hardcoded here. Use settings.parm for non-string input.
    // Hard processes in one step, but pT-weighted.
    else if (mode == 5) {
      settings.parm("PhaseSpace:pTHatMin", pTlimitTwo[iBin]);
      settings.parm("PhaseSpace:pTHatMax", pTlimitTwo[iBin + 1]);
      if (iBin == 1) {
        pythia.readString("PhaseSpace:bias2Selection = on");
        pythia.readString("PhaseSpace:bias2SelectionPow = 4.");
        pythia.readString("PhaseSpace:bias2SelectionRef = 20.");
      }
    }
    // Initialize for LHC at 14 TeV.
    pythia.readString("Beams:eCM = 14000.");
    pythia.init();
    // Reset local histograms (that need to be rescaled before added).
    pTnormPart.null();
    pTpow3Part.null();
    pTpow5Part.null();
    // Begin event loop.
    for (int iEvent = 0; iEvent < nEvent; ++iEvent) {
      // Generate events. Skip if failure.
      if (!pythia.next()) continue;
      // Soft events have no upper pT limit. They therefore overlap
      // with hard events, and the overlap must be removed by hand.
      // No overlap for elastic/diffraction, which is only part of soft.
      double pTHat  = info.pTHat();
      if (mode > 3 && iBin == 0 && info.isNonDiffractive()
        && pTHat > pTlimitLow[1]) continue;
      // Fill hard scale of event.
      double weight = info.weight();
      pTraw.fill( pTHat );
      pTnormPart.fill( pTHat, weight);
      pTpow3Part.fill( pTHat, weight * pow3(pTHat) );
      pTpow5Part.fill( pTHat, weight * pow5(pTHat) );
    // End of event loop. Statistics.
    }
    if (!smallOutput) pythia.stat();
    // Normalize to cross section for each case, and add to sum.
    double sigmaNorm = (info.sigmaGen() / info.weightSum())
                     * (nRange / pTrange);
    pTnorm += sigmaNorm * pTnormPart;
    pTpow3 += sigmaNorm * pTpow3Part;
    pTpow5 += sigmaNorm * pTpow5Part;
  // End of pT-bin loop.
  }
  // Output histograms.
  cout << pTraw << pTnorm << pTpow3 << pTpow5;
  // Done.
  return 0;
}

main09.cc


// main09.cc is a part of the PYTHIA event generator.
// Copyright (C) 2016 Torbjorn Sjostrand.
// PYTHIA is licenced under the GNU GPL version 2, see COPYING for details.
// Please respect the MCnet Guidelines, see GUIDELINES for details.
// Generate a predetermined second hard interaction.
#include "Pythia8/Pythia.h"
using namespace Pythia8;
int main() {
  // Generator.
  Pythia pythia;
  Event& event   = pythia.event;
  // Select first hard process (just a small sample of possibilities).
  //pythia.readString("HardQCD:all = on");
  pythia.readString("Top:all = on");
  //pythia.readString("WeakSingleBoson:ffbar2gmZ = on");
  //pythia.readString("WeakSingleBoson:ffbar2W = on");
  // Select second hard process (complete list of options).
  pythia.readString("SecondHard:generate = on");
  //pythia.readString("SecondHard:TwoJets = on");
  pythia.readString("SecondHard:PhotonAndJet = on");
  //pythia.readString("SecondHard:TwoPhotons = on");
  //pythia.readString("SecondHard:SingleGmZ = on");
  //pythia.readString("SecondHard:SingleW = on");
  //pythia.readString("SecondHard:TwoBJets = on");
  // Kinematics cuts, common for the two.
  pythia.readString("PhaseSpace:mHatMin = 40.");
  pythia.readString("PhaseSpace:pTHatMin = 20.");
  // Initialize for LHC at 8 TeV.
  pythia.readString("Beams:eCM = 8000.");
  pythia.init();
  // Histogram.
  Hist pTfirst("pT first collision",    100, 0., 400.);
  Hist pTsecond("pT second collision",  100, 0., 200.);
  Hist pTdiff("pT first-second collision", 100, -100., 300.);
  Hist nMult("number of multiparton interactions", 100, -0.5, 99.5);
  Hist bMore("b enhancement factor",    100, 0., 10.);
  Hist nChg("charged multiplicity", 100, -0.5, 999.5);
  // Generate events.
  for (int iev = 0; iev < 1000; ++iev) {
    pythia.next();
    // Histogram pT.
    double pT1 = pythia.info.pTMPI(0);
    double pT2 = pythia.info.pTMPI(1);
    pTfirst.fill( pT1 );
    pTsecond.fill( pT2 );
    pTdiff.fill( pT1 - pT2 );
    // Histogram multiparton interactions
    double nMPI = pythia.info.nMPI();
    nMult.fill( nMPI );
    bMore.fill( pythia.info.enhanceMPI() );
    // Histogram charged multiplicity.
    int nCharged = 0;
    for (int i = 0; i < event.size(); ++i)
      if (event[i].isFinal() && event[i].isCharged()) ++nCharged;
    nChg.fill( nCharged );
  }
  // Compare full statistics listing with what is set in info.
  pythia.stat();
  cout << scientific << setprecision(3) << "\n From pythia.info: sigma = "
       << pythia.info.sigmaGen() << " +- " << pythia.info.sigmaErr()
       << endl;
  // Print histograms.
  cout << pTfirst << pTsecond << pTdiff << nMult << bMore << nChg;
  // Done.
  return 0;
}

main10.cc


// main10.cc is a part of the PYTHIA event generator.
// Copyright (C) 2016 Torbjorn Sjostrand.
// PYTHIA is licenced under the GNU GPL version 2, see COPYING for details.
// Please respect the MCnet Guidelines, see GUIDELINES for details.
// Example how you can use UserHooks to trace pT spectrum through program,
// and veto undesirable jet multiplicities.
#include "Pythia8/Pythia.h"
using namespace Pythia8;
//==========================================================================
// Put histograms here to make them global, so they can be used both
// in MyUserHooks and in the main program.
Hist pTtrial("trial pT spectrum", 100, 0., 400.);
Hist pTselect("selected pT spectrum (before veto)", 100, 0., 400.);
Hist pTaccept("accepted pT spectrum (after veto)", 100, 0., 400.);
Hist nPartonsB("number of partons before veto", 20, -0.5, 19.5);
Hist nJets("number of jets before veto", 20, -0.5, 19.5);
Hist nPartonsA("number of partons after veto", 20, -0.5, 19.5);
Hist nFSRatISR("number of FSR emissions at first ISR emission",
  20, -0.5, 19.5);
//==========================================================================
// Write own derived UserHooks class.
class MyUserHooks : public UserHooks {
public:
  // Constructor creates anti-kT jet finder with (-1, R, pTmin, etaMax).
  MyUserHooks() { slowJet = new SlowJet(-1, 0.7, 10., 5.); }
  // Destructor deletes anti-kT jet finder.
  ~MyUserHooks() {delete slowJet;}
  // Allow process cross section to be modified...
  virtual bool canModifySigma() {return true;}
  // ...which gives access to the event at the trial level, before selection.
  virtual double multiplySigmaBy(const SigmaProcess* sigmaProcessPtr,
    const PhaseSpace* phaseSpacePtr, bool inEvent) {
    // All events should be 2 -> 2, but kill them if not.
    if (sigmaProcessPtr->nFinal() != 2) return 0.;
    // Extract the pT for 2 -> 2 processes in the event generation chain
    // (inEvent = false for initialization).
    if (inEvent) {
      pTHat = phaseSpacePtr->pTHat();
      // Fill histogram of pT spectrum.
      pTtrial.fill( pTHat );
    }
    // Here we do not modify 2 -> 2 cross sections.
    return 1.;
  }
  // Allow a veto for the interleaved evolution in pT.
  virtual bool canVetoPT() {return true;}
  // Do the veto test at a pT scale of 5 GeV.
  virtual double scaleVetoPT() {return 5.;}
  // Access the event in the interleaved evolution.
  virtual bool doVetoPT(int iPos, const Event& event) {
    // iPos <= 3 for interleaved evolution; skip others.
    if (iPos > 3) return false;
    // Fill histogram of pT spectrum at this stage.
    pTselect.fill(pTHat);
    // Extract a copy of the partons in the hardest system.
    subEvent(event);
    nPartonsB.fill( workEvent.size() );
    // Find number of jets with given conditions.
    slowJet->analyze(event);
    int nJet = slowJet->sizeJet();
    nJets.fill( nJet );
    // Veto events which do not have exactly three jets.
    if (nJet != 3) return true;
    // Statistics of survivors.
    nPartonsA.fill( workEvent.size() );
    pTaccept.fill(pTHat);
    // Do not veto events that got this far.
    return false;
  }
  // Allow a veto after (by default) first step.
  virtual bool canVetoStep() {return true;}
  // Access the event in the interleaved evolution after first step.
  virtual bool doVetoStep( int iPos, int nISR, int nFSR, const Event& ) {
    // Only want to study what happens at first ISR emission
    if (iPos == 2 && nISR == 1) nFSRatISR.fill( nFSR );
    // Not intending to veto any events here.
    return false;
  }
private:
  // The anti-kT (or kT, C/A) jet finder.
  SlowJet* slowJet;
  // Save the pThat scale.
  double pTHat;
};
//==========================================================================
int main() {
  // Generator.
  Pythia pythia;
  //  Process selection. No need to study hadron level.
  pythia.readString("HardQCD:all = on");
  pythia.readString("PhaseSpace:pTHatMin = 50.");
  pythia.readString("HadronLevel:all = off");
  // Set up to do a user veto and send it in.
  MyUserHooks* myUserHooks = new MyUserHooks();
  pythia.setUserHooksPtr( myUserHooks);
  // Tevatron initialization.
  pythia.readString("Beams:idB = -2212");
  pythia.readString("Beams:eCM = 1960.");
  pythia.init();
  // Begin event loop.
  for (int iEvent = 0; iEvent < 1000; ++iEvent) {
    // Generate events.
    pythia.next();
  // End of event loop.
  }
  // Statistics. Histograms.
  pythia.stat();
  cout << pTtrial << pTselect << pTaccept
       << nPartonsB << nJets << nPartonsA
       << nFSRatISR;
  // Done.
  delete myUserHooks;
  return 0;
}

main11.cc


// main11.cc is a part of the PYTHIA event generator.
// Copyright (C) 2016 Torbjorn Sjostrand.
// PYTHIA is licenced under the GNU GPL version 2, see COPYING for details.
// Please respect the MCnet Guidelines, see GUIDELINES for details.
// This is a simple test program.
// It illustrates how Les Houches Event File input can be used in Pythia8.
// It uses the ttsample.lhe(.gz) input file, the latter only with 100 events.
#include "Pythia8/Pythia.h"
using namespace Pythia8;
int main() {
  // You can always read an plain LHE file,
  // but if you ran "./configure --with-gzip" before "make"
  // then you can also read a gzipped LHE file.
#ifdef GZIPSUPPORT
  bool useGzip = true;
#else
  bool useGzip = false;
#endif
  cout << " useGzip = " << useGzip << endl;
  // Generator. We here stick with default values, but changes
  // could be inserted with readString or readFile.
  Pythia pythia;
  // Initialize Les Houches Event File run. List initialization information.
  pythia.readString("Beams:frameType = 4");
  if (useGzip) pythia.readString("Beams:LHEF = ttbar.lhe.gz");
  else         pythia.readString("Beams:LHEF = ttbar.lhe");
  pythia.init();
  // Book histogram.
  Hist nCharged("charged particle multiplicity",100,-0.5,399.5);
  // Allow for possibility of a few faulty events.
  int nAbort = 10;
  int iAbort = 0;
  // Begin event loop; generate until none left in input file.
  for (int iEvent = 0; ; ++iEvent) {
    // Generate events, and check whether generation failed.
    if (!pythia.next()) {
      // If failure because reached end of file then exit event loop.
      if (pythia.info.atEndOfFile()) break;
      // First few failures write off as "acceptable" errors, then quit.
      if (++iAbort < nAbort) continue;
      break;
    }
    // Sum up final charged multiplicity and fill in histogram.
    int nChg = 0;
    for (int i = 0; i < pythia.event.size(); ++i)
    if (pythia.event[i].isFinal() && pythia.event[i].isCharged())
      ++nChg;
    nCharged.fill(nChg);
  // End of event loop.
  }
  // Give statistics. Print histogram.
  pythia.stat();
  cout << nCharged;
  // Done.
  return 0;
}

main12.cc


// main12.cc is a part of the PYTHIA event generator.
// Copyright (C) 2016 Torbjorn Sjostrand.
// PYTHIA is licenced under the GNU GPL version 2, see COPYING for details.
// Please respect the MCnet Guidelines, see GUIDELINES for details.
// This is a simple test program.
// It illustrates how Les Houches Event File input can be used in PYTHIA.
// It uses two LHE files, ttbar.lhe and ttbar2.lhe, which are combined
// using Beams:newLHEFsameInit = on to skip new initialization second time.
// Then the second file is viewed as a simple continuation of the first,
// just split for practical reasons, rather than as a separate new run
// with a new set of processes.
// In the first file top decays have been performed, in the second not,
// and are instead handled by the internal PYTHIA resonance-decay machinery.
// Furthermore the internal top production processes are switched on and
// mixed in, giving an unrealistic "double up" total top cross section.
// Much of this of course is not intended to be realistic,
// but rather illustrates several tricks that can be useful.
#include "Pythia8/Pythia.h"
using namespace Pythia8;
int main() {
  //  Number of listed events. Allow for possibility of a few faulty events.
  int nPrintLHA  = 1;
  int nPrintRest = 0;
  int nAbort     = 10;
  // Generator
  Pythia pythia;
  // Switch on internal ttbar production.
  pythia.readString("Top:gg2ttbar = on");
  pythia.readString("Top:qqbar2ttbar = on");
  // Use same top mass as in Pythia 6.4 to simplify comparison.
  pythia.readString("6:m0 = 175.");
  // No automatic event listings - do it manually below.
  pythia.readString("Next:numberShowLHA = 0");
  pythia.readString("Next:numberShowInfo = 0");
  pythia.readString("Next:numberShowProcess = 0");
  pythia.readString("Next:numberShowEvent = 0");
  // Initialize Les Houches Event File run.
  pythia.readString("Beams:frameType = 4");
  pythia.readString("Beams:LHEF = ttbar.lhe");
  pythia.init();
  // Book histogram.
  Hist nCharged("charged particle multiplicity",100,-0.5,399.5);
  // Set counters.
  int iPrintLHA  = 0;
  int iPrintRest = 0;
  int iAbort     = 0;
  int iFile      = 1;
  // Begin event loop
  for (int iEvent = 0; ; ++iEvent) {
    // Generate until none left in input file.
    if (!pythia.next()) {
      if (pythia.info.atEndOfFile()) {
        // First time open next file, second time stop event loop.
        if (iFile == 1) {
          pythia.readString("Beams:newLHEFsameInit = on");
          pythia.readString("Beams:LHEF = ttbar2.lhe");
          pythia.init();
          ++iFile;
          continue;
        } else break;
      }
      // First few failures write off as "acceptable" errors, then quit.
      if (++iAbort < nAbort) continue;
      break;
    }
    // List first few Les Houches and other events.
    if (pythia.info.isLHA() && iPrintLHA < nPrintLHA) {
      pythia.LHAeventList();
      pythia.info.list();
      pythia.process.list();
      pythia.event.list();
      ++iPrintLHA;
    } else if (!pythia.info.isLHA() && iPrintRest < nPrintRest) {
      pythia.info.list();
      pythia.process.list();
      pythia.event.list();
      ++iPrintRest;
    }
    // Sum up final charged multiplicity and fill in histogram.
    int nChg = 0;
    for (int i = 0; i < pythia.event.size(); ++i)
    if (pythia.event[i].isFinal() && pythia.event[i].isCharged())
      ++nChg;
    nCharged.fill(nChg);
  // End of event loop.
  }
  // Give statistics. Print histogram.
  pythia.stat();
  cout << nCharged;
  // Done.
  return 0;
}

main13.cc


// main13.cc is a part of the PYTHIA event generator.
// Copyright (C) 2016 Torbjorn Sjostrand.
// PYTHIA is licenced under the GNU GPL version 2, see COPYING for details.
// Please respect the MCnet Guidelines, see GUIDELINES for details.
// This is a simple test program.
// It illustrates how two Les Houches Event Files can be combined in PYTHIA,
// just like in main12.cc, but here with the difference that information is
// stored in main13.cmnd and read out using the subruns possibility.
#include "Pythia8/Pythia.h"
using namespace Pythia8;
int main() {
  // Book histogram.
  Hist nCharged("charged particle multiplicity",100,-0.5,399.5);
  // Generator.
  Pythia pythia;
  // Read in subrun-independent data from main13.cmnd.
  pythia.readFile( "main13.cmnd", 0);
  // Extract data to be used in main program. Set counters.
  int nSubrun = pythia.mode("Main:numberOfSubruns");
  int nAbort  = pythia.mode("Main:timesAllowErrors");
  int iAbort  = 0;
  // Begin loop over subruns.
  for (int iSubrun = 1; iSubrun <= nSubrun; ++iSubrun) {
    // Read in subrun-specific data from main13.cmnd.
    pythia.readFile( "main13.cmnd", iSubrun);
    // Initialize generator.
    pythia.init();
    // Begin infinite event loop - to be exited at end of file.
    for (int iEvent = 0; ; ++iEvent) {
      // Generate next event.
      if (!pythia.next()) {
        // Leave event loop if at end of file.
        if (pythia.info.atEndOfFile()) break;
        // First few failures write off as "acceptable" errors, then quit.
        if (++iAbort < nAbort) continue;
        break;
      }
      // Sum up final charged multiplicity and fill in histogram.
      int nChg = 0;
      for (int i = 0; i < pythia.event.size(); ++i)
      if (pythia.event[i].isFinal() && pythia.event[i].isCharged()) ++nChg;
      nCharged.fill(nChg);
    // End of event loop.
    }
  // End of subrun loop.
  }
  // Give statistics. Print histogram.
  pythia.stat();
  cout << nCharged;
  // Done.
  return 0;
}

main14.cc


// main14.cc is a part of the PYTHIA event generator.
// Copyright (C) 2016 Torbjorn Sjostrand.
// PYTHIA is licenced under the GNU GPL version 2, see COPYING for details.
// Please respect the MCnet Guidelines, see GUIDELINES for details.
// Comparison with some PYTHIA 6.413 cross sections process by process.
// Several processes have been left out to keep reasonable execution time.
// Some processes are not handled absolutely identically, so minor
// systematic differences may occur in addition to the statistical ones.
// (For some MSSM Higgs processes 6.413 has been modified to use
// running quark masses in loops, like 8.1, to allow proper comparison.)
// Subruns  0 -  5 : QCD jets
//          6 - 10 : prompt photons.
//         11 - 12 : t-channel gamma/Z/W exchange.
//         13 - 23 : gamma*/Z^0/W^+-, singly, in pairs or with parton
//         24 - 25 : onia.
//         26 - 30 : top.
//         31 - 40 : Standard Model Higgs.
//         41 - 45 : MSSM Higgses (trivial couplings).
//         46 - 47 : Z' and W'
//         48 - 51 : Left-right-symmetric scenario.
//         52 - 52 : Leptoquark.
//         53 - 55 : Excited fermions (compositeness).
//         56 - 56 : excited Graviton (RS extra dimensions).
#include "Pythia8/Pythia.h"
using namespace Pythia8;
int main() {
  // First and last process to test: can run from 0 through 40.
  int iFirst = 0;
  int iLast  = 56;
  // Statistics. Pythia6 run was with 10000, so no point to use more.
  int nEvent = 10000;
  // Normally one subprocess word per subrun, but exceptions exist.
  int nSub[100];
  for (int i = 0; i < 100; ++i) nSub[i] = 1;
  nSub[1] = 3;
  nSub[5] = 3;
  // Starting positions in subprocess words list, recursively defined.
  int iBeg[101] = { 0 };
  for (int i = 0; i < 100; ++i) iBeg[i + 1] = iBeg[i] + nSub[i];
  // List of subprocess words.
  string processes[61] = { "HardQCD:gg2gg", "HardQCD:gg2qqbar",
    "HardQCD:gg2ccbar",  "HardQCD:gg2bbbar","HardQCD:qg2qg" ,
    "HardQCD:qq2qq", "HardQCD:qqbar2gg", "HardQCD:qqbar2qqbarNew",
    "HardQCD:qqbar2ccbar", "HardQCD:qqbar2bbbar", "PromptPhoton:qg2qgamma",
    "PromptPhoton:qqbar2ggamma", "PromptPhoton:gg2ggamma",
    "PromptPhoton:ffbar2gammagamma", "PromptPhoton:gg2gammagamma",
    "WeakBosonExchange:ff2ff(t:gmZ)", "WeakBosonExchange:ff2ff(t:W)",
    "WeakSingleBoson:ffbar2gmZ", "WeakSingleBoson:ffbar2W",
    "WeakDoubleBoson:ffbar2gmZgmZ", "WeakDoubleBoson:ffbar2ZW",
    "WeakDoubleBoson:ffbar2WW", "WeakBosonAndParton:qqbar2gmZg",
    "WeakBosonAndParton:qg2gmZq", "WeakBosonAndParton:ffbar2gmZgm",
    "WeakBosonAndParton:qqbar2Wg", "WeakBosonAndParton:qg2Wq",
    "WeakBosonAndParton:ffbar2Wgm", "Charmonium:all", "Bottomonium:all",
    "Top:gg2ttbar",  "Top:qqbar2ttbar",  "Top:qq2tq(t:W)",
    "Top:ffbar2ttbar(s:gmZ)", "Top:ffbar2tqbar(s:W)",
    "HiggsSM:ffbar2H", "HiggsSM:gg2H", "HiggsSM:ffbar2HZ",
    "HiggsSM:ffbar2HW", "HiggsSM:ff2Hff(t:ZZ)", "HiggsSM:ff2Hff(t:WW)",
    "HiggsSM:qg2Hq", "HiggsSM:gg2Hg(l:t)", "HiggsSM:qg2Hq(l:t)",
    "HiggsSM:qqbar2Hg(l:t)", "HiggsBSM:allH1", "HiggsBSM:allH2",
    "HiggsBSM:allA3", "HiggsBSM:allH+-", "HiggsBSM:allHpair",
    "NewGaugeBoson:ffbar2gmZZprime", "NewGaugeBoson:ffbar2Wprime",
    "LeftRightSymmmetry:ffbar2ZR", "LeftRightSymmmetry:ffbar2WR",
    "LeftRightSymmmetry:ffbar2HLHL", "LeftRightSymmmetry:ffbar2HRHR",
    "LeptoQuark:all", "ExcitedFermion:dg2dStar",
    "ExcitedFermion:qq2dStarq", "ExcitedFermion:qqbar2eStare",
    "ExtraDimensionsG*:all" };
  // List of cross sections from Pythia6.
  double sigma6[57] = {   4.960e-01, 1.627e-02, 2.790e-01, 2.800e-02,
    3.310e-04, 3.653e-04, 1.697e-04, 1.163e-05, 1.065e-07, 8.259e-08,
    8.237e-08, 2.544e-05, 5.321e-06, 5.571e-05, 1.621e-04, 9.039e-09,
    2.247e-08, 5.893e-08, 3.781e-06, 1.078e-05, 4.551e-08, 1.025e-05,
    3.208e-05, 5.435e-08, 1.038e-04, 3.929e-05, 4.155e-07, 6.685e-08,
    1.898e-07, 4.240e-10, 7.142e-09, 1.547e-10, 7.064e-09, 1.316e-10,
    2.332e-10, 5.105e-10, 1.316e-09, 4.462e-11, 5.557e-09, 1.966e-09,
    8.725e-12, 2.450e-08, 5.839e-09, 1.687e-08, 8.950e-11, 4.188e-11,
    1.980e-07, 4.551e-07, 6.005e-09, 1.102e-07, 7.784e-11, 3.488e-11,
    6.006e-08, 3.235e-06, 1.689e-05, 5.986e-07, 3.241e-10 };
  // Generator.
  Pythia pythia;
  // Standard set of masses for comparison with Fortran code.
  pythia.readString("5:m0  = 4.2");
  pythia.readString("6:m0  = 175.");
  pythia.readString("23:m0 = 91.2");
  pythia.readString("24:m0 = 80.");
  // Same kinematics cuts as Fortran code.
  pythia.readString("PhaseSpace:pTHatMin = 20.");
  pythia.readString("6:mMin = 20.");
  pythia.readString("23:mMin = 20.");
  pythia.readString("24:mMin = 20.");
  pythia.readString("25:mMin = 20.");
  pythia.readString("32:mMin = 400.");
  pythia.readString("34:mMin = 400.");
  pythia.readString("42:mMin = 50.");
  pythia.readString("5000039:mMin = 50.");
  // Also same renormalization and factorization scale.
  pythia.readString("SigmaProcess:renormScale2 = 3");
  pythia.readString("SigmaProcess:factorScale2 = 3");
  // Switch off unnecessary parts.
  pythia.readString("PartonLevel:all = off");
  pythia.readString("ProcessLevel:resonanceDecays = off");
  // No printing of settings, particle data or events.
  pythia.readString("Init:showProcesses = off");
  pythia.readString("Init:showChangedSettings = off");
  pythia.readString("Init:showChangedParticleData = off");
  pythia.readString("Next:numberCount = 0");
  pythia.readString("Next:numberShowInfo = 0");
  pythia.readString("Next:numberShowProcess = 0");
  pythia.readString("Next:numberShowEvent = 0");
  // Debug: show information on cross section maximum and violation.
  //pythia.readString("PhaseSpace:showSearch = on");
  //pythia.readString("PhaseSpace:showViolation = on");
  // Loop over processes.
  for (int iProc = iFirst; iProc <= iLast; ++iProc) {
    cout << "\n Begin subrun number " << iProc << " : ";
    // Switch off previous process(es) and switch on new one(s).
    if (iProc > iFirst) for (int i = iBeg[iProc - 1]; i < iBeg[iProc]; ++i)
      pythia.readString( processes[i] + " = off" );
    for (int i = iBeg[iProc]; i < iBeg[iProc + 1]; ++i) {
      pythia.readString( processes[i] + " = on" );
      if (i > iBeg[iProc]) cout << " + ";
      cout << processes[i];
    }
    cout << endl;
    // Switch between SM and MSSM Higgs scenario.
    if (iProc <= 40) {
      pythia.readString("Higgs:useBSM = off");
      pythia.readString("25:m0 = 200.");
    } else {
      pythia.readString("Higgs:useBSM = on");
      pythia.readString("25:m0 = 115.");
      pythia.readString("35:m0 = 300.");
      pythia.readString("36:m0 = 300.");
      pythia.readString("37:m0 = 320.");
      // With default option Higgs:clipWings = on need to reset mass range.
      pythia.readString("25:mMin = 50.");
      pythia.readString("25:mMax = 0.");
    }
    // Initialize for LHC.
    pythia.readString("Beams:eCM = 14000.");
    pythia.init();
    // Debug: show initialized resonance data first time around.
    //if (iProc == iFirst) pythia.particleData.listChanged(true);
    // Generate events to get cross section statistics.
    for (int iEvent = 0; iEvent < nEvent; ++iEvent) pythia.next();
    // Show statistics.
    //pythia.stat();
    double sigma = pythia.info.sigmaGen();
    cout << " Cross section is " << scientific << setprecision(3)
         << sigma << " and in Pythia6 was " << sigma6[iProc]
         << ",\n i.e. now is factor >>> " << fixed
         << sigma / sigma6[iProc] << " <<< different" <<endl;
  // End of loop over processes.
  }
  // Done.
  return 0;
}

main15.cc


// main15.cc is a part of the PYTHIA event generator.
// Copyright (C) 2016 Torbjorn Sjostrand.
// PYTHIA is licenced under the GNU GPL version 2, see COPYING for details.
// Please respect the MCnet Guidelines, see GUIDELINES for details.
// This is a simple test program.
// It illustrates how either
// (a) B decays (sections marked "Repeated decays:), or
// (b) all hadronization (sections marked "Repeated hadronization:")
// could be repeated a number of times for each event,
// to improve statistics when this could be a problem.
// Option (a) is faster than (b), but less generic.
// Note 1: the compartmentalization of hadronization in forceHadronLevel
// from the rest of the event processing somewhat limits the ways the
// program can retry in case of problems, and so an occasional abort
// may occur more easily than normally.
// Note 2: for simple cases, where it is only one particle that is to be
// decayed repeatedly, the event[i].undoDecay() method is handy.
// When used for several particles, remember that the position of
// some particles may be moved by the undoDecay step.
#include "Pythia8/Pythia.h"
using namespace Pythia8;
int main() {
  // Main switches: redo B decays only or redo all hadronization, but not both.
  bool redoBDecays = false;
  bool redoHadrons = true;
  if (redoHadrons) redoBDecays = false;
  // Number of events. Number to list redone events.
  int nEvent = 100;
  int nListRedo = 1;
  // Number of times decays/hadronization should be redone for each event.
  int nRepeat = 10;
  if (!redoBDecays && !redoHadrons) nRepeat = 1;
  // Generator. Shorthand for event.
  Pythia pythia;
  Event& event = pythia.event;
  // Simulate b production above given pTmin scale.
  // Warning: these processes do not catch all possible production modes.
  // You would need to use HardQCD:all or even SoftQCD:nonDiffractive for that.
  pythia.readString("HardQCD:gg2bbbar = on");
  pythia.readString("HardQCD:qqbar2bbbar = on");
  pythia.readString("PhaseSpace:pTHatMin = 50.");
  // Repeated decays: list of weakly decaying B hadrons.
  // Note: this list is overkill; some will never be produced.
  int bCodes[28] = {511, 521, 531, 541, 5122, 5132, 5142, 5232, 5242,
    5332, 5342, 5412, 5414, 5422, 5424, 5432, 5434, 5442, 5444, 5512,
    5514, 5522, 5524, 5532, 5534, 5542, 5544, 5544 };
  int nCodes = 28;
  // Repeated decays: location of B handrons.
  vector<int> iBHad;
  int nBHad = 0;
  // Repeated hadronization: spare copy of event.
  Event savedEvent;
  // Repeated hadronization: switch off normal HadronLevel call.
  if (redoHadrons) pythia.readString("HadronLevel:all = off");
  // Initialize for LHC energies; default 14 TeV
  pythia.init();
  // Histogram invariant mass of muon pairs.
  Hist nBperEvent("number of b quarks in an event", 10, -0.5, 9.5);
  Hist nSameEvent("number of times same event is used", 10, -0.5, 9.5);
  Hist oppSignMass("mass of opposite-sign muon pair", 100, 0.0, 100.0);
  Hist sameSignMass("mass of same-sign muon pair", 100, 0.0, 100.0);
  // Begin event loop.
  for (int iEvent = 0; iEvent < nEvent; ++iEvent) {
    // Repeated decays: switch off decays of weakly decaying B hadrons.
    // (More compact solution than repeated readString(..).)
    if (redoBDecays) for (int iC = 0; iC < nCodes; ++iC)
      pythia.particleData.mayDecay( bCodes[iC], false);
    // Generate event. Skip it if error.
    if (!pythia.next()) continue;
    // Find and histogram number of b quarks.
    int nBquark = 0;
    int stat;
    for (int i = 0; i < event.size(); ++i) {
      stat = event[i].statusAbs();
      if (event[i].idAbs() == 5 && (stat == 62 || stat == 63)) ++nBquark;
    }
    nBperEvent.fill( nBquark );
    // Repeated decays: find all locations where B hadrons are stored.
    if (redoBDecays) {
      iBHad.resize(0);
      for (int i = 0; i < event.size(); ++i) {
        int idAbs = event[i].idAbs();
        for (int iC = 0; iC < 28; ++iC)
        if (idAbs == bCodes[iC]) {
          iBHad.push_back(i);
          break;
        }
      }
      // Repeated decays: check that #b = #B.
      nBHad = iBHad.size();
      if (nBquark != nBHad) cout << " Warning: " << nBquark
        << " b quarks but " << nBHad << " B hadrons" << endl;
      // Repeated decays: store size of current event.
      event.saveSize();
      // Repeated decays: switch back on weakly decaying B hadrons.
      for (int iC = 0; iC < nCodes; ++iC)
        pythia.particleData.mayDecay( bCodes[iC], true);
    //  Repeated hadronization: copy event into spare position.
    } else if (redoHadrons) {
      savedEvent = event;
    }
    // Begin loop over rounds of decays / hadronization for same event.
    int nWithPair = 0;
    for (int iRepeat = 0; iRepeat < nRepeat; ++iRepeat) {
      // Repeated decays: remove B decay products from previous round.
      if (redoBDecays) {
        if (iRepeat > 0) {
          event.restoreSize();
          // Repeated decays: mark decayed B hadrons as undecayed.
          for (int iB = 0; iB < nBHad; ++iB) event[ iBHad[iB] ].statusPos();
        }
        // Repeated decays: do decays of B hadrons, sequentially for products.
        // Note: modeDecays does not work for bottomonium (or heavier) states,
        // since there decays like Upsilon -> g g g also need hadronization.
        // Also, there is no provision for Bose-Einstein effects.
        if (!pythia.moreDecays()) continue;
      // Repeated hadronization: restore saved event record.
      } else if (redoHadrons) {
        if (iRepeat > 0) event = savedEvent;
        // Repeated hadronization: do HadronLevel (repeatedly).
        // Note: argument false needed owing to bug in junction search??
        if (!pythia.forceHadronLevel(false)) continue;
      }
      // List last repetition of first few events.
      if ( (redoBDecays || redoHadrons) && iEvent < nListRedo
        && iRepeat == nRepeat - 1) event.list();
      // Look for muons among decay products (also from charm/tau/...).
      vector<int> iMuNeg, iMuPos;
      for (int i = 0; i < event.size(); ++i) {
        int id = event[i].id();
        if (id ==  13) iMuNeg.push_back(i);
        if (id == -13) iMuPos.push_back(i);
      }
      // Check whether pair(s) present.
      int nMuNeg = iMuNeg.size();
      int nMuPos = iMuPos.size();
      if (nMuNeg + nMuPos > 1) {
        ++nWithPair;
        // Fill masses of opposite-sign pairs.
        for (int iN = 0; iN < nMuNeg; ++iN)
        for (int iP = 0; iP < nMuPos; ++iP)
          oppSignMass.fill(
            (event[iMuNeg[iN]].p() + event[iMuPos[iP]].p()).mCalc() );
        // Fill masses of same-sign pairs.
        for (int i1 = 0; i1 < nMuNeg - 1; ++i1)
        for (int i2 = i1 + 1; i2 < nMuNeg; ++i2)
          sameSignMass.fill(
            (event[iMuNeg[i1]].p() + event[iMuNeg[i2]].p()).mCalc() );
        for (int i1 = 0; i1 < nMuPos - 1; ++i1)
        for (int i2 = i1 + 1; i2 < nMuPos; ++i2)
          sameSignMass.fill(
            (event[iMuPos[i1]].p() + event[iMuPos[i2]].p()).mCalc() );
      // Finished analysis of current round.
      }
    // End of loop over many rounds. fill number of rounds with pairs.
    }
    nSameEvent.fill( nWithPair );
  // End of event loop.
  }
  // Statistics. Histograms.
  pythia.stat();
  cout << nBperEvent << nSameEvent << oppSignMass << sameSignMass << endl;
  // Done.
  return 0;
}

main16.cc


// main16.cc is a part of the PYTHIA event generator.
// Copyright (C) 2016 Torbjorn Sjostrand.
// PYTHIA is licenced under the GNU GPL version 2, see COPYING for details.
// Please respect the MCnet Guidelines, see GUIDELINES for details.
// This is a simple test program.
// It illustrates (a) how to collect the analysis code in a separate class
// and (b) how to provide the .cmnd filename on the command line
// Once you have linked the main program you can run it with a command line
// ./main16.exe main16.cmnd > out16
#include "Pythia8/Pythia.h"
using namespace Pythia8;
//==========================================================================
// Put all your own analysis code in the myAnalysis class.
class MyAnalysis {
public:
  // Constructor can be empty.
  MyAnalysis() {}
  // Initialization actions.
  void init();
  // Analysis of each new event.
  void analyze(Event& event);
  // Show final results.
  void finish();
private:
  // Declare variables and objects that span init - analyze - finish.
  int  nEvt;
  Hist brH, yH, etaChg, mult;
};
//--------------------------------------------------------------------------
// The initialization code.
void MyAnalysis::init() {
  // Initialize counter for number of events.
  nEvt = 0;
  // Book histograms.
  brH.book("Higgs branching ratios by flavour", 30, -0.5, 29.5);
  yH.book("Higgs rapidity", 100, -10., 10.);
  etaChg.book("charged pseudorapidity", 100, -10., 10.);
  mult.book( "charged multiplicity", 100, -0.5, 799.5);
}
//--------------------------------------------------------------------------
// The event analysis code.
void MyAnalysis::analyze(Event& event) {
  // Increase counter.
  ++nEvt;
  // Find latest copy of Higgs and plot its rapidity.
  int iH = 0;
  for (int i = 0; i < event.size(); ++i)
    if (event[i].id() == 25) iH = i;
  yH.fill( event[iH].y() );
  // Plot flavour of decay channel.
  int idDau1 = event[ event[iH].daughter1() ].idAbs();
  int idDau2 = event[ event[iH].daughter2() ].idAbs();
  int iChan  = 29;
  if (idDau2 == idDau1 && idDau1 < 25) iChan = idDau1;
  if (min( idDau1, idDau2) == 22 && max( idDau1, idDau2) == 23) iChan = 26;
  brH.fill( iChan);
  // Plot pseudorapidity distribution. Sum up charged multiplicity.
  int nChg = 0;
  for (int i = 0; i < event.size(); ++i)
  if (event[i].isFinal() && event[i].isCharged()) {
    etaChg.fill( event[i].eta() );
    ++nChg;
  }
  mult.fill( nChg );
}
//--------------------------------------------------------------------------
// The finishing code.
void MyAnalysis::finish() {
  // Normalize histograms.
  double binFactor = 5. / nEvt;
  yH     *= binFactor;
  etaChg *= binFactor;
  // Print histograms.
  cout << brH << yH << etaChg << mult;
}
//==========================================================================
// You should not need to touch the main program: its actions are
// determined by the .cmnd file and the rest belongs in MyAnalysis.
int main(int argc, char* argv[]) {
  // Check that correct number of command-line arguments
  if (argc != 2) {
    cerr << " Unexpected number of command-line arguments. \n"
         << " You are expected to provide a file name and nothing else. \n"
         << " Program stopped! " << endl;
    return 1;
  }
  // Check that the provided file name corresponds to an existing file.
  ifstream is(argv[1]);
  if (!is) {
    cerr << " Command-line file " << argv[1] << " was not found. \n"
         << " Program stopped! " << endl;
    return 1;
  }
  // Confirm that external file will be used for settings..
  cout << " PYTHIA settings will be read from file " << argv[1] << endl;
  // Declare generator. Read in commands from external file.
  Pythia pythia;
  pythia.readFile(argv[1]);
  // Initialization.
  pythia.init();
  // Declare user analysis class. Do initialization part of it.
  MyAnalysis myAnalysis;
  myAnalysis.init();
  // Read in number of event and maximal number of aborts.
  int nEvent = pythia.mode("Main:numberOfEvents");
  int nAbort = pythia.mode("Main:timesAllowErrors");
  bool hasPL = pythia.flag("PartonLevel:all");
  // Begin event loop.
  int iAbort = 0;
  for (int iEvent = 0; iEvent < nEvent; ++iEvent) {
    // Generate events. Quit if too many failures.
    if (!pythia.next()) {
      if (++iAbort < nAbort) continue;
      cout << " Event generation aborted prematurely, owing to error!\n";
      break;
    }
    // User Analysis of current event.
    myAnalysis.analyze( (hasPL ? pythia.event : pythia.process) );
  // End of event loop.
  }
  // Final statistics.
  pythia.stat();
  // User finishing.
  myAnalysis.finish();
  // Done.
  return 0;
}

main17.cc


// main17.cc is a part of the PYTHIA event generator.
// Copyright (C) 2016 Torbjorn Sjostrand.
// PYTHIA is licenced under the GNU GPL version 2, see COPYING for details.
// Please respect the MCnet Guidelines, see GUIDELINES for details.
// This is a simple test program.
// It illustrates
// (a) how to use UserHooks to regularize onium cross section for pT -> 0,
// (b) how decays could be handled externally.
#include "Pythia8/Pythia.h"
using namespace Pythia8;
//==========================================================================
// A derived class to do J/psi decays.
class JpsiDecay : public DecayHandler {
public:
  // Constructor.
  JpsiDecay(ParticleData* pdtPtrIn, Rndm* rndmPtrIn) {times = 0;
    pdtPtr = pdtPtrIn; rndmPtr = rndmPtrIn;}
  // Routine for doing the decay.
  bool decay(vector<int>& idProd, vector<double>& mProd,
    vector<Vec4>& pProd, int iDec, const Event& event);
private:
  // Count number of times JpsiDecay is called.
  int times;
  // Pointer to the particle data table.
  ParticleData* pdtPtr;
  // Pointer to the random number generator.
  Rndm* rndmPtr;
};
//--------------------------------------------------------------------------
// The actual J/psi decay routine.
// Not intended for realism, just to illustrate the principles.
bool JpsiDecay::decay(vector<int>& idProd, vector<double>& mProd,
  vector<Vec4>& pProd, int iDec, const Event& event) {
  // Always do decay J/psi -> mu+ mu-; store the muons.
  idProd.push_back(-13);
  idProd.push_back(13);
  // Muon mass(es), here from Pythia tables, also stored.
  double mMuon = pdtPtr->m0(13);
  mProd.push_back(mMuon);
  mProd.push_back(mMuon);
  // Calculate muon energy and momentum in J/psi rest frame.
  double eMuon = 0.5 * mProd[0];
  double pAbsMuon = sqrt(eMuon * eMuon - mMuon * mMuon);
  // Assume decay angles isotropic in rest frame.
  double cosTheta = 2. * rndmPtr->flat() - 1.;
  double sinTheta = sqrt(max(0., 1. - cosTheta * cosTheta));
  double phi = 2. * M_PI * rndmPtr->flat();
  double pxMuon = pAbsMuon * sinTheta * cos(phi);
  double pyMuon = pAbsMuon * sinTheta * sin(phi);
  double pzMuon = pAbsMuon * cosTheta;
  // Define mu+ and mu- four-vectors in the J/psi rest frame.
  Vec4 pMuPlus(   pxMuon,  pyMuon,  pzMuon, eMuon);
  Vec4 pMuMinus( -pxMuon, -pyMuon, -pzMuon, eMuon);
  // Boost them by velocity vector of the J/psi mother and store.
  pMuPlus.bst(pProd[0]);
  pMuMinus.bst(pProd[0]);
  pProd.push_back(pMuPlus);
  pProd.push_back(pMuMinus);
  // Print message the first few times, to show that it works.
  if (times++ < 10) {
    int iMother = event[iDec].mother1();
    int idMother = event[iMother].id();
    cout << "\n J/psi decay performed, J/psi in line " << iDec
         << ", mother id = " << idMother << "\n";
  }
  // Done
  return true;
}
//==========================================================================
int main() {
  // Number of events to generate and to list. Max number of errors.
  int nEvent = 2000;
  int nList  = 2;
  int nAbort = 5;
  // Pythia generator.
  Pythia pythia;
  // Initialization for charmonium (singlet+octet) production at the LHC.
  pythia.readString("Charmonium:all = on");
  pythia.readString("Beams:eCM = 7000.");
  // Normally cutoff at pTHat = 1, but push it lower combined with dampening.
  pythia.readString("PhaseSpace:pTHatMin = 0.5");
  pythia.readString("PhaseSpace:pTHatMinDiverge = 0.5");
  // Set up to do a user veto and send it in.
  // First argument: multiplies the pT0 of multiparton interactions
  // to define the pT dampeing scale.
  // Second argument: howe many powers of alpha_strong to
  // reweight with new (larger) argument.
  // Third argument: choice of process scale two different ways;
  // probably does not make much difference.
  // See "User Hooks" in manual for detail on SuppressSmallPT.
  UserHooks* oniumUserHook = new SuppressSmallPT( 1., 3, false);
  pythia.setUserHooksPtr( oniumUserHook);
  // A class to do J/psi decays externally.
  DecayHandler* handleDecays = new JpsiDecay(&pythia.particleData,
    &pythia.rndm);
  // The list of particles the class can handle.
  vector<int> handledParticles;
  handledParticles.push_back(443);
  // Hand pointer and list to Pythia.
  pythia.setDecayPtr( handleDecays, handledParticles);
  // Switch off automatic event listing in favour of manual.
  pythia.readString("Next:numberShowInfo = 0");
  pythia.readString("Next:numberShowProcess = 0");
  pythia.readString("Next:numberShowEvent = 0");
  // Initialization.
  pythia.init();
  // Book histograms.
  Hist pThard("pTHat of hard subprocess", 100, 0., 50.);
  Hist pTJPsi("pT of J/Psi", 100, 0., 50.);
  // Begin event loop.
  int iList = 0;
  int iAbort = 0;
  for (int iEvent = 0; iEvent < nEvent; ++iEvent) {
    // Generate events. Quit if many failures.
    if (!pythia.next()) {
      if (++iAbort < nAbort) continue;
      cout << " Event generation aborted prematurely, owing to error!\n";
      break;
    }
    // Histogram pThard spectrum of process.
    double pTHat = pythia.info.pTHat();
    pThard.fill( pTHat );
    // Look for event with externally handled decays.
    bool externalDecay = false;
    for (int i = 0; i < pythia.event.size(); ++i) {
      int status = pythia.event[i].statusAbs();
      if (status == 93 || status == 94) {externalDecay = true; break;}
    }
    // List first few events with external decay.
    if (externalDecay && ++iList <= nList) {
      pythia.process.list();
      pythia.event.list();
    }
    // Histogram pT spectrum of J/Psi.
   for (int i = 0; i < pythia.event.size(); ++i)
   if (pythia.event[i].id() == 443) pTJPsi.fill( pythia.event[i].pT() );
  // End of event loop.
  }
  // Final statistics. Print histograms.
  pythia.stat();
  cout << pThard << pTJPsi;
  // Done.
  delete handleDecays;
  delete oniumUserHook;
  return 0;
}

main18.cc


// main18.cc is a part of the PYTHIA event generator.
// Copyright (C) 2016 Torbjorn Sjostrand.
// PYTHIA is licenced under the GNU GPL version 2, see COPYING for details.
// Please respect the MCnet Guidelines, see GUIDELINES for details.
// This is a simple test program.
// It illustrates how to write an event filter.
// No new functionality is involved - all could be done in the main program
// - but the division of tasks may be more convenient for recurrent cuts.
#include "Pythia8/Pythia.h"
using namespace Pythia8;
//==========================================================================
// The EventFilter class.
// The constructor takes the following arguments
// select = 1 : keep only final particles.
//        = 2 : keep only final visible particles (i.e. not neutrinos).
//        = 3 : keep only final charged particles.
// etaMax (default = 50) : keep only particles with pseudorapidity
//        |eta| < etaMax.
// pTminCharged (default = 0) : keep a charged particle only if
//        its transverse momentum pT < pTminCharged.
// pTminNeutral (default = 0) : keep a neutral particle only if
//        its transverse momentum pT < pTminNeutral.
// Main methods:
// filter( event) takes an event record as input and analyzes it.
// size() returns the number of particles kept.
// index(i) returns the index in the full event of the i'th kept particle.
// particlePtr(i) returns a pointer to the i'th kept particle.
// particleRef(i) returns a reference to the i'th kept particle.
// list() gives a listing of the kept particles only.
class EventFilter {
public:
  // Constructor sets properties of filter.
  EventFilter( int selectIn, double etaMaxIn = 50.,
    double pTminChargedIn = 0., double pTminNeutralIn = 0.)
    : select(selectIn), etaMax(etaMaxIn), pTminCharged(pTminChargedIn),
    pTminNeutral(pTminNeutralIn) {}
  // Analysis of each new event to find acceptable particles.
  void filter(Event& event);
  // Return size of array, and index of a particle.
  int size()       const {return keptPtrs.size();}
  int index(int i) const {return keptIndx[i];}
  // Return pointer or reference to a particle.
  Particle* particlePtr(int i) {return  keptPtrs[i];}
  Particle& particleRef(int i) {return *keptPtrs[i];}
  // List kept particles only.
  void list(ostream& os = cout);
private:
  // Filter properties, set by constructor.
  int    select;
  double etaMax, pTminCharged, pTminNeutral;
  // Kept particle indices and pointers, referring to original event.
  vector<int>       keptIndx;
  vector<Particle*> keptPtrs;
};
//--------------------------------------------------------------------------
// The filter method.
void EventFilter::filter(Event& event) {
  // Reset arrays in preparation for new event.
  keptIndx.resize(0);
  keptPtrs.resize(0);
  // Loop over all particles in the event record.
  for (int i = 0; i < event.size(); ++i) {
    // Skip if particle kind selection criteria not fulfilled.
    if (!event[i].isFinal()) continue;
    if (select == 2 && !event[i].isVisible()) continue;
    bool isCharged = event[i].isCharged();
    if (select == 3 && !isCharged) continue;
    // Skip if too large pseudorapidity.
    if (abs(event[i].eta()) > etaMax) continue;
    // Skip if too small pT.
    if       (isCharged && event[i].pT() < pTminCharged) continue;
    else if (!isCharged && event[i].pT() < pTminNeutral) continue;
    // Add particle to vectors of indices and pointers.
    keptIndx.push_back( i );
    keptPtrs.push_back( &event[i] );
  // End of particle loop. Done.
  }
}
//--------------------------------------------------------------------------
// The list method: downscaled version of Event::list.
void EventFilter::list(ostream& os) {
  // Header.
  os << "\n --------  PYTHIA Event Listing  (filtered)  ------------------"
     << "-----------------------------------------------------------------"
     << "----\n \n    no        id   name            status     mothers  "
     << " daughters     colours      p_x        p_y        p_z         e  "
     << "        m \n";
  // At high energy switch to scientific format for momenta.
  double eSum = 0.;
  for (int iKept = 0; iKept < size(); ++iKept) eSum += keptPtrs[iKept]->e();
  bool useFixed = (eSum < 1e5);
  // Listing of kept particles in event.
  for (int iKept = 0; iKept < size(); ++iKept) {
    int i = keptIndx[iKept];
    Particle& pt = *keptPtrs[iKept];
    // Basic line for a particle, always printed.
    os << setw(6) << i << setw(10) << pt.id() << "   " << left
       << setw(18) << pt.nameWithStatus(18) << right << setw(4)
       << pt.status() << setw(6) << pt.mother1() << setw(6)
       << pt.mother2() << setw(6) << pt.daughter1() << setw(6)
       << pt.daughter2() << setw(6) << pt.col() << setw(6) << pt.acol()
       << ( (useFixed) ? fixed : scientific ) << setprecision(3)
       << setw(11) << pt.px() << setw(11) << pt.py() << setw(11)
       << pt.pz() << setw(11) << pt.e() << setw(11) << pt.m() << "\n";
  }
  // Listing finished.
  os << "\n --------  End PYTHIA Event Listing  ----------------------------"
     << "-------------------------------------------------------------------"
     << endl;
}
//==========================================================================
// Use the EventFilter method to plot some event properties.
int main() {
  // Number of events to generate, to list, to allow aborts.
  int    nEvent   = 100;
  int    nList    = 1;
  int    nAbort   = 3;
  // Declare generator.
  Pythia pythia;
  // Hard QCD events with pThat > 100.
  pythia.readString("HardQCD:all = on");
  pythia.readString("PhaseSpace:pTHatMin = 100.");
  // No automatic event listings - do it manually below.
  pythia.readString("Next:numberShowInfo = 0");
  pythia.readString("Next:numberShowProcess = 0");
  pythia.readString("Next:numberShowEvent = 0");
  // Initialization for LHC.
  pythia.init();
  // Values for filter.
  int    select   = 3;
  double etaMax   = 3.;
  double pTminChg = 1.;
  // Declare Event Filter according to specification.
  EventFilter filter( select, etaMax, pTminChg);
  // Histograms.
  Hist nCharged(   "selected charged multiplicity",     100, -0.5, 199.5);
  Hist etaCharged( "selected charged eta distribution", 100, -5.0, 5.0);
  Hist pTCharged(  "selected charged pT distribution",  100,  0.0, 50.0);
  // Begin event loop.
  int iAbort = 0;
  for (int iEvent = 0; iEvent < nEvent; ++iEvent) {
    // Generate events. Quit if too many failures.
    if (!pythia.next()) {
      if (++iAbort < nAbort) continue;
      cout << " Event generation aborted prematurely, owing to error!\n";
      break;
    }
    // Find final charged particles with |eta| < 3 and pT > 1 GeV.
    filter.filter( pythia.event);
    // List first few events, both complete and after filtering.
    if (iEvent < nList) {
      pythia.info.list();
      pythia.process.list();
      pythia.event.list();
      filter.list();
    }
    // Analyze selected particle sample.
    nCharged.fill( filter.size() );
    for (int i = 0; i < filter.size(); ++i) {
      // Use both reference and pointer notation to illustrate freedom.
      etaCharged.fill( filter.particleRef(i).eta() );
      pTCharged.fill(  filter.particlePtr(i)->pT() );
    }
  // End of event loop.
  }
  // Final statistics.
  pythia.stat();
  // Histograms.
  cout << nCharged << etaCharged << pTCharged;
  // Done.
  return 0;
}

main19.cc


// main19.cc is a part of the PYTHIA event generator.
// Copyright (C) 2016 Torbjorn Sjostrand.
// PYTHIA is licenced under the GNU GPL version 2, see COPYING for details.
// Please respect the MCnet Guidelines, see GUIDELINES for details.
// This program runs four instances of Pythia simultaneously,
// one for signal events, one for pileup background ones, and two
// For beam-gas background ones. Note that Pythia does not do nuclear
// effects, so beam-gas is represented by "fixed-target" pp collisions.
// The = and += overloaded operators are used to join several
// event records into one, but should be used with caution.
// The possibility to instantiate Pythia with Settings and ParticleData
// databases is illustrated, but not essential here. It means that the
// share/Pythia8/xmldoc/*.xml files are only read once, saving some time.
// Note that each instance of Pythia is running independently of any other,
// but with two important points to remember.
// 1) By default all generate the same random number sequence,
//    which has to be corrected if they are to generate the same
//    physics, like the two beam-gas ones below.
// 2) Interfaces to external Fortran programs are "by definition" static.
//    Thus it is not a good idea to use LHAPDF5 to set different PDF's
//    in different instances.
#include "Pythia8/Pythia.h"
using namespace Pythia8;
//==========================================================================
// Method to pick a number according to a Poissonian distribution.
int poisson(double nAvg, Rndm& rndm) {
  // Set maximum to avoid overflow.
  const int NMAX = 100;
  // Random number.
  double rPoisson = rndm.flat() * exp(nAvg);
  // Initialize.
  double rSum  = 0.;
  double rTerm = 1.;
  // Add to sum and check whether done.
  for (int i = 0; i < NMAX; ) {
    rSum += rTerm;
    if (rSum > rPoisson) return i;
    // Evaluate next term.
    ++i;
    rTerm *= nAvg / i;
  }
  // Emergency return.
  return NMAX;
}
//==========================================================================
int main() {
  // Number of signal events to generate.
  int nEvent = 100;
  // Beam Energy.
  double eBeam = 7000.;
  // Average number of pileup events per signal event.
  double nPileupAvg = 2.5;
  // Average number of beam-gas events per signal ones, on two sides.
  double nBeamAGasAvg = 0.5;
  double nBeamBGasAvg = 0.5;
  // Signal generator instance.
  Pythia pythiaSignal;
  // Switch off automatic event listing (illustrates settings inheritance).
  pythiaSignal.readString("Next:numberShowInfo = 0");
  pythiaSignal.readString("Next:numberShowProcess = 0");
  pythiaSignal.readString("Next:numberShowEvent = 0");
  // Switch off K0S decay (illustrates particle data inheritance).
  pythiaSignal.readString("130:mayDecay = off");
  // Background generator instances copies settings and particle data.
  Pythia pythiaPileup(   pythiaSignal.settings, pythiaSignal.particleData);
  Pythia pythiaBeamAGas( pythiaSignal.settings, pythiaSignal.particleData);
  Pythia pythiaBeamBGas( pythiaSignal.settings, pythiaSignal.particleData);
  // Switch off Lambda decay (illustrates particle data non-inheritance).
  pythiaSignal.readString("3122:mayDecay = off");
  // One object where all individual events are to be collected.
  Event sumEvent;
  // Initialize generator for signal processes.
  pythiaSignal.readString("HardQCD:all = on");
  pythiaSignal.readString("PhaseSpace:pTHatMin = 50.");
  pythiaSignal.settings.parm("Beams:eCM", 2. * eBeam);
  pythiaSignal.init();
  // Initialize generator for pileup (background) processes.
  pythiaPileup.readString("Random:setSeed = on");
  pythiaPileup.readString("Random:seed = 10000002");
  pythiaPileup.readString("SoftQCD:all = on");
  pythiaPileup.settings.parm("Beams:eCM", 2. * eBeam);
  pythiaPileup.init();
  // Initialize generators for beam A - gas (background) processes.
  pythiaBeamAGas.readString("Random:setSeed = on");
  pythiaBeamAGas.readString("Random:seed = 10000003");
  pythiaBeamAGas.readString("SoftQCD:all = on");
  pythiaBeamAGas.readString("Beams:frameType = 2");
  pythiaBeamAGas.settings.parm("Beams:eA", eBeam);
  pythiaBeamAGas.settings.parm("Beams:eB", 0.);
  pythiaBeamAGas.init();
  // Initialize generators for beam B - gas (background) processes.
  pythiaBeamBGas.readString("Random:setSeed = on");
  pythiaBeamBGas.readString("Random:seed = 10000004");
  pythiaBeamBGas.readString("SoftQCD:all = on");
  pythiaBeamBGas.readString("Beams:frameType = 2");
  pythiaBeamBGas.settings.parm("Beams:eA", 0.);
  pythiaBeamBGas.settings.parm("Beams:eB", eBeam);
  pythiaBeamBGas.init();
  // Histograms: number of pileups, total charged multiplicity.
  Hist nPileH("number of pileup events per signal event", 100, -0.5, 99.5);
  Hist nAGH("number of beam A + gas events per signal event", 100, -0.5, 99.5);
  Hist nBGH("number of beam B + gas events per signal event", 100, -0.5, 99.5);
  Hist nChgH("number of charged multiplicity",100, -0.5, 1999.5);
  Hist sumPZH("total pZ of system",100, -100000., 100000.);
  // Loop over events.
  for (int iEvent = 0; iEvent < nEvent; ++iEvent) {
    // Generate a signal event. Copy this event into sumEvent.
    if (!pythiaSignal.next()) continue;
    sumEvent = pythiaSignal.event;
    // Select the number of pileup events to generate.
    int nPileup = poisson(nPileupAvg, pythiaPileup.rndm);
    nPileH.fill( nPileup );
    // Generate a number of pileup events. Add them to sumEvent.
    for (int iPileup = 0; iPileup < nPileup; ++iPileup) {
      pythiaPileup.next();
      sumEvent += pythiaPileup.event;
    }
    // Select the number of beam A + gas events to generate.
    int nBeamAGas = poisson(nBeamAGasAvg, pythiaBeamAGas.rndm);
    nAGH.fill( nBeamAGas );
    // Generate a number of beam A + gas events. Add them to sumEvent.
    for (int iAG = 0; iAG < nBeamAGas; ++iAG) {
      pythiaBeamAGas.next();
      sumEvent += pythiaBeamAGas.event;
    }
    // Select the number of beam B + gas events to generate.
    int nBeamBGas = poisson(nBeamBGasAvg, pythiaBeamBGas.rndm);
    nBGH.fill( nBeamBGas );
    // Generate a number of beam B + gas events. Add them to sumEvent.
    for (int iBG = 0; iBG < nBeamBGas; ++iBG) {
      pythiaBeamBGas.next();
      sumEvent += pythiaBeamBGas.event;
    }
    // List first few events.
    if (iEvent < 1) {
      pythiaSignal.info.list();
      pythiaSignal.process.list();
      sumEvent.list();
    }
    // Find charged multiplicity.
    int nChg = 0;
    for (int i = 0; i < sumEvent.size(); ++i)
      if (sumEvent[i].isFinal() && sumEvent[i].isCharged()) ++nChg;
    nChgH.fill( nChg );
    // Fill net pZ - nonvanishing owing to beam + gas.
    sumPZH.fill( sumEvent[0].pz() );
  // End of event loop
  }
  // Statistics. Histograms.
  pythiaSignal.stat();
  pythiaPileup.stat();
  pythiaBeamAGas.stat();
  pythiaBeamBGas.stat();
  cout << nPileH << nAGH << nBGH << nChgH << sumPZH;
  return 0;
}

main20.cc


// main20.cc is a part of the PYTHIA event generator.
// Copyright (C) 2016 Torbjorn Sjostrand.
// PYTHIA is licenced under the GNU GPL version 2, see COPYING for details.
// Please respect the MCnet Guidelines, see GUIDELINES for details.
// This is a simple test program. It shows how PYTHIA 8 can write
// a Les Houches Event File based on its process-level events.
#include "Pythia8/Pythia.h"
using namespace Pythia8;
int main() {
  // Generator.
  Pythia pythia;
  // Process selection. Minimal masses for gamma*/Z and W+-.
  pythia.readString("WeakDoubleBoson:all = on");
  pythia.readString("23:mMin = 50.");
  pythia.readString("24:mMin = 50.");
  // Switch off generation of steps subsequent to the process level one.
  // (These will not be stored anyway, so only steal time.)
  pythia.readString("PartonLevel:all = off");
  // Create an LHAup object that can access relevant information in pythia.
  LHAupFromPYTHIA8 myLHA(&pythia.process, &pythia.info);
  // Open a file on which LHEF events should be stored, and write header.
  myLHA.openLHEF("weakbosons.lhe");
  // LHC 8 TeV initialization.
  pythia.readString("Beams:eCM = 8000.");
  pythia.init();
  // Store initialization info in the LHAup object.
  myLHA.setInit();
  // Write out this initialization info on the file.
  myLHA.initLHEF();
  // Loop over events.
  for (int i = 0; i < 100; ++i) {
    // Generate an event.
    pythia.next();
    // Store event info in the LHAup object.
    myLHA.setEvent();
    // Write out this event info on the file.
    // With optional argument (verbose =) false the file is smaller.
    myLHA.eventLHEF();
  }
  // Statistics: full printout.
  pythia.stat();
  // Update the cross section info based on Monte Carlo integration during run.
  myLHA.updateSigma();
  // Write endtag. Overwrite initialization info with new cross sections.
  myLHA.closeLHEF(true);
  // Done.
  return 0;
}

main21.cc


// main21.cc is a part of the PYTHIA event generator.
// Copyright (C) 2016 Torbjorn Sjostrand.
// PYTHIA is licenced under the GNU GPL version 2, see COPYING for details.
// Please respect the MCnet Guidelines, see GUIDELINES for details.
// This is a simple test program.
// It illustrates how to feed in a single particle (including a resonance)
// or a toy parton-level configurations.
#include "Pythia8/Pythia.h"
using namespace Pythia8;
//==========================================================================
// Single-particle gun. The particle must be a colour singlet.
// Input: flavour, energy, direction (theta, phi).
// If theta < 0 then random choice over solid angle.
// Optional final argument to put particle at rest => E = m.
void fillParticle(int id, double ee, double thetaIn, double phiIn,
  Event& event, ParticleData& pdt, Rndm& rndm, bool atRest = false) {
  // Reset event record to allow for new event.
  event.reset();
  // Select particle mass; where relevant according to Breit-Wigner.
  double mm = pdt.mSel(id);
  double pp = sqrtpos(ee*ee - mm*mm);
  // Special case when particle is supposed to be at rest.
  if (atRest) {
    ee = mm;
    pp = 0.;
  }
  // Angles as input or uniform in solid angle.
  double cThe, sThe, phi;
  if (thetaIn >= 0.) {
    cThe = cos(thetaIn);
    sThe = sin(thetaIn);
    phi  = phiIn;
  } else {
    cThe = 2. * rndm.flat() - 1.;
    sThe = sqrtpos(1. - cThe * cThe);
    phi = 2. * M_PI * rndm.flat();
  }
  // Store the particle in the event record.
  event.append( id, 1, 0, 0, pp * sThe * cos(phi), pp * sThe * sin(phi),
    pp * cThe, ee, mm);
}
//==========================================================================
// Simple method to do the filling of partons into the event record.
void fillPartons(int type, double ee, Event& event, ParticleData& pdt,
  Rndm& rndm) {
  // Reset event record to allow for new event.
  event.reset();
  // Information on a q qbar system, to be hadronized.
  if (type == 1 || type == 12) {
    int    id = 2;
    double mm = pdt.m0(id);
    double pp = sqrtpos(ee*ee - mm*mm);
    event.append(  id, 23, 101,   0, 0., 0.,  pp, ee, mm);
    event.append( -id, 23,   0, 101, 0., 0., -pp, ee, mm);
  // Information on a g g system, to be hadronized.
  } else if (type == 2 || type == 13) {
    event.append( 21, 23, 101, 102, 0., 0.,  ee, ee);
    event.append( 21, 23, 102, 101, 0., 0., -ee, ee);
  // Information on a g g g system, to be hadronized.
  } else if (type == 3) {
    event.append( 21, 23, 101, 102,        0., 0.,        ee, ee);
    event.append( 21, 23, 102, 103,  0.8 * ee, 0., -0.6 * ee, ee);
    event.append( 21, 23, 103, 101, -0.8 * ee, 0., -0.6 * ee, ee);
  // Information on a q q q junction system, to be hadronized.
  } else if (type == 4 || type == 5) {
    // Need a colour singlet mother parton to define junction origin.
    event.append( 1000022, -21, 0, 0, 2, 4, 0, 0,
                  0., 0., 1.01 * ee, 1.01 * ee);
    // The three endpoint q q q; the minimal system.
    double rt75 = sqrt(0.75);
    event.append( 2, 23, 1, 0, 0, 0, 101, 0,
                          0., 0., 1.01 * ee, 1.01 * ee);
    event.append( 2, 23, 1, 0, 0, 0, 102, 0,
                   rt75 * ee, 0., -0.5 * ee,        ee );
    event.append( 1, 23, 1, 0, 0, 0, 103, 0,
                  -rt75 * ee, 0., -0.5 * ee,        ee );
    // Define the qqq configuration as starting point for adding gluons.
    if (type == 5) {
      int colNow[4] = {0, 101, 102, 103};
      Vec4 pQ[4];
      pQ[1] = Vec4(0., 0., 1., 0.);
      pQ[2] = Vec4( rt75, 0., -0.5, 0.);
      pQ[3] = Vec4(-rt75, 0., -0.5, 0.);
      // Minimal cos(q-g opening angle), allows more or less nasty events.
      double cosThetaMin =0.;
      // Add a few gluons (almost) at random.
      for (int nglu = 0; nglu < 5; ++nglu) {
        int iq = 1 + int( 2.99999 * rndm.flat() );
        double px, py, pz, e, prod;
        do {
          e =  ee * rndm.flat();
          double cThe = 2. * rndm.flat() - 1.;
          double phi = 2. * M_PI * rndm.flat();
          px = e * sqrt(1. - cThe*cThe) * cos(phi);
          py = e * sqrt(1. - cThe*cThe) * sin(phi);
          pz = e * cThe;
          prod = ( px * pQ[iq].px() + py * pQ[iq].py() + pz * pQ[iq].pz() )
            / e;
        } while (prod < cosThetaMin);
        int colNew = 104 + nglu;
        event.append( 21, 23, 1, 0, 0, 0, colNew, colNow[iq],
          px, py, pz, e, 0.);
        colNow[iq] = colNew;
      }
      // Update daughter range of mother.
      event[1].daughters(2, event.size() - 1);
    }
  // Information on a q q qbar qbar dijunction system, to be hadronized.
  } else if (type >= 6) {
    // The two fictitious beam remnant particles; needed for junctions.
    event.append( 2212, -12, 0, 0, 3, 5, 0, 0, 0., 0., ee, ee, 0.);
    event.append(-2212, -12, 0, 0, 6, 8, 0, 0, 0., 0., ee, ee, 0.);
    // Opening angle between "diquark" legs.
    double theta = 0.2;
    double cThe = cos(theta);
    double sThe = sin(theta);
    // Set one colour depending on whether more gluons or not.
    int acol = (type == 6) ? 103 : 106;
    // The four endpoint q q qbar qbar; the minimal system.
    // Two additional fictitious partons to make up original beams.
    event.append(  2,   23, 1, 0, 0, 0, 101, 0,
                  ee * sThe, 0.,  ee * cThe, ee, 0.);
    event.append(  1,   23, 1, 0, 0, 0, 102, 0,
                 -ee * sThe, 0.,  ee * cThe, ee, 0.);
    event.append(  2, -21, 1, 0, 0, 0, 103, 0,
                         0., 0.,  ee       , ee, 0.);
    event.append( -2,   23, 2, 0, 0, 0, 0, 104,
                  ee * sThe, 0., -ee * cThe, ee, 0.);
    event.append( -1,   23, 2, 0, 0, 0, 0, 105,
                 -ee * sThe, 0., -ee * cThe, ee, 0.);
    event.append( -2, -21, 2, 0, 0, 0, 0, acol,
                         0., 0., -ee       , ee, 0.);
    // Add extra gluons on string between junctions.
    if (type == 7) {
      event.append( 21, 23, 5, 8, 0, 0, 103, 106, 0., ee, 0., ee, 0.);
    } else if (type == 8) {
      event.append( 21, 23, 5, 8, 0, 0, 103, 108, 0., ee, 0., ee, 0.);
      event.append( 21, 23, 5, 8, 0, 0, 108, 106, 0.,-ee, 0., ee, 0.);
    } else if (type == 9) {
      event.append( 21, 23, 5, 8, 0, 0, 103, 107, 0., ee, 0., ee, 0.);
      event.append( 21, 23, 5, 8, 0, 0, 107, 108, ee, 0., 0., ee, 0.);
      event.append( 21, 23, 5, 8, 0, 0, 108, 106, 0.,-ee, 0., ee, 0.);
    } else if (type == 10) {
      event.append( 21, 23, 5, 8, 0, 0, 103, 107, 0., ee, 0., ee, 0.);
      event.append( 21, 23, 5, 8, 0, 0, 107, 108, ee, 0., 0., ee, 0.);
      event.append( 21, 23, 5, 8, 0, 0, 108, 109, 0.,-ee, 0., ee, 0.);
      event.append( 21, 23, 5, 8, 0, 0, 109, 106,-ee, 0., 0., ee, 0.);
    }
  // No more cases: done.
  }
}
//==========================================================================
int main() {
  // Pick kind of events to generate:
  // 0 = single-particle gun.
  // 1 = q qbar.
  // 2 = g g.
  // 3 = g g g.
  // 4 = minimal q q q junction topology.
  // 5 = q q q junction topology with gluons on the strings.
  // 6 = q q qbar qbar dijunction topology, no gluons.
  // 7 - 10 = ditto, but with 1 - 4 gluons on string between junctions.
  // 11 = single-resonance gun.
  // 12 = q qbar plus parton shower.
  // 13 = g g plus parton shower.
  int type = 11;
  // Set particle species and energy for single-particle gun.
  int    idGun  = (type == 0) ? 15 : 25;
  double eeGun  = (type == 0) ? 20. : 125.;
  bool   atRest = (type == 0) ? false : true;
  // Set typical energy per parton.
  double ee = 20.0;
  // Set number of events to generate and to list.
  int nEvent = 10000;
  int nList = 3;
  // Generator; shorthand for event and particleData.
  Pythia pythia;
  Event& event      = pythia.event;
  ParticleData& pdt = pythia.particleData;
  // Key requirement: switch off ProcessLevel, and thereby also PartonLevel.
  pythia.readString("ProcessLevel:all = off");
  // Optionally switch off resonance decays, or only showers in them.
  //pythia.readString("ProcessLevel:resonanceDecays = off");
  //pythia.readString("PartonLevel:FSRinResonances = off");
  // Optionally switch off ordinary decays.
  //pythia.readString("HadronLevel:Decay = off");
  // Switch off automatic event listing in favour of manual.
  pythia.readString("Next:numberShowInfo = 0");
  pythia.readString("Next:numberShowProcess = 0");
  pythia.readString("Next:numberShowEvent = 0");
  // Initialize.
  pythia.init();
  // Book histograms.
  Hist epCons("deviation from energy-momentum conservation",100,0.,1e-4);
  Hist chgCons("deviation from charge conservation",57,-9.5,9.5);
  Hist nFinal("final particle multiplicity",100,-0.5,99.5);
  Hist dnparticledp("dn/dp for particles",100,0.,ee);
  Hist status85("multiplicity status code 85",50,-0.5,49.5);
  Hist status86("multiplicity status code 86",50,-0.5,49.5);
  Hist status83("multiplicity status code 83",50,-0.5,49.5);
  Hist status84("multiplicity status code 84",50,-0.5,49.5);
  Hist dndtheta("particle flow in event plane",100,-M_PI,M_PI);
  Hist dedtheta("energy flow in event plane",100,-M_PI,M_PI);
  Hist dpartondtheta("parton flow in event plane",100,-M_PI,M_PI);
  Hist dndyAnti("dn/dy primaries antijunction",100, -10., 10.);
  Hist dndyJun("dn/dy primaries junction",100, -10., 10.);
  Hist dndySum("dn/dy all primaries",100, -10., 10.);
  // Begin of event loop.
  for (int iEvent = 0; iEvent < nEvent; ++iEvent) {
    // Set up single particle, with random direction in solid angle.
    if (type == 0 || type == 11) fillParticle( idGun, eeGun, -1., 0.,
      event, pdt, pythia.rndm, atRest);
    // Set up parton-level configuration.
    else fillPartons( type, ee, event, pdt, pythia.rndm);
    // To have partons shower they must be set maximum allowed scale.
    // (Can be set individually to restrict radiation differently.)
    if (type == 12 || type == 13) {
      double scale = ee;
      event[1].scale( scale);
      event[2].scale( scale);
      // Now actually do the shower, for range of partons, and max scale.
      // (Most restrictive of global and individual applied to each parton.)
      pythia.forceTimeShower( 1, 2, scale);
    }
    // Generate events. Quit if failure.
    if (!pythia.next()) {
      cout << " Event generation aborted prematurely, owing to error!\n";
      break;
    }
    // List first few events.
    if (iEvent < nList) {
      event.list();
      // Also list junctions.
      event.listJunctions();
    }
    // Initialize statistics.
    Vec4 pSum = - event[0].p();
    double chargeSum = 0.;
    if (type == 0) chargeSum = -event[1].charge();
    if (type == 4 || type == 5) chargeSum = -1;
    int nFin = 0;
    int n85 = 0;
    int n86 = 0;
    int n83 = 0;
    int n84 = 0;
    // Loop over all particles.
    for (int i = 0; i < event.size(); ++i) {
      int status = event[i].statusAbs();
      // Find any unrecognized particle codes.
      int id = event[i].id();
      if (id == 0 || !pdt.isParticle(id))
        cout << " Error! Unknown code id = " << id << "\n";
      // Find particles with E-p mismatch.
      double eCalc = event[i].eCalc();
      if (abs(eCalc/event[i].e() - 1.) > 1e-6) cout << " e mismatch, i = "
        << i << " e_nominal = " << event[i].e() << " e-from-p = "
        << eCalc << " m-from-e " << event[i].mCalc() << "\n";
      // Parton flow in event plane.
      if (status == 71 || status == 72) {
        double thetaXZ = event[i].thetaXZ();
        dpartondtheta.fill(thetaXZ);
      }
      // Origin of primary hadrons.
      if (status == 85) ++n85;
      if (status == 86) ++n86;
      if (status == 83) ++n83;
      if (status == 84) ++n84;
      // Flow of primary hadrons in the event plane.
      if (status > 80 && status < 90) {
        double eAbs = event[i].e();
        if (eAbs < 0.) {cout << " e < 0 line " << i; event.list();}
        double thetaXZ = event[i].thetaXZ();
        dndtheta.fill(thetaXZ);
        dedtheta.fill(thetaXZ, eAbs);
        // Rapidity distribution of primary hadrons.
        double y = event[i].y();
        dndySum.fill(y);
        if (type >= 6) {
          int motherId = event[event[i].mother1()].id();
          if (motherId > 0 ) dndyJun.fill(event[i].y());
          else dndyAnti.fill(event[i].y());
        }
      }
      // Study final-state particles.
      if (event[i].isFinal()) {
        pSum += event[i].p();
        chargeSum += event[i].charge();
        nFin++;
        double pAbs = event[i].pAbs();
        dnparticledp.fill(pAbs);
      }
    }
    // Fill histograms once for each event.
    double epDev = abs(pSum.e()) + abs(pSum.px()) + abs(pSum.py())
      + abs(pSum.pz());
    epCons.fill(epDev);
    chgCons.fill(chargeSum);
    nFinal.fill(nFin);
    status85.fill(n85);
    status86.fill(n86);
    status83.fill(n83);
    status84.fill(n84);
    if (epDev > 1e-3  || abs(chargeSum) > 0.1) event.list();
  // End of event loop.
  }
  // Print statistics, histograms and done.
  pythia.stat();
  cout << epCons << chgCons << nFinal << dnparticledp
       << dndtheta << dedtheta << dpartondtheta << dndySum;
  if (type >= 4) cout << status85 << status86 << status83
       << status84;
  if (type >= 6) cout << dndyJun << dndyAnti;
  // Done.
  return 0;
}

main22.cc


// main22.cc is a part of the PYTHIA event generator.
// Copyright (C) 2016 Torbjorn Sjostrand.
// PYTHIA is licenced under the GNU GPL version 2, see COPYING for details.
// Please respect the MCnet Guidelines, see GUIDELINES for details.
// Simple illustration how to provide (a) your own resonance-width class,
// and (b) your own cross-section class, with instances handed in to Pythia.
// The hypothetical scenario is that top would have been so long-lived
// that a toponium resonance Theta could form. Then production could
// proceed via q qbar -> gamma*/Z* -> Theta, with decay either to
// a fermion pair or (dominantly) to three gluons.
// The implementation is not physically correct in any number of ways,
// but should exemplify the strategy needed for realistic cases.
#include "Pythia8/Pythia.h"
using namespace Pythia8;
//==========================================================================
// The ResonanceTheta class handles a toponium resonance.
class ResonanceTheta : public ResonanceWidths {
public:
  // Constructor.
  ResonanceTheta(int idResIn) {initBasic(idResIn);}
private:
  // Locally stored properties and couplings.
  double normTheta2qqbar, normTheta2llbar, normTheta2ggg;
  // Initialize constants.
  virtual void initConstants();
  // Calculate various common prefactors for the current mass.
  // Superfluous here, so skipped.
  //virtual void calcPreFac(bool = false);
  // Calculate width for currently considered channel.
  virtual void calcWidth(bool = false);
};
//--------------------------------------------------------------------------
// Initialize constants.
void ResonanceTheta::initConstants() {
  // Dummy normalization of couplings to the allowed decay channels.
  normTheta2qqbar = 0.0001;
  normTheta2llbar = 0.0001;
  normTheta2ggg   = 0.001;
}
//--------------------------------------------------------------------------
// Calculate width for currently considered channel.
void ResonanceTheta::calcWidth(bool) {
  // Expression for Theta -> q qbar (q up to b). Colour factor.
  if (id1Abs < 6) widNow = 3. * normTheta2qqbar * mHat;
  // Expression for Theta -> l lbar (l = e, mu, tau).
  else if (id1Abs == 11  || id1Abs == 13 || id1Abs == 15)
    widNow = normTheta2llbar * mHat;
  // Expression for Theta -> g g g. Colour factor.
  else if (id1Abs == 21) widNow = 8. * normTheta2ggg * mHat;
}
//==========================================================================
// A derived class for q qbar -> Theta (toponium bound state).
class Sigma1qqbar2Theta : public Sigma1Process {
public:
  // Constructor.
  Sigma1qqbar2Theta() {}
  // Initialize process.
  virtual void initProc();
  // Calculate flavour-independent parts of cross section.
  virtual void sigmaKin();
  // Evaluate sigmaHat(sHat). Assumed flavour-independent so simple.
  virtual double sigmaHat() {return sigma;}
  // Select flavour, colour and anticolour.
  virtual void setIdColAcol();
  // Evaluate weight for decay angles.
  virtual double weightDecay( Event& process, int iResBeg, int iResEnd);
  // Info on the subprocess.
  virtual string name()       const {return "q qbar -> Theta";}
  virtual int    code()       const {return 621;}
  virtual string inFlux()     const {return "qqbarSame";}
  virtual int    resonanceA() const {return 663;}
private:
  // Store flavour-specific process information and standard prefactor.
  int    idTheta;
  double mRes, GammaRes, m2Res, GamMRat, normTheta2qqbar, sigma;
  // Pointer to properties of Theta, to access decay width.
  ParticleDataEntry* particlePtr;
};
//--------------------------------------------------------------------------
// Initialize process.
void Sigma1qqbar2Theta::initProc() {
  // Store Theta mass and width for propagator.
  idTheta  = 663;
  mRes     = particleDataPtr->m0(idTheta);
  GammaRes = particleDataPtr->mWidth(idTheta);
  m2Res    = mRes*mRes;
  GamMRat  = GammaRes / mRes;
  // Same normlization as in ResonanceTheta for coupling strength.
  normTheta2qqbar = 0.0001;
  // Set pointer to particle properties and decay table.
  particlePtr = particleDataPtr->particleDataEntryPtr(idTheta);
}
//--------------------------------------------------------------------------
// Evaluate sigmaHat(sHat); first step when inflavours unknown.
void Sigma1qqbar2Theta::sigmaKin() {
  // Incoming width with colour factor.
  double widthIn  = normTheta2qqbar * mH / 3.;
  // Breit-Wigner, including some (guessed) spin factors.
  double sigBW    = 12. * M_PI / ( pow2(sH - m2Res) + pow2(sH * GamMRat) );
  // Outgoing width: only includes channels left open.
  double widthOut = particlePtr->resWidthOpen(663, mH);
  // Total answer.
  sigma = widthIn * sigBW * widthOut;
}
//--------------------------------------------------------------------------
// Select identity, colour and anticolour.
void Sigma1qqbar2Theta::setIdColAcol() {
  // Flavours trivial.
  setId( id1, id2, idTheta);
  // Colour flow topologies. Swap when antiquarks.
  setColAcol( 1, 0, 0, 1, 0, 0);
  if (id1 < 0) swapColAcol();
}
//--------------------------------------------------------------------------
// Evaluate weight for Theta -> g g g.
double Sigma1qqbar2Theta::weightDecay( Event& process, int iResBeg,
  int iResEnd) {
  // Should be Theta decay. (This is only option here, so overkill.)
  if (iResEnd != iResBeg || process[iResBeg].idAbs() != idTheta)
    return 1.;
  // Should be decay to three gluons.
  int i1 = process[iResBeg].daughter1();
  int i2 = i1 + 1;
  int i3 = i2 + 1;
  if (i3 != process[iResBeg].daughter2() || process[i1].id() != 21)
    return 1.;
  // Energy fractions x_i = 2 E_i/m_Theta of gluons in Theta rest frame.
  double x1 = 2. * process[i1].p() * process[iResBeg].p()
            / process[iResBeg].m2();
  double x2 = 2. * process[i2].p() * process[iResBeg].p()
            / process[iResBeg].m2();
  double x3 = 2. * process[i3].p() * process[iResBeg].p()
            / process[iResBeg].m2();
  // Matrix-element expression for Theta -> g g g.
  double wtME = pow2( (1. - x1) / (x2 * x3) )
    + pow2( (1. - x2) / (x1 * x3) ) + pow2( (1. - x3) / (x1 * x2) );
  double wtMEmax = 2.;
  return wtME / wtMEmax;
}
//==========================================================================
int main() {
  // Number of events to generate. Max number of errors.
  // Warning: generation of complete events is much slower than if you use
  // PartonLevel:all = off to only get cross sections, so adjust nEvent.
  int nEvent = 1000;
  int nAbort = 5;
  // Pythia generator.
  Pythia pythia;
  // Create the toponium resonance and a few production/decay channels.
  // Warning: many more exist, e.g. weak ones of one top quark.
  // Note: to obtain the correct width for the Breit-Wigner you must
  // include all channels, but you only need leave those on that you
  // want to study.
  pythia.readString("663:new = Theta void 3 0 0 342.0 0.2 300. 400. 0.");
  pythia.readString("663:addChannel = 1 0. 0 1 -1");
  pythia.readString("663:addChannel = 1 0. 0 2 -2");
  pythia.readString("663:addChannel = 1 0. 0 3 -3");
  pythia.readString("663:addChannel = 1 0. 0 4 -4");
  pythia.readString("663:addChannel = 1 0. 0 5 -5");
  pythia.readString("663:addChannel = 1 0. 0 11 -11");
  pythia.readString("663:addChannel = 1 0. 0 13 -13");
  pythia.readString("663:addChannel = 1 0. 0 15 -15");
  pythia.readString("663:addChannel = 1 0. 0 21 21 21");
  // Create instance of a class to calculate the width of Theta to the
  // above channels. Hand in pointer to Pythia.
  // Note: Pythia will automatically delete this pointer,
  // along with all other resonances.
  ResonanceWidths* resonanceTheta = new ResonanceTheta(663);
  pythia.setResonancePtr(resonanceTheta);
  // Create instance of a class to generate the q qbar -> Theta process
  // from an external matrix element. Hand in pointer to Pythia.
  SigmaProcess* sigma1Theta = new Sigma1qqbar2Theta();
  pythia.setSigmaPtr(sigma1Theta);
  // Optionally only compare cross sections.
  //pythia.readString("PartonLevel:all = off");
  pythia.readString("Check:nErrList = 2");
  // Initialization for LHC.
  pythia.init();
  // Book histogram.
  Hist mTheta("Theta mass", 100, 300., 400.);
  // Begin event loop.
  int iAbort = 0;
  for (int iEvent = 0; iEvent < nEvent; ++iEvent) {
    // Generate events. Quit if many failures.
    if (!pythia.next()) {
      if (++iAbort < nAbort) continue;
      cout << " Event generation aborted prematurely, owing to error!\n";
      break;
    }
    // Fill Theta mass. End of event loop.
    mTheta.fill( pythia.process[5].m() );
  }
  // Final statistics. Print histogram.
  pythia.stat();
  cout << mTheta;
  // Done.
  delete sigma1Theta;
  return 0;
}

main23.cc


// main23.cc is a part of the PYTHIA event generator.
// Copyright (C) 2016 Torbjorn Sjostrand.
// PYTHIA is licenced under the GNU GPL version 2, see COPYING for details.
// Please respect the MCnet Guidelines, see GUIDELINES for details.
// Example how to write a derived class for beam momentum and vertex spread,
// with an instance handed to Pythia for internal generation.
// Also how to write a derived class for external random numbers,
// and how to write a derived class for external parton distributions.
// Warning: the parameters are not realistic.
#include "Pythia8/Pythia.h"
using namespace Pythia8;
//==========================================================================
// A derived class to set beam momentum and interaction vertex spread.
class MyBeamShape : public BeamShape {
public:
  // Constructor.
  MyBeamShape() {}
  // Initialize beam parameters.
  // In this particular example we will reuse the existing settings names
  // but with modified meaning, so init() in the base class can be kept.
  //virtual void init( Settings& settings, Rndm* rndmPtrIn);
  // Set the two beam momentum deviations and the beam vertex.
  virtual void pick();
};
//--------------------------------------------------------------------------
// Set the two beam momentum deviations and the beam vertex.
// Note that momenta are in units of GeV and vertices in mm,
// always with c = 1, so that e.g. time is in mm/c.
void MyBeamShape::pick() {
  // Reset all values.
  deltaPxA = deltaPyA = deltaPzA = deltaPxB = deltaPyB = deltaPzB
    = vertexX = vertexY = vertexZ = vertexT = 0.;
  // Set beam A transverse momentum deviation by a two-dimensional Gaussian.
  if (allowMomentumSpread) {
    double totalDev, gauss;
    do {
      totalDev = 0.;
      if (sigmaPxA > 0.) {
        gauss     = rndmPtr->gauss();
        deltaPxA  = sigmaPxA * gauss;
        totalDev += gauss * gauss;
      }
      if (sigmaPyA > 0.) {
        gauss     = rndmPtr->gauss();
        deltaPyA  = sigmaPyA * gauss;
        totalDev += gauss * gauss;
      }
    } while (totalDev > maxDevA * maxDevA);
    // Set beam A longitudinal momentum as a triangular shape.
    // Reuse sigmaPzA to represent maximum deviation in this case.
    if (sigmaPzA > 0.) {
      deltaPzA    = sigmaPzA * ( 1. - sqrt(rndmPtr->flat()) );
      if (rndmPtr->flat() < 0.5) deltaPzA = -deltaPzA;
    }
    // Set beam B transverse momentum deviation by a two-dimensional Gaussian.
    do {
      totalDev = 0.;
      if (sigmaPxB > 0.) {
        gauss     = rndmPtr->gauss();
        deltaPxB  = sigmaPxB * gauss;
        totalDev += gauss * gauss;
      }
      if (sigmaPyB > 0.) {
        gauss     = rndmPtr->gauss();
        deltaPyB  = sigmaPyB * gauss;
        totalDev += gauss * gauss;
      }
    } while (totalDev > maxDevB * maxDevB);
    // Set beam B longitudinal momentum as a triangular shape.
    // Reuse sigmaPzB to represent maximum deviation in this case.
    if (sigmaPzB > 0.) {
      deltaPzB = sigmaPzB * ( 1. - sqrt(rndmPtr->flat()) );
      if (rndmPtr->flat() < 0.5) deltaPzB = -deltaPzB;
    }
  }
  // Set beam vertex location by a two-dimensional Gaussian.
  if (allowVertexSpread) {
    double totalDev, gauss;
    do {
      totalDev = 0.;
      if (sigmaVertexX > 0.) {
        gauss     = rndmPtr->gauss();
        vertexX   = sigmaVertexX * gauss;
        totalDev += gauss * gauss;
      }
      if (sigmaVertexY > 0.) {
        gauss     = rndmPtr->gauss();
        vertexY   = sigmaVertexY * gauss;
        totalDev += gauss * gauss;
      }
    } while (totalDev > maxDevVertex * maxDevVertex);
    // Set beam B longitudinal momentum as a triangular shape.
    // This corresponds to two step-function beams colliding.
    // Reuse sigmaVertexZ to represent maximum deviation in this case.
    if (sigmaVertexZ > 0.) {
      vertexZ     = sigmaVertexZ * ( 1. - sqrt(rndmPtr->flat()) );
      if (rndmPtr->flat() < 0.5) vertexZ = -vertexZ;
      // Set beam collision time flat between +-(sigmaVertexZ - |vertexZ|).
      // This corresponds to two step-function beams colliding (with v = c).
      vertexT = (2. * rndmPtr->flat() - 1.) * (sigmaVertexZ - abs(vertexZ));
    }
    // Add offset to beam vertex.
    vertexX      += offsetX;
    vertexY      += offsetY;
    vertexZ      += offsetZ;
    vertexT      += offsetT;
  }
}
//==========================================================================
// A derived class to generate random numbers.
// A guranteed VERY STUPID generator, just to show principles.
class stupidRndm : public RndmEngine {
public:
  // Constructor.
  stupidRndm() { init();}
  // Routine for generating a random number.
  double flat();
private:
  // Initialization.
  void init();
  // State of the generator.
  double value, exp10;
};
//--------------------------------------------------------------------------
// Initialization method for the random numbers.
void stupidRndm::init() {
  // Initial values.
  value = 0.5;
  exp10 = exp(10.);
}
//--------------------------------------------------------------------------
// Generation method for the random numbers.
double stupidRndm::flat() {
  // Update counter. Add to current value.
  do {
    value *= exp10;
    value += M_PI;
    value -= double(int(value));
    if (value < 0.) value += 1.;
  } while (value <= 0. || value >= 1.);
  // Return new value.
  return value;
}
//==========================================================================
// A simple scaling PDF. Not realistic; only to check that it works.
class Scaling : public PDF {
public:
  // Constructor.
  Scaling(int idBeamIn = 2212) : PDF(idBeamIn) {}
private:
  // Update PDF values.
  void xfUpdate(int id, double x, double Q2);
};
//--------------------------------------------------------------------------
// No dependence on Q2, so leave out name for last argument.
void Scaling::xfUpdate(int, double x, double ) {
  // Valence quarks, carrying 60% of the momentum.
  double dv  = 4. * x * pow3(1. - x);
  double uv  = 2. * dv;
  // Gluons and sea quarks carrying the rest.
  double gl  = 2.  * pow5(1. - x);
  double sea = 0.4 * pow5(1. - x);
  // Update values
  xg    = gl;
  xu    = uv + 0.18 * sea;
  xd    = dv + 0.18 * sea;
  xubar = 0.18 * sea;
  xdbar = 0.18 * sea;
  xs    = 0.08 * sea;
  xc    = 0.04 * sea;
  xb    = 0.02 * sea;
  // Subdivision of valence and sea.
  xuVal = uv;
  xuSea = xubar;
  xdVal = dv;
  xdSea = xdbar;
  // idSav = 9 to indicate that all flavours reset.
  idSav = 9;
}
//==========================================================================
int main() {
  // Number of events to generate. Max number of errors.
  int nEvent = 10000;
  int nAbort = 5;
  // Pythia generator.
  Pythia pythia;
  // Process selection.
  pythia.readString("HardQCD:all = on");
  pythia.readString("PhaseSpace:pTHatMin = 20.");
  // LHC with acollinear beams in the x plane.
  // Use that default is pp with pz = +-7000 GeV, so this need not be set.
  pythia.readString("Beams:frameType = 3");
  pythia.readString("Beams:pxA = 1.");
  pythia.readString("Beams:pxB = 1.");
  // A class to generate beam parameters according to own parametrization.
  BeamShape* myBeamShape = new MyBeamShape();
  // Hand pointer to Pythia.
  // If you comment this out you get internal Gaussian-style implementation.
  pythia.setBeamShapePtr( myBeamShape);
  // Set up beam spread parameters - reused by MyBeamShape.
  pythia.readString("Beams:allowMomentumSpread = on");
  pythia.readString("Beams:sigmapxA = 0.1");
  pythia.readString("Beams:sigmapyA = 0.1");
  pythia.readString("Beams:sigmapzA = 5.");
  pythia.readString("Beams:sigmapxB = 0.1");
  pythia.readString("Beams:sigmapyB = 0.1");
  pythia.readString("Beams:sigmapzB = 5.");
  // Set up beam vertex parameters - reused by MyBeamShape.
  pythia.readString("Beams:allowVertexSpread = on");
  pythia.readString("Beams:sigmaVertexX = 0.3");
  pythia.readString("Beams:sigmaVertexY = 0.3");
  pythia.readString("Beams:sigmaVertexZ = 50.");
  // In MyBeamShape the time width is not an independent parameter.
  //pythia.readString("Beams:sigmaTime = 50.");
  // Optionally simplify generation.
  pythia.readString("PartonLevel:all = off");
  // A class to do random numbers externally. Hand pointer to Pythia.
  RndmEngine* badRndm = new stupidRndm();
  pythia.setRndmEnginePtr( badRndm);
  // Two classes to do the two PDFs externally. Hand pointers to Pythia.
  PDF* pdfAPtr = new Scaling(2212);
  PDF* pdfBPtr = new Scaling(2212);
  pythia.setPDFPtr( pdfAPtr, pdfBPtr);
  // Initialization.
  pythia.init();
  // Read out nominal energy.
  double eCMnom = pythia.info.eCM();
  // Histograms.
  Hist eCM("center-of-mass energy deviation", 100, -20., 20.);
  Hist pXsum("net pX offset", 100, -1.0, 1.0);
  Hist pYsum("net pY offset", 100, -1.0, 1.0);
  Hist pZsum("net pZ offset", 100, -10., 10.);
  Hist pZind("individual abs(pZ) offset", 100, -10., 10.);
  Hist vtxX("vertex x position", 100, -1.0, 1.0);
  Hist vtxY("vertex y position", 100, -1.0, 1.0);
  Hist vtxZ("vertex z position", 100, -100., 100.);
  Hist vtxT("vertex time", 100, -100., 100.);
  Hist vtxZT("vertex |x| + |t|", 100, 0., 100.);
  // Begin event loop. Generate event.
  int iAbort = 0;
  for (int iEvent = 0; iEvent < nEvent; ++iEvent) {
    if (!pythia.next()) {
      // List faulty events and quit if many failures.
      pythia.info.list();
      pythia.process.list();
      //pythia.event.list();
      if (++iAbort < nAbort) continue;
      cout << " Event generation aborted prematurely, owing to error!\n";
      break;
    }
    // Fill histograms.
    double eCMnow = pythia.info.eCM();
    eCM.fill( eCMnow - eCMnom);
    pXsum.fill(  pythia.process[0].px() - 2. );
    pYsum.fill(  pythia.process[0].py() );
    pZsum.fill(  pythia.process[0].pz() );
    pZind.fill(  pythia.process[1].pz() - 7000. );
    pZind.fill( -pythia.process[2].pz() - 7000. );
    vtxX.fill(  pythia.process[0].xProd() );
    vtxY.fill(  pythia.process[0].yProd() );
    vtxZ.fill(  pythia.process[0].zProd() );
    vtxT.fill(  pythia.process[0].tProd() );
    double absSum = abs(pythia.process[0].zProd())
                  + abs(pythia.process[0].tProd());
    vtxZT.fill( absSum );
  // End of event loop. Statistics. Histograms.
  }
  pythia.stat();
  cout << eCM << pXsum << pYsum << pZsum << pZind
       << vtxX << vtxY << vtxZ << vtxT << vtxZT;
  // Study standard Pythia random number generator.
  Hist rndmDist("standard random number distribution", 100, 0., 1.);
  Hist rndmCorr("standard random number correlation", 100, 0., 1.);
  double rndmNow;
  double rndmOld = pythia.rndm.flat();
  for (int i = 0; i < 100000; ++i) {
    rndmNow = pythia.rndm.flat();
    rndmDist.fill(rndmNow);
    rndmCorr.fill( abs(rndmNow - rndmOld) );
    rndmOld = rndmNow;
  }
  cout << rndmDist << rndmCorr;
  // Study bad "new" random number generator.
  Hist rndmDist2("stupid random number distribution", 100, 0., 1.);
  Hist rndmCorr2("stupid random number correlation", 100, 0., 1.);
  rndmOld = pythia.rndm.flat();
  for (int i = 0; i < 100000; ++i) {
    rndmNow = pythia.rndm.flat();
    rndmDist2.fill(rndmNow);
    rndmCorr2.fill( abs(rndmNow - rndmOld) );
    rndmOld = rndmNow;
  }
  cout << rndmDist2 << rndmCorr2;
  // Done.
  delete myBeamShape;
  delete badRndm;
  delete pdfAPtr;
  delete pdfBPtr;
  return 0;
}

main24.cc


// main24.cc is a part of the PYTHIA event generator.
// Copyright (C) 2016 Peter Skands, Torbjorn Sjostrand.
// PYTHIA is licenced under the GNU GPL version 2, see COPYING for details.
// Please respect the MCnet Guidelines, see GUIDELINES for details.
// This is a simple test program.
// It illustrates how to run SUSY processes in Pythia8.
// All input is specified in the main22.cmnd file.
#include "Pythia8/Pythia.h"
using namespace Pythia8;
int main() {
  // Generator. Shorthand for the event.
  Pythia pythia;
  Event& event = pythia.event;
  // Read in commands from external file.
  pythia.readFile("main24.cmnd");
  // Extract settings to be used in the main program.
  int nEvent   = pythia.mode("Main:numberOfEvents");
  int nAbort   = pythia.mode("Main:timesAllowErrors");
  double eCM   = pythia.parm("Beams:eCM");
  // Initialize.
  pythia.init();
  // Histograms.
  double epTol = 1e-6 * eCM;
  Hist epCons("deviation from energy-momentum conservation",100,0.,epTol);
  Hist nFinal("final particle multiplicity",100,-0.5,799.5);
  Hist dnparticledy("dn/dy for particles",100,-10.,10.);
  // Begin event loop.
  int iAbort = 0;
  for (int iEvent = 0; iEvent < nEvent; ++iEvent) {
    // Generate events. Quit if failure.
    if (!pythia.next()) {
      if (++iAbort < nAbort) continue;
      cout << " Event generation aborted prematurely, owing to error!\n";
      break;
    }
    // Loop over final particles in the event.
    int nFin = 0;
    Vec4 pSum;
    for (int i = 0; i < event.size(); ++i) if (event[i].isFinal()) {
      nFin++;
      pSum += event[i].p();
      dnparticledy.fill(event[i].y());
    }
    // Check and print event with too big energy-momentum deviation.
    nFinal.fill(nFin);
    double epDev = abs(pSum.e() - eCM) + abs(pSum.px()) + abs(pSum.py())
      + abs(pSum.pz());
    epCons.fill(epDev);
    if (epDev > epTol) {
      cout << " Warning! Event with epDev = " << scientific
           << setprecision(4) << epDev << " now listed:";
      event.list();
    }
  // End of event loop.
  }
  // Final statistics and histogram output.
  pythia.stat();
  cout << epCons << nFinal << dnparticledy;
  return 0;
}

main25.cc


// main25.cc is a part of the PYTHIA event generator.
// Copyright (C) 2016 Torbjorn Sjostrand.
// PYTHIA is licenced under the GNU GPL version 2, see COPYING for details.
// Please respect the MCnet Guidelines, see GUIDELINES for details.
// This is a simple test program.
// It illustrates how Les Houches Event File input can be used in Pythia8.
// Here the very few events are generated with MadGraph, and illustrate
// more complicated colour topologies.
#include "Pythia8/Pythia.h"
using namespace Pythia8;
int main() {
  // Generator
  Pythia pythia;
  // Stick with default values, so do not bother with a separate file
  // for changes. However, do one change, to show readString in action.
  pythia.readString("PartonLevel:ISR = off");
  pythia.readString("PartonLevel:FSR = off");
  pythia.readString("PartonLevel:MPI = off");
  pythia.readString("HadronLevel:Hadronize = on");
  // Initialize Les Houches Event File run.
  pythia.readString("Beams:frameType = 4");
  pythia.readString("Beams:LHEF = main25.lhe");
  pythia.init();
  // Book histogram.
  Hist nCharged("charged particle multiplicity",100,-0.5,399.5);
  // Allow for possibility of a few faulty events.
  int nAbort = 10;
  int iAbort = 0;
  // Begin event loop; generate until none left in input file.
  for (int iEvent = 0; ; ++iEvent) {
    cout << endl << "Begin event # " << iEvent << endl;
    // Generate events, and check whether generation failed.
    if (!pythia.next()) {
      // If failure because reached end of file then exit event loop.
      if (pythia.info.atEndOfFile()) break;
      // First few failures write off as "acceptable" errors, then quit.
      if (++iAbort < nAbort) continue;
      break;
    }
    // Sum up final charged multiplicity and fill in histogram.
    int nChg = 0;
    for (int i = 0; i < pythia.event.size(); ++i)
    if (pythia.event[i].isFinal() && pythia.event[i].isCharged())
      ++nChg;
    nCharged.fill(nChg);
  // End of event loop.
  }
  // Give statistics. Print histogram.
  pythia.stat();
  cout << nCharged;
  // Done.
  return 0;
}

main26.cc


// main26.cc is a part of the PYTHIA event generator.
// Copyright (C) 2016 Torbjorn Sjostrand.
// PYTHIA is licenced under the GNU GPL version 2, see COPYING for details.
// Please respect the MCnet Guidelines, see GUIDELINES for details.
// This is a test program for the extra dimensions processes.
// Author: Stefan Ask (Stefan DOT Ask AT cern DOT ch)
// Documentation: S. Ask et al., arXiv:0809.4750 and arXiv:0912.4233
#include "Pythia8/Pythia.h"
using namespace Pythia8;
// The main program.
int main() {
  // Test cases
  // 1  = Jet + G       (real G emission)
  // 2  = Jet + U       (real U emission)
  // 3  = Z + G         (real G emission)
  // 4  = Z + U         (real U emission)
  // 5  = gamma gamma   (LED G* exchange)
  // 6  = l lbar        (LED U* exchange).
  //      Note: charged leptons only!
  // 7  = Z_KK/gamma_KK (TEV ED resonance)
  // 8  = G*            (RS resonance, SM on the TeV brane)
  // 9  = kk-gluon*     (RS resonance)
  int nTest = 1;
  // Number of events to generate. Max number of errors.
  int nEvent     = 1000;
  int nAbort     = 50;
  // Pythia generator.
  Pythia pythia;
  // PYTHIA paramters:
  pythia.readString("PhaseSpace:showViolation = off");
  // Test case parameters
  if (nTest == 1) {
    pythia.readString("ExtraDimensionsLED:monojet = on");
    pythia.readString("ExtraDimensionsLED:n = 4");
    pythia.readString("ExtraDimensionsLED:MD = 4000.");
    pythia.readString("ExtraDimensionsLED:CutOffmode = 3");
    pythia.readString("ExtraDimensionsLED:t = 2");
    pythia.readString("5000039:m0 = 2500.");
    pythia.readString("5000039:mWidth = 1500.");
    pythia.readString("5000039:mMin = 1.");
    pythia.readString("5000039:mMax = 13990.");
    pythia.readString("PhaseSpace:pTHatMin = 700.");
  } else if (nTest == 2){
    pythia.readString("ExtraDimensionsUnpart:gg2Ug = off");
    pythia.readString("ExtraDimensionsUnpart:qg2Uq = on");
    pythia.readString("ExtraDimensionsUnpart:qqbar2Ug = on");
    pythia.readString("ExtraDimensionsUnpart:spinU = 1");
    pythia.readString("ExtraDimensionsUnpart:dU = 1.2");
    pythia.readString("ExtraDimensionsUnpart:LambdaU = 1000");
    pythia.readString("ExtraDimensionsUnpart:lambda = 1.0");
    pythia.readString("ExtraDimensionsUnpart:CutOffmode = 0");
    pythia.readString("5000039:m0 = 300.");
    pythia.readString("5000039:mWidth = 500.");
    pythia.readString("5000039:mMin = 1.");
    pythia.readString("5000039:mMax = 13990.");
    pythia.readString("PhaseSpace:pTHatMin = 700.");
  } else if (nTest == 3){
    pythia.readString("ExtraDimensionsLED:ffbar2GZ = on");
    pythia.readString("ExtraDimensionsLED:n = 6");
    pythia.readString("ExtraDimensionsLED:MD = 2000.");
    pythia.readString("ExtraDimensionsLED:CutOffmode = 1");
    pythia.readString("5000039:m0 = 3000.");
    pythia.readString("5000039:mWidth = 1500.");
    pythia.readString("5000039:mMin = 1.");
    pythia.readString("5000039:mMax = 13990.");
    pythia.readString("PhaseSpace:pTHatMin = 50.");
  } else if (nTest == 4){
    pythia.readString("ExtraDimensionsUnpart:ffbar2UZ = on");
    pythia.readString("ExtraDimensionsUnpart:spinU = 1");
    pythia.readString("ExtraDimensionsUnpart:dU = 2.0");
    pythia.readString("ExtraDimensionsUnpart:LambdaU = 1000");
    pythia.readString("ExtraDimensionsUnpart:lambda = 1.000");
    pythia.readString("ExtraDimensionsUnpart:CutOffmode = 0");
    pythia.readString("5000039:m0 = 500.");
    pythia.readString("5000039:mWidth = 1000.");
    pythia.readString("5000039:mMin = 1.");
    pythia.readString("5000039:mMax = 13990.");
    pythia.readString("PhaseSpace:pTHatMin = 50.");
  } else if (nTest == 5){
    pythia.readString("ExtraDimensionsLED:ffbar2gammagamma = on");
    pythia.readString("ExtraDimensionsLED:gg2gammagamma = on");
    pythia.readString("ExtraDimensionsLED:LambdaT = 3300.");
    pythia.readString("PhaseSpace:mHatMin = 800.");
  } else if (nTest == 6){
    pythia.readString("ExtraDimensionsUnpart:ffbar2llbar = on");
    pythia.readString("ExtraDimensionsUnpart:gg2llbar = off");
    pythia.readString("ExtraDimensionsUnpart:spinU = 1");
    pythia.readString("ExtraDimensionsUnpart:dU = 1.3");
    pythia.readString("ExtraDimensionsUnpart:LambdaU = 1000");
    pythia.readString("ExtraDimensionsUnpart:lambda = 1.0");
    pythia.readString("ExtraDimensionsUnpart:gXX = 0");
    pythia.readString("ExtraDimensionsUnpart:gXY = 0");
    pythia.readString("PhaseSpace:mHatMin = 300.");
  } else if (nTest == 7){
    pythia.readString("ExtraDimensionsTEV:ffbar2mu+mu- = on");
    pythia.readString("ExtraDimensionsTEV:gmZmode = 3");
    pythia.readString("ExtraDimensionsTEV:nMax = 100");
    pythia.readString("ExtraDimensionsTEV:mStar = 4000");
    pythia.readString("PhaseSpace:mHatMin = 1000");
    pythia.readString("PhaseSpace:mHatMax = 6000");
    pythia.readString("5000023:isResonance = false");
  } else if (nTest == 8){
    pythia.readString("ExtraDimensionsG*:all = on");
  } else if (nTest == 9){
    pythia.readString("ExtraDimensionsG*:qqbar2KKgluon* = on");
    pythia.readString("ExtraDimensionsG*:KKintMode = 2");
    pythia.readString("ExtraDimensionsG*:KKgqR = -0.2");
    pythia.readString("ExtraDimensionsG*:KKgqL = -0.2");
    pythia.readString("ExtraDimensionsG*:KKgbR = -0.2");
    pythia.readString("ExtraDimensionsG*:KKgbL = 1.0");
    pythia.readString("ExtraDimensionsG*:KKgtR = 5.0");
    pythia.readString("ExtraDimensionsG*:KKgtL = 1.0");
    pythia.readString("5100021:m0 = 2000");
  }
  // Switch off sophisticated tau treatment: not yet matched to SUSY.
  pythia.readString("TauDecays:mode = 0");
  // Initialization for LHC.
  pythia.readString("Beams:eCM = 14000.");
  pythia.init();
  // Validation histograms
  Hist hEtjet("dN/dETjet: monojet check", 100, 0., 7000.);
  Hist hMass("dN/m: graviton mass spectrum", 100, 0., 7000.);
  // Begin event loop.
  int iAbort = 0;
  for (int iEvent = 0; iEvent < nEvent; ++iEvent) {
    // Generate events. Quit if many failures.
    if (!pythia.next()) {
      if (++iAbort < nAbort) continue;
      std::cout << " Event generation aborted prematurely, owing to error!\n";
      break;
    }
    // Checked particle index
    int tmp_monojet = -1;
    // Particle loop
    for (int iPart = 0; iPart < pythia.event.size(); ++iPart) {
      // From hard process (inital = 21, interm.=22, final=23 state)
      if (pythia.event[iPart].statusAbs()  == 22) {
        // Find Z_KK/gamma_KK or kk-gluon
        if( pythia.event[iPart].idAbs() == 5000023
         || pythia.event[iPart].idAbs() == 5100021
         || pythia.event[iPart].idAbs() == 5100039){
          hMass.fill( pythia.event[iPart].m() );
        }
      } else if ( pythia.event[iPart].statusAbs()  == 23 ) {
        // Find graviton/unparticle
        if( pythia.event[iPart].idAbs() == 5000039){
          hMass.fill( pythia.event[iPart].m() );
        }
        // Find mono-jets
        if (nTest == 1 || nTest == 2) {
          if ( pythia.event[iPart].idAbs() <= 6
            || pythia.event[iPart].idAbs() == 21 ){
            if (tmp_monojet >= 0) {
              std::cout << "More than one (hard process) mono-jet ! \n";
            } else {
              tmp_monojet  = iPart;
            }
          }
        }
      }
    }
    // Validation mono-jet wrt G.Giudice et al. paper [hep-ph/9811291v2]
    if (tmp_monojet >= 0) {
      double tmp_eta = pythia.event[tmp_monojet].eta();
      double tmp_et = pythia.event[tmp_monojet].eT();
      double tmp_et_cut = 1000;
      if ( tmp_et >=  tmp_et_cut && abs(tmp_eta) < 3 ) {
        hEtjet.fill( fabs(tmp_et) );
      }
    }
  }
  // Final statistics.
  pythia.stat();
  cout << hMass << hEtjet;
  return 0;
}

main27.cc


// main27.cc is a part of the PYTHIA event generator.
// Copyright (C) 2016 Torbjorn Sjostrand.
// PYTHIA is licenced under the GNU GPL version 2, see COPYING for details.
// Please respect the MCnet Guidelines, see GUIDELINES for details.
// Kaluza-Klein gamma*/Z resonances in TeV-sized extra dimensions.
#include <assert.h>
#include <time.h>
#include <sstream>
#include "Pythia8/Pythia.h"
using namespace Pythia8;
int main() {
  // Generator.
  Pythia pythia;
  ParticleData& pdt = pythia.particleData;
  // Pick new random number seed for each run, based on clock.
  pythia.readString("Random:setSeed = on");
  pythia.readString("Random:seed = 0");
  // Process selection.
  // ANY COMBINATION OF THE PROCESSES FLAGS BELOW IS ALLOWED
  // HERE WE SWITCH ON ONLY THE MU+MU- FINAL STATE.
  // TO SWITCH ALL POSSIBLE FINAL STATES ON, UNCOMMENT ALL
  // THE RELEVANT LINES BELOW:
  //pythia.readString("ExtraDimensionsTEV:ffbar2e+e- = on");
  pythia.readString("ExtraDimensionsTEV:ffbar2mu+mu- = on");
  //pythia.readString("ExtraDimensionsTEV:ffbar2tau+tau- = on");
  //pythia.readString("ExtraDimensionsTEV:ffbar2uubar = on");
  //pythia.readString("ExtraDimensionsTEV:ffbar2ddbar = on");
  //pythia.readString("ExtraDimensionsTEV:ffbar2ccbar = on");
  //pythia.readString("ExtraDimensionsTEV:ffbar2ssbar = on");
  //pythia.readString("ExtraDimensionsTEV:ffbar2bbbar = on");
  //pythia.readString("ExtraDimensionsTEV:ffbar2ttbar = on");
  //pythia.readString("ExtraDimensionsTEV:ffbar2nuenuebar = on");
  //pythia.readString("ExtraDimensionsTEV:ffbar2numunumubar = on");
  //pythia.readString("ExtraDimensionsTEV:ffbar2nutaunutaubar = on");
  // Pick KK mass.
  double newMass = 4000.; // GeV
  cout << "|-------------------------" << endl;
  cout << "| KK mass is: " << newMass << endl;
  cout << "|-------------------------" << endl;
  stringstream strm;
  string sNewMass, sNewWidth, sNewLowBound, sNewHighBound;
  // Manually set the mass and therefore the width
  // and the phase space for the sampling
  strm.clear();
  strm << newMass;
  strm >> sNewMass;
  strm.clear();
  strm << newMass / pdt.m0(5000023) * pdt.mWidth(5000023);
  strm >> sNewWidth;
  strm.clear();
  strm << newMass/4.;
  strm >> sNewLowBound;
  strm.clear();
  strm << newMass*2.;
  strm >> sNewHighBound;
  // Feed in KK state information and other generation specifics.
  pythia.readString("5000023:m0 = " + sNewMass);
  pythia.readString("5000023:mWidth = " + sNewWidth);
  pythia.readString("5000023:mMin = " + sNewLowBound);
  pythia.readString("5000023:mMax = " + sNewHighBound);
  //////////////////////////////////////////////////////////////////////////
  pythia.readString("5000023:isResonance = false"); // THIS IS MANDATORY  //
  //////////////////////////////////////////////////////////////////////////
  // 0=(gm+Z), 1=(gm), 2=(Z), 3=(gm+Z+gmKK+ZKK), 4=(m+Z+gmKK), 5=(m+Z+ZKK)
  pythia.readString("ExtraDimensionsTEV:gmZmode = 3");
  // min=0, max=100, default=10
  pythia.readString("ExtraDimensionsTEV:nMax = 100");
  pythia.readString("ExtraDimensionsTEV:mStar = " + sNewMass);
  pythia.readString("PhaseSpace:mHatMin = " + sNewLowBound);
  pythia.readString("PhaseSpace:mHatMax = " + sNewHighBound);
  // Initialize for LHC.
  pythia.readString("Beams:eCM = 14000.");
  pythia.init();
  // Histograms.
  Hist mHatHisto("dN/dmHat", 50, newMass/4., newMass*2.);
  Hist pTmuHisto("(dN/dpT)_mu^-", 50, 1., 2501.);
  vector<int> moms;
  // Measure the cpu runtime.
  clock_t start, stop;
  double t = 0.0;
  // Depending on operating system, either of lines below gives warning.
  //assert((start = clock()) != -1); // Start timer; clock_t signed.
  //assert((start = clock()) != -1u); // Start timer; clock_t unsigned.
  // Simpler option, not using assert.
  start = clock();
  // Begin event loop. Generate event. Skip if error. List first one.
  for (int iEvent = 0 ; iEvent < 500 ; ++iEvent) {
    if (!pythia.next()) continue;
    // Begin event analysis.
    bool isZ = false;
    bool ismu = false;
    int iZ = 0;
    int imu = 0;
    for (int i = 0 ; i < pythia.event.size() ; ++i) {
      // find the most recent Z
      if (pythia.event[i].id() == 5000023) {
        iZ = i;
        isZ = true;
      }
      // find the final muon who's first mother is the Z
      if (pythia.event[i].id() == 13 && pythia.event[i].isFinal()) {
        moms.clear();
        moms = pythia.event[i].motherList();
        for (int m = 0 ; m < int(moms.size()) ; m++) {
          if( pythia.event[ moms[m] ].id() == 5000023 ) {
            imu = i;
            ismu = true;
            break;
          } // end if 5000023
        } // end for moms.size()
      } // end if final muon
    } // end for event.size()
    if(isZ && ismu) {
      mHatHisto.fill( pythia.event[iZ].m() );
      pTmuHisto.fill( pythia.event[imu].pT() );
    }
    if(iEvent%10 == 0) cout << "Event: " << iEvent << endl << std::flush;
  } // end for iEvent<500
  // Done. Print results.
  stop = clock(); // Stop timer
  t = (double) (stop-start)/CLOCKS_PER_SEC;
  pythia.stat();
  cout << mHatHisto;
  cout << pTmuHisto;
  cout << "\n" << "|----------------------------------------|" << endl;
  cout << "| CPU Runtime = " << t << " sec" << endl;
  cout << "|----------------------------------------|" << "\n" << endl;
  return 0;
}

main28.cc


// main28.cc is a part of the PYTHIA event generator.
// Copyright (C) 2016 Peter Skands, Torbjorn Sjostrand.
// PYTHIA is licenced under the GNU GPL version 2, see COPYING for details.
// Please respect the MCnet Guidelines, see GUIDELINES for details.
// Example of of R-hadron production.
// Several of the possibilities shown here, like displaced vertices,
// are extras that need not be used for the basic setup.
#include "Pythia8/Pythia.h"
using namespace Pythia8;
int main() {
  // Key settings to be used in the main program.
  // nGluino = 0, 1, 2 give stop pair, single gluino or gluino pair.
  int nGluino  = 2;
  int nEvent   = 200;
  int nAbort   = 3;
  int nList    = 0;
  double eCM   = 7000.;
  // Generator. Shorthand for the event.
  Pythia pythia;
  Event& event = pythia.event;
  // Set up beams: p p is default so only need set energy.
  pythia.settings.parm("Beams:eCM", eCM);
  // Squark pair: use stop-antistop as example.
  if (nGluino == 0) {
    pythia.readString("SUSY:gg2squarkantisquark = on");
    pythia.readString("SUSY:idA = 1000006");
    pythia.readString("SUSY:idB = 1000006");
  // Squark-gluino pair: also supersymmetric u has been made long-lived.
  // Stop does not work since then one would need inoming top PDF.
  // Nevertheless R-hadrons are numbered/named as if containing a stop.
  } else if (nGluino == 1) {
    pythia.readString("SUSY:qg2squarkgluino  = on");
    pythia.readString("SUSY:idA = 1000002");
    pythia.readString("RHadrons:idStop = 1000002");
    pythia.readString("SUSY:idB = 1000021");
  // Gluino pair.
  } else {
    pythia.readString("SUSY:gg2gluinogluino  = on");
  }
  // Use hacked sps1a file, with stop (+su) and gluino made long-lived.
  // This is based on the width being less than 0.2 GeV by default.
  pythia.readString("SLHA:file = sps1aNarrowStopGluino.spc");
  // Further hacked file, to test R-parity violating gluino decay.
  //pythia.readString("SLHA:file = sps1aNarrowStopGluinoRPV.spc");
  // Allow R-hadron formation.
  pythia.readString("Rhadrons:allow = on");
  // If you want to do the decay separately later,
  // you need to switch off automatic decays.
  pythia.readString("RHadrons:allowDecay = off");
  // Fraction of gluinoballs.
  pythia.readString("RHadrons:probGluinoball = 0.1");
  // Switch off key components.
  //pythia.readString("PartonLevel:MPI = off");
  //pythia.readString("PartonLevel:ISR = off");
  //pythia.readString("PartonLevel:FSR = off");
  //pythia.readString("HadronLevel:Hadronize = off");
  // Allow the R-hadrons to have secondary vertices: set c*tau in mm.
  // Note that width and lifetime can be set independently.
  // (Nonzero small widths are needed e.g. to select branching ratios.)
  pythia.readString("1000002:tau0 = 200.");
  pythia.readString("1000006:tau0 = 250.");
  pythia.readString("1000021:tau0 = 300.");
  // Checks. Optionally relax E-p-conservation.
  pythia.readString("Check:nErrList = 2");
  //pythia.readString("Check:epTolErr = 2e-3");
  // Possibility to switch off particle data and event listings.
  // Also to shop location of displaced vertices.
  pythia.readString("Init:showChangedSettings = on");
  pythia.readString("Init:showChangedParticleData = off");
  pythia.readString("Next:numberShowInfo = 1");
  pythia.readString("Next:numberShowProcess = 1");
  pythia.readString("Next:numberShowEvent = 0");
  pythia.readString("Next:showScaleAndVertex = on");
  // Initialize.
  pythia.init();
  // Histograms.
  Hist nChargedH("charged multiplicity", 100, -0.5, 799.5);
  Hist dndyChargedH("dn/dy charged", 100, -10., 10.);
  Hist dndyRH("dn/dy R-hadrons", 100, -5., 5.);
  Hist pTRH("pT R-hadrons", 100, 0., 1000.);
  Hist xRH("p_RHadron / p_sparticle", 100, 0.9, 1.1);
  Hist mDiff("m(Rhadron) - m(sparticle)", 100, 0., 5.);
  Hist decVtx("R-hadron decay vertex (mm from origin)", 100, 0., 1000.);
  // R-hadron flavour composition.
  map<int, int> flavours;
  // Begin event loop.
  int iAbort = 0;
  for (int iEvent = 0; iEvent < nEvent; ++iEvent) {
    // Generate events. Quit if failure.
    if (!pythia.next()) {
      if (++iAbort < nAbort) continue;
      cout << " Event generation aborted prematurely, owing to error!\n";
      break;
    }
    // Loop over final charged particles in the event.
    // The R-hadrons may not yet have decayed here.
    int nCharged = 0;
    Vec4 pSum;
    for (int i = 0; i < event.size(); ++i) {
      if (event[i].isFinal()) {
        pSum += event[i].p();
        if (event[i].isCharged()) {
          ++nCharged;
          dndyChargedH.fill( event[i].y() );
        }
      }
    }
    nChargedH.fill( nCharged );
    // Loop over final R-hadrons in the event: kinematic distribution
    for (int i = 0; i < event.size(); ++i) {
      int idAbs = event[i].idAbs();
      if (idAbs > 1000100 && idAbs < 2000000 && idAbs != 1009002) {
        ++flavours[ event[i].id() ];
        dndyRH.fill( event[i].y() );
        pTRH.fill( event[i].pT() );
        // Trace back to mother; compare momenta and masses.
        int iMother = i;
        while( event[iMother].statusAbs() > 100)
          iMother = event[iMother].mother1();
        double xFrac = event[i].pAbs() / event[iMother].pAbs();
        xRH.fill( xFrac);
        double mShift = event[i].m() - event[iMother].m();
        mDiff.fill( mShift );
        // Separation of R-hadron decay vertex from origin.
        // Don't be fooled by pAbs(); it gives the three-vector length
        // of any Vec4, also one representing spatial coordinates.
        double dist = event[i].vDec().pAbs();
        decVtx.fill( dist);
        // This is a place where you could allow a R-hadron shift of
        // identity, momentum and decay vertex to allow for detector effects.
        // Identity not illustrated here; requires a change of mass as well.
        // Toy model: assume an exponential energy loss, < > = 1 GeV,
        // but at most half of kinetic energy. Unchanged direction.
        // Note that event will no longer conserve energy and momentum.
        double eLossAvg = 1.;
        double eLoss = 0.;
        do { eLoss = eLossAvg * pythia.rndm.exp(); }
        while (eLoss > 0.5 * (event[i].e() - event[i].m()));
        double eNew = event[i].e() - eLoss;
        Vec4   pNew = event[i].p() * sqrt( pow2(eNew) - pow2(event[i].m()) )
                    / event[i].pAbs();
        pNew.e( eNew);
        event[i].p( pNew);
        // The decay vertex will be calculated based on the production vertex,
        // the proper lifetime tau and the NEW four-momentum, rather than
        // e.g. some average momentum, if you do not set it by hand.
        // This commented-out piece illustrates brute-force setting,
        // but you should provide real numbers from some tracking program.
        // With tau = 0 the decay is right at the chosen point.
        //event[i].tau( 0.);
        //event[i].vProd( 132., 155., 233., 177.);
      // End of loop over final R-hadrons.
      }
    }
    // If you have set R-hadrons stable above,
    // you can still force them to decay at this stage.
    pythia.forceRHadronDecays();
    if (iEvent < nList) pythia.event.list(true);
  // End of event loop.
  }
  // Final statistics, flavour composition and histogram output.
  pythia.stat();
  cout << "\n Composition of produced R-hadrons \n    code            "
       << "name   times " << endl;
  for (map<int, int>::iterator flavNow = flavours.begin();
    flavNow != flavours.end(); ++flavNow)  cout << setw(8)
    << flavNow->first << setw(16) << pythia.particleData.name(flavNow->first)
    << setw(8) << flavNow->second << endl;
  cout << nChargedH << dndyChargedH << dndyRH << pTRH << xRH << mDiff
       << decVtx;
  // Done.
  return 0;
}

main29.cc


// main29.cc is a part of the PYTHIA event generator.
// Copyright (C) 2016 Torbjorn Sjostrand.
// PYTHIA is licenced under the GNU GPL version 2, see COPYING for details.
// Please respect the MCnet Guidelines, see GUIDELINES for details.
// Omnibus version for colour reconnection (CR) effect studies.
// Links to two UserHooks that, along with the internal models,
// implement all the models used for the top mass study in
// S. Argyropoulos and T. Sjostrand,
// arXiv:1407.6653 [hep-ph] (LU TP 14-23, DESY 14-134, MCnet-14-15)
// Warning: some small modifications have been made when collecting
// the models, but nothing intended to change the behaviour.
// Note: the move model is also available with ColourReconnection:mode = 2,
// while the ColourReconnection:mode = 1 model has not been used here.
// Note: the new models tend to be slower than the default CR scenario,
// since they have to probe many more reconnection possibilities.
// Important: the top mass shift analysis encoded here is very primitive,
// does not perform well at all, and should not be taken seriously.
// The important part is that you see how the different scenarios
// should be set up to operate as intended.
#include "Pythia8/Pythia.h"
#include "Pythia8Plugins/ColourReconnectionHooks.h"
using namespace Pythia8;
//==========================================================================
int main() {
  // Number of events to generate.
  // Warning: much statistics is needed for significant results,
  // so this is just an appetizer. Anyway, the reconstruction is
  // pretty lousy, so not useful for real studies.
  int nEvent = 1000;
  // Target t and W masses.
  double mT = 173.3;
  double mW = 80.385;
  // Set up anti-kT jet finder.
  double Rjet = 0.5;
  double pTjetMin = 20.;
  SlowJet sJet( -1, Rjet, pTjetMin);
  // Loop over different reconnection scenarios.
  for (int mLoop = 0; mLoop < 14; ++mLoop) {
  cout << "\n\n ================================ Now begin mLoop = "
       << mLoop << " ================================\n" << endl;
    // Generator at 8 TeV LHC.
    Pythia pythia;
    Event& event = pythia.event;
    pythia.readString("Beams:eCM = 8000.");
    // q qbar, g g -> t tbar.
    pythia.readString("Top:qqbar2ttbar = on");
    pythia.readString("Top:gg2ttbar = on");
    // Colour reconnection setups.
    UserHooks* myUserHooks;
    // Tuning parameters for CR scenarios have tune 4C as a starting point.
    pythia.readString("Tune:pp = 5");
    // No reconnection at all.
    if (mLoop == 0) {
      pythia.readString("ColourReconnection:reconnect = off");
      pythia.readString("PartonLevel:earlyResDec = off");
      pythia.readString("MultipartonInteractions:pT0Ref = 2.30");
    // Standard reconnection, but top decay products unaffected.
    } else if (mLoop == 1) {
      pythia.readString("ColourReconnection:reconnect = on");
      pythia.readString("PartonLevel:earlyResDec = off");
    // Standard reconnection, including top decay products.
    } else if (mLoop == 2) {
      pythia.readString("ColourReconnection:reconnect = on");
      pythia.readString("PartonLevel:earlyResDec = on");
    // New gluon swap and move scenarios, including top decay products.
    // (Note: the move scenario is also implemented internally.)
    } else if (mLoop >= 3 && mLoop <= 8) {
      pythia.readString("ColourReconnection:reconnect = off");
      pythia.readString("PartonLevel:earlyResDec = off");
      // Swap (mode = 1) or move (2), and flip (1, 2) or not (0).
      int mode = (mLoop <= 5) ? 1 : 2;
      int flip = ( mLoop - 3 * mode) % 3;
      // Possibilities to vary effects by further parameters.
      double dLamCut   = 0.;
      double fracGluon = 1.;
      if ( mode == 1 ) {
        if ( flip > 0 )
             pythia.readString("MultipartonInteractions:pT0Ref = 2.20");
        else pythia.readString("MultipartonInteractions:pT0Ref = 2.30");
      }
      else {
        if ( flip > 0 )
             pythia.readString("MultipartonInteractions:pT0Ref = 2.15");
        else pythia.readString("MultipartonInteractions:pT0Ref = 2.25");
      }
      myUserHooks = new MBReconUserHooks(mode, flip, dLamCut, fracGluon);
      pythia.setUserHooksPtr( myUserHooks);
    // New scenaros that do top reconnections separately from normal one.
    // =  9: reconnect with random background gluon;
    // = 10: reconnect with nearest (smallest-mass) background gluon;
    // = 11: reconnect with furthest (largest-mass) background gluon;
    // = 12: reconnect with smallest (with sign) lambda measure shift;
    // = 13: reconnect only if reduced lamda, and then to most reduction.
    } else if (mLoop >= 9 && mLoop <= 13) {
      pythia.readString("ColourReconnection:reconnect = on");
      pythia.readString("PartonLevel:earlyResDec = off");
      // Possibility with reduced reconnection strength.
      double strength = ( mLoop == 13 ) ? 1. : 0.075;
      myUserHooks = new TopReconUserHooks(mLoop - 8, strength);
      pythia.setUserHooksPtr( myUserHooks);
    }
    // Simplify generation. For tryout only.
    //pythia.readString("ProcessLevel:resonanceDecays = off");
    //pythia.readString("PartonLevel:ISR = off");
    //pythia.readString("PartonLevel:FSR = off");
    //pythia.readString("PartonLevel:MPI = off");
    //pythia.readString("BeamRemnants:primordialKT = off");
    //pythia.readString("HadronLevel:all = off");
    // Top and W masses. Semileptonic top decay chosen by W decay.
    // (One of two charge states, so properly ought to symmetrize.)
    // Trick: only allow decay to stable tau, standing in for e and mu
    // as well, but the tau is easy to remove before jet finding.
    pythia.readString("6:m0 = 173.3");
    pythia.readString("24:m0 = 80.385");
    pythia.readString("24:onPosIfAny = 1 2 3 4 5");
    pythia.readString("24:onNegIfAny = 15");
    pythia.readString("24:offIfAny = 11 13");
    pythia.readString("15:mayDecay = off");
    // Reduce printout.
    pythia.readString("Init:showChangedParticleData = off");
    pythia.readString("Next:numberShowInfo = 0");
    pythia.readString("Next:numberShowProcess = 0");
    pythia.readString("Next:numberShowEvent = 0");
    pythia.readString("Next:numberCount = 100000");
    // Initialize.
    pythia.init();
    // Histograms for current scenario.
    Hist nRecH(  "number of top reconnections",  100, -0.5, 99.5);
    Hist nchH(   "charged multiplicity",         100,  -1., 799.);
    Hist nJetH(  "jet multiplicity",              20, -0.5, 19.5);
    Hist mWH(    "reconstructed W mass",         100,  40., 140.);
    Hist mTH(    "reconstructed t mass",         100, 120., 220.);
    Hist mWerrH( "reconstructed W mass error",   100, -10.,  10.);
    Hist mTerrH( "reconstructed t mass error",   100, -20.,  20.);
    Hist pTTH(   "reconstructed pT_t",            11,   0., 275.);
    Hist mTpTH(  "reconstructed delta-m_t(pT_t)", 11,   0., 275.);
    // Begin event loop. Generate event. Skip if error.
    for (int iEvent = 0; iEvent < nEvent; ++iEvent) {
      if (!pythia.next()) continue;
      // Charged multiplicity.
      int nch = 0;
      for (int i = 0; i < event.size(); ++i)
        if (event[i].isFinal() && event[i].isCharged()) ++nch;
      nchH.fill(nch);
      // Remove tau leptons. (Recall: they were put stable, so simple.)
      for (int i = 0; i < event.size(); ++i)
        if (event[i].idAbs() == 15) event[i].statusNeg();
      // Find number of jets. At least four to keep going.
      sJet.analyze(event);
      int nJet = sJet.sizeJet();
      nJetH.fill( nJet);
      if (nJet < 4) continue;
      // Find two jets that form mass closest to mW.
      int i1min     = 0;
      int i2min     = 0;
      double m12min = 0.;
      double diff   = 1e10;
      for (int i1 = 0; i1 < nJet - 1; ++i1)
      for (int i2 = i1 + 1; i2 < nJet; ++i2) {
        double m12 = (sJet.p(i1) + sJet.p(i2)).mCalc();
        if (abs(m12 - mW) < diff) {
          i1min  = i1;
          i2min  = i2;
          m12min = m12;
          diff   = abs(m12 - mW);
        }
      }
      mWH.fill( m12min);
      mWerrH.fill( m12min - mW);
      // Only keep going if within +-5 GeV.
      if (abs(m12min - mW) > 5.) continue;
      // Find third jet that forms mass closest to mT.
      int i3min      = 0;
      double m123min = 0.;
      diff           = 1e10;
      for (int i3 = 0; i3 < nJet; ++i3)
      if (i3 != i1min && i3 != i2min) {
        double m123 = (sJet.p(i1min) + sJet.p(i2min) + sJet.p(i3)).mCalc();
        if (abs(m123 - mT) < diff) {
          i3min   = i3;
          m123min = m123;
          diff    = abs(m123 - mT);
        }
      }
      mTH.fill( m123min);
      mTerrH.fill( m123min - mT);
      // Only keep going if within +-20 GeV.
      if (abs(m123min - mT) > 20.) continue;
      // Study top pT and dependence of top mass error.
      double pTT = (sJet.p(i1min) + sJet.p(i2min) + sJet.p(i3min)).pT();
      if (pTT > 250.) pTT = 260.;
      pTTH.fill( pTT);
      mTpTH.fill( pTT, m123min - mT);
    // End of event loop. Statistics. Histograms.
    }
    pythia.stat();
    mTpTH /= pTTH;
    cout <<  nchH << nJetH << mWH << mTH << mWerrH
         << mTerrH << pTTH << mTpTH;
    // End loop over top colour reconnection scenarios.
    if (mLoop >=3) delete myUserHooks;
  }
  // Done.
  return 0;
}

main30.cc


// main30.cc is a part of the PYTHIA event generator.
// Copyright (C) 2016 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: Steve Mrenna.
// Example how to create a copy of the event record, where the original one
// is translated to another format, to meet various analysis needs.
// In this specific case the idea is to set up the history information
// of the underlying hard process to be close to the PYTHIA 6 structure.
#include "Pythia8/Pythia.h"
using namespace Pythia8;
//--------------------------------------------------------------------------
void translate(Event&, Event&);
//--------------------------------------------------------------------------
int main() {
  // Generator.
  Pythia pythia;
  // Shorthand for the event record in pythia.
  Event& event = pythia.event;
  // Read in commands from external file.
  pythia.readFile("main30.cmnd");
  // Extract settings to be used in the main program.
  int nEvent = pythia.mode("Main:numberOfEvents");
  int nAbort = pythia.mode("Main:timesAllowErrors");
  int nShow  = pythia.mode("Next:numberShowEvent");
  // Initialize.
  pythia.init();
  // Event record for hard interaction and resonance decays.
  Event hard;
  hard.init("(Pythia 6 conventions)", &pythia.particleData);
  // Begin event loop.
  int iAbort = 0;
  for (int iEvent = 0; iEvent < nEvent; ++iEvent) {
    // Generate events. Quit if many failures.
    if (!pythia.next()) {
      if (++iAbort < nAbort) continue;
      cout << " Event generation aborted prematurely, owing to error!\n";
      break;
    }
    // Reset record for this event. List first few.
    translate( event, hard );
    if (iEvent < nShow) hard.list();
  // End of event loop.
  }
  // Final statistics.
  pythia.stat();
  // Done.
  return 0;
}
//--------------------------------------------------------------------------
// Routine to identify the hard process of the event after
// accounting for the affects of ISR and resonance decay.
void translate(Event& event, Event& hard) {
    // Reset translated event record.
    hard.reset();
    // Identify primordial partons with kT smearing.
    int iL1 = event[1].daughter1();
    int iL2 = event[2].daughter1();
    int iLast = min(iL1,iL2);
    // Identify initial hard partons.
    int iP1 = 3;
    int iP2 = 4;
    int iEv=-1;
    // Counters to identify ISR radiator, recoil, and radiation.
    int i41 = 0, i42 = 0, i43 = 0;
    while ( iEv < iLast ) {
      iEv++;
      // Identify hard process by status in the 20s.
      int iStatus = event[iEv].status();
      if ( abs(iStatus) > 20 && abs(iStatus) < 30 ) {
        hard.append(event[iEv]);
        if ( iStatus==-21 ) {
          hard[hard.size()-1].mothers(0,0);
        } else {
          hard[hard.size()-1].mothers(1,2);
        }
        continue;
      }
      // Follow the flow of the hard event.
      int iDa1 = event[iEv].daughter2();
      // Test to determine origin of this shower.
      bool hardTest = (iDa1 == iP1) || (iDa1 == iP2);
      // Status -41 is the ISR radiator
      // Status -42 is the ISR recoil
      // Status -61 is the primordial parton with kT smearing
      // Status -53 is a recoil in initial-final dipole radiation
      if ( iStatus == -41 && hardTest ) {
        i41 = iEv;
      } else if ( iStatus == -42 && hardTest ) {
        i42 = iEv;
      } else if ( iStatus == -61 && hardTest ) {
        if ( i41 == 0 ) {
          i41 = iEv;
        } else {
          i42 = iEv;
        }
      } else if ( iStatus == -53 ) {
        if ( iDa1 == iP1 ) {
          iP1 = iEv;
        } else if ( iDa1 == iP2 ) {
          iP2 = iEv;
        }
      }
      if ( !(i41 > 0 && i42 > 0) ) continue;
      int ik2 = event[i41].daughter2();
      int ik1 = event[i42].daughter2();
      if ( event[ik2].pz() > 0 ) {
        int iTemp=ik1;
        ik1=ik2;
        ik2=iTemp;
      }
      // Boost to CM frame of hard partons.
      RotBstMatrix toCMS;
      toCMS.toCMframe(event[ik1].p(),event[ik2].p());
      // Momentum of off-shell incoming parton.
      i43 = event[i41].daughter1();
      Vec4 pBoost = event[i41].p()-event[i43].p();
      RotBstMatrix toHard;
      if ( event[i41].pz() > 0 ) {
        toHard.fromCMframe(pBoost,event[i42].p());
      } else {
        toHard.fromCMframe(event[i42].p(),pBoost);
      }
      // Boost to CM frame of old initiators,
      // then boost from frame of new initiators.
      for( int i = 0; i< hard.size(); ++i ) {
        hard[i].rotbst(toCMS);
        hard[i].rotbst(toHard);
      }
      // Update counter to location of new parton
      iEv = i43;
      // Update event history
      iDa1 = event[i41].daughter2();
      if ( iDa1 == iP1 ) {
        iP1 = i41;
        iP2 = i42;
      } else {
        iP2 = i41;
        iP1 = i42;
      }
      i41=0; i42=0;
    }
    // Handle kT smearing of initial partons.
    RotBstMatrix ref0, ref1;
    if ( event[iP1].pz() > 0 ) {
      ref0.toCMframe(event[iP1].p(),event[iP2].p());
    } else {
      ref0.toCMframe(event[iP2].p(),event[iP1].p());
    }
    if ( event[iL1].pz() > 0 ) {
      ref1.fromCMframe(event[iL1].p(),event[iL2].p());
    } else {
      ref1.fromCMframe(event[iL2].p(),event[iL1].p());
    }
    for( int i=0; i< hard.size(); ++i ) {
      hard[i].rotbst(ref0);
      hard[i].rotbst(ref1);
    }
    hard[1].daughters(3,hard.size()-1);
    hard[2].daughters(3,hard.size()-1);
    int iMax = hard.size();
    // Add resonance decays; start here.
    for( int i = 3; i < iMax && i < event.size(); ++i ) {
      int ilast = -1;
      int ida1, ida2 = -1;
      if ( hard[i].status()!=-22 ) {
        hard[i].statusPos();
        continue;
      }
      if ( hard[i].mother1()==3 ) {
        ilast = hard[i].daughter1();
        ida1 = event[ilast].daughter1();
        ida2 = event[ilast].daughter2();
      } else {
        ilast = i;
        ida1 = hard[ilast].daughter1();
        ida2 = hard[ilast].daughter2();
      }
      // Resonance decays occur when there are multiple daughters and
      // it is NOT FSR.
      while( ilast > 0 && ilast < event.size() ) {
        if ( ida1 != ida2 && event[ida1].status() != -51 ) break;
        ilast = ida1;
        ida1 = event[ilast].daughter1();
        ida2 = event[ilast].daughter2();
      }
      // Add daughters to the event record, boosting to the frame
      // of the mother.
      if ( ilast > 0 ) {
        Vec4 pall = Vec4(0,0,0,0);
        for(int ida = ida1; ida <= ida2; ++ida) {
          pall += event[ida].p();
        }
        RotBstMatrix toResonance;
        toResonance.bst( pall, hard[i].p() );
        int nDau = 0;
        for(int ida = ida1; ida <= ida2; ++ida) {
          Particle tmp = Particle(event[ida]);
          tmp.rotbst(toResonance);
          hard.append( tmp );
          hard[hard.size()-1].mothers(i,i);
          iMax++;
          nDau++;
        }
        int ip1 = hard.size() - nDau;
        hard[i].daughters(ip1,ip1+nDau-1);
      }
    }
}

main31.cc


// main31.cc is a part of the PYTHIA event generator.
// Copyright (C) 2016 Richard Corke, Torbjorn Sjostrand.
// PYTHIA is licenced under the GNU GPL version 2, see COPYING for details.
// Please respect the MCnet Guidelines, see GUIDELINES for details.
// Example how to perform merging with PWOHEG-BOX events,
// based on the code found in include/Pythia8Plugins/PowhegHooks.h.
#include "Pythia8/Pythia.h"
#include "Pythia8Plugins/PowhegHooks.h"
using namespace Pythia8;
//==========================================================================
int main() {
  // Generator
  Pythia pythia;
  // Load configuration file
  pythia.readFile("main31.cmnd");
  // Read in main settings
  int nEvent      = pythia.settings.mode("Main:numberOfEvents");
  int nError      = pythia.settings.mode("Main:timesAllowErrors");
  // Read in key POWHEG merging settings
  int vetoMode    = pythia.settings.mode("POWHEG:veto");
  int MPIvetoMode = pythia.settings.mode("POWHEG:MPIveto");
  bool loadHooks  = (vetoMode > 0 || MPIvetoMode > 0);
  // Add in user hooks for shower vetoing
  PowhegHooks *powhegHooks = NULL;
  if (loadHooks) {
    // Set ISR and FSR to start at the kinematical limit
    if (vetoMode > 0) {
      pythia.readString("SpaceShower:pTmaxMatch = 2");
      pythia.readString("TimeShower:pTmaxMatch = 2");
    }
    // Set MPI to start at the kinematical limit
    if (MPIvetoMode > 0) {
      pythia.readString("MultipartonInteractions:pTmaxMatch = 2");
    }
    powhegHooks = new PowhegHooks();
    pythia.setUserHooksPtr((UserHooks *) powhegHooks);
  }
  // Initialise and list settings
  pythia.init();
  // Counters for number of ISR/FSR emissions vetoed
  unsigned long int nISRveto = 0, nFSRveto = 0;
  // Begin event loop; generate until nEvent events are processed
  // or end of LHEF file
  int iEvent = 0, iError = 0;
  while (true) {
    // Generate the next event
    if (!pythia.next()) {
      // If failure because reached end of file then exit event loop
      if (pythia.info.atEndOfFile()) break;
      // Otherwise count event failure and continue/exit as necessary
      cout << "Warning: event " << iEvent << " failed" << endl;
      if (++iError == nError) {
        cout << "Error: too many event failures.. exiting" << endl;
        break;
      }
      continue;
    }
    /*
     * Process dependent checks and analysis may be inserted here
     */
    // Update ISR/FSR veto counters
    if (loadHooks) {
      nISRveto += powhegHooks->getNISRveto();
      nFSRveto += powhegHooks->getNFSRveto();
    }
    // If nEvent is set, check and exit loop if necessary
    ++iEvent;
    if (nEvent != 0 && iEvent == nEvent) break;
  } // End of event loop.
  // Statistics, histograms and veto information
  pythia.stat();
  cout << "Number of ISR emissions vetoed: " << nISRveto << endl;
  cout << "Number of FSR emissions vetoed: " << nFSRveto << endl;
  cout << endl;
  // Done.
  if (powhegHooks) delete powhegHooks;
  return 0;
}

main32.cc


// main32.cc is a part of the PYTHIA event generator.
// Copyright (C) 2016 Torbjorn Sjostrand.
// PYTHIA is licenced under the GNU GPL version 2, see COPYING for details.
// Please respect the MCnet Guidelines, see GUIDELINES for details.
// This is a sample program showing Alpgen- or Madgraph-style MLM matching
// for Madgraph LHEF or native Alpgen format event files.
//
// Please see the 'Jet Matching Style' manual page for a description of the
// parameters and user options.
// Includes and namespace
#include "Pythia8/Pythia.h"
#include "Pythia8Plugins/CombineMatchingInput.h"
using namespace Pythia8;
//==========================================================================
int main() {
 // Generator and read in commands.
  Pythia pythia;
  pythia.readFile("main32.cmnd");
  // Extract settings to be used in the main program.
  int nEvent = pythia.mode("Main:numberOfEvents");
  int nAbort = pythia.mode("Main:timesAllowErrors");
  int nSkip  = pythia.mode("Main:spareMode1");
  // Create UserHooks pointer. Stop if it failed. Pass pointer to Pythia.
  CombineMatchingInput combined;
  UserHooks* matching = combined.getHook(pythia);
  if (!matching) return 1;
  pythia.setUserHooksPtr(matching);
  // Initialise Pythia.
  if (!pythia.init()) {
    cout << "Error: could not initialise Pythia" << endl;
    return 1;
  };
  // Optionally skip ahead in LHEF.
  pythia.LHAeventSkip( nSkip );
  // Begin event loop. Optionally quit it before end of file.
  int iAbort = 0;
  for (int iEvent = 0; ;  ++iEvent) {
    if (nEvent > 0 && iEvent >= nEvent) break;
    // Generate events. Quit if at end of file or many failures.
    if (!pythia.next()) {
      if (pythia.info.atEndOfFile()) {
        cout << "Info: end of input file reached" << endl;
        break;
      }
      if (++iAbort < nAbort) continue;
      cout << "Abort: too many errors in generation" << endl;
      break;
    }
    // Event analysis goes here.
  // End of event loop.
  }
  // Final statistics and done.
  pythia.stat();
  delete matching;
  return 0;
}

main33.cc


// main33.cc is a part of the PYTHIA event generator.
// Copyright (C) 2016 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: Philip Ilten.
// An example where the HVQ POWHEGBOX matrix element binary is
// interfaced directly with PYTHIA. For this example to run correctly
// PYTHIA must be configured with the
// --with-powheg-bin=<path to directory containing only POWHEG binaries>
// option. This will build plugin libraries of the name
// libpythia8powheg<binary name>.so in the library directory.
// For these plugin libraries to build correctly, special compiler flags
// must have been used when building the POWHEGBOX binaries. These are
// "-rdynamic -fPIE -fPIC -pie". The following SED command will correctly
// insert them into the relevant POWHEGBOX Makefile:
//     sed -i "s/F77= gfortran/F77= gfortran -rdynamic -fPIE -fPIC -pie/g"
//     Makefile
// For this specific example the library libpythia8powheghvq.so must
// have been built.
#include "Pythia8/Pythia.h"
#include "Pythia8Plugins/PowhegProcs.h"
using namespace Pythia8;
int main() {
  Pythia pythia;
  // The constructor PowhegProcs(process name, pythia, run directory,
  // PDF filename, use Pythia random) where run directory by default
  // is ./powhegrun, the PDF filename is empty, and using Pythia
  // random is true. If using native PDFs rather than LHAPDF, the PDF
  // filename is the full name of the PDF file to copy to the run
  // directory.
  PowhegProcs procs(&pythia, "hvq");
  // The PowhegProcs class automatically sets the Pythia user hooks to
  // an instance of PowhegHooks. However, this can be modified to a
  // user chosen set of hooks (or null).
  // pythia->setUserHooksPtr(userHooksPtr);
  // Pythia and the POWHEG user hooks must still be configured, here
  // this is done via main33.cmnd. These settings are sensible
  // defaults, but Powheg:nFinal is dependent upon the POWHEG matrix
  // element being used and so must be changed as appropriate.
  pythia.readFile("main33.cmnd");
  // The commands readFile and readString are used to configure the
  // POWHEG matrix element. If a setting is repeated a warning is
  // issued and the most recent setting is used.
  procs.readFile("main33.pwhg");
  // This init call must be made before PYTHIA is initialized. It
  // copies the POWHEG input and PDF file to the POWHEG run directory.
  procs.init();
  // Initialize Pythia, based on the specified settings.
  pythia.init();
  // Run PYTHIA. The random numbers are taken from the associated
  // PYTHIA random number generator.
  for (int iEvent = 0; iEvent < 100; ++iEvent) pythia.next();
  // End of run.
  pythia.stat();
  return 0;
}

main34.cc


// main34.cc is a part of the PYTHIA event generator.
// Copyright (C) 2016 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: Philip Ilten, December 2015.
// An example where the hard process (p p -> mu+ mu-) is automatically
// produced externally with MadGraph 5, read in, and the remainder of
// the event is then produced by Pythia (MPI, showers, hadronization,
// and decays). A comparison is made between events produced with
// Pythia at LO, MadGraph 5 at LO, and aMC@NLO at NLO.
// For this example to run, MadGraph 5 must be installed and the
// command "exe" (set by default as "mg5_aMC") must be available via
// the command line. Additionally, GZIP support must be enabled via
// the "--with-gzip" configuration option(s). Note that this example has
// only been tested with MadGraph 5 version 2.3.3; due to rapid
// MadGraph development, this example may not work with other
// versions. For more details on the LHAMadgraph class see the
// comments of Pythia8Plugins/LHAMadgraph.h.
#include "Pythia8/Pythia.h"
#include "Pythia8Plugins/LHAMadgraph.h"
using namespace Pythia8;
//==========================================================================
// A simple method to run Pythia, analyze the events, and fill a histogram.
void run(Pythia* pythia, Hist& hist, int nEvent) {
  pythia->readString("Random:setSeed = on");
  pythia->readString("Random:seed = 1");
  pythia->init();
  for (int iEvent = 0; iEvent < nEvent; ++iEvent) {
    if (!pythia->next()) continue;
    int iMu1(0), iMu2(0);
    for (int i = 0; i < pythia->event.size(); ++i) {
      if (!iMu1 && pythia->event[i].id() == 13)  iMu1 = i;
      if (!iMu2 && pythia->event[i].id() == -13) iMu2 = i;
      if (iMu1 && iMu2) {
        iMu1 = pythia->event[iMu1].iBotCopyId();
        iMu2 = pythia->event[iMu2].iBotCopyId();
        hist.fill((pythia->event[iMu1].p() + pythia->event[iMu2].p()).pT());
        break;
      }
    }
  }
  pythia->stat();
}
//==========================================================================
int main() {
  // The name of the MadGraph5_aMC@NLO executable.
  // You must prepend this string with the path to the executable
  // on your local installation, or otherwise make it available.
  string exe("mg5_aMC");
  // Create the histograms.
  Hist pyPtZ("Pythia dN/dpTZ", 100, 0., 100.);
  Hist mgPtZ("MadGraph dN/dpTZ", 100, 0., 100.);
  Hist amPtZ("aMC@NLO dN/dpTZ", 100, 0., 100.);
  // Produce leading-order events with Pythia.
  Pythia* pythia = new Pythia();
  pythia->readString("Beams:eCM = 13000.");
  pythia->readString("WeakSingleBoson:ffbar2gmZ = on");
  pythia->readString("23:onMode = off");
  pythia->readString("23:onIfMatch = -13 13");
  pythia->readString("PhaseSpace:mHatMin = 80.");
  run(pythia, pyPtZ, 1000);
  delete pythia;
  // Produce leading-order events with MadGraph 5.
  pythia = new Pythia();
  LHAupMadgraph madgraph(pythia, true, "madgraphrun", exe);
  madgraph.readString("generate p p > mu+ mu-");
  // Note the need for a blank character before "set".
  madgraph.readString(" set ebeam1 6500");
  madgraph.readString(" set ebeam2 6500");
  madgraph.readString(" set mmll 80");
  pythia->setLHAupPtr(&madgraph);
  run(pythia, mgPtZ, 1000);
  delete pythia;
  // Produce next-to-leading-order events with aMC@NLO.
  pythia = new Pythia();
  LHAupMadgraph amcatnlo(pythia, true, "amcatnlorun", exe);
  amcatnlo.readString("generate p p > mu+ mu- [QCD]");
  // Note the need for a blank character before "set".
  amcatnlo.readString(" set ebeam1 6500");
  amcatnlo.readString(" set ebeam2 6500");
  amcatnlo.readString(" set mll 80");
  pythia->setLHAupPtr(&amcatnlo);
  run(pythia, amPtZ, 1000);
  delete pythia;
  // Print the histograms.
  cout << pyPtZ;
  cout << mgPtZ;
  cout << amPtZ;
  return 0;
}

main37.cc


// main37.cc is a part of the PYTHIA event generator.
// Copyright (C) 2016 Torbjorn Sjostrand.
// PYTHIA is licenced under the GNU GPL version 2, see COPYING for details.
// Please respect the MCnet Guidelines, see GUIDELINES for details.
// This is a simple test program.
// It illustrates how Les Houches Event File version 3.0 input can be used
// to mix events according to several different event weights.
#include "Pythia8/Pythia.h"
using namespace Pythia8;
int main() {
  // Generator
  Pythia pythia;
  // Initialize Les Houches Event File run.
  pythia.readString("Beams:frameType = 4");
  pythia.readString("Beams:LHEF = wbj_lhef3.lhe");
  pythia.init();
  // Get number of event weights.
  int ninitrwgt = pythia.info.getInitrwgtSize();
  // Initialise as many histograms as there are event weights.
  vector<Hist> pTw;
  for (int iHist = 0; iHist < ninitrwgt; ++iHist)
    pTw.push_back( Hist("pT W",50,0.,200.) );
  // Begin event loop; generate until none left in input file.
  for (int iEvent = 0; iEvent < 10; ++iEvent) {
    // Generate events, and check whether generation failed.
    if (!pythia.next()) {
      // If failure because reached end of file then exit event loop.
      if (pythia.info.atEndOfFile()) break;
      else continue;
    }
    // Find the final copy of the W and its pT.
    int iW = 0;
    for (int i = pythia.event.size() - 1; i > 0; --i)
      if (pythia.event[i].idAbs() == 24) { iW = i; break;}
    double pT = pythia.event[iW].pT();
    // Loop over the event weights in the detailed format and histogram.
    unsigned int nwgt = pythia.info.getWeightsDetailedSize();
    for (unsigned int iwgt = 0; iwgt < nwgt; ++iwgt) {
      // The weights happen to have the identifiers 1001, 1002...
      string key;
      ostringstream convert;
      convert << iwgt + 1001;
      key = convert.str();
      double w = pythia.info.getWeightsDetailedValue(key);
      pTw[iwgt].fill( max(pT,0.5), w );
    }
  // End of event loop.
  }
  // Give statistics.
  pythia.stat();
  // Print histograms.
  ofstream write;
  stringstream suffix;
  for (int iHist = 0; iHist < ninitrwgt; ++iHist) {
    suffix << iHist << ".dat";
    // Write histograms to file.
    write.open( (char*)("PTW_" + suffix.str()).c_str());
    pTw[iHist].table(write);
    suffix.str("");
    write.close();
  }
  // Done.
  return 0;
}

main38.cc


// main38.cc is a part of the PYTHIA event generator.
// Copyright (C) 2016 Torbjorn Sjostrand.
// PYTHIA is licenced under the GNU GPL version 2, see COPYING for details.
// Please respect the MCnet Guidelines, see GUIDELINES for details.
// This is a simple test program.
// It illustrates how Les Houches Event File version 3.0 information
// can be extracted from pythia.info.
#include "Pythia8/Pythia.h"
using namespace Pythia8;
int main() {
  // Generator
  Pythia pythia;
  // Stick with default values, so do not bother with a separate file
  // for changes. However, do one change, to show readString in action.
  // pythia.readString("PartonLevel:ISR = off");
  // pythia.readString("PartonLevel:FSR = off");
  pythia.readString("PartonLevel:MPI = off");
  pythia.readString("HadronLevel:all = off");
  //pythia.readString("PDF:pSet = LHAPDF5:cteq6m.LHpdf");
  // Initialize gzipped Les Houches Event File run.
  pythia.readString("Beams:frameType = 4");
  pythia.readString("Beams:LHEF = wbj_lhef3.lhe");
  pythia.init();
  // Print extra LHEF v3 initialization information.
  cout << endl << "*****************************************************"
       << endl << "  RETRIEVE GENERATOR INFORMATION" << endl;
  unsigned int ngen = pythia.info.getGeneratorSize();
  cout << "Number of generator tags " << ngen << endl;
  for (unsigned int igen = 0; igen < ngen; ++igen) {
    cout << ".  generator tag ." << igen << ". : ."
         << pythia.info.getGeneratorValue(igen) << ".\n"
         << ".  name          ."
         << pythia.info.getGeneratorAttribute(igen,"name",igen)
         << ".  version       ."
         << pythia.info.getGeneratorAttribute(igen,"version",igen)
         << ".  random        ."
         << pythia.info.getGeneratorAttribute(igen,"random",igen)
         << "." << endl;
    cout << ".  generator tag ." << igen << ". : ."
         << pythia.info.getGeneratorValue(igen) << ".\n"
         << ".  name          ."
         << pythia.info.getGeneratorAttribute(igen,"name",true)
         << ".  version       ."
         << pythia.info.getGeneratorAttribute(igen,"version",true)
         << ".  random        ."
         << pythia.info.getGeneratorAttribute(igen,"random",true)
         << "." << endl;
  }
  // Get number of event weights.
  int ninitrwgt = pythia.info.getInitrwgtSize();
  // Initialise as many histograms as there are event weights.
  vector<Hist> pTw;
  for (int iHist = 0; iHist < ninitrwgt; ++iHist)
    pTw.push_back( Hist("pT W",50,0.,200.) );
  // Begin event loop; generate until none left in input file.
  for (int iEvent = 0; iEvent < 1000; ++iEvent) {
    cout << endl << "Read event # " << iEvent << endl;
    // Generate events, and check whether generation failed.
    if (!pythia.next()) {
      // If failure because reached end of file then exit event loop.
      if (pythia.info.atEndOfFile()) break;
      else continue;
    }
    // Print process-level event.
    pythia.process.list();
    // Print extra LHEF v3 event information.
    cout << endl << "Print event # " << iEvent << endl;
    cout << endl << "*****************************************************"
         << endl << "  RETRIEVE EVENT INFORMATION" << endl;
    if (pythia.info.eventAttributes) {
      for ( map<string,string>::const_iterator
        it = pythia.info.eventAttributes->begin();
        it != pythia.info.eventAttributes->end(); ++it )
          cout << ".  attributes    ." << it->first << ".  ." << it->second
               << ".  .";
      cout << "." << endl;
      cout << pythia.info.getEventAttribute("npLO") << ".  ."
           << pythia.info.getEventAttribute("npNLO") << endl;
      cout << pythia.info.getEventAttribute("npLO",true) << ".  ."
           << pythia.info.getEventAttribute("npNLO",true) << endl;
    }
    // Print extra LHEF v3 event weight information.
    cout << endl << "*****************************************************"
         << endl << "  RETRIEVE WEIGHTS (DETAILED FORMAT) INFORMATION" << endl;
    unsigned int nwgt = pythia.info.getWeightsDetailedSize();
    cout << "Number of wgt tags " << nwgt << endl;
    for (unsigned int iwgt = 0; iwgt < nwgt; ++iwgt) {
      string key;
      ostringstream convert;
      convert << iwgt + 1001;
      key = convert.str();
      cout << ".  wgt tag       ." << iwgt << ". : ."
           << pythia.info.getWeightsDetailedValue(key) << ".\n"
           << ".  id            ."
           << pythia.info.getWeightsDetailedAttribute(key,"id")
           << ".  version       ."
           << pythia.info.getWeightsDetailedAttribute(key,"version")
           << "." << endl;
    }
    // Print extra LHEF v3 event weight information directly from iterator.
    cout << "wgt tags directly from iterator" << endl;
    unsigned int nwgts = 0;
    if (pythia.info.rwgt) nwgts = pythia.info.rwgt->wgts.size();
    cout << "Number of weight tags " << nwgts << endl;
    for (unsigned int iwgts = 0; iwgts < nwgts; ++iwgts) {
      string key;
      ostringstream convert;
      convert << iwgts+1001;
      key = convert.str();
      cout << ".  wgt tag       ." << iwgts << ". : ."
           << pythia.info.rwgt->wgts[key].contents << ".\n"
           << ".  id            ." << pythia.info.rwgt->wgts[key].id;
      for ( std::map<std::string,std::string>::const_iterator
        it = pythia.info.rwgt->wgts[key].attributes.begin();
        it != pythia.info.rwgt->wgts[key].attributes.end(); ++it )
          cout << ".  attributes    ." << it->first << ".  ." << it->second
               << ".  .";
      cout << "." << endl;
    }
    // Print extra LHEF v3 compressed format event weight information.
    cout << endl << "*****************************************************"
         << endl << "  RETRIEVE WEIGHTS (COMPRESSED FORMAT) INFORMATION"
         << endl;
    unsigned int nweights = pythia.info.getWeightsCompressedSize();
    cout << "Number of weights (only one tag!) " << nweights << endl;
    for (unsigned int iweights = 0; iweights < nweights; ++iweights)
      cout << ".  weight        ." << iweights << ". : ."
           << pythia.info.getWeightsCompressedValue(iweights) << ".\n"
           << "." << endl;
    // Print extra LHEF v3 weight tags directly from iterator.
    cout << "weight tags directly from iterator" << endl;
    if (pythia.info.weights)
    for ( std::map<std::string,std::string>::const_iterator
      it = pythia.info.weights->attributes.begin();
      it != pythia.info.weights->attributes.end(); ++it )
        cout << ".  attributes    ." << it->first << ".  ." << it->second
             << ".  .";
    cout << "." << endl;
    // Print extra LHEF v3 scale information.
    cout << endl << "*****************************************************"
         << endl << "  RETRIEVE SCALES INFORMATION" << endl;
    cout << ".  ." << pythia.info.getScalesValue() << endl;
    cout << ".  ." << pythia.info.getScalesAttribute("muf") << endl;
    cout << ".  ." << pythia.info.getScalesAttribute("mur") << endl;
    cout << ".  ." << pythia.info.getScalesAttribute("mups") << endl;
    cout << ".  ." << pythia.info.getScalesAttribute("SCALUP") << endl;
    if(pythia.info.scales)
    for ( std::map<std::string,double>::const_iterator
      it = pythia.info.scales->attributes.begin();
      it != pythia.info.scales->attributes.end(); ++it )
        cout << ".  attributes    ." << it->first << ".  ." << it->second
             << ".  .";
    cout << "." << endl;
    // Find the final copy of the W.
    int iW = 0;
    for (int i = pythia.event.size()-1; i > 0; --i)
      if (pythia.event[i].idAbs() == 24) { iW = i; break;}
    double pT = pythia.event[iW].pT();
    // Loop over the event weights in the detailed format and histogram.
    nwgt = pythia.info.getWeightsDetailedSize();
    for (unsigned int iwgt = 0; iwgt < nwgt; ++iwgt) {
      string key;
      ostringstream convert;
      convert << iwgt + 1001;
      key = convert.str();
      double w = pythia.info.getWeightsDetailedValue(key);
      pTw[iwgt].fill( max(pT,0.5), w );
    }
  // End of event loop.
  }
  // Give statistics.
  pythia.stat();
  // Print histograms.
  ofstream write;
  stringstream suffix;
  for (int iHist = 0; iHist < ninitrwgt; ++iHist) {
    suffix << iHist << ".dat";
    // Write histograms to file.
    write.open( (char*)("PTW_" + suffix.str()).c_str());
    pTw[iHist].table(write);
    suffix.str("");
    write.close();
  }
  // Done.
  return 0;
}

main41.cc


// main41.cc is a part of the PYTHIA event generator.
// Copyright (C) 2016 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: Mikhail Kirsanov, Mikhail.Kirsanov@cern.ch, based on main01.cc.
// This program illustrates how HepMC can be interfaced to Pythia8.
// It studies the charged multiplicity distribution at the LHC.
// HepMC events are output to the hepmcout41.dat file.
// WARNING: typically one needs 25 MB/100 events at the LHC.
// Therefore large event samples may be impractical.
#include "Pythia8/Pythia.h"
#include "Pythia8Plugins/HepMC2.h"
using namespace Pythia8;
int main() {
  // Interface for conversion from Pythia8::Event to HepMC event.
  HepMC::Pythia8ToHepMC ToHepMC;
  // Specify file where HepMC events will be stored.
  HepMC::IO_GenEvent ascii_io("hepmcout41.dat", std::ios::out);
  // Generator. Process selection. LHC initialization. Histogram.
  Pythia pythia;
  pythia.readString("Beams:eCM = 8000.");
  pythia.readString("HardQCD:all = on");
  pythia.readString("PhaseSpace:pTHatMin = 20.");
  pythia.init();
  Hist mult("charged multiplicity", 100, -0.5, 799.5);
  // Begin event loop. Generate event. Skip if error.
  for (int iEvent = 0; iEvent < 100; ++iEvent) {
    if (!pythia.next()) continue;
    // Find number of all final charged particles and fill histogram.
    int nCharged = 0;
    for (int i = 0; i < pythia.event.size(); ++i)
      if (pythia.event[i].isFinal() && pythia.event[i].isCharged())
        ++nCharged;
    mult.fill( nCharged );
    // Construct new empty HepMC event and fill it.
    // Units will be as chosen for HepMC build; but can be changed
    // by arguments, e.g. GenEvt( HepMC::Units::GEV, HepMC::Units::MM)
    HepMC::GenEvent* hepmcevt = new HepMC::GenEvent();
    ToHepMC.fill_next_event( pythia, hepmcevt );
    // Write the HepMC event to file. Done with it.
    ascii_io << hepmcevt;
    delete hepmcevt;
  // End of event loop. Statistics. Histogram.
  }
  pythia.stat();
  cout << mult;
  // Done.
  return 0;
}

main42.cc


// main42.cc is a part of the PYTHIA event generator.
// Copyright (C) 2016 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: Mikhail Kirsanov, Mikhail.Kirsanov@cern.ch.
// This program illustrates how a file with HepMC events
// can be generated by Pythia8.
// Input and output files are specified on the command line, e.g. like
// ./main42.exe main42.cmnd hepmcout42.dat > out
// The main program contains no analysis; this is intended to happen later.
// It therefore "never" has to be recompiled to handle different tasks.
// WARNING: typically one needs 25 MB/100 events at the LHC.
// Therefore large event samples may be impractical.
#include "Pythia8/Pythia.h"
#include "Pythia8Plugins/HepMC2.h"
using namespace Pythia8;
int main(int argc, char* argv[]) {
  // Check that correct number of command-line arguments
  if (argc != 3) {
    cerr << " Unexpected number of command-line arguments. \n You are"
         << " expected to provide one input and one output file name. \n"
         << " Program stopped! " << endl;
    return 1;
  }
  // Check that the provided input name corresponds to an existing file.
  ifstream is(argv[1]);
  if (!is) {
    cerr << " Command-line file " << argv[1] << " was not found. \n"
         << " Program stopped! " << endl;
    return 1;
  }
  // Confirm that external files will be used for input and output.
  cout << "\n >>> PYTHIA settings will be read from file " << argv[1]
       << " <<< \n >>> HepMC events will be written to file "
       << argv[2] << " <<< \n" << endl;
  // Interface for conversion from Pythia8::Event to HepMC event.
  HepMC::Pythia8ToHepMC ToHepMC;
  // Specify file where HepMC events will be stored.
  HepMC::IO_GenEvent ascii_io(argv[2], std::ios::out);
  // Generator.
  Pythia pythia;
  // Read in commands from external file.
  pythia.readFile(argv[1]);
  // Extract settings to be used in the main program.
  int    nEvent    = pythia.mode("Main:numberOfEvents");
  int    nAbort    = pythia.mode("Main:timesAllowErrors");
  // Initialization.
  pythia.init();
  // Begin event loop.
  int iAbort = 0;
  for (int iEvent = 0; iEvent < nEvent; ++iEvent) {
    // Generate event.
    if (!pythia.next()) {
      // If failure because reached end of file then exit event loop.
      if (pythia.info.atEndOfFile()) {
        cout << " Aborted since reached end of Les Houches Event File\n";
        break;
      }
      // First few failures write off as "acceptable" errors, then quit.
      if (++iAbort < nAbort) continue;
      cout << " Event generation aborted prematurely, owing to error!\n";
      break;
    }
    // Construct new empty HepMC event and fill it.
    // Units will be as chosen for HepMC build, but can be changed
    // by arguments, e.g. GenEvt( HepMC::Units::GEV, HepMC::Units::MM)
    HepMC::GenEvent* hepmcevt = new HepMC::GenEvent();
    ToHepMC.fill_next_event( pythia, hepmcevt );
    // Write the HepMC event to file. Done with it.
    ascii_io << hepmcevt;
    delete hepmcevt;
  // End of event loop. Statistics.
  }
  pythia.stat();
  // Done.
  return 0;
}

main43.cc


// main43.cc is a part of the PYTHIA event generator.
// Copyright (C) 2016 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: Mikhail Kirsanov, Mikhail.Kirsanov@cern.ch. This program
// illustrates how a file with HepMC events can be generated by
// Pythia8.  It is similar to main42, except that it allows for
// several subruns, e.g. from related LHEF. Input and output files are
// specified on the command line, e.g. like
//     ./main43 main43.cmnd hepmcout43.dat > out
// The main program contains no analysis; this is intended to happen
// later. It therefore "never" has to be recompiled to handle
// different tasks.
// WARNING: typically one needs 25 MB/100 events at the LHC.
// Therefore large event samples may be impractical.
#include "Pythia8/Pythia.h"
#include "Pythia8Plugins/HepMC2.h"
using namespace Pythia8;
int main(int argc, char* argv[]) {
  // Check that correct number of command-line arguments
  if (argc != 3) {
    cerr << " Unexpected number of command-line arguments. \n You are"
         << " expected to provide one input and one output file name. \n"
         << " Program stopped! " << endl;
    return 1;
  }
  // Check that the provided input name corresponds to an existing file.
  ifstream is(argv[1]);
  if (!is) {
    cerr << " Command-line file " << argv[1] << " was not found. \n"
         << " Program stopped! " << endl;
    return 1;
  }
  // Confirm that external files will be used for input and output.
  cout << "\n >>> PYTHIA settings will be read from file " << argv[1]
       << " <<< \n >>> HepMC events will be written to file "
       << argv[2] << " <<< \n" << endl;
  // Interface for conversion from Pythia8::Event to HepMC event.
  HepMC::Pythia8ToHepMC ToHepMC;
  // Specify file where HepMC events will be stored.
  HepMC::IO_GenEvent ascii_io(argv[2], std::ios::out);
  // Generator.
  Pythia pythia;
  // Read in subrun-independent commands from external file.
  pythia.readFile( argv[1]);
  // Extract data to be used in main program. Set counters.
  int nSubrun = pythia.mode("Main:numberOfSubruns");
  int nAbort  = pythia.mode("Main:timesAllowErrors");
  int iAbort  = 0;
  // Begin loop over subruns.
  for (int iSubrun = 1; iSubrun <= nSubrun; ++iSubrun) {
    // Read in subrun-specific data from external file.
    pythia.readFile( argv[1], iSubrun);
    // Initialization.
    pythia.init();
    // Print name of Les Houches Event File.
    string lheFile = pythia.settings.word("Beams:LHEF");
    cout << "\n >>> Now begin subrun " << iSubrun
         << " with events from file " << lheFile << " <<< \n"
         << endl;
    // Begin infinite event loop - to be exited at end of file.
    for (int iEvent = 0; ; ++iEvent) {
      // Generate event.
      if (!pythia.next()) {
        // Leave event loop if at end of file.
        if (pythia.info.atEndOfFile()) break;
        // First few failures write off as "acceptable" errors, then quit.
        if (++iAbort < nAbort) continue;
        cout << " Event generation aborted prematurely, owing to error!\n";
        break;
      }
      // Construct new empty HepMC event and fill it.
      // Units will be as chosen for HepMC build, but can be changed
      // by arguments, e.g. GenEvt( HepMC::Units::GEV, HepMC::Units::MM)
      HepMC::GenEvent* hepmcevt = new HepMC::GenEvent();
      ToHepMC.fill_next_event( pythia, hepmcevt );
      // Write the HepMC event to file. Done with it.
      ascii_io << hepmcevt;
      delete hepmcevt;
    // End of event loop.
    }
  // End of subrun loop.
  }
  // Statistics.
  pythia.stat();
  // Done.
  return 0;
}

main46.cc


// main46.cc is a part of the PYTHIA event generator.
// Copyright (C) 2013 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: S.Chekanov (ANL).
// An example of how to write ProMC files.
//
// The ProMC library is described at http://atlaswww.hep.anl.gov/asc/promc/
// A makefile can be found in the ProMC  package, in examples/pythia.
#include <map>
// ProMC file. Google does not like these warnings.
#pragma GCC diagnostic ignored "-pedantic"
#pragma GCC diagnostic ignored "-Wshadow"
#include "ProMCBook.h"
// Pythia header and namespace.
#include "Pythia8/Pythia.h"
using namespace Pythia8;
//--------------------------------------------------------------------------
string getEnvVar( std::string const & key ) {
  char * val = getenv( key.c_str() );
  return (val == NULL) ? std::string("") : std::string(val);
}
//--------------------------------------------------------------------------
void readPDG( ProMCHeader * header  ) {
  string temp_string;
  istringstream curstring;
  string PdgTableFilename = getEnvVar("PROMC");
  if (PdgTableFilename.size() < 2) PdgTableFilename = string(PROMC);
  PdgTableFilename += "/data/particle.tbl";
  ifstream file_to_read(PdgTableFilename.c_str());
  if (!file_to_read.good()) {
    cout << "**        ERROR: PDG Table (" << PdgTableFilename
         <<  ") not found! exit.                        **" << endl;
    exit(1);
    return;
  }
  // First three lines of the file are useless.
  getline(file_to_read,temp_string);
  getline(file_to_read,temp_string);
  getline(file_to_read,temp_string);
  while (getline(file_to_read,temp_string)) {
    // Needed when using several times istringstream::str(string).
    curstring.clear();
    curstring.str(temp_string);
    long int ID; std::string name; int charge; float mass; float width;
    float lifetime;
    // ID name   chg       mass    total width   lifetime
    //  1 d      -1      0.33000     0.00000   0.00000E+00
    //  in the table, the charge is in units of e+/3
    //  the total width is in GeV
    //  the lifetime is ctau in mm
    curstring >> ID >> name >> charge >> mass >> width >> lifetime;
    ProMCHeader_ParticleData* pp= header->add_particledata();
    pp->set_id(ID);
    pp->set_mass(mass);
    pp->set_name(name);
    pp->set_width(width);
    pp->set_lifetime(lifetime);
    cout << ID << " " << name << " " << mass << endl;
  }
}
//--------------------------------------------------------------------------
int main() {
  int Ntot = 1000; // Total number of events.
  // Generator. Process selection. LHC initialization.
  Pythia pythia;
  pythia.readString("HardQCD:all = on");
  pythia.readString("PhaseSpace:pTHatMin = 20.");
  pythia.readString("Beams:eCM = 14000.");
  pythia.init();
  // ****************  book ProMC file **********************
  ProMCBook* epbook = new ProMCBook("Pythia8.promc","w");
  epbook->setDescription(Ntot,"PYTHIA8");
  // Info on incoming beams and CM energy.
  ProMCHeader header;
  header.set_id1( pythia.info.idA() );
  header.set_id2( pythia.info.idB() );
  header.set_ecm( pythia.info.eCM() );
  header.set_s( pythia.info.s() );
 // Use the range 0.01 MeV to 20 TeV using varints (integers).
 // With particle in GeV, we multiply it by kEV, to get 0.01 MeV = 1 unit.
 const double kEV = 1000*100;
 // With particle in mm, we multiply it by kL to get 0.01 mm = 1 unit.
  const double kL = 100;
  // Set units.
  header.set_momentumunit( (int)kEV );
  header.set_lengthunit( (int)kL );
   // Store a map with PDG information (stored in the header).
  readPDG( &header );
  epbook->setHeader(header); // write header
  // Begin event loop. Generate event. Skip if error.
  for (int n = 0; n < Ntot; n++) {
    if (!pythia.next()) {
      // If failure because reached end of file then exit event loop.
      if (pythia.info.atEndOfFile()) {
        cout << " Aborted since reached end of Les Houches Event File\n";
        break;
      }
      continue;
    }
    //************  ProMC file ***************//
    ProMCEvent promc;
    // Fill event information.
    ProMCEvent_Event *eve = promc.mutable_event();
    eve->set_number(n);
    eve->set_process_id( pythia.info.code() );     // process ID
    eve->set_scale( pythia.info.pTHat( ));         // relevant for 2 -> 2 only
    eve->set_alpha_qed( pythia.info.alphaEM() );
    eve->set_alpha_qcd( pythia.info.alphaS() );
    eve->set_scale_pdf( pythia.info.QFac() );
    eve->set_x1( pythia.info.x1pdf() );
    eve->set_x2( pythia.info.x2pdf() );
    eve->set_id1( pythia.info.id1pdf() );
    eve->set_id2( pythia.info.id2pdf() );
    eve->set_pdf1( pythia.info.pdf1() );
    eve->set_pdf2( pythia.info.pdf2() );
    eve->set_weight( pythia.info.weight() );
    // Fill truth particle information, looping over all particles in event.
    ProMCEvent_Particles *pa= promc.mutable_particles();
    for (int i = 0; i < pythia.event.size(); i++) {
      // Fill information particle by particle.
      pa->add_id( i  );
      pa->add_pdg_id( pythia.event[i].id() );
      // Particle status in HEPMC style.
      // pa->add_status(  pythia.event.statusHepMC(i) );
      pa->add_status(  pythia.event[i].status() );
      pa->add_mother1( pythia.event[i].mother1() );
      pa->add_mother2( pythia.event[i].mother2() );
      pa->add_daughter1( pythia.event[i].daughter1() );
      pa->add_daughter2( pythia.event[i].daughter2() );
      // Only store three-momentum and mass, so need to calculate energy.
      pa->add_px( (int)(pythia.event[i].px()*kEV) );
      pa->add_py( (int)(pythia.event[i].py()*kEV) );
      pa->add_pz( (int)(pythia.event[i].pz()*kEV) );
      pa->add_mass( (int)(pythia.event[i].m()*kEV) );
      // Store production vertex; will often be the origin.
      pa->add_x( int(pythia.event[i].xProd()*kL) );
      pa->add_y( int(pythia.event[i].yProd()*kL) );
      pa->add_z( int(pythia.event[i].zProd()*kL) );
      pa->add_t( int(pythia.event[i].tProd()*kL) );
    } // end loop over particles in the event
    epbook->write(promc); // write event
  } // end loop over events
  // Print statistics.
  pythia.stat();
  double sigmapb = pythia.info.sigmaGen() * 1.0E9;
  cout << "== Cross section for this run = " <<  sigmapb << " pb" << endl;
  cout << "== Events for this run = " <<  Ntot << endl;
  double lumi = (Ntot/sigmapb)/1000;
  cout << "== Luminosity for this run = " <<  lumi  << " fb-1" << endl;
  cout << "\n\n";
  // Save post-generation statistics for ProMC.
  ProMCStat stat;
  stat.set_cross_section_accumulated( sigmapb ); // in pb
  stat.set_cross_section_error_accumulated( pythia.info.sigmaErr() * 1e9 );
  stat.set_luminosity_accumulated( Ntot/sigmapb );
  stat.set_ntried( pythia.info.nTried() );
  stat.set_nselected( pythia.info.nSelected() );
  stat.set_naccepted( pythia.info.nAccepted() );
  epbook->setStatistics( stat );
  // Close the ProMC file.
  epbook->close(); // close
  return 0;
}

main48.cc


// main48.cc is a part of the PYTHIA event generator.
// Copyright (C) 2016 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: Philip Ilten.
// An example where decays are performed with EvtGen. See the
// documentation in Pythia8Plugins/EvtGen.h for further details on the
// EvtGenDecays class. In this example the decay B0 -> nu_e e+ D*-[->
// gamma D-[-> nu_ebar e- pi0]] is forced. The invariant mass spectrum
// of the final state electron and pion is then plotted.
// The syntax to run this example is:
//     ./main48 <EvtGen decay file> <EvtGen particle data> <PYTHIA8DATA>
//              <flag to use EvtGen>
// This example has only been tested with EvtGen version 1.3.0. The
// EvtGen package is designed to use Pythia 8 for any decays that it
// cannot perform. For this to be possible, EvtGen must be linked
// against the Pythia 8 shared library. To build EvtGen 1.3.0 with
// Pythia 8.2 the "-llhapdfdummy" library requirement must be
// removed. Prior to running "./configure" for EvtGen this can be
// accomplished via:
//     sed -i "s/-llhapdfdummy//g" configure
// To modify how this example program is compiled (i.e to remove
// linking against the EvtGenExternal library) change the main48 rule
// in the Makefile of this directory.
#include "Pythia8/Pythia.h"
#include "Pythia8Plugins/EvtGen.h"
using namespace Pythia8;
int main(int argc, char* argv[]) {
  // Check arguments.
  if (argc != 5) {
    cerr << " Unexpected number of command-line arguments. \n You are"
         << " expected to provide the arguments \n"
         << " 1. EvtGen decay file (e.g. DECAY_2010.DEC) \n"
         << " 2. EvtGen particle data (e.g. evt.pdl) \n"
         << " 3. PYTHIA8DATA path \n"
         << " 4. Flag to use EvtGen (true or false) \n"
         << " Program stopped. " << endl;
    return 1;
  }
  bool use(string(argv[4]) == "true");
  // Intialize Pythia.
  Pythia pythia;
  pythia.readString("Print:quiet = on");
  pythia.readString("HardQCD:hardbbbar = on");
  if (!use) {
    cout << "Not using EvtGen." << endl;
    pythia.readString("511:onMode = off");
    pythia.readString("511:onIfMatch = 12 -11 -413");
    pythia.readString("413:onMode = off");
    pythia.readString("413:onIfMatch = 411 22");
    pythia.readString("411:onMode = off");
    pythia.readString("411:onIfMatch = -11 12 111");
  } else cout << "Using EvtGen." << endl;
  pythia.init();
  // Initialize EvtGen.
  EvtGenDecays *evtgen = 0;
  if (use) {
    setenv("PYTHIA8DATA", argv[3], 1);
    evtgen = new EvtGenDecays(&pythia, argv[1], argv[2]);
    evtgen->readDecayFile("main48.dec");
  }
  // The event loop.
  Hist mass("m(e, pi0) [GeV]", 100, 0., 2.);
  for (int iEvent = 0; iEvent < 1000; ++iEvent) {
    // Generate the event.
    if (!pythia.next()) continue;
    // Perform the decays with EvtGen.
    if (evtgen) evtgen->decay();
    // Analyze the event.
    Event &event = pythia.event;
    for (int iPrt = 0; iPrt < (int)event.size(); ++iPrt) {
      if (event[iPrt].idAbs() != 511) continue;
      int iB0(event[iPrt].iBotCopyId()), iDsm(-1), iDm(-1), iE(-1), iPi0(-1);
      for (int iDtr = event[iB0].daughter1(); iDtr <= event[iB0].daughter2();
           ++ iDtr) {
        if (event[iDtr].idAbs() == 413) {
          iDsm = event[iDtr].iBotCopyId();
          continue;
        }
      }
      if (iDsm == -1) continue;
      for (int iDtr = event[iDsm].daughter1(); iDtr <= event[iDsm].daughter2();
           ++ iDtr) {
        if (event[iDtr].idAbs() == 411) {
          iDm = event[iDtr].iBotCopyId();
          continue;
        }
      }
      if (iDm == -1) continue;
      for (int iDtr = event[iDm].daughter1(); iDtr <= event[iDm].daughter2();
           ++ iDtr) {
        if (event[iDtr].idAbs() == 11)  iE   = event[iDtr].iBotCopyId();
        if (event[iDtr].idAbs() == 111) iPi0 = event[iDtr].iBotCopyId();
      }
      if (iE == -1 || iPi0 == -1) continue;
      mass.fill((event[iE].p() + event[iPi0].p()).mCalc());
    }
  }
  // Print the statistics and histogram.
  pythia.stat();
  mass /= mass.getEntries();
  cout << mass;
  if (evtgen) delete evtgen;
  return 0;
}

main51.cc


// main51.cc is a part of the PYTHIA event generator.
// Copyright (C) 2016 Torbjorn Sjostrand.
// PYTHIA is licenced under the GNU GPL version 2, see COPYING for details.
// Please respect the MCnet Guidelines, see GUIDELINES for details.
// Test of LHAPDF interface and whether PDF's behave sensibly.
#include "Pythia8/Pythia.h"
using namespace Pythia8;
//==========================================================================
// Integration to check momentum sum rule.
double integrate(PDF* nowPDF, double Q2) {
  // Number of points, x ranges and initial values.
  int    nLin  = 980;
  int    nLog  = 1000;
  double xLin  = 0.02;
  double xLog  = 1e-8;
  double dxLin = (1. - xLin) / nLin;
  double dxLog = log(xLin / xLog) / nLog;
  double sum   = 0.;
  double x, sumNow;
  // Integration at large x in linear steps.
  for (int iLin = 0; iLin < nLin; ++iLin) {
    x      = xLin + (iLin + 0.5) * dxLin;
    sumNow = nowPDF->xf( 21, x, Q2);
    for (int i = 1; i < 6; ++i)
      sumNow += nowPDF->xf( i, x, Q2) + nowPDF->xf( -i, x, Q2);
    sum   += dxLin * sumNow;
  }
  // Integration at small x in logarithmic steps.
  for (int iLog = 0; iLog < nLog; ++iLog) {
    x      = xLog * pow( xLin / xLog, (iLog + 0.5) / nLog );
    sumNow = nowPDF->xf( 21, x, Q2);
    for (int i = 1; i < 6; ++i)
      sumNow += nowPDF->xf( i, x, Q2) + nowPDF->xf( -i, x, Q2);
    sum   += dxLog * x * sumNow;
  }
  // Done.
  return sum;
}
//==========================================================================
int main() {
  // The Pythia class itself is not used, but some facilities that come along.
  //Pythia pythia;
  // Chosen new PDF set; LHAPDF5 file name conventions.
  //string pdfSet = "LHAPDF5:cteq5l.LHgrid";
  //string pdfSet = "LHAPDF5:cteq61.LHpdf";
  //string pdfSet = "LHAPDF5:cteq61.LHgrid";
  //string pdfSet = "LHAPDF5:MRST2004nlo.LHgrid";
  //string pdfSet = "LHAPDF5:MRST2001lo.LHgrid";
  string pdfSet = "LHAPDF5:MRST2007lomod.LHgrid";
  // Pointers to old default and new tryout PDF sets.
  Info info;
  PDF* oldPDF = new CTEQ5L(2212);
  PDF* newPDF = new LHAPDF(2212, pdfSet, &info);
  // Alternative: compare two Pomeron PDF's. Boost second by factor 2.
  //PDF* oldPDF = new PomFix( 990, -0.2, 2.5, 0., 3., 0.4, 0.5);
  //PDF* newPDF = new PomH1Jets( 990, 2.);
  //PDF* oldPDF = new PomH1FitAB( 990, 2);
  //PDF* newPDF = new PomH1FitAB( 990, 3);
  // Allow extrapolation of PDF's beyond x and Q2 boundaries, at own risk.
  // Default behaviour is to freeze PDF's at boundaries.
  newPDF->setExtrapolate(true);
  // Histogram F(x, Q2) = (9/4) x*g(x, Q2) + sum_{i = q, qbar} x*f_i(x, Q2)
  // for range 10^{-8} < x < 1 logarithmic in x and for Q2 = 4 and 100.
  Hist oldF4("F( x, Q2 = 4) old", 80 , -8., 0.);
  Hist newF4("F( x, Q2 = 4) new", 80 , -8., 0.);
  Hist ratF4("F( x, Q2 = 4) new/old", 80 , -8., 0.);
  Hist oldF100("F( x, Q2 = 100) old", 80 , -8., 0.);
  Hist newF100("F( x, Q2 = 100) new", 80 , -8., 0.);
  Hist ratF100("F( x, Q2 = 100) new/old", 80 , -8., 0.);
  // Loop over the two Q2 values.
  for (int iQ = 0; iQ < 2; ++iQ) {
    double Q2 = (iQ == 0) ? 4. : 100;
    // Loop over x values, in a logarithmic scale
    for (int iX = 0; iX < 80; ++iX) {
      double xLog = -(0.1 * iX + 0.05);
      double x = pow( 10., xLog);
      // Evaluate old summed PDF.
      double oldSum = 2.25 * oldPDF->xf( 21, x, Q2);
      for (int i = 1; i < 6; ++i)
        oldSum += oldPDF->xf( i, x, Q2) + oldPDF->xf( -i, x, Q2);
      if (iQ == 0) oldF4.fill ( xLog, oldSum );
      else       oldF100.fill ( xLog, oldSum );
      // Evaluate new summed PDF.
      double newSum = 2.25 * newPDF->xf( 21, x, Q2);
      for (int i = 1; i < 6; ++i)
        newSum += newPDF->xf( i, x, Q2) + newPDF->xf( -i, x, Q2);
      if (iQ == 0) newF4.fill ( xLog, newSum );
      else       newF100.fill ( xLog, newSum );
    //End loops over x and Q2 values.
    }
  }
  // Show F(x, Q2) and their ratio new/old.
  ratF4 = newF4 / oldF4;
  ratF100 = newF100 / oldF100;
  cout << oldF4 << newF4 << ratF4 << oldF100 << newF100 << ratF100;
  // Histogram momentum sum as a function of Q2 (or rather log10(Q2)).
  Hist oldXSum("momentum sum(log10(Q2)) old", 100, -2., 8.);
  Hist newXSum("momentum sum(log10(Q2)) new", 100, -2., 8.);
  // Loop over Q2 values.
  for (int iQ = 0; iQ < 100; ++iQ) {
    double log10Q2 = -2.0 + 0.1 * iQ + 0.05;
    double Q2 = pow( 10., log10Q2);
    // Evaluate old and new momentum sums.
    double oldSum = integrate( oldPDF, Q2);
    oldXSum.fill( log10Q2, oldSum);
    double newSum = integrate( newPDF, Q2);
    newXSum.fill( log10Q2, newSum);
  }
  // Show momentum sum as a function of Q2.
  cout << oldXSum << newXSum;
  // Done.
  delete oldPDF;
  delete newPDF;
  return 0;
}

main52.cc


// main52.cc is a part of the PYTHIA event generator.
// Copyright (C) 2016 Torbjorn Sjostrand.
// PYTHIA is licenced under the GNU GPL version 2, see COPYING for details.
// Please respect the MCnet Guidelines, see GUIDELINES for details.
// Studies of hadron-level and parton-level minimum-bias quantities,
// comparing internal default PDF with one from LHAPDF.
// Major differences indicate need for major retuning, e.g. pT0Ref.
// Access time information.
#include <ctime>
#include "Pythia8/Pythia.h"
using namespace Pythia8;
int main() {
  // Machine: 1 = Tevatron, 2 = LHC. Statistics.
  int machine = 1;
  int nEvent  = 10000;
  // Select new PDF set; LHAPDF5 file name conventions.
  //string pdfSet = "LHAPDF5:cteq5l.LHgrid";
  //string pdfSet = "LHAPDF5:cteq61.LHpdf";
  //string pdfSet = "LHAPDF5:cteq61.LHgrid";
  //string pdfSet = "LHAPDF5:MRST2004nlo.LHgrid";
  string pdfSet = "LHAPDF5:MRST2001lo.LHgrid";
  // Histograms for hadron-level quantities.
  double nMax = (machine == 1) ? 199.5 : 399.5;
  Hist nChargedOld("n_charged old PDF", 100, -0.5, nMax);
  Hist nChargedNew("n_charged new PDF", 100, -0.5, nMax);
  Hist nChargedRat("n_charged new/old PDF", 100, -0.5, nMax);
  Hist ySpecOld("y charged distribution old PDF", 100, -10., 10.);
  Hist ySpecNew("y charged distribution new PDF", 100, -10., 10.);
  Hist ySpecRat("y charged distribution new/old PDF", 100, -10., 10.);
  Hist pTSpecOld("pT charged distribution old PDF", 100, 0., 20.);
  Hist pTSpecNew("pT charged distribution new PDF", 100, 0., 20.);
  Hist pTSpecRat("pT charged distribution new/old PDF", 100, 0., 20.);
  Hist avgPTnChOld("<pT>(n_charged) old PDF", 100, -0.5, nMax);
  Hist avgPTnChNew("<pT>(n_charged) new PDF", 100, -0.5, nMax);
  Hist avgPTnChRat("<pT>(n_charged) new/old PDF", 100, -0.5, nMax);
  // Histograms for parton-level quantities.
  Hist xDistOld("MPI log(x) distribution old PDF", 80, -8., 0.);
  Hist xDistNew("MPI log(x) distribution new PDF", 80, -8., 0.);
  Hist xDistRat("MPI log(x) distribution new/old PDF", 80, -8., 0.);
  Hist pTDistOld("MPI pT (=Q) distribution old PDF", 100, 0., 20.);
  Hist pTDistNew("MPI pT (=Q) distribution new PDF", 100, 0., 20.);
  Hist pTDistRat("MPI pT (=Q) distribution new/old PDF", 100, 0., 20.);
  // Loop over one default run and one with new PDF.
  for (int iRun = 0; iRun < 2; ++iRun) {
    // Get starting time in seconds.
    time_t tBegin = time(0);
    // Generator.
    Pythia pythia;
    Event& event = pythia.event;
    // Generate minimum-bias events, with or without double diffraction.
    pythia.readString("SoftQCD:nonDiffractive = on");
    //pythia.readString("SoftQCD:doubleDiffractive = on");
    // Generate QCD jet events, above some threshold.
    //pythia.readString("HardQCD:all = on");
    //pythia.readString("PhaseSpace:pTHatMin = 50.");
    // In second run pick new PDF set.
    if (iRun == 1) {
      pythia.readString("PDF:pSet = " + pdfSet);
     // Allow extrapolation of PDF's beyond x and Q2 boundaries, at own risk.
     // Default behaviour is to freeze PDF's at boundaries.
     pythia.readString("PDF:extrapolate = on");
      // Need to change pT0Ref depending on choice of PDF.
      // One possibility: retune to same <n_charged>.
      //pythia.readString("MultipartonInteractions:pT0Ref = 2.17");
    }
    // Tevatron/LHC initialization.
    double eCM =  (machine == 1) ? 1960. : 7000.;
    pythia.settings.parm("Beams:eCM", eCM);
    if (machine == 1) pythia.readString("Beams:idB = -2212");
    pythia.init();
    // Begin event loop.
    for (int iEvent = 0; iEvent < nEvent; ++iEvent) {
      // Generate events.  Skip if error.
      if (!pythia.next()) continue;
      // Statistics on multiplicity and pT.
      int    nCh   = 0;
      double pTsum = 0.;
      for (int i = 0; i < event.size(); ++i)
      if (event[i].isFinal() && event[i].isCharged()) {
        ++nCh;
        pTsum += event[i].pT();
        // Fill histograms for charged y and pT spectra.
        if (iRun == 0) {
          ySpecOld.fill( event[i].y() );
          pTSpecOld.fill( event[i].pT() );
        } else {
          ySpecNew.fill( event[i].y() );
          pTSpecNew.fill( event[i].pT()  );
        }
      }
      // Fill histograms for summed quantities.
      if (iRun == 0) {
        nChargedOld.fill( nCh );
        avgPTnChOld.fill( nCh, pTsum / max(1, nCh) );
      } else {
        nChargedNew.fill( nCh );
        avgPTnChNew.fill( nCh, pTsum / max(1, nCh) );
      }
      // Loop through event record and fill x of all incoming partons.
      for (int i = 1; i < event.size(); ++i)
      if (event[i].status() == -21 || event[i].status() == -31) {
        double x = 2. * event[i].e() / eCM;
        if (iRun == 0) xDistOld.fill( log10(x) );
        else           xDistNew.fill( log10(x) );
      }
      // Loop through multiparton interactions list and fill pT of all MPI's.
      for (int i = 0; i < pythia.info.nMPI(); ++i) {
        double pT = pythia.info.pTMPI(i);
        if (iRun == 0) pTDistOld.fill( pT );
        else           pTDistNew.fill( pT );
      }
    // End of event loop.
    }
    // Statistics.
    pythia.readString("Stat:showPartonLevel = on");
    pythia.stat();
    // Get finishing time in seconds. Print used time.
    time_t tEnd = time(0);
    cout << "\n This subrun took " << tEnd - tBegin << " seconds \n" << endl;
  // End of loop over two runs.
  }
  // Form <pT>(n_charged) ratios.
  avgPTnChOld /= nChargedOld;
  avgPTnChNew /= nChargedNew;
  // Take ratios of new to old distributions.
  nChargedRat  = nChargedNew / nChargedOld;
  ySpecRat     = ySpecNew    / ySpecOld;
  pTSpecRat    = pTSpecNew    / pTSpecOld;
  avgPTnChRat  = avgPTnChNew / avgPTnChOld;
  xDistRat     = xDistNew    / xDistOld;
  pTDistRat    = pTDistNew   / pTDistOld;
  // Print histograms.
  cout << nChargedOld << nChargedNew << nChargedRat
       << ySpecOld    << ySpecNew    << ySpecRat
       << pTSpecOld   << pTSpecNew   << pTSpecRat
       << avgPTnChOld << avgPTnChNew << avgPTnChRat
       << xDistOld    << xDistNew    << xDistRat
       << pTDistOld   << pTDistNew   << pTDistRat;
  // Second part of study, as simple extra check:
  // Begin fill shape of effective PDF at typical MPI Q2 = 10 scale:
  // F_effective(x) = (9/4) x*g(x) + Sum_i (x*q_i(x) + x*qbar_i(x)).
  Info info;
  double Q2 = 10.;
  PDF* oldPDF = new CTEQ5L(2212);
  PDF* newPDF = new LHAPDF(2212, pdfSet, &info);
  // Histograms.
  Hist effFlinOld("F_effective( x, Q2 = 10) old", 100 , 0., 1.);
  Hist effFlinNew("F_effective( x, Q2 = 10) new", 100 , 0., 1.);
  Hist effFlinRat("F_effective( x, Q2 = 10) new/old", 100 , 0., 1.);
  Hist effFlogOld("F_effective( x, Q2 = 10) old", 80 , -8., 0.);
  Hist effFlogNew("F_effective( x, Q2 = 10) new", 80 , -8., 0.);
  Hist effFlogRat("F_effective( x, Q2 = 10) new/old", 80 , -8., 0.);
  // Loop over x values, in a linear scale.
  for (int iX = 0; iX < 99; ++iX) {
    double x = 0.005 + 0.01 * iX;
    // Evaluate old summed PDF.
    double oldSum = 2.25 * oldPDF->xf( 21, x, Q2);
    for (int i = 1; i < 6; ++i)
      oldSum += oldPDF->xf( i, x, Q2) + oldPDF->xf( -i, x, Q2);
    effFlinOld.fill ( x, oldSum );
    // Evaluate new summed PDF.
    double newSum = 2.25 * newPDF->xf( 21, x, Q2);
    for (int i = 1; i < 6; ++i)
      newSum += newPDF->xf( i, x, Q2) + newPDF->xf( -i, x, Q2);
    effFlinNew.fill ( x, newSum );
  //End loop over x values, in a linear scale.
  }
  // Loop over x values, in a logarithmic scale
  for (int iX = 0; iX < 80; ++iX) {
    double xLog = -(0.1 * iX + 0.05);
    double x = pow( 10., xLog);
    // Evaluate old summed PDF.
    double oldSum = 2.25 * oldPDF->xf( 21, x, Q2);
    for (int i = 1; i < 6; ++i)
      oldSum += oldPDF->xf( i, x, Q2) + oldPDF->xf( -i, x, Q2);
    effFlogOld.fill ( xLog, oldSum );
    // Evaluate new summed PDF.
    double newSum = 2.25 * newPDF->xf( 21, x, Q2);
    for (int i = 1; i < 6; ++i)
      newSum += newPDF->xf( i, x, Q2) + newPDF->xf( -i, x, Q2);
    effFlogNew.fill ( xLog, newSum );
  //End loop over x values, in a logarithmic scale.
  }
  // Take ratios of new to old distributions.
  effFlinRat   = effFlinNew  / effFlinOld;
  effFlogRat   = effFlogNew  / effFlogOld;
  // Print histograms.
  cout << effFlinOld  << effFlinNew  << effFlinRat
       << effFlogOld  << effFlogNew  << effFlogRat;
  // Done.
  delete oldPDF;
  delete newPDF;
  return 0;
}

main53.cc


// main53.cc is a part of the PYTHIA event generator.
// Copyright (C) 2016 Peter Skands, Torbjorn Sjostrand.
// PYTHIA is licenced under the GNU GPL version 2, see COPYING for details.
// Please respect the MCnet Guidelines, see GUIDELINES for details.
// This is a simple test program.
// It illustrates how to interface an external process with an incoming photon
// in a hadron beam, using the MRST2004QED PDF set.
// All input apart from the name of the external LHEF file is specified in the
// main53.cmnd file.
#include "Pythia8/Pythia.h"
using namespace Pythia8;
int main() {
  // Generator. Shorthand for the event.
  Pythia pythia;
  Event& event = pythia.event;
  // Read in commands from external file.
  pythia.readFile("main53.cmnd");
  // Extract settings to be used in the main program.
  int nEvent = pythia.mode("Main:numberOfEvents");
  // Initialize. Either of two opions, to be picked in main53.cmnd.
  // 1) Read in external event with incoming photon in the ME,
  // from pre-generated .lhe file (thanks to SANC and R. Sadykov).
  // 2) Use internal fermion gamma -> W+- fermion' process.
  pythia.init();
  // Histograms for pT distribution in gluon production vertex.
  Hist pTprim( "pT of photon production, no ISR", 100, 0., 100.);
  Hist pTwith( "pT of photon production, with ISR", 100, 0., 100.);
  // Begin event loop.
  for (int iEvent = 0; iEvent < nEvent; ++iEvent) {
    // Generate events. Quit if failure.
    if (!pythia.next()) {
      break;
    }
    // Analyze event to find branching where photon is produced.
    int iGam = (event[3].id() == 22) ? 3 : 4;
    int iGamMother = iGam;
    for ( ; ; ) {
      iGamMother = event[iGam].mother1();
      if (iGamMother < iGam || event[iGamMother].id() != 22) break;
      iGam = iGamMother;
    }
    // Find and histogram pT in this branching.
    if (iGamMother < iGam) pTprim.fill( event[iGam].pT() );
    else {
      int iQ = iGamMother;
      int size = event.size();
      do ++iQ;
      while (event[iQ].status() != -43 && iQ < size - 1);
      if (event[iQ].status() == -43) pTwith.fill( event[iQ].pT() );
    }
  // End of event loop.
  }
  // Final statistics and histogram output.
  pythia.stat();
  cout << pTprim << pTwith;
  return 0;
}

main54.cc


// main54.cc is a part of the PYTHIA event generator.
// Copyright (C) 2016 Torbjorn Sjostrand.
// PYTHIA is licenced under the GNU GPL version 2, see COPYING for details.
// Please respect the MCnet Guidelines, see GUIDELINES for details.
// This program compares the internal and LHAPDF implementations of the
// NNPDF 2.3 QCD+QED sets, for results and for timing.
// Author: Juan Rojo.
#include "Pythia8/Pythia.h"
using namespace Pythia8;
int main() {
  cout<<"\n NNPDF2.3 QED LO phenomenology \n "<<endl;
  cout<<"\n Check access to NNPDF2.3 LO QED sets \n "<<endl;
  // Generator.
  Pythia pythia;
  // Access the PDFs.
  int idBeamIn = 2212;
  string xmlPath = "../xmldoc/";
  Info info;
  // Grid of studied points.
  string xpdf[] = {"x*g","x*d","x*u","x*s"};
  double xlha[] = {1e-5, 1e-1};
  double Q2[] = { 2.0, 10000.0 };
  string setName;
  string setName_lha;
  // For timing checks.
  int const nq = 200;
  int const nx = 200;
  // Loop over all internal PDF sets in Pythia8
  // and compare with their LHAPDF5 correspondents.
  for (int iFitIn = 3; iFitIn < 5; iFitIn++) {
    // Constructor for internal PDFs.
    NNPDF pdfs_nnpdf( idBeamIn, iFitIn, xmlPath, &info);
    // Constructor for LHAPDF.
    if (iFitIn == 3) setName = "LHAPDF5:NNPDF23_nlo_as_0119_qed.LHgrid";
    if (iFitIn == 4) setName = "LHAPDF5:NNPDF23_nnlo_as_0119_qed.LHgrid";
    LHAPDF pdfs_nnpdf_lha( idBeamIn, setName, &info);
    cout << "\n PDF set = " << setName << " \n" << endl;
    // Check quarks and gluons.
    for (int f = 0; f < 4; f++) {
      for (int iq = 0; iq < 2; iq++) {
        cout << "  " << xpdf[f] << ", Q2 = " << Q2[iq] << endl;
        cout << "   x \t     Pythia8\t   LHAPDF\t   diff(%) " << endl;
        for (int ix = 0; ix < 2; ix++) {
          double a = pdfs_nnpdf.xf( f, xlha[ix], Q2[iq]);
          double b = pdfs_nnpdf_lha.xf( f, xlha[ix], Q2[iq]);
          double diff = 1e2 * fabs((a-b)/b);
          cout << scientific << xlha[ix] << " " << a << " " << b
               << " " << diff << endl;
          if (diff > 1e-8) exit(-10);
        }
      }
    }
    // Check photon.
    cout << "\n Now checking the photon PDF \n" << endl;
    for (int iq = 0; iq < 2; iq++) {
      cout << "  " << "x*gamma" << ", Q2 = " << Q2[iq] << endl;
      cout << "   x \t     Pythia8\t LHAPDF\t diff(%)" << endl;
      for (int ix = 0; ix < 2; ix++) {
        double a = pdfs_nnpdf.xf( 22, xlha[ix], Q2[iq]);
        double b = pdfs_nnpdf_lha.xf( 22, xlha[ix], Q2[iq]);
        double diff = 1e2 * fabs((a-b)/b);
        cout << scientific << xlha[ix] << " " << a << " " << b
             << " " << diff << endl;
        if(diff > 1e-8) exit(-10);
      }
    }
    // Now check the timings for evolution.
    cout << "\n Checking timings " << endl;
    clock_t t1 = clock();
    for (int f = -4; f < 4; f++) {
      for (int iq = 0; iq < nq; iq++) {
        double qq2 = 2.0 * pow( 1e6 / 2.0, double(iq)/nq);
        for (int ix = 0; ix < nx; ix++) {
          double xx = 1e-6 * pow( 9e-1 / 1e-6, double(ix)/nx);
          pdfs_nnpdf.xf(f,xx,qq2);
        }
      }
    }
    clock_t t2 = clock();
    cout << " NNPDF internal timing = " << (t2-t1)/(double)CLOCKS_PER_SEC
         << endl;
    t1=clock();
    for (int f = -4; f < 4; f++) {
      for (int iq = 0; iq < nq; iq++) {
        double qq2 = 2.0 * pow(1e6 / 2.0, double(iq)/nq);
        for (int ix = 0; ix < nx; ix++) {
          double xx = 1e-6 * pow( 9e-1 / 1e-6, double(ix)/nx);
          pdfs_nnpdf_lha.xf(f,xx,qq2);
        }
      }
    }
    t2=clock();
    cout << " NNPDF LHAPDF   timing = " << (t2-t1)/(double)CLOCKS_PER_SEC
         << endl;
  } // End loop over NNPDF internal sets
  // Done.
  cout << "\n Checked that LHAPDF and Internal Pythia8 give identical"
       << " results\n" << endl;
  return 0;
}

main61.cc


// main61.cc is a part of the PYTHIA event generator.
// Copyright (C) 2016 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: Christine O. Rasmussen.
// The y, pT, x_Pomeron and t distributions for forward Z bosons at the LHC,
// within the hard diffraction framework for an inclusive event sample.
// Tests the impact of successive requirements.
#include "Pythia8/Pythia.h"
using namespace Pythia8;
int main() {
  // Create Pythia instance. Shorthand for event and info.
  Pythia pythia;
  Event& event = pythia.event;
  Info&  info  = pythia.info;
  // Set it up to generate Z's at 8 TeV.
  pythia.readString("Beams:eCM = 8000.");
  pythia.readString("WeakSingleBoson:ffbar2gmZ = on");
  pythia.readString("23:mMin = 70.");
  pythia.readString("23:mMax = 110.");
  // Setup of diffractive framework.
  pythia.readString("Diffraction:doHard = on");
  pythia.readString("Diffraction:sampleType = 1");
  pythia.readString("Diffraction:PomFlux = 5");
  pythia.readString("PDF:PomSet = 6");
  // Simplify printout.
  pythia.readString("Init:showChangedSettings = off");
  pythia.readString("Init:showChangedParticleData = off");
  pythia.readString("Init:showMultipartonInteractions = off");
  pythia.readString("Next:numberShowInfo = 0");
  pythia.readString("Next:numberShowProcess = 0");
  pythia.readString("Next:numberShowEvent = 0");
  pythia.readString("Next:showScaleAndVertex = off");
  // Switch off hadronization, since not used here.
  pythia.readString("HadronLevel:all = off");
  // Initialize.
  pythia.init();
  // Collect information on the number of diffractive events
  int maxEvent      = 10000;
  int nDiffA        = 0;
  int nDiffB        = 0;
  int nReducedDiffA = 0;
  int nReducedDiffB = 0;
  // Histograms.
  Hist y0("dN/dy inclusive",               100, -5.,   5.);
  Hist y1("dN/dy after PDF selection",     100, -5.,   5.);
  Hist y2("dN/dy after MPI selection",     100, -5.,   5.);
  Hist pT0("dN/dpTZ inclusive",            100,  0., 100.);
  Hist pT1("dN/dpTZ after PDF selection",  100,  0., 100.);
  Hist pT2("dN/dpTZ after MPI selection",  100,  0., 100.);
  Hist xP1("dN/dxPom after PDF selection", 100,  0.,   1.);
  Hist xP2("dN/dxPom after MPI selection", 100,  0.,   1.);
  Hist tP1("dN/dt after PDF selection",    100, -2.,   0.);
  Hist tP2("dN/dt after MPI selection",    100, -2.,   0.);
  // Begin event loop. Generate event; skip if generation failed.
  for (int iEvent = 0; iEvent < maxEvent; ++iEvent) {
    if (!pythia.next()) continue;
    // Locate the Z0 and find its y and pT.
    int iZ = 0;
    for (int i = 0; i < event.size(); ++i) if (event[i].id() == 23) iZ = i;
    double yZ  = event[iZ].y();
    double pTZ = event[iZ].pT();
    y0.fill( yZ );
    pT0.fill( pTZ );
    // Find diffractive events. Histogram y and pT.
    if ( info.isHardDiffractiveA() == 1 || info.isHardDiffractiveB() == 1) {
      y1.fill( yZ );
      pT1.fill( pTZ );
      if (info.nMPI() == 1) {
        y2.fill( yZ );
        pT2.fill( pTZ );
      }
      // Statistics and histogram on x_Pomeron and t.
      if ( info.isHardDiffractiveA() == 1) {
        ++nDiffA;
        xP1.fill( info.xPomeronB() );
        tP1.fill( info.tPomeronB() );
        if (info.nMPI() == 1) {
          ++nReducedDiffA;
          xP2.fill( info.xPomeronB() );
          tP2.fill( info.tPomeronB() );
        }
      }
      else if ( info.isHardDiffractiveB() == 1) {
        ++nDiffB;
        xP1.fill( info.xPomeronA() );
        tP1.fill( info.tPomeronA() );
        if (info.nMPI() == 1) {
          ++nReducedDiffB;
          xP2.fill( info.xPomeronA() );
          tP2.fill( info.tPomeronA() );
        }
      }
    }
  // End of event loop. Statistics on event generation.
  }
  pythia.stat();
  // Statistics on diffraction.
  cout << "Side A is MPI-unchecked diffractive : " << nDiffA << endl;
  cout << "Side A is MPI-checked diffractive   : " << nReducedDiffA << endl;
  cout << "Side B is MPI-unchecked diffractive : " << nDiffB << endl;
  cout << "Side B is MPI-checked diffractive   : " << nReducedDiffB << endl;
  cout << "Total MPI-unchecked diffractive events : " << fixed
       << setprecision(2) << (nDiffA + nDiffB) / double(maxEvent) * 100.
       << "%" << endl;
  cout << "Total MPI-checked diffractive events : "
       << (nReducedDiffA + nReducedDiffB) / double(maxEvent) * 100.
       << "%" << endl;
  // Histograms.
  cout << y0 << y1 << y2 << pT0 << pT1 << pT2 << xP1 << xP2 << tP1 << tP2;
  return 0;
}

main62.cc


// main62.cc is a part of the PYTHIA event generator.
// Copyright (C) 2016 Torbjorn Sjostrand.
// PYTHIA is licenced under the GNU GPL version 2, see COPYING for details.
// Please respect the MCnet Guidelines, see GUIDELINES for details.
// Example how you can use UserHooks to set angular decay distributions
// for undecayed resonances from Les Houches input using the polarization
// information of the boson defined in its rest frame.
#include "Pythia8/Pythia.h"
using namespace Pythia8;
//==========================================================================
// Book a histogram to test the angular distribution in the UserHook.
// It is booked here so that it is global.
Hist cosRaw("cos(the*) raw",100,-1.,1.);
//==========================================================================
// Write own derived UserHooks class.
// Assumptions in this particular case:
// The W+- bosons were undecayed in the Les Houches Events input file,
// and subsequently decayed isotropically by the Pythia machinery.
// Now the angular distribution will be corrected for each W,
// based on the polarization value stored in the LHEF.
// For W- this is (1 -+ cos(theta))^2 for +-1, sin^2(theta) for 0,
// and isotropic for 9. For W+ it is flipped (i.e. theta->pi-theta).
// The Pythia decay products (i.e. the branching ratios) are retained.
class MyUserHooks : public UserHooks {
public:
  // Constructor can set helicity definition. Destructor does nothing.
  MyUserHooks(Info* infoPtrIn, bool inputOption = true)
    : infoPtr(infoPtrIn), helicityDefinedByMother(inputOption) {}
  ~MyUserHooks() {}
  // Allow a veto for the process level, to gain access to decays.
  bool canVetoProcessLevel() {return true;}
  // Access the event after resonance decays.
  bool doVetoProcessLevel(Event& process) {
    // Identify decayed W+- bosons for study.
    // Assume isotropic decay if polarization is unphysically big (|pol|>2)
    for (int i = 0; i < process.size(); ++i) {
      if (process[i].idAbs() == 24 && process[i].status() == -22
          && abs(process[i].pol()) < 2.) {
        // Pick decay angles according to desired distribution
        // based on polarization and particle/antiparticle.
        double cosThe = selectAngle( process[i].pol(), process[i].id() );
        // Accumulate the raw angular distribution.
        cosRaw.fill( cosThe );
        double sinThe = sqrt(1.0 - pow2(cosThe));
        double phi    = 2.0 * M_PI * rndmPtr->flat();
        // Identify W+- daughters, properly ordered.
        int idV = process[i].id();
        int i1  = process[i].daughter1();
        int i2  = process[i].daughter2();
        // The current distributions are for the particle with the
        // same charge sign as the mother, i.e. W- -> e-.
        if (process[i1].id() * idV > 0) swap( i1, i2);
        // Set up decay in rest frame of W+-.
        double mV = process[i].m();
        double m1 = process[i1].m();
        double m2 = process[i2].m();
        // Energy and absolute momentum of first decay product in W rest frame.
        double e1 = 0.5* (pow2(mV) + pow2(m1) - pow2(m2))/mV;
        double pA = sqrt(pow2(e1) - pow2(m1));
        // Four-vectors for the two decay products.
        Vec4 p1( pA * sinThe * cos(phi), pA *sinThe * sin(phi),
          pA * cosThe, e1);
        Vec4 p2   = Vec4(0,0,0,mV) - p1;
        // Reference four-vector for helicity definition.
        Vec4 pM;
        // Helicity is defined in the mother frame.
        if( helicityDefinedByMother ) {
          pM = process[process[i].mother1()].p();
        // Helicity is defined in the process CMS frame.
        // This is the convention for MadGraph.
        } else {
          pM = Vec4( 0., 0., 0., infoPtr->mHat());
        }
        // Angular reference axis defined as opposite the mother
        // direction in W rest frame.
        pM.bstback( process[i].p() );
        pM.flip3();
        RotBstMatrix Mrotbst;
        Mrotbst.rot( pM);
        // Rotate and boost W decay products.
        Mrotbst.bst( process[i].p() );
        p1.rotbst(Mrotbst);
        p2.rotbst(Mrotbst);
        process[i1].p( p1 );
        process[i2].p( p2 );
      }
      // End of loop over W's. Do not veto any events.
    }
    return false;
  }
  // Select polar angle for the W decay.
  double selectAngle( double inputSpin, double inputId ) {
    // Set up initial angles.
    double rdNow = rndmPtr->flat();
    double cosThe;
    // Small number to distinguish -1, 1, and 0 with round-off.
    double eps = 1e-10;
    // W+ distribution is "opposite" of W-.
    if (inputId > 0) inputSpin *= -1;
    // Different decay angular distributions.
    // 3/8 * (1 - cos(theta))^2  ++
    if (inputSpin > eps) {
      cosThe = max( 1.0 - 2.0 * pow(rdNow, 1./3.), -1.0);
    // 3/8 * (1 + cos(theta))^2  --
    } else if (inputSpin < -eps) {
      cosThe = min( 2.0 * pow(rdNow, 1./3.) - 1.0,  1.0);
    // 3/4 * sin(theta)^2        00
    // Solution of cubic equation that yields the correct result.
    } else {
      double theA = (acos(1.0 - 2.0 * rdNow) + 4.0 * M_PI) / 3.0;
      cosThe = 2.0 * cos(theA);
    }
    // Return the selected cos(theta) value.
    return cosThe;
  }
private:
  Info* infoPtr;
   // bool to define the frame for helicity.
  bool helicityDefinedByMother;
};
//==========================================================================
int main() {
  // Generator. Shorthand for the event.
  Pythia pythia;
  Event& event = pythia.event;
  // Set up to do a user veto and send it in. Initialize.
  //  Use this line for CMS definition of helicity.
  //  MyUserHooks* myUserHooks = new MyUserHooks(&pythia.info,false);
  // Default constructor uses mother frame for helicity.
  MyUserHooks* myUserHooks = new MyUserHooks(&pythia.info);
  pythia.setUserHooksPtr( myUserHooks);
  pythia.readFile("main62.cmnd");
  pythia.init();
  // Histograms.
  Hist polarization("W polarization", 99, -9.9, 9.9);
  Hist cosPlus( "cos(theta) W- -> f",    100, -1.0, 1.0);
  Hist cosMinus("cos(theta) W+ -> fbar", 100, -1.0, 1.0);
  Hist energy("daughter energy in W rest frame", 100, 0.0, 100.0);
  // Extract settings to be used in the main program.
  int nEvent = pythia.mode("Main:numberOfEvents");
  // Begin event loop.
  for (int iEvent = 0; iEvent < nEvent; ++iEvent) {
    // Generate events.
    pythia.next();
    // Loop through event, looking for a W and its daughters.
    for (int i = 0; i < event.size(); ++i) {
      // Select W boson when it decays to two partons,
      // not when it is a recoil in FSR.
      if (event[i].idAbs() == 24
          && event[i].daughter1() != event[i].daughter2() ) {
        int i1 = event[i].daughter1();
        // Angular distribution is defined with respect to the decay product
        // with the same sign charge as the W boson.
        if (event[i1].id() * event[i].id() > 0 ) i1 = event[i].daughter2();
        // Reconstruct W+- decay angle by boosting daughter and mother to W
        // rest frame. W direction in mother rest frame opposite to mother now.
        RotBstMatrix Mrotbst;
        Mrotbst.bstback( event[i].p() );
        Vec4 p1 = event[i1].p();
        p1.rotbst( Mrotbst );
        Vec4 pM = event[event[i].mother1()].p();
        pM.rotbst( Mrotbst );
        pM.flip3();
        double costhe = costheta( p1, pM );
        // Histogram information.
        polarization.fill( event[i].pol() );
        if ( event[i].id() > 0 ) cosPlus.fill( costhe );
        else                    cosMinus.fill( costhe );
        energy.fill( p1.e() );
      }
    }
  // End of event loop.
  }
  // Statistics. Histograms.
  pythia.stat();
  cout << polarization << cosPlus << cosMinus << energy << cosRaw;
  // Done.
  delete myUserHooks;
  return 0;
}

main63.cc


// main63.cc is a part of the PYTHIA event generator.
// Copyright (C) 2016 Torbjorn Sjostrand.
// PYTHIA is licenced under the GNU GPL version 2, see COPYING for details.
// Please respect the MCnet Guidelines, see GUIDELINES for details.
// Example how you can use UserHooks to enhance rare emission rates,
// in this case q -> q gamma.
// To concentrate on the photons from the showers, MPI and hadronization
// are switched off by default.
#include "Pythia8/Pythia.h"
using namespace Pythia8;
//==========================================================================
// Write own derived UserHooks class.
class EnhanceHooks : public UserHooks {
public:
  // Constructor and destructor do nothing.
  EnhanceHooks() {}
  ~EnhanceHooks() {}
  // Enhance real-emission rate. Thus no trial-emission enhancement.
  bool canEnhanceEmission() { return true;}
  bool canEnhanceTrial()    { return false;}
  // Function to return the weight enhance factor.
  double enhanceFactor(string name) {
    if (name == "isr:Q2QA") return 50.;
    return 1.0;
  }
  // Function to return the vetoing probability.
  double vetoProbability(string name) {
    if (name == "isr:Q2QA") return 0.5;
    return 0.0;
  }
};
//==========================================================================
int main() {
  // Histogram pT spectrum of photons and event weights.
  Hist gamNoEnh(   "gamma pT spectrum, no enhancement",   100, 0., 100.);
  Hist gamWithEnh( "gamma pT spectrum, with enhancement", 100, 0., 100.);
  Hist gamRatio("gamma pT spectrum, with/no enhancement", 100, 0., 100.);
  Hist gamBefWt(   "gamma pT spectrum, without weight",   100, 0., 100.);
  Hist eventWt(    "log10(event weight)",                 100, -7., 3.);
  // Compare generation without and with enhanced q -> q gamma emission.
  for (int iCase = 0; iCase < 2; ++iCase) {
    // Generator.
    Pythia pythia;
    pythia.readFile("main63.cmnd");
    int nEvent = pythia.mode("Main:numberOfEvents");
    // Set up a user hook and send it in.
    UserHooks* enhanceHooks = 0;
    if (iCase == 1) {
      enhanceHooks = new EnhanceHooks();
      pythia.setUserHooksPtr( enhanceHooks);
    }
    // LHC initialization.
    pythia.init();
    // Begin event loop.
    double sumWt = 0.;
    for (int iEvent = 0; iEvent < nEvent; ++iEvent) {
      // Generate events. Find and histogram event weight.
      pythia.next();
      double weight = (iCase == 1)
                    ? enhanceHooks->getEnhancedEventWeight() : 1.;
      if (iCase == 1) eventWt.fill( log10(weight) );
      sumWt += weight;
      // Find all final-state photons and histogram them.
      for (int i = 0; i < pythia.event.size(); ++i)
      if (pythia.event[i].isFinal() && pythia.event[i].id() == 22) {
        double pT = pythia.event[i].pT();
        if (iCase == 0) gamNoEnh.fill(   pT, 1.);
        if (iCase == 1) gamBefWt.fill(   pT, 1.);
        if (iCase == 1) gamWithEnh.fill( pT, weight);
      }
    // End of event loop.
    }
    // Statistics.
    pythia.stat();
    cout << "\n Average event weight = " << scientific
         << sumWt / nEvent << endl;
    // End of case loop.
    if (iCase == 1) delete enhanceHooks;
  }
  // Write histograms to output stream.
  gamRatio = gamWithEnh / gamNoEnh;
  cout << gamNoEnh << gamWithEnh << gamRatio << gamBefWt << eventWt;
  // Write histogram data to files.
  ofstream write;
  write.open("PTA_0");
  gamNoEnh.table(write);
  write.close();
  write.open("PTA_1");
  gamWithEnh.table(write);
  write.close();
  // Done.
  return 0;
}

main64.cc


// main64.cc is a part of the PYTHIA event generator.
// Copyright (C) 2016 Torbjorn Sjostrand.
// PYTHIA is licenced under the GNU GPL version 2, see COPYING for details.
// Please respect the MCnet Guidelines, see GUIDELINES for details.
// This is a simple test program. It shows how PYTHIA 8 can write
// a Les Houches Event File v. 3.0 based on its process-level events.
#include "Pythia8/Pythia.h"
using namespace Pythia8;
//==========================================================================
int main() {
  // Set up for external input of LHEF 3.0 events.
  Pythia pythia;
  pythia.readString("Beams:frameType = 4");
  pythia.readString("Beams:LHEF = wbj_lhef3.lhe");
  pythia.init();
  // Create and open file for LHEF 3.0 output.
  LHEF3FromPythia8 myLHEF3(&pythia.event, &pythia.settings, &pythia.info,
    &pythia.particleData);
  myLHEF3.openLHEF("weakbosons.lhe");
  // Write out initialization info on the file.
  myLHEF3.setInit();
  // Event generation loop.
  for (int iEvent = 0; iEvent < 10; ++iEvent) {
    // Generate next event.
    if (!pythia.next()) {
      if( pythia.info.atEndOfFile() ) break;
      else continue;
    }
    // Store and write event info.
    myLHEF3.setEvent();
  } // End loop over events to generate.
  // Statistics: full printout.
  pythia.stat();
  // Write endtag. Overwrite initialization info with new cross sections.
  myLHEF3.closeLHEF(true);
  // Done.
  return 0;
}

main71.cc


// main71.cc is a part of the PYTHIA event generator.
// Copyright (C) 2016 Richard Corke.
// PYTHIA is licenced under the GNU GPL version 2, see COPYING for details.
// Please respect the MCnet Guidelines, see GUIDELINES for details.
/*
 * Simple example of fastjet analysis. Roughly follows analysis of:
 * T. Aaltonen et al. [CDF Collaboration],
 * Measurement of the cross section for W-boson production in association
 * with jets in ppbar collisions at sqrt(s)=1.96$ TeV
 * Phys. Rev. D 77 (2008) 011108
 * arXiv:0711.4044 [hep-ex]
 *
 * Cuts:
 *   ET(elec)     > 20GeV
 *   |eta(elec)|  < 1.1
 *   ET(missing)  > 30GeV
 *   ET(jet)      > 20GeV
 *   |eta(jet)|   < 2.0
 *   deltaR(elec, jet) > 0.52
 * Not used:
 *   mT(W)        > 20GeV
 */
#include "Pythia8/Pythia.h"
// This is the minimal interface needed to access FastJet.
// A more sophisticated interface is demonstrated in main72.cc.
#include "fastjet/PseudoJet.hh"
#include "fastjet/ClusterSequence.hh"
using namespace Pythia8;
// Experimental cross section
// sigma(W -> ev + >= n-jet; ET(n'th-jet) > 25GeV), n = 0, 1, 2, 3, 4
const double expCrossSec[] = { 798.0, 53.5, 6.8, 0.84, 0.074 };
int main() {
  // Settings
  int  nEvent = 10000;
  bool doMPI  = true;
  // Generator
  Pythia pythia;
  // Single W production
  pythia.readString("WeakSingleBoson:ffbar2W = on");
  // Force decay W->ev
  pythia.readString("24:onMode = off");
  pythia.readString("24:onIfAny = 11 12");
  // Multiparton Interactions
  if (doMPI == false) pythia.readString("PartonLevel:MPI = off");
  // Initialisation, p pbar @ 1.96 TeV
  pythia.readString("Beams:idB = -2212");
  pythia.readString("Beams:eCM = 1960.");
  pythia.init();
  // Histograms
  Hist dSigma1("1-jet cross-section (E_jet1 > 20 GeV)", 70, 0.0, 350.0);
  Hist dSigma2("2-jet cross-section (E_jet2 > 20 GeV)", 38, 0.0, 190.0);
  Hist dSigma3("3-jet cross-section (E_jet3 > 20 GeV)", 16, 0.0, 80.0);
  Hist dSigma4("4-jet cross-section (E_jet4 > 20 GeV)",  7, 0.0, 35.0);
  Hist *dSigmaHist[5] = { NULL, &dSigma1, &dSigma2, &dSigma3, &dSigma4 };
  double dSigmaBin[5] = { 0.0, 350.0 / 70.0, 190.0 / 38.0,
                          80.0 / 16.0, 35.0 / 7.0 };
  // Fastjet analysis - select algorithm and parameters
  double Rparam = 0.4;
  fastjet::Strategy               strategy = fastjet::Best;
  fastjet::RecombinationScheme    recombScheme = fastjet::E_scheme;
  fastjet::JetDefinition         *jetDef = NULL;
  jetDef = new fastjet::JetDefinition(fastjet::kt_algorithm, Rparam,
                                      recombScheme, strategy);
  // Fastjet input
  std::vector <fastjet::PseudoJet> fjInputs;
  // Statistics for later
  int nEventAccept25[5] = { 0, 0, 0, 0, 0 };
  int vetoCount[4] = { 0, 0, 0, 0 };
  const char *vetoStr[] = { "ET(elec)", "|eta(elec)|",
                            "ET(missing)", "deltaR(elec, jet)" };
  bool firstEvent = true;
  // Begin event loop. Generate event. Skip if error.
  for (int iEvent = 0; iEvent < nEvent; ++iEvent) {
    if (!pythia.next()) continue;
    // Need to find the electron from the W decay - cheat a bit here
    // and find it from the W in the event record
    int idxW = -1;
    for (int i = pythia.event.size() - 1; i > 0; i--) {
      if (pythia.event[i].idAbs() == 24) {
        idxW = i;
        break;
      }
    }
    if (idxW == -1) {
      cout << "Error: Could not find W" << endl;
      continue;
    }
    // Find the electron from the W decay
    int idxElec = idxW;
    while(true) {
      int daughter = pythia.event[idxElec].daughter1();
      if   (daughter == 0) break;
      else                 idxElec = daughter;
    }
    if (pythia.event[idxElec].idAbs() != 11 ||
       !pythia.event[idxElec].isFinal()) {
      cout << "Error: Found incorrect decay product of the W" << endl;
      continue;
    }
    // Electron cuts
    if (pythia.event[idxElec].pT() < 20.0) {
      vetoCount[0]++;
      continue;
    }
    if (abs(pythia.event[idxElec].eta()) > 1.1) {
      vetoCount[1]++;
      continue;
    }
    // Reset Fastjet input
    fjInputs.resize(0);
    // Keep track of missing ET
    Vec4 missingETvec;
    // Loop over event record to decide what to pass to FastJet
    for (int i = 0; i < pythia.event.size(); ++i) {
      // Final state only
      if (!pythia.event[i].isFinal())        continue;
      // No neutrinos
      if (pythia.event[i].idAbs() == 12 || pythia.event[i].idAbs() == 14 ||
          pythia.event[i].idAbs() == 16)     continue;
      // Only |eta| < 3.6
      if (fabs(pythia.event[i].eta()) > 3.6) continue;
      // Missing ET
      missingETvec += pythia.event[i].p();
      // Do not include the electron from the W decay
      if (i == idxElec)                      continue;
      // Store as input to Fastjet
      fjInputs.push_back( fastjet::PseudoJet( pythia.event[i].px(),
        pythia.event[i].py(), pythia.event[i].pz(), pythia.event[i].e() ) );
    }
    if (fjInputs.size() == 0) {
      cout << "Error: event with no final state particles" << endl;
      continue;
    }
    // Run Fastjet algorithm
    vector <fastjet::PseudoJet> inclusiveJets, sortedJets;
    fastjet::ClusterSequence clustSeq(fjInputs, *jetDef);
    // For the first event, print the FastJet details
    if (firstEvent) {
      cout << "Ran " << jetDef->description() << endl;
      cout << "Strategy adopted by FastJet was "
           << clustSeq.strategy_string() << endl << endl;
      firstEvent = false;
    }
    // Extract inclusive jets sorted by pT (note minimum pT of 20.0 GeV)
    inclusiveJets = clustSeq.inclusive_jets(20.0);
    sortedJets    = sorted_by_pt(inclusiveJets);
    // Missing ET cut
    double missingET = missingETvec.pT();
    if (missingET < 30.0) {
      vetoCount[2]++;
      continue;
    }
    // Keep track of jets with pT > 20/25 GeV
    int  jetCount20 = 0, jetCount25 = 0;
    // For the deltaR calculation below
    bool vetoEvent = false;
    fastjet::PseudoJet fjElec(pythia.event[idxElec].px(),
                              pythia.event[idxElec].py(),
                              pythia.event[idxElec].pz(),
                              pythia.event[idxElec].e());
    for (unsigned int i = 0; i < sortedJets.size(); i++) {
      // Only count jets that have |eta| < 2.0
      if (fabs(sortedJets[i].rap()) > 2.0) continue;
      // Check distance between W decay electron and jets
      if (fjElec.squared_distance(sortedJets[i]) < 0.52 * 0.52)
        { vetoEvent = true; break; }
      // Fill dSigma histograms and count jets with ET > 25.0
      if (sortedJets[i].perp() > 25.0)
        jetCount25++;
      if (jetCount20 <= 3)
        dSigmaHist[++jetCount20]->fill(sortedJets[i].perp());
    }
    if (vetoEvent) { vetoCount[3]++; continue; }
    if (jetCount25 > 4) jetCount25 = 4;
    for (int i = jetCount25; i >= 0; i--)
      nEventAccept25[i]++;
  // End of event loop.
  }
  // Statistics
  pythia.stat();
  // Output histograms
  double sigmapb = pythia.info.sigmaGen() * 1.0E9;
  for (int i = 1; i <= 4; i++)
    (*dSigmaHist[i]) = ((*dSigmaHist[i]) * sigmapb) / nEvent / dSigmaBin[i];
  cout << dSigma1 << dSigma2 << dSigma3 << dSigma4 << endl;
  // Output cross-sections
  cout << "Jet algorithm is kT" << endl;
  cout << "Multiparton interactions are switched "
       << ( (doMPI) ? "on" : "off" ) << endl;
  cout << endl << nEvent << " events generated. " << nEventAccept25[0]
       << " events passed cuts." << endl;
  cout << "Vetos:" << endl;
  for (int i = 0; i < 4; i++)
    cout << "  " << vetoStr[i] << " = " << vetoCount[i] << endl;
  cout << endl << "Inclusive cross-sections (pb):" << endl;
  for (int i = 0; i < 5; i++) {
    cout << scientific << setprecision(3)
         << "  " << i << "-jet - Pythia = "
         << ((double) nEventAccept25[i] / (double) nEvent) * sigmapb;
    cout << ", Experimental = " << expCrossSec[i];
    if (i != 0) {
      cout << scientific << setprecision(3)
           << ", Pythia ratio to " << i - 1 << "-jet = "
           << ((double) nEventAccept25[i] / (double) nEventAccept25[i - 1]);
      cout << scientific << setprecision(3)
           << ", Experimental ratio to " << i - 1 << "-jet = "
           << expCrossSec[i] / expCrossSec[i - 1];
    }
    cout << endl;
  }
  // Done.
  delete jetDef;
  return 0;
}

main72.cc


// main72.cc is a part of the PYTHIA event generator.
// Copyright (C) 2016 Torbjorn Sjostrand.
// PYTHIA is licenced under the GNU GPL version 2, see COPYING for details.
// Please respect the MCnet Guidelines, see GUIDELINES for details.
// This is a simple test program.
// It compares SlowJet, FJcore and FastJet, showing that they
// find the same jets.
#include "Pythia8/Pythia.h"
// The FastJet3.h header enables automatic initialisation of
// fastjet::PseudoJet objects from Pythia8 Particle and Vec4 objects,
// as well as advanced features such as access to (a copy of)
// the original Pythia 8 Particle directly from the PseudoJet,
// and fastjet selectors that make use of the Particle properties.
// See the extensive comments in the header file for further details
// and examples.
#include "Pythia8Plugins/FastJet3.h"
using namespace Pythia8;
int main() {
  // Number of events, generated and listed ones (for jets).
  int nEvent    = 1000;
  int nListJets = 3;
  // Select common parameters for SlowJet and FastJet analyses.
  int    power   = -1;     // -1 = anti-kT; 0 = C/A; 1 = kT.
  double R       = 0.7;    // Jet size.
  double pTMin   = 5.0;    // Min jet pT.
  double etaMax  = 5.0;    // Pseudorapidity range of detector.
  int    select  = 2;      // Which particles are included?
  int    massSet = 2;      // Which mass are they assumed to have?
  // Generator. Shorthand for event.
  Pythia pythia;
  Event& event = pythia.event;
  // Process selection.
  pythia.readString("HardQCD:all = on");
  pythia.readString("PhaseSpace:pTHatMin = 200.");
  // No event record printout.
  pythia.readString("Next:numberShowInfo = 0");
  pythia.readString("Next:numberShowProcess = 0");
  pythia.readString("Next:numberShowEvent = 0");
  // LHC initialization.
  pythia.readString("Beams:eCM = 14000.");
  pythia.init();
  // Set up SlowJet jet finder in native mode.
  SlowJet slowJet( power, R, pTMin, etaMax, select, massSet, 0, false);
  // Set up SlowJet jet finder as a wrapper to the fjcore package.
  // Note that this is now the default SlowJet constructor choice.
  SlowJet fjCore( power, R, pTMin, etaMax, select, massSet, 0, true);
  // Set up FastJet jet finder.
  //   one can use either explicitly use antikt, cambridge, etc., or
  //   just use genkt_algorithm with specification of power
  //fastjet::JetAlgorithm algorithm;
  //if (power == -1)      algorithm = fastjet::antikt_algorithm;
  //if (power ==  0)      algorithm = fastjet::cambridge_algorithm;
  //if (power ==  1)      algorithm = fastjet::kt_algorithm;
  //fastjet::JetDefinition jetDef(algorithm, R);
  // there's no need for a pointer to the jetDef (it's a fairly small object)
  fastjet::JetDefinition jetDef(fastjet::genkt_algorithm, R, power);
  std::vector <fastjet::PseudoJet> fjInputs;
  // Histograms.
  Hist nJetsS("number of jets (SlowJet)", 100, -0.5, 99.5);
  Hist nJetsC("number of jets, FJcore - SlowJet ", 99, -49.5, 49.5);
  Hist nJetsF("number of jets, FastJet - SlowJet", 99, -49.5, 49.5);
  Hist pTjetsS("pT for jets (SlowJet)", 100, 0., 500.);
  Hist pTjetsC("pT for jets, FJcore - SlowJet ", 100, -10., 10.);
  Hist pTjetsF("pT for jets, FastJet - SlowJet", 100, -10., 10.);
  Hist etaJetsS("eta for jets (SlowJet)", 100, -5., 5.);
  Hist phiJetsS("phi for jets (SlowJet)", 100, -M_PI, M_PI);
  Hist RdistC("R distance FJcore to SlowJet ", 100, 0., 1.);
  Hist RdistF("R distance FastJet to SlowJet", 100, 0., 1.);
  Hist distJets("R distance between jets", 100, 0., 10.);
  Hist pTdiff("pT difference between consecutive jets", 100, -100., 400.);
  Hist nAna("multiplicity of analyzed event", 100, -0.5, 999.5);
  Hist tGen("generation time as fn of multiplicity", 100, -0.5, 999.5);
  Hist tSlow("SlowJet time as fn of multiplicity", 100, -0.5, 999.5);
  Hist tCore("FJcore time as fn of multiplicity ", 100, -0.5, 999.5);
  Hist tFast("FastJet time as fn of multiplicity", 100, -0.5, 999.5);
  Hist tSlowGen("SlowJet/generation time as fn of multiplicity",
    100, -0.5, 999.5);
  Hist tCoreGen("FJcore/generation time as fn of multiplicity",
    100, -0.5, 999.5);
  Hist tFastGen("FastJet/generation time as fn of multiplicity",
    100, -0.5, 999.5);
  Hist tFastCore("FastJet/FJcore time as fn of multiplicity",
    100, -0.5, 999.5);
  // Begin event loop. Generate event. Skip if error.
  for (int iEvent = 0; iEvent < nEvent; ++iEvent) {
    clock_t befGen = clock();
    if (!pythia.next()) continue;
    clock_t aftGen = clock();
    // Begin SlowJet analysis of jet properties. List first few.
    clock_t befSlow = clock();
    slowJet.analyze( pythia.event );
    clock_t aftSlow = clock();
    if (iEvent < nListJets) slowJet.list();
    // Fill inclusive SlowJet jet distributions.
    int nSlow = slowJet.sizeJet();
    nJetsS.fill( nSlow );
    for (int i = 0; i < nSlow; ++i) {
      pTjetsS.fill( slowJet.pT(i) );
      etaJetsS.fill( slowJet.y(i) );
      phiJetsS.fill( slowJet.phi(i) );
    }
    // Fill distance between SlowJet jets.
    for (int i = 0; i < nSlow - 1; ++i)
    for (int j = i + 1; j < nSlow; ++j) {
      double dY = slowJet.y(i)  - slowJet.y(j);
      double dPhi = abs( slowJet.phi(i) - slowJet.phi(j) );
      if (dPhi > M_PI) dPhi = 2. * M_PI - dPhi;
      double dR = sqrt( pow2(dY) + pow2(dPhi) );
      distJets.fill( dR );
    }
    // Fill pT-difference between SlowJet jets (to check ordering of list).
    for (int i = 1; i < nSlow; ++i)
      pTdiff.fill( slowJet.pT(i-1)- slowJet.pT(i) );
    // Begin FJcore analysis of jet properties. List first few.
    clock_t befCore = clock();
    fjCore.analyze( pythia.event );
    clock_t aftCore = clock();
    if (iEvent < nListJets) fjCore.list();
    // Fill distribution of fjCore jets relative to SlowJet ones.
    int nCore = fjCore.sizeJet();
    nJetsC.fill( nCore - nSlow);
    if (nCore == nSlow) {
      for (int i = 0; i < nCore; ++i) {
        pTjetsC.fill( fjCore.pT(i) - slowJet.pT(i) );
        double dist2 = pow2( fjCore.y(i) - slowJet.y(i))
          + pow2( fjCore.phi(i) - slowJet.phi(i) );
        RdistC.fill( sqrt(dist2) );
      }
    }
    // Begin FastJet analysis: extract particles from event record.
    clock_t befFast = clock();
    fjInputs.resize(0);
    Vec4   pTemp;
    double mTemp;
    int nAnalyze = 0;
    for (int i = 0; i < event.size(); ++i) if (event[i].isFinal()) {
      // Require visible/charged particles inside detector.
      if      (select > 2 &&  event[i].isNeutral() ) continue;
      else if (select == 2 && !event[i].isVisible() ) continue;
      if (etaMax < 20. && abs(event[i].eta()) > etaMax) continue;
      // Create a PseudoJet from the complete Pythia particle.
      fastjet::PseudoJet particleTemp = event[i];
      // Optionally modify mass and energy.
      pTemp = event[i].p();
      mTemp = event[i].m();
      if (massSet < 2) {
        mTemp = (massSet == 0 || event[i].id() == 22) ? 0. : 0.13957;
        pTemp.e( sqrt(pTemp.pAbs2() + mTemp*mTemp) );
        particleTemp.reset_momentum( pTemp.px(), pTemp.py(),
           pTemp.pz(), pTemp.e() );
      }
      // Store acceptable particles as input to Fastjet.
      // Conversion to PseudoJet is performed automatically
      // with the help of the code in FastJet3.h.
      fjInputs.push_back( particleTemp);
      ++nAnalyze;
    }
    // Run Fastjet algorithm and sort jets in pT order.
    vector <fastjet::PseudoJet> inclusiveJets, sortedJets;
    fastjet::ClusterSequence clustSeq(fjInputs, jetDef);
    inclusiveJets = clustSeq.inclusive_jets(pTMin);
    sortedJets    = sorted_by_pt(inclusiveJets);
    clock_t aftFast = clock();
    // List first few FastJet jets and some info about them.
    // Note: the final few columns are illustrative of what information
    // can be extracted, but does not exhaust the possibilities.
    if (iEvent < nListJets) {
      cout << "\n --------  FastJet jets, p = " << setw(2) << power
           << "  --------------------------------------------------\n\n "
           << "  i         pT        y      phi  mult chgmult photons"
           << "      hardest  pT in neutral " << endl
           << "                                                       "
           << "  constituent        hadrons " << endl;
      for (int i = 0; i < int(sortedJets.size()); ++i) {
        vector<fastjet::PseudoJet> constituents
          = sortedJets[i].constituents();
        fastjet::PseudoJet hardest
          = fastjet::SelectorNHardest(1)(constituents)[0];
        vector<fastjet::PseudoJet> neutral_hadrons
          = ( fastjet::SelectorIsHadron()
           && fastjet::SelectorIsNeutral())(constituents);
        double neutral_hadrons_pt = join(neutral_hadrons).perp();
        cout << setw(4) << i << fixed << setprecision(3) << setw(11)
             << sortedJets[i].perp() << setw(9)  << sortedJets[i].rap()
             << setw(9) << sortedJets[i].phi_std()
             << setw(6) << constituents.size()
             << setw(8) << fastjet::SelectorIsCharged().count(constituents)
             << setw(8) << fastjet::SelectorId(22).count(constituents)
             << setw(13) << hardest.user_info<Particle>().name()
             << "     " << setw(10) << neutral_hadrons_pt << endl;
      }
      cout << "\n --------  End FastJet Listing  ------------------"
           << "---------------------------------" << endl;
    }
    // Fill distribution of FastJet jets relative to SlowJet ones.
    int nFast = sortedJets.size();
    nJetsF.fill( nFast - nSlow);
    if (nFast == nSlow) {
      for (int i = 0; i < nFast; ++i) {
        pTjetsF.fill( sortedJets[i].perp() - slowJet.pT(i) );
        double dist2 = pow2( sortedJets[i].rap() - slowJet.y(i))
          + pow2( sortedJets[i].phi_std() - slowJet.phi(i));
        RdistF.fill( sqrt(dist2) );
      }
    }
    // Comparison of time consumption by analyzed multiplicity.
    nAna.fill( nAnalyze);
    tGen.fill( nAnalyze, aftGen - befGen);
    tSlow.fill( nAnalyze, aftSlow - befSlow);
    tCore.fill( nAnalyze, aftCore - befCore);
    tFast.fill( nAnalyze, aftFast - befFast);
  // End of event loop.
  }
  // Statistics. Histograms.
  pythia.stat();
  tSlowGen  = tSlow / tGen;
  tCoreGen  = tCore / tGen;
  tFastGen  = tFast / tGen;
  tFastCore = tFast / tCore;
  tGen     /= nAna;
  tSlow    /= nAna;
  tCore    /= nAna;
  tFast    /= nAna;
  cout << nJetsS << nJetsC << nJetsF << pTjetsS << pTjetsC << pTjetsF
       << etaJetsS << phiJetsS << RdistC << RdistF << distJets << pTdiff
       << nAna << tGen << tSlow << tCore << tFast << tSlowGen << tCoreGen
       << tFastGen << tFastCore;
  // Done.
  return 0;
}

main73.cc


// main73.cc is a part of the PYTHIA event generator.
// Copyright (C) 2016 Torbjorn Sjostrand.
// PYTHIA is licenced under the GNU GPL version 2, see COPYING for details.
// Please respect the MCnet Guidelines, see GUIDELINES for details.
// Example how to compare "parton-level" and "hadron-level" properties.
#include "Pythia8/Pythia.h"
using namespace Pythia8;
//--------------------------------------------------------------------------
// Generic routine to extract the particles that existed right before
// the hadronization machinery was invoked.
void getPartonLevelEvent( Event& event, Event& partonLevelEvent) {
  // Copy over all particles that existed right before hadronization.
  partonLevelEvent.reset();
  for (int i = 0; i < event.size(); ++i)
  if (event[i].isFinalPartonLevel()) {
    int iNew = partonLevelEvent.append( event[i] );
    // Set copied properties more appropriately: positive status,
    // original location as "mother", and with no daughters.
    partonLevelEvent[iNew].statusPos();
    partonLevelEvent[iNew].mothers( i, i);
    partonLevelEvent[iNew].daughters( 0, 0);
  }
}
//--------------------------------------------------------------------------
// Generic routine to extract the particles that exist after the
// hadronization machinery. Normally not needed, since SlowJet
// contains the standard possibilities preprogrammed, but this
// method illustrates further discrimination.
void getHadronLevelEvent( Event& event, Event& hadronLevelEvent) {
  // Iterate over all final particles.
  hadronLevelEvent.reset();
  for (int i = 0; i < event.size(); ++i) {
    bool accept = false;
    if (event[i].isFinal()) accept = true;
    // Example 1: reject neutrinos (standard option).
    int idAbs = event[i].idAbs();
    if (idAbs == 12 || idAbs == 14 || idAbs == 16) accept = false;
    // Example 2: reject particles with pT < 0.1 GeV (new possibility).
    if (event[i].pT() < 0.1) accept = false;
    // Copy over accepted particles, with original location as "mother".
    if (accept) {
      int iNew = hadronLevelEvent.append( event[i] );
      hadronLevelEvent[iNew].mothers( i, i);
    }
  }
}
//--------------------------------------------------------------------------
int main() {
  // Number of events, generated and listed ones.
  int nEvent    = 1000;
  int nListEvts = 1;
  int nListJets = 5;
  // Generator. LHC process and output selection. Initialization.
  Pythia pythia;
  pythia.readString("Beams:eCM = 13000.");
  pythia.readString("HardQCD:all = on");
  pythia.readString("PhaseSpace:pTHatMin = 200.");
  pythia.readString("Next:numberShowInfo = 0");
  pythia.readString("Next:numberShowProcess = 0");
  pythia.readString("Next:numberShowEvent = 0");
  pythia.init();
  // Parton and Hadron Level event records. Remeber to initalize.
  Event partonLevelEvent;
  partonLevelEvent.init("Parton Level event record", &pythia.particleData);
  Event hadronLevelEvent;
  hadronLevelEvent.init("Hadron Level event record", &pythia.particleData);
  //  Parameters for the jet finders. Need select = 1 to catch partons.
  double radius   = 0.5;
  double pTjetMin = 10.;
  double etaMax   = 4.;
  int select      = 1;
  // Set up anti-kT clustering, comparing parton and hadron levels.
  SlowJet antiKTpartons( -1, radius, pTjetMin, etaMax, select);
  SlowJet antiKThadrons( -1, radius, pTjetMin, etaMax, select);
  // Histograms.
  Hist nJetsP("number of jets, parton level", 50, -0.5, 49.5);
  Hist nJetsH("number of jets, hadron level", 50, -0.5, 49.5);
  Hist pTallP("pT for jets, parton level", 100, 0., 500.);
  Hist pTallH("pT for jets, hadron level", 100, 0., 500.);
  Hist pThardP("pT for hardest jet, parton level", 100, 0., 500.);
  Hist pThardH("pT for hardest jet, hadron level", 100, 0., 500.);
  Hist pTdiff("pT for hardest jet, hadron - parton", 100, -100., 100.);
  // Begin event loop. Generate event. Skip if error.
  for (int iEvent = 0; iEvent < nEvent; ++iEvent) {
    if (!pythia.next()) continue;
    // Construct parton and hadron level event.
    getPartonLevelEvent( pythia.event, partonLevelEvent);
    getHadronLevelEvent( pythia.event, hadronLevelEvent);
    // List first few events.
    if (iEvent < nListEvts) {
      pythia.event.list();
      partonLevelEvent.list();
      hadronLevelEvent.list();
    }
    // Analyze jet properties and list first few analyses.
    antiKTpartons.analyze( partonLevelEvent );
    antiKThadrons.analyze( hadronLevelEvent );
    if (iEvent < nListJets) {
      antiKTpartons.list();
      antiKThadrons.list();
    }
    // Fill jet properties distributions.
    nJetsP.fill( antiKTpartons.sizeJet() );
    nJetsH.fill( antiKThadrons.sizeJet() );
    for (int i = 0; i < antiKTpartons.sizeJet(); ++i)
      pTallP.fill( antiKTpartons.pT(i) );
    for (int i = 0; i < antiKThadrons.sizeJet(); ++i)
      pTallH.fill( antiKThadrons.pT(i) );
    if ( antiKTpartons.sizeJet() > 0 && antiKThadrons.sizeJet() > 0) {
      pThardP.fill( antiKTpartons.pT(0) );
      pThardH.fill( antiKThadrons.pT(0) );
      pTdiff.fill( antiKThadrons.pT(0) - antiKTpartons.pT(0) );
    }
  // End of event loop. Statistics. Histograms.
  }
  pythia.stat();
  cout << nJetsP << nJetsH << pTallP << pTallH
       <<  pThardP << pThardH << pTdiff;
  // Done.
  return 0;
}

main80.cc


// main80.cc is a part of the PYTHIA event generator.
// Copyright (C) 2016 Torbjorn Sjostrand.
// PYTHIA is licenced under the GNU GPL version 2, see COPYING for details.
// Please respect the MCnet Guidelines, see GUIDELINES for details.
// This program is written by Stefan Prestel.
// It illustrates how to do CKKW-L merging,
// see the Matrix Element Merging page in the online manual.
#include "Pythia8/Pythia.h"
using namespace Pythia8;
int main() {
  // Generator. Input parameters.
  Pythia pythia;
  pythia.readFile("main80.cmnd");
  // Extract number of events and max number of jets in merging.
  int nEvent = pythia.mode("Main:numberOfEvents");
  int nMerge = pythia.mode("Merging:nJetMax");
  // Histograms combined over all jet multiplicities.
  Hist pTWsum("pT of W, summed over all subruns", 100, 0., 200.);
  // Merged total cross section, summed over subruns.
  double sigmaTotal = 0.;
  // Loop over subruns with varying number of jets.
  for (int iMerge = 0; iMerge <= nMerge; ++iMerge) {
    double sigmaSample = 0.;
    // Read in name of LHE file for current subrun and initialize.
    pythia.readFile("main80.cmnd", iMerge);
    pythia.init();
    // Histograms for current jet multiplicity.
    Hist weightNow("event weights, current subrun", 100, 0., 2.5);
    Hist pTWnow("pT of W, current subrun", 100, 0., 200.);
    // Start event generation loop.
    for (int iEvent = 0; iEvent < nEvent; ++iEvent) {
      // Generate next event. Break out of event loop if at end of LHE file.
      if ( !pythia.next() ) {
        if ( pythia.info.atEndOfFile() ) break;
        else continue;
      }
      // Get CKKWL weight of current event. Histogram and accumulate it.
      double weight = pythia.info.mergingWeight();
      weightNow.fill( weight);
      sigmaSample += weight;
      // Find the final copy of the W+, which is after the full shower.
      int iW = 0;
      for (int i = 1; i < pythia.event.size(); ++i)
        if (pythia.event[i].id() == 24) iW = i;
      // Fill the pT of the W histogram, with CKKWL weight.
      double pTW = pythia.event[iW].pT();
      pTWnow.fill( pTW, weight);
    // End of event loop.
    }
    // Normalize pTW histogram, convert mb -> pb, and correct for bin width.
    pTWnow *= 1e9 * pythia.info.sigmaGen() / (2. * pythia.info.nAccepted());
    // Print cross section and histograms for current subrun.
    pythia.stat();
    cout << weightNow << pTWnow;
    // Sum up merged cross section of current run.
    sigmaSample *= pythia.info.sigmaGen() / double(pythia.info.nAccepted());
    sigmaTotal  += sigmaSample;
    // Add current histogram to the combined one. End of subrun loop.
    pTWsum += pTWnow;
  }
  // Print final histograms and info on merged cross section..
  cout << pTWsum;
  cout << "\n\n The inclusive cross section after merging is: "
       << scientific << setprecision(4) << sigmaTotal << " mb " << endl;
  // Done
  return 0;
}

main81.cc


// main81.cc is a part of the PYTHIA event generator.
// Copyright (C) 2016 Torbjorn Sjostrand.
// PYTHIA is licenced under the GNU GPL version 2, see COPYING for details.
// Please respect the MCnet Guidelines, see GUIDELINES for details.
// This program is written by Stefan Prestel.
// It illustrates how to do CKKW-L merging, see the Matrix Element
// Merging page in the online manual. An example command is
//     ./main81 main81.cmnd w+_production_lhc_0.lhe histout81.dat
// where main81.cmnd supplies the commands, w+_production_lhc_0.lhe
// provides the input LHE events, and histout81.dat is the output
// file. This example requires FastJet.
#include "Pythia8/Pythia.h"
using namespace Pythia8;
// Functions for histogramming
#include "fastjet/PseudoJet.hh"
#include "fastjet/ClusterSequence.hh"
#include "fastjet/CDFMidPointPlugin.hh"
#include "fastjet/CDFJetCluPlugin.hh"
#include "fastjet/D0RunIIConePlugin.hh"
//==========================================================================
// Find the Durham kT separation of the clustering from
// nJetMin --> nJetMin-1 jets in the input event
double pTfirstJet( const Event& event, int nJetMin, double Rparam) {
  double yPartonMax = 4.;
  // Fastjet analysis - select algorithm and parameters
  fastjet::Strategy               strategy = fastjet::Best;
  fastjet::RecombinationScheme    recombScheme = fastjet::E_scheme;
  fastjet::JetDefinition         *jetDef = NULL;
  // For hadronic collision, use hadronic Durham kT measure
  if(event[3].colType() != 0 || event[4].colType() != 0)
    jetDef = new fastjet::JetDefinition(fastjet::kt_algorithm, Rparam,
                                      recombScheme, strategy);
  // For e+e- collision, use e+e- Durham kT measure
  else
    jetDef = new fastjet::JetDefinition(fastjet::ee_kt_algorithm,
                                      recombScheme, strategy);
  // Fastjet input
  std::vector <fastjet::PseudoJet> fjInputs;
  // Reset Fastjet input
  fjInputs.resize(0);
  // Loop over event record to decide what to pass to FastJet
  for (int i = 0; i < event.size(); ++i) {
    // (Final state && coloured+photons) only!
    if ( !event[i].isFinal()
      || event[i].isLepton()
      || event[i].id() == 23
      || abs(event[i].id()) == 24
      || abs(event[i].y()) > yPartonMax)
      continue;
    // Store as input to Fastjet
    fjInputs.push_back( fastjet::PseudoJet (event[i].px(),
            event[i].py(), event[i].pz(),event[i].e() ) );
  }
  // Do nothing for empty input
  if (int(fjInputs.size()) == 0) {
    delete jetDef;
    return 0.0;
  }
  // Run Fastjet algorithm
  fastjet::ClusterSequence clustSeq(fjInputs, *jetDef);
  // Extract kT of first clustering
  double pTFirst = sqrt(clustSeq.exclusive_dmerge_max(nJetMin-1));
  delete jetDef;
  // Return kT
  return pTFirst;
}
//==========================================================================
// Example main programm to illustrate merging
int main( int argc, char* argv[] ){
  // Check that correct number of command-line arguments
  if (argc != 4) {
    cerr << " Unexpected number of command-line arguments ("<<argc<<"). \n"
         << " You are expected to provide the arguments" << endl
         << " 1. Input file for settings" << endl
         << " 2. Full name of the input LHE file (with path)" << endl
         << " 3. Path for output histogram files" << endl
         << " Program stopped. " << endl;
    return 1;
  }
  Pythia pythia;
  // Input parameters:
  //  1. Input file for settings
  //  2. Path to input LHE file
  //  3. Output histogram path
  pythia.readFile(argv[1]);
  string iPath = string(argv[2]);
  string oPath = string(argv[3]);
  // Number of events
  int nEvent = pythia.mode("Main:numberOfEvents");
  // For ISR regularisation off
  pythia.settings.forceParm("SpaceShower:pT0Ref",0.);
  // Declare histograms
  Hist histPTFirst("pT of first jet",100,0.,100.);
  Hist histPTSecond("pT of second jet",100,0.,100.);
  Hist histPTThird("pT of third jet",100,0.,100.);
  // Read in ME configurations
  pythia.readString("Beams:frameType = 4");
  pythia.readString("Beams:LHEF = " + iPath);
  pythia.init();
  // Start generation loop
  for( int iEvent=0; iEvent<nEvent; ++iEvent ){
    // Generate next event
    if( ! pythia.next()) continue;
    // Get CKKWL weight of current event
    double weight = pythia.info.mergingWeight();
    // Fill bins with CKKWL weight
    // Functions use fastjet to get first / second jet
    double pTfirst = pTfirstJet(pythia.event,1, 0.4);
    double pTsecnd = pTfirstJet(pythia.event,2, 0.4);
    double pTthird = pTfirstJet(pythia.event,3, 0.4);
    histPTFirst.fill( pTfirst, weight);
    histPTSecond.fill( pTsecnd, weight);
    histPTThird.fill( pTthird, weight);
    if(iEvent%1000 == 0) cout << iEvent << endl;
  } // end loop over events to generate
  // print cross section, errors
  pythia.stat();
  // Normalise histograms
  double norm = 1.
              * pythia.info.sigmaGen()
              * 1./ double(nEvent);
  histPTFirst           *= norm;
  histPTSecond          *= norm;
  histPTThird           *= norm;
  // Get the number of jets in the LHE file from the file name
  string jetsInLHEF = iPath.substr(iPath.size()-5, iPath.size());
  jetsInLHEF = jetsInLHEF.substr(0, jetsInLHEF.size()-4);
  // Write histograms to dat file. Use "jetsInLHEF" to label the files
  // Once all the samples up to the maximal desired jet multiplicity from the
  // matrix element are run, add all histograms to produce a
  // matrix-element-merged prediction
  ofstream write;
  stringstream suffix;
  suffix << jetsInLHEF << "_wv.dat";
  // Write histograms to file
  write.open( (char*)(oPath + "PTjet1_" + suffix.str()).c_str());
  histPTFirst.table(write);
  write.close();
  write.open( (char*)(oPath + "PTjet2_" + suffix.str()).c_str());
  histPTSecond.table(write);
  write.close();
  write.open( (char*)(oPath + "PTjet3_" + suffix.str()).c_str());
  histPTThird.table(write);
  write.close();
  // Done
  return 0;
}

main82.cc


// main82.cc is a part of the PYTHIA event generator.
// Copyright (C) 2016 Torbjorn Sjostrand.
// PYTHIA is licenced under the GNU GPL version 2, see COPYING for details.
// Please respect the MCnet Guidelines, see GUIDELINES for details.
// This program is written by Stefan Prestel.
// It illustrates how to do CKKW-L merging, see the Matrix Element
// Merging page in the online manual. An example command is
//     ./main82 main82.cmnd w+_production_lhc_0.lhe histout82.dat
// where main82.cmnd supplies the commands, w+_production_lhc_0.lhe
// provides the input LHE events, and histout82.dat is the output
// file. This example requires FastJet.
#include "Pythia8/Pythia.h"
using namespace Pythia8;
// Functions for histogramming
#include "fastjet/PseudoJet.hh"
#include "fastjet/ClusterSequence.hh"
#include "fastjet/CDFMidPointPlugin.hh"
#include "fastjet/CDFJetCluPlugin.hh"
#include "fastjet/D0RunIIConePlugin.hh"
//==========================================================================
// Find the Durham kT separation of the clustering from
// nJetMin --> nJetMin-1 jets in te input event
double pTfirstJet( const Event& event, int nJetMin, double Rparam) {
  double yPartonMax = 4.;
  // Fastjet analysis - select algorithm and parameters
  fastjet::Strategy               strategy = fastjet::Best;
  fastjet::RecombinationScheme    recombScheme = fastjet::E_scheme;
  fastjet::JetDefinition         *jetDef = NULL;
  // For hadronic collision, use hadronic Durham kT measure
  if(event[3].colType() != 0 || event[4].colType() != 0)
    jetDef = new fastjet::JetDefinition(fastjet::kt_algorithm, Rparam,
                                      recombScheme, strategy);
  // For e+e- collision, use e+e- Durham kT measure
  else
    jetDef = new fastjet::JetDefinition(fastjet::ee_kt_algorithm,
                                      recombScheme, strategy);
  // Fastjet input
  std::vector <fastjet::PseudoJet> fjInputs;
  // Reset Fastjet input
  fjInputs.resize(0);
  // Loop over event record to decide what to pass to FastJet
  for (int i = 0; i < event.size(); ++i) {
    // (Final state && coloured+photons) only!
    if ( !event[i].isFinal()
      || event[i].isLepton()
      || event[i].id() == 23
      || abs(event[i].id()) == 24
      || abs(event[i].y()) > yPartonMax)
      continue;
    // Store as input to Fastjet
    fjInputs.push_back( fastjet::PseudoJet (event[i].px(),
            event[i].py(), event[i].pz(),event[i].e() ) );
  }
  // Do nothing for empty input
  if (int(fjInputs.size()) == 0) {
    delete jetDef;
    return 0.0;
  }
  // Run Fastjet algorithm
  fastjet::ClusterSequence clustSeq(fjInputs, *jetDef);
  // Extract kT of first clustering
  double pTFirst = sqrt(clustSeq.exclusive_dmerge_max(nJetMin-1));
  delete jetDef;
  // Return kT
  return pTFirst;
}
//==========================================================================
// Class for user interaction with the merging
class MyMergingHooks : public MergingHooks {
private:
public:
  // Default constructor
  MyMergingHooks();
  // Destructor
  ~MyMergingHooks();
  // Functional definition of the merging scale
  virtual double tmsDefinition( const Event& event);
  // Helper function for tms definition
  double myKTdurham(const Particle& RadAfterBranch,
           const Particle& EmtAfterBranch, int Type, double D );
};
//--------------------------------------------------------------------------
// Constructor
MyMergingHooks::MyMergingHooks() {}
// Destructor
MyMergingHooks::~MyMergingHooks() {}
//--------------------------------------------------------------------------
// Definition of the merging scale
double MyMergingHooks::tmsDefinition( const Event& event){
  // Cut only on QCD partons!
  // Count particle types
  int nFinalColoured = 0;
  int nFinalNow =0;
  for( int i=0; i < event.size(); ++i) {
    if(event[i].isFinal()){
      if(event[i].id() != 23 && abs(event[i].id()) != 24)
        nFinalNow++;
      if( event[i].colType() != 0)
        nFinalColoured++;
    }
  }
  // Use MergingHooks in-built functions to get information on the hard process
  int nLeptons = nHardOutLeptons();
  int nQuarks  = nHardOutPartons();
  int nResNow  = nResInCurrent();
  // Check if photons, electrons etc. have been produced. If so, do not veto
  if(nFinalNow - ( (nLeptons+nQuarks)/2 - nResNow)*2 != nFinalColoured){
    // Sometimes, Pythia detaches the decay products even though no
    // resonance was put into the LHE file, to catch this, add another
    // if statement
    if(nFinalNow != nFinalColoured) return 0.;
  }
  // Check that one parton has been produced. If not (e.g. in MPI), do not veto
  int nMPI = infoPtr->nMPI();
  if(nMPI > 1) return 0.;
  // Declare kT algorithm parameters
  double Dparam = 0.4;
  int kTtype = -1;
  // Declare final parton vector
  vector <int> FinalPartPos;
  FinalPartPos.clear();
  // Search event record for final state partons
  for (int i=0; i < event.size(); ++i)
    if(event[i].isFinal() && event[i].colType() != 0)
      FinalPartPos.push_back(i);
  // Find minimal Durham kT in event, using own function: Check
  // definition of separation
  int type = (event[3].colType() == 0 && event[4].colType() == 0) ? 1 : kTtype;
  // Find minimal kT
  double ktmin = event[0].e();
  for(int i=0; i < int(FinalPartPos.size()); ++i){
    double kt12  = ktmin;
    // Compute separation to the beam axis for hadronic collisions
    if(type == -1 || type == -2) {
      double temp = event[FinalPartPos[i]].pT();
      kt12 = min(kt12, temp);
    }
    // Compute separation to other final state jets
    for(int j=i+1; j < int(FinalPartPos.size()); ++j) {
      double temp = kTdurham( event[FinalPartPos[i]], event[FinalPartPos[j]],
                      type, Dparam);
      kt12 = min(kt12, temp);
    }
    // Keep the minimal Durham separation
    ktmin = min(ktmin,kt12);
  }
  // Return minimal Durham kT
  return ktmin;
}
//--------------------------------------------------------------------------
// Function to compute durham y separation from Particle input
double MyMergingHooks::myKTdurham(const Particle& RadAfterBranch,
  const Particle& EmtAfterBranch, int Type, double D ){
  // Declare return variable
  double ktdur;
  // Save 4-momenta of final state particles
  Vec4 jet1 = RadAfterBranch.p();
  Vec4 jet2 = EmtAfterBranch.p();
  if( Type == 1) {
    // Get angle between jets for e+e- collisions, make sure that
    // -1 <= cos(theta) <= 1
    double costh;
    if (jet1.pAbs()*jet2.pAbs() <=0.) costh = 1.;
    else {
      costh = costheta(jet1,jet2);
    }
    // Calculate kt durham separation between jets for e+e- collisions
    ktdur = 2.0*min( pow(jet1.e(),2) , (pow(jet2.e(),2)) )*(1.0 - costh);
  } else if( Type == -1 ){
    // Get delta_eta and cosh(Delta_eta) for hadronic collisions
    double eta1 = 0.5*log( (jet1.e() + jet1.pz()) / (jet1.e() - jet1.pz()) );
    double eta2 = 0.5*log( (jet2.e() + jet2.pz()) / (jet2.e() - jet2.pz()) );
    // Get delta_phi and cos(Delta_phi) for hadronic collisions
    double pt1 = sqrt( pow(jet1.px(),2) + pow(jet1.py(),2) );
    double pt2 = sqrt( pow(jet2.px(),2) + pow(jet2.py(),2) );
    double cosdPhi = ( jet1.px()*jet2.px() + jet1.py()*jet2.py() ) / (pt1*pt2);
    double dPhi = acos( cosdPhi );
    // Calculate kT durham like fastjet
     ktdur = min( pow(pt1,2),pow(pt2,2) )
           * ( pow(eta1-eta2,2) + pow(dPhi,2) ) / pow(D,2);
  } else if( Type == -2 ){
    // Get delta_eta and cosh(Delta_eta) for hadronic collisions
    double eta1 = 0.5*log( (jet1.e() + jet1.pz()) / (jet1.e() - jet1.pz()) );
    double eta2 = 0.5*log( (jet2.e() + jet2.pz()) / (jet2.e() - jet2.pz()) );
     double coshdEta = cosh( eta1 - eta2 );
    // Get delta_phi and cos(Delta_phi) for hadronic collisions
    double pt1 = sqrt( pow(jet1.px(),2) + pow(jet1.py(),2) );
    double pt2 = sqrt( pow(jet2.px(),2) + pow(jet2.py(),2) );
    double cosdPhi = ( jet1.px()*jet2.px() + jet1.py()*jet2.py() ) / (pt1*pt2);
    // Calculate kT durham separation "SHERPA-like"
     ktdur = 2.0*min( pow(pt1,2),pow(pt2,2) )
           * ( coshdEta - cosdPhi ) / pow(D,2);
  } else {
    ktdur = 0.0;
  }
  // Return kT
  return sqrt(ktdur);
}
//==========================================================================
// Example main programm to illustrate merging
int main( int argc, char* argv[] ){
  // Check that correct number of command-line arguments
  if (argc != 4) {
    cerr << " Unexpected number of command-line arguments. \n You are"
         << " expected to provide the arguments \n"
         << " 1. Input file for settings \n"
         << " 2. Full name of the input LHE file (with path) \n"
         << " 3. Path for output histogram files \n"
         << " Program stopped. " << endl;
    return 1;
  }
  Pythia pythia;
  // Input parameters:
  //  1. Input file for settings
  //  2. Path to input LHE file
  //  3. Output histogram path
  pythia.readFile(argv[1]);
  string iPath = string(argv[2]);
  string oPath = string(argv[3]);
  // Number of events
  int nEvent = pythia.mode("Main:numberOfEvents");
  // Construct user inut for merging
  MergingHooks* myMergingHooks = new MyMergingHooks();
  pythia.setMergingHooksPtr( myMergingHooks );
  // For ISR regularisation off
  pythia.settings.forceParm("SpaceShower:pT0Ref",0.);
  // Declare histograms
  Hist histPTFirst("pT of first jet",100,0.,100.);
  Hist histPTSecond("pT of second jet",100,0.,100.);
  // Read in ME configurations
  pythia.readString("Beams:frameType = 4");
  pythia.readString("Beams:LHEF = " + iPath);
  pythia.init();
  // Start generation loop
  for( int iEvent=0; iEvent<nEvent; ++iEvent ){
    // Generate next event
    if( ! pythia.next()) continue;
    // Get CKKWL weight of current event
    double weight = pythia.info.mergingWeight();
    // Fill bins with CKKWL weight
    double pTfirst = pTfirstJet(pythia.event,1, 0.4);
    double pTsecnd = pTfirstJet(pythia.event,2, 0.4);
    histPTFirst.fill( pTfirst, weight);
    histPTSecond.fill( pTsecnd, weight);
    if(iEvent%1000 == 0) cout << iEvent << endl;
  } // end loop over events to generate
  // print cross section, errors
  pythia.stat();
  // Normalise histograms
  double norm = 1.
              * pythia.info.sigmaGen()
              * 1./ double(nEvent);
  histPTFirst           *= norm;
  histPTSecond          *= norm;
  // Get the number of jets in the LHE file from the file name
  string jetsInLHEF = iPath.substr(iPath.size()-5, iPath.size());
  jetsInLHEF = jetsInLHEF.substr(0, jetsInLHEF.size()-4);
  // Write histograms to dat file. Use "jetsInLHEF" to label the files
  // Once all the samples up to the maximal desired jet multiplicity from the
  // matrix element are run, add all histograms to produce a
  // matrix-element-merged prediction
  ofstream write;
  stringstream suffix;
  suffix << jetsInLHEF << "_wv.dat";
  // Write histograms to file
  write.open( (char*)(oPath + "PTjet1_" + suffix.str()).c_str());
  histPTFirst.table(write);
  write.close();
  write.open( (char*)(oPath + "PTjet2_" + suffix.str()).c_str());
  histPTSecond.table(write);
  write.close();
  delete myMergingHooks;
  return 0;
  // Done
}

main83.cc


// main83.cc is a part of the PYTHIA event generator.
// Copyright (C) 2016 Torbjorn Sjostrand.
// PYTHIA is licenced under the GNU GPL version 2, see COPYING for details.
// Please respect the MCnet Guidelines, see GUIDELINES for details.
// This program is written by Stefan Prestel.
// It illustrates how to do CKKW-L merging, see the Matrix Element
// Merging page in the online manual. An example command is
//     ./main83 main83.cmnd w+_production_lhc_0.lhe histout83.dat
// where main83.cmnd supplies the commands, w+_production_lhc_0.lhe
// provides the input LHE events, and histout83.dat is the output
// file. This example requires FastJet.
#include "Pythia8/Pythia.h"
using namespace Pythia8;
// Functions for histogramming
#include "fastjet/PseudoJet.hh"
#include "fastjet/ClusterSequence.hh"
#include "fastjet/CDFMidPointPlugin.hh"
#include "fastjet/CDFJetCluPlugin.hh"
#include "fastjet/D0RunIIConePlugin.hh"
//==========================================================================
// Find the Durham kT separation of the clustering from
// nJetMin --> nJetMin-1 jets in te input event
double pTfirstJet( const Event& event, int nJetMin, double Rparam) {
  double yPartonMax = 4.;
  // Fastjet analysis - select algorithm and parameters
  fastjet::Strategy               strategy = fastjet::Best;
  fastjet::RecombinationScheme    recombScheme = fastjet::E_scheme;
  fastjet::JetDefinition         *jetDef = NULL;
  // For hadronic collision, use hadronic Durham kT measure
  if(event[3].colType() != 0 || event[4].colType() != 0)
    jetDef = new fastjet::JetDefinition(fastjet::kt_algorithm, Rparam,
                                      recombScheme, strategy);
  // For e+e- collision, use e+e- Durham kT measure
  else
    jetDef = new fastjet::JetDefinition(fastjet::ee_kt_algorithm,
                                      recombScheme, strategy);
  // Fastjet input
  std::vector <fastjet::PseudoJet> fjInputs;
  // Reset Fastjet input
  fjInputs.resize(0);
  // Loop over event record to decide what to pass to FastJet
  for (int i = 0; i < event.size(); ++i) {
    // (Final state && coloured+photons) only!
    if ( !event[i].isFinal()
      || event[i].isLepton()
      || event[i].id() == 23
      || abs(event[i].id()) == 24
      || abs(event[i].y()) > yPartonMax)
      continue;
    // Store as input to Fastjet
    fjInputs.push_back( fastjet::PseudoJet (event[i].px(),
            event[i].py(), event[i].pz(),event[i].e() ) );
  }
  // Do nothing for empty input
  if (int(fjInputs.size()) == 0) {
    delete jetDef;
    return 0.0;
  }
  // Run Fastjet algorithm
  fastjet::ClusterSequence clustSeq(fjInputs, *jetDef);
  // Extract kT of first clustering
  double pTFirst = sqrt(clustSeq.exclusive_dmerge_max(nJetMin-1));
  delete jetDef;
  // Return kT
  return pTFirst;
}
//==========================================================================
// Class for user interaction with the merging
class MyMergingHooks : public MergingHooks {
private:
public:
  // Default constructor
  MyMergingHooks();
  // Destructor
  ~MyMergingHooks();
  // Functional definition of the merging scale
  virtual double tmsDefinition( const Event& event);
  // Function to dampen weights calculated from histories with lowest
  // multiplicity reclustered events that do not pass the ME cuts
  virtual double dampenIfFailCuts( const Event& inEvent );
  // Helper function for tms definition
  double myKTdurham(const Particle& RadAfterBranch,
           const Particle& EmtAfterBranch, int Type, double D );
};
//--------------------------------------------------------------------------
// Constructor
MyMergingHooks::MyMergingHooks() {}
// Desctructor
MyMergingHooks::~MyMergingHooks() {}
//--------------------------------------------------------------------------
double MyMergingHooks::dampenIfFailCuts( const Event& inEvent ){
  // Get pT for pure QCD 2->2 state
  double pT = 0.;
  for( int i=0; i < inEvent.size(); ++i)
    if(inEvent[i].isFinal() && inEvent[i].colType() != 0) {
      pT = sqrt(pow(inEvent[i].px(),2) + pow(inEvent[i].py(),2));
      break;
    }
  // Veto history if lowest multiplicity event does not pass ME cuts
  if(pT < 10.) return 0.;
  return 1.;
}
//--------------------------------------------------------------------------
// Definition of the merging scale
double MyMergingHooks::tmsDefinition( const Event& event){
  // Cut only on QCD partons!
  // Count particle types
  int nFinalColoured = 0;
  int nFinalNow =0;
  for( int i=0; i < event.size(); ++i) {
    if(event[i].isFinal()){
      if(event[i].id() != 23 && abs(event[i].id()) != 24)
        nFinalNow++;
      if( event[i].colType() != 0)
        nFinalColoured++;
    }
  }
  // Use MergingHooks in-built functions to get information on the hard process
  int nLeptons = nHardOutLeptons();
  int nQuarks  = nHardOutPartons();
  int nResNow  = nResInCurrent();
  // Check if photons, electrons etc. have been produced. If so, do not veto
  if(nFinalNow - ( (nLeptons+nQuarks)/2 - nResNow)*2 != nFinalColoured){
    // Sometimes, Pythia detaches the decay products even though no
    // resonance was put into the LHE file, to catch this, add another
    // if statement
    if(nFinalNow != nFinalColoured) return 0.;
  }
  // Check that one parton has been produced. If not (e.g. in MPI), do not veto
  int nMPI = infoPtr->nMPI();
  if(nMPI > 1) return 0.;
  // Declare kT algorithm parameters
  double Dparam = 0.4;
  int kTtype = -1;
  // Declare final parton vector
  vector <int> FinalPartPos;
  FinalPartPos.clear();
  // Search event record for final state partons
  for (int i=0; i < event.size(); ++i)
    if(event[i].isFinal() && event[i].colType() != 0)
      FinalPartPos.push_back(i);
  // Find minimal Durham kT in event, using own function: Check
  // definition of separation
  int type = (event[3].colType() == 0 && event[4].colType() == 0) ? 1 : kTtype;
  // Find minimal kT
  double ktmin = event[0].e();
  for(int i=0; i < int(FinalPartPos.size()); ++i){
    double kt12  = ktmin;
    // Compute separation to the beam axis for hadronic collisions
    if(type == -1 || type == -2) {
      double temp = event[FinalPartPos[i]].pT();
      kt12 = min(kt12, temp);
    }
    // Compute separation to other final state jets
    for(int j=i+1; j < int(FinalPartPos.size()); ++j) {
      double temp = kTdurham( event[FinalPartPos[i]], event[FinalPartPos[j]],
                      type, Dparam);
      kt12 = min(kt12, temp);
    }
    // Keep the minimal Durham separation
    ktmin = min(ktmin,kt12);
  }
  // Return minimal Durham kT
  return ktmin;
}
//--------------------------------------------------------------------------
// Function to compute durham y separation from Particle input
double MyMergingHooks::myKTdurham(const Particle& RadAfterBranch,
  const Particle& EmtAfterBranch, int Type, double D ){
  // Declare return variable
  double ktdur;
  // Save 4-momenta of final state particles
  Vec4 jet1 = RadAfterBranch.p();
  Vec4 jet2 = EmtAfterBranch.p();
  if( Type == 1) {
    // Get angle between jets for e+e- collisions, make sure that
    // -1 <= cos(theta) <= 1
    double costh;
    if (jet1.pAbs()*jet2.pAbs() <=0.) costh = 1.;
    else {
      costh = costheta(jet1,jet2);
    }
    // Calculate kt durham separation between jets for e+e- collisions
    ktdur = 2.0*min( pow(jet1.e(),2) , (pow(jet2.e(),2)) )*(1.0 - costh);
  } else if( Type == -1 ){
    // Get delta_eta and cosh(Delta_eta) for hadronic collisions
    double eta1 = 0.5*log( (jet1.e() + jet1.pz()) / (jet1.e() - jet1.pz()) );
    double eta2 = 0.5*log( (jet2.e() + jet2.pz()) / (jet2.e() - jet2.pz()) );
    // Get delta_phi and cos(Delta_phi) for hadronic collisions
    double pt1 = sqrt( pow(jet1.px(),2) + pow(jet1.py(),2) );
    double pt2 = sqrt( pow(jet2.px(),2) + pow(jet2.py(),2) );
    double cosdPhi = ( jet1.px()*jet2.px() + jet1.py()*jet2.py() ) / (pt1*pt2);
    double dPhi = acos( cosdPhi );
    // Calculate kT durham like fastjet
     ktdur = min( pow(pt1,2),pow(pt2,2) )
           * ( pow(eta1-eta2,2) + pow(dPhi,2) ) / pow(D,2);
  } else if( Type == -2 ){
    // Get delta_eta and cosh(Delta_eta) for hadronic collisions
    double eta1 = 0.5*log( (jet1.e() + jet1.pz()) / (jet1.e() - jet1.pz()) );
    double eta2 = 0.5*log( (jet2.e() + jet2.pz()) / (jet2.e() - jet2.pz()) );
     double coshdEta = cosh( eta1 - eta2 );
    // Get delta_phi and cos(Delta_phi) for hadronic collisions
    double pt1 = sqrt( pow(jet1.px(),2) + pow(jet1.py(),2) );
    double pt2 = sqrt( pow(jet2.px(),2) + pow(jet2.py(),2) );
    double cosdPhi = ( jet1.px()*jet2.px() + jet1.py()*jet2.py() ) / (pt1*pt2);
    // Calculate kT durham separation "SHERPA-like"
     ktdur = 2.0*min( pow(pt1,2),pow(pt2,2) )
           * ( coshdEta - cosdPhi ) / pow(D,2);
  } else {
    ktdur = 0.0;
  }
  // Return kT
  return sqrt(ktdur);
}
//==========================================================================
// Example main programm to illustrate merging
int main( int argc, char* argv[] ){
  // Check that correct number of command-line arguments
  if (argc != 4) {
    cerr << " Unexpected number of command-line arguments. \n You are"
         << " expected to provide the arguments \n"
         << " 1. Input file for settings \n"
         << " 2. Full name of the input LHE file (with path) \n"
         << " 3. Path for output histogram files \n"
         << " Program stopped. " << endl;
    return 1;
  }
  Pythia pythia;
  // Input parameters:
  //  1. Input file for settings
  //  2. Path to input LHE file
  //  3. Output histogram path
  pythia.readFile(argv[1]);
  string iPath = string(argv[2]);
  string oPath = string(argv[3]);
  // Number of events
  int nEvent = pythia.mode("Main:numberOfEvents");
  // Construct user inut for merging
  MergingHooks* myMergingHooks = new MyMergingHooks();
  pythia.setMergingHooksPtr( myMergingHooks );
  // For ISR regularisation off
  pythia.settings.forceParm("SpaceShower:pT0Ref",0.);
  // Declare histograms
  Hist histPTFirst("pT of first jet",100,0.,100.);
  Hist histPTSecond("pT of second jet",100,0.,100.);
  // Read in ME configurations
  pythia.readString("Beams:frameType = 4");
  pythia.readString("Beams:LHEF = " + iPath);
  pythia.init();
  // Start generation loop
  for( int iEvent=0; iEvent<nEvent; ++iEvent ){
    // Generate next event
    if( ! pythia.next()) continue;
    // Get CKKWL weight of current event
    double weight = pythia.info.mergingWeight();
    // Fill bins with CKKWL weight
    double pTfirst = pTfirstJet(pythia.event,1, 0.4);
    double pTsecnd = pTfirstJet(pythia.event,2, 0.4);
    histPTFirst.fill( pTfirst, weight);
    histPTSecond.fill( pTsecnd, weight);
    if(iEvent%1000 == 0) cout << iEvent << endl;
  } // end loop over events to generate
  // print cross section, errors
  pythia.stat();
  // Normalise histograms
  double norm = 1.
              * pythia.info.sigmaGen()
              * 1./ double(nEvent);
  histPTFirst           *= norm;
  histPTSecond          *= norm;
  // Get the number of jets in the LHE file from the file name
  string jetsInLHEF = iPath.substr(iPath.size()-5, iPath.size());
  jetsInLHEF = jetsInLHEF.substr(0, jetsInLHEF.size()-4);
  // Write histograms to dat file. Use "jetsInLHEF" to label the files
  // Once all the samples up to the maximal desired jet multiplicity from the
  // matrix element are run, add all histograms to produce a
  // matrix-element-merged prediction
  ofstream write;
  stringstream suffix;
  suffix << jetsInLHEF << "_wv.dat";
  // Write histograms to file
  write.open( (char*)(oPath + "PTjet1_" + suffix.str()).c_str());
  histPTFirst.table(write);
  write.close();
  write.open( (char*)(oPath + "PTjet2_" + suffix.str()).c_str());
  histPTSecond.table(write);
  write.close();
  delete myMergingHooks;
  return 0;
  // Done
}

main84.cc


// main84.cc is a part of the PYTHIA event generator.
// Copyright (C) 2016 Torbjorn Sjostrand.
// PYTHIA is licenced under the GNU GPL version 2, see COPYING for details.
// Please respect the MCnet Guidelines, see GUIDELINES for details.
// This program is written by Stefan Prestel.
// It illustrates how to do CKKW-L merging, see the Matrix Element
// Merging page in the online manual. An example command is
//     ./main84 main84.cmnd hepmcout84.dat 2 w+_production_lhc histout84.dat
// where main84.cmnd supplies the commands, hepmcout84.dat is the
// HepMC output, 2 is the maximial number of jets, w+_production_lhc
// provides the input LHE events, and histout84.dat is the output
// histogram file. This example requires FastJet and HepMC.
#include <time.h>
#include "Pythia8/Pythia.h"
#include "Pythia8Plugins/HepMC2.h"
using namespace Pythia8;
// Functions for histogramming
#include "fastjet/PseudoJet.hh"
#include "fastjet/ClusterSequence.hh"
#include "fastjet/CDFMidPointPlugin.hh"
#include "fastjet/CDFJetCluPlugin.hh"
#include "fastjet/D0RunIIConePlugin.hh"
//==========================================================================
// Find the Durham kT separation of the clustering from
// nJetMin --> nJetMin-1 jets in te input event
double pTfirstJet( const Event& event, int nJetMin, double Rparam) {
  double yPartonMax = 4.;
  // Fastjet analysis - select algorithm and parameters
  fastjet::Strategy               strategy = fastjet::Best;
  fastjet::RecombinationScheme    recombScheme = fastjet::E_scheme;
  fastjet::JetDefinition         *jetDef = NULL;
  // For hadronic collision, use hadronic Durham kT measure
  if(event[3].colType() != 0 || event[4].colType() != 0)
    jetDef = new fastjet::JetDefinition(fastjet::kt_algorithm, Rparam,
                                      recombScheme, strategy);
  // For e+e- collision, use e+e- Durham kT measure
  else
    jetDef = new fastjet::JetDefinition(fastjet::ee_kt_algorithm,
                                      recombScheme, strategy);
  // Fastjet input
  std::vector <fastjet::PseudoJet> fjInputs;
  // Reset Fastjet input
  fjInputs.resize(0);
  // Loop over event record to decide what to pass to FastJet
  for (int i = 0; i < event.size(); ++i) {
    // (Final state && coloured+photons) only!
    if ( !event[i].isFinal()
      || event[i].isLepton()
      || event[i].id() == 23
      || abs(event[i].id()) == 24
      || abs(event[i].y()) > yPartonMax)
      continue;
    // Store as input to Fastjet
    fjInputs.push_back( fastjet::PseudoJet (event[i].px(),
            event[i].py(), event[i].pz(),event[i].e() ) );
  }
  // Do nothing for empty input
  if (int(fjInputs.size()) == 0) {
    delete jetDef;
    return 0.0;
  }
  // Run Fastjet algorithm
  fastjet::ClusterSequence clustSeq(fjInputs, *jetDef);
  // Extract kT of first clustering
  double pTFirst = sqrt(clustSeq.exclusive_dmerge_max(nJetMin-1));
  delete jetDef;
  // Return kT
  return pTFirst;
}
//==========================================================================
int main( int argc, char* argv[] ){
  // Check that correct number of command-line arguments
  if (argc != 6) {
    cerr << " Unexpected number of command-line arguments. \n You are"
         << " expected to provide the arguments" << endl
         << " 1. Input file for settings" << endl
         << " 2. Name of output HepMC file" << endl
         << " 3. Maximal number of additional jets"
         << " (not used internally in Pythia, only used to construct the full"
         << " name of lhe files with additional jets, and to label output"
         << " histograms)" << endl
         << " 4. Full name of the input LHE file (with path"
         << " , without any _0.lhe suffix)" << endl
         << " 5. Path for output histogram files" << endl
         << " Program stopped. " << endl;
    return 1;
  }
  Pythia pythia;
  // First argument: Get input from an input file
  pythia.readFile(argv[1]);
  int nEvent = pythia.mode("Main:numberOfEvents");
  // Interface for conversion from Pythia8::Event to HepMC event.
  // Will fill cross section and event weight directly in this program,
  // so switch it off for normal conversion routine.
  HepMC::Pythia8ToHepMC ToHepMC;
  ToHepMC.set_store_xsec(false);
  // Specify file where HepMC events will be stored.
  HepMC::IO_GenEvent ascii_io(argv[2], std::ios::out);
  // Third argument: Maximal number of additional jets
  int njet = atoi(argv[3]);
  // Read input and output paths
  string iPath = string(argv[4]);
  string oPath = string(argv[5]);
  // To write correctly normalized events to hepmc file, first get
  // a reasonable accurate of the cross section
  int njetCounterEstimate = njet;
  vector<double> xsecEstimate;
  vector<double> nTrialEstimate;
  vector<double> nAcceptEstimate;
  pythia.readString("Random:setSeed = on");
  pythia.readString("Random:seed = 42390964");
  while(njetCounterEstimate >= 0) {
    // Number of runs
    int nRun = 1;
    double nTrial = 0.;
    double nAccept = 0.;
    int countEvents = 0;
    // Run pythia nRun times with the same lhe file to get nRun times
    // higher statistics in the histograms
    for(int n = 1; n <= nRun ; ++n ) {
      // Get process and events from LHE file, initialize only the
      // first time
      if(n > 1) pythia.readString("Main:LHEFskipInit = on");
      // From njet, choose LHE file
      stringstream in;
      in   << "_" << njetCounterEstimate << ".lhe";
      string LHEfile = iPath + in.str();
      pythia.readString("HadronLevel:all = off");
      // Read in ME configurations
      pythia.readString("Beams:frameType = 4");
      pythia.readString("Beams:LHEF = " + LHEfile);
      pythia.init();
      for( int iEvent=0; iEvent<nEvent; ++iEvent ){
        countEvents++;
        nTrial += 1.;
        if(iEvent == 0) pythia.stat();
        // Generate next event
        if(pythia.next()) nAccept += 1.;
        if(countEvents == nEvent*nRun-1){
          xsecEstimate.push_back(pythia.info.sigmaGen());
          nTrialEstimate.push_back(nTrial+1.);
          nAcceptEstimate.push_back(nAccept+1.);
        }
      } // end loop over events to generate
    } // end outer loop to rerun pythia with the same lhe file
    // Restart with ME of a reduced the number of jets
    if( njetCounterEstimate > 0 )
      njetCounterEstimate--;
    else
      break;
  } // end loop over different jet multiplicities
  cout << endl << "Finished estimating cross section"
    << endl;
  for(int i=0; i < int(xsecEstimate.size()); ++i)
    cout << "  Cross section estimate for " << njet-i << " jets :"
      << scientific << setprecision(8) << xsecEstimate[i]
      << endl;
  for(int i=0; i < int(nTrialEstimate.size()); ++i)
    cout << "  Trial events for " << njet-i << " jets :"
      << scientific << setprecision(3) << nTrialEstimate[i]
      << "  Accepted events for " << njet-i << " jets :"
      << scientific << setprecision(3) << nAcceptEstimate[i]
      << endl;
  cout << endl;
  // Now start merging procedure
  int njetCounter = njet;
  Hist histPTFirstSum("pT of first jet",100,0.,100.);
  Hist histPTSecondSum("pT of second jet",100,0.,100.);
  pythia.readString("Random:setSeed = on");
  pythia.readString("Random:seed = 42390964");
  // Sum of event weights
  double sigma = 0.0;
  double sigma2 = 0.0;
  while(njetCounter >= 0) {
    cout << "   Path to lhe files: " << iPath << "_*" << endl;
    cout << "   Output written to: " << oPath << "'name'.dat" << endl;
    // Set up histograms of pT of the first jet
    Hist histPTFirst("pT of first jet",100,0.,200.);
    Hist histPTSecond("pT of second jet",100,0.,200.);
    Hist histPTThird("pT of third jet",100,0.,200.);
    Hist histPTFourth("pT of fourth jet",50,0.,100.);
    Hist histPTFifth("pT of fifth jet",30,0.,50.);
    Hist histPTSixth("pT of sixth jet",30,0.,50.);
    // Number of runs
    int nRun = 1;
    // Number of tried events
    int nTriedEvents = 0;
    // Number of accepted events
    int nAccepEvents = 0;
    // Run pythia nRun times with the same lhe file to get nRun times
    // higher statistics in the histograms
    for(int n = 1; n <= nRun ; ++n ) {
      // Get process and events from LHE file, initialize only the
      // first time
      if(n > 1) pythia.readString("Main:LHEFskipInit = on");
      // From njet, choose LHE file
      stringstream in;
      in   << "_" << njetCounter << ".lhe";
      string LHEfile = iPath + in.str();
      cout << endl << endl
        << "\t LHE FILE FOR + " << njetCounter
        << " JET SAMPLE READ FROM " << LHEfile
        << endl << endl;
      cout << "Normalise with xsection " << xsecEstimate[njet-njetCounter]
        << endl << endl;
      pythia.readString("HadronLevel:all = on");
      // Read in ME configurations
      pythia.readString("Beams:frameType = 4");
      pythia.readString("Beams:LHEF = " + LHEfile);
      pythia.init();
      for( int iEvent=0; iEvent<nEvent; ++iEvent ){
        nTriedEvents++;
        if(iEvent == 0) pythia.stat();
        // Generate next event
        if( pythia.next()) {
          double weight = pythia.info.mergingWeight();
          nAccepEvents++;
          // Jet pT's
          double D = 0.4;
          double pTfirst = pTfirstJet(pythia.event,1, D);
          double pTsecnd = pTfirstJet(pythia.event,2, D);
          double pTthird = pTfirstJet(pythia.event,3, D);
          double pTfourt = pTfirstJet(pythia.event,4, D);
          double pTfifth = pTfirstJet(pythia.event,5, D);
          double pTsixth = pTfirstJet(pythia.event,6, D);
          histPTFirst.fill( pTfirst, weight);
          histPTSecond.fill( pTsecnd, weight);
          histPTThird.fill( pTthird, weight);
          histPTFourth.fill( pTfourt, weight);
          histPTFifth.fill( pTfifth, weight);
          histPTSixth.fill( pTsixth, weight);
          if(weight > 0.){
            // Construct new empty HepMC event and fill it.
            // Units will be as chosen for HepMC build, but can be changed
            // by arguments, e.g. GenEvt( HepMC::Units::GEV, HepMC::Units::MM)
            HepMC::GenEvent* hepmcevt = new HepMC::GenEvent();
            double normhepmc = 1.* xsecEstimate[njet-njetCounter]
                * nTrialEstimate[njet-njetCounter]
                / nAcceptEstimate[njet-njetCounter]
                * 1./ (double(nRun)*double(nEvent));
            sigma += weight*normhepmc;
            sigma2 += pow(weight*normhepmc,2);
            // Set event weight
            hepmcevt->weights().push_back(weight*normhepmc);
            // Fill summed histograms
            histPTFirstSum.fill( pTfirst, weight*normhepmc);
            histPTSecondSum.fill( pTsecnd, weight*normhepmc);
            // Fill HepMC event, with PDF info.
            ToHepMC.fill_next_event( pythia, hepmcevt );
            // Report cross section to hepmc
            HepMC::GenCrossSection xsec;
            xsec.set_cross_section( sigma*1e9,
              pythia.info.sigmaErr()*1e9 );
            hepmcevt->set_cross_section( xsec );
            // Write the HepMC event to file. Done with it.
            ascii_io << hepmcevt;
            delete hepmcevt;
          }
        } // if( pythia.next() )
        if(nTriedEvents%10000 == 0)
          cout << nTriedEvents << endl;
      } // end loop over events to generate
      // print cross section, errors
      pythia.stat();
    } // end outer loop to rerun pythia with the same lhe file
    // Normalise histograms for this particular multiplicity
    double norm = 1.
                * pythia.info.sigmaGen()
                * double(nTriedEvents)/double(nAccepEvents)
                * 1./ (double(nRun)*double(nEvent));
    histPTFirst           *= norm;
    histPTSecond          *= norm;
    histPTThird           *= norm;
    histPTFourth          *= norm;
    histPTFifth           *= norm;
    histPTSixth           *= norm;
    // Write histograms for this particular multiplicity to file
    ofstream write;
    stringstream suffix;
    suffix << njet << "_" << njetCounter;
    suffix << "_wv.dat";
    write.open( (char*)(oPath + "PTjet1_" + suffix.str()).c_str());
    histPTFirst.table(write);
    write.close();
    write.open( (char*)(oPath + "PTjet2_" + suffix.str()).c_str());
    histPTSecond.table(write);
    write.close();
    write.open( (char*)(oPath + "PTjet3_" + suffix.str()).c_str());
    histPTThird.table(write);
    write.close();
    write.open( (char*)(oPath + "PTjet4_" + suffix.str()).c_str());
    histPTFourth.table(write);
    write.close();
    write.open( (char*)(oPath + "PTjet5_" + suffix.str()).c_str());
    histPTFifth.table(write);
    write.close();
    write.open( (char*)(oPath + "PTjet6_" + suffix.str()).c_str());
    histPTSixth.table(write);
    write.close();
    histPTFirst.null();
    histPTSecond.null();
    histPTThird.null();
    histPTFourth.null();
    histPTFifth.null();
    histPTSixth.null();
    // Restart with ME of a reduced the number of jets
    if( njetCounter > 0 )
      njetCounter--;
    else
      break;
  } // end loop over different jet multiplicities
  // Since the histograms have been filled with the correct weight for
  // each jet multiplicity, no normalisation is needed.
  // Write summed histograms to file.
  ofstream writeSum;
  stringstream suffixSum;
  suffixSum << njet << "_wv.dat";
  writeSum.open( (char*)(oPath + "PTjet1Sum_" + suffixSum.str()).c_str());
  histPTFirstSum.table(writeSum);
  writeSum.close();
  writeSum.open( (char*)(oPath + "PTjet2Sum_" + suffixSum.str()).c_str());
  histPTSecondSum.table(writeSum);
  writeSum.close();
  for(int i=0; i < int(xsecEstimate.size()); ++i)
    cout << "  Cross section estimate for " << njet-i << " jets :"
      << scientific << setprecision(8) << xsecEstimate[i]
      << endl;
  for(int i=0; i < int(nTrialEstimate.size()); ++i)
    cout << "  Trial events for " << njet-i << " jets :"
      << scientific << setprecision(3) << nTrialEstimate[i]
      << "  Accepted events for " << njet-i << " jets :"
      << scientific << setprecision(3) << nAcceptEstimate[i]
      << endl;
  cout << endl;
  cout << "Histogrammed cross section for "
     << iPath << " with " << njet << " additional jets is "
     << scientific << setprecision(8) << sigma
     << " error " << sqrt(sigma2) << endl;
  return 0;
}

main85.cc


// main85.cc is a part of the PYTHIA event generator.
// Copyright (C) 2016 Torbjorn Sjostrand.
// PYTHIA is licenced under the GNU GPL version 2, see COPYING for details.
// Please respect the MCnet Guidelines, see GUIDELINES for details.
// This program is written by Stefan Prestel.
// It illustrates how to do CKKW-L merging, see the Matrix Element
// Merging page in the online manual. An example command is
//     ./main85 main85.cmnd w_production hepmcout85.dat
// where main85.cmnd supplies the commands, w_production provides the
// input LHE events, and hepmcout85.dat is the output file. This
// example requires HepMC.
#include "Pythia8/Pythia.h"
#include "Pythia8Plugins/HepMC2.h"
#include <unistd.h>
using namespace Pythia8;
//==========================================================================
// Example main programm to illustrate merging
int main( int argc, char* argv[] ){
  // Check that correct number of command-line arguments
  if (argc != 4) {
    cerr << " Unexpected number of command-line arguments ("<<argc<<"). \n"
         << " You are expected to provide the arguments" << endl
         << " 1. Input file for settings" << endl
         << " 2. Name of the input LHE file (with path), up to the '_tree'"
         << " identifier" << endl
         << " 3. Output hepmc file name" << endl
         << " Program stopped. " << endl;
    return 1;
  }
  Pythia pythia;
  // Input parameters:
  pythia.readFile(argv[1]);
  // Interface for conversion from Pythia8::Event to HepMC one.
  HepMC::Pythia8ToHepMC ToHepMC;
  // Specify file where HepMC events will be stored.
  HepMC::IO_GenEvent ascii_io(argv[3], std::ios::out);
  // Switch off warnings for parton-level events.
  ToHepMC.set_print_inconsistency(false);
  ToHepMC.set_free_parton_warnings(false);
  // Do not store cross section information, as this will be done manually.
  ToHepMC.set_store_pdf(false);
  ToHepMC.set_store_proc(false);
  ToHepMC.set_store_xsec(false);
  // Path to input events, with name up to the "_tree" identifier included.
  string iPath = string(argv[2]);
  // Number of events.
  int nEvent = pythia.mode("Main:numberOfEvents");
  // Maximal number of additional LO jets.
  int nMaxLO =  pythia.mode("Merging:nJetMax");
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
  // Switch off all showering and MPI when estimating the cross section after
  // the merging scale cut.
  bool fsr = pythia.flag("PartonLevel:FSR");
  bool isr = pythia.flag("PartonLevel:ISR");
  bool mpi = pythia.flag("PartonLevel:MPI");
  bool had = pythia.flag("HadronLevel:all");
  pythia.settings.flag("PartonLevel:FSR",false);
  pythia.settings.flag("PartonLevel:ISR",false);
  pythia.settings.flag("HadronLevel:all",false);
  pythia.settings.flag("PartonLevel:MPI",false);
  // Switch on cross section estimation procedure.
  pythia.settings.flag("Merging:doXSectionEstimate", true);
  int njetcounterLO  = nMaxLO;
  string iPathTree   = iPath + "_tree";
  // Save estimates in vectors.
  vector<double> xsecLO;
  vector<double> nAcceptLO;
  vector<double> nSelectedLO;
  vector<int> strategyLO;
  cout << endl << endl << endl;
  cout << "Start estimating ckkwl tree level cross section" << endl;
  while(njetcounterLO >= 0) {
    // From njetcounter, choose LHE file
    stringstream in;
    in   << "_" << njetcounterLO << ".lhe";
#ifdef GZIPSUPPORT
    if(access( (iPathTree+in.str()+".gz").c_str(), F_OK) != -1) in << ".gz";
#endif
    string LHEfile = iPathTree + in.str();
    pythia.settings.mode("Merging:nRequested", njetcounterLO);
    pythia.settings.mode("Beams:frameType", 4);
    pythia.settings.word("Beams:LHEF", LHEfile);
    pythia.init();
    // Start generation loop
    for( int iEvent=0; iEvent<nEvent; ++iEvent ){
      // Generate next event
      if( !pythia.next() ) {
        if( pythia.info.atEndOfFile() ){
          break;
        }
        else continue;
      }
    } // end loop over events to generate
    // print cross section, errors
    pythia.stat();
    xsecLO.push_back(pythia.info.sigmaGen());
    nSelectedLO.push_back(pythia.info.nSelected());
    nAcceptLO.push_back(pythia.info.nAccepted());
    strategyLO.push_back(pythia.info.lhaStrategy());
    // Restart with ME of a reduced the number of jets
    if( njetcounterLO > 0 )
      njetcounterLO--;
    else
      break;
  } // end loop over different jet multiplicities
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
  // Switch off cross section estimation.
  pythia.settings.flag("Merging:doXSectionEstimate", false);
  // Switch showering and multiple interaction back on.
  pythia.settings.flag("PartonLevel:FSR",fsr);
  pythia.settings.flag("PartonLevel:ISR",isr);
  pythia.settings.flag("HadronLevel:all",had);
  pythia.settings.flag("PartonLevel:MPI",mpi);
  // Declare sample cross section for output.
  double sigmaTemp  = 0.;
  vector<double> sampleXStree;
  // Cross section an error.
  double sigmaTotal  = 0.;
  double errorTotal  = 0.;
  int sizeLO    = int(xsecLO.size());
  njetcounterLO = nMaxLO;
  iPathTree     = iPath + "_tree";
  while(njetcounterLO >= 0){
    // From njetcounter, choose LHE file
    stringstream in;
    in   << "_" << njetcounterLO << ".lhe";
#ifdef GZIPSUPPORT
    if(access( (iPathTree+in.str()+".gz").c_str(), F_OK) != -1) in << ".gz";
#endif
    string LHEfile = iPathTree + in.str();
    cout << endl << endl << endl
         << "Start tree level treatment for " << njetcounterLO << " jets"
         << endl;
    pythia.settings.mode("Merging:nRequested", njetcounterLO);
    pythia.settings.mode("Beams:frameType", 4);
    pythia.settings.word("Beams:LHEF", LHEfile);
    pythia.init();
    // Remember position in vector of cross section estimates.
    int iNow = sizeLO-1-njetcounterLO;
    // Start generation loop
    for( int iEvent=0; iEvent<nEvent; ++iEvent ){
      // Generate next event
      if( !pythia.next() ) {
        if( pythia.info.atEndOfFile() ) break;
        else continue;
      }
      // Get event weight(s).
      double weight = pythia.info.mergingWeight();
      double evtweight = pythia.info.weight();
      weight *= evtweight;
      // Do not print zero-weight events.
      if ( weight == 0. ) continue;
      // Construct new empty HepMC event.
      HepMC::GenEvent* hepmcevt = new HepMC::GenEvent();
      // Get correct cross section from previous estimate.
      double normhepmc = xsecLO[iNow] / nAcceptLO[iNow];
      // weighted events
      if( abs(strategyLO[iNow]) == 4)
        normhepmc = 1. / (1e9*nSelectedLO[iNow]);
      // Set event weight
      hepmcevt->weights().push_back(weight*normhepmc);
      // Fill HepMC event
      ToHepMC.fill_next_event( pythia, hepmcevt );
      // Add the weight of the current event to the cross section.
      sigmaTotal += weight*normhepmc;
      sigmaTemp  += weight*normhepmc;
      errorTotal += pow2(weight*normhepmc);
      // Report cross section to hepmc
      HepMC::GenCrossSection xsec;
      xsec.set_cross_section( sigmaTotal*1e9, pythia.info.sigmaErr()*1e9 );
      hepmcevt->set_cross_section( xsec );
      // Write the HepMC event to file. Done with it.
      ascii_io << hepmcevt;
      delete hepmcevt;
    } // end loop over events to generate
    // print cross section, errors
    pythia.stat();
    // Save sample cross section for output.
    sampleXStree.push_back(sigmaTemp);
    sigmaTemp = 0.;
    // Restart with ME of a reduced the number of jets
    if( njetcounterLO > 0 )
      njetcounterLO--;
    else
      break;
  }
  // Print cross section information.
  cout << endl << endl;
  cout << " *---------------------------------------------------*" << endl;
  cout << " |                                                   |" << endl;
  cout << " | Sample cross sections after CKKW-L merging        |" << endl;
  cout << " |                                                   |" << endl;
  cout << " | Leading order cross sections (mb):                |" << endl;
  for (int i = 0; i < int(sampleXStree.size()); ++i)
    cout << " |     " << sampleXStree.size()-1-i << "-jet:  "
         << setw(17) << scientific << setprecision(6)
         << sampleXStree[i] << "                     |" << endl;
  cout << " |                                                   |" << endl;
  cout << " |---------------------------------------------------|" << endl;
  cout << " |---------------------------------------------------|" << endl;
  cout << " | Inclusive cross sections:                         |" << endl;
  cout << " |                                                   |" << endl;
  cout << " | CKKW-L merged inclusive cross section:            |" << endl;
  cout << " |    " << setw(17) << scientific << setprecision(6)
       << sigmaTotal << "  +-  " << setw(17) << sqrt(errorTotal) << " mb "
       << "   |" << endl;
  cout << " |                                                   |" << endl;
  cout << " | LO inclusive cross section:                       |" << endl;
  cout << " |    " << setw(17) << scientific << setprecision(6)
       << xsecLO.back() << " mb                           |" << endl;
  cout << " |                                                   |" << endl;
  cout << " *---------------------------------------------------*" << endl;
  cout << endl << endl;
  // Done
  return 0;
}

main86.cc


// main86.cc is a part of the PYTHIA event generator.
// Copyright (C) 2016 Torbjorn Sjostrand.
// PYTHIA is licenced under the GNU GPL version 2, see COPYING for details.
// Please respect the MCnet Guidelines, see GUIDELINES for details.
// This program is written by Stefan Prestel.
// It illustrates how to do UMEPS merging, see the Matrix Element
// Merging page in the online manual. An example command is
//     ./main86 main86.cmnd w_production hepmcout86.dat
// where main86.cmnd supplies the commands, w_production provides the
// input LHE events, and hepmcout86.dat is the output file. This
// example requires HepMC.
#include "Pythia8/Pythia.h"
#include "Pythia8Plugins/HepMC2.h"
#include <unistd.h>
using namespace Pythia8;
//==========================================================================
// Example main programm to illustrate merging
int main( int argc, char* argv[] ){
  // Check that correct number of command-line arguments
  if (argc != 4) {
    cerr << " Unexpected number of command-line arguments ("<<argc<<"). \n"
         << " You are expected to provide the arguments" << endl
         << " 1. Input file for settings" << endl
         << " 2. Name of the input LHE file (with path), up to the '_tree'"
         << " identifier" << endl
         << " 3. Path for output HepMC" << endl
         << " Program stopped. " << endl;
    return 1;
  }
  Pythia pythia;
  // Input parameters:
  pythia.readFile(argv[1]);
  // Interface for conversion from Pythia8::Event to HepMC one.
  HepMC::Pythia8ToHepMC ToHepMC;
  // Specify file where HepMC events will be stored.
  HepMC::IO_GenEvent ascii_io(argv[3], std::ios::out);
  // Switch off warnings for parton-level events.
  ToHepMC.set_print_inconsistency(false);
  ToHepMC.set_free_parton_warnings(false);
  // Do not store cross section information, as this will be done manually.
  ToHepMC.set_store_pdf(false);
  ToHepMC.set_store_proc(false);
  ToHepMC.set_store_xsec(false);
  // Path to input events, with name up to the "_tree" identifier included.
  string iPath = string(argv[2]);
  // Number of events
  int nEvent = pythia.mode("Main:numberOfEvents");
  // Maximal number of additional LO jets.
  int nMaxLO =  pythia.mode("Merging:nJetMax");
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
  // Switch off all showering and MPI when extimating the cross section after
  // the merging scale cut.
  bool fsr = pythia.flag("PartonLevel:FSR");
  bool isr = pythia.flag("PartonLevel:ISR");
  bool mpi = pythia.flag("PartonLevel:MPI");
  bool had = pythia.flag("HadronLevel:all");
  pythia.settings.flag("PartonLevel:FSR",false);
  pythia.settings.flag("PartonLevel:ISR",false);
  pythia.settings.flag("HadronLevel:all",false);
  pythia.settings.flag("PartonLevel:MPI",false);
  // Switch on cross section estimation procedure.
  pythia.settings.flag("Merging:doXSectionEstimate", true);
  pythia.settings.flag("Merging:doUMEPSTree",true);
  int njetcounterLO = nMaxLO;
  string iPathTree  = iPath + "_tree";
  // Save estimates in vectors.
  vector<double> xsecLO;
  vector<double> nAcceptLO;
  cout << endl << endl << endl;
  cout << "Start estimating umeps tree level cross section" << endl;
  while(njetcounterLO >= 0) {
    // From njet, choose LHE file
    stringstream in;
    in   << "_" << njetcounterLO << ".lhe";
#ifdef GZIPSUPPORT
    if(access( (iPathTree+in.str()+".gz").c_str(), F_OK) != -1) in << ".gz";
#endif
    string LHEfile = iPathTree + in.str();
    pythia.settings.mode("Merging:nRequested", njetcounterLO);
    pythia.settings.mode("Beams:frameType", 4);
    pythia.settings.word("Beams:LHEF", LHEfile);
    pythia.init();
    // Start generation loop
    for( int iEvent=0; iEvent<nEvent; ++iEvent ){
      // Generate next event
      if( !pythia.next() ) {
        if( pythia.info.atEndOfFile() ){
          break;
        }
        else continue;
      }
    } // end loop over events to generate
    // print cross section, errors
    pythia.stat();
    xsecLO.push_back(pythia.info.sigmaGen());
    nAcceptLO.push_back(pythia.info.nAccepted());
    // Restart with ME of a reduced the number of jets
    if( njetcounterLO > 0 )
      njetcounterLO--;
    else
      break;
  } // end loop over different jet multiplicities
  // Switch off cross section estimation.
  pythia.settings.flag("Merging:doXSectionEstimate", false);
  // Switch showering and multiple interaction back on.
  pythia.settings.flag("PartonLevel:FSR",fsr);
  pythia.settings.flag("PartonLevel:ISR",isr);
  pythia.settings.flag("HadronLevel:all",had);
  pythia.settings.flag("PartonLevel:MPI",mpi);
  // Declare sample cross section for output.
  double sigmaTemp  = 0.;
  vector<double> sampleXStree;
  vector<double> sampleXSsubtTree;
  // Cross section an error.
  double sigmaTotal  = 0.;
  double errorTotal  = 0.;
  int sizeLO    = int(xsecLO.size());
  njetcounterLO = nMaxLO;
  iPathTree     = iPath + "_tree";
  while(njetcounterLO >= 0){
    // From njet, choose LHE file
    stringstream in;
    in   << "_" << njetcounterLO << ".lhe";
#ifdef GZIPSUPPORT
    if(access( (iPathTree+in.str()+".gz").c_str(), F_OK) != -1) in << ".gz";
#endif
    string LHEfile = iPathTree + in.str();
    pythia.settings.flag("Merging:doUMEPSTree",true);
    pythia.settings.flag("Merging:doUMEPSSubt",false);
    pythia.settings.mode("Merging:nRecluster",0);
    cout << endl << endl << endl
         << "Start tree level treatment for " << njetcounterLO << " jets"
         << endl;
    pythia.settings.mode("Merging:nRequested", njetcounterLO);
    pythia.settings.mode("Beams:frameType", 4);
    pythia.settings.word("Beams:LHEF", LHEfile);
    pythia.init();
    // Remember position in vector of cross section estimates.
    int iNow = sizeLO-1-njetcounterLO;
    // Start generation loop
    for( int iEvent=0; iEvent<nEvent; ++iEvent ){
      // Generate next event
      if( !pythia.next() ) {
        if( pythia.info.atEndOfFile() ) break;
        else continue;
      }
      // Get event weight(s).
      double weight = pythia.info.mergingWeight();
      double evtweight = pythia.info.weight();
      weight *= evtweight;
      // Do not print zero-weight events.
      if ( weight == 0. ) continue;
      // Construct new empty HepMC event.
      HepMC::GenEvent* hepmcevt = new HepMC::GenEvent();
      // Get correct cross section from previous estimate.
      double normhepmc = xsecLO[iNow] / nAcceptLO[iNow];
      // Set event weight
      hepmcevt->weights().push_back(weight*normhepmc);
      // Fill HepMC event.
      ToHepMC.fill_next_event( pythia, hepmcevt );
      // Add the weight of the current event to the cross section.
      sigmaTotal += weight*normhepmc;
      sigmaTemp  += weight*normhepmc;
      errorTotal += pow2(weight*normhepmc);
      // Report cross section to hepmc
      HepMC::GenCrossSection xsec;
      xsec.set_cross_section( sigmaTotal*1e9, pythia.info.sigmaErr()*1e9 );
      hepmcevt->set_cross_section( xsec );
      // Write the HepMC event to file. Done with it.
      ascii_io << hepmcevt;
      delete hepmcevt;
    } // end loop over events to generate
    // print cross section, errors
    pythia.stat();
    // Save sample cross section for output.
    sampleXStree.push_back(sigmaTemp);
    sigmaTemp = 0.;
    // Restart with ME of a reduced the number of jets
    if( njetcounterLO > 0 )
      njetcounterLO--;
    else
      break;
  }
  cout << endl << endl << endl;
  cout << "Do UMEPS subtraction" << endl;
  int njetcounterLS   = nMaxLO;
  string iPathSubt    = iPath + "_tree";
  while(njetcounterLS >= 1){
    // From njet, choose LHE file
    stringstream in;
    in   << "_" << njetcounterLS << ".lhe";
#ifdef GZIPSUPPORT
    if(access( (iPathSubt+in.str()+".gz").c_str(), F_OK) != -1) in << ".gz";
#endif
    string LHEfile = iPathSubt + in.str();
    pythia.settings.flag("Merging:doUMEPSTree",false);
    pythia.settings.flag("Merging:doUMEPSSubt",true);
    pythia.settings.mode("Merging:nRecluster",1);
    cout << endl << endl << endl
         << "Start subtractive treatment for " << njetcounterLS << " jets"
         << endl;
    pythia.settings.mode("Merging:nRequested", njetcounterLS);
    pythia.settings.mode("Beams:frameType", 4);
    pythia.settings.word("Beams:LHEF", LHEfile);
    pythia.init();
    // Remember position in vector of cross section estimates.
    int iNow = sizeLO-1-njetcounterLS;
    // Start generation loop
    for( int iEvent=0; iEvent<nEvent; ++iEvent ){
      // Generate next event
      if( !pythia.next() ) {
        if( pythia.info.atEndOfFile() ) break;
        else continue;
      }
      // Get event weight(s).
      double weight    = pythia.info.mergingWeight();
      double evtweight = pythia.info.weight();
      weight *= evtweight;
      // Do not print zero-weight events.
      if ( weight == 0. ) continue;
      // Construct new empty HepMC event.
      HepMC::GenEvent* hepmcevt = new HepMC::GenEvent();
      // Get correct cross section from previous estimate.
      double normhepmc = -1*xsecLO[iNow] / nAcceptLO[iNow];
      // Set event weight
      hepmcevt->weights().push_back(weight*normhepmc);
      // Fill HepMC event.
      ToHepMC.fill_next_event( pythia, hepmcevt );
      // Add the weight of the current event to the cross section.
      sigmaTotal += weight*normhepmc;
      sigmaTemp  += weight*normhepmc;
      errorTotal += pow2(weight*normhepmc);
      // Report cross section to hepmc.
      HepMC::GenCrossSection xsec;
      xsec.set_cross_section( sigmaTotal*1e9, pythia.info.sigmaErr()*1e9 );
      hepmcevt->set_cross_section( xsec );
      // Write the HepMC event to file. Done with it.
      ascii_io << hepmcevt;
      delete hepmcevt;
    } // end loop over events to generate
    // print cross section, errors
    pythia.stat();
    // Save sample cross section for output.
    sampleXSsubtTree.push_back(sigmaTemp);
    sigmaTemp = 0.;
    // Restart with ME of a reduced the number of jets
    if( njetcounterLS > 1 )
      njetcounterLS--;
    else
      break;
  }
  // Print cross section information.
  cout << endl << endl;
  cout << " *---------------------------------------------------*" << endl;
  cout << " |                                                   |" << endl;
  cout << " | Sample cross sections after UMEPS merging         |" << endl;
  cout << " |                                                   |" << endl;
  cout << " | Leading order cross sections (mb):                |" << endl;
  for (int i = 0; i < int(sampleXStree.size()); ++i)
    cout << " |     " << sampleXStree.size()-1-i << "-jet:  "
         << setw(17) << scientific << setprecision(6)
         << sampleXStree[i] << "                     |" << endl;
  cout << " |                                                   |" << endl;
  cout << " | Leading-order subtractive cross sections (mb):    |" << endl;
  for (int i = 0; i < int(sampleXSsubtTree.size()); ++i)
    cout << " |     " << sampleXSsubtTree.size()-1-i+1 << "-jet:  "
         << setw(17) << scientific << setprecision(6)
         << sampleXSsubtTree[i] << "                     |" << endl;
  cout << " |                                                   |" << endl;
  cout << " |---------------------------------------------------|" << endl;
  cout << " |---------------------------------------------------|" << endl;
  cout << " | Inclusive cross sections:                         |" << endl;
  cout << " |                                                   |" << endl;
  cout << " | UMEPS merged inclusive cross section:             |" << endl;
  cout << " |    " << setw(17) << scientific << setprecision(6)
       << sigmaTotal << "  +-  " << setw(17) << sqrt(errorTotal) << " mb "
       << "   |" << endl;
  cout << " |                                                   |" << endl;
  cout << " | LO inclusive cross section:                       |" << endl;
  cout << " |    " << setw(17) << scientific << setprecision(6)
       << xsecLO.back() << " mb                           |" << endl;
  cout << " |                                                   |" << endl;
  cout << " *---------------------------------------------------*" << endl;
  cout << endl << endl;
  // Done
  return 0;
}

main87.cc


// main87.cc is a part of the PYTHIA event generator.
// Copyright (C) 2016 Torbjorn Sjostrand.
// PYTHIA is licenced under the GNU GPL version 2, see COPYING for details.
// Please respect the MCnet Guidelines, see GUIDELINES for details.
// This program is written by Stefan Prestel.
// It illustrates how to do NL3 merging, see the Matrix Element
// Merging page in the online manual. An example command is
//     ./main87 main87.cmnd w_production hepmcout87.dat
// where main87.cmnd supplies the commands, w_production provides the
// input LHE events, and hepmcout87.dat is the output file. This
// example requires HepMC.
#include "Pythia8/Pythia.h"
#include "Pythia8Plugins/HepMC2.h"
#include <unistd.h>
using namespace Pythia8;
//==========================================================================
// Example main programm to illustrate merging
int main( int argc, char* argv[] ){
  // Check that correct number of command-line arguments
  if (argc != 4) {
    cerr << " Unexpected number of command-line arguments ("<<argc<<"). \n"
         << " You are expected to provide the arguments" << endl
         << " 1. Input file for settings" << endl
         << " 2. Name of the input LHE file (with path), up to the '_tree'"
         << " or '_powheg' identifiers" << endl
         << " 3. Output hepmc file name" << endl
         << " Program stopped. " << endl;
    return 1;
  }
  Pythia pythia;
  // Input parameters:
  //  1. Input file for settings
  //  2. Path to input LHE file
  //  3. Output histogram path
  pythia.readFile(argv[1]);
  // Interface for conversion from Pythia8::Event to HepMC one.
  HepMC::Pythia8ToHepMC ToHepMC;
  // Specify file where HepMC events will be stored.
  HepMC::IO_GenEvent ascii_io(argv[3], std::ios::out);
  // Switch off warnings for parton-level events.
  ToHepMC.set_print_inconsistency(false);
  ToHepMC.set_free_parton_warnings(false);
  // Do not store cross section information, as this will be done manually.
  ToHepMC.set_store_pdf(false);
  ToHepMC.set_store_proc(false);
  ToHepMC.set_store_xsec(false);
  // Path to input events, with name up to the "_tree", "_powheg" identifier
  // included.
  string iPath = string(argv[2]);
  // Number of events
  int nEvent = pythia.mode("Main:numberOfEvents");
  // Maximal number of additional LO jets.
  int nMaxLO   = pythia.mode("Merging:nJetMax");
  // maximal number of additional NLO jets.
  int nMaxNLO  = pythia.mode("Merging:nJetMaxNLO");
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
  // Switch off all showering and MPI when extimating the cross section after
  // the merging scale cut.
  bool fsr = pythia.flag("PartonLevel:FSR");
  bool isr = pythia.flag("PartonLevel:ISR");
  bool mpi = pythia.flag("PartonLevel:MPI");
  bool had = pythia.flag("HadronLevel:all");
  pythia.settings.flag("PartonLevel:FSR",false);
  pythia.settings.flag("PartonLevel:ISR",false);
  pythia.settings.flag("HadronLevel:all",false);
  pythia.settings.flag("PartonLevel:MPI",false);
  // Switch on cross section estimation procedure.
  pythia.settings.flag("Merging:doXSectionEstimate", true);
  pythia.settings.flag("Merging:doNL3Tree", true);
  int njetcounterLO = nMaxLO;
  string iPathTree     = iPath + "_tree";
  vector<double> xsecLO;
  vector<double> nSelectedLO;
  vector<double> nAcceptLO;
  cout << endl << endl << endl;
  cout << "Start estimating nl3 tree level cross section" << endl;
  while(njetcounterLO >= 0){
    // From njetcounter, choose LHE file
    stringstream in;
    in   << "_" << njetcounterLO << ".lhe";
#ifdef GZIPSUPPORT
    if(access( (iPathTree+in.str()+".gz").c_str(), F_OK) != -1) in << ".gz";
#endif
    string LHEfile = iPathTree + in.str();
    pythia.settings.mode("Merging:nRequested", njetcounterLO);
    pythia.settings.mode("Beams:frameType", 4);
    pythia.settings.word("Beams:LHEF", LHEfile);
    pythia.init();
    // Start generation loop
    for( int iEvent=0; iEvent<nEvent; ++iEvent ){
      // Generate next event
      if( !pythia.next() ) {
        if( pythia.info.atEndOfFile() ){
          break;
        }
        else continue;
      }
    } // end loop over events to generate
    // print cross section, errors
    pythia.stat();
    xsecLO.push_back(pythia.info.sigmaGen());
    nSelectedLO.push_back(pythia.info.nSelected());
    nAcceptLO.push_back(pythia.info.nAccepted());
    // Restart with ME of a reduced the number of jets
    if( njetcounterLO > 0 )
      njetcounterLO--;
    else
      break;
  }
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
  cout << endl << endl << endl;
  cout << "Start estimating nl3 virtual corrections cross section" << endl;
  pythia.settings.flag("Merging:doNL3Tree",false);
  pythia.settings.flag("Merging:doNL3Loop",true);
  int njetcounterNLO = nMaxNLO;
  string iPathLoop= iPath + "_powheg";
  vector<double> xsecNLO;
  vector<double> nSelectedNLO;
  vector<double> nAcceptNLO;
  vector<int> strategyNLO;
  while(njetcounterNLO >= 0){
    // From njetcounter, choose LHE file
    stringstream in;
    in   << "_" << njetcounterNLO << ".lhe";
#ifdef GZIPSUPPORT
    if(access( (iPathLoop+in.str()+".gz").c_str(), F_OK) != -1) in << ".gz";
#endif
    string LHEfile = iPathLoop + in.str();
    pythia.settings.mode("Merging:nRequested", njetcounterNLO);
    pythia.settings.mode("Beams:frameType", 4);
    pythia.settings.word("Beams:LHEF", LHEfile);
    pythia.init();
    // Start generation loop
    for( int iEvent=0; iEvent<nEvent; ++iEvent ){
      // Generate next event
      if( !pythia.next() ) {
        if( pythia.info.atEndOfFile() ){
          break;
        }
        else continue;
      }
    } // end loop over events to generate
    // print cross section, errors
    pythia.stat();
    xsecNLO.push_back(pythia.info.sigmaGen());
    nSelectedNLO.push_back(pythia.info.nSelected());
    nAcceptNLO.push_back(pythia.info.nAccepted());
    strategyNLO.push_back(pythia.info.lhaStrategy());
    // Restart with ME of a reduced the number of jets
    if( njetcounterNLO > 0 )
      njetcounterNLO--;
    else
      break;
  }
  // Set k-factors
  int sizeLO   = int(xsecLO.size());
  int sizeNLO  = int(xsecNLO.size());
  double k0    = 1.;
  double k1    = 1.;
  double k2    = 1.;
  // Lowest order k-factor only
  if ( false ) k1 = k2 = k0 = xsecNLO.back() / xsecLO.back();
  // No k-factors
  if ( true ) k0 = k1 = k2 = 1.;
  cout << " K-Factors :" << endl;
  cout << "k0 = " << k0 << endl;
  cout << "k1 = " << k1 << endl;
  cout << "k2 = " << k2 << endl;
  // Switch off cross section estimation.
  pythia.settings.flag("Merging:doXSectionEstimate", false);
  // Switch showering and multiple interaction back on.
  pythia.settings.flag("PartonLevel:FSR",fsr);
  pythia.settings.flag("PartonLevel:ISR",isr);
  pythia.settings.flag("HadronLevel:all",had);
  pythia.settings.flag("PartonLevel:MPI",mpi);
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
  // Declare sample cross section for output.
  double sigmaTemp  = 0.;
  vector<double> sampleXStree;
  vector<double> sampleXSvirt;
  vector<double> sampleXSsubtTree;
  // Cross section an error.
  double sigmaTotal  = 0.;
  double errorTotal  = 0.;
  // Switch on tree-level processing.
  pythia.settings.flag("Merging:doNL3Tree",true);
  pythia.settings.flag("Merging:doNL3Loop",false);
  pythia.settings.flag("Merging:doNL3Subt",false);
  pythia.settings.mode("Merging:nRecluster",0);
  pythia.settings.mode("Merging:nRequested", -1);
  njetcounterLO = nMaxLO;
  iPathTree     = iPath + "_tree";
  while(njetcounterLO >= 0){
    // Set k factors
    pythia.settings.parm("Merging:kFactor0j", k0);
    pythia.settings.parm("Merging:kFactor1j", k1);
    pythia.settings.parm("Merging:kFactor2j", k2);
    // From njetcounter, choose LHE file
    stringstream in;
    in   << "_" << njetcounterLO << ".lhe";
#ifdef GZIPSUPPORT
    if(access( (iPathTree+in.str()+".gz").c_str(), F_OK) != -1) in << ".gz";
#endif
    string LHEfile = iPathTree + in.str();
    cout << endl << endl << endl
         << "Start tree level treatment for " << njetcounterLO << " jets"
         << endl;
    pythia.settings.mode("Merging:nRequested", njetcounterLO);
    pythia.settings.mode("Beams:frameType", 4);
    pythia.settings.word("Beams:LHEF", LHEfile);
    pythia.init();
    // Remember position in vector of cross section estimates.
    int iNow = sizeLO-1-njetcounterLO;
    // Start generation loop
    for( int iEvent=0; iEvent<nEvent; ++iEvent ){
      // Generate next event
      if( !pythia.next() ) {
        if( pythia.info.atEndOfFile() ) break;
        else continue;
      }
      // Get event weight(s).
      double weightNLO = pythia.info.mergingWeightNLO();
      double evtweight = pythia.info.weight();
      weightNLO *= evtweight;
      // Do not print zero-weight events.
      if ( weightNLO == 0. ) continue;
      // Construct new empty HepMC event.
      HepMC::GenEvent* hepmcevt = new HepMC::GenEvent();
      // Get correct cross section from previous estimate.
      double normhepmc = xsecLO[iNow] / nAcceptLO[iNow];
      // powheg box weighted events
      if( abs(pythia.info.lhaStrategy()) == 4 )
        normhepmc = 1. / (1e9*nSelectedLO[iNow]);
      // Set event weight.
      hepmcevt->weights().push_back(weightNLO*normhepmc);
      // Fill HepMC event.
      ToHepMC.fill_next_event( pythia, hepmcevt );
      // Add the weight of the current event to the cross section.
      sigmaTotal += weightNLO*normhepmc;
      sigmaTemp  += weightNLO*normhepmc;
      errorTotal += pow2(weightNLO*normhepmc);
      // Report cross section to hepmc
      HepMC::GenCrossSection xsec;
      xsec.set_cross_section( sigmaTotal*1e9, pythia.info.sigmaErr()*1e9 );
      hepmcevt->set_cross_section( xsec );
      // Write the HepMC event to file. Done with it.
      ascii_io << hepmcevt;
      delete hepmcevt;
    } // end loop over events to generate
    // print cross section, errors
    pythia.stat();
    // Save sample cross section for output.
    sampleXStree.push_back(sigmaTemp);
    sigmaTemp = 0.;
    // Restart with ME of a reduced the number of jets
    if( njetcounterLO > 0 )
      njetcounterLO--;
    else
      break;
  }
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
  cout << endl << endl << endl;
  cout << "Start nl3 virtual corrections part" << endl;
  // Switch on loop-level processing.
  pythia.settings.flag("Merging:doNL3Tree",false);
  pythia.settings.flag("Merging:doNL3Loop",true);
  pythia.settings.flag("Merging:doNL3Subt",false);
  pythia.settings.mode("Merging:nRecluster",0);
  njetcounterNLO = nMaxNLO;
  iPathLoop      = iPath + "_powheg";
  while(njetcounterNLO >= 0){
    // From njetcounter, choose LHE file
    stringstream in;
    in   << "_" << njetcounterNLO << ".lhe";
#ifdef GZIPSUPPORT
    if(access( (iPathLoop+in.str()+".gz").c_str(), F_OK) != -1) in << ".gz";
#endif
    string LHEfile = iPathLoop + in.str();
    cout << endl << endl << endl
         << "Start loop level treatment for " << njetcounterNLO << " jets"
         << endl;
    pythia.settings.mode("Merging:nRequested", njetcounterNLO);
    pythia.settings.mode("Beams:frameType", 4);
    pythia.settings.word("Beams:LHEF", LHEfile);
    pythia.init();
    // Remember position in vector of cross section estimates.
    int iNow = sizeNLO-1-njetcounterNLO;
    // Start generation loop
    for( int iEvent=0; iEvent<nEvent; ++iEvent ){
      // Generate next event
      if( !pythia.next() ) {
        if( pythia.info.atEndOfFile() ) break;
        else continue;
      }
      // Get event weight(s).
      double weightNLO = pythia.info.mergingWeightNLO();
      double evtweight = pythia.info.weight();
      weightNLO *= evtweight;
      // Do not print zero-weight events.
      if ( weightNLO == 0. ) continue;
      // Construct new empty HepMC event.
      HepMC::GenEvent* hepmcevt = new HepMC::GenEvent();
      // Get correct cross section from previous estimate.
      double normhepmc = xsecNLO[iNow] / nAcceptNLO[iNow];
      // powheg box weighted events
      if( abs(pythia.info.lhaStrategy()) == 4 )
        normhepmc = 1. / (1e9*nSelectedNLO[iNow]);
      // Set event weight.
      hepmcevt->weights().push_back(weightNLO*normhepmc);
      // Fill HepMC event.
      ToHepMC.fill_next_event( pythia, hepmcevt );
      // Add the weight of the current event to the cross section.
      sigmaTotal += weightNLO*normhepmc;
      sigmaTemp  += weightNLO*normhepmc;
      errorTotal += pow2(weightNLO*normhepmc);
      // Report cross section to hepmc
      HepMC::GenCrossSection xsec;
      xsec.set_cross_section( sigmaTotal*1e9, pythia.info.sigmaErr()*1e9 );
      hepmcevt->set_cross_section( xsec );
      // Write the HepMC event to file. Done with it.
      ascii_io << hepmcevt;
      delete hepmcevt;
    } // end loop over events to generate
    // print cross section, errors
    pythia.stat();
    // Save sample cross section for output.
    sampleXSvirt.push_back(sigmaTemp);
    sigmaTemp = 0.;
    // Restart with ME of a reduced the number of jets
    if( njetcounterNLO > 0)
      njetcounterNLO--;
    else
      break;
  }
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
  cout << endl << endl << endl;
  cout << "Shower subtractive events" << endl;
  // Switch on processing of counter-events.
  pythia.settings.flag("Merging:doNL3Tree",false);
  pythia.settings.flag("Merging:doNL3Loop",false);
  pythia.settings.flag("Merging:doNL3Subt",true);
  pythia.settings.mode("Merging:nRecluster",1);
  pythia.settings.mode("Merging:nRequested", -1);
  int nMaxCT        = nMaxNLO + 1;
  int njetcounterCT = nMaxCT;
  string iPathSubt  = iPath + "_tree";
  while(njetcounterCT >= 1){
    // From njetcounter, choose LHE file
    stringstream in;
    in   << "_" << njetcounterCT << ".lhe";
#ifdef GZIPSUPPORT
    if(access( (iPathSubt+in.str()+".gz").c_str(), F_OK) != -1) in << ".gz";
#endif
    string LHEfile = iPathSubt + in.str();
    cout << endl << endl << endl
         << "Start subtractive treatment for " << njetcounterCT << " jets"
         << endl;
    pythia.settings.mode("Merging:nRequested", njetcounterCT);
    pythia.settings.mode("Beams:frameType", 4);
    pythia.settings.word("Beams:LHEF", LHEfile);
    pythia.init();
    // Remember position in vector of cross section estimates.
    int iNow = sizeLO-1-njetcounterCT;
    // Start generation loop
    for( int iEvent=0; iEvent<nEvent; ++iEvent ){
      // Generate next event
      if( !pythia.next() ) {
        if( pythia.info.atEndOfFile() ) break;
        else continue;
      }
      // Get event weight(s).
      double weightNLO = pythia.info.mergingWeightNLO();
      double evtweight = pythia.info.weight();
      weightNLO *= evtweight;
      // Do not print zero-weight events.
      if ( weightNLO == 0. ) continue;
      // Construct new empty HepMC event.
      HepMC::GenEvent* hepmcevt = new HepMC::GenEvent();
      // Get correct cross section from previous estimate.
      double normhepmc = -1.*xsecLO[iNow] / nAcceptLO[iNow];
      // powheg box weighted events
      if( abs(pythia.info.lhaStrategy()) == 4 )
        normhepmc = -1. / (1e9*nSelectedLO[iNow]);
      // Set event weight.
      hepmcevt->weights().push_back( weightNLO*normhepmc);
      // Fill HepMC event.
      ToHepMC.fill_next_event( pythia, hepmcevt );
      // Add the weight of the current event to the cross section.
      sigmaTotal += weightNLO*normhepmc;
      sigmaTemp  += weightNLO*normhepmc;
      errorTotal += pow2(weightNLO*normhepmc);
      // Report cross section to hepmc
      HepMC::GenCrossSection xsec;
      xsec.set_cross_section( sigmaTotal*1e9, pythia.info.sigmaErr()*1e9 );
      hepmcevt->set_cross_section( xsec );
      // Write the HepMC event to file. Done with it.
      ascii_io << hepmcevt;
      delete hepmcevt;
    } // end loop over events to generate
    // print cross section, errors
    pythia.stat();
    // Save sample cross section for output.
    sampleXSsubtTree.push_back(sigmaTemp);
    sigmaTemp = 0.;
    // Restart with ME of a reduced the number of jets
    if( njetcounterCT > 1 )
      njetcounterCT--;
    else
      break;
  }
  // Print cross section information.
  cout << endl << endl;
  cout << " *---------------------------------------------------*" << endl;
  cout << " |                                                   |" << endl;
  cout << " | Sample cross sections after NL3 merging           |" << endl;
  cout << " |                                                   |" << endl;
  cout << " | Leading order cross sections (mb):                |" << endl;
  for (int i = 0; i < int(sampleXStree.size()); ++i)
    cout << " |     " << sampleXStree.size()-1-i << "-jet:  "
         << setw(17) << scientific << setprecision(6)
         << sampleXStree[i] << "                     |" << endl;
  cout << " |                                                   |" << endl;
  cout << " | NLO order cross sections (mb):                    |" << endl;
  for (int i = 0; i < int(sampleXSvirt.size()); ++i)
    cout << " |     " << sampleXSvirt.size()-1-i << "-jet:  "
         << setw(17) << scientific << setprecision(6)
         << sampleXSvirt[i] << "                     |" << endl;
  cout << " |                                                   |" << endl;
  cout << " | Leading-order subtractive cross sections (mb):    |" << endl;
  for (int i = 0; i < int(sampleXSsubtTree.size()); ++i)
    cout << " |     " << sampleXSsubtTree.size()-1-i+1 << "-jet:  "
         << setw(17) << scientific << setprecision(6)
         << sampleXSsubtTree[i] << "                     |" << endl;
  cout << " |                                                   |" << endl;
  cout << " |---------------------------------------------------|" << endl;
  cout << " |---------------------------------------------------|" << endl;
  cout << " | Inclusive cross sections:                         |" << endl;
  cout << " |                                                   |" << endl;
  cout << " | NL3 merged inclusive cross section:               |" << endl;
  cout << " |    " << setw(17) << scientific << setprecision(6)
       << sigmaTotal << "  +-  " << setw(17) << sqrt(errorTotal) << " mb "
       << "   |" << endl;
  cout << " |                                                   |" << endl;
  cout << " | NLO inclusive cross section:                      |" << endl;
  cout << " |    " << setw(17) << scientific << setprecision(6)
       << xsecNLO.back() << " mb                           |"  << endl;
  cout << " |                                                   |" << endl;
  cout << " | LO inclusive cross section:                       |" << endl;
  cout << " |    " << setw(17) << scientific << setprecision(6)
       << xsecLO.back() << " mb                           |" << endl;
  cout << " |                                                   |" << endl;
  cout << " *---------------------------------------------------*" << endl;
  cout << endl << endl;
  // Done
  return 0;
}

main88.cc


// main88.cc is a part of the PYTHIA event generator.
// Copyright (C) 2016 Torbjorn Sjostrand.
// PYTHIA is licenced under the GNU GPL version 2, see COPYING for details.
// Please respect the MCnet Guidelines, see GUIDELINES for details.
// This program is written by Stefan Prestel.
// It illustrates how to do UNLOPS merging, see the Matrix Element
// Merging page in the online manual. An example command is
//     ./main88 main88.cmnd w_production hepmcout88.dat
// where main88.cmnd supplies the commands, w_production provides the
// input LHE events, and hepmcout88.dat is the output file. This
// example requires HepMC.
#include "Pythia8/Pythia.h"
#include "Pythia8Plugins/HepMC2.h"
#include <unistd.h>
using namespace Pythia8;
//==========================================================================
// Example main programm to illustrate UNLOPS merging
int main( int argc, char* argv[] ){
  // Check that correct number of command-line arguments
  if (argc != 4) {
    cerr << " Unexpected number of command-line arguments ("<<argc<<"). \n"
         << " You are expected to provide the arguments" << endl
         << " 1. Input file for settings" << endl
         << " 2. Name of the input LHE file (with path), up to the '_tree'"
         << " or '_powheg' identifiers" << endl
         << " 3. Output hepmc file name" << endl
         << " Program stopped. " << endl;
    return 1;
  }
  Pythia pythia;
  // Input parameters:
  //  1. Input file for settings
  //  2. Path to input LHE file
  //  3. Output histogram path
  pythia.readFile(argv[1]);
  // Interface for conversion from Pythia8::Event to HepMC one.
  HepMC::Pythia8ToHepMC ToHepMC;
  // Specify file where HepMC events will be stored.
  HepMC::IO_GenEvent ascii_io(argv[3], std::ios::out);
  // Switch off warnings for parton-level events.
  ToHepMC.set_print_inconsistency(false);
  ToHepMC.set_free_parton_warnings(false);
  // Do not store cross section information, as this will be done manually.
  ToHepMC.set_store_pdf(false);
  ToHepMC.set_store_proc(false);
  ToHepMC.set_store_xsec(false);
  // Path to input events, with name up to the "_tree", "_powheg" identifier
  // included.
  string iPath = string(argv[2]);
  // Number of events
  int nEvent   = pythia.mode("Main:numberOfEvents");
  // Maximal number of additional LO jets.
  int nMaxLO   = pythia.mode("Merging:nJetMax");
  // maximal number of additional NLO jets.
  int nMaxNLO  = pythia.mode("Merging:nJetMaxNLO");
//----------------------------------------------------------------------------
//----------------------------------------------------------------------------
  // Switch off all showering and MPI when extimating the cross section after
  // the merging scale cut.
  bool fsr = pythia.flag("PartonLevel:FSR");
  bool isr = pythia.flag("PartonLevel:ISR");
  bool mpi = pythia.flag("PartonLevel:MPI");
  bool had = pythia.flag("HadronLevel:all");
  pythia.settings.flag("PartonLevel:FSR",false);
  pythia.settings.flag("PartonLevel:ISR",false);
  pythia.settings.flag("HadronLevel:all",false);
  pythia.settings.flag("PartonLevel:MPI",false);
  // Switch on cross section estimation procedure.
  pythia.settings.flag("Merging:doXSectionEstimate", true);
  pythia.settings.flag("Merging:doUNLOPSTree", true);
  int njetcounterLO  = nMaxLO;
  string iPathTree   = iPath + "_tree";
  // Save estimates in vectors.
  vector<double> xsecLO;
  vector<double> nSelectedLO;
  vector<double> nAcceptLO;
  vector<int> strategyLO;
  cout << endl << endl << endl;
  cout << "Start estimating unlops tree level cross section" << endl;
  while(njetcounterLO >= 0){
    // From njetcounter, choose LHE file
    stringstream in;
    in   << "_" << njetcounterLO << ".lhe";
#ifdef GZIPSUPPORT
    if(access( (iPathTree+in.str()+".gz").c_str(), F_OK) != -1) in << ".gz";
#endif
    string LHEfile = iPathTree + in.str();
    pythia.settings.mode("Merging:nRequested", njetcounterLO);
    pythia.settings.mode("Beams:frameType", 4);
    pythia.settings.word("Beams:LHEF", LHEfile);
    pythia.init();
    // Start generation loop
    for( int iEvent=0; iEvent<nEvent; ++iEvent ){
      // Generate next event
      if( !pythia.next() ) {
        if( pythia.info.atEndOfFile() ){
          break;
        }
        else continue;
      }
    } // end loop over events to generate
    // print cross section, errors
    pythia.stat();
    xsecLO.push_back(pythia.info.sigmaGen());
    nSelectedLO.push_back(pythia.info.nSelected());
    nAcceptLO.push_back(pythia.info.nAccepted());
    strategyLO.push_back(pythia.info.lhaStrategy());
    // Restart with ME of a reduced the number of jets
    if( njetcounterLO > 0 )
      njetcounterLO--;
    else
      break;
  }
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
  cout << endl << endl << endl;
  cout << "Start estimating unlops virtual corrections cross section" << endl;
  pythia.settings.flag("Merging:doUNLOPSTree",false);
  pythia.settings.flag("Merging:doUNLOPSLoop", true);
  int njetcounterNLO  = nMaxNLO;
  string iPathLoop    = iPath + "_powheg";
  // Save estimates in vectors.
  vector<double> xsecNLO;
  vector<double> nSelectedNLO;
  vector<double> nAcceptNLO;
  vector<int> strategyNLO;
  while(njetcounterNLO >= 0){
    // From njetcounter, choose LHE file
    stringstream in;
    in   << "_" << njetcounterNLO << ".lhe";
#ifdef GZIPSUPPORT
    if(access( (iPathLoop+in.str()+".gz").c_str(), F_OK) != -1) in << ".gz";
#endif
    string LHEfile = iPathLoop + in.str();
    pythia.settings.mode("Merging:nRequested", njetcounterNLO);
    pythia.settings.mode("Beams:frameType", 4);
    pythia.settings.word("Beams:LHEF", LHEfile);
    pythia.init();
    // Start generation loop
    for( int iEvent=0; iEvent<nEvent; ++iEvent ){
      // Generate next event
      if( !pythia.next() ) {
        if( pythia.info.atEndOfFile() ){
          break;
        }
        else continue;
      }
    } // end loop over events to generate
    // print cross section, errors
    pythia.stat();
    xsecNLO.push_back(pythia.info.sigmaGen());
    nSelectedNLO.push_back(pythia.info.nSelected());
    nAcceptNLO.push_back(pythia.info.nAccepted());
    strategyNLO.push_back(pythia.info.lhaStrategy());
    // Restart with ME of a reduced the number of jets
    if( njetcounterNLO > 0 )
      njetcounterNLO--;
    else
      break;
  }
  int sizeLO   = int(xsecLO.size());
  int sizeNLO  = int(xsecNLO.size());
  // Switch off cross section estimation.
  pythia.settings.flag("Merging:doXSectionEstimate", false);
  // Switch showering and multiple interaction back on.
  pythia.settings.flag("PartonLevel:FSR",fsr);
  pythia.settings.flag("PartonLevel:ISR",isr);
  pythia.settings.flag("HadronLevel:all",had);
  pythia.settings.flag("PartonLevel:MPI",mpi);
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
  // Declare sample cross section for output.
  double sigmaTemp  = 0.;
  vector<double> sampleXStree;
  vector<double> sampleXSvirt;
  vector<double> sampleXSsubtTree;
  vector<double> sampleXSsubtVirt;
  // Cross section an error.
  double sigmaTotal  = 0.;
  double errorTotal  = 0.;
  // Switch on tree-level processing.
  pythia.settings.flag("Merging:doUNLOPSTree",true);
  pythia.settings.flag("Merging:doUNLOPSLoop",false);
  pythia.settings.flag("Merging:doUNLOPSSubt",false);
  pythia.settings.flag("Merging:doUNLOPSSubtNLO",false);
  pythia.settings.mode("Merging:nRecluster",0);
  // Start looping through input event files.
  njetcounterLO = nMaxLO;
  iPathTree     = iPath + "_tree";
  while(njetcounterLO >= 0){
    // From njetcounter, choose LHE file
    stringstream in;
    in   << "_" << njetcounterLO << ".lhe";
#ifdef GZIPSUPPORT
    if(access( (iPathTree+in.str()+".gz").c_str(), F_OK) != -1) in << ".gz";
#endif
    string LHEfile = iPathTree + in.str();
    cout << endl << endl << endl
         << "Start tree level treatment for " << njetcounterLO << " jets"
         << endl;
    // UNLOPS does not contain a zero-jet tree-level sample.
    if ( njetcounterLO == 0 ) break;
    pythia.settings.mode("Merging:nRequested", njetcounterLO);
    pythia.settings.mode("Beams:frameType", 4);
    pythia.settings.word("Beams:LHEF", LHEfile);
    pythia.init();
    // Remember position in vector of cross section estimates.
    int iNow = sizeLO-1-njetcounterLO;
    // Start generation loop
    for( int iEvent=0; iEvent<nEvent; ++iEvent ){
      // Generate next event
      if( !pythia.next() ) {
        if( pythia.info.atEndOfFile() ) break;
        else continue;
      }
      // Get event weight(s).
      double weightNLO  = pythia.info.mergingWeightNLO();
      double evtweight  = pythia.info.weight();
      weightNLO        *= evtweight;
      // Do not print zero-weight events.
      if ( weightNLO == 0. ) continue;
      // Construct new empty HepMC event.
      HepMC::GenEvent* hepmcevt = new HepMC::GenEvent();
      // Get correct cross section from previous estimate.
      double normhepmc = xsecLO[iNow] / nAcceptLO[iNow];
      // Set hepmc event weight.
      hepmcevt->weights().push_back(weightNLO*normhepmc);
      // Fill HepMC event.
      ToHepMC.fill_next_event( pythia, hepmcevt );
      // Add the weight of the current event to the cross section.
      sigmaTotal += weightNLO*normhepmc;
      sigmaTemp  += weightNLO*normhepmc;
      errorTotal += pow2(weightNLO*normhepmc);
      // Report cross section to hepmc.
      HepMC::GenCrossSection xsec;
      xsec.set_cross_section( sigmaTotal*1e9, pythia.info.sigmaErr()*1e9 );
      hepmcevt->set_cross_section( xsec );
      // Write the HepMC event to file. Done with it.
      ascii_io << hepmcevt;
      delete hepmcevt;
    } // end loop over events to generate
    // print cross section, errors
    pythia.stat();
    // Restart with ME of a reduced the number of jets
    if( njetcounterLO > 0 )
      njetcounterLO--;
    else
      break;
    // Save sample cross section for output.
    sampleXStree.push_back(sigmaTemp);
    sigmaTemp = 0.;
  }
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
  cout << endl << endl << endl;
  cout << "Start unlops virtual corrections part" << endl;
  // Switch on loop-level processing.
  pythia.settings.flag("Merging:doUNLOPSTree",false);
  pythia.settings.flag("Merging:doUNLOPSLoop",true);
  pythia.settings.flag("Merging:doUNLOPSSubt",false);
  pythia.settings.flag("Merging:doUNLOPSSubtNLO",false);
  pythia.settings.mode("Merging:nRecluster",0);
  njetcounterNLO = nMaxNLO;
  iPathLoop= iPath + "_powheg";
  while(njetcounterNLO >= 0){
    // From njetcounter, choose LHE file
    stringstream in;
    in   << "_" << njetcounterNLO << ".lhe";
#ifdef GZIPSUPPORT
    if(access( (iPathLoop+in.str()+".gz").c_str(), F_OK) != -1) in << ".gz";
#endif
    string LHEfile = iPathLoop + in.str();
    cout << endl << endl << endl
         << "Start loop level treatment for " << njetcounterNLO << " jets"
         << endl;
    pythia.settings.mode("Merging:nRequested", njetcounterNLO);
    pythia.settings.mode("Beams:frameType", 4);
    pythia.settings.word("Beams:LHEF", LHEfile);
    pythia.init();
    // Remember position in vector of cross section estimates.
    int iNow = sizeNLO-1-njetcounterNLO;
    // Start generation loop
    for( int iEvent=0; iEvent<nEvent; ++iEvent ){
      // Generate next event
      if( !pythia.next() ) {
        if( pythia.info.atEndOfFile() ) break;
        else continue;
      }
      // Get event weight(s).
      double weightNLO  = pythia.info.mergingWeightNLO();
      double evtweight  = pythia.info.weight();
      weightNLO        *= evtweight;
      // Do not print zero-weight events.
      if ( weightNLO == 0. ) continue;
      // Construct new empty HepMC event.
      HepMC::GenEvent* hepmcevt = new HepMC::GenEvent();
      // Get correct cross section from previous estimate.
      double normhepmc = xsecNLO[iNow] / nAcceptNLO[iNow];
      // powheg weighted events
      if( abs(strategyNLO[iNow]) == 4)
        normhepmc = 1. / (1e9*nSelectedNLO[iNow]);
      // Set hepmc event weight.
      hepmcevt->weights().push_back(weightNLO*normhepmc);
      // Fill HepMC event.
      ToHepMC.fill_next_event( pythia, hepmcevt );
      // Add the weight of the current event to the cross section.
      sigmaTotal += weightNLO*normhepmc;
      sigmaTemp  += weightNLO*normhepmc;
      errorTotal += pow2(weightNLO*normhepmc);
      // Report cross section to hepmc
      HepMC::GenCrossSection xsec;
      xsec.set_cross_section( sigmaTotal*1e9, pythia.info.sigmaErr()*1e9 );
      hepmcevt->set_cross_section( xsec );
      // Write the HepMC event to file. Done with it.
      ascii_io << hepmcevt;
      delete hepmcevt;
    } // end loop over events to generate
    // print cross section, errors
    pythia.stat();
    // Save sample cross section for output.
    sampleXSvirt.push_back(sigmaTemp);
    sigmaTemp = 0.;
    // Restart with ME of a reduced the number of jets
    if( njetcounterNLO > 0)
      njetcounterNLO--;
    else
      break;
  }
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
  cout << endl << endl << endl;
  cout << "Shower subtractive events" << endl;
  // Switch on processing of counter-events.
  pythia.settings.flag("Merging:doUNLOPSTree",false);
  pythia.settings.flag("Merging:doUNLOPSLoop",false);
  pythia.settings.flag("Merging:doUNLOPSSubt",true);
  pythia.settings.flag("Merging:doUNLOPSSubtNLO",false);
  pythia.settings.mode("Merging:nRecluster",1);
  int nMaxCT = nMaxLO;
  int njetcounterCT = nMaxCT;
  string iPathSubt= iPath + "_tree";
  while(njetcounterCT >= 1){
    // From njetcounter, choose LHE file
    stringstream in;
    in   << "_" << njetcounterCT << ".lhe";
#ifdef GZIPSUPPORT
    if(access( (iPathSubt+in.str()+".gz").c_str(), F_OK) != -1) in << ".gz";
#endif
    string LHEfile = iPathSubt + in.str();
    cout << endl << endl << endl
         << "Start subtractive treatment for " << njetcounterCT << " jets"
         << endl;
    pythia.settings.mode("Merging:nRequested", njetcounterCT);
    pythia.settings.mode("Beams:frameType", 4);
    pythia.settings.word("Beams:LHEF", LHEfile);
    pythia.init();
    // Remember position in vector of cross section estimates.
    int iNow = sizeLO-1-njetcounterCT;
    // Start generation loop
    for( int iEvent=0; iEvent<nEvent; ++iEvent ){
      // Generate next event
      if( !pythia.next() ) {
        if( pythia.info.atEndOfFile() ) break;
        else continue;
      }
      // Get event weight(s).
      double weightNLO  = pythia.info.mergingWeightNLO();
      double evtweight  = pythia.info.weight();
      weightNLO        *= evtweight;
      // Do not print zero-weight events.
      if ( weightNLO == 0. ) continue;
      // Construct new empty HepMC event.
      HepMC::GenEvent* hepmcevt = new HepMC::GenEvent();
      // Get correct cross section from previous estimate.
      double normhepmc = -1*xsecLO[iNow] / nAcceptLO[iNow];
      // Set hepmc event weight.
      hepmcevt->weights().push_back(weightNLO*normhepmc);
      // Fill HepMC event.
      ToHepMC.fill_next_event( pythia, hepmcevt );
      // Add the weight of the current event to the cross section.
      sigmaTotal += weightNLO*normhepmc;
      sigmaTemp  += weightNLO*normhepmc;
      errorTotal += pow2(weightNLO*normhepmc);
      // Report cross section to hepmc.
      HepMC::GenCrossSection xsec;
      xsec.set_cross_section( sigmaTotal*1e9, pythia.info.sigmaErr()*1e9 );
      hepmcevt->set_cross_section( xsec );
      // Write the HepMC event to file. Done with it.
      ascii_io << hepmcevt;
      delete hepmcevt;
    } // end loop over events to generate
    // print cross section, errors
    pythia.stat();
    // Save sample cross section for output.
    sampleXSsubtTree.push_back(sigmaTemp);
    sigmaTemp = 0.;
    // Restart with ME of a reduced the number of jets
    if( njetcounterCT > 1 )
      njetcounterCT--;
    else
      break;
  }
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
  cout << endl << endl << endl;
  cout << "Shower subtractive events" << endl;
  pythia.settings.flag("Merging:doUNLOPSTree",false);
  pythia.settings.flag("Merging:doUNLOPSLoop",false);
  pythia.settings.flag("Merging:doUNLOPSSubt",false);
  pythia.settings.flag("Merging:doUNLOPSSubtNLO",true);
  pythia.settings.mode("Merging:nRecluster",1);
  nMaxCT = nMaxNLO;
  njetcounterCT = nMaxCT;
  iPathSubt= iPath + "_powheg";
  while(njetcounterCT >= 1){
    // From njetcounter, choose LHE file
    stringstream in;
    in   << "_" << njetcounterCT << ".lhe";
#ifdef GZIPSUPPORT
    if(access( (iPathSubt+in.str()+".gz").c_str(), F_OK) != -1) in << ".gz";
#endif
    string LHEfile = iPathSubt + in.str();
    cout << endl << endl << endl
         << "Start subtractive treatment for " << njetcounterCT << " nlo jets"
         << endl;
    pythia.settings.mode("Merging:nRequested", njetcounterCT);
    pythia.settings.mode("Beams:frameType", 4);
    pythia.settings.word("Beams:LHEF", LHEfile);
    pythia.init();
    // Remember position in vector of cross section estimates.
    int iNow = sizeNLO-1-njetcounterCT;
    // Start generation loop
    for( int iEvent=0; iEvent<nEvent; ++iEvent ){
      // Generate next event
      if( !pythia.next() ) {
        if( pythia.info.atEndOfFile() ) break;
        else continue;
      }
      // Get event weight(s).
      double weightNLO  = pythia.info.mergingWeightNLO();
      double evtweight  = pythia.info.weight();
      weightNLO        *= evtweight;
      // Do not print zero-weight events.
      if ( weightNLO == 0. ) continue;
      // Construct new empty HepMC event.
      HepMC::GenEvent* hepmcevt = new HepMC::GenEvent();
      // Get correct cross section from previous estimate.
      double normhepmc = -1*xsecNLO[iNow] / nAcceptNLO[iNow];
      // powheg weighted events
      if( abs(strategyNLO[iNow]) == 4)
        normhepmc = -1. / (1e9*nSelectedNLO[iNow]);
      // Set hepmc event weight.
      hepmcevt->weights().push_back(weightNLO*normhepmc);
      // Fill HepMC event.
      ToHepMC.fill_next_event( pythia, hepmcevt );
      // Add the weight of the current event to the cross section.
      sigmaTotal += weightNLO*normhepmc;
      sigmaTemp  += weightNLO*normhepmc;
      errorTotal += pow2(weightNLO*normhepmc);
      // Report cross section to hepmc.
      HepMC::GenCrossSection xsec;
      xsec.set_cross_section( sigmaTotal*1e9, pythia.info.sigmaErr()*1e9 );
      hepmcevt->set_cross_section( xsec );
      // Write the HepMC event to file. Done with it.
      ascii_io << hepmcevt;
      delete hepmcevt;
    } // end loop over events to generate
    // print cross section, errors
    pythia.stat();
    // Save sample cross section for output.
    sampleXSsubtVirt.push_back(sigmaTemp);
    sigmaTemp = 0.;
    // Restart with ME of a reduced the number of jets
    if( njetcounterCT > 1 )
      njetcounterCT--;
    else
      break;
  }
  // Print cross section information.
  cout << endl << endl;
  cout << " *---------------------------------------------------*" << endl;
  cout << " |                                                   |" << endl;
  cout << " | Sample cross sections after UNLOPS merging        |" << endl;
  cout << " |                                                   |" << endl;
  cout << " | Leading order cross sections (mb):                |" << endl;
  for (int i = 0; i < int(sampleXStree.size()); ++i)
    cout << " |     " << sampleXStree.size()-1-i+1 << "-jet:  "
         << setw(17) << scientific << setprecision(6)
         << sampleXStree[i] << "                     |" << endl;
  cout << " |     (No 0-jet tree-level sample in UNLOPS)        |" << endl;
  cout << " |                                                   |" << endl;
  cout << " | NLO order cross sections (mb):                    |" << endl;
  for (int i = 0; i < int(sampleXSvirt.size()); ++i)
    cout << " |     " << sampleXSvirt.size()-1-i << "-jet:  "
         << setw(17) << scientific << setprecision(6)
         << sampleXSvirt[i] << "                     |" << endl;
  cout << " |                                                   |" << endl;
  cout << " | Leading-order subtractive cross sections (mb):    |" << endl;
  for (int i = 0; i < int(sampleXSsubtTree.size()); ++i)
    cout << " |     " << sampleXSsubtTree.size()-1-i+1 << "-jet:  "
         << setw(17) << scientific << setprecision(6)
         << sampleXSsubtTree[i] << "                     |" << endl;
  cout << " |                                                   |" << endl;
  if ( sampleXSsubtVirt.size() > 0) {
  cout << " | NLO subtractive cross sections (mb):              |" << endl;
  for (int i = 0; i < int(sampleXSsubtVirt.size()); ++i)
    cout << " |     " << sampleXSsubtVirt.size()-1-i+1 << "-jet:  "
         << setw(17) << scientific << setprecision(6)
         << sampleXSsubtVirt[i] << "                     |" << endl;
  cout << " |                                                   |" << endl;
  }
  cout << " |---------------------------------------------------|" << endl;
  cout << " |---------------------------------------------------|" << endl;
  cout << " | Inclusive cross sections:                         |" << endl;
  cout << " |                                                   |" << endl;
  cout << " | UNLOPS merged inclusive cross section:            |" << endl;
  cout << " |    " << setw(17) << scientific << setprecision(6)
       << sigmaTotal << "  +-  " << setw(17) << sqrt(errorTotal) << " mb "
       << "   |" << endl;
  cout << " |                                                   |" << endl;
  cout << " | NLO inclusive cross section:                      |" << endl;
  cout << " |    " << setw(17) << scientific << setprecision(6)
       << xsecNLO.back() << " mb                           |"  << endl;
  cout << " |                                                   |" << endl;
  cout << " | LO inclusive cross section:                       |" << endl;
  cout << " |    " << setw(17) << scientific << setprecision(6)
       << xsecLO.back() << " mb                           |" << endl;
  cout << " |                                                   |" << endl;
  cout << " *---------------------------------------------------*" << endl;
  cout << endl << endl;
  // Done
  return 0;
}

main89.cc


// main89.cc is a part of the PYTHIA event generator.
// Copyright (C) 2016 Torbjorn Sjostrand.
// PYTHIA is licenced under the GNU GPL version 2, see COPYING for details.
// Please respect the MCnet Guidelines, see GUIDELINES for details.
// This program is written by Stefan Prestel.
// It illustrates how to do run PYTHIA with LHEF input, allowing a
// sample-by-sample generation of
// a) Non-matched/non-merged events
// b) MLM jet-matched events (kT-MLM, shower-kT, FxFx)
// c) CKKW-L and UMEPS-merged events
// d) UNLOPS NLO merged events
// see the respective sections in the online manual for details.
#include "Pythia8/Pythia.h"
#include "Pythia8Plugins/HepMC2.h"
#include <unistd.h>
// Include UserHooks for Jet Matching.
#include "Pythia8Plugins/CombineMatchingInput.h"
// Include UserHooks for randomly choosing between integrated and
// non-integrated treatment for unitarised merging.
#include "Pythia8Plugins/aMCatNLOHooks.h"
using namespace Pythia8;
//==========================================================================
// Example main programm to illustrate merging.
int main( int argc, char* argv[] ){
  // Check that correct number of command-line arguments
  if (argc != 3) {
    cerr << " Unexpected number of command-line arguments ("<<argc<<"). \n"
         << " You are expected to provide the arguments" << endl
         << " 1. Input file for settings" << endl
         << " 2. Output file for HepMC events" << endl
         << " Program stopped. " << endl;
    return 1;
  }
  Pythia pythia;
  // New setting to allow processing of multiple input LHEFs.
  pythia.settings.addMode("LHEFInputs:nSubruns",0,true,false,0,100);
  // Input parameters:
  pythia.readFile(argv[1],0);
  // Interface for conversion from Pythia8::Event to HepMC one.
  HepMC::Pythia8ToHepMC ToHepMC;
  // Specify file where HepMC events will be stored.
  HepMC::IO_GenEvent ascii_io(argv[2], std::ios::out);
  // Switch off warnings for parton-level events.
  ToHepMC.set_print_inconsistency(false);
  ToHepMC.set_free_parton_warnings(false);
  // Do not store cross section information, as this will be done manually.
  ToHepMC.set_store_pdf(false);
  ToHepMC.set_store_proc(false);
  ToHepMC.set_store_xsec(false);
  // Check if jet matching should be applied.
  bool doMatch   = pythia.settings.flag("JetMatching:merge");
  // Check if internal merging should be applied.
  bool doMerge   = !(pythia.settings.word("Merging:Process").compare("void")
    == 0);
  // Currently, only one scheme at a time is allowed.
  if (doMatch && doMerge) {
    cerr << " Jet matching and merging cannot be used simultaneously.\n"
         << " Program stopped.";
  }
  // Get number of subruns.
  int nMerge = pythia.mode("LHEFInputs:nSubruns");
  // Number of events. Negative numbers mean all events in the LHEF will be
  // used.
  long nEvent = pythia.settings.mode("Main:numberOfEvents");
  if (nEvent < 1) nEvent = 1000000000000000;
  // For jet matching, initialise the respective user hooks code.
  CombineMatchingInput* combined = NULL;
  UserHooks* matching            = NULL;
  // Allow to set the number of addtional partons dynamically.
  amcnlo_unitarised_interface* setting = NULL;
  if ( doMerge ) {
    // Store merging scheme.
    int scheme = ( pythia.settings.flag("Merging:doUMEPSTree")
                || pythia.settings.flag("Merging:doUMEPSSubt")) ?
                1 :
                 ( ( pythia.settings.flag("Merging:doUNLOPSTree")
                || pythia.settings.flag("Merging:doUNLOPSSubt")
                || pythia.settings.flag("Merging:doUNLOPSLoop")
                || pythia.settings.flag("Merging:doUNLOPSSubtNLO")) ?
                2 :
                0 );
    setting = new amcnlo_unitarised_interface(scheme);
    pythia.setUserHooksPtr(setting);
  }
  // For jet matching, initialise the respective user hooks code.
  if (doMatch) {
    matching = combined->getHook(pythia);
    if (!matching) {
      cerr << " Failed to initialise jet matching structures.\n"
           << " Program stopped.";
      return 1;
    }
    pythia.setUserHooksPtr(matching);
  }
  // Cross section and error.
  double sigmaTotal  = 0.;
  double errorTotal  = 0.;
  // Allow abort of run if many errors.
  int  nAbort  = pythia.mode("Main:timesAllowErrors");
  int  iAbort  = 0;
  bool doAbort = false;
  cout << endl << endl << endl;
  cout << "Start generating events" << endl;
  // Loop over subruns with varying number of jets.
  for (int iMerge = 0; iMerge < nMerge; ++iMerge) {
    double sigmaSample = 0., errorSample = 0.;
    // Read in name of LHE file for current subrun and initialize.
    pythia.readFile(argv[1], iMerge);
    // Initialise.
    pythia.init();
    // Get the inclusive x-section by summing over all process x-sections.
    double xs = 0.;
    for (int i=0; i < pythia.info.nProcessesLHEF(); ++i)
      xs += pythia.info.sigmaLHEF(i);
    // Start generation loop
    while( pythia.info.nSelected() < nEvent ){
      // Generate next event
      if( !pythia.next() ) {
        if ( pythia.info.atEndOfFile() ) break;
        else if (++iAbort > nAbort) {doAbort = true; break;}
        else continue;
      }
      // Get event weight(s).
      double evtweight         = pythia.info.weight();
      // Additional PDF/alphaS weight for internal merging.
      if (doMerge) evtweight  *= pythia.info.mergingWeightNLO()
      // Additional weight due to random choice of reclustered/non-reclustered
      // treatment. Also contains additional sign for subtractive samples.
                                *setting->getNormFactor();
      // Do not print zero-weight events.
      if ( evtweight == 0. ) continue;
      // Construct new empty HepMC event.
      HepMC::GenEvent* hepmcevt = new HepMC::GenEvent();
      // Work with weighted (LHA strategy=-4) events.
      double normhepmc = 1.;
      if (abs(pythia.info.lhaStrategy()) == 4)
        normhepmc = 1. / double(1e9*nEvent);
      // Work with unweighted events.
      else
        normhepmc = xs / double(1e9*nEvent);
      // Set event weight
      hepmcevt->weights().push_back(evtweight*normhepmc);
      // Fill HepMC event
      ToHepMC.fill_next_event( pythia, hepmcevt );
      // Add the weight of the current event to the cross section.
      sigmaTotal  += evtweight*normhepmc;
      sigmaSample += evtweight*normhepmc;
      errorTotal  += pow2(evtweight*normhepmc);
      errorSample += pow2(evtweight*normhepmc);
      // Report cross section to hepmc
      HepMC::GenCrossSection xsec;
      xsec.set_cross_section( sigmaTotal*1e9, pythia.info.sigmaErr()*1e9 );
      hepmcevt->set_cross_section( xsec );
      // Write the HepMC event to file. Done with it.
      ascii_io << hepmcevt;
      delete hepmcevt;
    } // end loop over events to generate.
    if (doAbort) break;
    // print cross section, errors
    pythia.stat();
    cout << endl << " Contribution of sample " << iMerge
         << " to the inclusive cross section : "
         << scientific << setprecision(8)
         << sigmaSample << "  +-  " << sqrt(errorSample)  << endl;
  }
  cout << endl << endl << endl;
  if (doAbort)
    cout << " Run was not completed owing to too many aborted events" << endl;
  else
    cout << "Inclusive cross section: " << scientific << setprecision(8)
         << sigmaTotal << "  +-  " << sqrt(errorTotal) << " mb " << endl;
  cout << endl << endl << endl;
  // Done
  return 0;
}

main91.cc


// main91.cc is a part of the PYTHIA event generator.
// Copyright (C) 2016 Torbjorn Sjostrand.
// PYTHIA is licenced under the GNU GPL version 2, see COPYING for details.
// Please respect the MCnet Guidelines, see GUIDELINES for details.
// This is a simple test program.
// It studies the charged multiplicity distribution at the LHC.
// Modified by Rene Brun, Axel Naumann and Bernhard Meirose
// to use ROOT for histogramming.
// Stdlib header file for input and output.
#include <iostream>
// Header file to access Pythia 8 program elements.
#include "Pythia8/Pythia.h"
// ROOT, for histogramming.
#include "TH1.h"
// ROOT, for interactive graphics.
#include "TVirtualPad.h"
#include "TApplication.h"
// ROOT, for saving file.
#include "TFile.h"
using namespace Pythia8;
int main(int argc, char* argv[]) {
  // Create the ROOT application environment.
  TApplication theApp("hist", &argc, argv);
  // Create Pythia instance and set it up to generate hard QCD processes
  // above pTHat = 20 GeV for pp collisions at 14 TeV.
  Pythia pythia;
  pythia.readString("HardQCD:all = on");
  pythia.readString("PhaseSpace:pTHatMin = 20.");
  pythia.readString("Beams:eCM = 14000.");
  pythia.init();
  // Create file on which histogram(s) can be saved.
  TFile* outFile = new TFile("hist.root", "RECREATE");
  // Book histogram.
  TH1F *mult = new TH1F("mult","charged multiplicity", 100, -0.5, 799.5);
  // Begin event loop. Generate event; skip if generation aborted.
  for (int iEvent = 0; iEvent < 100; ++iEvent) {
    if (!pythia.next()) continue;
    // Find number of all final charged particles.
    int nCharged = 0;
    for (int i = 0; i < pythia.event.size(); ++i)
      if (pythia.event[i].isFinal() && pythia.event[i].isCharged())
        ++nCharged;
    // Fill charged multiplicity in histogram. End event loop.
    mult->Fill( nCharged );
  }
  // Statistics on event generation.
  pythia.stat();
  // Show histogram. Possibility to close it.
  mult->Draw();
  std::cout << "\nDouble click on the histogram window to quit.\n";
  gPad->WaitPrimitive();
  // Save histogram on file and close file.
  mult->Write();
  delete outFile;
  // Done.
  return 0;
}

main92.cc


// main92.cc is a part of the PYTHIA event generator.
// Copyright (C) 2016 Torbjorn Sjostrand.
// PYTHIA is licenced under the GNU GPL version 2, see COPYING for details.
// Please respect the MCnet Guidelines, see GUIDELINES for details.
// This is a simple test program.
// Modified by Rene Brun and Axel Naumann to put the Pythia::event
// into a TTree.
// Header file to access Pythia 8 program elements.
#include "Pythia8/Pythia.h"
// ROOT, for saving Pythia events as trees in a file.
#include "TTree.h"
#include "TFile.h"
using namespace Pythia8;
int main() {
  // Create Pythia instance and set it up to generate hard QCD processes
  // above pTHat = 20 GeV for pp collisions at 14 TeV.
  Pythia pythia;
  pythia.readString("HardQCD:all = on");
  pythia.readString("PhaseSpace:pTHatMin = 20.");
  pythia.readString("Beams:eCM = 14000.");
  pythia.init();
  // Set up the ROOT TFile and TTree.
  TFile *file = TFile::Open("pytree.root","recreate");
  Event *event = &pythia.event;
  TTree *T = new TTree("T","ev1 Tree");
  T->Branch("event",&event);
 // Begin event loop. Generate event; skip if generation aborted.
  for (int iEvent = 0; iEvent < 100; ++iEvent) {
    if (!pythia.next()) continue;
    // Fill the pythia event into the TTree.
    // Warning: the files will rapidly become large if all events
    // are saved. In some cases it may be convenient to do some
    // processing of events and only save those that appear
    // interesting for future analyses.
    T->Fill();
  // End event loop.
  }
  // Statistics on event generation.
  pythia.stat();
  //  Write tree.
  T->Print();
  T->Write();
  delete file;
  // Done.
  return 0;
}