1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 """Definitions of the Helas objects needed for the implementation of MadFKS
17 from born"""
18
19
20 from __future__ import absolute_import
21 import madgraph.core.base_objects as MG
22 import madgraph.core.helas_objects as helas_objects
23 import madgraph.core.diagram_generation as diagram_generation
24 import madgraph.core.color_amp as color_amp
25 import madgraph.core.color_algebra as color_algebra
26 import madgraph.fks.fks_base as fks_base
27 import madgraph.fks.fks_common as fks_common
28 import madgraph.loop.loop_helas_objects as loop_helas_objects
29 import madgraph.loop.loop_diagram_generation as loop_diagram_generation
30 import madgraph.various.misc as misc
31 import copy
32 import logging
33 import array
34 import multiprocessing
35 import signal
36 import tempfile
37 import six.moves.cPickle
38 import itertools
39 import os
40 import sys
41 from six.moves import zip
42 from madgraph import MG5DIR
43 pjoin = os.path.join
44 logger = logging.getLogger('madgraph.fks_helas_objects')
45
46
47
49 i = args[0]
50 real_amp = args[1]
51
52 amplitude = real_amp.generate_real_amplitude()
53 helasreal = helas_objects.HelasMatrixElement(amplitude)
54 logger.info('Generating real %s' % \
55 real_amp.process.nice_string(print_weighted=False).replace('Process', 'process'))
56
57
58
59 list_colorize = []
60 list_color_basis = []
61 list_color_matrices = []
62
63
64
65
66 dict_loopborn_matrices = {}
67
68
69 color_information = { 'list_colorize' : list_colorize,
70 'list_color_basis' : list_color_basis,
71 'list_color_matrices' : list_color_matrices,
72 'dict_loopborn_matrices' : dict_loopborn_matrices}
73
74 helas_objects.HelasMultiProcess.process_color(helasreal,color_information)
75
76 outdata = [amplitude,helasreal]
77
78 output = tempfile.NamedTemporaryFile(delete = False)
79
80 six.moves.cPickle.dump(outdata,output,protocol=2)
81 output.close()
82
83 return [output.name,helasreal.get_num_configs(),helasreal.get_nexternal_ninitial()[0]]
84
85
87 i = args[0]
88 born = args[1]
89 born_pdg_list = args[2]
90 loop_orders = args[3]
91 pdg_list = args[4]
92 loop_optimized = args[5]
93 OLP = args[6]
94 realmapout = args[7]
95
96 logger.info('Generating born %s' % \
97 born.born_proc.nice_string(print_weighted=False).replace('Process', 'process'))
98
99
100 helasreal_list = []
101 for amp in born.real_amps:
102 idx = pdg_list.index(amp.pdgs)
103 infilename = realmapout[idx]
104 infile = open(infilename,'rb')
105 realdata = six.moves.cPickle.load(infile)
106 infile.close()
107 amp.amplitude = realdata[0]
108 helasreal_list.append(realdata[1])
109
110 born.link_born_reals()
111
112 for amp in born.real_amps:
113 amp.find_fks_j_from_i(born_pdg_list)
114
115
116 has_loops = False
117 if born.born_proc.get('NLO_mode') == 'all' and OLP == 'MadLoop':
118 myproc = copy.copy(born.born_proc)
119
120 myproc['orders'] = loop_orders
121 myproc['legs'] = fks_common.to_legs(copy.copy(myproc['legs']))
122 myamp = loop_diagram_generation.LoopAmplitude(myproc)
123 if myamp.get('diagrams'):
124 has_loops = True
125 born.virt_amp = myamp
126
127 helasfull = FKSHelasProcess(born, helasreal_list,
128 loop_optimized = loop_optimized,
129 decay_ids=[],
130 gen_color=False)
131
132 processes = helasfull.born_matrix_element.get('processes')
133
134 max_configs = helasfull.born_matrix_element.get_num_configs()
135
136 metag = helas_objects.IdentifyMETag.create_tag(helasfull.born_matrix_element.get('base_amplitude'))
137
138 outdata = helasfull
139
140 output = tempfile.NamedTemporaryFile(delete = False)
141 six.moves.cPickle.dump(outdata,output,protocol=2)
142 output.close()
143
144 return [output.name,metag,has_loops,processes,max_configs]
145
146
148
149 i = args[0]
150 mefile = args[1]
151 duplist = args[2]
152
153 infile = open(mefile,'rb')
154 me = six.moves.cPickle.load(infile)
155 infile.close()
156
157
158 me.get('processes')[0].set('uid', i)
159
160
161
162
163 col_basis = color_amp.ColorBasis()
164 new_amp = me.born_matrix_element.get_base_amplitude()
165 me.born_matrix_element.set('base_amplitude', new_amp)
166 colorize_obj = col_basis.create_color_dict_list(new_amp)
167
168 col_basis.build()
169 col_matrix = color_amp.ColorMatrix(col_basis)
170
171 me.born_matrix_element.set('color_basis',col_basis)
172 me.born_matrix_element.set('color_matrix',col_matrix)
173
174 for iother,othermefile in enumerate(duplist):
175 infileother = open(othermefile,'rb')
176 otherme = six.moves.cPickle.load(infileother)
177 infileother.close()
178 me.add_process(otherme)
179
180 me.set_color_links()
181
182 initial_states=[]
183 for fksreal in me.real_processes:
184
185 initial_states.append(sorted(list(set((p.get_initial_pdg(1),p.get_initial_pdg(2)) for \
186 p in fksreal.matrix_element.get('processes')))))
187
188 if me.virt_matrix_element:
189 has_virtual = True
190 else:
191 has_virtual = False
192
193
194 outdata = me
195
196 output = tempfile.NamedTemporaryFile(delete = False)
197 six.moves.cPickle.dump(outdata,output,protocol=2)
198 output.close()
199
200
201 return [output.name,initial_states,me.get_used_lorentz(),me.get_used_couplings(),has_virtual]
202
203
205 """class to generate the helas calls for a FKSMultiProcess"""
206
208 """Return particle property names as a nicely sorted list."""
209 keys = super(FKSHelasMultiProcess, self).get_sorted_keys()
210 keys += ['real_matrix_elements', ['has_isr'], ['has_fsr'],
211 'used_lorentz', 'used_couplings', 'max_configs', 'max_particles', 'processes']
212 return keys
213
214 - def filter(self, name, value):
220
221 - def __init__(self, fksmulti, loop_optimized = False, gen_color =True, decay_ids =[]):
222 """Initialization from a FKSMultiProcess"""
223
224
225 loggers_off = [logging.getLogger('madgraph.diagram_generation'),
226 logging.getLogger('madgraph.helas_objects')]
227 old_levels = [logg.level for logg in loggers_off]
228 for logg in loggers_off:
229 logg.setLevel(logging.WARNING)
230
231 self.loop_optimized = loop_optimized
232
233 self['used_lorentz'] = []
234 self['used_couplings'] = []
235 self['processes'] = []
236
237 self['max_particles'] = -1
238 self['max_configs'] = -1
239
240 if not fksmulti['ncores_for_proc_gen']:
241
242
243 if fksmulti['real_amplitudes']:
244 logger.info('Generating real emission matrix-elements...')
245 self['real_matrix_elements'] = self.generate_matrix_elements(
246 copy.copy(fksmulti['real_amplitudes']), combine_matrix_elements = False)
247 else:
248 self['real_matrix_elements'] = helas_objects.HelasMatrixElementList()
249
250 self['matrix_elements'] = self.generate_matrix_elements_fks(
251 fksmulti,
252 gen_color, decay_ids)
253 self['initial_states']=[]
254 self['has_loops'] = len(self.get_virt_matrix_elements()) > 0
255
256 else:
257 self['has_loops'] = False
258
259 born_procs = fksmulti.get('born_processes')
260 born_pdg_list = [[l['id'] for l in born.born_proc['legs']] \
261 for born in born_procs ]
262 loop_orders = {}
263 for born in born_procs:
264 for coup, val in fks_common.find_orders(born.born_amp).items():
265 try:
266 loop_orders[coup] = max([loop_orders[coup], val])
267 except KeyError:
268 loop_orders[coup] = val
269 pdg_list = []
270 real_amp_list = []
271 for born in born_procs:
272 for amp in born.real_amps:
273 if not pdg_list.count(amp.pdgs):
274 pdg_list.append(amp.pdgs)
275 real_amp_list.append(amp)
276
277
278 real_out_list = []
279 realmapin = []
280 for i,real_amp in enumerate(real_amp_list):
281 realmapin.append([i,real_amp])
282
283
284 original_sigint_handler = signal.signal(signal.SIGINT, signal.SIG_IGN)
285 if six.PY3:
286 ctx = multiprocessing.get_context('fork')
287 else:
288 ctx = multiprocessing
289 if fksmulti['ncores_for_proc_gen'] < 0:
290 pool = ctx.Pool(maxtasksperchild=1)
291 else:
292 pool = ctx.Pool(processes=fksmulti['ncores_for_proc_gen'],maxtasksperchild=1)
293 signal.signal(signal.SIGINT, original_sigint_handler)
294
295 logger.info('Generating real matrix elements...')
296 import time
297 try:
298
299
300 modelpath = born_procs[0].born_proc['model'].get('modelpath')
301
302 with misc.TMP_variable(sys, 'path', sys.path + [pjoin(MG5DIR, 'models'), modelpath]):
303 realmapout = pool.map_async(async_generate_real,realmapin).get(9999999)
304 except KeyboardInterrupt:
305 pool.terminate()
306 raise KeyboardInterrupt
307
308 realmapfiles = []
309 for realout in realmapout:
310 realmapfiles.append(realout[0])
311
312 logger.info('Generating born and virtual matrix elements...')
313
314 bornmapin = []
315 OLP=fksmulti['OLP']
316 for i,born in enumerate(born_procs):
317 bornmapin.append([i,born,born_pdg_list,loop_orders,pdg_list,loop_optimized,OLP,realmapfiles])
318
319 try:
320 bornmapout = pool.map_async(async_generate_born,bornmapin).get(9999999)
321 except KeyboardInterrupt:
322 pool.terminate()
323 raise KeyboardInterrupt
324
325
326 for realtmp in realmapout:
327 os.remove(realtmp[0])
328
329 logger.info('Collecting infos and finalizing matrix elements...')
330 unique_me_list = []
331 duplicate_me_lists = []
332 for bornout in bornmapout:
333 mefile = bornout[0]
334 metag = bornout[1]
335 has_loops = bornout[2]
336 self['has_loops'] = self['has_loops'] or has_loops
337 processes = bornout[3]
338 self['processes'].extend(processes)
339 self['max_particles'] = max([self['max_configs']] + [len(p['legs']) + 1 for p in bornout[3]])
340 self['max_configs'] = max(self['max_configs'], bornout[4])
341 unique = True
342 for ime2,bornout2 in enumerate(unique_me_list):
343 mefile2 = bornout2[0]
344 metag2 = bornout2[1]
345 if metag==metag2:
346 duplicate_me_lists[ime2].append(mefile)
347 unique = False
348 break;
349 if unique:
350 unique_me_list.append(bornout)
351 duplicate_me_lists.append([])
352
353 memapin = []
354 for i,bornout in enumerate(unique_me_list):
355 mefile = bornout[0]
356 memapin.append([i,mefile, duplicate_me_lists[i]])
357
358 try:
359 memapout = pool.map_async(async_finalize_matrix_elements,memapin).get(9999999)
360 except KeyboardInterrupt:
361 pool.terminate()
362 raise KeyboardInterrupt
363
364
365 for bornout in bornmapout:
366 mefile = bornout[0]
367 os.remove(mefile)
368
369 pool.close()
370 pool.join()
371
372
373 matrix_elements = []
374 for meout in memapout:
375 matrix_elements.append(meout[0])
376
377 self['matrix_elements']=matrix_elements
378
379
380
381 initial_states = []
382 for meout in memapout:
383 me_initial_states = meout[1]
384 for state in me_initial_states:
385 initial_states.append(state)
386
387
388 checked = []
389 for e in initial_states:
390 if e not in checked:
391 checked.append(e)
392 initial_states=checked
393
394 self['initial_states']=initial_states
395
396 helas_list = []
397 for meout in memapout:
398 helas_list.extend(meout[2])
399 self['used_lorentz']=list(set(helas_list))
400
401 coupling_list = []
402 for meout in memapout:
403 coupling_list.extend([c for l in meout[3] for c in l])
404 self['used_couplings'] = list(set(coupling_list))
405
406 has_virtuals = False
407 for meout in memapout:
408 if meout[4]:
409 has_virtuals = True
410 break
411 self['has_virtuals'] = has_virtuals
412
413 configs_list = [self['max_configs']]
414 for meout in realmapout:
415 configs_list.append(meout[1])
416 self['max_configs'] = max(configs_list)
417
418 nparticles_list = [self['max_particles']]
419 for meout in realmapout:
420 nparticles_list.append(meout[2])
421 self['max_particles'] = max(nparticles_list)
422
423 self['has_isr'] = fksmulti['has_isr']
424 self['has_fsr'] = fksmulti['has_fsr']
425
426 logger.info('... Done')
427
428 for i, logg in enumerate(loggers_off):
429 logg.setLevel(old_levels[i])
430
431
433 """Return a list of (lorentz_name, conjugate, outgoing) with
434 all lorentz structures used by this HelasMultiProcess."""
435
436 if not self['used_lorentz']:
437 helas_list = []
438 for me in self.get('matrix_elements'):
439 helas_list.extend(me.get_used_lorentz())
440 self['used_lorentz'] = list(set(helas_list))
441
442 return self['used_lorentz']
443
444
446 """Return a list with all couplings used by this
447 HelasMatrixElement."""
448
449 if not self['used_couplings']:
450 coupling_list = []
451 for me in self.get('matrix_elements'):
452 coupling_list.extend([c for l in me.get_used_couplings() for c in l])
453 self['used_couplings'] = list(set(coupling_list))
454
455 return self['used_couplings']
456
457
459 """Return a list with all couplings used by this
460 HelasMatrixElement."""
461
462 if not self['processes']:
463 process_list = []
464 for me in self.get('matrix_elements'):
465 process_list.extend(me.born_matrix_element.get('processes'))
466 self['processes'] = process_list
467
468 return self['processes']
469
470
472 """Return max_configs"""
473
474 if self['max_configs'] < 0:
475 try:
476 self['max_configs'] = max([me.get_num_configs() \
477 for me in self['real_matrix_elements']])
478 except ValueError:
479 pass
480 self['max_configs'] = max(self['max_configs'],\
481 max([me.born_matrix_element.get_num_configs() \
482 for me in self['matrix_elements']]))
483
484 return self['max_configs']
485
486
488 """Return max_paricles"""
489
490 if self['max_particles'] < 0:
491 self['max_particles'] = max([me.get_nexternal_ninitial()[0] \
492 for me in self['matrix_elements']])
493
494 return self['max_particles']
495
496
498 """Extract the list of matrix elements"""
499 return self.get('matrix_elements')
500
501
503 """Extract the list of virtuals matrix elements"""
504 return [me.virt_matrix_element for me in self.get('matrix_elements') \
505 if me.virt_matrix_element]
506
507
510 """Generate the HelasMatrixElements for the amplitudes,
511 identifying processes with identical matrix elements, as
512 defined by HelasMatrixElement.__eq__. Returns a
513 HelasMatrixElementList and an amplitude map (used by the
514 SubprocessGroup functionality). decay_ids is a list of decayed
515 particle ids, since those should not be combined even if
516 matrix element is identical."""
517
518 fksprocs = fksmulti['born_processes']
519 assert isinstance(fksprocs, fks_base.FKSProcessList), \
520 "%s is not valid FKSProcessList" % \
521 repr(fksprocs)
522
523
524
525 list_colorize = []
526 list_color_links =[]
527 list_color_basis = []
528 list_color_matrices = []
529 real_me_list = []
530 me_id_list = []
531
532 matrix_elements = FKSHelasProcessList()
533
534 for i, proc in enumerate(fksprocs):
535 logger.info("Generating Helas calls for FKS %s (%d / %d)" % \
536 (proc.born_amp.get('process').nice_string(print_weighted = False).\
537 replace('Process', 'process'),
538 i + 1, len(fksprocs)))
539 matrix_element_list = [FKSHelasProcess(proc, self['real_matrix_elements'],
540 fksmulti['real_amplitudes'],
541 loop_optimized = self.loop_optimized,
542 decay_ids=decay_ids,
543 gen_color=False)]
544 for matrix_element in matrix_element_list:
545 assert isinstance(matrix_element, FKSHelasProcess), \
546 "Not a FKSHelasProcess: %s" % matrix_element
547
548 try:
549
550
551
552 other = \
553 matrix_elements[matrix_elements.index(matrix_element)]
554 except ValueError:
555
556
557 if matrix_element.born_matrix_element.get('processes') and \
558 matrix_element.born_matrix_element.get('diagrams'):
559 matrix_elements.append(matrix_element)
560
561 if not gen_color:
562 continue
563
564
565
566
567 col_basis = color_amp.ColorBasis()
568 new_amp = matrix_element.born_matrix_element.get_base_amplitude()
569 matrix_element.born_matrix_element.set('base_amplitude', new_amp)
570 colorize_obj = col_basis.create_color_dict_list(new_amp)
571
572 try:
573
574
575
576 col_index = list_colorize.index(colorize_obj)
577 logger.info(\
578 "Reusing existing color information for %s" % \
579 matrix_element.born_matrix_element.get('processes')\
580 [0].nice_string(print_weighted=False).\
581 replace('Process', 'process'))
582 except ValueError:
583
584
585 list_colorize.append(colorize_obj)
586 col_basis.build()
587 list_color_basis.append(col_basis)
588 col_matrix = color_amp.ColorMatrix(col_basis)
589 list_color_matrices.append(col_matrix)
590 col_index = -1
591
592 logger.info(\
593 "Processing color information for %s" % \
594 matrix_element.born_matrix_element.\
595 get('processes')[0].nice_string(print_weighted=False).\
596 replace('Process', 'process'))
597 matrix_element.born_matrix_element.set('color_basis',
598 list_color_basis[col_index])
599 matrix_element.born_matrix_element.set('color_matrix',
600 list_color_matrices[col_index])
601 else:
602
603
604 other.add_process(matrix_element)
605
606 for me in matrix_elements:
607 me.set_color_links()
608 return matrix_elements
609
610
612 """class to handle lists of FKSHelasProcesses"""
613
615 """Test if object obj is a valid FKSProcess for the list."""
616 return isinstance(obj, FKSHelasProcess)
617
618
620 """class to generate the Helas calls for a FKSProcess. Contains:
621 -- born ME
622 -- list of FKSHelasRealProcesses
623 -- color links"""
624
625 - def __init__(self, fksproc=None, real_me_list =[], real_amp_list=[],
626 loop_optimized = False, **opts):
627 """ constructor, starts from a FKSProcess,
628 sets reals and color links. Real_me_list and real_amp_list are the lists of pre-genrated
629 matrix elements in 1-1 correspondence with the amplitudes"""
630
631 if fksproc != None:
632 self.born_matrix_element = helas_objects.HelasMatrixElement(
633 fksproc.born_amp, **opts)
634 self.real_processes = []
635 self.orders = fksproc.born_proc.get('orders')
636 self.perturbation = fksproc.perturbation
637 real_amps_new = []
638
639 if fksproc.ncores_for_proc_gen:
640
641 for real_me, proc in zip(real_me_list,fksproc.real_amps):
642 fksreal_me = FKSHelasRealProcess(proc, real_me, **opts)
643 try:
644 other = self.real_processes[self.real_processes.index(fksreal_me)]
645 other.matrix_element.get('processes').extend(\
646 fksreal_me.matrix_element.get('processes') )
647 except ValueError:
648 if fksreal_me.matrix_element.get('processes') and \
649 fksreal_me.matrix_element.get('diagrams'):
650 self.real_processes.append(fksreal_me)
651 real_amps_new.append(proc)
652 else:
653
654 for proc in fksproc.real_amps:
655 fksreal_me = FKSHelasRealProcess(proc, real_me_list, real_amp_list, **opts)
656 try:
657 other = self.real_processes[self.real_processes.index(fksreal_me)]
658 other.matrix_element.get('processes').extend(\
659 fksreal_me.matrix_element.get('processes') )
660 except ValueError:
661 if fksreal_me.matrix_element.get('processes') and \
662 fksreal_me.matrix_element.get('diagrams'):
663 self.real_processes.append(fksreal_me)
664 real_amps_new.append(proc)
665 fksproc.real_amps = real_amps_new
666 if fksproc.virt_amp:
667 self.virt_matrix_element = \
668 loop_helas_objects.LoopHelasMatrixElement(fksproc.virt_amp,
669 optimized_output = loop_optimized)
670 else:
671 self.virt_matrix_element = None
672
673 self.color_links = []
674
676 """this function computes and returns the color links, it should be called
677 after the initialization and the setting of the color basis"""
678 if not self.color_links:
679 legs = self.born_matrix_element.get('base_amplitude').get('process').get('legs')
680 model = self.born_matrix_element.get('base_amplitude').get('process').get('model')
681 color_links_info = fks_common.find_color_links(fks_common.to_fks_legs(legs, model),
682 symm = True,pert = self.perturbation)
683 col_basis = self.born_matrix_element.get('color_basis')
684 self.color_links = fks_common.insert_color_links(col_basis,
685 col_basis.create_color_dict_list(
686 self.born_matrix_element.get('base_amplitude')),
687 color_links_info)
688
690 """Returns the list of the fks infos for all processes in the format
691 {n_me, pdgs, fks_info}, where n_me is the number of real_matrix_element the configuration
692 belongs to"""
693 info_list = []
694 for n, real in enumerate(self.real_processes):
695 pdgs = [l['id'] for l in real.matrix_element.get_base_amplitude()['process']['legs']]
696 for info in real.fks_infos:
697 info_list.append({'n_me' : n + 1,'pdgs' : pdgs, 'fks_info' : info})
698 return info_list
699
700
702 """Returns the pdgs of the legs in the form "i1 i2 -> f1 f2 ...", which may
703 be useful (eg. to be written in a B-LH order file)"""
704
705 initial = ''
706 final = ''
707 for leg in self.born_matrix_element.get('processes')[0].get('legs'):
708 if leg.get('state'):
709 final += '%d ' % leg.get('id')
710 else:
711 initial += '%d ' % leg.get('id')
712 return initial + '-> ' + final
713
714
715 - def get(self, key):
716 """the get function references to born_matrix_element"""
717 return self.born_matrix_element.get(key)
718
720 """the get_used_lorentz function references to born, reals
721 and virtual matrix elements"""
722 lorentz_list = self.born_matrix_element.get_used_lorentz()
723 for real in self.real_processes:
724 lorentz_list.extend(real.matrix_element.get_used_lorentz())
725 if self.virt_matrix_element:
726 lorentz_list.extend(self.virt_matrix_element.get_used_lorentz())
727
728 return list(set(lorentz_list))
729
731 """the get_used_couplings function references to born, reals
732 and virtual matrix elements"""
733 coupl_list = self.born_matrix_element.get_used_couplings()
734 for real in self.real_processes:
735 coupl_list.extend([c for c in\
736 real.matrix_element.get_used_couplings()])
737 if self.virt_matrix_element:
738 coupl_list.extend(self.virt_matrix_element.get_used_couplings())
739 return coupl_list
740
742 """the nexternal_ninitial function references to the real emissions if they have been
743 generated, otherwise to the born"""
744 if self.real_processes:
745 (nexternal, ninitial) = self.real_processes[0].matrix_element.get_nexternal_ninitial()
746 else:
747 (nexternal, ninitial) = self.born_matrix_element.get_nexternal_ninitial()
748 nexternal += 1
749 return (nexternal, ninitial)
750
752 """the equality between two FKSHelasProcesses is defined up to the
753 color links"""
754 selftag = helas_objects.IdentifyMETag.create_tag(self.born_matrix_element.get('base_amplitude'))
755 othertag = helas_objects.IdentifyMETag.create_tag(other.born_matrix_element.get('base_amplitude'))
756
757 if self.born_matrix_element != other.born_matrix_element or \
758 selftag != othertag:
759 return False
760
761 reals2 = copy.copy(other.real_processes)
762 for real in self.real_processes:
763 try:
764 reals2.remove(real)
765 except ValueError:
766 return False
767 if not reals2:
768 return True
769 else:
770 return False
771
773 """adds processes from born and reals of other to itself. Note that
774 corresponding real processes may not be in the same order. This is
775 taken care of by constructing the list of self_reals."""
776 self.born_matrix_element.get('processes').extend(
777 other.born_matrix_element.get('processes'))
778 if self.virt_matrix_element and other.virt_matrix_element:
779 self.virt_matrix_element.get('processes').extend(
780 other.virt_matrix_element.get('processes'))
781 self_reals = [real.matrix_element for real in self.real_processes]
782 for oth_real in other.real_processes:
783 this_real = self.real_processes[self_reals.index(oth_real.matrix_element)]
784
785 this_pdgs = [[leg['id'] for leg in proc['legs']] \
786 for proc in this_real.matrix_element['processes']]
787 for oth_proc in oth_real.matrix_element['processes']:
788 oth_pdgs = [leg['id'] for leg in oth_proc['legs']]
789 if oth_pdgs not in this_pdgs:
790 this_real.matrix_element['processes'].append(oth_proc)
791 this_pdgs.append(oth_pdgs)
792
793
794
795
796
798 """class to generate the Helas calls for a FKSRealProcess
799 contains:
800 -- colors
801 -- charges
802 -- i/j/ij fks, ij refers to the born leglist
803 -- ijglu
804 -- need_color_links
805 -- fks_j_from_i
806 -- matrix element
807 -- is_to_integrate
808 -- leg permutation<<REMOVED"""
809
810 - def __init__(self, fksrealproc=None, real_me_list = [], real_amp_list =[], **opts):
811 """constructor, starts from a fksrealproc and then calls the
812 initialization for HelasMatrixElement.
813 Sets i/j fks and the permutation.
814 real_me_list and real_amp_list are the lists of pre-generated matrix elements in 1-1
815 correspondance with the amplitudes"""
816
817 if fksrealproc != None:
818 self.isfinite = False
819 self.colors = fksrealproc.colors
820 self.charges = fksrealproc.charges
821 self.fks_infos = fksrealproc.fks_infos
822 self.is_to_integrate = fksrealproc.is_to_integrate
823
824
825
826 if type(real_me_list) == list and len(real_me_list) != len(real_amp_list):
827 raise fks_common.FKSProcessError(
828 'not same number of amplitudes and matrix elements: %d, %d' % \
829 (len(real_amp_list), len(real_me_list)))
830 if type(real_me_list) == list and real_me_list and real_amp_list:
831 self.matrix_element = copy.deepcopy(real_me_list[real_amp_list.index(fksrealproc.amplitude)])
832 self.matrix_element['processes'] = copy.deepcopy(self.matrix_element['processes'])
833
834 elif type(real_me_list) == helas_objects.HelasMatrixElement:
835
836 self.matrix_element = real_me_list
837
838 else:
839
840 if real_me_list and real_amp_list:
841 self.matrix_element = copy.deepcopy(real_me_list[real_amp_list.index(fksrealproc.amplitude)])
842 self.matrix_element['processes'] = copy.deepcopy(self.matrix_element['processes'])
843 else:
844 logger.info('generating matrix element...')
845 self.matrix_element = helas_objects.HelasMatrixElement(
846 fksrealproc.amplitude, **opts)
847
848 self.matrix_element.get('color_basis').build(
849 self.matrix_element.get('base_amplitude'))
850 self.matrix_element.set('color_matrix',
851 color_amp.ColorMatrix(
852 self.matrix_element.get('color_basis')))
853
854 self.fks_j_from_i = fksrealproc.fks_j_from_i
855
859
861 """Equality operator:
862 compare two FKSHelasRealProcesses by comparing their dictionaries"""
863
864 if self.__dict__ == other.__dict__:
865 return True
866 else:
867
868
869
870
871
872
873 return False
874
875
876 return self.__dict__ == other.__dict__
877
879 """Inequality operator:
880 compare two FKSHelasRealProcesses by comparing their dictionaries"""
881 return not self.__eq__(other)
882