CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
Pythia8Hadronizer.cc
Go to the documentation of this file.
1 #include <iostream>
2 #include <sstream>
3 #include <string>
4 #include <memory>
5 #include <stdint.h>
6 
7 #include <HepMC/GenEvent.h>
8 #include <HepMC/GenParticle.h>
9 
10 #include <Pythia.h>
11 #include <HepMCInterface.h>
12 
14 
16 
17 // PS matchning prototype
18 //
20 
21 
22 // Emission Veto Hooks
23 //
26 
31 
34 
38 
40 
41 #include "HepPID/ParticleIDTranslations.hh"
42 
44 
45 using namespace gen;
46 using namespace Pythia8;
47 
49 
50  public:
51 
52  Pythia8Hadronizer(const edm::ParameterSet &params);
54 
55  bool initializeForInternalPartons();
56  bool initializeForExternalPartons();
57 
58  bool generatePartonsAndHadronize();
59  bool hadronize();
60 
61  virtual bool residualDecay();
62 
63  void finalizeEvent();
64 
65  void statistics();
66 
67  const char *classname() const { return "Pythia8Hadronizer"; }
68 
69  private:
70 
72  double comEnergy;
73 
75  std::auto_ptr<LHAupLesHouches> lhaUP;
76 
77  enum { PP, PPbar, ElectronPositron };
78  int fInitialState ; // pp, ppbar, or e-e+
79 
80  double fBeam1PZ;
81  double fBeam2PZ;
82 
83  // Reweight user hook
84  //
85  UserHooks* fReweightUserHook;
86 
87  // PS matching protot6ype
88  //
90 
91  // Emission Veto Hooks
92  //
95 
97  bool EV1_vetoOn;
104 
105 };
106 
107 
109  BaseHadronizer(params), Py8InterfaceBase(params),
110  comEnergy(params.getParameter<double>("comEnergy")),
111  LHEInputFileName(params.getUntrackedParameter<string>("LHEInputFileName","")),
112  fInitialState(PP),
113  fReweightUserHook(0),
114  fJetMatchingHook(0),
115  fEmissionVetoHook(0),fEmissionVetoHook1(0)
116 {
117 
118  // J.Y.: the following 3 parameters are hacked "for a reason"
119  //
120  if ( params.exists( "PPbarInitialState" ) )
121  {
122  if ( fInitialState == PP )
123  {
125  edm::LogInfo("GeneratorInterface|Pythia6Interface")
126  << "Pythia6 will be initialized for PROTON-ANTIPROTON INITIAL STATE. "
127  << "This is a user-request change from the DEFAULT PROTON-PROTON initial state." << std::endl;
128  std::cout << "Pythia6 will be initialized for PROTON-ANTIPROTON INITIAL STATE." << std::endl;
129  std::cout << "This is a user-request change from the DEFAULT PROTON-PROTON initial state." << std::endl;
130  }
131  else
132  {
133  // probably need to throw on attempt to override ?
134  }
135  }
136  else if ( params.exists( "ElectronPositronInitialState" ) )
137  {
138  if ( fInitialState == PP )
139  {
141  edm::LogInfo("GeneratorInterface|Pythia6Interface")
142  << "Pythia6 will be initialized for ELECTRON-POSITRON INITIAL STATE. "
143  << "This is a user-request change from the DEFAULT PROTON-PROTON initial state." << std::endl;
144  std::cout << "Pythia6 will be initialized for ELECTRON-POSITRON INITIAL STATE." << std::endl;
145  std::cout << "This is a user-request change from the DEFAULT PROTON-PROTON initial state." << std::endl;
146  }
147  else
148  {
149  // probably need to throw on attempt to override ?
150  }
151  }
152  else if ( params.exists( "ElectronProtonInitialState" ) || params.exists( "PositronProtonInitialState" ) )
153  {
154  // throw on unknown initial state !
155  throw edm::Exception(edm::errors::Configuration,"Pythia8Interface")
156  <<" UNKNOWN INITIAL STATE. \n The allowed initial states are: PP, PPbar, ElectronPositron \n";
157  }
158 
159  if( params.exists( "SLHAFileForPythia8" ) ) {
160  std::string slhafilenameshort = params.getParameter<string>("SLHAFileForPythia8");
161  edm::FileInPath f1( slhafilenameshort );
162  std::string slhafilename = f1.fullPath();
163  std::string pythiacommandslha = std::string("SLHA:file = ") + slhafilename;
164  fMasterGen->readString(pythiacommandslha);
166  line != fParameters.end(); ++line ) {
167  if (line->find("SLHA:file") != std::string::npos)
168  throw cms::Exception("PythiaError") << "Attempted to set SLHA file name twice, "
169  << "using Pythia8 card SLHA:file and Pythia8Interface card SLHAFileForPythia8"
170  << std::endl;
171  }
172  }
173 
174  // Reweight user hook
175  //
176  if( params.exists( "reweightGen" ) )
178 
179  if( params.exists( "useUserHook" ) )
180  throw edm::Exception(edm::errors::Configuration,"Pythia8Interface")
181  <<" Obsolete parameter: useUserHook \n Please use the actual one instead \n";
182 
183  // PS matching prototype
184  //
185  if ( params.exists("jetMatching") )
186  {
187  edm::ParameterSet jmParams =
188  params.getUntrackedParameter<edm::ParameterSet>("jetMatching");
189  std::string scheme = jmParams.getParameter<std::string>("scheme");
190  if ( scheme == "Madgraph" || scheme == "MadgraphFastJet" )
191  {
192  fJetMatchingHook = new JetMatchingHook( jmParams, &fMasterGen->info );
193  }
194  }
195 
196  // Emission vetos
197  //
198  if ( params.exists("emissionVeto") )
199  {
201  }
202 
203  if ( params.exists("emissionVeto1") )
204  {
205  EV1_nFinal = -1;
206  if(params.exists("EV1_nFinal")) EV1_nFinal = params.getParameter<int>("EV1_nFinal");
207  EV1_vetoOn = true;
208  if(params.exists("EV1_vetoOn")) EV1_vetoOn = params.getParameter<bool>("EV1_vetoOn");
209  EV1_maxVetoCount = 10;
210  if(params.exists("EV1_maxVetoCount")) EV1_maxVetoCount = params.getParameter<int>("EV1_maxVetoCount");
211  EV1_pThardMode = 1;
212  if(params.exists("EV1_pThardMode")) EV1_pThardMode = params.getParameter<int>("EV1_pThardMode");
213  EV1_pTempMode = 0;
214  if(params.exists("EV1_pTempMode")) EV1_pTempMode = params.getParameter<int>("EV1_pTempMode");
215  if(EV1_pTempMode > 2 || EV1_pTempMode < 0)
216  throw edm::Exception(edm::errors::Configuration,"Pythia8Interface")
217  <<" Wrong value for EV1_pTempMode code\n";
218  EV1_emittedMode = 0;
219  if(params.exists("EV1_emittedMode")) EV1_emittedMode = params.getParameter<int>("EV1_emittedMode");
220  EV1_pTdefMode = 1;
221  if(params.exists("EV1_pTdefMode")) EV1_pTdefMode = params.getParameter<int>("EV1_pTdefMode");
222  EV1_MPIvetoOn = false;
223  if(params.exists("EV1_MPIvetoOn")) EV1_MPIvetoOn = params.getParameter<bool>("EV1_MPIvetoOn");
227  }
228 
229  int NHooks=0;
230  if(fReweightUserHook) NHooks++;
231  if(fJetMatchingHook) NHooks++;
232  if(fEmissionVetoHook) NHooks++;
233  if(fEmissionVetoHook1) NHooks++;
234  if(NHooks > 1)
235  throw edm::Exception(edm::errors::Configuration,"Pythia8Interface")
236  <<" Too many User Hooks. \n Please choose one from: reweightGen, jetMatching, emissionVeto \n";
237 
238  if(fReweightUserHook) fMasterGen->setUserHooksPtr(fReweightUserHook);
239  if(fJetMatchingHook) fMasterGen->setUserHooksPtr(fJetMatchingHook);
241  cout << "Turning on Emission Veto Hook";
242  if(fEmissionVetoHook1) cout << " 1";
243  cout << endl;
244  int nversion = (int)(1000.*(fMasterGen->settings.parm("Pythia:versionNumber") - 8.));
245  if(nversion < 157) {
246  cout << "obsolete pythia8 version for this Emission Veto code" << endl;
247  cout << "Please update pythia8 version using the instructions here:" << endl;
248  cout << "https://twiki.cern.ch/twiki/bin/view/CMS/Pythia8Interface" << endl;
249  cout << "or try to use tag V00-01-28 of this interface" << endl;
250  throw edm::Exception(edm::errors::Configuration,"Pythia8Interface")
251  <<" Obsolete pythia8 version for this Emission Veto code\n";
252  }
253  if(fEmissionVetoHook) fMasterGen->setUserHooksPtr(fEmissionVetoHook);
254  if(fEmissionVetoHook1) fMasterGen->setUserHooksPtr(fEmissionVetoHook1);
255  }
256 }
257 
258 
260 {
261 // do we need to delete UserHooks/JetMatchingHook here ???
262 
265 }
266 
268 {
269 
270  // pythiaEvent = &pythia->event;
271 
272  if ( fInitialState == PP ) // default
273  {
274  fMasterGen->init(2212, 2212, comEnergy);
275  }
276  else if ( fInitialState == PPbar )
277  {
278  fMasterGen->init(2212, -2212, comEnergy);
279  }
280  else if ( fInitialState == ElectronPositron )
281  {
282  fMasterGen->init(11, -11, comEnergy);
283  }
284  else
285  {
286  // throw on unknown initial state !
287  throw edm::Exception(edm::errors::Configuration,"Pythia8Interface")
288  <<" UNKNOWN INITIAL STATE. \n The allowed initial states are: PP, PPbar, ElectronPositron \n";
289  }
290 
291  fMasterGen->settings.listChanged();
292 
293  if ( pythiaPylistVerbosity > 10 )
294  {
295  if ( pythiaPylistVerbosity == 11 || pythiaPylistVerbosity == 13 )
296  fMasterGen->settings.listAll();
297  if ( pythiaPylistVerbosity == 12 || pythiaPylistVerbosity == 13 )
298  fMasterGen->particleData.listAll();
299  }
300 
301  // init decayer
302  fDecayer->readString("ProcessLevel:all = off"); // trick
303  fDecayer->readString("Standalone:allowResDec=on");
304  // pythia->readString("ProcessLevel::resonanceDecays=on");
305  fDecayer->init();
306 
307  return true;
308 }
309 
310 
312 {
313 
314  std::cout << "Initializing for external partons" << std::endl;
315 
316  // pythiaEvent = &pythia->event;
317 
318  if(LHEInputFileName != string()) {
319 
320  cout << endl;
321  cout << "LHE Input File Name = " << LHEInputFileName << endl;
322  cout << endl;
324 
325  } else {
326 
327  lhaUP.reset(new LHAupLesHouches());
328  lhaUP->loadRunInfo(lheRunInfo());
329 
330  if ( fJetMatchingHook )
331  {
333  }
334 
335  fMasterGen->init(lhaUP.get());
336 
337  }
338 
339  if ( pythiaPylistVerbosity > 10 )
340  {
341  if ( pythiaPylistVerbosity == 11 || pythiaPylistVerbosity == 13 )
342  fMasterGen->settings.listAll();
343  if ( pythiaPylistVerbosity == 12 || pythiaPylistVerbosity == 13 )
344  fMasterGen->particleData.listAll();
345  }
346 
347  // init decayer
348  fDecayer->readString("ProcessLevel:all = off"); // trick
349  fDecayer->readString("Standalone:allowResDec=on");
350  // pythia->readString("ProcessLevel::resonanceDecays=on");
351  fDecayer->init();
352 
353  return true;
354 }
355 
356 #if 0
357 // naive Pythia8 HepMC status fixup
358 static int getStatus(const HepMC::GenParticle *p)
359 {
360  int status = p->status();
361  if (status > 0)
362  return status;
363  else if (status > -30 && status < 0)
364  return 3;
365  else
366  return 2;
367 }
368 #endif
369 
370 
372 {
373  fMasterGen->statistics();
374 
375  double xsec = fMasterGen->info.sigmaGen(); // cross section in mb
376  xsec *= 1.0e9; // translate to pb (CMS/Gen "convention" as of May 2009)
377  runInfo().setInternalXSec(xsec);
378 }
379 
380 
382 {
383 
384  if (!fMasterGen->next()) return false;
385 
386  event().reset(new HepMC::GenEvent);
387  return toHepMC.fill_next_event( *(fMasterGen.get()), event().get());
388 
389 }
390 
391 
393 {
394  if(LHEInputFileName == string()) lhaUP->loadEvent(lheEvent());
395 
396  if ( fJetMatchingHook )
397  {
400  }
401 
402  bool py8next = fMasterGen->next();
403 
404  if (!py8next)
405  {
407  event().reset();
408  return false;
409  }
410 
411  // update LHE matching statistics
412  //
414 
415  event().reset(new HepMC::GenEvent);
416  return toHepMC.fill_next_event( *(fMasterGen.get()), event().get());
417 
418 }
419 
420 
422 {
423 
424  Event* pythiaEvent = &(fMasterGen->event);
425 
426  int NPartsBeforeDecays = pythiaEvent->size();
427  int NPartsAfterDecays = event().get()->particles_size();
428  int NewBarcode = NPartsAfterDecays;
429 
430  for ( int ipart=NPartsAfterDecays; ipart>NPartsBeforeDecays; ipart-- )
431  {
432 
433  HepMC::GenParticle* part = event().get()->barcode_to_particle( ipart );
434 
435  if ( part->status() == 1 )
436  {
437  fDecayer->event.reset();
438  Particle py8part( part->pdg_id(), 93, 0, 0, 0, 0, 0, 0,
439  part->momentum().x(),
440  part->momentum().y(),
441  part->momentum().z(),
442  part->momentum().t(),
443  part->generated_mass() );
444  HepMC::GenVertex* ProdVtx = part->production_vertex();
445  py8part.vProd( ProdVtx->position().x(), ProdVtx->position().y(),
446  ProdVtx->position().z(), ProdVtx->position().t() );
447  py8part.tau( (fDecayer->particleData).tau0( part->pdg_id() ) );
448  fDecayer->event.append( py8part );
449  int nentries = fDecayer->event.size();
450  if ( !fDecayer->event[nentries-1].mayDecay() ) continue;
451  fDecayer->next();
452  int nentries1 = fDecayer->event.size();
453  // fDecayer->event.list(std::cout);
454  if ( nentries1 <= nentries ) continue; //same number of particles, no decays...
455 
456  part->set_status(2);
457 
458  Particle& py8daughter = fDecayer->event[nentries]; // the 1st daughter
459  HepMC::GenVertex* DecVtx = new HepMC::GenVertex( HepMC::FourVector(py8daughter.xProd(),
460  py8daughter.yProd(),
461  py8daughter.zProd(),
462  py8daughter.tProd()) );
463 
464  DecVtx->add_particle_in( part ); // this will cleanup end_vertex if exists, replace with the new one
465  // I presume (vtx) barcode will be given automatically
466 
467  HepMC::FourVector pmom( py8daughter.px(), py8daughter.py(), py8daughter.pz(), py8daughter.e() );
468 
469  HepMC::GenParticle* daughter =
470  new HepMC::GenParticle( pmom, py8daughter.id(), 1 );
471 
472  NewBarcode++;
473  daughter->suggest_barcode( NewBarcode );
474  DecVtx->add_particle_out( daughter );
475 
476  for ( int ipart1=nentries+1; ipart1<nentries1; ipart1++ )
477  {
478  py8daughter = fDecayer->event[ipart1];
479  HepMC::FourVector pmomN( py8daughter.px(), py8daughter.py(), py8daughter.pz(), py8daughter.e() );
480  HepMC::GenParticle* daughterN =
481  new HepMC::GenParticle( pmomN, py8daughter.id(), 1 );
482  NewBarcode++;
483  daughterN->suggest_barcode( NewBarcode );
484  DecVtx->add_particle_out( daughterN );
485  }
486 
487  event().get()->add_vertex( DecVtx );
488  // fCurrentEventState->add_vertex( DecVtx );
489 
490  }
491  }
492  return true;
493 
494 }
495 
496 
498 {
499  bool lhe = lheEvent() != 0;
500 
501  // now create the GenEventInfo product from the GenEvent and fill
502  // the missing pieces
503  eventInfo().reset( new GenEventInfoProduct( event().get() ) );
504 
505  // in pythia pthat is used to subdivide samples into different bins
506  // in LHE mode the binning is done by the external ME generator
507  // which is likely not pthat, so only filling it for Py6 internal mode
508  if (!lhe) {
509  eventInfo()->setBinningValues(std::vector<double>(1, fMasterGen->info.pTHat()));
510  }
511 
512  //******** Verbosity ********
513 
514  if (maxEventsToPrint > 0 &&
517  if (pythiaPylistVerbosity) {
518  fMasterGen->info.list(std::cout);
519  fMasterGen->event.list(std::cout);
520  }
521 
522  if (pythiaHepMCVerbosity) {
523  std::cout << "Event process = "
524  << fMasterGen->info.code() << "\n"
525  << "----------------------" << std::endl;
526  event()->print();
527  }
528  }
529 }
530 
531 
534 
535 
T getParameter(std::string const &) const
T getUntrackedParameter(std::string const &, T const &) const
virtual bool residualDecay()
ParameterCollector fParameters
double comEnergy
Center-of-Mass energy.
std::auto_ptr< Pythia8::Pythia > fMasterGen
EmissionVetoHook1 * fEmissionVetoHook1
edm::GeneratorFilter< Pythia8Hadronizer, ExternalDecayDriver > Pythia8GeneratorFilter
UserHooks * fReweightUserHook
EmissionVetoHook * fEmissionVetoHook
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:17
bool exists(std::string const &parameterName) const
checks if a parameter exists
HepMC::I_Pythia8 toHepMC
void count(LHERunInfo::CountMode count, double weight=1.0, double matchWeight=1.0)
Definition: LHEEvent.cc:206
static int getStatus(const HepMC::GenParticle *p)
void setInternalXSec(const XSec &xsec)
virtual void beforeHadronization(lhef::LHEEvent *lhee)
std::auto_ptr< HepMC::GenEvent > & event()
GenRunInfoProduct & runInfo()
std::auto_ptr< LHAupLesHouches > lhaUP
lhef::LHEEvent * lheEvent()
const char * classname() const
unsigned int pythiaPylistVerbosity
std::auto_ptr< GenEventInfoProduct > & eventInfo()
lhef::LHERunInfo * lheRunInfo()
virtual void init(lhef::LHERunInfo *runInfo)
JetMatchingHook * fJetMatchingHook
part
Definition: HCALResponse.h:20
unsigned int maxEventsToPrint
std::auto_ptr< Pythia8::Pythia > fDecayer
Pythia8Hadronizer(const edm::ParameterSet &params)
void resetMatchingStatus()
const_iterator end() const
const_iterator begin() const
tuple cout
Definition: gather_cfg.py:121
tuple status
Definition: ntuplemaker.py:245
edm::HadronizerFilter< Pythia8Hadronizer, ExternalDecayDriver > Pythia8HadronizerFilter