CMS 3D CMS Logo

HydjetSource.cc

Go to the documentation of this file.
00001 /*
00002  * $Id: HydjetSource.cc,v 1.20 2008/04/11 08:49:31 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/Framework/interface/InputSourceDescription.h"
00016 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00017 #include "FWCore/ParameterSet/interface/ParameterSet.h"
00018 #include "FWCore/ServiceRegistry/interface/Service.h"
00019 #include "FWCore/Utilities/interface/RandomNumberGenerator.h"
00020 
00021 #include "GeneratorInterface/HydjetInterface/interface/HydjetSource.h"
00022 #include "GeneratorInterface/HydjetInterface/interface/PYR.h"
00023 #include "GeneratorInterface/HydjetInterface/interface/HydjetWrapper.h"
00024 #include "GeneratorInterface/CommonInterface/interface/PythiaCMS.h"
00025 
00026 #include "HepMC/PythiaWrapper6_2.h"
00027 #include "HepMC/GenEvent.h"
00028 #include "HepMC/HeavyIon.h"
00029 #include "HepMC/SimpleVector.h"
00030 
00031 #include "SimDataFormats/HepMCProduct/interface/HepMCProduct.h"
00032 #include "SimDataFormats/HiGenData/interface/GenHIEvent.h"
00033 
00034 
00035 using namespace edm;
00036 using namespace std;
00037 
00038 
00039 HydjetSource::HydjetSource(const ParameterSet &pset, InputSourceDescription const &desc)
00040   : GeneratedInputSource(pset, desc), evt(0), 
00041     abeamtarget_(pset.getParameter<double>("aBeamTarget")),
00042     bfixed_(pset.getParameter<double>("bFixed")),
00043     bmax_(pset.getParameter<double>("bMax")),
00044     bmin_(pset.getParameter<double>("bMin")),
00045     cflag_(pset.getParameter<int>("cFlag")),
00046     comenergy(pset.getParameter<double>("comEnergy")),
00047     doradiativeenloss_(pset.getParameter<bool>("doRadiativeEnLoss")),
00048     docollisionalenloss_(pset.getParameter<bool>("doCollisionalEnLoss")),
00049     fracsoftmult_(pset.getParameter<double>("fracSoftMultiplicity")),
00050     hadfreeztemp_(pset.getParameter<double>("hadronFreezoutTemperature")),
00051     hymode_(pset.getParameter<string>("hydjetMode")),
00052     maxEventsToPrint_(pset.getUntrackedParameter<int>("maxEventsToPrint", 1)),
00053     maxlongy_(pset.getParameter<double>("maxLongitudinalRapidity")),
00054     maxtrany_(pset.getParameter<double>("maxTransverseRapidity")),
00055     nsub_(0),
00056     nhard_(0),
00057     nmultiplicity_(pset.getParameter<int>("nMultiplicity")),
00058     nsoft_(0),
00059     nquarkflavor_(pset.getParameter<int>("qgpNumQuarkFlavor")),
00060     pythiaPylistVerbosity_(pset.getUntrackedParameter<int>("pythiaPylistVerbosity", 0)),
00061     qgpt0_(pset.getParameter<double>("qgpInitialTemperature")),
00062     qgptau0_(pset.getParameter<double>("qgpProperTimeFormation")),
00063     shadowingswitch_(pset.getParameter<int>("shadowingSwitch")),
00064     signn_(pset.getParameter<double>("sigmaInelNN"))
00065 {
00066   // Default constructor
00067 
00068   // PYLIST Verbosity Level
00069   // Valid PYLIST arguments are: 1, 2, 3, 5, 7, 11, 12, 13
00070   pythiaPylistVerbosity_ = pset.getUntrackedParameter<int>("pythiaPylistVerbosity",0);
00071   LogDebug("PYLISTverbosity") << "Pythia PYLIST verbosity level = " << pythiaPylistVerbosity_;
00072 
00073   //Max number of events printed on verbosity level 
00074   maxEventsToPrint_ = pset.getUntrackedParameter<int>("maxEventsToPrint",0);
00075   LogDebug("Events2Print") << "Number of events to be printed = " << maxEventsToPrint_;
00076 
00077   // the input impact parameter (bxx_) is in [fm]; transform in [fm/RA] for hydjet usage
00078   const float ra = nuclear_radius();
00079   LogInfo("RAScaling")<<"Nuclear radius(RA) =  "<<ra;
00080   bmin_     /= ra;
00081   bmax_     /= ra;
00082   bfixed_   /= ra;
00083 
00084   // initialize pythia
00085   hyjpythia_init(pset);
00086 
00087   // hydjet running options
00088   hydjet_init(pset);
00089 
00090   // initialize hydjet
00091   LogInfo("HYDJETinAction") << "##### Calling HYINIT("<<comenergy<<","<<abeamtarget_<<","<<cflag_<<","<<bmin_<<","<<bmax_<<","<<bfixed_<<","<<nmultiplicity_<<") ####";
00092 
00093   call_hyinit(comenergy,abeamtarget_,cflag_,bmin_,bmax_,bfixed_,nmultiplicity_);
00094     
00095   produces<HepMCProduct>();
00096   produces<GenHIEvent>();
00097 }
00098 
00099 
00100 //_____________________________________________________________________
00101 HydjetSource::~HydjetSource()
00102 {
00103   // destructor
00104 
00105   call_pystat(1);
00106 
00107   clear();
00108 }
00109 
00110 
00111 //_____________________________________________________________________
00112 void HydjetSource::add_heavy_ion_rec(HepMC::GenEvent *evt)
00113 {
00114   // heavy ion record in the final CMSSW Event
00115 
00116   HepMC::HeavyIon* hi = new HepMC::HeavyIon(
00117     nsub_,                               // Ncoll_hard/N of SubEvents
00118     static_cast<int>(hyfpar.npart / 2),  // Npart_proj
00119     static_cast<int>(hyfpar.npart / 2),  // Npart_targ
00120     static_cast<int>(hyfpar.nbcol),      // Ncoll
00121     0,                                   // spectator_neutrons
00122     0,                                   // spectator_protons
00123     0,                                   // N_Nwounded_collisions
00124     0,                                   // Nwounded_N_collisions
00125     0,                                   // Nwounded_Nwounded_collisions
00126     hyfpar.bgen * nuclear_radius(),      // impact_parameter in [fm]
00127     0,                                   // event_plane_angle
00128     0,                                   // eccentricity
00129     hyjpar.sigin                         // sigma_inel_NN
00130   );
00131 
00132   evt->set_heavy_ion(*hi);
00133 
00134   delete hi;
00135 }
00136 
00137 
00138 //________________________________________________________________
00139 HepMC::GenParticle* HydjetSource::build_hyjet(int index, int barcode)
00140 {
00141    // Build particle object corresponding to index in hyjets (soft+hard)
00142 
00143    HepMC::GenParticle* p = new HepMC::GenParticle(
00144                                                   HepMC::FourVector(hyjets.phj[0][index],  // px
00145                                                                     hyjets.phj[1][index],  // py
00146                                                                     hyjets.phj[2][index],  // pz
00147                                                                     hyjets.phj[3][index]), // E
00148                                                   hyjets.khj[1][index],// id
00149                                                   hyjets.khj[0][index] // status
00150                                                   );
00151    p->suggest_barcode(barcode);
00152 
00153    return p;
00154 }
00155 
00156 
00157 //___________________________________________________________________
00158 HepMC::GenVertex* HydjetSource::build_hyjet_vertex(int i,int id)
00159 {
00160   // build verteces for the hyjets stored events 
00161 
00162    double x=hyjets.vhj[0][i];
00163    double y=hyjets.vhj[1][i];
00164    double z=hyjets.vhj[2][i];
00165    double t=hyjets.vhj[4][i];
00166 
00167    HepMC::GenVertex* vertex = new HepMC::GenVertex(HepMC::FourVector(x,y,z,t),id);
00168    return vertex;
00169 }
00170 
00171 
00172 //______________________________________________________________________
00173 bool HydjetSource::call_pygive(const std::string& iParm ) 
00174 {
00175   // Set Pythia parameters
00176 
00177   int numWarn = pydat1.mstu[26]; //# warnings
00178   int numErr = pydat1.mstu[22];// # errors
00179   // call the fortran routine pygive with a fortran string
00180   PYGIVE( iParm.c_str(), iParm.length() );  
00181 
00182   // if an error or warning happens it is problem
00183   return pydat1.mstu[26] == numWarn && pydat1.mstu[22] == numErr;   
00184 }
00185 
00186 
00187 //____________________________________________________________________
00188 void HydjetSource::clear()
00189 {
00190 
00191 }
00192 
00193 
00194 //_____________________________________________________________________
00195 bool HydjetSource::get_hard_particles(HepMC::GenEvent *evt, vector<SubEvent>& subs )
00196 {
00197    // Hard particles. The first nhard_ lines from hyjets array.
00198    // Pythia/Pyquen sub-events (sub-collisions) for a given event
00199    // Return T/F if success/failure
00200    // Create particles from lujet entries, assign them into vertices and 
00201    // put the vertices in the GenEvent, for each SubEvent
00202    // The SubEvent information is kept by storing indeces of main vertices 
00203    // of subevents as a vector in GenHIEvent.
00204 
00205    int nhard = nhard_;
00206    
00207    vector<HepMC::GenVertex*>  sub_vertices(nsub_); 
00208 
00209    int ihy  = 0;   
00210    for(int isub=0;isub<nsub_;isub++){
00211      
00212       int sub_up = (isub+1)*10000; // Upper limit in mother index, determining the range of Sub-Event
00213       vector<HepMC::GenParticle*> particles;
00214       vector<int>                 mother_ids;
00215       vector<HepMC::GenVertex*>   prods;
00216 
00217       sub_vertices[isub] = new HepMC::GenVertex(HepMC::FourVector(0,0,0,0),isub);
00218       evt->add_vertex(sub_vertices[isub]);
00219       subs.push_back(SubEvent(isub));
00220 
00221       while(ihy<nhard && hyjets.khj[2][ihy] < sub_up){
00222         
00223          particles.push_back(build_hyjet(ihy,ihy+1));
00224          prods.push_back(build_hyjet_vertex(ihy,isub));
00225          mother_ids.push_back(hyjets.khj[2][ihy]);
00226 
00227          ihy++;
00228       }       
00229 
00230       //Produce Vertices and add them to the GenEvent. Remember that GenParticles are adopted by
00231       //GenVertex and GenVertex is adopted by GenEvent.
00232 
00233       for (unsigned int i = 0; i<particles.size(); i++) {
00234 
00235          HepMC::GenParticle* part = particles[i];
00236 
00237          //The Fortran code is modified to preserve mother id info, by seperating the beginning 
00238          //mother indices of successive subevents by 10000.
00239          int mid = mother_ids[i]-isub*10000-1;
00240          if(mid <= 0){
00241             sub_vertices[isub]->add_particle_out(part);
00242             continue;
00243          }
00244 
00245          if(mid > 0){
00246             HepMC::GenParticle* mother = particles[mid];
00247             HepMC::GenVertex* prod_vertex = mother->end_vertex();
00248             if(!prod_vertex){
00249                prod_vertex = prods[i];
00250                prod_vertex->add_particle_in(mother);
00251                evt->add_vertex(prod_vertex);
00252                prods[i]=0; // mark to protect deletion
00253             }
00254             prod_vertex->add_particle_out(part);
00255          }
00256       }
00257 
00258       // cleanup vertices not assigned to evt
00259       for (unsigned int i = 0; i<prods.size(); i++) {
00260          if(prods[i]) delete prods[i];
00261       }
00262    }
00263 
00264   return true;
00265 }
00266 
00267 
00268 //___________________________________________________________
00269 bool HydjetSource::get_soft_particles(HepMC::GenEvent *evt, vector<SubEvent>& subs)
00270 {
00271    // Soft particles. The last nsoft_ lines of hyjets
00272    // It corresponds to HYDRO-induced, hadrons only
00273    // As they have no mothers and no daughters, all are assigned to a single background vertex
00274 
00275    vector<HepMC::GenParticle*> hyj_entries(nsoft_);
00276    for (int i1 = 0; i1<nsoft_; i1++) {
00277       hyj_entries[i1] = build_hyjet(nhard_+i1, nhard_+i1+1);
00278    }
00279    HepMC::GenVertex* soft_vertex = new HepMC::GenVertex(HepMC::FourVector(0,0,0,0),nsub_);
00280    subs.push_back(SubEvent(nsub_));
00281    
00282    for ( int i2 = 0; i2<nsoft_; i2++ ) {
00283       soft_vertex->add_particle_out( hyj_entries[i2] ) ;
00284    } 
00285    evt->add_vertex( soft_vertex );
00286 
00287    return true;
00288 }
00289 
00290 
00291 //______________________________________________________________
00292 bool HydjetSource::call_hyinit(double energy,double a, int ifb, double bmin,
00293                                double bmax,double bfix,int nh)
00294 {
00295   // initialize hydjet  
00296 
00297    pydatr.mrpy[2]=1;
00298    HYINIT(energy,a,ifb,bmin,bmax,bfix,nh);
00299     return true;
00300 }
00301 
00302 
00303 //______________________________________________________________
00304 bool HydjetSource::hydjet_init(const ParameterSet &pset)
00305 {
00306   // set hydjet options
00307 
00308   edm::Service<RandomNumberGenerator> rng;
00309   randomEngine = &(rng->getEngine());
00310   uint32_t seed = rng->mySeed();
00311   ludatr.mrlu[0]=seed;
00312 
00313   // hydjet running mode mode
00314   // kHydroOnly --- nhsel=0 jet production off (pure HYDRO event), nhsel=0
00315   // kHydroJets --- nhsle=1 jet production on, jet quenching off (HYDRO+njet*PYTHIA events)
00316   // kHydroQJet --- nhsel=2 jet production & jet quenching on (HYDRO+njet*PYQUEN events)
00317   // kJetsOnly  --- nhsel=3 jet production on, jet quenching off, HYDRO off (njet*PYTHIA events)
00318   // kQJetsOnly --- nhsel=4 jet production & jet quenching on, HYDRO off (njet*PYQUEN events)
00319 
00320   if(hymode_ == "kHydroOnly") hyjpar.nhsel=0;
00321   else if ( hymode_ == "kHydroJets") hyjpar.nhsel=1;
00322   else if ( hymode_ == "kHydroQJets") hyjpar.nhsel=2;
00323   else if ( hymode_ == "kJetsOnly") hyjpar.nhsel=3;
00324   else if ( hymode_ == "kQJetsOnly") hyjpar.nhsel=4;
00325   else  hyjpar.nhsel=2;
00326 
00327   // fraction of soft hydro induced multiplicity 
00328   hyflow.fpart =  fracsoftmult_; 
00329 
00330   // hadron freez-out temperature
00331   hyflow.Tf   = hadfreeztemp_;
00332 
00333   // maximum longitudinal collective rapidity
00334   hyflow.ylfl = maxlongy_;
00335   
00336   // maximum transverse collective rapidity
00337   hyflow.ytfl = maxtrany_;  
00338 
00339   // shadowing on=1, off=0
00340   hyjpar.ishad  = shadowingswitch_;
00341 
00342   // set inelastic nucleon-nucleon cross section
00343   hyjpar.sigin  = signn_;
00344 
00345   // number of active quark flavors in qgp
00346   pyqpar.nfu    = nquarkflavor_;
00347 
00348   // initial temperature of QGP
00349   pyqpar.T0u    = qgpt0_;
00350 
00351   // proper time of QGP formation
00352   pyqpar.tau0u  = qgptau0_;
00353 
00354   // type of medium induced partonic energy loss
00355   if( doradiativeenloss_ && docollisionalenloss_ ){
00356     edm::LogInfo("HydjetEnLoss") << "##### Radiative AND Collisional partonic energy loss ON ####";
00357     pyqpar.ienglu = 0; 
00358   } else if ( doradiativeenloss_ ) {
00359     edm::LogInfo("HydjetenLoss") << "##### Only RADIATIVE partonic energy loss ON ####";
00360     pyqpar.ienglu = 1; 
00361   } else if ( docollisionalenloss_ ) {
00362     edm::LogInfo("HydjetEnLoss") << "##### Only COLLISIONAL partonic energy loss ON ####";
00363     pyqpar.ienglu = 2; 
00364   } else {
00365     edm::LogInfo("HydjetEnLoss") << "##### Radiative AND Collisional partonic energy loss ON ####";
00366     pyqpar.ienglu = 0; 
00367   }
00368 
00369   return true;
00370 }
00371 
00372 
00373 //____________________________________________________________________
00374 bool HydjetSource::hyjpythia_init(const ParameterSet &pset)
00375 {
00376   //Set PYTHIA parameters
00377 
00378   //random number seed
00379   edm::Service<RandomNumberGenerator> rng;
00380   uint32_t seed = rng->mySeed();
00381   ostringstream sRandomSet;
00382   sRandomSet << "MRPY(1)=" << seed;
00383   call_pygive(sRandomSet.str());
00384 
00385     // Set PYTHIA parameters in a single ParameterSet
00386   ParameterSet pythia_params = pset.getParameter<ParameterSet>("PythiaParameters") ;
00387   // The parameter sets to be read 
00388   vector<string> setNames = pythia_params.getParameter<vector<string> >("parameterSets");
00389 
00390     // Loop over the sets
00391   for ( unsigned i=0; i<setNames.size(); ++i ) {
00392     string mySet = setNames[i];
00393     
00394     // Read the PYTHIA parameters for each set of parameters
00395     vector<string> pars = pythia_params.getParameter<vector<string> >(mySet);
00396     
00397     cout << "----------------------------------------------" << endl;
00398     cout << "Read PYTHIA parameter set " << mySet << endl;
00399     cout << "----------------------------------------------" << endl;
00400     
00401     // Loop over all parameters and stop in case of mistake
00402     for( vector<string>::const_iterator itPar = pars.begin(); itPar != pars.end(); ++itPar ) {
00403       static string sRandomValueSetting("MRPY(1)");
00404       if( 0 == itPar->compare(0,sRandomValueSetting.size(),sRandomValueSetting) ) {
00405         throw edm::Exception(edm::errors::Configuration,"PythiaError")
00406           <<" Attempted to set random number using 'MRPY(1)'. NOT ALLOWED! \n Use RandomNumberGeneratorService to set the random number seed.";
00407       }
00408       if( !call_pygive(*itPar) ) {
00409         throw edm::Exception(edm::errors::Configuration,"PythiaError") 
00410           <<"PYTHIA did not accept \""<<*itPar<<"\"";
00411       }
00412     }
00413   }
00414 
00415   return true;
00416 }
00417 
00418 
00419 //_____________________________________________________________________
00420 bool HydjetSource::produce(Event & e)
00421 {
00422   // generate single event
00423 
00424   nsoft_    = 0;
00425   nhard_    = 0;
00426 
00427   edm::LogInfo("HYDJETmode") << "##### HYDJET  nhsel = " << hyjpar.nhsel;
00428   edm::LogInfo("HYDJETfpart") << "##### HYDJET fpart = " << hyflow.fpart;
00429   edm::LogInfo("HYDJETtf") << "##### HYDJET hadron freez-out temp, Tf = " << hyflow.Tf;
00430   edm::LogInfo("HYDJETinTemp") << "##### HYDJET: QGP init temperature, T0 ="<<pyqpar.T0u;
00431   edm::LogInfo("HYDJETinTau") << "##### HYDJET: QGP formation time,tau0 ="<<pyqpar.tau0u;
00432 
00433   // generate a HYDJET event
00434   int ntry = 0;
00435   while(nsoft_ == 0 && nhard_ == 0){
00436      if(ntry > 100){
00437         edm::LogError("HydjetEmptyEvent") << "##### HYDJET: No Particles generated, Number of tries ="<<ntry;
00438         return false;
00439      }else{
00440         HYEVNT();
00441         nsoft_    = hyfpar.nhyd;
00442         nhard_    = hyfpar.npyt;
00443         ntry++;
00444      }
00445   }
00446   
00447   nsub_     = hyjpar.njet;
00448 
00449   std::vector<SubEvent> subvector;
00450 
00451   // event information
00452   HepMC::GenEvent *evt = new HepMC::GenEvent();
00453 
00454   if(nhard_>0) get_hard_particles(evt,subvector); 
00455   if(nsoft_>0) get_soft_particles(evt,subvector);
00456 
00457   evt->set_signal_process_id(pypars.msti[0]);      // type of the process
00458   evt->set_event_scale(pypars.pari[16]);           // Q^2
00459   evt->set_event_number(numberEventsInRun() - remainingEvents() - 1);
00460 
00461   add_heavy_ion_rec(evt);
00462 
00463   auto_ptr<HepMCProduct> bare_product(new HepMCProduct());
00464   bare_product->addHepMCData(evt );
00465   auto_ptr<GenHIEvent> genhi(new GenHIEvent(subvector,hyjpar.nhsel));
00466   e.put(bare_product);
00467   e.put(genhi);
00468 
00469   // print PYLIST info
00470   if (event() <= maxEventsToPrint_ && pythiaPylistVerbosity_)     
00471      call_pylist(pythiaPylistVerbosity_);      
00472   
00473   return true;
00474 }
00475 

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