StRoot  1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
FragmentationFlavZpT.h
1 // FragmentationFlavZpT.h is a part of the PYTHIA event generator.
2 // Copyright (C) 2018 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 helper classes for fragmentation.
7 // StringFlav is used to select quark and hadron flavours.
8 // StringPT is used to select transverse momenta.
9 // StringZ is used to sample the fragmentation function f(z).
10 
11 #ifndef Pythia8_FragmentationFlavZpT_H
12 #define Pythia8_FragmentationFlavZpT_H
13 
14 #include "Pythia8/Basics.h"
15 #include "Pythia8/ParticleData.h"
16 #include "Pythia8/PythiaStdlib.h"
17 #include "Pythia8/Settings.h"
18 
19 namespace Pythia8 {
20 
21 //==========================================================================
22 
23 // The FlavContainer class is a simple container for flavour,
24 // including the extra properties needed for popcorn baryon handling.
25 // id = current flavour.
26 // rank = current rank; 0 for endpoint flavour and then increase by 1.
27 // nPop = number of popcorn mesons yet to be produced (1 or 0).
28 // idPop = (absolute sign of) popcorn quark, shared between B and Bbar.
29 // idVtx = (absolute sign of) vertex (= non-shared) quark in diquark.
30 
31 class FlavContainer {
32 
33 public:
34 
35  // Constructor.
36  FlavContainer(int idIn = 0, int rankIn = 0, int nPopIn = 0,
37  int idPopIn = 0, int idVtxIn = 0) : id(idIn), rank(rankIn),
38  nPop(nPopIn), idPop(idPopIn), idVtx(idVtxIn) {}
39 
40  // Overloaded equal operator.
41  FlavContainer& operator=(const FlavContainer& flav) { if (this != &flav) {
42  id = flav.id; rank = flav.rank; nPop = flav.nPop; idPop = flav.idPop;
43  idVtx = flav.idVtx; } return *this; }
44 
45  // Invert flavour.
46  FlavContainer& anti() {id = -id; return *this;}
47 
48  // Read in a container into another, without/with id sign flip.
49  FlavContainer& copy(const FlavContainer& flav) { if (this != &flav) {
50  id = flav.id; rank = flav.rank; nPop = flav.nPop; idPop = flav.idPop;
51  idVtx = flav.idVtx; } return *this; }
52  FlavContainer& anti(const FlavContainer& flav) { if (this != &flav) {
53  id = -flav.id; rank = flav.rank; nPop = flav.nPop; idPop = flav.idPop;
54  idVtx = flav.idVtx; } return *this; }
55 
56  // Check whether is diquark.
57  bool isDiquark() {int idAbs = abs(id);
58  return (idAbs > 1000 && idAbs < 10000 && (idAbs/10)%10 == 0);}
59 
60  // Stored properties.
61  int id, rank, nPop, idPop, idVtx;
62 
63 };
64 
65 //==========================================================================
66 
67 // The StringFlav class is used to select quark and hadron flavours.
68 
69 class StringFlav {
70 
71 public:
72 
73  // Constructor.
74  StringFlav() {
75  // Initialize winning parameters.
76  hadronIDwin = 0; idNewWin = 0; hadronMassWin = -1.0;
77  }
78 
79  // Destructor.
80  virtual ~StringFlav() {}
81 
82  // Initialize data members.
83  virtual void init(Settings& settings, ParticleData* particleDataPtrIn,
84  Rndm* rndmPtrIn, Info* infoPtrIn);
85 
86  // Pick a light d, u or s quark according to fixed ratios.
87  int pickLightQ() { double rndmFlav = probQandS * rndmPtr->flat();
88  if (rndmFlav < 1.) return 1;
89  if (rndmFlav < 2.) return 2;
90  return 3; }
91 
92  // Pick a new flavour (including diquarks) given an incoming one,
93  // either by old standard Gaussian or new alternative exponential.
94  virtual FlavContainer pick(FlavContainer& flavOld, double pT = -1.0,
95  double nNSP = 0.0) { hadronIDwin = 0; idNewWin = 0; hadronMassWin = -1.0;
96  if ( (thermalModel || mT2suppression) && (pT >= 0.0) )
97  return pickThermal(flavOld, pT, nNSP);
98  return pickGauss(flavOld); }
99  virtual FlavContainer pickGauss(FlavContainer& flavOld);
100  virtual FlavContainer pickThermal(FlavContainer& flavOld,
101  double pT, double nNSP);
102 
103  // Combine two flavours (including diquarks) to produce a hadron.
104  virtual int combine(FlavContainer& flav1, FlavContainer& flav2);
105 
106  // Ditto, simplified input argument for simple configurations.
107  virtual int combineId( int id1, int id2, bool keepTrying = true) {
108  FlavContainer flag1(id1); FlavContainer flag2(id2);
109  for (int i = 0; i < 100; ++i) { int idNew = combine( flag1, flag2);
110  if (idNew != 0 || !keepTrying) return idNew;} return 0;}
111 
112  // Return chosen hadron in case of thermal model.
113  virtual int getHadronIDwin() { return hadronIDwin; }
114 
115  // Combine two flavours into hadron for last two remaining flavours
116  // for thermal model.
117  virtual int combineLastThermal(FlavContainer& flav1, FlavContainer& flav2,
118  double pT, double nNSP);
119 
120  // General function, decides whether to just return the hadron id
121  // if thermal model was use or whether to combine the two flavours.
122  virtual int getHadronID(FlavContainer& flav1, FlavContainer& flav2,
123  double pT = -1.0, double nNSP = 0, bool finalTwo = false) {
124  if (finalTwo) return ((thermalModel || mT2suppression) ?
125  combineLastThermal(flav1, flav2, pT, nNSP) : combine(flav1, flav2));
126  if ((thermalModel || mT2suppression)&& (hadronIDwin != 0)
127  && (idNewWin != 0)) return getHadronIDwin();
128  return combine(flav1, flav2); }
129 
130  // Return hadron mass. Used one if present, pick otherwise.
131  virtual double getHadronMassWin(int idHad) { return
132  ((hadronMassWin < 0.0) ? particleDataPtr->mSel(idHad) : hadronMassWin); }
133 
134  // Assign popcorn quark inside an original (= rank 0) diquark.
135  void assignPopQ(FlavContainer& flav);
136 
137  // Combine two quarks to produce a diquark.
138  int makeDiquark(int id1, int id2, int idHad = 0);
139 
140  // Check if quark-diquark combination should be added. If so add.
141  void addQuarkDiquark(vector< pair<int,int> >& quarkCombis,
142  int qID, int diqID, int hadronID) {
143  bool allowed = true;
144  for (int iCombi = 0; iCombi < int(quarkCombis.size()); iCombi++)
145  if ( (qID == quarkCombis[iCombi].first ) &&
146  (diqID == quarkCombis[iCombi].second) ) allowed = false;
147  if (allowed) quarkCombis.push_back( (hadronID > 0) ?
148  make_pair( qID, diqID) : make_pair(-qID, -diqID) ); }
149 
150  // Get spin counter for mesons.
151  int getMesonSpinCounter(int hadronID) { hadronID = abs(hadronID);
152  int j = (hadronID % 10);
153  if (hadronID < 1000) return ((j==1) ? 0 : ( (j==3) ? 1 : 5 ));
154  if (hadronID < 20000) return ((j==1) ? 3 : 2);
155  if (hadronID > 20000) return 4;
156  return -1; }
157 
158 protected:
159 
160  // Pointer to the random number generator.
161  Rndm* rndmPtr;
162 
163  // Pointer to the particle data table.
164  ParticleData* particleDataPtr;
165 
166  // Pointer to event information.
167  Info* infoPtr;
168 
169  // Constants: could only be changed in the code itself.
170  static const int mesonMultipletCode[6];
171  static const double baryonCGOct[6], baryonCGDec[6];
172 
173  // Settings for Gaussian model.
174  bool suppressLeadingB, mT2suppression, useWidthPre;
175  double probQQtoQ, probStoUD, probSQtoQQ, probQQ1toQQ0, probQandQQ,
176  probQandS, probQandSinQQ, probQQ1corr, probQQ1corrInv, probQQ1norm,
177  probQQ1join[4], mesonRate[4][6], mesonRateSum[4], mesonMix1[2][6],
178  mesonMix2[2][6], etaSup, etaPrimeSup, decupletSup, baryonCGSum[6],
179  baryonCGMax[6], popcornRate, popcornSpair, popcornSmeson, scbBM[3],
180  popFrac, popS[3], dWT[3][7], lightLeadingBSup, heavyLeadingBSup;
181  double sigmaHad, widthPreStrange, widthPreDiquark;
182 
183  // Settings for thermal model.
184  bool thermalModel, mesonNonetL1;
185  double temperature, tempPreFactor;
186  int nNewQuark;
187  double mesMixRate1[2][6], mesMixRate2[2][6], mesMixRate3[2][6];
188  double baryonOctWeight[6][6][6][2], baryonDecWeight[6][6][6][2];
189 
190  // Settings used by both models.
191  bool closePacking;
192  double exponentMPI, exponentNSP;
193 
194  // Key = hadron id, value = list of constituent ids.
195  map< int, vector< pair<int,int> > > hadronConstIDs;
196  // Key = initial (di)quark id, value = list of possible hadron ids
197  // + nr in hadronConstIDs.
198  map< int, vector< pair<int,int> > > possibleHadrons;
199  // Key = initial (di)quark id, value = prefactor to multiply rate.
200  map< int, vector<double> > possibleRatePrefacs;
201  // Similar, but for combining the last two (di)quarks. Key = (di)quark pair.
202  map< pair<int,int>, vector< pair<int,int> > > possibleHadronsLast;
203  map< pair<int,int>, vector<double> > possibleRatePrefacsLast;
204 
205  // Selection in thermal model.
206  int hadronIDwin, idNewWin;
207  double hadronMassWin;
208 
209 };
210 
211 //==========================================================================
212 
213 // Auxiliary class to encapsulate (unnormalised) Lund FF.
214 
216 
217 public:
218 
219  // Constructor and destructor.
220  LundFFRaw() {};
221  virtual ~LundFFRaw() {};
222 
223  // f(z) = (1-z)^a / z^c * Exp ( - b * mT2 / z).
224  virtual double f(vector<double> args) {
225  if (args.size() < 5) return -1.;
226  double z = args[0];
227  if (z <= 0. || z >= 1.) return 0.;
228  double a = args[1];
229  double b = args[2];
230  double c = args[3];
231  double mT2 = args[4];
232  return pow(1. - z, a) / pow(z, c) * exp(-b * mT2 / z);
233  }
234 
235 };
236 
237 //==========================================================================
238 
239 // Auxiliary class to encapsulate average, <z>, of Lund FF.
240 
242 
243 public:
244 
245  // Constructor and destructor.
246  LundFFAvg() {};
247  virtual ~LundFFAvg() {};
248 
249  // <z> = integral( z * f(z) dz ) / integral( f(z) dz ),
250  // argsIn[] : a, b, c, mT2, and optionally integrator tolerance parameter.
251  virtual double f(vector<double> argsIn) {
252 
253  // Do sanity checks and set initial values.
254  if (argsIn.size() < 4) return -1.;
255  double tol = 1.e-6;
256  if (argsIn.size() >= 5) tol = argsIn[4];
257  double denom = 1.;
258  double numerator = 0.;
259 
260  // Evaluate denominator integral. LundFF expects args: z, a, b, c, mT2.
261  vector<double> args(1);
262  args.insert(args.end(), argsIn.begin(), argsIn.end());
263  check = lundFF.integrateGauss(denom, 0, 0., 1., args, tol);
264  if ( !check || denom <= 0. ) return -1.;
265 
266  // Evaluate numerator integral. Evaluating z*f is equivalent to c -> c-1.
267  args[3] -= 1.;
268  check = lundFF.integrateGauss(numerator, 0, 0., 1., args, tol);
269  if ( !check || numerator < 0. ) return -1.;
270  return numerator/denom;
271  }
272 
273 private:
274 
275  LundFFRaw lundFF;
276  bool check;
277 };
278 
279 //==========================================================================
280 
281 // The StringZ class is used to sample the fragmentation function f(z).
282 
283 class StringZ {
284 
285 public:
286 
287  // Constructor.
288  StringZ() {}
289 
290  // Destructor.
291  virtual ~StringZ() {}
292 
293  // Initialize data members.
294  virtual void init(Settings& settings, ParticleData& particleData,
295  Rndm* rndmPtrIn, Info* infoPtrIn);
296 
297  // Fragmentation function: top-level to determine parameters.
298  virtual double zFrag( int idOld, int idNew = 0, double mT2 = 1.);
299 
300  // Parameters for stopping in the middle; overloaded for Hidden Valley.
301  virtual double stopMass() {return stopM;}
302  virtual double stopNewFlav() {return stopNF;}
303  virtual double stopSmear() {return stopS;}
304 
305  // a and b fragmentation parameters needed in some operations.
306  virtual double aAreaLund() {return aLund;}
307  virtual double bAreaLund() {return bLund;}
308 
309  // Method to derive bLund from <z> (for fixed a and reference mT2).
310  bool deriveBLund(Settings& settings, ParticleData& particleData);
311 
312 protected:
313 
314  // Constants: could only be changed in the code itself.
315  static const double CFROMUNITY, AFROMZERO, AFROMC, EXPMAX;
316 
317  // Initialization data, to be read from Settings.
318  bool useNonStandC, useNonStandB, useNonStandH,
319  usePetersonC, usePetersonB, usePetersonH;
320  double mc2, mb2, aLund, bLund, aExtraSQuark, aExtraDiquark, rFactC,
321  rFactB, rFactH, aNonC, aNonB, aNonH, bNonC, bNonB, bNonH,
322  epsilonC, epsilonB, epsilonH, stopM, stopNF, stopS;
323 
324  // Fragmentation function: select z according to provided parameters.
325  double zLund( double a, double b, double c = 1.);
326  double zPeterson( double epsilon);
327 
328  // Pointer to the random number generator.
329  Rndm* rndmPtr;
330 
331  // Pointer to event information.
332  Info* infoPtr;
333 
334 };
335 
336 //==========================================================================
337 
338 // The StringPT class is used to select select transverse momenta.
339 
340 class StringPT {
341 
342 public:
343 
344  // Constructor.
345  StringPT() {}
346 
347  // Destructor.
348  virtual ~StringPT() {}
349 
350  // Initialize data members.
351  virtual void init(Settings& settings, ParticleData* particleDataPtr,
352  Rndm* rndmPtrIn, Info* infoPtrIn);
353 
354  // General function, return px and py as a pair in the same call
355  // in either model.
356  pair<double, double> pxy(int idIn, double nNSP = 0.0) {
357  return (thermalModel ? pxyThermal(idIn, nNSP) :
358  pxyGauss(idIn, nNSP)); }
359  pair<double, double> pxyGauss(int idIn = 0, double nNSP = 0.0);
360  pair<double, double> pxyThermal(int idIn, double nNSP = 0.0);
361 
362  // Gaussian suppression of given pT2; used in MiniStringFragmentation.
363  double suppressPT2(double pT2) { return (thermalModel ?
364  exp(-sqrt(pT2)/temperature) : exp(-pT2/sigma2Had)); }
365 
366 protected:
367 
368  // Constants: could only be changed in the code itself.
369  static const double SIGMAMIN;
370 
371  // Initialization data, to be read from Settings.
372  // Gaussian model.
373  bool useWidthPre;
374  double sigmaQ, enhancedFraction, enhancedWidth, sigma2Had,
375  widthPreStrange, widthPreDiquark;
376  // Thermal model.
377  bool thermalModel;
378  double temperature, tempPreFactor, fracSmallX;
379  // Both.
380  bool closePacking;
381  double exponentMPI, exponentNSP;
382 
383  // Pointer to the particle data table.
384  ParticleData* particleDataPtr;
385 
386  // Pointer to the random number generator.
387  Rndm* rndmPtr;
388 
389  // Pointer to event information.
390  Info* infoPtr;
391 
392 private:
393 
394  // Evaluate Bessel function K_{1/4}(x).
395  double BesselK14(double x);
396 
397 };
398 
399 //==========================================================================
400 
401 } // end namespace Pythia8
402 
403 #endif // Pythia8_FragmentationFlavZpT_H