StRoot  1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
Pythia.cc
1 // Pythia.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 Pythia class.
7 
8 #include "Pythia8/Pythia.h"
9 #include "Pythia8/BeamShape.h"
10 #include "Pythia8/ColourReconnection.h"
11 #include "Pythia8/Dire.h"
12 #include "Pythia8/HeavyIons.h"
13 #include "Pythia8/History.h"
14 #include "Pythia8/StringInteractions.h"
15 #include "Pythia8/Vincia.h"
16 
17 // Access time information.
18 #include <ctime>
19 
20 // Allow string and character manipulation.
21 #include <cctype>
22 
23 namespace Pythia8 {
24 
25 //==========================================================================
26 
27 // The Pythia class.
28 
29 //--------------------------------------------------------------------------
30 
31 // The current Pythia (sub)version number, to agree with XML version.
32 const double Pythia::VERSIONNUMBERHEAD = PYTHIA_VERSION;
33 const double Pythia::VERSIONNUMBERCODE = 8.303;
34 
35 //--------------------------------------------------------------------------
36 
37 // Constructor.
38 
39 Pythia::Pythia(string xmlDir, bool printBanner) {
40 
41  // Initialise / reset pointers and global variables.
42  initPtrs();
43 
44  // Find path to data files, i.e. xmldoc directory location.
45  // Environment variable takes precedence, then constructor input,
46  // and finally the pre-processor constant XMLDIR.
47  const char* envPath = getenv("PYTHIA8DATA");
48  xmlPath = envPath ? envPath : "";
49  if (xmlPath == "") {
50  if (xmlDir.length() && xmlDir[xmlDir.length() - 1] != '/') xmlDir += "/";
51  xmlPath = xmlDir;
52  ifstream xmlFile((xmlPath + "Index.xml").c_str());
53  if (!xmlFile.good()) xmlPath = XMLDIR;
54  xmlFile.close();
55  }
56  if (xmlPath.empty() || (xmlPath.length() && xmlPath[xmlPath.length() - 1]
57  != '/')) xmlPath += "/";
58 
59  // Read in files with all flags, modes, parms and words.
60  settings.initPtrs( &infoPrivate);
61  string initFile = xmlPath + "Index.xml";
62  isConstructed = settings.init( initFile);
63  if (!isConstructed) {
64  infoPrivate.errorMsg("Abort from Pythia::Pythia: settings unavailable");
65  return;
66  }
67 
68  // Save XML path in settings.
69  settings.addWord( "xmlPath", xmlPath);
70 
71  // Check that XML and header version numbers match code version number.
72  if (!checkVersion()) return;
73 
74  // Read in files with all particle data.
75  particleData.initPtrs( &infoPrivate);
76  string dataFile = xmlPath + "ParticleData.xml";
77  isConstructed = particleData.init( dataFile);
78  if (!isConstructed) {
79  infoPrivate.errorMsg
80  ("Abort from Pythia::Pythia: particle data unavailable");
81  return;
82  }
83 
84  // Write the Pythia banner to output.
85  if (printBanner) banner();
86 
87  // Not initialized until at the end of the init() call.
88  isInit = false;
89  infoPrivate.addCounter(0);
90 
92 
93 }
94 
95 //--------------------------------------------------------------------------
96 
97 // Constructor from pre-initialised ParticleData and Settings objects.
98 
99 Pythia::Pythia(Settings& settingsIn, ParticleData& particleDataIn,
100  bool printBanner) {
101 
102  // Initialise / reset pointers and global variables.
103  initPtrs();
104 
105  // Copy XML path from existing Settings database.
106  xmlPath = settingsIn.word("xmlPath");
107 
108  // Copy settings database and redirect pointers.
109  settings = settingsIn;
110  settings.initPtrs( &infoPrivate);
111  isConstructed = settings.getIsInit();
112  if (!isConstructed) {
113  infoPrivate.errorMsg("Abort from Pythia::Pythia: settings unavailable");
114  return;
115  }
116 
117  // Check XML and header version numbers match code version number.
118  if (!checkVersion()) return;
119 
120  // Copy particleData database and redirect pointers.
121  particleData = particleDataIn;
122  particleData.initPtrs( &infoPrivate);
123  isConstructed = particleData.getIsInit();
124  if (!isConstructed) {
125  infoPrivate.errorMsg
126  ("Abort from Pythia::Pythia: particle data unavailable");
127  return;
128  }
129 
130  // Write the Pythia banner to output.
131  if (printBanner) banner();
132 
133  // Not initialized until at the end of the init() call.
134  isInit = false;
135  infoPrivate.addCounter(0);
136 
137 }
138 
139 //--------------------------------------------------------------------------
140 
141 // Constructor from string streams.
142 
143 Pythia::Pythia( istream& settingsStrings, istream& particleDataStrings,
144  bool printBanner) {
145 
146  // Initialise / reset pointers and global variables.
147  initPtrs();
148 
149  // Copy settings database
150  settings.init( settingsStrings );
151 
152  // Reset pointers to pertain to this PYTHIA object.
153  settings.initPtrs( &infoPrivate);
154  isConstructed = settings.getIsInit();
155  if (!isConstructed) {
156  infoPrivate.errorMsg("Abort from Pythia::Pythia: settings unavailable");
157  return;
158  }
159 
160  // Check XML and header version numbers match code version number.
161  if (!checkVersion()) return;
162 
163  // Read in files with all particle data.
164  particleData.initPtrs( &infoPrivate);
165  isConstructed = particleData.init( particleDataStrings );
166  if (!isConstructed) {
167  infoPrivate.errorMsg
168  ("Abort from Pythia::Pythia: particle data unavailable");
169  return;
170  }
171 
172  // Write the Pythia banner to output.
173  if (printBanner) banner();
174 
175  // Not initialized until at the end of the init() call.
176  isInit = false;
177  infoPrivate.addCounter(0);
178 
179 }
180 
181 //--------------------------------------------------------------------------
182 
183 // Initialise new Pythia object (common code called by constructors).
184 
185 void Pythia::initPtrs() {
186 
187  // Setup of Info.
188  infoPrivate.setPtrs( &settings, &particleData, &rndm, &coupSM, &coupSUSY,
189  &beamA, &beamB, &beamPomA, &beamPomB, &beamGamA, &beamGamB, &beamVMDA,
190  &beamVMDB, &partonSystems, &sigmaTot, &hadronWidths, &weightContainer);
191  registerPhysicsBase(processLevel);
192  registerPhysicsBase(partonLevel);
193  registerPhysicsBase(trialPartonLevel);
194  registerPhysicsBase(hadronLevel);
195  registerPhysicsBase(sigmaTot);
196  registerPhysicsBase(hadronWidths);
197  registerPhysicsBase(junctionSplitting);
198  registerPhysicsBase(rHadrons);
199  registerPhysicsBase(beamA);
200  registerPhysicsBase(beamB);
201  registerPhysicsBase(beamPomA);
202  registerPhysicsBase(beamPomB);
203  registerPhysicsBase(beamGamA);
204  registerPhysicsBase(beamGamB);
205  registerPhysicsBase(beamVMDA);
206  registerPhysicsBase(beamVMDB);
207 
208 }
209 
210 //--------------------------------------------------------------------------
211 
212 // Check for consistency of version numbers (called by constructors).
213 
214 bool Pythia::checkVersion() {
215 
216  // Check that XML version number matches code version number.
217  double versionNumberXML = parm("Pythia:versionNumber");
218  isConstructed = (abs(versionNumberXML - VERSIONNUMBERCODE) < 0.0005);
219  if (!isConstructed) {
220  ostringstream errCode;
221  errCode << fixed << setprecision(3) << ": in code " << VERSIONNUMBERCODE
222  << " but in XML " << versionNumberXML;
223  infoPrivate.errorMsg
224  ("Abort from Pythia::Pythia: unmatched version numbers", errCode.str());
225  return false;
226  }
227 
228  // Check that header version number matches code version number.
229  isConstructed = (abs(VERSIONNUMBERHEAD - VERSIONNUMBERCODE) < 0.0005);
230  if (!isConstructed) {
231  ostringstream errCode;
232  errCode << fixed << setprecision(3) << ": in code " << VERSIONNUMBERCODE
233  << " but in header " << VERSIONNUMBERHEAD;
234  infoPrivate.errorMsg
235  ("Abort from Pythia::Pythia: unmatched version numbers", errCode.str());
236  return false;
237  }
238 
239  // All is well that ends well.
240  return true;
241 
242 }
243 
244 //--------------------------------------------------------------------------
245 
246 // Read in one update for a setting or particle data from a single line.
247 
248 bool Pythia::readString(string line, bool warn) {
249 
250  // Check that constructor worked.
251  if (!isConstructed) return false;
252 
253  // If empty line then done.
254  if (line.find_first_not_of(" \n\t\v\b\r\f\a") == string::npos) return true;
255 
256  // If Settings input stretches over several lines then continue with it.
257  if (settings.unfinishedInput()) return settings.readString(line, warn);
258 
259  // If first character is not a letter/digit, then taken to be a comment.
260  int firstChar = line.find_first_not_of(" \n\t\v\b\r\f\a");
261  if (!isalnum(line[firstChar])) return true;
262 
263  // Send on particle data to the ParticleData database.
264  if (isdigit(line[firstChar])) {
265  bool passed = particleData.readString(line, warn);
266  if (passed) particleDataBuffer << line << endl;
267  return passed;
268  }
269 
270  // Everything else sent on to Settings.
271  return settings.readString(line, warn);
272 
273 }
274 
275 //--------------------------------------------------------------------------
276 
277 // Read in updates for settings or particle data from user-defined file.
278 
279 bool Pythia::readFile(string fileName, bool warn, int subrun) {
280 
281  // Check that constructor worked.
282  if (!isConstructed) return false;
283 
284  // Open file for reading.
285  const char* cstring = fileName.c_str();
286  ifstream is(cstring);
287  if (!is.good()) {
288  infoPrivate.errorMsg
289  ("Error in Pythia::readFile: did not find file", fileName);
290  return false;
291  }
292 
293  // Hand over real work to next method.
294  return readFile( is, warn, subrun);
295 
296 }
297 
298 //--------------------------------------------------------------------------
299 
300 // Read in updates for settings or particle data
301 // from user-defined stream (or file).
302 
303 bool Pythia::readFile(istream& is, bool warn, int subrun) {
304 
305  // Check that constructor worked.
306  if (!isConstructed) return false;
307 
308  // Read in one line at a time.
309  string line;
310  bool isCommented = false;
311  bool accepted = true;
312  int subrunNow = SUBRUNDEFAULT;
313  while ( getline(is, line) ) {
314 
315  // Check whether entering, leaving or inside commented-commands section.
316  int commentLine = readCommented( line);
317  if (commentLine == +1) isCommented = true;
318  else if (commentLine == -1) isCommented = false;
319  else if (isCommented) ;
320 
321  else {
322  // Check whether entered new subrun.
323  int subrunLine = readSubrun( line, warn);
324  if (subrunLine >= 0) subrunNow = subrunLine;
325 
326  // Process the line if in correct subrun.
327  if ( (subrunNow == subrun || subrunNow == SUBRUNDEFAULT)
328  && !readString( line, warn) ) accepted = false;
329  }
330 
331  // Reached end of input file.
332  };
333  return accepted;
334 
335 }
336 
337 //--------------------------------------------------------------------------
338 
339 // Routine to pass in pointers to PDF's. Usage optional.
340 
341 bool Pythia::setPDFPtr( PDFPtr pdfAPtrIn, PDFPtr pdfBPtrIn,
342  PDFPtr pdfHardAPtrIn, PDFPtr pdfHardBPtrIn, PDFPtr pdfPomAPtrIn,
343  PDFPtr pdfPomBPtrIn, PDFPtr pdfGamAPtrIn, PDFPtr pdfGamBPtrIn,
344  PDFPtr pdfHardGamAPtrIn, PDFPtr pdfHardGamBPtrIn, PDFPtr pdfUnresAPtrIn,
345  PDFPtr pdfUnresBPtrIn, PDFPtr pdfUnresGamAPtrIn, PDFPtr pdfUnresGamBPtrIn,
346  PDFPtr pdfVMDAPtrIn, PDFPtr pdfVMDBPtrIn) {
347 
348  pdfAPtr = pdfBPtr = pdfHardAPtr = pdfHardBPtr = pdfPomAPtr = pdfPomBPtr
349  = pdfGamAPtr = pdfGamBPtr = pdfHardGamAPtr = pdfHardGamBPtr = pdfUnresAPtr
350  = pdfUnresBPtr = pdfUnresGamAPtr = pdfUnresGamBPtr = pdfVMDAPtr
351  = pdfVMDBPtr = nullptr;
352 
353  // Switch off external PDF's by zero as input.
354  if ( !pdfAPtrIn && !pdfBPtrIn) return true;
355 
356  // The two PDF objects cannot be one and the same.
357  if (pdfAPtrIn == pdfBPtrIn) return false;
358 
359  // Save pointers.
360  pdfAPtr = pdfAPtrIn;
361  pdfBPtr = pdfBPtrIn;
362 
363  // By default same pointers for hard-process PDF's.
364  pdfHardAPtr = pdfAPtrIn;
365  pdfHardBPtr = pdfBPtrIn;
366 
367  // Optionally allow separate pointers for hard process.
368  if (pdfHardAPtrIn && pdfHardBPtrIn) {
369  if (pdfHardAPtrIn == pdfHardBPtrIn) return false;
370  pdfHardAPtr = pdfHardAPtrIn;
371  pdfHardBPtr = pdfHardBPtrIn;
372  }
373 
374  // Optionally allow pointers for Pomerons in the proton.
375  if (pdfPomAPtrIn && pdfPomBPtrIn) {
376  if (pdfPomAPtrIn == pdfPomBPtrIn) return false;
377  pdfPomAPtr = pdfPomAPtrIn;
378  pdfPomBPtr = pdfPomBPtrIn;
379  }
380 
381  // Optionally allow pointers for Gammas in the leptons.
382  if (pdfGamAPtrIn && pdfGamBPtrIn) {
383  if (pdfGamAPtrIn == pdfGamBPtrIn) return false;
384  pdfGamAPtr = pdfGamAPtrIn;
385  pdfGamBPtr = pdfGamBPtrIn;
386  }
387 
388  // Optionally allow pointers for Hard PDFs for photons in the leptons.
389  if (pdfHardGamAPtrIn && pdfHardGamBPtrIn) {
390  if (pdfHardGamAPtrIn == pdfHardGamBPtrIn) return false;
391  pdfHardGamAPtr = pdfHardGamAPtrIn;
392  pdfHardGamBPtr = pdfHardGamBPtrIn;
393  }
394 
395  // Optionally allow pointers for unresolved PDFs.
396  if (pdfUnresAPtrIn && pdfUnresBPtrIn) {
397  if (pdfUnresAPtrIn == pdfUnresBPtrIn) return false;
398  pdfUnresAPtr = pdfUnresAPtrIn;
399  pdfUnresBPtr = pdfUnresBPtrIn;
400  }
401 
402  // Optionally allow pointers for unresolved PDFs for photons from leptons.
403  if (pdfUnresGamAPtrIn && pdfUnresGamBPtrIn) {
404  if (pdfUnresGamAPtrIn == pdfUnresGamBPtrIn) return false;
405  pdfUnresGamAPtr = pdfUnresGamAPtrIn;
406  pdfUnresGamBPtr = pdfUnresGamBPtrIn;
407  }
408 
409  // Optionally allow pointers for VMD in the gamma.
410  if (pdfVMDAPtrIn && pdfVMDBPtrIn) {
411  if (pdfVMDAPtrIn == pdfVMDBPtrIn) return false;
412  pdfVMDAPtr = pdfVMDAPtrIn;
413  pdfVMDBPtr = pdfVMDBPtrIn;
414  }
415 
416  // Done.
417  return true;
418 }
419 
420 //--------------------------------------------------------------------------
421 
422 // Routine to pass in pointers to PDF's. Usage optional.
423 
424 bool Pythia::setPDFAPtr( PDFPtr pdfAPtrIn ) {
425 
426  // Reset pointers to be empty.
427  pdfAPtr = pdfBPtr = pdfHardAPtr = pdfHardBPtr = pdfPomAPtr = pdfPomBPtr
428  = pdfGamAPtr = pdfGamBPtr = pdfHardGamAPtr = pdfHardGamBPtr = pdfUnresAPtr
429  = pdfUnresBPtr = pdfUnresGamAPtr = pdfUnresGamBPtr = pdfVMDAPtr
430  = pdfVMDBPtr = nullptr;
431 
432  // Switch off external PDF's by zero as input.
433  if (!pdfAPtrIn) return true;
434 
435  // Save pointers.
436  pdfAPtr = pdfAPtrIn;
437  // By default same pointers for hard-process PDF's.
438  pdfHardAPtr = pdfAPtrIn;
439 
440  // Done.
441  return true;
442 }
443 
444 //--------------------------------------------------------------------------
445 
446 // Routine to pass in pointers to PDF's. Usage optional.
447 
448 bool Pythia::setPDFBPtr( PDFPtr pdfBPtrIn ) {
449 
450  // Reset pointers to be empty.
451  pdfAPtr = pdfBPtr = pdfHardAPtr = pdfHardBPtr = pdfPomAPtr = pdfPomBPtr
452  = pdfGamAPtr = pdfGamBPtr = pdfHardGamAPtr = pdfHardGamBPtr = pdfUnresAPtr
453  = pdfUnresBPtr = pdfUnresGamAPtr = pdfUnresGamBPtr = pdfVMDAPtr
454  = pdfVMDBPtr = nullptr;
455 
456  // Switch off external PDF's by zero as input.
457  if (!pdfBPtrIn) return true;
458 
459  // Save pointers.
460  pdfBPtr = pdfBPtrIn;
461  // By default same pointers for hard-process PDF's.
462  pdfHardBPtr = pdfBPtrIn;
463 
464  // Done.
465  return true;
466 }
467 
468 //--------------------------------------------------------------------------
469 
470 // Routine to initialize with the variable values of the Beams kind.
471 
472 bool Pythia::init() {
473 
474  // Check that constructor worked.
475  isInit = false;
476  if (!isConstructed) {
477  infoPrivate.errorMsg("Abort from Pythia::init: constructor "
478  "initialization failed");
479  return false;
480  }
481 
482  // Early catching of heavy ion mode.
483  doHeavyIons = HeavyIons::isHeavyIon(settings) ||
484  settings.mode("HeavyIon:mode") == 2;
485  if ( doHeavyIons ) {
486  if ( !heavyIonsPtr ) heavyIonsPtr = make_shared<Angantyr>(*this);
487  registerPhysicsBase(*heavyIonsPtr);
488  if ( hiHooksPtr ) heavyIonsPtr->setHIUserHooksPtr(hiHooksPtr);
489  if ( !heavyIonsPtr->init() ) doHeavyIons = false;
490  }
491 
492  // Master choice of shower model.
493  int showerModel = settings.mode("PartonShowers:model");
494 
495  // Early readout, if return false or changed when no beams.
496  doProcessLevel = settings.flag("ProcessLevel:all");
497 
498  // Check that changes in Settings and ParticleData have worked.
499  if (settings.unfinishedInput()) {
500  infoPrivate.errorMsg("Abort from Pythia::init: opening { not matched by "
501  "closing }");
502  return false;
503  }
504  if (settings.readingFailed()) {
505  infoPrivate.errorMsg("Abort from Pythia::init: some user settings "
506  "did not make sense");
507  return false;
508  }
509  if (particleData.readingFailed()) {
510  infoPrivate.errorMsg("Abort from Pythia::init: some user particle data "
511  "did not make sense");
512  return false;
513  }
514 
515  // Initialize the random number generator.
516  if ( settings.flag("Random:setSeed") )
517  rndm.init( settings.mode("Random:seed") );
518 
519  // Find which frame type to use.
520  infoPrivate.addCounter(1);
521  frameType = mode("Beams:frameType");
522 
523  // Already get the Les Houches File name here, to have it for later
524  // new merging initialization (e.g. by new showers).
525  string lhef = word("Beams:LHEF");
526 
527  // Set up values related to CKKW-L merging.
528  bool doUserMerging = settings.flag("Merging:doUserMerging");
529  bool doMGMerging = settings.flag("Merging:doMGMerging");
530  bool doKTMerging = settings.flag("Merging:doKTMerging");
531  bool doPTLundMerging = settings.flag("Merging:doPTLundMerging");
532  bool doCutBasedMerging = settings.flag("Merging:doCutBasedMerging");
533  // Set up values related to unitarised CKKW merging
534  bool doUMEPSTree = settings.flag("Merging:doUMEPSTree");
535  bool doUMEPSSubt = settings.flag("Merging:doUMEPSSubt");
536  // Set up values related to NL3 NLO merging
537  bool doNL3Tree = settings.flag("Merging:doNL3Tree");
538  bool doNL3Loop = settings.flag("Merging:doNL3Loop");
539  bool doNL3Subt = settings.flag("Merging:doNL3Subt");
540  // Set up values related to unitarised NLO merging
541  bool doUNLOPSTree = settings.flag("Merging:doUNLOPSTree");
542  bool doUNLOPSLoop = settings.flag("Merging:doUNLOPSLoop");
543  bool doUNLOPSSubt = settings.flag("Merging:doUNLOPSSubt");
544  bool doUNLOPSSubtNLO = settings.flag("Merging:doUNLOPSSubtNLO");
545  bool doXSectionEst = settings.flag("Merging:doXSectionEstimate");
546  doMerging = doUserMerging || doMGMerging || doKTMerging
547  || doPTLundMerging || doCutBasedMerging || doUMEPSTree || doUMEPSSubt
548  || doNL3Tree || doNL3Loop || doNL3Subt || doUNLOPSTree
549  || doUNLOPSLoop || doUNLOPSSubt || doUNLOPSSubtNLO || doXSectionEst;
550  doMerging = doMerging || settings.flag("Merging:doMerging");
551 
552  // Set/Reset the weights
553  weightContainer.initPtrs(&infoPrivate);
554  weightContainer.init(doMerging);
555 
556  // Set up MergingHooks object for simple shower model.
557  if (doMerging && showerModel == 1) {
558  if (!mergingHooksPtr) mergingHooksPtr = make_shared<MergingHooks>();
559  registerPhysicsBase(*mergingHooksPtr);
560  mergingHooksPtr->setLHEInputFile("");
561  }
562 
563  // Set up Merging object for simple shower model.
564  if ( doMerging && showerModel == 1 && !mergingPtr ) {
565  mergingPtr = make_shared<Merging>();
566  registerPhysicsBase(*mergingPtr);
567  }
568 
569  // Initialization with internal processes: read in and set values.
570  if (frameType < 4 ) {
571  doLHA = false;
572  boostType = frameType;
573  idA = mode("Beams:idA");
574  idB = mode("Beams:idB");
575  eCM = parm("Beams:eCM");
576  eA = parm("Beams:eA");
577  eB = parm("Beams:eB");
578  pxA = parm("Beams:pxA");
579  pyA = parm("Beams:pyA");
580  pzA = parm("Beams:pzA");
581  pxB = parm("Beams:pxB");
582  pyB = parm("Beams:pyB");
583  pzB = parm("Beams:pzB");
584 
585  // Initialization with a Les Houches Event File or an LHAup object.
586  } else {
587  doLHA = true;
588  boostType = 2;
589  string lhefHeader = word("Beams:LHEFheader");
590  bool readHeaders = flag("Beams:readLHEFheaders");
591  bool setScales = flag("Beams:setProductionScalesFromLHEF");
592  bool skipInit = flag("Beams:newLHEFsameInit");
593  int nSkipAtInit = mode("Beams:nSkipLHEFatInit");
594 
595  // For file input: renew file stream or (re)new Les Houches object.
596  if (frameType == 4) {
597  const char* cstring1 = lhef.c_str();
598  bool useExternal = (lhaUpPtr && !useNewLHA && lhaUpPtr->useExternal());
599  if (!useExternal && useNewLHA && skipInit)
600  lhaUpPtr->newEventFile(cstring1);
601  else if (!useExternal) {
602  // Header is optional, so use NULL pointer to indicate no value.
603  const char* cstring2 = (lhefHeader == "void")
604  ? NULL : lhefHeader.c_str();
605  lhaUpPtr = make_shared<LHAupLHEF>(&infoPrivate, cstring1, cstring2,
606  readHeaders, setScales);
607  }
608 
609  // Check that file was properly opened.
610  if (!lhaUpPtr->fileFound()) {
611  infoPrivate.errorMsg("Abort from Pythia::init: "
612  "Les Houches Event File not found");
613  return false;
614  }
615 
616  // For object input: at least check that not null pointer.
617  } else {
618  if (lhaUpPtr == 0) {
619  infoPrivate.errorMsg("Abort from Pythia::init: "
620  "LHAup object not found");
621  return false;
622  }
623 
624  // LHAup object generic abort using fileFound() routine.
625  if (!lhaUpPtr->fileFound()) {
626  infoPrivate.errorMsg("Abort from Pythia::init: "
627  "LHAup initialisation error");
628  return false;
629  }
630  }
631 
632  // Send in pointer to info. Store or replace LHA pointer in other classes.
633  lhaUpPtr->setPtr( &infoPrivate);
634  processLevel.setLHAPtr( lhaUpPtr);
635 
636  // If second time around, only with new file, then simplify.
637  // Optionally skip ahead a number of events at beginning of file.
638  if (skipInit) {
639  isInit = true;
640  infoPrivate.addCounter(2);
641  if (nSkipAtInit > 0) lhaUpPtr->skipEvent(nSkipAtInit);
642  return true;
643  }
644 
645  // Set up values related to merging hooks.
646  if (frameType == 4 || frameType == 5) {
647 
648  // Store the name of the input LHEF for merging.
649  if (doMerging && showerModel == 1 ) {
650  string lhefIn = (frameType == 4) ? lhef : "";
651  mergingHooksPtr->setLHEInputFile( lhefIn);
652  }
653 
654  }
655 
656  // Set LHAinit information (in some external program).
657  if ( !lhaUpPtr->setInit()) {
658  infoPrivate.errorMsg("Abort from Pythia::init: "
659  "Les Houches initialization failed");
660  return false;
661  }
662 
663  // Extract beams from values set in an LHAinit object.
664  idA = lhaUpPtr->idBeamA();
665  idB = lhaUpPtr->idBeamB();
666  int idRenameBeams = settings.mode("LesHouches:idRenameBeams");
667  if (abs(idA) == idRenameBeams) idA = 16;
668  if (abs(idB) == idRenameBeams) idB = -16;
669  if (idA == 0 || idB == 0) doProcessLevel = false;
670  eA = lhaUpPtr->eBeamA();
671  eB = lhaUpPtr->eBeamB();
672 
673  // Optionally skip ahead a number of events at beginning of file.
674  if (nSkipAtInit > 0) lhaUpPtr->skipEvent(nSkipAtInit);
675  }
676 
677  // Set up values related to user hooks.
678  doVetoProcess = false;
679  doVetoPartons = false;
680  retryPartonLevel = false;
681 
682  if ( userHooksPtr ) {
683  infoPrivate.userHooksPtr = userHooksPtr;
684  registerPhysicsBase(*userHooksPtr);
685  pushInfo();
686  if (!userHooksPtr->initAfterBeams()) {
687  infoPrivate.errorMsg("Abort from Pythia::init: could not initialise"
688  " UserHooks");
689  return false;
690  }
691  doVetoProcess = userHooksPtr->canVetoProcessLevel();
692  doVetoPartons = userHooksPtr->canVetoPartonLevel();
693  retryPartonLevel = userHooksPtr->retryPartonLevel();
694  }
695 
696  // Setup objects for string interactions (swing, colour
697  // reconnection, shoving and rope hadronisation).
698  if ( !stringInteractionsPtr ) {
699  if ( flag("Ropewalk:RopeHadronization") )
700  stringInteractionsPtr = make_shared<Ropewalk>();
701  else
702  stringInteractionsPtr = make_shared<StringInteractions>();
703  registerPhysicsBase(*stringInteractionsPtr);
704 
705  }
706  stringInteractionsPtr->init();
707 
708  // Back to common initialization. Reset error counters.
709  nErrEvent = 0;
710  infoPrivate.setTooLowPTmin(false);
711  infoPrivate.sigmaReset();
712 
713  // Initialize data members extracted from database.
714  doPartonLevel = settings.flag("PartonLevel:all");
715  doHadronLevel = settings.flag("HadronLevel:all");
716  doCentralDiff = settings.flag("SoftQCD:centralDiffractive");
717  doSoftQCDall = settings.flag("SoftQCD:all");
718  doSoftQCDinel = settings.flag("SoftQCD:inelastic");
719  doDiffraction = settings.flag("SoftQCD:singleDiffractive")
720  || settings.flag("SoftQCD:doubleDiffractive")
721  || doSoftQCDall || doSoftQCDinel || doCentralDiff;
722  doSoftQCD = doDiffraction ||
723  settings.flag("SoftQCD:nonDiffractive") ||
724  settings.flag("SoftQCD:elastic");
725  doHardDiff = settings.flag("Diffraction:doHard");
726  doResDec = settings.flag("ProcessLevel:resonanceDecays");
727  doFSRinRes = doPartonLevel && settings.flag("PartonLevel:FSR")
728  && settings.flag("PartonLevel:FSRinResonances");
729  decayRHadrons = settings.flag("RHadrons:allowDecay");
730  doMomentumSpread = settings.flag("Beams:allowMomentumSpread");
731  doVertexSpread = settings.flag("Beams:allowVertexSpread");
732  doVarEcm = settings.flag("Beams:allowVariableEnergy");
733  doPartonVertex = settings.flag("PartonVertex:setVertex");
734  doVertexPlane = settings.flag("PartonVertex:randomPlane");
735  eMinPert = settings.parm("Beams:eMinPert");
736  eWidthPert = settings.parm("Beams:eWidthPert");
737  abortIfVeto = settings.flag("Check:abortIfVeto");
738  checkEvent = settings.flag("Check:event");
739  checkHistory = settings.flag("Check:history");
740  nErrList = settings.mode("Check:nErrList");
741  epTolErr = settings.parm("Check:epTolErr");
742  epTolWarn = settings.parm("Check:epTolWarn");
743  mTolErr = settings.parm("Check:mTolErr");
744  mTolWarn = settings.parm("Check:mTolWarn");
745 
746  // Warn/abort for unallowed process and beam combinations.
747  bool doHardProc = settings.hasHardProc() || doLHA;
748  if (doSoftQCD && doHardProc) {
749  infoPrivate.errorMsg("Warning from Pythia::init: "
750  "should not combine softQCD processes with hard ones");
751  }
752  if (doVarEcm) doMomentumSpread = false;
753  if (doVarEcm && doHardProc) {
754  infoPrivate.errorMsg("Abort from Pythia::init: "
755  "variable energy only works for softQCD processes");
756  return false;
757  }
758 
759  // Find out if beams are or have a resolved photon beam.
760  // The PDF:lepton2gamma is kept for backwards compatibility, now
761  // beamA2gamma and beamB2gamma are the master switches.
762  bool lepton2gamma = settings.flag("PDF:lepton2gamma");
763  if (lepton2gamma && ( abs(idA) == 11 || abs(idA) == 13 || abs(idA) == 15 ))
764  settings.flag("PDF:beamA2gamma", true);
765  if (lepton2gamma && ( abs(idB) == 11 || abs(idB) == 13 || abs(idB) == 15 ))
766  settings.flag("PDF:beamB2gamma", true);
767  beamA2gamma = settings.flag("PDF:beamA2gamma");
768  beamB2gamma = settings.flag("PDF:beamB2gamma");
769  gammaMode = settings.mode("Photon:ProcessType");
770 
771  // Check if resolved photons are needed.
772  beamAResGamma = (beamA2gamma || idA == 22)
773  && ( (gammaMode == 1) || (gammaMode == 2) || (gammaMode == 0) );
774  beamBResGamma = (beamB2gamma || idB == 22)
775  && ( (gammaMode == 1) || (gammaMode == 3) || (gammaMode == 0) );
776 
777  // Check if unresolved photons are needed.
778  beamAUnresGamma = (beamA2gamma || idA == 22)
779  && ( (gammaMode == 4) || (gammaMode == 3) || (gammaMode == 0) );
780  beamBUnresGamma = (beamB2gamma || idB == 22)
781  && ( (gammaMode == 4) || (gammaMode == 2) || (gammaMode == 0) );
782 
783  // Check if VMD sampling is required for beam A and/or B.
784  doVMDsideA = doSoftQCD && beamAResGamma;
785  doVMDsideB = doSoftQCD && beamBResGamma;
786 
787  // Turn off central diffraction for VMD processes.
788  if (doVMDsideA || doVMDsideB) {
789  if (doCentralDiff) {
790  infoPrivate.errorMsg("Warning in Pythia::init: "
791  "Central diffractive events not implemented for gamma + p/gamma");
792  return false;
793  }
794  if (doSoftQCDall) {
795  infoPrivate.errorMsg("Warning in Pythia::init: "
796  "Central diffractive events not implemented for gamma + p/gamma");
797  settings.flag("SoftQCD:all", false);
798  settings.flag("SoftQCD:elastic", true);
799  settings.flag("SoftQCD:nonDiffractive", true);
800  settings.flag("SoftQCD:singleDiffractive", true);
801  settings.flag("SoftQCD:doubleDiffractive", true);
802  }
803  if (doSoftQCDinel) {
804  infoPrivate.errorMsg("Warning in Pythia::init: "
805  "Central diffractive events not implemented for gamma + p/gamma");
806  settings.flag("SoftQCD:inelastic", false);
807  settings.flag("SoftQCD:nonDiffractive", true);
808  settings.flag("SoftQCD:singleDiffractive", true);
809  settings.flag("SoftQCD:doubleDiffractive", true);
810  }
811  }
812 
813  // Initialise merging hooks.
814  if ( doMerging && mergingHooksPtr ) mergingHooksPtr->init();
815 
816  // Check that combinations of settings are allowed; change if not.
817  checkSettings();
818 
819  // Initialize the SM couplings (needed to initialize resonances).
820  coupSM.init( settings, &rndm );
821 
822  // Initialize SLHA interface (including SLHA/BSM couplings).
823  bool useSLHAcouplings = false;
824  slhaInterface = SLHAinterface();
825  slhaInterface.setPtr( &infoPrivate);
826  slhaInterface.init( useSLHAcouplings, particleDataBuffer );
827 
828  // Reset couplingsPtr to the correct memory address.
829  particleData.initPtrs( &infoPrivate);
830 
831  // Set headers to distinguish the two event listing kinds.
832  int startColTag = settings.mode("Event:startColTag");
833  process.init("(hard process)", &particleData, startColTag);
834  event.init("(complete event)", &particleData, startColTag);
835 
836  // Final setup stage of particle data, notably resonance widths.
837  particleData.initWidths( resonancePtrs);
838 
839  // Read in files with particle widths.
840  string dataFile = xmlPath + "HadronWidths.dat";
841  if (!hadronWidths.init(dataFile)) {
842  infoPrivate.errorMsg("Abort from Pythia::init: hadron widths unavailable");
843  return false;
844  }
845  if (!hadronWidths.check()) {
846  infoPrivate.errorMsg("Abort from Pythia::init: hadron widths are invalid");
847  return false;
848  }
849 
850  // Set up R-hadrons particle data, where relevant.
851  rHadrons.init();
852 
853  // Set up and initialize setting of parton production vertices.
854  if (doPartonVertex) {
855  if (!partonVertexPtr) partonVertexPtr = make_shared<PartonVertex>();
856  registerPhysicsBase(*partonVertexPtr);
857  partonVertexPtr->init();
858  }
859 
860  // Prepare for low-energy QCD processes.
861  doNonPert = hadronLevel.initLowEnergyProcesses();
862  if (doNonPert && !doSoftQCD && !doHardProc) doProcessLevel = false;
863 
864  // Set up and initialize the ShowerModel (if not provided by user).
865  if ( !showerModelPtr ) {
866  if ( showerModel == 2 )
867  showerModelPtr = make_shared<Vincia>();
868  else if (showerModel == 3 )
869  showerModelPtr = make_shared<Dire>();
870  else
871  showerModelPtr = make_shared<SimpleShowerModel>();
872  // Register shower model as physicsBase object (also sets pointers)
873  registerPhysicsBase(*showerModelPtr);
874  }
875 
876  // Initialise shower model
877  if ( !showerModelPtr->init(mergingPtr, mergingHooksPtr,
878  partonVertexPtr, &weightContainer) ) {
879  infoPrivate.errorMsg("Abort from Pythia::init: "
880  "Shower model failed to initialise.");
881  return false;
882  }
883 
884  // Get relevant pointers from shower models.
885  if (doMerging && showerModel != 1) {
886  mergingPtr = showerModelPtr->getMerging();
887  mergingHooksPtr = showerModelPtr->getMergingHooks();
888  }
889  timesPtr = showerModelPtr->getTimeShower();
890  timesDecPtr = showerModelPtr->getTimeDecShower();
891  spacePtr = showerModelPtr->getSpaceShower();
892 
893  // Initialize pointers in showers.
894  if (showerModel == 1 || showerModel == 3) {
895  if ( timesPtr )
896  timesPtr->initPtrs( mergingHooksPtr, partonVertexPtr,
897  &weightContainer);
898  if ( timesDecPtr && timesDecPtr != timesPtr )
899  timesDecPtr->initPtrs( mergingHooksPtr, partonVertexPtr,
900  &weightContainer);
901  if ( spacePtr )
902  spacePtr->initPtrs( mergingHooksPtr, partonVertexPtr,
903  &weightContainer);
904  }
905 
906  // At this point, the mergingPtr should be set. If that is not the
907  // case, then the initialization should be aborted.
908  if (doMerging && !mergingPtr) {
909  infoPrivate.errorMsg("Abort from Pythia::init: "
910  "Merging requested, but merging class not correctly created");
911  return false;
912  }
913 
914  // Set up values related to beam shape.
915  if (!beamShapePtr) beamShapePtr = make_shared<BeamShape>();
916  beamShapePtr->init( settings, &rndm);
917 
918  // Check that beams and beam combination can be handled.
919  if (!checkBeams()) {
920  infoPrivate.errorMsg("Abort from Pythia::init: "
921  "checkBeams initialization failed");
922  return false;
923  }
924 
925  // Simplified beam setup when no process level.
926  if (doNonPert && !doSoftQCD) {
927  if (!initKinematics()) {
928  infoPrivate.errorMsg("Abort from Pythia::init: "
929  "kinematics initialization failed");
930  return false;
931  }
932  }
933  else if (!doProcessLevel) boostType = 1;
934 
935  // Full beam setup: first beam kinematics.
936  else {
937  if (!initKinematics()) {
938  infoPrivate.errorMsg("Abort from Pythia::init: "
939  "kinematics initialization failed");
940  return false;
941  }
942 
943  // Set up pointers to PDFs.
944  if (!initPDFs()) {
945  infoPrivate.errorMsg
946  ("Abort from Pythia::init: PDF initialization failed");
947  return false;
948  }
949 
950  // Set up the two beams and the common remnant system.
951  StringFlav* flavSelPtr = hadronLevel.getStringFlavPtr();
952  beamA.init( idA, pzAcm, eA, mA, pdfAPtr, pdfHardAPtr,
953  isUnresolvedA, flavSelPtr);
954  beamB.init( idB, pzBcm, eB, mB, pdfBPtr, pdfHardBPtr,
955  isUnresolvedB, flavSelPtr);
956 
957  // Pass information whether the beam will contain a photon beam.
958  if (beamA2gamma) beamA.initGammaInBeam();
959  if (beamB2gamma) beamB.initGammaInBeam();
960 
961  // Init also unresolved PDF pointers for photon beams when needed.
962  if (beamAUnresGamma) beamA.initUnres( pdfUnresAPtr);
963  if (beamBUnresGamma) beamB.initUnres( pdfUnresBPtr);
964 
965  // Optionally set up new alternative beams for these Pomerons.
966  if ( doDiffraction || doHardDiff ) {
967  beamPomA.init( 990, 0.5 * eCM, 0.5 * eCM, 0., pdfPomAPtr, pdfPomAPtr,
968  false, flavSelPtr);
969  beamPomB.init( 990, -0.5 * eCM, 0.5 * eCM, 0., pdfPomBPtr, pdfPomBPtr,
970  false, flavSelPtr);
971  }
972 
973  // Initialise VMD beams from gammas (in leptons). Use pion PDF for VMDs.
974  if (doVMDsideA)
975  beamVMDA.init( 111, 0.5 * eCM, 0.5 * eCM, 0., pdfVMDAPtr, pdfVMDAPtr,
976  false, flavSelPtr);
977  if (doVMDsideB)
978  beamVMDB.init( 111, 0.5 * eCM, 0.5 * eCM, 0., pdfVMDBPtr, pdfVMDBPtr,
979  false, flavSelPtr);
980 
981  // Optionally set up photon beams from lepton beams if resolved photons.
982  if ( !(beamA.isGamma()) && beamA2gamma) {
983  if ( gammaMode < 4 ) {
984  beamGamA.init( 22, 0.5 * eCM, 0.5 * eCM, 0.,
985  pdfGamAPtr, pdfHardGamAPtr, false, flavSelPtr);
986  }
987  if ( beamAUnresGamma ) beamGamA.initUnres( pdfUnresGamAPtr);
988  }
989  if ( !(beamB.isGamma()) && beamB2gamma) {
990  if ( gammaMode < 4 ) {
991  beamGamB.init( 22, -0.5 * eCM, 0.5 * eCM, 0.,
992  pdfGamBPtr, pdfHardGamBPtr, false, flavSelPtr);
993  }
994  if ( beamBUnresGamma ) beamGamB.initUnres( pdfUnresGamBPtr);
995  }
996 
997  }
998 
999  // Send info/pointers to process level for initialization.
1000  if ( doProcessLevel ) {
1001  sigmaTot.init();
1002  if (!processLevel.init(doLHA, &slhaInterface, sigmaPtrs, phaseSpacePtrs)) {
1003  infoPrivate.errorMsg("Abort from Pythia::init: "
1004  "processLevel initialization failed");
1005  return false;
1006  }
1007  }
1008 
1009  // Initialize shower handlers using intialized beams.
1010  if (!showerModelPtr->initAfterBeams()) {
1011  string message = "Abort in Pythia::init: Fail to initialize ";
1012  if (showerModel==1) message += "default";
1013  else if (showerModel==2) message += "Vincia";
1014  else if (showerModel==3) message += "Dire";
1015  message += " shower.";
1016  infoPrivate.errorMsg(message);
1017  return false;
1018  }
1019 
1020  // Initialize timelike showers already here, since needed in decays.
1021  // The pointers to the beams are needed by some external plugin showers.
1022  timesDecPtr->init( &beamA, &beamB);
1023 
1024  // Alternatively only initialize resonance decays.
1025  if ( !doProcessLevel) processLevel.initDecays(lhaUpPtr);
1026 
1027  // Send info/pointers to parton level for initialization.
1028  if ( doPartonLevel && doProcessLevel && !partonLevel.init(timesDecPtr,
1029  timesPtr, spacePtr, &rHadrons, mergingHooksPtr,
1030  partonVertexPtr, stringInteractionsPtr, false) ) {
1031  infoPrivate.errorMsg("Abort from Pythia::init: "
1032  "partonLevel initialization failed" );
1033  return false;
1034  }
1035 
1036  // Make pointer to shower available for merging machinery.
1037  if ( doMerging && mergingHooksPtr )
1038  mergingHooksPtr->setShowerPointer(&partonLevel);
1039 
1040  // Alternatively only initialize final-state showers in resonance decays.
1041  if ( !doProcessLevel || !doPartonLevel) partonLevel.init(
1042  timesDecPtr, nullptr, nullptr, &rHadrons, nullptr,
1043  partonVertexPtr, stringInteractionsPtr, false);
1044 
1045  // Set up shower variation groups if enabled
1046  bool doVariations = flag("UncertaintyBands:doVariations");
1047  if ( doVariations && showerModel==1 ) weightContainer.weightsPS.
1048  initAutomatedVariationGroups(true);
1049 
1050  // Send info/pointers to parton level for trial shower initialization.
1051  if ( doMerging && !trialPartonLevel.init( timesDecPtr, timesPtr,
1052  spacePtr, &rHadrons, mergingHooksPtr, partonVertexPtr,
1053  stringInteractionsPtr, true) ) {
1054  infoPrivate.errorMsg("Abort from Pythia::init: "
1055  "trialPartonLevel initialization failed");
1056  return false;
1057  }
1058 
1059  // Initialise the merging wrapper class.
1060  if (doMerging && mergingPtr && mergingHooksPtr) {
1061  mergingPtr->initPtrs( mergingHooksPtr, &trialPartonLevel);
1062  mergingPtr->init();
1063  }
1064 
1065  // Send info/pointers to hadron level for initialization.
1066  // Note: forceHadronLevel() can come, so we must always initialize.
1067  if ( !hadronLevel.init( timesDecPtr, &rHadrons, decayHandlePtr,
1068  handledParticles, stringInteractionsPtr, partonVertexPtr) ) {
1069  infoPrivate.errorMsg("Abort from Pythia::init: "
1070  "hadronLevel initialization failed");
1071  return false;
1072  }
1073 
1074  // Optionally check particle data table for inconsistencies.
1075  if ( settings.flag("Check:particleData") )
1076  particleData.checkTable( settings.mode("Check:levelParticleData") );
1077 
1078  // Optionally show settings and particle data, changed or all.
1079  bool showCS = settings.flag("Init:showChangedSettings");
1080  bool showAS = settings.flag("Init:showAllSettings");
1081  bool showCPD = settings.flag("Init:showChangedParticleData");
1082  bool showCRD = settings.flag("Init:showChangedResonanceData");
1083  bool showAPD = settings.flag("Init:showAllParticleData");
1084  int show1PD = settings.mode("Init:showOneParticleData");
1085  bool showPro = settings.flag("Init:showProcesses");
1086  if (showCS) settings.listChanged();
1087  if (showAS) settings.listAll();
1088  if (show1PD > 0) particleData.list(show1PD);
1089  if (showCPD) particleData.listChanged(showCRD);
1090  if (showAPD) particleData.listAll();
1091 
1092  // Listing options for the next() routine.
1093  nCount = settings.mode("Next:numberCount");
1094  nShowLHA = settings.mode("Next:numberShowLHA");
1095  nShowInfo = settings.mode("Next:numberShowInfo");
1096  nShowProc = settings.mode("Next:numberShowProcess");
1097  nShowEvt = settings.mode("Next:numberShowEvent");
1098  showSaV = settings.flag("Next:showScaleAndVertex");
1099  showMaD = settings.flag("Next:showMothersAndDaughters");
1100 
1101  // Init junction splitting.
1102  junctionSplitting.init();
1103 
1104  // Flags for colour reconnection.
1105  doReconnect = settings.flag("ColourReconnection:reconnect");
1106  reconnectMode = settings.mode("ColourReconnection:mode");
1107  forceHadronLevelCR = settings.flag("ColourReconnection:forceHadronLevelCR");
1108  if ( doReconnect ) colourReconnectionPtr =
1109  stringInteractionsPtr->getColourReconnections();
1110 
1111  // Succeeded.
1112  isInit = true;
1113  infoPrivate.addCounter(2);
1114  if (useNewLHA && showPro) lhaUpPtr->listInit();
1115  return true;
1116 
1117 }
1118 
1119 //--------------------------------------------------------------------------
1120 
1121 // Check that combinations of settings are allowed; change if not.
1122 
1123 void Pythia::checkSettings() {
1124 
1125  // Double rescattering not allowed if ISR or FSR.
1126  if ((settings.flag("PartonLevel:ISR") || settings.flag("PartonLevel:FSR"))
1127  && settings.flag("MultipartonInteractions:allowDoubleRescatter")) {
1128  infoPrivate.errorMsg("Warning in Pythia::checkSettings: "
1129  "double rescattering switched off since showering is on");
1130  settings.flag("MultipartonInteractions:allowDoubleRescatter", false);
1131  }
1132 
1133  // Optimize settings for collisions with direct photon(s).
1134  if ( beamA2gamma || beamB2gamma || (idA == 22) || (idB == 22) ) {
1135  if ( settings.flag("PartonLevel:MPI") && (gammaMode > 1) ) {
1136  infoPrivate.errorMsg("Warning in Pythia::checkSettings: "
1137  "MPIs turned off for collision with unresolved photon");
1138  settings.flag("PartonLevel:MPI", false);
1139  }
1140  if ( settings.flag("SoftQCD:nonDiffractive") && (gammaMode > 1) ) {
1141  infoPrivate.errorMsg("Warning in Pythia::checkSettings: "
1142  "Soft QCD processes turned off for collision with unresolved photon");
1143  settings.flag("SoftQCD:nonDiffractive", false);
1144  }
1145  }
1146 
1147 }
1148 
1149 //--------------------------------------------------------------------------
1150 
1151 // Check that beams and beam combination can be handled. Set up unresolved.
1152 
1153 bool Pythia::checkBeams() {
1154 
1155  // Absolute flavours. If not to do process level then no check needed.
1156  int idAabs = abs(idA);
1157  int idBabs = abs(idB);
1158  if (!doProcessLevel) return true;
1159 
1160  // Special case for low-energy nonperturbative processes.
1161  if (doNonPert) {
1162  if (!particleData.isHadron(idA) || !particleData.isHadron(idB)) {
1163  infoPrivate.errorMsg("Error in Pythia::checkBeams: non-perturbative "
1164  "processes are defined only for hadron-hadron collisions.");
1165  return false;
1166  }
1167  if (particleData.m0(idA) + particleData.m0(idB) > eCM) {
1168  infoPrivate.errorMsg("Error in Pythia::checkBeams: beam particles "
1169  "have higher mass than eCM");
1170  return false;
1171  }
1172  return true;
1173  }
1174 
1175  // Neutrino beams always unresolved, charged lepton ones conditionally.
1176  bool isLeptonA = (idAabs > 10 && idAabs < 17);
1177  bool isLeptonB = (idBabs > 10 && idBabs < 17);
1178  bool isUnresLep = !settings.flag("PDF:lepton");
1179  bool isGammaA = idAabs == 22;
1180  bool isGammaB = idBabs == 22;
1181  isUnresolvedA = (isLeptonA && isUnresLep);
1182  isUnresolvedB = (isLeptonB && isUnresLep);
1183 
1184  // Also photons may be unresolved.
1185  if ( idAabs == 22 && !beamAResGamma ) isUnresolvedA = true;
1186  if ( idBabs == 22 && !beamBResGamma ) isUnresolvedB = true;
1187 
1188  // But not if resolved photons present.
1189  if ( beamAResGamma ) isUnresolvedA = false;
1190  if ( beamBResGamma ) isUnresolvedB = false;
1191 
1192  // Equate Dark Matter "beams" with incoming neutrinos.
1193  if (idAabs > 50 && idAabs < 61) isLeptonA = isUnresolvedA = true;
1194  if (idBabs > 50 && idBabs < 61) isLeptonB = isUnresolvedB = true;
1195 
1196  // Photon-initiated processes.
1197  if ( beamA2gamma || beamB2gamma || isGammaA || isGammaB ) {
1198 
1199  // No photon inside photon beams.
1200  if ( (beamA2gamma && isGammaA) || (beamB2gamma && isGammaB) ) {
1201  infoPrivate.errorMsg
1202  ("Error in Pythia::init: Not possible to have a photon sub-beam"
1203  " within a photon beam");
1204  return false;
1205  }
1206 
1207  // Only gm+gm in lepton+lepton collisions.
1208  if ( isLeptonA && isLeptonB && ( !beamA2gamma || !beamB2gamma ) ) {
1209  infoPrivate.errorMsg("Error in Pythia::init: DIS with resolved"
1210  " photons currently not supported");
1211  return false;
1212  }
1213 
1214  // Photon beam and photon sub-beam not simultaneously allowed.
1215  if ( ( beamA2gamma && isGammaB ) || ( beamB2gamma && isGammaA ) ) {
1216  infoPrivate.errorMsg("Error in Pythia::init: Photoproduction"
1217  " together with pure photon beam currently not supported");
1218  return false;
1219  }
1220 
1221  // Allow soft QCD processes only when no direct photons present.
1222  bool isSoft = settings.flag("SoftQCD:all")
1223  || settings.flag("SoftQCD:nonDiffractive")
1224  || settings.flag("SoftQCD:elastic")
1225  || settings.flag("SoftQCD:singleDiffractive")
1226  || settings.flag("SoftQCD:DoubleDiffractive")
1227  || settings.flag("SoftQCD:CentralDiffractive")
1228  || settings.flag("SoftQCD:inelastic");
1229  if (isSoft) {
1230  if ( ( (beamA2gamma || isGammaA) && !beamAResGamma )
1231  || ( (beamB2gamma || isGammaB) && !beamBResGamma ) ) {
1232  infoPrivate.errorMsg("Error in Pythia::init: Soft QCD only with"
1233  " resolved photons");
1234  return false;
1235 
1236  // Soft processes OK with resolved photons and hadrons.
1237  } else {
1238  return true;
1239  }
1240 
1241  // Otherwise OK.
1242  } else {
1243  return true;
1244  }
1245  }
1246 
1247  // Lepton-lepton collisions.
1248  if (isLeptonA && isLeptonB ) {
1249 
1250  // Lepton-lepton collisions OK (including neutrinos) if both (un)resolved
1251  if (isUnresolvedA == isUnresolvedB) return true;
1252  }
1253 
1254  // MBR model only implemented for pp/ppbar/pbarp collisions.
1255  int PomFlux = settings.mode("SigmaDiffractive:PomFlux");
1256  if (PomFlux == 5) {
1257  bool ispp = (idAabs == 2212 && idBabs == 2212);
1258  bool ispbarpbar = (idA == -2212 && idB == -2212);
1259  if (ispp && !ispbarpbar) return true;
1260  infoPrivate.errorMsg("Error in Pythia::init: cannot handle this beam"
1261  " combination with PomFlux == 5");
1262  return false;
1263  }
1264 
1265  // Hadron-hadron collisions OK, with Pomeron counted as hadron.
1266  bool isHadronA = (idAabs == 2212) || (idAabs == 2112) || (idA == 111)
1267  || (idAabs == 211) || (idA == 990);
1268  bool isHadronB = (idBabs == 2212) || (idBabs == 2112) || (idB == 111)
1269  || (idBabs == 211) || (idB == 990);
1270  int modeUnresolvedHadron = settings.mode("BeamRemnants:unresolvedHadron");
1271  if (isHadronA && modeUnresolvedHadron%2 == 1) isUnresolvedA = true;
1272  if (isHadronB && modeUnresolvedHadron > 1) isUnresolvedB = true;
1273  if (isHadronA && isHadronB) return true;
1274 
1275  // Lepton-hadron collisions OK for DIS processes or LHEF input,
1276  // although still primitive.
1277  if ( (isLeptonA && isHadronB) || (isHadronA && isLeptonB) ) {
1278  bool doDIS = settings.flag("WeakBosonExchange:all")
1279  || settings.flag("WeakBosonExchange:ff2ff(t:gmZ)")
1280  || settings.flag("WeakBosonExchange:ff2ff(t:W)")
1281  || !settings.flag("Check:beams")
1282  || (frameType == 4);
1283  if (doDIS) return true;
1284  }
1285 
1286  // Allow to explicitly omit beam check for LHEF input.
1287  if ( settings.mode("Beams:frameType") == 4
1288  && !settings.flag("Check:beams")) return true;
1289 
1290  // If no case above then failed.
1291  infoPrivate.errorMsg("Error in Pythia::init: cannot handle this beam"
1292  " combination");
1293  return false;
1294 
1295 }
1296 
1297 //--------------------------------------------------------------------------
1298 
1299 // Calculate kinematics at initialization. Store beam four-momenta.
1300 
1301 bool Pythia::initKinematics() {
1302 
1303  // Find masses. Initial guess that we are in CM frame.
1304  mA = particleData.m0(idA);
1305  mB = particleData.m0(idB);
1306  betaZ = 0.;
1307  gammaZ = 1.;
1308 
1309  // Collinear beams not in CM frame: find CM energy.
1310  if (boostType == 2) {
1311  eA = max(eA, mA);
1312  eB = max(eB, mB);
1313  pzA = sqrt(eA*eA - mA*mA);
1314  pzB = -sqrt(eB*eB - mB*mB);
1315  pAinit = Vec4( 0., 0., pzA, eA);
1316  pBinit = Vec4( 0., 0., pzB, eB);
1317  eCM = sqrt( pow2(eA + eB) - pow2(pzA + pzB) );
1318 
1319  // Find boost to rest frame.
1320  betaZ = (pzA + pzB) / (eA + eB);
1321  gammaZ = (eA + eB) / eCM;
1322  if (abs(betaZ) < 1e-10) boostType = 1;
1323  }
1324 
1325  // Completely general beam directions: find CM energy.
1326  else if (boostType == 3) {
1327  eA = sqrt( pxA*pxA + pyA*pyA + pzA*pzA + mA*mA);
1328  eB = sqrt( pxB*pxB + pyB*pyB + pzB*pzB + mB*mB);
1329  pAinit = Vec4( pxA, pyA, pzA, eA);
1330  pBinit = Vec4( pxB, pyB, pzB, eB);
1331  eCM = (pAinit + pBinit).mCalc();
1332 
1333  // Find boost+rotation needed to move from/to CM frame.
1334  MfromCM.reset();
1335  MfromCM.fromCMframe( pAinit, pBinit);
1336  MtoCM = MfromCM;
1337  MtoCM.invert();
1338  }
1339 
1340  // Fail if CM energy below beam masses.
1341  if (eCM < mA + mB) {
1342  infoPrivate.errorMsg("Error in Pythia::initKinematics: too low energy");
1343  return false;
1344  }
1345 
1346  // Set up CM-frame kinematics with beams along +-z axis.
1347  pzAcm = 0.5 * sqrtpos( (eCM + mA + mB) * (eCM - mA - mB)
1348  * (eCM - mA + mB) * (eCM + mA - mB) ) / eCM;
1349  pzBcm = -pzAcm;
1350  eA = sqrt(mA*mA + pzAcm*pzAcm);
1351  eB = sqrt(mB*mB + pzBcm*pzBcm);
1352 
1353  // If in CM frame then store beam four-vectors (else already done above).
1354  if (boostType != 2 && boostType != 3) {
1355  pAinit = Vec4( 0., 0., pzAcm, eA);
1356  pBinit = Vec4( 0., 0., pzBcm, eB);
1357  }
1358 
1359  // Store main info for access in process generation.
1360  infoPrivate.setBeamA( idA, pzAcm, eA, mA);
1361  infoPrivate.setBeamB( idB, pzBcm, eB, mB);
1362  infoPrivate.setECM( eCM);
1363 
1364  // Must allow for generic boost+rotation when beam momentum spread.
1365  if (doMomentumSpread) boostType = 3;
1366 
1367  // Done.
1368  return true;
1369 
1370 }
1371 
1372 //--------------------------------------------------------------------------
1373 
1374 // Set up pointers to PDFs.
1375 
1376 bool Pythia::initPDFs() {
1377 
1378  // Optionally set up photon PDF's for lepton -> gamma collisions. Done before
1379  // the main PDFs so that the gamma pointer can be used for the main PDF
1380  // (lepton). Both set also in case that only one of the photons is resolved.
1381  bool setupGammaBeams = ( (beamA2gamma || beamB2gamma) && (gammaMode < 4) );
1382  if (setupGammaBeams) {
1383  if ( beamA2gamma && pdfGamAPtr == 0 ) {
1384  pdfGamAPtr = getPDFPtr(22, 1, "A");
1385  if (!pdfGamAPtr->isSetup()) return false;
1386 
1387  // Set also unresolved photon beam when also unresolved photons.
1388  if (gammaMode != 1) {
1389  pdfUnresGamAPtr = getPDFPtr(22, 1, "A", false);
1390  if (!pdfUnresGamAPtr->isSetup()) return false;
1391  }
1392 
1393  // Set up optional hard photon PDF pointers.
1394  if (settings.flag("PDF:useHard")) {
1395  pdfHardGamAPtr = getPDFPtr(22, 2);
1396  if (!pdfHardGamAPtr->isSetup()) return false;
1397  } else pdfHardGamAPtr = pdfGamAPtr;
1398  }
1399  if ( beamB2gamma && pdfGamBPtr == 0 ) {
1400  pdfGamBPtr = getPDFPtr(22, 1, "B");
1401  if (!pdfGamBPtr->isSetup()) return false;
1402 
1403  // Set also unresolved photon beam when also unresolved photons.
1404  if (gammaMode != 1) {
1405  pdfUnresGamBPtr = getPDFPtr(22, 1, "B", false);
1406  if (!pdfUnresGamBPtr->isSetup()) return false;
1407  }
1408 
1409  // Set up optional hard photon PDF pointers.
1410  if (settings.flag("PDF:useHard")) {
1411  pdfHardGamBPtr = getPDFPtr(22, 2, "B");
1412  if (!pdfHardGamBPtr->isSetup()) return false;
1413  } else pdfHardGamBPtr = pdfGamBPtr;
1414  }
1415  }
1416 
1417  // Set up the PDF's, if not already done.
1418  if (pdfAPtr == 0) {
1419  pdfAPtr = getPDFPtr(idA);
1420  if (pdfAPtr == 0 || !pdfAPtr->isSetup()) {
1421  infoPrivate.errorMsg("Error in Pythia::init: "
1422  "could not set up PDF for beam A");
1423  return false;
1424  }
1425  pdfHardAPtr = pdfAPtr;
1426  }
1427  if (pdfBPtr == 0) {
1428  pdfBPtr = getPDFPtr(idB, 1, "B");
1429  if (pdfBPtr == 0 || !pdfBPtr->isSetup()) {
1430  infoPrivate.errorMsg("Error in Pythia::init: "
1431  "could not set up PDF for beam B");
1432  return false;
1433  }
1434  pdfHardBPtr = pdfBPtr;
1435  }
1436 
1437  // Optionally set up separate PDF's for hard process.
1438  if (settings.flag("PDF:useHard")) {
1439  pdfHardAPtr = getPDFPtr(idA, 2);
1440  if (!pdfHardAPtr->isSetup()) return false;
1441  pdfHardBPtr = getPDFPtr(idB, 2, "B");
1442  if (!pdfHardBPtr->isSetup()) return false;
1443  }
1444 
1445  // Optionally use nuclear modifications for hard process PDFs.
1446  if (settings.flag("PDF:useHardNPDFA")) {
1447  int idANucleus = settings.mode("PDF:nPDFBeamA");
1448  pdfHardAPtr = getPDFPtr(idANucleus, 2, "A");
1449  if (!pdfHardAPtr->isSetup()) {
1450  infoPrivate.errorMsg("Error in Pythia::init: "
1451  "could not set up nuclear PDF for beam A");
1452  return false;
1453  }
1454  }
1455  if (settings.flag("PDF:useHardNPDFB")) {
1456  int idBNucleus = settings.mode("PDF:nPDFBeamB");
1457  pdfHardBPtr = getPDFPtr(idBNucleus, 2, "B");
1458  if (!pdfHardBPtr->isSetup()) {
1459  infoPrivate.errorMsg("Error in Pythia::init: "
1460  "could not set up nuclear PDF for beam B");
1461  return false;
1462  }
1463  }
1464 
1465  // Set up additional unresolved PDFs for photon beams when relevant.
1466  if ( (idA == 22 || beamA2gamma) && (gammaMode != 1 && gammaMode != 2) ) {
1467  if ( pdfUnresAPtr == 0 ) {
1468  pdfUnresAPtr = getPDFPtr(idA, 1, "A", false);
1469  if (!pdfUnresAPtr->isSetup()) return false;
1470  }
1471  }
1472  if ( (idB == 22 || beamB2gamma) && (gammaMode != 1 && gammaMode != 3) ) {
1473  if ( pdfUnresBPtr == 0 ) {
1474  pdfUnresBPtr = getPDFPtr(idB, 1, "B", false);
1475  if (!pdfUnresBPtr->isSetup()) return false;
1476  }
1477  }
1478 
1479  // Optionally set up Pomeron PDF's for diffractive physics.
1480  if ( doDiffraction || doHardDiff) {
1481  if (pdfPomAPtr == 0) {
1482  pdfPomAPtr = getPDFPtr(990);
1483  }
1484  if (pdfPomBPtr == 0) {
1485  pdfPomBPtr = getPDFPtr(990);
1486  }
1487  }
1488 
1489  // Optionally set up VMD PDF's for photon physics.
1490  if ( doSoftQCD && (doVMDsideA || doVMDsideB)) {
1491  if (pdfVMDAPtr == 0) {
1492  pdfVMDAPtr = getPDFPtr(111);
1493  }
1494  if (pdfVMDBPtr == 0) {
1495  pdfVMDBPtr = getPDFPtr(111);
1496  }
1497  }
1498 
1499  // Done.
1500  return true;
1501 
1502 }
1503 
1504 //--------------------------------------------------------------------------
1505 
1506 // Main routine to generate the next event, using internal machinery.
1507 
1508 bool Pythia::next() {
1509 
1510  // Check that constructor worked.
1511  if (!isConstructed) {
1512  endEvent(PhysicsBase::CONSTRUCTOR_FAILED);
1513  return false;
1514  }
1515 
1516  // Flexible-use call at the beginning of each new event.
1517  beginEvent();
1518 
1519  // Check if the generation is taken over by the HeavyIons object.
1520  // Allows HeavyIons::next to call next for this Pythia object
1521  // without going into a loop.
1522  if ( doHeavyIons ) {
1523  doHeavyIons = false;
1524  bool ok = heavyIonsPtr->next();
1525  doHeavyIons = true;
1526  endEvent(ok ? PhysicsBase::COMPLETE : PhysicsBase::HEAVYION_FAILED);
1527  return ok;
1528  }
1529 
1530  // Regularly print how many events have been generated.
1531  int nPrevious = infoPrivate.getCounter(3);
1532  if (nCount > 0 && nPrevious > 0 && nPrevious%nCount == 0)
1533  cout << "\n Pythia::next(): " << nPrevious
1534  << " events have been generated " << endl;
1535 
1536  // Set/reset info counters specific to each event.
1537  infoPrivate.addCounter(3);
1538  for (int i = 10; i < 13; ++i) infoPrivate.setCounter(i);
1539 
1540  // Simpler option when no hard process, i.e. mainly hadron level.
1541  if (!doProcessLevel && !doNonPert) {
1542  // Optionally fetch in resonance decays from LHA interface.
1543  if (doLHA && !processLevel.nextLHAdec( event)) {
1544  if (infoPrivate.atEndOfFile()) infoPrivate.errorMsg
1545  ("Abort from Pythia::next:"
1546  " reached end of Les Houches Events File");
1547  endEvent(PhysicsBase::LHEF_END);
1548  return false;
1549  }
1550 
1551  // Reset info and partonSystems arrays (while event record contains data).
1552  infoPrivate.clear();
1553  weightContainer.clear();
1554  partonSystems.clear();
1555 
1556  // Set correct energy for system.
1557  Vec4 pSum = 0.;
1558  for (int i = 1; i < event.size(); ++i)
1559  if (event[i].isFinal()) pSum += event[i].p();
1560  event[0].p( pSum );
1561  event[0].m( pSum.mCalc() );
1562 
1563  // Generate parton showers where appropriate.
1564  if (doFSRinRes) {
1565  process = event;
1566  process.init("(hard process)", &particleData);
1567  partonLevel.setupShowerSys( process, event);
1568  partonLevel.resonanceShowers( process, event, true);
1569  }
1570 
1571  // Generate hadronization and decays.
1572  bool status = (doHadronLevel) ? forceHadronLevel() : true;
1573  if (status) infoPrivate.addCounter(4);
1574  if (doLHA && nPrevious < nShowLHA) lhaUpPtr->listEvent();
1575  if (doFSRinRes && nPrevious < nShowProc) process.list(showSaV, showMaD);
1576  if (status && nPrevious < nShowEvt) event.list(showSaV, showMaD);
1577  endEvent(status ? PhysicsBase::COMPLETE : PhysicsBase::HADRONLEVEL_FAILED);
1578  return status;
1579  }
1580 
1581  // Reset arrays.
1582  infoPrivate.clear();
1583  weightContainer.clear();
1584  process.clear();
1585  event.clear();
1586  partonSystems.clear();
1587  beamA.clear();
1588  beamB.clear();
1589  beamPomA.clear();
1590  beamPomB.clear();
1591  beamGamA.clear();
1592  beamGamB.clear();
1593  beamVMDA.clear();
1594  beamVMDB.clear();
1595 
1596  // Pick current beam valence flavours (for pi0, K0S, K0L, Pomeron).
1597  beamA.newValenceContent();
1598  beamB.newValenceContent();
1599  if ( doDiffraction || doHardDiff) {
1600  beamPomA.newValenceContent();
1601  beamPomB.newValenceContent();
1602  }
1603  if (doVMDsideA) beamVMDA.newValenceContent();
1604  if (doVMDsideB) beamVMDB.newValenceContent();
1605 
1606  // Can only generate event if initialization worked.
1607  if (!isInit) {
1608  infoPrivate.errorMsg("Abort from Pythia::next: "
1609  "not properly initialized so cannot generate events");
1610  endEvent(PhysicsBase::INIT_FAILED);
1611  return false;
1612  }
1613 
1614  // Pick beam momentum spread and beam vertex.
1615  if (doMomentumSpread || doVertexSpread) beamShapePtr->pick();
1616 
1617  // Recalculate kinematics when beam momentum spread.
1618  if (doMomentumSpread || doVarEcm) nextKinematics();
1619 
1620  // Simplified special treatment for low-energy nonperturbative collisions.
1621  double pertRate = (eCM - eMinPert) / eWidthPert;
1622  if ( (doNonPert && !doSoftQCD)
1623  || ( doVarEcm && pertRate < 10
1624  && (pertRate <= 0 || exp( -pertRate ) > rndm.flat())) ) {
1625  bool nextNP = nextNonPert();
1626 
1627  // Optionally check final event for problems.
1628  if (nextNP && checkEvent && !check()) {
1629  infoPrivate.errorMsg("Error in Pythia::next: "
1630  "check of event revealed problems");
1631  endEvent(PhysicsBase::CHECK_FAILED);
1632  return false;
1633  }
1634  endEvent(nextNP ? PhysicsBase::COMPLETE : PhysicsBase::LOWENERGY_FAILED);
1635  return nextNP;
1636  }
1637 
1638  // Outer loop over hard processes; only relevant for user-set vetoes.
1639  for ( ; ; ) {
1640 
1641  infoPrivate.addCounter(10);
1642  bool hasVetoed = false;
1643  bool hasVetoedDiff = false;
1644 
1645  // Provide the hard process that starts it off. Only one try.
1646  infoPrivate.clear();
1647  process.clear();
1648  partonSystems.clear();
1649 
1650  // Reset the event information. Necessary if the previous event was read
1651  // from LHEF, while the current event is not read from LHEF.
1652  infoPrivate.setLHEF3EventInfo();
1653 
1654  if ( !processLevel.next( process) ) {
1655  if (doLHA && infoPrivate.atEndOfFile()) infoPrivate.errorMsg
1656  ("Abort from "
1657  "Pythia::next: reached end of Les Houches Events File");
1658  else infoPrivate.errorMsg("Abort from Pythia::next: "
1659  "processLevel failed; giving up");
1660  endEvent(PhysicsBase::PROCESSLEVEL_FAILED);
1661  return false;
1662  }
1663 
1664  infoPrivate.addCounter(11);
1665 
1666  // Update tried and selected events immediately after next event was
1667  // generated. Note: This does not accumulate cross section.
1668  processLevel.accumulate(false);
1669 
1670  // Possibility for a user veto of the process-level event.
1671  if (doVetoProcess) {
1672  hasVetoed = userHooksPtr->doVetoProcessLevel( process);
1673  if (hasVetoed) {
1674  if (abortIfVeto) {
1675  endEvent(PhysicsBase::PROCESSLEVEL_USERVETO);
1676  return false;
1677  }
1678  continue;
1679  }
1680  }
1681 
1682  // Possibility to perform matrix element merging for this event.
1683  if (doMerging && mergingPtr) {
1684  int veto = mergingPtr->mergeProcess( process );
1685  // Apply possible merging scale cut.
1686  if (veto == -1) {
1687  hasVetoed = true;
1688  if (abortIfVeto) {
1689  endEvent(PhysicsBase::MERGING_FAILED);
1690  return false;
1691  }
1692  continue;
1693  // Exit because of vanishing no-emission probability.
1694  } else if (veto == 0) {
1695  event = process;
1696  break;
1697  }
1698 
1699  // Redo resonance decays after the merging, in case the resonance
1700  // structure has been changed because of reclusterings.
1701  if (veto == 2 && doResDec) processLevel.nextDecays( process);
1702  }
1703 
1704  // Possibility to stop the generation at this stage.
1705  if (!doPartonLevel) {
1706  boostAndVertex( true, true);
1707  processLevel.accumulate();
1708  event.scale( process.scale() );
1709  event.scaleSecond( process.scaleSecond() );
1710  infoPrivate.addCounter(4);
1711  if (doLHA && nPrevious < nShowLHA) lhaUpPtr->listEvent();
1712  if (nPrevious < nShowInfo) infoPrivate.list();
1713  if (nPrevious < nShowProc) process.list(showSaV, showMaD);
1714  endEvent(PhysicsBase::COMPLETE);
1715  return true;
1716  }
1717 
1718  // Save spare copy of process record in case of problems.
1719  Event processSave = process;
1720  int sizeMPI = infoPrivate.sizeMPIarrays();
1721  infoPrivate.addCounter(12);
1722  for (int i = 14; i < 19; ++i) infoPrivate.setCounter(i);
1723 
1724  // Allow up to ten tries for parton- and hadron-level processing.
1725  bool physical = true;
1726  for (int iTry = 0; iTry < NTRY; ++iTry) {
1727 
1728  infoPrivate.addCounter(14);
1729  physical = true;
1730  hasVetoed = false;
1731 
1732  // Restore original process record if problems.
1733  if (iTry > 0) {
1734  process = processSave;
1735  infoPrivate.resizeMPIarrays( sizeMPI);
1736  }
1737 
1738  // Reset event record and (extracted partons from) beam remnants.
1739  event.clear();
1740  beamA.clear();
1741  beamB.clear();
1742  beamPomA.clear();
1743  beamPomB.clear();
1744  beamGamA.clear();
1745  beamGamB.clear();
1746  beamVMDA.clear();
1747  beamVMDB.clear();
1748  partonSystems.clear();
1749 
1750  // Parton-level evolution: ISR, FSR, MPI.
1751  if ( !partonLevel.next( process, event) ) {
1752 
1753  // Abort event generation if parton level is set to abort.
1754  if (infoPrivate.getAbortPartonLevel()) {
1755  endEvent(PhysicsBase::PARTONLEVEL_FAILED);
1756  return false;
1757  }
1758 
1759  // Skip to next hard process for failure owing to deliberate veto,
1760  // or alternatively retry for the same hard process.
1761  hasVetoed = partonLevel.hasVetoed();
1762  if (hasVetoed) {
1763  if (retryPartonLevel) {
1764  --iTry;
1765  continue;
1766  }
1767  if (abortIfVeto) {
1768  endEvent(PhysicsBase::PARTONLEVEL_FAILED);
1769  return false;
1770  }
1771  break;
1772  }
1773 
1774  // If hard diffractive event has been discarded retry partonLevel.
1775  hasVetoedDiff = partonLevel.hasVetoedDiff();
1776  if (hasVetoedDiff) {
1777  infoPrivate.errorMsg("Warning in Pythia::next: "
1778  "discarding hard diffractive event from partonLevel; try again");
1779  break;
1780  }
1781 
1782  // Else make a new try for other failures.
1783  infoPrivate.errorMsg("Error in Pythia::next: "
1784  "partonLevel failed; try again");
1785  physical = false;
1786  continue;
1787  }
1788  infoPrivate.addCounter(15);
1789 
1790  // Possibility for a user veto of the parton-level event.
1791  if (doVetoPartons) {
1792  hasVetoed = userHooksPtr->doVetoPartonLevel( event);
1793  if (hasVetoed) {
1794  if (abortIfVeto) {
1795  endEvent(PhysicsBase::PARTONLEVEL_USERVETO);
1796  return false;
1797  }
1798  break;
1799  }
1800  }
1801 
1802  // Boost to lab frame (before decays, for vertices).
1803  boostAndVertex( true, true);
1804 
1805  // Possibility to stop the generation at this stage.
1806  if (!doHadronLevel) {
1807  processLevel.accumulate();
1808  partonLevel.accumulate();
1809  event.scale( process.scale() );
1810  event.scaleSecond( process.scaleSecond() );
1811  // Optionally check final event for problems.
1812  if (checkEvent && !check()) {
1813  infoPrivate.errorMsg("Abort from Pythia::next: "
1814  "check of event revealed problems");
1815  endEvent(PhysicsBase::CHECK_FAILED);
1816  return false;
1817  }
1818  infoPrivate.addCounter(4);
1819  if (doLHA && nPrevious < nShowLHA) lhaUpPtr->listEvent();
1820  if (nPrevious < nShowInfo) infoPrivate.list();
1821  if (nPrevious < nShowProc) process.list(showSaV, showMaD);
1822  if (nPrevious < nShowEvt) event.list(showSaV, showMaD);
1823  endEvent(PhysicsBase::COMPLETE);
1824  return true;
1825  }
1826 
1827  // Hadron-level: hadronization, decays.
1828  infoPrivate.addCounter(16);
1829  if ( !hadronLevel.next( event) ) {
1830  infoPrivate.errorMsg("Error in Pythia::next: "
1831  "hadronLevel failed; try again");
1832  physical = false;
1833  continue;
1834  }
1835 
1836  // If R-hadrons have been formed, then (optionally) let them decay.
1837  if (decayRHadrons && rHadrons.exist() && !doRHadronDecays()) {
1838  infoPrivate.errorMsg("Error in Pythia::next: "
1839  "decayRHadrons failed; try again");
1840  physical = false;
1841  continue;
1842  }
1843  infoPrivate.addCounter(17);
1844 
1845  // Optionally check final event for problems.
1846  if (checkEvent && !check()) {
1847  infoPrivate.errorMsg("Error in Pythia::next: "
1848  "check of event revealed problems");
1849  physical = false;
1850  continue;
1851  }
1852 
1853  // Stop parton- and hadron-level looping if you got this far.
1854  infoPrivate.addCounter(18);
1855  break;
1856  }
1857 
1858  // If event vetoed then to make a new try.
1859  if (hasVetoed || hasVetoedDiff) {
1860  if (abortIfVeto) {
1861  endEvent(PhysicsBase::PARTONLEVEL_USERVETO);
1862  return false;
1863  }
1864  continue;
1865  }
1866 
1867  // If event failed any other way (after ten tries) then give up.
1868  if (!physical) {
1869  infoPrivate.errorMsg("Abort from Pythia::next: "
1870  "parton+hadronLevel failed; giving up");
1871  endEvent(PhysicsBase::OTHER_UNPHYSICAL);
1872  return false;
1873  }
1874 
1875  // Process- and parton-level statistics. Event scale.
1876  processLevel.accumulate();
1877  partonLevel.accumulate();
1878  event.scale( process.scale() );
1879  event.scaleSecond( process.scaleSecond() );
1880 
1881  // End of outer loop over hard processes. Done with normal option.
1882  infoPrivate.addCounter(13);
1883  break;
1884  }
1885 
1886  // List events.
1887  if (doLHA && nPrevious < nShowLHA) lhaUpPtr->listEvent();
1888  if (nPrevious < nShowInfo) infoPrivate.list();
1889  if (nPrevious < nShowProc) process.list(showSaV,showMaD);
1890  if (nPrevious < nShowEvt) event.list(showSaV, showMaD);
1891 
1892  // Done.
1893  infoPrivate.addCounter(4);
1894  endEvent(PhysicsBase::COMPLETE);
1895  return true;
1896 
1897 }
1898 
1899 //--------------------------------------------------------------------------
1900 
1901 // Variant of the main event-generation routine, for variable CM energies.
1902 
1903 bool Pythia::next(double eCMin) {
1904 
1905  // Check that constructor worked.
1906  if (!isConstructed) return false;
1907 
1908  // Check that generation has been initialized for variable energy.
1909  if (!doVarEcm) {
1910  infoPrivate.errorMsg("Abort from Pythia::next: "
1911  "generation not initialized for variable energies");
1912  return false;
1913  }
1914 
1915  // Check that the frameType matches the input provided.
1916  if (frameType != 1) {
1917  infoPrivate.errorMsg("Abort from Pythia::next: "
1918  "input parameters do not match frame type");
1919  return false;
1920  }
1921 
1922  // Save input value.
1923  eCM = eCMin;
1924 
1925  // Call regular next method for event generation.
1926  return next();
1927 
1928 }
1929 
1930 //--------------------------------------------------------------------------
1931 
1932 // Variant of the main event-generation routine, for variable beam energies.
1933 
1934 bool Pythia::next(double eAin, double eBin) {
1935 
1936  // Check that constructor worked.
1937  if (!isConstructed) return false;
1938 
1939  // Check that generation has been initialized for variable energy.
1940  if (!doVarEcm) {
1941  infoPrivate.errorMsg("Abort from Pythia::next: "
1942  "generation not initialized for variable energies");
1943  return false;
1944  }
1945 
1946  // Check that the frameType matches the input provided.
1947  if (frameType != 2) {
1948  infoPrivate.errorMsg("Abort from Pythia::next: "
1949  "input parameters do not match frame type");
1950  return false;
1951  }
1952 
1953  // Save input values.
1954  eA = eAin;
1955  eB = eBin;
1956 
1957  // Call regular next method for event generation.
1958  return next();
1959 
1960 }
1961 
1962 //--------------------------------------------------------------------------
1963 
1964 // Variant of the main event-generation routine, for variable beam momenta.
1965 
1966 bool Pythia::next(double pxAin, double pyAin, double pzAin,
1967  double pxBin, double pyBin, double pzBin) {
1968 
1969  // Check that constructor worked.
1970  if (!isConstructed) return false;
1971 
1972  // Check that generation has been initialized for variable energy.
1973  if (!doVarEcm) {
1974  infoPrivate.errorMsg("Abort from Pythia::next: "
1975  "generation not initialized for variable energies");
1976  return false;
1977  }
1978 
1979  // Check that the frameType matches the input provided.
1980  if (frameType != 3) {
1981  infoPrivate.errorMsg("Abort from Pythia::next: "
1982  "input parameters do not match frame type");
1983  return false;
1984  }
1985 
1986  // Save input value.
1987  pxA = pxAin;
1988  pyA = pyAin;
1989  pzA = pzAin;
1990  pxB = pxBin;
1991  pyB = pyBin;
1992  pzB = pzBin;
1993 
1994  // Call regular next method for event generation.
1995  return next();
1996 
1997 }
1998 
1999 //--------------------------------------------------------------------------
2000 
2001 // Flexible-use call at the beginning of each event in pythia.next().
2002 
2003 void Pythia::beginEvent() {
2004 
2005  // Loop through all PhysicsBase-derived objects.
2006  for ( auto physicsPtr : physicsPtrs ) physicsPtr->beginEvent();
2007 
2008  // Done.
2009  return;
2010 
2011 }
2012 
2013 //--------------------------------------------------------------------------
2014 
2015 // Flexible-use call at the end of each event in pythia.next().
2016 
2017 void Pythia::endEvent(PhysicsBase::Status status) {
2018 
2019  // Loop through all PhysicsBase-derived objects.
2020  for ( auto physicsPtr : physicsPtrs ) physicsPtr->endEvent(status);
2021 
2022  // Update the event weight by the Dire shower weight when relevant.
2023  // Code to be moved to the Dire endEvent method.
2024  /*
2025  if (useNewDire) {
2026  // Retrieve the shower weight.
2027  direPtr->weightsPtr->calcWeight(0.);
2028  direPtr->weightsPtr->reset();
2029  double pswt = direPtr->weightsPtr->getShowerWeight();
2030  // Multiply the shower weight to the event weight.
2031  double wt = infoPrivate.weight();
2032  infoPrivate.updateWeight(wt * pswt);
2033  }
2034  */
2035 
2036  // Done.
2037  return;
2038 
2039 }
2040 //--------------------------------------------------------------------------
2041 
2042 // Possibilty to set a pointer to a new object.
2043 
2044 void Pythia::pushInfo() {
2045  for ( auto physicsPtr : physicsPtrs ) physicsPtr->initInfoPtr(infoPrivate);
2046 }
2047 
2048 //--------------------------------------------------------------------------
2049 
2050 // Generate only the hadronization/decay stage, using internal machinery.
2051 // The "event" instance should already contain a parton-level configuration.
2052 
2053 bool Pythia::forceHadronLevel(bool findJunctions) {
2054 
2055  // Can only generate event if initialization worked.
2056  if (!isInit) {
2057  infoPrivate.errorMsg("Abort from Pythia::forceHadronLevel: "
2058  "not properly initialized so cannot generate events");
2059  return false;
2060  }
2061 
2062  // Check whether any junctions in system. (Normally done in ProcessLevel.)
2063  // Avoid it if there are no final-state coloured partons.
2064  if (findJunctions) {
2065  event.clearJunctions();
2066  for (int i = 0; i < event.size(); ++i)
2067  if (event[i].isFinal()
2068  && (event[i].col() != 0 || event[i].acol() != 0)) {
2069  processLevel.findJunctions( event);
2070  break;
2071  }
2072  }
2073 
2074  // Allow for CR before the hadronization.
2075  if (forceHadronLevelCR) {
2076 
2077  // Setup parton system for SK-I and SK-II colour reconnection.
2078  // Require all final state particles to have the Ws as mothers.
2079  if (reconnectMode == 3 || reconnectMode == 4) {
2080  partonSystems.clear();
2081  partonSystems.addSys();
2082  partonSystems.addSys();
2083  partonSystems.setInRes(0, 3);
2084  partonSystems.setInRes(1, 4);
2085  for (int i = 5; i < event.size(); ++i) {
2086  if (event[i].mother1() - 3 < 0 || event[i].mother1() - 3 > 1) {
2087  infoPrivate.errorMsg("Error in Pythia::forceHadronLevel: "
2088  " Event is not setup correctly for SK-I or SK-II CR");
2089  return false;
2090  }
2091  partonSystems.addOut(event[i].mother1() - 3,i);
2092  }
2093  }
2094 
2095  // save spare copy of event in case of failure.
2096  Event spareEvent = event;
2097  bool colCorrect = false;
2098 
2099  // Allow up to ten tries for CR.
2100  for (int iTry = 0; iTry < NTRY; ++ iTry) {
2101  if ( colourReconnectionPtr ) colourReconnectionPtr->next(event, 0);
2102  if (junctionSplitting.checkColours(event)) {
2103  colCorrect = true;
2104  break;
2105  }
2106  else event = spareEvent;
2107  }
2108 
2109  if (!colCorrect) {
2110  infoPrivate.errorMsg("Error in Pythia::forceHadronLevel: "
2111  "Colour reconnection failed.");
2112  return false;
2113  }
2114  }
2115 
2116  // Save spare copy of event in case of failure.
2117  Event spareEvent = event;
2118 
2119  // Allow up to ten tries for hadron-level processing.
2120  bool physical = true;
2121  for (int iTry = 0; iTry < NTRY; ++ iTry) {
2122  physical = true;
2123 
2124  // Check whether any resonances need to be handled at process level.
2125  if (doResDec) {
2126  process = event;
2127  processLevel.nextDecays( process);
2128 
2129  // Allow for showers if decays happened at process level.
2130  if (process.size() > event.size()) {
2131  if (doFSRinRes) {
2132  partonLevel.setupShowerSys( process, event);
2133  partonLevel.resonanceShowers( process, event, false);
2134  } else event = process;
2135  }
2136  }
2137 
2138  // Hadron-level: hadronization, decays.
2139  if (hadronLevel.next( event)) break;
2140 
2141  // If failure then warn, restore original configuration and try again.
2142  infoPrivate.errorMsg("Error in Pythia::forceHadronLevel: "
2143  "hadronLevel failed; try again");
2144  physical = false;
2145  event = spareEvent;
2146  }
2147 
2148  // Done for simpler option.
2149  if (!physical) {
2150  infoPrivate.errorMsg("Abort from Pythia::forceHadronLevel: "
2151  "hadronLevel failed; giving up");
2152  return false;
2153  }
2154 
2155  // Optionally check final event for problems.
2156  if (checkEvent && !check()) {
2157  infoPrivate.errorMsg("Abort from Pythia::forceHadronLevel: "
2158  "check of event revealed problems");
2159  return false;
2160  }
2161 
2162  // Done.
2163  return true;
2164 
2165 }
2166 
2167 //--------------------------------------------------------------------------
2168 
2169 // Recalculate kinematics for each event when beam momentum has a spread.
2170 
2171 void Pythia::nextKinematics() {
2172 
2173  // Momentum spread: read out momentum shift to give current beam momenta.
2174  if (doMomentumSpread) {
2175  pAnow = pAinit + beamShapePtr->deltaPA();
2176  pAnow.e( sqrt(pAnow.pAbs2() + mA*mA) );
2177  pBnow = pBinit + beamShapePtr->deltaPB();
2178  pBnow.e( sqrt(pBnow.pAbs2() + mB*mB) );
2179  eCM = (pAnow + pBnow).mCalc();
2180 
2181  // For variable energy in rest frame only need new eCM value, already set.
2182  } else if (frameType == 1) {
2183 
2184  // Variable energy but collinear beams: give current beam momenta.
2185  } else if (frameType == 2) {
2186  pAnow = Vec4( 0., 0., sqrtpos( eA*eA - mA*mA), eA);
2187  pBnow = Vec4( 0., 0., -sqrtpos( eB*eB - mB*mB), eB);
2188  eCM = (pAnow + pBnow).mCalc();
2189 
2190  // Variable three-momenta stored and energy calculated.
2191  } else if (frameType == 3) {
2192  pAnow = Vec4( pxA, pyA, pzA, sqrt(pxA*pxA + pyA*pyA + pzA*pzA + mA*mA) );
2193  pBnow = Vec4( pxB, pyB, pzB, sqrt(pxB*pxB + pyB*pyB + pzB*pzB + mB*mB) );
2194  eCM = (pAnow + pBnow).mCalc();
2195 
2196  // Other possibilites not supported.
2197  } else {
2198  infoPrivate.errorMsg("Error from Pythia::nextKinematics: unsupported"
2199  " frameType");
2200  return;
2201  }
2202 
2203  // Construct CM frame kinematics.
2204  pzAcm = 0.5 * sqrtpos( (eCM + mA + mB) * (eCM - mA - mB)
2205  * (eCM - mA + mB) * (eCM + mA - mB) ) / eCM;
2206  pzBcm = -pzAcm;
2207  eA = sqrt(mA*mA + pzAcm*pzAcm);
2208  eB = sqrt(mB*mB + pzBcm*pzBcm);
2209 
2210  // Set relevant info for other classes to use.
2211  infoPrivate.setBeamA( idA, pzAcm, eA, mA);
2212  infoPrivate.setBeamB( idB, pzBcm, eB, mB);
2213  infoPrivate.setECM( eCM);
2214  beamA.newPzE( pzAcm, eA);
2215  beamB.newPzE( pzBcm, eB);
2216 
2217  // Set boost/rotation matrices from/to CM frame.
2218  if (frameType != 1) {
2219  MfromCM.reset();
2220  MfromCM.fromCMframe( pAnow, pBnow);
2221  MtoCM = MfromCM;
2222  MtoCM.invert();
2223  }
2224 
2225 }
2226 
2227 //--------------------------------------------------------------------------
2228 
2229 // Simplified treatment for low-energy nonperturbative collisions.
2230 
2231 bool Pythia::nextNonPert() {
2232 
2233  // Fill collision instate.
2234  process.append( 90, -11, 0, 0, 0, 0, 0, 0, Vec4(0., 0., 0., eCM), eCM, 0. );
2235  process.append(idA, -12, 0, 0, 0, 0, 0, 0, Vec4(0., 0., pzAcm, eA), mA, 0. );
2236  process.append(idB, -12, 0, 0, 0, 0, 0, 0, Vec4(0., 0., pzBcm, eB), mB, 0. );
2237  for (int i = 0; i < 3; ++i) event.append( process[i] );
2238 
2239  // Pick process type.
2240  int procType = hadronLevel.pickLowEnergyProcess(idA, idB, eCM, mA, mB);
2241  int procCode = 150 + min( 9, abs(procType));
2242 
2243  if (procType == 0) {
2244  infoPrivate.errorMsg("Error in Pythia::nextNonPert: "
2245  "unable to pick process");
2246  return false;
2247  }
2248 
2249  // Do a low-energy collision.
2250  if (!doLowEnergyProcess( 1, 2, procType)) {
2251  infoPrivate.errorMsg("Error in Pythia::nextNonPert: "
2252  "low energy process failed");
2253  return false;
2254  }
2255 
2256  // Do hadron level.
2257  if (doHadronLevel) {
2258  if (!hadronLevel.next(event)) {
2259  infoPrivate.errorMsg("Error in Pythia::nextNonPert: "
2260  "Further hadron level processes failed");
2261  return false;
2262  }
2263  }
2264 
2265  // Set event info.
2266  string procName ="Low-energy ";
2267  if (procCode == 151) procName += "nonDiffractive";
2268  else if (procCode == 152) procName += "elastic";
2269  else if (procCode == 153) procName += "single diffractive (XB)";
2270  else if (procCode == 154) procName += "single diffractive (AX)";
2271  else if (procCode == 155) procName += "double diffractive";
2272  else if (procCode == 157) procName += "excitation";
2273  else if (procCode == 158) procName += "annihilation";
2274  else if (procCode == 159) procName += "resonant";
2275  infoPrivate.setType( procName, procCode, 0, (procCode == 151), false,
2276  (procCode == 153 || procCode == 155),
2277  (procCode == 154 || procCode == 155));
2278 
2279  // List events.
2280  int nPrevious = infoPrivate.getCounter(3) - 1;
2281  if (doLHA && nPrevious < nShowLHA) lhaUpPtr->listEvent();
2282  if (nPrevious < nShowInfo) infoPrivate.list();
2283  if (nPrevious < nShowProc) process.list(showSaV,showMaD);
2284  if (nPrevious < nShowEvt) event.list(showSaV, showMaD);
2285 
2286  // Done.
2287  infoPrivate.addCounter(4);
2288  return true;
2289 
2290 }
2291 
2292 //--------------------------------------------------------------------------
2293 
2294 // Boost from CM frame to lab frame, or inverse. Set production vertex.
2295 
2296 void Pythia::boostAndVertex( bool toLab, bool setVertex) {
2297 
2298  // Optionally rotate event around its axis to randomize parton vertices.
2299  if (toLab && doPartonVertex && event.size() > 2) {
2300  if (process.size() > 2) {
2301  process[1].vProd( event[1].vProd() );
2302  process[2].vProd( event[2].vProd() );
2303  }
2304  if (doVertexPlane) {
2305  double phiVert = 2. * M_PI * rndm.flat();
2306  process.rot( 0., phiVert);
2307  event.rot( 0., phiVert);
2308  }
2309  }
2310 
2311  // Boost process from CM frame to lab frame.
2312  if (toLab) {
2313  if (boostType == 2) process.bst(0., 0., betaZ, gammaZ);
2314  else if (boostType == 3) process.rotbst(MfromCM);
2315 
2316  // Boost nonempty event from CM frame to lab frame.
2317  if (event.size() > 0) {
2318  if (boostType == 2) event.bst(0., 0., betaZ, gammaZ);
2319  else if (boostType == 3) event.rotbst(MfromCM);
2320  }
2321 
2322  // Boost process from lab frame to CM frame.
2323  } else {
2324  if (boostType == 2) process.bst(0., 0., -betaZ, gammaZ);
2325  else if (boostType == 3) process.rotbst(MtoCM);
2326 
2327  // Boost nonempty event from lab frame to CM frame.
2328  if (event.size() > 0) {
2329  if (boostType == 2) event.bst(0., 0., -betaZ, gammaZ);
2330  else if (boostType == 3) event.rotbst(MtoCM);
2331  }
2332  }
2333 
2334  // Set production vertex; assumes particles are in lab frame and at origin.
2335  if (setVertex && doVertexSpread) {
2336  Vec4 vertex = beamShapePtr->vertex();
2337  for (int i = 0; i < process.size(); ++i) process[i].vProdAdd( vertex);
2338  for (int i = 0; i < event.size(); ++i) event[i].vProdAdd( vertex);
2339  }
2340 
2341 }
2342 
2343 //--------------------------------------------------------------------------
2344 
2345 // Perform R-hadron decays, either as part of normal evolution or forced.
2346 
2347 bool Pythia::doRHadronDecays( ) {
2348 
2349  // Check if R-hadrons exist to be processed.
2350  if ( !rHadrons.exist() ) return true;
2351 
2352  // Do the R-hadron decay itself.
2353  if ( !rHadrons.decay( event) ) return false;
2354 
2355  // Perform showers in resonance decay chains.
2356  if ( !partonLevel.resonanceShowers( process, event, false) ) return false;
2357 
2358  // Subsequent hadronization and decays.
2359  if ( !hadronLevel.next( event) ) return false;
2360 
2361  // Done.
2362  return true;
2363 
2364 }
2365 
2366 //--------------------------------------------------------------------------
2367 
2368 // Print statistics on event generation.
2369 
2370 void Pythia::stat() {
2371 
2372  if ( doHeavyIons ) {
2373  heavyIonsPtr->stat();
2374  return;
2375  }
2376 
2377  // Read out settings for what to include.
2378  bool showPrL = settings.flag("Stat:showProcessLevel");
2379  bool showPaL = settings.flag("Stat:showPartonLevel");
2380  bool showErr = settings.flag("Stat:showErrors");
2381  bool reset = settings.flag("Stat:reset");
2382 
2383  // Statistics on cross section and number of events.
2384  if (doProcessLevel) {
2385  if (showPrL) processLevel.statistics(false);
2386  if (reset) processLevel.resetStatistics();
2387  }
2388 
2389  // Statistics from other classes, currently multiparton interactions.
2390  if (showPaL) partonLevel.statistics(false);
2391  if (reset) partonLevel.resetStatistics();
2392 
2393  // Merging statistics.
2394  if (doMerging && mergingPtr ) mergingPtr->statistics();
2395 
2396  // Summary of which and how many warnings/errors encountered.
2397  if (showErr) infoPrivate.errorStatistics();
2398  if (reset) infoPrivate.errorReset();
2399 
2400  // Loop through all PhysicsBase-derived objects.
2401  for ( auto physicsPtr : physicsPtrs ) physicsPtr->stat();
2402 
2403 }
2404 
2405 //--------------------------------------------------------------------------
2406 
2407 // Write the Pythia banner, with symbol and version information.
2408 
2409 void Pythia::banner() {
2410 
2411  // Read in version number and last date of change.
2412  double versionNumber = settings.parm("Pythia:versionNumber");
2413  int versionDate = settings.mode("Pythia:versionDate");
2414  string month[12] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun",
2415  "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
2416 
2417  // Get date and time.
2418  time_t t = time(0);
2419  char dateNow[12];
2420  strftime(dateNow,12,"%d %b %Y",localtime(&t));
2421  char timeNow[9];
2422  strftime(timeNow,9,"%H:%M:%S",localtime(&t));
2423 
2424  cout << "\n"
2425  << " *-------------------------------------------"
2426  << "-----------------------------------------* \n"
2427  << " | "
2428  << " | \n"
2429  << " | *----------------------------------------"
2430  << "--------------------------------------* | \n"
2431  << " | | "
2432  << " | | \n"
2433  << " | | "
2434  << " | | \n"
2435  << " | | PPP Y Y TTTTT H H III A "
2436  << " Welcome to the Lund Monte Carlo! | | \n"
2437  << " | | P P Y Y T H H I A A "
2438  << " This is PYTHIA version " << fixed << setprecision(3)
2439  << setw(5) << versionNumber << " | | \n"
2440  << " | | PPP Y T HHHHH I AAAAA"
2441  << " Last date of change: " << setw(2) << versionDate%100
2442  << " " << month[ min(11, (versionDate/100)%100 - 1) ]
2443  << " " << setw(4) << versionDate/10000 << " | | \n"
2444  << " | | P Y T H H I A A"
2445  << " | | \n"
2446  << " | | P Y T H H III A A"
2447  << " Now is " << dateNow << " at " << timeNow << " | | \n"
2448  << " | | "
2449  << " | | \n"
2450  << " | | Christian Bierlich; Department of As"
2451  << "tronomy and Theoretical Physics, | | \n"
2452  << " | | Lund University, Solvegatan 14A, S"
2453  << "E-223 62 Lund, Sweden; | | \n"
2454  << " | | e-mail: christian.bierlich@thep.lu"
2455  << ".se | | \n"
2456  << " | | Nishita Desai; Department of Theoret"
2457  << "ical Physics, Tata Institute, | | \n"
2458  << " | | Homi Bhabha Road, Mumbai 400005, I"
2459  << "ndia; | | \n"
2460  << " | | e-mail: desai@theory.tifr.res.in "
2461  << " | | \n"
2462  << " | | Leif Gellersen; Department of Astron"
2463  << "omy and Theoretical Physics, | | \n"
2464  << " | | Lund University, Solvegatan 14A, S"
2465  << "E-223 62 Lund, Sweden; | | \n"
2466  << " | | e-mail: leif.gellersen@thep.lu.se "
2467  << " | | \n"
2468  << " | | Ilkka Helenius; Department of Physic"
2469  << "s, University of Jyvaskyla, | | \n"
2470  << " | | P.O. Box 35, FI-40014 University o"
2471  << "f Jyvaskyla, Finland; | | \n"
2472  << " | | e-mail: ilkka.m.helenius@jyu.fi "
2473  << " | | \n"
2474  << " | | Philip Ilten; Department of Physics,"
2475  << " | | \n"
2476  << " | | University of Cincinnati, Cincinna"
2477  << "ti, OH 45221, USA; | | \n"
2478  << " | | School of Physics and Astronomy, "
2479  << " | | \n"
2480  << " | | University of Birmingham, Birmingh"
2481  << "am, B152 2TT, UK; | | \n"
2482  << " | | e-mail: philten@cern.ch "
2483  << " | | \n"
2484  << " | | Leif Lonnblad; Department of Astrono"
2485  << "my and Theoretical Physics, | | \n"
2486  << " | | Lund University, Solvegatan 14A, S"
2487  << "E-223 62 Lund, Sweden; | | \n"
2488  << " | | e-mail: leif.lonnblad@thep.lu.se "
2489  << " | | \n"
2490  << " | | Stephen Mrenna; Computing Division, "
2491  << "Simulations Group, | | \n"
2492  << " | | Fermi National Accelerator Laborat"
2493  << "ory, MS 234, Batavia, IL 60510, USA; | | \n"
2494  << " | | e-mail: mrenna@fnal.gov "
2495  << " | | \n"
2496  << " | | Stefan Prestel; Department of Astron"
2497  << "omy and Theoretical Physics, | | \n"
2498  << " | | Lund University, Solvegatan 14A, S"
2499  << "E-223 62 Lund, Sweden; | | \n"
2500  << " | | e-mail: stefan.prestel@thep.lu.se "
2501  << " | | \n"
2502  << " | | Christine O. Rasmussen; Department o"
2503  << "f Astronomy and Theoretical Physics, | | \n"
2504  << " | | Lund University, Solvegatan 14A, S"
2505  << "E-223 62 Lund, Sweden; | | \n"
2506  << " | | e-mail: christine.rasmussen@thep.l"
2507  << "u.se | | \n"
2508  << " | | Torbjorn Sjostrand; Department of As"
2509  << "tronomy and Theoretical Physics, | | \n"
2510  << " | | Lund University, Solvegatan 14A, S"
2511  << "E-223 62 Lund, Sweden; | | \n"
2512  << " | | e-mail: torbjorn@thep.lu.se "
2513  << " | | \n"
2514  << " | | Peter Skands; School of Physics and "
2515  << "Astronomy, | | \n"
2516  << " | | Monash University, PO Box 27, 3800"
2517  << " Melbourne, Australia; | | \n"
2518  << " | | e-mail: peter.skands@monash.edu "
2519  << " | | \n"
2520  << " | | Marius Utheim; Department of Astrono"
2521  << "my and Theoretical Physics, | | \n"
2522  << " | | Lund University, Solvegatan 14A, S"
2523  << "E-223 62 Lund, Sweden; | | \n"
2524  << " | | e-mail: marius.utheim@thep.lu.se "
2525  << " | | \n"
2526  << " | | "
2527  << " | | \n"
2528  << " | | The main program reference is 'An Int"
2529  << "roduction to PYTHIA 8.2', | | \n"
2530  << " | | T. Sjostrand et al, Comput. Phys. Com"
2531  << "mun. 191 (2015) 159 | | \n"
2532  << " | | [arXiv:1410.3012 [hep-ph]] "
2533  << " | | \n"
2534  << " | | "
2535  << " | | \n"
2536  << " | | The main physics reference is the 'PY"
2537  << "THIA 6.4 Physics and Manual', | | \n"
2538  << " | | T. Sjostrand, S. Mrenna and P. Skands"
2539  << ", JHEP05 (2006) 026 [hep-ph/0603175] | | \n"
2540  << " | | "
2541  << " | | \n"
2542  << " | | An archive of program versions and do"
2543  << "cumentation is found on the web: | | \n"
2544  << " | | http://www.thep.lu.se/Pythia "
2545  << " | | \n"
2546  << " | | "
2547  << " | | \n"
2548  << " | | This program is released under the GN"
2549  << "U General Public Licence version 2. | | \n"
2550  << " | | Please respect the MCnet Guidelines f"
2551  << "or Event Generator Authors and Users. | | \n"
2552  << " | | "
2553  << " | | \n"
2554  << " | | Disclaimer: this program comes withou"
2555  << "t any guarantees. | | \n"
2556  << " | | Beware of errors and use common sense"
2557  << " when interpreting results. | | \n"
2558  << " | | "
2559  << " | | \n"
2560  << " | | Copyright (C) 2020 Torbjorn Sjostrand"
2561  << " | | \n"
2562  << " | | "
2563  << " | | \n"
2564  << " | | "
2565  << " | | \n"
2566  << " | *----------------------------------------"
2567  << "--------------------------------------* | \n"
2568  << " | "
2569  << " | \n"
2570  << " *-------------------------------------------"
2571  << "-----------------------------------------* \n" << endl;
2572 
2573 }
2574 
2575 //--------------------------------------------------------------------------
2576 
2577 // Check for lines in file that mark the beginning of new subrun.
2578 
2579 int Pythia::readSubrun(string line, bool warn) {
2580 
2581  // If empty line then done.
2582  int subrunLine = SUBRUNDEFAULT;
2583  if (line.find_first_not_of(" \n\t\v\b\r\f\a") == string::npos)
2584  return subrunLine;
2585 
2586  // If first character is not a letter, then done.
2587  string lineNow = line;
2588  int firstChar = lineNow.find_first_not_of(" \n\t\v\b\r\f\a");
2589  if (!isalpha(lineNow[firstChar])) return subrunLine;
2590 
2591  // Replace an equal sign by a blank to make parsing simpler.
2592  while (lineNow.find("=") != string::npos) {
2593  int firstEqual = lineNow.find_first_of("=");
2594  lineNow.replace(firstEqual, 1, " ");
2595  }
2596 
2597  // Get first word of a line.
2598  istringstream splitLine(lineNow);
2599  string name;
2600  splitLine >> name;
2601 
2602  // Replace two colons by one (:: -> :) to allow for such mistakes.
2603  while (name.find("::") != string::npos) {
2604  int firstColonColon = name.find_first_of("::");
2605  name.replace(firstColonColon, 2, ":");
2606  }
2607 
2608  // Convert to lowercase. If no match then done.
2609  if (toLower(name) != "main:subrun") return subrunLine;
2610 
2611  // Else find new subrun number and return it.
2612  splitLine >> subrunLine;
2613  if (!splitLine) {
2614  if (warn) cout << "\n PYTHIA Warning: Main:subrun number not"
2615  << " recognized; skip:\n " << line << endl;
2616  subrunLine = SUBRUNDEFAULT;
2617  }
2618  return subrunLine;
2619 
2620 }
2621 
2622 //--------------------------------------------------------------------------
2623 
2624 // Check for lines in file that mark the beginning or end of commented section.
2625 // Return +1 for beginning, -1 for end, 0 else.
2626 
2627 int Pythia::readCommented(string line) {
2628 
2629  // If less than two nontrivial characters on line then done.
2630  if (line.find_first_not_of(" \n\t\v\b\r\f\a") == string::npos) return 0;
2631  int firstChar = line.find_first_not_of(" \n\t\v\b\r\f\a");
2632  if (int(line.size()) < firstChar + 2) return 0;
2633 
2634  // If first two nontrivial characters are /* or */ then done.
2635  if (line.substr(firstChar, 2) == "/*") return +1;
2636  if (line.substr(firstChar, 2) == "*/") return -1;
2637 
2638  // Else done.
2639  return 0;
2640 
2641 }
2642 
2643 //--------------------------------------------------------------------------
2644 
2645 // Check that the final event makes sense: no unknown id codes;
2646 // charge and energy-momentum conserved.
2647 
2648 bool Pythia::check() {
2649 
2650  // Reset.
2651  bool physical = true;
2652  bool listVertices = false;
2653  bool listHistory = false;
2654  bool listSystems = false;
2655  bool listBeams = false;
2656  iErrId.resize(0);
2657  iErrCol.resize(0);
2658  iErrEpm.resize(0);
2659  iErrNan.resize(0);
2660  iErrNanVtx.resize(0);
2661  Vec4 pSum;
2662  double chargeSum = 0.;
2663 
2664  // Incoming beams counted with negative momentum and charge.
2665  if (doProcessLevel || doNonPert) {
2666  // Incoming particles will be at position "1" and "2" in most cases.
2667  // However, need to be careful how to find incoming particles after
2668  // QED radiation in DIS-type collisions. Thus, first find both incoming
2669  // particles.
2670  int iA = 1;
2671  int iB = 2;
2672  if (!(beamA2gamma || beamB2gamma)) {
2673  if (beamA.isLepton() && beamB.isHadron())
2674  { iA = beamA[0].iPos(); iB = 2; }
2675  if (beamB.isLepton() && beamA.isHadron())
2676  { iB = beamB[0].iPos(); iA = 1; }
2677  int iPos = 0;
2678  while ( beamA.isHadron() && iPos < beamB.size()
2679  && beamA.id() == beamB[iPos].id() )
2680  { iA = beamA[iPos].iPos(); iPos++;}
2681  iPos = 0;
2682  while ( beamB.isHadron() && iPos < beamB.size()
2683  && beamB.id() == beamB[iPos].id() )
2684  { iB = beamB[iPos].iPos(); iPos++; }
2685  }
2686  // Count incoming momentum and charge.
2687  pSum = - (event[iA].p() + event[iB].p());
2688  chargeSum = - (event[1].charge() + event[2].charge());
2689 
2690  // If no ProcessLevel then sum final state of process record.
2691  } else if (process.size() > 0) {
2692  pSum = - process[0].p();
2693  for (int i = 0; i < process.size(); ++i)
2694  if (process[i].isFinal()) chargeSum -= process[i].charge();
2695 
2696  // If process not filled, then use outgoing primary in event.
2697  } else {
2698  pSum = - event[0].p();
2699  for (int i = 1; i < event.size(); ++i)
2700  if (event[i].statusAbs() < 10 || event[i].statusAbs() == 23)
2701  chargeSum -= event[i].charge();
2702  }
2703  double eLab = abs(pSum.e());
2704 
2705  // Loop over particles in the event.
2706  for (int i = 0; i < event.size(); ++i) {
2707 
2708  // Look for any unrecognized particle codes.
2709  int id = event[i].id();
2710  if (id == 0 || !particleData.isParticle(id)) {
2711  ostringstream errCode;
2712  errCode << ", i = " << i << ", id = " << id;
2713  infoPrivate.errorMsg("Error in Pythia::check: "
2714  "unknown particle code", errCode.str());
2715  physical = false;
2716  iErrId.push_back(i);
2717 
2718  // Check that colour assignments are the expected ones.
2719  } else {
2720  int colType = event[i].colType();
2721  int col = event[i].col();
2722  int acol = event[i].acol();
2723  if ( event[i].statusAbs() / 10 == 8 ) acol = col = 0;
2724  if ( (colType == 0 && (col > 0 || acol > 0))
2725  || (colType == 1 && (col <= 0 || acol > 0))
2726  || (colType == -1 && (col > 0 || acol <= 0))
2727  || (colType == 2 && (col <= 0 || acol <= 0)) ) {
2728  ostringstream errCode;
2729  errCode << ", i = " << i << ", id = " << id << " cols = " << col
2730  << " " << acol;
2731  infoPrivate.errorMsg("Error in Pythia::check: "
2732  "incorrect colours", errCode.str());
2733  physical = false;
2734  iErrCol.push_back(i);
2735  }
2736  }
2737 
2738  // Some intermediate shower partons excepted from (E, p, m) consistency.
2739  bool checkMass = event[i].statusAbs() != 49 && event[i].statusAbs() != 59;
2740 
2741  // Look for particles with mismatched or not-a-number energy/momentum/mass.
2742  if (isfinite(event[i].p()) && isfinite(event[i].m())) {
2743  double errMass = abs(event[i].mCalc() - event[i].m())
2744  / max( 1.0, event[i].e());
2745  if (checkMass && errMass > mTolErr) {
2746  infoPrivate.errorMsg("Error in Pythia::check: "
2747  "unmatched particle energy/momentum/mass");
2748  physical = false;
2749  iErrEpm.push_back(i);
2750  } else if (checkMass && errMass > mTolWarn) {
2751  infoPrivate.errorMsg("Warning in Pythia::check: "
2752  "not quite matched particle energy/momentum/mass");
2753  }
2754  } else {
2755  infoPrivate.errorMsg("Error in Pythia::check: "
2756  "not-a-number energy/momentum/mass");
2757  physical = false;
2758  iErrNan.push_back(i);
2759  }
2760 
2761  // Look for particles with not-a-number vertex/lifetime.
2762  if (isfinite(event[i].vProd()) && isfinite(event[i].tau())) ;
2763  else {
2764  infoPrivate.errorMsg("Error in Pythia::check: "
2765  "not-a-number vertex/lifetime");
2766  physical = false;
2767  listVertices = true;
2768  iErrNanVtx.push_back(i);
2769  }
2770 
2771  // Add final-state four-momentum and charge.
2772  if (event[i].isFinal()) {
2773  pSum += event[i].p();
2774  chargeSum += event[i].charge();
2775  }
2776 
2777  // End of particle loop.
2778  }
2779 
2780  // Check energy-momentum/charge conservation.
2781  double epDev = abs(pSum.e()) + abs(pSum.px()) + abs(pSum.py())
2782  + abs(pSum.pz());
2783  if (epDev > epTolErr * eLab) {
2784  infoPrivate.errorMsg
2785  ("Error in Pythia::check: energy-momentum not conserved");
2786  physical = false;
2787  } else if (epDev > epTolWarn * eLab) {
2788  infoPrivate.errorMsg("Warning in Pythia::check: "
2789  "energy-momentum not quite conserved");
2790  }
2791  if (abs(chargeSum) > 0.1) {
2792  infoPrivate.errorMsg("Error in Pythia::check: charge not conserved");
2793  physical = false;
2794  }
2795 
2796  // Check that beams and event records agree on incoming partons.
2797  // Only meaningful for resolved beams.
2798  if (infoPrivate.isResolved() && !info.hasUnresolvedBeams())
2799  for (int iSys = 0; iSys < beamA.sizeInit(); ++iSys) {
2800  int eventANw = partonSystems.getInA(iSys);
2801  int eventBNw = partonSystems.getInB(iSys);
2802  // For photon sub-beams make sure to use correct beams.
2803  int beamANw = ( beamA.getGammaMode() == 0 || !beamA2gamma
2804  || (beamA.getGammaMode() == 2 && beamB.getGammaMode() == 2)) ?
2805  beamA[iSys].iPos() : beamGamA[iSys].iPos();
2806  int beamBNw = ( beamB.getGammaMode() == 0 || !beamB2gamma
2807  || (beamB.getGammaMode() == 2 && beamA.getGammaMode() == 2)) ?
2808  beamB[iSys].iPos() : beamGamB[iSys].iPos();
2809  if (eventANw != beamANw || eventBNw != beamBNw) {
2810  infoPrivate.errorMsg("Error in Pythia::check: "
2811  "event and beams records disagree");
2812  physical = false;
2813  listSystems = true;
2814  listBeams = true;
2815  }
2816  }
2817 
2818  // Check that mother and daughter information match for each particle.
2819  vector<int> noMot;
2820  vector<int> noDau;
2821  vector< pair<int,int> > noMotDau;
2822  if (checkHistory) {
2823 
2824  // Loop through the event and check that there are beam particles.
2825  bool hasBeams = false;
2826  for (int i = 0; i < event.size(); ++i) {
2827  int status = event[i].status();
2828  if (abs(status) == 12) hasBeams = true;
2829 
2830  // Check that mother and daughter lists not empty where not expected to.
2831  vector<int> mList = event[i].motherList();
2832  vector<int> dList = event[i].daughterList();
2833  if (mList.size() == 0 && abs(status) != 11 && abs(status) != 12)
2834  noMot.push_back(i);
2835  if (dList.size() == 0 && status < 0 && status != -11)
2836  noDau.push_back(i);
2837 
2838  // Check that the particle appears in the daughters list of each mother.
2839  for (int j = 0; j < int(mList.size()); ++j) {
2840  if ( event[mList[j]].daughter1() <= i
2841  && event[mList[j]].daughter2() >= i ) continue;
2842  vector<int> dmList = event[mList[j]].daughterList();
2843  bool foundMatch = false;
2844  for (int k = 0; k < int(dmList.size()); ++k)
2845  if (dmList[k] == i) {
2846  foundMatch = true;
2847  break;
2848  }
2849  if (!hasBeams && mList.size() == 1 && mList[0] == 0) foundMatch = true;
2850  if (!foundMatch) {
2851  bool oldPair = false;
2852  for (int k = 0; k < int(noMotDau.size()); ++k)
2853  if (noMotDau[k].first == mList[j] && noMotDau[k].second == i) {
2854  oldPair = true;
2855  break;
2856  }
2857  if (!oldPair) noMotDau.push_back( make_pair( mList[j], i) );
2858  }
2859  }
2860 
2861  // Check that the particle appears in the mothers list of each daughter.
2862  for (int j = 0; j < int(dList.size()); ++j) {
2863  if ( event[dList[j]].statusAbs() > 80
2864  && event[dList[j]].statusAbs() < 90
2865  && event[dList[j]].mother1() <= i
2866  && event[dList[j]].mother2() >= i) continue;
2867  vector<int> mdList = event[dList[j]].motherList();
2868  bool foundMatch = false;
2869  for (int k = 0; k < int(mdList.size()); ++k)
2870  if (mdList[k] == i) {
2871  foundMatch = true;
2872  break;
2873  }
2874  if (!foundMatch) {
2875  bool oldPair = false;
2876  for (int k = 0; k < int(noMotDau.size()); ++k)
2877  if (noMotDau[k].first == i && noMotDau[k].second == dList[j]) {
2878  oldPair = true;
2879  break;
2880  }
2881  if (!oldPair) noMotDau.push_back( make_pair( i, dList[j]) );
2882  }
2883  }
2884  }
2885 
2886  // Warn if any errors were found.
2887  if (noMot.size() > 0 || noDau.size() > 0 || noMotDau.size() > 0) {
2888  infoPrivate.errorMsg("Error in Pythia::check: "
2889  "mismatch in daughter and mother lists");
2890  physical = false;
2891  listHistory = true;
2892  }
2893  }
2894 
2895  // Done for sensible events.
2896  if (physical) return true;
2897 
2898  // Print (the first few) flawed events: local info.
2899  if (nErrEvent < nErrList) {
2900  cout << "\n PYTHIA erroneous event info: \n";
2901  if (iErrId.size() > 0) {
2902  cout << " unknown particle codes in lines ";
2903  for (int i = 0; i < int(iErrId.size()); ++i)
2904  cout << iErrId[i] << " ";
2905  cout << "\n";
2906  }
2907  if (iErrCol.size() > 0) {
2908  cout << " incorrect colour assignments in lines ";
2909  for (int i = 0; i < int(iErrCol.size()); ++i)
2910  cout << iErrCol[i] << " ";
2911  cout << "\n";
2912  }
2913  if (iErrEpm.size() > 0) {
2914  cout << " mismatch between energy/momentum/mass in lines ";
2915  for (int i = 0; i < int(iErrEpm.size()); ++i)
2916  cout << iErrEpm[i] << " ";
2917  cout << "\n";
2918  }
2919  if (iErrNan.size() > 0) {
2920  cout << " not-a-number energy/momentum/mass in lines ";
2921  for (int i = 0; i < int(iErrNan.size()); ++i)
2922  cout << iErrNan[i] << " ";
2923  cout << "\n";
2924  }
2925  if (iErrNanVtx.size() > 0) {
2926  cout << " not-a-number vertex/lifetime in lines ";
2927  for (int i = 0; i < int(iErrNanVtx.size()); ++i)
2928  cout << iErrNanVtx[i] << " ";
2929  cout << "\n";
2930  }
2931  if (epDev > epTolErr * eLab) cout << scientific << setprecision(3)
2932  << " total energy-momentum non-conservation = " << epDev << "\n";
2933  if (abs(chargeSum) > 0.1) cout << fixed << setprecision(2)
2934  << " total charge non-conservation = " << chargeSum << "\n";
2935  if (noMot.size() > 0) {
2936  cout << " missing mothers for particles ";
2937  for (int i = 0; i < int(noMot.size()); ++i) cout << noMot[i] << " ";
2938  cout << "\n";
2939  }
2940  if (noDau.size() > 0) {
2941  cout << " missing daughters for particles ";
2942  for (int i = 0; i < int(noDau.size()); ++i) cout << noDau[i] << " ";
2943  cout << "\n";
2944  }
2945  if (noMotDau.size() > 0) {
2946  cout << " inconsistent history for (mother,daughter) pairs ";
2947  for (int i = 0; i < int(noMotDau.size()); ++i)
2948  cout << "(" << noMotDau[i].first << "," << noMotDau[i].second << ") ";
2949  cout << "\n";
2950  }
2951 
2952  // Print (the first few) flawed events: standard listings.
2953  infoPrivate.list();
2954  event.list(listVertices, listHistory);
2955  if (listSystems) partonSystems.list();
2956  if (listBeams) {beamA.list(); beamB.list();}
2957  }
2958 
2959  // Update error counter. Done also for flawed event.
2960  ++nErrEvent;
2961  return false;
2962 
2963 }
2964 
2965 //--------------------------------------------------------------------------
2966 
2967 // Routine to set up a PDF pointer.
2968 
2969 PDFPtr Pythia::getPDFPtr(int idIn, int sequence, string beam, bool resolved) {
2970 
2971  // Temporary pointer to be returned.
2972  PDFPtr tempPDFPtr = 0;
2973 
2974  // Data file directory.
2975  string pdfdataPath = xmlPath.substr(0, xmlPath.length() - 7) + "pdfdata/";
2976 
2977  // One option is to treat a Pomeron like a pi0.
2978  if (idIn == 990 && settings.word("PDF:PomSet") == "2") idIn = 111;
2979 
2980  // Check if photon beam inside proton.
2981  bool proton2gamma = (abs(idIn) == 2212) && ( ( beamA2gamma && (beam == "A") )
2982  || ( beamB2gamma && (beam == "B") ) );
2983 
2984  // Proton beam, normal or hard choice. Also used for neutron.
2985  if ( (abs(idIn) == 2212 || abs(idIn) == 2112) && !proton2gamma ) {
2986  string pWord = settings.word("PDF:p"
2987  + string(sequence == 1 ? "" : "Hard") + "Set"
2988  + string(beam == "A" ? "" : "B") ) ;
2989  if (pWord == "void" && sequence != 1 && beam == "B")
2990  pWord = settings.word("PDF:pHardSet");
2991  if (pWord == "void") pWord = settings.word("PDF:pSet");
2992  istringstream pStream(pWord);
2993  int pSet = 0;
2994  pStream >> pSet;
2995 
2996  // Use internal LHAgrid1 implementation for LHAPDF6 files.
2997  if (pSet == 0 && pWord.length() > 9
2998  && toLower(pWord).substr(0,9) == "lhagrid1:")
2999  tempPDFPtr = make_shared<LHAGrid1>
3000  (idIn, pWord, pdfdataPath, &infoPrivate);
3001 
3002  // Use sets from LHAPDF.
3003  else if (pSet == 0)
3004  tempPDFPtr = make_shared<LHAPDF>(idIn, pWord, &infoPrivate);
3005 
3006  // Use internal sets.
3007  else if (pSet == 1) tempPDFPtr = make_shared<GRV94L>(idIn);
3008  else if (pSet == 2) tempPDFPtr = make_shared<CTEQ5L>(idIn);
3009  else if (pSet <= 6)
3010  tempPDFPtr = make_shared<MSTWpdf>
3011  (idIn, pSet - 2, pdfdataPath, &infoPrivate);
3012  else if (pSet <= 12)
3013  tempPDFPtr = make_shared<CTEQ6pdf>(idIn, pSet - 6, 1.,
3014  pdfdataPath, &infoPrivate);
3015  else if (pSet <= 22)
3016  tempPDFPtr = make_shared<LHAGrid1>
3017  (idIn, pWord, pdfdataPath, &infoPrivate);
3018  else tempPDFPtr = 0;
3019  }
3020 
3021  // Quasi-real photons inside a (anti-)proton beam.
3022  else if (proton2gamma) {
3023 
3024  // Find the resolved photon PDF to combine with the flux.
3025  PDFPtr tempGammaPDFPtr = nullptr;
3026 
3027  // Set up the combination of flux and PDF for resolved photons.
3028  if (resolved) {
3029 
3030  // Find the pre-set photon PDF, hard or normal.
3031  if (beam == "A") {
3032  tempGammaPDFPtr = (sequence == 1) ? pdfGamAPtr : pdfHardGamAPtr;
3033  } else {
3034  tempGammaPDFPtr = (sequence == 1) ? pdfGamBPtr : pdfHardGamBPtr;
3035  }
3036  }
3037 
3038  // Set the photon flux pointer and construct approximation.
3039  // Use the existing machinery for external fluxes.
3040  PDFPtr tempGammaFluxPtr = nullptr;
3041  double m2beam = pow2(particleData.m0(idIn));
3042 
3043  // Externally provided flux.
3044  if (settings.mode("PDF:proton2gammaSet") == 0) {
3045 
3046  // Find the correct flux for given beam set with setPhotonFluxPtr().
3047  tempGammaFluxPtr = (beam == "A") ? pdfGamFluxAPtr : pdfGamFluxBPtr;
3048 
3049  // Check that external flux exist and complain if not.
3050  if (tempGammaFluxPtr == 0) {
3051  tempPDFPtr = 0;
3052  infoPrivate.errorMsg("Error in Pythia::getPDFPtr: "
3053  "No external photon flux provided with PDF:proton2gammaSet == 0 "
3054  "for beam " + beam );
3055  }
3056 
3057  // Classic EPA proton by Budnev, Ginzburg, Meledin and Serbo.
3058  } else if (settings.mode("PDF:proton2gammaSet") == 1) {
3059 
3060  // Check if Q^2 sampling on and turn off if necessary.
3061  if (settings.flag("Photon:sampleQ2") == true ) {
3062  settings.flag("Photon:sampleQ2", false);
3063  infoPrivate.errorMsg("Warning in Pythia::getPDFPtr: "
3064  "Photon virtuality sampling turned off as chosen flux "
3065  "is Q2 independent");
3066  }
3067  tempGammaFluxPtr = make_shared<ProtonPoint>(idIn, &infoPrivate);
3068 
3069  // EPA approximation by Drees and Zeppenfeld.
3070  } else if (settings.mode("PDF:proton2gammaSet") == 2) {
3071  tempGammaFluxPtr = make_shared<Proton2gammaDZ>(idIn);
3072  } else {
3073  infoPrivate.errorMsg("Error in Pythia::getPDFPtr: "
3074  "Invalid option for photon flux from proton");
3075  }
3076 
3077  // Construct flux object when pointer succesfully created.
3078  if ( tempGammaFluxPtr != 0) {
3079  tempPDFPtr = make_shared<EPAexternal>(idIn, m2beam, tempGammaFluxPtr,
3080  tempGammaPDFPtr, &infoPrivate);
3081  } else {
3082  tempPDFPtr = 0;
3083  infoPrivate.errorMsg("Error in Pythia::getPDFPtr: "
3084  "Failed to set photon flux from protons");
3085  }
3086  }
3087 
3088  // Pion beam (or, in one option, Pomeron beam).
3089  else if (abs(idIn) == 211 || idIn == 111) {
3090  string piWord = settings.word("PDF:piSet"
3091  + string(beam == "A" ? "" : "B") ) ;
3092  if (piWord == "void" && beam == "B") piWord = settings.word("PDF:piSet");
3093  istringstream piStream(piWord);
3094  int piSet = 0;
3095  piStream >> piSet;
3096 
3097  // If VMD process then scale PDF accordingly:
3098  // f_a^VMD = alphaEM * (1/f_rho^2 + 1/f_omega^2 + 1/f_phi^2 + 1/f_J/psi)
3099  // * f_a^pi0.
3100  // COR: New value here includes J/psi
3101  double rescale = (doVMDsideA || doVMDsideB) ? 0.0046549 : 1.;
3102 
3103  // Use internal LHAgrid1 implementation for LHAPDF6 files.
3104  if (piSet == 0 && piWord.length() > 9
3105  && toLower(piWord).substr(0,9) == "lhagrid1:")
3106  tempPDFPtr = make_shared<LHAGrid1>
3107  (idIn, piWord, pdfdataPath, &infoPrivate);
3108 
3109  // Use sets from LHAPDF.
3110  else if (piSet == 0)
3111  tempPDFPtr = make_shared<LHAPDF>(idIn, piWord, &infoPrivate);
3112 
3113  // Use internal set.
3114  else if (piSet == 1) tempPDFPtr = make_shared<GRVpiL>(idIn, rescale);
3115  else tempPDFPtr = nullptr;
3116  }
3117 
3118  // Pomeron beam, if not treated like a pi0 beam.
3119  else if (idIn == 990) {
3120  string pomWord = settings.word("PDF:PomSet");
3121  double rescale = settings.parm("PDF:PomRescale");
3122  istringstream pomStream(pomWord);
3123  int pomSet = 0;
3124  pomStream >> pomSet;
3125 
3126  // Use internal LHAgrid1 implementation for LHAPDF6 files.
3127  if (pomSet == 0 && pomWord.length() > 9
3128  && toLower(pomWord).substr(0,9) == "lhagrid1:")
3129  tempPDFPtr = make_shared<LHAGrid1>
3130  (idIn, pomWord, pdfdataPath, &infoPrivate);
3131 
3132  // Use sets from LHAPDF.
3133  else if (pomSet == 0)
3134  tempPDFPtr = make_shared<LHAPDF>(idIn, pomWord, &infoPrivate);
3135 
3136  // A generic Q2-independent parametrization.
3137  else if (pomSet == 1) {
3138  double gluonA = settings.parm("PDF:PomGluonA");
3139  double gluonB = settings.parm("PDF:PomGluonB");
3140  double quarkA = settings.parm("PDF:PomQuarkA");
3141  double quarkB = settings.parm("PDF:PomQuarkB");
3142  double quarkFrac = settings.parm("PDF:PomQuarkFrac");
3143  double strangeSupp = settings.parm("PDF:PomStrangeSupp");
3144  tempPDFPtr = make_shared<PomFix>( 990, gluonA, gluonB, quarkA, quarkB,
3145  quarkFrac, strangeSupp);
3146  }
3147 
3148  // The H1 Q2-dependent parametrizations. Initialization requires files.
3149  else if (pomSet == 3 || pomSet == 4) tempPDFPtr =
3150  make_shared<PomH1FitAB>( 990, pomSet - 2, rescale, pdfdataPath,
3151  &infoPrivate);
3152  else if (pomSet == 5) tempPDFPtr =
3153  make_shared<PomH1Jets>( 990, 1, rescale, pdfdataPath, &infoPrivate);
3154  else if (pomSet == 6) tempPDFPtr =
3155  make_shared<PomH1FitAB>( 990, 3, rescale, pdfdataPath, &infoPrivate);
3156  // The parametrizations of Alvero, Collins, Terron and Whitmore.
3157  else if (pomSet > 6 && pomSet < 11) {
3158  tempPDFPtr = make_shared<CTEQ6pdf>( 990, pomSet + 4, rescale,
3159  pdfdataPath, &infoPrivate);
3160  infoPrivate.errorMsg("Warning: Pomeron flux parameters forced for"
3161  " ACTW PDFs");
3162  settings.mode("SigmaDiffractive:PomFlux", 4);
3163  double pomFluxEps = (pomSet == 10) ? 0.19 : 0.14;
3164  settings.parm("SigmaDiffractive:PomFluxEpsilon", pomFluxEps);
3165  settings.parm("SigmaDiffractive:PomFluxAlphaPrime", 0.25);
3166  }
3167  else if (pomSet == 11 ) tempPDFPtr =
3168  make_shared<PomHISASD>(990, getPDFPtr(2212), settings, &infoPrivate);
3169  else if (pomSet >= 12 && pomSet <= 15) tempPDFPtr =
3170  make_shared<LHAGrid1>(idIn, "1" + pomWord, pdfdataPath, &infoPrivate);
3171  else tempPDFPtr = 0;
3172  }
3173 
3174  // Set up nuclear PDFs.
3175  else if (idIn > 100000000) {
3176 
3177  // Which nPDF set to use.
3178  int nPDFSet = (beam == "B") ? settings.mode("PDF:nPDFSetB")
3179  : settings.mode("PDF:nPDFSetA");
3180 
3181  // Temporary pointer for storing proton PDF pointer.
3182  PDFPtr tempProtonPDFPtr = (beam == "B") ? pdfHardBPtr : pdfHardAPtr;
3183  if (nPDFSet == 0)
3184  tempPDFPtr = make_shared<Isospin>(idIn, tempProtonPDFPtr);
3185  else if (nPDFSet == 1 || nPDFSet == 2)
3186  tempPDFPtr = make_shared<EPS09>(idIn, nPDFSet, 1, pdfdataPath,
3187  tempProtonPDFPtr, &infoPrivate);
3188  else if (nPDFSet == 3)
3189  tempPDFPtr = make_shared<EPPS16>(idIn, 1, pdfdataPath,
3190  tempProtonPDFPtr, &infoPrivate);
3191  else tempPDFPtr = 0;
3192  }
3193 
3194  // Photon beam, either point-like (unresolved) or resolved.
3195  else if (abs(idIn) == 22) {
3196 
3197  // For unresolved beam use the point-like PDF.
3198  if (!resolved) {
3199  tempPDFPtr = make_shared<GammaPoint>(idIn);
3200  } else {
3201  int gammaSet = settings.mode("PDF:GammaSet");
3202 
3203  // Point-like beam if unresolved photons.
3204  bool beamIsPoint
3205  = ( !beamAResGamma && beamAUnresGamma && !(beam == "B") )
3206  || ( !beamBResGamma && beamBUnresGamma && (beam == "B") );
3207 
3208  // Use different PDFs for hard process.
3209  if ( sequence == 2) {
3210 
3211  // Find the name or number of the hard PDF set.
3212  string gmWord = settings.word("PDF:GammaHardSet");
3213  int gmSet = 0;
3214  if (gmWord == "void") gmSet = settings.mode("PDF:GammaSet");
3215  else {
3216  istringstream gmStream(gmWord);
3217  gmStream >> gmSet;
3218  }
3219 
3220  // Use sets from LHAPDF. Only available for hard processes.
3221  if (gmSet == 0 && !beamIsPoint) {
3222  tempPDFPtr = make_shared<LHAPDF>(idIn, gmWord, &infoPrivate);
3223  return tempPDFPtr;
3224  }
3225 
3226  // Or set up an internal set (though currently only one).
3227  gammaSet = gmSet;
3228  }
3229 
3230  // Set up the PDF.
3231  if (beamIsPoint) tempPDFPtr = make_shared<GammaPoint>(idIn);
3232  else if (gammaSet == 1) tempPDFPtr = make_shared<CJKL>(idIn, &rndm);
3233  else tempPDFPtr = 0;
3234  }
3235  }
3236 
3237  // Lepton beam: neutrino, resolved charged lepton or unresolved ditto.
3238  // Also photon inside lepton PDFs.
3239  else if (abs(idIn) > 10 && abs(idIn) < 17) {
3240  if (abs(idIn)%2 == 0) tempPDFPtr = make_shared<NeutrinoPoint>(idIn);
3241 
3242  // Set up resolved photon inside lepton for beam A.
3243  if ( beamAResGamma && (beam == "A") && resolved ) {
3244 
3245  // Find the pre-set photon PDF, hard or normal.
3246  PDFPtr tempGammaPDFPtr = 0;
3247  if ( sequence == 2) tempGammaPDFPtr = pdfHardGamAPtr;
3248  else tempGammaPDFPtr = pdfGamAPtr;
3249 
3250  // Get the mass of lepton and maximum virtuality of the photon.
3251  double m2beam = pow2(particleData.m0(idIn));
3252  double Q2maxGamma = settings.parm("Photon:Q2max");
3253 
3254  // Initialize the gamma-inside-lepton PDFs with internal photon flux.
3255  if (settings.mode("PDF:lepton2gammaSet") == 1) {
3256  tempPDFPtr = make_shared<Lepton2gamma>(idIn, m2beam, Q2maxGamma,
3257  tempGammaPDFPtr, &infoPrivate);
3258 
3259  // Initialize the gamma-inside-lepton PDFs with external photon flux.
3260  // Requires that the pointer to the flux set.
3261  } else if ( settings.mode("PDF:lepton2gammaSet") == 0 ) {
3262  PDFPtr tempGammaFluxPtr = pdfGamFluxAPtr;
3263  if ( tempGammaFluxPtr != 0)
3264  tempPDFPtr = make_shared<EPAexternal>(idIn, m2beam,
3265  tempGammaFluxPtr, tempGammaPDFPtr, &infoPrivate);
3266  else {
3267  tempPDFPtr = 0;
3268  infoPrivate.errorMsg("Error in Pythia::getPDFPtr: "
3269  "No external photon flux provided with PDF:lepton2gammaSet == 0");
3270  }
3271  } else tempPDFPtr = 0;
3272 
3273  // Set up resolved photon inside lepton for beam B.
3274  } else if ( beamBResGamma && (beam == "B") && resolved ) {
3275 
3276  // Find the pre-set photon PDF, hard or normal.
3277  PDFPtr tempGammaPDFPtr = 0;
3278  if ( sequence == 2) tempGammaPDFPtr = pdfHardGamBPtr;
3279  else tempGammaPDFPtr = pdfGamBPtr;
3280 
3281  // Get the mass of lepton and maximum virtuality of the photon.
3282  double m2beam = pow2(particleData.m0(idIn));
3283  double Q2maxGamma = settings.parm("Photon:Q2max");
3284 
3285  // Initialize the gamma-inside-lepton PDFs with internal photon flux.
3286  if (settings.mode("PDF:lepton2gammaSet") == 1) {
3287  tempPDFPtr = make_shared<Lepton2gamma>(idIn, m2beam, Q2maxGamma,
3288  tempGammaPDFPtr, &infoPrivate);
3289 
3290  // Initialize the gamma-inside-lepton PDFs with external photon flux.
3291  } else if ( settings.mode("PDF:lepton2gammaSet") == 0 ) {
3292  PDFPtr tempGammaFluxPtr = pdfGamFluxBPtr;
3293  if ( tempGammaFluxPtr != 0)
3294  tempPDFPtr = make_shared<EPAexternal>(idIn, m2beam,
3295  tempGammaFluxPtr, tempGammaPDFPtr, &infoPrivate );
3296  else {
3297  tempPDFPtr = 0;
3298  infoPrivate.errorMsg("Error in Pythia::getPDFPtr: "
3299  "No external photon flux provided with PDF:lepton2gammaSet == 0");
3300  }
3301  } else tempPDFPtr = 0;
3302 
3303  // Usual lepton PDFs.
3304  } else if (settings.flag("PDF:lepton")) {
3305  double m2beam = pow2(particleData.m0(idIn));
3306  double Q2maxGamma = settings.parm("Photon:Q2max");
3307  if (settings.mode("PDF:lepton2gammaSet") == 1 ) {
3308  tempPDFPtr = make_shared<Lepton>(idIn, Q2maxGamma, &infoPrivate);
3309 
3310  // External photon flux for direct-photon processes.
3311  } else if (settings.mode("PDF:lepton2gammaSet") == 0 ) {
3312  PDFPtr tempGammaPDFPtr;
3313  PDFPtr tempGammaFluxPtr = (beam == "B") ?
3314  pdfGamFluxBPtr : pdfGamFluxAPtr;
3315  if ( tempGammaFluxPtr != 0) tempPDFPtr =
3316  make_shared<EPAexternal>(idIn, m2beam,
3317  tempGammaFluxPtr, tempGammaPDFPtr, &infoPrivate);
3318  else {
3319  tempPDFPtr = 0;
3320  infoPrivate.errorMsg("Error in Pythia::getPDFPtr: "
3321  "No external photon flux provided with PDF:lepton2gammaSet == 0");
3322  }
3323  } else tempPDFPtr = 0;
3324  }
3325  else tempPDFPtr = make_shared<LeptonPoint>(idIn);
3326 
3327  // Dark matter beam set up as pointlike lepton.
3328  } else if (abs(idIn) > 50 && abs(idIn) < 60) {
3329  tempPDFPtr = make_shared<LeptonPoint>(idIn);
3330  }
3331 
3332  // Optionally allow extrapolation beyond x and Q2 limits.
3333  if (tempPDFPtr)
3334  tempPDFPtr->setExtrapolate( settings.flag("PDF:extrapolate") );
3335 
3336  // Done.
3337  return tempPDFPtr;
3338 }
3339 
3340 //==========================================================================
3341 
3342 } // end namespace Pythia8
bool setHIUserHooksPtr(HIUserHooks *userHooksPtrIn)
Possibility to pass in pointer for special heavy ion user hooks.
Definition: HeavyIons.h:69
static void addSpecialSettings(Settings &settings)
Definition: HeavyIons.cc:24
Definition: beam.h:43
Definition: AgUStep.h:26
virtual bool init()=0
virtual bool next()=0
static bool isHeavyIon(Settings &settings)
Definition: HeavyIons.cc:258