00001 // -*- C++ -*- 00002 #include "AGILe/Phojet/Phojet.hh" 00003 #include "AGILe/Phojet/PhojetWrapper62.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: S.Todorova 00012 00013 00015 Phojet::Phojet() { 00017 FC_PYJETS.n = 0; //< Ensure dummyness of the next call 00018 call_pyhepc(1); 00019 //HepMC::HEPEVT_Wrapper::set_max_number_entries(4000); 00020 //HepMC::HEPEVT_Wrapper::set_sizeof_real(8); 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 Phojet 00029 int irej=0; 00030 int mode = -1; 00031 FC_PHO_INIT(&mode,&irej); 00032 00033 // Initialize Pythia PYDATA block data as external 00034 FC_INITPYDATA(); 00035 00036 // Write the full shower structure 00037 //setParam("MSTP(125)", 2); 00038 00039 // Tell Pythia not to write multiple copies of particles in event record. 00040 //setParam("MSTP(128)", 2); 00041 00042 // Set up particle names map 00044 _particleNames[ELECTRON] = "e-"; 00045 _particleNames[POSITRON] = "e+"; 00046 _particleNames[PROTON] = "p+"; 00047 _particleNames[ANTIPROTON] = "pbar-"; 00048 _particleNames[NEUTRON] = "n0"; 00049 _particleNames[ANTINEUTRON] = "nbar0"; 00050 _particleNames[PHOTON] = "gamma"; 00051 _particleNames[MUON] = "mu-"; 00052 _particleNames[ANTIMUON] = "mu+"; 00053 // TAU, ANTITAU 00054 _particleNames[NU_E] = "nu_e"; 00055 _particleNames[NU_EBAR] = "nu_ebar"; 00056 _particleNames[NU_MU] = "nu_mu"; 00057 _particleNames[NU_MUBAR] = "nu_mubar"; 00058 _particleNames[NU_TAU] = "nu_tau"; 00059 _particleNames[NU_TAUBAR] = "nu_taubar"; 00060 _particleNames[PIPLUS] = "pi+"; 00061 _particleNames[PIMINUS] = "pi-"; 00062 // PIZERO 00063 // PHOTOELECTRON, PHOTOPOSITRON, 00064 // PHOTOMUON, PHOTOANTIMUON, 00065 // PHOTOTAU, PHOTOANTITAU, 00072 } 00073 00074 00075 void Phojet::setGenSpecificInitialState(PdgCode id1, double e1, PdgCode id2, double e2) { 00076 getLog() << Log::INFO << "Setting initial state..." << endl; 00077 // For Pythia, we have to hold on to this state until initialize() is called. 00078 _particleName1 = _particleNames[id1]; 00079 _particleName2 = _particleNames[id2]; 00080 00081 _p1 = new double[4]; 00082 _p2 = new double[4]; 00083 00084 (_p1)[0]=0.; (_p1)[1]=0.; 00085 (_p2)[0]=0.; (_p2)[1]=0.; 00086 (_p1)[3]=e1; (_p2)[3]=e2; 00087 00088 } 00089 00090 00092 void Phojet::initialize() { 00093 Generator::initialize(); 00094 00095 double zero=0.; 00096 00097 // hardcoded input ! 00098 int i1=1; 00099 int i2=2; 00100 int id=2212; 00101 int mode = 0; 00102 FC_PHO_SETPAR(&i1,&id,&mode,&zero); 00103 FC_PHO_SETPAR(&i2,&id,&mode,&zero); 00104 00105 double m = 0.93827; 00106 double m2 = m*m; 00107 double e = _p1[3]; 00108 _pz = sqrt(e*e - m2); 00109 00110 (_p1)[2]= _pz; 00111 (_p2)[2]=-_pz; 00112 00113 double sigmax=0.; 00114 int irej=0; 00115 int mod0 = -1; 00116 00117 FC_PHO_EVENT(&mod0,_p1,_p2, &sigmax, &irej); 00118 00119 _initialized = true; 00120 00121 } 00122 00123 // Set a parameter with a string value 00124 bool Phojet::setParam(const string& name, const string& value) { 00125 Generator::setParam(name, value); 00126 00127 if (name.substr(0,5) == "IPRON" || name.substr(0,5) == "ipron") { 00128 size_t il = 0; size_t ir = 0; size_t ic = 0; 00129 while (il<name.size() && name.substr(il,1)!="(") il++; 00130 while (ic<name.size() && name.substr(ic,1)!=",") ic++; 00131 while (ir<name.size() && name.substr(ir,1)!=")") ir++; 00132 size_t ip1 = 0; size_t ip2 = 0; 00133 if (il > 3 && ic > il) { 00134 const string& num1 = name.substr(il+1,ic-il-1); 00135 ip1 = std::atoi(num1.c_str()); 00136 } 00137 if (ic > 3 && ir > ic) { 00138 const string& num2 = name.substr(ic+1,ir-ic-1); 00139 ip2 = std::atoi(num2.c_str()); 00140 } 00141 double val = std::atof(value.c_str()); 00142 00143 //std::cout <<"old value:"<<FC_POPRCS.ipron[ip1-1][ip2-1]<<std::endl; 00144 FC_POPRCS.ipron[ip1-1][ip2-1] = int(val); 00145 //std::cout <<"new value:"<<FC_POPRCS.ipron[ip1-1][ip2-1]<<std::endl; 00146 } else if (name.substr(0,6)=="ISWMDL" || name.substr(0,6)=="iswmdl" ) { 00147 size_t il = 0; size_t ir = 0; 00148 while (il<name.size() && name.substr(il,1)!="(") il++; 00149 while (ir<name.size() && name.substr(ir,1)!=")") ir++; 00150 size_t ip = 0; 00151 if (il>3 && ir>il ) { 00152 const string& num = name.substr(il+1,ir-il-1); 00153 ip = std::atoi(num.c_str()); 00154 } 00155 double val = std::atof(value.c_str()); 00156 00157 //std::cout <<"old value:"<<FC_POMDLS.iswmdl[ip-1]<<std::endl; 00158 FC_POMDLS.iswmdl[ip-1] = int(val); 00159 //std::cout <<"new value:"<<FC_POMDLS.iswmdl[ip-1]<<std::endl; 00160 } else if (name.substr(0,6)=="IPAMDL" || name.substr(0,6)=="ipamdl" ) { 00161 size_t il =0; size_t ir = 0; 00162 while (il<name.size() && name.substr(il,1)!="(") il++; 00163 while (ir<name.size() && name.substr(ir,1)!=")") ir++; 00164 size_t ip=0; 00165 if (il>3 && ir>il ) { 00166 const string& num= name.substr(il+1,ir-il-1); 00167 ip = std::atoi(num.c_str()); 00168 } 00169 double val = std::atof(value.c_str()); 00170 00171 //std::cout <<"old value:"<<FC_POMDLS.ipamdl[ip-1]<<std::endl; 00172 FC_POMDLS.ipamdl[ip-1] = int(val); 00173 //std::cout <<"new value:"<<FC_POMDLS.ipamdl[ip-1]<<std::endl; 00174 } else if (name.substr(0,6)=="PARMDL" || name.substr(0,6)=="parmdl" ) { 00175 size_t il = 0; size_t ir = 0; 00176 while (il<name.size() && name.substr(il,1)!="(") il++; 00177 while (ir<name.size() && name.substr(ir,1)!=")") ir++; 00178 size_t ip = 0; 00179 if (il>3 && ir>il ) { 00180 const string& num= name.substr(il+1,ir-il-1); 00181 ip = std::atoi(num.c_str()); 00182 } 00183 double val = std::atof(value.c_str()); 00184 00185 //std::cout <<"old value:"<<FC_POMDLS.parmdl[ip-1]<<std::endl; 00186 FC_POMDLS.parmdl[ip-1] = val; 00187 //std::cout <<"new value:"<<FC_POMDLS.parmdl[ip-1]<<std::endl; 00188 } else if (name.substr(0,4)=="RNDM" || name.substr(0,4)=="rndm" ) { 00189 00190 double val = std::atof(value.c_str()); 00191 int ir1=int(val/100.); 00192 int rndm1=int(val-100*ir1); 00193 int ir2=int(ir1/100.); 00194 int rndm2=int(ir1-100*ir2); 00195 int ir3=int(ir2/100.); 00196 int rndm3=int(ir2-100*ir3); 00197 int rndm4=ir3; 00198 rndm1 = max(rndm1,1); 00199 rndm2 = max(rndm2,1); 00200 rndm3 = max(rndm3,1); 00201 rndm4 = max(rndm4,1); 00202 rndm4 = min(rndm4,178); 00203 //std::cout << " RNDM init with input:"<<rndm1<<":"<<rndm2<<":"<<rndm3<<":"<<rndm4 << std::endl; 00204 FC_PHO_RNDIN(&rndm1,&rndm2,&rndm3,&rndm4); 00205 00206 } else { 00207 const string pygive_input(toUpper(name) + "=" + value); 00208 call_pygive(pygive_input.c_str()); 00209 } 00210 return SUCCESS; 00211 } 00212 00213 // Run the generator for one event 00214 void Phojet::makeEvent(HepMC::GenEvent& evt) { 00215 Generator::makeEvent(evt); 00217 // Generate one event. 00218 // run Phojet 00219 double sigcur = 0.; 00220 int irej = 0; 00221 int mod = 1; 00222 00223 FC_PHO_EVENT(&mod,_p1,_p2,&sigcur,&irej); 00224 00225 //FC_PHO_HEPEVT(); 00226 00227 // Increment an event counter (Pythia does not count for itself). 00228 _nevt++; 00229 // fill the event using HepMC 00230 fillEvent(evt); 00231 evt.set_event_number(_nevt); 00232 } 00233 00234 00235 // Fill a HepMC event 00236 void Phojet::fillEvent(HepMC::GenEvent& evt) { 00237 00238 // check event first 00239 // bool iok = HepMC::HEPEVT_Wrapper::check_hepevt_consistency(); 00240 00241 _hepevt.fill_next_event(&evt); 00242 fixHepMCUnitsFromGeVmm(evt); 00243 #ifdef HEPMC_HAS_CROSS_SECTION 00244 HepMC::GenCrossSection xsec; 00245 const double xsecval = getCrossSection(); 00246 const double xsecerr = getCrossSection() / std::sqrt(FC_PYPARS.msti[4]); 00247 getLog() << Log::DEBUG << "Writing cross-section = " << xsecval << " +- " << xsecerr << endl; 00248 xsec.set_cross_section(xsecval, xsecerr); 00249 evt.set_cross_section(xsec); 00250 #endif 00251 } 00252 00253 00254 string Phojet::getPDFSet(PdgCode pid) { 00255 switch(pid) { 00256 case PROTON: 00257 case ANTIPROTON: 00258 if (FC_PYPARS.mstp[51] == 1) { 00259 return "PYINTERNAL"; 00260 } else if(FC_PYPARS.mstp[51] == 2) { 00261 return "PYLHAPDF"; 00262 } 00263 break; 00264 00265 case ELECTRON: 00266 case POSITRON: 00267 if (FC_PYPARS.mstp[55] == 1) { 00268 return "PYINTERNAL"; 00269 } else if(FC_PYPARS.mstp[55] == 2) { 00270 return "PYLHAPDF"; 00271 } 00272 break; 00273 default: 00274 break; 00275 } 00276 throw runtime_error("Unknown particle for PDF Set"); 00277 } 00278 00279 00280 int Phojet::getPDFMember(PdgCode pid) { 00281 switch(pid) { 00282 case PROTON: 00283 case ANTIPROTON: 00284 return FC_PYPARS.mstp[50]; 00285 break; 00286 case ELECTRON: 00287 case POSITRON: 00288 return FC_PYPARS.mstp[54]; 00289 break; 00290 default: 00291 break; 00292 } 00293 throw runtime_error("Unknown particle for PDF Set"); 00294 } 00295 00296 00297 string Phojet::getPDFScheme(PdgCode pid) const { 00298 switch(pid){ 00299 case PROTON: 00300 case ANTIPROTON: 00301 if (FC_PYPARS.mstp[51]==1) { 00302 return "PYINTERNAL"; 00303 } else if(FC_PYPARS.mstp[51]==2) { 00304 return "LHAPDF"; 00305 } 00306 break; 00307 case ELECTRON: 00308 case POSITRON: 00309 if (FC_PYPARS.mstp[55]==1) { 00310 return "PYINTERNAL"; 00311 } else if(FC_PYPARS.mstp[55]==2) { 00312 return "LHAPDF"; 00313 } 00314 break; 00315 default: 00316 break; 00317 } 00318 throw runtime_error("Unknown particle for PDF Set"); 00319 } 00320 00321 00322 const double Phojet::getCrossSection(){ 00323 // _crossSection = FC_PYINT5.xsec[2][0] * 1e09; 00324 _crossSection = FC_PYPARS.pari[0] * 1e09; 00325 return _crossSection; 00326 } 00327 00328 const string Phojet::getVersion(){ 00329 stringstream s; 00330 s << FC_PYPARS.mstp[180] << "." << FC_PYPARS.mstp[181]; 00331 return s.str(); 00332 } 00333 00334 // Tidy up after ourselves 00335 void Phojet::finalize() { 00336 getLog() << Log::INFO << "Finalising..." << endl; 00337 // Print out stats from run 00338 double sig=0.; 00339 int irej=0; 00340 int mod = -2; 00341 FC_PHO_EVENT(&mod,_p1,_p2, &sig, &irej); 00342 } 00343 00344 00345 } 00346 00347 00348 extern "C" { 00349 AGILe::Generator* create() { return new AGILe::Phojet(); } 00350 void destroy(AGILe::Generator* gen) { delete gen; } 00351 }