69 LesHouchesReader::doinit();
77 bool readingSLHA =
false;
79 unsigned int newNumber(0);
81 line = StringUtils::car(block,
"\r\n");
82 block = StringUtils::cdr(block,
"\r\n");
83 if(line[0]==
'#')
continue;
87 if(line.find(
"</slha") != string::npos) {
92 vector<string>
split = StringUtils::split(line,
"#");
96 if(
split[0].
find(
"block qnumbers")==string::npos)
100 if(
split.size()>=2) {
101 name = StringUtils::stripws(
split[1]);
106 tname <<
"NP" << newNumber;
111 istringstream is(
split[2]);
116 for(
unsigned int ix=0;ix<4;++ix) {
117 line = StringUtils::car(block,
"\r\n");
118 block = StringUtils::cdr(block,
"\r\n");
120 istringstream is(line);
121 is >> dummy[0] >> dummy[1];
141 newParticle.first = getParticleData(PDGCode);
142 if(newParticle.first) Throw<SetupException>()
143 <<
"Particle with PDG code " << PDGCode
144 <<
" whose creation was requested in a QNUMBERS Block"
145 <<
" already exists. Retaining the original particle"
146 << Exception::warning;
148 newParticle.second = getParticleData(-PDGCode);
149 if(newParticle.second) Throw<SetupException>()
150 <<
"Anti-particle with PDG code " << -PDGCode
151 <<
" whose creation was requested in a QNUMBERS Block"
152 <<
" already exists. Retaining the original particle"
153 << Exception::warning;
154 if(( newParticle.first && !newParticle.second ) ||
155 ( newParticle.second && !newParticle.first ) )
156 Throw<SetupException>()
157 <<
"Either particle or anti-particle with PDG code " << PDGCode
158 <<
" whose creation was requested in a QNUMBERS Block"
159 <<
" already exists, but not both the particle and antiparticle. "
160 <<
" Something dodgy here stopping"
161 << Exception::runerror;
164 if(newParticle.first)
continue;
175 newParticle.first = ParticleData::Create(PDGCode,name);
187 nameAnti = temp2.str();
191 auto swapSign=[](
char & t){
193 else if (t==
'+') t=
'-';
195 std::for_each(nameAnti.begin(),nameAnti.end(), swapSign);
196 if(nameAnti==name) nameAnti +=
"bar";
199 newParticle = ParticleData::Create(PDGCode,name,nameAnti);
202 if(colour==1) colour = 0;
203 newParticle.first->iColour(PDT::Colour(colour));
204 newParticle.first->iSpin (PDT::Spin (
spin ));
205 newParticle.first->iCharge(PDT::Charge(
charge));
207 generator()->preinitRegister(newParticle.first,
208 "/Herwig/Particles/"+newParticle.first->PDGName());
210 if(newParticle.second) {
211 if(colour==3||colour==6) colour *= -1;
213 newParticle.second->iColour(PDT::Colour(colour));
214 newParticle.second->iSpin (PDT::Spin (
spin ));
215 newParticle.second->iCharge(PDT::Charge(
charge));
217 generator()->preinitRegister(newParticle.second,
218 "/Herwig/Particles/"+newParticle.second->PDGName());
222 else if(line.find(
"<slha") != string::npos) {
233 line = StringUtils::car(block,
"\r\n");
234 block = StringUtils::cdr(block,
"\r\n");
238 if(line.starts_with(
"</slha")) {
243 transform(line.begin(),line.end(),line.begin(), pf);
245 if(line.find(
"block mass")!=string::npos) {
247 line = StringUtils::car(block,
"\r\n");
249 while(line[0] !=
'D' && line[0] !=
'B' &&
250 line[0] !=
'd' && line[0] !=
'b' &&
254 block = StringUtils::cdr(block,
"\r\n");
255 line = StringUtils::car(block,
"\r\n");
259 istringstream
temp(line);
265 if(std::abs(
id) <= 6 || (std::abs(
id) >= 11 && std::abs(
id) <= 16) ||
266 std::abs(
id) == 23 || std::abs(
id) == 24) {
267 block = StringUtils::cdr(block,
"\r\n");
268 line = StringUtils::car(block,
"\r\n");
274 tPDPtr particle = getParticleData(
id);
275 if(!particle)
throw SetupException()
276 <<
"powhegLesHouchesFileReader::doinit() - Particle with PDG code not"
277 <<
id <<
" not found." << Exception::runerror;
278 const InterfaceBase * ifb = BaseRepository::FindInterface(particle,
282 ifb->exec(*particle,
"set", os.str());
284 block = StringUtils::cdr(block,
"\r\n");
285 line = StringUtils::car(block,
"\r\n");
289 else if(line.starts_with(
"decay")) {
291 istringstream iss(line);
295 iss >> dummy >> parent >> iunit(
width,
GeV);
297 PDPtr inpart = getParticleData(parent);
299 throw SetupException()
300 <<
"powhegLesHouchesFileReader::doinit() - A ParticleData object with the PDG code "
301 << parent <<
" does not exist. " << Exception::runerror;
304 if ( std::abs(inpart->id()) == 6 ||
305 std::abs(inpart->id()) == 15 ||
306 std::abs(inpart->id()) == 23 ||
307 std::abs(inpart->id()) == 24 ||
308 std::abs(inpart->id()) == 25 ) {
309 Throw<SetupException>() <<
"\n"
310 "************************************************************************\n"
311 "* Your LHE file changes the width of " << inpart->PDGName() <<
".\n"
312 "* This can cause serious problems in the event generation!\n"
313 "************************************************************************\n"
314 "\n" << Exception::warning;
316 else if (inpart->width() > ZERO &&
width <= ZERO) {
317 Throw<SetupException>() <<
"\n"
318 "************************************************************************\n"
319 "* Your LHE file zeroes the non-zero width of " << inpart->PDGName() <<
".\n"
320 "* If " << inpart->PDGName() <<
" is a decaying SM particle,\n"
321 "* this can cause serious problems in the event generation!\n"
322 "************************************************************************\n"
323 "\n" << Exception::warning;
326 inpart->width(
width);
328 inpart->cTau(hbarc/
width);
329 inpart->widthCut(5.*
width);
330 inpart->stable(
false);
333 string prefix(inpart->name() +
"->"), tag(prefix),line(
"");
334 unsigned int nmode(0);
336 line = StringUtils::car(block,
"\r\n");
337 while(line[0] !=
'D' && line[0] !=
'B' &&
338 line[0] !=
'd' && line[0] !=
'b' &&
339 line[0] !=
'<' && line !=
"") {
342 block = StringUtils::cdr(block,
"\r\n");
343 line = StringUtils::car(block,
"\r\n");
347 istringstream is(line);
349 unsigned int nda(0),npr(0);
354 if( is.fail() )
break;
355 if( t == std::abs(parent) )
356 throw SetupException()
357 <<
"An error occurred while read a decay of the "
358 << inpart->PDGName() <<
". One of its products has the same PDG code "
359 <<
"as the parent particle in powhegLesHouchesFileReader::doinit()."
360 <<
" Please check the Les Houches file.\n"
361 << Exception::runerror;
362 tcPDPtr p = getParticleData(t);
364 throw SetupException()
365 <<
"powhegLesHouchesFileReader::doinit() -"
366 <<
" An unknown PDG code has been encounterd "
367 <<
"while reading a decay mode. ID: " << t
368 << Exception::runerror;
370 tag += p->name() +
",";
373 throw SetupException()
374 <<
"powhegLesHouchesFileReader::doinit() - While reading a decay of the "
375 << inpart->PDGName() <<
" from an SLHA file, an inconsistency "
376 <<
"between the number of decay products and the value in "
377 <<
"the 'NDA' column was found. Please check if the spectrum "
378 <<
"file is correct.\n"
379 << Exception::warning;
383 generator()->preinitInterface(inpart,
"VariableRatio" ,
"set",
"false");
384 if(inpart->massGenerator()) {
386 Throw<SetupException>()
387 << inpart->PDGName() <<
" already has a MassGenerator set"
388 <<
" this is incompatible with using QNUMBERS "
390 <<
"set " << inpart->fullName() <<
":Mass_generator NULL\n"
391 <<
"to fix this." << Exception::warning;
393 if(inpart->widthGenerator()) {
395 Throw<SetupException>()
396 << inpart->PDGName() <<
" already has a WidthGenerator set"
397 <<
" this is incompatible with using QNUMBERS "
399 <<
"set " << inpart->fullName() <<
":Width_generator NULL\n"
400 <<
"to fix this." << Exception::warning;
402 unsigned int ntemp=0;
403 for(DecaySet::const_iterator dit = inpart->decayModes().begin();
404 dit != inpart->decayModes().end(); ++dit ) {
405 if((**dit).on()) ++ntemp;
409 Throw<SetupException>()
410 << inpart->PDGName() <<
" already has DecayModes"
411 <<
" this is incompatible with using QNUMBERS "
413 <<
"do " << inpart->fullName() <<
":SelectDecayModes none\n"
414 <<
" to fix this." << Exception::warning;
417 inpart->stable(
false);
418 tag.replace(tag.size() - 1, 1,
";");
419 DMPtr dm = generator()->findDecayMode(tag);
421 <<
"powhegLesHouchesFileReader::doinit() Decayer must be set using the "
422 <<
"powhegLesHouchesFileReader:Decayer"
423 <<
" must be set to allow the creation of new"
425 << Exception::runerror;
427 dm = generator()->preinitCreateDecayMode(tag);
429 Throw<SetupException>()
430 <<
"powhegLesHouchesFileReader::doinit() - Needed to create "
431 <<
"new decaymode but one could not be created for the tag "
432 << tag << Exception::warning;
434 generator()->preinitInterface(dm,
"Decayer",
"set",
437 br << setprecision(13) << brat;
438 generator()->preinitInterface(dm,
"BranchingRatio",
"set", br.str());
439 generator()->preinitInterface(dm,
"Active",
"set",
"Yes");
441 generator()->preinitInterface(dm->CC(),
"BranchingRatio",
"set", br.str());
442 generator()->preinitInterface(dm->CC(),
"Active",
"set",
"Yes");
448 block = StringUtils::cdr(block,
"\r\n");
449 line = StringUtils::car(block,
"\r\n");
454 inpart->CC()->update();
459 else if(line.find(
"<slha") != string::npos) {
465 throw SetupException() <<
"Problem reading QNUMBERS blocks in powhegLesHouchesFileReader::doinit()"
466 << Exception::runerror;
627 if (
heprup.NPRUP < 0 )
return false;
632 optionalWeights.clear();
646 istringstream ievat(
m_cfile.getline());
647 int we(0), npLO(-99), npNLO(-99);
649 string sub; ievat >> sub;
650 if(we==2) { npLO = atoi(sub.c_str()); }
651 if(we==5) { npNLO = atoi(sub.c_str()); }
655 optionalnpNLO = npNLO;
656 std::stringstream npstringstream;
657 npstringstream <<
"np " << npLO <<
" " << npNLO;
658 std::string npstrings = npstringstream.str();
666 if ( !
m_cfile.readline() )
return false;
675 for (
int i = 0; i <
hepeup.NUP; ++i ) {
676 if ( !
m_cfile.readline() )
return false;
685 if(std::isnan(
hepeup.PUP[i][0])||std::isnan(
hepeup.PUP[i][1])||
686 std::isnan(
hepeup.PUP[i][2])||std::isnan(
hepeup.PUP[i][3])||
687 std::isnan(
hepeup.PUP[i][4]))
689 <<
"nan's as momenta in Les Houches file "
690 << Exception::eventerror;
691 if(
hepeup.MOTHUP[i].first -1==i ||
692 hepeup.MOTHUP[i].second-1==i) {
694 <<
"Particle has itself as a mother in Les Houches "
695 <<
"file, this is not allowed\n"
696 << Exception::eventerror;
702 bool readingWeights =
false, readingaMCFast =
false, readingMG5ClusInfo =
false;
705 if(
m_cfile.find(
"</applgrid")) { readingaMCFast=
false; }
706 if(
m_cfile.find(
"</rwgt")) { readingWeights=
false; }
707 if(
m_cfile.find(
"</clustering")) { readingMG5ClusInfo=
false; }
714 if(!
m_cfile.find(
"<wgt")) {
continue; }
715 istringstream iss(
m_cfile.getline());
716 double weightValue(0);
717 std::string hs=
m_cfile.getline();
718 hs.erase(
std::remove(hs.begin(), hs.end(),
' '), hs.end());
719 std::string IdLabel = hs.substr(0, hs.find(
">", 0));
720 IdLabel = std::regex_replace(IdLabel, std::regex(R
"([\D])"), "");
722 std::string value=std::move(hs);
727 weightValue=std::stod(value);
729 optionalWeights[weightName] = weightValue;
736 std::stringstream amcfstringstream;
737 amcfstringstream <<
"aMCFast " <<
m_cfile.getline();
738 std::string amcfstrings = amcfstringstream.str();
739 string str_newline =
"\n";
741 optionalWeights[amcfstrings.c_str()] = -111;
747 if(readingMG5ClusInfo) {
749 string startDEL =
"<clus scale=";
750 string stopDEL =
"</clus>";
751 unsigned firstLim = hs.find(startDEL);
752 string mg5clusinfo = hs.substr(firstLim);
755 string str_arrow =
">";
757 string str_quotation =
"\"";
759 optionalWeights[mg5clusinfo.c_str()] = -222;
765 string startDEL =
"<scales";
766 string stopDEL =
"</scales>";
767 unsigned firstLim = hs.find(startDEL);
768 string mg5scinfo = hs.substr(firstLim);
771 string str_arrow =
">";
773 optionalWeights[mg5scinfo.c_str()] = -333;
777 if(
m_cfile.find(
"<applgrid")) { readingaMCFast =
true;}
779 if(
m_cfile.find(
"<rwgt")) { readingWeights =
true; }
781 if(
m_cfile.find(
"<clustering")) { readingMG5ClusInfo =
true;}
783 string str_quote =
"'";
784 string str_doublequote =
"\"";
788 string id_1 = it->first;
793 string id_2 = it2->first;
797 string info = it2->second;
798 string str_newline =
"\n";
801 optionalWeights[info] = it->second;
808 string central =
"central";
839 static ClassDocumentation<powhegLesHouchesFileReader>
documentation
840 (
"ThePEG::powhegLesHouchesFileReader is an base class to be used for objects "
841 "which reads event files from matrix element generators. This class is "
842 "able to read plain event files conforming to the Les Houches Event File "
845 static Parameter<powhegLesHouchesFileReader,string> interfaceFileName
847 "The name of a file containing events conforming to the Les Houches "
848 "protocol to be read into ThePEG. A file name ending in "
849 "<code>.gz</code> will be read from a pipe which uses "
850 "<code>zcat</code>. If a file name ends in <code>|</code> the "
851 "preceeding string is interpreted as a command, the output of which "
852 "will be read through a pipe.",
855 interfaceFileName.fileType();
856 interfaceFileName.rank(11);
858 static Switch<powhegLesHouchesFileReader,bool> interfaceQNumbers
860 "Whether or not to read search for and read a QNUMBERS"
861 " block in the header of the file.",
863 static SwitchOption interfaceQNumbersYes
868 static SwitchOption interfaceQNumbersNo
871 "Don't use QNUMBERS",
874 static Switch<powhegLesHouchesFileReader,bool> interfaceIncludeFxFxTags
878 static SwitchOption interfaceIncludeFxFxTagsYes
879 (interfaceIncludeFxFxTags,
883 static SwitchOption interfaceIncludeFxFxTagsNo
884 (interfaceIncludeFxFxTags,
886 "Don't use the FxFx tags",
889 static Switch<powhegLesHouchesFileReader,bool> interfaceIncludeCentral
891 "Include definition of central weight",
893 static SwitchOption interfaceIncludeCentralYes
894 (interfaceIncludeCentral,
896 "include definition of central weight",
898 static SwitchOption interfaceIncludeCentralNo
899 (interfaceIncludeCentral,
901 "Don't include definition of central weight",
906 static Reference<powhegLesHouchesFileReader,Decayer> interfaceDecayer
908 "Decayer to use for any decays read from the QNUMBERS Blocks",