File indexing completed on 2025-08-05 08:19:25
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018 #include "PythiaGun.h"
0019 #include <sstream>
0020 #include <iostream>
0021 #include <fstream>
0022 #define MAGENTA "\033[35m"
0023
0024 using namespace std;
0025
0026
0027 RegisterJetScapeModule<PythiaGun> PythiaGun::reg("PythiaGun");
0028
0029 PythiaGun::~PythiaGun() { VERBOSE(8); }
0030
0031 void PythiaGun::InitTask() {
0032
0033 JSDEBUG << "Initialize PythiaGun";
0034 VERBOSE(8);
0035
0036
0037 readString("Init:showProcesses = off");
0038 readString("Init:showChangedSettings = off");
0039 readString("Init:showMultipartonInteractions = off");
0040 readString("Init:showChangedParticleData = off");
0041 if (JetScapeLogger::Instance()->GetInfo()) {
0042 readString("Init:showProcesses = on");
0043 readString("Init:showChangedSettings = on");
0044 readString("Init:showMultipartonInteractions = on");
0045 readString("Init:showChangedParticleData = on");
0046 }
0047
0048
0049 readString("Next:numberShowInfo = 0");
0050 readString("Next:numberShowProcess = 0");
0051 readString("Next:numberShowEvent = 0");
0052
0053
0054 stringstream numbf(stringstream::app | stringstream::in | stringstream::out);
0055 numbf.setf(ios::fixed, ios::floatfield);
0056 numbf.setf(ios::showpoint);
0057 numbf.precision(1);
0058 stringstream numbi(stringstream::app | stringstream::in | stringstream::out);
0059
0060 std::string s = GetXMLElementText({"Hard", "PythiaGun", "name"});
0061 SetId(s);
0062
0063
0064
0065 readString("HadronLevel:Decay = off");
0066 readString("HadronLevel:all = off");
0067 readString("PartonLevel:ISR = on");
0068 readString("PartonLevel:MPI = on");
0069
0070 readString("PromptPhoton:all=on");
0071 readString("WeakSingleBoson:all=off");
0072 readString("WeakDoubleBoson:all=off");
0073
0074 pTHatMin = GetXMLElementDouble({"Hard", "PythiaGun", "pTHatMin"});
0075 pTHatMax = GetXMLElementDouble({"Hard", "PythiaGun", "pTHatMax"});
0076
0077 if(pTHatMin < 0.01){
0078
0079 readString("HardQCD:all = off");
0080 readString("SoftQCD:nonDiffractive = on");
0081 softQCD = true;
0082 }
0083 else{
0084 readString("HardQCD:all = on");
0085
0086
0087 numbf.str("PhaseSpace:pTHatMin = "); numbf << pTHatMin; readString(numbf.str());
0088 numbf.str("PhaseSpace:pTHatMax = "); numbf << pTHatMax; readString(numbf.str());
0089 softQCD = false;
0090 }
0091
0092
0093 FSR_on = GetXMLElementInt({"Hard", "PythiaGun", "FSR_on"});
0094 if (FSR_on)
0095 readString("PartonLevel:FSR = on");
0096 else
0097 readString("PartonLevel:FSR = off");
0098
0099 JSINFO << MAGENTA << "Pythia Gun with FSR_on: " << FSR_on;
0100 JSINFO << MAGENTA << "Pythia Gun with " << pTHatMin << " < pTHat < " << pTHatMax;
0101
0102
0103
0104 tinyxml2::XMLElement *RandomXmlDescription = GetXMLElement({"Random"});
0105 readString("Random:setSeed = on");
0106 numbi.str("Random:seed = ");
0107 unsigned int seed = 0;
0108 if (RandomXmlDescription) {
0109 tinyxml2::XMLElement *xmle =
0110 RandomXmlDescription->FirstChildElement("seed");
0111 if (!xmle)
0112 throw std::runtime_error("Cannot parse xml");
0113 xmle->QueryUnsignedText(&seed);
0114 } else {
0115 JSWARN << "No <Random> element found in xml, seeding to 0";
0116 }
0117 VERBOSE(7) << "Seeding pythia to " << seed;
0118 numbi << seed;
0119 readString(numbi.str());
0120
0121
0122 readString("Beams:idA = 2212");
0123 readString("Beams:idB = 2212");
0124
0125
0126 eCM = GetXMLElementDouble({"Hard", "PythiaGun", "eCM"});
0127 numbf.str("Beams:eCM = ");
0128 numbf << eCM;
0129 readString(numbf.str());
0130
0131
0132 vir_factor = GetXMLElementDouble({"Eloss", "Matter", "vir_factor"});
0133 softMomentumCutoff = GetXMLElementDouble({"Hard", "PythiaGun", "softMomentumCutoff"});
0134
0135 std::stringstream lines;
0136 lines << GetXMLElementText({"Hard", "PythiaGun", "LinesToRead"}, false);
0137 int i = 0;
0138 while (std::getline(lines, s, '\n')) {
0139 if (s.find_first_not_of(" \t\v\f\r") == s.npos)
0140 continue;
0141 VERBOSE(7) << "Also reading in: " << s;
0142 readString(s);
0143 }
0144
0145
0146 if (!init()) {
0147 throw std::runtime_error("Pythia init() failed.");
0148 }
0149
0150 std::ofstream sigma_printer;
0151 sigma_printer.open(printer, std::ios::trunc);
0152
0153
0154 }
0155
0156 void PythiaGun::Exec() {
0157 VERBOSE(1) << "Run Hard Process : " << GetId() << " ...";
0158 VERBOSE(8) << "Current Event #" << GetCurrentEvent();
0159
0160 bool flag62 = false;
0161 vector<Pythia8::Particle> p62;
0162
0163
0164 struct greater_than_pt {
0165 inline bool operator()(const Pythia8::Particle &p1,
0166 const Pythia8::Particle &p2) {
0167 return (p1.pT() > p2.pT());
0168 }
0169 };
0170
0171 do {
0172 next();
0173 p62.clear();
0174 if (!printer.empty()){
0175 std::ofstream sigma_printer;
0176 sigma_printer.open(printer, std::ios::out | std::ios::app);
0177
0178 sigma_printer << "sigma = " << GetSigmaGen() << " Err = " << GetSigmaErr() << endl ;
0179
0180
0181
0182 };
0183
0184
0185
0186
0187 for (int parid = 0; parid < event.size(); parid++) {
0188 if (parid < 3)
0189 continue;
0190 Pythia8::Particle &particle = event[parid];
0191
0192
0193
0194
0195
0196 if( (std::abs(particle.id()) > 1100) && (std::abs(particle.id()) < 6000) && ((std::abs(particle.id())/10)%10 == 0) ){
0197 if(particle.id() > 0){particle.id( -1*particle.id()/1000 );}
0198 else{particle.id( particle.id()/1000 );}
0199 }
0200
0201 if (!FSR_on) {
0202
0203 if (particle.status() != 62)
0204 continue;
0205
0206
0207 if (fabs(particle.id()) > 5 &&
0208 (particle.id() != 21 && particle.id() != 22))
0209 continue;
0210
0211
0212
0213 if (vir_factor > 0. && (particle.pT() < softMomentumCutoff)) {
0214
0215 continue;
0216 } else if(vir_factor < 0. && (particle.pAbs() < softMomentumCutoff)) {
0217 continue;
0218 } else if(vir_factor < rounding_error) {
0219 JSWARN << "vir_factor should not be zero.";
0220 exit(1);
0221 }
0222
0223
0224
0225 } else {
0226 if (!particle.isFinal())
0227 continue;
0228
0229
0230 if (fabs(particle.id()) > 5 &&
0231 (particle.id() != 21 && particle.id() != 22))
0232 continue;
0233 }
0234 p62.push_back(particle);
0235 }
0236
0237
0238 if (p62.size() < 2)
0239 continue;
0240
0241
0242
0243
0244 std::sort(p62.begin(), p62.end(), greater_than_pt());
0245
0246
0247
0248
0249 if(softQCD && (info.pTHat() >= pTHatMax)){continue;}
0250
0251 flag62 = true;
0252
0253 } while (!flag62);
0254
0255 double p[4], xLoc[4];
0256
0257
0258 for (int i = 0; i <= 3; i++) {
0259 xLoc[i] = 0.0;
0260 };
0261
0262
0263
0264
0265
0266
0267 if (!ini) {
0268 VERBOSE(1) << "No initial state module, setting the starting location to "
0269 "0. Make sure to add e.g. trento before PythiaGun.";
0270 } else {
0271 double x, y;
0272 ini->SampleABinaryCollisionPoint(x, y);
0273 xLoc[1] = x;
0274 xLoc[2] = y;
0275 }
0276
0277
0278
0279
0280
0281
0282
0283
0284 int hCounter = 0;
0285 for (int np = 0; np < p62.size(); ++np) {
0286 Pythia8::Particle &particle = p62.at(np);
0287
0288 VERBOSE(7) << "Adding particle with pid = " << particle.id()
0289 << " at x=" << xLoc[1] << ", y=" << xLoc[2] << ", z=" << xLoc[3];
0290
0291 VERBOSE(7) << "Adding particle with pid = " << particle.id()
0292 << ", pT = " << particle.pT() << ", eta = " << particle.eta()
0293 << ", phi = " << particle.phi() << ", e = " << particle.e();
0294
0295 VERBOSE(7) << " at x=" << xLoc[1] << ", y=" << xLoc[2] << ", z=" << xLoc[3];
0296
0297 auto ptn = make_shared<Parton>(0, particle.id(), 0, particle.pT(), particle.eta(),particle.phi(), particle.e(), xLoc);
0298 ptn->set_color(particle.col());
0299 ptn->set_anti_color(particle.acol());
0300 ptn->set_max_color(1000 * (np + 1));
0301 AddParton(ptn);
0302 }
0303
0304 VERBOSE(8) << GetNHardPartons();
0305 }