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