00001
00002
00003
00004
00005
00006
00007
00008
00009 #include <iostream>
00010 #include <cmath>
00011
00012 #include "boost/lexical_cast.hpp"
00013
00014 #include "FWCore/Framework/interface/Event.h"
00015 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00016 #include "FWCore/ParameterSet/interface/ParameterSet.h"
00017 #include "FWCore/ServiceRegistry/interface/Service.h"
00018 #include "FWCore/Utilities/interface/RandomNumberGenerator.h"
00019 #include "FWCore/Utilities/interface/EDMException.h"
00020 #include "CLHEP/Random/RandomEngine.h"
00021
00022 #include "GeneratorInterface/HydjetInterface/interface/HydjetProducer.h"
00023 #include "GeneratorInterface/HydjetInterface/interface/PYR.h"
00024 #include "GeneratorInterface/HydjetInterface/interface/HydjetWrapper.h"
00025 #include "GeneratorInterface/CommonInterface/interface/PythiaCMS.h"
00026
00027 #include "HepMC/PythiaWrapper6_2.h"
00028 #include "HepMC/GenEvent.h"
00029 #include "HepMC/HeavyIon.h"
00030 #include "HepMC/SimpleVector.h"
00031
00032 #include "SimDataFormats/HepMCProduct/interface/HepMCProduct.h"
00033 #include "SimDataFormats/HiGenData/interface/GenHIEvent.h"
00034
00035
00036 using namespace edm;
00037 using namespace std;
00038
00039
00040 HydjetProducer::HydjetProducer(const ParameterSet &pset) :
00041 EDProducer(), evt(0),
00042 abeamtarget_(pset.getParameter<double>("aBeamTarget")),
00043 bfixed_(pset.getParameter<double>("bFixed")),
00044 bmax_(pset.getParameter<double>("bMax")),
00045 bmin_(pset.getParameter<double>("bMin")),
00046 cflag_(pset.getParameter<int>("cFlag")),
00047 comenergy(pset.getParameter<double>("comEnergy")),
00048 doradiativeenloss_(pset.getParameter<bool>("doRadiativeEnLoss")),
00049 docollisionalenloss_(pset.getParameter<bool>("doCollisionalEnLoss")),
00050 fracsoftmult_(pset.getParameter<double>("fracSoftMultiplicity")),
00051 hadfreeztemp_(pset.getParameter<double>("hadronFreezoutTemperature")),
00052 hymode_(pset.getParameter<string>("hydjetMode")),
00053 maxEventsToPrint_(pset.getUntrackedParameter<int>("maxEventsToPrint", 1)),
00054 maxlongy_(pset.getParameter<double>("maxLongitudinalRapidity")),
00055 maxtrany_(pset.getParameter<double>("maxTransverseRapidity")),
00056 nsub_(0),
00057 nhard_(0),
00058 nmultiplicity_(pset.getParameter<int>("nMultiplicity")),
00059 nsoft_(0),
00060 nquarkflavor_(pset.getParameter<int>("qgpNumQuarkFlavor")),
00061 pythiaPylistVerbosity_(pset.getUntrackedParameter<int>("pythiaPylistVerbosity", 0)),
00062 qgpt0_(pset.getParameter<double>("qgpInitialTemperature")),
00063 qgptau0_(pset.getParameter<double>("qgpProperTimeFormation")),
00064 shadowingswitch_(pset.getParameter<int>("shadowingSwitch")),
00065 signn_(pset.getParameter<double>("sigmaInelNN")),
00066 eventNumber_(0)
00067 {
00068
00069
00070
00071
00072 pythiaPylistVerbosity_ = pset.getUntrackedParameter<int>("pythiaPylistVerbosity",0);
00073 LogDebug("PYLISTverbosity") << "Pythia PYLIST verbosity level = " << pythiaPylistVerbosity_;
00074
00075
00076 maxEventsToPrint_ = pset.getUntrackedParameter<int>("maxEventsToPrint",0);
00077 LogDebug("Events2Print") << "Number of events to be printed = " << maxEventsToPrint_;
00078
00079
00080 const float ra = nuclear_radius();
00081 LogInfo("RAScaling")<<"Nuclear radius(RA) = "<<ra;
00082 bmin_ /= ra;
00083 bmax_ /= ra;
00084 bfixed_ /= ra;
00085
00086
00087 hyjpythia_init(pset);
00088
00089
00090 hydjet_init(pset);
00091
00092
00093 LogInfo("HYDJETinAction") << "##### Calling HYINIT("<<comenergy<<","<<abeamtarget_<<","<<cflag_<<","<<bmin_<<","<<bmax_<<","<<bfixed_<<","<<nmultiplicity_<<") ####";
00094
00095 call_hyinit(comenergy,abeamtarget_,cflag_,bmin_,bmax_,bfixed_,nmultiplicity_);
00096
00097 produces<HepMCProduct>();
00098 produces<GenHIEvent>();
00099 }
00100
00101
00102
00103 HydjetProducer::~HydjetProducer()
00104 {
00105
00106
00107 call_pystat(1);
00108
00109 clear();
00110 }
00111
00112
00113
00114 void HydjetProducer::add_heavy_ion_rec(HepMC::GenEvent *evt)
00115 {
00116
00117
00118 HepMC::HeavyIon* hi = new HepMC::HeavyIon(
00119 nsub_,
00120 static_cast<int>(hyfpar.npart / 2),
00121 static_cast<int>(hyfpar.npart / 2),
00122 static_cast<int>(hyfpar.nbcol),
00123 0,
00124 0,
00125 0,
00126 0,
00127 0,
00128 hyfpar.bgen * nuclear_radius(),
00129 0,
00130 0,
00131 hyjpar.sigin
00132 );
00133
00134 evt->set_heavy_ion(*hi);
00135 delete hi;
00136
00137 }
00138
00139
00140
00141 HepMC::GenParticle* HydjetProducer::build_hyjet(int index, int barcode)
00142 {
00143
00144
00145 HepMC::GenParticle* p = new HepMC::GenParticle(
00146 HepMC::FourVector(hyjets.phj[0][index],
00147 hyjets.phj[1][index],
00148 hyjets.phj[2][index],
00149 hyjets.phj[3][index]),
00150 hyjets.khj[1][index],
00151 hyjets.khj[0][index]
00152 );
00153 p->suggest_barcode(barcode);
00154
00155 return p;
00156 }
00157
00158
00159
00160 HepMC::GenVertex* HydjetProducer::build_hyjet_vertex(int i,int id)
00161 {
00162
00163
00164 double x=hyjets.vhj[0][i];
00165 double y=hyjets.vhj[1][i];
00166 double z=hyjets.vhj[2][i];
00167 double t=hyjets.vhj[4][i];
00168
00169 HepMC::GenVertex* vertex = new HepMC::GenVertex(HepMC::FourVector(x,y,z,t),id);
00170 return vertex;
00171 }
00172
00173
00174
00175 bool HydjetProducer::call_pygive(const std::string& iParm )
00176 {
00177
00178
00179 int numWarn = pydat1.mstu[26];
00180 int numErr = pydat1.mstu[22];
00181
00182 PYGIVE( iParm.c_str(), iParm.length() );
00183
00184
00185 return pydat1.mstu[26] == numWarn && pydat1.mstu[22] == numErr;
00186 }
00187
00188
00189
00190 void HydjetProducer::clear()
00191 {
00192
00193 }
00194
00195
00196
00197 bool HydjetProducer::get_hard_particles(HepMC::GenEvent *evt, vector<SubEvent>& subs )
00198 {
00199
00200
00201
00202
00203
00204
00205
00206
00207 int nhard = nhard_;
00208
00209 vector<HepMC::GenVertex*> sub_vertices(nsub_);
00210
00211 int ihy = 0;
00212 for(int isub=0;isub<nsub_;isub++){
00213
00214 int sub_up = (isub+1)*10000;
00215 vector<HepMC::GenParticle*> particles;
00216 vector<int> mother_ids;
00217 vector<HepMC::GenVertex*> prods;
00218
00219 sub_vertices[isub] = new HepMC::GenVertex(HepMC::FourVector(0,0,0,0),isub);
00220 evt->add_vertex(sub_vertices[isub]);
00221 subs.push_back(SubEvent(isub));
00222
00223 while(ihy<nhard && hyjets.khj[2][ihy] < sub_up){
00224
00225 particles.push_back(build_hyjet(ihy,ihy+1));
00226 prods.push_back(build_hyjet_vertex(ihy,isub));
00227 mother_ids.push_back(hyjets.khj[2][ihy]);
00228
00229 ihy++;
00230 }
00231
00232
00233
00234
00235 for (unsigned int i = 0; i<particles.size(); i++) {
00236
00237 HepMC::GenParticle* part = particles[i];
00238
00239
00240
00241
00242 int mid = mother_ids[i]-isub*10000-1;
00243 if(mid <= 0){
00244 sub_vertices[isub]->add_particle_out(part);
00245 continue;
00246 }
00247
00248 if(mid > 0){
00249 HepMC::GenParticle* mother = particles[mid];
00250 HepMC::GenVertex* prod_vertex = mother->end_vertex();
00251 if(!prod_vertex){
00252 prod_vertex = prods[i];
00253 prod_vertex->add_particle_in(mother);
00254 evt->add_vertex(prod_vertex);
00255 prods[i]=0;
00256 }
00257 prod_vertex->add_particle_out(part);
00258 }
00259 }
00260
00261
00262 for (unsigned int i = 0; i<prods.size(); i++) {
00263 if(prods[i]) delete prods[i];
00264 }
00265 }
00266 return true;
00267 }
00268
00269
00270
00271 bool HydjetProducer::get_soft_particles(HepMC::GenEvent *evt, vector<SubEvent>& subs)
00272 {
00273
00274
00275
00276
00277 vector<HepMC::GenParticle*> hyj_entries(nsoft_);
00278 for (int i1 = 0; i1<nsoft_; i1++) {
00279 hyj_entries[i1] = build_hyjet(nhard_+i1, nhard_+i1+1);
00280 }
00281 HepMC::GenVertex* soft_vertex = new HepMC::GenVertex(HepMC::FourVector(0,0,0,0),nsub_);
00282 subs.push_back(SubEvent(nsub_));
00283
00284 for ( int i2 = 0; i2<nsoft_; i2++ ) {
00285 soft_vertex->add_particle_out( hyj_entries[i2] ) ;
00286 }
00287 evt->add_vertex( soft_vertex );
00288
00289 return true;
00290 }
00291
00292
00293
00294 bool HydjetProducer::call_hyinit(double energy,double a, int ifb, double bmin,
00295 double bmax,double bfix,int nh)
00296 {
00297
00298
00299 pydatr.mrpy[2]=1;
00300 HYINIT(energy,a,ifb,bmin,bmax,bfix,nh);
00301 return true;
00302 }
00303
00304
00305
00306 bool HydjetProducer::hydjet_init(const ParameterSet &pset)
00307 {
00308
00309
00310 edm::Service<RandomNumberGenerator> rng;
00311 randomEngine = fRandomEngine = &(rng->getEngine());
00312 uint32_t seed = rng->mySeed();
00313 ludatr.mrlu[0]=seed;
00314
00315
00316
00317
00318
00319
00320
00321
00322 if(hymode_ == "kHydroOnly") hyjpar.nhsel=0;
00323 else if ( hymode_ == "kHydroJets") hyjpar.nhsel=1;
00324 else if ( hymode_ == "kHydroQJets") hyjpar.nhsel=2;
00325 else if ( hymode_ == "kJetsOnly") hyjpar.nhsel=3;
00326 else if ( hymode_ == "kQJetsOnly") hyjpar.nhsel=4;
00327 else hyjpar.nhsel=2;
00328
00329
00330 hyflow.fpart = fracsoftmult_;
00331
00332
00333 hyflow.Tf = hadfreeztemp_;
00334
00335
00336 hyflow.ylfl = maxlongy_;
00337
00338
00339 hyflow.ytfl = maxtrany_;
00340
00341
00342 hyjpar.ishad = shadowingswitch_;
00343
00344
00345 hyjpar.sigin = signn_;
00346
00347
00348 pyqpar.nfu = nquarkflavor_;
00349
00350
00351 pyqpar.T0u = qgpt0_;
00352
00353
00354 pyqpar.tau0u = qgptau0_;
00355
00356
00357 if( doradiativeenloss_ && docollisionalenloss_ ){
00358 edm::LogInfo("HydjetEnLoss") << "##### Radiative AND Collisional partonic energy loss ON ####";
00359 pyqpar.ienglu = 0;
00360 } else if ( doradiativeenloss_ ) {
00361 edm::LogInfo("HydjetenLoss") << "##### Only RADIATIVE partonic energy loss ON ####";
00362 pyqpar.ienglu = 1;
00363 } else if ( docollisionalenloss_ ) {
00364 edm::LogInfo("HydjetEnLoss") << "##### Only COLLISIONAL partonic energy loss ON ####";
00365 pyqpar.ienglu = 2;
00366 } else {
00367 edm::LogInfo("HydjetEnLoss") << "##### Radiative AND Collisional partonic energy loss ON ####";
00368 pyqpar.ienglu = 0;
00369 }
00370
00371 return true;
00372 }
00373
00374
00375
00376 bool HydjetProducer::hyjpythia_init(const ParameterSet &pset)
00377 {
00378
00379
00380
00381 edm::Service<RandomNumberGenerator> rng;
00382 uint32_t seed = rng->mySeed();
00383 ostringstream sRandomSet;
00384 sRandomSet << "MRPY(1)=" << seed;
00385 call_pygive(sRandomSet.str());
00386
00387
00388 ParameterSet pythia_params = pset.getParameter<ParameterSet>("PythiaParameters") ;
00389
00390 vector<string> setNames = pythia_params.getParameter<vector<string> >("parameterSets");
00391
00392
00393 for ( unsigned i=0; i<setNames.size(); ++i ) {
00394 string mySet = setNames[i];
00395
00396
00397 vector<string> pars = pythia_params.getParameter<vector<string> >(mySet);
00398
00399 cout << "----------------------------------------------" << endl;
00400 cout << "Read PYTHIA parameter set " << mySet << endl;
00401 cout << "----------------------------------------------" << endl;
00402
00403
00404 for( vector<string>::const_iterator itPar = pars.begin(); itPar != pars.end(); ++itPar ) {
00405 static string sRandomValueSetting("MRPY(1)");
00406 if( 0 == itPar->compare(0,sRandomValueSetting.size(),sRandomValueSetting) ) {
00407 throw edm::Exception(edm::errors::Configuration,"PythiaError")
00408 <<" Attempted to set random number using 'MRPY(1)'. NOT ALLOWED! \n Use RandomNumberGeneratorService to set the random number seed.";
00409 }
00410 if( !call_pygive(*itPar) ) {
00411 throw edm::Exception(edm::errors::Configuration,"PythiaError")
00412 <<"PYTHIA did not accept \""<<*itPar<<"\"";
00413 }
00414 }
00415 }
00416
00417 return true;
00418 }
00419
00420
00421
00422 void HydjetProducer::produce(Event & e, const EventSetup& es)
00423 {
00424
00425
00426 nsoft_ = 0;
00427 nhard_ = 0;
00428
00429 edm::LogInfo("HYDJETmode") << "##### HYDJET nhsel = " << hyjpar.nhsel;
00430 edm::LogInfo("HYDJETfpart") << "##### HYDJET fpart = " << hyflow.fpart;
00431 edm::LogInfo("HYDJETtf") << "##### HYDJET hadron freez-out temp, Tf = " << hyflow.Tf;
00432 edm::LogInfo("HYDJETinTemp") << "##### HYDJET: QGP init temperature, T0 ="<<pyqpar.T0u;
00433 edm::LogInfo("HYDJETinTau") << "##### HYDJET: QGP formation time,tau0 ="<<pyqpar.tau0u;
00434
00435
00436
00437 int ntry = 0;
00438 while(nsoft_ == 0 && nhard_ == 0){
00439 if(ntry > 100){
00440 edm::LogError("HydjetEmptyEvent") << "##### HYDJET: No Particles generated, Number of tries ="<<ntry;
00441
00442
00443
00444
00445 std::ostringstream sstr;
00446 sstr << "HydjetProducerProducer: No particles generated after " << ntry << " tries.\n";
00447 edm::Exception except(edm::errors::EventCorruption, sstr.str());
00448 throw except;
00449 } else {
00450 HYEVNT();
00451 nsoft_ = hyfpar.nhyd;
00452 nsub_ = hyjpar.njet;
00453 nhard_ = hyfpar.npyt;
00454 ++ntry;
00455 }
00456 }
00457
00458 std::vector<SubEvent> subvector;
00459
00460
00461 HepMC::GenEvent *evt = new HepMC::GenEvent();
00462
00463 if(nhard_>0) get_hard_particles(evt,subvector);
00464 if(nsoft_>0) get_soft_particles(evt,subvector);
00465
00466 evt->set_signal_process_id(pypars.msti[0]);
00467 evt->set_event_scale(pypars.pari[16]);
00468 ++eventNumber_;
00469 evt->set_event_number(eventNumber_);
00470
00471 add_heavy_ion_rec(evt);
00472
00473 auto_ptr<HepMCProduct> bare_product(new HepMCProduct());
00474 bare_product->addHepMCData(evt );
00475 auto_ptr<GenHIEvent> genhi(new GenHIEvent(subvector,hyjpar.nhsel));
00476 e.put(bare_product);
00477 e.put(genhi);
00478
00479
00480 if (e.id().event() <= maxEventsToPrint_ && pythiaPylistVerbosity_)
00481 call_pylist(pythiaPylistVerbosity_);
00482 }
00483
00484
00485