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