Package madgraph :: Package various :: Module rambo
[hide private]
[frames] | no frames]

Source Code for Module madgraph.various.rambo

  1  from __future__ import division 
  2  import math 
  3  import random 
  4   
5 -class FortranList(list):
6
7 - def __init__(self, min, max=None):
8 if max is None: 9 self.min = 1 10 self.max = min + 1 11 else: 12 self.min = min 13 self.max = max + 1 14 list.__init__(self,[0]*(self.max-self.min))
15 16
17 - def __getitem__(self, index):
18 assert self.min <= index < self.max, 'outside range %s <= %s < %s' % (self.min, index, self.max) 19 return list.__getitem__(self, index - self.min)
20
21 - def __setitem__(self, index, value):
22 assert self.min <= index < self.max 23 return list.__setitem__(self, index - self.min , value)
24
25 -class DoubleFortranList(FortranList):
26
27 - def __init__(self, min, max=(None,None)):
28 29 min1 = min[0] 30 max1 = max[0] 31 FortranList.__init__(self, min1, max1) 32 33 min2 = min[1] 34 max2 = max[1] 35 36 for i in range(len(self)): 37 list.__setitem__(self,i,FortranList(min2,max2))
38
39 - def __getitem__(self, index):
40 var1 = index[0] 41 var2 = index[1] 42 list1 = FortranList.__getitem__(self, var1) 43 return list1.__getitem__(var2)
44
45 - def __setitem__(self, index, value):
46 var1 = index[0] 47 var2 = index[1] 48 49 list1 = FortranList.__getitem__(self, var1) 50 list1.__setitem__(var2, value)
51 52
53 -class RAMBOError(Exception):
54 """ A Error class for RAMBO routine """ 55 pass
56
57 -def RAMBO(N,ET,XM):
58 """*********************************************************************** 59 * RAMBO * 60 * RA(NDOM) M(OMENTA) B(EAUTIFULLY) O(RGANIZED) * 61 * * 62 * A DEMOCRATIC MULTI-PARTICLE PHASE SPACE GENERATOR * 63 * AUTHORS: S.D. ELLIS, R. KLEISS, W.J. STIRLING * 64 * -- ADJUSTED BY HANS KUIJF, WEIGHTS ARE LOGARITHMIC (20-08-90) * 65 * THIS IS PY VERSION 1.0 - WRITTEN BY O. MATTELAER * 66 * * 67 * N = NUMBER OF PARTICLES * 68 * ET = TOTAL CENTRE-OF-MASS ENERGY * 69 * XM = PARTICLE MASSES ( DIM=NEXTERNAL-nincoming ) * 70 * RETURN * 71 * P = PARTICLE MOMENTA ( DIM=(4,NEXTERNAL-nincoming) ) * 72 * WT = WEIGHT OF THE EVENT * 73 ***********************************************************************""" 74 # RUN PARAMETER 75 acc = 1e-14 76 itmax = 6 77 ibegin = 0 78 iwarn = FortranList(5) 79 Nincoming = 2 80 81 82 # Object Initialization 83 Z = FortranList(N) 84 Q = DoubleFortranList((4,N)) 85 P = DoubleFortranList((4,N)) 86 R = FortranList(4) 87 B = FortranList(3) 88 XM2 = FortranList(N) 89 P2 = FortranList(N) 90 E = FortranList(N) 91 V= FortranList(N) 92 IWARN = [0,0] 93 # Check input object 94 assert isinstance(XM, FortranList) 95 assert XM.min == 1 96 assert XM.max == N+1 97 98 # INITIALIZATION STEP: FACTORIALS FOR THE PHASE SPACE WEIGHT 99 if not ibegin: 100 ibegin = 1 101 twopi = 8 * math.atan(1) 102 po2log = math.log(twopi/4) 103 Z[2] = po2log 104 for k in range(3, N+1): 105 Z[k] = Z[k-1] + po2log - 2.*math.log(k-2) - math.log(k-1) 106 107 # CHECK ON THE NUMBER OF PARTICLES 108 assert 1 < N < 101 109 110 # CHECK WHETHER TOTAL ENERGY IS SUFFICIENT; COUNT NONZERO MASSES 111 xmt = 0 112 nm = 0 113 for i in range(1,N+1): 114 if XM[i] != 0: 115 nm +=1 116 xmt += abs(XM[i]) 117 118 if xmt > ET: 119 raise RAMBOError, ' Not enough energy in this case' 120 121 # 122 # THE PARAMETER VALUES ARE NOW ACCEPTED 123 # 124 # GENERATE N MASSLESS MOMENTA IN INFINITE PHASE SPACE 125 for i in range(1,N+1): 126 r1=random_nb(1) 127 c = 2 * r1 -1 128 s = math.sqrt(1 - c**2) 129 f = twopi * random_nb(2) 130 r1 = random_nb(3) 131 r2 = random_nb(4) 132 133 Q[(4,i)]=-math.log(r1*r2) 134 Q[(3,i)]= Q[(4,i)]*c 135 Q[(2,i)]=Q[(4,i)]*s*math.cos(f) 136 Q[(1,i)]=Q[(4,i)]*s*math.sin(f) 137 138 # CALCULATE THE PARAMETERS OF THE CONFORMAL TRANSFORMATION 139 for i in range(1, N+1): 140 for k in range(1,5): 141 R[k] = R[k] + Q[(k,i)] 142 rmas = math.sqrt(R[4]**2-R[3]**2-R[2]**2-R[1]**2) 143 for k in range(1,4): 144 B[k] = - R[k]/rmas 145 146 g = R[4] / rmas 147 a = 1.0 / (1+g) 148 x = ET / rmas 149 150 # TRANSFORM THE Q'S CONFORMALLY INTO THE P'S 151 for i in range(1, N+1): 152 bq = B[1]*Q[(1,i)]+B[2]*Q[(2,i)]+B[3]*Q[(3,i)] 153 for k in range(1,4): 154 P[k,i] = x*(Q[(k,i)]+B[k]*(Q[(4,i)]+a*bq)) 155 P[(4,i)] = x*(g*Q[(4,i)]+bq) 156 157 # CALCULATE WEIGHT AND POSSIBLE WARNINGS 158 wt = po2log 159 if N != 2: 160 wt = (2 * N-4) * math.log(ET) + Z[N] 161 if wt < -180 and iwarn[1] < 5: 162 print "RAMBO WARNS: WEIGHT = EXP(%f20.9) MAY UNDERFLOW" % wt 163 iwarn[1] += 1 164 if wt > 174 and iwarn[2] < 5: 165 print " RAMBO WARNS: WEIGHT = EXP(%f20.9) MAY OVERFLOW" % wt 166 iwarn[2] += 1 167 168 169 # RETURN FOR WEIGHTED MASSLESS MOMENTA 170 if nm == 0: 171 return P, wt 172 173 174 # MASSIVE PARTICLES: RESCALE THE MOMENTA BY A FACTOR X 175 xmax = math.sqrt(1-(xmt/ET)**2) 176 for i in range(1,N+1): 177 XM2[i] = XM[i] **2 178 P2[i] = P[(4,i)]**2 179 n_iter = 0 180 x= xmax 181 accu = ET * acc 182 183 while 1: 184 f0 = -ET 185 g0 = 0 186 x2 = x**2 187 for i in range(1, N+1): 188 E[i] = math.sqrt(XM2[i]+x2*P2[i]) 189 f0 += E[i] 190 g0 += P2[i]/E[i] 191 if abs(f0) <= accu: 192 break 193 n_iter += 1 194 if n_iter > itmax: 195 print "RAMBO WARNS: %s ITERATIONS DID NOT GIVE THE DESIRED ACCURACY = %s" \ 196 %(n_iter , f0) 197 break 198 x=x-f0/(x*g0) 199 for i in range(1, N+1): 200 V[i] = x * P[(4,i)] 201 for k in range(1,4): 202 P[(k,i)] = x * P[(k,i)] 203 P[(4,i)] = E[i] 204 205 # CALCULATE THE MASS-EFFECT WEIGHT FACTOR 206 wt2 = 1. 207 wt3 = 0. 208 for i in range(1, N+1): 209 wt2 *= V[i]/E[i] 210 wt3 += V[i]**2/E[i] 211 wtm = (2.*N-3.)*math.log(x)+math.log(wt2/wt3*ET) 212 213 # RETURN FOR WEIGHTED MASSIVE MOMENTA 214 wt += wtm 215 if(wt < -180 and iwarn[3] < 5): 216 print " RAMBO WARNS: WEIGHT = EXP(%s) MAY UNDERFLOW" % wt 217 iwarn[3] += 1 218 if(wt > 174 and iwarn[4] > 5): 219 print " RAMBO WARNS: WEIGHT = EXP(%s) MAY OVERFLOW" % wt 220 iwarn[4] += 1 221 222 # RETURN 223 return P, wt
224
225 -def random_nb(value):
226 """ random number """ 227 output = 0 228 while output < 1e-16: 229 output= random.uniform(0,1) 230 return output
231