PYTHIA  8.317
Basics.h
1 // Basics.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 // Header file for basic, often-used helper classes.
7 // RndmEngine: base class for external random number generators.
8 // Rndm: random number generator.
9 // Vec4: simple four-vectors.
10 // RotBstMatrix: matrices encoding rotations and boosts of Vec4 objects.
11 // Hist: simple one-dimensional histograms.
12 
13 #ifndef Pythia8_Basics_H
14 #define Pythia8_Basics_H
15 
16 #include "Pythia8/PythiaStdlib.h"
17 #include "Pythia8/SharedPointers.h"
18 
19 namespace Pythia8 {
20 
21 //==========================================================================
22 
23 // Forward reference to RotBstMatrix class; needed in Vec4 class.
24 class RotBstMatrix;
25 
26 //--------------------------------------------------------------------------
27 
28 // Vec4 class.
29 // This class implements four-vectors, in energy-momentum space.
30 // (But can equally well be used to hold space-time four-vectors.)
31 
32 class Vec4 {
33 
34 public:
35 
36  // Constructors.
37  Vec4(double xIn = 0., double yIn = 0., double zIn = 0., double tIn = 0.)
38  : xx(xIn), yy(yIn), zz(zIn), tt(tIn) { }
39  Vec4(const Vec4& v) : xx(v.xx), yy(v.yy), zz(v.zz), tt(v.tt) { }
40  Vec4& operator=(const Vec4& v) { if (this != &v) { xx = v.xx; yy = v.yy;
41  zz = v.zz; tt = v.tt; } return *this; }
42  Vec4& operator=(double value) { xx = value; yy = value; zz = value;
43  tt = value; return *this; }
44 
45  // Member functions for input.
46  void reset() {xx = 0.; yy = 0.; zz = 0.; tt = 0.;}
47  void p(double xIn, double yIn, double zIn, double tIn)
48  {xx = xIn; yy = yIn; zz = zIn; tt = tIn;}
49  void p(Vec4 pIn) {xx = pIn.xx; yy = pIn.yy; zz = pIn.zz; tt = pIn.tt;}
50  void px(double xIn) {xx = xIn;}
51  void py(double yIn) {yy = yIn;}
52  void pz(double zIn) {zz = zIn;}
53  void e(double tIn) {tt = tIn;}
54 
55  // Member functions for output.
56  double px() const {return xx;}
57  double py() const {return yy;}
58  double pz() const {return zz;}
59  double e() const {return tt;}
60  double& operator[](int i) {
61  switch(i) {
62  case 1: return xx;
63  case 2: return yy;
64  case 3: return zz;
65  default: return tt;
66  }
67  }
68  double mCalc() const {double temp = tt*tt - xx*xx - yy*yy - zz*zz;
69  return (temp >= 0.) ? sqrt(temp) : -sqrt(-temp);}
70  double m2Calc() const {return tt*tt - xx*xx - yy*yy - zz*zz;}
71  double pT() const {return sqrt(xx*xx + yy*yy);}
72  double pT2() const {return xx*xx + yy*yy;}
73  double pAbs() const {return sqrt(xx*xx + yy*yy + zz*zz);}
74  double pAbs2() const {return xx*xx + yy*yy + zz*zz;}
75  double eT() const {double temp = xx*xx + yy*yy;
76  return tt * sqrt( temp / (temp + zz*zz) );}
77  double eT2() const {double temp = xx*xx + yy*yy;
78  return tt*tt * temp / (temp + zz*zz);}
79  double theta() const {return atan2(sqrt(xx*xx + yy*yy), zz);}
80  double phi() const {return atan2(yy,xx);}
81  double thetaXZ() const {return atan2(xx,zz);}
82  double pPos() const {return tt + zz;}
83  double pNeg() const {return tt - zz;}
84  double rap() const {
85  double txyz = (tt > 0.) ? tt : sqrt(xx*xx + yy*yy + zz*zz);
86  if (zz >= txyz) return 20.;
87  if (zz <= -txyz) return -20.;
88  return 0.5 * log( (txyz + zz) / (txyz - zz) );}
89  double eta() const {double xyz = sqrt(xx*xx + yy*yy + zz*zz);
90  if (zz >= xyz) return 20.;
91  if (zz <= -xyz) return -20.;
92  return 0.5 * log( (xyz + zz) / (xyz - zz) );}
93 
94  // Member functions that perform operations.
95  void rescale3(double fac) {xx *= fac; yy *= fac; zz *= fac;}
96  void rescale4(double fac) {xx *= fac; yy *= fac; zz *= fac; tt *= fac;}
97  void flip3() {xx = -xx; yy = -yy; zz = -zz;}
98  void flip4() {xx = -xx; yy = -yy; zz = -zz; tt = -tt;}
99  void rot(double thetaIn, double phiIn);
100  void rotaxis(double phiIn, double nx, double ny, double nz);
101  void rotaxis(double phiIn, const Vec4& n);
102  void bst(double betaX, double betaY, double betaZ);
103  void bst(double betaX, double betaY, double betaZ, double gamma);
104  void bst(const Vec4& pIn);
105  void bst(const Vec4& pIn, double mIn);
106  void bstback(const Vec4& pIn);
107  void bstback(const Vec4& pIn, double mIn);
108  void rotbst(const RotBstMatrix& M);
109  double eInFrame(const Vec4& pIn) const;
110 
111  // Operator overloading with member functions
112  inline Vec4 operator-() const {Vec4 tmp; tmp.xx = -xx; tmp.yy = -yy;
113  tmp.zz = -zz; tmp.tt = -tt; return tmp;}
114  inline Vec4& operator+=(const Vec4& v) {xx += v.xx; yy += v.yy; zz += v.zz;
115  tt += v.tt; return *this;}
116  inline Vec4& operator-=(const Vec4& v) {xx -= v.xx; yy -= v.yy; zz -= v.zz;
117  tt -= v.tt; return *this;}
118  inline Vec4& operator*=(double f) {xx *= f; yy *= f; zz *= f;
119  tt *= f; return *this;}
120  inline Vec4& operator/=(double f) {xx /= f; yy /= f; zz /= f;
121  tt /= f; return *this;}
122  inline Vec4 operator+(const Vec4& v) const {
123  Vec4 tmp = *this; return tmp += v;}
124  inline Vec4 operator-(const Vec4& v) const {
125  Vec4 tmp = *this; return tmp -= v;}
126  inline Vec4 operator*(double f) const {
127  Vec4 tmp = *this; return tmp *= f;}
128  inline Vec4 operator/(double f) const {
129  Vec4 tmp = *this; return tmp /= f;}
130  inline double operator*(const Vec4& v) const {
131  return tt*v.tt - xx*v.xx - yy*v.yy - zz*v.zz;}
132 
133  // Operator overloading with friends.
134  friend Vec4 operator*(double f, const Vec4& v1);
135 
136  // Print a four-vector.
137  friend ostream& operator<<(ostream&, const Vec4& v) ;
138 
139  // Check if NaN, INF, or finite.
140  friend inline bool isnan(const Vec4 &v) {
141  return isnan(v.tt) || isnan(v.xx) || isnan(v.yy) || isnan(v.zz);}
142  friend inline bool isinf(const Vec4 &v) {
143  return isinf(v.tt) || isinf(v.xx) || isinf(v.yy) || isinf(v.zz);}
144  friend inline bool isfinite(const Vec4 &v) {
145  return isfinite(v.tt) && isfinite(v.xx) && isfinite(v.yy)
146  && isfinite(v.zz);}
147 
148  // Invariant mass and its square.
149  friend double m(const Vec4& v1);
150  friend double m(const Vec4& v1, const Vec4& v2);
151  friend double m2(const Vec4& v1);
152  friend double m2(const Vec4& v1, const Vec4& v2);
153  friend double m2(const Vec4& v1, const Vec4& v2, const Vec4& v3);
154  friend double m2(const Vec4& v1, const Vec4& v2, const Vec4& v3,
155  const Vec4& v4);
156 
157  // Scalar and cross product of 3-vector parts.
158  friend double dot3(const Vec4& v1, const Vec4& v2);
159  friend Vec4 cross3(const Vec4& v1, const Vec4& v2);
160 
161  // Cross-product of three 4-vectors ( p_i = epsilon_{iabc} p_a p_b p_c).
162  friend Vec4 cross4(const Vec4& a, const Vec4& b, const Vec4& c);
163 
164  // theta is the opening angle (on the unit sphere) between v1 and v2.
165  friend double theta(const Vec4& v1, const Vec4& v2);
166  friend double costheta(const Vec4& v1, const Vec4& v2);
167  friend double sintheta(const Vec4& v1, const Vec4& v2);
168 
169  // phi is azimuthal angle between v1 and v2 around z axis.
170  friend double phi(const Vec4& v1, const Vec4& v2);
171  friend double cosphi(const Vec4& v1, const Vec4& v2);
172 
173  // phi is azimuthal angle between v1 and v2 around n axis.
174  friend double phi(const Vec4& v1, const Vec4& v2, const Vec4& n);
175  friend double cosphi(const Vec4& v1, const Vec4& v2, const Vec4& n);
176 
177  // R is distance in cylindrical (y/eta, phi) coordinates.
178  friend double RRapPhi(const Vec4& v1, const Vec4& v2);
179  friend double REtaPhi(const Vec4& v1, const Vec4& v2);
180 
181  // Shift four-momenta within pair from old to new masses.
182  friend bool pShift( Vec4& p1Move, Vec4& p2Move, double m1New, double m2New);
183 
184  // Create two vectors that are perpendicular to both input vectors.
185  friend pair<Vec4,Vec4> getTwoPerpendicular(const Vec4& v1, const Vec4& v2);
186 
187 private:
188 
189  // Constants: could only be changed in the code itself.
190  static const double TINY;
191 
192  // The four-vector data members.
193  double xx, yy, zz, tt;
194 
195 };
196 
197 //--------------------------------------------------------------------------
198 
199 // Namespace function declarations; friends of Vec4 class.
200 
201 // Implementation of operator overloading with friends.
202 inline Vec4 operator*(double f, const Vec4& v1)
203  {Vec4 v = v1; return v *= f;}
204 
205 // Invariant mass and its square.
206 double m(const Vec4& v1);
207 double m(const Vec4& v1, const Vec4& v2);
208 double m2(const Vec4& v1);
209 double m2(const Vec4& v1, const Vec4& v2);
210 double m2(const Vec4& v1, const Vec4& v2, const Vec4& v3);
211 double m2(const Vec4& v1, const Vec4& v2, const Vec4& v3,
212  const Vec4& v4);
213 
214 // Scalar and cross product of 3-vector parts.
215 double dot3(const Vec4& v1, const Vec4& v2);
216 Vec4 cross3(const Vec4& v1, const Vec4& v2);
217 
218 // Cross-product of three 4-vectors ( p_i = epsilon_{iabc} p_a p_b p_c).
219 Vec4 cross4(const Vec4& a, const Vec4& b, const Vec4& c);
220 
221 // Fully antisymetric product of four 4-vectors
222 // (Levi-Civita epsilon_{abcd} p_a p_b p_c p_d ).
223 double eps4(const Vec4& a, const Vec4& b, const Vec4& c,
224  const Vec4& d);
225 
226 // theta is polar angle between v1 and v2.
227 double theta(const Vec4& v1, const Vec4& v2);
228 double costheta(const Vec4& v1, const Vec4& v2);
229 double sintheta(const Vec4& v1, const Vec4& v2);
230 double costheta(double e1, double e2, double m1, double m2, double s12);
231 
232 // phi is azimuthal angle between v1 and v2 around z axis.
233 double phi(const Vec4& v1, const Vec4& v2);
234 double cosphi(const Vec4& v1, const Vec4& v2);
235 
236 // phi is azimuthal angle between v1 and v2 around n axis.
237 double phi(const Vec4& v1, const Vec4& v2, const Vec4& n);
238 double cosphi(const Vec4& v1, const Vec4& v2, const Vec4& n);
239 
240 // R is distance in cylindrical (y/eta, phi) coordinates.
241 double RRapPhi(const Vec4& v1, const Vec4& v2);
242 double REtaPhi(const Vec4& v1, const Vec4& v2);
243 
244 // Print a four-vector.
245 ostream& operator<<(ostream&, const Vec4& v) ;
246 
247 // Shift four-momenta within pair from old to new masses.
248 bool pShift( Vec4& p1Move, Vec4& p2Move, double m1New, double m2New);
249 
250 // Create two vectors that are perpendicular to both input vectors.
251 pair<Vec4,Vec4> getTwoPerpendicular(const Vec4& v1, const Vec4& v2);
252 
253 //==========================================================================
254 
255 // RotBstMatrix class.
256 // This class implements 4 * 4 matrices that encode an arbitrary combination
257 // of rotations and boosts, that can be applied to Vec4 four-vectors.
258 
260 
261 public:
262 
263  // Constructors.
264  RotBstMatrix() : M() {for (int i = 0; i < 4; ++i) {
265  for (int j = 0; j < 4; ++j) { M[i][j] = (i==j) ? 1. : 0.; } } }
266  RotBstMatrix(const RotBstMatrix& Min) : M() {
267  for (int i = 0; i < 4; ++i) { for (int j = 0; j < 4; ++j) {
268  M[i][j] = Min.M[i][j]; } } }
269  RotBstMatrix& operator=(const RotBstMatrix& Min) {if (this != &Min) {
270  for (int i = 0; i < 4; ++i) { for (int j = 0; j < 4; ++j) {
271  M[i][j] = Min.M[i][j]; } } } return *this; }
272 
273  // Member functions.
274  void rot(double = 0., double = 0.);
275  void rot(const Vec4& p);
276  void bst(double = 0., double = 0., double = 0., double = 0.);
277  void bst(const Vec4&);
278  void bstback(const Vec4&);
279  void bst(const Vec4&, const Vec4&);
280  void toCMframe(const Vec4&, const Vec4&);
281  void fromCMframe(const Vec4&, const Vec4&, bool flip = false);
282  void toSameVframe(const Vec4&, const Vec4&);
283  void fromSameVframe(const Vec4&, const Vec4&);
284  void rotbst(const RotBstMatrix&);
285  void invert();
286  RotBstMatrix inverse() const { RotBstMatrix tmp = *this;
287  tmp.invert(); return tmp; }
288  void reset();
289 
290  // Return value of matrix element.
291  double value(int i, int j) { return M[i][j];}
292 
293  // Crude estimate deviation from unit matrix.
294  double deviation() const;
295 
296  // Print a transformation matrix.
297  friend ostream& operator<<(ostream&, const RotBstMatrix&) ;
298 
299  // Private members to be accessible from Vec4.
300  friend class Vec4;
301 
302  // Multiplication.
303  Vec4 operator*(Vec4 p) const { p.rotbst(*this); return p; }
304  RotBstMatrix operator*(RotBstMatrix R) const { R.rotbst(*this); return R; }
305 
306 private:
307 
308  // Constants: could only be changed in the code itself.
309  static const double TINY;
310 
311  // The rotation-and-boost matrix data members.
312  double M[4][4];
313 
314 };
315 
316 //--------------------------------------------------------------------------
317 
318 // Namespace function declaration; friend of RotBstMatrix class.
319 
320 // Print a transformation matrix.
321 ostream& operator<<(ostream&, const RotBstMatrix&) ;
322 
323 // Get a RotBstMatrix to rest frame of p.
324 inline RotBstMatrix toCMframe(const Vec4& p) {
325  RotBstMatrix tmp; tmp.bstback(p); return tmp; }
326 
327 // Get a RotBstMatrix from rest frame of p.
328 inline RotBstMatrix fromCMframe(const Vec4& p) {
329  RotBstMatrix tmp; tmp.bst(p); return tmp; }
330 
331 // Get a RotBstMatrix to rest frame of p1 and p2, where p1 is along
332 // the z-axis.
333 inline RotBstMatrix toCMframe(const Vec4& p1, const Vec4& p2) {
334  RotBstMatrix tmp; tmp.toCMframe(p1, p2); return tmp; }
335 
336 // Get a RotBstMatrix from rest frame of p1 and p2, where p1 is
337 // assumed by default to be along the z-axis. The flip option
338 // handles the case when p1 is along the negative z-axis.
339 inline RotBstMatrix fromCMframe(const Vec4& p1, const Vec4& p2,
340  bool flip = false) {
341  RotBstMatrix tmp; tmp.fromCMframe(p1, p2, flip); return tmp; }
342 
343 // Get a RotBstMatrix to rest frame of ptot where pz is along the
344 // z-axis and pxz is in the xz-plane with positive x.
345 inline RotBstMatrix toCMframe(const Vec4& ptot, const Vec4& pz,
346  const Vec4 & pxz) { RotBstMatrix tmp = toCMframe(ptot);
347  Vec4 pzp = tmp*pz; tmp.rot(0.0, -pzp.phi()); tmp.rot(-pzp.theta());
348  tmp.rot(0.0, -(tmp*pxz).phi()); return tmp; }
349 
350 // Get a RotBstMatrix from rest frame of ptot where pz is along the
351 // z-axis and pxz is in the xz-plane with positive x.
352 inline RotBstMatrix fromCMframe(const Vec4& ptot, const Vec4& pz,
353  const Vec4 & pxz) { return toCMframe(ptot, pz, pxz).inverse(); }
354 
355 //==========================================================================
356 
357 // RndmEngine is the base class for external random number generators.
358 // There is only one pure virtual method, that should do the generation.
359 
360 class RndmEngine {
361 
362 public:
363 
364  // Destructor.
365  virtual ~RndmEngine() {}
366 
367  // A virtual method, wherein the derived class method
368  // generates a random number uniformly distributed between 0 and 1.
369  virtual double flat() {return 1;}
370 
371 };
372 
373 //==========================================================================
374 
375 // RndmState class.
376 // This class describes the configuration of a Rndm object.
377 
378 struct RndmState {
379  int i97{}, j97{}, seed{0};
380  long sequence{0};
381  double u[97]{}, c{}, cd{}, cm{};
382 
383  // Test whether two random states would generate the same random sequence.
384  bool operator==(const RndmState& other) const;
385 };
386 
387 //==========================================================================
388 
389 // Rndm class.
390 // This class handles random number generation according to the
391 // Marsaglia-Zaman-Tsang algorithm.
392 
393 class Rndm {
394 
395 public:
396 
397  // Constructors.
398  Rndm() : initRndm(false), stateSave(), useExternalRndm(false) { }
399  Rndm(int seedIn) : initRndm(false), stateSave(), useExternalRndm(false) {
400  init(seedIn);}
401 
402  // Possibility to pass in pointer for external random number generation.
403  bool rndmEnginePtr( RndmEnginePtr rndmEngPtrIn);
404 
405  // Initialize, normally at construction or in first call.
406  void init(int seedIn = 0) ;
407 
408  // Generate next random number uniformly between 0 and 1.
409  double flat() ;
410 
411  // Generate random numbers according to exp(-x).
412  double exp() ;
413 
414  // Generate random numbers according to x * exp(-x).
415  double xexp() { return -log(flat() * flat()) ;}
416 
417  // Generate random numbers according to exp(-x^2/2).
418  double gauss() {return sqrt(-2. * log(flat())) * cos(M_PI * flat());}
419 
420  // Generate two random numbers according to exp(-x^2/2-y^2/2).
421  pair<double, double> gauss2() {double r = sqrt(-2. * log(flat()));
422  double phi = 2. * M_PI * flat();
423  return { r * sin(phi), r * cos(phi) };}
424 
425  // Generate a random number according to a Gamma-distribution.
426  double gamma(double k0, double r0);
427 
428  // Generate two random vectors according to the phase space distribution
429  pair<Vec4, Vec4> phaseSpace2(double eCM, double m1, double m2);
430 
431  // Pick one option among vector of (positive) probabilities.
432  int pick(const vector<double>& prob) ;
433 
434  // Randomly shuffle a vector, standard Fisher-Yates algorithm.
435  template<typename T> void shuffle(vector<T>& vec);
436 
437  // Peek at the next random number in sequence without updating
438  // the generator state.
439  double peekFlat() {if (useExternalRndm) return -1;
440  RndmState oldState = stateSave;
441  double f = this->flat();
442  stateSave = oldState;
443  return f;
444  }
445 
446  // Save or read current state to or from a binary file.
447  bool dumpState(string fileName);
448  bool readState(string fileName);
449 
450  // Get or set the state of the random number generator.
451  RndmState getState() const {return stateSave;}
452  void setState(const RndmState& state) {stateSave = state;}
453 
454  // The default seed, i.e. the Marsaglia-Zaman random number sequence.
455  static constexpr int DEFAULTSEED = 19780503;
456 
457 #ifdef RNGDEBUG
458  // Random number methods used for debugging only.
459  double flatDebug(string loc, string file, int line);
460  double xexpDebug(string loc, string file, int line);
461  double gaussDebug(string loc, string file, int line);
462  pair<double, double> gauss2Debug(string loc, string file, int line);
463  double gammaDebug(string loc, string file, int line, double k0, double r0);
464  pair<Vec4, Vec4> phaseSpace2Debug(string loc, string file, int line,
465  double eCM, double m1, double m2);
466 
467  // Static members for debugging to print call file location or filter.
468  static bool debugNow, debugLocation, debugIndex;
469  static int debugPrecision, debugCall;
470  static set<string> debugStarts, debugEnds, debugContains, debugMatches;
471 #endif
472 
473 private:
474 
475  // State of the random number generator.
476  bool initRndm;
477  RndmState stateSave;
478 
479  // Pointer for external random number generation.
480  bool useExternalRndm;
481  RndmEnginePtr rndmEngPtr{};
482 
483 };
484 
485 //==========================================================================
486 
487 // Hist class.
488 // This class handles a single histogram at a time.
489 
490 class Hist {
491 
492 public:
493 
494  // Constructors, including copy constructors.
495  Hist() : titleSave(""), nBin(), nFill(), nNonFinite(), xMin(),
496  xMax(), linX(), doStats(), dx(), under(), inside(), over(), sumxNw()
497  { }
498  Hist(string titleIn, int nBinIn = 100, double xMinIn = 0.,
499  double xMaxIn = 1., bool logXIn = false, bool doStatsIn = false) :
500  nBin(), nFill(), nNonFinite(), xMin(), xMax(), linX(), doStats(), dx(),
501  under(), inside(), over(), sumxNw()
502  { book(titleIn, nBinIn, xMinIn, xMaxIn, logXIn, doStatsIn); }
503  Hist(const Hist& h)
504  : titleSave(h.titleSave), nBin(h.nBin), nFill(h.nFill),
505  nNonFinite(h.nNonFinite), xMin(h.xMin), xMax(h.xMax), linX(h.linX),
506  doStats(h.doStats), dx(h.dx), under(h.under), inside(h.inside),
507  over(h.over), res(h.res), res2(h.res2), sumxNw() {
508  for (int i = 0; i < nMoments; ++i) sumxNw[i] = h.sumxNw[i];
509  }
510  Hist(string titleIn, const Hist& h)
511  : titleSave(titleIn), nBin(h.nBin), nFill(h.nFill),
512  nNonFinite(h.nNonFinite), xMin(h.xMin), xMax(h.xMax), linX(h.linX),
513  doStats(h.doStats), dx(h.dx), under(h.under), inside(h.inside),
514  over(h.over), res(h.res), res2(h.res2), sumxNw() {
515  for (int i = 0; i < nMoments; ++i) sumxNw[i] = h.sumxNw[i];
516  }
517  Hist& operator=(const Hist& h) { if(this != &h) {
518  nBin = h.nBin; nFill = h.nFill; nNonFinite = h.nNonFinite; xMin = h.xMin;
519  xMax = h.xMax; linX = h.linX; doStats = h.doStats; dx = h.dx;
520  under = h.under; inside = h.inside; over = h.over;
521  for (int i = 0; i < nMoments; ++i) sumxNw[i] = h.sumxNw[i];
522  res = h.res; res2 = h.res2; } return *this; }
523 
524  // Create a histogram that is the plot of the given function.
525  static Hist plotFunc(function<double(double)> f, string titleIn,
526  int nBinIn, double xMinIn, double xMaxIn, bool logXIn = false);
527 
528  // Book a histogram.
529  void book(string titleIn = " ", int nBinIn = 100, double xMinIn = 0.,
530  double xMaxIn = 1., bool logXIn = false, bool doStatsIn = false) ;
531 
532  // Set title of a histogram.
533  void title(string titleIn = " ") {titleSave = titleIn; }
534 
535  // Reset bin contents.
536  void null() ;
537 
538  // Fill bin with weight w and weight uncertainty sig.
539  // (Default sig < 0 => use sig = w, for pure stat counting.)
540  void fill(double x, double w = 1., double sig = -1.) ;
541 
542  // Print a histogram with overloaded << operator.
543  friend ostream& operator<<(ostream& os, const Hist& h) ;
544 
545  // Print histogram contents as a table (e.g. for Gnuplot, Rivet or Pyplot),
546  // optionally with statistical errors.
547  void table(ostream& os = cout, bool printOverUnder = false,
548  bool xMidBin = true, bool printError = false) const ;
549  void table(string fileName, bool printOverUnder = false,
550  bool xMidBin = true, bool printError = false) const {
551  ofstream fileStream(fileName.c_str());
552  table(fileStream, printOverUnder, xMidBin, printError);}
553  void yodaTable(ostream& os = cout, string path = "hist",
554  double scaledBy = 1.0, vector<int> maskedBins = {}) const;
555  void yodaTable(string fileName, string path, double scaledBy = 1.0,
556  vector<int> maskedBins = {}) const {
557  ofstream fileStream(fileName.c_str());
558  yodaTable(fileStream, path, scaledBy, maskedBins);}
559  void rivetTable(ostream& os = cout, bool printError = true) const;
560  void rivetTable(string fileName, bool printError = true) const {
561  ofstream fileStream(fileName.c_str());
562  rivetTable(fileStream, printError);}
563  void pyplotTable(ostream& os = cout, bool isHist = true,
564  bool printError = false) const;
565  void pyplotTable(string fileName, bool isHist = true,
566  bool printError = false) const {
567  ofstream fileStream(fileName.c_str());
568  pyplotTable(fileStream, isHist, printError);}
569 
570  // Fill contents of a two-column (x,y) table, e.g. written by table() above.
571  void fillTable(istream& is = cin);
572  void fillTable(string fileName) { ifstream streamName(fileName.c_str());
573  fillTable(streamName);}
574 
575  // Print a table out of two histograms with same x axis (no errors printed).
576  friend void table(const Hist& h1, const Hist& h2, ostream& os,
577  bool printOverUnder, bool xMidBin) ;
578  friend void table(const Hist& h1, const Hist& h2, string fileName,
579  bool printOverUnder, bool xMidBin) ;
580 
581  // Return title and size of histogram. Also if logarithmic x scale.
582  string getTitle() const {return titleSave;}
583  int getBinNumber() const {return nBin;}
584  int getNonFinite() const {return nNonFinite;}
585  bool getLinX() const {return linX;}
586 
587  // Return min and max in x and y directions.
588  double getXMin() const {return xMin;}
589  double getXMax() const {return xMax;}
590  double getYMin() const { if (nBin == 0) return 0.;
591  double yMin = res[0];
592  for (int ix = 1; ix < nBin; ++ix)
593  if (res[ix] < yMin ) yMin = res[ix];
594  return yMin;}
595  double getYMax() const { if (nBin == 0) return 0.;
596  double yMax = res[0];
597  for (int ix = 1; ix < nBin; ++ix)
598  if (res[ix] > yMax ) yMax = res[ix];
599  return yMax;}
600  double getYAbsMin() const { double yAbsMin = 1e20; double yAbs;
601  for (int ix = 0; ix < nBin; ++ix) { yAbs = abs(res[ix]);
602  if (yAbs > 1e-20 && yAbs < yAbsMin) yAbsMin = yAbs; }
603  return yAbsMin;}
604 
605  // Return <X> and error on <X>, unbinned from saved weight sums (default)
606  // or directly from the histogram bins (unbinned = false). In the latter
607  // case, the error estimate includes the difference between the binned and
608  // unbinned value summed in quadrature with the statistical error, as a
609  // measure of bin granularity error.
610  double getXMean(bool unbinned=true) const;
611  double getXMeanErr(bool unbinned=true) const;
612 
613  // Return Median in X and its statistical error, ignoring underflow and
614  // overflow (default) or including them (includeOverUnder = true). By
615  // default, error includes granularity estimate obtained by comparing binned
616  // vs unbinned mean value, but this can be switched off (unbinned = false).
617  double getXPercentile(double n, bool includeOverUnder = false) const;
618  double getXMedian(bool includeOverUnder=false) const {
619  return getXPercentile(50.0, includeOverUnder);}
620  double getXMedianErr(bool unbinned=true) const;
621 
622  // Return average <Y> value.
623  double getYMean() const { return inside / nFill; }
624 
625  // Return RMS and equivalent n'th roots of n'th moments about the mean,
626  // and their error estimates. Up to n = 6, both unbinned and binned moments
627  // can be calculated. For n >= 7, and for all error estimates, only
628  // binned values are available. Note that (unlike ROOT), the error estimates
629  // do not assume normal distributions.
630  // RMN(2) = RMS is the standard root-mean-square deviation from the mean.
631  // RMN(3) is the cube root of the mean-cube deviation,
632  // cbrt(<(x - <x>)^3>). It is sensitive to single-sided tails,
633  // as are characteristic of many particle-physics distributions.
634  // RMN(4) adds sensitivity to double-sided long tails (eg BW vs
635  // Gaussian), and further sensitivity to long single-sided ones.
636  // Etc.
637  double getXRMN(int n=2, bool unbinned=true) const;
638  double getXRMS(bool unbinned=true) const {return getXRMN(2, unbinned);}
639 
640  double getXRMNErr(int n=2, bool unbinned=true) const;
641  double getXRMSErr(bool unbinned=true) const {
642  return getXRMNErr(2, unbinned);}
643 
644  // Return content of specific bin: 0 gives underflow and nBin+1 overflow.
645  double getBinContent(int iBin) const;
646 
647  // Return the statistical uncertainty of the bin.
648  double getBinError(int iBin) const;
649 
650  // Return the squared statistical uncertainty of the bin.
651  double getBinError2(int iBin) const;
652 
653  // Return the lower edge of the bin.
654  double getBinEdge(int iBin) const;
655 
656  // Return the width of the bin.
657  double getBinWidth(int iBin=1) const;
658 
659  // Return the center of the bin.
660  double getBinCenter(int iBin) const;
661 
662  // Return the contents for all bins.
663  vector<double> getBinContents() const;
664 
665  // Return the statitistical uncertainty for all bins.
666  vector<double> getBinErrors() const;
667 
668  // Return the squared statitistical uncertainty for all bins.
669  vector<double> getBinError2s() const;
670 
671  // Return the lower edges for all bins.
672  vector<double> getBinEdges() const;
673 
674  // Return the widths for all bins.
675  vector<double> getBinWidths() const;
676 
677  // Return the center for all bins.
678  vector<double> getBinCenters() const;
679 
680  // Return total number of entries.
681  int getEntries(bool alsoNonFinite = true) const {
682  return alsoNonFinite ? nNonFinite + nFill : nFill; }
683 
684  // Return total sum of weights.
685  double getWeightSum(bool alsoOverUnder = true) const {
686  return alsoOverUnder ? inside + over + under : inside; }
687 
688  // Return total effective entries (for weighted histograms = number
689  // of equivalent unweighted events for same statistical power).
690  double getNEffective() const {
691  double sumw2 = 0.;
692  for (int ix = 0; ix < nBin; ++ix) sumw2 += res2[ix];
693  if (sumw2 <= Hist::TINY) return 0.;
694  else return pow2(sumxNw[0]) / sumw2;
695  }
696 
697  // Check whether another histogram has same size and limits.
698  bool sameSize(const Hist& h) const ;
699 
700  // Take an arbitrary function of bin contents.
701  void takeFunc(function<double(double)> func);
702 
703  // Take logarithm (base 10 or e) of bin contents.
704  void takeLog(bool tenLog = true);
705 
706  // Take square root of bin contents.
707  void takeSqrt();
708 
709  // Normalize sum of bin contents to value, with or without overflow bins.
710  void normalize(double f = 1, bool overflow = true) ;
711 
712  // Normalize sum of bin areas to value, with or without overflow bins.
713  void normalizeIntegral(double f = 1, bool overflow = true);
714 
715  // Scale each bin content by 1 / (wtSum * bin width).
716  void normalizeSpectrum(double wtSum);
717 
718  // Add contents of all previous bins to each bin, like an integral.
719  void makeCumulative( bool updateStatistics = false,
720  bool withUnderflow = false);
721 
722  // Operator overloading with member functions
723  Hist& operator+=(const Hist& h) ;
724  Hist& operator-=(const Hist& h) ;
725  Hist& operator*=(const Hist& h) ;
726  Hist& operator/=(const Hist& h) ;
727  Hist& operator+=(double f) ;
728  Hist& operator-=(double f) ;
729  Hist& operator*=(double f) ;
730  Hist& operator/=(double f) ;
731  Hist operator+(double f) const;
732  Hist operator+(const Hist& h2) const;
733  Hist operator-(double f) const;
734  Hist operator-(const Hist& h2) const;
735  Hist operator*(double f) const;
736  Hist operator*(const Hist& h2) const;
737  Hist operator/(double f) const;
738  Hist operator/(const Hist& h2) const;
739 
740  // Operator overloading with friends
741  friend Hist operator+(double f, const Hist& h1);
742  friend Hist operator-(double f, const Hist& h1);
743  friend Hist operator*(double f, const Hist& h1);
744  friend Hist operator/(double f, const Hist& h1);
745 
746 private:
747 
748  // Constants: could only be changed in the code itself.
749  static const int NBINMAX, NCOLMAX, NLINES;
750  static const double TOLERANCE, TINY, LARGE, SMALLFRAC, DYAC[];
751  static const char NUMBER[];
752 
753  // Properties and contents of a histogram.
754  string titleSave;
755  int nBin, nFill, nNonFinite;
756  double xMin, xMax;
757  bool linX, doStats;
758  double dx, under, inside, over;
759  vector<double> res, res2;
760 
761  // Sum x^N w, for different powers N, for calculation of unbinned moments.
762  static constexpr int nMoments = 7;
763  double sumxNw[nMoments];
764 
765 };
766 
767 //--------------------------------------------------------------------------
768 
769 // Namespace function declarations; friends of Hist class.
770 
771 // Print a histogram with overloaded << operator.
772 ostream& operator<<(ostream& os, const Hist& h) ;
773 
774 // Print a table out of two histograms with same x axis.
775 void table(const Hist& h1, const Hist& h2, ostream& os = cout,
776  bool printOverUnder = false, bool xMidBin = true) ;
777 void table(const Hist& h1, const Hist& h2, string fileName,
778  bool printOverUnder = false, bool xMidBin = true) ;
779 
780 // Operator overloading with friends
781 Hist operator+(double f, const Hist& h1);
782 Hist operator-(double f, const Hist& h1);
783 Hist operator*(double f, const Hist& h1);
784 Hist operator/(double f, const Hist& h1);
785 
786 //==========================================================================
787 
788 // HistPlot class.
789 // Writes a Python program that can generate PDF plots from Hist histograms.
790 
791 class HistPlot {
792 
793 public:
794 
795  // Constructor requires name of Python program (and adds .py).
796  HistPlot(string pythonName, bool useLegacyIn = false)
797  : nFrame(), nTable(), useLegacy(useLegacyIn) {
798  toPython.open((pythonName + ".py").c_str());
799  toPython << "from matplotlib import pyplot as plt" << endl
800  << "from matplotlib.backends.backend_pdf import PdfPages" << endl;
801  nPDF = 0; }
802 
803  // Destructor should do final close.
804  ~HistPlot() { toPython << "pp.close()" << endl; }
805 
806  // New plot frame, with title, x and y labels, x and y sizes.
807  void frame( string frameIn, string titleIn = "", string xLabIn = "",
808  string yLabIn = "", double xSizeIn = 8., double ySizeIn = 6.) {
809  framePrevious = frameName; frameName = frameIn; title = titleIn;
810  xLabel = xLabIn; yLabel = yLabIn; xSize = xSizeIn; ySize = ySizeIn;
811  histos.clear(); styles.clear(); legends.clear(); files.clear();
812  fileStyles.clear(); fileLegends.clear(); filexyerr.clear();}
813 
814  // Add a histogram to the current plot, with optional style and legend.
815  void add( const Hist& histIn, string styleIn = "h",
816  string legendIn = "void") {
817  if (histIn.getBinNumber() == 0) {
818  cout << " Error: histogram is not booked" << endl;
819  return;
820  }
821  histos.push_back(histIn);
822  styles.push_back(styleIn); legends.push_back(legendIn); }
823 
824  // Add a file of (x, y) values not from a histogram, e.g. data points.
825  void addFile( string fileIn, string styleIn = "o",
826  string legendIn = "void", string xyerrIn="") { files.push_back(fileIn);
827  fileStyles.push_back(styleIn); fileLegends.push_back(legendIn);
828  filexyerr.push_back(xyerrIn);}
829 
830  // Plot a frame given the information from the new and add calls.
831  void plot( bool logY = false, bool logX = false, bool userBorders = false);
832  void plot( double xMinUserIn, double xMaxUserIn, double yMinUserIn,
833  double yMaxUserIn, bool logY = false, bool logX = false) {
834  xMinUser = xMinUserIn; xMaxUser = xMaxUserIn; yMinUser = yMinUserIn;
835  yMaxUser = yMaxUserIn; plot( logY, logX, true);}
836 
837  // Omnibus single call when only one histogram in the frame.
838  void plotFrame( string frameIn, const Hist& histIn, string titleIn = "",
839  string xLabIn = "", string yLabIn = "", string styleIn = "h",
840  string legendIn = "void", bool logY = false) {
841  frame( frameIn, titleIn, xLabIn, yLabIn);
842  add( histIn, styleIn, legendIn); plot( logY); }
843 
844 private:
845 
846  // Initialization code.
847  void init( string pythonName);
848 
849  // Stored quantities.
850  ofstream toPython;
851  int nPDF, nFrame, nTable;
852  double xSize, ySize, xMinUser, xMaxUser, yMinUser, yMaxUser;
853  string frameName, framePrevious, title, xLabel, yLabel, fileName, tmpFig;
854  vector<Hist> histos;
855  vector<string> styles, legends, files, fileStyles, fileLegends, filexyerr;
856 
857  // If true, use old linthreshy matplotlib parameter (removed in 3.5.0)
858  bool useLegacy;
859 
860 };
861 
862 //==========================================================================
863 
864 // Methods used for debugging random number sequences.
865 
866 #ifdef RNGDEBUG
867 #define flat() flatDebug(__METHOD_NAME__, __FILE__, __LINE__)
868 #define xexp() xexpDebug(__METHOD_NAME__, __FILE__, __LINE__)
869 #define gauss() gaussDebug(__METHOD_NAME__, __FILE__, __LINE__)
870 #define gamma(...) gammaDebug(__METHOD_NAME__, __FILE__, __LINE__, __VA_ARGS__)
871 #define phaseSpace2(...) phaseSpace2Debug(__METHOD_NAME__, __FILE__, __LINE__,\
872  __VA_ARGS__)
873 #endif
874 
875 //==========================================================================
876 
877 // Randomly shuffle a vector, standard Fisher-Yates algorithm.
878 // This must be defined after possible RNG debugging.
879 
880 template<typename T> void Rndm::shuffle(vector<T>& vec) {
881  for (int i = vec.size() - 1; i > 0; --i)
882  swap(vec[i], vec[floor(flat() * (i + 1))]);
883 }
884 
885 //==========================================================================
886 
887 } // end namespace Pythia8
888 
889 #endif // Pythia8_Basics_H
RndmState getState() const
Get or set the state of the random number generator.
Definition: Basics.h:451
double px() const
Member functions for output.
Definition: Basics.h:56
constexpr double pow2(const double &x)
Powers of small integers - for balance speed/code clarity.
Definition: PythiaStdlib.h:175
double value(int i, int j)
Return value of matrix element.
Definition: Basics.h:291
pair< double, double > gauss2()
Generate two random numbers according to exp(-x^2/2-y^2/2).
Definition: Basics.h:421
friend double m2(const Vec4 &v1)
The squared invariant mass of one or more four-vectors.
Definition: Basics.cc:597
void rot(double=0., double=0.)
Member functions.
Definition: Basics.cc:857
Hist()
Constructors, including copy constructors.
Definition: Basics.h:495
void bstback(const Vec4 &pIn)
Boost given by a Vec4 p; boost in opposite direction.
Definition: Basics.cc:508
void invert()
Invert the rotation and boost.
Definition: Basics.cc:1077
void rotbst(const RotBstMatrix &)
Combine existing rotation/boost matrix with another one.
Definition: Basics.cc:1062
void rescale3(double fac)
Member functions that perform operations.
Definition: Basics.h:95
void frame(string frameIn, string titleIn="", string xLabIn="", string yLabIn="", double xSizeIn=8., double ySizeIn=6.)
New plot frame, with title, x and y labels, x and y sizes.
Definition: Basics.h:807
friend bool isnan(const Vec4 &v)
Check if NaN, INF, or finite.
Definition: Basics.h:140
Vec4 operator*(double f, const Vec4 &v1)
Namespace function declarations; friends of Vec4 class.
Definition: Basics.h:202
double eps4(const Vec4 &a, const Vec4 &b, const Vec4 &c, const Vec4 &d)
Definition: Basics.cc:652
void rotaxis(double phiIn, double nx, double ny, double nz)
Azimuthal rotation phi around an arbitrary axis (nz, ny, nz).
Definition: Basics.cc:386
friend double sintheta(const Vec4 &v1, const Vec4 &v2)
Sine of opening angle between two three-vectors, using cross product.
Definition: Basics.cc:686
RotBstMatrix()
Constructors.
Definition: Basics.h:264
RotBstMatrix toCMframe(const Vec4 &p)
Get a RotBstMatrix to rest frame of p.
Definition: Basics.h:324
void title(string titleIn=" ")
Set title of a histogram.
Definition: Basics.h:533
void addFile(string fileIn, string styleIn="o", string legendIn="void", string xyerrIn="")
Add a file of (x, y) values not from a histogram, e.g. data points.
Definition: Basics.h:825
double peekFlat()
Definition: Basics.h:439
Vec4 operator*(Vec4 p) const
Multiplication.
Definition: Basics.h:303
void rotbst(const RotBstMatrix &M)
Arbitrary combination of rotations and boosts defined by 4 * 4 matrix.
Definition: Basics.cc:550
virtual ~RndmEngine()
Destructor.
Definition: Basics.h:365
RotBstMatrix fromCMframe(const Vec4 &p)
Get a RotBstMatrix from rest frame of p.
Definition: Basics.h:328
void plotFrame(string frameIn, const Hist &histIn, string titleIn="", string xLabIn="", string yLabIn="", string styleIn="h", string legendIn="void", bool logY=false)
Omnibus single call when only one histogram in the frame.
Definition: Basics.h:838
const double DYAC[]
Constants for printout: fixed steps on y scale; filling characters.
Definition: Basics.cc:1153
friend double costheta(const Vec4 &v1, const Vec4 &v2)
Cosine of the opening angle between two three-vectors.
Definition: Basics.cc:673
void bstback(const Vec4 &)
Boost so vector originally with same velocity as p is brought to rest.
Definition: Basics.cc:939
Rndm()
Constructors.
Definition: Basics.h:398
Definition: Basics.h:393
void rot(double thetaIn, double phiIn)
Rotation (simple).
Definition: Basics.cc:367
double getNEffective() const
Definition: Basics.h:690
friend ostream & operator<<(ostream &, const Vec4 &v)
Print a four-vector.
Definition: Basics.cc:576
friend double m(const Vec4 &v1)
Invariant mass and its square.
Definition: Basics.cc:587
friend Vec4 cross3(const Vec4 &v1, const Vec4 &v2)
The cross product of two three-vectors.
Definition: Basics.cc:625
string getTitle() const
Return title and size of histogram. Also if logarithmic x scale.
Definition: Basics.h:582
A derived class for nuclear PDFs. Needs a pointer for (free) proton PDFs.
Definition: PartonDistributions.h:1060
Vec4(double xIn=0., double yIn=0., double zIn=0., double tIn=0.)
Constructors.
Definition: Basics.h:37
friend bool pShift(Vec4 &p1Move, Vec4 &p2Move, double m1New, double m2New)
Shift four-momenta within pair from old to new masses.
Definition: Basics.cc:791
double getYMean() const
Return average <Y> value.
Definition: Basics.h:623
friend double dot3(const Vec4 &v1, const Vec4 &v2)
Scalar and cross product of 3-vector parts.
Definition: Basics.cc:617
~HistPlot()
Destructor should do final close.
Definition: Basics.h:804
int getEntries(bool alsoNonFinite=true) const
Return total number of entries.
Definition: Basics.h:681
friend Vec4 cross4(const Vec4 &a, const Vec4 &b, const Vec4 &c)
Cross-product of three 4-vectors ( p_i = epsilon_{iabc} p_a p_b p_c).
Definition: Basics.cc:637
void table(const Hist &h1, const Hist &h2, ostream &os=cout, bool printOverUnder=false, bool xMidBin=true)
Print a table out of two histograms with same x axis.
Definition: Basics.cc:1673
void bst(double betaX, double betaY, double betaZ)
Boost (simple).
Definition: Basics.cc:433
Definition: Basics.h:360
Definition: Basics.h:490
void bst(double=0., double=0., double=0., double=0.)
Boost with velocity vector (betaX, betaY, betaZ).
Definition: Basics.cc:899
void add(const Hist &histIn, string styleIn="h", string legendIn="void")
Add a histogram to the current plot, with optional style and legend.
Definition: Basics.h:815
Definition: Basics.h:259
Definition: Basics.h:791
Definition: Basics.h:378
friend double cosphi(const Vec4 &v1, const Vec4 &v2)
Cosine of the azimuthal angle between two three-vectors.
Definition: Basics.cc:719
virtual double flat()
Definition: Basics.h:369
double gauss()
Generate random numbers according to exp(-x^2/2).
Definition: Basics.h:418
friend double RRapPhi(const Vec4 &v1, const Vec4 &v2)
R is distance in cylindrical (y/eta, phi) coordinates.
Definition: Basics.cc:768
friend pair< Vec4, Vec4 > getTwoPerpendicular(const Vec4 &v1, const Vec4 &v2)
Create two vectors that are perpendicular to both input vectors.
Definition: Basics.cc:819
HistPlot(string pythonName, bool useLegacyIn=false)
Constructor requires name of Python program (and adds .py).
Definition: Basics.h:796
void shuffle(vector< T > &vec)
Randomly shuffle a vector, standard Fisher-Yates algorithm.
Definition: Basics.h:880
Header for classes to set beam momentum and interaction vertex spread.
Definition: Analysis.h:20
void toCMframe(const Vec4 &, const Vec4 &)
Definition: Basics.cc:965
double eInFrame(const Vec4 &pIn) const
Definition: Basics.cc:565
friend double REtaPhi(const Vec4 &v1, const Vec4 &v2)
Distance in cylindrical (eta, phi) coordinates.
Definition: Basics.cc:779
Hist operator+(double f, const Hist &h1)
Operator overloading with friends.
Definition: Basics.cc:2393
void reset()
Member functions for input.
Definition: Basics.h:46
Vec4 operator-() const
Operator overloading with member functions.
Definition: Basics.h:112
Definition: Basics.h:32
double getWeightSum(bool alsoOverUnder=true) const
Return total sum of weights.
Definition: Basics.h:685
double xexp()
Generate random numbers according to x * exp(-x).
Definition: Basics.h:415
double getXMin() const
Return min and max in x and y directions.
Definition: Basics.h:588
void fromCMframe(const Vec4 &, const Vec4 &, bool flip=false)
Definition: Basics.cc:984