CMS 3D CMS Logo

HydjetProducer.cc

Go to the documentation of this file.
00001 /*
00002  * $Id: HydjetProducer.cc,v 1.3 2008/04/21 16:51:48 yilmaz Exp $
00003  *
00004  * Interface to the HYDJET generator, produces HepMC events
00005  *
00006  * Original Author: Camelia Mironov
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   // Default constructor
00069 
00070   // PYLIST Verbosity Level
00071   // Valid PYLIST arguments are: 1, 2, 3, 5, 7, 11, 12, 13
00072   pythiaPylistVerbosity_ = pset.getUntrackedParameter<int>("pythiaPylistVerbosity",0);
00073   LogDebug("PYLISTverbosity") << "Pythia PYLIST verbosity level = " << pythiaPylistVerbosity_;
00074 
00075   //Max number of events printed on verbosity level 
00076   maxEventsToPrint_ = pset.getUntrackedParameter<int>("maxEventsToPrint",0);
00077   LogDebug("Events2Print") << "Number of events to be printed = " << maxEventsToPrint_;
00078 
00079   // the input impact parameter (bxx_) is in [fm]; transform in [fm/RA] for hydjet usage
00080   const float ra = nuclear_radius();
00081   LogInfo("RAScaling")<<"Nuclear radius(RA) =  "<<ra;
00082   bmin_     /= ra;
00083   bmax_     /= ra;
00084   bfixed_   /= ra;
00085 
00086   // initialize pythia
00087   hyjpythia_init(pset);
00088 
00089   // hydjet running options
00090   hydjet_init(pset);
00091 
00092   // initialize hydjet
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   // destructor
00106 
00107   call_pystat(1);
00108 
00109   clear();
00110 }
00111 
00112 
00113 //_____________________________________________________________________
00114 void HydjetProducer::add_heavy_ion_rec(HepMC::GenEvent *evt)
00115 {
00116   // heavy ion record in the final CMSSW Event
00117 
00118   HepMC::HeavyIon* hi = new HepMC::HeavyIon(
00119     nsub_,                               // Ncoll_hard/N of SubEvents
00120     static_cast<int>(hyfpar.npart / 2),  // Npart_proj
00121     static_cast<int>(hyfpar.npart / 2),  // Npart_targ
00122     static_cast<int>(hyfpar.nbcol),      // Ncoll
00123     0,                                   // spectator_neutrons
00124     0,                                   // spectator_protons
00125     0,                                   // N_Nwounded_collisions
00126     0,                                   // Nwounded_N_collisions
00127     0,                                   // Nwounded_Nwounded_collisions
00128     hyfpar.bgen * nuclear_radius(),      // impact_parameter in [fm]
00129     0,                                   // event_plane_angle
00130     0,                                   // eccentricity
00131     hyjpar.sigin                         // sigma_inel_NN
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    // Build particle object corresponding to index in hyjets (soft+hard)
00144 
00145    HepMC::GenParticle* p = new HepMC::GenParticle(
00146                                                   HepMC::FourVector(hyjets.phj[0][index],  // px
00147                                                                     hyjets.phj[1][index],  // py
00148                                                                     hyjets.phj[2][index],  // pz
00149                                                                     hyjets.phj[3][index]), // E
00150                                                   hyjets.khj[1][index],// id
00151                                                   hyjets.khj[0][index] // status
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   // build verteces for the hyjets stored events 
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   // Set Pythia parameters
00178 
00179   int numWarn = pydat1.mstu[26]; //# warnings
00180   int numErr = pydat1.mstu[22];// # errors
00181   // call the fortran routine pygive with a fortran string
00182   PYGIVE( iParm.c_str(), iParm.length() );  
00183 
00184   // if an error or warning happens it is problem
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    // Hard particles. The first nhard_ lines from hyjets array.
00200    // Pythia/Pyquen sub-events (sub-collisions) for a given event
00201    // Return T/F if success/failure
00202    // Create particles from lujet entries, assign them into vertices and 
00203    // put the vertices in the GenEvent, for each SubEvent
00204    // The SubEvent information is kept by storing indeces of main vertices 
00205    // of subevents as a vector in GenHIEvent.
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; // Upper limit in mother index, determining the range of Sub-Event
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       //Produce Vertices and add them to the GenEvent. Remember that GenParticles are adopted by
00233       //GenVertex and GenVertex is adopted by GenEvent.
00234 
00235       for (unsigned int i = 0; i<particles.size(); i++) {
00236 
00237          HepMC::GenParticle* part = particles[i];
00238 
00239          //The Fortran code is modified to preserve mother id info, by seperating the beginning 
00240          //mother indices of successive subevents by 10000.
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; // mark to protect deletion
00256             }
00257             prod_vertex->add_particle_out(part);
00258          }
00259       }
00260 
00261       // cleanup vertices not assigned to evt
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    // Soft particles. The last nsoft_ lines of hyjets
00274    // It corresponds to HYDRO-induced, hadrons only
00275    // As they have no mothers and no daughters, all are assigned to a single background vertex
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   // initialize hydjet  
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   // set hydjet options
00309 
00310   edm::Service<RandomNumberGenerator> rng;
00311   randomEngine = fRandomEngine = &(rng->getEngine());
00312   uint32_t seed = rng->mySeed();
00313   ludatr.mrlu[0]=seed;
00314 
00315   // hydjet running mode mode
00316   // kHydroOnly --- nhsel=0 jet production off (pure HYDRO event), nhsel=0
00317   // kHydroJets --- nhsle=1 jet production on, jet quenching off (HYDRO+njet*PYTHIA events)
00318   // kHydroQJet --- nhsel=2 jet production & jet quenching on (HYDRO+njet*PYQUEN events)
00319   // kJetsOnly  --- nhsel=3 jet production on, jet quenching off, HYDRO off (njet*PYTHIA events)
00320   // kQJetsOnly --- nhsel=4 jet production & jet quenching on, HYDRO off (njet*PYQUEN events)
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   // fraction of soft hydro induced multiplicity 
00330   hyflow.fpart =  fracsoftmult_; 
00331 
00332   // hadron freez-out temperature
00333   hyflow.Tf   = hadfreeztemp_;
00334 
00335   // maximum longitudinal collective rapidity
00336   hyflow.ylfl = maxlongy_;
00337   
00338   // maximum transverse collective rapidity
00339   hyflow.ytfl = maxtrany_;  
00340 
00341   // shadowing on=1, off=0
00342   hyjpar.ishad  = shadowingswitch_;
00343 
00344   // set inelastic nucleon-nucleon cross section
00345   hyjpar.sigin  = signn_;
00346 
00347   // number of active quark flavors in qgp
00348   pyqpar.nfu    = nquarkflavor_;
00349 
00350   // initial temperature of QGP
00351   pyqpar.T0u    = qgpt0_;
00352 
00353   // proper time of QGP formation
00354   pyqpar.tau0u  = qgptau0_;
00355 
00356   // type of medium induced partonic energy loss
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   //Set PYTHIA parameters
00379 
00380   //random number seed
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     // Set PYTHIA parameters in a single ParameterSet
00388   ParameterSet pythia_params = pset.getParameter<ParameterSet>("PythiaParameters") ;
00389   // The parameter sets to be read 
00390   vector<string> setNames = pythia_params.getParameter<vector<string> >("parameterSets");
00391 
00392     // Loop over the sets
00393   for ( unsigned i=0; i<setNames.size(); ++i ) {
00394     string mySet = setNames[i];
00395     
00396     // Read the PYTHIA parameters for each set of parameters
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     // Loop over all parameters and stop in case of mistake
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   // generate single event
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   // generate a HYDJET event
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 // Throw an exception.  Use the EventCorruption exception since it maps onto SkipEvent
00443 // which is what we want to do here.
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   // event information
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]);      // type of the process
00467   evt->set_event_scale(pypars.pari[16]);           // Q^2
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   // print PYLIST info
00480   if (e.id().event() <= maxEventsToPrint_ && pythiaPylistVerbosity_)     
00481      call_pylist(pythiaPylistVerbosity_);      
00482 }
00483 
00484 
00485 //________________________________________________________________

Generated on Tue Jun 9 17:36:57 2009 for CMSSW by  doxygen 1.5.4