29
29
import madgraph.core.base_objects as base_objects
30
import madgraph.loop.loop_base_objects as loop_base_objects
30
31
import madgraph.core.diagram_generation as diagram_generation
31
32
import madgraph.core.helas_objects as helas_objects
32
33
import madgraph.iolibs.drawing_eps as draw
34
35
import madgraph.iolibs.file_writers as writers
35
36
import madgraph.iolibs.template_files as template_files
36
37
import madgraph.iolibs.ufo_expression_parsers as parsers
38
import madgraph.loop.loop_diagram_generation as loop_diagram_generation
39
import madgraph.loop.loop_helas_objects as loop_helas_objects
38
41
import madgraph.various.misc as misc
112
115
self['diagram_maps'] = {}
113
116
self['diagrams_for_configs'] = []
114
117
self['amplitude_map'] = {}
118
self['matrix_element_opts'] = {}
117
120
def filter(self, name, value):
118
121
"""Filter for valid property values."""
147
150
raise self.PhysicsObjectError, \
148
151
"%s is not a valid dict object" % str(value)
153
if name == 'matrix_element_opts':
154
if not isinstance(value, dict):
155
raise self.PhysicsObjectError, \
156
"%s is not a valid dictionary object" % str(value)
152
160
def get_sorted_keys(self):
195
203
amplitudes = copy.copy(self.get('amplitudes'))
197
self.set('matrix_elements',
205
# The conditional statement tests whether we are dealing with a
206
# loop induced process. We must set compute_loop_nc to True here
207
# since the knowledge of the power of Nc coming from potential
208
# loop color trace is necessary for the loop induced output with MadEvent
209
if isinstance(amplitudes[0], loop_diagram_generation.LoopAmplitude):
210
self.set('matrix_elements',
211
loop_helas_objects.LoopHelasProcess.generate_matrix_elements(
212
amplitudes, compute_loop_nc=True,
213
matrix_element_opts = self['matrix_element_opts']))
215
self.set('matrix_elements',
198
216
helas_objects.HelasMultiProcess.\
199
217
generate_matrix_elements(amplitudes))
288
306
# diagram maps, pointing to the mapping_diagrams (starting at
289
307
# 1). Diagrams with multi-particle vertices will have 0.
290
308
diagram_maps = {}
291
masswidth_to_pdg = {}
293
310
for ime, me in enumerate(matrix_elements):
294
diagrams = me.get('base_amplitude').get('diagrams')
311
# Define here a FDStructure repository which will be used for the
312
# tagging all the diagrams in get_contracted_loop_diagram. Remember
313
# the the tagging of each loop updates the FDStructre repository
314
# with the new structures identified.
316
if isinstance(me, loop_helas_objects.LoopHelasMatrixElement):
317
FDStructRepo = loop_base_objects.FDStructureList([])
318
diagrams = [(d.get_contracted_loop_diagram(model,FDStructRepo) if
319
isinstance(d,loop_base_objects.LoopDiagram) else d) for d in
320
me.get('base_amplitude').get('loop_diagrams') if d.get('type')>0]
322
diagrams = me.get('base_amplitude').get('diagrams')
295
324
# Check the minimal number of legs we need to include in order
296
325
# to make sure we'll have some valid configurations
297
326
max_legs = min([max([len(v.get('legs')) for v in \
298
d.get('vertices') if v.get('id') > 0]) \
327
d.get('vertices') if not v.get('id') in [0, -1]]) \
300
329
diagram_maps[ime] = []
301
331
for diagram in diagrams:
302
332
# Only use diagrams with all vertices == min_legs
303
if any([len(v.get('legs')) > max_legs \
304
for v in diagram.get('vertices') if v.get('id') > 0]):
333
if any([len(v.get('legs')) > max_legs for v in \
334
diagram.get('vertices') if not v.get('id') in [0, -1]]):
305
335
diagram_maps[ime].append(0)
307
337
# Create the equivalent diagram, in the format
352
382
# group_amplitudes
353
383
#===========================================================================
355
def group_amplitudes(amplitudes, criteria='madevent'):
385
def group_amplitudes(amplitudes, criteria='madevent', matrix_elements_opts={}):
356
386
"""Return a SubProcessGroupList with the amplitudes divided
357
387
into subprocess groups"""
372
402
for num in process_class_numbers:
373
403
amp_nums = [key for (key, val) in process_classes.items() if \
375
group = SubProcessGroup()
405
group = SubProcessGroup({'matrix_element_opts':matrix_elements_opts})
376
406
group.set('amplitudes',
377
407
diagram_generation.AmplitudeList([amplitudes[i] for i in \
409
439
fs_parts = [model.get_particle(l.get('id')) for l in \
410
440
process.get('legs') if l.get('state')]
411
diagrams = amplitude.get('diagrams')
413
442
# This is where the requirements for which particles to
414
443
# combine are defined. Include p.get('is_part') in
655
684
# group_amplitudes
656
685
#===========================================================================
658
def group_amplitudes(decay_chain_amps, criteria='madevent'):
687
def group_amplitudes(decay_chain_amps, criteria='madevent', matrix_elements_opts={}):
659
688
"""Recursive function. Starting from a DecayChainAmplitude,
660
689
return a DecayChainSubProcessGroup with the core amplitudes
661
690
and decay chains divided into subprocess groups"""