diff --git a/Models/Feynrules/python/ufo2peg/check_lorentz.py b/Models/Feynrules/python/ufo2peg/check_lorentz.py --- a/Models/Feynrules/python/ufo2peg/check_lorentz.py +++ b/Models/Feynrules/python/ufo2peg/check_lorentz.py @@ -1,3084 +1,3431 @@ import itertools,cmath,re,sys,copy from .helpers import SkipThisVertex,extractAntiSymmetricIndices,def_from_model from .converter import py2cpp from .lorentzparser import parse_lorentz import sympy,string from string import Template from sympy import Matrix,Symbol imap=["t","x","y","z"] +RSDotProduct = Template("${s}ts${si}*${v}t-${s}xs${si}*${v}x-${s}ys${si}*${v}y-${s}zs${si}*${v}z") + vTemplateT="""\ if(sbarW{iloc}.id()=={id}) {{ return ({res})*({cf}); }} else {{ return ({resT})*({cf}); }} """ vTemplate4="""\ if(id{iloc1}=={id1}) {{ if(id{iloc2}=={id2}) {{ return ({res1})*({cf}); }} else {{ return ({res2})*({cf}); }} }} else {{ if(id{iloc2}=={id2}) {{ return ({res3})*({cf}); }} else {{ return ({res4})*({cf}); }} }} """ vecTemplate="""\ LorentzPolarizationVector vtemp = {res}; Energy2 p2 = P{iloc}.m2(); Complex fact = -Complex(0.,1.)*({cf})*propagator(iopt,p2,out,mass,width); if(mass.real() < ZERO) mass = (iopt==5) ? ZERO : out->mass(); complex<Energy2> mass2 = sqr(mass); if(mass.real()==ZERO) {{ vtemp =fact*vtemp; }} else {{ complex<Energy> dot = P{iloc}*vtemp; vtemp = fact*(vtemp-dot/mass2*P{iloc}); }} return VectorWaveFunction(P{iloc},out,vtemp.x(),vtemp.y(),vtemp.z(),vtemp.t()); """ vecTTemplate="""\ LorentzPolarizationVector vtemp; if(sbarW{isp}.id()=={id}) {{ vtemp = {res}; }} else {{ vtemp = {resT}; }} Energy2 p2 = P{iloc}.m2(); Complex fact = -Complex(0.,1.)*({cf})*propagator(iopt,p2,out,mass,width); if(mass.real() < ZERO) mass = (iopt==5) ? ZERO : out->mass(); complex<Energy2> mass2 = sqr(mass); if(mass.real()==ZERO) {{ vtemp =fact*vtemp; }} else {{ complex<Energy> dot = P{iloc}*vtemp; vtemp = fact*(vtemp-dot/mass2*P{iloc}); }} return VectorWaveFunction(P{iloc},out,vtemp.x(),vtemp.y(),vtemp.z(),vtemp.t()); """ sTemplate="""\ if(mass.real() < ZERO) mass = (iopt==5) ? ZERO : out->mass(); Energy2 p2 = P{iloc}.m2(); Complex fact = Complex(0.,1.)*({cf})*propagator(iopt,p2,out,mass,width); Lorentz{offTypeA}<double> newSpin = fact*({res}); return {offTypeB}(P{iloc},out,newSpin); """ RSTemplate="""\ if(mass.real() < ZERO) mass = (iopt==5) ? ZERO : out->mass(); Energy2 p2 = P{iloc}.m2(); Complex fact = Complex(0.,1.)*({cf})*propagator(iopt,p2,out,mass,width); Lorentz{offTypeA}<double> newSpin = fact*({res}); return {offTypeB}(P{iloc},out,newSpin); """ sTTemplate="""\ if(mass.real() < ZERO) mass = (iopt==5) ? ZERO : out->mass(); Energy2 p2 = P{iloc}.m2(); Complex fact = Complex(0.,1.)*({cf})*propagator(iopt,p2,out,mass,width); if(out->id()=={id}) {{ Lorentz{offTypeA}<double> newSpin = fact*({res}); return {offTypeB}(P{iloc},out,newSpin); }} else {{ Lorentz{offTypeA}<double> newSpin = fact*({resT}); return {offTypeB}(P{iloc},out,newSpin); }} """ scaTemplate="""\ if(mass.real() < ZERO) mass = (iopt==5) ? ZERO : out->mass(); Energy2 p2 = P{iloc}.m2(); Complex fact = Complex(0.,1.)*({cf})*propagator(iopt,p2,out,mass,width); complex<double> output = fact*({res}); return ScalarWaveFunction(P{iloc},out,output); """ scaTTemplate="""\ if(mass.real() < ZERO) mass = (iopt==5) ? ZERO : out->mass(); Energy2 p2 = P{iloc}.m2(); Complex fact = Complex(0.,1.)*({cf})*propagator(iopt,p2,out,mass,width); complex<double> output = sbarW{isp}.id()=={id} ? fact*({res}) : fact*({resT}); }} return ScalarWaveFunction(P{iloc},out,output); """ tenTemplate="""\ if(mass.real() < ZERO) mass = (iopt==5) ? ZERO : out->mass(); InvEnergy2 OM{iloc} = mass.real()==ZERO ? InvEnergy2(ZERO) : 1./sqr(mass.real()); Energy2 p2 = P{iloc}.m2(); Complex fact = Complex(0.,1.)*({cf})*propagator(iopt,p2,out,mass,width); LorentzTensor<double> output = fact*({res}); return TensorWaveFunction(P{iloc},out,output); """ tenTTemplate="""\ if(mass.real() < ZERO) mass = (iopt==5) ? ZERO : out->mass(); InvEnergy2 OM{iloc} = mass.real()==ZERO ? InvEnergy2(ZERO) : 1./sqr(mass); Energy2 p2 = P{iloc}.m2(); Complex fact = Complex(0.,1.)*({cf})*propagator(iopt,p2,out,mass,width); LorentzTensor<double> output = sbarW{isp}.id()=={id} ? fact*({res}) : fact*({resT}); return TensorWaveFunction(P{iloc},out,output); """ # various strings for matrixes I4 = "Matrix([[1,0,0,0],[0,1,0,0],[0,0,1,0],[0,0,0,1]])" G5 = "Matrix([[-1,0,0,0],[0,-1,0,0],[0,0,1,0],[0,0,0,1]])" PM = "Matrix([[1,0,0,0],[0,1,0,0],[0,0,0,0],[0,0,0,0]])" PP = "Matrix([[0,0,0,0],[0,0,0,0],[0,0,1,0],[0,0,0,1]])" vslash = Template("Matrix([[0,0,${v}tmz,-${v}xmy],[0,0,-${v}xpy,${v}tpz],[${v}tpz,${v}xmy,0,0],[${v}xpy,${v}tmz,0,0]])") vslashS = Template("${v}tpz=Symbol(\"${v}tpz\")\n${v}tmz=Symbol(\"${v}tmz\")\n${v}xpy=Symbol(\"${v}xpy\")\n${v}xmy=Symbol(\"${v}xmy\")\n") momCom = Template("${v}t = Symbol(\"${v}t\")\n${v}x = Symbol(\"${v}x\")\n${v}y = Symbol(\"${v}y\")\n${v}z = Symbol(\"${v}z\")\n") vslashD = Template("complex<${var}> ${v}tpz = ${v}.t()+${v}.z();\n complex<${var}> ${v}tmz = ${v}.t()-${v}.z();\n complex<${var}> ${v}xpy = ${v}.x()+Complex(0.,1.)*${v}.y();\n complex<${var}> ${v}xmy = ${v}.x()-Complex(0.,1.)*${v}.y();") vslashM = Template("Matrix([[$m,0,${v}tmz,-${v}xmy],[0,$m,-${v}xpy,${v}tpz],[${v}tpz,${v}xmy,$m,0],[${v}xpy,${v}tmz,0,$m]])") vslashM2 = Template("Matrix([[$m,0,-${v}tmz,${v}xmy],[0,$m,${v}xpy,-${v}tpz],[-${v}tpz,-${v}xmy,$m,0],[-${v}xpy,-${v}tmz,0,$m]])") vslashMS = Template("${v}tpz=Symbol(\"${v}tpz\")\n${v}tmz=Symbol(\"${v}tmz\")\n${v}xpy=Symbol(\"${v}xpy\")\n${v}xmy=Symbol(\"${v}xmy\")\n${m}=Symbol(\"${m}\")\nO${m}=Symbol(\"O${m}\")\n") -rslash = Template("Matrix([[$m,0,${v}tmz,-${v}xmy],[0,$m,-${v}xpy,${v}tpz],[${v}tpz,${v}xmy,$m,0],[${v}xpy,${v}tmz,0,$m]])*( (ETA(B!,A!)-2/3*O${m}**2*${v}A!*${v}B!)*Matrix([[1,0,0,0],[0,1,0,0],[0,0,1,0],[0,0,0,1]]) -1/3*R${loc}A*R${loc}B -1/3*O${m}*(${v}B!*R${loc}A-${v}A!*R${loc}B))") -rslash2 = Template("Matrix([[$m,0,-${v}tmz,${v}xmy],[0,$m,${v}xpy,-${v}tpz],[-${v}tpz,-${v}xmy,$m,0],[-${v}xpy,-${v}tmz,0,$m]])*( (ETA(B!,A!)-2/3*O${m}**2*${v}B!*${v}A!)*Matrix([[1,0,0,0],[0,1,0,0],[0,0,1,0],[0,0,0,1]]) -1/3*R${loc}B*R${loc}A +1/3*O${m}*(${v}A!*R${loc}B-${v}B!*R${loc}A))") +rslash = Template("Matrix([[$m,0,${v}tmz,-${v}xmy],[0,$m,-${v}xpy,${v}tpz],[${v}tpz,${v}xmy,$m,0],[${v}xpy,${v}tmz,0,$m]])*( ($${eta}-2/3*O${m}**2*${v}$${A}*${v}$${B})*Matrix([[1,0,0,0],[0,1,0,0],[0,0,1,0],[0,0,0,1]]) -1/3*$${DA}*$${DB} -1/3*O${m}*(${v}$${B}*$${DA}-${v}$${A}*$${DB}))") +rslashB = Template("Matrix([[$m,0,${v}tmz,-${v}xmy],[0,$m,-${v}xpy,${v}tpz],[${v}tpz,${v}xmy,$m,0],[${v}xpy,${v}tmz,0,$m]])*( (${v2}$${A}-2/3*O${m}**2*${v}$${A}*${dot})*Matrix([[1,0,0,0],[0,1,0,0],[0,0,1,0],[0,0,0,1]]) -1/3*$${DA}*${DB} -1/3*O${m}*(${dot}*$${DA}-${v}$${A}*${DB}))") + + + +rslash2 = Template("Matrix([[$m,0,-${v}tmz,${v}xmy],[0,$m,${v}xpy,-${v}tpz],[-${v}tpz,-${v}xmy,$m,0],[-${v}xpy,-${v}tmz,0,$m]])*( ($${eta}-2/3*O${m}**2*${v}$${A}*${v}$${B})*Matrix([[1,0,0,0],[0,1,0,0],[0,0,1,0],[0,0,0,1]]) -1/3*$${DA}*$${DB} +1/3*O${m}*(${v}$${B}*$${DA}-${v}$${A}*$${DB}))") +rslash2B = Template("Matrix([[$m,0,-${v}tmz,${v}xmy],[0,$m,${v}xpy,-${v}tpz],[-${v}tpz,-${v}xmy,$m,0],[-${v}xpy,-${v}tmz,0,$m]])*( (${v2}$${B}-2/3*O${m}**2*${dot}*${v}$${B})*Matrix([[1,0,0,0],[0,1,0,0],[0,0,1,0],[0,0,0,1]]) -1/3*${DA}*$${DB} +1/3*O${m}*(${v}$${B}*${DA}-${dot}*$${DB}))") dirac=["Matrix([[0,0,1,0],[0,0,0,1],[1,0,0,0],[0,1,0,0]])","Matrix([[0,0,0,1],[0,0,1,0],[0,-1,0,0],[-1,0,0,0]])", "Matrix([[0,0,0,complex(0, -1)],[0,0,complex(0, 1),0],[0,complex(0, 1),0,0],[complex(0, -1),0,0,0]])", "Matrix([[0,0,1,0],[0,0,0,-1],[-1,0,0,0],[0,1,0,0]])"] CC = "Matrix([[0,1,0,0],[-1,0,0,0],[0,0,0,-1],[0,0,1,0]])" CD = "Matrix([[0,-1,0,0],[1,0,0,0],[0,0,0,1],[0,0,-1,0]])" +evaluateTemplate = """\ +{decl} {{ + {momenta} + {waves} +{swap} + {symbols} + {couplings} +{defns} + {result} +}} +""" +spinor = Template("Matrix([[${s}s1],[${s}s2],[${s}s3],[${s}s4]])") +sbar = Template("Matrix([[${s}s1,${s}s2,${s}s3,${s}s4]])") +sline = Template("${s}s1=Symbol(\"${s}s1\")\n${s}s2=Symbol(\"${s}s2\")\n${s}s3=Symbol(\"${s}s3\")\n${s}s4=Symbol(\"${s}s4\")\n") + +RSSpinorTemplate = Template("${type}<double>(${outxs1},\n${outxs2},\n${outxs3},\n${outxs4},\n${outys1},\n${outys2},\n${outys3},\n${outys4},\n${outzs1},\n${outzs2},\n${outzs3},\n${outzs4},\n${outts1},\n${outts2},\n${outts3},\n${outts4})") +SpinorTemplate = Template("${type}<double>(${outs1},\n${outs2},\n${outs3},\n${outs4})") + def compare(a,b) : num=abs(a-b) den=abs(a+b) if(den == 0. and 1e-10) : return True return num/den<1e-10 def evaluate(x,model,parmsubs): import cmath return eval(x, {'cmath':cmath, 'complexconjugate':model.function_library.complexconjugate}, parmsubs) def pdgCC(particle) : pdgid = particle.pdg_code if(particle.name!=particle.antiname) : pdgid *= -1 return pdgid # ordering for EW VVV vertices (ordering not an issue as all same spin) def VVVordering(vertex) : pattern = "if((p1->id()==%s&&p2->id()==%s&&p3->id()==%s)"+\ "||(p1->id()==%s&&p2->id()==%s&&p3->id()==%s)||"+\ "(p1->id()==%s&&p2->id()==%s&&p3->id()==%s)) {norm(-norm());}" ordering = pattern%(vertex.particles[1].pdg_code, vertex.particles[0].pdg_code, vertex.particles[2].pdg_code, vertex.particles[0].pdg_code, vertex.particles[2].pdg_code, vertex.particles[1].pdg_code, vertex.particles[2].pdg_code, vertex.particles[1].pdg_code, vertex.particles[0].pdg_code) return ordering def tensorCouplings(vertex,value,prefactors,L,lorentztag,pos,all_couplings,order) : # split the structure into its different terms for analysis ordering="" structures = extractStructures(L) if(lorentztag == 'SST') : terms=[['P(1003,2)','P(2003,1)'], ['P(1003,1)','P(2003,2)'], ['P(-1,1)','P(-1,2)','Metric(1003,2003)'], ['Metric(1003,2003)']] signs=[1.,1.,-1.,-1.] new_couplings=[False]*len(terms) elif(lorentztag == 'FFT' ) : terms=[['P(2003,1)','Gamma(1003,2,1)'], ['P(2003,2)','Gamma(1003,2,1)'], ['P(1003,1)','Gamma(2003,2,1)'], ['P(1003,2)','Gamma(2003,2,1)'], ['P(-1,1)','Gamma(-1,2,1)','Metric(1003,2003)'], ['P(-1,2)','Gamma(-1,2,1)','Metric(1003,2003)'], ['Metric(1003,2003)']] signs=[1.,-1.,1.,-1.,-0.5,0.5,1.] new_couplings=[False]*3*len(terms) elif(lorentztag == 'VVT' ) : terms=[['P(-1,1)','P(-1,2)','Metric(1,2003)','Metric(2,1003)'], # from C term ['P(-1,1)','P(-1,2)','Metric(1,1003)','Metric(2,2003)'], # from C term ['P(-1,1)','P(-1,2)','Metric(1,2)','Metric(1003,2003)'], # from C term ['P(1,2)','P(2,1)','Metric(1003,2003)'], # from D term (sym) ['P(1,2)','P(2003,1)','Metric(2,1003)'], # 1st term ['P(1,2)','P(1003,1)','Metric(2,2003)'], # 1st swap ['P(2,1)','P(2003,2)','Metric(1,1003)'], # 2nd term ['P(2,1)','P(1003,2)','Metric(1,2003)'], # 2nd swap ['P(1003,2)','P(2003,1)','Metric(1,2)'], # 3rd term ['P(1003,1)','P(2003,2)','Metric(1,2)'], # 3rd swap ['Metric(1,2003)','Metric(2,1003)'], # from mass term ['Metric(1,1003)','Metric(2,2003)'], # from mass term ['Metric(1,2)','Metric(1003,2003)'], # from mass term ['P(1,1)','P(2,1)','Metric(1003,2003)'], # gauge terms ['P(1,2)','P(2,2)','Metric(1003,2003)'], # gauge terms ['P(1,1)','P(2,2)','Metric(1003,2003)'], # gauge terms ['P(1003,1)','P(1,1)','Metric(2,2003)'], # gauge terms ['P(1003,2)','P(2,2)','Metric(1,2003)'], # gauge terms ['P(2003,1)','P(1,1)','Metric(2,1003)'], # gauge terms ['P(2003,2)','P(2,2)','Metric(1,1003)'], # gauge terms ] signs=[1.,1.,-1.,1.,-1.,-1.,-1.,-1.,1.,1.,1.,1.,-1.,1.,1.,0.25,-1.,-1.,-1.,-1.] new_couplings=[False]*len(terms) elif(lorentztag == 'FFVT' ) : terms = [['Gamma(2004,2,1)','Metric(3,1004)'], ['Gamma(1004,2,1)','Metric(3,2004)'], ['Gamma(3,2,1)','Metric(1004,2004)'], ['Gamma(2004,2,-1)','Metric(3,1004)'], ['Gamma(1004,2,-1)','Metric(3,2004)'], ['Gamma(3,2,-1)','Metric(1004,2004)']] signs=[1.,1.,-0.5,1.,1.,-0.5] new_couplings=[False]*3*len(terms) elif(lorentztag == 'VVVT' ) : # the F(mu nu,rho sigma lambda) terms first terms = [['P(2004,2)','Metric(1,1004)','Metric(2,3)'],['P(2004,3)','Metric(1,1004)','Metric(2,3)'], ['P(1004,2)','Metric(1,2004)','Metric(2,3)'],['P(1004,3)','Metric(1,2004)','Metric(2,3)'], ['P(2004,3)','Metric(1,3)','Metric(2,1004)'],['P(2004,1)','Metric(1,3)','Metric(2,1004)'], ['P(1004,3)','Metric(1,3)','Metric(2,2004)'],['P(1004,1)','Metric(1,3)','Metric(2,2004)'], ['P(2004,1)','Metric(1,2)','Metric(3,1004)'],['P(2004,2)','Metric(1,2)','Metric(3,1004)'], ['P(1004,1)','Metric(1,2)','Metric(3,2004)'],['P(1004,2)','Metric(1,2)','Metric(3,2004)'], ['P(3,1)','Metric(1,2004)','Metric(2,1004)'],['P(3,2)','Metric(1,2004)','Metric(2,1004)'], ['P(3,1)','Metric(1,1004)','Metric(2,2004)'],['P(3,2)','Metric(1,1004)','Metric(2,2004)'], ['P(3,1)','Metric(1,2)','Metric(1004,2004)'],['P(3,2)','Metric(1,2)','Metric(1004,2004)'], ['P(2,3)','Metric(1,2004)','Metric(3,1004)'],['P(2,1)','Metric(1,2004)','Metric(3,1004)'], ['P(2,3)','Metric(1,1004)','Metric(3,2004)'],['P(2,1)','Metric(1,1004)','Metric(3,2004)'], ['P(2,3)','Metric(1,3)','Metric(1004,2004)'],['P(2,1)','Metric(1,3)','Metric(1004,2004)'], ['P(1,2)','Metric(2,2004)','Metric(3,1004)'],['P(1,3)','Metric(2,2004)','Metric(3,1004)'], ['P(1,2)','Metric(2,1004)','Metric(3,2004)'],['P(1,3)','Metric(2,1004)','Metric(3,2004)'], ['P(1,2)','Metric(2,3)','Metric(1004,2004)'],['P(1,3)','Metric(2,3)','Metric(1004,2004)']] signs = [1.,-1.,1.,-1.,1.,-1.,1.,-1.,1.,-1.,1.,-1., 1.,-1.,1.,-1.,-1.,1.,1.,-1.,1.,-1.,-1.,1.,1.,-1.,1.,-1.,-1.,1.] new_couplings=[False]*len(terms) l = lambda c: len(pos[c]) if l(8)!=3 : ordering = VVVordering(vertex) # unknown else : raise Exception('Unknown data type "%s".' % lorentztag) iterm=0 try : for term in terms: for perm in itertools.permutations(term): label = '*'.join(perm) for istruct in range(0,len(structures)) : if label in structures[istruct] : reminder = structures[istruct].replace(label,'1.',1) loc=iterm if(reminder.find("ProjM")>=0) : reminder=re.sub("\*ProjM\(.*,.\)","",reminder) loc+=len(terms) elif(reminder.find("ProjP")>=0) : reminder=re.sub("\*ProjP\(.*,.\)","",reminder) loc+=2*len(terms) structures[istruct] = "Done" val = eval(reminder, {'cmath':cmath} )*signs[iterm] if(new_couplings[loc]) : new_couplings[loc] += val else : new_couplings[loc] = val iterm+=1 except : SkipThisVertex() # check we've handled all the terms for val in structures: if(val!="Done") : raise SkipThisVertex() # special for FFVT if(lorentztag=="FFVT") : t_couplings=new_couplings new_couplings=[False]*9 for i in range(0,9) : j = i+3*(i/3) k = i+3+3*(i/3) if( not t_couplings[j]) : new_couplings[i] = t_couplings[k] else : new_couplings[i] = t_couplings[j] # set the couplings for icoup in range(0,len(new_couplings)) : if(new_couplings[icoup]) : new_couplings[icoup] = '(%s) * (%s) *(%s)' % (new_couplings[icoup],prefactors,value) if(len(all_couplings)==0) : all_couplings=new_couplings else : for icoup in range(0,len(new_couplings)) : if(new_couplings[icoup] and all_couplings[icoup]) : all_couplings[icoup] = '(%s) + (%s) ' % (new_couplings[icoup],all_couplings[icoup]) elif(new_couplings[icoup]) : all_couplings[icoup] = new_couplings[icoup] # return the results return (ordering,all_couplings) def processTensorCouplings(lorentztag,vertex,model,parmsubs,all_couplings,order) : # check for fermion vertices (i.e. has L/R couplings) fermions = "FF" in lorentztag # test and process the values of the couplings tval = [False]*3 value = [False]*3 # loop over the colours for icolor in range(0,len(all_couplings)) : lmax = len(all_couplings[icolor]) if(fermions) : lmax /=3 # loop over the different terms for ix in range(0,lmax) : test = [False]*3 # normal case if( not fermions ) : test[0] = all_couplings[icolor][ix] else : # first case vector but no L/R couplings if( not all_couplings[icolor][lmax+ix] and not all_couplings[icolor][2*lmax+ix] ) : test[0] = all_couplings[icolor][ix] # special for mass terms and massless particles if(not all_couplings[icolor][ix]) : code = abs(vertex.particles[order[0]-1].pdg_code) if(ix==6 and code ==12 or code ==14 or code==16) : continue else : raise SkipThisVertex() # second case L/R couplings elif( not all_couplings[icolor][ix] ) : # L=R, replace with vector if(all_couplings[icolor][lmax+ix] == all_couplings[icolor][2*lmax+ix]) : test[0] = all_couplings[icolor][lmax+ix] else : test[1] = all_couplings[icolor][lmax+ix] test[2] = all_couplings[icolor][2*lmax+ix] else : raise SkipThisVertex() # special handling of mass terms # scalar divide by m**2 if((ix==3 and lorentztag=="SST") or ( ix>=10 and ix<=12 and lorentztag=="VVT" )) : for i in range(0,len(test)) : if(test[i]) : test[i] = '(%s)/%s**2' % (test[i],vertex.particles[order[0]-1].mass.value) # fermions divide by 4*m elif(ix==6 and lorentztag=="FFT" and float(vertex.particles[order[0]-1].mass.value) != 0. ) : for i in range(0,len(test)) : if(test[i]) : test[i] = '-(%s)/%s/4' % (test[i],vertex.particles[order[0]-1].mass.value) # set values on first pass if(not tval[0] and not tval[1] and not tval[2]) : value = test for i in range(0,len(test)) : if(test[i]) : tval[i] = evaluate(test[i],model,parmsubs) else : for i in range(0,len(test)) : if(not test[i] and not tval[i]) : continue if(not test[i] or not tval[i]) : # special for mass terms and vectors if(lorentztag=="VVT" and ix >=10 and ix <=12 and float(vertex.particles[order[0]-1].mass.value) == 0. ) : continue # special for vector gauge terms if(lorentztag=="VVT" and ix>=13) : continue raise SkipThisVertex() tval2 = evaluate(test[i],model,parmsubs) if(abs(tval[i]-tval2)>1e-6) : # special for fermion mass term if fermions massless if(lorentztag=="FFT" and ix ==6 and tval2 == 0. and float(vertex.particles[order[0]-1].mass.value) == 0. ) : continue raise SkipThisVertex() # simple clean up for i in range(0,len(value)): if(value[i]) : value[i] = value[i].replace("(1.0) * ","").replace(" * (1)","") # put everything together coup_left = 0. coup_right = 0. coup_norm = 0. if(lorentztag == "SST" or lorentztag == "VVT" or lorentztag == "VVVT" or lorentztag == "FFT" ) : coup_norm = value[0] if(value[1] or value[2]) : raise SkipThisVertex() elif(lorentztag=="FFVT") : if(not value[1] and not value[2]) : coup_norm = value[0] coup_left = "1." coup_right = "1." elif(not value[0]) : coup_norm = "1." if(value[1] and value[2]) : coup_left = value[1] coup_right = value[2] elif(value[1]) : coup_left = value[1] coup_right = "0." elif(value[2]) : coup_left = "0." coup_right = value[2] else : raise SkipThisVertex() else : raise SkipThisVertex() else : raise SkipThisVertex() # return the answer return (coup_left,coup_right,coup_norm) def extractStructures(L) : structure1 = L.structure.split() structures =[] sign='' for struct in structure1 : if(struct=='+') : continue elif(struct=='-') : sign='-' else : structures.append(sign+struct.strip()) sign='' return structures def changeSign(sign1,sign2) : if((sign1=="+" and sign2=="+") or\ (sign1=="-" and sign2=="-")) : return "+" else : return "-" def epsilonOrder(eps) : terms,sign = extractAntiSymmetricIndices(eps,"Epsilon(") return (sign,"Epsilon(%s,%s,%s,%s)" % (terms[0],terms[1],terms[2],terms[3])) def VVSEpsilon(couplings,struct) : if(struct.find("Epsilon")<0) : return fact="" sign="+" if(struct[-1]==")") : fact=struct.split("(")[0] if(fact.find("Epsilon")>=0) : fact="" else : struct=struct.split("(",1)[1][:-1] if(fact[0]=="-") : sign="-" fact=fact[1:] split = struct.split("*") # find the epsilon eps="" for piece in split : if(piece.find("Epsilon")>=0) : eps=piece split.remove(piece) break # and any prefactors for piece in split : if(piece.find("P(")<0) : split.remove(piece) if(piece[0]=="+" or piece[0]=="-") : sign=changeSign(sign,piece[0]) piece=piece[1:] if(fact=="") : fact=piece else : fact = "( %s ) * ( %s )" % (fact , piece) # now sort out the momenta for piece in split : terms=piece.split(",") terms[0]=terms[0].strip("P(") terms[1]=terms[1].strip(")") eps=eps.replace(terms[0],"P%s"%terms[1]) (nsign,eps)=epsilonOrder(eps) if(nsign>0) : sign=changeSign(sign,"-") if(fact=="") : fact="1." if(eps!="Epsilon(1,2,P1,P2)") : return if(couplings[6]==0.) : couplings[6] = "( %s%s )" % (sign,fact) else : couplings[6] = "( %s ) + ( %s%s )" % (couplings[6],sign,fact) def scalarVectorCouplings(value,prefactors,L,lorentztag,all_couplings,order) : # set up the types of term we are looking for if(lorentztag=="VVS") : couplings=[0.,0.,0.,0.,0.,0.,0.] terms=[['P(-1,%s)' % order[0], 'P(-1,%s)' % order[1], 'Metric(%s,%s)' %(order[0],order[1])], ['P(1,%s)' % order[0], 'P(2,%s)' % order[0]], ['P(1,%s)' % order[0], 'P(2,%s)' % order[1]], ['P(1,%s)' % order[1], 'P(2,%s)' % order[0]], ['P(1,%s)' % order[1], 'P(2,%s)' % order[1]], ['Metric(%s,%s)'%(order[0],order[1])]] elif(lorentztag=="VVSS") : couplings=[0.] terms=[['Metric(%s,%s)' % (order[0],order[1])]] elif(lorentztag=="VSS"): couplings=[0.,0.] terms=[['P(%s,%s)' % (order[0],order[2])], ['P(%s,%s)' % (order[0],order[1])]] # extract the lorentz structures structures = extractStructures(L) # handle the scalar couplings itype=-1 try : for term in terms: itype+=1 for perm in itertools.permutations(term): label = '*'.join(perm) for istruct in range(0,len(structures)) : if label in structures[istruct] : reminder = structures[istruct].replace(label,'1.',1) couplings[itype]+=eval(reminder, {'cmath':cmath} ) structures[istruct]='Done' except : raise SkipThisVertex() # special for VVS and epsilon # handle the pseudoscalar couplings for struct in structures : if(struct != "Done" ) : if(lorentztag=="VVS") : VVSEpsilon(couplings,struct) else : raise SkipThisVertex() # put it all together if(len(all_couplings)==0) : for ic in range(0,len(couplings)) : if(couplings[ic]!=0.) : all_couplings.append('(%s) * (%s) * (%s)' % (prefactors,value,couplings[ic])) else : all_couplings.append(False) else : for ic in range(0,len(couplings)) : if(couplings[ic]!=0. and all_couplings[ic]) : all_couplings[ic] = '(%s) * (%s) * (%s) + (%s) ' % (prefactors,value, couplings[ic],all_couplings[ic]) elif(couplings[ic]!=0) : all_couplings[ic] = '(%s) * (%s) * (%s) ' % (prefactors,value,couplings[ic]) return all_couplings def processScalarVectorCouplings(lorentztag,vertex,model,parmsubs,all_couplings,header,order) : # check the values tval = [False]*len(all_couplings[0]) value =[False]*len(all_couplings[0]) for icolor in range(0,len(all_couplings)) : for ix in range(0,len(all_couplings[icolor])) : if(not value[ix]) : value[ix] = all_couplings[icolor][ix] if(value[ix] and not tval[ix]) : tval[ix] = evaluate(value[ix],model,parmsubs) elif(value[ix]) : tval2 = evaluate(all_couplings[icolor][0],model,parmsubs) if(abs(tval[ix]-tval2)>1e-6) : raise SkipThisVertex() append = "" symbols = set() coup_norm=0. if(lorentztag=="VVS") : if(not value[0] and not value[1] and not value[2] and \ not value[3] and not value[4] and not value[6] and value[5]) : coup_norm=value[5] else : for ix in range(0,len(value)) : if(value[ix]) : value[ix], sym = py2cpp(value[ix]) symbols |= sym else : value[ix]=0. lorentztag = 'GeneralVVS' header="kinematics(true);" # g_mu,nv piece of coupling if(value[5]!=0.) : append +='a00( %s + Complex(( %s )* GeV2/invariant(1,2)));\n' % ( value[0],value[5]) else : append +='a00( %s );\n' % value[0] # other couplings append += 'a11( %s );\n a12( %s );\n a21( %s );\n a22( %s );\n aEp( %s );\n' % \ ( value[1],value[2],value[3],value[4],value[6] ) coup_norm="1." elif(lorentztag=="VVSS") : coup_norm = value[0] elif(lorentztag=="VSS") : if(abs(tval[0]+tval[1])>1e-6) : for ix in range(0,len(value)) : if(value[ix]) : value[ix], sym = py2cpp(value[ix]) symbols |= sym else : value[ix]=0. coup_norm = "1." append = 'if(p2->id()==%s) { a( %s ); b( %s);}\n else { a( %s ); b( %s);}' \ % (vertex.particles[order[1]-1].pdg_code, value[0],value[1],value[1],value[0]) else : coup_norm = value[1] append = 'if(p2->id()!=%s){norm(-norm());}' \ % vertex.particles[order[1]-1].pdg_code # return the answer return (coup_norm,append,lorentztag,header,symbols) def getIndices(term) : if(term[0:2]=="P(") : indices = term.strip(")").strip("P(").split(",") mom = int(indices[1]) index = int(indices[0]) return (True,mom,index) else : return (False,0,0) def lorentzScalar(vertex,L) : dotProduct = """(invariant( i[{i1}], i[{i2}] )/GeV2)""" structures=L.structure.split() output="(" for struct in structures: if(struct=="+" or struct=="-") : output+=struct continue structure = struct.split("*") worked = False mom=-1 newTerm="" while True : term = structure[-1] structure.pop() (momentum,mom,index) = getIndices(term) if( not momentum) : break # look for the matching momenta for term in structure : (momentum,mom2,index2) = getIndices(term) if(index2==index) : structure.remove(term) dot = dotProduct.format(i1=mom-1,i2=mom2-1) if(newTerm=="") : newTerm = dot else : newTerm = " ( %s) * ( %s ) " % (newTerm,dot) if(len(structure)==0) : worked = True break if(not worked) : return False else : output+=newTerm output+=")" return output kinematicsline = """\ long id [3]={{{id1},{id2},{id3}}}; long id2[3]={{p1->id(),p2->id(),p3->id()}}; unsigned int i[3]; for(unsigned int ix=0;ix<3;++ix) {{ for(unsigned int iy=0;iy<3;++iy) {{ if(id[ix]==id2[iy]) {{ i[ix] = iy; id2[iy]=0; break; }} }} }} double hw_kine1 = {kine}; """ kinematicsline2 = """\ long id [4]={{{id1},{id2},{id3},{id4}}}; long id2[4]={{p1->id(),p2->id(),p3->id(),p4->id()}}; unsigned int i[4]; for(unsigned int ix=0;ix<4;++ix) {{ for(unsigned int iy=0;iy<4;++iy) {{ if(id[ix]==id2[iy]) {{ i[ix] = iy; id2[iy]=0; break; }} }} }} double hw_kine1 = {kine}; """ kinematicsline3 ="""\ double hw_kine{i} = {kine}; """ def scalarCouplings(vertex,value,prefactors,L,lorentztag, all_couplings,prepend,header) : try : val = int(L.structure) except : output = lorentzScalar(vertex,L) if( not output ) : raise SkipThisVertex() else : if(prepend=="") : if(lorentztag=="SSS") : # order doesn't matter here, all same spin prepend = kinematicsline.format(id1=vertex.particles[0].pdg_code, id2=vertex.particles[1].pdg_code, id3=vertex.particles[2].pdg_code, kine=output) else : # order doesn't matter here, all same spin prepend = kinematicsline2.format(id1=vertex.particles[0].pdg_code, id2=vertex.particles[1].pdg_code, id3=vertex.particles[2].pdg_code, id4=vertex.particles[3].pdg_code, kine=output) value = "(%s) *(hw_kine1)" % value else : osplit=prepend.split("\n") i=-1 while osplit[i]=="": i=i-1 ikin=int(osplit[i].split("=")[0].replace("double hw_kine",""))+1 prepend +=kinematicsline3.format(kine=output,i=ikin) value = "(%s) *(hw_kine%s)" % (value,ikin) header="kinematics(true);" if(len(all_couplings)==0) : all_couplings.append('(%s) * (%s)' % (prefactors,value)) else : all_couplings[0] = '(%s) * (%s) + (%s)' % (prefactors,value,all_couplings[0]) return (prepend, header,all_couplings) def processScalarCouplings(model,parmsubs,all_couplings) : tval = False value = False for icolor in range(0,len(all_couplings)) : if(len(all_couplings[icolor])!=1) : raise SkipThisVertex() if(not value) : value = all_couplings[icolor][0] m = re.findall('hw_kine[0-9]*', all_couplings[icolor][0]) if m: for kine in m: # bizarre number for checks, must be a better option parmsubs[kine] = 987654321. if(not tval) : tval = evaluate(value,model,parmsubs) else : tval2 = evaluate(all_couplings[icolor][0],model,parmsubs) if(abs(tval[i]-tval2)>1e-6) : raise SkipThisVertex() # cleanup and return the answer return value.replace("(1.0) * ","").replace(" * (1)","") def vectorCouplings(vertex,value,prefactors,L,lorentztag,pos, all_couplings,append,qcd,order) : structures=extractStructures(L) terms=[] signs=[] if(lorentztag=="VVV") : terms=[['P(%s,%s)' % (order[2],order[0]),'Metric(%s,%s)' % (order[0],order[1])], ['P(%s,%s)' % (order[2],order[1]),'Metric(%s,%s)' % (order[0],order[1])], ['P(%s,%s)' % (order[1],order[0]),'Metric(%s,%s)' % (order[0],order[2])], ['P(%s,%s)' % (order[1],order[2]),'Metric(%s,%s)' % (order[0],order[2])], ['P(%s,%s)' % (order[0],order[1]),'Metric(%s,%s)' % (order[1],order[2])], ['P(%s,%s)' % (order[0],order[2]),'Metric(%s,%s)' % (order[1],order[2])]] signs=[1.,-1.,-1.,1.,1.,-1.] elif(lorentztag=="VVVV") : terms=[['Metric(%s,%s)' % (order[0],order[3]),'Metric(%s,%s)' % (order[1],order[2])], ['Metric(%s,%s)' % (order[0],order[2]),'Metric(%s,%s)' % (order[1],order[3])], ['Metric(%s,%s)' % (order[0],order[1]),'Metric(%s,%s)' % (order[2],order[3])]] signs=[1.,1.,1.] elif(lorentztag=="VVVS") : terms=[['P(%s,%s)' % (order[2],order[0]),'Metric(%s,%s)' % (order[0],order[1])], ['P(%s,%s)' % (order[2],order[1]),'Metric(%s,%s)' % (order[0],order[1])], ['P(%s,%s)' % (order[1],order[0]),'Metric(%s,%s)' % (order[0],order[2])], ['P(%s,%s)' % (order[1],order[2]),'Metric(%s,%s)' % (order[0],order[2])], ['P(%s,%s)' % (order[0],order[1]),'Metric(%s,%s)' % (order[1],order[2])], ['P(%s,%s)' % (order[0],order[2]),'Metric(%s,%s)' % (order[1],order[2])], ['Epsilon(1,2,3,-1)','P(-1,1)'],['Epsilon(1,2,3,-1)','P(-1,2)'], ['Epsilon(1,2,3,-1)','P(-1,3)']] signs=[1.,-1.,-1.,1.,1.,-1.,1.,1.,1.] # extract the couplings new_couplings = [False]*len(terms) iterm=0 try : for term in terms: for perm in itertools.permutations(term): label = '*'.join(perm) for istruct in range(0,len(structures)) : if label in structures[istruct] : reminder = structures[istruct].replace(label,'1.',1) structures[istruct] = "Done" val = eval(reminder, {'cmath':cmath} )*signs[iterm] if(new_couplings[iterm]) : new_couplings[iterm] += val else : new_couplings[iterm] = val iterm += 1 except : raise SkipThisVertex() # check we've handled all the terms for val in structures: if(val!="Done") : raise SkipThisVertex() # set the couplings for icoup in range(0,len(new_couplings)) : if(new_couplings[icoup]) : new_couplings[icoup] = '(%s) * (%s) *(%s)' % (new_couplings[icoup],prefactors,value) if(len(all_couplings)==0) : all_couplings=new_couplings else : for icoup in range(0,len(new_couplings)) : if(new_couplings[icoup] and all_couplings[icoup]) : all_couplings[icoup] = '(%s) * (%s) *(%s) + (%s) ' % (new_couplings[icoup],prefactors,value,all_couplings[icoup]) elif(new_couplings[icoup]) : all_couplings[icoup] = new_couplings[icoup] # ordering for VVV type vertices if(len(pos[8]) != 3 and (lorentztag=="VVV" or lorentztag=="VVVS")) : append = VVVordering(vertex) return all_couplings,append def processVectorCouplings(lorentztag,vertex,model,parmsubs,all_couplings,append,header) : value = False tval = False if(lorentztag=="VVV") : for icolor in range(0,len(all_couplings)) : # loop over the different terms for ix in range(0,len(all_couplings[icolor])) : if(not value) : value = all_couplings[icolor][ix] tval = evaluate(value,model,parmsubs) else : tval2 = evaluate(all_couplings[icolor][ix],model,parmsubs) if(abs(tval-tval2)>1e-6) : raise SkipThisVertex() elif(lorentztag=="VVVV") : order=[] colours = vertex.color if(len(colours)==1) : tval=[] for i in range(0,3) : tval.append(evaluate(all_couplings[0][i],model,parmsubs)) if(compare(tval[2],-2.*tval[1]) and compare(tval[2],-2.*tval[0]) ) : order=[0,1,2,3] value = "0.5*(%s)" % all_couplings[0][2] elif(compare(tval[1],-2.*tval[2]) and compare(tval[1],-2.*tval[0]) ) : order=[0,2,1,3] value = "0.5*(%s)" % all_couplings[0][1] elif(compare(tval[0],-2.*tval[2]) and compare(tval[0],-2.*tval[1]) ) : order=[0,3,1,2] value = "0.5*(%s)" % all_couplings[0][0] else: raise SkipThisVertex() pattern = \ "bool done[4]={false,false,false,false};\n" + \ " tcPDPtr part[4]={p1,p2,p3,p4};\n" + \ " unsigned int iorder[4]={0,0,0,0};\n" + \ " for(unsigned int ix=0;ix<4;++ix) {\n" + \ " if(!done[0] && part[ix]->id()==%s) {done[0]=true; iorder[%s] = ix; continue;}\n" + \ " if(!done[1] && part[ix]->id()==%s) {done[1]=true; iorder[%s] = ix; continue;}\n" + \ " if(!done[2] && part[ix]->id()==%s) {done[2]=true; iorder[%s] = ix; continue;}\n" + \ " if(!done[3] && part[ix]->id()==%s) {done[3]=true; iorder[%s] = ix; continue;}\n" + \ " }\n" + \ " setType(2);\n" + \ " setOrder(iorder[0],iorder[1],iorder[2],iorder[3]);" # order doesn't matter here same spin append = pattern % ( vertex.particles[0].pdg_code,order[0], vertex.particles[1].pdg_code,order[1], vertex.particles[2].pdg_code,order[2], vertex.particles[3].pdg_code,order[3] ) else : for icolor in range(0,len(all_couplings)) : col=colours[icolor].split("*") if(len(col)==2 and "f(" in col[0] and "f(" in col[1]) : sign = 1 for i in range(0,2) : col[i],stemp = extractAntiSymmetricIndices(col[i],"f(") for ix in range(0,len(col[i])): col[i][ix]=int(col[i][ix]) sign *=stemp if(col[0][0]>col[1][0]) : col[0],col[1] = col[1],col[0] # first flow if(col[0][0]==1 and col[0][1]==2 and col[1][0] ==3 and col[1][1] == 4) : if(all_couplings[icolor][2] or not all_couplings[icolor][0] or not all_couplings[icolor][1]) : raise SkipThisVertex() if(not value) : value = all_couplings[icolor][1] tval = evaluate(value,model,parmsubs) tval2 = -evaluate(all_couplings[icolor][0],model,parmsubs) tval3 = evaluate(all_couplings[icolor][1],model,parmsubs) elif(col[0][0]==1 and col[0][1]==3 and col[1][0] ==2 and col[1][1] == 4) : if(all_couplings[icolor][1] or not all_couplings[icolor][0] or not all_couplings[icolor][2]) : raise SkipThisVertex() if(not value) : value = all_couplings[icolor][2] tval = evaluate(value,model,parmsubs) tval2 = -evaluate(all_couplings[icolor][0],model,parmsubs) tval3 = evaluate(all_couplings[icolor][2],model,parmsubs) elif(col[0][0]==1 and col[0][1]==4 and col[1][0] ==2 and col[1][1] == 3) : if(all_couplings[icolor][0] or not all_couplings[icolor][1] or not all_couplings[icolor][2]) : raise SkipThisVertex() if(not value) : value = all_couplings[icolor][2] tval = evaluate(value,model,parmsubs) tval2 = -evaluate(all_couplings[icolor][1],model,parmsubs) tval3 = evaluate(all_couplings[icolor][2],model,parmsubs) else : raise SkipThisVertex() if(abs(tval-tval2)>1e-6 or abs(tval-tval3)>1e-6 ) : raise SkipThisVertex() append = 'setType(1);\nsetOrder(0,1,2,3);' else : print 'unknown colour structure for VVVV vertex' raise SkipThisVertex() elif(lorentztag=="VVVS") : try : # two distinct cases 0-5 = , 6-8= if(all_couplings[0][0]) : imin=0 imax=6 header="scalar(true);" else : imin=6 imax=9 header="scalar(false);" for icolor in range(0,len(all_couplings)) : # loop over the different terms for ix in range(imin,imax) : if(not value) : value = all_couplings[icolor][ix] tval = evaluate(value,model,parmsubs) else : tval2 = evaluate(value,model,parmsubs) if(abs(tval-tval2)>1e-6) : raise SkipThisVertex() except : SkipThisVertex() # cleanup and return the answer value = value.replace("(1.0) * ","").replace(" * (1)","") return (value,append,header) def fermionCouplings(value,prefactors,L,all_couplings,order) : new_couplings=[False,False] try : new_couplings[0],new_couplings[1] = parse_lorentz(L.structure) except : raise SkipThisVertex() for i in range(0,2) : if new_couplings[i]: new_couplings[i] = '(%s) * (%s) * (%s)' % (prefactors,new_couplings[i],value) if(len(all_couplings)==0) : all_couplings=new_couplings else : for i in range(0,len(new_couplings)) : if(new_couplings[i] and all_couplings[i]) : all_couplings[i] = '(%s) + (%s) ' % (new_couplings[i],all_couplings[i]) elif(new_couplings[i]) : all_couplings[i] = new_couplings[i] return all_couplings def processFermionCouplings(lorentztag,vertex,model,parmsubs,all_couplings,order) : leftcontent = all_couplings[0][0] if all_couplings[0][0] else "0." rightcontent = all_couplings[0][1] if all_couplings[0][1] else "0." tval=[evaluate( leftcontent,model,parmsubs), evaluate(rightcontent,model,parmsubs)] for icolor in range(0,len(all_couplings)) : # loop over the different terms for ix in range(0,len(all_couplings[icolor])) : tval2 = evaluate(all_couplings[icolor][ix],model,parmsubs) if all_couplings[icolor][ix] else 0. if(abs(tval[ix]-tval2)>1e-6) : raise SkipThisVertex() normcontent = "1." append="" if lorentztag == 'FFV': append = ('if(p1->id()!=%s) {Complex ltemp=left(), rtemp=right(); left(-rtemp); right(-ltemp);}' % vertex.particles[order[0]-1].pdg_code) return normcontent,leftcontent,rightcontent,append def RSCouplings(value,prefactors,L,all_couplings,order) : raise SkipThisVertex() class LorentzIndex : """ A simple classs to store a Lorentz index """ type="" value=0 def __repr__(self): return "%s%s" % (self.type,self.value) def __init__(self,val) : if(isinstance(val,int)) : if(val<0) : self.type="D" self.value = val elif(val>0 and val/1000==0) : self.type="E" self.value = val elif(val>0 and val/1000==1) : self.type="T1" self.value = val%1000 elif(val>0 and val/1000==2) : self.type="T2" self.value = val%1000 else : print "INDEX",val quit() else : print 'unknown value in lorentz index',val quit() def __eq__(self,other): + if(not isinstance(other,LorentzIndex)) : + return False return ( (self.type, self.value) == (other.type, other.value) ) def __hash__(self) : return hash((self.type,self.value)) -# def indexEqual(i1,i2): -# return ( (i1.type, i1.value) == (i2.type, i2.value) ) +class DiracMatrix: + """A simple class to store Dirac matrices""" + name ="" + value="" + index=0 + def __init(self) : + self.name="" + self.value="" + self.index=0 + def __repr__(self) : + if(self.value==0) : + return "%s" % self.index + else : + return "%s" % self.value + class LorentzStructure: """A simple class to store a Lorentz structures""" name="" value=0 lorentz=[] spin=[] + + def __init(self) : + self.name="" + self.value=0 + self.lorentz=[] + self.spin=[] + def __repr__(self): output = self.name if((self.name=="P" or self.name=="Tensor") and self.value!=0) : output += "%s" % self.value if(self.name=="int" or self.name=="sign") : output += "=%s" % self.value elif(len(self.spin)==0) : output += "(" for val in self.lorentz : output += "%s," % val output=output.rstrip(",") output+=")" elif(len(self.lorentz)==0) : output += "(" for val in self.spin : output += "%s," % val output=output.rstrip(",") output+=")" else : output += "(" for val in self.lorentz : output += "%s," % val for val in self.spin : output += "%s," % val output=output.rstrip(",") output+=")" return output def LorentzCompare(a,b) : if(a.name=="int" and b.name=="int") : return int(b.value-a.value) elif(a.name=="int") : return -1 elif(b.name=="int") : return 1 elif(len(a.spin)==0) : if(len(b.spin)==0) : return len(b.lorentz)-len(a.lorentz) else : return -1 elif(len(b.spin)==0) : return 1 else : if(len(a.spin)==0 or len(b.spin)==0) : print 'index problem',a.name,b.name print a.spin,b.spin quit() if(a.spin[0]>0 or b.spin[1]>0 ) : return -1 if(a.spin[1]>0 or b.spin[0]>0 ) : return 1 if(a.spin[1]==b.spin[0]) : return -1 if(b.spin[1]==a.spin[0]) : return 1 return 0 def extractIndices(struct) : if(struct.find("(")<0) : return [] temp=struct.split("(")[1].split(")")[0].split(",") output=[] for val in temp : output.append(int(val)) return output -def parse_structure(structure) : +def parse_structure(structure,spins) : output=[] found = True while(found) : found = False # signs between terms if(structure=="+" or structure=="-") : output.append(LorentzStructure()) output[0].name="sign" output[0].value=structure[0]+"1." output[0].value=float(output[0].value) + output[0].lorentz=[] + output[0].spin=[] return output # simple numeric pre/post factors elif((structure[0]=="-" or structure[0]=="+") and structure[-1]==")" and structure[1]=="(") : output.append(LorentzStructure()) output[-1].name="int" output[-1].value=structure[0]+"1." output[-1].value=float(output[-1].value) + output[-1].lorentz=[] + output[-1].spin=[] structure=structure[2:-1] found=True elif(structure[0]=="(") : temp=structure.rsplit(")",1) structure=temp[0][1:] output.append(LorentzStructure()) output[-1].name="int" output[-1].value="1."+temp[1] output[-1].value=float(eval(output[-1].value)) + output[-1].lorentz=[] + output[-1].spin=[] found=True elif(structure[0:2]=="-(") : temp=structure.rsplit(")",1) structure=temp[0][2:] output.append(LorentzStructure()) output[-1].name="int" output[-1].value="-1."+temp[1] output[-1].value=float(eval(output[-1].value)) + output[-1].lorentz=[] + output[-1].spin=[] found=True # special handling for powers , assume only 2 power = False if("**" in structure ) : power = True structure = structure.replace("**","^") structures = structure.split("*") if(power) : for j in range(0,len(structures)): if(structures[j].find("^")>=0) : temp = structures[j].split("^") structures[j] = temp[0] for i in range(0,int(temp[1])-1) : structures.append(temp[0]) # split up the structure for struct in structures: ind = extractIndices(struct) # different types of object # object with only spin indices if(struct.find("Identity")==0 or struct.find("Proj")==0 or struct.find("Gamma5")==0) : - print 'found proj' output.append(LorentzStructure()) output[-1].spin=ind + output[-1].lorentz=[] output[-1].name=struct.split("(")[0] output[-1].value=0 if(len(struct.replace("%s(%s,%s)" % (output[-1].name,ind[0],ind[1]),""))!=0) : print "Problem handling %s structure " % output[-1].name raise SkipThisVertex() # objects with 2 lorentz indices elif(struct.find("Metric")==0) : output.append(LorentzStructure()) output[-1].lorentz=[LorentzIndex(ind[0]),LorentzIndex(ind[1])] output[-1].name=struct.split("(")[0] output[-1].value=0 + output[-1].spin=[] if(len(struct.replace("%s(%s,%s)" % (output[-1].name,ind[0],ind[1]),""))!=0) : print "Problem handling %s structure " % output[-1].name raise SkipThisVertex() elif(struct.find("P(")==0) : output.append(LorentzStructure()) output[-1].lorentz=[LorentzIndex(ind[0])] output[-1].name=struct.split("(")[0] output[-1].value=ind[1] + output[-1].spin=[] if(len(struct.replace("%s(%s,%s)" % (output[-1].name,ind[0],ind[1]),""))!=0) : print "Problem handling %s structure " % output[-1].name raise SkipThisVertex() # 1 lorentz and 1 spin index elif(struct.find("Gamma")==0) : output.append(LorentzStructure()) output[-1].lorentz=[LorentzIndex(ind[0])] output[-1].spin=[ind[1],ind[2]] output[-1].name=struct.split("(")[0] output[-1].value=1 if(len(struct.replace("%s(%s,%s,%s)" % (output[-1].name,ind[0],ind[1],ind[2]),""))!=0) : print "problem parsing gamma matrix",struct raise SkipThisVertex() # objects with 4 lorentz indices elif(struct.find("Epsilon")==0) : - print 'eps' - quit() output.append(LorentzStructure()) - output[-1].lorentz=ind + for i in range(0,len(ind)) : + output[-1].lorentz.append(LorentzIndex(ind[i])) + output[-1].spin=[] output[-1].name=struct.split("(")[0] - output[-1].value=1. + output[-1].spin=[] + output[-1].value=1 if(len(struct.replace("%s(%s,%s,%s,%s)" % (output[-1].name,ind[0],ind[1],ind[2],ind[3]),""))!=0) : - print "problem D" - quit() + print 'problem parsing epsilon',struct + raise SkipThisVertex() # scalars else : try : output.append(LorentzStructure()) output[-1].value=float(struct) output[-1].name="int" + output[-1].lorentz=[] + output[-1].spin=[] except : if(struct.find("complex")==0) : vals = struct[0:-1].replace("complex(","").split(",") output[-1].value=complex(float(vals[0]),float(vals[1])) output[-1].name="int" + output[-1].lorentz=[] + output[-1].spin=[] else : print 'scalar problem',struct print complex(struct) quit() # now do the sorting if(len(output)==1) : return output output = sorted(output,cmp=LorentzCompare) - print output + # fix indices in the RS case + if(4 in spins) : + for i in range(0,len(output)) : + for ll in range(0,len(output[i].lorentz)) : + if(spins[output[i].lorentz[ll].value-1]==4 and + output[i].lorentz[ll].type=="E") : + output[i].lorentz[ll].type="R" + # return the answer return output def contract(parsed) : - print "!!!!!!!!!!!!!!!!!!!!!!!!! IN CONTRACT !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" - print parsed for j in range(0,len(parsed)) : if(parsed[j]=="") : continue if(parsed[j].name=="P") : # simplest case if(parsed[j].lorentz[0].type=="E" or parsed[j].lorentz[0].type=="P") : newIndex = LorentzIndex(parsed[j].value) newIndex.type="P" parsed[j].name="Metric" parsed[j].lorentz.append(newIndex) parsed[j].lorentz = sorted(parsed[j].lorentz,cmp=indSort) continue ll=1 found=False for k in range(0,len(parsed)) : if(j==k or parsed[k]=="" ) : continue for i in range(0,len(parsed[k].lorentz)) : if(parsed[k].lorentz[i] == parsed[j].lorentz[0]) : parsed[k].lorentz[i].type="P" parsed[k].lorentz[i].value = parsed[j].value if(parsed[k].name=="P") : parsed[k].lorentz.append(LorentzIndex(parsed[k].value)) parsed[k].lorentz[1].type="P" parsed[k].name="Metric" parsed[k].value = 0 found=True break if(found) : parsed[j]="" break return [x for x in parsed if x != ""] def computeUnit(dimension) : if(isinstance(dimension,int)) : dtemp = dimension else : dtemp=dimension[1]+dimension[2] if(dtemp==0) : unit="double" elif(dtemp==1) : unit="Energy" elif(dtemp==-1) : unit="InvEnergy" elif(dtemp>0) : unit="Energy%s" % (dtemp) elif(dtemp<0) : unit="InvEnergy%s" % (dtemp) return unit def computeUnit2(dimension,vDim) : # first correct for any coupling power in vertex totalDim = int(dimension[0])+dimension[2]+vDim-4 output="" if(totalDim!=0) : if(totalDim>0) : if(totalDim==1) : output = "1./GeV" elif(totalDim==2) : output = "1./GeV2" else : output="1." for i in range(0,totalDim) : output +="/GeV" else : if(totalDim==-1) : output = "GeV" elif(totalDim==-2) : output = "GeV2" else : output="1." for i in range(0,-totalDim) : output +="*GeV" expr="" # now remove the remaining dimensionality removal=dimension[1]-int(dimension[0])-vDim+4 if(removal!=0) : if(removal>0) : if(removal==1) : expr = "UnitRemoval::InvE" else : expr = "UnitRemoval::InvE%s" % removal else : if(removal==-1) : expr = "UnitRemoval::E" else : expr = "UnitRemoval::E%s" % (-removal) if(output=="") : return expr elif(expr=="") : return output else : return "%s*%s" %(output,expr) # order the indices of a dot product def indSort(a,b) : if(not isinstance(a,LorentzIndex) or not isinstance(b,LorentzIndex)) : quit() if(a.type==b.type) : i1=a.value i2=b.value if(i1>i2) : return 1 elif(i1<i2) : return -1 else : return 0 else : if(a.type=="E") : return 1 else : return -1 - -def finishParsing(parsed,dimension,lorentztag,iloc,defns) : +def finishParsing(parsed,dimension,lorentztag,iloc,defns,eps) : output=1. # replace signs if(len(parsed)==1 and parsed[0].name=="sign") : if(parsed[0].value>0) : output="+" else : output="-" parsed=[] - return (output,parsed,dimension) + return (output,parsed,dimension,eps) # replace integers (really lorentz scalars) - print parsed for j in range(0,len(parsed)) : if(parsed[j]!="" and parsed[j].name=="int") : - print output,parsed[j] output *= parsed[j].value parsed[j]="" # bracket this for safety if(output!="") : output = "(%s)" % output # special for tensor indices if("T" in lorentztag) : for j in range(0,len(parsed)) : if(parsed[j]=="") :continue - print "!!!!!!!!!",parsed[j] # check for tensor index found=False for li in parsed[j].lorentz : if(li.type[0]=="T") : index = li found=True break if(not found) : continue # workout the other index for the tensor index2 = LorentzIndex(li.value) if(index.type=="T1") : index2.type="T2" else : index2.type="T1" print index,index2 # special is tensor contracted with itself if(parsed[j].name=="Metric" and index2 == parsed[j].lorentz[1]) : parsed[j].name = "Tensor" parsed[j].value = index.value parsed[j].lorentz = [] if(iloc!=index.value) : name= "traceT%s" % parsed[j].value if( name in defns ) : output += "*(%s)" % defns[name][0] else : defns[name] = [name,"Complex %s = T%s.trace();" % (name,parsed[j].value)] output += "*(%s)" % defns[name][0] parsed[j]="" continue # otherwise search for the match for k in range(j+1,len(parsed)) : print parsed[k] found = False for li in parsed[k].lorentz : if(li == index2) : found=True break if(not found) : continue if(parsed[j].name=="P") : newIndex1 = LorentzIndex(parsed[j].value) newIndex1.type="P" elif(parsed[j].name=="Metric") : for li in parsed[j].lorentz : if(li != index) : newIndex1=li break else : print 'unknown type' print parsed[j] quit() if(parsed[k].name=="P") : newIndex2 = LorentzIndex(parsed[k].value) newIndex2.type="P" elif(parsed[k].name=="Metric") : for li in parsed[k].lorentz : if(li != index) : newIndex2=li break else : print 'unknown type' print parsed[j] quit() parsed[j].name = "Tensor" parsed[j].value= int(index.value) parsed[j].lorentz= [newIndex1,newIndex2] parsed[k]="" # main handling of lorentz structures for j in range(0,len(parsed)) : if(parsed[j]=="") : continue if(parsed[j].name=="Metric") : (ind1,ind2) = sorted((parsed[j].lorentz[0],parsed[j].lorentz[1]),cmp=indSort) # this product already dealt with ? if((ind1,ind2) in defns) : output += "*(%s)" % defns[(ind1,ind2)][0] parsed[j]="" if(ind1.type=="P") : dimension[2] +=1 if(ind2.type=="P") : dimension[2] +=1 continue # handle the product name = "dot%s" % (len(defns)+1) if(ind1.type=="P") : # dot product of two momenta if(ind2.type=="P") : dimension[2] +=2 defns[(ind1,ind2)] = [name,"Energy2 %s = %s*%s;" % (name,ind1,ind2)] output += "*(%s)" % name parsed[j]="" - elif(ind2.type=="E") : - if(ind2.value!=iloc) : - dimension[2] += 1 - defns[(ind1,ind2)] = [name,"complex<Energy> %s = %s*%s;" % (name,ind1,ind2)] - output += "*(%s)" % name - parsed[j]="" - # - # if(int(ind2[1])==iloc) : - # output += "*(%s)" % ind1 - # else : - # - # + elif(ind2.type=="E" and ind2.value!=iloc) : + dimension[2] += 1 + defns[(ind1,ind2)] = [name,"complex<Energy> %s = %s*%s;" % (name,ind1,ind2)] + output += "*(%s)" % name + parsed[j]="" elif(ind1.type=="E") : if(ind2.type!="E") : print "EE problem",ind1,ind2 quit() elif(ind1.value!=iloc and ind2.value!=iloc) : defns[(ind1,ind2)] = [name,"complex<double> %s = %s*%s;" % (name,ind1,ind2)] output += "*(%s)" % name parsed[j]="" + elif(parsed[j].name=="Epsilon") : + if(not eps) : eps = True + print parsed[j] + print 'epsilon' + # work out which, if any of the indices can be summed over + summable=[] + for ix in range(0,len(parsed[j].lorentz)) : + if(parsed[j].lorentz[ix].type=="P" or + (parsed[j].lorentz[ix].type=="E" and iloc !=parsed[j].lorentz[ix].value)) : + summable.append(True) + else : + summable.append(False) + print summable.count(True) + if(summable.count(True)<3) : + print "leave for later" + continue + else : + print 'can be handled' - # if(int(ind1[1])==iloc) : - # output += "*(%s)" % ind2 - # elif(int(ind2[1])==iloc) : - # output += "*(%s)" % ind1 - # else : - # - # - # elif(parsed[j].name=="Epsilon") : - # if(not eps) : eps = True + quit() + # # offLoc = -1 # indices=[] # dTemp=0 # for ix in range(0,len(parsed[j].lorentz)) : # if(isinstance(parsed[j].lorentz[ix],int)) : # offLoc = ix # break # elif(parsed[j].lorentz[ix][0]=="E" and int(parsed[j].lorentz[ix][1])==iloc ) : # offLoc = ix # break # for ix in range(0,len(parsed[j].lorentz)) : # if(isinstance(parsed[j].lorentz[ix],basestring) and # parsed[j].lorentz[ix][0]=="P") : dTemp+=1 # if((offLoc<0 and ix != 0) or # (offLoc>=0 and offLoc!=ix) ) : # indices.append(parsed[j].lorentz[ix]) # dimension[2] += dTemp # if(offLoc<0) : # iTemp = (parsed[j].lorentz[0],parsed[j].lorentz[1], # parsed[j].lorentz[2],parsed[j].lorentz[3]) # if(iTemp in defns) : # output += "*(%s)" % defns[iTemp][0] # parsed[j]="" # else : # name = "dot%s" % (len(defns)+1) # unit = computeUnit(dTemp) # defns[iTemp] = [name,"complex<%s> %s =-%s*epsilon(%s,%s,%s);" % (unit,name,parsed[j].lorentz[0], # indices[0],indices[1],indices[2]) ] # output += "*(%s)" % name # else : # iTemp = (indices[0],indices[1],indices[2]) # sign = "" # if(offLoc%2!=0) : sign="-" # print iTemp # if(iTemp in defns) : # output += "*(%s%s)" % (sign,defns[iTemp][0]) # parsed[j]="" # else : # name = "vec%s" % (len(defns)+1) # output += "*(%s%s)" % (sign,name) # unit = computeUnit(dTemp) # defns[iTemp] = [name,"LorentzVector<complex<%s> > %s =-epsilon(%s,%s,%s);" % (unit,name, # indices[0],indices[1],indices[2]) ] elif(parsed[j].name=="Tensor") : # not an exteral tensor if(parsed[j].value!=iloc) : # now check the lorentz indices con=[] uncon=[] dtemp=0 for li in parsed[j].lorentz : if(li.type=="P") : con.append(li) dtemp+=1 elif(li.type=="E") : if(li.value!=iloc) : con.append(li) else : uncon.append(li) else : print 'need to handle ',li,'in tensor',parsed[j] print li quit() if(len(con)==2) : iTemp = ("T%s%s%s"% (parsed[j].value,con[0],con[1])) dimension[2]+=dtemp if(iTemp in defns) : output += "*(%s)" % defns[iTemp][0] else : unit=computeUnit(dtemp) name = "dot%s" % (len(defns)+1) defns[iTemp] = [name,"complex<%s> %s = T%s.preDot(%s)*%s;" % (unit,name,parsed[j].value,con[0],con[1])] output += "*(%s)" % name parsed[j]="" elif(len(con)==1 and len(uncon)==1) : print 'uncon' else : print "can't happen" quit() else : dtemp=0 for li in parsed[j].lorentz : if(li.type=="P") : dtemp+=1 dimension[2]+=dtemp elif(parsed[j].name.find("Proj")>=0 or parsed[j].name.find("Gamma")>=0) : continue + elif(parsed[j].name=="P" and parsed[j].lorentz[0].type=="R") : + continue else : - print 'not handled',parsed[j] + print 'not handled',parsed[j],iloc quit() # remove leading * if(output!="" and output[0]=="*") : output = output[1:] # remove any (now) empty elements parsed = [x for x in parsed if x != ""] - return (output,parsed,dimension) + return (output,parsed,dimension,eps) def finalContractions(output,parsed,dimension,lorentztag,iloc,defns) : if(len(parsed)==0) : return (output,dimension) elif(len(parsed)!=1) : print "summation can't be handled",parsed,iloc,output quit() raise SkipThisVertex() if(parsed[0].name=="Tensor") : # contracted with off-shell vector if(parsed[0].value!=iloc) : found = False for ll in parsed[0].lorentz : if(ll.type=="E" and ll.value==iloc) : found = True else : lo=ll if(found) : unit="double" if(lo.type=="P") : dimension[2]+=1 unit="Energy" if(lo==parsed[0].lorentz[0]) : name="T%s%sF" % (parsed[0].value,lo) defns[name] = [name,"LorentzVector<complex<%s> > %s = T%s.preDot(%s);" % (unit,name,parsed[0].value,lo)] else : name="T%s%sS" % (parsed[0].value,lo) defns[name] = [name,"LorentzVector<complex<%s> > %s = T%s.postDot(%s);" % (unit,name,parsed[0].value,lo)] parsed[0]="" if(output=="") : output="1." output = "(%s)*(%s)" %(output,name) else : print 'problem with tensor',iloc print parsed quit() # off-shell tensor else : tensor = tensorPropagator(parsed[0],defns) if(output=="") : output="1." output = [output,tensor,()] elif(parsed[0].name=="Metric") : found = False for ll in parsed[0].lorentz : if(ll.type=="E" and ll.value==iloc) : found = True else : lo=ll if(found) : parsed[0]="" if(lo.type=="P") : dimension[2]+=1 if(output=="") : output="1." output = "(%s)*(%s)" %(output,lo) else : print "structure can't be handled",parsed,iloc quit() raise SkipThisVertex() return (output,dimension) def tensorPropagator(struct,defns) : # dummy index i0 = LorentzIndex(-1000) # index for momentum of propagator ip = LorentzIndex(struct.value) ip.type="P" # the metric tensor terms=[] if(len(struct.lorentz)==0) : iTemp=(ip,ip) if(iTemp in defns) : dp = defns[iTemp][0] else : dp = "dot%s" % (len(defns)+1) defns[iTemp] = [dp,"Energy2 %s = %s*%s;" % (dp,ip,ip)] - pre = "2./3.*(1.-%s*OM%s)" % (dp,struct.value) - terms.append(("-"+pre,i0,i0)) + pre = "-2./3.*(1.-%s*OM%s)" % (dp,struct.value) + terms.append((pre,i0,i0)) + pre = "-4./3.*(1.-%s*OM%s)" % (dp,struct.value) terms.append(("%s*OM%s" %(pre,struct.value),ip,ip)) else : # indices of the tensor ind1 = struct.lorentz[0] ind2 = struct.lorentz[1] # the dot products we need iTemp = tuple(sorted((ind1,ip),cmp=indSort)) if(iTemp in defns) : d1 = defns[iTemp][0] else : d1 = "dot%s" % (len(defns)+1) unit = "Energy" if(ind1.type=="P") : unit="Energy2" defns[iTemp] = [d1,"complex<%s> %s = %s*%s;" % (unit,d1,ind1,ip)] iTemp = tuple(sorted((ind2,ip),cmp=indSort)) if(iTemp in defns) : d2 = defns[iTemp][0] else : d2 = "dot%s" % (len(defns)+1) unit = "Energy" if(ind2.type=="P") : unit="Energy2" defns[iTemp] = [d2,"complex<%s> %s = %s*%s;" % (unit,d2,ind2,ip)] iTemp = tuple(sorted((ind1,ind2),cmp=indSort)) if(iTemp in defns) : d3 = defns[iTemp][0] else : d3 = "dot%s" % (len(defns)+1) dtemp=0 if(ind1.type=="P") : dtemp+=1 if(ind2.type=="P") : dtemp+=1 unit=computeUnit(dtemp) defns[iTemp] = [d3,"complex<%s> %s = %s*%s;" % (unit,d3,ind1,ind2)] # various terms in the propagator terms.append(("1",ind1,ind2)) terms.append(("-OM%s*%s"%(struct.value,d1),ip,ind2)) terms.append(("-OM%s*%s"%(struct.value,d2),ind1,ip)) terms.append(("1",ind2,ind1)) terms.append(("-OM%s*%s"%(struct.value,d2),ip,ind1)) terms.append(("-OM%s*%s"%(struct.value,d1),ind2,ip)) terms.append(("-2./3.*"+d3,i0,i0)) terms.append(("2./3.*OM%s*%s*%s"%(struct.value,d1,d2),i0,i0)) terms.append(("2./3.*OM%s*%s"%(struct.value,d3),ip,ip)) terms.append(("4./3.*OM%s*OM%s*%s*%s"%(struct.value,struct.value,d1,d2),ip,ip)) # compute the output as a dict output={} for i1 in imap: for i2 in imap : val="" for term in terms: if(term[0][0]!="-") : pre = "+"+term[0] else : pre = term[0] if(term[1]==i0) : if(i1==i2) : if(i1=="t") : val += pre else : if(pre[0]=="+") : val +="-"+pre[1:] else : val +="+"+pre[1:] else : val += "%s*%s.%s()*%s.%s()" % (pre,term[1],i1,term[2],i2) output["%s%s" % (i1,i2) ] = val.replace("+1*","+").replace("-1*","-") return output def generateVertex(iloc,L,parsed,lorentztag,vertex,defns) : eps=False # parse the lorentz structures output = [1.]*len(parsed) dimension=[] for i in range(0,len(parsed)) : dimension.append([0,0,0]) for i in range (0,len(parsed)) : - (output[i],parsed[i],dimension[i]) = finishParsing(parsed[i],dimension[i],lorentztag,iloc,defns) + (output[i],parsed[i],dimension[i],eps) = finishParsing(parsed[i],dimension[i],lorentztag,iloc,defns,eps) # still need to process gamma matrix strings for fermions if(lorentztag[0] in ["F","R"] ) : return convertDirac(output,dimension,eps,iloc,L,parsed,lorentztag,vertex,defns) # return the answer else : handled=True for i in range (0,len(parsed)) : if(len(parsed[i])!=0) : handled = False break if(not handled) : print 'in NOT HANDLED',parsed,output for i in range (0,len(parsed)) : (output[i],dimension[i]) = finalContractions(output[i],parsed[i],dimension[i],lorentztag,iloc,defns) print output[i] return (output,dimension,eps) def convertDirac(output,dimension,eps,iloc,L,parsed,lorentztag,vertex,defns) : for i in range(0,len(parsed)): # skip empty elements if(len(parsed[i])==0 or (len(parsed[i])==1 and parsed[i][0]=="")) : continue # parse the string (output[i],dimension[i],defns) = convertDiracStructure(parsed[i],output[i],dimension[i], defns,iloc,L,lorentztag,vertex) - print 'after convert loop',output - print dimension return (output,dimension,eps) # parse the gamma matrices -def convertMatrix(structure,expr,spins,unContracted,Symbols,dtemp,iloc,defns) : +def convertMatrix(structure,spins,unContracted,Symbols,dtemp,defns,iloc) : i1 = structure.spin[0] i2 = structure.spin[1] if(structure.name=="Identity") : - expr += "*%s" % I4 + output = DiracMatrix() + output.value = I4 + output.index=0 + output.name="M" structure="" elif(structure.name=="Gamma5") : - expr += "*%s" % G5 + output = DiracMatrix() + output.value = G5 + output.index=0 + output.name="M" structure="" elif(structure.name=="ProjM") : - expr += "*%s" % PM + output = DiracMatrix() + output.value = PM + output.index=0 + output.name="M" structure="" elif(structure.name=="ProjP") : - expr += "*%s" % PP + output = DiracMatrix() + output.value = PP + output.index=0 + output.name="M" structure="" elif(structure.name=="Gamma") : print structure - # lorentz matrix contracted with the propagator - if(structure.lorentz[0].type=="D") : - if(abs(structure.lorentz[0].value) not in unContracted) : - unContracted.append(abs(structure.lorentz[0].value)) - expr += "*U%s" % abs(structure.lorentz[0].value) - structure="" - elif(structure.lorentz[0].type=="E" and - spins[structure.lorentz[0].value-1]==4) : - expr += "*R%s" % structure.lorentz[0][1] - unContracted.append("R%s" % structure.lorentz[0][1]) + # gamma(mu) lorentz matrix contracted with dummy index + if(structure.lorentz[0].type=="D" or structure.lorentz[0].type=="R") : + if(structure.lorentz[0] not in unContracted) : + unContracted[structure.lorentz[0]] = 0 + output = DiracMatrix() + output.value=0 + output.index=structure.lorentz[0] + output.name="GMU" structure="" elif(structure.lorentz[0].type == "E" and structure.lorentz[0].value == iloc ) : - expr += "*V%s" % iloc - unContracted.append("V%s" % iloc) + if(structure.lorentz[0] not in unContracted) : + unContracted[structure.lorentz[0]] = 0 + output = DiracMatrix() + output.value=0 + output.index=structure.lorentz[0] + output.name="GMU" structure="" else : - expr += "*"+vslash.substitute({ "v" : structure.lorentz[0]}) + output=DiracMatrix() + output.name="M" + output.value = vslash.substitute({ "v" : structure.lorentz[0]}) Symbols += vslashS.substitute({ "v" : structure.lorentz[0]}) if(structure.lorentz[0].type=="P") : dtemp[2] += 1 variable="Energy" else : variable="double" defns["vv%s" % structure.lorentz[0] ] = \ ["vv%s" % structure.lorentz[0], vslashD.substitute({ "var" : variable, "v" : structure.lorentz[0]})] structure="" else : print 'Unknown Gamma matrix structure',structure + quit() + print output.name,output.value,output.index + return (i1,i2,output,structure,Symbols) + + +def checkRSContract(parsed,loc,dtemp) : + contract="" + for i in range(0,len(parsed)) : + if(parsed[i]=="") : continue + found = False + for ll in range(0,len(parsed[i].lorentz)) : + if(parsed[i].lorentz[ll].type=="R" and + parsed[i].lorentz[ll].value==loc) : + found=True + break + if(not found) : + continue + if(parsed[i].name=="P") : + dtemp[2]+=1 + contract = LorentzIndex(parsed[i].value) + contract.type="P" + parsed[i]="" + break + elif(parsed[i].name=="Epsilon") : + continue + else : + print " CONT TEST A",parsed + print 'unkonwn type',parsed[i] + return contract + +def processChain(dtemp,parsed,spins,Symbols,unContracted,defns,iloc) : + # piece of dimension which is common (0.5 for sbar and spinor) + dtemp[0]+=1 + # set up the spin indices + sind = 0 + lind = 0 + expr=[] + # now find the next thing in the matrix string + ii = 0 + index=0 + while True : + # already handled + if(parsed[ii]=="") : + ii+=1 + continue + # start of the chain + elif(sind==0 and len(parsed[ii].spin)==2 and parsed[ii].spin[0]>0 ) : + (sind,index,matrix,parsed[ii],Symbols) \ + = convertMatrix(parsed[ii],spins,unContracted,Symbols,dtemp,defns,iloc) + expr.append(matrix) + # next element in the chain + elif(index!=0 and len(parsed[ii].spin)==2 and parsed[ii].spin[0]==index) : + (crap,index,matrix,parsed[ii],Symbols) \ + = convertMatrix(parsed[ii],spins,unContracted,Symbols,dtemp,defns,iloc) + expr.append(matrix) + # check the index to see if we're at the end + if(index>0) : + lind=index + break + ii+=1 + if(ii>=len(parsed)) : + print "Can't parsed the chain of dirac matrices" + quit() + SkipThisVertex() + # start and end of the spin chains + # easy case, both spin 1/2 + if(spins[sind-1]==2 and spins[lind-1]==2) : + start = DiracMatrix() + end = DiracMatrix() + start.index=0 + end .index=0 + start.name="S" + end .name="S" + # start of chain + # off shell + if(sind==iloc) : + start.name="M" + start.value = vslashM.substitute({ "v" : "P%s" % sind, "m" : "M%s" % sind} ) + Symbols += vslashMS.substitute({ "v" : "P%s" % sind, "m" : "M%s" % sind} ) + defns["vvP%s" % sind ] = ["vvP%s" % sind , + vslashD.substitute({ "var" : "Energy", + "v" : "P%s" % sind })] + dtemp[1]+=1 + # onshell + else : + subs = {'s' : ("sbar%s" % sind)} + start.value = sbar .substitute(subs) + Symbols += sline.substitute(subs) + # end of chain + if(lind==iloc) : + end.name="M" + end.value = vslashM2.substitute({ "v" : "P%s" % lind, "m" : "M%s" % lind} ) + Symbols += vslashMS.substitute({ "v" : "P%s" % lind, "m" : "M%s" % lind} ) + defns["vvP%s" % lind ] = ["vvP%s" % lind , + vslashD.substitute({ "var" : "Energy", + "v" : "P%s" % lind })] + dtemp[1] += 1 + else : + subs = {'s' : ("s%s" % lind)} + end.value = spinor.substitute(subs) + Symbols += sline.substitute(subs) + startT = start + endT = end + # start 1/2 and end 3/2 + elif spins[sind-1]==2 and spins[lind-1]==4 : + start = DiracMatrix() + endT = DiracMatrix() + start.index=0 + endT .index=0 + # spin 1/2 fermion + if(sind==iloc) : + start.value = vslashM.substitute({ "v" : "P%s" % sind, "m" : "M%s" % sind} ) + Symbols += vslashMS.substitute({ "v" : "P%s" % sind, "m" : "M%s" % sind} ) + endT.value = vslashM2.substitute({ "v" : "P%s" % sind, "m" : "M%s" % sind} ) + defns["vvP%s" % sind ] = ["vvP%s" % sind , + vslashD.substitute({ "var" : "Energy", + "v" : "P%s" % sind })] + dtemp[1]+=1 + start.name="M" + endT .name="M" + else : + start.name="S" + endT .name="S" + subs = {'s' : ("sbar%s" % sind)} + start.value = sbar .substitute(subs) + Symbols += sline.substitute(subs) + subs = {'s' : ("s%s" % sind)} + endT.value = spinor.substitute(subs) + Symbols += sline.substitute(subs) + # spin 3/2 fermion + # check if we can easily contract + contract=checkRSContract(parsed,lind,dtemp) + # off-shell + if(lind==iloc) : + oindex = LorentzIndex(lind) + oindex.type="O" + unContracted[oindex]=0 + Symbols += vslashMS.substitute({ "v" : "P%s" % lind, "m" : "M%s" % lind} ) + Symbols += momCom.substitute({"v" : "P%s" %lind }) + defns["vvP%s" % lind ] = ["vvP%s" % lind , + vslashD.substitute({ "var" : "Energy", + "v" : "P%s" % lind })] + dtemp[1] += 1 + if(contract=="") : + rindex = LorentzIndex(lind) + rindex.type="R" + end=DiracMatrix() + end.value = Template(rslash2.substitute({ "v" : "P%s" % lind, "m" : "M%s" % lind, "loc" : lind })) + end.name = "RP" + end.index = (rindex,oindex) + startT=DiracMatrix() + startT.value=Template(rslash.substitute({ "v" : "P%s" % lind, "m" : "M%s" % lind, "loc" : lind })) + startT.name = "RP" + startT.index = (oindex,rindex) + else : + print 'contract A ',contract + quit() + # if(contract!="") : + # Symbols += momCom.substitute({"v" : contract }) + # RB = vslash.substitute({ "v" : contract}) + # Symbols += vslashS.substitute({ "v" : contract }) + # startT = startT.replace("R%sB"%lind,RB) + # end = end .replace("R%sB"%lind,RB) + # name = "dot%s" % (len(defns)+1) + # pi = LorentzIndex(lind) + # pi.type="P" + # defns[(pi,contract)] = [name,"complex<Energy2> %s = %s*%s;" % (name,pi,contract) ] + # Symbols += "%s = Symbol('%s')\n" % (name,name) + # startT = startT.replace("P%sB!" % lind, name).replace("ETA(B!,","ETA(%s," % contract) + # end = end .replace("P%sB!" % lind, name).replace("ETA(B!,","ETA(%s," % contract) + # unContracted.append("RC%s"%lind) + # on-shell + else : + end = DiracMatrix() + startT = DiracMatrix() + # no contraction + if(contract=="") : + # end of matrix string + end.value = Template(spinor.substitute({'s' : ("Rs%s${L}" % lind)})) + end.name = "RS" + end.index = LorentzIndex(lind) + end.index.type = "R" + # start of matrix string + startT.value = Template(sbar .substitute({'s' : ("Rsbar%s${L}" % lind)})) + startT.name = "RS" + startT.index = LorentzIndex(lind) + startT.index.type = "R" + if(not startT.index) : + unContracted[startT.index]=0 + # variables for sympy + for LI in imap : + Symbols += sline.substitute({'s' : ("Rs%s%s" % (lind,LI))}) + Symbols += sline.substitute({'s' : ("Rsbar%s%s" % (lind,LI))}) + # contraction + else : + # end of the matrix string + end.name = "S" + end.value = "Matrix([[%s],[%s],[%s],[%s]])" % (RSDotProduct.substitute({'s' : ("Rs%s" % lind), 'v':contract, 'si' : 1}), + RSDotProduct.substitute({'s' : ("Rs%s" % lind), 'v':contract, 'si' : 2}), + RSDotProduct.substitute({'s' : ("Rs%s" % lind), 'v':contract, 'si' : 3}), + RSDotProduct.substitute({'s' : ("Rs%s" % lind), 'v':contract, 'si' : 4})) + startT.name = "S" + startT.value = "Matrix([[%s,%s,%s,%s]])" % (RSDotProduct.substitute({'s' : ("Rsbar%s" % lind), 'v':contract, 'si' : 1}), + RSDotProduct.substitute({'s' : ("Rsbar%s" % lind), 'v':contract, 'si' : 2}), + RSDotProduct.substitute({'s' : ("Rsbar%s" % lind), 'v':contract, 'si' : 3}), + RSDotProduct.substitute({'s' : ("Rsbar%s" % lind), 'v':contract, 'si' : 4})) + Symbols += momCom.substitute({"v" : contract }) + for LI in ["x","y","z","t"] : + Symbols += sline.substitute({'s' : ("Rs%s%s" % (lind,LI))}) + Symbols += sline.substitute({'s' : ("Rsbar%s%s" % (lind,LI))}) + # start 3/2 and end 1/2 + elif spins[sind-1]==4 and spins[lind-1]==2 : + # spin 1/2 fermion + end = DiracMatrix() + startT = DiracMatrix() + if(lind==iloc) : + end.value = vslashM2.substitute({ "v" : "P%s" % lind, "m" : "M%s" % lind} ) + startT.value = vslashM.substitute({ "v" : "P%s" % lind, "m" : "M%s" % lind} ) + Symbols += vslashMS.substitute({ "v" : "P%s" % lind, "m" : "M%s" % lind} ) + defns["vvP%s" % lind ] = ["vvP%s" % lind , + vslashD.substitute({ "var" : "Energy", + "v" : "P%s" % lind })] + dtemp[1] += 1 + startT.name="M" + end .name="M" + else : + subs = {'s' : ("s%s" % lind)} + end.value = spinor.substitute(subs) + Symbols += sline.substitute(subs) + subs = {'s' : ("sbar%s" % lind)} + startT.value = sbar .substitute(subs) + Symbols += sline.substitute(subs) + startT.name="S" + end .name="S" + # spin 3/2 fermion + # check if we can easily contract + contract=checkRSContract(parsed,sind,dtemp) + # off-shell + if(sind==iloc) : + oindex = LorentzIndex(sind) + oindex.type="O" + unContracted[oindex]=0 + Symbols += vslashMS.substitute({ "v" : "P%s" % sind, "m" : "M%s" % sind} ) + Symbols += momCom.substitute({"v" : "P%s" %sind }) + defns["vvP%s" % sind ] = ["vvP%s" % sind , + vslashD.substitute({ "var" : "Energy", + "v" : "P%s" % sind })] + dtemp[1] += 1 + if(contract=="") : + rindex = LorentzIndex(sind) + rindex.type="R" + start=DiracMatrix() + start.value = Template(rslash.substitute({ "v" : "P%s" % sind, "m" : "M%s" % sind, "loc" : sind })) + start.name = "RP" + start.index = (oindex,rindex) + endT=DiracMatrix() + endT.value = Template(rslash2.substitute({ "v" : "P%s" % sind, "m" : "M%s" % sind, "loc" : sind })) + endT.name = "RP" + endT.index = (rindex,oindex) + else : + # contstrct dot product + pi = LorentzIndex(sind) + pi.type="P" + iTemp = tuple(sorted((pi,contract),cmp=indSort)) + if iTemp in defns : + name = defns[iTemp][0] + else : + name = "dot%s" % (len(defns)+1) + unit = "double" + if(contract.type=="P") : + unit = "Energy2" + defns[iTemp] = [name,"complex<%s> %s = %s*%s;" % (unit,name,pi,contract) ] + Symbols += momCom.substitute({"v" : contract }) + RB = vslash.substitute({ "v" : contract}) + Symbols += vslashS.substitute({ "v" : contract }) + Symbols += "%s = Symbol('%s')\n" % (name,name) + start=DiracMatrix() + start.name="RQ" + start.index = oindex + start.value =Template( rslashB.substitute({ "v" : "P%s" % sind, "m" : "M%s" % sind, "loc" : sind, + "DB" : RB, "dot" : name , "v2" : contract})) + + endT=DiracMatrix() + endT.name = "RQ" + endT.index = oindex + endT.value = Template(rslash2B.substitute({ "v" : "P%s" % sind, "m" : "M%s" % sind, "loc" : sind , + "DA" : RB, "dot" : name , "v2" : contract})) + # on-shell + else : + start = DiracMatrix() + endT = DiracMatrix() + # no contraction + if(contract=="") : + # start of matrix string + start.value = Template(sbar .substitute({'s' : ("Rsbar%s${L}" % sind)})) + start.name="RS" + start.index = LorentzIndex(sind) + start.index.type="R" + # end of transpose string + endT.value=Template(spinor.substitute({'s' : ("Rs%s${L}" % sind)})) + endT.name="RS" + endT.index = LorentzIndex(sind) + endT.index.type="R" + # variables for sympy + for LI in imap : + Symbols += sline.substitute({'s' : ("Rs%s%s" % (sind,LI))}) + Symbols += sline.substitute({'s' : ("Rsbar%s%s" % (sind,LI))}) + else : + # start of matrix string + start.name="S" + start.value = "Matrix([[%s,%s,%s,%s]])" % (RSDotProduct.substitute({'s' : ("Rsbar%s" % sind), 'v':contract, 'si' : 1}), + RSDotProduct.substitute({'s' : ("Rsbar%s" % sind), 'v':contract, 'si' : 2}), + RSDotProduct.substitute({'s' : ("Rsbar%s" % sind), 'v':contract, 'si' : 3}), + RSDotProduct.substitute({'s' : ("Rsbar%s" % sind), 'v':contract, 'si' : 4})) + endT.name="S" + endT.value = "Matrix([[%s],[%s],[%s],[%s]])" % (RSDotProduct.substitute({'s' : ("Rs%s" % sind), 'v':contract, 'si' : 1}), + RSDotProduct.substitute({'s' : ("Rs%s" % sind), 'v':contract, 'si' : 2}), + RSDotProduct.substitute({'s' : ("Rs%s" % sind), 'v':contract, 'si' : 3}), + RSDotProduct.substitute({'s' : ("Rs%s" % sind), 'v':contract, 'si' : 4})) + Symbols += momCom.substitute({"v" : contract }) + for LI in ["x","y","z","t"] : + Symbols += sline.substitute({'s' : ("Rs%s%s" % (sind,LI))}) + Symbols += sline.substitute({'s' : ("Rsbar%s%s" % (sind,LI))}) + else : + print 'At most one R-S spinor allowed in a vertex' raise SkipThisVertex() - return (i1,i2,expr,structure,unContracted,Symbols,dtemp) + return(sind,lind,expr,start,startT,end,endT,Symbols) +def calculateDirac(expr,start,end,startT,endT,sind,lind,Symbols,iloc) : + res=[] + for ichain in range(0,len(start)) : + # calculate the matrix string + etemp="*".join(str(x) for x in expr[ichain]) + temp={} + exec("import sympy\nfrom sympy import Symbol,Matrix\n"+Symbols+"result="+ + ( "%s*%s*%s" %(start[ichain],etemp,end[ichain]))) in temp + res.append(temp["result"]) + tempT={} + exec("import sympy\nfrom sympy import Symbol,Matrix,Transpose\n"+Symbols+"result="+ + ( "%s*%s*Transpose(%s)*%s*%s" %(startT[0],CC,etemp,CD,endT[0]))) in tempT + res.append(tempT["result"]) + if(len(start)==1) : + if(iloc==0 or (iloc!=sind[0] and iloc!=lind[0])) : + sVal = {'s' : temp ["result"][0,0],'sT' : tempT["result"][0,0]} + else : + sVal={} + for jj in range(1,5) : + sVal["s%s" % jj] = temp ["result"][jj-1] + sVal["sT%s" % jj] = tempT["result"][jj-1] + else : + sVal={} + sVal["s" ] = res[0][0,0]*res[2][0,0] + sVal["sT2" ] = res[0][0,0]*res[3][0,0] + sVal["sT1" ] = res[1][0,0]*res[2][0,0] + sVal["sT12"] = res[1][0,0]*res[3][0,0] + return sVal + + +def addToOutput(res,nchain,sign,rTemp) : + # 1 spin chain + if(nchain==1) : + for ii in range(0,2) : + if(rTemp[ii][0].shape[0]==1) : + # result is scalar + if(rTemp[ii][0].shape[1]==1) : + if(len(res[ii])==0) : + res[ii].append(sign*rTemp [ii][0][0,0]) + else : + res[ii][0] += sign*rTemp [ii][0][0,0] + # result is a spinor + elif(rTemp[ii][0].shape[1]==4) : + if(len(res[ii])==0) : + for j in range(0,4) : + res[ii].append(sign*rTemp[ii][0][0,j]) + else : + for j in range(0,4) : + res[ii][j] += sign*rTemp[ii][0][0,j] + else : + print "SIZE PROBLEM A",sign,rTemp[ii].shape + quit() + raise SkipThisVertex() + # spinor + elif(rTemp[ii][0].shape[0]==4 and rTemp[ii][0].shape[1]==1 ) : + if(len(res[ii])==0) : + for j in range(0,4) : + res[ii].append(sign*rTemp[ii][0][j,0]) + else : + for j in range(0,4) : + res[ii][j] += sign*rTemp[ii][0][j,0] + else : + print "SIZE PROBLEM B ",sign,rTemp[ii][0].shape + quit() + raise SkipThisVertex() + # 2 spin chains, should only be for a vertex + else : + for j1 in range(0,2) : + for j2 in range (0,2) : + val = sign*rTemp[j1][0]*rTemp[j2][1] + if(len(res[3])==0) : + res[2*j1+j2].append(val[0,0]) + else : + res[2*j1+j2][0] += val[0,0] + +def calculateDirac2(expr,start,end,startT,endT,sind,lind,Symbols,defns, + iloc,unContracted,spins,lorentz) : + # output + sVal={} + # no of chains + nchain=len(expr) + # now deal with the uncontracted cases + contracted={} + # sort out contracted and uncontracted indices + keys = unContracted.keys() + for key in keys: + # summed dummy index + if key.type=="D" : + contracted[key]=0 + del unContracted[key] + # RS index + elif key.type =="R" : + contracted[key]=0 + del unContracted[key] + # external index + elif key.type == "O" : + continue + # uncontracted vector index + elif key.type=="E" or key.type=="Q": + continue + else : + print 'uknown type of uncontracted index',key + quit() + raise SkipThisVertex() + # check the lorentz structures + for lstruct in lorentz : + if(lstruct.name=="Epsilon") : + for index in lstruct.lorentz : + if(index.type=="E" and index.value==iloc) : + unContracted[index]=0 + elif(index.type=="P" or index.type=="E" + or index.type=="R" or index.type=="D") : + contracted[index]=0 + else : + print 'unknown index',index + quit() + else : + print 'unkonwn lorentz object',lstruct + quit() + # iterate over the uncontracted indices + defns["I"] = ["I","static Complex I(0.,1.);"] + print contracted + print unContracted + while True : + # loop over the unContracted indices + res = [] + for i in range(0,nchain) : + res.append([]) + res.append([]) + # loop over the contracted indices + while True : + sign = 1 + eTemp =[] + sTemp =[] + fTemp =[] + sTTemp=[] + fTTemp=[] + # make the necessary replacements for remaining indices + for ichain in range(0,nchain) : + # compute the main expression + eTemp.append([]) + for val in expr[ichain] : + # already a matrix + if(val.name=="M") : + eTemp[ichain].append(val) + # gamma(mu), replace with correct dirac matrix + elif(val.name=="GMU") : + if(val.index in contracted) : + eTemp[ichain].append(dirac[contracted[val.index]]) + elif(val.index in unContracted) : + eTemp[ichain].append(dirac[unContracted[val.index]]) + else : + print 'unknown index' + print val + print val.name + print val.value + print val.index + quit() + # unknown to be sorted out + else : + print 'unkonwn type in expr' + print val + print val.name + print val.value + print val.index + quit() + # start and end + # start + if(start[ichain].name=="S" or start[ichain].name=="M" ) : + sTemp.append(start[ichain].value) + elif(start[ichain].name=="RS") : + sTemp.append(start[ichain].value.substitute({"L" : imap[contracted[start[ichain].index]] })) + elif(start[ichain].name=="RQ") : + i1 = unContracted[start[ichain].index] + sTemp.append(start[ichain].value.substitute({"A" : imap[i1], "DA" : dirac[i1] })) + elif(start[ichain].name=="RP") : + print 'indices',start[ichain].index + print unContracted + print contracted + i1 = unContracted[start[ichain].index[0]] + i2 = contracted[start[ichain].index[1]] + eta=0 + if(i1==i2) : + if(i1==0) : eta = 1 + else : eta = -1 + sTemp.append(start[ichain].value.substitute({"eta" : eta, "A":imap[i1] , "B":imap[i2] , + "DA": dirac[i1], "DB": dirac[i2]})) + else : + print 'barred spinor not a spinor' + print start[ichain].name + print start[ichain].value + print start[ichain].index + quit() + if(startT[ichain].name=="S" or startT[ichain].name=="M" ) : + sTTemp.append(startT[ichain].value) + elif(startT[ichain].name=="RS") : + sTTemp.append(startT[ichain].value.substitute({"L" : imap[contracted[startT[ichain].index]] })) + elif(start[ichain].name=="RQ") : + i1 = unContracted[startT[ichain].index] + sTTemp.append(startT[ichain].value.substitute({"A" : imap[i1], "DA" : dirac[i1] })) + elif(startT[ichain].name=="RP") : + i1 = unContracted[startT[ichain].index[0]] + i2 = contracted[startT[ichain].index[1]] + eta=0 + if(i1==i2) : + if(i1==0) : eta = 1 + else : eta = -1 + sTTemp.append(startT[ichain].value.substitute({"eta" : eta, "A":imap[i1] , "B":imap[i2] , + "DA": dirac[i1], "DB": dirac[i2]})) + else : + print 'barred spinorT not a spinor' + print startT[ichain].name + print startT[ichain].value + print startT[ichain].index + quit() + # end + if(end[ichain].name=="S" or end[ichain].name=="M" ) : + fTemp.append(end[ichain].value) + elif(end[ichain].name=="RS") : + fTemp.append(end[ichain].value.substitute({"L" : imap[contracted[end[ichain].index]] })) + elif(end[ichain].name=="RQ") : + i1 = unContracted[end[ichain].index] + fTemp.append(end[ichain].value.substitute({"B" : imap[i1], "DB": dirac[i1] })) + elif(end[ichain].name=="RP") : + i1 = contracted[end[ichain].index[0]] + i2 = unContracted[end[ichain].index[1]] + eta=0 + if(i1==i2) : + if(i1==0) : eta = 1 + else : eta = -1 + fTemp.append(end[ichain].value.substitute({"eta" : eta, "A":imap[i1] , "B":imap[i2] , + "DA": dirac[i1], "DB": dirac[i2]})) + else : + print 'spinor not a spinor' + print end[ichain].name + print end[ichain].value + print end[ichain].index + quit() + if(endT[ichain].name=="S" or endT[ichain].name=="M" ) : + fTTemp.append(endT[ichain].value) + elif(endT[ichain].name=="RS") : + fTTemp.append(endT[ichain].value.substitute({"L" : imap[contracted[endT[ichain].index]] })) + elif(endT[ichain].name=="RQ") : + i1 = unContracted[endT[ichain].index] + fTTemp.append(endT[ichain].value.substitute({"B" : imap[i1], "DB": dirac[i1] })) + elif(endT[ichain].name=="RP") : + i1 = contracted[endT[ichain].index[0]] + i2 = unContracted[endT[ichain].index[1]] + eta=0 + if(i1==i2) : + if(i1==0) : eta = 1 + else : eta = -1 + fTTemp.append(endT[ichain].value.substitute({"eta" : eta, "A":imap[i1] , "B":imap[i2] , + "DA": dirac[i1], "DB": dirac[i2]})) + else : + print 'spinorT not a spinor' + print endT[ichain].name + print endT[ichain].value + print endT[ichain].index + quit() + # and none dirac lorentz structures + for li in lorentz: + # uncontracted vector + if(li.name=="Vector") : + index = unContracted[li.lorentz[0]] + Symbols += momCom.substitute({"v":li.value}) + for ichain in range(0,nchain) : + eTemp[ichain].append("%s%s"% (li.value,imap[index]) ) + # unknown + else : + print 'unknown expression in lorentz loop' + print li.name + print li.value + quit() + raise SkipThisVertex() + + + # if(unContracted[j][0]=="R") : + # print 'uncontracted R' + # ii = int(unContracted[j][1]) + # sTemp[ichain] = sTemp[ichain].replace(unContracted[j]+"A",dirac[unI[j]]) + # sTTemp[ichain] = sTTemp[ichain].replace(unContracted[j]+"A",dirac[unI[j]]) + # fTemp[ichain] = fTemp[ichain].replace(unContracted[j]+"A",dirac[unI[j]]) + # fTTemp[ichain] = fTTemp[ichain].replace(unContracted[j]+"A",dirac[unI[j]]) + # sTemp[ichain] = sTemp[ichain].replace("A!",imap[unI[j]]) + # sTTemp[ichain] = sTTemp[ichain].replace("A!",imap[unI[j]]) + # fTemp[ichain] = fTemp[ichain].replace("A!",imap[unI[j]]) + # fTTemp[ichain] = fTTemp[ichain].replace("A!",imap[unI[j]]) + # # handle metric tensors + # eta=re.search("ETA\(.*,.\)",sTemp[ichain]) + # if(eta) : + # eta = eta.group(0) + # if(eta.find("!")<0) : + # temp = eta.split("(")[1].split(",") + # replace = temp[0]+temp[1][0] + # sTemp[ichain] = sTemp[ichain].replace(eta,replace) + # sTTemp[ichain] = sTTemp[ichain].replace(eta,replace) + # fTemp[ichain] = fTemp[ichain].replace(eta,replace) + # fTTemp[ichain] = fTTemp[ichain].replace(eta,replace) + # # make the necessary replacements for contracted indices + # for ichain in range(0,nchain) : + # for j in range(0,len(contracted)) : + # if(isinstance(contracted[j],int)) : + # eTemp[ichain]=eTemp[ichain].replace("U%s"%contracted[j],dirac[coI[j]]) + # if(ichain==0 and coI[j]>0) : sign *= -1 + # elif(contracted[j][0]=="R") : + # ii = int(contracted[j][1]) + # # replace metric + # for k in range(0,4) : + # test = "ETA(B!,%s)" % (imap[k]) + # esign="0" + # if(coI[j]==k) : esign="1" + # print test,sTemp,ichain + # sTemp[ichain] = sTemp[ichain].replace(test,esign) + # sTTemp[ichain] = sTTemp[ichain].replace(test,esign) + # fTemp[ichain] = fTemp[ichain].replace(test,esign) + # fTTemp[ichain] = fTTemp[ichain].replace(test,esign) + # # replace dirac matrices + # eTemp[ichain] = eTemp[ichain].replace(contracted[j],dirac[coI[j]]) + # sTemp[ichain] = sTemp[ichain].replace(contracted[j]+"B",dirac[coI[j]]) + # sTTemp[ichain] = sTTemp[ichain].replace(contracted[j]+"B",dirac[coI[j]]) + # fTemp[ichain] = fTemp[ichain].replace(contracted[j]+"B",dirac[coI[j]]) + # fTTemp[ichain] = fTTemp[ichain].replace(contracted[j]+"B",dirac[coI[j]]) + # # replacements for start + # sTemp[ichain] = sTemp[ichain].replace("Rsbar%sL" % ii,"Rsbar%s%s" % (ii,imap[coI[j]])) + # sTemp[ichain] = sTemp[ichain].replace("B!",imap[coI[j]]) + # sTTemp[ichain] = sTTemp[ichain].replace("B!",imap[coI[j]]) + # # replacements for end + # fTemp[ichain] = fTemp[ichain].replace("Rs%sL" % ii,"Rs%s%s" % (ii,imap[coI[j]])) + # fTTemp[ichain] = fTTemp[ichain].replace("Rs%sL" % ii,"Rs%s%s" % (ii,imap[coI[j]])) + # fTemp[ichain] = fTemp[ichain].replace("B!",imap[coI[j]]) + # fTTemp[ichain] = fTTemp[ichain].replace("B!",imap[coI[j]]) + # if(ichain==0 and coI[j]>0) : sign *= -1 + # else : + # print 'need to implment',contracted[j] + # quit() + + + + + + + + + + # now evaluate the result + rTemp =[[],[]] + for ichain in range(0,nchain) : + core = "*".join(str(x) for x in eTemp[ichain]) + temp={} + exec("import sympy\nfrom sympy import Symbol,Matrix\n"+Symbols+"result="+ + ( "(%s)*(%s)*(%s)" %(sTemp[ichain],core,fTemp[ichain]))) in temp + rTemp[0].append(temp["result"]) + temp={} + exec("import sympy\nfrom sympy import Symbol,Matrix,Transpose\n"+Symbols+"result="+ + ( "(%s)*(%s)*(Transpose(%s))*(%s)*(%s)" %(sTTemp[ichain],CC,core,CD,fTTemp[ichain]))) in temp + rTemp[1].append(temp["result"]) + # and add it to the output + addToOutput(res,nchain,sign,rTemp) + #### END OF THE CONTRACTED LOOP ##### + # increment the indices being summed over + keys=contracted.keys() + ii = len(keys)-1 + while ii >=0 : + if(contracted[keys[ii]]<3) : + contracted[keys[ii]]+=1 + break + else : + contracted[keys[ii]]=0 + ii-=1 + nZero=0 + for (key,val) in contracted.iteritems() : + if(val==0) : nZero+=1 + if(nZero==len(contracted)) : break + ###### END OF THE UNCONTRACTED LOOP ###### + # no uncontracted indices + if(len(unContracted)==0) : + if(len(res[0])==1) : + # scalar + if(len(res)==2) : + sVal["s" ] = res[0] + sVal["sT"] = res[1] + # 4 fermion + else : + sVal["s" ] = res[0][0] + sVal["sT2" ] = res[1][0] + sVal["sT1" ] = res[2][0] + sVal["sT12"] = res[3][0] + # spinor + elif(len(res[0])==4) : + for k in range(0,4) : + sVal[ "s%s" % (k+1) ] = res[0][k] + sVal[ "sT%s" % (k+1) ] = res[1][k] + else : + print 'summ problem',len(res),len(res[0]) + quit() + break + # uncontracted indices + else : + istring = "" + for (key,val) in unContracted.iteritems() : + istring +=imap[val] + if(len(istring)!=1) : + print 'index problem',istring + print unContracted + print unI + quit() + sVal[istring] = res[0] + sVal[istring+"T"] = res[1] + # increment the unsummed indices + keys=unContracted.keys() + ii = len(keys)-1 + while ii >=0 : + if(unContracted[keys[ii]]<3) : + unContracted[keys[ii]]+=1 + break + else : + unContracted[keys[ii]]=0 + ii-=1 + nZero=0 + for (key,val) in unContracted.iteritems() : + if(val==0) : nZero+=1 + if(nZero==len(unContracted)) : break + # handle the vector case + if( "t" in sVal ) : + # deal with pure vectors + if(len(sVal)==8 and "t" in sVal and len(sVal["t"])==1) : + pass + # RS spinors + elif(len(sVal)==8 and "t" in sVal and len(sVal["t"])==4) : + pass + else : + print sVal + print 'val problrm A',len(sVal) + quit() + else : + if("s" in sVal) : + for key in sVal: + sVal[key] = sVal[key][0] +# print sVal +# quit() + return sVal + def convertDiracStructure(parsed,output,dimension,defns,iloc,L,lorentztag,vertex) : - print 'start of structure',iloc - # templates - spinor = Template("Matrix([[${s}s1],[${s}s2],[${s}s3],[${s}s4]])") - sbar = Template("Matrix([[${s}s1,${s}s2,${s}s3,${s}s4]])") - sline = Template("${s}s1=Symbol(\"${s}s1\")\n${s}s2=Symbol(\"${s}s2\")\n${s}s3=Symbol(\"${s}s3\")\n${s}s4=Symbol(\"${s}s4\")\n") # get the spins of the particles spins = vertex.lorentz[0].spins # check if we have one or two spin chains nchain = (lorentztag.count("F")+lorentztag.count("R"))/2 - expr=[] - sind=[] - lind=[] - start=[] - end=[] + # storage of the intermediate results + expr =[] + start =[] + end =[] startT=[] - endT=[] - unContracted=[] + endT =[] + sind=[0]*nchain + lind=[0]*nchain + unContracted={} Symbols="" dtemp=[0,0,0] + # parse the dirac matrix strings for ichain in range(0,nchain) : - # piece of dimension which is common (0.5 for sbar and spinor) - dtemp[0]+=1 - # set up the spin indices - sind.append(0) - lind.append(0) - # and the expresion - expr.append("") - # now find the next thing in the string - ii = 0 - index=0 - while True : - # already handled - if(parsed[ii]=="") : - ii+=1 - continue - # start of the chain - elif(sind[ichain]==0 and len(parsed[ii].spin)==2 and parsed[ii].spin[0]>0 ) : - (sind[ichain],index,expr[ichain],parsed[ii],unContracted,Symbols,dtemp) \ - = convertMatrix(parsed[ii],expr[ichain],spins,unContracted,Symbols,dtemp,iloc,defns) - # next element in the chain - elif(index!=0 and len(parsed[ii].spin)==2 and parsed[ii].spin[0]==index) : - (crap,index,expr[ichain],parsed[ii],unContracted,Symbols,dtemp) \ - = convertMatrix(parsed[ii],expr[ichain],spins,unContracted,Symbols,dtemp,iloc,defns) - # check the index to see if we're at the end - if(index>0) : - lind[ichain]=index - break - ii+=1 - if(ii>=len(parsed)) :break - # start and end of the spin chains - # easy case, both spin 1/2 - if(spins[sind[ichain]-1]==2 and spins[lind[ichain]-1]==2) : - # start of chain - # off shell - if(sind[ichain]==iloc) : - start.append(vslashM.substitute({ "v" : "P%s" % sind[ichain], "m" : "M%s" % sind[ichain]} )) - Symbols += vslashMS.substitute({ "v" : "P%s" % sind[ichain], "m" : "M%s" % sind[ichain]} ) - defns["vvP%s" % sind[ichain] ] = ["vvP%s" % sind[ichain] , - vslashD.substitute({ "var" : "Energy", - "v" : "P%s" % sind[ichain] })] - dtemp[1]+=1 - # onshell - else : - subs = {'s' : ("sbar%s" % sind[ichain])} - start.append(sbar .substitute(subs)) - Symbols += sline.substitute(subs) - # end of chain - if(lind[ichain]==iloc) : - end.append(vslashM2.substitute({ "v" : "P%s" % lind[ichain], "m" : "M%s" % lind[ichain]} )) - Symbols += vslashMS.substitute({ "v" : "P%s" % lind[ichain], "m" : "M%s" % lind[ichain]} ) - defns["vvP%s" % lind[ichain] ] = ["vvP%s" % lind[ichain] , - vslashD.substitute({ "var" : "Energy", - "v" : "P%s" % lind[ichain] })] - dtemp[1] += 1 - else : - subs = {'s' : ("s%s" % lind[ichain])} - end.append(spinor.substitute(subs)) - Symbols += sline.substitute(subs) - startT.append(start[ichain]) - endT .append(end[ichain]) - # start 1/2 and end 3/2 - elif spins[sind[ichain]-1]==2 and spins[lind[ichain]-1]==4 : - # spin 1/2 fermion - if(sind[ichain]==iloc) : - start.append(vslashM.substitute({ "v" : "P%s" % sind[ichain], "m" : "M%s" % sind[ichain]} )) - Symbols += vslashMS.substitute({ "v" : "P%s" % sind[ichain], "m" : "M%s" % sind[ichain]} ) - endT.append(vslashM2.substitute({ "v" : "P%s" % sind[ichain], "m" : "M%s" % sind[ichain]} )) - defns["vvP%s" % sind[ichain] ] = ["vvP%s" % sind[ichain] , - vslashD.substitute({ "var" : "Energy", - "v" : "P%s" % sind[ichain] })] - dtemp[1]+=1 - else : - subs = {'s' : ("sbar%s" % sind[ichain])} - start.append(sbar .substitute(subs)) - Symbols += sline.substitute(subs) - subs = {'s' : ("s%s" % sind[ichain])} - endT.append(spinor.substitute(subs)) - Symbols += sline.substitute(subs) - # spin 3/2 fermion - if(lind[ichain]==iloc) : - contract="" - for k in range(1,len(vertex.particles)+1) : - if(output.find("(P%s)" %k)>=0) : - output = output.replace("(P%s)" %k,"1.") - contract="P%s" %k - end.append(rslash2.substitute({ "v" : "P%s" % lind[ichain], "m" : "M%s" % lind[ichain], - "loc" : lind[ichain] })) - Symbols += vslashMS.substitute({ "v" : "P%s" % lind[ichain], "m" : "M%s" % lind[ichain]} ) - startT.append(rslash.substitute({ "v" : "P%s" % lind[ichain], - "m" : "M%s" % lind[ichain], "loc" : lind[ichain] })) - defns["vvP%s" % lind[ichain] ] = ["vvP%s" % lind[ichain] , - vslashD.substitute({ "var" : "Energy", - "v" : "P%s" % lind[ichain] })] - Symbols += momCom.substitute({"v" : "P%s" %lind[ichain] }) - dtemp[1] += 1 - if(contract!="") : - Symbols += momCom.substitute({"v" : contract }) - RB = vslash.substitute({ "v" : contract}) - Symbols += vslashS.substitute({ "v" : contract }) - startT[ichain] = startT[ichain].replace("R%sB"%lind[ichain],RB) - end [ichain] = end [ichain].replace("R%sB"%lind[ichain],RB) - name = "dot%s" % (len(defns)+1) - defns[('P%s'%lind[ichain],contract)] = [name,"complex<Energy2> %s = P%s*%s;" % (name,lind[ichain],contract) ] - Symbols += "%s = Symbol('%s')\n" % (name,name) - startT[ichain] = startT[ichain].replace("P%sB!" % lind[ichain], name).replace("ETA(B!,","ETA(%s," % contract) - end [ichain] = end [ichain].replace("P%sB!" % lind[ichain], name).replace("ETA(B!,","ETA(%s," % contract) - unContracted.append("RC%s"%lind[ichain]) - else : - # check if we have a contraction issue - contract="" - for key,val in defns.iteritems() : - if(not isinstance(key,tuple)) : continue - if(key[0]== "E%s" %lind[ichain]) : - if(output.find("(%s)"%val[0])>=0) : - contract=key[1] - output = output.replace("(%s)"%val[0],"1.") - elif(key[1]=="E%s" %lind[ichain]) : - if(output.find("(%s)"%val[0])>=0) : - contract=key[0] - output = output.replace("(%s)"%val[0],"1.") - if(contract=="") : - end.append(spinor.substitute({'s' : ("Rs%sL" % lind[ichain])})) - startT.append(sbar .substitute({'s' : ("Rsbar%sL" % lind[ichain])})) - for LI in imap : - Symbols += sline.substitute({'s' : ("Rs%s%s" % (lind[ichain],LI))}) - Symbols += sline.substitute({'s' : ("Rsbar%s%s" % (lind[ichain],LI))}) - else : - dTemp = Template("${s}ts${si}*${v}t-${s}xs${si}*${v}x-${s}ys${si}*${v}y-${s}zs${si}*${v}z") - startT.append("Matrix([[%s,%s,%s,%s]])" % (dTemp.substitute({'s' : ("Rsbar%s" % lind[ichain]), 'v':contract, 'si' : 1}), - dTemp.substitute({'s' : ("Rsbar%s" % lind[ichain]), 'v':contract, 'si' : 2}), - dTemp.substitute({'s' : ("Rsbar%s" % lind[ichain]), 'v':contract, 'si' : 3}), - dTemp.substitute({'s' : ("Rsbar%s" % lind[ichain]), 'v':contract, 'si' : 4}))) - end .append("Matrix([[%s],[%s],[%s],[%s]])" % (dTemp.substitute({'s' : ("Rs%s" % lind[ichain]), 'v':contract, 'si' : 1}), - dTemp.substitute({'s' : ("Rs%s" % lind[ichain]), 'v':contract, 'si' : 2}), - dTemp.substitute({'s' : ("Rs%s" % lind[ichain]), 'v':contract, 'si' : 3}), - dTemp.substitute({'s' : ("Rs%s" % lind[ichain]), 'v':contract, 'si' : 4}))) - Symbols += momCom.substitute({"v" : contract }) - for LI in ["x","y","z","t"] : - Symbols += sline.substitute({'s' : ("Rs%s%s" % (lind[ichain],LI))}) - Symbols += sline.substitute({'s' : ("Rsbar%s%s" % (lind[ichain],LI))}) - # start 1/2 and end 3/2 - elif spins[sind[ichain]-1]==4 and spins[lind[ichain]-1]==2 : - # spin 3/2 fermion - if(sind[ichain]==iloc) : - contract="" - for k in range(1,len(vertex.particles)+1) : - if(output.find("(P%s)" %k)>=0) : - output = output.replace("(P%s)" %k,"1.") - contract="P%s" %k - start.append(rslash.substitute({ "v" : "P%s" % sind[ichain], "m" : "M%s" % sind[ichain], "loc" : sind[ichain] })) - Symbols += vslashMS.substitute({ "v" : "P%s" % sind[ichain], "m" : "M%s" % sind[ichain]} ) - endT.append(rslash2.substitute({ "v" : "P%s" % sind[ichain], "m" : "M%s" % sind[ichain], "loc" : sind[ichain] })) - defns["vvP%s" % sind[ichain] ] = ["vvP%s" % sind[ichain] , - vslashD.substitute({ "var" : "Energy", - "v" : "P%s" % sind[ichain] })] - Symbols += momCom.substitute({"v" : "P%s" %sind[ichain] }) - dtemp[1] += 1 - if(contract!="") : - Symbols += momCom.substitute({"v" : contract }) - RB = vslash.substitute({ "v" : contract}) - Symbols += vslashS.substitute({ "v" : contract }) - start[ichain] = start[ichain].replace("R%sB"%sind[ichain],RB) - endT [ichain] = endT [ichain].replace("R%sB"%sind[ichain],RB) - name = "dot%s" % (len(defns)+1) - defns[('P%s'%sind[ichain],contract)] = [name,"complex<Energy2> %s = P%s*%s;" % (name,sind[ichain],contract) ] - Symbols += "%s = Symbol('%s')\n" % (name,name) - start[ichain] = start[ichain].replace("P%sB!" % sind[ichain], name).replace("ETA(B!,","ETA(%s," % contract) - endT [ichain] = endT [ichain].replace("P%sB!" % sind[ichain], name).replace("ETA(B!,","ETA(%s," % contract) - unContracted.append("RC%s"%sind[ichain]) - else : - # check if we have a contraction issue - contract="" - for key,val in defns.iteritems() : - if(not isinstance(key,tuple)) : continue - if(key[0]== "E%s" %sind[ichain]) : - if(output.find("(%s)"%val[0])>=0) : - contract=key[1] - output = output.replace("(%s)"%val[0],"1.") - elif(key[1]=="E%s" %sind[ichain]) : - if(output.find("(%s)"%val[0])>=0) : - contract=key[0] - output = output.replace("(%s)"%val[0],"1.") - if(contract=="") : - start = sbar .substitute({'s' : ("Rsbar%sL" % sind[ichain])}) - endT = spinor.substitute({'s' : ("Rs%sL" % sind[ichain])}) - for LI in imap : - Symbols += sline.substitute({'s' : ("Rs%s%s" % (sind[ichain],LI))}) - Symbols += sline.substitute({'s' : ("Rsbar%s%s" % (sind[ichain],LI))}) - else : - dTemp = Template("${s}ts${si}*${v}t-${s}xs${si}*${v}x-${s}ys${si}*${v}y-${s}zs${si}*${v}z") - start.append("Matrix([[%s,%s,%s,%s]])" % (dTemp.substitute({'s' : ("Rsbar%s" % sind[ichain]), 'v':contract, 'si' : 1}), - dTemp.substitute({'s' : ("Rsbar%s" % sind[ichain]), 'v':contract, 'si' : 2}), - dTemp.substitute({'s' : ("Rsbar%s" % sind[ichain]), 'v':contract, 'si' : 3}), - dTemp.substitute({'s' : ("Rsbar%s" % sind[ichain]), 'v':contract, 'si' : 4}))) - endT .append("Matrix([[%s],[%s],[%s],[%s]])" % (dTemp.substitute({'s' : ("Rs%s" % sind[ichain]), 'v':contract, 'si' : 1}), - dTemp.substitute({'s' : ("Rs%s" % sind[ichain]), 'v':contract, 'si' : 2}), - dTemp.substitute({'s' : ("Rs%s" % sind[ichain]), 'v':contract, 'si' : 3}), - dTemp.substitute({'s' : ("Rs%s" % sind[ichain]), 'v':contract, 'si' : 4}))) - Symbols += momCom.substitute({"v" : contract }) - for LI in ["x","y","z","t"] : - Symbols += sline.substitute({'s' : ("Rs%s%s" % (sind[ichain],LI))}) - Symbols += sline.substitute({'s' : ("Rsbar%s%s" % (sind[ichain],LI))}) - if(lind[ichain]==iloc) : - end .append(vslashM2.substitute({ "v" : "P%s" % lind[ichain], "m" : "M%s" % lind[ichain]} )) - startT.append(vslashM.substitute({ "v" : "P%s" % lind[ichain], "m" : "M%s" % lind[ichain]} )) - Symbols += vslashMS.substitute({ "v" : "P%s" % lind[ichain], "m" : "M%s" % lind[ichain]} ) - defns["vvP%s" % lind[ichain] ] = ["vvP%s" % lind[ichain] , - vslashD.substitute({ "var" : "Energy", - "v" : "P%s" % lind[ichain] })] - dtemp[1] += 1 - else : - subs = {'s' : ("s%s" % lind[ichain])} - end .append(spinor.substitute(subs)) - Symbols += sline.substitute(subs) - subs = {'s' : ("sbar%s" % lind[ichain])} - startT .append(sbar .substitute(subs)) - Symbols += sline.substitute(subs) - else : - print 'At most one R-S spinor allowed in a vertex' - raise SkipThisVertex() - # remove leading * - for i in range(0,nchain) : expr[i]=expr[i][1:] + expr .append([]) + start .append("") + startT.append("") + end .append("") + endT .append("") + sind[ichain],lind[ichain],expr[ichain],start[ichain],startT[ichain],end[ichain],endT[ichain],Symbols =\ + processChain(dtemp,parsed,spins,Symbols,unContracted,defns,iloc) + # clean up parsed # check we've dealt with everything parsed = [x for x in parsed if x != ""] + lorentz=[] if(len(parsed)!=0) : for i in range(0,len(parsed)) : if(parsed[i].name=="Metric") : found = False for ll in parsed[i].lorentz : if(ll.type=="E" and ll.value==iloc) : found = True + un=ll else : lo=ll if(found) : + lstruct = LorentzStructure() + lstruct.name="Vector" + lstruct.value=lo + lstruct.lorentz=[un] + lstruct.spin=[] + lorentz.append(lstruct) parsed[i]="" - for i in range(0,nchain) : - expr[i]+="*%s(V%s)" % (lo,iloc) - unContracted.append("V%s" % iloc) + unContracted[un]=0 if(lo.type=="P") : dimension[2]+=1 + # elif(parsed[i].name=="Tensor") : + # print "tensor",parsed[i],iloc + elif(parsed[i].name=="Epsilon") : + lstruct = LorentzStructure() + lstruct.name="Epsilon" + lstruct.lorentz=parsed[i].lorentz + lstruct.value=0 + lstruct.spin=[] + for index in lstruct.lorentz: + if(index.type=="P") : + dimension[2]+=1 + lorentz.append(lstruct) + parsed[i]="" + else : + print 'unkonwn lorentz structure',parsed[i] + quit() + parsed = [x for x in parsed if x != ""] if(len(parsed)!=0) : print expr print "Can't parse ",parsed,iloc quit() raise SkipThisVertex() sVal ={} # deal with the simplest case first if len(unContracted) == 0 : - print 'testing in simple case' - temp={} - exec("import sympy\nfrom sympy import Symbol,Matrix\n"+Symbols+"result="+ - ( "%s*%s*%s" %(start[0],expr[0],end[0]))) in temp - tempT={} - exec("import sympy\nfrom sympy import Symbol,Matrix,Transpose\n"+Symbols+"result="+ - ( "%s*%s*Transpose(%s)*%s*%s" %(startT[0],CC,expr[0],CD,endT[0]))) in tempT - if(iloc==0 or (iloc!=sind[ichain] and iloc!=lind[ichain])) : - sVal = {'s' : temp ["result"][0,0],'sT' : tempT["result"][0,0]} - else : - for jj in range(1,5) : - sVal["s%s" % jj] = temp ["result"][jj-1] - sVal["sT%s" % jj] = tempT["result"][jj-1] - print 'before un',sVal - # now deal with the uncontracted cases - contracted=[] - # sort out contracted and uncontracted indices - for j in range(0,len(unContracted)) : - # summed index - if(isinstance(unContracted[j],int)) : - contracted.append(unContracted[j]) - unContracted.remove(unContracted[j]) - # RS index - elif unContracted[j][0]=="R" : - if(unContracted[j][1]=="C") : - unContracted[j] = unContracted[j].replace("C","") - else : - contracted.append(unContracted[j]) - if(int(unContracted[j][1])!=iloc): - unContracted.remove(unContracted[j]) - # uncontracted vector index - elif unContracted[j][0]=="V" : - continue - else : - print 'uknown type of uncontracted index',unContracted[j] - raise SkipThisVertex() - # iterate over the uncontracted indices - unI=[0]*len(unContracted) - defns["I"] = ["I","static Complex I(0.,1.);"] - print 'before un loop',unContracted,contracted - while True : - if(len(contracted)==0 and len(unContracted)==0) : break - coI=[0]*len(contracted) - # loop over the contracted indices - res = [] - for i in range(0,nchain) : - res.append([]) - res.append([]) - while True : - sign = 1 - sTemp = copy.copy(start ) - sTTemp = copy.copy(startT) - eTemp = copy.copy(expr ) - fTemp = copy.copy(end ) - fTTemp = copy.copy(endT ) - # make the necessary replacements for uncontracted indices - for ichain in range(0,nchain) : - for j in range(0,len(unContracted)) : - if(unContracted[j][0]=="R") : - ii = int(unContracted[j][1]) - sTemp[ichain] = sTemp[ichain].replace(unContracted[j]+"A",dirac[unI[j]]) - sTTemp[ichain] = sTTemp[ichain].replace(unContracted[j]+"A",dirac[unI[j]]) - fTemp[ichain] = fTemp[ichain].replace(unContracted[j]+"A",dirac[unI[j]]) - fTTemp[ichain] = fTTemp[ichain].replace(unContracted[j]+"A",dirac[unI[j]]) - sTemp[ichain] = sTemp[ichain].replace("A!",imap[unI[j]]) - sTTemp[ichain] = sTTemp[ichain].replace("A!",imap[unI[j]]) - fTemp[ichain] = fTemp[ichain].replace("A!",imap[unI[j]]) - fTTemp[ichain] = fTTemp[ichain].replace("A!",imap[unI[j]]) - # handle metric tensors - eta=re.search("ETA\(.*,.\)",sTemp[ichain]) - if(eta) : - eta = eta.group(0) - if(eta.find("!")<0) : - temp = eta.split("(")[1].split(",") - replace = temp[0]+temp[1][0] - sTemp[ichain] = sTemp[ichain].replace(eta,replace) - sTTemp[ichain] = sTTemp[ichain].replace(eta,replace) - fTemp[ichain] = fTemp[ichain].replace(eta,replace) - fTTemp[ichain] = fTTemp[ichain].replace(eta,replace) - elif(unContracted[j][0]=="V") : - print unContracted[j][0] - print eTemp[ichain] - loc = eTemp[ichain].find("(%s)"%unContracted[j]) - if(loc>=0) : - vec=eTemp[ichain][loc-2:loc] - Symbols += momCom.substitute({"v":vec}) - print "!!!!!!",vec - eTemp[ichain] = eTemp[ichain].replace("(%s)"%unContracted[j],imap[unI[j]]) - else : - eTemp[ichain] = eTemp[ichain].replace(unContracted[j],dirac[unI[j]]) - print eTemp[ichain] - else : - print 'uknown type of uncontracted index',unContracted[j] - raise SkipThisVertex() - # make the necessary replacements for contracted indices - for ichain in range(0,nchain) : - for j in range(0,len(contracted)) : - if(isinstance(contracted[j],int)) : - eTemp[ichain]=eTemp[ichain].replace("U%s"%contracted[j],dirac[coI[j]]) - if(ichain==0 and coI[j]>0) : sign *= -1 - elif(contracted[j][0]=="R") : - ii = int(contracted[j][1]) - # replace metric - for k in range(0,4) : - test = "ETA(B!,%s)" % (imap[k]) - esign="0" - if(coI[j]==k) : esign="1" - sTemp[ichain] = sTemp[ichain].replace(test,esign) - sTTemp[ichain] = sTTemp[ichain].replace(test,esign) - fTemp[ichain] = fTemp[ichain].replace(test,esign) - fTTemp[ichain] = fTTemp[ichain].replace(test,esign) - # replace dirac matrices - eTemp[ichain] = eTemp[ichain].replace(contracted[j],dirac[coI[j]]) - sTemp[ichain] = sTemp[ichain].replace(contracted[j]+"B",dirac[coI[j]]) - sTTemp[ichain] = sTTemp[ichain].replace(contracted[j]+"B",dirac[coI[j]]) - fTemp[ichain] = fTemp[ichain].replace(contracted[j]+"B",dirac[coI[j]]) - fTTemp[ichain] = fTTemp[ichain].replace(contracted[j]+"B",dirac[coI[j]]) - # replacements for start - sTemp[ichain] = sTemp[ichain].replace("Rsbar%sL" % ii,"Rsbar%s%s" % (ii,imap[coI[j]])) - sTTemp[ichain] = sTTemp[ichain].replace("Rsbar%sL" % ii,"Rsbar%s%s" % (ii,imap[coI[j]])) - sTemp[ichain] = sTemp[ichain].replace("B!",imap[coI[j]]) - sTTemp[ichain] = sTTemp[ichain].replace("B!",imap[coI[j]]) - # replacements for end - fTemp[ichain] = fTemp[ichain].replace("Rs%sL" % ii,"Rs%s%s" % (ii,imap[coI[j]])) - fTTemp[ichain] = fTTemp[ichain].replace("Rs%sL" % ii,"Rs%s%s" % (ii,imap[coI[j]])) - fTemp[ichain] = fTemp[ichain].replace("B!",imap[coI[j]]) - fTTemp[ichain] = fTTemp[ichain].replace("B!",imap[coI[j]]) - if(ichain==0 and coI[j]>0) : sign *= -1 - else : - print 'need to implment',contracted[j] - quit() - # now evaluate the result - rTemp =[[],[]] - for ichain in range(0,nchain) : - temp={} - exec("import sympy\nfrom sympy import Symbol,Matrix\n"+Symbols+"result="+ - ( "(%s)*(%s)*(%s)" %(sTemp[ichain],eTemp[ichain],fTemp[ichain]))) in temp - rTemp[0].append(temp["result"]) - temp={} - exec("import sympy\nfrom sympy import Symbol,Matrix,Transpose\n"+Symbols+"result="+ - ( "(%s)*(%s)*(Transpose(%s))*(%s)*(%s)" %(sTTemp[ichain],CC,eTemp[ichain],CD,fTTemp[ichain]))) in temp - rTemp[1].append(temp["result"]) - # and add it to the output - # 1 spin chain - if(nchain==1) : - for ii in range(0,2) : - if(rTemp[ii][0].shape[0]==1) : - if(rTemp[ii][0].shape[1]==1) : - if(len(res[ii])==0) : - res[ii].append(sign*rTemp [ii][0][0,0]) - else : - res[ii][0] += sign*rTemp [ii][0][0,0] - elif(rTemp[ii][0].shape[1]==4) : - if(len(res[ii])==0) : - for j in range(0,4) : - res[ii].append(sign*rTemp[ii][0][0,j]) - else : - for j in range(0,4) : - res[ii][j] += sign*rTemp[ii][0][0,j] - else : - print "SIZE PROBLEM A",sign,rTemp[ii].shape - quit() - raise SkipThisVertex() - elif(rTemp[ii][0].shape[0]==4 and rTemp[ii][0].shape[1]==1 ) : - if(len(res[ii])==0) : - for j in range(0,4) : - res[ii].append(sign*rTemp[ii][0][j,0]) - else : - for j in range(0,4) : - res[ii][j] += sign*rTemp[ii][0][j,0] - else : - print "SIZE PROBLEM B ",sign,rTemp[ii][0].shape - quit() - raise SkipThisVertex() - # 2 spin chains, should only be for a vertex - else : - for j1 in range(0,2) : - for j2 in range (0,2) : - val = sign*rTemp[j1][0]*rTemp[j2][1] - if(len(res[3])==0) : - res[2*j1+j2].append(val[0,0]) - else : - res[2*j1+j2][0] += val[0,0] - #### END OF THE CONTRACTED LOOP ##### - # increment the indices being summed over - ii = len(coI)-1 - while ii >=0 : - if(coI[ii]<3) : - coI[ii]+=1 - break - else : - coI[ii]=0 - ii-=1 - if(coI.count(0)==len(coI)) : break - ###### END OF THE UNCONTRACTED LOOP ###### - # no uncontracted indices - if(len(unI)==0) : - if(len(res[0])==1) : - if(len(res)==2) : - sVal["s" ] = res[0] - sVal["sT"] = res[1] - else : - sVal["s" ] = res[0][0] - sVal["sT2" ] = res[1][0] - sVal["sT1" ] = res[2][0] - sVal["sT12"] = res[3][0] - elif(len(res)==4) : - for k in range(0,4) : - sVal[ "s%s" % (k+1) ] = res[0][k] - sVal[ "sT%s" % (k+1) ] = res[1][k] - break - # uncontracted indices - else : - istring = "" - for val in unI: - istring +=imap[val] - if(len(istring)!=1) : - print 'index problem',istring - print unContracted - print unI - quit() - sVal[istring] = res[0] - sVal[istring+"T"] = res[1] - ii = len(unI)-1 - while ii >=0 : - if(unI[ii]<3) : - unI[ii]+=1 - break - else : - unI[ii]=0 - ii-=1 - if(unI.count(0)==len(unI)) : break - # handle the vector case - if( "t" in sVal ) : - # deal with pure vectors - if(len(sVal)==8 and "t" in sVal and len(sVal["t"])==1) : - for key in sVal: - sVal[key] = sVal[key][0] - - - # unit = computeUnit(dtemp) - # sVal = { "s" : "LorentzVector<complex<%s> >(%s,%s,%s,%s)" % (unit,sVal["x" ][0],sVal["y" ][0],sVal["z" ][0],sVal["t" ][0]), - # "sT" : "LorentzVector<complex<%s> >(%s,%s,%s,%s)" % (unit,sVal["xT"][0],sVal["yT"][0],sVal["zT"][0],sVal["tT"][0]) } - # print sVal - else : - print 'val problrm A' - quit() - # # print 'testing vector problem',len(sVal),len(sVal["t"]) - # # quit() - # # # if(expr=="") : - # # # expr ={} - # # # exprT={} - # # # defns["I"] = ["I","static Complex I(0.,1.);"] - # # # unit = computeUnit(dtemp) - # # # if(pre=="") : - # # # exprT["s"] = "LorentzVector<complex<%s> >(%s,%s,%s,%s)" % \ - # # # (unit,vals[i][2]["x"],vals[i][2]["y"],vals[i][2]["z"],vals[i][2]["t"]) - # # # else : - # # # expr ["s"] = "%s*LorentzVector<complex<%s> >(%s,%s,%s,%s)" % \ - # # # (pre,unit,vals[i][1]["x"],vals[i][1]["y"],vals[i][1]["z"],vals[i][1]["t"]) - # # # exprT["s"] = "%s*LorentzVector<complex<%s> >(%s,%s,%s,%s)" % \ - # # # (pre,unit,vals[i][2]["x"],vals[i][2]["y"],vals[i][2]["z"],vals[i][2]["t"]) - # # # else : - # # # unit = computeUnit(dtemp) - # # # if(pre=="") : - # # # expr ["s"] += "LorentzVector<complex<%s> >(%s,%s,%s,%s)" % \ - # # # (unit,vals[i][1]["x"],vals[i][1]["y"],vals[i][1]["z"],vals[i][1]["t"]) - # # # exprT["s"] += "LorentzVector<complex<%s> >(%s,%s,%s,%s)" % \ - # # # (unit,vals[i][2]["x"],vals[i][2]["y"],vals[i][2]["z"],vals[i][2]["t"]) - # # # else : - # # # expr ["s"] += "%s*LorentzVector<complex<%s> >(%s,%s,%s,%s)" % \ - # # # (pre,unit,vals[i][1]["x"],vals[i][1]["y"],vals[i][1]["z"],vals[i][1]["t"]) - # # # exprT["s"] += "%s*LorentzVector<complex<%s> >(%s,%s,%s,%s)" % \ - # # # (pre,unit,vals[i][2]["x"],vals[i][2]["y"],vals[i][2]["z"],vals[i][2]["t"]) - # # # print 'CCCCC',len(vals[i]) + sVal = calculateDirac(expr,start,end,startT,endT,sind,lind,Symbols,iloc) + else : + sVal = calculateDirac2(expr,start,end,startT,endT,sind,lind,Symbols,defns, + iloc,unContracted,spins,lorentz) + # set up the output old = output if(nchain==1) : - print "SETTING UP THE OUTPUT ",old - print "B",sVal output = [old,sVal,(lind[0],sind[0])] else : output = [old,sVal,(lind[0],sind[0],lind[1],sind[1])] dimension = list(map(lambda x, y: x + y, dtemp, dimension)) - # remove any dot products involving RS fermions - if("R" in lorentztag ) : - for key in defns.keys() : - if(not isinstance(key,tuple)) : continue - if(key[0]== "E%s" %sind or key[1]=="E%s" %sind or - key[0]== "E%s" %lind[ichain] or key[1]=="E%s" %lind[ichain]) : - del defns[key] return (output,dimension,defns) def convertLorentz(Lstruct,lorentztag,order,vertex,iloc,defns,evalVertex) : + print '!!!!!!! START OF CONVERT LORENTZ !!!!!!!!!!',vertex,iloc + print Lstruct.structure eps = False # split the structure into individual terms structures=Lstruct.structure.split() parsed=[] + # parse structures and convert lorentz contractions to dot products for struct in structures : - print struct - parsed.append(parse_structure(struct)) - # convert lorentz contractions to dot products - print "before loop ", Lstruct.structure - print parsed - for l in range(0,len(parsed)) : - parsed[l] = contract(parsed[l]) - print 'after loop',parsed + ptemp = parse_structure(struct,Lstruct.spins) + parsed.append(contract(ptemp)) # now in a position to generate the code vals=generateVertex(iloc,Lstruct,parsed,lorentztag,vertex,defns) - print iloc,Lstruct,lorentztag - print vals evalVertex.append((vals[0],vals[1])) if(vals[2]) : eps=True - print "END OF CONVERT LORENTZ",Lstruct,iloc,len(evalVertex) - print evalVertex return eps -evaluateTemplate = """\ -{decl} {{ - {momenta} - {waves} -{swap} - {symbols} - {couplings} -{defns} - {result} -}} -""" - def swapOrder(vertex,iloc,momenta,fIndex) : # special for 4 fermion case if(vertex.lorentz[0].spins.count(2)==4) : return swapOrderFFFF(vertex,iloc,momenta,fIndex) names=['','sca','sp','v'] waves=['','sca','' ,'E'] output="" for i in range(1,4) : ns = vertex.lorentz[0].spins.count(i) if((ns<=1 and i!=2) or (ns<=2 and i==2)) : continue if(i!=3 and i!=1) : print 'swap problem',i quit() sloc=[] for j in range(0,len(vertex.lorentz[0].spins)) : if(vertex.lorentz[0].spins[j]==i) : sloc.append(j+1) if iloc in sloc : sloc.remove(iloc) if(len(sloc)==1) : continue for j in range(0,len(sloc)) : output += " long id%s = %sW%s.id();\n" % (sloc[j],names[i],sloc[j]) for j in range(0,len(sloc)) : for k in range(j+1,len(sloc)) : code = vertex.particles[sloc[j]-1].pdg_code output += " if(id%s!=%s) {\n" % (sloc[j],code) output += " swap(id%s,id%s);\n" % (sloc[j],sloc[k]) output += " swap(%s%s,%s%s);\n" % (waves[i],sloc[j],waves[i],sloc[k]) if(momenta[sloc[j]-1][0] or momenta[sloc[k]-1][0]) : momenta[sloc[j]-1][0] = True momenta[sloc[k]-1][0] = True output += " swap(P%s,P%s);\n" % (sloc[j],sloc[k]) output += " };\n" return output def swapOrderFFFF(vertex,iloc,momenta,fIndex) : output="" for j in range(0,len(fIndex)) : if(j%2==0) : output += " long id%s = sW%s.id();\n" % (fIndex[j],fIndex[j]) else : output += " long id%s = sbarW%s.id();\n" % (fIndex[j],fIndex[j]) for j in range(0,2) : code = vertex.particles[fIndex[j]-1].pdg_code output += " if(id%s!=%s) {\n" % (fIndex[j],code) output += " swap(id%s,id%s);\n" % (fIndex[j],fIndex[j+2]) wave="s" if(j==1) : wave = "sbar" output += " swap(%s%s,%s%s);\n" % (wave,fIndex[j],wave,fIndex[j+2]) if(momenta[fIndex[j]-1][0] or momenta[fIndex[j+2]-1][0]) : momenta[fIndex[j]-1][0] = True momenta[fIndex[j+2]-1][0] = True output += " swap(P%s,P%s);\n" % (fIndex[j],fIndex[j+2]) output += " };\n" return output def constructSignature(vertex,order,iloc,decls,momenta,waves,fermionReplace,fIndex) : nf=0 poff="" offType="Complex" for i in order : spin = vertex.lorentz[0].spins[i-1] if(i==iloc) : if(spin==1) : offType="ScalarWaveFunction" elif(spin==2) : if(i%2==1) : offType="SpinorBarWaveFunction" else : offType="SpinorWaveFunction" nf+=1 elif(spin==4) : - if(i==1) : + if(i%2==1) : offType="RSSpinorBarWaveFunction" else : offType="RSSpinorWaveFunction" nf+=1 elif(spin==3) : offType="VectorWaveFunction" elif(spin==5) : offType="TensorWaveFunction" else : print 'unknown spin',spin quit() momenta.append([False,""]) else : if(spin==1) : decls.append("ScalarWaveFunction & scaW%s" % (i)) momenta.append([False,"Lorentz5Momentum P%s =-scaW%s.momentum();" % (i,i)]) waves.append("Complex sca%s = scaW%s.wave();" % (i,i)) elif(spin==2) : if(i%2==1) : decls.append("SpinorWaveFunction & sW%s" % (fIndex[i-1])) momenta.append([False,"Lorentz5Momentum P%s =-sW%s.momentum();" % (fIndex[i-1],fIndex[i-1])]) waves.append("LorentzSpinor<double> s%s = sW%s.wave();" % (fIndex[i-1],fIndex[i-1])) fermionReplace.append("s%s"%(fIndex[i-1])) fermionReplace.append("sbar%s"%(fIndex[i-1])) nf+=1 else : decls.append("SpinorBarWaveFunction & sbarW%s" % (fIndex[i-1])) momenta.append([False,"Lorentz5Momentum P%s =-sbarW%s.momentum();" % (fIndex[i-1],fIndex[i-1])]) waves.append("LorentzSpinorBar<double> sbar%s = sbarW%s.wave();" % (fIndex[i-1],fIndex[i-1])) fermionReplace.append("sbar%s"%(fIndex[i-1])) fermionReplace.append("s%s"%(fIndex[i-1])) nf+=1 elif(spin==3) : decls.append("VectorWaveFunction & vW%s" % (i)) momenta.append([False,"Lorentz5Momentum P%s =-vW%s.momentum();" % (i,i)]) waves.append("LorentzPolarizationVector E%s = vW%s.wave();" % (i,i)) elif(spin==4) : if(i%2==1) : decls.append("RSSpinorWaveFunction & RsW%s" % (i)) momenta.append([False,"Lorentz5Momentum P%s =-RsW%s.momentum();" % (i,i)]) waves.append("LorentzRSSpinor<double> Rs%s = RsW%s.wave();" % (i,i)) fermionReplace.append("Rs%s"%(i)) fermionReplace.append("Rsbar%s"%(i)) nf+=1 else : decls.append("RSSpinorBarWaveFunction & RsbarW%s" % (i)) momenta.append([False,"Lorentz5Momentum P%s =-RsbarW%s.momentum();" % (i,i)]) waves.append("LorentzRSSpinorBar<double> Rsbar%s = RsbarW%s.wave();" % (i,i)) fermionReplace.append("Rs%s"%(i)) fermionReplace.append("Rsbar%s"%(i)) nf+=1 elif(spin==5) : decls.append("TensorWaveFunction & tW%s" % (i)) momenta.append([False,"Lorentz5Momentum P%s =-tW%s.momentum();" % (i,i)]) waves.append("LorentzTensor<double> T%s = tW%s.wave();" % (i,i)) else : print 'unknown spin',spin quit() poff += "-P%s" % (i) + # ensure unbarred spinro first + ibar=-1 + isp=-1 + for i in range(0,len(decls)) : + if(decls[i].find("Bar")>0 and ibar==-1) : + ibar=i + elif(decls[i].find("Spinor")>=0 and isp==-1) : + isp=i + print 'testing order',vertex,isp,ibar + print decls + if(isp!=-1 and ibar!=-1 and isp>ibar) : + print 'swapping order' + decls[ibar],decls[isp] = decls[isp],decls[ibar] + + + poff = ("Lorentz5Momentum P%s = " % iloc ) + poff sig="" if(iloc==0) : sig="%s evaluate(Energy2, const %s)" % (offType,", const ".join(decls)) # special for VVT vertex if(len(vertex.lorentz[0].spins)==3 and vertex.lorentz[0].spins.count(3)==2 and vertex.lorentz[0].spins.count(5)==1) : sig = sig[0:-1] + ", Energy vmass=-GeV)" else : sig="%s evaluate(Energy2, int iopt, tcPDPtr out, const %s, complex<Energy> mass=-GeV, complex<Energy> width=-GeV)" % (offType,", const ".join(decls)) momenta.append([True,poff+";"]) # special for VVT vertex if(len(vertex.lorentz[0].spins)==3 and vertex.lorentz[0].spins.count(3)==2 and vertex.lorentz[0].spins.count(5)==1 and vertex.lorentz[0].spins[iloc-1]==5) : sig=sig.replace("complex<Energy> mass=-GeV","Energy vmass=-GeV, complex<Energy> mass=-GeV") for i in range(0,len(momenta)) : momenta[i][0]=True return offType,nf,poff,sig def combineResult(res,nf,ispin,fermionReplace,vertex) : # extract the vals and dimensions (vals,dim) = res + print vals # construct the output structure # vertex and off-shell scalars if(ispin<=1) : otype={'res':""} # spins elif(ispin==2) : otype={'s1':"",'s2':"",'s3':"",'s4':""} # vectors elif(ispin==3) : if( "t" in vals[0][1] ) : otype={'t':"",'x':"",'y':"",'z':""} else : otype={"res":""} + # RS spinors + elif(ispin==4) : + otype={} + for i1 in imap : + for i in range(1,5) : + otype["%ss%s"% (i1,i)]="" # off-shell tensors elif(ispin==5) : otype={} for i1 in imap : for i2 in imap : otype["%s%s"%(i1,i2)]="" - else : - + else : print vals print 'spin problem',ispin quit() expr=[otype] for i in range(0,nf-1) : expr.append(copy.copy(otype)) # dimension for checking dimCheck=dim[0] for i in range(0,len(vals)) : # simple signs if(vals[i]=="+" or vals[i]=="-") : for ii in range(0,len(expr)) : for(key,val) in expr[ii].iteritems() : expr[ii][key] = expr[ii][key]+vals[i] continue # check the dimensions if(dimCheck[0]!=dim[i][0] or dimCheck[1]!=dim[i][1] or dimCheck[2]!=dim[i][2]) : print vertex.lorentz for i in range(0,len(vals)) : print dim[i],vals[i] print "DIMENSION PROBLEM",i,dimCheck,dim,vertex quit() # simplest case if(isinstance(vals[i], basestring)) : for ii in range(0,len(expr)) : for(key,val) in expr[ii].iteritems() : expr[ii][key] = expr[ii][key]+vals[i] continue # more complex structures pre = vals[i][0] if(pre=="(1.0)") : pre="" if(not isinstance(vals[i][1],dict)) : print 'must be a dict here' raise SkipThisVertex() + print vals[i] # tensors if("tt" in vals[i][1]) : for i1 in imap : for i2 in imap : key="%s%s"%(i1,i2) if(pre=="") : expr[0][key] += "(%s)" % vals[i][1][key] else : expr[0][key] += "%s*(%s)" % (pre,vals[i][1][key]) if(len(expr)==2) : if(pre=="") : expr[1][key] +="(%s)" % vals[i][1][key+"T"] else : expr[1][key] +="%s*(%s)" % (pre,vals[i][1][key+"T"]) # standard fermion vertex case elif(len(vals[i][1])==2 and "s" in vals[i][1] and "sT" in vals[i][1]) : - print expr if(pre=="") : expr[0]["res"] += "(%s)" % vals[i][1]["s"] expr[1]["res"] += "(%s)" % vals[i][1]["sT"] else : expr[0]["res"] += "%s*(%s)" % (pre,vals[i][1]["s"]) expr[1]["res"] += "%s*(%s)" % (pre,vals[i][1]["sT"]) # spinor case elif(len(vals[i][1])==8 and "s1" in vals[i][1]) : for jj in range(1,5) : if(pre=="") : expr[0]["s%s" % jj] += "(%s)" % vals[i][1]["s%s" % jj] expr[1]["s%s" % jj] += "(%s)" % vals[i][1]["sT%s" % jj] else : expr[0]["s%s" % jj] += "%s*(%s)" % (pre,vals[i][1]["s%s" % jj]) expr[1]["s%s" % jj] += "%s*(%s)" % (pre,vals[i][1]["sT%s" % jj]) # vector - elif(len(vals[i][1])%4==0 and "t" in vals[i][1]) : + elif(len(vals[i][1])%4==0 and "t" in vals[i][1] and len(vals[i][1]["t"])==1 ) : for i1 in imap : if(pre=="") : - expr[0][i1] += "(%s)" % vals[i][1][i1] + expr[0][i1] += "(%s)" % vals[i][1][i1][0] else : - expr[0][i1] += "%s*(%s)" % (pre,vals[i][1][i1]) + expr[0][i1] += "%s*(%s)" % (pre,vals[i][1][i1][0]) if(len(expr)==2) : if(pre=="") : - expr[1][i1] +="(%s)" % vals[i][1][i1+"T"] + expr[1][i1] +="(%s)" % vals[i][1][i1+"T"][0] else : - expr[1][i1] +="%s*(%s)" % (pre,vals[i][1][i1+"T"]) + expr[1][i1] +="%s*(%s)" % (pre,vals[i][1][i1+"T"][0]) # 4 fermion vertex case elif(len(vals[i][1])==4 and "sT12" in vals[i][1]) : if(pre=="") : expr[0]["res"] += "(%s)" % vals[i][1]["s"] expr[1]["res"] += "(%s)" % vals[i][1]["sT2"] expr[2]["res"] += "(%s)" % vals[i][1]["sT1"] expr[3]["res"] += "(%s)" % vals[i][1]["sT12"] else : expr[0]["res"] += "%s*(%s)" % (pre,vals[i][1]["s"]) expr[1]["res"] += "%s*(%s)" % (pre,vals[i][1]["sT2"]) expr[2]["res"] += "(%s)" % vals[i][1]["sT1"] expr[3]["res"] += "(%s)" % vals[i][1]["sT12"] + # RS spinor + elif(len(vals[i][1])%4==0 and "t" in vals[i][1] and len(vals[i][1]["t"])==4 ) : + for i1 in imap : + for k in range(1,5) : + key = "%ss%s" % (i1,k) + if(pre=="") : + expr[0][key] += "(%s)" % vals[i][1][i1][k-1] + expr[1][key] += "(%s)" % vals[i][1][i1+"T"][k-1] + else : + expr[0][key] += "%s*(%s)" % (pre,vals[i][1][i1][k-1]) + expr[1][key] += "%s*(%s)" % (pre,vals[i][1][i1+"T"][k-1]) else : print vals[i] print 'problem with type' quit() - # # unknown - # else : - # print 'unrecongnised case',vals[i] - # quit() - # # elif(len(vals[i][1])==4 and "t" in vals[i][1]) : - # # # two cases, either already a 'simple' vector - # # # or its an RS spinor - # # # RS first - # # if(len(vals[i][1]["t"])==4) : - # # if(expr=="") : - # # expr ={} - # # exprT={} - # # for jj in range(0,4) : - # # for k in range(1,5) : - # # if(pre=="") : - # # expr ["%ss%s" % (imap[jj],k)] = "(%s)" % vals[i][1][imap[jj]][k-1] - # # exprT["%ss%s" % (imap[jj],k)] = "(%s)" % vals[i][2][imap[jj]][k-1] - # # else : - # # expr ["%ss%s" % (imap[jj],k)] = "%s*(%s)" % (pre,vals[i][1][imap[jj]][k-1]) - # # exprT["%ss%s" % (imap[jj],k)] = "%s*(%s)" % (pre,vals[i][2][imap[jj]][k-1]) - # # else : - # # for jj in range(0,4) : - # # for k in range(1,5) : - # # if(pre=="") : - # # expr ["%ss%s" % (imap[jj],k)] += "(%s)" % vals[i][1][imap[jj]][k-1] - # # exprT["%ss%s" % (imap[jj],k)] += "(%s)" % vals[i][2][imap[jj]][k-1] - # # else : - # # expr ["%ss%s" % (imap[jj],k)] += "%s*(%s)" % (pre,vals[i][1][imap[jj]][k-1]) - # # exprT["%ss%s" % (imap[jj],k)] += "%s*(%s)" % (pre,vals[i][2][imap[jj]][k-1]) - # # # simple vector - # # else : - # # print 'vector case' - # # print vals[i] - # # print expr - # # quit() - - # # else : - # # print "AAAAAAA" - # # print vertex,len(vals[i][1]) - # # quit() - - # tidy up fermion defns for rep in fermionReplace : for i in range(1,5) : kmax=1 if(rep[0]=="R") : kmax=4 for k in range(0,kmax) : if(rep[0]=="R") : oldVal = "%s%ss%s" % (rep,imap[k],i) newVal = "%s.%ss%s()" % (rep,imap[k],i) else : oldVal = "%ss%s" % (rep,i) newVal = "%s.s%s()" % (rep,i) for ii in range (0,len(expr)) : for (key,val) in expr[ii].iteritems() : expr[ii][key] = val.replace(oldVal,newVal) # no of particles in the vertex vDim = len(vertex.lorentz[0].spins) # tidy up momentum components for i in range(1,vDim+1) : for k in range(0,4) : oldVal = "P%s%s*" % (i,imap[k]) newVal = "P%s.%s()*" % (i,imap[k]) for ii in range(0,len(expr)) : for (key,val) in expr[ii].iteritems() : expr[ii][key] = val.replace(oldVal,newVal) unit = computeUnit2(dimCheck,vDim) if(unit!="") : for ii in range(0,len(expr)) : for (key,val) in expr[ii].iteritems() : expr[ii][key] = "(%s)*(%s)" % (val,unit) return expr def combineComponents(result,offType,RS) : # simplest case, just a value if(len(result[0])==1 and "res" in result[0]) : for i in range(0,len(result)) : result[i] = result[i]["res"] return # calculate the substitutions if(not isinstance(result[0],basestring)) : subs=[] for ii in range(0,len(result)) : subs.append({}) for (key,val) in result[ii].iteritems() : subs[ii]["out%s" % key]= val # spinors if("s1" in result[0]) : stype = "LorentzSpinor" sbtype = "LorentzSpinorBar" if(offType.find("Bar")>0) : (stype,sbtype)=(sbtype,stype) if(not RS) : sbtype=stype subs[0]["type"] = stype - result[0] = Template("${type}<double>(${outs1},\n${outs2},\n${outs3},\n${outs4})").substitute(subs[0]) + result[0] = SpinorTemplate.substitute(subs[0]) subs[1]["type"] = sbtype - result[1] = Template("${type}<double>(${outs1},\n${outs2},\n${outs3},\n${outs4})").substitute(subs[1]) + result[1] = SpinorTemplate.substitute(subs[1]) # tensors elif("tt" in result[0]) : for ii in range(0,len(result)) : result[ii] = Template("LorentzTensor<double>(${outxx},\n${outxy},\n${outxz},\n${outxt},\n${outyx},\n${outyy},\n${outyz},\n${outyt},\n${outzx},\n${outzy},\n${outzz},\n${outzt},\n${outtx},\n${outty},\n${outtz},\n${outtt})").substitute(subs[ii]) result[ii]=result[ii].replace("(+","(") # vectors elif("t" in result[0]) : for ii in range(0,len(result)) : result[ii] = Template("LorentzVector<Complex>(${outx},\n${outy},\n${outz},\n${outt})").substitute(subs[ii]) result[ii]=result[ii].replace("(+","(") + # RS spinors + elif("ts1" in result[0]) : + stype = "LorentzRSSpinor" + sbtype = "LorentzRSSpinorBar" + if(offType.find("Bar")>0) : (stype,sbtype)=(sbtype,stype) + subs[0]["type"] = stype + result[0] = RSSpinorTemplate.substitute(subs[0]) + subs[1]["type"] = sbtype + result[1] = RSSpinorTemplate.substitute(subs[1]) else : - print subs[0] print result print 'type not implemented' quit() - - # # final defns for more complicated types - - # if("ts1" in result) : - # stype = "LorentzRSSpinor" - # sbtype = "LorentzRSSpinorBar" - # if(offType.find("Bar")>0) : (stype,sbtype)=(sbtype,stype) - # subs["type"] = stype - # result = Template("${type}<double>(${outxs1},\n${outxs2},\n${outxs3},\n${outxs4},\n${outys1},\n${outys2},\n${outys3},\n${outys4},\n${outzs1},\n${outzs2},\n${outzs3},\n${outzs4},\n${outts1},\n${outts2},\n${outts3},\n${outts4})").substitute(subs) - # subsT["type"] = sbtype - # resultT = Template("${type}<double>(${outxs1},\n${outxs2},\n${outxs3},\n${outxs4},\n${outys1},\n${outys2},\n${outys3},\n${outys4},\n${outzs1},\n${outzs2},\n${outzs3},\n${outzs4},\n${outts1},\n${outts2},\n${outts3},\n${outts4})").substitute(subsT) - # else : - # print result - # print 'type problem' - # quit() - - def generateEvaluateFunction(model,vertex,iloc,values,defns,vertexEval,cf,order) : RS = "R" in vertex.lorentz[0].name FM = "F" in vertex.lorentz[0].name # extract the start and end of the spin chains if( RS or FM ) : fIndex = vertexEval[0][0][0][2] else : fIndex=0 # first construct the signature of the function decls=[] momenta=[] waves=[] fermionReplace=[] offType,nf,poff,sig = constructSignature(vertex,order,iloc,decls,momenta,waves,fermionReplace,fIndex) # combine the different terms in the result symbols=set() localCouplings=[] result=[] ispin = 0 if(iloc!=0) : ispin = vertex.lorentz[0].spins[iloc-1] # put the lorentz structures and couplings together for j in range(0,len(vertexEval)) : # get the lorentz structure piece - print 'calling combine',j,vertex.lorentz[j] + print 'calling combine',iloc,vertex,j,vertex.lorentz[j] expr = combineResult(vertexEval[j],nf,ispin,fermionReplace,vertex) # get the coupling for this bit val, sym = py2cpp(values[j]) localCouplings.append("Complex local_C%s = %s;\n" % (j,val)) symbols |=sym # put them together vtype="Complex" if("res" in expr[0] and offType=="VectorWaveFunction") : vtype="LorentzPolarizationVector" if(len(result)==0) : for ii in range(0,len(expr)) : result.append({}) for (key,val) in expr[ii].iteritems() : result[ii][key] = " %s((local_C%s)*(%s)) " % (vtype,j,val) else : for ii in range(0,len(expr)) : for (key,val) in expr[ii].iteritems(): result[ii][key] += " + %s((local_C%s)*(%s)) " % (vtype,j,val) # for more complex types merge the spin/lorentz components combineComponents(result,offType,RS) # multiple by scalar wavefunctions scalars="" for i in range (0,len(vertex.lorentz[0].spins)) : if(vertex.lorentz[0].spins[i]==1 and i+1!=iloc) : scalars += "sca%s*" % (i+1) if(scalars!="") : for ii in range(0,len(result)) : result[ii] = "(%s)*(%s)" % (result[ii],scalars[0:-1]) # vertex, just return the answer if(iloc==0) : if(FM and not RS) : if(nf!=4) : - result = vTemplateT.format(iloc=fIndex[1],id=vertex.particles[fIndex[1]-1].pdg_code, - cf=py2cpp(cf)[0],res=result[0],resT=result[1]) + result[0] = vTemplateT.format(iloc=fIndex[1],id=vertex.particles[fIndex[1]-1].pdg_code, + cf=py2cpp(cf)[0],res=result[0],resT=result[1]) else : - result = vTemplate4.format(iloc1=fIndex[1],iloc2=fIndex[3], - id1=vertex.particles[fIndex[1]-1].pdg_code, - id2=vertex.particles[fIndex[3]-1].pdg_code, - cf=py2cpp(cf)[0],res1=result[0],res2=result[1],res3=result[2],res4=result[3]) + result[0] = vTemplate4.format(iloc1=fIndex[1],iloc2=fIndex[3], + id1=vertex.particles[fIndex[1]-1].pdg_code, + id2=vertex.particles[fIndex[3]-1].pdg_code, + cf=py2cpp(cf)[0],res1=result[0],res2=result[1],res3=result[2],res4=result[3]) else : - result = "return (%s)*(%s);\n" % (result[0],py2cpp(cf)[0]) + result[0] = "return (%s)*(%s);\n" % (result[0],py2cpp(cf)[0]) if(RS) : - result[1] = "return (%s)*(%s);\n" % (result[1],py2cpp(cf[0])[0]) + result[1] = "return (%s)*(%s);\n" % (result[1],py2cpp(cf)[0]) # off-shell particle else : # off-shell scalar if(vertex.lorentz[0].spins[iloc-1] == 1 ) : if(RS) : - resultT = scaTemplate.format(iloc=iloc,cf=py2cpp(cf[0])[0],res=result[1]) + result[1] = scaTemplate.format(iloc=iloc,cf=py2cpp(cf[0])[0],res=result[1]) if(FM and not RS) : - result = scaTTemplate.format(iloc=iloc,res=result[0],resT=result[1],isp=fIndex[1], - id=vertex.particles[fIndex[1]-1].pdg_code,cf=py2cpp(cf[0])[0]) + result[0] = scaTTemplate.format(iloc=iloc,res=result[0],resT=result[1],isp=fIndex[1], + id=vertex.particles[fIndex[1]-1].pdg_code,cf=py2cpp(cf[0])[0]) else : - result = scaTemplate.format(iloc=iloc,cf=py2cpp(cf[0])[0],res=result[0]) + result[0] = scaTemplate.format(iloc=iloc,cf=py2cpp(cf[0])[0],res=result[0]) # off-shell fermion elif(vertex.lorentz[0].spins[iloc-1] == 2 ) : if(RS) : if(offType.find("Bar")>0) : offTypeT=offType.replace("Bar","") else : offTypeT=offType.replace("Spinor","SpinorBar") - resultT = sTemplate.format(iloc=iloc,cf=py2cpp(cf[0])[0],offTypeA=offTypeT.replace("WaveFunction",""), - res=result[1].replace( "M%s" % iloc, "mass" ),offTypeB=offTypeT) + result[1] = sTemplate.format(iloc=iloc,cf=py2cpp(cf[0])[0],offTypeA=offTypeT.replace("WaveFunction",""), + res=result[1].replace( "M%s" % iloc, "mass" ),offTypeB=offTypeT) if(FM and not RS) : - result = sTTemplate.format(iloc=iloc,cf=py2cpp(cf[0])[0],offTypeA=offType.replace("WaveFunction",""), - res=result[0].replace( "M%s" % iloc, "mass" ),resT=result[1].replace( "M%s" % iloc, "mass" ), - offTypeB=offType,id=vertex.particles[iloc-1].pdg_code) + result = [sTTemplate.format(iloc=iloc,cf=py2cpp(cf[0])[0],offTypeA=offType.replace("WaveFunction",""), + res=result[0].replace( "M%s" % iloc, "mass" ),resT=result[1].replace( "M%s" % iloc, "mass" ), + offTypeB=offType,id=vertex.particles[iloc-1].pdg_code)] else : - result = sTemplate.format(iloc=iloc,cf=py2cpp(cf[0])[0],offTypeA=offType.replace("WaveFunction",""), - res=result[0].replace( "M%s" % iloc, "mass" ),offTypeB=offType) + result[0] = sTemplate.format(iloc=iloc,cf=py2cpp(cf[0])[0],offTypeA=offType.replace("WaveFunction",""), + res=result[0].replace( "M%s" % iloc, "mass" ),offTypeB=offType) # off-shell vector elif(vertex.lorentz[0].spins[iloc-1] == 3 ) : if(FM and not RS) : - result = vecTTemplate.format(iloc=iloc,res=result[0],resT=result[1],isp=fIndex[1], - id=vertex.particles[fIndex[1]-1].pdg_code, - cf=py2cpp(cf[0])[0]) + result = [vecTTemplate.format(iloc=iloc,res=result[0],resT=result[1],isp=fIndex[1], + id=vertex.particles[fIndex[1]-1].pdg_code, + cf=py2cpp(cf[0])[0])] + elif(RS) : + print "need vecor rs bit" + quit() else : - result = vecTemplate.format(iloc=iloc,res=result[0],cf=py2cpp(cf)[0]) + result = [vecTemplate.format(iloc=iloc,res=result[0],cf=py2cpp(cf)[0])] elif(vertex.lorentz[0].spins[iloc-1] == 4 ) : if(offType.find("Bar")>0) : offTypeT=offType.replace("Bar","") else : offTypeT=offType.replace("Spinor","SpinorBar") - resultT = RSTemplate.format(iloc=iloc,cf=py2cpp(cf[0])[0],offTypeA=offTypeT.replace("WaveFunction",""), - res=result[1].replace( "M%s" % iloc, "mass" ),offTypeB=offTypeT) - result = RSTemplate.format(iloc=iloc,cf=py2cpp(cf[0])[0],offTypeA=offType.replace("WaveFunction",""), - res=result[0].replace( "M%s" % iloc, "mass" ),offTypeB=offType) + result[1] = RSTemplate.format(iloc=iloc,cf=py2cpp(cf[0])[0],offTypeA=offTypeT.replace("WaveFunction",""), + res=result[1].replace( "M%s" % iloc, "mass" ),offTypeB=offTypeT) + result[0] = RSTemplate.format(iloc=iloc,cf=py2cpp(cf[0])[0],offTypeA=offType.replace("WaveFunction",""), + res=result[0].replace( "M%s" % iloc, "mass" ),offTypeB=offType) # tensors elif(vertex.lorentz[0].spins[iloc-1]) : if(RS) : print "RS spinors and tensors not handled" quit() if(FM) : - result = tenTTemplate.format(iloc=iloc,res=result[0],resT=result[1],isp=fIndex[1], - id=vertex.particles[fIndex[1]-1].pdg_code,cf=py2cpp(cf[0])[0]) + result = [tenTTemplate.format(iloc=iloc,res=result[0],resT=result[1],isp=fIndex[1], + id=vertex.particles[fIndex[1]-1].pdg_code,cf=py2cpp(cf[0])[0])] else : - result = tenTemplate.format(iloc=iloc,cf=py2cpp(cf)[0],res=result[0]) + result = [tenTemplate.format(iloc=iloc,cf=py2cpp(cf)[0],res=result[0])] else : print 'unknown spin for off-shell particle',vertex.lorentz[0].spins[iloc-1] quit() # check if momenta defns needed to clean up compile of code for (key,val) in defns.iteritems() : if( isinstance(key, basestring)) : if(key.find("vvP")==0) : momenta[int(key[3])-1][0] = True else : + print val for vals in key : + print vals if(vals.type=="P") : momenta[vals.value-1][0] = True # cat the definitions defString="" for (key,value) in defns.iteritems() : defString+=" %s\n" %value[1] sorder=swapOrder(vertex,iloc,momenta,fIndex) momentastring="" for i in range(0,len(momenta)) : if(momenta[i][0] and momenta[i][1]!="") : momentastring+=momenta[i][1]+"\n " # special for 4-point VVVV if(vertex.lorentz[0].spins.count(3)==4 and iloc==0) : sig=sig.replace("Energy2","Energy2,int") header="virtual %s" % sig sig=sig.replace("=-GeV","") symboldefs = [ def_from_model(model,s) for s in symbols ] function = evaluateTemplate.format(decl=sig,momenta=momentastring,defns=defString, waves="\n ".join(waves),symbols='\n '.join(symboldefs), couplings="\n ".join(localCouplings), - result=result,swap=sorder) + result=result[0],swap=sorder) # special for transpose in the RS case if(FM and RS) : htemp = header.split(",") irs=-1 isp=-1 for i in range(0,len(htemp)) : if(htemp[i].find("RS")>0) : if(htemp[i].find("Bar")>0) : htemp[i]=htemp[i].replace("Bar","").replace("RsbarW","RsW") else : htemp[i]=htemp[i].replace("Spinor","SpinorBar").replace("RsW","RsbarW") if(i>0) : irs=i elif(htemp[i].find("Spinor")>0) : if(htemp[i].find("Bar")>0) : htemp[i]=htemp[i].replace("Bar","").replace("sbarW","sW") else : htemp[i]=htemp[i].replace("Spinor","SpinorBar").replace("sW","sbarW") if(i>0) : isp=i if(irs>0 and isp >0) : htemp[irs],htemp[isp] = htemp[isp],htemp[irs] hnew = ','.join(htemp) header += ";\n" + hnew hnew = hnew.replace("virtual ","").replace("=-GeV","") for i in range(0,len(waves)) : if(waves[i].find("Spinor")<0) : continue if(waves[i].find("Bar")>0) : waves[i] = waves[i].replace("Bar","").replace("bar","") else : waves[i] = waves[i].replace("Spinor","SpinorBar").replace(" s"," sbar").replace("Rs","Rsbar") momentastring="" for i in range(0,len(momenta)) : if(momenta[i][0] and momenta[i][1]!="") : if(momenta[i][1].find("barW")>0) : momentastring+=momenta[i][1].replace("barW","W")+"\n " elif(momenta[i][1].find("sW")>0) : momentastring+=momenta[i][1].replace("sW","sbarW")+"\n " else : momentastring+=momenta[i][1]+"\n " fnew = evaluateTemplate.format(decl=hnew,momenta=momentastring,defns=defString, waves="\n ".join(waves),symbols='\n '.join(symboldefs), couplings="\n ".join(localCouplings), result=result[1],swap=sorder) function +="\n" + fnew return (header,function) evaluateMultiple = """\ {decl} {{ {code} }} """ def multipleEvaluate(vertex,spin,defns) : if(spin==1) : name="scaW" elif(spin==3) : name="vW" else : print 'testing evaluate multiple problem',spin quit() if(len(defns)==0) : return ("","") header = defns[0] ccdefn = header.replace("=-GeV","").replace("virtual ","").replace("Energy2","Energy2 q2") code="" spins=vertex.lorentz[0].spins iloc=1 waves=[] for i in range(0,len(spins)) : if(spins[i]==spin) : waves.append("%s%s" %(name,i+1)) for i in range(0,len(spins)) : if(spins[i]==spin) : if(iloc==1) : el="" else : el="else " call = defns[iloc].replace("virtual","").replace("ScalarWaveFunction","").replace("SpinorWaveFunction","") \ .replace("SpinorBarWaveFunction","").replace("VectorWaveFunction","").replace("TensorWaveFunction","") \ .replace("Energy2","q2").replace("int","").replace("complex<Energy>","").replace("Energy","").replace("=-GeV","") \ .replace("const &","").replace("tcPDPtr","").replace(" "," ") if(iloc!=1) : call = call.replace(waves[0],waves[iloc-1]) pdgid = vertex.particles[i].pdg_code code += " %sif(out->id()==%s) return %s;\n" % (el,pdgid,call) iloc+=1 code+=" else assert(false);\n" return (header,evaluateMultiple.format(decl=ccdefn,code=code)) diff --git a/Models/Feynrules/python/ufo2peg/vertices.py b/Models/Feynrules/python/ufo2peg/vertices.py --- a/Models/Feynrules/python/ufo2peg/vertices.py +++ b/Models/Feynrules/python/ufo2peg/vertices.py @@ -1,828 +1,830 @@ import sys,pprint from .helpers import CheckUnique,getTemplate,writeFile,coupling_orders,def_from_model from .converter import py2cpp from .collapse_vertices import collapse_vertices from .check_lorentz import tensorCouplings,VVVordering,lorentzScalar,\ processTensorCouplings,scalarCouplings,processScalarCouplings,scalarVectorCouplings,\ processScalarVectorCouplings,vectorCouplings,processVectorCouplings,fermionCouplings,processFermionCouplings,\ RSCouplings,convertLorentz,generateEvaluateFunction,multipleEvaluate from .helpers import SkipThisVertex,extractAntiSymmetricIndices,isGoldstone # prefactors for vertices lfactors = { 'FFV' : '-complex(0,1)', # ok 'VVV' : 'complex(0,1)', # changed to fix ttbar 'VVVS' : 'complex(0,1)', # should be as VVV 'VVVV' : 'complex(0,1)', 'VVS' : '-complex(0,1)', 'VSS' : '-complex(0,1)', # changed to minus to fix dL ->x1 W- d 'SSS' : '-complex(0,1)', # ok 'VVSS' : '-complex(0,1)', # ok 'VVT' : 'complex(0,2)', 'VVVT' : '-complex(0,2)', 'SSSS' : '-complex(0,1)', # ok 'FFS' : '-complex(0,1)', # ok 'SST' : 'complex(0,2)', 'FFT' : '-complex(0,8)', 'FFVT' : '-complex(0,4)', 'RFS' : 'complex(0,1)', 'RFV' : 'complex(0,1)', } genericVertices=['FFFF','FFVV','FFSS','FFVS','VVVV','VVVT','FFVT','VVSS'] skipped5Point=False # template for the header for a vertex VERTEXHEADER = """\ #include "ThePEG/Helicity/Vertex/{spindirectory}/{lorentztag}Vertex.h" """ GENERALVERTEXHEADER = """\ #include "ThePEG/Helicity/Vertex/Abstract{lorentztag}Vertex.h" """ # template for the implmentation for a vertex VERTEXCLASS = getTemplate('Vertex_class') GENERALVERTEXCLASS = getTemplate('GeneralVertex_class') # template for the .cc file for vertices VERTEX = getTemplate('Vertex.cc') vertexline = """\ create Herwig::FRModel{classname} /Herwig/{modelname}/{classname} insert {modelname}:ExtraVertices 0 /Herwig/{modelname}/{classname} """ def get_lorentztag(spin): """Produce a ThePEG spin tag for the given numeric FR spins.""" spins = { 1 : 'S', 2 : 'F', 3 : 'V', 4 : 'R', 5 : 'T', -1 : 'U' } result=[] for i in range(0,len(spin)) : result.append((spins[spin[i]],i+1)) def spinsort(a,b): """Helper function for ThePEG's FVST spin tag ordering.""" (a1,a2) = a (b1,b2) = b if a1 == b1: return 0 for letter in 'URFVST': if a1 == letter: return -1 if b1 == letter: return 1 result = sorted(result, cmp=spinsort) order=[] output="" for i in range(0,len(result)) : (a,b) = result[i] order.append(b) output+=a return (output,order) def unique_lorentztag(vertex): """Check and return the Lorentz tag of the vertex.""" unique = CheckUnique() for l in vertex.lorentz: (lorentztag,order) = get_lorentztag(l.spins) unique( lorentztag ) lname = l.name[:len(lorentztag)] if sorted(lorentztag) != sorted(lname): raise Exception("Lorentztags: %s is not %s in %s" % (lorentztag,lname,vertex)) return (lorentztag,order) def colors(vertex) : try: unique = CheckUnique() for pl in vertex.particles_list: struct = [ p.color for p in pl ] unique(struct) except: struct = [ p.color for p in vertex.particles ] pos = colorpositions(struct) L = len(struct) return (L,pos) def coloursort(a,b) : if a == b: return 0 i1=int(a[4]) i2=int(b[4]) if(i1==i2) : return 0 elif(i1<i2) : return -1 else : return 1 def colorfactor(vertex,L,pos,lorentztag): def match(patterns,color=vertex.color): result = [ p == t for p,t in zip(patterns,color) ] return all(result) label = None l = lambda c: len(pos[c]) if l(1) == L: label = ('1',) if match(label): return ("SINGLET",('1.',)) elif l(3) == l(-3) == 1 and l(1) == L-2: nums = [pos[3][0], pos[-3][0]] label = ('Identity({0},{1})'.format(*sorted(nums)),) if match(label): return ("DELTA",('1.',)) elif l(6) == l(-6) == 1 and l(1) == L-2: nums = [pos[6][0], pos[-6][0]] label = ('Identity({0},{1})'.format(*sorted(nums)),) if match(label): return ("DELTA",('1.',)) elif l(6) == l(-6) == 2 and L==4: sys.stderr.write( 'Warning: Unknown colour structure 6 6 6~ 6~ ( {ps} ) in {name}.\n' .format(name=vertex.name, ps=' '.join(map(str,vertex.particles))) ) raise SkipThisVertex() elif l(8) == l(3) == l(-3) == 1 and l(1) == L-3: label = ('T({g},{q},{qb})'.format(g=pos[8][0],q=pos[3][0],qb=pos[-3][0]),) if match(label): return ("SU3TFUND",('1.',)) elif l(8) == l(6) == l(-6) == 1 and l(1) == L-3: label = ('T6({g},{s},{sb})'.format(g=pos[8][0],s=pos[6][0],sb=pos[-6][0]),) if match(label): return ("SU3T6",('1.',)) elif l(6) == 1 and l(-3) == 2 and L==3: label = ('K6({s},{qb1},{qb2})'.format(s=pos[6][0],qb1=pos[-3][0],qb2=pos[-3][1]),) if match(label): return ("K6",('1.',)) elif l(-6) == 1 and l(3) == 2 and L==3: label = ('K6Bar({sb},{q1},{q2})'.format(sb=pos[-6][0],q1=pos[3][0],q2=pos[3][1]),) if match(label): return ("K6",('1.',)) elif l(3) == L == 3: colors=[] for color in vertex.color : order,sign = extractAntiSymmetricIndices(color,"Epsilon(") colors.append("Epsilon(%s,%s,%s)" % (order[0],order[1],order[2])) label = ('Epsilon(1,2,3)',) if match(label,colors): return ("EPS",('1.',)) # TODO check factor! elif l(-3) == L == 3: colors=[] for color in vertex.color : order,sign = extractAntiSymmetricIndices(color,"EpsilonBar(") colors.append("Epsilon(%s,%s,%s)" % (order[0],order[1],order[2])) label = ('EpsilonBar(1,2,3)',) if match(label): return ("EPS",('1.',)) # TODO check factor! elif l(8) == L == 3: colors=[] for color in vertex.color : order,sign = extractAntiSymmetricIndices(color,"f(") colors.append("f(%s,%s,%s)" % (order[0],order[1],order[2])) # if lorentz is FFV get extra minus sign if lorentztag in ['FFV'] : sign *=-1 label = ('f(1,2,3)',) if match(label,colors): return ("SU3F",('-complex(0,1.)*(%s)'%sign,)) elif l(8) == L == 4: colors=[] for color in vertex.color : f = color.split("*") (o1,s1) = extractAntiSymmetricIndices(f[0],"f(") (o2,s2) = extractAntiSymmetricIndices(f[1],"f(") if(o2[0]<o1[0]) : o1,o2=o2,o1 colors.append("f(%s)*f(%s)" % (",".join(o1),",".join(o2))) colors=sorted(colors,cmp=coloursort) label = ('f(1,2,-1)*f(3,4,-1)', 'f(1,3,-1)*f(2,4,-1)', 'f(1,4,-1)*f(2,3,-1)') nmatch=0 for c1 in label: for c2 in colors : if(c1==c2) : nmatch+=1 if(nmatch==2 and lorentztag=="VVSS") : return ("SU3TTFUND",('1.','1.')) elif(nmatch==3 and lorentztag=="VVVV") : return ("SU3FF",('1.','1.','1.')) elif l(8) == 2 and l(3) == l(-3) == 1 and L==4: subs = { 'g1' : pos[8][0], 'g2' : pos[8][1], 'qq' : pos[3][0], 'qb' : pos[-3][0] } if(vertex.lorentz[0].spins.count(1)==2) : label = ('T({g1},-1,{qb})*T({g2},{qq},-1)'.format(**subs), 'T({g1},{qq},-1)*T({g2},-1,{qb})'.format(**subs)) if match(label): return ("SU3TTFUNDS",('1.','1.')) elif(vertex.lorentz[0].spins.count(2)==2) : label = ('f({g1},{g2},-1)*T(-1,{qq},{qb})'.format(**subs),) if match(label): return ("SU3TTFUNDD",('-complex(0.,1.)',)) label = ('f(-1,{g1},{g2})*T(-1,{qq},{qb})'.format(**subs),) if match(label): return ("SU3TTFUNDD",('-complex(0.,1.)',)) elif l(8) == 2 and l(6) == l(-6) == 1 and L==4: subs = { 'g1' : pos[8][0], 'g2' : pos[8][1], 'qq' : pos[6][0], 'qb' : pos[-6][0] } label = ('T6({g1},-1,{qb})*T6({g2},{qq},-1)'.format(**subs), 'T6({g1},{qq},-1)*T6({g2},-1,{qb})'.format(**subs)) if match(label): return ("SU3TT6",('1.','1.')) elif l(8) == 2 and l(8)+l(1)==L : subs = { 'g1' : pos[8][0], 'g2' : pos[8][1] } label = ('Identity({g1},{g2})'.format(**subs),) if match(label) : return ("DELTA",('1.',)) elif l(8) == 3 and l(1)==1 and L==4 : colors=[] for color in vertex.color : order,sign = extractAntiSymmetricIndices(color,"f(") colors.append("f(%s,%s,%s)" % (order[0],order[1],order[2])) label = ('f(1,2,3)',) if match(label,colors): return ("SU3F",('-complex(0.,1.)*(%s)'%sign,)) elif l(3)==2 and l(-3) == 2 and L==4 and lorentztag=="FFFF" : labels=["Identity(1,2)*Identity(3,4)", "Identity(1,4)*Identity(2,3)", "T(-1,2,1)*T(-1,4,3)", "T(-1,2,3)*T(-1,4,1)"] cstruct=["SU3I12I34","SU3I14I23","SU3T21T43","SU3T23T41"] oname=[] ovalue=[] for color in vertex.color : for i in range(0,len(labels)) : if labels[i]==color : break if(i<len(labels)) : oname.append(cstruct[i]) ovalue.append("1.") else : sys.stderr.write( "Warning: Unknown colour structure {color} ( {ps} ) in {name} for FFFF vertex.\n" .format(color = ' '.join(vertex.color), name = vertex.name, ps = ' '.join(map(str,vertex.particles))) ) raise SkipThisVertex() return(oname,ovalue) sys.stderr.write( "Warning: Unknown colour structure {color} ( {ps} ) in {name}.\n" .format(color = ' '.join(vertex.color), name = vertex.name, ps = ' '.join(map(str,vertex.particles))) ) raise SkipThisVertex() def colorpositions(struct): positions = { 1 : [], 3 : [], -3 : [], 6 : [], -6 : [], 8 : [], } for i,s in enumerate(struct,1): positions[s].append(i) return positions def spindirectory(lt): """Return the spin directory name for a given Lorentz tag.""" if 'T' in lt: spin_directory = 'Tensor' elif 'S' in lt: spin_directory = 'Scalar' elif 'V' in lt: spin_directory = 'Vector' else: raise Exception("Unknown Lorentz tag {lt}.".format(lt=lt)) return spin_directory def write_vertex_file(subs): 'Write the .cc file for some vertices' newname = '%s_Vertices_%03d.cc' % (subs['ModelName'],subs['vertexnumber']) subs['newname'] = newname writeFile( newname, VERTEX.substitute(subs) ) def checkGhostGoldstoneVertex(lorentztag,vertex) : 'check if vertex has ghosts or goldstones' # remove vertices involving ghost fields if 'U' in lorentztag: return True # remove vertices involving goldstones for p in vertex.particles: if(isGoldstone(p)): return True return False def calculatePrefactor(lf,cf) : prefactor = '(%s) * (%s)' % (lf,cf) return prefactor def couplingValue(coupling) : if type(coupling) is not list: value = coupling.value else: value = "(" for coup in coupling : value += '+(%s)' % coup.value value +=")" return value def epsilonSign(vertex,couplingptrs,append) : EPSSIGN = """\ double sign = {epssign}; if((p1->id()=={id1} && p2->id()=={id3} && p3->id()=={id2}) || (p1->id()=={id2} && p2->id()=={id1} && p3->id()=={id3}) || (p1->id()=={id3} && p2->id()=={id2} && p3->id()=={id1})) {{ sign *= -1.; }} norm(norm()*sign); """ if(not "p1" in couplingptrs[0]) : couplingptrs[0] += ' p1' if(not "p2" in couplingptrs[1]) : couplingptrs[1] += ' p2' if(not "p3" in couplingptrs[2]) : couplingptrs[2] += ' p3' if("Bar" not in vertex.color[0]) : order,sign = extractAntiSymmetricIndices(vertex.color[0],"Epsilon(") else : order,sign = extractAntiSymmetricIndices(vertex.color[0],"EpsilonBar(") subs = {"id1" : vertex.particles[int(order[0])-1].pdg_code, "id2" : vertex.particles[int(order[1])-1].pdg_code, "id3" : vertex.particles[int(order[2])-1].pdg_code, "epssign" : sign } append+=EPSSIGN.format(**subs) return couplingptrs,append class VertexConverter: 'Convert the vertices in a FR model to extract the information ThePEG needs.' def __init__(self,model,parmsubs,defns) : 'Initialize the parameters' self.verbose=False self.vertex_skipped=False self.ignore_skipped=False self.model=model self.all_vertices= [] self.vertex_names = {} self.modelname="" self.no_generic_loop_vertices = False self.parmsubs = parmsubs self.couplingDefns = defns def readArgs(self,args) : 'Extract the relevant command line arguments' self.ignore_skipped = args.ignore_skipped self.verbose = args.verbose self.modelname = args.name self.no_generic_loop_vertices = args.no_generic_loop_vertices self.include_generic = args.include_generic def should_print(self) : 'Check if we should output the results' return not self.vertex_skipped or self.ignore_skipped def convert(self) : 'Convert the vertices' if(self.verbose) : print 'verbose mode on: printing all vertices' print '-'*60 labels = ('vertex', 'particles', 'Lorentz', 'C_L', 'C_R', 'norm') pprint.pprint(labels) # extract the vertices self.all_vertices = self.model.all_vertices # convert the vertices vertexclasses, vertexheaders = [], set() for vertexnumber,vertex in enumerate(self.all_vertices,1) : # process the vertex (skip,vertexClass,vertexHeader) = \ self.processVertex(vertexnumber,vertex) # check it can be handled if(skip) : continue # add to the list vertexclasses.append(vertexClass) vertexheaders.add(vertexHeader) WRAP = 25 if vertexnumber % WRAP == 0: write_vertex_file({'vertexnumber' : vertexnumber//WRAP, 'vertexclasses' : '\n'.join(vertexclasses), 'vertexheaders' : ''.join(vertexheaders), 'ModelName' : self.modelname}) vertexclasses = [] vertexheaders = set() # exit if there's vertices we can't handle if not self.should_print(): sys.stderr.write( """ Error: The conversion was unsuccessful, some vertices could not be generated. If you think the missing vertices are not important and want to go ahead anyway, use --ignore-skipped. Herwig may not give correct results, though. """ ) sys.exit(1) # if still stuff to output it do it if vertexclasses: write_vertex_file({'vertexnumber' : vertexnumber//WRAP + 1, 'vertexclasses' : '\n'.join(vertexclasses), 'vertexheaders' : ''.join(vertexheaders), 'ModelName' : self.modelname}) print '='*60 def setCouplingPtrs(self,lorentztag,qcd,append,prepend) : couplingptrs = [',tcPDPtr']*len(lorentztag) if lorentztag == 'VSS': couplingptrs[1] += ' p2' elif lorentztag == 'FFV': couplingptrs[0] += ' p1' elif (lorentztag == 'VVV' or lorentztag == 'VVVS' or lorentztag == "SSS" or lorentztag == "VVVT" ) \ and (append or prepend ) : couplingptrs[0] += ' p1' couplingptrs[1] += ' p2' couplingptrs[2] += ' p3' elif (lorentztag == 'VVVV' and qcd < 2) or\ (lorentztag == "SSSS" and prepend ): couplingptrs[0] += ' p1' couplingptrs[1] += ' p2' couplingptrs[2] += ' p3' couplingptrs[3] += ' p4' return couplingptrs def processVertex(self,vertexnumber,vertex) : global skipped5Point # get the Lorentz tag for the vertex lorentztag,order = unique_lorentztag(vertex) print "START OF VERTEX",vertex,lorentztag,order,vertex.particles # check if we should skip the vertex vertex.herwig_skip_vertex = checkGhostGoldstoneVertex(lorentztag,vertex) # check the order of the vertex and skip 5 points if(len(lorentztag)>=5) : vertex.herwig_skip_vertex = True if(not skipped5Point) : skipped5Point = True print "Skipping 5 point vertices which aren\'t used in Herwig7" - + + if(vertexnumber<=1100) : + vertex.herwig_skip_vertex = True + if(vertex.herwig_skip_vertex) : return (True,"","") # check if we support this at all if( lorentztag not in lfactors and lorentztag not in genericVertices) : msg = 'Warning: Lorentz structure {tag} ( {ps} ) in {name} ' \ 'is not supported.\n'.format(tag=lorentztag, name=vertex.name, ps=' '.join(map(str,vertex.particles))) sys.stderr.write(msg) vertex.herwig_skip_vertex = True self.vertex_skipped=True return (True,"","") # get the factor for the vertex generic = False try: lf = lfactors[lorentztag] - if "SST" in lorentztag or "VVT" in lorentztag : - raise KeyError + if "T" in lorentztag : raise KeyError except KeyError: if(not self.include_generic) : msg = 'Warning: Lorentz structure {tag} ( {ps} ) in {name} ' \ 'is not supported.\n'.format(tag=lorentztag, name=vertex.name, ps=' '.join(map(str,vertex.particles))) sys.stderr.write(msg) vertex.herwig_skip_vertex = True self.vertex_skipped=True return (True,"","") else : lf=1. generic=True # get the ids of the particles at the vertex plistarray = [ ','.join([ str(vertex.particles[o-1].pdg_code) for o in order ]) ] # parse the colour structure for the vertex try: L,pos = colors(vertex) cs,cf = colorfactor(vertex,L,pos,lorentztag) except SkipThisVertex: msg = 'Warning: Color structure for vertex ( {ps} ) in {name} ' \ 'is not supported.\n'.format(tag=lorentztag, name=vertex.name, ps=' '.join(map(str,vertex.particles))) sys.stderr.write(msg) vertex.herwig_skip_vertex = True self.vertex_skipped=True return (True,"","") ### classname classname = 'V_%s' % vertex.name if(not generic) : try : return self.extractGeneric(vertex,order,lorentztag,classname,plistarray,pos,lf,cf,cs) except SkipThisVertex: if(not self.include_generic) : msg = 'Warning: Lorentz structure {tag} ( {ps} ) in {name} ' \ 'is not supported, may have a non-perturbative form.\n'.format(tag=lorentztag, name=vertex.name, ps=' '.join(map(str,vertex.particles))) sys.stderr.write(msg) vertex.herwig_skip_vertex = True self.vertex_skipped=True return (True,"","") else : try : return self.extractGeneral(vertex,order,lorentztag,classname,plistarray,pos,cf,cs) except SkipThisVertex: msg = 'Warning: Lorentz structure {tag} ( {ps} ) in {name} ' \ 'is not supported, may have a non-perturbative form.\n'.format(tag=lorentztag, name=vertex.name, ps=' '.join(map(str,vertex.particles))) sys.stderr.write(msg) vertex.herwig_skip_vertex = True self.vertex_skipped=True return (True,"","") else : try : return self.extractGeneral(vertex,order,lorentztag,classname,plistarray,pos,cf,cs) except SkipThisVertex: msg = 'Warning: Lorentz structure {tag} ( {ps} ) in {name} ' \ 'is not supported, may have a non-perturbative form.\n'.format(tag=lorentztag, name=vertex.name, ps=' '.join(map(str,vertex.particles))) sys.stderr.write(msg) vertex.herwig_skip_vertex = True self.vertex_skipped=True return (True,"","") def extractGeneric(self,vertex,order,lorentztag,classname,plistarray,pos,lf,cf,cs) : classes="" headers="" # identify the maximum colour flow and orders of the couplings maxColour=0 couplingOrders=[] self.vertex_names[vertex.name] = [classname] for (color_idx,lorentz_idx),coupling in vertex.couplings.iteritems(): maxColour=max(maxColour,color_idx) orders = coupling_orders(vertex, coupling, self.couplingDefns) if(orders not in couplingOrders) : couplingOrders.append(orders) # loop the order of the couplings iorder = 0 for corder in couplingOrders : iorder +=1 cname=classname if(iorder!=1) : cname= "%s_%s" % (classname,iorder) self.vertex_names[vertex.name].append(cname) header = "" prepend="" append="" all_couplings=[] for ix in range(0,maxColour+1) : all_couplings.append([]) # loop over the colour structures for colour in range(0,maxColour+1) : for (color_idx,lorentz_idx),coupling in vertex.couplings.iteritems() : # check colour structure and coupling order if(color_idx!=colour) : continue if(coupling_orders(vertex, coupling, self.couplingDefns)!=corder) : continue # get the prefactor for the lorentz structure L = vertex.lorentz[lorentz_idx] prefactors = calculatePrefactor(lf,cf[color_idx]) # calculate the value of the coupling value = couplingValue(coupling) # handling of the different types of couplings if lorentztag in ['FFS','FFV']: all_couplings[color_idx] = fermionCouplings(value,prefactors,L,all_couplings[color_idx],order) elif 'T' in lorentztag : append, all_couplings[color_idx] = tensorCouplings(vertex,value,prefactors,L,lorentztag,pos, all_couplings[color_idx],order) elif 'R' in lorentztag : all_couplings[color_idx] = RSCouplings(value,prefactors,L,all_couplings[color_idx],order) elif lorentztag == 'VVS' or lorentztag == "VVSS" or lorentztag == "VSS" : all_couplings[color_idx] = scalarVectorCouplings(value,prefactors,L,lorentztag, all_couplings[color_idx],order) elif lorentztag == "SSS" or lorentztag == "SSSS" : prepend, header, all_couplings[color_idx] = scalarCouplings(vertex,value,prefactors,L,lorentztag, all_couplings[color_idx],prepend,header) elif "VVV" in lorentztag : all_couplings[color_idx],append = vectorCouplings(vertex,value,prefactors,L,lorentztag,pos, all_couplings[color_idx],append,corder["QCD"],order) else: raise SkipThisVertex() # set the coupling ptrs in the setCoupling call couplingptrs = self.setCouplingPtrs(lorentztag,corder["QCD"],append != '',prepend != '') # final processing of the couplings symbols = set() if(lorentztag in ['FFS','FFV']) : (normcontent,leftcontent,rightcontent,append) = processFermionCouplings(lorentztag,vertex, self.model,self.parmsubs, all_couplings,order) elif('T' in lorentztag) : (leftcontent,rightcontent,normcontent) = processTensorCouplings(lorentztag,vertex,self.model, self.parmsubs,all_couplings,order) elif(lorentztag=="SSS" or lorentztag=="SSSS") : normcontent = processScalarCouplings(self.model,self.parmsubs,all_couplings) elif(lorentztag=="VVS" or lorentztag =="VVSS" or lorentztag=="VSS") : normcontent,append,lorentztag,header,sym = processScalarVectorCouplings(lorentztag,vertex, self.model,self.parmsubs, all_couplings,header,order) symbols |=sym elif("VVV" in lorentztag) : normcontent,append,header =\ processVectorCouplings(lorentztag,vertex,self.model,self.parmsubs,all_couplings,append,header) else : SkipThisVertex() ### do we need left/right? if 'FF' in lorentztag and lorentztag != "FFT": #leftcalc = aStoStrongCoup(py2cpp(leftcontent)[0], paramstoreplace_, paramstoreplace_expressions_) #rightcalc = aStoStrongCoup(py2cpp(rightcontent)[0], paramstoreplace_, paramstoreplace_expressions_) leftcalc, sym = py2cpp(leftcontent) symbols |= sym rightcalc, sym = py2cpp(rightcontent) symbols |= sym left = 'left(' + leftcalc + ');' right = 'right(' + rightcalc + ');' else: left = '' right = '' leftcalc = '' rightcalc = '' #normcalc = aStoStrongCoup(py2cpp(normcontent)[0], paramstoreplace_, paramstoreplace_expressions_) normcalc, sym = py2cpp(normcontent) symbols |= sym # UFO is GeV by default if lorentztag in ['VVS','SSS']: normcalc = 'Complex((%s) * GeV / UnitRemoval::E)' % normcalc elif lorentztag in ['GeneralVVS']: normcalc = 'Complex(-(%s) * UnitRemoval::E / GeV )' % normcalc elif lorentztag in ['FFT','VVT', 'SST', 'FFVT', 'VVVT' , 'VVVS' ]: normcalc = 'Complex((%s) / GeV * UnitRemoval::E)' % normcalc norm = 'norm(' + normcalc + ');' # finally special handling for eps tensors if(len(vertex.color)==1 and vertex.color[0].find("Epsilon")>=0) : couplingptrs, append = epsilonSign(vertex,couplingptrs,append) # define unkown symbols from the model symboldefs = [ def_from_model(self.model,s) for s in symbols ] couplingOrder="" for coupName,coupVal in corder.iteritems() : couplingOrder+=" orderInCoupling(CouplingType::%s,%s);\n" %(coupName,coupVal) ### assemble dictionary and fill template subs = { 'lorentztag' : lorentztag, # ok 'classname' : cname, # ok 'symbolrefs' : '\n '.join(symboldefs), 'left' : left, # doesn't always exist in base 'right' : right, # doesn't always exist in base 'norm' : norm, # needs norm, too 'addToPlist' : '\n'.join([ 'addToList(%s);'%s for s in plistarray]), 'parameters' : '', 'couplingOrders' : couplingOrder, 'colourStructure' : cs, 'couplingptrs' : ''.join(couplingptrs), 'spindirectory' : spindirectory(lorentztag), 'ModelName' : self.modelname, 'prepend' : prepend, 'append' : append, 'header' : header } # ok # print info if required if self.verbose: print '-'*60 pprint.pprint(( classname, plistarray, leftcalc, rightcalc, normcalc )) headers+=VERTEXHEADER.format(**subs) classes+=VERTEXCLASS.substitute(subs) return (False,classes,headers) def extractGeneral(self,vertex,order,lorentztag,classname,plistarray,pos,cf,cs) : eps=False classes="" headers="" # check the colour flows, three cases supported either 1 flow or 3 in gggg # or multiple wierd ones in FFFF cidx=-1 gluon4point = (len(pos[8])==4 and vertex.lorentz[0].spins.count(3)==4) FFFF = (len(pos[3])==2 and len(pos[-3])==2 and vertex.lorentz[0].spins.count(2)==4) couplingOrders=[] colours={} for (color_idx,lorentz_idx),coupling in vertex.couplings.iteritems() : orders = coupling_orders(vertex, coupling, self.couplingDefns) if(orders not in couplingOrders) : couplingOrders.append(orders) if(gluon4point) : color = vertex.color[color_idx] f = color.split("*") (o1,s1) = extractAntiSymmetricIndices(f[0],"f(") (o2,s2) = extractAntiSymmetricIndices(f[1],"f(") if(o2[0]<o1[0]) : o1,o2=o2,o1 color = "f(%s)*f(%s)" % (",".join(o1),",".join(o2)) label = 'f(1,3,-1)*f(2,4,-1)' if(label==color) : cidx=color_idx colours[cidx] = (cs,cf[cidx]) elif (FFFF) : colours[color_idx] = (cs[color_idx],cf[color_idx]) else : cidx=color_idx if(color_idx!=0) : vertex.herwig_skip_vertex = True self.vertex_skipped=True msg = 'Warning: General spin structure code currently only '\ 'supports 1 colour structure for {tag} ( {ps} ) in {name}\n'.format(tag=lorentztag, name=vertex.name, ps=' '.join(map(str,vertex.particles))) sys.stderr.write(msg) return (True,"","") if(isinstance(cs,basestring)) : colours[cidx] = (cs,cf[cidx]) else : vertex.herwig_skip_vertex = True self.vertex_skipped=True msg = 'Warning: General spin structure code currently only '\ 'supports 1 colour structure for {tag} ( {ps} ) in {name}\n'.format(tag=lorentztag, name=vertex.name, ps=' '.join(map(str,vertex.particles))) sys.stderr.write(msg) return (True,"","") if(len(colours)==0) : msg = 'Warning: General spin structure code currently only '\ 'supports 1 colour structure for {tag} ( {ps} ) in {name}\n'.format(tag=lorentztag, name=vertex.name, ps=' '.join(map(str,vertex.particles))) sys.stderr.write(msg) vertex.herwig_skip_vertex = True self.vertex_skipped=True return (True,"","") # loop over the different orders in the couplings # and colour structures iorder=0 self.vertex_names[vertex.name]=[classname] for corder in couplingOrders : for (cidx,(cstruct,cfactor)) in colours.iteritems() : iorder +=1 cname=classname if(iorder!=1) : cname= "%s_%s" % (classname,iorder) self.vertex_names[vertex.name].append(cname) defns=[] vertexEval=[] values=[] imax = len(vertex.particles)+1 if lorentztag in genericVertices : imax=1 for (color_idx,lorentz_idx),coupling in vertex.couplings.iteritems() : # only the colour structre and coupling order we want if(color_idx != cidx) : continue if(coupling_orders(vertex, coupling, self.couplingDefns)!=corder) : continue # calculate the value of the coupling values.append(couplingValue(coupling)) # now to convert the spin structures for i in range(0,imax) : if(len(defns)<i+1) : defns.append({}) vertexEval.append([]) eps |= convertLorentz(vertex.lorentz[lorentz_idx],lorentztag,order,vertex, i,defns[i],vertexEval[i]) # we can now generate the evaluate member functions header="" impls="" spins=vertex.lorentz[0].spins mult={} for i in range(1,6) : if( spins.count(i)>1 and i!=2) : mult[i] = [] for i in range(0,imax) : (evalHeader,evalCC) = generateEvaluateFunction(self.model,vertex,i,values,defns[i],vertexEval[i],cfactor,order) if(i!=0 and spins[i-1] in mult) : if(len(mult[spins[i-1]])==0) : mult[spins[i-1]].append(evalHeader) evalHeader=evalHeader.replace("evaluate(","evaluate%s(" % i) evalCC =evalCC .replace("evaluate(","evaluate%s(" % i) mult[spins[i-1]].append(evalHeader) header+=" "+evalHeader+";\n" impls+=evalCC # combine the multiple defn if needed for (key,val) in mult.iteritems() : (evalHeader,evalCC) = multipleEvaluate(vertex,key,val) if(evalHeader!="") : header += " "+evalHeader+";\n" if(evalCC!="") : impls += evalCC impls=impls.replace("evaluate", "FRModel%s::evaluate" % cname) couplingOrder="" for coupName,coupVal in corder.iteritems() : couplingOrder+=" orderInCoupling(CouplingType::%s,%s);\n" %(coupName,coupVal) ### assemble dictionary and fill template subs = { 'lorentztag' : lorentztag, 'classname' : cname, 'addToPlist' : '\n'.join([ 'addToList(%s);'%s for s in plistarray]), 'ModelName' : self.modelname, 'couplingOrders' : couplingOrder, 'colourStructure' : cstruct, 'evaldefs' : header, 'evalimpls' : impls} newHeader = GENERALVERTEXHEADER.format(**subs) if(eps) : newHeader +="#include \"ThePEG/Helicity/epsilon.h\"\n" headers+=newHeader classes+=GENERALVERTEXCLASS.substitute(subs) return (False,classes,headers) def get_vertices(self,libname): vlist = ['library %s\n' % libname] for v in self.all_vertices: if v.herwig_skip_vertex: continue for name in self.vertex_names[v.name] : vlist.append( vertexline.format(modelname=self.modelname, classname=name) ) if( not self.no_generic_loop_vertices) : vlist.append('insert {modelname}:ExtraVertices 0 /Herwig/{modelname}/V_GenericHPP\n'.format(modelname=self.modelname) ) vlist.append('insert {modelname}:ExtraVertices 0 /Herwig/{modelname}/V_GenericHGG\n'.format(modelname=self.modelname) ) return ''.join(vlist)