12 #pragma GCC diagnostic ignored "-Wuse-after-free"
16 #include "ThePEG/Interface/ClassDocumentation.h"
17 #include "ThePEG/Interface/Reference.h"
18 #include "ThePEG/Interface/Switch.h"
19 #include "ThePEG/Interface/Parameter.h"
20 #include "ThePEG/Utilities/Throw.h"
21 #include "ThePEG/PDT/DecayMode.h"
22 #include "ThePEG/Persistency/PersistentOStream.h"
23 #include "ThePEG/Persistency/PersistentIStream.h"
24 #include "ThePEG/LesHouches/LesHouchesReader.fh"
25 #include "ThePEG/LesHouches/LesHouchesFileReader.h"
26 #include "ThePEG/LesHouches/LesHouchesFileReader.fh"
44 : LesHouchesReader(
x), m_neve(
x.m_neve), m_ieve(0),
45 m_LHFVersion(
x.m_LHFVersion), m_outsideBlock(
x.m_outsideBlock),
46 m_headerBlock(
x.m_headerBlock), m_initComments(
x.m_initComments),
47 m_initAttributes(
x.m_initAttributes), m_eventComments(
x.m_eventComments),
48 m_eventAttributes(
x.m_eventAttributes),
49 m_theFileName(
x.m_theFileName), m_theQNumbers(
x.m_theQNumbers),
50 m_theIncludeFxFxTags(
x.m_theIncludeFxFxTags),
51 m_theIncludeCentral(
x.m_theIncludeCentral),
52 m_theDecayer(
x.m_theDecayer) {}
57 return new_ptr(*
this);
61 return new_ptr(*
this);
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) {
96 if(
split[0].
find(
"block qnumbers")==string::npos)
100 if(
split.size()>=2) {
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);
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);
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) {
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.find(
"</slha") == 0 ) {
245 if(
line.find(
"block mass")!=string::npos) {
247 line = StringUtils::car(block,
"\r\n");
249 while(
line[0] !=
'D' &&
line[0] !=
'B' &&
254 block = StringUtils::cdr(block,
"\r\n");
255 line = StringUtils::car(block,
"\r\n");
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,
284 block = StringUtils::cdr(block,
"\r\n");
285 line = StringUtils::car(block,
"\r\n");
289 else if(
line.find(
"decay") == 0) {
291 istringstream iss(
line);
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;
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);
329 inpart->widthCut(5.*
width);
330 inpart->stable(
false);
334 unsigned int nmode(0);
336 line = StringUtils::car(block,
"\r\n");
337 while(
line[0] !=
'D' &&
line[0] !=
'B' &&
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;
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,
";");
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;
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;
472 Throw<powhegLesHouchesFileError>()
473 <<
"The file associated with '" <<
name() <<
"' does not contain a "
474 <<
"proper formatted Les Houches event file. The events may not be "
475 <<
"properly sampled." << Exception::warning;
482 throw powhegLesHouchesFileError()
483 <<
"No Les Houches file name. "
484 <<
"Use 'set " <<
name() <<
":FileName'."
485 << Exception::runerror;
488 throw powhegLesHouchesFileError()
489 <<
"The powhegLesHouchesFileReader '" <<
name() <<
"' could not open the "
491 << Exception::runerror;
495 if ( !
m_cfile.find(
"<LesHouchesEvents") )
return;
497 StringUtils::xmlAttributes(
"LesHouchesEvents",
m_cfile.getline());
501 bool readingHeader =
false;
502 bool readingInit =
false;
507 bool readingInitWeights =
false, readingInitWeights_sc =
false;
511 if(
m_cfile.find(
"<initrwgt")) readingInitWeights =
true;
514 if(
m_cfile.find(
"</initrwgt")) {
515 readingInitWeights =
false;
516 readingInitWeights_sc =
false;
530 if(readingInitWeights) {
531 string scalename =
"";
532 if(
m_cfile.find(
"<weightgroup")) {
537 readingInitWeights_sc =
true;
538 weightinfo =
m_cfile.getline();
541 string str_weightgroup =
"<weightgroup";
542 string str_arrow =
">";
543 string str_newline =
"\n";
553 if(readingInitWeights_sc && !
m_cfile.find(
"</weightgroup")) {
556 std::string IdLabel =
hs.substr(0,
hs.find(
">", 0));
557 IdLabel = std::regex_replace(IdLabel,
std::regex(R
"([\D])"), "");
562 optionalWeightsNames.push_back(
name);
567 if (
m_cfile.find(
"<header") ) {
570 readingHeader =
true;
590 for (
int i = 0;
i <
heprup.NPRUP; ++
i ) {
600 if (
m_cfile.find(
"</header") ) {
601 readingHeader =
false;
604 if ( readingHeader ) {
614 string central =
"central";
615 optionalWeightsNames.push_back(central);
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;
676 if ( !
m_cfile.readline() )
return false;
689 <<
"nan's as momenta in Les Houches file "
690 << Exception::eventerror;
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);
719 std::string IdLabel =
hs.substr(0,
hs.find(
">", 0));
720 IdLabel = std::regex_replace(IdLabel,
std::regex(R
"([\D])"), "");
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";
833 const ClassDescription<powhegLesHouchesFileReader>
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",
915 while((
pos = subject.find(
search,
pos)) != std::string::npos) {