source: HiSusy/trunk/Pythia8/pythia8170/src/SigmaQCD.cc @ 1

Last change on this file since 1 was 1, checked in by zerwas, 11 years ago

first import of structure, PYTHIA8 and DELPHES

File size: 45.9 KB
Line 
1// SigmaQCD.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// QCD simulation classes.
8
9#include "SigmaQCD.h"
10
11namespace Pythia8 {
12
13//==========================================================================
14
15// Sigma0AB2AB class.
16// Cross section for elastic scattering A B -> A B.
17
18//--------------------------------------------------------------------------
19
20// Select identity, colour and anticolour.
21
22void Sigma0AB2AB::setIdColAcol() {
23
24  // Flavours and colours are trivial.
25  setId( idA, idB, idA, idB);
26  setColAcol( 0, 0, 0, 0, 0, 0, 0, 0);
27}
28
29//==========================================================================
30
31// Sigma0AB2XB class.
32// Cross section for single diffractive scattering A B -> X B.
33
34//--------------------------------------------------------------------------
35
36// Select identity, colour and anticolour.
37
38void Sigma0AB2XB::setIdColAcol() {
39
40  // Flavours and colours are trivial.
41  int idX          = 10* (abs(idA) / 10) + 9900000; 
42  if (idA < 0) idX = -idX;
43  setId( idA, idB, idX, idB);
44  setColAcol( 0, 0, 0, 0, 0, 0, 0, 0);
45
46}
47
48//==========================================================================
49
50// Sigma0AB2AX class.
51// Cross section for single diffractive scattering A B -> A X.
52
53//--------------------------------------------------------------------------
54
55// Select identity, colour and anticolour.
56
57void Sigma0AB2AX::setIdColAcol() {
58
59  // Flavours and colours are trivial.
60  int idX          = 10* (abs(idB) / 10) + 9900000; 
61  if (idB < 0) idX = -idX;
62  setId( idA, idB, idA, idX);
63  setColAcol( 0, 0, 0, 0, 0, 0, 0, 0);
64
65}
66
67//==========================================================================
68
69// Sigma0AB2XX class.
70// Cross section for double diffractive scattering A B -> X X.
71
72//--------------------------------------------------------------------------
73
74// Select identity, colour and anticolour.
75
76void Sigma0AB2XX::setIdColAcol() {
77
78  // Flavours and colours are trivial.
79  int          idX1 = 10* (abs(idA) / 10) + 9900000; 
80  if (idA < 0) idX1 = -idX1;
81  int          idX2 = 10* (abs(idB) / 10) + 9900000; 
82  if (idB < 0) idX2 = -idX2;
83  setId( idA, idB, idX1, idX2);
84  setColAcol( 0, 0, 0, 0, 0, 0, 0, 0);
85
86}
87
88//==========================================================================
89
90// Sigma0AB2AXB class.
91// Cross section for central scattering A B -> A X B.
92
93//--------------------------------------------------------------------------
94
95// Select identity, colour and anticolour.
96
97void Sigma0AB2AXB::setIdColAcol() {
98 
99  // Central diffractive state represented by rho_diffr0. Colours trivial.
100  int idX = 9900110; 
101  setId( idA, idB, idA, idB,idX);
102  setColAcol( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
103 
104}
105
106//==========================================================================
107
108// Sigma2gg2gg class.
109// Cross section for g g -> g g.
110
111//--------------------------------------------------------------------------
112
113// Evaluate d(sigmaHat)/d(tHat) - no incoming flavour dependence.
114
115void Sigma2gg2gg::sigmaKin() {
116
117  // Calculate kinematics dependence.
118  sigTS  = (9./4.) * (tH2 / sH2 + 2. * tH / sH + 3. + 2. * sH / tH
119           + sH2 / tH2);
120  sigUS  = (9./4.) * (uH2 / sH2 + 2. * uH / sH + 3. + 2. * sH / uH
121           + sH2 / uH2);
122  sigTU  = (9./4.) * (tH2 / uH2 + 2. * tH / uH + 3. + 2. * uH / tH
123           + uH2 / tH2);
124  sigSum = sigTS + sigUS + sigTU;
125
126  // Answer contains factor 1/2 from identical gluons.
127  sigma  = (M_PI / sH2) * pow2(alpS) * 0.5 * sigSum; 
128
129}
130
131//--------------------------------------------------------------------------
132
133// Select identity, colour and anticolour.
134
135void Sigma2gg2gg::setIdColAcol() {
136
137  // Flavours are trivial.
138  setId( id1, id2, 21, 21);
139
140  // Three colour flow topologies, each with two orientations.
141  double sigRand = sigSum * rndmPtr->flat();
142  if (sigRand < sigTS) setColAcol( 1, 2, 2, 3, 1, 4, 4, 3);
143  else if (sigRand < sigTS + sigUS) 
144                       setColAcol( 1, 2, 3, 1, 3, 4, 4, 2);
145  else                 setColAcol( 1, 2, 3, 4, 1, 4, 3, 2); 
146  if (rndmPtr->flat() > 0.5) swapColAcol();
147
148}
149
150//==========================================================================
151
152// Sigma2gg2qqbar class.
153// Cross section for g g -> q qbar (q = u, d, s, i.e. almost massless).
154
155//--------------------------------------------------------------------------
156
157// Initialize process.
158 
159void Sigma2gg2qqbar::initProc() {
160
161  // Read number of quarks to be considered in massless approximation.
162  nQuarkNew       = settingsPtr->mode("HardQCD:nQuarkNew");
163
164} 
165
166//--------------------------------------------------------------------------
167
168// Evaluate d(sigmaHat)/d(tHat) - no incoming flavour dependence.
169
170void Sigma2gg2qqbar::sigmaKin() { 
171
172  // Pick new flavour.
173  idNew = 1 + int( nQuarkNew * rndmPtr->flat() ); 
174  mNew  = particleDataPtr->m0(idNew);
175  m2New = mNew*mNew;
176 
177  // Calculate kinematics dependence.
178  sigTS = 0.;
179  sigUS = 0.;
180  if (sH > 4. * m2New) {
181    sigTS = (1./6.) * uH / tH - (3./8.) * uH2 / sH2;
182    sigUS = (1./6.) * tH / uH - (3./8.) * tH2 / sH2; 
183  }
184  sigSum = sigTS + sigUS;
185
186  // Answer is proportional to number of outgoing flavours.
187  sigma  = (M_PI / sH2) * pow2(alpS) * nQuarkNew * sigSum; 
188
189}
190
191//--------------------------------------------------------------------------
192
193// Select identity, colour and anticolour.
194
195void Sigma2gg2qqbar::setIdColAcol() {
196
197  // Flavours are trivial.
198  setId( id1, id2, idNew, -idNew);
199
200  // Two colour flow topologies.
201  double sigRand = sigSum * rndmPtr->flat();
202  if (sigRand < sigTS) setColAcol( 1, 2, 2, 3, 1, 0, 0, 3);
203  else                 setColAcol( 1, 2, 3, 1, 3, 0, 0, 2); 
204
205}
206
207//==========================================================================
208
209// Sigma2qg2qg class.
210// Cross section for q g -> q g.
211
212//--------------------------------------------------------------------------
213
214// Evaluate d(sigmaHat)/d(tHat) - no incoming flavour dependence.
215
216void Sigma2qg2qg::sigmaKin() { 
217
218  // Calculate kinematics dependence.
219  sigTS  = uH2 / tH2 - (4./9.) * uH / sH;
220  sigTU  = sH2 / tH2 - (4./9.) * sH / uH;
221  sigSum = sigTS + sigTU;
222
223  // Answer.
224  sigma  = (M_PI / sH2) * pow2(alpS) * sigSum; 
225
226}
227
228//--------------------------------------------------------------------------
229
230// Select identity, colour and anticolour.
231
232void Sigma2qg2qg::setIdColAcol() {
233
234  // Outgoing = incoming flavours.
235  setId( id1, id2, id1, id2);
236
237  // Two colour flow topologies. Swap if first is gluon, or when antiquark.
238  double sigRand = sigSum * rndmPtr->flat();
239  if (sigRand < sigTS) setColAcol( 1, 0, 2, 1, 3, 0, 2, 3);
240  else                 setColAcol( 1, 0, 2, 3, 2, 0, 1, 3); 
241  if (id1 == 21) swapCol1234();
242  if (id1 < 0 || id2 < 0) swapColAcol();
243
244}
245
246//==========================================================================
247
248// Sigma2qq2qq class.
249// Cross section for q qbar' -> q qbar' or q q' -> q q'
250// (qbar qbar' -> qbar qbar'), q' may be same as q.
251
252//--------------------------------------------------------------------------
253
254// Evaluate d(sigmaHat)/d(tHat), part independent of incoming flavour.
255
256void Sigma2qq2qq::sigmaKin() { 
257
258  // Calculate kinematics dependence for different terms.
259  sigT   = (4./9.) * (sH2 + uH2) / tH2;
260  sigU   = (4./9.) * (sH2 + tH2) / uH2;
261  sigTU  = - (8./27.) * sH2 / (tH * uH);
262  sigST  = - (8./27.) * uH2 / (sH * tH);
263
264}
265
266//--------------------------------------------------------------------------
267
268
269// Evaluate d(sigmaHat)/d(tHat), including incoming flavour dependence.
270
271double Sigma2qq2qq::sigmaHat() { 
272
273  // Combine cross section terms; factor 1/2 when identical quarks.
274  if      (id2 ==  id1) sigSum = 0.5 * (sigT + sigU + sigTU);
275  else if (id2 == -id1) sigSum = sigT + sigST;
276  else                      sigSum = sigT;
277
278  // Answer.
279  return (M_PI/sH2) * pow2(alpS) * sigSum; 
280
281}
282
283//--------------------------------------------------------------------------
284
285// Select identity, colour and anticolour.
286
287void Sigma2qq2qq::setIdColAcol() {
288
289  // Outgoing = incoming flavours.
290  setId( id1, id2, id1, id2);
291
292  // Colour flow topologies. Swap when antiquarks.
293  if (id1 * id2 > 0)  setColAcol( 1, 0, 2, 0, 2, 0, 1, 0);
294  else                setColAcol( 1, 0, 0, 1, 2, 0, 0, 2);
295  if (id2 == id1 && (sigT + sigU) * rndmPtr->flat() > sigT)
296                      setColAcol( 1, 0, 2, 0, 1, 0, 2, 0);
297  if (id1 < 0) swapColAcol();
298
299}
300
301//==========================================================================
302
303// Sigma2qqbar2gg class.
304// Cross section for q qbar -> g g.
305
306//--------------------------------------------------------------------------
307
308// Evaluate d(sigmaHat)/d(tHat) - no incoming flavour dependence.
309
310void Sigma2qqbar2gg::sigmaKin() { 
311
312  // Calculate kinematics dependence.
313  sigTS  = (32./27.) * uH / tH - (8./3.) * uH2 / sH2;
314  sigUS  = (32./27.) * tH / uH - (8./3.) * tH2 / sH2;
315  sigSum = sigTS + sigUS;
316
317  // Answer contains factor 1/2 from identical gluons.
318  sigma  = (M_PI / sH2) * pow2(alpS) * 0.5 * sigSum; 
319
320}
321
322//--------------------------------------------------------------------------
323
324// Select identity, colour and anticolour.
325
326void Sigma2qqbar2gg::setIdColAcol() {
327
328  // Outgoing flavours trivial.
329  setId( id1, id2, 21, 21);
330
331  // Two colour flow topologies. Swap if first is antiquark.
332  double sigRand = sigSum * rndmPtr->flat();
333  if (sigRand < sigTS) setColAcol( 1, 0, 0, 2, 1, 3, 3, 2);
334  else                 setColAcol( 1, 0, 0, 2, 3, 2, 1, 3); 
335  if (id1 < 0) swapColAcol();
336
337}
338
339//==========================================================================
340
341// Sigma2qqbar2qqbarNew class.
342// Cross section q qbar -> q' qbar'.
343
344//--------------------------------------------------------------------------
345
346// Initialize process.
347 
348void Sigma2qqbar2qqbarNew::initProc() {
349
350  // Read number of quarks to be considered in massless approximation.
351  nQuarkNew       = settingsPtr->mode("HardQCD:nQuarkNew");
352
353} 
354
355//--------------------------------------------------------------------------
356
357// Evaluate d(sigmaHat)/d(tHat) - no incoming flavour dependence.
358
359void Sigma2qqbar2qqbarNew::sigmaKin() { 
360
361  // Pick new flavour.
362  idNew = 1 + int( nQuarkNew * rndmPtr->flat() ); 
363  mNew  = particleDataPtr->m0(idNew);
364  m2New = mNew*mNew;
365
366  // Calculate kinematics dependence.
367  sigS                      = 0.;
368  if (sH > 4. * m2New) sigS = (4./9.) * (tH2 + uH2) / sH2; 
369
370  // Answer is proportional to number of outgoing flavours.
371  sigma = (M_PI / sH2) * pow2(alpS) * nQuarkNew * sigS; 
372
373}
374
375//--------------------------------------------------------------------------
376
377// Select identity, colour and anticolour.
378
379void Sigma2qqbar2qqbarNew::setIdColAcol() {
380
381  // Set outgoing flavours ones.
382  id3 = (id1 > 0) ? idNew : -idNew;
383  setId( id1, id2, id3, -id3);
384
385  // Colour flow topologies. Swap when antiquarks.
386  setColAcol( 1, 0, 0, 2, 1, 0, 0, 2);
387  if (id1 < 0) swapColAcol();
388
389}
390
391//==========================================================================
392
393// Sigma2gg2QQbar class.
394// Cross section g g -> Q Qbar (Q = c, b or t).
395// Only provided for fixed m3 = m4 so do some gymnastics:
396// i) s34Avg picked so that beta34 same when s3, s4 -> s34Avg.
397// ii) tHQ = tH - mQ^2 = -0.5 sH (1 - beta34 cos(thetaH)) for m3 = m4 = mQ,
398//     but tH - uH = sH beta34 cos(thetaH) also for m3 != m4, so use
399//     tH, uH selected for m3 != m4 to derive tHQ, uHQ valid for m3 = m4.   
400
401//--------------------------------------------------------------------------
402
403// Initialize process.
404 
405void Sigma2gg2QQbar::initProc() {
406
407  // Process name.
408  nameSave                 = "g g -> Q Qbar";
409  if (idNew == 4) nameSave = "g g -> c cbar";
410  if (idNew == 5) nameSave = "g g -> b bbar";
411  if (idNew == 6) nameSave = "g g -> t tbar";
412  if (idNew == 7) nameSave = "g g -> b' b'bar";
413  if (idNew == 8) nameSave = "g g -> t' t'bar";
414
415  // Secondary open width fraction.
416  openFracPair = particleDataPtr->resOpenFrac(idNew, -idNew);
417
418} 
419
420//--------------------------------------------------------------------------
421
422// Evaluate d(sigmaHat)/d(tHat) - no incoming flavour dependence.
423
424void Sigma2gg2QQbar::sigmaKin() { 
425
426  // Modified Mandelstam variables for massive kinematics with m3 = m4.
427  double s34Avg = 0.5 * (s3 + s4) - 0.25 * pow2(s3 - s4) / sH; 
428  double tHQ    = -0.5 * (sH - tH + uH);
429  double uHQ    = -0.5 * (sH + tH - uH); 
430  double tHQ2   = tHQ * tHQ;
431  double uHQ2   = uHQ * uHQ;
432
433  // Calculate kinematics dependence.
434  double tumHQ = tHQ * uHQ - s34Avg * sH;
435  sigTS = ( uHQ / tHQ - 2.25 * uHQ2 / sH2 + 4.5 * s34Avg * tumHQ
436    / ( sH * tHQ2) + 0.5 * s34Avg * (tHQ + s34Avg) / tHQ2
437    - s34Avg*s34Avg / (sH * tHQ) ) / 6.;
438  sigUS = ( tHQ / uHQ - 2.25 * tHQ2 / sH2 + 4.5 * s34Avg * tumHQ
439    / ( sH * uHQ2) + 0.5 * s34Avg * (uHQ + s34Avg) / uHQ2
440    - s34Avg*s34Avg / (sH * uHQ) ) / 6.;
441  sigSum = sigTS + sigUS;
442
443  // Answer.
444  sigma = (M_PI / sH2) * pow2(alpS) * sigSum * openFracPair; 
445
446}
447
448//--------------------------------------------------------------------------
449
450// Select identity, colour and anticolour.
451
452void Sigma2gg2QQbar::setIdColAcol() {
453
454  // Flavours are trivial.
455  setId( id1, id2, idNew, -idNew);
456
457  // Two colour flow topologies.
458  double sigRand = sigSum * rndmPtr->flat();
459  if (sigRand < sigTS) setColAcol( 1, 2, 2, 3, 1, 0, 0, 3);
460  else                 setColAcol( 1, 2, 3, 1, 3, 0, 0, 2); 
461
462}
463
464//--------------------------------------------------------------------------
465
466// Evaluate weight for decay angles of W in top decay.
467
468double Sigma2gg2QQbar::weightDecay( Event& process, int iResBeg, 
469  int iResEnd) {
470
471  // For top decay hand over to standard routine, else done.
472  if (idNew == 6 && process[process[iResBeg].mother1()].idAbs() == 6) 
473       return weightTopDecay( process, iResBeg, iResEnd);
474  else return 1.; 
475
476}
477
478//==========================================================================
479
480// Sigma2qqbar2QQbar class.
481// Cross section q qbar -> Q Qbar (Q = c, b or t).
482// Only provided for fixed m3 = m4 so do some gymnastics:
483// i) s34Avg picked so that beta34 same when s3, s4 -> s34Avg.
484// ii) tHQ = tH - mQ^2 = -0.5 sH (1 - beta34 cos(thetaH)) for m3 = m4 = mQ,
485//     but tH - uH = sH beta34 cos(thetaH) also for m3 != m4, so use
486//     tH, uH selected for m3 != m4 to derive tHQ, uHQ valid for m3 = m4.   
487
488//--------------------------------------------------------------------------
489
490// Initialize process, especially parton-flux object.
491 
492void Sigma2qqbar2QQbar::initProc() {
493
494  // Process name.
495  nameSave                 = "q qbar -> Q Qbar";
496  if (idNew == 4) nameSave = "q qbar -> c cbar";
497  if (idNew == 5) nameSave = "q qbar -> b bbar";
498  if (idNew == 6) nameSave = "q qbar -> t tbar";
499  if (idNew == 7) nameSave = "q qbar -> b' b'bar";
500  if (idNew == 8) nameSave = "q qbar -> t' t'bar";
501
502  // Secondary open width fraction.
503  openFracPair = particleDataPtr->resOpenFrac(idNew, -idNew);
504
505} 
506
507//--------------------------------------------------------------------------
508
509// Evaluate d(sigmaHat)/d(tHat) - no incoming flavour dependence.
510
511void Sigma2qqbar2QQbar::sigmaKin() { 
512
513  // Modified Mandelstam variables for massive kinematics with m3 = m4.
514  double s34Avg = 0.5 * (s3 + s4) - 0.25 * pow2(s3 - s4) / sH; 
515  double tHQ    = -0.5 * (sH - tH + uH);
516  double uHQ    = -0.5 * (sH + tH - uH); 
517  double tHQ2   = tHQ * tHQ;
518  double uHQ2   = uHQ * uHQ;
519
520  // Calculate kinematics dependence.
521  double sigS = (4./9.) * ((tHQ2 + uHQ2) / sH2 + 2. * s34Avg / sH); 
522
523  // Answer.
524  sigma = (M_PI / sH2) * pow2(alpS) * sigS * openFracPair; 
525
526}
527
528//--------------------------------------------------------------------------
529
530// Select identity, colour and anticolour.
531
532void Sigma2qqbar2QQbar::setIdColAcol() {
533
534  // Set outgoing flavours.
535  id3 = (id1 > 0) ? idNew : -idNew;
536  setId( id1, id2, id3, -id3);
537
538  // Colour flow topologies. Swap when antiquarks.
539  setColAcol( 1, 0, 0, 2, 1, 0, 0, 2);
540  if (id1 < 0) swapColAcol();
541
542}
543
544//--------------------------------------------------------------------------
545
546// Evaluate weight for decay angles of W in top decay.
547
548double Sigma2qqbar2QQbar::weightDecay( Event& process, int iResBeg, 
549  int iResEnd) {
550
551  // For top decay hand over to standard routine, else done.
552  if (idNew == 6 && process[process[iResBeg].mother1()].idAbs() == 6) 
553       return weightTopDecay( process, iResBeg, iResEnd);
554  else return 1.; 
555
556}
557
558
559//==========================================================================
560
561// Sigma3gg2ggg class.
562// Cross section for g g -> g g g.
563
564//--------------------------------------------------------------------------
565
566// Evaluate |M|^2 - no incoming flavour dependence.
567
568void Sigma3gg2ggg::sigmaKin() {
569
570  // Calculate all four-vector products.
571  Vec4 p1cm( 0., 0.,  0.5 * mH, 0.5 * mH);
572  Vec4 p2cm( 0., 0., -0.5 * mH, 0.5 * mH);
573  pp[1][2] = p1cm * p2cm;
574  pp[1][3] = p1cm * p3cm;
575  pp[1][4] = p1cm * p4cm;
576  pp[1][5] = p1cm * p5cm;
577  pp[2][3] = p2cm * p3cm;
578  pp[2][4] = p2cm * p4cm;
579  pp[2][5] = p2cm * p5cm;
580  pp[3][4] = p3cm * p4cm;
581  pp[3][5] = p3cm * p5cm;
582  pp[4][5] = p4cm * p5cm;
583  for (int i = 1; i < 5; ++i)
584    for (int j = i + 1; j < 6; ++j) pp[j][i] = pp[i][j];       
585 
586  // Cross section, in three main sections.
587  double num1 = cycle(1,2,3,4,5) + cycle(1,2,3,5,4) + cycle(1,2,4,3,5) 
588              + cycle(1,2,4,5,3) + cycle(1,2,5,3,4) + cycle(1,2,5,4,3)
589              + cycle(1,3,2,4,5) + cycle(1,3,2,5,4) + cycle(1,3,4,2,5)
590              + cycle(1,3,5,2,4) + cycle(1,4,2,3,5) + cycle(1,4,3,2,5);
591  double num2 = pow4(pp[1][2]) + pow4(pp[1][3]) + pow4(pp[1][4]) 
592              + pow4(pp[1][5]) + pow4(pp[2][3]) + pow4(pp[2][4])
593              + pow4(pp[2][5]) + pow4(pp[3][4]) + pow4(pp[3][5])
594              + pow4(pp[4][5]);
595  double den  = pp[1][2] * pp[1][3] * pp[1][4] * pp[1][5] * pp[2][3]
596              * pp[2][4] * pp[2][5] * pp[3][4] * pp[3][5] * pp[4][5];
597
598  // Answer has a factor 6 due to identical gluons
599  // This is cancelled by phase space factor (1 / 6)
600  sigma = pow3(4. * M_PI * alpS) * (27./16.) * num1 * num2 / den;
601
602}
603
604//--------------------------------------------------------------------------
605
606// Select identity, colour and anticolour.
607
608void Sigma3gg2ggg::setIdColAcol() {
609
610  // Flavours are trivial.
611  setId( id1, id2, 21, 21, 21);
612
613  // Three colour flow topologies, each with two orientations.
614  /*
615  double sigRand = sigSum * rndmPtr->flat();
616  if (sigRand < sigTS) setColAcol( 1, 2, 2, 3, 1, 4, 4, 3);
617  else if (sigRand < sigTS + sigUS)
618                       setColAcol( 1, 2, 3, 1, 3, 4, 4, 2);
619  else                 setColAcol( 1, 2, 3, 4, 1, 4, 3, 2);
620  if (rndmPtr->flat() > 0.5) swapColAcol();
621  */
622
623  // Temporary solution.
624  setColAcol( 1, 2, 2, 3, 1, 4, 4, 5, 5, 3); 
625}
626
627
628//==========================================================================
629
630// Sigma3qqbar2ggg class.
631// Cross section for q qbar -> g g g.
632
633//--------------------------------------------------------------------------
634
635// Evaluate |M|^2 - no incoming flavour dependence.
636void Sigma3qqbar2ggg::sigmaKin() {
637
638  // Setup four-vectors
639  pCM[0] = Vec4( 0., 0.,  0.5 * mH, 0.5 * mH);
640  pCM[1] = Vec4( 0., 0., -0.5 * mH, 0.5 * mH);
641  pCM[2] = p3cm;
642  pCM[3] = p4cm;
643  pCM[4] = p5cm;
644
645  // Calculate |M|^2
646  // Answer has a factor 6 due to identical gluons,
647  // which is cancelled by phase space factor (1 / 6)
648  sigma = m2Calc();
649
650}
651
652//--------------------------------------------------------------------------
653
654// |M|^2
655
656inline double Sigma3qqbar2ggg::m2Calc() {
657
658  // Calculate four-products
659  double sHnow  = (pCM[0] + pCM[1]).m2Calc();
660  double sHhalf = sH / 2.;
661
662  // qbar (p+) + q(p-) -> g(k1) g(k2) g(k3)
663  // a_i = (p+ . ki), i = 1, 2, 3
664  // b_i = (p- . ki), i = 1, 2, 3
665  a[0] = pCM[0] * pCM[2];
666  a[1] = pCM[0] * pCM[3];
667  a[2] = pCM[0] * pCM[4];
668  b[0] = pCM[1] * pCM[2];
669  b[1] = pCM[1] * pCM[3];
670  b[2] = pCM[1] * pCM[4];
671
672  pp[0][1] = pCM[2] * pCM[3];
673  pp[1][2] = pCM[3] * pCM[4];
674  pp[2][0] = pCM[4] * pCM[2];
675
676  // ab[i][j] = a_i * b_j + a_j * b_i
677  ab[0][1] = a[0] * b[1] + a[1] * b[0];
678  ab[1][2] = a[1] * b[2] + a[2] * b[1];
679  ab[2][0] = a[2] * b[0] + a[0] * b[2];
680
681  // Cross section
682  double num1 = a[0] * b[0] * (a[0] * a[0] + b[0] * b[0]) +
683                a[1] * b[1] * (a[1] * a[1] + b[1] * b[1]) +
684                a[2] * b[2] * (a[2] * a[2] + b[2] * b[2]);
685  double den1 = a[0] * a[1] * a[2] * b[0] * b[1] * b[2];
686  double num2 = - ( ab[0][1] / pp[0][1] )
687                - ( ab[1][2] / pp[1][2] )
688                - ( ab[2][0] / pp[2][0] );
689  double num3 = a[2] * b[2] * ab[0][1] / (pp[1][2] * pp[2][0] ) +
690                a[0] * b[0] * ab[1][2] / (pp[2][0] * pp[0][1] ) +
691                a[1] * b[1] * ab[2][0] / (pp[0][1] * pp[1][2] );
692
693  // Final answer
694  return  pow3(4. * M_PI * alpS) * (8. / 324.) * (num1 / den1) *
695          ( sHhalf + 9. * (sHhalf + num2) + (2. * 81. / sHnow) * num3 );
696
697}
698
699//--------------------------------------------------------------------------
700
701// Select identity, colour and anticolour.
702
703void Sigma3qqbar2ggg::setIdColAcol(){
704
705  // Flavours are trivial.
706  setId( id1, id2, 21, 21, 21);
707
708  // Temporary solution.
709  setColAcol( 1, 0, 0, 2, 1, 3, 3, 4, 4, 2); 
710  if (id1 < 0) swapColAcol();
711}
712
713//--------------------------------------------------------------------------
714
715// Map a final state configuration
716
717inline void Sigma3qqbar2ggg::mapFinal() {
718  switch (config) {
719  case 0: pCM[2] = p3cm; pCM[3] = p4cm; pCM[4] = p5cm; break;
720  case 1: pCM[2] = p3cm; pCM[3] = p5cm; pCM[4] = p4cm; break;
721  case 2: pCM[2] = p4cm; pCM[3] = p3cm; pCM[4] = p5cm; break;
722  case 3: pCM[2] = p4cm; pCM[3] = p5cm; pCM[4] = p3cm; break;
723  case 4: pCM[2] = p5cm; pCM[3] = p3cm; pCM[4] = p4cm; break;
724  case 5: pCM[2] = p5cm; pCM[3] = p4cm; pCM[4] = p3cm; break;
725  }
726}
727
728//==========================================================================
729
730// Sigma3qg2qgg class.
731// Cross section for q g -> q g g.
732// Crossed relation from q qbar -> g g g:
733//   qbar(p+) q(p-) -> g(k1) g(k2) g(k3)
734
735//--------------------------------------------------------------------------
736
737// Evaluate |M|^2 - no incoming flavour dependence
738// Note: two different contributions from gq and qg incoming
739
740void Sigma3qg2qgg::sigmaKin() {
741
742  // Pick a final state configuration
743  pickFinal();
744
745  // gq and qg incoming
746  for (int i = 0; i < 2; i++) {
747
748    // Map incoming four-vectors to p+, p-, k1, k2, k3
749    pCM[0] = Vec4( 0., 0.,  0.5 * mH, 0.5 * mH);
750    pCM[1] = Vec4( 0., 0., -0.5 * mH, 0.5 * mH);
751    mapFinal();
752
753    // Crossing
754    swap(pCM[i], pCM[2]);
755
756    // |M|^2
757    // XXX - Extra factor of (3) from selecting a final state
758    // configuration (already a factor of 2 in the original
759    // answer due to two identical final state gluons)???
760    // Extra factor of (3 / 8) as average over incoming gluon
761    sigma[i] = 3. * (3. / 8.) * m2Calc();
762
763  } // for (int i = 0; i < 2; i++)
764
765}
766
767//--------------------------------------------------------------------------
768
769// Evaluate |M|^2 - incoming flavour dependence
770// Pick from two configurations calculated previously
771
772double Sigma3qg2qgg::sigmaHat() {
773  // gq or qg incoming
774  return (id1 == 21) ? sigma[0] : sigma[1];
775}
776
777//--------------------------------------------------------------------------
778
779// Select identity, colour and anticolour.
780
781void Sigma3qg2qgg::setIdColAcol(){
782  // Outgoing flavours; only need to know where the quark is
783  int qIdx    = config / 2;
784  int idTmp[3] = { 21, 21, 21 };
785  idTmp[qIdx]  = (id1 == 21) ? id2 : id1;
786  setId( id1, id2, idTmp[0], idTmp[1], idTmp[2]);
787
788  // Temporary solution
789  if      (qIdx == 0) setColAcol(1, 0, 2, 1, 4, 0, 3, 4, 2, 3);
790  else if (qIdx == 1) setColAcol(1, 0, 2, 1, 3, 4, 4, 0, 2, 3);
791  else                setColAcol(1, 0, 2, 1, 3, 4, 2, 3, 4, 0);
792  // gq or qg incoming
793  if (id1 == 21) {
794    swap( colSave[1], colSave[2]);
795    swap(acolSave[1], acolSave[2]);
796  }
797  // qbar rather than q incoming
798  if (id1 < 0 || id2 < 0) swapColAcol();
799
800}
801
802//==========================================================================
803
804// Sigma3gg2qqbarg class.
805// Cross section for g g -> q qbar g
806// Crossed relation from q qbar -> g g g
807
808//--------------------------------------------------------------------------
809
810// Initialize process.
811 
812void Sigma3gg2qqbarg::initProc() {
813
814  // Read number of quarks to be considered in massless approximation.
815  nQuarkNew       = settingsPtr->mode("HardQCD:nQuarkNew");
816
817}
818
819//--------------------------------------------------------------------------
820 
821// Evaluate |M|^2 - no incoming flavour dependence.
822
823void Sigma3gg2qqbarg::sigmaKin() {
824
825  // Incoming four-vectors
826  pCM[0] = Vec4( 0., 0.,  0.5 * mH, 0.5 * mH);
827  pCM[1] = Vec4( 0., 0., -0.5 * mH, 0.5 * mH);
828
829  // Pick and map a final state configuration
830  pickFinal();
831  mapFinal();
832
833  // Crossing
834  swap(pCM[0], pCM[2]);
835  swap(pCM[1], pCM[3]);
836
837  // |M|^2
838  // Extra factor of (6.) from picking a final state configuration
839  // Extra factor of nQuarkNew
840  // Extra factor of (3. / 8.) ^ 2 as averaging over two incoming gluons
841  sigma = 6. * nQuarkNew * (3. / 8.) * (3. / 8.) * m2Calc();
842
843}
844
845//--------------------------------------------------------------------------
846
847// Select identity, colour and anticolour.
848
849void Sigma3gg2qqbarg::setIdColAcol(){
850
851  // Pick new flavour
852  int idNew = 1 + int( nQuarkNew * rndmPtr->flat() ); 
853
854  // Outgoing flavours; easiest just to map by hand
855  switch (config) {
856  case 0: id3 =  idNew; id4 = -idNew; id5 =  21;    break;
857  case 1: id3 =  idNew; id4 =  21;    id5 = -idNew; break;
858  case 2: id3 = -idNew; id4 =  idNew; id5 =  21;    break;
859  case 3: id3 =  21;    id4 =  idNew; id5 = -idNew; break;
860  case 4: id3 = -idNew; id4 =  21;    id5 =  idNew; break;
861  case 5: id3 =  21;    id4 = -idNew; id5 =  idNew; break;
862  }
863  setId(id1, id2, id3, id4, id5);
864
865  // Temporary solution
866  switch (config) {
867  case 0: setColAcol( 1, 2, 2, 3, 4, 0, 0, 3, 1, 4 ); break;
868  case 1: setColAcol( 1, 2, 2, 3, 4, 0, 1, 4, 0, 3 ); break;
869  case 2: setColAcol( 1, 2, 2, 3, 0, 3, 4, 0, 1, 4 ); break;
870  case 3: setColAcol( 1, 2, 2, 3, 1, 4, 4, 0, 0, 3 ); break;
871  case 4: setColAcol( 1, 2, 2, 3, 0, 3, 1, 4, 4, 0 ); break;
872  case 5: setColAcol( 1, 2, 2, 3, 1, 4, 0, 3, 4, 0 ); break;
873  }
874 
875}
876
877//==========================================================================
878
879// Sigma3qq2qqgDiff class.
880// Cross section for q q' -> q q' g, q != q'
881
882//--------------------------------------------------------------------------
883
884// Evaluate |M|^2 - no incoming flavour dependence
885
886void Sigma3qq2qqgDiff::sigmaKin() {
887
888  // q1(p+) q2(p-) -> q1(q+) q2(q-) g(k)
889
890  // Incoming four-vectors
891  pCM[0] = Vec4( 0., 0.,  0.5 * mH, 0.5 * mH);
892  pCM[1] = Vec4( 0., 0., -0.5 * mH, 0.5 * mH);
893  // Pick and map a final state configuration
894  pickFinal();
895  mapFinal();
896
897  // |M|^2
898  // Extra factor of (6.) from picking a final state configuration
899  sigma = 6. * m2Calc();
900}
901
902//--------------------------------------------------------------------------
903
904// |M|^2
905
906inline double Sigma3qq2qqgDiff::m2Calc() {
907
908  // Four-products
909  s  = (pCM[0] + pCM[1]).m2Calc();
910  t  = (pCM[0] - pCM[2]).m2Calc();
911  u  = (pCM[0] - pCM[3]).m2Calc();
912  up = (pCM[1] - pCM[2]).m2Calc();
913  sp = (pCM[2] + pCM[3]).m2Calc();
914  tp = (pCM[1] - pCM[3]).m2Calc();
915
916  // |M|^2
917  double num1 = (s * s + sp * sp + u * u + up * up) / (t * tp);
918  double den1 = (pCM[0] * pCM[4]) * (pCM[1] * pCM[4]) *
919                (pCM[2] * pCM[4]) * (pCM[3] * pCM[4]);
920  double num2 = (u + up) * (s * sp + t * tp - u * up) +
921                u * (s * t + sp * tp) + up * (s * tp + sp * t);
922  double num3 = (s + sp) * (s * sp - t * tp - u * up) +
923                2. * t * tp * (u + up) + 2. * u * up * (t + tp);
924   
925  // (N^2 - 1)^2 / 4N^3 = 16. / 27.
926  // (N^2 - 1)   / 4N^3 =  2. / 27.
927  return (1. / 8.) * pow3(4. * M_PI * alpS) * num1 / den1 *
928         ( (16. / 27.) * num2 - (2. / 27.) * num3 );
929
930}
931
932//--------------------------------------------------------------------------
933
934// Evaluate |M|^2 - incoming flavour dependence
935
936double Sigma3qq2qqgDiff::sigmaHat() {
937  // Different incoming flavours only
938  if (abs(id1) == abs(id2)) return 0.;
939  return sigma;
940}
941
942//--------------------------------------------------------------------------
943
944// Select identity, colour and anticolour.
945
946void Sigma3qq2qqgDiff::setIdColAcol(){
947 
948  // Outgoing flavours; easiest just to map by hand
949  switch (config) {
950  case 0: id3 = id1; id4 = id2; id5 = 21;  break;
951  case 1: id3 = id1; id4 = 21;  id5 = id2; break;
952  case 2: id3 = id2; id4 = id1; id5 = 21;  break;
953  case 3: id3 = 21;  id4 = id1; id5 = id2; break;
954  case 4: id3 = id2; id4 = 21;  id5 = id1; break;
955  case 5: id3 = 21;  id4 = id2; id5 = id1; break;
956  }
957  setId(id1, id2, id3, id4, id5);
958
959  // Temporary solution; id1 and id2 can be q/qbar independently
960  int cols[5][2];
961  if (id1 > 0) {
962    cols[0][0] = 1; cols[0][1] = 0;
963    cols[2][0] = 1; cols[2][1] = 0;
964  } else {
965    cols[0][0] = 0; cols[0][1] = 1;
966    cols[2][0] = 0; cols[2][1] = 1;
967  }
968  if (id2 > 0) {
969    cols[1][0] = 2; cols[1][1] = 0;
970    cols[3][0] = 3; cols[3][1] = 0;
971    cols[4][0] = 2; cols[4][1] = 3;
972  } else {
973    cols[1][0] = 0; cols[1][1] = 2;
974    cols[3][0] = 0; cols[3][1] = 3;
975    cols[4][0] = 3; cols[4][1] = 2;
976  }
977  // Map correct final state configuration
978  int i3 = 0, i4 = 0, i5 = 0;
979  switch (config) {
980  case 0: i3 = 2; i4 = 3; i5 = 4; break;
981  case 1: i3 = 2; i4 = 4; i5 = 3; break;
982  case 2: i3 = 3; i4 = 2; i5 = 4; break;
983  case 3: i3 = 4; i4 = 2; i5 = 3; break;
984  case 4: i3 = 3; i4 = 4; i5 = 2; break;
985  case 5: i3 = 4; i4 = 3; i5 = 2; break;
986  }
987  // Put colours in place
988  setColAcol(cols[0][0],  cols[0][1],  cols[1][0],  cols[1][1],
989             cols[i3][0], cols[i3][1], cols[i4][0], cols[i4][1],
990             cols[i5][0], cols[i5][1]);
991
992}
993
994//--------------------------------------------------------------------------
995
996// Map a final state configuration
997
998inline void Sigma3qq2qqgDiff::mapFinal() {
999  switch (config) {
1000  case 0: pCM[2] = p3cm; pCM[3] = p4cm; pCM[4] = p5cm; break;
1001  case 1: pCM[2] = p3cm; pCM[3] = p5cm; pCM[4] = p4cm; break;
1002  case 2: pCM[2] = p4cm; pCM[3] = p3cm; pCM[4] = p5cm; break;
1003  case 3: pCM[2] = p4cm; pCM[3] = p5cm; pCM[4] = p3cm; break;
1004  case 4: pCM[2] = p5cm; pCM[3] = p3cm; pCM[4] = p4cm; break;
1005  case 5: pCM[2] = p5cm; pCM[3] = p4cm; pCM[4] = p3cm; break;
1006  }
1007}
1008
1009
1010//==========================================================================
1011
1012// Sigma3qqbar2qqbargDiff
1013// Cross section for q qbar -> q' qbar' g
1014// Crossed relation from q q' -> q q' g, q != q'
1015
1016//--------------------------------------------------------------------------
1017
1018// Initialize process.
1019 
1020void Sigma3qqbar2qqbargDiff::initProc() {
1021
1022  // Read number of quarks to be considered in massless approximation.
1023  nQuarkNew       = settingsPtr->mode("HardQCD:nQuarkNew");
1024
1025}
1026
1027//--------------------------------------------------------------------------
1028
1029// Evaluate |M|^2 - no incoming flavour dependence.
1030
1031void Sigma3qqbar2qqbargDiff::sigmaKin() {
1032  // Overall 6 possibilities for final state ordering
1033  // To keep symmetry between final states, always map to:
1034  //  1) q1(p+)    qbar1(p-)  -> qbar2(q+)  q2(q-)     g(k)
1035  //  2) qbar1(p+) q1(p-)     -> q2(q+)     qbar2(q-)  g(k)
1036  // Crossing p- and q+ gives:
1037  //  1) q1(p+)    q2(-q+)    -> q1(-p-)    q2(q-)     g(k)
1038  //  2) qbar1(p+) qbar2(-q+) -> qbar1(-p-) qbar2(q-)  g(k)
1039
1040  // Incoming four-vectors
1041  pCM[0] = Vec4( 0., 0.,  0.5 * mH, 0.5 * mH);
1042  pCM[1] = Vec4( 0., 0., -0.5 * mH, 0.5 * mH);
1043  // Pick and map a final state configuration
1044  pickFinal();
1045  mapFinal();
1046
1047  // Crossing
1048  swap(pCM[1], pCM[2]);
1049  pCM[1] = -pCM[1];
1050  pCM[2] = -pCM[2];
1051
1052  // |M|^2
1053  // Extra factor of (6.) from picking a final state configuration
1054  // Extra factor of (nQuarkNew - 1) from new q/qbar pairs
1055  // XXX - Extra factor of (2.) from second possible crossing???
1056  sigma = 6. * (nQuarkNew - 1) * 2. * m2Calc();
1057 
1058}
1059
1060//--------------------------------------------------------------------------
1061
1062// Select identity, colour and anticolour.
1063
1064void Sigma3qqbar2qqbargDiff::setIdColAcol(){
1065
1066  // Pick new q qbar flavour with incoming flavour disallowed
1067  int idNew = 1 + int( (nQuarkNew - 1) * rndmPtr->flat() ); 
1068  if (idNew >= abs(id1)) ++idNew;
1069  // For qbar q incoming, q+ is always mapped to q2
1070  // For q qbar incoming, q+ is always mapped to qbar2
1071  if (id1 > 0) idNew = -idNew;
1072
1073  // Outgoing flavours; easiest just to map by hand
1074  switch (config) {
1075  case 0: id3 =  idNew; id4 = -idNew; id5 =  21;    break;
1076  case 1: id3 =  idNew; id4 =  21;    id5 = -idNew; break;
1077  case 2: id3 = -idNew; id4 =  idNew; id5 =  21;    break;
1078  case 3: id3 =  21;    id4 =  idNew; id5 = -idNew; break;
1079  case 4: id3 = -idNew; id4 =  21;    id5 =  idNew; break;
1080  case 5: id3 =  21;    id4 = -idNew; id5 =  idNew; break;
1081  }
1082  setId(id1, id2, id3, id4, id5);
1083
1084  // Temporary solution; start with q qbar -> qbar q g
1085  int cols[5][2];
1086  cols[0][0] = 1; cols[0][1] = 0;
1087  cols[1][0] = 0; cols[1][1] = 2;
1088  cols[2][0] = 0; cols[2][1] = 3;
1089  cols[3][0] = 1; cols[3][1] = 0;
1090  cols[4][0] = 3; cols[4][1] = 2;
1091  // Map into correct place
1092  int i3 = 0, i4 = 0, i5 = 0;
1093  switch (config) {
1094  case 0: i3 = 2; i4 = 3; i5 = 4; break;
1095  case 1: i3 = 2; i4 = 4; i5 = 3; break;
1096  case 2: i3 = 3; i4 = 2; i5 = 4; break;
1097  case 3: i3 = 4; i4 = 2; i5 = 3; break;
1098  case 4: i3 = 3; i4 = 4; i5 = 2; break;
1099  case 5: i3 = 4; i4 = 3; i5 = 2; break;
1100  }
1101  setColAcol(cols[0][0], cols[0][1], cols[1][0], cols[1][1],
1102             cols[i3][0], cols[i3][1], cols[i4][0], cols[i4][1],
1103             cols[i5][0], cols[i5][1]);
1104  // Swap for qbar q incoming
1105  if (id1 < 0) swapColAcol();
1106
1107}
1108
1109//==========================================================================
1110
1111// Sigma3qg2qqqbarDiff class.
1112// Cross section for q g -> q q' qbar'
1113// Crossed relation from q q' -> q q' g, q != q'
1114//   q1(p+) q2(p-) -> q1(q+) q2(q-) g(k)
1115
1116//--------------------------------------------------------------------------
1117
1118// Initialize process.
1119 
1120void Sigma3qg2qqqbarDiff::initProc() {
1121
1122  // Read number of quarks to be considered in massless approximation.
1123  nQuarkNew       = settingsPtr->mode("HardQCD:nQuarkNew");
1124
1125}
1126
1127//--------------------------------------------------------------------------
1128
1129// Evaluate |M|^2 - no incoming flavour dependence
1130
1131void Sigma3qg2qqqbarDiff::sigmaKin() {
1132
1133  // Pick a final state configuration
1134  pickFinal();
1135
1136  // gq or qg incoming
1137  for (int i = 0; i < 2; i++) {
1138
1139    // Map incoming four-vectors
1140    pCM[0] = Vec4( 0., 0.,  0.5 * mH, 0.5 * mH);
1141    pCM[1] = Vec4( 0., 0., -0.5 * mH, 0.5 * mH);
1142    mapFinal();
1143
1144    // Crossing (note extra -ve sign in total sigma)
1145    swap(pCM[i], pCM[4]);
1146    pCM[i] = -pCM[i];
1147    pCM[4] = -pCM[4];
1148
1149    // |M|^2
1150    // Extra factor of (6) from picking a final state configuration
1151    // Extra factor of (3 / 8) as averaging over incoming gluon
1152    // Extra factor of (nQuarkNew - 1) due to new q/qbar pair
1153    sigma[i] = -6. * (3. / 8.) * (nQuarkNew - 1) * m2Calc();
1154
1155  }
1156 
1157}
1158
1159//--------------------------------------------------------------------------
1160
1161// Evaluate |M|^2 - incoming flavour dependence
1162
1163double Sigma3qg2qqqbarDiff::sigmaHat() {
1164  // gq or qg incoming
1165  return (id1 == 21) ? sigma[0] : sigma[1];
1166}
1167
1168//--------------------------------------------------------------------------
1169
1170// Select identity, colour and anticolour.
1171
1172void Sigma3qg2qqqbarDiff::setIdColAcol(){
1173  // Pick new q qbar flavour with incoming flavour disallowed
1174  int sigmaIdx = (id1 == 21) ? 0 : 1;
1175  int idIn     = (id1 == 21) ? id2 : id1;
1176  int idNew    = 1 + int( (nQuarkNew - 1) * rndmPtr->flat() );
1177  if (idNew >= abs(idIn)) ++idNew;
1178
1179  // qbar instead of q incoming means swap outgoing q/qbar pair
1180  int id3Tmp = idIn, id4Tmp = idNew, id5Tmp = -idNew;
1181  if (idIn < 0)  swap(id4Tmp, id5Tmp);
1182  // If g q incoming rather than q g, idIn and idNew
1183  // should be exchanged (see sigmaKin)
1184  if (sigmaIdx == 0) swap(id3Tmp, id4Tmp);
1185  // Outgoing flavours; now just map as if q g incoming
1186  switch (config) {
1187  case 0: id3 = id3Tmp; id4 = id4Tmp; id5 = id5Tmp; break;
1188  case 1: id3 = id3Tmp; id4 = id5Tmp; id5 = id4Tmp; break;
1189  case 2: id3 = id4Tmp; id4 = id3Tmp; id5 = id5Tmp; break;
1190  case 3: id3 = id5Tmp; id4 = id3Tmp; id5 = id4Tmp; break;
1191  case 4: id3 = id4Tmp; id4 = id5Tmp; id5 = id3Tmp; break;
1192  case 5: id3 = id5Tmp; id4 = id4Tmp; id5 = id3Tmp; break;
1193  }
1194  setId(id1, id2, id3, id4, id5);
1195
1196  // Temporary solution; start with either
1197  // g q1    -> q1    q2 qbar2
1198  // g qbar1 -> qbar1 qbar2 q2
1199  int cols[5][2];
1200  cols[0][0] = 1; cols[0][1] = 2;
1201  if (idIn > 0) {
1202    cols[1][0] = 3; cols[1][1] = 0;
1203    cols[2][0] = 1; cols[2][1] = 0;
1204    cols[3][0] = 3; cols[3][1] = 0;
1205    cols[4][0] = 0; cols[4][1] = 2;
1206  } else {
1207    cols[1][0] = 0; cols[1][1] = 3;
1208    cols[2][0] = 0; cols[2][1] = 2;
1209    cols[3][0] = 0; cols[3][1] = 3;
1210    cols[4][0] = 1; cols[4][1] = 0;
1211  }
1212  // Swap incoming if q/qbar g instead
1213  if (id2 == 21) {
1214    swap(cols[0][0], cols[1][0]);
1215    swap(cols[0][1], cols[1][1]);
1216  }
1217  // Map final state
1218  int i3 = 0, i4 = 0, i5 = 0;
1219  if (sigmaIdx == 0) {
1220    switch (config) {
1221    case 0: i3 = 3; i4 = 2; i5 = 4; break;
1222    case 1: i3 = 3; i4 = 4; i5 = 2; break;
1223    case 2: i3 = 2; i4 = 3; i5 = 4; break;
1224    case 3: i3 = 4; i4 = 3; i5 = 2; break;
1225    case 4: i3 = 2; i4 = 4; i5 = 3; break;
1226    case 5: i3 = 4; i4 = 2; i5 = 3; break;
1227    }
1228  } else {
1229    switch (config) {
1230    case 0: i3 = 2; i4 = 3; i5 = 4; break;
1231    case 1: i3 = 2; i4 = 4; i5 = 3; break;
1232    case 2: i3 = 3; i4 = 2; i5 = 4; break;
1233    case 3: i3 = 4; i4 = 2; i5 = 3; break;
1234    case 4: i3 = 3; i4 = 4; i5 = 2; break;
1235    case 5: i3 = 4; i4 = 3; i5 = 2; break;
1236    }
1237  }
1238  setColAcol(cols[0][0],  cols[0][1],  cols[1][0],  cols[1][1],
1239             cols[i3][0], cols[i3][1], cols[i4][0], cols[i4][1],
1240             cols[i5][0], cols[i5][1]);
1241}
1242
1243//==========================================================================
1244
1245// Sigma3qq2qqgSame class.
1246// Cross section for q q' -> q q' g, q == q'.
1247
1248//--------------------------------------------------------------------------
1249
1250// Evaluate |M|^2 - no incoming flavour dependence
1251
1252void Sigma3qq2qqgSame::sigmaKin() {
1253  // q1(p+) q2(p-) -> q1(q+) q2(q-) g(k)
1254
1255  // Incoming four-vectors
1256  pCM[0] = Vec4( 0., 0.,  0.5 * mH, 0.5 * mH);
1257  pCM[1] = Vec4( 0., 0., -0.5 * mH, 0.5 * mH);
1258  // Pick/map a final state configuration
1259  pickFinal();
1260  mapFinal();
1261
1262  // |M|^2
1263  // Extra factor (3) from picking final state configuration
1264  // (original answer already has a factor 2 from identical
1265  // quarks in the final state)
1266  sigma = 3. * m2Calc();
1267
1268}
1269
1270//--------------------------------------------------------------------------
1271
1272// |M|^2
1273
1274inline double Sigma3qq2qqgSame::m2Calc() {
1275
1276  // Four-products
1277  s  = (pCM[0] + pCM[1]).m2Calc();
1278  t  = (pCM[0] - pCM[2]).m2Calc();
1279  u  = (pCM[0] - pCM[3]).m2Calc();
1280  sp = (pCM[2] + pCM[3]).m2Calc();
1281  tp = (pCM[1] - pCM[3]).m2Calc();
1282  up = (pCM[1] - pCM[2]).m2Calc();
1283
1284  // |M|^2
1285  ssp  = s * sp;
1286  ttp  = t * tp;
1287  uup  = u * up;
1288  s_sp = s + sp;
1289  t_tp = t + tp;
1290  u_up = u + up;
1291
1292  double den1 = (pCM[0] * pCM[4]) * (pCM[1] * pCM[4]) *
1293                (pCM[2] * pCM[4]) * (pCM[3] * pCM[4]);
1294
1295  double fac1 = s * (t * u + tp * up) + sp * (t * up + tp * u);
1296  double fac2 = ssp - ttp - uup;
1297  double fac3 = 2. * (ttp * u_up + uup * t_tp);
1298
1299  double num1 = u_up * (ssp + ttp - uup) + fac1;
1300  double num2 = s_sp * fac2 + fac3;
1301  double num3 = (s * s + sp * sp + u * u + up * up) / (t * tp);
1302
1303  double num4 = t_tp * (ssp - ttp + uup) + fac1;
1304  double num5 = (s * s + sp * sp + t * t + tp * tp) / (u * up);
1305
1306  double num6 = s_sp * fac2 - fac3 - 2. * fac1;
1307  double num7 = (s * s + sp * sp) * fac2;
1308  double den7 = (ttp * uup);
1309 
1310  // C1 = (N^2 - 1)^2 / 4N^3 = 16. / 27.
1311  // C2 = (N^2 - 1)   / 4N^3 =  2. / 27.
1312  // C3 = (N^4 - 1)   / 8N^4 = 10. / 81.
1313  // C4 = (N^2 - 1)^2 / 8N^4 =  8. / 81.
1314  return (1. / 8.) * pow3(4. * M_PI * alpS) *
1315         ( ( (16. / 27.) * num1 - (2. / 27.) * num2 ) * num3 +
1316         ( (16. / 27.) * num4 - (2. / 27.) * num2 ) * num5 +
1317         ( (10. / 81.) * num2 + (8. / 81.) * num6 ) *
1318         ( num7 / den7 ) ) / den1;
1319
1320}
1321
1322//--------------------------------------------------------------------------
1323
1324// Evaluate |M|^2 - incoming flavour dependence
1325
1326double Sigma3qq2qqgSame::sigmaHat() {
1327  // q q / qbar qbar incoming states only
1328  if (id1 != id2) return 0.;
1329  return sigma;
1330}
1331
1332//--------------------------------------------------------------------------
1333
1334// Select identity, colour and anticolour.
1335
1336void Sigma3qq2qqgSame::setIdColAcol(){
1337
1338  // Need to know where the gluon was mapped (pCM[4])
1339  int gIdx = 0;
1340  switch (config) {
1341  case 3: case 5: gIdx = 0; break;
1342  case 1: case 4: gIdx = 1; break;
1343  case 0: case 2: gIdx = 2; break;
1344  }
1345
1346  // Outgoing flavours
1347  int idTmp[3] = { id1, id1, id1 };
1348  idTmp[gIdx]  = 21;
1349  setId(id1, id2, idTmp[0], idTmp[1], idTmp[2]);
1350
1351  // Temporary solution; start with q q -> q q g
1352  setColAcol(1, 0, 2, 0, 1, 0, 3, 0, 2, 3);
1353  // Map gluon
1354  swap( colSave[5],  colSave[gIdx + 3]);
1355  swap(acolSave[5], acolSave[gIdx + 3]);
1356  // Swap if qbar qbar incoming
1357  if (id1 < 0) swapColAcol();
1358 
1359}
1360
1361//--------------------------------------------------------------------------
1362
1363// Map a final state configuration
1364inline void Sigma3qq2qqgSame::mapFinal() {
1365  switch (config) {
1366  case 0: pCM[2] = p3cm; pCM[3] = p4cm; pCM[4] = p5cm; break;
1367  case 1: pCM[2] = p3cm; pCM[3] = p5cm; pCM[4] = p4cm; break;
1368  case 2: pCM[2] = p4cm; pCM[3] = p3cm; pCM[4] = p5cm; break;
1369  case 3: pCM[2] = p4cm; pCM[3] = p5cm; pCM[4] = p3cm; break;
1370  case 4: pCM[2] = p5cm; pCM[3] = p3cm; pCM[4] = p4cm; break;
1371  case 5: pCM[2] = p5cm; pCM[3] = p4cm; pCM[4] = p3cm; break;
1372  }
1373}
1374
1375//==========================================================================
1376
1377// Sigma3qqbar2qqbargSame class.
1378// Cross section for q qbar -> q qbar g
1379// Crossed relation from q(bar) q(bar) -> q(bar) q(bar) g:
1380//   q1(p+) q2(p-) -> q1(q+) q2(q-) g(k)
1381//--------------------------------------------------------------------------
1382
1383// Evaluate |M|^2 - no incoming flavour dependence
1384
1385void Sigma3qqbar2qqbargSame::sigmaKin() {
1386
1387  // Incoming four-vectors
1388  pCM[0] = Vec4( 0., 0.,  0.5 * mH, 0.5 * mH);
1389  pCM[1] = Vec4( 0., 0., -0.5 * mH, 0.5 * mH);
1390
1391  // Pick and map a final state configuration
1392  pickFinal();
1393  mapFinal();
1394
1395  // Crossing
1396  swap(pCM[1], pCM[3]);
1397  pCM[1] = -pCM[1];
1398  pCM[3] = -pCM[3];
1399
1400  // |M|^2
1401  // Extra factor of (6) from picking a final state configuration
1402  sigma = 6. * m2Calc();
1403
1404}
1405
1406//--------------------------------------------------------------------------
1407
1408// Select identity, colour and anticolour.
1409
1410void Sigma3qqbar2qqbargSame::setIdColAcol(){
1411  // Outgoing flavours; easiest to map by hand
1412  switch (config) {
1413  case 0: id3 = id1; id4 = id2; id5 = 21;  break;
1414  case 1: id3 = id1; id4 = 21;  id5 = id2; break;
1415  case 2: id3 = id2; id4 = id1; id5 = 21;  break;
1416  case 3: id3 = 21;  id4 = id1; id5 = id2; break;
1417  case 4: id3 = id2; id4 = 21;  id5 = id1; break;
1418  case 5: id3 = 21;  id4 = id2; id5 = id1; break;
1419  }
1420  setId(id1, id2, id3, id4, id5);
1421
1422  // Temporary solution; start with q qbar -> q qbar g
1423  int cols[5][2];
1424  cols[0][0] = 1; cols[0][1] = 0;
1425  cols[1][0] = 0; cols[1][1] = 2;
1426  cols[2][0] = 1; cols[2][1] = 0;
1427  cols[3][0] = 0; cols[3][1] = 3;
1428  cols[4][0] = 3; cols[4][1] = 2;
1429  // Map final state
1430  int i3 = 0, i4 = 0, i5 = 0;
1431  switch (config) {
1432  case 0: i3 = 2; i4 = 3; i5 = 4; break;
1433  case 1: i3 = 2; i4 = 4; i5 = 3; break;
1434  case 2: i3 = 3; i4 = 2; i5 = 4; break;
1435  case 3: i3 = 4; i4 = 2; i5 = 3; break;
1436  case 4: i3 = 3; i4 = 4; i5 = 2; break;
1437  case 5: i3 = 4; i4 = 3; i5 = 2; break;
1438  }
1439  setColAcol(cols[0][0],  cols[0][1],  cols[1][0],  cols[1][1],
1440             cols[i3][0], cols[i3][1], cols[i4][0], cols[i4][1],
1441             cols[i5][0], cols[i5][1]);
1442  // Swap for qbar q incoming
1443  if (id1 < 0) swapColAcol();
1444}
1445
1446//==========================================================================
1447
1448// Sigma3qg2qqqbarSame class.
1449// Cross section for q g -> q q qbar.
1450// Crossed relation from q(bar) q(bar) -> q(bar) q(bar) g:
1451//   q1(p+) q1(p-) -> q1(q+) q1(q-) g(k)
1452
1453//--------------------------------------------------------------------------
1454
1455// Evaluate |M|^2 - no incoming flavour dependence
1456
1457void Sigma3qg2qqqbarSame::sigmaKin() {
1458
1459  // Pick a final state configuration
1460  pickFinal();
1461
1462  // gq and qg incoming
1463  for (int i = 0; i < 2; i++) {
1464
1465    // Map incoming four-vectors
1466    pCM[0] = Vec4( 0., 0.,  0.5 * mH, 0.5 * mH);
1467    pCM[1] = Vec4( 0., 0., -0.5 * mH, 0.5 * mH);
1468    mapFinal();
1469
1470    // Crossing (note extra -ve sign in total sigma)
1471    swap(pCM[i], pCM[4]);
1472    pCM[i] = -pCM[i];
1473    pCM[4] = -pCM[4];
1474
1475    // |M|^2
1476    // XXX - Extra factor of (3) from picking a final state configuration???
1477    // Extra factor of (3 / 8) as averaging over incoming gluon
1478    sigma[i] = -3. * (3. / 8.) * m2Calc();
1479
1480  }
1481
1482}
1483
1484//--------------------------------------------------------------------------
1485
1486// Evaluate |M|^2 - incoming flavour dependence
1487
1488double Sigma3qg2qqqbarSame::sigmaHat() {
1489  // gq or qg incoming
1490  return (id1 == 21) ? sigma[0] : sigma[1];
1491}
1492
1493//--------------------------------------------------------------------------
1494
1495// Select identity, colour and anticolour.
1496
1497void Sigma3qg2qqqbarSame::setIdColAcol(){
1498
1499  // Pick outgoing flavour configuration
1500  int idIn = (id1 == 21) ? id2 : id1;
1501
1502  // Outgoing flavours; easiest just to map by hand
1503  switch (config) {
1504  case 0: id3 =  idIn; id4 =  idIn;   id5 = -idIn; break;
1505  case 1: id3 =  idIn; id4 = -idIn;   id5 =  idIn; break;
1506  case 2: id3 =  idIn; id4 =  idIn;   id5 = -idIn; break;
1507  case 3: id3 = -idIn; id4 =  idIn;   id5 =  idIn; break;
1508  case 4: id3 =  idIn; id4 = -idIn;   id5 =  idIn; break;
1509  case 5: id3 = -idIn; id4 =  idIn;   id5 =  idIn; break;
1510  }
1511  setId(id1, id2, id3, id4, id5);
1512
1513  // Temporary solution; start with either
1514  // g q1    -> q1    q2 qbar2
1515  // g qbar1 -> qbar1 qbar2 q2
1516  int cols[5][2];
1517  cols[0][0] = 1; cols[0][1] = 2;
1518  if (idIn > 0) {
1519    cols[1][0] = 3; cols[1][1] = 0;
1520    cols[2][0] = 1; cols[2][1] = 0;
1521    cols[3][0] = 3; cols[3][1] = 0;
1522    cols[4][0] = 0; cols[4][1] = 2;
1523  } else {
1524    cols[1][0] = 0; cols[1][1] = 3;
1525    cols[2][0] = 0; cols[2][1] = 2;
1526    cols[3][0] = 0; cols[3][1] = 3;
1527    cols[4][0] = 1; cols[4][1] = 0;
1528  }
1529  // Swap incoming if q/qbar g instead
1530  if (id2 == 21) {
1531    swap(cols[0][0], cols[1][0]);
1532    swap(cols[0][1], cols[1][1]);
1533  }
1534  // Map final state
1535  int i3 = 0, i4 = 0, i5 = 0;
1536  switch (config) {
1537  case 0: i3 = 2; i4 = 3; i5 = 4; break;
1538  case 1: i3 = 2; i4 = 4; i5 = 3; break;
1539  case 2: i3 = 3; i4 = 2; i5 = 4; break;
1540  case 3: i3 = 4; i4 = 2; i5 = 3; break;
1541  case 4: i3 = 3; i4 = 4; i5 = 2; break;
1542  case 5: i3 = 4; i4 = 3; i5 = 2; break;
1543  }
1544  setColAcol(cols[0][0],  cols[0][1],  cols[1][0],  cols[1][1],
1545             cols[i3][0], cols[i3][1], cols[i4][0], cols[i4][1],
1546             cols[i5][0], cols[i5][1]);
1547}
1548
1549//==========================================================================
1550
1551} // end namespace Pythia8
Note: See TracBrowser for help on using the repository browser.