ATLAS Offline Software
Loading...
Searching...
No Matches
PowhegLesHouchesFileReader.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
4// -*- C++ -*-
5//
6// powhegLesHouchesFileReader.cc - (c) Silvia Ferrario Ravasio and Tomas Jezo
7// inspired by LesHouchesFileReader.cc which is a part of ThePEG
8//
9
10#if __GNUC__ >= 12
11// Suppress a gcc12 false positive
12#pragma GCC diagnostic ignored "-Wuse-after-free"
13#endif
14
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"
27
28#include <sstream>
29#include <iostream>
30#include <string>
31#include <regex>
32#include <iterator>
33
34using namespace ThePEG;
35using namespace std;
36
40double upbfact[2] = {1., 1.}; /*Corrective factors in case upper bound violations are computed, they depend on radtype */
41
53
55
57 return new_ptr(*this);
58}
59
61 return new_ptr(*this);
62}
63
65 return true;
66}
67
69 LesHouchesReader::doinit();
70
71 // are we using QNUMBERS
72 if(!m_theQNumbers) return;
73 // parse the header block and create
74 // any new particles needed in QNUMBERS blocks
75 string block = m_headerBlock;
76 string line = "";
77 bool readingSLHA = false;
78 int (*pf)(int) = tolower;
79 unsigned int newNumber(0);
80 do {
81 line = StringUtils::car(block,"\r\n");
82 block = StringUtils::cdr(block,"\r\n");
83 if(line[0]=='#') continue;
84 // are we reading the SLHA block
85 if(readingSLHA) {
86 // reached the end of slha block
87 if(line.find("</slha") != string::npos) {
88 readingSLHA = false;
89 break;
90 }
91 // remove trailing comment from line
92 vector<string> split = StringUtils::split(line,"#");
93 // check for a qnumbers block
94 transform(split[0].begin(), split[0].end(), split[0].begin(), pf);
95 // if not contine
96 if(split[0].find("block qnumbers")==string::npos)
97 continue;
98 // get name from comment
99 string name;
100 if(split.size()>=2) {
101 name = StringUtils::stripws(split[1]);
102 }
103 else {
104 ++newNumber;
105 ostringstream tname;
106 tname << "NP" << newNumber;
107 name = tname.str();
108 }
109 // extract the PDG code
110 split = StringUtils::split(split[0]," ");
111 istringstream is(split[2]);
112 long PDGCode(0);
113 is >> PDGCode;
114 // get the charge, spin, colour and whether an antiparticle
115 int charge(0),spin(0),colour(0),anti(0);
116 for(unsigned int ix=0;ix<4;++ix) {
117 line = StringUtils::car(block,"\r\n");
118 block = StringUtils::cdr(block,"\r\n");
119 int dummy[2];
120 istringstream is(line);
121 is >> dummy[0] >> dummy[1];
122 switch (dummy[0]) {
123 case 1:
124 charge = dummy[1];
125 break;
126 case 2:
127 spin = dummy[1];
128 break;
129 case 3:
130 colour = dummy[1];
131 break;
132 case 4:
133 anti = dummy[1];
134 break;
135 default:
136 assert(false);
137 }
138 }
139 // check if particles already exist
140 PDPair newParticle;
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;
147 if(anti) {
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;
162 }
163 // already exists continue
164 if(newParticle.first) continue;
165 // create the particles
166 // particle with no anti particle
167 if( anti == 0 ) {
168 // construct the name
169 if(name=="") {
170 ostringstream temp;
171 temp << PDGCode;
172 name = temp.str();
173 }
174 // create the ParticleData object
175 newParticle.first = ParticleData::Create(PDGCode,name);
176 }
177 // particle anti-particle pair
178 else {
179 // construct the names
180 string nameAnti;
181 if(name=="") {
182 ostringstream temp;
183 temp << PDGCode;
184 name = temp.str();
185 ostringstream temp2;
186 temp << -PDGCode;
187 nameAnti = temp2.str();
188 }
189 else {
190 nameAnti=name;
191 auto swapSign=[](char & t){
192 if (t=='-') t= '+';
193 else if (t=='+') t= '-';
194 };
195 std::for_each(nameAnti.begin(),nameAnti.end(), swapSign);
196 if(nameAnti==name) nameAnti += "bar";
197 }
198 // create the ParticleData objects
199 newParticle = ParticleData::Create(PDGCode,name,nameAnti);
200 }
201 // set the particle properties
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));
206 // register it
207 generator()->preinitRegister(newParticle.first,
208 "/Herwig/Particles/"+newParticle.first->PDGName());
209 // set the antiparticle properties
210 if(newParticle.second) {
211 if(colour==3||colour==6) colour *= -1;
212 charge = -charge;
213 newParticle.second->iColour(PDT::Colour(colour));
214 newParticle.second->iSpin (PDT::Spin (spin ));
215 newParticle.second->iCharge(PDT::Charge(charge));
216 // register it
217 generator()->preinitRegister(newParticle.second,
218 "/Herwig/Particles/"+newParticle.second->PDGName());
219 }
220 }
221 // start of SLHA block ?
222 else if(line.find("<slha") != string::npos) {
223 readingSLHA = true;
224 }
225 }
226 while(line!="");
227 // now set any masses/decay modes
228 block = m_headerBlock;
229 line="";
230 readingSLHA=false;
231 bool ok=true;
232 do {
233 line = StringUtils::car(block,"\r\n");
234 block = StringUtils::cdr(block,"\r\n");
235 // are we reading the SLHA block
236 if(readingSLHA) {
237 // reached the end?
238 if(line.starts_with("</slha")) {
239 readingSLHA = false;
240 break;
241 }
242 // make lower case
243 transform(line.begin(),line.end(),line.begin(), pf);
244 // found the mass block ?
245 if(line.find("block mass")!=string::npos) {
246 // read it
247 line = StringUtils::car(block,"\r\n");
248 // check not at end
249 while(line[0] != 'D' && line[0] != 'B' &&
250 line[0] != 'd' && line[0] != 'b' &&
251 line != "") {
252 // skip comment lines
253 if(line[0] == '#') {
254 block = StringUtils::cdr(block,"\r\n");
255 line = StringUtils::car(block,"\r\n");
256 continue;
257 }
258 // get the mass and PGD code
259 istringstream temp(line);
260 long id;
261 double mass;
262 temp >> id >> mass;
263 // skip resetting masses on SM particles
264 // as it can cause problems later on in event generation
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");
269 continue;
270 }
271 // magnitude of mass for susy models
272 mass = abs(mass);
273 // set the mass
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,
279 "NominalMass");
280 ostringstream os;
281 os << mass;
282 ifb->exec(*particle, "set", os.str());
283 // read the next line
284 block = StringUtils::cdr(block,"\r\n");
285 line = StringUtils::car(block,"\r\n");
286 };
287 }
288 // found a decay block
289 else if(line.starts_with("decay")) {
290 // get PGD code and width
291 istringstream iss(line);
292 string dummy;
293 long parent(0);
294 Energy width(ZERO);
295 iss >> dummy >> parent >> iunit(width, GeV);
296 // get the ParticleData object
297 PDPtr inpart = getParticleData(parent);
298 if(!inpart) {
299 throw SetupException()
300 << "powhegLesHouchesFileReader::doinit() - A ParticleData object with the PDG code "
301 << parent << " does not exist. " << Exception::runerror;
302 return;
303 }
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;
315 }
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;
324 }
325 // set the width
326 inpart->width(width);
327 if( width > ZERO ) {
328 inpart->cTau(hbarc/width);
329 inpart->widthCut(5.*width);
330 inpart->stable(false);
331 }
332 // construct prefix for DecayModes
333 string prefix(inpart->name() + "->"), tag(prefix),line("");
334 unsigned int nmode(0);
335 // read any decay modes
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 != "") {
340 // skip comments
341 if(line[0] == '#') {
342 block = StringUtils::cdr(block,"\r\n");
343 line = StringUtils::car(block,"\r\n");
344 continue;
345 }
346 // read decay mode and construct the tag
347 istringstream is(line);
348 double brat(0.);
349 unsigned int nda(0),npr(0);
350 is >> brat >> nda;
351 while( true ) {
352 long t;
353 is >> t;
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);
363 if( !p )
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;
369 ++npr;
370 tag += p->name() + ",";
371 }
372 if( npr != nda )
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;
380 // create the DecayMode
381 if( npr > 1 ) {
382 if( nmode==0 ) {
383 generator()->preinitInterface(inpart, "VariableRatio" , "set","false");
384 if(inpart->massGenerator()) {
385 ok = false;
386 Throw<SetupException>()
387 << inpart->PDGName() << " already has a MassGenerator set"
388 << " this is incompatible with using QNUMBERS "
389 << "Use\n"
390 << "set " << inpart->fullName() << ":Mass_generator NULL\n"
391 << "to fix this." << Exception::warning;
392 }
393 if(inpart->widthGenerator()) {
394 ok = false;
395 Throw<SetupException>()
396 << inpart->PDGName() << " already has a WidthGenerator set"
397 << " this is incompatible with using QNUMBERS "
398 << "Use\n"
399 << "set " << inpart->fullName() << ":Width_generator NULL\n"
400 << "to fix this." << Exception::warning;
401 }
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;
406 }
407 if(ntemp!=0) {
408 ok = false;
409 Throw<SetupException>()
410 << inpart->PDGName() << " already has DecayModes"
411 << " this is incompatible with using QNUMBERS "
412 << "Use\n"
413 << "do " << inpart->fullName() << ":SelectDecayModes none\n"
414 << " to fix this." << Exception::warning;
415 }
416 }
417 inpart->stable(false);
418 tag.replace(tag.size() - 1, 1, ";");
419 DMPtr dm = generator()->findDecayMode(tag);
420 if(!m_theDecayer) Throw<SetupException>()
421 << "powhegLesHouchesFileReader::doinit() Decayer must be set using the "
422 << "powhegLesHouchesFileReader:Decayer"
423 << " must be set to allow the creation of new"
424 << " decay modes."
425 << Exception::runerror;
426 if(!dm) {
427 dm = generator()->preinitCreateDecayMode(tag);
428 if(!dm)
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;
433 }
434 generator()->preinitInterface(dm, "Decayer", "set",
435 m_theDecayer->fullName());
436 ostringstream br;
437 br << setprecision(13) << brat;
438 generator()->preinitInterface(dm, "BranchingRatio", "set", br.str());
439 generator()->preinitInterface(dm, "Active", "set", "Yes");
440 if(dm->CC()) {
441 generator()->preinitInterface(dm->CC(), "BranchingRatio", "set", br.str());
442 generator()->preinitInterface(dm->CC(), "Active", "set", "Yes");
443 }
444 ++nmode;
445 }
446 tag=prefix;
447 // read the next line
448 block = StringUtils::cdr(block,"\r\n");
449 line = StringUtils::car(block,"\r\n");
450 };
451 if(nmode>0) {
452 inpart->update();
453 if(inpart->CC())
454 inpart->CC()->update();
455 }
456 }
457 }
458 // start of SLHA block ?
459 else if(line.find("<slha") != string::npos) {
460 readingSLHA = true;
461 }
462 }
463 while(line!="");
464 if(!ok)
465 throw SetupException() << "Problem reading QNUMBERS blocks in powhegLesHouchesFileReader::doinit()"
466 << Exception::runerror;
467}
468
469void powhegLesHouchesFileReader::initialize(LesHouchesEventHandler & eh) {
470 LesHouchesReader::initialize(eh);
471 if ( m_LHFVersion.empty() )
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;
476}
477
478vector<string> powhegLesHouchesFileReader::optWeightsNamesFunc() { return optionalWeightsNames; }
479
481 if ( filename().empty() )
482 throw powhegLesHouchesFileError()
483 << "No Les Houches file name. "
484 << "Use 'set " << name() << ":FileName'."
485 << Exception::runerror;
486 m_cfile.open(filename());
487 if ( !m_cfile )
488 throw powhegLesHouchesFileError()
489 << "The powhegLesHouchesFileReader '" << name() << "' could not open the "
490 << "event file called '" << m_theFileName << "'."
491 << Exception::runerror;
492
493
494 m_cfile.readline();
495 if ( !m_cfile.find("<LesHouchesEvents") ) return;
496 map<string,string> attributes =
497 StringUtils::xmlAttributes("LesHouchesEvents", m_cfile.getline());
498 m_LHFVersion = attributes["version"];
499 if ( m_LHFVersion.empty() ) return;
500
501 bool readingHeader = false;
502 bool readingInit = false;
503 m_headerBlock = "";
504 string hs;
505
506 // Loop over all lines until we hit the </init> tag.
507 bool readingInitWeights = false, readingInitWeights_sc = false;
508 string weightinfo;
509 while ( m_cfile.readline() ) {
510 // found the init block for multiple weights
511 if(m_cfile.find("<initrwgt")) readingInitWeights = true;
512
513 // found end of init block for multiple weights: end the while loop
514 if(m_cfile.find("</initrwgt")) {
515 readingInitWeights = false;
516 readingInitWeights_sc = false;
517 continue;
518 }
519
520 // found the end of init block
521 if(m_cfile.find("</init")) {
522 readingInit = false;
523 break;
524 }
525
526 /* read the weight information block
527 * optionalWeightNames will contain information about the weights
528 * this will be appended to the weight information
529 */
530 if(readingInitWeights) {
531 string scalename = "";
532 if(m_cfile.find("<weightgroup")) {
533 /* we found a weight group
534 * start reading the information
535 * within it
536 */
537 readingInitWeights_sc = true;
538 weightinfo = m_cfile.getline();
539 /* to make it shorter, erase some stuff
540 */
541 string str_weightgroup = "<weightgroup";
542 string str_arrow = ">";
543 string str_newline = "\n";
544 erase_substr(weightinfo, str_weightgroup);
545 erase_substr(weightinfo, str_arrow);
546 erase_substr(weightinfo, str_newline);
547 continue;
548 }
549 /* if we are reading a new weightgroup, go on
550 * until we find the end of it
551 */
552 /* BEGIN MOD*/
553 if(readingInitWeights_sc && !m_cfile.find("</weightgroup")) {
554 hs = m_cfile.getline();
555 hs.erase(std::remove(hs.begin(), hs.end(), ' '), hs.end());
556 std::string IdLabel = hs.substr(0, hs.find(">", 0));
557 IdLabel = std::regex_replace(IdLabel, std::regex(R"([\D])"), "");
558 std::string name = hs;
559 erase_substr(name, "<weightid='"+IdLabel+"'>");
560 name.erase(name.find('<'));
561 m_optionalWeightsLabel[IdLabel]=name;
562 optionalWeightsNames.push_back(std::move(name));
563 }
564 /*END MOD*/
565 }
566
567 if ( m_cfile.find("<header") ) {
568 // We have hit the header block, so we should dump this and all
569 // following lines to m_headerBlock until we hit the end of it.
570 readingHeader = true;
571 m_headerBlock = m_cfile.getline() + "\n";
572 }
573 if ( (m_cfile.find("<init ") && !m_cfile.find("<initrwgt")) || m_cfile.find("<init>") ) {
574 // We have hit the init block, so we should expect to find the
575 // standard information in the following. But first check for
576 // attributes.
577 m_initAttributes = StringUtils::xmlAttributes("init", m_cfile.getline());
578 readingInit = true;
579 m_cfile.readline();
580 if ( !( m_cfile >> heprup.IDBMUP.first >> heprup.IDBMUP.second
581 >> heprup.EBMUP.first >> heprup.EBMUP.second
582 >> heprup.PDFGUP.first >> heprup.PDFGUP.second
583 >> heprup.PDFSUP.first >> heprup.PDFSUP.second
584 >> heprup.IDWTUP >> heprup.NPRUP ) ) {
585 heprup.NPRUP = -42;
586 m_LHFVersion = "";
587 return;
588 }
589 heprup.resize();
590 for ( int i = 0; i < heprup.NPRUP; ++i ) {
591 m_cfile.readline();
592 if ( !( m_cfile >> heprup.XSECUP[i] >> heprup.XERRUP[i]
593 >> heprup.XMAXUP[i] >> heprup.LPRUP[i] ) ) {
594 heprup.NPRUP = -42;
595 m_LHFVersion = "";
596 return;
597 }
598 }
599 }
600 if ( m_cfile.find("</header") ) {
601 readingHeader = false;
602 m_headerBlock += m_cfile.getline() + "\n";
603 }
604 if ( readingHeader ) {
605 /* We are in the process of reading the header block. Dump the
606 line to m_headerBlock.*/
607 m_headerBlock += m_cfile.getline() + "\n";
608 }
609 if ( readingInit ) {
610 // Here we found a comment line. Dump it to m_initComments.
611 m_initComments += m_cfile.getline() + "\n";
612 }
613 }
614
615 optionalWeightsNames.emplace_back("central");
616
617 if ( !m_cfile ) {
618 heprup.NPRUP = -42;
619 m_LHFVersion = "";
620 return;
621 }
622}
623
625 if ( !m_cfile ) return false;
626 if ( m_LHFVersion.empty() ) return false;
627 if ( heprup.NPRUP < 0 ) return false;
628 m_eventComments = "";
629 m_outsideBlock = "";
630 hepeup.NUP = 0;
631 hepeup.XPDWUP.first = hepeup.XPDWUP.second = 0.0;
632 optionalWeights.clear();
633 m_optionalWeightsTemp.clear();
634 // Keep reading lines until we hit the next event or the end of
635 // the event block. Save any inbetween lines. Exit if we didn't
636 // find an event.
637 while ( m_cfile.readline() && !m_cfile.find("<event") )
638 m_outsideBlock += m_cfile.getline() + "\n";
639
640 // We found an event. First scan for attributes.
641 m_eventAttributes = StringUtils::xmlAttributes("event", m_cfile.getline());
642
643 /* information necessary for FxFx merging:
644 * the npLO and npNLO tags
645 */
646 istringstream ievat(m_cfile.getline());
647 int we(0), npLO(-99), npNLO(-99);
648 do {
649 string sub; ievat >> sub;
650 if(we==2) { npLO = atoi(sub.c_str()); }
651 if(we==5) { npNLO = atoi(sub.c_str()); }
652 ++we;
653 } while (ievat);
654 optionalnpLO = npLO;
655 optionalnpNLO = npNLO;
656 std::stringstream npstringstream;
657 npstringstream << "np " << npLO << " " << npNLO;
658 std::string npstrings = npstringstream.str();
659 /* the FxFx merging information
660 * becomes part of the optionalWeights, labelled -999
661 * for future reference
662 */
663
664 if(m_theIncludeFxFxTags) optionalWeights[npstrings.c_str()] = -999;
665
666 if ( !m_cfile.readline() ) return false;
667
668 // The first line determines how many subsequent particle lines we
669 // have.
670 if ( !( m_cfile >> hepeup.NUP >> hepeup.IDPRUP >> hepeup.XWGTUP
671 >> hepeup.SCALUP >> hepeup.AQEDUP >> hepeup.AQCDUP ) )
672 return false;
673 hepeup.resize();
674 // Read all particle lines.
675 for ( int i = 0; i < hepeup.NUP; ++i ) {
676 if ( !m_cfile.readline() ) return false;
677 if ( !( m_cfile >> hepeup.IDUP[i] >> hepeup.ISTUP[i]
678 >> hepeup.MOTHUP[i].first >> hepeup.MOTHUP[i].second
679 >> hepeup.ICOLUP[i].first >> hepeup.ICOLUP[i].second
680 >> hepeup.PUP[i][0] >> hepeup.PUP[i][1] >> hepeup.PUP[i][2]
681 >> hepeup.PUP[i][3] >> hepeup.PUP[i][4]
682 >> hepeup.VTIMUP[i] >> hepeup.SPINUP[i] ) )
683 return false;
684 //print momenta for debugging
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]))
688 throw Exception()
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) {
693 throw Exception()
694 << "Particle has itself as a mother in Les Houches "
695 << "file, this is not allowed\n"
696 << Exception::eventerror;
697 }
698 }
699
700 // Now read any additional comments and named weights.
701 // read until the end of rwgt is found
702 bool readingWeights = false, readingaMCFast = false, readingMG5ClusInfo = false;
703 while ( m_cfile.readline() && !m_cfile.find("</event>")) {
704
705 if(m_cfile.find("</applgrid")) { readingaMCFast=false; } //aMCFast weights end
706 if(m_cfile.find("</rwgt")) { readingWeights=false; } //optional weights end
707 if(m_cfile.find("</clustering")) { readingMG5ClusInfo=false; } // mg5 mclustering scale info end
708
709 /* reading of optional weights
710 */
711
712 /* BEGIN MOD*/
713 if(readingWeights) {
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])"), "");
721 std::string weightName = m_optionalWeightsLabel[IdLabel];
722 std::string value=std::move(hs);
723 erase_substr(value, "<wgtid='"+IdLabel+"'>");
724 erase_substr(value, "<wgtid=\""+IdLabel+"\">");
725 erase_substr(value, "</wgt>");
726 erase_substr(value, "\n");
727 weightValue=std::stod(value);
728 m_optionalWeightsTemp[weightName] = weightValue;
729 optionalWeights[weightName] = weightValue;
730 }
731 /* END MOD */
732
733 /* reading of aMCFast weights
734 */
735 if(readingaMCFast) {
736 std::stringstream amcfstringstream;
737 amcfstringstream << "aMCFast " << m_cfile.getline();
738 std::string amcfstrings = amcfstringstream.str();
739 string str_newline = "\n";
740 erase_substr(amcfstrings,str_newline);
741 optionalWeights[amcfstrings.c_str()] = -111; //for the aMCFast we give them a weight -111 for future identification
742 }
743
744 /* read additional MG5 Clustering information
745 * used in LO merging
746 */
747 if(readingMG5ClusInfo) {
748 string hs = m_cfile.getline();
749 string startDEL = "<clus scale="; //starting delimiter
750 string stopDEL = "</clus>"; //end delimiter
751 unsigned firstLim = hs.find(startDEL); //find start of delimiter
752 string mg5clusinfo = hs.substr(firstLim); //define the information for the scale
753 erase_substr(mg5clusinfo,stopDEL);
754 erase_substr(mg5clusinfo,startDEL);
755 string str_arrow = ">";
756 erase_substr(mg5clusinfo,str_arrow);
757 string str_quotation = "\"";
758 erase_substr(mg5clusinfo,str_quotation);
759 optionalWeights[mg5clusinfo.c_str()] = -222; //for the mg5 scale info weights we give them a weight -222 for future identification
760 }
761
762 //store MG5 clustering information
763 if(m_cfile.find("<scales")) {
764 string hs = m_cfile.getline();
765 string startDEL = "<scales"; //starting delimiter
766 string stopDEL = "</scales>"; //end delimiter
767 unsigned firstLim = hs.find(startDEL); //find start of delimiter
768 string mg5scinfo = hs.substr(firstLim); //define the information for the scale
769 erase_substr(mg5scinfo,stopDEL);
770 erase_substr(mg5scinfo,startDEL);
771 string str_arrow = ">";
772 erase_substr(mg5scinfo,str_arrow);
773 optionalWeights[mg5scinfo.c_str()] = -333; //for the mg5 scale info weights we give them a weight -333 for future identification
774 }
775
776 //determine start of aMCFast weights
777 if(m_cfile.find("<applgrid")) { readingaMCFast = true;}
778 //determine start of optional weights
779 if(m_cfile.find("<rwgt")) { readingWeights = true; }
780 //determine start of MG5 clustering scale information
781 if(m_cfile.find("<clustering")) { readingMG5ClusInfo = true;}
782 }
783 string str_quote = "'";
784 string str_doublequote = "\"";
785 // loop over the optional weights and add the extra information as found in the init
787 //to avoid issues with inconsistencies of defining the weight ids, remove "" and ''
788 string id_1 = it->first;
789 erase_substr(id_1, str_quote);
790 erase_substr(id_1, str_doublequote);
791 for (map<string,string>::const_iterator it2=m_scalemap.begin(); it2!=m_scalemap.end(); ++it2){
792 //find the scale id in the scale information and add this information
793 string id_2 = it2->first;
794 erase_substr(id_2, str_quote);
795 erase_substr(id_2, str_doublequote);
796 if(id_1==id_2) {
797 string info = it2->second;
798 string str_newline = "\n";
799 erase_substr(info, str_newline);
800 //set the optional weights
801 optionalWeights[info] = it->second;
802 }
803 }
804 }
805 /* additionally, we set the "central" scale
806 * this is actually the default event weight
807 */
808 string central = "central";
809 if (m_theIncludeCentral) optionalWeights[central] = hepeup.XWGTUP;
810
811 if ( !m_cfile ) return false;
812 return true;
813
814}
815
819
825
832
833const ClassDescription<powhegLesHouchesFileReader>
835// Definition of the static class description member.
836
837void powhegLesHouchesFileReader::Init ATLAS_NOT_THREAD_SAFE () {
838
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 "
843 "accord.");
844
845 static Parameter<powhegLesHouchesFileReader,string> interfaceFileName
846 ("FileName",
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.",
854
855 interfaceFileName.fileType();
856 interfaceFileName.rank(11);
857
858 static Switch<powhegLesHouchesFileReader,bool> interfaceQNumbers
859 ("QNumbers",
860 "Whether or not to read search for and read a QNUMBERS"
861 " block in the header of the file.",
862 &powhegLesHouchesFileReader::m_theQNumbers, false, false, false);
863 static SwitchOption interfaceQNumbersYes
864 (interfaceQNumbers,
865 "Yes",
866 "Use QNUMBERS",
867 true);
868 static SwitchOption interfaceQNumbersNo
869 (interfaceQNumbers,
870 "No",
871 "Don't use QNUMBERS",
872 false);
873
874 static Switch<powhegLesHouchesFileReader,bool> interfaceIncludeFxFxTags
875 ("IncludeFxFxTags",
876 "Include FxFx tags",
878 static SwitchOption interfaceIncludeFxFxTagsYes
879 (interfaceIncludeFxFxTags,
880 "Yes",
881 "Use the FxFx tags",
882 true);
883 static SwitchOption interfaceIncludeFxFxTagsNo
884 (interfaceIncludeFxFxTags,
885 "No",
886 "Don't use the FxFx tags",
887 false);
888
889 static Switch<powhegLesHouchesFileReader,bool> interfaceIncludeCentral
890 ("IncludeCentral",
891 "Include definition of central weight",
893 static SwitchOption interfaceIncludeCentralYes
894 (interfaceIncludeCentral,
895 "Yes",
896 "include definition of central weight",
897 true);
898 static SwitchOption interfaceIncludeCentralNo
899 (interfaceIncludeCentral,
900 "No",
901 "Don't include definition of central weight",
902 false);
903
904
905
906 static Reference<powhegLesHouchesFileReader,Decayer> interfaceDecayer
907 ("Decayer",
908 "Decayer to use for any decays read from the QNUMBERS Blocks",
909 &powhegLesHouchesFileReader::m_theDecayer, false, false, true, true, false);
910
911}
912
913void powhegLesHouchesFileReader::erase_substr(std::string& subject, const std::string& search) {
914 size_t pos = 0;
915 while((pos = subject.find(search, pos)) != std::string::npos) {
916 subject.erase( pos, search.length() );
917 }
918}
919
void tolower(std::string &s)
double spin(const T &p)
Definition AtlasPID.h:1147
double charge(const T &p)
Definition AtlasPID.h:997
std::vector< double > Energy
double upbfact[2]
const double width
This is the draft of TileDetDescr documentation
#define x
static const Attributes_t empty
#define ATLAS_NOT_THREAD_SAFE
getNoisyStrip() Find noisy strips from hitmaps and write out into xml/db formats
map< string, string > m_eventAttributes
If LHF.
virtual bool preInitialize() const
Return true if this object needs to be initialized before all other objects because it needs to extra...
static const ClassDescription< powhegLesHouchesFileReader > m_initpowhegLesHouchesFileReader
Describe an abstract base class with persistent data.
void persistentInput(PersistentIStream &is, int version)
Function used to read in object persistently.
virtual vector< string > optWeightsNamesFunc()
Return the optional weights information string ("Names")
virtual void initialize(LesHouchesEventHandler &eh)
Initialize.
map< string, string > m_initAttributes
If LHF.
string filename() const
Return the name of the file from where to read events.
virtual void doinit()
Initialize this object after the setup phase before saving an EventGenerator to disk.
bool m_theIncludeFxFxTags
Include/Read FxFx tags.
virtual IBPtr clone() const
Make a simple clone of this object.
virtual IBPtr fullclone() const
Make a clone of this object, possibly modifying the cloned object to make it sane.
CFileLineReader m_cfile
The wrapper around the C FILE stream from which to read.
map< string, double > m_optionalWeightsTemp
Temporary holder for optional weights.
bool m_theQNumbers
Whether or not to search for QNUMBERS stuff.
bool m_theIncludeCentral
Include central weight (for backup use)
void erase_substr(std::string &subject, const std::string &search)
Erases all occurences of a substring from a string.
void persistentOutput(PersistentOStream &os) const
Function used to write out object persistently.
long m_neve
The number of events in this file.
string m_theFileName
The name of the file from where to read events.
virtual void close()
Close the file from which events have been read.
string m_LHFVersion
If the file is a standard Les Houches formatted file (LHF) this is its version number.
DecayerPtr m_theDecayer
Decayer for any decay modes read from the file.
virtual void open()
Open a file with events.
map< string, string > m_scalemap
Further information on the weights.
virtual bool doReadEvent()
Read the next event from the file or stream into the corresponding protected variables.
STL iterator class.
void search(TDirectory *td, const std::string &s, std::string cwd, node *n)
recursive directory search for TH1 and TH2 and TProfiles
Definition hcg.cxx:739
std::string find(const std::string &s)
return a remapped string
Definition hcg.cxx:138
std::vector< std::string > split(const std::string &s, const std::string &t=":")
Definition hcg.cxx:177
STL namespace.
DataModel_detail::iterator< DVL > remove(typename DataModel_detail::iterator< DVL > beg, typename DataModel_detail::iterator< DVL > end, const T &value)
Specialization of remove for DataVector/List.