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,1617 +1,1617 @@
 import itertools,cmath,re,sys
 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
 
 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)
 
 # ordering for EW VVV vertices
 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) :
     # 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[0].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[0].mass.value)
             # fermions divide by 4*m
             elif(ix==6 and lorentztag=="FFT" and
                  float(vertex.particles[0].mass.value) != 0. ) :
                 for i in range(0,len(test)) :
                     if(test[i]) :
                         test[i] = '-(%s)/%s/4' % (test[i],vertex.particles[0].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[0].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[0].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") :
                     prepend = kinematicsline.format(id1=vertex.particles[0].pdg_code,
                                                      id2=vertex.particles[1].pdg_code,
                                                      id3=vertex.particles[2].pdg_code,
                                                      kine=output)
                 else :
                     prepend = kinematicsline2.format(id1=vertex.particles[0].pdg_code,
                                                       id2=vertex.particles[1].pdg_code,
                                                       id3=vertex.particles[2].pdg_code,
                                                       id4=vertex.particles[2].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]);"
             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][0]
+                            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][0]
+                            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][1]
+                            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) :
     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[0].pdg_code)
     return normcontent,leftcontent,rightcontent,append
 
 def RSCouplings(value,prefactors,L,all_couplings,order) :
     raise SkipThisVertex()
 
 class LorentzStructure:
     """A simple example class to store a Lorentz structures"""
     name=""
     value=0.
     lorentz=[]
     spin=[]
     def __repr__(self):
         output = self.name
         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 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) :
     output=[]
     # 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)
         return output
     # simple numeric pre/post factors
     elif((structure[0]=="-" or structure[0]=="+") and
        structure[-1]==")" and structure[1]=="(") :
         output.append(LorentzStructure())
         output[0].name="int"
         output[0].value=structure[0]+"1."
         output[0].value=float(output[0].value)
         structure=structure[2:-1]
     elif(structure[0]=="(") :
         temp=structure.rsplit(")",1)
         structure=temp[0][1:]
         output.append(LorentzStructure())
         output[0].name="int"
         output[0].value="1."+temp[1]
         output[0].value=float(eval(output[0].value))
     # 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) :
             output.append(LorentzStructure())
             output[-1].spin=ind
             output[-1].name=struct.split("(")[0]
             output[-1].value=1.
             if(len(struct.replace("%s(%s,%s)" % (output[-1].name,ind[0],ind[1]),""))!=0) :
                 print "problem A"
                 quit()
         # objects with 2 lorentz indices
         elif(struct.find("Metric")==0 or struct.find("P(")==0) :
             output.append(LorentzStructure())
             output[-1].lorentz=ind
             output[-1].name=struct.split("(")[0]
             output[-1].value=1.
             if(len(struct.replace("%s(%s,%s)" % (output[-1].name,ind[0],ind[1]),""))!=0) :
                 print "problem B"
                 quit()
         # 1 lorentz and 1 spin index
         elif(struct.find("Gamma")==0) :
             output.append(LorentzStructure())
             output[-1].lorentz=[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 C",struct
                 quit()
         # objects with 4 lorentz indices
         elif(struct.find("Epsilon")==0) :
             output.append(LorentzStructure())
             output[-1].lorentz=ind
             output[-1].name=struct.split("(")[0]
             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()
         # scalars
         else :
             try :
                 output.append(LorentzStructure())
                 output[-1].value=float(struct)
                 output[0].name="int"
             except :
                 print struct
                 quit()
     # now do the sorting
     if(len(output)==1) : return output
     return sorted(output,cmp=LorentzCompare)
 
 def contractLorentz(L,parsed,lorentztag,order) :
     for l in range(0,len(parsed)) :
         for j in range(0,len(parsed[l])) :
             # replace indices with polarization vectors
             ll = len(parsed[l][j].lorentz)
             if(parsed[l][j].name=="P") :
                 ll=1
                 found=False
                 for k in range(0,len(parsed[l])) :
                     if(j==k or parsed[l][k]=="" ) : continue
                     imax = len(parsed[l][k].lorentz)
                     if(parsed[l][k].name=="P") : imax=1
                     for i in range(0,imax) :
                         if(parsed[l][k].lorentz[i]==parsed[l][j].lorentz[0]) :
                             parsed[l][k].lorentz[i] = "P%s" % parsed[l][j].lorentz[1]
                             if(parsed[l][k].name=="P") :
                                 parsed[l][k].lorentz[1] = "P%s" % parsed[l][k].lorentz[1]
                                 parsed[l][k].name="Metric"
                             found=True
                             break
                 if(found) :
                     parsed[l][j]=''
                     ll=0
             for i in range(0,ll) :
                 if(parsed[l][j]!="" and parsed[l][j].lorentz[i]>=0
                    and isinstance(parsed[l][j].lorentz[i],(int,long)) and
                    L.spins[parsed[l][j].lorentz[i]-1]==3 ) :
                     parsed[l][j].lorentz[i]=  "E%s" % parsed[l][j].lorentz[i]
                     if(parsed[l][j].name=="P") :
                         parsed[l][j].lorentz[1] = "P%s" % parsed[l][j].lorentz[1]
                         parsed[l][j].name="Metric"
         parsed[l] = [x for x in parsed[l] 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" % (-dimension)
     if(output=="") : return expr
     elif(expr=="") : return output
     else           : return "%s*%s" %(output,expr)
 
 def generateVertex(iloc,L,parsed,lorentztag,order,defns) :
     eps=False
     # 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")
     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}\")\n")
     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]])"]
     # order the indices of a dot product
     def indSort(a,b) :
         if(a[0]==b[0]) :
             i1=int(a[1])
             i2=int(b[1])
             if(i1>i2) :
                 return 1
             elif(i1<i2) :
                 return -1
             else :
                 return 0
         else :
             if(a[0]=="E") :
                 return 1
             else :
                 return -1
     # 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)) :
         # replace signs
         if(len(parsed[i])==1 and parsed[i][0].name=="sign") :
             if(parsed[i][0].value>0) :
                 output[i]="+"
             else :
                 output[i]="-"
             parsed[i][0]=''
             continue
         # replace integers
         for j in range(0,len(parsed[i])) :
             if(parsed[i][j]!="" and parsed[i][j].name=="int") :
                 output[i] *= parsed[i][j].value
                 parsed[i][j]=""
                 continue
         output[i] = "(%s)" % output[i]
         for j in range(0,len(parsed[i])) :
             if(parsed[i][j]!="" and parsed[i][j].name=="Metric") :
                 (ind1,ind2) = sorted((parsed[i][j].lorentz[0],parsed[i][j].lorentz[1]),cmp=indSort)
                 # this product already dealt with ?
                 if((ind1,ind2) in defns) :
                     output[i] += "*(%s)" % defns[(ind1,ind2)][0]
                     parsed[i][j]=""
                     if(ind1[0]=="P") : dimension[i][2] +=1
                     if(ind2[0]=="P") : dimension[i][2] +=1
                     continue
                 # handle the product
                 name = "dot%s" % (len(defns)+1)
                 parsed[i][j]=""
                 if(ind1[0]=="P") :
                     # dot product of two momenta
                     if(ind2[0]=="P") :
                         dimension[i][2] +=2
                         defns[(ind1,ind2)] = [name,"Energy2 %s = %s*%s;" % (name,ind1,ind2)]
                         output[i] += "*(%s)" % name
                     elif(ind2[0]=="E") :
                         dimension[i][2] +=1
                         if(int(ind2[1])==iloc) :
                             output[i] += "*(%s)" % ind1
                         else :
                             defns[(ind1,ind2)] = [name,"complex<Energy> %s = %s*%s;" % (name,ind1,ind2)]
                             output[i] += "*(%s)" % name
                 elif(ind1[0]=="E") :
                     if(ind2[0]!="E") :
                         print "problem"
                         quit()
                     if(int(ind1[1])==iloc) :
                         output[i] += "*(%s)" % ind2
                     elif(int(ind2[1])==iloc) :
                         output[i] += "*(%s)" % ind1
                     else :
                         defns[(ind1,ind2)] = [name,"complex<double> %s = %s*%s;" % (name,ind1,ind2)]
                         output[i] += "*(%s)" % name
             elif(parsed[i][j]!="" and parsed[i][j].name=="Epsilon") :
                 if(not eps) : eps = True
                 offLoc = -1
                 indices=[]
                 dTemp=0
                 for ix in range(0,len(parsed[i][j].lorentz)) :
                     if(parsed[i][j].lorentz[ix][0]=="E" and int(parsed[i][j].lorentz[ix][1])==iloc ) :
                         offLoc = ix
                         break
                 for ix in range(0,len(parsed[i][j].lorentz)) :
                     if(parsed[i][j].lorentz[ix][0]=="P") : dTemp+=1
                     if((offLoc<0 and ix != 0) or
                        (offLoc>=0 and offLoc!=ix) ) :
                         indices.append(parsed[i][j].lorentz[ix])
                 dimension[i][2] += dTemp
                 if(offLoc<0) :
                     iTemp = (parsed[i][j].lorentz[0],parsed[i][j].lorentz[1],
                              parsed[i][j].lorentz[2],parsed[i][j].lorentz[3])
                     if(iTemp in defns) :
                         output[i] += "*(%s)" % defns[iTemp][0]
                         parsed[i][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[i][j].lorentz[0],
                                                                                         indices[0],indices[1],indices[2]) ]
                         output[i] += "*(%s)" % name
                 else :
                     iTemp = (indices[0],indices[1],indices[2])
                     sign = ""
                     if(offLoc%2!=0) : sign="-"
                     if(iTemp in defns) :
                         output[i] += "*(%s%s)" % (sign,defns[iTemp][0])
                         parsed[i][j]=""
                     else :
                         name = "vec%s" % (len(defns)+1)
                         output[i] += "*(%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]) ]
     # remove any (now) empty elements
     for i in range (0,len(parsed)) :
         parsed[i] = [x for x in parsed[i] if x != ""]
     # now for gamma matrix strings
     if(lorentztag[0]=="F") :
         result=""
         for i in range(0,len(parsed)): 
             if(len(parsed[i])==0) :
                 continue
             if(len(parsed[i])==1 and parsed[i][0]=="") :
                 result+=parsed[i][0]
                 continue
             # first and last lorentz indices
             sind=parsed[i][0].spin[0]
             lind=0
             # first piece of the expression we need to evaluate
             dtemp=[0,0,0]
             if(sind==iloc) :
                 expr = 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
                 dtemp[0]+=0.5
             else :
                 Symbols=Template("sbar${s}s1=Symbol(\"sbar${s}s1\")\nsbar${s}s2=Symbol(\"sbar${s}s2\")\nsbar${s}s3=Symbol(\"sbar${s}s3\")\nsbar${s}s4=Symbol(\"sbar${s}s4\")\n").substitute({'s' :parsed[i][0].spin[0]})
                 expr=Template("Matrix([[sbar${s}s1,sbar${s}s2,sbar${s}s3,sbar${s}s4]])").substitute({'s' : sind })
                 dtemp[0]+=0.5
             # parse the remaining structures
             for j in range(0,len(parsed[i])) :
                 if(parsed[i][j].name=="Identity") :
                     expr += "*%s" % I4
                     lind = parsed[i][j].spin[1]
                     parsed[i][j]=""
                 elif(parsed[i][j].name=="Gamma5") :
                     expr += "*%s" % G5
                     lind = parsed[i][j].spin[1]
                     parsed[i][j]=""
                 elif(parsed[i][j].name=="ProjM") :
                     expr += "*%s" % PM
                     lind = parsed[i][j].spin[1]
                     parsed[i][j]=""
                 elif(parsed[i][j].name=="ProjP") :
                     expr += "*%s" % PP
                     lind = parsed[i][j].spin[1]
                     parsed[i][j]=""
                 elif(parsed[i][j].name=="Gamma") :
                     lind = parsed[i][j].spin[1]
                     # lorentz matrix contracted with the propagator
                     if(parsed[i][j].lorentz[0] == ("E%s" % iloc ) ) :
                         expr += "*DUMMY"
                     else :
                         expr += "*"+vslash.substitute({ "v" : parsed[i][j].lorentz[0]})
                         Symbols += vslashS.substitute({ "v" : parsed[i][j].lorentz[0]})
                         if(parsed[i][j].lorentz[0][0]=="P") :
                             dtemp[2] += 1
                             variable="Energy"
                         else :
                             variable="double"
                         defns["vv%s" % parsed[i][j].lorentz[0] ] = \
                                                                    ["vv%s" % parsed[i][j].lorentz[0],
                                                                     vslashD.substitute({ "var" : variable,
                                                                                          "v" : parsed[i][j].lorentz[0]})]
                     parsed[i][j]=""
                 else :
                     print 'FFFFFF'
                     print parsed[i][j]
                     quit()
             # last piece of spin chain
             if(lind==iloc) :
                 expr += "*"+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
                 dtemp[0] += 0.5
             else :
                 expr+=Template("*Matrix([[s${s}s1],[s${s}s2],[s${s}s3],[s${s}s4]])").substitute({'s' : lind})
                 Symbols+=Template("s${s}s1=Symbol(\"s${s}s1\")\ns${s}s2=Symbol(\"s${s}s2\")\ns${s}s3=Symbol(\"s${s}s3\")\ns${s}s4=Symbol(\"s${s}s4\")\n").substitute({'s' : lind})
                 dtemp[0] += 0.5
             parsed[i] = [x for x in parsed[i] if x != ""]
             if(len(parsed[i])!=0) :
                 print "ERROR"
                 quit()
             # off-shell vector
             if(expr.find("DUMMY")>=0) :
                 vtemp=[]
                 defns["I"] = ["I","static Complex I(0.,1.);"]
                 for matrix in dirac :
                     temp={}
                     exec("import sympy\nfrom sympy import Symbol,Matrix\n"+Symbols+"result="+expr.replace("DUMMY",matrix)) in temp
                     vtemp.append(temp["result"][0,0])
                 unit = computeUnit(dtemp)
                 output[i] += "*LorentzVector<complex<%s> >(%s,%s,%s,%s)" % (unit,vtemp[1],vtemp[2],vtemp[3],vtemp[0])
             else :
                 temp={}
                 if(iloc==0 or (iloc!=sind and iloc!=lind)) :
                     exec("import sympy\nfrom sympy import Symbol,Matrix\n"+Symbols+"result="+expr) in temp
                     output[i] += "*(%s)" % temp["result"][0,0]
                 else :
                     exec("import sympy\nfrom sympy import Symbol,Matrix\n"+Symbols+"result="+expr) in temp
                     unit = computeUnit(dtemp)
                     if(iloc==sind) :
                         output[i] += "*LorentzSpinor<%s>(%s,%s,%s,%s)" % (unit,temp["result"][0],temp["result"][1],
                                                                           temp["result"][2],temp["result"][3])
                     else :
                         output[i] += "*LorentzSpinorBar<%s >(%s,%s,%s,%s)" % (unit,temp["result"][0],temp["result"][1],
                                                                              temp["result"][2],temp["result"][3])
             dimension[i] = list(map(lambda x, y: x + y, dtemp, dimension[i]))
     return (output,dimension,eps)
             
 def convertLorentz(Lstruct,lorentztag,order,iloc,defns,evalVertex) :
     eps = False
     # split the structure into individual terms
     structures=Lstruct.structure.split()
     parsed=[]
     for struct in structures :
         parsed.append(parse_structure(struct))
     # convert lorentz contractions to dot products
     contractLorentz(Lstruct,parsed,lorentztag,order)
     # now in a position to generate the code
     vals=generateVertex(iloc,Lstruct,parsed,lorentztag,order,defns)
     evalVertex.append((vals[0],vals[1]))
     if(vals[2]) : eps=True
     return eps
 
 evaluateTemplate = """\
 {decl} {{
     {momenta}
     {waves}
 {swap}
 {defns}
     {symbols}
     {couplings}
     {result}
 }}
 """
 
 def swapOrder(vertex,iloc,momenta) :
     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
                 if(vertex.particles[sloc[j]-1].name!=vertex.particles[sloc[j]-1].antiname) :
                     code *= -1
                 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 generateEvaluateFunction(model,vertex,iloc,values,defns,vertexEval,cf) :
     # first construct the signature of the function
     iferm=0
     decls=[]
     offType="Complex"
     momenta=[]
     waves=[]
     poff=""
     fermionReplace=[]
     for i in range(0,len(vertex.lorentz[0].spins)) :
         spin = vertex.lorentz[0].spins[i]
         if(i+1==iloc) :
             if(spin==1) :
                 offType="ScalarWaveFunction"
             elif(spin==2) :
                 if(iferm==0) :
                     offType="SpinorBarWaveFunction"
                 else :
                     offType="SpinorWaveFunction"
                 iferm+=1
             elif(spin==3) :
                 offType="VectorWaveFunction"
             elif(spin==4) :
                 offType="TensorWaveFunction"
             else :
                 print 'unknown spin',spin
                 quit()
             momenta.append([False,""])
         else :
             if(spin==1) :
                 decls.append("ScalarWaveFunction & scaW%s" % (i+1))
                 momenta.append([False,"Lorentz5Momentum P%s =-scaW%s.momentum();" % (i+1,i+1)])
                 waves.append("Complex sca%s = scaW%s.wave();" % (i+1,i+1))
             elif(spin==2) :
                 if(iferm==0) :
                     decls.append("SpinorWaveFunction & sW%s" % (i+1))
                     momenta.append([False,"Lorentz5Momentum P%s =-sW%s.momentum();" % (i+1,i+1)])
                     waves.append("LorentzSpinor<double> s%s = sW%s.wave();" % (i+1,i+1))
                     fermionReplace.append("s%s"%(i+1))
                 else :
                     decls.append("SpinorBarWaveFunction & sbarW%s" % (i+1))
                     momenta.append([False,"Lorentz5Momentum P%s =-sbarW%s.momentum();" % (i+1,i+1)])
                     waves.append("LorentzSpinorBar<double> sbar%s = sbarW%s.wave();" % (i+1,i+1))
                     fermionReplace.append("sbar%s"%(i+1))
                 iferm +=1
             elif(spin==3) :
                 decls.append("VectorWaveFunction & vW%s" % (i+1))
                 momenta.append([False,"Lorentz5Momentum P%s =-vW%s.momentum();" % (i+1,i+1)])
                 waves.append("LorentzPolarizationVector E%s = vW%s.wave();" % (i+1,i+1))
             elif(spin==4) :
                 decls.append("TensorWaveFunction & tW%s" % (i+1))
                 momenta.append([False,"Lorentz5Momentum P%s =-tW%s.momentum();" % (i+1,i+1)])
                 waves.append("LorentzTensor t%s = tW%s.wave()" % (i+1,i+1))
             else :
                 print 'unknown spin',spin
                 quit()
             poff += "-P%s" % (i+1)
     poff = ("Lorentz5Momentum P%s = " % iloc ) + poff
     sig=""
     if(iloc==0) :
         sig="%s evaluate(Energy2, const %s)" % (offType,", const ".join(decls))
     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+";"])
         for i in range(0,len(momenta)) : momenta[i][0]=True
     # cat the definitions
     defString=""
     for (key,value) in defns.iteritems() :
         defString+="    %s\n" %value[1]
 
     oval=""
     symbols=set()
     localCouplings=[]
     result=""
     for j in range(0,len(vertexEval)) :
         (vals,dim) = vertexEval[j]
         expr=""
         dimCheck=dim[0]
         for i in range(0,len(vals)) :
             if(vals[i]=="+" or vals[i]=="-") :
                 expr +=vals[i]
             else :
                 if(dimCheck[0]!=dim[i][0] or dimCheck[1]!=dim[i][1] or
                    dimCheck[2]!=dim[i][2]) :
                     print defns
                     print vertex.lorentz[j]
                     print vertex.lorentz[j].structure
                     print "DIMENSION PROBLEM",i,j,dimCheck,dim[i],vertex,vals[i]
                     print vals
                     quit()
                 expr += "(%s)" % vals[i]
         for rep in fermionReplace :
             for i in range(1,5) :
                 oldVal = "%ss%s" % (rep,i)
                 newVal = "%s.s%s()" % (rep,i)
                 expr=expr.replace(oldVal,newVal)
         vDim = len(vertex.lorentz[0].spins)
 
         unit = computeUnit2(dimCheck,vDim)
         if(unit!="") :
             expr = "(%s)*(%s)" % (expr,unit)  
         val, sym = py2cpp(values[j])
         localCouplings.append("Complex local_C%s = %s;\n" % (j,val))
         symbols |=sym
         if(result!="") :
             if(iloc==0 or vertex.lorentz[0].spins[iloc-1]==1) :
                 result += " + (local_C%s)*Complex(%s)" % (j,expr)
             else :
                 result += " + (local_C%s)*(%s)" % (j,expr)
         else :
             if(iloc==0 or vertex.lorentz[0].spins[iloc-1]==1) :
                 result += " (local_C%s)*Complex(%s) " % (j,expr)
             else :
                 result += " (local_C%s)*(%s) " % (j,expr)
     # 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!="") :
         result = "(%s)*(%s)" % (result,scalars[0:-1])
     if(iloc==0) :
         result = "return (%s)*(%s);\n" % (result,py2cpp(cf[0])[0])
     else :
         if(vertex.lorentz[0].spins[iloc-1] == 3 ) :
             result = "LorentzPolarizationVector vtemp = %s;\n" % result
             result +="    Energy2 p2 = P%s.m2();\nComplex fact = -Complex(0.,1.)*(%s)*propagator(iopt,p2,out,mass,width);\n    if(mass.real() < ZERO) mass  = (iopt==5) ? ZERO : out->mass();\n    complex<Energy2> mass2 = sqr(mass);\n    if(mass.real()==ZERO) {\n vtemp =fact*vtemp;\n}\n    else {\ncomplex<Energy> dot = P%s*vtemp;\n vtemp = fact*(vtemp-dot/mass2*P%s);\n}\nreturn VectorWaveFunction(P%s,out,vtemp.x(),vtemp.y(),vtemp.z(),vtemp.t());\n" % (iloc,py2cpp(cf[0])[0],iloc,iloc,iloc)
         elif(vertex.lorentz[0].spins[iloc-1] == 2 ) :
             result = "if(mass.real() < ZERO) mass  = (iopt==5) ? ZERO : out->mass();\n     Energy2 p2 = P%s.m2();\n    Complex fact = Complex(0.,1.)*(%s)*propagator(iopt,p2,out,mass,width);\n Lorentz%s<double> newSpin = fact*(%s);\n    return %s(P%s,out,newSpin.s1(),newSpin.s2(),newSpin.s3(),newSpin.s4());" % \
                                                          (iloc,py2cpp(cf[0])[0],offType.replace("WaveFunction",""),result.replace( "M%s" % iloc, "mass" ),offType,iloc)
         elif(vertex.lorentz[0].spins[iloc-1] == 1 ) :
             result = "if(mass.real() < ZERO) mass  = (iopt==5) ? ZERO : out->mass();\n     Energy2 p2 = P%s.m2();\n    Complex fact = Complex(0.,1.)*(%s)*propagator(iopt,p2,out,mass,width);\n complex<double> output = fact*(%s);\n    return ScalarWaveFunction(P%s,out,output);\n" % (iloc,py2cpp(cf[0])[0],result,iloc)
 
     # 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 :
             for vals in key :
                 if(vals[0]=="P") :
                     momenta[int(vals[1])-1][0] = True
     sorder=swapOrder(vertex,iloc,momenta)
     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)
     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 porblem',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("=-GeV","") \
                               .replace("const  &","").replace("tcPDPtr","").replace("  "," ")
             if(iloc!=1) :
                 call = call.replace(waves[0],waves[iloc-1])
             pdgid = vertex.particles[i].pdg_code
             if(vertex.particles[i].name!=vertex.particles[i].antiname) :
                 pdgid *= -1
             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,767 +1,767 @@
 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=['FFVV','FFSS','FFVS','VVVV']
 
 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 ('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 ('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 ('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 ('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 ('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 ('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 ('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 ('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 ('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 ('-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 ('1.','1.')
         elif(nmatch==3 and lorentztag=="VVVV") :
-            return ('-1.','-1.','-1.')
+            return ('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 ('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 ('complex(0.,1.)',)
             label = ('f(-1,{g1},{g2})*T(-1,{qq},{qb})'.format(**subs),)
             if match(label): return ('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 ('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 ('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 ('-complex(0.,1.)*(%s)'%sign,)
 
     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) :
         '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
         
     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)
         # 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(vertex.herwig_skip_vertex) :
             return (True,"","")
         # get the factor for the vertex
         generic = False
         try:
             lf = lfactors[lorentztag]
         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)
             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)
             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)
                     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)
             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) :
         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.model)
             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.model)!=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)
             elif('T' in lorentztag) :
                 (leftcontent,rightcontent,normcontent) = processTensorCouplings(lorentztag,vertex,self.model,
                                                                                 self.parmsubs,all_couplings)
             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,
                      '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) :
         eps=False
         classes=""
         headers=""
         # check the colour flows, two cases supported either 1 flow or 3 in gggg
         cidx=-1
         gluon4point = (len(pos[8])==4 and vertex.lorentz[0].spins.count(3)==4)
         couplingOrders=[]
         for (color_idx,lorentz_idx),coupling in vertex.couplings.iteritems() :
             orders = coupling_orders(vertex, coupling, self.model)
             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,2,-1)*f(3,4,-1)'
+                label = 'f(1,3,-1)*f(2,4,-1)'
                 if(label==color) :
                     cidx=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(cidx<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)
         # loop over the different orders in the couplings
         iorder=0
         self.vertex_names[vertex.name]=[classname]
         for corder in couplingOrders :
             iorder +=1
             cname=classname
             if(iorder!=1) :
                 cname= "%s_%s" % (classname,iorder)
                 self.vertex_names[vertex.name].append(cname)
             defns=[]
             vertexEval=[]
             values=[]
             for (color_idx,lorentz_idx),coupling in vertex.couplings.iteritems() :
                 if(color_idx != cidx) : continue
                 if(coupling_orders(vertex, coupling, self.model)!=corder) : continue
                 # calculate the value of the coupling
                 values.append(couplingValue(coupling))
                 # now to convert the spin structures
                 for i in range(0,len(vertex.particles)+1) :
                     if(len(defns)<i+1) :
                         defns.append({})
                         vertexEval.append([])
                     eps |= convertLorentz(vertex.lorentz[lorentz_idx],lorentztag,order,i,defns[i],vertexEval[i])
             # we can now generate the evaluate member functions
             header=""
             impls=""
             imax = len(vertex.particles)+1
             if lorentztag in genericVertices :
                 imax=1
             spins=vertex.lorentz[0].spins
             mult={}
             for i in range(1,6) :
                 if( (spins.count(i)>1 and i!=2) or
                     (spins.count(i)>2 and i==2) ) : mult[i] = []
             for i in range(0,imax) :
                 (evalHeader,evalCC) = generateEvaluateFunction(self.model,vertex,i,values,defns[i],vertexEval[i],cf)
                 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,
                      '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)