StRoot  1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
Info.cc
1 // Info.cc is a part of the PYTHIA event generator.
2 // Copyright (C) 2020 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 
6 // Function definitions (not found in the header) for the Info class.
7 
8 #include "Pythia8/Info.h"
9 #include <limits>
10 
11 namespace Pythia8 {
12 
13 //==========================================================================
14 
15 // Info class.
16 // This class contains a mixed bag of information on the event generation
17 // activity, especially on the current subprocess properties.
18 
19 //--------------------------------------------------------------------------
20 
21 // Constants: could be changed here if desired, but normally should not.
22 // These are of technical nature, as described for each.
23 
24 // Number of times the same error message will be repeated at most.
25 const int Info::TIMESTOPRINT = 1;
26 
27 // LHA convention with cross section in pb may require conversion from mb.
28 const double Info::CONVERTMB2PB = 1e9;
29 
30 //--------------------------------------------------------------------------
31 
32 // List (almost) all information currently set.
33 
34 void Info::list() const {
35 
36  // Header and beam info.
37  cout << "\n -------- PYTHIA Info Listing ------------------------"
38  << "---------------- \n \n"
39  << scientific << setprecision(3)
40  << " Beam A: id = " << setw(6) << idASave << ", pz = " << setw(10)
41  << pzASave << ", e = " << setw(10) << eASave << ", m = " << setw(10)
42  << mASave << ".\n"
43  << " Beam B: id = " << setw(6) << idBSave << ", pz = " << setw(10)
44  << pzBSave << ", e = " << setw(10) << eBSave << ", m = " << setw(10)
45  << mBSave << ".\n\n";
46 
47  // Done if no subprocess has been defined.
48  if (codeSave == 0 && nFinalSave == 0) {
49  cout << " No process has been set; something must have gone wrong! \n"
50  << "\n -------- End PYTHIA Info Listing --------------------"
51  << "----------------" << endl;
52  return;
53  }
54 
55  // Colliding parton info.
56  if (isRes) {
57  cout << " In 1: id = " << setw(4) << id1pdfSave[0] << ", x = "
58  << setw(10) << x1pdfSave[0] << ", pdf = " << setw(10) << pdf1Save[0]
59  << " at Q2 = " << setw(10) << Q2FacSave[0] << ".\n"
60  << " In 2: id = " << setw(4) << id2pdfSave[0] << ", x = "
61  << setw(10) << x2pdfSave[0] << ", pdf = " << setw(10) << pdf2Save[0]
62  << " at same Q2.\n";
63  bool matchIdX = true;
64  if (id1pdfSave[0] != id1Save[0] || id2pdfSave[0] != id2Save[0])
65  matchIdX = false;
66  if (abs(x1pdfSave[0] - x1Save[0]) > 1e-4 * x1Save[0]) matchIdX = false;
67  if (abs(x2pdfSave[0] - x2Save[0]) > 1e-4 * x2Save[0]) matchIdX = false;
68  if (!matchIdX) cout << " Warning: above flavour/x info does not match"
69  << " incoming partons in event!\n";
70  cout << "\n";
71  }
72 
73  // Process name and code.
74  cout << ((isRes && !hasSubSave[0]) ? " Subprocess " : " Process ")
75  << nameSave << " with code " << codeSave << " is 2 -> "
76  << nFinalSave << ".\n";
77 
78  // Subprocess name and code for nondiffractive processes.
79  if (hasSubSave[0])
80  cout << " Subprocess " << nameSubSave[0] << " with code " << codeSubSave[0]
81  << " is 2 -> " << nFinalSubSave[0] << ".\n";
82 
83  // Process-type-specific kinematics information.
84  if ( isRes && nFinalSave == 1)
85  cout << " It has sHat = " << setw(10) << sH[0] << ".\n";
86  else if ( isRes && nFinalSave == 2)
87  cout << " It has sHat = " << setw(10) << sH[0] << ", tHat = "
88  << setw(10) << tH[0] << ", uHat = " << setw(10) << uH[0] << ",\n"
89  << " pTHat = " << setw(10) << pTH[0] << ", m3Hat = "
90  << setw(10) << m3H[0] << ", m4Hat = " << setw(10) << m4H[0] << ",\n"
91  << " thetaHat = " << setw(10) << thetaH[0] << ", phiHat = "
92  << setw(10) << phiH[0] << ".\n";
93  else if ( nFinalSave == 2)
94  cout << " It has s = " << setw(10) << sH[0] << ", t = " << setw(10)
95  << tH[0] << ", u = " << setw(10) << uH[0] << ",\n"
96  << " pT = " << setw(10) << pTH[0] << ", m3 = " << setw(10)
97  << m3H[0] << ", m4 = " << setw(10) << m4H[0] << ",\n"
98  << " theta = " << setw(10) << thetaH[0] << ", phi = " << setw(10)
99  << phiH[0] << ".\n";
100  else if ( isRes && nFinalSave == 3)
101  cout << " It has sHat = " << setw(10) << sH[0] << ", <pTHat> = "
102  << setw(10) << pTH[0] << ".\n";
103  else if ( nFinalSave == 3)
104  cout << " It has s = " << setw(10) << sH[0] << ", t_A = " << setw(10)
105  << tH[0] << ", t_B = " << setw(10) << uH[0] << ",\n"
106  << " <pT> = " << setw(10) << pTH[0] << ".\n";
107 
108  // Couplings.
109  if (isRes) cout << " alphaEM = " << setw(10) << alphaEMSave[0]
110  << ", alphaS = " << setw(10) << alphaSSave[0] << " at Q2 = "
111  << setw(10) << Q2RenSave[0] << ".\n";
112 
113  // Diffractive subsystems.
114  for (int iDS = 1; iDS < 4; ++iDS) if (id1Save[iDS] != 0) {
115  if (iDS == 1) cout << "\n Diffractive system on side A: \n";
116  if (iDS == 2) cout << "\n Diffractive system on side B: \n";
117  if (iDS == 3) cout << "\n Central diffractive system: \n";
118  cout << " In 1: id = " << setw(4) << id1pdfSave[iDS] << ", x = "
119  << setw(10) << x1pdfSave[iDS] << ", pdf = " << setw(10)
120  << pdf1Save[iDS] << " at Q2 = " << setw(10) << Q2FacSave[iDS]
121  << ".\n" << " In 2: id = " << setw(4) << id2pdfSave[iDS]
122  << ", x = " << setw(10) << x2pdfSave[iDS] << ", pdf = "
123  << setw(10) << pdf2Save[iDS] << " at same Q2.\n";
124  cout << " Subprocess " << nameSubSave[iDS] << " with code "
125  << codeSubSave[iDS] << " is 2 -> " << nFinalSubSave[iDS] << ".\n";
126  if (nFinalSubSave[iDS] == 1) {
127  cout << " It has sHat = " << setw(10) << sH[iDS] << ".\n";
128  } else if (nFinalSubSave[iDS] == 2) {
129  cout << " It has sHat = " << setw(10) << sH[iDS] << ", tHat = "
130  << setw(10) << tH[iDS] << ", uHat = " << setw(10) << uH[iDS]
131  << ",\n" << " pTHat = " << setw(10) << pTH[iDS]
132  << ", m3Hat = " << setw(10) << m3H[iDS] << ", m4Hat = "
133  << setw(10) << m4H[iDS] << ",\n" << " thetaHat = " << setw(10)
134  << thetaH[iDS] << ", phiHat = " << setw(10) << phiH[iDS] << ".\n";
135  }
136  cout << " alphaEM = " << setw(10) << alphaEMSave[iDS]
137  << ", alphaS = " << setw(10) << alphaSSave[iDS] << " at Q2 = "
138  << setw(10) << Q2RenSave[iDS] << ".\n";
139  }
140 
141  // Impact parameter.
142  if (bIsSet) cout << "\n Impact parameter b = " << setw(10) << bMPISave
143  << " gives enhancement factor = " << setw(10) << enhanceMPISave
144  << ".\n";
145 
146  // Multiparton interactions and shower evolution.
147  if (evolIsSet) cout << " Max pT scale for MPI = " << setw(10) << pTmaxMPISave
148  << ", ISR = " << setw(10) << pTmaxISRSave << ", FSR = " << setw(10)
149  << pTmaxISRSave << ".\n Number of MPI = " << setw(5) << nMPISave
150  << ", ISR = " << setw(5) << nISRSave << ", FSRproc = " << setw(5)
151  << nFSRinProcSave << ", FSRreson = " << setw(5) << nFSRinResSave
152  << ".\n";
153 
154  // Listing finished.
155  cout << "\n -------- End PYTHIA Info Listing --------------------"
156  << "----------------" << endl;
157 
158 }
159 
160 //--------------------------------------------------------------------------
161 
162 // Event weights and accumulated weight.
163 
164 double Info::weight(int iWeight) const {
165  double weightNominal = weightContainerPtr->weightNominal;
166  double wt = (iWeight <= 0 ||
167  iWeight >= int(weightContainerPtr->weightsPS.getWeightsSize()))
168  ? weightNominal :
169  weightContainerPtr->weightsPS.getWeightsValue(iWeight)*weightNominal;
170  return wt;
171 }
172 
173 double Info::weightSum() const {
174  return (abs(lhaStrategySave) == 4) ? CONVERTMB2PB * wtAccSum : wtAccSum;
175 }
176 
177 //--------------------------------------------------------------------------
178 
179 // List of all hard processes switched on.
180 
181 vector<int> Info::codesHard() {
182  vector<int> codesNow;
183  for (map<int, long>::iterator nTryEntry = nTryM.begin();
184  nTryEntry != nTryM.end(); ++nTryEntry)
185  codesNow.push_back( nTryEntry->first );
186  return codesNow;
187 }
188 
189 //--------------------------------------------------------------------------
190 
191 // Print a message the first few times. Insert in database.
192 
193 void Info::errorMsg(string messageIn, string extraIn, bool showAlways) {
194 
195  // Recover number of times message occured. Also inserts new string.
196  int times = messages[messageIn];
197  ++messages[messageIn];
198 
199  // Print message the first few times.
200  if (times < TIMESTOPRINT || showAlways) cout << " PYTHIA "
201  << messageIn << " " << extraIn << endl;
202 
203 }
204 
205 //--------------------------------------------------------------------------
206 
207 // Provide total number of errors/aborts/warnings experienced to date.
208 
209 int Info::errorTotalNumber() const {
210 
211  int nTot = 0;
212  for (pair<string, int> messageEntry : messages)
213  nTot += messageEntry.second;
214  return nTot;
215 
216 }
217 
218 //--------------------------------------------------------------------------
219 
220 // Print statistics on errors/aborts/warnings.
221 
222 void Info::errorStatistics() const {
223 
224  // Header.
225  cout << "\n *------- PYTHIA Error and Warning Messages Statistics "
226  << "----------------------------------------------------------* \n"
227  << " | "
228  << " | \n"
229  << " | times message "
230  << " | \n"
231  << " | "
232  << " | \n";
233 
234  // Loop over all messages
235  map<string, int>::const_iterator messageEntry = messages.begin();
236  if (messageEntry == messages.end())
237  cout << " | 0 no errors or warnings to report "
238  << " | \n";
239  while (messageEntry != messages.end()) {
240  // Message printout.
241  string temp = messageEntry->first;
242  int len = temp.length();
243  temp.insert( len, max(0, 102 - len), ' ');
244  cout << " | " << setw(6) << messageEntry->second << " "
245  << temp << " | \n";
246  ++messageEntry;
247  }
248 
249  // Done.
250  cout << " | "
251  << " | \n"
252  << " *------- End PYTHIA Error and Warning Messages Statistics"
253  << " ------------------------------------------------------* "
254  << endl;
255 
256 }
257 
258 //--------------------------------------------------------------------------
259 
260 // Return a list of all header key names
261 
262 vector<string> Info::headerKeys() const {
263  vector<string> keys;
264  for (pair<string, string> headerEntry : headers)
265  keys.push_back(headerEntry.first);
266  return keys;
267 }
268 
269 //--------------------------------------------------------------------------
270 
271 // Reset the LHEF3 objects read from the init and header blocks.
272 
273 void Info::setLHEF3InitInfo() {
274  initrwgt = 0;
275  generators = 0;
276  weightgroups = 0;
277  init_weights = 0;
278  headerBlock = "";
279 }
280 
281 //--------------------------------------------------------------------------
282 
283 // Set the LHEF3 objects read from the init and header blocks.
284 
285 void Info::setLHEF3InitInfo( int LHEFversionIn, LHAinitrwgt *initrwgtIn,
286  vector<LHAgenerator> *generatorsIn,
287  map<string,LHAweightgroup> *weightgroupsIn,
288  map<string,LHAweight> *init_weightsIn, string headerBlockIn ) {
289  LHEFversionSave = LHEFversionIn;
290  initrwgt = initrwgtIn;
291  generators = generatorsIn;
292  weightgroups = weightgroupsIn;
293  init_weights = init_weightsIn;
294  headerBlock = headerBlockIn;
295  weightContainerPtr->weightsLHEF.
296  identifyVariationsFromLHAinit( init_weightsIn );
297  weightContainerPtr->weightsMerging.setLHEFvariationMapping();
298 }
299 
300 //--------------------------------------------------------------------------
301 
302 // Reset the LHEF3 objects read from the event block.
303 
304 void Info::setLHEF3EventInfo() {
305  eventAttributes = 0;
306  weights_detailed = 0;
307  weights_compressed = 0;
308  scales = 0;
309  weights = 0;
310  rwgt = 0;
311  weights_detailed_vector.resize(0);
312  eventComments = "";
313  eventWeightLHEF = 1.0;
314  weightContainerPtr->weightsLHEF.clear();
315 }
316 
317 //--------------------------------------------------------------------------
318 
319 // Set the LHEF3 objects read from the event block.
320 
321 void Info::setLHEF3EventInfo( map<string, string> *eventAttributesIn,
322  map<string,double> *weights_detailedIn,
323  vector<double> *weights_compressedIn,
324  LHAscales *scalesIn, LHAweights *weightsIn,
325  LHArwgt *rwgtIn, vector<double> weights_detailed_vecIn,
326  vector<string> weights_detailed_name_vecIn,
327  string eventCommentsIn, double eventWeightLHEFIn ) {
328  eventAttributes = eventAttributesIn;
329  weights_detailed = weights_detailedIn;
330  weights_compressed = weights_compressedIn;
331  scales = scalesIn;
332  weights = weightsIn;
333  rwgt = rwgtIn;
334  weights_detailed_vector = weights_detailed_vecIn;
335  eventComments = eventCommentsIn;
336  eventWeightLHEF = eventWeightLHEFIn;
337  weightContainerPtr->weightsLHEF.bookVectors(weights_detailed_vecIn,
338  weights_detailed_name_vecIn);
339 }
340 
341 //--------------------------------------------------------------------------
342 
343 // Retrieve events tag information.
344 
345 string Info::getEventAttribute(string key, bool doRemoveWhitespace) const {
346  if (!eventAttributes) return "";
347  if ( eventAttributes->find(key) != eventAttributes->end() ) {
348  string res = (*eventAttributes)[key];
349  if (doRemoveWhitespace)
350  res.erase (remove (res.begin(), res.end(), ' '), res.end());
351  return res;
352  }
353  return "";
354 }
355 
356 //--------------------------------------------------------------------------
357 
358 // Retrieve initrwgt tag information.
359 
360 unsigned int Info::getInitrwgtSize() const {
361  if (!initrwgt) return 0;
362  return initrwgt->weights.size();
363 }
364 
365 //--------------------------------------------------------------------------
366 
367 // Retrieve generator tag information.
368 
369 unsigned int Info::getGeneratorSize() const {
370  if (!generators) return 0;
371  return generators->size();
372 }
373 
374 string Info::getGeneratorValue(unsigned int n) const {
375  if (!generators || generators->size() < n+1) return "";
376  return (*generators)[n].contents;
377 }
378 
379 string Info::getGeneratorAttribute( unsigned int n, string key,
380  bool doRemoveWhitespace) const {
381  if (!generators || generators->size() < n+1) return "";
382  string res("");
383  if ( key == "name") {
384  res = (*generators)[n].name;
385  } else if ( key == "version") {
386  res = (*generators)[n].version;
387  } else if ( (*generators)[n].attributes.find(key)
388  != (*generators)[n].attributes.end() ) {
389  res = (*generators)[n].attributes[key];
390  }
391  if (doRemoveWhitespace && res != "")
392  res.erase (remove (res.begin(), res.end(), ' '), res.end());
393  return res;
394 }
395 
396 //--------------------------------------------------------------------------
397 
398 // Retrieve rwgt tag information.
399 
400 unsigned int Info::getWeightsDetailedSize() const {
401  if (!weights_detailed) return 0;
402  return weights_detailed->size();
403 }
404 
405 double Info::getWeightsDetailedValue(string n) const {
406  if (weights_detailed->empty()
407  || weights_detailed->find(n) == weights_detailed->end())
408  return std::numeric_limits<double>::quiet_NaN();
409  return (*weights_detailed)[n];
410 }
411 
412 string Info::getWeightsDetailedAttribute(string n, string key,
413  bool doRemoveWhitespace) const {
414  if (!rwgt || rwgt->wgts.find(n) == rwgt->wgts.end())
415  return "";
416  string res("");
417  if ( key == "id") {
418  res = rwgt->wgts[n].id;
419  } else if ( rwgt->wgts[n].attributes.find(key)
420  != rwgt->wgts[n].attributes.end() ) {
421  res = rwgt->wgts[n].attributes[key];
422  }
423  if (doRemoveWhitespace && res != "")
424  res.erase (remove (res.begin(), res.end(), ' '), res.end());
425  return res;
426 }
427 
428 //--------------------------------------------------------------------------
429 
430 // Retrieve weights tag information.
431 
432 unsigned int Info::getWeightsCompressedSize() const {
433  if (!weights_compressed) return 0;
434  return weights_compressed->size();
435 }
436 
437 double Info::getWeightsCompressedValue(unsigned int n) const {
438  if (weights_compressed->empty() || weights_compressed->size() < n+1)
439  return std::numeric_limits<double>::quiet_NaN();
440  return (*weights_compressed)[n];
441 }
442 
443 string Info::getWeightsCompressedAttribute(string key,
444  bool doRemoveWhitespace) const {
445  if (!weights || weights->attributes.find(key) == weights->attributes.end())
446  return "";
447  string res("");
448  if ( weights->attributes.find(key)
449  != weights->attributes.end() ) {
450  res = weights->attributes[key];
451  }
452  if (doRemoveWhitespace && res != "")
453  res.erase (remove (res.begin(), res.end(), ' '), res.end());
454  return res;
455 }
456 
457 //--------------------------------------------------------------------------
458 
459 // Retrieve scales tag information.
460 
461 string Info::getScalesValue(bool doRemoveWhitespace) const {
462  if (!scales) return "";
463  string res = scales->contents;
464  if (doRemoveWhitespace && res != "")
465  res.erase (remove (res.begin(), res.end(), ' '), res.end());
466  return res;
467 }
468 
469 double Info::getScalesAttribute(string key) const {
470  if (!scales) return std::numeric_limits<double>::quiet_NaN();
471  double res = std::numeric_limits<double>::quiet_NaN();
472  if ( key == "muf") {
473  res = scales->muf;
474  } else if ( key == "mur") {
475  res = scales->mur;
476  } else if ( key == "mups") {
477  res = scales->mups;
478  } else if ( key == "SCALUP") {
479  res = scales->SCALUP;
480  } else if ( scales->attributes.find(key)
481  != scales->attributes.end() ) {
482  res = scales->attributes[key];
483  }
484  return res;
485 }
486 
487 //--------------------------------------------------------------------------
488 //==========================================================================
489 
490 // Class for loading plugin libraries at run time.
491 
492 //--------------------------------------------------------------------------
493 
494 // Constructor, with library name and info pointer.
495 
496 Plugin::Plugin(string nameIn, Info *infoPtrIn) {
497  name = nameIn;
498  infoPtr = infoPtrIn;
499  libPtr = dlopen(nameIn.c_str(), RTLD_LAZY);
500  const char* cerror = dlerror();
501  string serror(cerror == nullptr ? "" : cerror);
502  dlerror();
503  if (serror.size()) {
504  errorMsg("Error in Plugin::Plugin: " + serror);
505  libPtr = nullptr;
506  }
507 
508 }
509 
510 //--------------------------------------------------------------------------
511 
512 // Destructor.
513 
514 Plugin::~Plugin() {
515  if (libPtr != nullptr) dlclose(libPtr);
516  dlerror();
517 
518 }
519 
520 //--------------------------------------------------------------------------
521 
522 // Access plugin library symbols.
523 
524 Plugin::Symbol Plugin::symbol(string symName) {
525  Symbol sym(0);
526  const char* error(0);
527  if (libPtr == nullptr) return sym;
528  sym = (Symbol)dlsym(libPtr, symName.c_str());
529  error = dlerror();
530  if (error) errorMsg("Error in Plugin::symbol: " + string(error));
531  dlerror();
532  return sym;
533 
534 }
535 
536 
537 //==========================================================================
538 
539 } // end namespace Pythia8