CMS 3D CMS Logo

Herwig6Hadronizer.cc
Go to the documentation of this file.
1 #include <cstring>
2 #include <sstream>
3 #include <string>
4 #include <vector>
5 #include <memory>
6 #include <map>
7 #include <set>
8 #include <boost/shared_ptr.hpp>
9 #include <boost/algorithm/string/classification.hpp>
10 #include <boost/algorithm/string/split.hpp>
11 #include <HepMC/GenEvent.h>
12 #include <HepMC/GenParticle.h>
13 #include <HepMC/GenVertex.h>
14 #include <HepMC/PdfInfo.h>
15 #include <HepMC/HerwigWrapper.h>
16 #include <HepMC/HEPEVT_Wrapper.h>
17 #include <HepMC/IO_HERWIG.h>
18 #include "HepPID/ParticleIDTranslations.hh"
19 
22 
25 
28 
34 
36 
39 
41 
42 namespace CLHEP {
43  class HepRandomEngine;
44 }
45 
46 extern "C" {
47  void hwuidt_(int *iopt, int *ipdg, int *iwig, char nwig[8]);
48  double hwualf_(int *mode, double* scale);
49  double hwuaem_(double* scale);
50 }
51 
52 // helpers
53 namespace {
54  inline bool call_hwmatch()
55  {
56  int result;
57  hwmatch(&result);
58  return result;
59  }
60  inline bool call_hwmsct()
61  {
62  int result;
63  hwmsct(&result);
64  return result;
65  }
66 
67  int pdgToHerwig(int ipdg, char *nwig)
68  {
69  int iopt = 1;
70  int iwig = 0;
71  hwuidt_(&iopt, &ipdg, &iwig, nwig);
72  return ipdg ? iwig : 0;
73  }
74 
75  bool markStable(int pdgId)
76  {
77  char nwig[9] = " ";
78  if (!pdgToHerwig(pdgId, nwig))
79  return false;
80  hwusta(nwig, 1);
81  return true;
82  }
83 }
84 
86  public gen::Herwig6Instance {
87  public:
88  Herwig6Hadronizer(const edm::ParameterSet &params);
89  ~Herwig6Hadronizer() override;
90 
91  void setSLHAFromHeader(const std::vector<std::string> &lines);
92  bool initialize(const lhef::HEPRUP *heprup);
93 
94  bool readSettings( int );
95 
96  // bool initializeForInternalPartons() { return initialize(0); }
97  // bool initializeForExternalPartons() { return initialize(lheRunInfo()->getHEPRUP()); }
98 
99  bool initializeForInternalPartons();
100  bool initializeForExternalPartons() { return initializeForInternalPartons(); }
101 
102  bool declareStableParticles( const std::vector<int> &pdgIds);
103  bool declareSpecialSettings( const std::vector<std::string>& );
104 
105  void statistics();
106 
107 
108  bool generatePartonsAndHadronize() { return hadronize(); }
109  bool hadronize();
110  bool decay();
111  bool residualDecay();
112  void finalizeEvent();
113 
114  const char *classname() const { return "Herwig6Hadronizer"; }
115 
116  private:
117 
118  void doSetRandomEngine(CLHEP::HepRandomEngine* v) override;
119  std::vector<std::string> const& doSharedResources() const override { return theSharedResources; }
120 
121  void clear();
122 
123  int pythiaStatusCode(const HepMC::GenParticle *p) const;
124  void pythiaStatusCodes();
125 
126  void upInit() override;
127  void upEvnt() override;
128 
129  static const std::vector<std::string> theSharedResources;
130 
131  HepMC::IO_HERWIG conv;
132  bool needClear;
134 
141  double comEnergy;
142  bool useJimmy;
145  bool fConvertToPDG; // convert PIDs
148  int nMatch;
150 
152 
153  // -------------------------------------------------------------------------------
154  std::string particleSpecFileName; //Lars 20/Jul/2011
156  // -------------------------------------------------------------------------------
157 
158 };
159 
160 extern "C" {
161  void hwwarn_(const char *method, int *id);
162  void setherwpdf_(void);
163  void mysetpdfpath_(const char *path);
164 } // extern "C"
165 
168 
170  BaseHadronizer(params),
171  needClear(false),
172  parameters(params.getParameter<edm::ParameterSet>("HerwigParameters")),
173  herwigVerbosity(params.getUntrackedParameter<int>("herwigVerbosity", 0)),
174  hepmcVerbosity(params.getUntrackedParameter<int>("hepmcVerbosity", 0)),
175  maxEventsToPrint(params.getUntrackedParameter<int>("maxEventsToPrint", 0)),
176  printCards(params.getUntrackedParameter<bool>("printCards", false)),
177  emulatePythiaStatusCodes(params.getUntrackedParameter<bool>("emulatePythiaStatusCodes", false)),
178  comEnergy(params.getParameter<double>("comEnergy")),
179  useJimmy(params.getParameter<bool>("useJimmy")),
180  doMPInteraction(params.getParameter<bool>("doMPInteraction")),
181  numTrials(params.getUntrackedParameter<int>("numTrialsMPI", 100)),
182  doMatching(params.getUntrackedParameter<bool>("doMatching", false)),
183  inclusiveMatching(params.getUntrackedParameter<bool>("inclusiveMatching", true)),
184  nMatch(params.getUntrackedParameter<int>("nMatch", 0)),
185  matchingScale(params.getUntrackedParameter<double>("matchingScale", 0.0)),
186  readMCatNLOfile(false),
187 
188  // added to be able to read external particle spectrum file
189  particleSpecFileName(params.getUntrackedParameter<std::string>("ParticleSpectrumFileName","")),
190  readParticleSpecFile(params.getUntrackedParameter<bool>("readParticleSpecFile", false))
191 
192 {
193 
194  fConvertToPDG = false;
195  if ( params.exists( "doPDGConvert" ) )
196  fConvertToPDG = params.getParameter<bool>("doPDGConvert");
197 }
198 
200 {
201  clear();
202 }
203 
204 void Herwig6Hadronizer::doSetRandomEngine(CLHEP::HepRandomEngine* v)
205 {
207 }
208 
210 {
211  if (!needClear)
212  return;
213 
214  // teminate elementary process
215  call(hwefin);
216  if (useJimmy)
217  call(jmefin);
218 
219  needClear = false;
220 }
221 
223  const std::vector<std::string> &lines)
224 {
225  std::set<std::string> blocks;
227  for(std::vector<std::string>::const_iterator iter = lines.begin();
228  iter != lines.end(); ++iter) {
229  std::string line = *iter;
230  std::transform(line.begin(), line.end(),
231  line.begin(), (int(*)(int))std::toupper);
232  std::string::size_type pos = line.find('#');
233  if (pos != std::string::npos)
234  line.resize(pos);
235 
236  if (line.empty())
237  continue;
238 
239  if (!boost::algorithm::is_space()(line[0])) {
240  std::vector<std::string> tokens;
241  boost::split(tokens, line,
242  boost::algorithm::is_space(),
243  boost::token_compress_on);
244  if (tokens.empty())
245  continue;
246  block.clear();
247  if (tokens.size() < 2)
248  continue;
249  if (tokens[0] == "BLOCK")
250  block = tokens[1];
251  else if (tokens[0] == "DECAY")
252  block = "DECAY";
253 
254  if (block.empty())
255  continue;
256 
257  if (!blocks.count(block)) {
258  blocks.insert(block);
259  edm::LogWarning("Generator|Herwig6Hadronzier")
260  << "Unsupported SLHA block \"" << block
261  << "\". It will be ignored."
262  << std::endl;
263  }
264  }
265  }
266 }
267 
269 {
270 
271  clear();
272  const lhef::HEPRUP* heprup = lheRunInfo()->getHEPRUP();
273  externalPartons = ( heprup != nullptr );
274 
275  if ( key == 0 && externalPartons ) return false;
276  if ( key > 0 && !externalPartons ) return false;
277 
278  std::ostringstream info;
279  info << "---------------------------------------------------\n";
280  info << "Taking in settinsg for Herwig6Hadronizer for "
281  << (externalPartons ? "external" : "internal") << " partons\n";
282  info << "---------------------------------------------------\n";
283 
284  info << " Herwig verbosity level = " << herwigVerbosity << "\n";
285  info << " HepMC verbosity = " << hepmcVerbosity << "\n";
286  info << " Number of events to be printed = " << maxEventsToPrint << "\n";
287 
288  // Call hwudat to set up HERWIG block data
289  hwudat();
290 
291  // Setting basic parameters
292  if (externalPartons) {
293  hwproc.PBEAM1 = heprup->EBMUP.first;
294  hwproc.PBEAM2 = heprup->EBMUP.second;
295  pdgToHerwig(heprup->IDBMUP.first, hwbmch.PART1);
296  pdgToHerwig(heprup->IDBMUP.second, hwbmch.PART2);
297  }
298  else
299  {
300  hwproc.PBEAM1 = 0.5 * comEnergy;
301  hwproc.PBEAM2 = 0.5 * comEnergy;
302  pdgToHerwig(2212, hwbmch.PART1);
303  pdgToHerwig(2212, hwbmch.PART2);
304  }
305 
306  if (doMatching) {
307  hwmatchpram.n_match = nMatch;
308  hwmatchpram.matching_scale = matchingScale;
309 
310  if (inclusiveMatching)
311  hwmatchpram.max_multiplicity_flag = 1;
312  else
313  hwmatchpram.max_multiplicity_flag = 0;
314 
315  }
316 
317  if (useJimmy)
318  {
319  info << " HERWIG will be using JIMMY for UE/MI.\n";
320  jmparm.MSFLAG = 1;
321  if (doMPInteraction)
322  info << " JIMMY trying to generate multiple interactions.\n";
323  }
324 
325 
326  // set the IPROC already here... needed for VB pairs
327 
328  bool iprocFound=false;
329 
331  line != parameters.end(); ++line)
332  {
333  if(!strcmp((line->substr(0,5)).c_str(),"IPROC")) {
334  if (!give(*line))
336  << "Herwig 6 did not accept the following: \""
337  << *line << "\"." << std::endl;
338  else iprocFound=true;
339  }
340  }
341 
342  if (!iprocFound && !externalPartons)
344  << "You have to define the process with IPROC." << std::endl;
345 
346  // initialize other common blocks ...
347  call(hwigin); // default init
348 
349  hwevnt.MAXER = 100000000; // O(inf)
350  hwpram.LWSUD = 0; // don't write Sudakov form factors
351  hwdspn.LWDEC = 0; // don't write three/four body decays
352  // (no fort.77 and fort.88 ...)
353  // init LHAPDF glue
354  std::memset(hwprch.AUTPDF, ' ', sizeof hwprch.AUTPDF);
355  for(unsigned int i = 0; i < 2; i++) {
356  hwpram.MODPDF[i] = -111;
357  std::memcpy(hwprch.AUTPDF[i], "HWLHAPDF", 8);
358  }
359 
360  hwevnt.MAXPR = maxEventsToPrint;
361  hwpram.IPRINT = herwigVerbosity;
362 // hwprop.RMASS[6] = 175.0; //FIXME
363 
364  if (printCards) {
365  info << "\n";
366  info << "------------------------------------\n";
367  info << "Reading HERWIG parameters\n";
368  info << "------------------------------------\n";
369 
370  }
372  line != parameters.end(); ++line) {
373  if (printCards)
374  info << " " << *line << "\n";
375  if (!give(*line))
377  << "Herwig 6 did not accept the following: \""
378  << *line << "\"." << std::endl;
379  }
380 
381  if (printCards)
382  info << "\n";
383 
384  if (externalPartons) {
385  std::vector<std::string> slha =
386  lheRunInfo()->findHeader("slha");
387  if (!slha.empty())
388  setSLHAFromHeader(slha);
389  }
390 
391  needClear = true;
392 
393  std::pair<int, int> pdfs(-1, -1);
394  if (externalPartons)
395  pdfs = lheRunInfo()->pdfSetTranslation();
396 
397  if (hwpram.MODPDF[0] != -111 || hwpram.MODPDF[1] != -111) {
398  for(unsigned int i = 0; i < 2; i++)
399  if (hwpram.MODPDF[i] == -111)
400  hwpram.MODPDF[i] = -1;
401 
402  if (pdfs.first != -1 || pdfs.second != -1)
403  edm::LogError("Generator|Herwig6Hadronzier")
404  << "Both external Les Houches event and "
405  "config file specify a PDF set. "
406  "User PDF will override external one."
407  << std::endl;
408 
409  pdfs.first = hwpram.MODPDF[0] != -111 ? hwpram.MODPDF[0] : -1;
410  pdfs.second = hwpram.MODPDF[1] != -111 ? hwpram.MODPDF[1] : -1;
411  }
412 
413  printf("pdfs.first = %i, pdfs.second = %i\n",pdfs.first,pdfs.second);
414 
415  hwpram.MODPDF[0] = pdfs.first;
416  hwpram.MODPDF[1] = pdfs.second;
417 
418  if (externalPartons && hwproc.IPROC>=0)
419  hwproc.IPROC = -1;
420 
421 
422  //Lars: lower EFFMIN threshold, to continue execution of IPROC=4000, lambda'_211=0.01 at LM7,10
423  if( readParticleSpecFile ) {
425  hwpram.EFFMIN = 1e-5;
426  }
427 
428 
429  edm::LogInfo(info.str());
430 
431  return true;
432 
433 }
434 
436 {
437 
438  if (useJimmy) call(jimmin);
439 
440  call(hwuinc);
441 
442  // initialize HERWIG event generation
443  call(hweini);
444 
445  if (useJimmy) {
446  call(jminit);
447  }
448 
449  return true;
450 
451 }
452 
453 
455 {
456  clear();
457 
458  externalPartons = (heprup != nullptr);
459 
460  std::ostringstream info;
461  info << "---------------------------------------------------\n";
462  info << "Initializing Herwig6Hadronizer for "
463  << (externalPartons ? "external" : "internal") << " partons\n";
464  info << "---------------------------------------------------\n";
465 
466  info << " Herwig verbosity level = " << herwigVerbosity << "\n";
467  info << " HepMC verbosity = " << hepmcVerbosity << "\n";
468  info << " Number of events to be printed = " << maxEventsToPrint << "\n";
469 
470  // Call hwudat to set up HERWIG block data
471  hwudat();
472 
473  // Setting basic parameters
474  if (externalPartons) {
475  hwproc.PBEAM1 = heprup->EBMUP.first;
476  hwproc.PBEAM2 = heprup->EBMUP.second;
477  pdgToHerwig(heprup->IDBMUP.first, hwbmch.PART1);
478  pdgToHerwig(heprup->IDBMUP.second, hwbmch.PART2);
479  } else {
480  hwproc.PBEAM1 = 0.5 * comEnergy;
481  hwproc.PBEAM2 = 0.5 * comEnergy;
482  pdgToHerwig(2212, hwbmch.PART1);
483  pdgToHerwig(2212, hwbmch.PART2);
484  }
485 
486  if (useJimmy) {
487  info << " HERWIG will be using JIMMY for UE/MI.\n";
488  jmparm.MSFLAG = 1;
489  if (doMPInteraction)
490  info << " JIMMY trying to generate multiple interactions.\n";
491  }
492 
493  // set the IPROC already here... needed for VB pairs
494 
495  bool iprocFound=false;
496 
498  line != parameters.end(); ++line) {
499  if(!strcmp((line->substr(0,5)).c_str(),"IPROC")) {
500  if (!give(*line))
502  << "Herwig 6 did not accept the following: \""
503  << *line << "\"." << std::endl;
504  else iprocFound=true;
505  }
506  }
507 
508  if (!iprocFound && !externalPartons)
510  << "You have to define the process with IPROC." << std::endl;
511 
512  // initialize other common blocks ...
513  call(hwigin);
514  hwevnt.MAXER = 100000000; // O(inf)
515  hwpram.LWSUD = 0; // don't write Sudakov form factors
516  hwdspn.LWDEC = 0; // don't write three/four body decays
517  // (no fort.77 and fort.88 ...)
518 
519  // init LHAPDF glue
520 
521  std::memset(hwprch.AUTPDF, ' ', sizeof hwprch.AUTPDF);
522  for(unsigned int i = 0; i < 2; i++) {
523  hwpram.MODPDF[i] = -111;
524  std::memcpy(hwprch.AUTPDF[i], "HWLHAPDF", 8);
525  }
526 
527  if (useJimmy)
528  call(jimmin);
529 
530  hwevnt.MAXPR = maxEventsToPrint;
531  hwpram.IPRINT = herwigVerbosity;
532 // hwprop.RMASS[6] = 175.0; //FIXME
533 
534  if (printCards) {
535  info << "\n";
536  info << "------------------------------------\n";
537  info << "Reading HERWIG parameters\n";
538  info << "------------------------------------\n";
539 
540  }
542  line != parameters.end(); ++line) {
543  if (printCards)
544  info << " " << *line << "\n";
545  if (!give(*line))
547  << "Herwig 6 did not accept the following: \""
548  << *line << "\"." << std::endl;
549  }
550 
551  if (printCards)
552  info << "\n";
553 
554  if (externalPartons) {
555  std::vector<std::string> slha =
556  lheRunInfo()->findHeader("slha");
557  if (!slha.empty())
558  setSLHAFromHeader(slha);
559  }
560 
561  needClear = true;
562 
563  std::pair<int, int> pdfs(-1, -1);
564  if (externalPartons)
565  pdfs = lheRunInfo()->pdfSetTranslation();
566 
567  if (hwpram.MODPDF[0] != -111 || hwpram.MODPDF[1] != -111) {
568  for(unsigned int i = 0; i < 2; i++)
569  if (hwpram.MODPDF[i] == -111)
570  hwpram.MODPDF[i] = -1;
571 
572  if (pdfs.first != -1 || pdfs.second != -1)
573  edm::LogError("Generator|Herwig6Hadronzier")
574  << "Both external Les Houches event and "
575  "config file specify a PDF set. "
576  "User PDF will override external one."
577  << std::endl;
578 
579  pdfs.first = hwpram.MODPDF[0] != -111 ? hwpram.MODPDF[0] : -1;
580  pdfs.second = hwpram.MODPDF[1] != -111 ? hwpram.MODPDF[1] : -1;
581  }
582 
583  printf("pdfs.first = %i, pdfs.second = %i\n",pdfs.first,pdfs.second);
584 
585  hwpram.MODPDF[0] = pdfs.first;
586  hwpram.MODPDF[1] = pdfs.second;
587 
588  if (externalPartons)
589  hwproc.IPROC = -1;
590 
591  //Lars: lower EFFMIN threshold, to continue execution of IPROC=4000, lambda'_211=0.01 at LM7,10
592  if( readParticleSpecFile ) {
594  hwpram.EFFMIN = 1e-5;
595  }
596 
597  // HERWIG preparations ...
598  call(hwuinc);
599  markStable(13); // MU+
600  markStable(-13); // MU-
601  markStable(3112); // SIGMA+
602  markStable(-3112); // SIGMABAR+
603  markStable(3222); // SIGMA-
604  markStable(-3222); // SIGMABAR-
605  markStable(3122); // LAMBDA0
606  markStable(-3122); // LAMBDABAR0
607  markStable(3312); // XI-
608  markStable(-3312); // XIBAR+
609  markStable(3322); // XI0
610  markStable(-3322); // XI0BAR
611  markStable(3334); // OMEGA-
612  markStable(-3334); // OMEGABAR+
613  markStable(211); // PI+
614  markStable(-211); // PI-
615  markStable(321); // K+
616  markStable(-321); // K-
617  markStable(310); // K_S0
618  markStable(130); // K_L0
619 
620  // better: merge with declareStableParticles
621  // and get the list from configuration / Geant4 / Core somewhere
622 
623  // initialize HERWIG event generation
624  call(hweini);
625 
626  if (useJimmy)
627  call(jminit);
628 
629  edm::LogInfo(info.str());
630 
631  return true;
632 }
633 
634 bool Herwig6Hadronizer::declareStableParticles(const std::vector<int> &pdgIds)
635 {
636  markStable(13); // MU+
637  markStable(-13); // MU-
638  markStable(3112); // SIGMA+
639  markStable(-3112); // SIGMABAR+
640  markStable(3222); // SIGMA-
641  markStable(-3222); // SIGMABAR-
642  markStable(3122); // LAMBDA0
643  markStable(-3122); // LAMBDABAR0
644  markStable(3312); // XI-
645  markStable(-3312); // XIBAR+
646  markStable(3322); // XI0
647  markStable(-3322); // XI0BAR
648  markStable(3334); // OMEGA-
649  markStable(-3334); // OMEGABAR+
650  markStable(211); // PI+
651  markStable(-211); // PI-
652  markStable(321); // K+
653  markStable(-321); // K-
654  markStable(310); // K_S0
655  markStable(130); // K_L0
656 
657  for(std::vector<int>::const_iterator iter = pdgIds.begin();
658  iter != pdgIds.end(); ++iter)
659  if (!markStable(*iter))
660  return false;
661  return true;
662 }
663 
664 bool Herwig6Hadronizer::declareSpecialSettings( const std::vector<std::string>& )
665 {
666  return true;
667 }
668 
670 {
671  if (!runInfo().internalXSec()) {
672  // not set via LHE, so get it from HERWIG
673  // the reason is that HERWIG doesn't compute the xsec
674  // in all LHE modes
675 
676  double RNWGT = 1. / hwevnt.NWGTS;
677  double AVWGT = hwevnt.WGTSUM * RNWGT;
678 
679  double xsec = 1.0e3 * AVWGT;
680 
681  runInfo().setInternalXSec(xsec);
682  }
683 }
684 
686 {
687  // hard process generation, parton shower, hadron formation
688 
689  InstanceWrapper wrapper(this); // safe guard
690 
691  event().reset();
692 
693  // call herwig routines to create HEPEVT
694 
695  hwuine(); // initialize event
696 
697  if (callWithTimeout(10, hwepro)) { // process event and PS
698  // We hung for more than 10 seconds
699  int error = 199;
700  hwwarn_("HWHGUP", &error);
701  }
702 
703  hwbgen(); // parton cascades
704 
705  // call jimmy ... only if event is not killed yet by HERWIG
706  if (useJimmy && doMPInteraction && !hwevnt.IERROR && call_hwmsct()) {
708  return false;
709  }
710 
711  hwdhob(); // heavy quark decays
712  hwcfor(); // cluster formation
713  hwcdec(); // cluster decays
714 
715 // // if event *not* killed by HERWIG, return true
716 // if (hwevnt.IERROR) {
717 // hwufne(); // finalize event, to keep system clean
718 // if (lheEvent()) lheEvent()->count(lhef::LHERunInfo::kKilled);
719 // return false;
720 // }
721 
722  //if (lheEvent()) lheEvent()->count(lhef::LHERunInfo::kAccepted);
723 
724  hwdhad(); // unstable particle decays
725  hwdhvy(); // heavy flavour decays
726  hwmevt(); // soft underlying event
727 
728 
729  hwufne(); // finalize event
730 
731 
732  // if event *not* killed by HERWIG, return true
733  if (hwevnt.IERROR) {
735  return false;
736  }
737 
738  if (doMatching) {
739  bool pass = call_hwmatch();
740  if (!pass) {
741  printf("Event failed MLM matching\n");
743  return false;
744  }
745  }
746 
748 
749  event().reset(new HepMC::GenEvent);
750  if (!conv.fill_next_event(event().get()))
751  throw cms::Exception("Herwig6Error")
752  << "HepMC Conversion problems in event." << std::endl;
753 
754  // do particle ID conversion Herwig->PDG, if requested
755  if ( fConvertToPDG ) {
756  for ( HepMC::GenEvent::particle_iterator part = event()->particles_begin(); part != event()->particles_end(); ++part) {
757  if ((*part)->pdg_id() != HepPID::translateHerwigtoPDT((*part)->pdg_id()))
758  (*part)->set_pdg_id(HepPID::translateHerwigtoPDT((*part)->pdg_id()));
759  }
760  }
761 
762  return true;
763 }
764 
766 {
768 
769  HepMC::PdfInfo pdfInfo;
770  if(externalPartons) {
771  lheEvent()->fillEventInfo( event().get() );
772  lheEvent()->fillPdfInfo( &pdfInfo );
773 
774  // for MC@NLO: IDWRUP is not filled...
775  if(event()->signal_process_id()==0)
776  event()->set_signal_process_id( abs(hwproc.IPROC) );
777 
778  }
779 
780  HepMC::GenParticle* incomingParton = nullptr;
781  HepMC::GenParticle* targetParton = nullptr;
782 
783  HepMC::GenParticle* incomingProton = nullptr;
784  HepMC::GenParticle* targetProton = nullptr;
785 
786  // find incoming parton (first entry with IST=121)
787  for(HepMC::GenEvent::particle_const_iterator it = event()->particles_begin();
788  (it != event()->particles_end() && incomingParton==nullptr); it++)
789  if((*it)->status()==121) incomingParton = (*it);
790 
791  // find target parton (first entry with IST=122)
792  for(HepMC::GenEvent::particle_const_iterator it = event()->particles_begin();
793  (it != event()->particles_end() && targetParton==nullptr); it++)
794  if((*it)->status()==122) targetParton = (*it);
795 
796  // find incoming Proton (first entry ID=2212, IST=101)
797  for(HepMC::GenEvent::particle_const_iterator it = event()->particles_begin();
798  (it != event()->particles_end() && incomingProton==nullptr); it++)
799  if((*it)->status()==101 && (*it)->pdg_id()==2212) incomingProton = (*it);
800 
801  // find target Proton (first entry ID=2212, IST=102)
802  for(HepMC::GenEvent::particle_const_iterator it = event()->particles_begin();
803  (it != event()->particles_end() && targetProton==nullptr); it++)
804  if((*it)->status()==102 && (*it)->pdg_id()==2212) targetProton = (*it);
805 
806  // find hard scale Q (computed from colliding partons)
807  if( incomingParton && targetParton ) {
808  math::XYZTLorentzVector totMomentum(0,0,0,0);
809  totMomentum+=incomingParton->momentum();
810  totMomentum+=targetParton->momentum();
811  double evScale = totMomentum.mass();
812  double evScale2 = evScale*evScale;
813 
814  // find alpha_QED & alpha_QCD
815  int one=1;
816  double alphaQCD=hwualf_(&one,&evScale);
817  double alphaQED=hwuaem_(&evScale2);
818 
819  if(!externalPartons || event()->event_scale() < 0) event()->set_event_scale(evScale);
820  if(!externalPartons || event()->alphaQCD() < 0) event()->set_alphaQCD(alphaQCD);
821  if(!externalPartons || event()->alphaQED() < 0) event()->set_alphaQED(alphaQED);
822 
823  if(!externalPartons || pdfInfo.x1() < 0) {
824  // get the PDF information
825  pdfInfo.set_id1( incomingParton->pdg_id()==21 ? 0 : incomingParton->pdg_id());
826  pdfInfo.set_id2( targetParton->pdg_id()==21 ? 0 : targetParton->pdg_id());
827  if( incomingProton && targetProton ) {
828  double x1 = incomingParton->momentum().pz()/incomingProton->momentum().pz();
829  double x2 = targetParton->momentum().pz()/targetProton->momentum().pz();
830  pdfInfo.set_x1(x1);
831  pdfInfo.set_x2(x2);
832  }
833  // we do not fill pdf1 & pdf2, since they are not easily available (what are they needed for anyways???)
834  pdfInfo.set_scalePDF(evScale); // the same as Q above... does this make sense?
835  }
836 
837  if(!externalPartons || event()->signal_process_id() < 0) event()->set_signal_process_id( abs(hwproc.IPROC) );
838  event()->set_pdf_info( pdfInfo );
839  }
840 
841  // add event weight & PDF information
842  if (lheRunInfo() != nullptr && std::abs(lheRunInfo()->getHEPRUP()->IDWTUP) == 4)
843  // in LHE weighting mode 4 the weight is an xsec, so convert form HERWIG
844  // to standard CMS unit "picobarn"
845  event()->weights().push_back( 1.0e3 * hwevnt.EVWGT );
846  else
847  event()->weights().push_back( hwevnt.EVWGT );
848 
849 
850  // find final parton (first entry with IST=123)
851  HepMC::GenParticle* finalParton = nullptr;
852  for(HepMC::GenEvent::particle_const_iterator it = event()->particles_begin();
853  (it != event()->particles_end() && finalParton==nullptr); it++)
854  if((*it)->status()==123) finalParton = (*it);
855 
856 
857  // add GenEventInfo & binning Values
858  eventInfo().reset(new GenEventInfoProduct(event().get()));
859  if(finalParton) {
860  double thisPt=finalParton->momentum().perp();
861  eventInfo()->setBinningValues(std::vector<double>(1, thisPt));
862  }
863 
864  // emulate PY6 status codes, if switched on...
867 
868 }
869 
870 
872 {
873  // hadron decays
874 
875 // InstanceWrapper wrapper(this); // safe guard
876 //
877 // //int iproc = hwproc.IPROC;
878 // //hwproc.IPROC = 312;
879 // hwdhad(); // unstable particle decays
880 // //hwproc.IPROC = iproc;
881 //
882 // hwdhvy(); // heavy flavour decays
883 // hwmevt(); // soft underlying event
884 //
885 // if (doMatching) {
886 // bool pass = call_hwmatch();
887 // if (!pass) {
888 // printf("Event failed MLM matching\n");
889 // hwufne();
890 // if (lheEvent()) lheEvent()->count(lhef::LHERunInfo::kKilled);
891 // return false;
892 // }
893 // }
894 //
895 // hwufne(); // finalize event
896 //
897 // if (hwevnt.IERROR)
898 // return false;
899 //
900 // if (lheEvent()) lheEvent()->count(lhef::LHERunInfo::kAccepted);
901 //
902 // event().reset(new HepMC::GenEvent);
903 // if (!conv.fill_next_event(event().get()))
904 // throw cms::Exception("Herwig6Error")
905 // << "HepMC Conversion problems in event." << std::endl;
906 //
907 // // do particle ID conversion Herwig->PDG, if requested
908 // if ( fConvertToPDG ) {
909 // for ( HepMC::GenEvent::particle_iterator part = event()->particles_begin(); part != event()->particles_end(); ++part) {
910 // if ((*part)->pdg_id() != HepPID::translateHerwigtoPDT((*part)->pdg_id()))
911 // (*part)->set_pdg_id(HepPID::translateHerwigtoPDT((*part)->pdg_id()));
912 // }
913 // }
914 
915  return true;
916 }
917 
919 {
920  return true;
921 }
922 
924 {
926  heprup_.pdfgup[0] = heprup_.pdfgup[1] = -1;
927  heprup_.pdfsup[0] = heprup_.pdfsup[1] = -1;
928  // we set up the PDFs ourselves
929 
930  // pass HERWIG paramaters fomr header (if present)
931  std::string mcnloHeader="herwig6header";
932  std::vector<lhef::LHERunInfo::Header> headers=lheRunInfo()->getHeaders();
933  for(std::vector<lhef::LHERunInfo::Header>::const_iterator hIter=headers.begin();hIter!=headers.end(); ++hIter) {
934  if(hIter->tag()==mcnloHeader){
935  readMCatNLOfile=true;
936  for(lhef::LHERunInfo::Header::const_iterator lIter=hIter->begin(); lIter != hIter->end(); ++lIter) {
937  if((lIter->c_str())[0]!='#' && (lIter->c_str())[0]!='\n') { // it's not a comment)
938  if (!give(*lIter))
940  << "Herwig 6 did not accept the following: \""
941  << *lIter << "\"." << std::endl;
942  }
943  }
944  }
945  }
946 }
947 
949 {
951 
952  // if MCatNLO external file is read, read comment & pass IHPRO to HERWIG
953  if(readMCatNLOfile) {
954  for(std::vector<std::string>::const_iterator iter=lheEvent()->getComments().begin();
955  iter!=lheEvent()->getComments().end(); ++iter) {
956  std::string toParse(iter->substr(1));
957  if (!give(toParse))
959  << "Herwig 6 did not accept the following: \""
960  << toParse << "\"." << std::endl;
961  }
962  }
963 
964 }
965 
967 {
968  int status = p->status();
969 
970  // weird 9922212 particles...
971  if (status == 3 && !p->end_vertex())
972  return 2;
973 
974  if (status >= 1 && status <= 3)
975  return status;
976 
977  if (!p->end_vertex())
978  return 1;
979 
980  // let's prevent particles having status 3, if the identical
981  // particle downstream is a better status 3 candidate
982  int currentId = p->pdg_id();
983  int orig = status;
984  if (status == 123 || status == 124 ||
985  status == 155 || status == 156 || status == 160 ||
986  (status >= 195 && status <= 197)) {
987  for(const HepMC::GenParticle *q = p;;) {
988  const HepMC::GenVertex *vtx = q->end_vertex();
989  if (!vtx)
990  break;
991 
992  HepMC::GenVertex::particles_out_const_iterator iter;
993  for(iter = vtx->particles_out_const_begin();
994  iter != vtx->particles_out_const_end(); ++iter)
995  if ((*iter)->pdg_id() == currentId)
996  break;
997 
998  if (iter == vtx->particles_out_const_end())
999  break;
1000 
1001  q = *iter;
1002  if (q->status() == 3 ||
1003  ((status == 120 || status == 123 ||
1004  status == 124) && orig > 124))
1005  return 4;
1006  }
1007  }
1008 
1009  int nesting = 0;
1010  for(;;) {
1011  if ((status >= 120 && status <= 122) || status == 3) {
1012  // avoid flagging status 3 if there is a
1013  // better status 3 candidate upstream
1014  if (externalPartons)
1015  return ((orig >= 121 && orig <= 124) ||
1016  orig == 3) ? 3 : 4;
1017  else
1018  return (nesting ||
1019  (status != 3 && orig <= 124)) ? 3 : 4;
1020  }
1021 
1022  // check whether we are leaving the hard process
1023  // including heavy resonance decays
1024  if (!(status == 4 || status == 123 || status == 124 ||
1025  status == 155 || status == 156 || status == 160 ||
1026  (status >= 195 && status <= 197)))
1027  break;
1028 
1029  const HepMC::GenVertex *vtx = p->production_vertex();
1030  if (!vtx || !vtx->particles_in_size())
1031  break;
1032 
1033  p = *vtx->particles_in_const_begin();
1034  status = p->status();
1035 
1036  int newId = p->pdg_id();
1037 
1038  if (!newId)
1039  break;
1040 
1041  // nesting increases if we move to the next-best mother
1042  if (newId != currentId) {
1043  if (++nesting > 1 && externalPartons)
1044  break;
1045  currentId = newId;
1046  }
1047  }
1048 
1049  return 2;
1050 }
1051 
1053 {
1054  for(HepMC::GenEvent::particle_iterator iter =
1055  event()->particles_begin();
1056  iter != event()->particles_end(); iter++)
1057  (*iter)->set_status(pythiaStatusCode(*iter));
1058 
1059  for(HepMC::GenEvent::particle_iterator iter =
1060  event()->particles_begin();
1061  iter != event()->particles_end(); iter++)
1062  if ((*iter)->status() == 4)
1063  (*iter)->set_status(2);
1064 }
1065 
1067 
1069 DEFINE_FWK_MODULE(Herwig6GeneratorFilter);
1070 
1072 DEFINE_FWK_MODULE(Herwig6HadronizerFilter);
T getParameter(std::string const &) const
static AlgebraicMatrix initialize()
#define jmparm
Definition: herwig.h:301
static const TGPicture * info(bool iBackgroundIsBlack)
void call(void(&fn)())
#define hwmatch
Definition: herwig.h:340
void setSLHAFromHeader(const std::vector< std::string > &lines)
bool declareStableParticles(const std::vector< int > &pdgIds)
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:17
void fillEventInfo(HepMC::GenEvent *hepmc) const
Definition: LHEEvent.cc:249
std::pair< double, double > EBMUP
Definition: LesHouches.h:78
const char * classname() const
#define jminit
Definition: herwig.h:320
int pdfgup[2]
edm::HadronizerFilter< Herwig6Hadronizer, gen::ExternalDecayDriver > Herwig6HadronizerFilter
bool exists(std::string const &parameterName) const
checks if a parameter exists
HepMC::IO_HERWIG conv
static void fixHepMCEventTimeOrdering(HepMC::GenEvent *event)
Definition: LHEEvent.cc:513
void openParticleSpecFile(const std::string fileName)
void count(LHERunInfo::CountMode count, double weight=1.0, double matchWeight=1.0)
Definition: LHEEvent.cc:207
std::pair< int, int > IDBMUP
Definition: LesHouches.h:73
struct HEPRUP_ heprup_
std::vector< std::string >::const_iterator const_iterator
edm::GeneratorFilter< Herwig6Hadronizer, gen::ExternalDecayDriver > Herwig6GeneratorFilter
#define nullptr
bool initialize(const lhef::HEPRUP *heprup)
void setInternalXSec(const XSec &xsec)
uint16_t size_type
std::auto_ptr< HepMC::GenEvent > & event()
int pythiaStatusCode(const HepMC::GenParticle *p) const
double hwualf_(int *mode, double *scale)
double hwuaem_(double *scale)
XYZTLorentzVectorD XYZTLorentzVector
Lorentz vector with cylindrical internal representation using pseudorapidity.
Definition: LorentzVector.h:29
GenRunInfoProduct & runInfo()
#define hwprch
Definition: herwig.h:63
void hwuidt_(int *iopt, int *ipdg, int *iwig, char nwig[8])
const std::vector< std::string > & getComments() const
Definition: LHEEvent.h:46
void mysetpdfpath_(const char *path)
lhef::LHEEvent * lheEvent()
bool callWithTimeout(unsigned int secs, void(*fn)())
void hwwarn_(const char *method, int *id)
void clear(CLHEP::HepGenMatrix &m)
Helper function: Reset all elements of a matrix to 0.
Definition: matutil.cc:167
static void fillHEPEUP(const HEPEUP *hepeup)
~Herwig6Hadronizer() override
void fillPdfInfo(HepMC::PdfInfo *info) const
Definition: LHEEvent.cc:221
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
const std::vector< Header > & getHeaders() const
Definition: LHERunInfo.h:58
std::vector< std::string > const & doSharedResources() const override
#define jmefin
Definition: herwig.h:322
static const std::vector< std::string > theSharedResources
std::auto_ptr< GenEventInfoProduct > & eventInfo()
bool give(const std::string &line)
lhef::LHERunInfo * lheRunInfo()
static const std::string kFortranInstance
bool declareSpecialSettings(const std::vector< std::string > &)
void upEvnt() override
const HEPRUP * getHEPRUP() const
Definition: LHERunInfo.h:52
part
Definition: HCALResponse.h:20
#define hwdspn
Definition: herwig.h:223
std::string particleSpecFileName
std::pair< int, int > pdfSetTranslation() const
Definition: LHERunInfo.cc:637
#define hwmsct
Definition: herwig.h:321
#define begin
Definition: vmac.h:30
HLT enums.
const_iterator end() const
Herwig6Hadronizer(const edm::ParameterSet &params)
#define hwmatchpram
Definition: herwig.h:334
void setHerwigRandomEngine(CLHEP::HepRandomEngine *v)
const_iterator begin() const
void setherwpdf_(void)
std::vector< std::string > findHeader(const std::string &tag) const
Definition: LHERunInfo.cc:525
void doSetRandomEngine(CLHEP::HepRandomEngine *v) override
int pdfsup[2]
static const std::string kHerwig6
#define jimmin
Definition: herwig.h:319
gen::ParameterCollector parameters
double split
Definition: MVATrainer.cc:139
void upInit() override
static void fillHEPRUP(const HEPRUP *heprup)
Definition: event.py:1
static HepMC::HEPEVT_Wrapper wrapper