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 #include <vector>
7 
8 #include "HepMC/GenEvent.h"
9 #include "HepMC/GenParticle.h"
10 
11 #include "Pythia8/Pythia.h"
12 #include "Pythia8/Pythia8ToHepMC.h"
13 
15 
17 
18 // PS matchning prototype
19 //
23 
24 // Emission Veto Hooks
25 //
28 
34 
37 
41 
43 
44 #include "HepPID/ParticleIDTranslations.hh"
45 
47 
48 namespace CLHEP {
49  class HepRandomEngine;
50 }
51 
52 using namespace gen;
53 using namespace Pythia8;
54 
56 
57  public:
58 
59  Pythia8Hadronizer(const edm::ParameterSet &params);
61 
62  bool initializeForInternalPartons() override;
63  bool initializeForExternalPartons();
64 
65  bool generatePartonsAndHadronize() override;
66  bool hadronize();
67 
68  virtual bool residualDecay();
69 
70  void finalizeEvent() override;
71 
72  void statistics() override;
73 
74  const char *classname() const override { return "Pythia8Hadronizer"; }
75 
76  private:
77 
78  virtual void doSetRandomEngine(CLHEP::HepRandomEngine* v) override { p8SetRandomEngine(v); }
79  virtual std::vector<std::string> const& doSharedResources() const override { return p8SharedResources; }
80 
82  double comEnergy;
83 
85  std::auto_ptr<LHAupLesHouches> lhaUP;
86 
87  enum { PP, PPbar, ElectronPositron };
88  int fInitialState ; // pp, ppbar, or e-e+
89 
90  double fBeam1PZ;
91  double fBeam2PZ;
92 
93  // Reweight user hooks
94  //
95  UserHooks* fReweightUserHook;
96  UserHooks* fReweightRapUserHook;
98 
99  // PS matching prototype
100  //
104 
105  // Emission Veto Hooks
106  //
109 
118 
119  static const std::vector<std::string> p8SharedResources;
120 
122 
123  vector<float> DJR;
124  int nME;
126 };
127 
129 
131  BaseHadronizer(params), Py8InterfaceBase(params),
132  comEnergy(params.getParameter<double>("comEnergy")),
133  LHEInputFileName(params.getUntrackedParameter<string>("LHEInputFileName","")),
134  fInitialState(PP),
135  fReweightUserHook(0),fReweightRapUserHook(0),fReweightPtHatRapUserHook(0),
136  fJetMatchingHook(0),fJetMatchingPy8InternalHook(0), fSetNumberOfPartonsDynamicallyHook(0),
137  fEmissionVetoHook(0),fEmissionVetoHook1(0), nME(-1), nMEFiltered(-1)
138 {
139 
140  // J.Y.: the following 3 parameters are hacked "for a reason"
141  //
142  if ( params.exists( "PPbarInitialState" ) )
143  {
144  if ( fInitialState == PP )
145  {
147  edm::LogImportant("GeneratorInterface|Pythia8Interface")
148  << "Pythia8 will be initialized for PROTON-ANTIPROTON INITIAL STATE. "
149  << "This is a user-request change from the DEFAULT PROTON-PROTON initial state.";
150  }
151  else
152  {
153  // probably need to throw on attempt to override ?
154  }
155  }
156  else if ( params.exists( "ElectronPositronInitialState" ) )
157  {
158  if ( fInitialState == PP )
159  {
161  edm::LogInfo("GeneratorInterface|Pythia8Interface")
162  << "Pythia8 will be initialized for ELECTRON-POSITRON INITIAL STATE. "
163  << "This is a user-request change from the DEFAULT PROTON-PROTON initial state.";
164  }
165  else
166  {
167  // probably need to throw on attempt to override ?
168  }
169  }
170  else if ( params.exists( "ElectronProtonInitialState" ) || params.exists( "PositronProtonInitialState" ) )
171  {
172  // throw on unknown initial state !
173  throw edm::Exception(edm::errors::Configuration,"Pythia8Interface")
174  <<" UNKNOWN INITIAL STATE. \n The allowed initial states are: PP, PPbar, ElectronPositron \n";
175  }
176 
177  if( params.exists( "SLHAFileForPythia8" ) ) {
178  std::string slhafilenameshort = params.getParameter<string>("SLHAFileForPythia8");
179  edm::FileInPath f1( slhafilenameshort );
180  slhafile_ = f1.fullPath();
181  std::string pythiacommandslha = std::string("SLHA:file = ") + slhafile_;
182  fMasterGen->readString(pythiacommandslha);
184  line != fParameters.end(); ++line ) {
185  if (line->find("SLHA:file") != std::string::npos)
186  throw cms::Exception("PythiaError") << "Attempted to set SLHA file name twice, "
187  << "using Pythia8 card SLHA:file and Pythia8Interface card SLHAFileForPythia8"
188  << std::endl;
189  }
190  }
191 
192  // Reweight user hook
193  //
194  if( params.exists( "reweightGen" ) )
196  if( params.exists( "reweightGenRap" ) )
197  {
198  edm::LogInfo("Pythia8Interface") << "Start setup for reweightGenRap";
199  edm::ParameterSet rgrParams =
200  params.getParameter<edm::ParameterSet>("reweightGenRap");
202  new RapReweightUserHook(rgrParams.getParameter<std::string>("yLabSigmaFunc"),
203  rgrParams.getParameter<double>("yLabPower"),
204  rgrParams.getParameter<std::string>("yCMSigmaFunc"),
205  rgrParams.getParameter<double>("yCMPower"),
206  rgrParams.getParameter<double>("pTHatMin"),
207  rgrParams.getParameter<double>("pTHatMax"));
208  edm::LogInfo("Pythia8Interface") << "End setup for reweightGenRap";
209  }
210  if( params.exists( "reweightGenPtHatRap" ) )
211  {
212  edm::LogInfo("Pythia8Interface") << "Start setup for reweightGenPtHatRap";
213  edm::ParameterSet rgrParams =
214  params.getParameter<edm::ParameterSet>("reweightGenPtHatRap");
216  new PtHatRapReweightUserHook(rgrParams.getParameter<std::string>("yLabSigmaFunc"),
217  rgrParams.getParameter<double>("yLabPower"),
218  rgrParams.getParameter<std::string>("yCMSigmaFunc"),
219  rgrParams.getParameter<double>("yCMPower"),
220  rgrParams.getParameter<double>("pTHatMin"),
221  rgrParams.getParameter<double>("pTHatMax"));
222  edm::LogInfo("Pythia8Interface") << "End setup for reweightGenPtHatRap";
223  }
224 
225  if( params.exists( "useUserHook" ) )
226  throw edm::Exception(edm::errors::Configuration,"Pythia8Interface")
227  <<" Obsolete parameter: useUserHook \n Please use the actual one instead \n";
228 
229  // PS matching prototype
230  //
231  if ( params.exists("jetMatching") )
232  {
233  edm::ParameterSet jmParams =
234  params.getUntrackedParameter<edm::ParameterSet>("jetMatching");
235  std::string scheme = jmParams.getParameter<std::string>("scheme");
236  if ( scheme == "Madgraph" || scheme == "MadgraphFastJet" )
237  {
238  fJetMatchingHook = new JetMatchingHook( jmParams, &fMasterGen->info );
239  }
240  else if (scheme == "MadgraphPy8Internal") {
241  fJetMatchingPy8InternalHook = new ::JetMatchingMadgraph;
242  }
243  else if (scheme == "CKKWPy8Internal") {
245  }
246  }
247 
248  // Emission vetos
249  //
250  if ( params.exists("emissionVeto") )
251  {
253  }
254 
255  if ( params.exists("emissionVeto1") )
256  {
257  EV1_nFinal = -1;
258  if(params.exists("EV1_nFinal")) EV1_nFinal = params.getParameter<int>("EV1_nFinal");
259  EV1_vetoOn = true;
260  if(params.exists("EV1_vetoOn")) EV1_vetoOn = params.getParameter<bool>("EV1_vetoOn");
261  EV1_maxVetoCount = 10;
262  if(params.exists("EV1_maxVetoCount")) EV1_maxVetoCount = params.getParameter<int>("EV1_maxVetoCount");
263  EV1_pThardMode = 1;
264  if(params.exists("EV1_pThardMode")) EV1_pThardMode = params.getParameter<int>("EV1_pThardMode");
265  EV1_pTempMode = 0;
266  if(params.exists("EV1_pTempMode")) EV1_pTempMode = params.getParameter<int>("EV1_pTempMode");
267  if(EV1_pTempMode > 2 || EV1_pTempMode < 0)
268  throw edm::Exception(edm::errors::Configuration,"Pythia8Interface")
269  <<" Wrong value for EV1_pTempMode code\n";
270  EV1_emittedMode = 0;
271  if(params.exists("EV1_emittedMode")) EV1_emittedMode = params.getParameter<int>("EV1_emittedMode");
272  EV1_pTdefMode = 1;
273  if(params.exists("EV1_pTdefMode")) EV1_pTdefMode = params.getParameter<int>("EV1_pTdefMode");
274  EV1_MPIvetoOn = false;
275  if(params.exists("EV1_MPIvetoOn")) EV1_MPIvetoOn = params.getParameter<bool>("EV1_MPIvetoOn");
279  }
280 
281  int NHooks=0;
282  if(fReweightUserHook) NHooks++;
283  if(fReweightRapUserHook) NHooks++;
284  if(fReweightPtHatRapUserHook) NHooks++;
285  if(fJetMatchingHook) NHooks++;
286  if(fJetMatchingPy8InternalHook) NHooks++;
288  if(fEmissionVetoHook) NHooks++;
289  if(fEmissionVetoHook1) NHooks++;
290  if(NHooks > 1)
291  throw edm::Exception(edm::errors::Configuration,"Pythia8Interface")
292  <<" Too many User Hooks. \n Please choose one from: reweightGen, reweightGenRap, reweightGenPtHatRap, jetMatching, emissionVeto, emissionVeto1 \n";
293  if(fReweightUserHook) fMasterGen->setUserHooksPtr(fReweightUserHook);
296  if(fJetMatchingHook) fMasterGen->setUserHooksPtr(fJetMatchingHook);
300  std::cout << "Turning on Emission Veto Hook";
301  if(fEmissionVetoHook1) std::cout << " 1";
302  std::cout << std::endl;
303  if(fEmissionVetoHook) fMasterGen->setUserHooksPtr(fEmissionVetoHook);
304  if(fEmissionVetoHook1) fMasterGen->setUserHooksPtr(fEmissionVetoHook1);
305  }
306 }
307 
308 
310 {
311 // do we need to delete UserHooks/JetMatchingHook here ???
312 
315 }
316 
318 {
319 
320  // pythiaEvent = &pythia->event;
321 
322  if ( fInitialState == PP ) // default
323  {
324  fMasterGen->init(2212, 2212, comEnergy);
325  }
326  else if ( fInitialState == PPbar )
327  {
328  fMasterGen->init(2212, -2212, comEnergy);
329  }
330  else if ( fInitialState == ElectronPositron )
331  {
332  fMasterGen->init(11, -11, comEnergy);
333  }
334  else
335  {
336  // throw on unknown initial state !
337  throw edm::Exception(edm::errors::Configuration,"Pythia8Interface")
338  <<" UNKNOWN INITIAL STATE. \n The allowed initial states are: PP, PPbar, ElectronPositron \n";
339  }
340 
341  fMasterGen->settings.listChanged();
342 
343  if ( pythiaPylistVerbosity > 10 )
344  {
345  if ( pythiaPylistVerbosity == 11 || pythiaPylistVerbosity == 13 )
346  fMasterGen->settings.listAll();
347  if ( pythiaPylistVerbosity == 12 || pythiaPylistVerbosity == 13 )
348  fMasterGen->particleData.listAll();
349  }
350 
351  // init decayer
352  fDecayer->readString("ProcessLevel:all = off"); // trick
353  fDecayer->readString("ProcessLevel::resonanceDecays=on");
354  fDecayer->init();
355 
356  return true;
357 }
358 
359 
361 {
362 
363  std::cout << "Initializing for external partons" << std::endl;
364 
365  if(LHEInputFileName != string()) {
366 
367  std::cout << std::endl;
368  std::cout << "LHE Input File Name = " << LHEInputFileName << std::endl;
369  std::cout << std::endl;
371 
372  } else {
373 
374  lhaUP.reset(new LHAupLesHouches());
375  lhaUP->loadRunInfo(lheRunInfo());
376 
377  if ( fJetMatchingHook )
378  {
380  }
381 
382  //pythia 8 doesn't currently support reading SLHA table from lhe header in memory
383  //so dump it to a temp file and set the appropriate pythia parameters to read it
384  std::vector<std::string> slha = lheRunInfo()->findHeader("slha");
385  const char *fname = std::tmpnam(NULL);
386  //read slha header from lhe only if header is present AND no slha header was specified
387  //for manual loading.
388  bool doslha = !slha.empty() && slhafile_.empty();
389 
390  if (doslha) {
391  std::ofstream file(fname, std::fstream::out | std::fstream::trunc);
393  for(std::vector<std::string>::const_iterator iter = slha.begin();
394  iter != slha.end(); ++iter) {
395  file << *iter;
396  }
397  file.close();
398 
399  std::string lhareadcmd = "SLHA:readFrom = 2";
400  std::string lhafilecmd = std::string("SLHA:file = ") + std::string(fname);
401 
402  fMasterGen->readString(lhareadcmd);
403  fMasterGen->readString(lhafilecmd);
404  }
405 
406  fMasterGen->init(lhaUP.get());
407 
408  if (doslha) {
409  std::remove( fname );
410  }
411 
412  }
413 
414  if ( pythiaPylistVerbosity > 10 )
415  {
416  if ( pythiaPylistVerbosity == 11 || pythiaPylistVerbosity == 13 )
417  fMasterGen->settings.listAll();
418  if ( pythiaPylistVerbosity == 12 || pythiaPylistVerbosity == 13 )
419  fMasterGen->particleData.listAll();
420  }
421 
422  // init decayer
423  fDecayer->readString("ProcessLevel:all = off"); // trick
424  fDecayer->readString("ProcessLevel::resonanceDecays=on");
425  fDecayer->init();
426 
427  return true;
428 }
429 
430 
432 {
433  fMasterGen->statistics();
434 
435  double xsec = fMasterGen->info.sigmaGen(); // cross section in mb
436  xsec *= 1.0e9; // translate to pb (CMS/Gen "convention" as of May 2009)
437  runInfo().setInternalXSec(xsec);
438 }
439 
440 
442 {
443 
444  if (!fMasterGen->next()) return false;
445 
446  event().reset(new HepMC::GenEvent);
447  return toHepMC.fill_next_event( *(fMasterGen.get()), event().get());
448 
449 }
450 
451 
453 {
454  DJR.resize(0);
455  nME = -1;
456  nMEFiltered = -1;
457  if(LHEInputFileName == string()) lhaUP->loadEvent(lheEvent());
458 
459  if ( fJetMatchingHook )
460  {
463  }
464 
465  bool py8next = fMasterGen->next();
466 
467  double mergeweight = fMasterGen.get()->info.mergingWeight();
468 
469  //protect against 0-weight from ckkw or similar
470  if (!py8next || mergeweight<=0.)
471  {
473  event().reset();
474  return false;
475  }
476 
478  const std::vector<double> djrmatch = fJetMatchingPy8InternalHook->GetDJR();
479  //cap size of djr vector to save storage space (keep only up to first 6 elements)
480  unsigned int ndjr = std::min(djrmatch.size(), std::vector<double>::size_type(6));
481  for (unsigned int idjr=0; idjr<ndjr; ++idjr) {
482  DJR.push_back(djrmatch[idjr]);
483  }
484 
485  nME=fJetMatchingPy8InternalHook->nMEPartons()[0];
486  nMEFiltered=fJetMatchingPy8InternalHook->nMEPartons()[1];
487  }
488 
489  // update LHE matching statistics
490  //
492 
493  event().reset(new HepMC::GenEvent);
494  bool py8hepmc = toHepMC.fill_next_event( *(fMasterGen.get()), event().get());
495  if (!py8hepmc) {
496  return false;
497  }
498 
499  //add ckkw merging weight
500  if (mergeweight!=1.) {
501  event()->weights().push_back(mergeweight);
502  }
503 
504  return true;
505 
506 
507 }
508 
509 
511 {
512 
513  Event* pythiaEvent = &(fMasterGen->event);
514 
515  int NPartsBeforeDecays = pythiaEvent->size();
516  int NPartsAfterDecays = event().get()->particles_size();
517  int NewBarcode = NPartsAfterDecays;
518 
519  for ( int ipart=NPartsAfterDecays; ipart>NPartsBeforeDecays; ipart-- )
520  {
521 
522  HepMC::GenParticle* part = event().get()->barcode_to_particle( ipart );
523 
524  if ( part->status() == 1 )
525  {
526  fDecayer->event.reset();
527  Particle py8part( part->pdg_id(), 93, 0, 0, 0, 0, 0, 0,
528  part->momentum().x(),
529  part->momentum().y(),
530  part->momentum().z(),
531  part->momentum().t(),
532  part->generated_mass() );
533  HepMC::GenVertex* ProdVtx = part->production_vertex();
534  py8part.vProd( ProdVtx->position().x(), ProdVtx->position().y(),
535  ProdVtx->position().z(), ProdVtx->position().t() );
536  py8part.tau( (fDecayer->particleData).tau0( part->pdg_id() ) );
537  fDecayer->event.append( py8part );
538  int nentries = fDecayer->event.size();
539  if ( !fDecayer->event[nentries-1].mayDecay() ) continue;
540  fDecayer->next();
541  int nentries1 = fDecayer->event.size();
542  if ( nentries1 <= nentries ) continue; //same number of particles, no decays...
543 
544  part->set_status(2);
545 
546  Particle& py8daughter = fDecayer->event[nentries]; // the 1st daughter
547  HepMC::GenVertex* DecVtx = new HepMC::GenVertex( HepMC::FourVector(py8daughter.xProd(),
548  py8daughter.yProd(),
549  py8daughter.zProd(),
550  py8daughter.tProd()) );
551 
552  DecVtx->add_particle_in( part ); // this will cleanup end_vertex if exists, replace with the new one
553  // I presume (vtx) barcode will be given automatically
554 
555  HepMC::FourVector pmom( py8daughter.px(), py8daughter.py(), py8daughter.pz(), py8daughter.e() );
556 
557  HepMC::GenParticle* daughter =
558  new HepMC::GenParticle( pmom, py8daughter.id(), 1 );
559 
560  NewBarcode++;
561  daughter->suggest_barcode( NewBarcode );
562  DecVtx->add_particle_out( daughter );
563 
564  for ( int ipart1=nentries+1; ipart1<nentries1; ipart1++ )
565  {
566  py8daughter = fDecayer->event[ipart1];
567  HepMC::FourVector pmomN( py8daughter.px(), py8daughter.py(), py8daughter.pz(), py8daughter.e() );
568  HepMC::GenParticle* daughterN =
569  new HepMC::GenParticle( pmomN, py8daughter.id(), 1 );
570  NewBarcode++;
571  daughterN->suggest_barcode( NewBarcode );
572  DecVtx->add_particle_out( daughterN );
573  }
574 
575  event().get()->add_vertex( DecVtx );
576 
577  }
578  }
579  return true;
580 
581 }
582 
583 
585 {
586  bool lhe = lheEvent() != 0;
587 
588  // now create the GenEventInfo product from the GenEvent and fill
589  // the missing pieces
590  eventInfo().reset( new GenEventInfoProduct( event().get() ) );
591 
592  // in pythia pthat is used to subdivide samples into different bins
593  // in LHE mode the binning is done by the external ME generator
594  // which is likely not pthat, so only filling it for Py6 internal mode
595  if (!lhe) {
596  eventInfo()->setBinningValues(std::vector<double>(1, fMasterGen->info.pTHat()));
597  }
598 
599  eventInfo()->setDJR(DJR);
600  eventInfo()->setNMEPartons(nME);
601  eventInfo()->setNMEPartonsFiltered(nMEFiltered);
602 
603  //******** Verbosity ********
604 
605  if (maxEventsToPrint > 0 &&
608  if (pythiaPylistVerbosity) {
609  fMasterGen->info.list(std::cout);
610  fMasterGen->event.list(std::cout);
611  }
612 
613  if (pythiaHepMCVerbosity) {
614  std::cout << "Event process = "
615  << fMasterGen->info.code() << "\n"
616  << "----------------------" << std::endl;
617  event()->print();
618  }
619  }
620 }
621 
624 
625 
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
bool initializeForInternalPartons() override
UserHooks * fReweightUserHook
EmissionVetoHook * fEmissionVetoHook
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:17
void statistics() override
bool exists(std::string const &parameterName) const
checks if a parameter exists
#define NULL
Definition: scimark2.h:8
void count(LHERunInfo::CountMode count, double weight=1.0, double matchWeight=1.0)
Definition: LHEEvent.cc:207
void setInternalXSec(const XSec &xsec)
uint16_t size_type
virtual void beforeHadronization(lhef::LHEEvent *lhee)
double v[5][pyjets_maxn]
std::auto_ptr< HepMC::GenEvent > & event()
virtual std::vector< std::string > const & doSharedResources() const override
GenRunInfoProduct & runInfo()
std::auto_ptr< LHAupLesHouches > lhaUP
lhef::LHEEvent * lheEvent()
UserHooks * fReweightPtHatRapUserHook
JetMatchingMadgraph * fJetMatchingPy8InternalHook
static const std::vector< std::string > p8SharedResources
unsigned int pythiaPylistVerbosity
const char * classname() const override
UserHooks * fReweightRapUserHook
std::auto_ptr< GenEventInfoProduct > & eventInfo()
lhef::LHERunInfo * lheRunInfo()
bool generatePartonsAndHadronize() override
tuple out
Definition: dbtoconf.py:99
virtual void init(lhef::LHERunInfo *runInfo)
JetMatchingHook * fJetMatchingHook
part
Definition: HCALResponse.h:20
unsigned int maxEventsToPrint
std::auto_ptr< Pythia8::Pythia > fDecayer
string fname
main script
Pythia8Hadronizer(const edm::ParameterSet &params)
vector< float > DJR
void resetMatchingStatus()
const_iterator end() const
const_iterator begin() const
HepMC::Pythia8ToHepMC toHepMC
tuple cout
Definition: gather_cfg.py:121
std::vector< std::string > findHeader(const std::string &tag) const
Definition: LHERunInfo.cc:390
static const std::string kPythia8
void finalizeEvent() override
virtual void doSetRandomEngine(CLHEP::HepRandomEngine *v) override
edm::HadronizerFilter< Pythia8Hadronizer, ExternalDecayDriver > Pythia8HadronizerFilter
SetNumberOfPartonsDynamically * fSetNumberOfPartonsDynamicallyHook