main343
Back to index.
// main343.cc is a part of the PYTHIA event generator.
// Copyright (C) 2024 Torbjorn Sjostrand.
// PYTHIA is licenced under the GNU GPL v2 or later, see COPYING for details.
// Please respect the MCnet Guidelines, see GUIDELINES for details.
// Authors:
// Ilkka Helenius
// Keywords:
// Photon beam
// Photoproduction
// Photon‑photon
// Main program to generate charged hadron spectra from photon-initiated
// hard processes, by combining sub-runs with direct or resolved photons
// or by generating all with contributions in a single run.
// In case of photon-photon interactions four different contributions are
// present: ProcessType:
// - resolved-resolved 1
// - resolved-direct 2
// - direct-resolved 3
// - direct-direct 4
// Events can be generated either with photon beams or with photons emitted
// from lepton beams.
// In case of photon-proton interaction two contributions are present
// - resolved
// - direct
// When the photon is from beam A the relevant contributions are
// set with "Photon:ProcessType" values 1 (resolved) and 3 (direct) as the
// convention follows the photon-photon case above.
// Also lepton->photon + proton can be generated.
#include "Pythia8/Pythia.h"
using namespace Pythia8;
//==========================================================================
int main() {
// Generator.
Pythia pythia;
// Decrease the output.
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");
// Shorthand for some public members of pythia (also static ones).
Settings& settings = pythia.settings;
const Info& info = pythia.info;
// Photon-proton collisions.
bool photonProton = false;
// Generate photon-photon events in leptonic or photon beams.
bool photonsFromElectrons = false;
// Each contributions separately or in a one combined run.
bool automaticMix = true;
// Optionally use different PDFs from LHAPDF for hard process.
// Requires linking with LHAPDF5.
// pythia.readString("PDF:useHard = on");
// pythia.readString("PDF:GammaHardSet = LHAPDF5:SASG.LHgrid/5");
// Beam parameters.
pythia.readString("Beams:eCM = 200.");
// Set up beam particles for electron -> photon + proton.
if ( photonProton) {
if ( photonsFromElectrons) {
pythia.readString("Beams:idA = 11");
pythia.readString("Beams:idB = 2212");
pythia.readString("PDF:beamA2gamma = on");
// Set up beam particles for photon + proton.
} else {
pythia.readString("Beams:idA = 22");
pythia.readString("Beams:idB = 2212");
}
// Set up beam particles for photon-photon in e+e-.
} else if ( photonsFromElectrons) {
pythia.readString("Beams:idA = -11");
pythia.readString("Beams:idB = 11");
pythia.readString("PDF:beamA2gamma = on");
pythia.readString("PDF:beamB2gamma = on");
// Set up beam particles for photon-photon.
} else {
pythia.readString("Beams:idA = 22");
pythia.readString("Beams:idB = 22");
}
// Cuts on photon virtuality and invariant mass of gamma-gamma/hadron pair.
if ( photonsFromElectrons) {
pythia.readString("Photon:Q2max = 1.0");
pythia.readString("Photon:Wmin = 10.0");
}
// For photon-proton increase pT0Ref (for better agreement with HERA data).
// Photon-photon has a new default pT0 parametrization tuned to LEP data.
if ( photonProton)
pythia.readString("MultipartonInteractions:pT0Ref = 3.00");
// Limit partonic pThat.
settings.parm("PhaseSpace:pTHatMin", 5.0);
// Reset statistics after each subrun.
pythia.readString("Stat:reset = on");
// Parameters for histograms.
double pTmin = 0.0;
double pTmax = 40.0;
int nBinsPT = 40;
// Initialize the histograms.
Hist pTtot("Total charged hadron pT distribution", nBinsPT, pTmin, pTmax);
Hist pTresres("Resolved-resolved contribution for pT distribution",
nBinsPT, pTmin, pTmax);
Hist pTresdir("Resolved-direct contribution for pT distribution",
nBinsPT, pTmin, pTmax);
Hist pTdirres("Direct-resolved contribution for pT distribution",
nBinsPT, pTmin, pTmax);
Hist pTdirdir("Direct-direct contribution for pT distribution",
nBinsPT, pTmin, pTmax);
Hist pTiRun("Contribution from Run i for pT distribution",
nBinsPT, pTmin, pTmax);
// Initialize hard QCD processes with 0, 1, or 2 initial photons.
pythia.readString("HardQCD:all = on");
pythia.readString("PhotonParton:all = on");
if ( !photonProton) {
pythia.readString("PhotonCollision:gmgm2qqbar = on");
pythia.readString("PhotonCollision:gmgm2ccbar = on");
pythia.readString("PhotonCollision:gmgm2bbbar = on");
}
// Number of runs.
int nRuns = photonProton ? 2 : 4;
if (automaticMix) nRuns = 1;
// Number of events per run.
int nEvent = 10000;
// Loop over relevant processes.
for ( int iRun = 1; iRun < nRuns + 1; ++iRun) {
// Turn of MPIs for processes with unresolved photons.
if (iRun == 2) pythia.readString("PartonLevel:MPI = off");
// For photon+proton direct contribution with processType = 3.
if (photonProton && iRun == 2) iRun = 3;
// Set the type of gamma-gamma process:
// 0 = mix of all below,
// 1 = resolved-resolved,
// 2 = resolved-direct,
// 3 = direct-resolved,
// 4 = direct-direct.
if (automaticMix) settings.mode("Photon:ProcessType", 0);
else settings.mode("Photon:ProcessType", iRun);
// If Pythia fails to initialize, exit with error.
if (!pythia.init()) return 1;
// Clear the histogram.
pTiRun.null();
// Begin event loop. Skip if fails.
for (int iEvent = 0; iEvent < nEvent; ++iEvent) {
// Generate next event.
if (!pythia.next()) continue;
// List the first process and event for each run.
if (iEvent == 0) {
pythia.process.list();
pythia.event.list();
}
// Possible event weights.
double weight = info.weight();
// Loop over event record and find charged final state particles.
for (int i = 0; i < pythia.event.size(); ++i){
if ( pythia.event[i].isFinal() && pythia.event[i].isCharged() ) {
// Store the pT value.
double pTch = pythia.event[i].pT();
// Fill the correct histogram depending on the process type.
if (automaticMix) {
pTtot.fill(pTch, weight);
if (info.photonMode() == 1) pTresres.fill(pTch, weight);
if (info.photonMode() == 2) pTresdir.fill(pTch, weight);
if (info.photonMode() == 3) pTdirres.fill(pTch, weight);
if (info.photonMode() == 4) pTdirdir.fill(pTch, weight);
} else {
pTiRun.fill(pTch, weight);
}
}
}
} // End of event loop.
// Show statistics after each run.
pythia.stat();
// Normalize to cross section [mb].
double sigmaNorm = info.sigmaGen() / info.weightSum();
double pTBin = (pTmax - pTmin) / (1. * nBinsPT);
// For mix of all contributions normalize with total cross section.
if (automaticMix) {
pTtot *= sigmaNorm / pTBin;
pTresres *= sigmaNorm / pTBin;
pTresdir *= sigmaNorm / pTBin;
pTdirres *= sigmaNorm / pTBin;
pTdirdir *= sigmaNorm / pTBin;
// For each contribution normalize with cross section for the given run.
} else {
pTiRun *= sigmaNorm / pTBin;
if (iRun == 1) pTresres = pTiRun;
if (iRun == 2) pTresdir = pTiRun;
if (iRun == 3) pTdirres = pTiRun;
if (iRun == 4) pTdirdir = pTiRun;
pTtot += pTiRun;
}
// End of loop over runs.
}
// Print histograms.
cout << pTresres << pTresdir << pTdirres << pTdirdir << pTtot;
// Done.
return 0;
}