CMS 3D CMS Logo

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