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" 43 class HepRandomEngine;
47 void hwuidt_(
int *iopt,
int *ipdg,
int *iwig,
char nwig[8]);
54 inline bool call_hwmatch() {
59 inline bool call_hwmsct() {
65 int pdgToHerwig(
int ipdg,
char *nwig) {
68 hwuidt_(&iopt, &ipdg, &iwig, nwig);
69 return ipdg ? iwig : 0;
72 bool markStable(
int pdgId) {
74 if (!pdgToHerwig(pdgId, nwig))
86 void setSLHAFromHeader(
const std::vector<std::string> &
lines);
89 bool readSettings(
int);
94 bool initializeForInternalPartons();
97 bool declareStableParticles(
const std::vector<int> &
pdgIds);
98 bool declareSpecialSettings(
const std::vector<std::string> &);
105 bool residualDecay();
106 void finalizeEvent();
108 const char *
classname()
const {
return "Herwig6Hadronizer"; }
111 void doSetRandomEngine(CLHEP::HepRandomEngine *
v)
override;
112 std::vector<std::string>
const &
doSharedResources()
const override {
return theSharedResources; }
117 void pythiaStatusCodes();
119 void upInit()
override;
120 void upEvnt()
override;
162 : BaseHadronizer(params),
166 hepmcVerbosity(params.getUntrackedParameter<
int>(
"hepmcVerbosity", 0)),
169 emulatePythiaStatusCodes(params.getUntrackedParameter<
bool>(
"emulatePythiaStatusCodes",
false)),
170 comEnergy(params.getParameter<double>(
"comEnergy")),
173 numTrials(params.getUntrackedParameter<
int>(
"numTrialsMPI", 100)),
175 inclusiveMatching(params.getUntrackedParameter<
bool>(
"inclusiveMatching",
true)),
176 nMatch(params.getUntrackedParameter<
int>(
"nMatch", 0)),
177 matchingScale(params.getUntrackedParameter<double>(
"matchingScale", 0.0)),
178 readMCatNLOfile(
false),
181 particleSpecFileName(params.getUntrackedParameter<
std::
string>(
"ParticleSpectrumFileName",
"")),
182 readParticleSpecFile(params.getUntrackedParameter<
bool>(
"readParticleSpecFile",
false))
186 if (params.
exists(
"doPDGConvert"))
207 std::set<std::string>
blocks;
209 for (std::vector<std::string>::const_iterator iter = lines.begin(); iter != lines.end(); ++iter) {
213 if (pos != std::string::npos)
219 if (!boost::algorithm::is_space()(line[0])) {
220 std::vector<std::string> tokens;
221 boost::split(tokens, line, boost::algorithm::is_space(), boost::token_compress_on);
225 if (tokens.size() < 2)
227 if (tokens[0] ==
"BLOCK")
229 else if (tokens[0] ==
"DECAY")
235 if (!blocks.count(block)) {
236 blocks.insert(block);
238 <<
"Unsupported SLHA block \"" << block <<
"\". It will be ignored." << std::endl;
254 std::ostringstream
info;
255 info <<
"---------------------------------------------------\n";
256 info <<
"Taking in settinsg for Herwig6Hadronizer for " << (
externalPartons ?
"external" :
"internal")
258 info <<
"---------------------------------------------------\n";
269 hwproc.PBEAM1 = heprup->
EBMUP.first;
270 hwproc.PBEAM2 = heprup->
EBMUP.second;
271 pdgToHerwig(heprup->
IDBMUP.first, hwbmch.PART1);
272 pdgToHerwig(heprup->
IDBMUP.second, hwbmch.PART2);
276 pdgToHerwig(2212, hwbmch.PART1);
277 pdgToHerwig(2212, hwbmch.PART2);
291 info <<
" HERWIG will be using JIMMY for UE/MI.\n";
294 info <<
" JIMMY trying to generate multiple interactions.\n";
299 bool iprocFound =
false;
302 if (!strcmp((
line->substr(0, 5)).c_str(),
"IPROC")) {
305 <<
"Herwig 6 did not accept the following: \"" << *
line <<
"\"." << std::endl;
317 hwevnt.MAXER = 100000000;
323 for (
unsigned int i = 0;
i < 2;
i++) {
324 hwpram.MODPDF[
i] = -111;
325 std::memcpy(
hwprch.AUTPDF[
i],
"HWLHAPDF", 8);
334 info <<
"------------------------------------\n";
335 info <<
"Reading HERWIG parameters\n";
336 info <<
"------------------------------------\n";
340 info <<
" " << *
line <<
"\n";
343 <<
"Herwig 6 did not accept the following: \"" << *line <<
"\"." << std::endl;
357 std::pair<int, int> pdfs(-1, -1);
361 if (hwpram.MODPDF[0] != -111 || hwpram.MODPDF[1] != -111) {
362 for (
unsigned int i = 0;
i < 2;
i++)
363 if (hwpram.MODPDF[
i] == -111)
364 hwpram.MODPDF[
i] = -1;
366 if (pdfs.first != -1 || pdfs.second != -1)
367 edm::LogError(
"Generator|Herwig6Hadronzier") <<
"Both external Les Houches event and " 368 "config file specify a PDF set. " 369 "User PDF will override external one." 372 pdfs.first = hwpram.MODPDF[0] != -111 ? hwpram.MODPDF[0] : -1;
373 pdfs.second = hwpram.MODPDF[1] != -111 ? hwpram.MODPDF[1] : -1;
376 printf(
"pdfs.first = %i, pdfs.second = %i\n", pdfs.first, pdfs.second);
378 hwpram.MODPDF[0] = pdfs.first;
379 hwpram.MODPDF[1] = pdfs.second;
387 hwpram.EFFMIN = 1
e-5;
416 std::ostringstream
info;
417 info <<
"---------------------------------------------------\n";
418 info <<
"Initializing Herwig6Hadronizer for " << (
externalPartons ?
"external" :
"internal") <<
" partons\n";
419 info <<
"---------------------------------------------------\n";
430 hwproc.PBEAM1 = heprup->
EBMUP.first;
431 hwproc.PBEAM2 = heprup->
EBMUP.second;
432 pdgToHerwig(heprup->
IDBMUP.first, hwbmch.PART1);
433 pdgToHerwig(heprup->
IDBMUP.second, hwbmch.PART2);
437 pdgToHerwig(2212, hwbmch.PART1);
438 pdgToHerwig(2212, hwbmch.PART2);
442 info <<
" HERWIG will be using JIMMY for UE/MI.\n";
445 info <<
" JIMMY trying to generate multiple interactions.\n";
450 bool iprocFound =
false;
453 if (!strcmp((
line->substr(0, 5)).c_str(),
"IPROC")) {
456 <<
"Herwig 6 did not accept the following: \"" << *
line <<
"\"." << std::endl;
467 hwevnt.MAXER = 100000000;
475 for (
unsigned int i = 0;
i < 2;
i++) {
476 hwpram.MODPDF[
i] = -111;
477 std::memcpy(
hwprch.AUTPDF[
i],
"HWLHAPDF", 8);
489 info <<
"------------------------------------\n";
490 info <<
"Reading HERWIG parameters\n";
491 info <<
"------------------------------------\n";
495 info <<
" " << *
line <<
"\n";
498 <<
"Herwig 6 did not accept the following: \"" << *line <<
"\"." << std::endl;
512 std::pair<int, int> pdfs(-1, -1);
516 if (hwpram.MODPDF[0] != -111 || hwpram.MODPDF[1] != -111) {
517 for (
unsigned int i = 0;
i < 2;
i++)
518 if (hwpram.MODPDF[
i] == -111)
519 hwpram.MODPDF[
i] = -1;
521 if (pdfs.first != -1 || pdfs.second != -1)
522 edm::LogError(
"Generator|Herwig6Hadronzier") <<
"Both external Les Houches event and " 523 "config file specify a PDF set. " 524 "User PDF will override external one." 527 pdfs.first = hwpram.MODPDF[0] != -111 ? hwpram.MODPDF[0] : -1;
528 pdfs.second = hwpram.MODPDF[1] != -111 ? hwpram.MODPDF[1] : -1;
531 printf(
"pdfs.first = %i, pdfs.second = %i\n", pdfs.first, pdfs.second);
533 hwpram.MODPDF[0] = pdfs.first;
534 hwpram.MODPDF[1] = pdfs.second;
542 hwpram.EFFMIN = 1
e-5;
604 for (std::vector<int>::const_iterator iter = pdgIds.begin(); iter != pdgIds.end(); ++iter)
605 if (!markStable(*iter))
613 if (!
runInfo().internalXSec()) {
618 double RNWGT = 1. / hwevnt.NWGTS;
619 double AVWGT = hwevnt.WGTSUM * RNWGT;
621 double xsec = 1.0e3 * AVWGT;
680 bool pass = call_hwmatch();
682 printf(
"Event failed MLM matching\n");
693 if (!
conv.fill_next_event(
event().
get()))
694 throw cms::Exception(
"Herwig6Error") <<
"HepMC Conversion problems in event." << std::endl;
698 for (HepMC::GenEvent::particle_iterator
part =
event()->particles_begin();
part !=
event()->particles_end();
700 if ((*part)->pdg_id() != HepPID::translateHerwigtoPDT((*part)->pdg_id()))
701 (*part)->set_pdg_id(HepPID::translateHerwigtoPDT((*part)->pdg_id()));
711 HepMC::PdfInfo pdfInfo;
717 if (
event()->signal_process_id() == 0)
718 event()->set_signal_process_id(
abs(hwproc.IPROC));
728 for (HepMC::GenEvent::particle_const_iterator it =
event()->particles_begin();
729 (it !=
event()->particles_end() && incomingParton ==
nullptr);
731 if ((*it)->status() == 121)
732 incomingParton = (*it);
735 for (HepMC::GenEvent::particle_const_iterator it =
event()->particles_begin();
736 (it !=
event()->particles_end() && targetParton ==
nullptr);
738 if ((*it)->status() == 122)
739 targetParton = (*it);
742 for (HepMC::GenEvent::particle_const_iterator it =
event()->particles_begin();
743 (it !=
event()->particles_end() && incomingProton ==
nullptr);
745 if ((*it)->status() == 101 && (*it)->pdg_id() == 2212)
746 incomingProton = (*it);
749 for (HepMC::GenEvent::particle_const_iterator it =
event()->particles_begin();
750 (it !=
event()->particles_end() && targetProton ==
nullptr);
752 if ((*it)->status() == 102 && (*it)->pdg_id() == 2212)
753 targetProton = (*it);
756 if (incomingParton && targetParton) {
758 totMomentum += incomingParton->momentum();
759 totMomentum += targetParton->momentum();
760 double evScale = totMomentum.mass();
761 double evScale2 = evScale * evScale;
765 double alphaQCD =
hwualf_(&one, &evScale);
766 double alphaQED =
hwuaem_(&evScale2);
769 event()->set_event_scale(evScale);
771 event()->set_alphaQCD(alphaQCD);
773 event()->set_alphaQED(alphaQED);
777 pdfInfo.set_id1(incomingParton->pdg_id() == 21 ? 0 : incomingParton->pdg_id());
778 pdfInfo.set_id2(targetParton->pdg_id() == 21 ? 0 : targetParton->pdg_id());
779 if (incomingProton && targetProton) {
780 double x1 = incomingParton->momentum().pz() / incomingProton->momentum().pz();
781 double x2 = targetParton->momentum().pz() / targetProton->momentum().pz();
786 pdfInfo.set_scalePDF(evScale);
790 event()->set_signal_process_id(
abs(hwproc.IPROC));
791 event()->set_pdf_info(pdfInfo);
798 event()->weights().push_back(1.0
e3 * hwevnt.EVWGT);
800 event()->weights().push_back(hwevnt.EVWGT);
804 for (HepMC::GenEvent::particle_const_iterator it =
event()->particles_begin();
805 (it !=
event()->particles_end() && finalParton ==
nullptr);
807 if ((*it)->status() == 123)
813 double thisPt = finalParton->momentum().perp();
814 eventInfo()->setBinningValues(std::vector<double>(1, thisPt));
879 for (std::vector<lhef::LHERunInfo::Header>::const_iterator hIter = headers.begin(); hIter != headers.end(); ++hIter) {
880 if (hIter->tag() == mcnloHeader) {
883 if ((lIter->c_str())[0] !=
'#' && (lIter->c_str())[0] !=
'\n') {
886 <<
"Herwig 6 did not accept the following: \"" << *lIter <<
"\"." << std::endl;
898 for (std::vector<std::string>::const_iterator iter =
lheEvent()->getComments().
begin();
904 <<
"Herwig 6 did not accept the following: \"" << toParse <<
"\"." << std::endl;
913 if (status == 3 && !p->end_vertex())
916 if (status >= 1 && status <= 3)
919 if (!p->end_vertex())
924 int currentId = p->pdg_id();
926 if (status == 123 || status == 124 || status == 155 || status == 156 || status == 160 ||
927 (status >= 195 && status <= 197)) {
929 const HepMC::GenVertex *
vtx =
q->end_vertex();
933 HepMC::GenVertex::particles_out_const_iterator iter;
934 for (iter = vtx->particles_out_const_begin(); iter != vtx->particles_out_const_end(); ++iter)
935 if ((*iter)->pdg_id() == currentId)
938 if (iter == vtx->particles_out_const_end())
942 if (
q->status() == 3 || ((status == 120 || status == 123 || status == 124) && orig > 124))
949 if ((status >= 120 && status <= 122) || status == 3) {
953 return ((orig >= 121 && orig <= 124) || orig == 3) ? 3 : 4;
955 return (nesting || (status != 3 && orig <= 124)) ? 3 : 4;
960 if (!(status == 4 || status == 123 || status == 124 || status == 155 || status == 156 || status == 160 ||
961 (status >= 195 && status <= 197)))
964 const HepMC::GenVertex *
vtx = p->production_vertex();
965 if (!vtx || !vtx->particles_in_size())
968 p = *vtx->particles_in_const_begin();
969 status = p->status();
971 int newId = p->pdg_id();
977 if (newId != currentId) {
988 for (HepMC::GenEvent::particle_iterator iter =
event()->particles_begin(); iter !=
event()->particles_end(); iter++)
991 for (HepMC::GenEvent::particle_iterator iter =
event()->particles_begin(); iter !=
event()->particles_end(); iter++)
992 if ((*iter)->status() == 4)
993 (*iter)->set_status(2);
std::vector< std::string_view > split(std::string_view, const char *)
T getParameter(std::string const &) const
static AlgebraicMatrix initialize()
bool readParticleSpecFile
void setSLHAFromHeader(const std::vector< std::string > &lines)
bool declareStableParticles(const std::vector< int > &pdgIds)
void fillEventInfo(HepMC::GenEvent *hepmc) const
std::pair< double, double > EBMUP
const char * classname() const
edm::HadronizerFilter< Herwig6Hadronizer, gen::ExternalDecayDriver > Herwig6HadronizerFilter
bool exists(std::string const ¶meterName) const
checks if a parameter exists
static void fixHepMCEventTimeOrdering(HepMC::GenEvent *event)
void openParticleSpecFile(const std::string fileName)
void count(LHERunInfo::CountMode count, double weight=1.0, double matchWeight=1.0)
std::pair< int, int > IDBMUP
bool generatePartonsAndHadronize()
edm::GeneratorFilter< Herwig6Hadronizer, gen::ExternalDecayDriver > Herwig6GeneratorFilter
bool initialize(const lhef::HEPRUP *heprup)
void setInternalXSec(const XSec &xsec)
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.
GenRunInfoProduct & runInfo()
bool initializeForInternalPartons()
#define DEFINE_FWK_MODULE(type)
void hwuidt_(int *iopt, int *ipdg, int *iwig, char nwig[8])
const std::vector< std::string > & getComments() const
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.
static void fillHEPEUP(const HEPEUP *hepeup)
~Herwig6Hadronizer() override
void fillPdfInfo(HepMC::PdfInfo *info) const
Abs< T >::type abs(const T &t)
const std::vector< Header > & getHeaders() const
std::vector< std::string > const & doSharedResources() const override
static const std::vector< std::string > theSharedResources
std::unique_ptr< HepMC::GenEvent > & event()
bool give(const std::string &line)
lhef::LHERunInfo * lheRunInfo()
static const std::string kFortranInstance
bool declareSpecialSettings(const std::vector< std::string > &)
const HEPRUP * getHEPRUP() const
std::unique_ptr< GenEventInfoProduct > & eventInfo()
std::string particleSpecFileName
std::pair< int, int > pdfSetTranslation() const
bool emulatePythiaStatusCodes
Herwig6Hadronizer(const edm::ParameterSet ¶ms)
void setHerwigRandomEngine(CLHEP::HepRandomEngine *v)
std::vector< std::string > findHeader(const std::string &tag) const
void doSetRandomEngine(CLHEP::HepRandomEngine *v) override
static const std::string kHerwig6
gen::ParameterCollector parameters
bool initializeForExternalPartons()
static void fillHEPRUP(const HEPRUP *heprup)
static HepMC::HEPEVT_Wrapper wrapper