Package aloha :: Module aloha_fct
[hide private]
[frames] | no frames]

Source Code for Module aloha.aloha_fct

  1  ################################################################################ 
  2  # 
  3  # Copyright (c) 2012 The ALOHA Development team and Contributors 
  4  # 
  5  # This file is a part of the ALOHA project, an application which  
  6  # automatically generates HELAS ROUTINES 
  7  # 
  8  # It is subject to the ALOHA license which should accompany this  
  9  # distribution. 
 10  # 
 11  # 
 12  ################################################################################ 
 13  from __future__ import absolute_import 
 14  from __future__ import print_function 
 15  from aloha.aloha_object import * 
 16  import aloha.aloha_lib as aloha_lib 
 17  import cmath 
 18  from six.moves import range 
 19   
20 -class WrongFermionFlow(Exception):
21 pass
22 23 ################################################################################ 24 ## CHECK FLOW VALIDITY OF A LORENTZ STRUCTURE 25 ################################################################################
26 -def get_fermion_flow(expression, nb_fermion):
27 """Get the fermion flow follows the UFO convention 28 {I1:O1, I2:O2,...}""" 29 30 assert nb_fermion != 0 and (nb_fermion % 2) == 0 31 # Need to expand the expression in order to have a simple sum of expression 32 try: 33 expr = eval(expression) 34 except Exception as error: 35 print(error) 36 return 37 expr = expr.simplify() 38 #expr is now a valid AddVariable object if they are a sum or 39 if expr.vartype != 1: # not AddVariable 40 expr = [expr] # put in a list to allow comparison 41 42 out = {} 43 for term in expr: 44 if term.vartype == 0: # Single object 45 if not term.spin_ind in [[1,2], [2,1]]: 46 raise WrongFermionFlow('Fermion should be the first particles of any interactions') 47 if isinstance(term, (Gamma, Gamma5, Sigma)): 48 if term.spin_ind == [2,1]: 49 out[1] = 2 50 else: 51 out[2] = 1 52 elif isinstance(term, Identity): 53 out[1] = 2 54 55 elif term.vartype == 2: # product of object 56 link, rlink = {}, {} 57 for obj in term: 58 obj = aloha_lib.KERNEL.objs[obj] 59 if not obj.spin_ind: 60 continue 61 ind1, ind2 = obj.spin_ind 62 if ind1 not in list(link.keys()): 63 link[ind1] = ind2 64 else: 65 raise WrongFermionFlow('a spin indices should appear only once on the left indices of an object: %s' % expr) 66 if ind2 not in list(rlink.keys()): 67 rlink[ind2] = ind1 68 else: 69 raise WrongFermionFlow('a spin indices should appear only once on the left indices of an object: %s' % expr) 70 71 for i in range(1, nb_fermion): 72 if i in list(out.keys()) or i in list(out.values()): 73 continue 74 old = [] 75 pos = i 76 while 1: 77 old.append(pos) 78 if pos in list(link.keys()) and link[pos] not in old: 79 pos = link[pos] 80 elif pos in list(rlink.keys()) and rlink[pos] not in old: 81 pos = rlink[pos] 82 else: 83 if pos in list(link.keys()) and i in list(rlink.keys()): 84 out[i] = pos 85 break 86 elif pos in list(rlink.keys()) and i in list(link.keys()): 87 out[pos] = i 88 break 89 else: 90 raise WrongFermionFlow('incoherent IO state: %s' % expr) 91 if not len(out) == nb_fermion //2: 92 raise WrongFermionFlow('Not coherent Incoming/outcoming fermion flow') 93 return out
94 95 96
97 -def check_flow_validity(expression, nb_fermion):
98 """Check that the fermion flow follows the UFO convention 99 1) Only one flow is defined and is 1 -> 2, 3 -> 4, ... 100 2) that 1/3/... are on the left side of any Gamma matrices 101 """ 102 103 assert nb_fermion != 0 and (nb_fermion % 2) == 0 104 105 # Need to expand the expression in order to have a simple sum of expression 106 try: 107 expr = eval(expression) 108 except Exception: 109 return 110 expr = expr.simplify() 111 #expr is now a valid AddVariable object if they are a sum or 112 if expr.vartype != 1: # not AddVariable 113 expr = [expr] # put in a list to allow comparison 114 115 for term in expr: 116 if term.vartype == 0: # Single object 117 if not term.spin_ind in [[1,2], [2,1]]: 118 raise WrongFermionFlow('Fermion should be the first particles of any interactions') 119 if isinstance(term, (Gamma, Gamma5, Sigma)): 120 if not term.spin_ind == [2,1]: 121 raise WrongFermionFlow('Not coherent Incoming/outcoming fermion flow') 122 123 elif term.vartype == 2: # product of object 124 link, rlink = {}, {} 125 for obj in term: 126 obj = aloha_lib.KERNEL.objs[obj] 127 if not obj.spin_ind: 128 continue 129 ind1, ind2 = obj.spin_ind 130 if isinstance(obj, (Gamma, Sigma)): 131 if (ind1 in range(1, nb_fermion+1) and ind1 % 2 == 1) or \ 132 (ind2 in range(2, nb_fermion+1) and ind2 % 2 == 0 ): 133 raise WrongFermionFlow('Not coherent Incoming/outcoming fermion flow') 134 if ind1 not in list(link.keys()): 135 link[ind1] = ind2 136 else: 137 rlink[ind1] = ind2 138 if ind2 not in list(link.keys()): 139 link[ind2] = ind1 140 else: 141 rlink[ind2] = ind1 142 for i in range(1, nb_fermion,2): 143 old = [] 144 pos = i 145 while 1: 146 old.append(pos) 147 if pos in list(link.keys()) and link[pos] not in old: 148 pos = link[pos] 149 elif pos in list(rlink.keys()) and rlink[pos] not in old: 150 pos = rlink[pos] 151 elif pos != i+1: 152 raise WrongFermionFlow('Not coherent Incoming/outcoming fermion flow') 153 elif pos == i+1: 154 break
155
156 -def guess_routine_from_name(names):
157 """ return (UFO name, tag , offshell) from a given name """ 158 159 output =[] 160 for name in names: 161 if name.startswith('MP_'): 162 name = name[3:] 163 tags = ['MP_'] 164 else: 165 tags = [] 166 167 data = name.split('_') 168 if len(data) == 2: 169 main, offshell = data 170 multiple = [] 171 else: 172 main, multiple, offshell = data[0], data[1:-1],data[-1] 173 174 # search for tag allow tag [L, L$, C$, MP] 175 allow_tag = ['C1','C2','C3','C4','C5','C6','C7'] 176 allow_tag += ['L%s' % i for i in range(1,20)] 177 allow_tag += ['P%s' % i for i in range(0,20)] 178 allow_tag += ['L'] 179 tags = [] 180 181 len_tag = -1 182 while len(tags) != len_tag: 183 len_tag = len(tags) 184 for tag in allow_tag: 185 if multiple and multiple[-1].endswith(tag): 186 multiple[-1] = multiple[-1][:-len(tag)] 187 tags.append(tag) 188 break 189 elif main.endswith(tag): 190 main = main[:-len(tag)] 191 tags.append(tag) 192 break 193 194 195 # create the correct lorentz 196 lorentz = [main] 197 if multiple: 198 base = main 199 while base[-1].isdigit(): 200 base = base[:-1] 201 for nb in multiple: 202 lorentz.append('%s%s' % (base, nb)) 203 204 # add in the results 205 output.append((tuple(lorentz), tuple(tags), int(offshell))) 206 return output
207