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"; }
155 void hwwarn_(
const char *method,
int *
id);
164 : BaseHadronizer(params),
167 herwigVerbosity(params.getUntrackedParameter<int>(
"herwigVerbosity", 0)),
168 hepmcVerbosity(params.getUntrackedParameter<int>(
"hepmcVerbosity", 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)),
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) {
213 std::transform(line.begin(), line.end(), line.begin(), (int (*)(int))std::toupper);
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")
237 if (!blocks.count(block)) {
238 blocks.insert(block);
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";
342 info <<
" " << *
line <<
"\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";
497 info <<
" " << *
line <<
"\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>();
695 if (!
conv.fill_next_event(
event().
get()))
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;
767 double alphaQCD =
hwualf_(&one, &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.0e3 * 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)
813 eventInfo() = std::make_unique<GenEventInfoProduct>(
event().get());
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())
918 if (status >= 1 && status <= 3)
921 if (!p->end_vertex())
926 int currentId = p->pdg_id();
928 if (status == 123 || status == 124 || status == 155 || status == 156 || status == 160 ||
929 (status >= 195 && status <= 197)) {
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())
944 if (
q->status() == 3 || ((status == 120 || status == 123 || status == 124) && orig > 124))
951 if ((status >= 120 && status <= 122) || status == 3) {
955 return ((orig >= 121 && orig <= 124) || orig == 3) ? 3 : 4;
957 return (nesting || (status != 3 && orig <= 124)) ? 3 : 4;
962 if (!(status == 4 || status == 123 || status == 124 || status == 155 || status == 156 || status == 160 ||
963 (status >= 195 && status <= 197)))
966 const HepMC::GenVertex *vtx = p->production_vertex();
967 if (!vtx || !vtx->particles_in_size())
970 p = *vtx->particles_in_const_begin();
971 status = p->status();
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);
bool readParticleSpecFile
void setSLHAFromHeader(const std::vector< std::string > &lines)
bool declareStableParticles(const std::vector< int > &pdgIds)
#define DEFINE_FWK_MODULE(type)
void fillEventInfo(HepMC::GenEvent *hepmc) const
std::pair< double, double > EBMUP
const char * classname() const
std::vector< std::string > const & doSharedResources() const override
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()
Log< level::Error, false > LogError
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()
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)
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
tuple key
prepare the HTCondor submission files and eventually submit them
Abs< T >::type abs(const T &t)
const std::vector< Header > & getHeaders() const
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 > &)
const HEPRUP * getHEPRUP() const
std::unique_ptr< GenEventInfoProduct > & eventInfo()
std::string particleSpecFileName
T getParameter(std::string const &) const
std::pair< int, int > pdfSetTranslation() const
bool emulatePythiaStatusCodes
const_iterator end() const
Herwig6Hadronizer(const edm::ParameterSet ¶ms)
void setHerwigRandomEngine(CLHEP::HepRandomEngine *v)
const_iterator begin() const
std::vector< std::string > findHeader(const std::string &tag) const
void doSetRandomEngine(CLHEP::HepRandomEngine *v) override
Log< level::Warning, false > LogWarning
static const std::string kHerwig6
gen::ParameterCollector parameters
bool initializeForExternalPartons()
static void fillHEPRUP(const HEPRUP *heprup)
static HepMC::HEPEVT_Wrapper wrapper