00001 // -*- C++ -*- 00002 #include "AGILe/FPythia/FPythia.hh" 00003 #include "AGILe/FPythia/FPythiaWrapper62.hh" 00004 #include "AGILe/Utils.hh" 00005 #include "AGILe/HepMCTools.hh" 00006 00007 #include "HepMC/HEPEVT_Wrapper.h" 00008 00009 namespace AGILe { 00010 00011 // Author: Andy Buckley 00012 00013 00015 FPythia::FPythia() { 00016 _myName = "Pythia"; 00017 00019 FC_PYJETS.n = 0; //< Ensure dummyness of the next call 00020 call_pyhepc(1); 00021 HepMC::HEPEVT_Wrapper::set_max_number_entries(FC_PYDAT1.mstu[8-1]); 00022 //HepMC::HEPEVT_Wrapper::set_max_number_entries(10000); 00023 HepMC::HEPEVT_Wrapper::set_sizeof_real(8); 00024 00025 // Start counting events at 1. 00026 _nevt = 1; 00027 00028 // Initialize Pythia PYDATA block data as external 00029 FC_INITPYDATA(); 00030 00031 // Write the full shower structure 00032 setParam("MSTP(125)", 2); 00033 00034 // Tell Pythia not to write multiple copies of particles in event record. 00035 setParam("MSTP(128)", 2); 00036 00037 // Set up particle names map 00039 _particleNames[ELECTRON] = "e-"; 00040 _particleNames[POSITRON] = "e+"; 00041 _particleNames[PROTON] = "p+"; 00042 _particleNames[ANTIPROTON] = "pbar-"; 00043 _particleNames[NEUTRON] = "n0"; 00044 _particleNames[ANTINEUTRON] = "nbar0"; 00045 _particleNames[PHOTON] = "gamma"; 00046 _particleNames[MUON] = "mu-"; 00047 _particleNames[ANTIMUON] = "mu+"; 00048 // TAU, ANTITAU 00049 _particleNames[NU_E] = "nu_e"; 00050 _particleNames[NU_EBAR] = "nu_ebar"; 00051 _particleNames[NU_MU] = "nu_mu"; 00052 _particleNames[NU_MUBAR] = "nu_mubar"; 00053 _particleNames[NU_TAU] = "nu_tau"; 00054 _particleNames[NU_TAUBAR] = "nu_taubar"; 00055 _particleNames[PIPLUS] = "pi+"; 00056 _particleNames[PIMINUS] = "pi-"; 00057 // PIZERO 00058 // PHOTOELECTRON, PHOTOPOSITRON, 00059 // PHOTOMUON, PHOTOANTIMUON, 00060 // PHOTOTAU, PHOTOANTITAU, 00067 } 00068 00069 00070 void FPythia::setGenSpecificInitialState(PdgCode p1, double e1, PdgCode p2, double e2) { 00071 MSG_DEBUG("Setting initial state..."); 00072 // For Pythia, we have to hold on to this state until initialize() is called. 00073 _particleName1 = _particleNames[p1]; 00074 _particleName2 = _particleNames[p2]; 00076 _e1 = e1; 00077 _e2 = e2; 00078 } 00079 00080 00082 void FPythia::initialize() { 00083 Generator::initialize(); 00084 // Make sure that PYINIT does not call PYTUNE (that should happen when the param is set). 00085 call_pygive("MSTP(5)=0"); 00086 // Call pythia initialization with stored parameters as set by setGenSpecificInitialState() 00087 if (FC_PYPARS.mstp[142] != 1) { 00088 if (fuzzyEquals(_e1, _e2)) { 00089 call_pyinit("CMS", _particleName1.c_str(), _particleName2.c_str(), _e1+_e2); 00090 } else { 00091 stringstream p13cmd, p23cmd; 00092 p13cmd << "P(1,3) = " << _e1; 00093 p23cmd << "P(2,3) = " << -_e2; 00094 call_pygive("P(1,1) = 0.0"); 00095 call_pygive("P(1,2) = 0.0"); 00096 call_pygive(p13cmd.str().c_str()); 00097 call_pygive("P(2,1) = 0.0"); 00098 call_pygive("P(2,2) = 0.0"); 00099 call_pygive(p23cmd.str().c_str()); 00100 call_pyinit("3MOM", _particleName1.c_str(), _particleName2.c_str(), 0.0); 00101 } 00102 } else { 00103 // User process, parameters taken from LHAPDF initialisation file. 00104 call_pyinit("USER"," "," ", 0.0); 00105 } 00106 _initialized = true; 00107 } 00108 00109 00110 // Set a parameter with a string value 00111 bool FPythia::setParam(const string& name, const string& value) { 00112 Generator::setParam(name, value); 00113 const string NAME = toUpper(name); 00114 if (NAME == "PYTUNE" || NAME == "MSTP(5)") { 00115 const int tunenumber = asInt(value); 00116 MSG_INFO("MSTP(5) param or PYTUNE meta-param has been set: calling PYTUNE *now*"); 00117 call_pytune(tunenumber); 00118 } else if (NAME == "LHEF") { 00119 MSG_INFO("LHEF meta-param has been set: calling OPEN *now* for LHE file = " << value); 00120 call_lhefopen(value.c_str()); 00121 setParam("MSTP(161)", 88); 00122 setParam("MSTP(162)", 88); 00123 } else { 00124 const string pygive_input(name + "=" + value); 00125 call_pygive(pygive_input.c_str()); 00126 } 00127 return SUCCESS; 00128 } 00129 00130 00131 // Run the generator for one event 00132 void FPythia::makeEvent(HepMC::GenEvent& evt) { 00133 Generator::makeEvent(evt); 00135 // Generate one event. 00136 call_pyevnt(); 00137 // Generate one event with new UE and shower. 00138 //call_pyevnw(); 00139 // Convert common PYJETS into common HEPEVT. 00140 call_pyhepc(1); 00141 // Increment an event counter (Pythia does not count for itself). 00142 _nevt++; 00143 // fill the event using HepMC 00144 fillEvent(evt); 00145 evt.set_event_number(_nevt); 00146 } 00147 00148 00149 // Fill a HepMC event 00150 void FPythia::fillEvent(HepMC::GenEvent& evt) { 00151 _hepevt.fill_next_event(&evt); 00152 fixHepMCUnitsFromGeVmm(evt); 00153 00154 // Set beam particle status = 4 00155 if (evt.valid_beam_particles()) { 00156 evt.beam_particles().first->set_status(4); 00157 evt.beam_particles().second->set_status(4); 00158 } 00159 00160 // Weight(s) 00161 evt.weights().clear(); 00162 if (FC_PYPARS.mstp[141] != 0) { 00163 evt.weights().push_back(FC_PYPARS.pari[9]); 00164 } else { 00165 evt.weights().push_back(1.0); 00166 } 00167 00168 // Cross-section 00169 #ifdef HEPMC_HAS_CROSS_SECTION 00170 HepMC::GenCrossSection xsec; 00171 const double xsecval = getCrossSection(); 00172 const double xsecerr = getCrossSection() / std::sqrt(FC_PYPARS.msti[4]); 00173 MSG_DEBUG("Writing cross-section = " << xsecval << " +- " << xsecerr); 00174 xsec.set_cross_section(xsecval, xsecerr); 00175 evt.set_cross_section(xsec); 00176 #endif 00177 00178 // PDF weights, using HepMC::PdfInfo object 00180 const int id1 = FC_PYPARS.msti[15-1]; 00181 const int id2 = FC_PYPARS.msti[16-1]; 00182 const double x1 = FC_PYPARS.pari[33-1]; 00183 const double x2 = FC_PYPARS.pari[34-1]; 00184 const double q = FC_PYPARS.pari[23-1]; 00185 const double pdf1 = FC_PYPARS.pari[29-1]; // x*pdf1 00186 const double pdf2 = FC_PYPARS.pari[30-1]; // x*pdf2 00187 // std::cout << q << ": " << id1 << ", " << x1 << ", " << pdf1 << "; " 00188 // << id2 << ", " << x2 << ", " << pdf2 << std::endl; 00189 HepMC::PdfInfo pdfi(id1, id2, x1, x2, q, pdf1, pdf2); 00190 evt.set_pdf_info(pdfi); 00191 } 00192 00193 00194 string FPythia::getPDFSet(PdgCode pid) { 00195 switch(pid) { 00196 case PROTON: 00197 case ANTIPROTON: 00198 if (FC_PYPARS.mstp[51] == 1) { 00199 return "PYINTERNAL"; 00200 } else if(FC_PYPARS.mstp[51] == 2) { 00201 return "PYLHAPDF"; 00202 } 00203 break; 00204 00205 case ELECTRON: 00206 case POSITRON: 00207 if (FC_PYPARS.mstp[55] == 1) { 00208 return "PYINTERNAL"; 00209 } else if(FC_PYPARS.mstp[55] == 2) { 00210 return "PYLHAPDF"; 00211 } 00212 break; 00213 default: 00214 break; 00215 } 00216 throw runtime_error("Unknown particle for PDF set"); 00217 } 00218 00219 00220 int FPythia::getPDFMember(PdgCode pid) { 00221 switch(pid) { 00222 case PROTON: 00223 case ANTIPROTON: 00224 return FC_PYPARS.mstp[50]; 00225 break; 00226 case ELECTRON: 00227 case POSITRON: 00228 return FC_PYPARS.mstp[54]; 00229 break; 00230 default: 00231 break; 00232 } 00233 throw runtime_error("Unknown particle for PDF set"); 00234 } 00235 00236 00237 string FPythia::getPDFScheme(PdgCode pid) const { 00238 switch(pid){ 00239 case PROTON: 00240 case ANTIPROTON: 00241 if (FC_PYPARS.mstp[51]==1) { 00242 return "PYINTERNAL"; 00243 } else if(FC_PYPARS.mstp[51]==2) { 00244 return "LHAPDF"; 00245 } 00246 break; 00247 case ELECTRON: 00248 case POSITRON: 00249 if (FC_PYPARS.mstp[55]==1) { 00250 return "PYINTERNAL"; 00251 } else if(FC_PYPARS.mstp[55]==2) { 00252 return "LHAPDF"; 00253 } 00254 break; 00255 default: 00256 break; 00257 } 00258 throw runtime_error("Unknown particle for PDF set"); 00259 } 00260 00261 00262 const double FPythia::getCrossSection(){ 00263 // _crossSection = FC_PYINT5.xsec[2][0] * 1e09; 00264 _crossSection = FC_PYPARS.pari[0] * 1e09; 00265 return _crossSection; 00266 } 00267 00268 const string FPythia::getVersion(){ 00269 stringstream s; 00270 s << FC_PYPARS.mstp[180] << "." << FC_PYPARS.mstp[181]; 00271 return s.str(); 00272 } 00273 00274 // Tidy up after ourselves 00275 void FPythia::finalize() { 00276 MSG_DEBUG("Finalising..."); 00277 // Print out stats from run 00278 call_pystat(1); 00279 } 00280 00281 00282 } 00283 00284 00285 extern "C" { 00286 AGILe::Generator* create() { return new AGILe::FPythia(); } 00287 void destroy(AGILe::Generator* gen) { delete gen; } 00288 }