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"
45 class HepRandomEngine;
49 void hwuidt_(
int *iopt,
int *ipdg,
int *iwig,
char nwig[8]);
56 inline bool call_hwmatch() {
61 inline bool call_hwmsct() {
67 int pdgToHerwig(
int ipdg,
char *nwig) {
70 hwuidt_(&iopt, &ipdg, &iwig, nwig);
71 return ipdg ? iwig : 0;
74 bool markStable(
int pdgId) {
76 if (!pdgToHerwig(
pdgId, nwig))
110 const char *
classname()
const {
return "Herwig6Hadronizer"; }
168 hepmcVerbosity(
params.getUntrackedParameter<
int>(
"hepmcVerbosity", 0)),
171 emulatePythiaStatusCodes(
params.getUntrackedParameter<
bool>(
"emulatePythiaStatusCodes",
false)),
175 numTrials(
params.getUntrackedParameter<
int>(
"numTrialsMPI", 100)),
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),
183 particleSpecFileName(
params.getUntrackedParameter<
std::
string>(
"ParticleSpectrumFileName",
"")),
184 readParticleSpecFile(
params.getUntrackedParameter<
bool>(
"readParticleSpecFile",
false))
188 if (
params.exists(
"doPDGConvert"))
209 std::set<std::string>
blocks;
211 for (std::vector<std::string>::const_iterator iter =
lines.begin(); iter !=
lines.end(); ++iter) {
215 if (
pos != std::string::npos)
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);
227 if (tokens.size() < 2)
229 if (tokens[0] ==
"BLOCK")
231 else if (tokens[0] ==
"DECAY")
240 <<
"Unsupported SLHA block \"" <<
block <<
"\". It will be ignored." << std::endl;
256 std::ostringstream
info;
257 info <<
"---------------------------------------------------\n";
258 info <<
"Taking in settinsg for Herwig6Hadronizer for " << (
externalPartons ?
"external" :
"internal")
260 info <<
"---------------------------------------------------\n";
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);
278 pdgToHerwig(2212, hwbmch.PART1);
279 pdgToHerwig(2212, hwbmch.PART2);
293 info <<
" HERWIG will be using JIMMY for UE/MI.\n";
296 info <<
" JIMMY trying to generate multiple interactions.\n";
301 bool iprocFound =
false;
304 if (!strcmp((
line->substr(0, 5)).c_str(),
"IPROC")) {
307 <<
"Herwig 6 did not accept the following: \"" << *
line <<
"\"." << std::endl;
319 hwevnt.MAXER = 100000000;
325 for (
unsigned int i = 0;
i < 2;
i++) {
326 hwpram.MODPDF[
i] = -111;
327 std::memcpy(
hwprch.AUTPDF[
i],
"HWLHAPDF", 8);
336 info <<
"------------------------------------\n";
337 info <<
"Reading HERWIG parameters\n";
338 info <<
"------------------------------------\n";
345 <<
"Herwig 6 did not accept the following: \"" << *
line <<
"\"." << std::endl;
359 std::pair<int, int> pdfs(-1, -1);
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;
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."
374 pdfs.first = hwpram.MODPDF[0] != -111 ? hwpram.MODPDF[0] : -1;
375 pdfs.second = hwpram.MODPDF[1] != -111 ? hwpram.MODPDF[1] : -1;
378 printf(
"pdfs.first = %i, pdfs.second = %i\n", pdfs.first, pdfs.second);
380 hwpram.MODPDF[0] = pdfs.first;
381 hwpram.MODPDF[1] = pdfs.second;
389 hwpram.EFFMIN = 1
e-5;
418 std::ostringstream
info;
419 info <<
"---------------------------------------------------\n";
420 info <<
"Initializing Herwig6Hadronizer for " << (
externalPartons ?
"external" :
"internal") <<
" partons\n";
421 info <<
"---------------------------------------------------\n";
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);
439 pdgToHerwig(2212, hwbmch.PART1);
440 pdgToHerwig(2212, hwbmch.PART2);
444 info <<
" HERWIG will be using JIMMY for UE/MI.\n";
447 info <<
" JIMMY trying to generate multiple interactions.\n";
452 bool iprocFound =
false;
455 if (!strcmp((
line->substr(0, 5)).c_str(),
"IPROC")) {
458 <<
"Herwig 6 did not accept the following: \"" << *
line <<
"\"." << std::endl;
469 hwevnt.MAXER = 100000000;
477 for (
unsigned int i = 0;
i < 2;
i++) {
478 hwpram.MODPDF[
i] = -111;
479 std::memcpy(
hwprch.AUTPDF[
i],
"HWLHAPDF", 8);
491 info <<
"------------------------------------\n";
492 info <<
"Reading HERWIG parameters\n";
493 info <<
"------------------------------------\n";
500 <<
"Herwig 6 did not accept the following: \"" << *
line <<
"\"." << std::endl;
514 std::pair<int, int> pdfs(-1, -1);
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;
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."
529 pdfs.first = hwpram.MODPDF[0] != -111 ? hwpram.MODPDF[0] : -1;
530 pdfs.second = hwpram.MODPDF[1] != -111 ? hwpram.MODPDF[1] : -1;
533 printf(
"pdfs.first = %i, pdfs.second = %i\n", pdfs.first, pdfs.second);
535 hwpram.MODPDF[0] = pdfs.first;
536 hwpram.MODPDF[1] = pdfs.second;
544 hwpram.EFFMIN = 1
e-5;
606 for (std::vector<int>::const_iterator iter =
pdgIds.begin(); iter !=
pdgIds.end(); ++iter)
607 if (!markStable(*iter))
615 if (!
runInfo().internalXSec()) {
620 double RNWGT = 1. / hwevnt.NWGTS;
621 double AVWGT = hwevnt.WGTSUM * RNWGT;
623 double xsec = 1.0e3 * AVWGT;
682 bool pass = call_hwmatch();
684 printf(
"Event failed MLM matching\n");
694 event() = std::make_unique<HepMC::GenEvent>();
696 throw cms::Exception(
"Herwig6Error") <<
"HepMC Conversion problems in event." << std::endl;
700 for (HepMC::GenEvent::particle_iterator
part =
event()->particles_begin();
part !=
event()->particles_end();
702 if ((*part)->pdg_id() != HepPID::translateHerwigtoPDT((*part)->pdg_id()))
703 (*part)->set_pdg_id(HepPID::translateHerwigtoPDT((*part)->pdg_id()));
713 HepMC::PdfInfo pdfInfo;
719 if (
event()->signal_process_id() == 0)
720 event()->set_signal_process_id(
abs(hwproc.IPROC));
730 for (HepMC::GenEvent::particle_const_iterator it =
event()->particles_begin();
731 (it !=
event()->particles_end() && incomingParton ==
nullptr);
733 if ((*it)->status() == 121)
734 incomingParton = (*it);
737 for (HepMC::GenEvent::particle_const_iterator it =
event()->particles_begin();
738 (it !=
event()->particles_end() && targetParton ==
nullptr);
740 if ((*it)->status() == 122)
741 targetParton = (*it);
744 for (HepMC::GenEvent::particle_const_iterator it =
event()->particles_begin();
745 (it !=
event()->particles_end() && incomingProton ==
nullptr);
747 if ((*it)->status() == 101 && (*it)->pdg_id() == 2212)
748 incomingProton = (*it);
751 for (HepMC::GenEvent::particle_const_iterator it =
event()->particles_begin();
752 (it !=
event()->particles_end() && targetProton ==
nullptr);
754 if ((*it)->status() == 102 && (*it)->pdg_id() == 2212)
755 targetProton = (*it);
758 if (incomingParton && targetParton) {
760 totMomentum += incomingParton->momentum();
761 totMomentum += targetParton->momentum();
762 double evScale = totMomentum.mass();
763 double evScale2 = evScale * evScale;
768 double alphaQED =
hwuaem_(&evScale2);
771 event()->set_event_scale(evScale);
773 event()->set_alphaQCD(alphaQCD);
775 event()->set_alphaQED(alphaQED);
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();
788 pdfInfo.set_scalePDF(evScale);
792 event()->set_signal_process_id(
abs(hwproc.IPROC));
793 event()->set_pdf_info(pdfInfo);
800 event()->weights().push_back(1.0
e3 * hwevnt.EVWGT);
802 event()->weights().push_back(hwevnt.EVWGT);
806 for (HepMC::GenEvent::particle_const_iterator it =
event()->particles_begin();
807 (it !=
event()->particles_end() && finalParton ==
nullptr);
809 if ((*it)->status() == 123)
815 double thisPt = finalParton->momentum().perp();
816 eventInfo()->setBinningValues(std::vector<double>(1, thisPt));
881 for (std::vector<lhef::LHERunInfo::Header>::const_iterator hIter =
headers.begin(); hIter !=
headers.end(); ++hIter) {
882 if (hIter->tag() == mcnloHeader) {
885 if ((lIter->c_str())[0] !=
'#' && (lIter->c_str())[0] !=
'\n') {
888 <<
"Herwig 6 did not accept the following: \"" << *lIter <<
"\"." << std::endl;
900 for (std::vector<std::string>::const_iterator iter =
lheEvent()->getComments().begin();
906 <<
"Herwig 6 did not accept the following: \"" << toParse <<
"\"." << std::endl;
915 if (
status == 3 && !
p->end_vertex())
921 if (!
p->end_vertex())
926 int currentId =
p->pdg_id();
931 const HepMC::GenVertex *
vtx =
q->end_vertex();
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)
940 if (iter ==
vtx->particles_out_const_end())
955 return ((orig >= 121 && orig <= 124) || orig == 3) ? 3 : 4;
957 return (nesting || (
status != 3 && orig <= 124)) ? 3 : 4;
966 const HepMC::GenVertex *
vtx =
p->production_vertex();
967 if (!
vtx || !
vtx->particles_in_size())
970 p = *
vtx->particles_in_const_begin();
973 int newId =
p->pdg_id();
979 if (newId != currentId) {
990 for (HepMC::GenEvent::particle_iterator iter =
event()->particles_begin(); iter !=
event()->particles_end(); iter++)
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);