PYTHIA  8.317
HISubCollisionModel.h
1 // HISubCollisionModel.h is a part of the PYTHIA event generator.
2 // Copyright (C) 2026 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 // This file contains the definition of the ImpactParameterGenerator,
7 // SubCollision, and SubCollisionModel classes, as well as a set of
8 // subclasses of SubCollisionModel.
9 //
10 // ImpactParameterGenerator: distributes nuclei in impact parameter space.
11 // SubCollision: a collision between a projectile and a target Nucleon.
12 // SubCollisionModel: Models the collision probabilities of nucleons.
13 // BlackSubCollisionModel: A very simple SubCollisionModel.
14 // NaiveSubCollisionModel: A very simple SubCollisionModel.
15 // DoubleStrikmanSubCollisionModel: A more advanced SubCollisionModel.
16 
17 #ifndef Pythia8_HISubCollisionModel_H
18 #define Pythia8_HISubCollisionModel_H
19 
20 #include "Pythia8/Pythia.h"
21 #include "Pythia8/HINucleusModel.h"
22 
23 namespace Pythia8 {
24 
25 //==========================================================================
26 
27 // SubCollision represents a possible collision between a projectile
28 // and a target nucleon.
29 
30 class SubCollision {
31 
32 public:
33 
34  // This defines the type of a binary nucleon collision.
36  NONE, // This is not a collision.
37  ELASTIC, // This is an elastic scattering
38  SDEP, // The projectile is diffractively excited.
39  SDET, // The target is diffractively excited.
40  DDE, // Both projectile and target are diffractively excited.
41  CDE, // Both excited but with central diffraction.
42  ABS, // This is an absorptive (non-diffractive) collision.
43  LEXC, // (Low energy) excitation of target and projectile.
44  LANN, // (Low energy) annihilation.
45  LRES // (Low energy) target--projectile resonance.
46  };
47 
48  // Constructor with configuration.
49  SubCollision(Nucleon & projIn, Nucleon & targIn,
50  double bIn, double bpIn, double olappIn, CollisionType typeIn)
51  : proj(&projIn), targ(&targIn), b(bIn), bp(bpIn), olapp(olappIn),
52  type(typeIn), failed(false) {}
53 
54  // Default constructor.
56  : proj(0), targ(0), b(0.0), bp(0.0), olapp(0.0),
57  type(NONE), failed(false) {}
58 
59  // Used to order sub-collisions in a set.
60  bool operator< (const SubCollision& s) const { return b < s.b; }
61 
62  // Return 0 if neither proj or target are neutrons, 1 if target is
63  // neutron, 2 if projectile is neutron, and 3 if both are neutrons.
64  int nucleons() const {return ( abs(targ->id()) == 2112? 1: 0 ) +
65  ( abs(proj->id()) == 2112? 2: 0 );}
66 
67  // The projectile nucleon.
69 
70  // The target nucleon.
72 
73  // The impact parameter distance between the nucleons in femtometer.
74  double b;
75 
76  // The impact parameter distance between the nucleons scaled like
77  // in Pythia to have unit average for non-diffractive collisions.
78  double bp;
79 
80  // The overlap for the given impact parameter scaled like in Pythia
81  // to have unit average for non-diffractive collisions.
82  double olapp;
83 
84  // The type of collision.
86 
87  // Whether the subcollision failed, i.e. has a failed excitation.
88  mutable bool failed;
89 
90 };
91 
92 //==========================================================================
93 
94 // The SubCollisionSet gives a set of subcollisions between two nuclei.
95 
97 
98 public:
99 
100  // Default constructor.
101  SubCollisionSet() = default;
102 
103  // Constructor with subcollisions.
104  SubCollisionSet(multiset<SubCollision> subCollisionsIn, double TIn)
105  : subCollisionsSave(subCollisionsIn), TSave({TIn, TIn, TIn, TIn}) {}
106 
107  // Constructor with subcollisions. Special case for subcollision
108  // models with 2x2 fluctuating radii.
109  SubCollisionSet(multiset<SubCollision> subCollisionsIn, double TIn,
110  double T12In, double T21In, double T22In)
111  : subCollisionsSave(subCollisionsIn), TSave({TIn, T12In, T21In, T22In}) {}
112 
113  // Reset the subcollisions.
114  bool empty() const { return subCollisionsSave.empty(); }
115 
116  // The full elastic amplitude, optionally returning alternate states
117  // to gauge fluctuations.
118  double T(unsigned i = 0) const { return TSave[i]; }
119 
120  // Iterators over the subcollisions.
121  multiset<SubCollision>::const_iterator begin() const {
122  return subCollisionsSave.begin(); }
123  multiset<SubCollision>::const_iterator end() const {
124  return subCollisionsSave.end(); }
125 
126 private:
127 
128  // Saved subcollisions.
129  multiset<SubCollision> subCollisionsSave;
130 
131  // The full elastic amplitude together with alternate states gauging
132  // fluctuations.
133  vector<double> TSave = {};
134 
135 };
136 
137 //==========================================================================
138 
139 // The SubCollisionModel is is able to model the collision between two
140 // nucleons to tell which type of collision has occurred. The model
141 // may manipulate the corresponding state of the nucleons.
142 
144 
145 public:
146 
147  // Internal class to report cross section estimates.
148  struct SigEst {
149  // The cross sections (tot, nd, dd, sdp, sdt, cd, el, bslope).
150  vector<double> sig;
151 
152  // The estimated error (squared)
153  vector<double> dsig2;
154 
155  // Which cross sections were actually fitted
156  vector<bool> fsig;
157 
158  // The estimate of the average (and squared error) impact
159  // parameter for inelastic non-diffractive collisions.
160  double avNDb, davNDb2, avNOF, davNOF2;
161 
162  // Constructor for zeros.
163  SigEst(): sig(8, 0.0), dsig2(8, 0.0), fsig(8, false),
164  avNDb(0.0), davNDb2(0.0), avNOF(0.0), davNOF2(0.0) {}
165 
166  };
167 
168  // The default constructor is empty.
169  // The avNDb has units femtometer.
170  SubCollisionModel(int nParm)
171  : sigTarg(11, 0.0), sigErr(8, 0.05), sigTargNN(4, vector<double>(11, 0.0)),
172  parmSave(nParm), NInt(100000), NPop(20), sigFuzz(0.2), impactFudge(1),
173  fitPrint(true), eCMlow(20.0), avNDb(1.0), avNDolap(1.0),
174  projPtr(), targPtr(), sigTotPtr(), sigCmbPtr(), settingsPtr(),
175  infoPtr(), rndmPtr(), loggerPtr(), particleDataPtr(),
176  idASave(0), idBSave(0), doVarECM(false), doVarBeams(false),
177  eMin(0.0), eMax(0.0), eSave(0.0), eCMPts(5), idAList(),
178  subCollParmsPtr(), subCollParmsMap(), elasticMode(1),
179  elasticFudge(0.0) {}
180 
181  // Virtual destructor.
182  virtual ~SubCollisionModel() {}
183 
184  // Create a new SubCollisionModel of the given model.
185  static shared_ptr<SubCollisionModel> create(int model);
186 
187  // Virtual init method.
188  virtual bool init(int idAIn, int idBIn, double eCMIn);
189 
190  // Initialize the pointers.
191  void initPtr(NucleusModel & projIn, NucleusModel & targIn,
192  SigmaTotal & sigTotIn, Settings & settingsIn,
193  Info & infoIn, Rndm & rndmIn) {
194  projPtr = &projIn;
195  targPtr = &targIn;
196  sigTotPtr = &sigTotIn;
197  settingsPtr = &settingsIn;
198  infoPtr = &infoIn;
199  rndmPtr = &rndmIn;
200  loggerPtr = infoIn.loggerPtr;
201  particleDataPtr = infoIn.particleDataPtr;
202  }
203 
204  // Initialize low energy treatment.
205  void initLowEnergy(SigmaCombined * sigmaCombPtrIn) {
206  lowEnergyCache.sigCmbPtr = sigCmbPtr = sigmaCombPtrIn;
207  lowEnergyCache.particleDataPtr = particleDataPtr;
208  }
209 
210  bool hasXSec() const {
211  if ( elasticMode )
212  return ( sigTargNN[0][0] + sigTargNN[1][0] +
213  sigTargNN[2][0] + sigTargNN[3][0] > 0.0 );
214  for ( int i = 0; i< 4; ++i )
215  for ( int j = 1; j < 11; ++j ) {
216  if ( j == 6 || j == 7 ) continue;
217  if ( sigTargNN[i][j] > 0.0 ) return true;
218  }
219  return false;
220  }
221 
222  // Access the nucleon-nucleon cross sections assumed
223  // for this model.
224 
225  // The target total nucleon-nucleon cross section.
226  double sigTot() const { return sigTarg[0]; }
227 
228  // The target elastic cross section.
229  double sigEl() const { return sigTarg[6]; }
230 
231  // The target central diffractive excitation cross section.
232  double sigCDE() const { return sigTarg[5]; }
233 
234  // The target single diffractive excitation cross section (both sides).
235  double sigSDE() const { return sigSDEP() + sigSDET(); }
236 
237  // The target single diffractive excitation cross section (projectile).
238  double sigSDEP() const { return sigTarg[3] - sigTarg[1] - sigTarg[2]; }
239 
240  // The target single diffractive excitation cross section (target).
241  double sigSDET() const { return sigTarg[4] - sigTarg[1] - sigTarg[2]; }
242 
243  // The target double diffractive excitation cross section.
244  double sigDDE() const { return sigTarg[2]; }
245 
246  // The target non-diffractive (absorptive) cross section.
247  double sigND() const { return sigTarg[1]; }
248 
249  // The Low-energy cross sections.
250  double sigLow() const { return sigLExc() + sigLAnn() + sigLRes(); }
251 
252  // The Low-energy excitation cross section (code 157).
253  double sigLExc() const { return sigTarg[8]; }
254 
255  // The Low-energy annihilation cross section (code 158).
256  double sigLAnn() const { return sigTarg[9]; }
257 
258  // The Low-energy resonant cross section (code 159).
259  double sigLRes() const { return sigTarg[10]; }
260 
261  // The target elastic b-slope parameter.
262  double bSlope() const { return sigTarg[7]; }
263 
264  // Return the average non-diffractive impact parameter.
265  double avNDB() const { return avNDb; }
266 
267  // Update internally stored cross sections.
268  void updateSig(int idAIn, int idBIn, double eCMIn);
269 
270  // Calculate the Chi2 for the given cross section estimates.
271  double Chi2(const SigEst & sigs, int npar) const;
272 
273  // Set beam kinematics.
274  bool setKinematics(double eCMIn);
275 
276  // Set projectile particle.
277  bool setIDA(int idA);
278 
279  // Use a genetic algorithm to fit the parameters.
280  bool evolve(int nGenerations, double eCM, int idANow);
281 
282  // Get the number of free parameters for the model.
283  int nParms() const { return parmSave.size(); }
284 
285  // Set the parameters of this model.
286  void setParm(const vector<double>& parmIn) {
287  for (size_t i = 0; i < parmSave.size(); ++i)
288  parmSave[i] = parmIn[i];
289  }
290 
291  // Get the current parameters of this model.
292  vector<double> getParm() const { return parmSave; }
293 
294  // Get the minimum allowed parameter values for this model.
295  virtual vector<double> minParm() const = 0;
296 
297  // Get the default parameter values for this model.
298  virtual vector<double> defParm() const = 0;
299 
300  // Get the maximum allowed parameter values for this model.
301  virtual vector<double> maxParm() const = 0;
302 
303  // Generate possible states for the nucleons in the projectile and
304  // target nuclei.
306 
307  // Take two nuclei and produce the corresponding subcollisions. The states
308  // of the nucleons may be changed if fluctuations are allowed by the model.
309  virtual SubCollisionSet getCollisions(Nucleus& proj, Nucleus& targ) = 0;
310 
311  // Calculate the cross sections for the given set of parameters.
312  virtual SigEst getSig() const = 0;
313 
314 private:
315 
316  // Generate parameters based on run settings and the evolutionary algorithm.
317  bool genParms();
318 
319  // Save/load parameter configuration to/from settings/disk.
320  bool saveParms(string fileName) const;
321  bool loadParms(string fileName);
322 
323 protected:
324 
325  // The nucleon-nucleon cross sections targets for this model
326  // (tot, nd, dd, sdp, sdt, cd, el, bslope) and the required precision.
327  vector<double> sigTarg, sigErr;
328  vector< vector<double> > sigTargNN;
329 
330  // Saved parameters.
331  vector<double> parmSave;
332 
333  // The parameters steering the fitting of internal parameters to
334  // the different nucleon-nucleon cross sections.
335  int NInt, NPop;
336  double sigFuzz;
337  double impactFudge;
338  bool fitPrint;
339  double eCMlow;
340 
341  // The estimated average impact parameter distance (in femtometer)
342  // for absorptive collisions.
343  double avNDb;
344  double avNDolap;
345 
346  // Info from the controlling HeavyIons object.
347  NucleusModel* projPtr = {};
348  NucleusModel* targPtr = {};
349  SigmaTotal* sigTotPtr = {};
350  SigmaCombined* sigCmbPtr = {};
351  Settings* settingsPtr = {};
352  Info* infoPtr = {};
353  Rndm* rndmPtr = {};
354  Logger* loggerPtr = {};
355  ParticleData * particleDataPtr = {};
356 
357  // For variable energies.
358  int idASave, idBSave;
359  bool doVarECM, doVarBeams;
360  double eMin, eMax, eSave;
361  int eCMPts;
362 
363  // The list of particles that have been fitted.
364  vector<int> idAList;
365 
366  // A vector of interpolators for the current particle. Each entry
367  // corresponds to one parameter, each interpolator is over the energy range.
368  vector<LogInterpolator> *subCollParmsPtr;
369 
370  // Mapping id -> interpolator, one entry for each particle.
371  map<int, vector<LogInterpolator>> subCollParmsMap;
372 
373  // Generation of elastic NN scatterings is turned on by default,
374  // even if the cross section comes out wrong.
376 
377  // Add in elastic NN scatterings to get the generated inelastic AA
378  // cross section better described.
379  double elasticFudge;
380 
381  // Helper class to cache cross sections at low energy
382  struct SigmaCache {
383 
384  map<pair<int,int>, map<int, vector< vector<double> > > > cache;
385 
386  ParticleData * particleDataPtr = {};
387  SigmaCombined * sigCmbPtr = {};
388  double eCMStep = 0.1;
389 
390  void set(vector< vector<double> > & sigNN,
391  int idAIn, int idBIn, double eCM) {
392  auto & beamCache = cache[{idAIn, idBIn}];
393  int iECMl = int(eCM/eCMStep);
394  int iECMh = iECMl + 1;
395  auto itl = beamCache.find(iECMl);
396  if ( itl == beamCache.end() ) {
397  fillCache(sigNN, idAIn, idBIn, iECMl);
398  itl = beamCache.find(iECMl);
399  }
400  auto ith = beamCache.find(iECMh);
401  if ( ith == beamCache.end() ) {
402  fillCache(sigNN, idAIn, idBIn, iECMh);
403  ith = beamCache.find(iECMh);
404  }
405  auto & sigl = itl->second;
406  auto & sigh = ith->second;
407  double fl = (eCM - iECMl*eCMStep)/eCMStep;
408  double fh = 1.0 - fl;
409  for ( size_t i = 0; i < sigl.size(); ++i )
410  for ( size_t j = 0; j < sigl[i].size(); ++j )
411  sigNN[i][j] =
412  ( sigl[i][j] > 0.0? fl*sigl[i][j] + fh*sigh[i][j]: 0.0 );
413  }
414 
415  void fillCache(vector< vector<double> > & sigNN,
416  int idAIn, int idBIn, int iECM) {
417  double eCMIn = iECM*eCMStep;
418  // Loop over both protons and neutrons.
419  for ( int i = 0; i < 4; ++i ) {
420  int idA = idAIn;
421  int idB = idBIn;
422  if ( i%2 == 1 ) {
423  if ( abs(idA) != 2212 ) continue;
424  idA = ( idA > 0? 2112: -2112 );
425  }
426  if ( i/2 == 1 ) {
427  if ( abs(idB) != 2212 ) continue;
428  idB = ( idB > 0? 2112: -2112 );
429  }
430  double mA = particleDataPtr->m0(idA);
431  double mB = particleDataPtr->m0(idB);
432  // Total.
433  sigNN[i][0] =
434  sigCmbPtr->sigmaPartial(idA, idB, eCMIn, mA, mB, 0)*MB2FMSQ;
435  // Non-diffractive.
436  sigNN[i][1] =
437  sigCmbPtr->sigmaPartial(idA, idB, eCMIn, mA, mB, 1)*MB2FMSQ;
438  // Doubly diffractive.
439  sigNN[i][2] =
440  sigCmbPtr->sigmaPartial(idA, idB, eCMIn, mA, mB, 5)*MB2FMSQ;
441  // Diffractive (and wounded) projectile.
442  sigNN[i][3] =
443  sigCmbPtr->sigmaPartial(idA, idB, eCMIn, mA, mB, 4)*MB2FMSQ +
444  sigNN[i][1] + sigNN[i][2];
445  // Diffractive (and wounded) target.
446  sigNN[i][4] =
447  sigCmbPtr->sigmaPartial(idA, idB, eCMIn, mA, mB, 3)*MB2FMSQ +
448  sigNN[i][1] + sigNN[i][2];
449  // Central diffractive.
450  sigNN[i][5] =
451  sigCmbPtr->sigmaPartial(idA, idB, eCMIn, mA, mB, 6)*MB2FMSQ;
452  // Elastic.
453  sigNN[i][6] =
454  sigCmbPtr->sigmaPartial(idA, idB, eCMIn, mA, mB, 2)*MB2FMSQ;
455  // b-slope not used for low energy.
456  sigNN[i][7] = 0.0;
457  // Low energy excitation.
458  sigNN[i][8] =
459  sigCmbPtr->sigmaPartial(idA, idB, eCMIn, mA, mB, 7)*MB2FMSQ;
460  // Low energy annihilation
461  sigNN[i][9] =
462  sigCmbPtr->sigmaPartial(idA, idB, eCMIn, mA, mB, 8)*MB2FMSQ;
463  // Low energy resonance
464  sigNN[i][10] =
465  sigCmbPtr->sigmaPartial(idA, idB, eCMIn, mA, mB, 9)*MB2FMSQ;
466  // Does not work for K0.
467  if ( idA == 130 ) sigNN[i][10] = 0;
468  }
469  cache[{idAIn, idBIn}][iECM] = sigNN;
470  }
471 
472  };
473 
474  SigmaCache lowEnergyCache;
475 
476 };
477 
478 //==========================================================================
479 
480 // The most naive sub-collision model, assuming static nucleons and
481 // an absorptive cross section equal to the total inelastic. No
482 // fluctuations, meaning no diffraction.
483 
485 
486 public:
487 
488  // The default constructor simply lists the nucleon-nucleon cross sections.
490 
491  // Virtual destructor.
492  virtual ~BlackSubCollisionModel() override {}
493 
494  // Get the minimum and maximum allowed parameter values for this model.
495  vector<double> minParm() const override { return vector<double>(); }
496  vector<double> defParm() const override { return vector<double>(); }
497  vector<double> maxParm() const override { return vector<double>(); }
498 
499  // Get cross sections used by this model.
500  virtual SigEst getSig() const override {
501  SigEst s;
502  s.sig[0] = sigTot();
503  s.sig[1] = sigND();
504  s.sig[6] = s.sig[0] - s.sig[1];
505  s.sig[7] = bSlope();
506  return s;
507  }
508 
509  // Take two nuclei and return the corresponding sub-collisions.
510  virtual SubCollisionSet getCollisions(Nucleus& proj, Nucleus& targ) override;
511 
512 };
513 
514 //==========================================================================
515 
516 // A very simple sub-collision model, assuming static nucleons and
517 // just assuring that the individual nucleon-nucleon cross sections
518 // are preserved.
519 
521 
522 public:
523 
524  // The default constructor simply lists the nucleon-nucleon cross sections.
526 
527  // Virtual destructor.
528  virtual ~NaiveSubCollisionModel() override {}
529 
530  // Get the minimum and maximum allowed parameter values for this model.
531  vector<double> minParm() const override { return vector<double>(); }
532  vector<double> defParm() const override { return vector<double>(); }
533  vector<double> maxParm() const override { return vector<double>(); }
534 
535  // Get cross sections used by this model.
536  virtual SigEst getSig() const override {
537  SigEst s;
538  s.sig[0] = sigTot();
539  s.sig[1] = sigND();
540  s.sig[3] = sigSDEP();
541  s.sig[4] = sigSDET();
542  s.sig[2] = sigDDE();
543  s.sig[6] = sigEl();
544  s.sig[7] = bSlope();
545  return s;
546  }
547 
548  // Take two nuclei and return the corresponding sub-collisions.
549  virtual SubCollisionSet getCollisions(Nucleus& proj, Nucleus& targ) override;
550 
551 };
552 
553 //==========================================================================
554 
555 // A base class for sub-collision models where each nucleon has a
556 // fluctuating "radius". The base model has two parameters, sigd and alpha,
557 // which are used for opacity calculations. Subclasses may have additional
558 // parameters to describe the radius distributions of that specific model.
559 
561 
562 public:
563 
564  // The default constructor simply lists the nucleon-nucleon cross sections.
565  FluctuatingSubCollisionModel(int nParmIn, int modein)
566  : SubCollisionModel(nParmIn + 2), opacityMode(modein),
567  sigd(parmSave[nParmIn]), alpha(parmSave[nParmIn + 1]) {}
568 
569 
570  // Virtual destructor.
571  virtual ~FluctuatingSubCollisionModel() override {}
572 
573  // Virtual init method.
574  virtual bool init(int idAIn, int idBIn, double eCMIn) override;
575 
576  // Generate fluctuating radii for the nucleons in the projectile and
577  // target nuclei.
578  virtual void generateNucleonStates(Nucleus& proj, Nucleus& targ) override;
579 
580  // Take two nuclei and pick specific states for each nucleon,
581  // then get the corresponding sub-collisions.
582  virtual SubCollisionSet getCollisions(Nucleus& proj, Nucleus& targ) override;
583  SubCollisionSet getCollisionsNew(Nucleus& proj, Nucleus& targ);
584  // Helper function.
585  vector<double> getCollTypeProbs(const vector<double> & T) const;
586 
587  // Calculate the cross sections for the given set of parameters.
588  virtual SigEst getSig() const override;
589 
590 protected:
591 
592  // Pick a radius for the nucleon, depending on the specific model.
593  virtual double pickRadiusProj() const = 0;
594  virtual double pickRadiusTarg() const = 0;
595 
596  // Optional mode for opacity.
598 
599 private:
600 
601  // Saturation scale of the nucleus.
602  double& sigd;
603 
604  // Power of the saturation scale
605  double& alpha;
606 
607  // The opacity of the collision at a given sigma.
608  double opacity(double sig) const {
609  sig /= sigd;
610  if ( opacityMode )
611  return pow(-expm1(-sig), alpha);
612  return sig > numeric_limits<double>::epsilon() ?
613  pow(-expm1(-1.0/sig), alpha) : 1.0;
614  }
615 
616  // Get the minus the log of 1-T0 safely even when T0 close to 1.
617  double log1mT0(double sig) const {
618  double T0 = opacity(sig);
619  if ( 1.0 - T0 > 1.0e6*numeric_limits<double>::epsilon() )
620  return -log(1.0 - T0);
621  if ( opacityMode == 1 )
622  return sig/sigd -log(alpha);
623  else
624  return sigd/sig -log(alpha);
625  }
626 
627  // Calculate the overlap of two nucleons.
628  double getOverlap(double b, double rt, double rp) const {
629  double sig = M_PI*pow2(rp+rt);
630  double T0 = opacity(sig);
631  // *** TODO *** check that T0 is never 0.
632  rt/=sqrt(2*T0);
633  rp/=sqrt(2*T0);
634  return (b>(rt+rp))? 0.0: 2.0*log1mT0(sig)/(2.0*T0 - pow2(T0));
635  }
636 
637  // Return the elastic amplitude for a projectile and target state
638  // and the impact parameter between the corresponding nucleons.
639  double Tpt(const Nucleon::State & p,
640  const Nucleon::State & t, double b) const {
641  double sig = M_PI*pow2(p[0] + t[0]);
642  double grey = opacity(sig);
643  return sig/grey > b*b*2.0*M_PI? grey: 0.0;
644  }
645 
646 };
647 
648 //==========================================================================
649 
650 // A sub-collision model where each nucleon has a fluctuating
651 // "radius" according to a Strikman-inspired distribution.
652 
654 
655 public:
656 
657  // The default constructor simply lists the nucleon-nucleon cross sections.
659  : FluctuatingSubCollisionModel(1, modeIn), k0(parmSave[0]) {}
660 
661  // Virtual destructor.
662  virtual ~DoubleStrikmanSubCollisionModel() override {}
663 
664  // Get the minimum and maximum allowed parameter values for this model.
665  vector<double> minParm() const override { return { 0.01, 1.0, 0.0 }; }
666  vector<double> defParm() const override { return { 2.15, 17.24, 0.33 }; }
667  vector<double> maxParm() const override {
668  return { (opacityMode == 0? 60.00: 10.0), 60.0,
669  (opacityMode == 0? 20.0: 2.0) }; }
670 
671 protected:
672 
673  double pickRadiusProj() const override {
674  double r = rndmPtr->gamma(k0, r0());
675  return (r < numeric_limits<double>::epsilon() ?
676  numeric_limits<double>::epsilon() : r);
677  }
678  double pickRadiusTarg() const override {
679  double r = rndmPtr->gamma(k0, r0());
680  return (r < numeric_limits<double>::epsilon() ?
681  numeric_limits<double>::epsilon() : r);
682  }
683 
684 private:
685 
686  // The power in the Gamma distribution.
687  double& k0;
688 
689  // Return the average radius deduced from other parameters and
690  // the total cross section.
691  double r0() const {
692  return sqrt(sigTot() / (M_PI * (2.0 * k0 + 4.0 * k0 * k0)));
693  }
694 
695 };
696 
697 //==========================================================================
698 
699 // ImpactParameterGenerator is able to generate a specific impact
700 // parameter together with a weight such that a weighted average over
701 // any quantity X(b) corresponds to the infinite integral over d^2b
702 // X(b). This base class gives a Gaussian profile, d^2b exp(-b^2/2w^2).
703 
705 
706 public:
707 
708  // The default constructor takes a general width (in femtometers) as
709  // argument.
710  ImpactParameterGenerator() = default;
711 
712  // Virtual destructor.
714 
715  // Virtual init method.
716  virtual bool init();
717  void initPtr(Info & infoIn, SubCollisionModel & collIn,
718  NucleusModel & projIn, NucleusModel & targIn);
719 
720  // Return a new impact parameter and set the corresponding weight provided.
721  virtual Vec4 generate(double & weight) const;
722 
723  // Return the scaling of the cross section used together with the
724  // weight in generate() to obtain the cross section. This is by
725  // default 1 unless forceUnitWeight is specified.
726  virtual double xSecScale() const {
727  return forceUnitWeight? M_PI*pow2(width()*cut): 2.0*M_PI *pow2(width());
728  }
729 
730  // Set the width (in femtometers).
731  void width(double widthIn) { widthSave = widthIn; }
732 
733  // Get the width.
734  double width() const { return widthSave; }
735 
736  // Update width based on the associated subcollision and nucleus models.
737  void updateWidth();
738 
739 private:
740 
741  // The width of a distribution.
742  double widthSave = 0.0;
743 
744  // The cut multiplied with widthSave to give the maximum allowed
745  // impact parameter.
746  double cut = 3.0;
747 
748  // Sample flat instead of with a Gaussian.
749  bool forceUnitWeight = false;
750 
751 protected:
752 
753  // Pointers from the controlling HeavyIons object.
754  Info* infoPtr{};
755  SubCollisionModel* collPtr{};
756  NucleusModel* projPtr{};
757  NucleusModel* targPtr{};
758  Settings* settingsPtr{};
759  Rndm* rndmPtr{};
760  Logger* loggerPtr{};
761 
762 };
763 
764 //==========================================================================
765 
766 // A sub-collision model where each nucleon fluctuates independently
767 // according to a log-normal distribution. Nucleons in the projectile and
768 // target may fluctuate according to different parameters, which is relevant
769 // e.g. for hadron-ion collisions with generic hadron species.
770 
772 
773 public:
774 
775  // The default constructor simply lists the nucleon-nucleon cross sections.
777  : FluctuatingSubCollisionModel(4, modeIn),
778  kProj(parmSave[0]), kTarg(parmSave[1]),
779  rProj(parmSave[2]), rTarg(parmSave[3]) {}
780 
781  // Virtual destructor.
783 
784  //virtual SigEst getSig() const override;
785 
786  // Get the minimum and maximum allowed parameter values for this model.
787  vector<double> minParm() const override {
788  return { 0.01, 0.01, 0.10, 0.10, 1.00, 0.00 }; }
789  vector<double> defParm() const override {
790  return { 1.00, 1.00, 0.54, 0.54, 17.24, 0.33 }; }
791  vector<double> maxParm() const override {
792  return { 2.00, 2.00, 4.00, 4.00, 20.00, 2.00 }; }
793 
794 protected:
795 
796  double pickRadiusProj() const override { return pickRadius(kProj, rProj); }
797  double pickRadiusTarg() const override { return pickRadius(kTarg, rTarg); }
798 
799 private:
800 
801  // The standard deviation of each log-normal distribution.
802  double& kProj;
803  double& kTarg;
804 
805  // The mean radius of each nucleon.
806  double& rProj;
807  double& rTarg;
808 
809  double pickRadius(double k0, double r0) const {
810  double logSig = log(M_PI * pow2(r0)) + k0 * rndmPtr->gauss();
811  return sqrt(exp(logSig) / M_PI);
812  }
813 };
814 
815 //==========================================================================
816 
817 } // end namespace Pythia8
818 
819 #endif // Pythia8_HISubCollisionModel_H
vector< LogInterpolator > * subCollParmsPtr
Definition: HISubCollisionModel.h:368
vector< int > idAList
The list of particles that have been fitted.
Definition: HISubCollisionModel.h:364
constexpr double pow2(const double &x)
Powers of small integers - for balance speed/code clarity.
Definition: PythiaStdlib.h:175
int elasticMode
Definition: HISubCollisionModel.h:375
CollisionType type
The type of collision.
Definition: HISubCollisionModel.h:85
bool failed
Whether the subcollision failed, i.e. has a failed excitation.
Definition: HISubCollisionModel.h:88
vector< double > defParm() const override
Get the default parameter values for this model.
Definition: HISubCollisionModel.h:496
vector< double > sigTarg
Definition: HISubCollisionModel.h:327
Definition: HISubCollisionModel.h:653
double sigmaPartial(int id1, int id2, double eCM12, double m1, double m2, int type, int mixLoHi=0)
Get partial cross sections.
Definition: SigmaLowEnergy.cc:1563
vector< double > maxParm() const override
Get the maximum allowed parameter values for this model.
Definition: HISubCollisionModel.h:667
int nParms() const
Get the number of free parameters for the model.
Definition: HISubCollisionModel.h:283
vector< double > defParm() const override
Get the default parameter values for this model.
Definition: HISubCollisionModel.h:789
double T(unsigned i=0) const
Definition: HISubCollisionModel.h:118
FluctuatingSubCollisionModel(int nParmIn, int modein)
The default constructor simply lists the nucleon-nucleon cross sections.
Definition: HISubCollisionModel.h:565
virtual ~FluctuatingSubCollisionModel() override
Virtual destructor.
Definition: HISubCollisionModel.h:571
Definition: Info.h:45
Helper class to cache cross sections at low energy.
Definition: HISubCollisionModel.h:382
double sigSDE() const
The target single diffractive excitation cross section (both sides).
Definition: HISubCollisionModel.h:235
SigEst()
Constructor for zeros.
Definition: HISubCollisionModel.h:163
double sigLRes() const
The Low-energy resonant cross section (code 159).
Definition: HISubCollisionModel.h:259
Nucleon * targ
The target nucleon.
Definition: HISubCollisionModel.h:71
Definition: HINucleusModel.h:152
Logger * loggerPtr
Pointer to the logger.
Definition: Info.h:86
Definition: SigmaLowEnergy.h:135
double sigLAnn() const
The Low-energy annihilation cross section (code 158).
Definition: HISubCollisionModel.h:256
Definition: HISubCollisionModel.h:520
double avNDb
Definition: HISubCollisionModel.h:343
virtual ~BlackSubCollisionModel() override
Virtual destructor.
Definition: HISubCollisionModel.h:492
vector< double > getParm() const
Get the current parameters of this model.
Definition: HISubCollisionModel.h:292
double bSlope() const
The target elastic b-slope parameter.
Definition: HISubCollisionModel.h:262
SubCollision(Nucleon &projIn, Nucleon &targIn, double bIn, double bpIn, double olappIn, CollisionType typeIn)
Constructor with configuration.
Definition: HISubCollisionModel.h:49
Definition: SigmaTotal.h:141
void initPtr(NucleusModel &projIn, NucleusModel &targIn, SigmaTotal &sigTotIn, Settings &settingsIn, Info &infoIn, Rndm &rndmIn)
Initialize the pointers.
Definition: HISubCollisionModel.h:191
vector< double > maxParm() const override
Get the maximum allowed parameter values for this model.
Definition: HISubCollisionModel.h:497
void width(double widthIn)
Set the width (in femtometers).
Definition: HISubCollisionModel.h:731
Both excited but with central diffraction.
Definition: HISubCollisionModel.h:42
LogNormalSubCollisionModel(int modeIn=0)
The default constructor simply lists the nucleon-nucleon cross sections.
Definition: HISubCollisionModel.h:776
int NInt
Definition: HISubCollisionModel.h:335
double bp
Definition: HISubCollisionModel.h:78
vector< double > State
The state of a nucleon is a general vector of doubles.
Definition: HINucleusModel.h:41
map< int, vector< LogInterpolator > > subCollParmsMap
Mapping id -> interpolator, one entry for each particle.
Definition: HISubCollisionModel.h:371
SubCollisionSet(multiset< SubCollision > subCollisionsIn, double TIn)
Constructor with subcollisions.
Definition: HISubCollisionModel.h:104
double sigND() const
The target non-diffractive (absorptive) cross section.
Definition: HISubCollisionModel.h:247
BlackSubCollisionModel()
The default constructor simply lists the nucleon-nucleon cross sections.
Definition: HISubCollisionModel.h:489
virtual SigEst getSig() const override
Get cross sections used by this model.
Definition: HISubCollisionModel.h:500
vector< double > parmSave
Saved parameters.
Definition: HISubCollisionModel.h:331
vector< double > maxParm() const override
Get the maximum allowed parameter values for this model.
Definition: HISubCollisionModel.h:791
double avNDb
Definition: HISubCollisionModel.h:160
double sigCDE() const
The target central diffractive excitation cross section.
Definition: HISubCollisionModel.h:232
Definition: HINucleusModel.h:28
Definition: HINucleusModel.h:198
virtual double xSecScale() const
Definition: HISubCollisionModel.h:726
Definition: HISubCollisionModel.h:704
double elasticFudge
Definition: HISubCollisionModel.h:379
(Low energy) excitation of target and projectile.
Definition: HISubCollisionModel.h:44
Definition: Logger.h:23
multiset< SubCollision >::const_iterator begin() const
Iterators over the subcollisions.
Definition: HISubCollisionModel.h:121
double avNDB() const
Return the average non-diffractive impact parameter.
Definition: HISubCollisionModel.h:265
The SubCollisionSet gives a set of subcollisions between two nuclei.
Definition: HISubCollisionModel.h:96
This is an absorptive (non-diffractive) collision.
Definition: HISubCollisionModel.h:43
ParticleData * particleDataPtr
Pointer to the particle data table.
Definition: PhysicsBase.h:88
void initLowEnergy(SigmaCombined *sigmaCombPtrIn)
Initialize low energy treatment.
Definition: HISubCollisionModel.h:205
The target is diffractively excited.
Definition: HISubCollisionModel.h:40
vector< bool > fsig
Which cross sections were actually fitted.
Definition: HISubCollisionModel.h:156
Definition: Basics.h:393
double width() const
Get the width.
Definition: HISubCollisionModel.h:734
vector< double > defParm() const override
Get the default parameter values for this model.
Definition: HISubCollisionModel.h:532
vector< double > dsig2
The estimated error (squared)
Definition: HISubCollisionModel.h:153
(Low energy) annihilation.
Definition: HISubCollisionModel.h:45
Definition: HISubCollisionModel.h:484
virtual ~ImpactParameterGenerator()
Virtual destructor.
Definition: HISubCollisionModel.h:713
bool empty() const
Reset the subcollisions.
Definition: HISubCollisionModel.h:114
Definition: HISubCollisionModel.h:143
double sigLExc() const
The Low-energy excitation cross section (code 157).
Definition: HISubCollisionModel.h:253
double sigDDE() const
The target double diffractive excitation cross section.
Definition: HISubCollisionModel.h:244
virtual ~DoubleStrikmanSubCollisionModel() override
Virtual destructor.
Definition: HISubCollisionModel.h:662
virtual SigEst getSig() const override
Get cross sections used by this model.
Definition: HISubCollisionModel.h:536
SubCollision()
Default constructor.
Definition: HISubCollisionModel.h:55
double olapp
Definition: HISubCollisionModel.h:82
This is an elastic scattering.
Definition: HISubCollisionModel.h:38
void setParm(const vector< double > &parmIn)
Set the parameters of this model.
Definition: HISubCollisionModel.h:286
virtual ~NaiveSubCollisionModel() override
Virtual destructor.
Definition: HISubCollisionModel.h:528
Definition: HISubCollisionModel.h:30
Internal class to report cross section estimates.
Definition: HISubCollisionModel.h:148
int id() const
Accessor functions:
Definition: HINucleusModel.h:52
DoubleStrikmanSubCollisionModel(int modeIn=0)
The default constructor simply lists the nucleon-nucleon cross sections.
Definition: HISubCollisionModel.h:658
double sigLow() const
The Low-energy cross sections.
Definition: HISubCollisionModel.h:250
void fillCache(vector< vector< double > > &sigNN, int idAIn, int idBIn, int iECM)
Definition: HISubCollisionModel.h:415
int nucleons() const
Definition: HISubCollisionModel.h:64
Both projectile and target are diffractively excited.
Definition: HISubCollisionModel.h:41
virtual ~SubCollisionModel()
Virtual destructor.
Definition: HISubCollisionModel.h:182
vector< double > defParm() const override
Get the default parameter values for this model.
Definition: HISubCollisionModel.h:666
ParticleData * particleDataPtr
Pointer to the particle data table.
Definition: Info.h:83
double sigEl() const
The target elastic cross section.
Definition: HISubCollisionModel.h:229
Definition: HISubCollisionModel.h:771
SubCollisionSet(multiset< SubCollision > subCollisionsIn, double TIn, double T12In, double T21In, double T22In)
Definition: HISubCollisionModel.h:109
CollisionType
This defines the type of a binary nucleon collision.
Definition: HISubCollisionModel.h:35
double pickRadiusProj() const override
Pick a radius for the nucleon, depending on the specific model.
Definition: HISubCollisionModel.h:796
virtual void generateNucleonStates(Nucleus &, Nucleus &)
Definition: HISubCollisionModel.h:305
vector< double > minParm() const override
Get the minimum and maximum allowed parameter values for this model.
Definition: HISubCollisionModel.h:531
Header for classes to set beam momentum and interaction vertex spread.
Definition: Analysis.h:20
double sigSDET() const
The target single diffractive excitation cross section (target).
Definition: HISubCollisionModel.h:241
Definition: HISubCollisionModel.h:560
virtual ~LogNormalSubCollisionModel()
Virtual destructor.
Definition: HISubCollisionModel.h:782
SubCollisionModel(int nParm)
Definition: HISubCollisionModel.h:170
double sigTot() const
The target total nucleon-nucleon cross section.
Definition: HISubCollisionModel.h:226
bool operator<(const SubCollision &s) const
Used to order sub-collisions in a set.
Definition: HISubCollisionModel.h:60
int idASave
For variable energies.
Definition: HISubCollisionModel.h:358
double sigSDEP() const
The target single diffractive excitation cross section (projectile).
Definition: HISubCollisionModel.h:238
Nucleon * proj
The projectile nucleon.
Definition: HISubCollisionModel.h:68
This is not a collision.
Definition: HISubCollisionModel.h:37
vector< double > minParm() const override
virtual SigEst getSig() const override;
Definition: HISubCollisionModel.h:787
vector< double > maxParm() const override
Get the maximum allowed parameter values for this model.
Definition: HISubCollisionModel.h:533
vector< double > minParm() const override
Get the minimum and maximum allowed parameter values for this model.
Definition: HISubCollisionModel.h:495
vector< double > sig
The cross sections (tot, nd, dd, sdp, sdt, cd, el, bslope).
Definition: HISubCollisionModel.h:150
This class holds a map of all ParticleDataEntries.
Definition: ParticleData.h:423
double pickRadiusProj() const override
Pick a radius for the nucleon, depending on the specific model.
Definition: HISubCollisionModel.h:673
Definition: Basics.h:32
vector< double > minParm() const override
Get the minimum and maximum allowed parameter values for this model.
Definition: HISubCollisionModel.h:665
Definition: Settings.h:196
double b
The impact parameter distance between the nucleons in femtometer.
Definition: HISubCollisionModel.h:74
NaiveSubCollisionModel()
The default constructor simply lists the nucleon-nucleon cross sections.
Definition: HISubCollisionModel.h:525
The projectile is diffractively excited.
Definition: HISubCollisionModel.h:39
int opacityMode
Optional mode for opacity.
Definition: HISubCollisionModel.h:597