PYTHIA  8.312
LHAPowheg.h
1 // LHAPowheg.h is a part of the PYTHIA event generator.
2 // Copyright (C) 2024 Torbjorn Sjostrand.
3 // PYTHIA is licenced under the GNU GPL v2 or later, see COPYING for details.
4 // Please respect the MCnet Guidelines, see GUIDELINES for details.
5 // Author: Philip Ilten, May 2015.
6 
7 #ifndef Pythia8_LHAPowheg_H
8 #define Pythia8_LHAPowheg_H
9 
10 #include "Pythia8/Plugins.h"
11 #include "Pythia8Plugins/LHAFortran.h"
12 #include <sys/stat.h>
13 #include <unistd.h>
14 
15 namespace Pythia8 {
16 
17 //==========================================================================
18 
19 // Give access to the POWHEG commonblocks and subroutines.
20 
21 extern "C" {
22 
23  // The random number common block.
24  extern struct {
25  int rnd_numseeds, rnd_initialseed, rnd_iwhichseed;
26  char rnd_cwhichseed[4];
27  int rnd_i1, rnd_i2;
28  } pwhg_rnd_;
29 
30  // The RANMAR (R48 modification) common block.
31  extern struct {
32  double u[97];
33  double c;
34  int i97, j97;
35  } r48st1_;
36 
37  // Initialize Powheg.
38  void pwhginit_();
39 
40  // Reset the counters.
41  void resetcnt_(const char *string, int length);
42 
43  // Generate an event.
44  void pwhgevent_();
45 
46  // Access Powheg input data.
47  double powheginput_(const char *string, int length);
48 
49 }
50 
51 //==========================================================================
52 
53 // A plugin class to generate events with hard processes from
54 // POWHEGBOX matrix elements. See http://powhegbox.mib.infn.it/ for
55 // further details on POWHEGBOX.
56 
57 // WARNING: If one wishes to use LHAPDF with both POWHEGBOX and
58 // Pythia, only LHAPDF 6 should be used. If not, and differing PDF
59 // sets are used between POWHEGBOX and Pythia, POWHEGBOX will not
60 // re-initialize the PDF set and consequently will use the PDF set
61 // last used by Pythia.
62 
63 class LHAupPowheg : public LHAupFortran {
64 
65 public:
66 
67  // Constructor.
68  LHAupPowheg(Pythia* pythiaPtr, Settings* settingsPtr, Logger* loggerPtr);
69 
70  // Call pwhginit and fill the HEPRUP commonblock.
71  bool fillHepRup();
72 
73  // Call pwhgevent and fill the HEEUP commonblock.
74  bool fillHepEup();
75 
76 private:
77 
78  // Read a POWHEG settings string.
79  bool readString(string line);
80 
81  // Read a POWHEG settings file.
82  bool readFile(string name);
83 
84  // Write out the input for POWHEG.
85  bool init();
86 
87  // The external random number generator.
88  Rndm* rndmPtr{};
89 
90  // Logger.
91  Logger* loggerPtr{};
92 
93  // The POWHEG run directory and PDF file (if not LHAPDF).
94  string dir, pdf;
95 
96  // The map of POWHEG settings.
97  map<string, string> settings;
98 
99  // The current working directory.
100  char cwd[FILENAME_MAX];
101 
102 };
103 
104 //--------------------------------------------------------------------------
105 
106 // Constructor.
107 
108 LHAupPowheg::LHAupPowheg(Pythia *pythiaPtr, Settings *settingsPtr,
109  Logger* loggerPtrIn) : loggerPtr(loggerPtrIn), dir("powhegrun"), pdf("") {
110 
111  // Load the settings.
112  if (settingsPtr != nullptr) {
113  dir = settingsPtr->word("POWHEG:dir");
114  pdf = settingsPtr->word("POWHEG:pdf");
115 
116  // Read the command files and strings.
117  for (string cmndFile : settingsPtr->wvec("POWHEG:cmndFiles"))
118  readFile(cmndFile);
119  for (string cmnd : settingsPtr->wvec("POWHEG:cmnds"))
120  readString(cmnd);
121  }
122 
123  // Set up the random number generator.
124  if (pythiaPtr != nullptr) {
125  if (settingsPtr->isFlag("POWHEG:pythiaRandom")) rndmPtr = &pythiaPtr->rndm;
126  }
127  mkdir(dir.c_str(), 0777);
128  init();
129 
130 }
131 
132 //--------------------------------------------------------------------------
133 
134 // Call pwhginit and fill the HEPRUP commonblock.
135 
137 
138  // Set multiple random seeds to none.
139  getcwd(cwd, sizeof(cwd));
140  chdir(dir.c_str());
141  strcpy(pwhg_rnd_.rnd_cwhichseed, "none");
142 
143  // Initialize Powheg.
144  pwhginit_();
145 
146  // Reset all the counters.
147  resetcnt_("upper bound failure in inclusive cross section", 46);
148  resetcnt_("vetoed calls in inclusive cross section", 39);
149  resetcnt_("upper bound failures in generation of radiation", 47);
150  resetcnt_("vetoed radiation", 16);
151  chdir(cwd);
152  return fillHepEup();
153 
154 }
155 
156 //--------------------------------------------------------------------------
157 
158 // Set the random numbers, call pwhgevent, and fill the HEPEUP commonblock.
159 
161 
162  // Change directory.
163  getcwd(cwd, sizeof(cwd));
164  chdir(dir.c_str());
165 
166  // Reset the random block if requested.
167  if (rndmPtr != nullptr) {
168  r48st1_.i97 = 97;
169  r48st1_.j97 = 33;
170  r48st1_.c = rndmPtr->flat();
171  for (int i = 0; i < 97; ++i) r48st1_.u[i] = rndmPtr->flat();
172  }
173 
174  // Generate the event.
175  pwhgevent_();
176  chdir(cwd);
177  return true;
178 
179 }
180 
181 //--------------------------------------------------------------------------
182 
183 // Read a POWHEG settings string. If a setting is repeated a warning
184 // is printed but the most recent setting is used.
185 
186 bool LHAupPowheg::readString(string line) {
187 
188  // Copy string without initial and trailing blanks.
189  if (line.find_first_not_of(" \n\t\v\b\r\f\a") == string::npos) return true;
190  int firstChar = line.find_first_not_of(" \n\t\v\b\r\f\a");
191  int lastChar = line.find_last_not_of(" \n\t\v\b\r\f\a");
192  line = line.substr(firstChar, lastChar + 1 - firstChar);
193 
194  // Find the key.
195  firstChar = line.find_first_of(" \t\f\v\n\r");
196  string key = toLower( line.substr(0, firstChar), false);
197 
198  // Add the setting.
199  if (key.size() > 0
200  && key.find_first_of("abcdedfghijklmnopqrtsuvwxyz") == 0) {
201  map<string, string>::iterator setting = settings.find(key);
202  if (setting != settings.end()) {
203  if (loggerPtr) loggerPtr->WARNING_MSG(
204  "replacing previous POWHEG setting for " + key);
205  setting->second = line;
206  } else settings[key] = line;
207  }
208  return true;
209 
210 }
211 
212 //--------------------------------------------------------------------------
213 
214 // Read a POWHEG settings file.
215 
216 bool LHAupPowheg::readFile(string name) {
217 
218  fstream config(name.c_str(), ios::in); string line;
219  while (getline(config, line, '\n')) readString(line);
220  config.close();
221  return true;
222 
223 }
224 
225 //--------------------------------------------------------------------------
226 
227 // Write the input for POWHEG.
228 
229 bool LHAupPowheg::init() {
230 
231  // Copy over the PDF file if needed.
232  if (pdf != "") {
233  fstream pdfin(pdf.c_str(), ios::in | ios::binary);
234  fstream pdfout((dir + "/" + pdf.substr(0, pdf.find_last_of("/"))).c_str(),
235  ios::out | ios::binary);
236  pdfout << pdfin.rdbuf();
237  pdfin.close();
238  pdfout.close();
239  }
240 
241  // Copy the settings to the configuration file.
242  fstream config((dir + "/" + "powheg.input").c_str(), ios::out);
243  for (map<string, string>::iterator setting = settings.begin();
244  setting != settings.end(); ++setting) config << setting->second << "\n";
245  config.close();
246  return true;
247 
248 }
249 
250 //--------------------------------------------------------------------------
251 
252 // Register POWHEG settings.
253 
254 void powhegSettings(Settings *settingsPtr) {
255  settingsPtr->addWord("POWHEG:dir", "powhegrun");
256  settingsPtr->addWord("POWHEG:pdf", "");
257  settingsPtr->addWVec("POWHEG:cmnds", {});
258  settingsPtr->addWVec("POWHEG:cmndFiles", {});
259  settingsPtr->addFlag("POWHEG:pythiaRandom", true);
260 }
261 
262 //--------------------------------------------------------------------------
263 
264 // Declare the plugin.
265 
266 PYTHIA8_PLUGIN_CLASS(LHAup, LHAupPowheg, true, true, true)
267 PYTHIA8_PLUGIN_SETTINGS(powhegSettings)
268 PYTHIA8_PLUGIN_VERSIONS(PYTHIA_VERSION_INTEGER)
269 
270 //==========================================================================
271 
272 } // end namespace Pythia8
273 
274 #endif // Pythia8_LHAPowheg_H
Rndm rndm
Random number generator.
Definition: Pythia.h:338
bool fillHepEup()
Call pwhgevent and fill the HEEUP commonblock.
Definition: LHAPowheg.h:160
Definition: LHAFortran.h:51
void powhegSettings(Settings *settingsPtr)
Register POWHEG settings.
Definition: LHAPowheg.h:254
struct Pythia8::@2 pwhg_rnd_
Give access to the POWHEG commonblocks and subroutines.
string toLower(const string &name, bool trim=true)
Definition: PythiaStdlib.cc:17
bool isFlag(string keyIn)
Query existence of an entry.
Definition: Settings.h:249
Definition: Logger.h:23
void resetcnt_(const char *string, int length)
Reset the counters.
double powheginput_(const char *string, int length)
Access Powheg input data.
void pwhgevent_()
Generate an event.
Definition: LesHouches.h:78
Definition: Basics.h:386
Definition: LHAPowheg.h:63
void pwhginit_()
Initialize Powheg.
LHAupPowheg(Pythia *pythiaPtr, Settings *settingsPtr, Logger *loggerPtr)
Constructor.
Definition: LHAPowheg.h:108
struct Pythia8::@3 r48st1_
The RANMAR (R48 modification) common block.
Header for classes to set beam momentum and interaction vertex spread.
Definition: Analysis.h:20
The Pythia class contains the top-level routines to generate an event.
Definition: Pythia.h:71
double flat()
Generate next random number uniformly between 0 and 1.
Definition: Basics.cc:189
bool fillHepRup()
Call pwhginit and fill the HEPRUP commonblock.
Definition: LHAPowheg.h:136
Definition: Settings.h:195
void addFlag(string keyIn, bool defaultIn)
Add new entry.
Definition: Settings.h:267