1
##############################################################################
3
# Copyright (c) 2010 The MadGraph5_aMC@NLO Development team and Contributors
5
# This file is a part of the MadGraph5_aMC@NLO project, an application which
6
# automatically generates Feynman diagrams and matrix elements for arbitrary
7
# high-energy processes in the Standard Model and beyond.
9
# It is subject to the MadGraph5_aMC@NLO license which should accompany this
12
# For more information, visit madgraph.phys.ucl.ac.be and amcatnlo.web.cern.ch
14
################################################################################
15
from __future__ import absolute_import
16
from __future__ import print_function
18
from six.moves import zip
19
""" Basic test of the command interface """
23
import madgraph.interface.master_interface as mgcmd
24
import madgraph.interface.extended_cmd as ext_cmd
25
import madgraph.interface.amcatnlo_interface as amcatnlocmd
27
import madgraph.fks.fks_helas_objects as fks_helas
29
import madgraph.iolibs.save_load_object as save_load_object
32
root_path = os.path.split(os.path.dirname(os.path.realpath( __file__ )))[0]
33
root_path = os.path.dirname(root_path)
34
# root_path is ./tests
37
class TestAMCatNLOEW(unittest.TestCase):
38
""" a suite of extra tests for the ew stuff """
41
self.interface = mgcmd.MasterCmd()
43
def test_generate_fks_ew(self):
44
"""check that the generate command works as expected.
45
In particular the correct number of born diagrams, real-emission processes
46
and diagrams is checked"""
48
'u u~ > d d~ QED^2=0 QCD^2=4 [real=QCD]',
49
'u u~ > d d~ QED^2=0 QCD^2=4 [real=QED]',
50
'u u~ > d d~ QED^2=0 QCD^2=4 [real=QED QCD]',
51
'u u~ > d d~ QCD^2=4 QED^2=4 [real=QCD]',
52
'u u~ > d d~ QCD^2=4 QED^2=4 [real=QED]',
53
'u u~ > d d~ QCD^2=4 QED^2=4 [real=QED QCD]']
55
# exp[ected splitting types
56
split_type_list = [['QCD'],
63
# expected born_orders
64
born_orders_list = [{'QED':0, 'QCD':4},
71
# perturbation couplings (always set to [QED, QCD]
72
pert_couplings_list = 9*[['QCD','QED']]
74
# expected squared_orders (should take into
75
# account the perturbation
76
squared_orders_list = [{'QED':0, 'QCD':6},
83
# number of expected born diagrams
84
# 1 QCD diagram and 3 EW ones
85
nborndiag_list = [1, 4, 4, 4, 4, 4]
87
# number of expected real emission processes
88
# for QED perturbations also the gluon emissions have to be generated,
89
# as their alpha x alpha_s^2 contribution has to be included
90
nrealproc_list = [3, 6, 6, 6, 6, 6]
92
# number of expected real emission diagrams
93
# u u~ > d d~ g has 5 with QED^2=0, 17 with QED^2=4
94
# u u~ > d d~ a has 4 with QED^2=2, 17 with QED^2=6
96
# for e.g. 'u u~ > d d~ QED^2=0 QCD^2=2 [real=QED]'
97
# the real emissions are ordered as follows:
98
# u u~ > d d~ a [ QED ] QED^2=4 QCD^2=8
99
# a u~ > d d~ u~ [ QED ] QED^2=4 QCD^2=8
100
# u u~ > d d~ g [ QED ] QED^2=4 QCD^2=8
101
# g u~ > d d~ u~ [ QED ] QED^2=4 QCD^2=8
102
# u a > d d~ u [ QED ] QED^2=4 QCD^2=8
103
# u g > d u d~ [ QED ] QED^2=4 QCD^2=8
104
nrealdiags_list = [[5, 5, 5],
105
[4, 4, 17, 17, 4, 17],
106
[4, 4, 17, 17, 4, 17],
107
[17, 17, 17, 17, 17, 17],
108
[17, 17, 17, 17, 17, 17],
109
[17, 17, 17, 17, 17, 17]]
111
for cmd, born_orders, squared_orders, pert_couplings, nborndiag, nrealproc, nrealdiags, split in \
112
zip(cmd_list, born_orders_list, squared_orders_list, pert_couplings_list, nborndiag_list,
113
nrealproc_list, nrealdiags_list, split_type_list):
114
self.interface.do_generate(cmd)
116
fksprocess = self.interface._fks_multi_proc['born_processes'][0]
118
# check that the extra_cnt_amp_list is empty
119
self.assertEqual(0, len(fksprocess.extra_cnt_amp_list))
121
self.assertEqual(born_orders, fksprocess.born_amp['process']['born_sq_orders'])
122
self.assertEqual(squared_orders, fksprocess.born_amp['process']['squared_orders'])
123
self.assertEqual(sorted(pert_couplings), sorted(fksprocess.born_amp['process']['perturbation_couplings']))
125
self.assertEqual(len(fksprocess.born_amp['diagrams']), nborndiag)
126
self.assertEqual(len(fksprocess.real_amps), nrealproc)
127
for amp, n in zip(fksprocess.real_amps, nrealdiags):
128
# check that the fks_j_from i have also been set
129
self.assertNotEqual(amp.fks_j_from_i, {})
130
self.assertEqual(n, len(amp.amplitude['diagrams']))
131
# and that no extra counterterm is needed
132
for info in amp.fks_infos:
133
self.assertEqual(info['extra_cnt_index'], -1)
134
self.assertEqual(len(info['underlying_born']), 1)
135
self.assertEqual(len(info['splitting_type']), 1)
138
def test_generate_fks_ew_noorders(self):
139
"""check that the generate command works as expected when no (or just some)
143
'u u~ > d d~ QED^2=0 QCD^2=4 [real=QED]',
144
'u u~ > d d~ QCD^2=4 [real=QED]',
145
'u u~ > d d~ [real=QED]',
147
'u u~ > d d~ QED^2=0 QCD^2=4 [real=QED QCD]',
148
'u u~ > d d~ QCD^2=4 [real=QED QCD]',
149
'u u~ > d d~ [real=QED QCD]',
151
'u u~ > d d~ QED^2=0 QCD^2=4 [real=QCD]',
152
'u u~ > d d~ QCD^2=4 [real=QCD]',
153
'u u~ > d d~ [real=QCD]']
155
# expected born_orders
156
born_orders_list = 9*[{'QED':0, 'QCD':4}]
158
# perturbation couplings (always set to [QED, QCD]
159
pert_couplings_list = 9*[['QCD','QED']]
161
# expected squared_orders (should take into
162
# account the perturbation
163
squared_orders_list = 3*[{'QED':2, 'QCD':4}] + \
164
3*[{'QED':2, 'QCD':6}] + \
165
3*[{'QED':0, 'QCD':6}]
167
# number of expected born diagrams
168
# 1 QCD diagram and 3 EW ones
169
nborndiag_list = [4, 4, 4, 4, 4, 4, 1, 1, 1]
171
# number of expected real emission processes
172
# for QED perturbations also the gluon emissions have to be generated,
173
# as their alpha x alpha_s^2 contribution has to be included
174
nrealproc_list = [6, 6, 6, 6, 6, 6, 3, 3, 3]
176
# number of expected real emission diagrams
177
# u u~ > d d~ g has 5 with QED^2=0, 17 with QED^2=4
178
# u u~ > d d~ a has 4 with QED^2=2, 17 with QED^2=6
180
# for e.g. 'u u~ > d d~ QED^2=0 QCD^2=4 [real=QED]'
181
# the real emissions are ordered as follows:
182
# u u~ > d d~ a [ QED ] QED^2=4 QCD^2=8
183
# a u~ > d d~ u~ [ QED ] QED^2=4 QCD^2=8
184
# u u~ > d d~ g [ QED ] QED^2=4 QCD^2=8
185
# g u~ > d d~ u~ [ QED ] QED^2=4 QCD^2=8
186
# u a > d d~ u [ QED ] QED^2=4 QCD^2=8
187
# u g > d u d~ [ QED ] QED^2=4 QCD^2=8
188
nrealdiags_list = 3*[[4, 4, 17, 17, 4, 17]] + \
189
3*[[4, 4, 17, 17, 4, 17]] + \
192
for cmd, born_orders, squared_orders, pert_couplings, nborndiag, nrealproc, nrealdiags in \
193
zip(cmd_list, born_orders_list, squared_orders_list, pert_couplings_list, nborndiag_list,
194
nrealproc_list, nrealdiags_list):
195
self.interface.do_generate(cmd)
197
fksprocess = self.interface._fks_multi_proc['born_processes'][0]
199
# no orders should be specified, only squared orders
200
self.assertEqual(fksprocess.born_amp['process']['orders'], {})
202
# check that the extra_cnt_amp_list is empty
203
self.assertEqual(0, len(fksprocess.extra_cnt_amp_list))
205
self.assertEqual(born_orders, fksprocess.born_amp['process']['born_sq_orders'])
206
self.assertEqual(squared_orders, fksprocess.born_amp['process']['squared_orders'])
207
self.assertEqual(sorted(pert_couplings), sorted(fksprocess.born_amp['process']['perturbation_couplings']))
209
self.assertEqual(len(fksprocess.born_amp['diagrams']), nborndiag)
210
self.assertEqual(len(fksprocess.real_amps), nrealproc)
211
for amp, n in zip(fksprocess.real_amps, nrealdiags):
212
# check that the fks_j_from i have also been set
213
self.assertNotEqual(amp.fks_j_from_i, {})
214
self.assertEqual(n, len(amp.amplitude['diagrams']))
215
# and that no extra counterterm is needed
216
for info in amp.fks_infos:
217
self.assertEqual(info['extra_cnt_index'], -1)
218
self.assertEqual(len(info['underlying_born']), 1)
219
self.assertEqual(len(info['splitting_type']), 1)
223
def test_generate_fks_ew_extra_cnts_ttx_full(self):
224
"""check that the generate command works as expected.
225
for processes which feature g/a > qqbar splitting.
226
Check if the extra countertersm are found when needed"""
228
self.interface.do_set('include_lepton_initiated_processes True')
229
self.interface.do_define('p p a')
230
self.interface.do_generate('p p > t t~ QED^2=4 QCD^2=4 [real=QCD QED]')
231
quarks = [-1,-2,-3,-4,1,2,3,4]
233
#there should be 12 processes: 4 qqbar + 4qbarq + gg + ga + ag + aa
234
self.assertEqual(len(self.interface._fks_multi_proc['born_processes']),12 )
235
for proc in self.interface._fks_multi_proc['born_processes']:
236
init_id = [l['id'] for l in proc.born_amp['process']['legs'] if not l['state']]
237
# gg initial state, 2 extra cnts
238
if init_id == [21, 21]:
239
self.assertEqual(len(proc.extra_cnt_amp_list), 2)
240
# 18 real emission MEs
241
self.assertEqual(len(proc.real_amps), 18)
242
# 22 real FKS configurations
243
self.assertEqual(len(sum([real.fks_infos for real in proc.real_amps], [])), 22)
244
for real in proc.real_amps:
245
init_real_id = real.pdgs[:2]
246
if any([idd in quarks for idd in init_real_id]):
247
self.assertNotEqual(real.fks_infos[0]['extra_cnt_index'], -1)
249
self.assertEqual(real.fks_infos[0]['extra_cnt_index'], -1)
250
# ag initial state, 1 extra cnt
251
elif init_id == [21, 22] or init_id == [22, 21]:
252
self.assertEqual(len(proc.extra_cnt_amp_list), 1)
253
# 14 real emission MEs (add mu/e leptons, photon splitting into quarks
254
# must not be incuded here)
255
self.assertEqual(len(proc.real_amps), 14)
256
# 17 real FKS configurations
257
self.assertEqual(len(sum([real.fks_infos for real in proc.real_amps], [])), 17)
258
for real in proc.real_amps:
259
init_real_id = real.pdgs[:2]
260
# the gluon has to split in order to need for an extra cnt
261
if any([idd in quarks for idd in init_real_id]) and 22 in init_real_id:
262
self.assertNotEqual(real.fks_infos[0]['extra_cnt_index'], -1)
264
self.assertEqual(real.fks_infos[0]['extra_cnt_index'], -1)
267
elif init_id == [22, 22]:
268
self.assertEqual(len(proc.extra_cnt_amp_list), 0)
269
# 14 real emission MEs (add mu/e leptons, photon splitting into quarks
270
# must not be incuded here)
271
self.assertEqual(len(proc.real_amps), 10)
272
for real in proc.real_amps:
273
self.assertEqual(real.fks_infos[0]['extra_cnt_index'], -1)
276
self.assertEqual(len(proc.extra_cnt_amp_list), 0)
277
for real in proc.real_amps:
278
self.assertEqual(real.fks_infos[0]['extra_cnt_index'], -1)
279
# avoid border effects
280
self.interface.do_set('include_lepton_initiated_processes False')
283
def test_generate_fks_ew_extra_cnts_ttx_qed2qcd1(self):
284
"""check that the generate command works as expected.
285
for processes which feature g/a > qqbar splitting.
286
Check if the extra countertersm are found when needed.
287
In this case the extra counterterms/splittings should not be
288
included in the gg since it is only needed for counterterms"""
290
self.interface.do_set('include_lepton_initiated_processes True')
291
self.interface.do_define('p p a')
292
self.interface.do_generate('p p > t t~ QED^2=4 QCD^2=2 [real=QCD QED]')
293
quarks = [-1,-2,-3,-4,1,2,3,4]
295
#there should be 12 processes: 4 qqbar + 4qbarq + gg + ga + ag + aa
296
self.assertEqual(len(self.interface._fks_multi_proc['born_processes']),12 )
297
for proc in self.interface._fks_multi_proc['born_processes']:
298
init_id = [l['id'] for l in proc.born_amp['process']['legs'] if not l['state']]
299
# gg initial state, no extra cnts
300
if init_id == [21, 21]:
301
self.assertEqual(len(proc.extra_cnt_amp_list), 0)
302
# 1 real emission MEs (only extra photon radiation
303
self.assertEqual(len(proc.real_amps), 1)
304
# 2 real FKS configurations
305
self.assertEqual(len(sum([real.fks_infos for real in proc.real_amps], [])), 2)
306
for real in proc.real_amps:
307
self.assertEqual(real.fks_infos[0]['extra_cnt_index'], -1)
308
# ag initial state, 1 extra cnt
309
elif init_id == [21, 22] or init_id == [22, 21]:
310
self.assertEqual(len(proc.extra_cnt_amp_list), 1)
311
# 22 real emission MEs (add mu/e leptons, photon splitting into quarks
312
# MUST be incuded here)
313
self.assertEqual(len(proc.real_amps), 22)
314
# 25 real FKS configurations
315
self.assertEqual(len(sum([real.fks_infos for real in proc.real_amps], [])), 25)
316
for real in proc.real_amps:
317
init_real_id = real.pdgs[:2]
318
# the gluon has to split in order to need for an extra cnt
319
if any([idd in quarks for idd in init_real_id]) and 22 in init_real_id:
320
self.assertNotEqual(real.fks_infos[0]['extra_cnt_index'], -1)
322
self.assertEqual(real.fks_infos[0]['extra_cnt_index'], -1)
325
elif init_id == [22, 22]:
326
self.assertEqual(len(proc.extra_cnt_amp_list), 0)
327
# 14 real emission MEs (add mu/e leptons, photon splitting into quarks
328
# must not be incuded here)
329
self.assertEqual(len(proc.real_amps), 10)
330
for real in proc.real_amps:
331
self.assertEqual(real.fks_infos[0]['extra_cnt_index'], -1)
334
self.assertEqual(len(proc.extra_cnt_amp_list), 0)
335
for real in proc.real_amps:
336
self.assertEqual(real.fks_infos[0]['extra_cnt_index'], -1)
337
# avoid border effects
338
self.interface.do_set('include_lepton_initiated_processes False')
341
# other tests for the extra cnts for dijet
342
# integrate one LO contribution with one kind of correction
343
def test_generate_fks_ew_dijet_qed0qcd2_qcd(self):
344
"""check that the generate command works as expected.
345
for processes which feature g/a > qqbar splitting.
346
Check if the extra countertersm are found when needed.
347
Here we will use a simplified dijet case, u u~ > g/a g/a
348
considering the NLO QCD corrections to the leftmost blob.
349
No extra cnts should be there"""
351
self.interface.do_set('include_lepton_initiated_processes False')
352
self.interface.do_define('jj = g a')
353
self.interface.do_generate('u u~ > jj jj QED^2=0 QCD^2=4 [real=QCD]')
354
quarks = [-1,-2,-3,-4,1,2,3,4]
355
# just one born processes u u~ > g g
356
self.assertEqual(len(self.interface._fks_multi_proc['born_processes']), 1)
357
for proc in self.interface._fks_multi_proc['born_processes']:
358
final_id = [l['id'] for l in proc.born_amp['process']['legs'] if l['state']]
359
self.assertEqual(final_id, [21, 21])
361
# there should never be extra cnts
362
self.assertEqual(len(proc.extra_cnt_amp_list), 0) #( 21, 22)
363
# make sure there are qqbar splittings in the fs
365
for real in proc.real_amps:
366
final_real_id = real.pdgs[2:]
367
# the gluon has to split in order to need for an extra cnt
368
if any([idd in quarks for idd in final_real_id]) and real.fks_infos[0]['ij'] > 2:
370
self.assertEqual(real.fks_infos[0]['extra_cnt_index'], -1)
371
self.assertTrue(foundqq)
374
def test_generate_fks_ew_dijet_qed2qcd0_qed(self):
375
"""check that the generate command works as expected.
376
for processes which feature g/a > qqbar splitting.
377
Check if the extra countertersm are found when needed.
378
Here we will use a simplified dijet case, u u~ > g/a g/a
379
considering the NLO QED corrections to the rightmost blob.
380
No extra cnts should be there"""
382
self.interface.do_set('include_lepton_initiated_processes False')
383
self.interface.do_define('jj = g a')
384
self.interface.do_generate('u u~ > jj jj QED^2=4 QCD^2=0 [real=QED]')
385
quarks = [-1,-2,-3,-4,1,2,3,4]
386
# just one born processes u u~ > a a
387
self.assertEqual(len(self.interface._fks_multi_proc['born_processes']), 1)
388
for proc in self.interface._fks_multi_proc['born_processes']:
389
final_id = [l['id'] for l in proc.born_amp['process']['legs'] if l['state']]
390
self.assertEqual(final_id, [22, 22])
392
# there should never be extra cnts
393
self.assertEqual(len(proc.extra_cnt_amp_list), 0)
394
# make sure there are qqbar splittings in the fs
396
for real in proc.real_amps:
397
final_real_id = real.pdgs[2:]
398
# the gluon has to split in order to need for an extra cnt
399
if any([idd in quarks for idd in final_real_id]) and real.fks_infos[0]['ij'] > 2:
401
self.assertEqual(real.fks_infos[0]['extra_cnt_index'], -1)
402
self.assertTrue(foundqq)
405
def test_generate_fks_ew_dijet_qed0qcd2_qed(self):
406
"""check that the generate command works as expected.
407
for processes which feature g/a > qqbar splitting.
408
Check if the extra countertersm are found when needed.
409
Here we will use a simplified dijet case, u u~ > g/a g/a
410
considering the NLO QED corrections to the leftmost blob,
411
or, equivalently, QCD corrections to the central blob
412
No extra cnts should be there"""
414
self.interface.do_set('include_lepton_initiated_processes False')
415
self.interface.do_define('jj = g a')
416
quarks = [-1,-2,-3,-4,1,2,3,4]
418
for orders in ['QED^2=0 QCD^2=4 [real=QED]', 'QED^2=2 QCD^2=2 [real=QCD]']:
419
self.interface.do_generate('u u~ > jj jj %s' % orders)
420
# two born processes u u~ > g g and g a
421
self.assertEqual(len(self.interface._fks_multi_proc['born_processes']), 2)
422
target_ids = [[21,21], [22,21]]
423
for ids, proc in zip(target_ids, self.interface._fks_multi_proc['born_processes']):
424
final_id = [l['id'] for l in proc.born_amp['process']['legs'] if l['state']]
425
self.assertEqual(ids, final_id)
427
# there should never be extra cnts
428
if final_id == [21, 21]:
429
# there should never be extra cnts
430
self.assertEqual(len(proc.extra_cnt_amp_list), 0)
431
# make sure there are qqbar splittings in the fs
433
for real in proc.real_amps:
434
final_real_id = real.pdgs[2:]
435
# the gluon has to split
436
if any([idd in quarks for idd in final_real_id]) and real.fks_infos[0]['ij'] > 2:
438
self.assertEqual(real.fks_infos[0]['extra_cnt_index'], -1)
439
self.assertTrue(foundqq)
441
elif final_id == [22, 21]:
442
self.assertEqual(len(proc.extra_cnt_amp_list), 0)
443
# make sure there are qqbar splittings in the fs
445
for real in proc.real_amps:
446
# check that real emissions with qqbar splitting has only one fks info
447
if len(real.fks_infos) > 1:
448
self.assertTrue(not any([real.pdgs[ii['i']-1] in quarks for ii in real.fks_infos]))
449
final_real_id = real.pdgs[2:]
450
# the gluon has to split
451
if any([idd in quarks for idd in final_real_id]) and real.fks_infos[0]['ij'] == 4:
453
self.assertEqual(real.fks_infos[0]['extra_cnt_index'], -1)
454
# make sure no qqbar splitting comes from the photon.
455
if real.fks_infos[0]['ij'] == 3:
456
self.assertTrue(not real.pdgs[real.fks_infos[0]['i']-1] in quarks)
457
self.assertTrue(not real.pdgs[real.fks_infos[0]['j']-1] in quarks)
458
self.assertTrue(foundqq)
461
def test_generate_fks_ew_dijet_qed1qcd1_qed(self):
462
"""check that the generate command works as expected.
463
for processes which feature g/a > qqbar splitting.
464
Check if the extra countertersm are found when needed.
465
Here we will use a simplified dijet case, u u~ > g/a g/a
466
considering the NLO QED corrections to the central blob,
467
or, equivalently, QCD corrections to the rightmost blob
468
No extra cnts should be there"""
470
self.interface.do_set('include_lepton_initiated_processes False')
471
self.interface.do_define('jj = g a')
472
quarks = [-1,-2,-3,-4,1,2,3,4]
474
for orders in ['QED^2=2 QCD^2=2 [real=QED]', 'QED^2=4 QCD^2=0 [real=QCD]']:
475
self.interface.do_generate('u u~ > jj jj %s' % orders)
476
# two born processes u u~ > g a and a a
477
self.assertEqual(len(self.interface._fks_multi_proc['born_processes']), 2)
478
target_ids = [[22,21], [22,22]]
479
for ids, proc in zip(target_ids, self.interface._fks_multi_proc['born_processes']):
480
final_id = [l['id'] for l in proc.born_amp['process']['legs'] if l['state']]
481
self.assertEqual(ids, final_id)
483
# there should never be extra cnts
484
if final_id == [22, 21]:
485
# there should never be extra cnts
486
self.assertEqual(len(proc.extra_cnt_amp_list), 0)
487
# make sure there are qqbar splittings in the fs
489
for real in proc.real_amps:
490
final_real_id = real.pdgs[2:]
491
# the gluon has to split
492
if any([idd in quarks for idd in final_real_id]) and real.fks_infos[0]['ij'] > 2:
494
self.assertEqual(real.fks_infos[0]['extra_cnt_index'], -1)
495
self.assertTrue(foundqq)
497
elif final_id == [22, 22]:
498
self.assertEqual(len(proc.extra_cnt_amp_list), 0)
499
# make sure there are qqbar splittings in the fs
501
for real in proc.real_amps:
502
# check that real emissions with qqbar splitting has only one fks info
503
if len(real.fks_infos) > 1:
504
self.assertTrue(not any([real.pdgs[ii['i']-1] in quarks for ii in real.fks_infos]))
505
self.assertEqual(real.fks_infos[0]['extra_cnt_index'], -1)
506
# make sure no qqbar splitting comes from the photon.
507
if real.fks_infos[0]['ij'] > 2:
508
self.assertTrue(not real.pdgs[real.fks_infos[0]['i']-1] in quarks)
509
self.assertTrue(not real.pdgs[real.fks_infos[0]['j']-1] in quarks)
512
# integrate one LO contribution with both corrections
513
def test_generate_fks_ew_dijet_qed0qcd2_qedqcd(self):
514
"""check that the generate command works as expected.
515
for processes which feature g/a > qqbar splitting.
516
Check if the extra countertersm are found when needed.
517
Here we will use a simplified dijet case, u u~ > g/a g/a
518
considering the NLO QED and QCD corrections to the leftmost blob
519
No extra cnts should be there"""
521
self.interface.do_set('include_lepton_initiated_processes False')
522
self.interface.do_define('jj = g a')
523
quarks = [-1,-2,-3,-4,1,2,3,4]
525
self.interface.do_generate('u u~ > jj jj QED^2=0 QCD^2=4 [real=QED QCD]')
526
# two born processes u u~ > g g and g a
527
self.assertEqual(len(self.interface._fks_multi_proc['born_processes']), 2)
528
target_ids = [[21,21], [22,21]]
529
for ids, proc in zip(target_ids, self.interface._fks_multi_proc['born_processes']):
530
final_id = [l['id'] for l in proc.born_amp['process']['legs'] if l['state']]
531
self.assertEqual(ids, final_id)
533
# there should never be extra cnts
534
if final_id == [21, 21]:
535
# there should never be extra cnts
536
self.assertEqual(len(proc.extra_cnt_amp_list), 0)
537
# make sure there are qqbar splittings in the fs
539
for real in proc.real_amps:
540
final_real_id = real.pdgs[2:]
541
# the gluon has to split
542
if any([idd in quarks for idd in final_real_id]) and real.fks_infos[0]['ij'] > 2:
544
self.assertEqual(real.fks_infos[0]['extra_cnt_index'], -1)
545
self.assertTrue(foundqq)
547
elif final_id == [22, 21]:
548
self.assertEqual(len(proc.extra_cnt_amp_list), 0)
549
# make sure there are qqbar splittings in the fs
551
for real in proc.real_amps:
552
# check that real emissions with qqbar splitting has only one fks info
553
if len(real.fks_infos) > 1:
554
self.assertTrue(not any([real.pdgs[ii['i']-1] in quarks for ii in real.fks_infos]))
555
final_real_id = real.pdgs[2:]
556
# the gluon has to split
557
if any([idd in quarks for idd in final_real_id]) and real.fks_infos[0]['ij'] == 4:
559
self.assertEqual(real.fks_infos[0]['extra_cnt_index'], -1)
560
# make sure no qqbar splitting comes from the photon.
561
if real.fks_infos[0]['ij'] == 3:
562
self.assertTrue(not real.pdgs[real.fks_infos[0]['i']-1] in quarks)
563
self.assertTrue(not real.pdgs[real.fks_infos[0]['j']-1] in quarks)
564
self.assertTrue(foundqq)
567
def test_generate_fks_ew_dijet_qed1qcd1_qedqcd(self):
568
"""check that the generate command works as expected.
569
for processes which feature g/a > qqbar splitting.
570
Check if the extra countertersm are found when needed.
571
Here we will use a simplified dijet case, u u~ > g/a g/a
572
considering the NLO QED and QCD corrections to the central blob
573
No extra cnts should be there"""
575
self.interface.do_set('include_lepton_initiated_processes False')
576
self.interface.do_define('jj = g a')
577
quarks = [-1,-2,-3,-4,1,2,3,4]
579
self.interface.do_generate('u u~ > jj jj QED^2=2 QCD^2=2 [real=QED QCD]')
580
# all three born processes u u~ > g g, g a and a a
581
self.assertEqual(len(self.interface._fks_multi_proc['born_processes']), 3)
582
target_ids = [[21,21], [22,21], [22,22]]
583
for ids, proc in zip(target_ids, self.interface._fks_multi_proc['born_processes']):
584
final_id = [l['id'] for l in proc.born_amp['process']['legs'] if l['state']]
585
self.assertEqual(ids, final_id)
587
# there should never be extra cnts
588
# for g g and a a no qqbar splitting should be there
589
if final_id in [[21, 21], [22, 22]]:
590
# there should never be extra cnts
591
self.assertEqual(len(proc.extra_cnt_amp_list), 0)
592
# make sure there are no qqbar splittings in the fs
594
for real in proc.real_amps:
595
final_real_id = real.pdgs[2:]
596
# the gluon has to split
597
if any([idd in quarks for idd in final_real_id]) and real.fks_infos[0]['ij'] > 2:
599
self.assertEqual(real.fks_infos[0]['extra_cnt_index'], -1)
600
self.assertTrue(not foundqq)
602
elif final_id == [22, 21]:
603
self.assertEqual(len(proc.extra_cnt_amp_list), 0)
604
# make sure there are qqbar splittings in the fs
607
for real in proc.real_amps:
608
# check that real emissions with qqbar splitting has only one fks info
609
if len(real.fks_infos) > 1:
610
self.assertTrue(not any([real.pdgs[ii['i']-1] in quarks for ii in real.fks_infos]))
611
final_real_id = real.pdgs[2:]
612
# the gluon has to split
613
if any([idd in quarks for idd in final_real_id]) and real.fks_infos[0]['ij'] == 3:
615
if any([idd in quarks for idd in final_real_id]) and real.fks_infos[0]['ij'] == 4:
617
self.assertEqual(real.fks_infos[0]['extra_cnt_index'], -1)
618
# make sure qqbar splittings come from both the photon and the gluon
619
self.assertTrue(foundqqg)
620
self.assertTrue(foundqqa)
623
def test_generate_fks_ew_dijet_qed2qcd0_qedqcd(self):
624
"""check that the generate command works as expected.
625
for processes which feature g/a > qqbar splitting.
626
Check if the extra countertersm are found when needed.
627
Here we will use a simplified dijet case, u u~ > g/a g/a
628
considering the NLO QED and QCD corrections to the rightmost blob,
629
No extra cnts should be there"""
631
self.interface.do_set('include_lepton_initiated_processes False')
632
self.interface.do_define('jj = g a')
633
quarks = [-1,-2,-3,-4,1,2,3,4]
635
self.interface.do_generate('u u~ > jj jj QED^2=4 QCD^2=0 [real=QCD QED]')
636
# two born processes u u~ > g a and a a
637
self.assertEqual(len(self.interface._fks_multi_proc['born_processes']), 2)
638
target_ids = [[22,21], [22,22]]
639
for ids, proc in zip(target_ids, self.interface._fks_multi_proc['born_processes']):
640
final_id = [l['id'] for l in proc.born_amp['process']['legs'] if l['state']]
641
self.assertEqual(ids, final_id)
643
# there should never be extra cnts
644
if final_id == [22, 21]:
645
# there should never be extra cnts
646
self.assertEqual(len(proc.extra_cnt_amp_list), 0)
647
# make sure there are qqbar splittings in the fs
649
for real in proc.real_amps:
650
final_real_id = real.pdgs[2:]
651
# the gluon has to split
652
if any([idd in quarks for idd in final_real_id]) and real.fks_infos[0]['ij'] > 2:
654
self.assertEqual(real.fks_infos[0]['extra_cnt_index'], -1)
655
# make sure no qqbar splitting comes from the gluon.
656
if real.fks_infos[0]['ij'] == 4:
657
self.assertTrue(not real.pdgs[real.fks_infos[0]['i']-1] in quarks)
658
self.assertTrue(not real.pdgs[real.fks_infos[0]['j']-1] in quarks)
659
self.assertTrue(foundqq)
661
elif final_id == [22, 22]:
662
self.assertEqual(len(proc.extra_cnt_amp_list), 0)
663
# make sure there are qqbar splittings in the fs
665
for real in proc.real_amps:
666
# check that real emissions with qqbar splitting has only one fks info
667
if len(real.fks_infos) > 1:
668
self.assertTrue(not any([real.pdgs[ii['i']-1] in quarks for ii in real.fks_infos]))
669
self.assertEqual(real.fks_infos[0]['extra_cnt_index'], -1)
672
# integrate two LO contributions together with one kind of correction
673
def test_generate_fks_ew_dijet_qed1qcd2_qcd(self):
674
"""check that the generate command works as expected.
675
for processes which feature g/a > qqbar splitting.
676
Check if the extra countertersm are found when needed.
677
Here we will use a simplified dijet case, u u~ > g/a g/a
678
considering the NLO QCD corrections to the leftmost and central blobs
679
No extra cnts should be there"""
681
self.interface.do_set('include_lepton_initiated_processes False')
682
self.interface.do_define('jj = g a')
683
quarks = [-1,-2,-3,-4,1,2,3,4]
685
self.interface.do_generate('u u~ > jj jj QED^2=2 QCD^2=4 [real=QCD]')
686
# two born processes u u~ > g g and g a
687
self.assertEqual(len(self.interface._fks_multi_proc['born_processes']), 2)
688
target_ids = [[21,21], [22,21]]
689
for ids, proc in zip(target_ids, self.interface._fks_multi_proc['born_processes']):
690
final_id = [l['id'] for l in proc.born_amp['process']['legs'] if l['state']]
691
self.assertEqual(ids, final_id)
693
# there should never be extra cnts
694
if final_id == [21, 21]:
695
# there should never be extra cnts
696
self.assertEqual(len(proc.extra_cnt_amp_list), 0)
697
# make sure there are qqbar splittings in the fs
699
for real in proc.real_amps:
700
final_real_id = real.pdgs[2:]
701
# the gluon has to split
702
if any([idd in quarks for idd in final_real_id]) and real.fks_infos[0]['ij'] > 2:
704
self.assertEqual(real.fks_infos[0]['extra_cnt_index'], -1)
705
self.assertTrue(foundqq)
707
elif final_id == [22, 21]:
708
self.assertEqual(len(proc.extra_cnt_amp_list), 0)
709
# make sure there are qqbar splittings in the fs
711
for real in proc.real_amps:
712
# check that real emissions with qqbar splitting has only one fks info
713
if len(real.fks_infos) > 1:
714
self.assertTrue(not any([real.pdgs[ii['i']-1] in quarks for ii in real.fks_infos]))
715
final_real_id = real.pdgs[2:]
716
# the gluon has to split
717
if any([idd in quarks for idd in final_real_id]) and real.fks_infos[0]['ij'] == 4:
719
self.assertEqual(real.fks_infos[0]['extra_cnt_index'], -1)
720
# make sure no qqbar splitting comes from the photon.
721
if real.fks_infos[0]['ij'] == 3:
722
self.assertTrue(not real.pdgs[real.fks_infos[0]['i']-1] in quarks)
723
self.assertTrue(not real.pdgs[real.fks_infos[0]['j']-1] in quarks)
724
self.assertTrue(foundqq)
727
def test_generate_fks_ew_dijet_qed1qcd2_qed(self):
728
"""check that the generate command works as expected.
729
for processes which feature g/a > qqbar splitting.
730
Check if the extra countertersm are found when needed.
731
Here we will use a simplified dijet case, u u~ > g/a g/a
732
considering the NLO QED corrections to the leftmost and central blobs
733
or, equivalently, QCD corrections to the rightmost and central blob
734
No extra cnts should be there"""
736
self.interface.do_set('include_lepton_initiated_processes False')
737
self.interface.do_define('jj = g a')
738
quarks = [-1,-2,-3,-4,1,2,3,4]
740
for orders in ['QED^2=2 QCD^2=4 [real=QED]', 'QED^2=4 QCD^2=2 [real=QCD]']:
741
self.interface.do_generate('u u~ > jj jj %s' % orders)
742
# all three born processes u u~ > g g , g a , aa
743
self.assertEqual(len(self.interface._fks_multi_proc['born_processes']), 3)
744
target_ids = [[21,21], [22,21], [22,22]]
745
for ids, proc in zip(target_ids, self.interface._fks_multi_proc['born_processes']):
746
final_id = [l['id'] for l in proc.born_amp['process']['legs'] if l['state']]
747
self.assertEqual(ids, final_id)
749
# there should never be extra cnts
750
if final_id == [21, 21]:
751
# there should never be extra cnts
752
self.assertEqual(len(proc.extra_cnt_amp_list), 0)
753
# make sure there are no qqbar splittings in the fs
755
for real in proc.real_amps:
756
final_real_id = real.pdgs[2:]
757
# there should not be any g > qq splitting here (it should be inside g a)
758
if any([idd in quarks for idd in final_real_id]) and real.fks_infos[0]['ij'] > 2:
760
self.assertEqual(real.fks_infos[0]['extra_cnt_index'], -1)
761
self.assertTrue(not foundqq)
763
elif final_id == [22, 21]:
764
# there should never be extra cnts
765
self.assertEqual(len(proc.extra_cnt_amp_list), 0)
766
# make sure there are qqbar splittings in the fs
768
for real in proc.real_amps:
769
# check that real emissions with qqbar splitting has only one fks info
770
if len(real.fks_infos) > 1:
771
self.assertTrue(not any([real.pdgs[ii['i']-1] in quarks for ii in real.fks_infos]))
772
final_real_id = real.pdgs[2:]
773
# both the gluon and photon have to split
774
if any([idd in quarks for idd in final_real_id]) and real.fks_infos[0]['ij'] == 3:
776
if any([idd in quarks for idd in final_real_id]) and real.fks_infos[0]['ij'] == 4:
778
self.assertEqual(real.fks_infos[0]['extra_cnt_index'], -1)
779
self.assertTrue(foundqqa)
780
self.assertTrue(foundqqg)
782
elif final_id == [22, 22]:
783
# there should never be extra cnts
784
self.assertEqual(len(proc.extra_cnt_amp_list), 0)
786
for real in proc.real_amps:
787
final_real_id = real.pdgs[2:]
788
# there should not be any g > qq splitting here (it should be inside g a)
789
if any([idd in quarks for idd in final_real_id]) and real.fks_infos[0]['ij'] > 2:
791
self.assertEqual(real.fks_infos[0]['extra_cnt_index'], -1)
792
self.assertTrue(not foundqq)
795
def test_generate_fks_ew_dijet_qed2qcd1_qed(self):
796
"""check that the generate command works as expected.
797
for processes which feature g/a > qqbar splitting.
798
Check if the extra countertersm are found when needed.
799
Here we will use a simplified dijet case, u u~ > g/a g/a
800
considering the NLO QED corrections to the rightmost and central blobs,
801
No extra cnts should be there"""
803
self.interface.do_set('include_lepton_initiated_processes False')
804
self.interface.do_define('jj = g a')
805
quarks = [-1,-2,-3,-4,1,2,3,4]
807
self.interface.do_generate('u u~ > jj jj QED^2=4 QCD^2=2 [real=QED]')
808
# two born processes u u~ > g a and a a
809
self.assertEqual(len(self.interface._fks_multi_proc['born_processes']), 2)
810
target_ids = [[22,21], [22,22]]
811
for ids, proc in zip(target_ids, self.interface._fks_multi_proc['born_processes']):
812
final_id = [l['id'] for l in proc.born_amp['process']['legs'] if l['state']]
813
self.assertEqual(ids, final_id)
815
# there should never be extra cnts
816
if final_id == [22, 21]:
817
# there should never be extra cnts
818
self.assertEqual(len(proc.extra_cnt_amp_list), 0)
819
# make sure there are qqbar splittings in the fs
821
for real in proc.real_amps:
822
final_real_id = real.pdgs[2:]
823
# the gluon has to split
824
if any([idd in quarks for idd in final_real_id]) and real.fks_infos[0]['ij'] > 2:
826
self.assertEqual(real.fks_infos[0]['extra_cnt_index'], -1)
827
# make sure no qqbar splitting comes from the gluon.
828
if real.fks_infos[0]['ij'] == 4:
829
self.assertTrue(not real.pdgs[real.fks_infos[0]['i']-1] in quarks)
830
self.assertTrue(not real.pdgs[real.fks_infos[0]['j']-1] in quarks)
831
self.assertTrue(foundqq)
833
elif final_id == [22, 22]:
834
self.assertEqual(len(proc.extra_cnt_amp_list), 0)
835
# make sure there are qqbar splittings in the fs
837
for real in proc.real_amps:
838
# check that real emissions with qqbar splitting has only one fks info
839
if len(real.fks_infos) > 1:
840
self.assertTrue(not any([real.pdgs[ii['i']-1] in quarks for ii in real.fks_infos]))
841
self.assertEqual(real.fks_infos[0]['extra_cnt_index'], -1)
844
# integrate three LO contributions together with one kind of correction
845
def test_generate_fks_ew_dijet_qed2qcd2_qcd(self):
846
"""check that the generate command works as expected.
847
for processes which feature g/a > qqbar splitting.
848
Check if the extra countertersm are found when needed.
849
Here we will use a simplified dijet case, u u~ > g/a g/a
850
considering the NLO QCD corrections to the three blobs
851
No extra cnts should be there"""
853
self.interface.do_set('include_lepton_initiated_processes False')
854
self.interface.do_define('jj = g a')
855
quarks = [-1,-2,-3,-4,1,2,3,4]
857
self.interface.do_generate('u u~ > jj jj QED^2=4 QCD^2=4 [real=QCD]')
858
self.assertEqual(len(self.interface._fks_multi_proc['born_processes']), 3)
859
target_ids = [[21,21], [22,21], [22,22]]
860
for ids, proc in zip(target_ids, self.interface._fks_multi_proc['born_processes']):
861
final_id = [l['id'] for l in proc.born_amp['process']['legs'] if l['state']]
862
self.assertEqual(ids, final_id)
864
if final_id == [21, 21]:
865
# gg state, should have extra_cnts with g a in the final state
866
self.assertEqual(len(proc.extra_cnt_amp_list), 1) #( 21, 22)
867
# make sure there are qqbar splittings in the fs
869
for real in proc.real_amps:
870
final_real_id = real.pdgs[2:]
871
# the gluon has to split in order to need for an extra cnt
872
if any([idd in quarks for idd in final_real_id]) and real.fks_infos[0]['ij'] > 2:
874
self.assertNotEqual(real.fks_infos[0]['extra_cnt_index'], -1)
876
self.assertEqual(real.fks_infos[0]['extra_cnt_index'], -1)
877
self.assertTrue(foundqq)
879
elif final_id == [22, 21]:
880
# ag state, should not have extra_cnts with a a in the final state
881
#(it should appear at order alpha^3, which is not inlcuded here
882
self.assertEqual(len(proc.extra_cnt_amp_list), 0) #( 21, 22)
883
# make sure there are qqbar splittings in the fs
885
for real in proc.real_amps:
886
# check that real emissions with qqbar splitting has only one fks info
887
if len(real.fks_infos) > 1:
888
self.assertTrue(not any([real.pdgs[ii['i']-1] in quarks for ii in real.fks_infos]))
889
final_real_id = real.pdgs[2:]
890
# the gluon has to split in order to need for an extra cnt
891
if any([idd in quarks for idd in final_real_id]) and real.fks_infos[0]['ij'] == 4:
893
self.assertEqual(real.fks_infos[0]['extra_cnt_index'], -1)
894
# make sure no qqbar splitting comes from the photon.
895
if real.fks_infos[0]['ij'] == 3:
896
self.assertTrue(not real.pdgs[real.fks_infos[0]['i']-1] in quarks)
897
self.assertTrue(not real.pdgs[real.fks_infos[0]['j']-1] in quarks)
898
self.assertTrue(foundqq)
900
elif final_id == [22, 22]:
901
# aa state, should have no extra_cnts
902
self.assertEqual(len(proc.extra_cnt_amp_list), 0) #( 22, 22)
903
for real in proc.real_amps:
904
# check that real emissions with qqbar splitting has only one fks info
905
if len(real.fks_infos) > 1:
906
self.assertTrue(not any([real.pdgs[ii['i']-1] in quarks for ii in real.fks_infos]))
907
final_real_id = real.pdgs[2:]
908
self.assertEqual(real.fks_infos[0]['extra_cnt_index'], -1)
909
# make sure no qqbar splitting comes from final state photons.
910
if real.fks_infos[0]['ij'] in [3, 4]:
911
self.assertTrue(not real.pdgs[real.fks_infos[0]['i']-1] in quarks)
912
self.assertTrue(not real.pdgs[real.fks_infos[0]['j']-1] in quarks)
915
def test_generate_fks_ew_dijet_qed2qcd2_qed(self):
916
"""check that the generate command works as expected.
917
for processes which feature g/a > qqbar splitting.
918
Check if the extra countertersm are found when needed.
919
Here we will use a simplified dijet case, u u~ > g/a g/a
920
considering the NLO QCD corrections to the tree blobs
921
No extra cnts should be there"""
923
self.interface.do_set('include_lepton_initiated_processes False')
924
self.interface.do_define('jj = g a')
925
quarks = [-1,-2,-3,-4,1,2,3,4]
927
self.interface.do_generate('u u~ > jj jj QED^2=4 QCD^2=4 [real=QED]')
928
self.assertEqual(len(self.interface._fks_multi_proc['born_processes']), 3)
929
target_ids = [[21,21], [22,21], [22,22]]
930
for ids, proc in zip(target_ids, self.interface._fks_multi_proc['born_processes']):
931
final_id = [l['id'] for l in proc.born_amp['process']['legs'] if l['state']]
932
self.assertEqual(ids, final_id)
934
if final_id == [22, 22]:
935
# aa state, should have no extra_cnts (it goes into g a)
936
self.assertEqual(len(proc.extra_cnt_amp_list), 0) #( 21, 22)
937
# make sure there are no qqbar splittings in the fs
939
for real in proc.real_amps:
940
final_real_id = real.pdgs[2:]
941
# the gluon has to split in order to need for an extra cnt
942
if any([idd in quarks for idd in final_real_id]) and real.fks_infos[0]['ij'] > 2:
944
self.assertEqual(real.fks_infos[0]['extra_cnt_index'], -1)
945
self.assertTrue(not foundqq)
947
elif final_id == [22, 21]:
948
# ag state, should not have extra_cnts with a a in the final state
949
#(it should appear at order alpha^3, which is not inlcuded here
950
self.assertEqual(len(proc.extra_cnt_amp_list), 1) #( 21, 22)
951
# make sure there are qqbar splittings in the fs
954
for real in proc.real_amps:
955
# check that real emissions with qqbar splitting has only one fks info
956
if len(real.fks_infos) > 1:
957
self.assertTrue(not any([real.pdgs[ii['i']-1] in quarks for ii in real.fks_infos]))
958
final_real_id = real.pdgs[2:]
959
# the gluon has to split in order to need for an extra cnt
960
if any([idd in quarks for idd in final_real_id]) and real.fks_infos[0]['ij'] == 4:
962
self.assertNotEqual(real.fks_infos[0]['extra_cnt_index'], -1)
963
# make sure no qqbar splitting comes from the photon.
964
if real.fks_infos[0]['ij'] == 3:
965
self.assertEqual(real.fks_infos[0]['extra_cnt_index'], -1)
966
if any([idd in quarks for idd in final_real_id]):
968
self.assertTrue(foundqqg)
969
self.assertTrue(foundqqa)
971
elif final_id == [21, 21]:
972
# gg state, should have no extra_cnts
973
self.assertEqual(len(proc.extra_cnt_amp_list), 0)
974
for real in proc.real_amps:
975
# check that real emissions with qqbar splitting has only one fks info
976
if len(real.fks_infos) > 1:
977
self.assertTrue(not any([real.pdgs[ii['i']-1] in quarks for ii in real.fks_infos]))
978
final_real_id = real.pdgs[2:]
979
self.assertEqual(real.fks_infos[0]['extra_cnt_index'], -1)
980
# make sure no qqbar splitting comes from final state photons.
981
if real.fks_infos[0]['ij'] in [3, 4]:
982
self.assertTrue(not real.pdgs[real.fks_infos[0]['i']-1] in quarks)
983
self.assertTrue(not real.pdgs[real.fks_infos[0]['j']-1] in quarks)
986
# integrate all LO and NLO contributions together
987
def test_generate_fks_ew_dijet_qed2qcd2_qedqcd(self):
988
"""check that the generate command works as expected.
989
for processes which feature g/a > qqbar splitting.
990
Check if the extra countertersm are found when needed.
991
Here we will use a simplified dijet case, u u~ > g/a g/a
992
with all born orders and all corrections"""
994
self.interface.do_set('include_lepton_initiated_processes False')
995
self.interface.do_define('jj = g a')
996
quarks = [-1,-2,-3,-4,1,2,3,4]
998
self.interface.do_generate('u u~ > jj jj QED^2=4 QCD^2=4 [real=QCD QED]')
999
# three born processes u u~ > g g ; a g ; a a
1000
self.assertEqual(len(self.interface._fks_multi_proc['born_processes']), 3)
1001
target_ids = [[21,21], [22,21], [22,22]]
1002
for ids, proc in zip(target_ids, self.interface._fks_multi_proc['born_processes']):
1003
final_id = [l['id'] for l in proc.born_amp['process']['legs'] if l['state']]
1004
self.assertEqual(ids, final_id)
1006
if final_id == [21, 21]:
1007
# gg state, should have extra_cnts with g a in the final state
1008
self.assertEqual(len(proc.extra_cnt_amp_list), 1) #( 21, 22)
1009
# make sure there are qqbar splittings in the fs
1011
for real in proc.real_amps:
1012
final_real_id = real.pdgs[2:]
1013
# the gluon has to split in order to need for an extra cnt
1014
if any([idd in quarks for idd in final_real_id]) and real.fks_infos[0]['ij'] > 2:
1016
self.assertNotEqual(real.fks_infos[0]['extra_cnt_index'], -1)
1018
self.assertEqual(real.fks_infos[0]['extra_cnt_index'], -1)
1019
self.assertTrue(foundqq)
1021
elif final_id == [22, 21]:
1022
# ag state, should have extra_cnts with a a in the final state
1023
self.assertEqual(len(proc.extra_cnt_amp_list), 1) #( 21, 22)
1024
# make sure there are qqbar splittings in the fs
1026
for real in proc.real_amps:
1027
# check that real emissions with qqbar splitting has only one fks info
1028
if len(real.fks_infos) > 1:
1029
self.assertTrue(not any([real.pdgs[ii['i']-1] in quarks for ii in real.fks_infos]))
1030
final_real_id = real.pdgs[2:]
1031
# the gluon has to split in order to need for an extra cnt
1032
if any([idd in quarks for idd in final_real_id]) and real.fks_infos[0]['ij'] == 4:
1033
self.assertNotEqual(real.fks_infos[0]['extra_cnt_index'], -1)
1036
self.assertEqual(real.fks_infos[0]['extra_cnt_index'], -1)
1037
# make sure no qqbar splitting comes from the photon.
1038
if real.fks_infos[0]['ij'] == 3:
1039
self.assertTrue(not real.pdgs[real.fks_infos[0]['i']-1] in quarks)
1040
self.assertTrue(not real.pdgs[real.fks_infos[0]['j']-1] in quarks)
1041
self.assertTrue(foundqq)
1043
elif final_id == [22, 22]:
1044
# aa state, should have no extra_cnts
1045
self.assertEqual(len(proc.extra_cnt_amp_list), 0) #( 22, 22)
1046
for real in proc.real_amps:
1047
# check that real emissions with qqbar splitting has only one fks info
1048
if len(real.fks_infos) > 1:
1049
self.assertTrue(not any([real.pdgs[ii['i']-1] in quarks for ii in real.fks_infos]))
1050
final_real_id = real.pdgs[2:]
1051
self.assertEqual(real.fks_infos[0]['extra_cnt_index'], -1)
1052
# make sure no qqbar splitting comes from final state photons.
1053
if real.fks_infos[0]['ij'] in [3, 4]:
1054
self.assertTrue(not real.pdgs[real.fks_infos[0]['i']-1] in quarks)
1055
self.assertTrue(not real.pdgs[real.fks_infos[0]['j']-1] in quarks)
1057
def test_generate_fks_2to1_no_finalstate_confs(self):
1058
"""check that in the case of a 2->1 process no final state
1059
FKS configurations are generated
1061
self.interface.do_set('include_lepton_initiated_processes False')
1062
self.interface.do_generate('u d~ > w+ [QED]')
1063
self.assertEqual(len(self.interface._fks_multi_proc['born_processes']), 1)
1065
# there should be 4 configurations, all due to initial-state splitting
1067
for real in self.interface._fks_multi_proc['born_processes'][0].real_amps:
1068
for info in real.fks_infos:
1069
self.assertTrue(info['j'] in [1,2])
1071
self.assertEqual(nconfs, 4)
1074
def test_combine_equal_processes_qcd_qed(self):
1075
"""check that two processes with the same matrix-elements are equal
1076
and check that the add_process function works as expected"""
1077
newinterface = mgcmd.MasterCmd()
1078
newinterface2 = mgcmd.MasterCmd()
1079
# generate the processes
1080
self.interface.do_generate('u u~ > t t~ QED^2=0 QCD^2=4 [real=QCD QED]')
1081
newinterface.do_generate('c c~ > t t~ QED^2=0 QCD^2=4 [real=QCD QED]')
1082
newinterface2.do_generate('d d~ > t t~ QED^2=0 QCD^2=4 [real=QCD QED]')
1084
fksproc1 = self.interface._fks_multi_proc
1085
fksproc2 = newinterface._fks_multi_proc
1086
fksproc3 = newinterface2._fks_multi_proc
1087
fksme1 = fks_helas.FKSHelasMultiProcess(fksproc1)['matrix_elements'][0]
1088
fksme2 = fks_helas.FKSHelasMultiProcess(fksproc2)['matrix_elements'][0]
1089
fksme3 = fks_helas.FKSHelasMultiProcess(fksproc3)['matrix_elements'][0]
1091
self.assertNotEqual(fksme2,fksme3)
1093
# check the reals, they should be in the same order
1094
for i1, r1, in enumerate(fksme1.real_processes):
1095
for i2, r2, in enumerate(fksme2.real_processes):
1097
self.assertEqual(r1,r2)
1099
self.assertNotEqual(r1,r2)
1100
self.assertEqual(fksme1, fksme2)
1102
fksme1.add_process(fksme2)
1104
self.assertEqual(len(fksme1.born_me['processes']), 2)
1105
for real in fksme1.real_processes:
1106
self.assertEqual(len(real.matrix_element['processes']), 2)
1108
def load_fksME(self, save_name, model_name, process_def, force=False):
1109
"""tries to recover the fksME from a pickle file, otherwise regenerate it."""
1111
if not force and os.path.isfile(pjoin(root_path,'input_files',save_name)):
1112
return save_load_object.load_from_file(pjoin(root_path,'input_files',save_name))
1114
self.interface.do_import('model %s'%model_name)
1115
print(( "Regenerating %s ..."%process_def))
1116
self.interface.do_generate(process_def)
1117
proc = copy.copy(self.interface._fks_multi_proc)
1118
me = fks_helas.FKSHelasMultiProcess(proc)['matrix_elements'][0]
1119
save_load_object.save_to_file(pjoin(root_path,'input_files',save_name),me)
1122
def notest_special_dijet_equal_process_qcd_qed_virt_test(self):
1123
fksme1 = self.load_fksME('aa_emep_dijet.pkl','loop_qcd_qed_sm-no_widths','a a > e- e+ QED^2=4 QCD^2=4 [QCD QED]')
1124
fksme2 = self.load_fksME('aa_mummup_dijet.pkl','loop_qcd_qed_sm-no_widths','a a > mu- mu+ QED^2=4 QCD^2=4 [QCD QED]')
1125
self.assertEqual(fksme1,fksme2)
1127
def test_combine_equal_processes_dijet_qcd_qed_virt(self):
1128
"""check that two processes with the same matrix-elements are equal
1129
and check that the add_process function works as expected.
1130
This test also cehck that equality works for virtuals.
1131
In particular b-initiate processes have same trees but different loops (w/top)"""
1132
# generate the processes
1134
self.interface.do_import('model loop_qcd_qed_sm-no_widths')
1136
self.interface.do_generate('u u~ > g g QED^2=0 QCD^2=4 [QCD QED]')
1137
fksproc1 = copy.copy(self.interface._fks_multi_proc)
1139
self.interface.do_generate('c c~ > g g QED^2=0 QCD^2=4 [QCD QED]')
1140
fksproc2 = copy.copy(self.interface._fks_multi_proc)
1142
self.interface.do_generate('d d~ > g g QED^2=0 QCD^2=4 [QCD QED]')
1143
fksproc3 = copy.copy(self.interface._fks_multi_proc)
1145
self.interface.do_generate('b b~ > g g QED^2=0 QCD^2=4 [QCD QED]')
1146
fksproc4 = copy.copy(self.interface._fks_multi_proc)
1148
fksme1 = fks_helas.FKSHelasMultiProcess(fksproc1)['matrix_elements'][0]
1149
fksme2 = fks_helas.FKSHelasMultiProcess(fksproc2)['matrix_elements'][0]
1150
fksme3 = fks_helas.FKSHelasMultiProcess(fksproc3)['matrix_elements'][0]
1151
fksme4 = fks_helas.FKSHelasMultiProcess(fksproc4)['matrix_elements'][0]
1153
## fksme1 = self.load_fksME('uux_gg_dijet.pkl','loop_qcd_qed_sm-no_widths','u u~ > g g QED^2=0 QCD^2=4 [QCD QED]')
1154
## fksme2 = self.load_fksME('ccx_gg_dijet.pkl','loop_qcd_qed_sm-no_widths','c c~ > g g QED^2=0 QCD^2=4 [QCD QED]')
1155
## fksme3 = self.load_fksME('ddx_gg_dijet.pkl','loop_qcd_qed_sm-no_widths','d d~ > g g QED^2=0 QCD^2=4 [QCD QED]')
1156
## fksme4 = self.load_fksME('bbx_gg_dijet.pkl','loop_qcd_qed_sm-no_widths','b b~ > g g QED^2=0 QCD^2=4 [QCD QED]')
1157
# check that the u and d initiated are not equal
1158
self.assertNotEqual(fksme2,fksme3)
1160
# check that the b-initiated is different from all other processes
1161
self.assertNotEqual(fksme1,fksme4)
1162
self.assertNotEqual(fksme2,fksme4)
1163
self.assertNotEqual(fksme3,fksme4)
1165
# check that the u and c initiated are equal
1166
self.assertEqual(fksme1, fksme2)
1168
# this is to avoid effects on other tests
1169
self.interface.do_import('model sm')
1171
def notest_combine_equal_processes_pp_hpwmbbx_virt(self):
1172
"""Makes sure the uux and ccx channel of the process can be merged."""
1174
if os.path.isfile(pjoin(root_path,'input_files','uux_hpwmbbx.pkl')) and\
1175
os.path.isfile(pjoin(root_path,'input_files','ccx_hpwmbbx.pkl')) and\
1176
os.path.isfile(pjoin(root_path,'input_files','ddx_hpwmbbx.pkl')):
1177
uux_me = save_load_object.load_from_file(pjoin(root_path,'input_files','uux_hpwmbbx.pkl'))
1178
ccx_me = save_load_object.load_from_file(pjoin(root_path,'input_files','ccx_hpwmbbx.pkl'))
1179
ddx_me = save_load_object.load_from_file(pjoin(root_path,'input_files','ddx_hpwmbbx.pkl'))
1181
self.interface.do_set('complex_mass_scheme True')
1182
self.interface.do_import('model 2HDMCMStIIymbMSbar')
1183
print ("Regenerating u u~ > h+ w- b b~ / h1 h2 h3 QED^2=2 YB=1 YT=1 QCD^2=2 [QCD] ...")
1184
self.interface.do_generate('u u~ > h+ w- b b~ / h1 h2 h3 QED^2=2 YB=1 YT=1 QCD^2=2 [QCD]')
1185
uux_proc = copy.copy(self.interface._fks_multi_proc)
1186
uux_me = fks_helas.FKSHelasMultiProcess(uux_proc)['matrix_elements'][0]
1187
save_load_object.save_to_file(pjoin(root_path,'input_files','uux_hpwmbbx.pkl'),uux_me)
1188
print ("Regenerating c c~ > h+ w- b b~ / h1 h2 h3 QED^2=2 YB=1 YT=1 QCD^2=2 [QCD] ...")
1189
self.interface.do_generate('c c~ > h+ w- b b~ / h1 h2 h3 QED^2=2 YB=1 YT=1 QCD^2=2 [QCD]')
1190
ccx_proc = copy.copy(self.interface._fks_multi_proc)
1191
ccx_me = fks_helas.FKSHelasMultiProcess(ccx_proc)['matrix_elements'][0]
1192
save_load_object.save_to_file(pjoin(root_path,'input_files','ccx_hpwmbbx.pkl'),ccx_me)
1193
uux_me = save_load_object.load_from_file(pjoin(root_path,'input_files','uux_hpwmbbx.pkl'))
1194
ccx_me = save_load_object.load_from_file(pjoin(root_path,'input_files','ccx_hpwmbbx.pkl'))
1195
print ("Regenerating d d~ > h+ w- b b~ / h1 h2 h3 QED^2=2 YB=1 YT=1 QCD^2=2 [QCD] ...")
1196
self.interface.do_generate('d d~ > h+ w- b b~ / h1 h2 h3 QED^2=2 YB=1 YT=1 QCD^2=2 [QCD]')
1197
ddx_proc = copy.copy(self.interface._fks_multi_proc)
1198
ddx_me = fks_helas.FKSHelasMultiProcess(ddx_proc)['matrix_elements'][0]
1199
save_load_object.save_to_file(pjoin(root_path,'input_files','ddx_hpwmbbx.pkl'),ddx_me)
1201
self.assertEqual(uux_me,ccx_me)
1202
self.assertEqual(uux_me,ddx_me)
1204
def test_combine_equal_processes_dy_qed_virt(self):
1205
"""check that two processes with the same matrix-elements are equal
1206
and check that the add_process function works as expected.
1207
This test also cehck that equality works for virtuals.
1208
In particular b-initiate processes have same trees but different loops (w/top)"""
1209
# generate the processes
1211
self.interface.do_import('model loop_qcd_qed_sm-no_widths')
1213
self.interface.do_generate('u u~ > e+ e- QED^2=4 QCD^2=0 [QED]')
1214
fksproc1 = copy.copy(self.interface._fks_multi_proc)
1216
self.interface.do_generate('c c~ > e+ e- QED^2=4 QCD^2=0 [QED]')
1217
fksproc2 = copy.copy(self.interface._fks_multi_proc)
1219
self.interface.do_generate('d d~ > e+ e- QED^2=4 QCD^2=0 [QED]')
1220
fksproc3 = copy.copy(self.interface._fks_multi_proc)
1222
self.interface.do_generate('b b~ > e+ e- QED^2=4 QCD^2=0 [QED]')
1223
fksproc4 = copy.copy(self.interface._fks_multi_proc)
1225
self.interface.do_generate('s s~ > e+ e- QED^2=4 QCD^2=0 [QED]')
1226
fksproc5 = copy.copy(self.interface._fks_multi_proc)
1228
fksme1 = fks_helas.FKSHelasMultiProcess(fksproc1)['matrix_elements'][0]
1229
fksme2 = fks_helas.FKSHelasMultiProcess(fksproc2)['matrix_elements'][0]
1230
fksme3 = fks_helas.FKSHelasMultiProcess(fksproc3)['matrix_elements'][0]
1231
fksme4 = fks_helas.FKSHelasMultiProcess(fksproc4)['matrix_elements'][0]
1232
fksme5 = fks_helas.FKSHelasMultiProcess(fksproc5)['matrix_elements'][0]
1234
# check that the u and d initiated are not equal
1235
self.assertNotEqual(fksme2,fksme3)
1237
# check that the b-initiated is different from all other processes
1238
self.assertNotEqual(fksme1,fksme4)
1239
self.assertNotEqual(fksme2,fksme4)
1240
self.assertNotEqual(fksme3,fksme4)
1242
# check that the u and c initiated are equal
1243
self.assertEqual(fksme1, fksme2)
1245
# check that the d and s initiated are equal
1246
self.assertEqual(fksme3, fksme5)
1248
# this is to avoid effects on other tests
1249
self.interface.do_import('model sm')
1252
def test_combine_equal_processes_qcd(self):
1253
"""check that two processes with the same matrix-elements are equal
1254
and check that the add_process function works as expected"""
1255
newinterface = mgcmd.MasterCmd()
1256
newinterface2 = mgcmd.MasterCmd()
1257
# generate the processes
1258
self.interface.do_generate('u u~ > t t~ QED^2=0 QCD^2=4 [real=QCD]')
1259
newinterface.do_generate('d d~ > t t~ QED^2=0 QCD^2=4 [real=QCD]')
1261
fksproc1 = self.interface._fks_multi_proc
1262
fksproc2 = newinterface._fks_multi_proc
1263
fksme1 = fks_helas.FKSHelasMultiProcess(fksproc1)['matrix_elements'][0]
1264
fksme2 = fks_helas.FKSHelasMultiProcess(fksproc2)['matrix_elements'][0]
1266
# check the reals, they should be in the same order
1267
for i1, r1, in enumerate(fksme1.real_processes):
1268
for i2, r2, in enumerate(fksme2.real_processes):
1270
self.assertEqual(r1,r2)
1272
self.assertNotEqual(r1,r2)
1273
self.assertEqual(fksme1, fksme2)
1275
fksme1.add_process(fksme2)
1277
self.assertEqual(len(fksme1.born_me['processes']), 2)
1278
for real in fksme1.real_processes:
1279
self.assertEqual(len(real.matrix_element['processes']), 2)
1282
def test_include_lep_split(self):
1283
"""test that the include_lepton_initiated_processes options works as expected"""
1284
interface = mgcmd.MasterCmd()
1287
# default should be set to false
1288
# initial state leptons
1289
self.interface.do_generate('a a > w+ w- QED^2=4 QCD^2=0 [real=QED]')
1290
fksproc = self.interface._fks_multi_proc['born_processes'][0]
1292
for real in reals[0]+reals[1]:
1293
self.assertTrue(all([lep not in [abs(l['id']) for l in real['leglist']] for lep in leptons]))
1295
# chack that this does not affect final state photons
1296
self.interface.do_generate('u u~ > g a QED^2=2 QCD^2=2 [real=QCD]')
1297
fksproc = self.interface._fks_multi_proc['born_processes'][0]
1299
self.assertTrue(any([leptons[0] in [abs(l['id']) for l in real['leglist']] for real in reals[2]]))
1301
# now set it to true
1302
self.interface.do_set('include_lepton_initiated_processes True')
1303
# initial state leptons
1304
self.interface.do_generate('a a > w+ w- QED^2=4 QCD^2=0 [real=QED]')
1305
fksproc = self.interface._fks_multi_proc['born_processes'][0]
1307
self.assertTrue(any([leptons[0] in [abs(l['id']) for l in real['leglist']] for real in reals[0]]))
1308
self.assertTrue(any([leptons[0] in [abs(l['id']) for l in real['leglist']] for real in reals[1]]))
1309
# avoid border effects
1310
self.interface.do_set('include_lepton_initiated_processes False')