~madteam/mg5amcnlo/series2.0

« back to all changes in this revision

Viewing changes to madgraph/iolibs/group_subprocs.py

  • Committer: olivier Mattelaer
  • Date: 2015-03-05 00:14:16 UTC
  • mfrom: (258.1.9 2.3)
  • mto: (258.8.1 2.3)
  • mto: This revision was merged to the branch mainline in revision 259.
  • Revision ID: olivier.mattelaer@uclouvain.be-20150305001416-y9mzeykfzwnl9t0j
partial merge

Show diffs side-by-side

added added

removed removed

Lines of Context:
27
27
import subprocess
28
28
 
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
37
40
 
38
41
import madgraph.various.misc as misc
39
42
 
112
115
        self['diagram_maps'] = {}
113
116
        self['diagrams_for_configs'] = []
114
117
        self['amplitude_map'] = {}
115
 
        
 
118
        self['matrix_element_opts'] = {}
116
119
 
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)
149
152
 
 
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)
 
157
 
150
158
        return True
151
159
 
152
160
    def get_sorted_keys(self):
194
202
 
195
203
        amplitudes = copy.copy(self.get('amplitudes'))
196
204
 
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']))
 
214
        else:
 
215
            self.set('matrix_elements',
198
216
                 helas_objects.HelasMultiProcess.\
199
217
                                   generate_matrix_elements(amplitudes))
200
218
 
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 = {}
292
309
 
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.
 
315
                                    
 
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]
 
321
            else:
 
322
                diagrams = me.get('base_amplitude').get('diagrams')
 
323
            
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]) \
299
 
                              for d in diagrams])
 
327
                             d.get('vertices') if not v.get('id') in [0, -1]]) \
 
328
                                                             for d in diagrams])
300
329
            diagram_maps[ime] = []
 
330
            
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)
306
336
                    continue
307
337
                # Create the equivalent diagram, in the format
352
382
    # group_amplitudes
353
383
    #===========================================================================
354
384
    @staticmethod
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"""
358
388
 
372
402
        for num in process_class_numbers:
373
403
            amp_nums = [key for (key, val) in process_classes.items() if \
374
404
                          val == num]
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 \
378
408
                                                        amp_nums]))
408
438
                        l.get('state')]
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')
412
441
 
413
442
            # This is where the requirements for which particles to
414
443
            # combine are defined. Include p.get('is_part') in
433
462
                amplitude_classes[iamp] = proc_classes.index(proc_class)
434
463
            except ValueError:
435
464
                proc_classes.append(proc_class)
436
 
                amplitude_classes[iamp] = proc_classes.index(proc_class)
 
465
                amplitude_classes[iamp] = len(proc_classes)-1
437
466
 
438
467
        return amplitude_classes
439
468
 
655
684
    # group_amplitudes
656
685
    #===========================================================================
657
686
    @staticmethod
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"""