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; }