~ubuntu-branches/ubuntu/trusty/pythia8/trusty-proposed

« back to all changes in this revision

Viewing changes to src/FragmentationFlavZpT.cc

  • Committer: Package Import Robot
  • Author(s): Lifeng Sun
  • Date: 2012-05-22 11:43:00 UTC
  • Revision ID: package-import@ubuntu.com-20120522114300-0jvsv2vl4o2bo435
Tags: upstream-8.1.65
ImportĀ upstreamĀ versionĀ 8.1.65

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// FragmentationFlavZpT.cc is a part of the PYTHIA event generator.
 
2
// Copyright (C) 2012 Torbjorn Sjostrand.
 
3
// PYTHIA is licenced under the GNU GPL version 2, see COPYING for details.
 
4
// Please respect the MCnet Guidelines, see GUIDELINES for details.
 
5
 
 
6
// Function definitions (not found in the header) for the 
 
7
// StringFlav, StringZ and StringPT classes.
 
8
 
 
9
#include "FragmentationFlavZpT.h"
 
10
 
 
11
namespace Pythia8 {
 
12
 
 
13
//==========================================================================
 
14
 
 
15
// The StringFlav class.
 
16
 
 
17
//--------------------------------------------------------------------------
 
18
 
 
19
// Constants: could be changed here if desired, but normally should not.
 
20
// These are of technical nature, as described for each.
 
21
 
 
22
// Offset for different meson multiplet id values.
 
23
const int StringFlav::mesonMultipletCode[6] 
 
24
  = { 1, 3, 10003, 10001, 20003, 5};
 
25
 
 
26
// Clebsch-Gordan coefficients for baryon octet and decuplet are
 
27
// fixed once and for all, so only weighted sum needs to be edited.
 
28
// Order: ud0 + u, ud0 + s, uu1 + u, uu1 + d, ud1 + u, ud1 + s.
 
29
const double StringFlav::baryonCGOct[6] 
 
30
  = { 0.75, 0.5, 0., 0.1667, 0.0833, 0.1667};
 
31
const double StringFlav::baryonCGDec[6] 
 
32
  = { 0.,  0.,  1., 0.3333, 0.6667, 0.3333};
 
33
 
 
34
//--------------------------------------------------------------------------
 
35
 
 
36
// Initialize data members of the flavour generation.
 
37
 
 
38
void StringFlav::init(Settings& settings, Rndm* rndmPtrIn) {
 
39
 
 
40
  // Save pointer.
 
41
  rndmPtr         = rndmPtrIn;
 
42
 
 
43
  // Basic parameters for generation of new flavour.
 
44
  probQQtoQ       = settings.parm("StringFlav:probQQtoQ");
 
45
  probStoUD       = settings.parm("StringFlav:probStoUD");
 
46
  probSQtoQQ      = settings.parm("StringFlav:probSQtoQQ");
 
47
  probQQ1toQQ0    = settings.parm("StringFlav:probQQ1toQQ0");
 
48
 
 
49
  // Parameters derived from above.
 
50
  probQandQQ      = 1. + probQQtoQ;
 
51
  probQandS       = 2. + probStoUD;
 
52
  probQandSinQQ   = 2. + probSQtoQQ * probStoUD;
 
53
  probQQ1corr     = 3. * probQQ1toQQ0;
 
54
  probQQ1corrInv  = 1. / probQQ1corr;
 
55
  probQQ1norm     = probQQ1corr / (1. + probQQ1corr);
 
56
 
 
57
  // Parameters for normal meson production.
 
58
  for (int i = 0; i < 4; ++i) mesonRate[i][0] = 1.;
 
59
  mesonRate[0][1] = settings.parm("StringFlav:mesonUDvector");
 
60
  mesonRate[1][1] = settings.parm("StringFlav:mesonSvector");
 
61
  mesonRate[2][1] = settings.parm("StringFlav:mesonCvector");
 
62
  mesonRate[3][1] = settings.parm("StringFlav:mesonBvector");
 
63
 
 
64
  // Parameters for L=1 excited-meson production.
 
65
  mesonRate[0][2] = settings.parm("StringFlav:mesonUDL1S0J1");
 
66
  mesonRate[1][2] = settings.parm("StringFlav:mesonSL1S0J1");
 
67
  mesonRate[2][2] = settings.parm("StringFlav:mesonCL1S0J1");
 
68
  mesonRate[3][2] = settings.parm("StringFlav:mesonBL1S0J1");
 
69
  mesonRate[0][3] = settings.parm("StringFlav:mesonUDL1S1J0");
 
70
  mesonRate[1][3] = settings.parm("StringFlav:mesonSL1S1J0");
 
71
  mesonRate[2][3] = settings.parm("StringFlav:mesonCL1S1J0");
 
72
  mesonRate[3][3] = settings.parm("StringFlav:mesonBL1S1J0");
 
73
  mesonRate[0][4] = settings.parm("StringFlav:mesonUDL1S1J1");
 
74
  mesonRate[1][4] = settings.parm("StringFlav:mesonSL1S1J1");
 
75
  mesonRate[2][4] = settings.parm("StringFlav:mesonCL1S1J1");
 
76
  mesonRate[3][4] = settings.parm("StringFlav:mesonBL1S1J1");
 
77
  mesonRate[0][5] = settings.parm("StringFlav:mesonUDL1S1J2");
 
78
  mesonRate[1][5] = settings.parm("StringFlav:mesonSL1S1J2");
 
79
  mesonRate[2][5] = settings.parm("StringFlav:mesonCL1S1J2");
 
80
  mesonRate[3][5] = settings.parm("StringFlav:mesonBL1S1J2");
 
81
 
 
82
  // Store sum over multiplets for Monte Carlo generation.
 
83
  for (int i = 0; i < 4; ++i) mesonRateSum[i] 
 
84
    = mesonRate[i][0] + mesonRate[i][1] + mesonRate[i][2] 
 
85
    + mesonRate[i][3] + mesonRate[i][4] + mesonRate[i][5];
 
86
 
 
87
  // Parameters for uubar - ddbar - ssbar meson mixing.
 
88
  for (int spin = 0; spin < 6; ++spin) { 
 
89
    double theta;
 
90
    if      (spin == 0) theta = settings.parm("StringFlav:thetaPS");
 
91
    else if (spin == 1) theta = settings.parm("StringFlav:thetaV");
 
92
    else if (spin == 2) theta = settings.parm("StringFlav:thetaL1S0J1");
 
93
    else if (spin == 3) theta = settings.parm("StringFlav:thetaL1S1J0");
 
94
    else if (spin == 4) theta = settings.parm("StringFlav:thetaL1S1J1");
 
95
    else                theta = settings.parm("StringFlav:thetaL1S1J2");
 
96
    double alpha = (spin == 0) ? 90. - (theta + 54.7) : theta + 54.7;
 
97
    alpha *= M_PI / 180.;
 
98
    // Fill in (flavour, spin)-dependent probability of producing
 
99
    // the lightest or the lightest two mesons of the nonet. 
 
100
    mesonMix1[0][spin] = 0.5;
 
101
    mesonMix2[0][spin] = 0.5 * (1. + pow2(sin(alpha)));
 
102
    mesonMix1[1][spin] = 0.;
 
103
    mesonMix2[1][spin] = pow2(cos(alpha));
 
104
  }
 
105
 
 
106
  // Additional suppression of eta and etaPrime.
 
107
  etaSup      = settings.parm("StringFlav:etaSup");
 
108
  etaPrimeSup = settings.parm("StringFlav:etaPrimeSup");
 
109
 
 
110
  // Sum of baryon octet and decuplet weights.
 
111
  decupletSup = settings.parm("StringFlav:decupletSup");
 
112
  for (int i = 0; i < 6; ++i) baryonCGSum[i]
 
113
    = baryonCGOct[i] + decupletSup * baryonCGDec[i];
 
114
 
 
115
  // Maximum SU(6) weight for ud0, ud1, uu1 types.
 
116
  baryonCGMax[0] = max( baryonCGSum[0], baryonCGSum[1]);
 
117
  baryonCGMax[1] = baryonCGMax[0]; 
 
118
  baryonCGMax[2] = max( baryonCGSum[2], baryonCGSum[3]);
 
119
  baryonCGMax[3] = baryonCGMax[2]; 
 
120
  baryonCGMax[4] = max( baryonCGSum[4], baryonCGSum[5]);
 
121
  baryonCGMax[5] = baryonCGMax[4]; 
 
122
 
 
123
  // Popcorn baryon parameters.
 
124
  popcornRate    = settings.parm("StringFlav:popcornRate");
 
125
  popcornSpair   = settings.parm("StringFlav:popcornSpair"); 
 
126
  popcornSmeson  = settings.parm("StringFlav:popcornSmeson");
 
127
  
 
128
  // Suppression of leading (= first-rank) baryons.
 
129
  suppressLeadingB = settings.flag("StringFlav:suppressLeadingB");
 
130
  lightLeadingBSup = settings.parm("StringFlav:lightLeadingBSup");
 
131
  heavyLeadingBSup = settings.parm("StringFlav:heavyLeadingBSup");
 
132
 
 
133
  // Begin calculation of derived parameters for baryon production.
 
134
 
 
135
  // Enumerate distinguishable diquark types (in diquark first is popcorn q).
 
136
  enum Diquark {ud0, ud1, uu1, us0, su0, us1, su1, ss1};
 
137
 
 
138
  // Maximum SU(6) weight by diquark type. 
 
139
  double barCGMax[8];
 
140
  barCGMax[ud0] = baryonCGMax[0]; 
 
141
  barCGMax[ud1] = baryonCGMax[4]; 
 
142
  barCGMax[uu1] = baryonCGMax[2]; 
 
143
  barCGMax[us0] = baryonCGMax[0]; 
 
144
  barCGMax[su0] = baryonCGMax[0]; 
 
145
  barCGMax[us1] = baryonCGMax[4]; 
 
146
  barCGMax[su1] = baryonCGMax[4]; 
 
147
  barCGMax[ss1] = baryonCGMax[2]; 
 
148
 
 
149
  // Diquark SU(6) survival = Sum_quark (quark tunnel weight) * SU(6).
 
150
  double dMB[8];
 
151
  dMB[ud0] = 2. * baryonCGSum[0] + probStoUD * baryonCGSum[1];
 
152
  dMB[ud1] = 2. * baryonCGSum[4] + probStoUD * baryonCGSum[5];
 
153
  dMB[uu1] = baryonCGSum[2] + (1. + probStoUD) * baryonCGSum[3];
 
154
  dMB[us0] = (1. + probStoUD) * baryonCGSum[0] + baryonCGSum[1];
 
155
  dMB[su0] = dMB[us0];
 
156
  dMB[us1] = (1. + probStoUD) * baryonCGSum[4] + baryonCGSum[5];  
 
157
  dMB[su1] = dMB[us1];
 
158
  dMB[ss1] = probStoUD * baryonCGSum[2] + 2. * baryonCGSum[3];
 
159
  for (int i = 1; i < 8; ++i) dMB[i] = dMB[i] / dMB[0];
 
160
 
 
161
  // Tunneling factors for diquark production; only half a pair = sqrt.
 
162
  double probStoUDroot    = sqrt(probStoUD);
 
163
  double probSQtoQQroot   = sqrt(probSQtoQQ);
 
164
  double probQQ1toQQ0root = sqrt(probQQ1toQQ0);
 
165
  double qBB[8];
 
166
  qBB[ud1] = probQQ1toQQ0root;
 
167
  qBB[uu1] = probQQ1toQQ0root;
 
168
  qBB[us0] = probSQtoQQroot;
 
169
  qBB[su0] = probStoUDroot * probSQtoQQroot;
 
170
  qBB[us1] = probQQ1toQQ0root * qBB[us0];
 
171
  qBB[su1] = probQQ1toQQ0root * qBB[su0];
 
172
  qBB[ss1] = probStoUDroot * pow2(probSQtoQQroot) * probQQ1toQQ0root;
 
173
 
 
174
  // spin * (vertex factor) * (half-tunneling factor above).
 
175
  double qBM[8];
 
176
  qBM[ud1] = 3. * qBB[ud1];
 
177
  qBM[uu1] = 6. * qBB[uu1];
 
178
  qBM[us0] = probStoUD * qBB[us0];
 
179
  qBM[su0] = qBB[su0]; 
 
180
  qBM[us1] = probStoUD * 3. * qBB[us1];
 
181
  qBM[su1] = 3. * qBB[su1];
 
182
  qBM[ss1] = probStoUD * 6. * qBB[ss1];
 
183
 
 
184
  // Combine above two into total diquark weight for q -> B Bbar.
 
185
  for (int i = 1; i < 8; ++i) qBB[i] = qBB[i] * qBM[i];
 
186
 
 
187
  // Suppression from having strange popcorn meson.
 
188
  qBM[us0] *= popcornSmeson;
 
189
  qBM[us1] *= popcornSmeson;
 
190
  qBM[ss1] *= popcornSmeson;
 
191
 
 
192
  // Suppression for a heavy quark of a diquark to fit into a baryon
 
193
  // on the other side of popcorn meson: (0) s/u for q -> B M;
 
194
  // (1) s/u for rank 0 diquark su -> M B; (2) ditto for s -> c/b.
 
195
  double uNorm = 1. + qBM[ud1] + qBM[uu1] + qBM[us0] + qBM[us1];
 
196
  scbBM[0] = (2. * (qBM[su0] + qBM[su1]) + qBM[ss1]) / uNorm;  
 
197
  scbBM[1] = scbBM[0] * popcornSpair * qBM[su0] / qBM[us0];
 
198
  scbBM[2] = (1. + qBM[ud1]) * (2. + qBM[us0]) / uNorm; 
 
199
 
 
200
  // Include maximum of Clebsch-Gordan coefficients.
 
201
  for (int i = 1; i < 8; ++i) dMB[i] *= qBM[i];
 
202
  for (int i = 1; i < 8; ++i) qBM[i] *= barCGMax[i] / barCGMax[0];
 
203
  for (int i = 1; i < 8; ++i) qBB[i] *= barCGMax[i] / barCGMax[0];
 
204
 
 
205
  // Popcorn fraction for normal diquark production.
 
206
  double qNorm = uNorm * popcornRate / 3.;
 
207
  double sNorm = scbBM[0] * popcornSpair;
 
208
  popFrac = qNorm * (1. + qBM[ud1] + qBM[uu1] + qBM[us0] + qBM[us1] 
 
209
    + sNorm * (qBM[su0] + qBM[su1] + 0.5 * qBM[ss1])) / (1. +  qBB[ud1] 
 
210
    + qBB[uu1] + 2. * (qBB[us0] + qBB[us1]) + 0.5 * qBB[ss1]);  
 
211
 
 
212
  // Popcorn fraction for rank 0 diquarks, depending on number of s quarks.
 
213
  popS[0] = qNorm * qBM[ud1] / qBB[ud1];
 
214
  popS[1] = qNorm * 0.5 * (qBM[us1] / qBB[us1] 
 
215
    + sNorm * qBM[su1] / qBB[su1]);
 
216
  popS[2] = qNorm * sNorm * qBM[ss1] / qBB[ss1]; 
 
217
 
 
218
  // Recombine diquark weights to flavour and spin ratios. Second index: 
 
219
  // 0 = s/u popcorn quark ratio.
 
220
  // 1, 2 = s/u ratio for vertex quark if popcorn quark is u/d or s.
 
221
  // 3 = q/q' vertex quark ratio if popcorn quark is light and = q.
 
222
  // 4, 5, 6 = (spin 1)/(spin 0) ratio for su, us and ud.  
 
223
 
 
224
  // Case 0: q -> B B. 
 
225
  dWT[0][0] = (2. * (qBB[su0] + qBB[su1]) + qBB[ss1])
 
226
    / (1. + qBB[ud1] + qBB[uu1] + qBB[us0] + qBB[us1]);
 
227
  dWT[0][1] = 2. * (qBB[us0] + qBB[us1]) / (1. + qBB[ud1] + qBB[uu1]);
 
228
  dWT[0][2] = qBB[ss1] / (qBB[su0] + qBB[su1]);
 
229
  dWT[0][3] = qBB[uu1] / (1. + qBB[ud1] + qBB[uu1]);
 
230
  dWT[0][4] = qBB[su1] / qBB[su0];
 
231
  dWT[0][5] = qBB[us1] / qBB[us0];
 
232
  dWT[0][6] = qBB[ud1];
 
233
 
 
234
  // Case 1: q -> B M B.
 
235
  dWT[1][0] = (2. * (qBM[su0] + qBM[su1]) + qBM[ss1])
 
236
    / (1. + qBM[ud1] + qBM[uu1] + qBM[us0] + qBM[us1]);
 
237
  dWT[1][1] = 2. * (qBM[us0] + qBM[us1]) / (1. + qBM[ud1] + qBM[uu1]);
 
238
  dWT[1][2] = qBM[ss1] / (qBM[su0] + qBM[su1]);
 
239
  dWT[1][3] = qBM[uu1] / (1. + qBM[ud1] + qBM[uu1]);
 
240
  dWT[1][4] = qBM[su1] / qBM[su0];
 
241
  dWT[1][5] = qBM[us1] / qBM[us0];
 
242
  dWT[1][6] = qBM[ud1];
 
243
  
 
244
  // Case 2: qq -> M B; diquark inside chain.
 
245
  dWT[2][0] = (2. * (dMB[su0] + dMB[su1]) + dMB[ss1])
 
246
    / (1. + dMB[ud1] + dMB[uu1] + dMB[us0] + dMB[us1]);
 
247
  dWT[2][1] = 2. * (dMB[us0] + dMB[us1]) / (1. + dMB[ud1] + dMB[uu1]);
 
248
  dWT[2][2] = dMB[ss1] / (dMB[su0] + dMB[su1]);
 
249
  dWT[2][3] = dMB[uu1] / (1. + dMB[ud1] + dMB[uu1]);
 
250
  dWT[2][4] = dMB[su1] / dMB[su0];
 
251
  dWT[2][5] = dMB[us1] / dMB[us0];
 
252
  dWT[2][6] = dMB[ud1];
 
253
 
 
254
}
 
255
 
 
256
//--------------------------------------------------------------------------
 
257
 
 
258
// Pick a new flavour (including diquarks) given an incoming one.
 
259
 
 
260
FlavContainer StringFlav::pick(FlavContainer& flavOld) {
 
261
 
 
262
  // Initial values for new flavour.
 
263
  FlavContainer flavNew;
 
264
  flavNew.rank = flavOld.rank + 1;
 
265
 
 
266
  // For original diquark assign popcorn quark and whether popcorn meson.
 
267
  int idOld = abs(flavOld.id);
 
268
  if (flavOld.rank == 0 && idOld > 1000) assignPopQ(flavOld);
 
269
 
 
270
  // Diquark exists, to be forced into baryon now.
 
271
  bool doOldBaryon    = (idOld > 1000 && flavOld.nPop == 0);
 
272
  // Diquark exists, but do meson now.
 
273
  bool doPopcornMeson = flavOld.nPop > 0;
 
274
  // Newly created diquark gives baryon now, antibaryon later.
 
275
  bool doNewBaryon    = false;
 
276
 
 
277
  // Choose whether to generate a new meson or a new baryon.
 
278
  if (!doOldBaryon && !doPopcornMeson && probQandQQ * rndmPtr->flat() > 1.) {
 
279
    doNewBaryon = true;
 
280
    if ((1. + popFrac) * rndmPtr->flat() > 1.) flavNew.nPop = 1;
 
281
  }
 
282
 
 
283
  // Optional suppression of first-rank baryon.
 
284
  if (flavOld.rank == 0 && doNewBaryon && suppressLeadingB) {
 
285
    double leadingBSup = (idOld < 4) ? lightLeadingBSup : heavyLeadingBSup; 
 
286
    if (rndmPtr->flat() > leadingBSup) {
 
287
      doNewBaryon = false;
 
288
      flavNew.nPop = 0;
 
289
    }
 
290
  }
 
291
 
 
292
  // Single quark for new meson or for baryon where diquark already exists.
 
293
  if (!doPopcornMeson && !doNewBaryon) {
 
294
    flavNew.id = pickLightQ();
 
295
    if ( (flavOld.id > 0 && flavOld.id < 9) || flavOld.id < -1000 ) 
 
296
      flavNew.id = -flavNew.id; 
 
297
 
 
298
    // Done for simple-quark case. 
 
299
    return flavNew;
 
300
  }
 
301
 
 
302
  // Case: 0 = q -> B B, 1 = q -> B M B, 2 = qq -> M B.
 
303
  int iCase = flavNew.nPop;
 
304
  if (flavOld.nPop == 1) iCase = 2; 
 
305
 
 
306
  // Flavour of popcorn quark (= q shared between B and Bbar).
 
307
  if (doNewBaryon) { 
 
308
    double sPopWT = dWT[iCase][0];
 
309
    if (iCase == 1) sPopWT *= scbBM[0] * popcornSpair;
 
310
    double rndmFlav = (2. + sPopWT) * rndmPtr->flat();
 
311
    flavNew.idPop = 1;
 
312
    if (rndmFlav > 1.) flavNew.idPop = 2;
 
313
    if (rndmFlav > 2.) flavNew.idPop = 3;
 
314
  } else flavNew.idPop = flavOld.idPop;
 
315
  
 
316
  // Flavour of vertex quark.
 
317
  double sVtxWT = dWT[iCase][1];
 
318
  if (flavNew.idPop >= 3) sVtxWT = dWT[iCase][2]; 
 
319
  if (flavNew.idPop > 3) sVtxWT *= 0.5 * (1. + 1./dWT[iCase][4]);
 
320
  double rndmFlav = (2. + sVtxWT) * rndmPtr->flat();
 
321
  flavNew.idVtx = 1;
 
322
  if (rndmFlav > 1.) flavNew.idVtx = 2;
 
323
  if (rndmFlav > 2.) flavNew.idVtx = 3;
 
324
 
 
325
  // Special case for light flavours, possibly identical. 
 
326
  if (flavNew.idPop < 3 && flavNew.idVtx < 3) {  
 
327
    flavNew.idVtx = flavNew.idPop;
 
328
    if (rndmPtr->flat() > dWT[iCase][3]) flavNew.idVtx = 3 - flavNew.idPop;
 
329
  }
 
330
 
 
331
  // Pick 2 * spin + 1.
 
332
  int spin = 3;
 
333
  if (flavNew.idVtx != flavNew.idPop) {
 
334
    double spinWT = dWT[iCase][6];
 
335
    if (flavNew.idVtx == 3) spinWT = dWT[iCase][5];
 
336
    if (flavNew.idPop >= 3) spinWT = dWT[iCase][4];
 
337
    if ((1. + spinWT) * rndmPtr->flat() < 1.) spin = 1;
 
338
  }
 
339
 
 
340
  // Form outgoing diquark. Done. 
 
341
  flavNew.id = 1000 * max(flavNew.idVtx, flavNew.idPop) 
 
342
    + 100 * min(flavNew.idVtx, flavNew.idPop) + spin;
 
343
  if ( (flavOld.id < 0 && flavOld.id > -9) || flavOld.id > 1000 ) 
 
344
    flavNew.id = -flavNew.id; 
 
345
  return flavNew;
 
346
 
 
347
}
 
348
 
 
349
//--------------------------------------------------------------------------
 
350
 
 
351
// Combine two flavours (including diquarks) to produce a hadron.
 
352
// The weighting of the combination may fail, giving output 0.
 
353
 
 
354
int StringFlav::combine(FlavContainer& flav1, FlavContainer& flav2) {
 
355
 
 
356
  // Recognize largest and smallest flavour.
 
357
  int id1Abs = abs(flav1.id); 
 
358
  int id2Abs = abs(flav2.id);
 
359
  int idMax = max(id1Abs, id2Abs);
 
360
  int idMin = min(id1Abs, id2Abs);
 
361
 
 
362
  // Construct a meson.
 
363
  if (idMax < 9 || idMin > 1000) {
 
364
 
 
365
    // Popcorn meson: use only vertex quarks. Fail if none.
 
366
    if (idMin > 1000) {
 
367
      id1Abs = flav1.idVtx;
 
368
      id2Abs = flav2.idVtx;
 
369
      idMax = max(id1Abs, id2Abs);
 
370
      idMin = min(id1Abs, id2Abs);
 
371
      if (idMin == 0) return 0;
 
372
    }
 
373
 
 
374
    // Pick spin state and preliminary code.
 
375
    int flav = (idMax < 3) ? 0 : idMax - 2;
 
376
    double rndmSpin = mesonRateSum[flav] * rndmPtr->flat();
 
377
    int spin = -1;
 
378
    do rndmSpin -= mesonRate[flav][++spin];
 
379
    while (rndmSpin > 0.);
 
380
    int idMeson = 100 * idMax + 10 * idMin + mesonMultipletCode[spin];
 
381
 
 
382
    // For nondiagonal mesons distinguish particle/antiparticle.
 
383
    if (idMax != idMin) {
 
384
      int sign = (idMax%2 == 0) ? 1 : -1;
 
385
      if ( (idMax == id1Abs && flav1.id < 0) 
 
386
        || (idMax == id2Abs && flav2.id < 0) ) sign = -sign;
 
387
      idMeson *= sign;  
 
388
 
 
389
    // For light diagonal mesons include uubar - ddbar - ssbar mixing.
 
390
    } else if (flav < 2) {
 
391
      double rMix = rndmPtr->flat();
 
392
      if      (rMix < mesonMix1[flav][spin]) idMeson = 110;
 
393
      else if (rMix < mesonMix2[flav][spin]) idMeson = 220;
 
394
      else                                   idMeson = 330;
 
395
      idMeson += mesonMultipletCode[spin];
 
396
 
 
397
      // Additional suppression of eta and eta' may give failure.
 
398
      if (idMeson == 221 && etaSup < rndmPtr->flat()) return 0;
 
399
      if (idMeson == 331 && etaPrimeSup < rndmPtr->flat()) return 0;
 
400
    }
 
401
 
 
402
    // Finished for mesons.
 
403
    return idMeson;
 
404
  }
 
405
 
 
406
  // SU(6) factors for baryon production may give failure.
 
407
  int idQQ1 = idMax / 1000;
 
408
  int idQQ2 = (idMax / 100) % 10;
 
409
  int spinQQ = idMax % 10;
 
410
  int spinFlav = spinQQ - 1;
 
411
  if (spinFlav == 2 && idQQ1 != idQQ2) spinFlav = 4;
 
412
  if (idMin != idQQ1 && idMin != idQQ2) spinFlav++;   
 
413
  if (baryonCGSum[spinFlav] < rndmPtr->flat() * baryonCGMax[spinFlav]) 
 
414
    return 0;
 
415
 
 
416
  // Order quarks to form baryon. Pick spin.
 
417
  int idOrd1 = max( idMin, max( idQQ1, idQQ2) ); 
 
418
  int idOrd3 = min( idMin, min( idQQ1, idQQ2) ); 
 
419
  int idOrd2 = idMin + idQQ1 + idQQ2 - idOrd1 - idOrd3;
 
420
  int spinBar = (baryonCGSum[spinFlav] * rndmPtr->flat() 
 
421
    < baryonCGOct[spinFlav]) ? 2 : 4;
 
422
  
 
423
  // Distinguish Lambda- and Sigma-like. 
 
424
  bool LambdaLike = false;
 
425
  if (spinBar == 2 && idOrd1 > idOrd2 && idOrd2 > idOrd3) {
 
426
    LambdaLike = (spinQQ == 1);
 
427
    if (idOrd1 != idMin && spinQQ == 1) LambdaLike = (rndmPtr->flat() < 0.25); 
 
428
    else if (idOrd1 != idMin)           LambdaLike = (rndmPtr->flat() < 0.75);
 
429
  }
 
430
 
 
431
  // Form baryon code and return with sign.  
 
432
  int idBaryon = (LambdaLike) 
 
433
    ? 1000 * idOrd1 + 100 * idOrd3 + 10 * idOrd2 + spinBar
 
434
    : 1000 * idOrd1 + 100 * idOrd2 + 10 * idOrd3 + spinBar;
 
435
   return (flav1.id > 0) ? idBaryon : -idBaryon;
 
436
 
 
437
}
 
438
 
 
439
//--------------------------------------------------------------------------
 
440
 
 
441
// Assign popcorn quark inside an original (= rank 0) diquark.
 
442
 
 
443
void StringFlav::assignPopQ(FlavContainer& flav) {
 
444
 
 
445
  // Safety check that intended to do something.
 
446
  int idAbs = abs(flav.id);
 
447
  if (flav.rank > 0 || idAbs < 1000) return;
 
448
 
 
449
  // Make choice of popcorn quark.
 
450
  int id1 = (idAbs/1000)%10;
 
451
  int id2 = (idAbs/100)%10;
 
452
  double pop2WT = 1.;
 
453
       if (id1 == 3) pop2WT = scbBM[1];
 
454
  else if (id1 >  3) pop2WT = scbBM[2];  
 
455
       if (id2 == 3) pop2WT /= scbBM[1];
 
456
  else if (id2 >  3) pop2WT /= scbBM[2];
 
457
  // Agrees with Patrik code, but opposite to intention??
 
458
  flav.idPop = ((1. + pop2WT) * rndmPtr->flat() > 1.) ? id2 : id1; 
 
459
  flav.idVtx = id1 + id2 - flav.idPop;
 
460
 
 
461
  // Also determine if to produce popcorn meson.
 
462
  flav.nPop = 0;
 
463
  double popWT = popS[0];
 
464
  if (id1 == 3) popWT = popS[1];
 
465
  if (id2 == 3) popWT = popS[2];
 
466
  if (idAbs%10 == 1) popWT *= sqrt(probQQ1toQQ0);
 
467
  if ((1. + popWT) * rndmPtr->flat() > 1.) flav.nPop = 1;
 
468
  
 
469
}
 
470
 
 
471
//--------------------------------------------------------------------------
 
472
 
 
473
// Combine two quarks to produce a diquark. 
 
474
// Normally according to production composition, but nonvanishing idHad
 
475
// means diquark from known hadron content, so use SU(6) wave fucntion.
 
476
 
 
477
int StringFlav::makeDiquark(int id1, int id2, int idHad) {
 
478
 
 
479
  // Initial values.
 
480
  int idMin = min( abs(id1), abs(id2));
 
481
  int idMax = max( abs(id1), abs(id2));
 
482
  int spin = 1;
 
483
 
 
484
  // Select spin of diquark formed from two valence quarks in proton.
 
485
  // (More hadron cases??)
 
486
  if (abs(idHad) == 2212) {
 
487
    if (idMin == 1 && idMax == 2 && rndmPtr->flat() < 0.75) spin = 0;  
 
488
 
 
489
  // Else select spin of diquark according to production composition.
 
490
  } else {
 
491
    if (idMin != idMax && rndmPtr->flat() > probQQ1norm) spin = 0; 
 
492
  }   
 
493
 
 
494
  // Combined diquark code.
 
495
  int idNewAbs = 1000 * idMax + 100 * idMin + 2 * spin + 1; 
 
496
  return (id1 > 0) ? idNewAbs : -idNewAbs; 
 
497
 
 
498
}
 
499
 
 
500
//==========================================================================
 
501
 
 
502
// The StringZ class.
 
503
 
 
504
//--------------------------------------------------------------------------
 
505
 
 
506
// Constants: could be changed here if desired, but normally should not.
 
507
// These are of technical nature, as described for each.
 
508
 
 
509
// When a or c are close to special cases, default to these.
 
510
const double StringZ::CFROMUNITY = 0.01;
 
511
const double StringZ::AFROMZERO  = 0.02;
 
512
const double StringZ::AFROMC     = 0.01;
 
513
 
 
514
// Do not take exponent of too large or small number.
 
515
const double StringZ::EXPMAX     = 50.; 
 
516
 
 
517
//--------------------------------------------------------------------------
 
518
 
 
519
// Initialize data members of the string z selection.
 
520
 
 
521
void StringZ::init(Settings& settings, ParticleData& particleData, 
 
522
  Rndm* rndmPtrIn) {
 
523
 
 
524
  // Save pointer.
 
525
  rndmPtr       = rndmPtrIn;
 
526
 
 
527
  // c and b quark masses.
 
528
  mc2           = pow2( particleData.m0(4)); 
 
529
  mb2           = pow2( particleData.m0(5)); 
 
530
 
 
531
  // Paramaters of Lund/Bowler symmetric fragmentation function.
 
532
  aLund         = settings.parm("StringZ:aLund");
 
533
  bLund         = settings.parm("StringZ:bLund");
 
534
  aExtraDiquark = settings.parm("StringZ:aExtraDiquark");
 
535
  rFactC        = settings.parm("StringZ:rFactC");
 
536
  rFactB        = settings.parm("StringZ:rFactB");
 
537
  rFactH        = settings.parm("StringZ:rFactH");
 
538
 
 
539
  // Flags and parameters of Peterson/SLAC fragmentation function.
 
540
  usePetersonC  = settings.flag("StringZ:usePetersonC");
 
541
  usePetersonB  = settings.flag("StringZ:usePetersonB");
 
542
  usePetersonH  = settings.flag("StringZ:usePetersonH");
 
543
  epsilonC      = settings.parm("StringZ:epsilonC");
 
544
  epsilonB      = settings.parm("StringZ:epsilonB");
 
545
  epsilonH      = settings.parm("StringZ:epsilonH");
 
546
 
 
547
  // Parameters for joining procedure.
 
548
  stopM         = settings.parm("StringFragmentation:stopMass");
 
549
  stopNF        = settings.parm("StringFragmentation:stopNewFlav");
 
550
  stopS         = settings.parm("StringFragmentation:stopSmear");
 
551
 
 
552
}
 
553
 
 
554
//--------------------------------------------------------------------------
 
555
 
 
556
// Generate the fraction z that the next hadron will take, 
 
557
// using either Lund/Bowler or, for heavy, Peterson/SLAC functions.
 
558
// Note: for a heavy new coloured particle we assume pT negligible.
 
559
 
 
560
double StringZ::zFrag( int idOld, int idNew, double mT2) {
 
561
 
 
562
  // Find if old or new flavours correspond to diquarks.
 
563
  int idOldAbs = abs(idOld);
 
564
  int idNewAbs = abs(idNew);
 
565
  bool isOldDiquark = (idOldAbs > 1000 && idOldAbs < 10000);
 
566
  bool isNewDiquark = (idNewAbs > 1000 && idNewAbs < 10000);
 
567
 
 
568
  // Find heaviest quark in fragmenting parton/diquark.
 
569
  int idFrag = idOldAbs;
 
570
  if (isOldDiquark) idFrag = max( idOldAbs / 1000, (idOldAbs / 100) % 10);
 
571
  
 
572
  // Use Peterson where explicitly requested for heavy flavours.
 
573
  if (idFrag == 4 && usePetersonC) return zPeterson( epsilonC);
 
574
  if (idFrag == 5 && usePetersonB) return zPeterson( epsilonB);
 
575
  if (idFrag >  5 && usePetersonH) {
 
576
    double epsilon = epsilonH * mb2 / mT2; 
 
577
    return zPeterson( epsilon);
 
578
  }
 
579
 
 
580
  // Shape parameters of Lund symmetric fragmentation function.
 
581
  double aShape = aLund;
 
582
  if (isOldDiquark) aShape += aExtraDiquark;
 
583
  double bShape = bLund * mT2;
 
584
  double cShape = 1.;
 
585
  if (isOldDiquark) cShape -= aExtraDiquark;
 
586
  if (isNewDiquark) cShape += aExtraDiquark;
 
587
  if (idFrag == 4) cShape += rFactC * bLund * mc2;
 
588
  if (idFrag == 5) cShape += rFactB * bLund * mb2;
 
589
  if (idFrag >  5) cShape += rFactH * bLund * mT2;
 
590
  return zLund( aShape, bShape, cShape);
 
591
 
 
592
}
 
593
 
 
594
//--------------------------------------------------------------------------
 
595
 
 
596
// Generate a random z according to the Lund/Bowler symmetric
 
597
// fragmentation function f(z) = (1 -z)^a * exp(-b/z) / z^c.
 
598
// Normalized so that f(z_max) = 1  it can also be written as
 
599
// f(z) = exp( a * ln( (1 - z) / (1 - z_max) ) + b * (1/z_max - 1/z) 
 
600
//           + c * ln(z_max/z) ).  
 
601
 
 
602
double StringZ::zLund( double a, double b, double c) {
 
603
 
 
604
  // Special cases for c = 1, a = 0 and a = c. 
 
605
  bool cIsUnity = (abs( c - 1.) < CFROMUNITY);
 
606
  bool aIsZero = (a < AFROMZERO);
 
607
  bool aIsC = (abs(a - c) < AFROMC);
 
608
 
 
609
  // Determine position of maximum.
 
610
  double zMax;
 
611
  if (aIsZero) zMax = (c > b) ? b / c : 1.; 
 
612
  else if (aIsC) zMax = b / (b + c);
 
613
  else { zMax = 0.5 * (b + c - sqrt( pow2(b - c) + 4. * a * b)) / (c - a);
 
614
         if (zMax > 0.9999 && b > 100.) zMax = min(zMax, 1. - a / b); }   
 
615
        
 
616
  // Subdivide z range if distribution very peaked near either endpoint.
 
617
  bool peakedNearZero = (zMax < 0.1);
 
618
  bool peakedNearUnity = (zMax > 0.85 && b > 1.);
 
619
 
 
620
  // Find integral of trial function everywhere bigger than f. 
 
621
  // (Dummy start values.)
 
622
  double fIntLow = 1.; 
 
623
  double fIntHigh = 1.; 
 
624
  double fInt = 2.; 
 
625
  double zDiv = 0.5; 
 
626
  double zDivC = 0.5;
 
627
  // When z_max is small use that f(z)
 
628
  //   < 1     for z < z_div = 2.75 * z_max,
 
629
  //   < (z_div/z)^c for z > z_div (=> logarithm for c = 1, else power).   
 
630
  if (peakedNearZero) {
 
631
    zDiv = 2.75 * zMax;
 
632
    fIntLow = zDiv; 
 
633
    if (cIsUnity) fIntHigh = -zDiv * log(zDiv);
 
634
    else { zDivC = pow( zDiv, 1. - c);
 
635
           fIntHigh = zDiv * (1. - 1./zDivC) / (c - 1.);} 
 
636
    fInt = fIntLow + fIntHigh;
 
637
  // When z_max large use that f(z)
 
638
  //   < exp( b * (z - z_div) ) for z < z_div with z_div messy expression,
 
639
  //   < 1   for z > z_div.
 
640
  // To simplify expressions the integral is extended to z =  -infinity.
 
641
  } else if (peakedNearUnity) {
 
642
    double rcb = sqrt(4. + pow2(c / b));
 
643
    zDiv = rcb - 1./zMax - (c / b) * log( zMax * 0.5 * (rcb + c / b) );  
 
644
    if (!aIsZero) zDiv += (a/b) * log(1. - zMax);
 
645
    zDiv = min( zMax, max(0., zDiv));
 
646
    fIntLow = 1. / b;
 
647
    fIntHigh = 1. - zDiv; 
 
648
    fInt = fIntLow + fIntHigh;
 
649
  }
 
650
 
 
651
  // Choice of z, preweighted for peaks at low or high z. (Dummy start values.)
 
652
  double z = 0.5;
 
653
  double fPrel = 1.; 
 
654
  double fVal = 1.; 
 
655
  do { 
 
656
    // Choice of z flat good enough for distribution peaked in the middle;
 
657
    // if not this z can be reused as a random number in general.
 
658
    z = rndmPtr->flat();
 
659
    fPrel = 1.;
 
660
    // When z_max small use flat below z_div and 1/z^c above z_div.
 
661
    if (peakedNearZero) {
 
662
      if (fInt * rndmPtr->flat() < fIntLow) z = zDiv * z;
 
663
      else if (cIsUnity) {z = pow( zDiv, z); fPrel = zDiv / z;}
 
664
      else { z = pow( zDivC + (1. - zDivC) * z, 1. / (1. - c) );
 
665
             fPrel = pow( zDiv / z, c); }
 
666
    // When z_max large use exp( b * (z -z_div) ) below z_div 
 
667
    // and flat above it.
 
668
    } else if (peakedNearUnity) {
 
669
      if (fInt * rndmPtr->flat() < fIntLow) { 
 
670
        z = zDiv + log(z) / b;
 
671
        fPrel = exp( b * (z - zDiv) ); 
 
672
      } else z = zDiv + (1. - zDiv) * z; 
 
673
    }  
 
674
 
 
675
    // Evaluate actual f(z) (if in physical range) and correct.
 
676
    if (z > 0 && z < 1) {
 
677
      double fExp = b * (1. / zMax - 1. / z)+ c * log(zMax / z);
 
678
      if (!aIsZero) fExp += a * log( (1. - z) / (1. - zMax) );
 
679
      fVal = exp( max( -EXPMAX, min( EXPMAX, fExp) ) ) ;
 
680
    } else fVal = 0.;
 
681
  } while (fVal < rndmPtr->flat() * fPrel);
 
682
 
 
683
  // Done.
 
684
  return z;
 
685
 
 
686
}
 
687
 
 
688
//--------------------------------------------------------------------------
 
689
 
 
690
// Generate a random z according to the Peterson/SLAC formula
 
691
// f(z) = 1 / ( z * (1 - 1/z - epsilon/(1-z))^2 )
 
692
//      = z * (1-z)^2 / ((1-z)^2 + epsilon * z)^2.
 
693
 
 
694
double StringZ::zPeterson( double epsilon) {
 
695
 
 
696
  double z, fVal;
 
697
 
 
698
  // For large epsilon pick z flat and reject, 
 
699
  // knowing that 4 * epsilon * f(z) < 1 everywhere.
 
700
  if (epsilon > 0.01) { 
 
701
    do { 
 
702
      z = rndmPtr->flat();
 
703
      fVal = 4. * epsilon * z * pow2(1. - z) 
 
704
        / pow2( pow2(1. - z) + epsilon * z);
 
705
    } while (fVal < rndmPtr->flat());
 
706
    return z; 
 
707
  } 
 
708
  
 
709
  // Else split range, using that 4 * epsilon * f(z) 
 
710
  //   < 4 * epsilon / (1 - z)^2 for 0 < z < 1 - 2 * sqrt(epsilon)
 
711
  //   < 1                       for 1 - 2 * sqrt(epsilon) < z < 1
 
712
  double epsRoot = sqrt(epsilon);
 
713
  double epsComb = 0.5 / epsRoot - 1.;
 
714
  double fIntLow = 4. * epsilon * epsComb;
 
715
  double fInt = fIntLow + 2. * epsRoot;
 
716
  do { 
 
717
    if (rndmPtr->flat() * fInt < fIntLow) {
 
718
      z = 1. - 1. / (1. + rndmPtr->flat() * epsComb);
 
719
      fVal = z * pow2( pow2(1. - z) / (pow2(1. - z) + epsilon * z) );
 
720
    } else {
 
721
      z = 1. - 2. * epsRoot * rndmPtr->flat();
 
722
      fVal = 4. * epsilon * z * pow2(1. - z) 
 
723
        / pow2( pow2(1. - z) + epsilon * z);
 
724
    }
 
725
  } while (fVal < rndmPtr->flat());
 
726
  return z; 
 
727
 
 
728
 
729
 
 
730
//==========================================================================
 
731
 
 
732
// The StringPT class.
 
733
 
 
734
//--------------------------------------------------------------------------
 
735
 
 
736
// Constants: could be changed here if desired, but normally should not.
 
737
// These are of technical nature, as described for each.
 
738
 
 
739
// To avoid division by zero one must have sigma > 0.
 
740
const double StringPT::SIGMAMIN     = 0.2;
 
741
 
 
742
//--------------------------------------------------------------------------
 
743
 
 
744
// Initialize data members of the string pT selection.
 
745
 
 
746
void StringPT::init(Settings& settings,  ParticleData& , Rndm* rndmPtrIn) {
 
747
 
 
748
  // Save pointer.
 
749
  rndmPtr        = rndmPtrIn;
 
750
 
 
751
  // Parameters of the pT width and enhancement.
 
752
  double sigma     = settings.parm("StringPT:sigma");
 
753
  sigmaQ           = sigma / sqrt(2.);
 
754
  enhancedFraction = settings.parm("StringPT:enhancedFraction");
 
755
  enhancedWidth    = settings.parm("StringPT:enhancedWidth");
 
756
 
 
757
  // Parameter for pT suppression in MiniStringFragmentation.
 
758
  sigma2Had        = 2. * pow2( max( SIGMAMIN, sigma) );
 
759
  
 
760
}
 
761
 
 
762
//--------------------------------------------------------------------------
 
763
 
 
764
// Generate Gaussian pT such that <p_x^2> = <p_x^2> = sigma^2 = width^2/2,
 
765
// but with small fraction multiplied up to a broader spectrum.
 
766
 
 
767
pair<double, double> StringPT::pxy() {
 
768
 
 
769
  double sigma = sigmaQ;
 
770
  if (rndmPtr->flat() < enhancedFraction) sigma *= enhancedWidth;
 
771
  pair<double, double> gauss2 = rndmPtr->gauss2();
 
772
  return pair<double, double>(sigma * gauss2.first, sigma * gauss2.second);
 
773
 
 
774
}
 
775
  
 
776
//==========================================================================
 
777
 
 
778
} // end namespace Pythia8