CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
HydjetHadronizer.cc
Go to the documentation of this file.
1 /*
2  *
3  * Interface to the HYDJET generator, produces HepMC events
4  *
5  * Original Author: Camelia Mironov
6  */
7 
8 #include <iostream>
9 #include <cmath>
10 
11 #include "boost/lexical_cast.hpp"
12 
19 
25 
26 #include "HepMC/PythiaWrapper6_4.h"
27 #include "HepMC/GenEvent.h"
28 #include "HepMC/HeavyIon.h"
29 #include "HepMC/SimpleVector.h"
30 
35 
36 using namespace edm;
37 using namespace std;
38 using namespace gen;
39 
40 namespace {
41  int convertStatus(int st){
42  if(st<= 0) return 0;
43  if(st<=10) return 1;
44  if(st<=20) return 2;
45  if(st<=30) return 3;
46  else return st;
47  }
48 }
49 
50 const std::vector<std::string> HydjetHadronizer::theSharedResources = { edm::SharedResourceNames::kPythia6,
52 
53 //_____________________________________________________________________
54 HydjetHadronizer::HydjetHadronizer(const ParameterSet &pset) :
55  BaseHadronizer(pset),
56  evt(0),
57  pset_(pset),
58  abeamtarget_(pset.getParameter<double>("aBeamTarget")),
59  bfixed_(pset.getParameter<double>("bFixed")),
60  bmax_(pset.getParameter<double>("bMax")),
61  bmin_(pset.getParameter<double>("bMin")),
62  cflag_(pset.getParameter<int>("cFlag")),
63  embedding_(pset.getParameter<bool>("embeddingMode")),
64  comenergy(pset.getParameter<double>("comEnergy")),
65  doradiativeenloss_(pset.getParameter<bool>("doRadiativeEnLoss")),
66  docollisionalenloss_(pset.getParameter<bool>("doCollisionalEnLoss")),
67  fracsoftmult_(pset.getParameter<double>("fracSoftMultiplicity")),
68  hadfreeztemp_(pset.getParameter<double>("hadronFreezoutTemperature")),
69  hymode_(pset.getParameter<string>("hydjetMode")),
70  maxEventsToPrint_(pset.getUntrackedParameter<int>("maxEventsToPrint", 1)),
71  maxlongy_(pset.getParameter<double>("maxLongitudinalRapidity")),
72  maxtrany_(pset.getParameter<double>("maxTransverseRapidity")),
73  nsub_(0),
74  nhard_(0),
75  nmultiplicity_(pset.getParameter<int>("nMultiplicity")),
76  nsoft_(0),
77  nquarkflavor_(pset.getParameter<int>("qgpNumQuarkFlavor")),
78  pythiaPylistVerbosity_(pset.getUntrackedParameter<int>("pythiaPylistVerbosity", 0)),
79  qgpt0_(pset.getParameter<double>("qgpInitialTemperature")),
80  qgptau0_(pset.getParameter<double>("qgpProperTimeFormation")),
81  phi0_(0.),
82  sinphi0_(0.),
83  cosphi0_(1.),
84  rotate_(pset.getParameter<bool>("rotateEventPlane")),
85  shadowingswitch_(pset.getParameter<int>("shadowingSwitch")),
86  signn_(pset.getParameter<double>("sigmaInelNN")),
87  pythia6Service_(new Pythia6Service(pset))
88 {
89  // Default constructor
90 
91  // PYLIST Verbosity Level
92  // Valid PYLIST arguments are: 1, 2, 3, 5, 7, 11, 12, 13
93  pythiaPylistVerbosity_ = pset.getUntrackedParameter<int>("pythiaPylistVerbosity",0);
94  LogDebug("PYLISTverbosity") << "Pythia PYLIST verbosity level = " << pythiaPylistVerbosity_;
95 
96  //Max number of events printed on verbosity level
97  maxEventsToPrint_ = pset.getUntrackedParameter<int>("maxEventsToPrint",0);
98  LogDebug("Events2Print") << "Number of events to be printed = " << maxEventsToPrint_;
99 
100  if(embedding_) src_ = pset.getParameter<edm::InputTag>("backgroundLabel");
101 
102 }
103 
104 
105 //_____________________________________________________________________
107 {
108  // destructor
109  call_pystat(1);
110  delete pythia6Service_;
111 }
112 
113 
114 //_____________________________________________________________________
115 void HydjetHadronizer::doSetRandomEngine(CLHEP::HepRandomEngine* v)
116 {
118 }
119 
120 
121 //_____________________________________________________________________
122 void HydjetHadronizer::add_heavy_ion_rec(HepMC::GenEvent *evt)
123 {
124  // heavy ion record in the final CMSSW Event
125  double npart = hyfpar.npart;
126  int nproj = static_cast<int>(npart / 2);
127  int ntarg = static_cast<int>(npart - nproj);
128 
129  HepMC::HeavyIon* hi = new HepMC::HeavyIon(
130  nsub_, // Ncoll_hard/N of SubEvents
131  nproj, // Npart_proj
132  ntarg, // Npart_targ
133  static_cast<int>(hyfpar.nbcol), // Ncoll
134  0, // spectator_neutrons
135  0, // spectator_protons
136  0, // N_Nwounded_collisions
137  0, // Nwounded_N_collisions
138  0, // Nwounded_Nwounded_collisions
139  hyfpar.bgen * nuclear_radius(), // impact_parameter in [fm]
140  phi0_, // event_plane_angle
141  0, // eccentricity
142  hyjpar.sigin // sigma_inel_NN
143  );
144 
145  evt->set_heavy_ion(*hi);
146  delete hi;
147 }
148 
149 //___________________________________________________________________
151 {
152  // Build particle object corresponding to index in hyjets (soft+hard)
153 
154  double x0 = hyjets.phj[0][index];
155  double y0 = hyjets.phj[1][index];
156 
157  double x = x0*cosphi0_-y0*sinphi0_;
158  double y = y0*cosphi0_+x0*sinphi0_;
159 
161  HepMC::FourVector(x, // px
162  y, // py
163  hyjets.phj[2][index], // pz
164  hyjets.phj[3][index]), // E
165  hyjets.khj[1][index], // id
166  convertStatus(hyjets.khj[0][index] // status
167  )
168  );
169 
170  p->suggest_barcode(barcode);
171  return p;
172 }
173 
174 //___________________________________________________________________
175 HepMC::GenVertex* HydjetHadronizer::build_hyjet_vertex(int i,int id)
176 {
177  // build verteces for the hyjets stored events
178 
179  double x0=hyjets.vhj[0][i];
180  double y0=hyjets.vhj[1][i];
181  double x = x0*cosphi0_-y0*sinphi0_;
182  double y = y0*cosphi0_+x0*sinphi0_;
183  double z=hyjets.vhj[2][i];
184  double t=hyjets.vhj[4][i];
185 
186  HepMC::GenVertex* vertex = new HepMC::GenVertex(HepMC::FourVector(x,y,z,t),id);
187  return vertex;
188 }
189 
190 //___________________________________________________________________
191 
193 {
195 
196  // generate single event
197  if(embedding_){
198  cflag_ = 0;
199  const edm::Event& e = getEDMEvent();
201  e.getByLabel(src_,input);
202  const HepMC::GenEvent * inev = input->GetEvent();
203  const HepMC::HeavyIon* hi = inev->heavy_ion();
204  if(hi){
205  bfixed_ = hi->impact_parameter();
206  phi0_ = hi->event_plane_angle();
207  sinphi0_ = sin(phi0_);
208  cosphi0_ = cos(phi0_);
209  }else{
210  LogWarning("EventEmbedding")<<"Background event does not have heavy ion record!";
211  }
212  }else if(rotate_) rotateEvtPlane();
213 
214  nsoft_ = 0;
215  nhard_ = 0;
216 
217  edm::LogInfo("HYDJETmode") << "##### HYDJET nhsel = " << hyjpar.nhsel;
218  edm::LogInfo("HYDJETfpart") << "##### HYDJET fpart = " << hyflow.fpart;
219  edm::LogInfo("HYDJETtf") << "##### HYDJET hadron freez-out temp, Tf = " << hyflow.Tf;
220  edm::LogInfo("HYDJETinTemp") << "##### HYDJET: QGP init temperature, T0 ="<<pyqpar.T0u;
221  edm::LogInfo("HYDJETinTau") << "##### HYDJET: QGP formation time,tau0 ="<<pyqpar.tau0u;
222 
223  // generate a HYDJET event
224  int ntry = 0;
225  while(nsoft_ == 0 && nhard_ == 0){
226  if(ntry > 100){
227  edm::LogError("HydjetEmptyEvent") << "##### HYDJET: No Particles generated, Number of tries ="<<ntry;
228 
229  // Throw an exception. Use the EventCorruption exception since it maps onto SkipEvent
230  // which is what we want to do here.
231 
232  std::ostringstream sstr;
233  sstr << "HydjetHadronizerProducer: No particles generated after " << ntry << " tries.\n";
234  edm::Exception except(edm::errors::EventCorruption, sstr.str());
235  throw except;
236  } else {
237  HYEVNT();
238  nsoft_ = hyfpar.nhyd;
239  nsub_ = hyjpar.njet;
240  nhard_ = hyfpar.npyt;
241  ++ntry;
242  }
243  }
244 
245  if(hyjpar.nhsel < 3) nsub_++;
246 
247  // event information
248  HepMC::GenEvent *evt = new HepMC::GenEvent();
249 
250  if(nhard_>0 || nsoft_>0) get_particles(evt);
251 
252  evt->set_signal_process_id(pypars.msti[0]); // type of the process
253  evt->set_event_scale(pypars.pari[16]); // Q^2
254  add_heavy_ion_rec(evt);
255 
256  event().reset(evt);
257  return true;
258 }
259 
260 
261 //_____________________________________________________________________
262 bool HydjetHadronizer::get_particles(HepMC::GenEvent *evt )
263 {
264  // Hard particles. The first nhard_ lines from hyjets array.
265  // Pythia/Pyquen sub-events (sub-collisions) for a given event
266  // Return T/F if success/failure
267  // Create particles from lujet entries, assign them into vertices and
268  // put the vertices in the GenEvent, for each SubEvent
269  // The SubEvent information is kept by storing indeces of main vertices
270  // of subevents as a vector in GenHIEvent.
271 
272  LogDebug("SubEvent")<< "Number of sub events "<<nsub_;
273  LogDebug("Hydjet")<<"Number of hard events "<<hyjpar.njet;
274  LogDebug("Hydjet")<<"Number of hard particles "<<nhard_;
275  LogDebug("Hydjet")<<"Number of soft particles "<<nsoft_;
276 
277  vector<HepMC::GenVertex*> sub_vertices(nsub_);
278 
279  int ihy = 0;
280  for(int isub=0;isub<nsub_;isub++){
281  LogDebug("SubEvent") <<"Sub Event ID : "<<isub;
282 
283  int sub_up = (isub+1)*50000; // Upper limit in mother index, determining the range of Sub-Event
284  vector<HepMC::GenParticle*> particles;
285  vector<int> mother_ids;
286  vector<HepMC::GenVertex*> prods;
287 
288  sub_vertices[isub] = new HepMC::GenVertex(HepMC::FourVector(0,0,0,0),isub);
289  evt->add_vertex(sub_vertices[isub]);
290  if(!evt->signal_process_vertex()) evt->set_signal_process_vertex(sub_vertices[isub]);
291 
292  while(ihy<nhard_+nsoft_ && (hyjets.khj[2][ihy] < sub_up || ihy > nhard_ )){
293  particles.push_back(build_hyjet(ihy,ihy+1));
294  prods.push_back(build_hyjet_vertex(ihy,isub));
295  mother_ids.push_back(hyjets.khj[2][ihy]);
296  LogDebug("DecayChain")<<"Mother index : "<<hyjets.khj[2][ihy];
297 
298  ihy++;
299  }
300 
301  //Produce Vertices and add them to the GenEvent. Remember that GenParticles are adopted by
302  //GenVertex and GenVertex is adopted by GenEvent.
303 
304  LogDebug("Hydjet")<<"Number of particles in vector "<<particles.size();
305 
306  for (unsigned int i = 0; i<particles.size(); i++) {
307  HepMC::GenParticle* part = particles[i];
308 
309  //The Fortran code is modified to preserve mother id info, by seperating the beginning
310  //mother indices of successive subevents by 5000
311  int mid = mother_ids[i]-isub*50000-1;
312  LogDebug("DecayChain")<<"Particle "<<i;
313  LogDebug("DecayChain")<<"Mother's ID "<<mid;
314  LogDebug("DecayChain")<<"Particle's PDG ID "<<part->pdg_id();
315 
316  if(mid <= 0){
317  sub_vertices[isub]->add_particle_out(part);
318  continue;
319  }
320 
321  if(mid > 0){
322  HepMC::GenParticle* mother = particles[mid];
323  LogDebug("DecayChain")<<"Mother's PDG ID "<<mother->pdg_id();
324 
325  HepMC::GenVertex* prod_vertex = mother->end_vertex();
326  if(!prod_vertex){
327  prod_vertex = prods[i];
328  prod_vertex->add_particle_in(mother);
329  evt->add_vertex(prod_vertex);
330  prods[i]=0; // mark to protect deletion
331  }
332  prod_vertex->add_particle_out(part);
333  }
334  }
335  // cleanup vertices not assigned to evt
336  for (unsigned int i = 0; i<prods.size(); i++) {
337  if(prods[i]) delete prods[i];
338  }
339  }
340  return true;
341 }
342 
343 
344 //______________________________________________________________
345 bool HydjetHadronizer::call_hyinit(double energy,double a, int ifb, double bmin,
346  double bmax,double bfix,int nh)
347 {
348  // initialize hydjet
349 
350  pydatr.mrpy[2]=1;
351  HYINIT(energy,a,ifb,bmin,bmax,bfix,nh);
352  return true;
353 }
354 
355 
356 //______________________________________________________________
358 {
359  // set hydjet options
360 
361  // hydjet running mode mode
362  // kHydroOnly --- nhsel=0 jet production off (pure HYDRO event), nhsel=0
363  // kHydroJets --- nhsle=1 jet production on, jet quenching off (HYDRO+njet*PYTHIA events)
364  // kHydroQJet --- nhsel=2 jet production & jet quenching on (HYDRO+njet*PYQUEN events)
365  // kJetsOnly --- nhsel=3 jet production on, jet quenching off, HYDRO off (njet*PYTHIA events)
366  // kQJetsOnly --- nhsel=4 jet production & jet quenching on, HYDRO off (njet*PYQUEN events)
367 
368  if(hymode_ == "kHydroOnly") hyjpar.nhsel=0;
369  else if ( hymode_ == "kHydroJets") hyjpar.nhsel=1;
370  else if ( hymode_ == "kHydroQJets") hyjpar.nhsel=2;
371  else if ( hymode_ == "kJetsOnly") hyjpar.nhsel=3;
372  else if ( hymode_ == "kQJetsOnly") hyjpar.nhsel=4;
373  else hyjpar.nhsel=2;
374 
375  // fraction of soft hydro induced multiplicity
376  hyflow.fpart = fracsoftmult_;
377 
378  // hadron freez-out temperature
379  hyflow.Tf = hadfreeztemp_;
380 
381  // maximum longitudinal collective rapidity
382  hyflow.ylfl = maxlongy_;
383 
384  // maximum transverse collective rapidity
385  hyflow.ytfl = maxtrany_;
386 
387  // shadowing on=1, off=0
388  hyjpar.ishad = shadowingswitch_;
389 
390  // set inelastic nucleon-nucleon cross section
391  hyjpar.sigin = signn_;
392 
393  // number of active quark flavors in qgp
394  pyqpar.nfu = nquarkflavor_;
395 
396  // initial temperature of QGP
397  pyqpar.T0u = qgpt0_;
398 
399  // proper time of QGP formation
400  pyqpar.tau0u = qgptau0_;
401 
402  // type of medium induced partonic energy loss
404  edm::LogInfo("HydjetEnLoss") << "##### Radiative AND Collisional partonic energy loss ON ####";
405  pyqpar.ienglu = 0;
406  } else if ( doradiativeenloss_ ) {
407  edm::LogInfo("HydjetenLoss") << "##### Only RADIATIVE partonic energy loss ON ####";
408  pyqpar.ienglu = 1;
409  } else if ( docollisionalenloss_ ) {
410  edm::LogInfo("HydjetEnLoss") << "##### Only COLLISIONAL partonic energy loss ON ####";
411  pyqpar.ienglu = 2;
412  } else {
413  edm::LogInfo("HydjetEnLoss") << "##### Radiative AND Collisional partonic energy loss ON ####";
414  pyqpar.ienglu = 0;
415  }
416  return true;
417 }
418 
419 //_____________________________________________________________________
420 
422 
425 
426  return true;
427 
428 }
429 
430 //_____________________________________________________________________
431 
433 
435  // pythia6Service_->setGeneralParams();
436 
437  // the input impact parameter (bxx_) is in [fm]; transform in [fm/RA] for hydjet usage
438  const float ra = nuclear_radius();
439  LogInfo("RAScaling")<<"Nuclear radius(RA) = "<<ra;
440  bmin_ /= ra;
441  bmax_ /= ra;
442  bfixed_ /= ra;
443 
444  // hydjet running options
446  // initialize hydjet
447  LogInfo("HYDJETinAction") << "##### Calling HYINIT("<<comenergy<<","<<abeamtarget_<<","
448  <<cflag_<<","<<bmin_<<","<<bmax_<<","<<bfixed_<<","<<nmultiplicity_<<") ####";
450  return true;
451 }
452 
453 bool HydjetHadronizer::declareStableParticles(const std::vector<int>& _pdg )
454 {
455  std::vector<int> pdg = _pdg;
456  for ( size_t i=0; i < pdg.size(); i++ ) {
457  int pyCode = pycomp_( pdg[i] );
458  std::ostringstream pyCard ;
459  pyCard << "MDCY(" << pyCode << ",1)=0";
460  std::cout << pyCard.str() << std::endl;
461  call_pygive( pyCard.str() );
462  }
463  return true;
464 }
465 
466 //________________________________________________________________
468 {
469  const double pi = 3.14159265358979;
470  phi0_ = 2.*pi*gen::pyr_(0) - pi;
471  sinphi0_ = sin(phi0_);
472  cosphi0_ = cos(phi0_);
473 }
474 
475 
476 //________________________________________________________________
478 {
479  return false;
480 }
481 
483 {
484  return true;
485 }
486 
488 {
489  return true;
490 }
491 
493 {
494 }
495 
497 {
498 }
499 
500 const char* HydjetHadronizer::classname() const
501 {
502  return "gen::HydjetHadronizer";
503 }
#define LogDebug(id)
#define HYEVNT
Definition: HydjetWrapper.h:26
T getParameter(std::string const &) const
T getUntrackedParameter(std::string const &, T const &) const
int i
Definition: DBlmapReader.cc:9
virtual void doSetRandomEngine(CLHEP::HepRandomEngine *v) override
HepMC::GenEvent * evt
bool docollisionalenloss_
DEFAULT = true.
bool hydjet_init(const edm::ParameterSet &pset)
Sin< T >::type sin(const T &t)
Definition: Sin.h:22
bool call_pygive(const std::string &line)
const reco::GenParticle * mother(const reco::GenParticle &p, unsigned int imoth=0)
double npart
Definition: HydjetWrapper.h:44
void add_heavy_ion_rec(HepMC::GenEvent *evt)
#define hyfpar
Definition: HydjetWrapper.h:49
float float float z
double v[5][pyjets_maxn]
std::auto_ptr< HepMC::GenEvent > & event()
static std::string const input
Definition: EdmProvDump.cc:43
const Double_t pi
static const std::string kPythia6
#define HYINIT
Definition: HydjetWrapper.h:18
double p[5][pyjets_maxn]
Cos< T >::type cos(const T &t)
Definition: Cos.h:22
const char * classname() const
unsigned int maxEventsToPrint_
def convertStatus
Definition: crabWrap.py:174
bool getByLabel(InputTag const &tag, Handle< PROD > &result) const
Definition: Event.h:405
HepMC::GenParticle * build_hyjet(int index, int barcode)
Pythia6Service * pythia6Service_
#define hyjpar
Definition: HydjetWrapper.h:94
static const std::string kFortranInstance
int pycomp_(int &)
#define pypars
double fracsoftmult_
DEFAULT = true.
HepMC::GenVertex * build_hyjet_vertex(int i, int id)
part
Definition: HCALResponse.h:20
#define hyjets
Definition: HydjetWrapper.h:79
double nuclear_radius() const
bool call_hyinit(double energy, double a, int ifb, double bmin, double bmax, double bfix, int nh)
unsigned int pythiaPylistVerbosity_
void setRandomEngine(CLHEP::HepRandomEngine *v)
#define pyqpar
#define hyflow
Definition: HydjetWrapper.h:37
double a
Definition: hdecay.h:121
edm::ParameterSet pset_
unsigned int shadowingswitch_
tuple cout
Definition: gather_cfg.py:121
Definition: DDAxes.h:10
double pyr_(int *idummy)
bool declareStableParticles(const std::vector< int > &)
bool get_particles(HepMC::GenEvent *evt)
edm::Event & getEDMEvent() const