CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_6_1_2_SLHC4_patch1/src/GeneratorInterface/PyquenInterface/src/PyquenHadronizer.cc

Go to the documentation of this file.
00001 /*
00002  *
00003  * Generates PYQUEN HepMC events
00004  *
00005  * $Id: PyquenHadronizer.cc,v 1.13 2011/03/02 10:35:17 yilmaz Exp $
00006 */
00007 
00008 #include <iostream>
00009 #include "time.h"
00010 
00011 #include "GeneratorInterface/PyquenInterface/interface/PyquenHadronizer.h"
00012 #include "GeneratorInterface/PyquenInterface/interface/PyquenWrapper.h"
00013 #include "GeneratorInterface/Pythia6Interface/interface/Pythia6Declarations.h"
00014 #include "GeneratorInterface/Pythia6Interface/interface/Pythia6Service.h"
00015 
00016 #include "SimDataFormats/GeneratorProducts/interface/GenEventInfoProduct.h"
00017 
00018 #include "SimDataFormats/GeneratorProducts/interface/HepMCProduct.h"
00019 #include "FWCore/Framework/interface/Event.h"
00020 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00021 #include "FWCore/ServiceRegistry/interface/Service.h"
00022 #include "FWCore/Utilities/interface/RandomNumberGenerator.h"
00023 
00024 #include "GeneratorInterface/HiGenCommon/interface/HiGenEvtSelectorFactory.h"
00025 
00026 #include "HepMC/IO_HEPEVT.h"
00027 #include "HepMC/PythiaWrapper.h"
00028 
00029 using namespace gen;
00030 using namespace edm;
00031 using namespace std;
00032 
00033 HepMC::IO_HEPEVT hepevtio;
00034 
00035 PyquenHadronizer :: PyquenHadronizer(const ParameterSet & pset):
00036    BaseHadronizer(pset),
00037    pset_(pset),
00038 abeamtarget_(pset.getParameter<double>("aBeamTarget")),
00039 angularspecselector_(pset.getParameter<int>("angularSpectrumSelector")),
00040 bmin_(pset.getParameter<double>("bMin")),
00041 bmax_(pset.getParameter<double>("bMax")),
00042 bfixed_(pset.getParameter<double>("bFixed")),
00043 cflag_(pset.getParameter<int>("cFlag")),
00044 comenergy(pset.getParameter<double>("comEnergy")),
00045 doquench_(pset.getParameter<bool>("doQuench")),
00046 doradiativeenloss_(pset.getParameter<bool>("doRadiativeEnLoss")),
00047 docollisionalenloss_(pset.getParameter<bool>("doCollisionalEnLoss")),
00048 doIsospin_(pset.getParameter<bool>("doIsospin")),
00049 embedding_(pset.getParameter<bool>("embeddingMode")),
00050 evtPlane_(0),
00051 nquarkflavor_(pset.getParameter<int>("qgpNumQuarkFlavor")),
00052 qgpt0_(pset.getParameter<double>("qgpInitialTemperature")),
00053 qgptau0_(pset.getParameter<double>("qgpProperTimeFormation")),
00054 maxEventsToPrint_(pset.getUntrackedParameter<int>("maxEventsToPrint",1)),
00055 pythiaHepMCVerbosity_(pset.getUntrackedParameter<bool>("pythiaHepMCVerbosity",false)),
00056 pythiaPylistVerbosity_(pset.getUntrackedParameter<int>("pythiaPylistVerbosity",0)),
00057 pythia6Service_(new Pythia6Service(pset)),
00058 filterType_(pset.getUntrackedParameter<string>("filterType","None"))
00059 {
00060   // Verbosity Level
00061   // Valid PYLIST arguments are: 1, 2, 3, 5, 7, 11, 12, 13
00062   LogDebug("PYLISTverbosity") << "Pythia PYLIST verbosity level = " << pythiaPylistVerbosity_ << endl;
00063   // HepMC event verbosity Level
00064   pythiaHepMCVerbosity_ = pset.getUntrackedParameter<bool>("pythiaHepMCVerbosity",false);
00065   LogDebug("HepMCverbosity")  << "Pythia HepMC verbosity = " << pythiaHepMCVerbosity_ << endl; 
00066 
00067   //Max number of events printed on verbosity level 
00068   maxEventsToPrint_ = pset.getUntrackedParameter<int>("maxEventsToPrint",0);
00069   LogDebug("Events2Print") << "Number of events to be printed = " << maxEventsToPrint_ << endl;
00070 
00071   if(embedding_){ 
00072      cflag_ = 0;
00073      src_ = pset.getParameter<InputTag>("backgroundLabel");
00074   }
00075   selector_ = HiGenEvtSelectorFactory::get(filterType_,pset);
00076 
00077 }
00078 
00079 
00080 //_____________________________________________________________________
00081 PyquenHadronizer::~PyquenHadronizer()
00082 {
00083   // distructor
00084   call_pystat(1);
00085 
00086   delete pythia6Service_;
00087 
00088 }
00089 
00090 
00091 //_____________________________________________________________________
00092 void PyquenHadronizer::add_heavy_ion_rec(HepMC::GenEvent *evt)
00093 {
00094   HepMC::HeavyIon *hi = new HepMC::HeavyIon(
00095     1,                                 // Ncoll_hard
00096     -1,                                 // Npart_proj
00097     -1,                                 // Npart_targ
00098     1,                                 // Ncoll
00099     -1,                                 // spectator_neutrons
00100     -1,                                 // spectator_protons
00101     -1,                                 // N_Nwounded_collisions
00102     -1,                                 // Nwounded_N_collisions
00103     -1,                                 // Nwounded_Nwounded_collisions
00104     plfpar.bgen,                        // impact_parameter in [fm]
00105     evtPlane_,                                  // event_plane_angle
00106     0,                                  // eccentricity
00107     -1                                  // sigma_inel_NN
00108   );
00109 
00110   evt->set_heavy_ion(*hi);
00111 
00112   delete hi;
00113 }
00114 
00115 //_____________________________________________________________________
00116 bool PyquenHadronizer::generatePartonsAndHadronize()
00117 {
00118    Pythia6Service::InstanceWrapper guard(pythia6Service_);
00119 
00120    // Not possible to retrieve impact paramter and event plane info
00121    // at this part, need to overwrite filter() in 
00122    // PyquenGeneratorFilter 
00123 
00124    const edm::Event& e = getEDMEvent();
00125 
00126    if(embedding_){
00127       Handle<HepMCProduct> input;
00128       e.getByLabel(src_,input);
00129       const HepMC::GenEvent * inev = input->GetEvent();
00130       const HepMC::HeavyIon* hi = inev->heavy_ion();
00131       if(hi){
00132          bfixed_ = hi->impact_parameter();
00133          evtPlane_ = hi->event_plane_angle();
00134       }else{
00135          LogWarning("EventEmbedding")<<"Background event does not have heavy ion record!";
00136       }
00137    }
00138 
00139    // Generate PYQUEN event
00140    // generate single partonic PYTHIA jet event
00141    
00142    // Take into account whether it's a nn or pp or pn interaction
00143    if(doIsospin_) call_pyinit("CMS", nucleon(), nucleon(), comenergy);
00144    call_pyevnt();
00145    
00146    // call PYQUEN to apply parton rescattering and energy loss 
00147    // if doQuench=FALSE, it is pure PYTHIA
00148    if( doquench_ ){
00149      PYQUEN(abeamtarget_,cflag_,bfixed_,bmin_,bmax_);
00150      edm::LogInfo("PYQUENinAction") << "##### Calling PYQUEN("<<abeamtarget_<<","<<cflag_<<","<<bfixed_<<") ####";
00151    } else {
00152      edm::LogInfo("PYQUENinAction") << "##### Calling PYQUEN: QUENCHING OFF!! This is just PYTHIA !!!! ####";
00153    }
00154    
00155    // call PYTHIA to finish the hadronization
00156    pyexec_();
00157    
00158    // fill the HEPEVT with the PYJETS event record
00159    call_pyhepc(1);
00160    
00161    // event information
00162     HepMC::GenEvent* evt = hepevtio.read_next_event();
00163 
00164    evt->set_signal_process_id(pypars.msti[0]);      // type of the process
00165    evt->set_event_scale(pypars.pari[16]);           // Q^2
00166    
00167    if(embedding_) rotateEvtPlane(evt,evtPlane_);
00168    add_heavy_ion_rec(evt);
00169    
00170    event().reset(evt);
00171 
00172   return true;
00173 }
00174 
00175 bool PyquenHadronizer::readSettings( int )
00176 {
00177 
00178    Pythia6Service::InstanceWrapper guard(pythia6Service_);
00179    pythia6Service_->setGeneralParams();
00180    pythia6Service_->setCSAParams();
00181 
00182    //Proton to Nucleon fraction
00183    pfrac_ = 1./(1.98+0.015*pow(abeamtarget_,2./3));
00184 
00185    //initialize pythia         
00186    pyqpythia_init(pset_);
00187 
00188    //initilize pyquen          
00189    pyquen_init(pset_);
00190 
00191    return true;
00192 
00193 }
00194 
00195 bool PyquenHadronizer::initializeForInternalPartons(){
00196 
00197 
00198    Pythia6Service::InstanceWrapper guard(pythia6Service_);
00199 
00200    // Call PYTHIA              
00201    call_pyinit("CMS", "p", "p", comenergy);
00202 
00203    return true;
00204 }
00205 
00206 
00207 //_____________________________________________________________________
00208 bool PyquenHadronizer::pyqpythia_init(const ParameterSet & pset)
00209 {
00210 
00211   //Turn Hadronization Off whether or not there is quenching  
00212   // PYEXEC is called later anyway
00213   string sHadOff("MSTP(111)=0");
00214   gen::call_pygive(sHadOff);
00215 
00216   return true;
00217 }
00218 
00219 
00220 //_________________________________________________________________
00221 bool PyquenHadronizer::pyquen_init(const ParameterSet &pset)
00222 {
00223   // PYQUEN initialization
00224 
00225   // angular emitted gluon  spectrum selection 
00226   pyqpar.ianglu = angularspecselector_;
00227 
00228   // type of medium induced partonic energy loss
00229   if( doradiativeenloss_ && docollisionalenloss_ ){
00230     edm::LogInfo("PYQUENinEnLoss") << "##### PYQUEN: Radiative AND Collisional partonic energy loss ON ####";
00231     pyqpar.ienglu = 0; 
00232   } else if ( doradiativeenloss_ ) {
00233     edm::LogInfo("PYQUENinRad") << "##### PYQUEN: Only RADIATIVE partonic energy loss ON ####";
00234     pyqpar.ienglu = 1; 
00235   } else if ( docollisionalenloss_ ) {
00236     edm::LogInfo("PYQUENinColl") << "##### PYQUEN: Only COLLISIONAL partonic energy loss ON ####";
00237     pyqpar.ienglu = 2; 
00238   } else {
00239     edm::LogInfo("PYQUENinEnLoss") << "##### PYQUEN: Radiative AND Collisional partonic energy loss ON ####";
00240     pyqpar.ienglu = 0; 
00241   }
00242 
00243   // number of active quark flavors in qgp
00244   pyqpar.nfu    = nquarkflavor_;
00245   // initial temperature of QGP
00246   pyqpar.T0u    = qgpt0_;
00247   // proper time of QGP formation
00248   pyqpar.tau0u  = qgptau0_;
00249 
00250   return true;
00251 }
00252 
00253 const char* PyquenHadronizer::nucleon(){
00254   int* dummy = 0;
00255   double random = gen::pyr_(dummy);
00256   const char* nuc = 0;
00257   if(random > pfrac_) nuc = "n";
00258   else nuc = "p";
00259   
00260   return nuc;
00261 }
00262 
00263 void PyquenHadronizer::rotateEvtPlane(HepMC::GenEvent* evt, double angle){
00264 
00265    double sinphi0 = sin(angle);
00266    double cosphi0 = cos(angle);
00267 
00268    for ( HepMC::GenEvent::vertex_iterator vt=evt->vertices_begin();
00269          vt!=evt->vertices_end(); ++vt )
00270       {
00271          
00272          double x0 = (*vt)->position().x();
00273          double y0 = (*vt)->position().y();
00274          double z = (*vt)->position().z();
00275          double t = (*vt)->position().t();
00276 
00277          double x = x0*cosphi0-y0*sinphi0;
00278          double y = y0*cosphi0+x0*sinphi0;
00279 
00280          (*vt)->set_position( HepMC::FourVector(x,y,z,t) ) ;      
00281       }
00282 
00283    for ( HepMC::GenEvent::particle_iterator vt=evt->particles_begin();
00284          vt!=evt->particles_end(); ++vt )
00285       {
00286 
00287          double x0 = (*vt)->momentum().x();
00288          double y0 = (*vt)->momentum().y();
00289          double z = (*vt)->momentum().z();
00290          double t = (*vt)->momentum().t();
00291 
00292          double x = x0*cosphi0-y0*sinphi0;
00293          double y = y0*cosphi0+x0*sinphi0;
00294 
00295          (*vt)->set_momentum( HepMC::FourVector(x,y,z,t) ) ;
00296       }
00297 }
00298 
00299 bool PyquenHadronizer::declareStableParticles( std::vector<int> pdg )
00300 {
00301    for ( size_t i=0; i < pdg.size(); i++ )
00302       {
00303          int pyCode = pycomp_( pdg[i] );
00304          std::ostringstream pyCard ;
00305          pyCard << "MDCY(" << pyCode << ",1)=0";
00306          std::cout << pyCard.str() << std::endl;
00307          call_pygive( pyCard.str() );
00308       }
00309 
00310    return true;
00311 
00312 }
00313 
00314 
00315 
00316 //____________________________________________________________________
00317 
00318 bool PyquenHadronizer::hadronize()
00319 {
00320    return false;
00321 }
00322 
00323 bool PyquenHadronizer::decay()
00324 {
00325    return true;
00326 }
00327 
00328 bool PyquenHadronizer::residualDecay()
00329 {
00330    return true;
00331 }
00332 
00333 void PyquenHadronizer::finalizeEvent(){
00334 
00335 }
00336 
00337 void PyquenHadronizer::statistics(){
00338 }
00339 
00340 const char* PyquenHadronizer::classname() const
00341 {
00342    return "gen::PyquenHadronizer";
00343 }
00344 
00345 
00346