Ejemplo n.º 1
0
    def __init__(self, start_proc = None, remove_reals = True):
        """initialization: starts either from an amplitude or a process,
        then init the needed variables.
        remove_borns tells if the borns not needed for integration will be removed
        from the born list (mainly used for testing)"""
                
        self.splittings = {}
        self.reals = []
        self.fks_dirs = []
        self.leglist = []
        self.myorders = {}
        self.pdg_codes = []
        self.colors = []
        self.nlegs = 0
        self.fks_ipos = []
        self.fks_j_from_i = {}
        self.real_amps = []
        self.remove_reals = remove_reals
        self.nincoming = 0
        self.virt_amp = None

        if not remove_reals in [True, False]:
            raise fks_common.FKSProcessError(\
                    'Not valid type for remove_reals in FKSProcess')
        
        if start_proc:
            if isinstance(start_proc, MG.Process):
                self.born_proc = fks_common.sort_proc(start_proc) 
                self.born_amp = diagram_generation.Amplitude(self.born_proc)
            elif isinstance(start_proc, diagram_generation.Amplitude):
                self.born_proc = fks_common.sort_proc(start_proc.get('process'))
                self.born_amp = diagram_generation.Amplitude(self.born_proc)
            else:
                raise fks_common.FKSProcessError(\
                    'Not valid start_proc in FKSProcess')

            self.born_proc.set('legs_with_decays', MG.LegList())

            self.leglist = fks_common.to_fks_legs(
                                    self.born_proc['legs'], self.born_proc['model'])
            self.nlegs = len(self.leglist)
            self.pdg_codes = [leg.get('id') for leg in self.leglist]
            self.colors = [leg.get('color') for leg in self.leglist]
            self.isr = set([leg.get('color') for leg in self.leglist if not leg.get('state')]) != set([1])
            self.fsr = set([leg.get('color') for leg in self.leglist if leg.get('state')]) != set([1])
            for leg in self.leglist:
                if not leg['state']:
                    self.nincoming += 1
            self.orders = self.born_amp['process']['orders']
            # this is for cases in which the user specifies e.g. QED=0
            if sum(self.orders.values()) == 0:
                self.orders = fks_common.find_orders(self.born_amp)
                
            self.ndirs = 0
            for order in self.born_proc.get('perturbation_couplings'):
                self.find_reals(order)
Ejemplo n.º 2
0
    def __init__(self, fksrealproc=None, real_me_list = [], real_amp_list =[], **opts):
        """constructor, starts from a fksrealproc and then calls the
        initialization for HelasMatrixElement.
        Sets i/j fks and the permutation.
        real_me_list and real_amp_list are the lists of pre-generated matrix elements in 1-1 
        correspondance with the amplitudes"""
        
        if fksrealproc != None:
            self.isfinite = False
            self.colors = fksrealproc.colors
            self.charges = fksrealproc.charges
            self.fks_infos = fksrealproc.fks_infos
            self.is_to_integrate = fksrealproc.is_to_integrate

            if len(real_me_list) != len(real_amp_list):
                raise fks_common.FKSProcessError(
                        'not same number of amplitudes and matrix elements: %d, %d' % \
                                (len(real_amp_list), len(real_me_list)))
            if real_me_list and real_amp_list:
                self.matrix_element = copy.deepcopy(real_me_list[real_amp_list.index(fksrealproc.amplitude)])
                self.matrix_element['processes'] = copy.deepcopy(self.matrix_element['processes'])
            else:
                logger.info('generating matrix element...')
                self.matrix_element = helas_objects.HelasMatrixElement(
                                                  fksrealproc.amplitude, **opts)
                #generate the color for the real
                self.matrix_element.get('color_basis').build(
                                    self.matrix_element.get('base_amplitude'))
                self.matrix_element.set('color_matrix',
                                 color_amp.ColorMatrix(
                                    self.matrix_element.get('color_basis')))
            #self.fks_j_from_i = fksrealproc.find_fks_j_from_i()
            self.fks_j_from_i = fksrealproc.fks_j_from_i
Ejemplo n.º 3
0
 def get_leg_j(self): #test written
     """Returns leg corresponding to j fks.
     An error is raised if the fks_infos list has more than one entry"""
     if len(self.fks_infos) > 1:
         raise fks_common.FKSProcessError(\
                 'get_leg_j should only be called before combining processes')
     return self.process.get('legs')[self.fks_infos[0]['j'] - 1]
Ejemplo n.º 4
0
 def find_reals(self, pert_order):
     """finds the FKS real configurations for a given process"""
     if range(len(self.leglist)) != [l['number']-1 for l in self.leglist]:
         raise fks_common.FKSProcessError('Disordered numbers of leglist')
     for i in self.leglist:
         i_i = i['number'] - 1
         self.reals.append([])
         self.splittings[i_i] = fks_common.find_splittings(i, self.born_proc['model'], {}, pert_order)
         for split in self.splittings[i_i]:
             self.reals[i_i].append(
                         fks_common.insert_legs(self.leglist, i, split,pert=pert_order))
Ejemplo n.º 5
0
    def find_reals(self, pert_order):
        """finds the FKS real configurations for a given process"""
        if list(range(len(self.leglist))) != [l['number']-1 for l in self.leglist]:
            raise fks_common.FKSProcessError('Disordered numbers of leglist')

        if [ i['state'] for i in self.leglist].count(False) == 1:
            decay_process=True
        else:
            decay_process=False

        for i in self.leglist:
            i_i = i['number'] - 1
            self.reals.append([])
            if decay_process and not i['state']:
                self.splittings[i_i]=[]
            else:
                self.splittings[i_i] = fks_common.find_splittings(i, self.born_proc['model'], {}, pert_order)
            for split in self.splittings[i_i]:
                self.reals[i_i].append(
                            fks_common.insert_legs(self.leglist, i, split,pert=pert_order))
Ejemplo n.º 6
0
    def __init__(self, procdef=None, options={}):
        """Initializes the original multiprocess, then generates the amps for the 
        borns, then generate the born processes and the reals.
        Real amplitudes are stored in real_amplitudes according on the pdgs of their
        legs (stored in pdgs, so that they need to be generated only once and then reicycled
        """

        #swhich the other loggers off
        loggers_off = [logging.getLogger('madgraph.diagram_generation'), 
                       logging.getLogger('madgraph.loop_diagram_generation')]
        old_levels = [logg.level for logg in loggers_off]
        for logg in loggers_off:
            logg.setLevel(logging.WARNING)
        
        # OLP option
        olp='MadLoop'
        if 'OLP' in list(options.keys()):
            olp = options['OLP']
            del options['OLP']

        ncores_for_proc_gen = 0
        # ncores_for_proc_gen has the following meaning
        #   0 : do things the old way
        #   > 0 use ncores_for_proc_gen
        #   -1 : use all cores
        if 'ncores_for_proc_gen' in list(options.keys()):
            ncores_for_proc_gen = options['ncores_for_proc_gen']
            del options['ncores_for_proc_gen']

        try:
            # Now generating the borns for the first time.
            super(FKSMultiProcess, self).__init__(procdef, **options)

        except diagram_generation.NoDiagramException as error:
            # If no born, then this process most likely does not have any.
            raise NoBornException("Born diagrams could not be generated for the "+\
               self['process_definitions'][0].nice_string().replace('Process',\
               'process')+". Notice that aMC@NLO does not handle loop-induced"+\
               " processes yet, but you can still use MadLoop if you want to "+\
               "only generate them."+\
               " For this, use the 'virt=' mode, without multiparticle labels.")

        self['OLP'] = olp
        self['ncores_for_proc_gen'] = ncores_for_proc_gen
            
        #check process definition(s):
        # a process such as g g > g g will lead to real emissions 
        #   (e.g: u g > u g g ) which will miss some corresponding born,
        #   leading to non finite results
        perturbation = []
        for procdef in self['process_definitions']:
            soft_particles = []
            # do not warn for decay processes
            if [ i['state'] for i in procdef['legs']].count(False) == 1:
                continue
            for pert in procdef['perturbation_couplings']:
                if pert not in perturbation:
                    perturbation.append(pert)
                soft_particles.extend(\
                        fks_common.find_pert_particles_interactions(\
                    procdef['model'], pert)['soft_particles'])
                soft_particles_string = ', '.join( \
                    [procdef['model'].get('particle_dict')[id][\
                    {True:'name', False:'antiname'}[id >0] ] \
                    for id in sorted(soft_particles, reverse=True)])
            for leg in procdef['legs']:
                if any([id in soft_particles for id in leg['ids']]) \
                        and sorted(leg['ids']) != soft_particles:
                    logger.warning(('%s can have real emission processes ' + \
            'which are not finite.\nTo avoid this, please use multiparticles ' + \
            'when generating the process and be sure to include all the following ' + \
            'particles in the multiparticle definition:\n %s' ) \
               % (procdef.nice_string(), soft_particles_string) )
                    break
        for procdef in self['process_definitions']:
            procdef.set('orders', diagram_generation.MultiProcess.find_optimal_process_orders(procdef))

        amps = self.get('amplitudes')
        for i, amp in enumerate(amps):
            logger.info("Generating FKS-subtracted matrix elements for born process%s (%d / %d)" \
                % (amp['process'].nice_string(print_weighted=False).replace(\
                                                                 'Process', ''),
                 i + 1, len(amps)))

            born = FKSProcess(amp, ncores_for_proc_gen = self['ncores_for_proc_gen'])
            self['born_processes'].append(born)
            born.generate_reals(self['pdgs'], self['real_amplitudes'])

        if not self['ncores_for_proc_gen']:
            # old generation mode 

            born_pdg_list = [[l['id'] for l in born.born_proc['legs']] \
                    for born in self['born_processes'] ]

            for born in self['born_processes']:
                for real in born.real_amps:
                    real.find_fks_j_from_i(born_pdg_list)
            if amps:
                if self['process_definitions'][0].get('NLO_mode') == 'all':
                    self.generate_virtuals()
                
                elif not self['process_definitions'][0].get('NLO_mode') in ['all', 'real','LOonly']:
                    raise fks_common.FKSProcessError(\
                       "Not a valid NLO_mode for a FKSMultiProcess: %s" % \
                       self['process_definitions'][0].get('NLO_mode'))

                # now get the total number of diagrams
                n_diag_born = sum([len(amp.get('diagrams')) 
                         for amp in self.get_born_amplitudes()])
                n_diag_real = sum([len(amp.get('diagrams')) 
                         for amp in self.get_real_amplitudes()])
                n_diag_virt = sum([len(amp.get('loop_diagrams')) 
                         for amp in self.get_virt_amplitudes()])

                if n_diag_virt == 0 and n_diag_real ==0 and \
                        not self['process_definitions'][0].get('NLO_mode') == 'LOonly':
                    raise fks_common.FKSProcessError(
                            'This process does not have any correction up to NLO in %s'\
                            %','.join(perturbation))

                logger.info(('Generated %d subprocesses with %d real emission diagrams, ' + \
                            '%d born diagrams and %d virtual diagrams') % \
                                    (len(self['born_processes']), n_diag_real, n_diag_born, n_diag_virt))

            for i, logg in enumerate(loggers_off):
                logg.setLevel(old_levels[i])

        self['has_isr'] = any([proc.isr for proc in self['born_processes']])
        self['has_fsr'] = any([proc.fsr for proc in self['born_processes']])
Ejemplo n.º 7
0
    def find_reals_to_integrate(self): #test written
        """Finds double countings in the real emission configurations, sets the 
        is_to_integrate variable and if "self.remove_reals" is True removes the 
        not needed ones from the born list.
        """
        #find the initial number of real configurations
        ninit = len(self.real_amps)
        remove = self.remove_reals
        
        for m in range(ninit):
            for n in range(m + 1, ninit):
                real_m = self.real_amps[m]
                real_n = self.real_amps[n]
                if len(real_m.fks_infos) > 1 or len(real_m.fks_infos) > 1:
                    raise fks_common.FKSProcessError(\
                    'find_reals_to_integrate should only be called before combining processes')

                i_m = real_m.fks_infos[0]['i']
                j_m = real_m.fks_infos[0]['j']
                i_n = real_n.fks_infos[0]['i']
                j_n = real_n.fks_infos[0]['j']
                if j_m > self.nincoming and j_n > self.nincoming:
                    if (real_m.get_leg_i()['id'] == real_n.get_leg_i()['id'] \
                        and \
                        real_m.get_leg_j()['id'] == real_n.get_leg_j()['id']) \
                        or \
                       (real_m.get_leg_i()['id'] == real_n.get_leg_j()['id'] \
                        and \
                        real_m.get_leg_j()['id'] == real_n.get_leg_i()['id']):
                        if i_m > i_n:
                            print(real_m.get_leg_i()['id'], real_m.get_leg_j()['id'])
                            if real_m.get_leg_i()['id'] == -real_m.get_leg_j()['id']:
                                self.real_amps[m].is_to_integrate = False
                            else:
                                self.real_amps[n].is_to_integrate = False
                        elif i_m == i_n and j_m > j_n:
                            print(real_m.get_leg_i()['id'], real_m.get_leg_j()['id'])
                            if real_m.get_leg_i()['id'] == -real_m.get_leg_j()['id']:
                                self.real_amps[m].is_to_integrate = False
                            else:
                                self.real_amps[n].is_to_integrate = False
                        # in case of g(a) > ffx splitting, keep the lowest ij
                        elif i_m == i_n and j_m == j_n and \
                          not real_m.get_leg_j()['self_antipart'] and \
                          not real_m.get_leg_i()['self_antipart']:
                            if real_m.fks_infos[0]['ij'] > real_n.fks_infos[0]['ij']:
                                real_m.is_to_integrate = False
                            else:
                                real_n.is_to_integrate = False
                        else:
                            if real_m.get_leg_i()['id'] == -real_m.get_leg_j()['id']:
                                self.real_amps[n].is_to_integrate = False
                            else:
                                self.real_amps[m].is_to_integrate = False
                         # self.real_amps[m].is_to_integrate = False
                elif j_m <= self.nincoming and j_n == j_m:
                    if real_m.get_leg_i()['id'] == real_n.get_leg_i()['id'] and \
                       real_m.get_leg_j()['id'] == real_n.get_leg_j()['id']:
                        if i_m > i_n:
                            self.real_amps[n].is_to_integrate = False
                        else:
                            self.real_amps[m].is_to_integrate = False
        if remove:
            newreal_amps = []
            for real in self.real_amps:
                if real.is_to_integrate:
                    newreal_amps.append(real)
            self.real_amps = newreal_amps
Ejemplo n.º 8
0
    def __init__(self, start_proc = None, remove_reals = True, ncores_for_proc_gen=0):
        """initialization: starts either from an amplitude or a process,
        then init the needed variables.
        remove_borns tells if the borns not needed for integration will be removed
        from the born list (mainly used for testing)
        ncores_for_proc_gen has the following meaning
           0 : do things the old way
           > 0 use ncores_for_proc_gen
           -1 : use all cores
        """
                
        self.splittings = {}
        self.reals = []
        self.fks_dirs = []
        self.leglist = []
        self.myorders = {}
        self.pdg_codes = []
        self.colors = [] # color
        self.charges = [] # charge
        self.nlegs = 0
        self.fks_ipos = []
        self.fks_j_from_i = {}
        self.real_amps = []
        self.remove_reals = remove_reals
        self.nincoming = 0
        self.virt_amp = None
        self.perturbation = 'QCD'
        self.ncores_for_proc_gen = ncores_for_proc_gen

        if not remove_reals in [True, False]:
            raise fks_common.FKSProcessError(\
                    'Not valid type for remove_reals in FKSProcess')

        if start_proc:
            if isinstance(start_proc, MG.Process):
                pertur = start_proc['perturbation_couplings']
                if pertur:
                    self.perturbation = sorted(pertur)[0]
                self.born_proc = fks_common.sort_proc(start_proc,pert = self.perturbation)
                # filter in Amplitude will legs sorted in bornproc
                bornproc = copy.copy(self.born_proc) # deepcopy might let T -> array
                assert bornproc==self.born_proc
                self.born_amp = diagram_generation.Amplitude(bornproc)
            elif isinstance(start_proc, diagram_generation.Amplitude):
                pertur = start_proc.get('process')['perturbation_couplings']
                if pertur:
                    self.perturbation = sorted(pertur)[0]
                self.born_proc = fks_common.sort_proc(start_proc.get('process'),\
                                                      pert = self.perturbation)
                # filter in Amplitude will legs sorted in bornproc
                bornproc = copy.copy(self.born_proc)
                assert bornproc == self.born_proc
                self.born_amp = diagram_generation.Amplitude(bornproc)
            else:
                raise fks_common.FKSProcessError(\
                    'Not valid start_proc in FKSProcess')
            self.born_proc.set('legs_with_decays', MG.LegList())

            self.leglist = fks_common.to_fks_legs(
                                    self.born_proc['legs'], self.born_proc['model'])
            self.nlegs = len(self.leglist)
            self.pdg_codes = [leg.get('id') for leg in self.leglist]
            if self.perturbation == 'QCD':
                self.colors = [leg.get('color') for leg in self.leglist]
                # in QCD, charge is irrelevant but impact the combine process !
                self.charges = [0. for leg in self.leglist]
                color = 'color'
                zero = 1
            elif self.perturbation == 'QED':
                self.colors = [leg.get('color') for leg in self.leglist]
                self.charges = [leg.get('charge') for leg in self.leglist]
                color = 'charge'
                zero = 0.
            # special treatment of photon is needed !
            self.isr = set([leg.get(color) for leg in self.leglist if not leg.get('state')]) != set([zero])
            self.fsr = set([leg.get(color) for leg in self.leglist if leg.get('state')]) != set([zero])
            for leg in self.leglist:
                if not leg['state']:
                    self.nincoming += 1
            self.orders = self.born_amp['process']['orders']
            # this is for cases in which the user specifies e.g. QED=0
            if sum(self.orders.values()) == 0:
                self.orders = fks_common.find_orders(self.born_amp)
                
            self.ndirs = 0
            # generate reals, when the mode is not LOonly
            # when is LOonly it is supposed to be a 'fake' NLO process
            # e.g. to be used in merged sampels at high multiplicities
            if self.born_proc['NLO_mode'] != 'LOonly':
                for order in self.born_proc.get('perturbation_couplings'):
                    self.find_reals(order)