Page Menu
Home
HEPForge
Search
Configure Global Search
Log In
Files
F8310080
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
114 KB
Subscribers
None
View Options
diff --git a/Models/Feynrules/python/ufo2herwig b/Models/Feynrules/python/ufo2herwig
--- a/Models/Feynrules/python/ufo2herwig
+++ b/Models/Feynrules/python/ufo2herwig
@@ -1,387 +1,392 @@
#! /usr/bin/env python
from __future__ import division
import os, sys, pprint, argparse, re,copy
from string import strip, Template
# add path to the ufo conversion modules
modulepath = os.path.join("@PKGLIBDIR@",'python')
sys.path.append(modulepath)
from ufo2peg import *
# set up the option parser for command line input
parser = argparse.ArgumentParser(
description='Create Herwig model files from Feynrules UFO input.'
)
parser.add_argument(
'ufodir',
metavar='UFO_directory',
help='the UFO model directory'
)
parser.add_argument(
'-v', '--verbose',
action="store_true",
help="print verbose output"
)
parser.add_argument(
'-n','--name',
default="FRModel",
help="set custom nametag for the model"
)
parser.add_argument(
'--ignore-skipped',
action="store_true",
help="ignore skipped vertices and produce output anyway"
)
parser.add_argument(
'--split-model',
action="store_true",
help="Split the model file into pieces to improve compilation for models with many parameters"
)
parser.add_argument(
'--no-generic-loop-vertices',
action="store_true",
help="Don't include the automatically generated generic loop vertices for h->gg and h->gamma gamma"
)
parser.add_argument(
+ '--include-generic',
+ action="store_true",
+ help="Include support for generic spin structures (still experimental)"
+)
+parser.add_argument(
'--forbidden-particle-name',
action="append",
default=["eta","phi"],
help="Add particle names not allowed as names in UFO models to avoid conflicts with"+\
"Herwig internal particles, names will have _UFO appended"
)
# get the arguments
args = parser.parse_args()
# import the model
import imp
path,mod = os.path.split(os.path.abspath(args.ufodir))
FR = imp.load_module(mod,*imp.find_module(mod,[path]))
##################################################
##################################################
# get the Model name from the arguments
modelname = args.name
libname = modelname + '.so'
# define arrays and variables
#allplist = ""
parmdecls = []
parmgetters = []
parmconstr = []
doinit = []
paramstoreplace_ = []
paramstoreplace_expressions_ = []
# get external parameters for printing
parmsubs = dict( [ (p.name, p.value)
for p in FR.all_parameters
if p.nature == 'external' ] )
# evaluate python cmath
def evaluate(x):
import cmath
return eval(x,
{'cmath':cmath,
'complexconjugate':FR.function_library.complexconjugate},
parmsubs)
## get internal params into arrays
internal = ( p for p in FR.all_parameters
if p.nature == 'internal' )
#paramstoreplaceEW_ = []
#paramstoreplaceEW_expressions_ = []
# calculate internal parameters
for p in internal:
parmsubs.update( { p.name : evaluate(p.value) } )
# if 'aS' in p.value and p.name != 'aS':
# paramstoreplace_.append(p.name)
# paramstoreplace_expressions_.append(p.value)
# if 'aEWM1' in p.value and p.name != 'aEWM1':
# paramstoreplaceEW_.append(p.name)
# paramstoreplaceEW_expressions_.append(p.value)
parmvalues=copy.copy(parmsubs)
# more arrays used for substitution in templates
paramsforstream = []
parmmodelconstr = []
# loop over parameters and fill in template stuff according to internal/external and complex/real
# WARNING: Complex external parameter input not tested!
if args.verbose:
print 'verbose mode on: printing all parameters'
print '-'*60
paramsstuff = ('name', 'expression', 'default value', 'nature')
pprint.pprint(paramsstuff)
interfacedecl_T = """\
static Parameter<{modelname}, {type}> interface{pname}
("{pname}",
"The interface for parameter {pname}",
&{modelname}::{pname}_, {value}, 0, 0,
false, false, Interface::nolimits);
"""
massnames = {}
widthnames = {}
for particle in FR.all_particles:
# skip ghosts and goldstones
if(isGhost(particle) or isGoldstone(particle)) :
continue
if particle.mass != 'ZERO':
massnames[particle.mass] = abs(particle.pdg_code)
if particle.width != 'ZERO':
widthnames[particle.width] = abs(particle.pdg_code)
interfaceDecls = []
modelparameters = {}
for p in FR.all_parameters:
value = parmsubs[p.name]
if p.type == 'real':
assert( value.imag < 1.0e-16 )
value = value.real
if p.nature == 'external':
if p not in massnames and p not in widthnames:
interfaceDecls.append(
interfacedecl_T.format(modelname=modelname,
pname=p.name,
value=value,
type=typemap(p.type))
)
else:
interfaceDecls.append('\n// no interface for %s. Use particle definition instead.\n' % p.name)
if hasattr(p,'lhablock'):
lhalabel = '{lhablock}_{lhacode}'.format( lhablock=p.lhablock.upper(), lhacode='_'.join(map(str,p.lhacode)) )
if p not in massnames and p not in widthnames:
parmmodelconstr.append('set %s:%s ${%s}' % (modelname, p.name, lhalabel))
else:
parmmodelconstr.append('# %s is taken from the particle setup' % p.name)
modelparameters[lhalabel] = value
parmsubs[p.name] = lhalabel
else:
if p not in massnames and p not in widthnames:
parmmodelconstr.append('set %s:%s %s' % (modelname, p.name, value))
else:
parmmodelconstr.append('# %s is taken from the particle setup' % p.name)
parmsubs[p.name] = value
if p not in massnames and p not in widthnames:
parmconstr.append('%s_(%s)' % (p.name, value))
else:
parmconstr.append('%s_()' % p.name)
else :
parmconstr.append('%s_()' % p.name)
parmsubs[p.name] = value
elif p.type == 'complex':
value = complex(value)
if p.nature == 'external':
#
# TODO: WE DO NOT HAVE COMPLEX INTERFACES IN THEPEG (yet?)
#
# interfaceDecls.append(
# interfacedecl_T.format(modelname=modelname,
# pname=p.name,
# value='Complex(%s,%s)'%(value.real,value.imag),
# type=typemap(p.type))
# )
#
# parmmodelconstr.append('set %s:%s (%s,%s)' % (modelname, p.name, value.real, value.imag))
parmconstr.append('%s_(%s,%s)' % (p.name, value.real, value.imag))
else :
parmconstr.append('%s_(%s,%s)' % (p.name, 0.,0.))
parmsubs[p.name] = value
else:
raise Exception('Unknown data type "%s".' % p.type)
parmdecls.append(' %s %s_;' % (typemap(p.type), p.name))
parmgetters.append(' %s %s() const { return %s_; }' % (typemap(p.type),p.name, p.name))
paramsforstream.append('%s_' % p.name)
expression, symbols = 'return %s_' % p.name, None
if p.nature != 'external':
expression, symbols = py2cpp(p.value)
text = add_brackets(expression, symbols)
text=text.replace('()()','()')
doinit.append(' %s_ = %s;' % (p.name, text) )
if p in massnames:
doinit.append(' resetMass(%s,%s_ * GeV);' % (massnames[p], p.name) )
elif p in widthnames:
doinit.append(' getParticleData(%s)->width(%s_ * GeV);' % (widthnames[p], p.name) )
doinit.append(' getParticleData(%s)->cTau (%s_ == 0.0 ? Length() : hbarc/(%s_*GeV));' % (widthnames[p], p.name, p.name) )
doinit.append(' getParticleData(%s)->widthCut(10. * %s_ * GeV);' % (widthnames[p], p.name) )
elif p.nature == 'external':
if p in massnames:
doinit.append(' %s_ = getParticleData(%s)->mass() / GeV;' % (p.name, massnames[p]) )
elif p in widthnames:
doinit.append(' %s_ = getParticleData(%s)->width() / GeV;' % (p.name, widthnames[p]) )
if args.verbose:
pprint.pprint((p.name,p.value, value, p.nature))
pcwriter = ParamCardWriter(FR.all_parameters)
paramcard_output = '\n'.join(pcwriter.output)
### special treatment
# if p.name == 'aS':
# expression = '0.25 * sqr(strongCoupling(q2)) / Constants::pi'
# elif p.name == 'aEWM1':
# expression = '4.0 * Constants::pi / sqr(electroMagneticCoupling(q2))'
# elif p.name == 'Gf':
# expression = 'generator()->standardModel()->fermiConstant() * GeV2'
paramconstructor=': '
for ncount in range(0,len(parmconstr)) :
paramconstructor += parmconstr[ncount]
if(ncount != len(parmconstr) -1) :
paramconstructor += ','
if(ncount%5 == 0 ) :
paramconstructor += "\n"
paramout=""
paramin =""
for ncount in range(0,len(paramsforstream)) :
if(ncount !=0 ) :
paramout += "<< " + paramsforstream[ncount]
paramin += ">> " + paramsforstream[ncount]
else :
paramout += paramsforstream[ncount]
paramin += paramsforstream[ncount]
if(ncount%5 == 0 ) :
paramout += "\n"
paramin += "\n"
parmtextsubs = { 'parmgetters' : '\n'.join(parmgetters),
'parmdecls' : '\n'.join(parmdecls),
'parmconstr' : paramconstructor,
'getters' : '',
'decls' : '',
'addVertex' : '',
'doinit' : '\n'.join(doinit),
'ostream' : paramout,
'istream' : paramin ,
'refs' : '',
'parmextinter': ''.join(interfaceDecls),
'ModelName': modelname,
'calcfunctions': '',
'param_card_data': paramcard_output
}
##################################################
##################################################
##################################################
# set up the conversion of the vertices
vertexConverter = VertexConverter(FR,parmvalues)
vertexConverter.readArgs(args)
# convert the vertices
vertexConverter.convert()
##################################################
##################################################
##################################################
plist, names = thepeg_particles(FR,parmsubs,modelname,modelparameters,args.forbidden_particle_name)
particlelist = [
"# insert HPConstructor:Outgoing 0 /Herwig/{n}/Particles/{p}".format(n=modelname,p=p)
for p in names
]
# make the first one active to have something runnable in the example .in file
particlelist[0] = particlelist[0][2:]
particlelist = '\n'.join(particlelist)
modelfilesubs = { 'plist' : plist,
'vlist' : vertexConverter.get_vertices(libname),
'setcouplings': '\n'.join(parmmodelconstr),
'ModelName': modelname
}
# write the files from templates according to the above subs
if vertexConverter.should_print():
MODEL_HWIN = getTemplate('LHC-FR.in')
if(not args.split_model) :
MODEL_CC = [getTemplate('Model.cc')]
else :
MODEL_EXTRA_CC=getTemplate('Model6.cc')
extra_names=[]
extra_calcs=[]
parmtextsubs['doinit']=""
for i in range(0,len(doinit)) :
if( i%20 == 0 ) :
function_name = "initCalc" +str(int(i/20))
parmtextsubs['doinit'] += function_name +"();\n"
parmtextsubs['calcfunctions'] += "void " + function_name + "();\n"
extra_names.append(function_name)
extra_calcs.append("")
extra_calcs[-1] += doinit[i] + "\n"
for i in range(0,len(extra_names)) :
ccname = '%s_extra_%s.cc' % (modelname,i)
writeFile( ccname, MODEL_EXTRA_CC.substitute({'ModelName' : modelname,
'functionName' : extra_names[i],
'functionCalcs' : extra_calcs[i] }) )
MODEL_CC = [getTemplate('Model1.cc'),getTemplate('Model2.cc'),getTemplate('Model3.cc'),
getTemplate('Model4.cc'),getTemplate('Model5.cc')]
MODEL_H = getTemplate('Model.h')
print 'LENGTH',len(MODEL_CC)
MODELINFILE = getTemplate('FR.model')
writeFile( 'LHC-%s.in' % modelname,
MODEL_HWIN.substitute({ 'ModelName' : modelname,
'Particles' : particlelist })
)
modeltemplate = Template( MODELINFILE.substitute(modelfilesubs) )
writeFile( '%s.h' % modelname, MODEL_H.substitute(parmtextsubs) )
for i in range(0,len(MODEL_CC)) :
if(len(MODEL_CC)==1) :
ccname = '%s.cc' % modelname
else :
ccname = '%s.cc' % (modelname + str(i))
writeFile( ccname, MODEL_CC[i].substitute(parmtextsubs) )
writeFile( modelname +'.template', modeltemplate.template )
writeFile( modelname +'.model', modeltemplate.substitute( modelparameters ) )
# copy the Makefile-FR to current directory,
# replace with the modelname for compilation
with open(os.path.join(modulepath,'Makefile-FR'),'r') as orig:
with open('Makefile','w') as dest:
dest.write(orig.read().replace("FeynrulesModel.so", libname))
print 'finished generating model:\t', modelname
print 'model directory:\t\t', args.ufodir
print 'generated:\t\t\t', len(FR.all_vertices), 'vertices'
print '='*60
print 'library:\t\t\t', libname
print 'input file:\t\t\t', 'LHC-' + modelname +'.in'
print 'model file:\t\t\t', modelname +'.model'
print '='*60
print """\
To complete the installation, compile by typing "make".
An example input file is provided as LHC-FRModel.in,
you'll need to change the required particles in there.
"""
print 'DONE!'
print '='*60
diff --git a/Models/Feynrules/python/ufo2peg/Vertex_class.template b/Models/Feynrules/python/ufo2peg/GeneralVertex_class.template
copy from Models/Feynrules/python/ufo2peg/Vertex_class.template
copy to Models/Feynrules/python/ufo2peg/GeneralVertex_class.template
--- a/Models/Feynrules/python/ufo2peg/Vertex_class.template
+++ b/Models/Feynrules/python/ufo2peg/GeneralVertex_class.template
@@ -1,43 +1,39 @@
-class ${ModelName}${classname}: public ${lorentztag}Vertex {
+class ${ModelName}${classname}: public Abstract${lorentztag}Vertex {
public:
${ModelName}${classname}() {
- ${header}
${addToPlist}
}
- void setCoupling(Energy2 ${couplingptrs}) {
- ${symbolrefs}
- ${prepend}
- // getParams(q2);
- ${norm}
- ${left}
- ${right}
- ${append}
- }
+
+ ${evaldefs}
+
void persistentOutput(PersistentOStream & os) const { os << model_; }
void persistentInput(PersistentIStream & is, int) { is >> model_; }
- // static void Init();
+
+ virtual void setCoupling(Energy2, tcPDPtr,
+ tcPDPtr, tcPDPtr) {assert(false);}
+
+ virtual void setCoupling(Energy2,tcPDPtr,tcPDPtr,tcPDPtr,
+ tcPDPtr) {assert(false);}
+
protected:
+
IBPtr clone() const { return new_ptr(*this); }
IBPtr fullclone() const { return new_ptr(*this); }
void doinit() {
model_ = dynamic_ptr_cast<tcHw${ModelName}Ptr>
(generator()->standardModel());
assert(model_);
- // getParams(q2);
- ${parameters}
- ${setCouplings}
- orderInGem(${qedorder});
- orderInGs(${qcdorder});
- ${lorentztag}Vertex::doinit();
+ Abstract${lorentztag}Vertex::doinit();
}
- // void getParams(Energy2);
+
private:
+
${ModelName}${classname} & operator=(const ${ModelName}${classname} &);
- // Complex leftval, rightval, normval;
+
tcHw${ModelName}Ptr model_;
};
-DescribeClass<${ModelName}${classname},Helicity::${lorentztag}Vertex>
+DescribeClass<${ModelName}${classname},Helicity::Abstract${lorentztag}Vertex>
describeHerwig${ModelName}${classname}("Herwig::${ModelName}${classname}",
"${ModelName}.so");
-// void ${ModelName}${classname}::getParams(Energy2 ) {
-// }
+
+${evalimpls}
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,864 +1,1435 @@
import itertools,cmath,re,sys
-from .helpers import SkipThisVertex,extractAntiSymmetricIndices
+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:
sys.stderr.write(
'Warning: unsupported {tag} ( {ps} ) Lorentz structure in {name}:\n'
.format(tag="VVVV", name=vertex.name, ps=' '.join(map(str,vertex.particles)))
)
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]
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]
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]
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))
+ # split up the structure
+ for struct in structure.split("*"):
+ 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) : continue
+ for i in range(0,len(parsed[l][k].lorentz)) :
+ 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) :
+ 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"
+ else :
+ output = "1./GeV%s" % totalDim
+ else :
+ if(totalDim==-1) :
+ output = "GeV"
+ else :
+ output = "GeV%s" % (-totalDim)
+ 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) :
+ # 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(ind1[1]=="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
+ # 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 = vslashM2.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 += "*"+vslashM.substitute({ "v" : "P%s" % lind, "m" : "M%s" % lind} )
+ Symbols += vslashMS.substitute({ "v" : "P%s" % lind, "m" : "M%s" % lind} )
+ defns["vvP%s" % lind ] = ["vvP%s" % lind ,
+ vslashD.substitute({ "var" : "Energy",
+ "v" : "P%s" % lind })]
+ dtemp[1] += 1
+ 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)
+
+def convertLorentz(Lstruct,lorentztag,order,iloc,defns,evalVertex) :
+ # 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
+ evalVertex.append(generateVertex(iloc,Lstruct,parsed,lorentztag,order,defns))
+
+evaluateTemplate = """\
+{decl} {{
+ {momenta}
+ {waves}
+ {defns}
+ {symbols}
+ {couplings}
+ {result}
+}}
+"""
+
+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()
+ poff = ("Lorentz5Momentum P%s = " % (i+1) ) + poff
+ else :
+ if(spin==1) :
+ decls.append("ScalarWaveFunction & scaW%s" % (i+1))
+ momenta.append("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("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("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("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("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)
+ 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(poff+";")
+ # 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 "DIMENSION PROBLEM",dimCheck,dim[i],vertex
+ 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!="") :
+ result += " + (local_C%s)*(%s)" % (j,expr)
+ else :
+ result += " (local_C%s)*(%s) " % (j,expr)
+ 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)
+
+ header="virtual %s" % sig
+ sig=sig.replace("=-GeV","")
+ symboldefs = [ def_from_model(model,s) for s in symbols ]
+ function = evaluateTemplate.format(decl=sig,momenta="\n ".join(momenta),defns=defString,
+ waves="\n ".join(waves),symbols='\n '.join(symboldefs),
+ couplings="\n ".join(localCouplings),
+ result=result)
+ return (header,function)
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,663 +1,683 @@
import sys,pprint
from .helpers import CheckUnique,getTemplate,writeFile,qcd_qed_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
+ RSCouplings,convertLorentz,generateEvaluateFunction
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']
+
# 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::{modelname}V_{vname} /Herwig/{modelname}/V_{vname}
insert {modelname}:ExtraVertices 0 /Herwig/{modelname}/V_{vname}
"""
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 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',)
+ 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',)
+ 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',)
+ 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',)
+ 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',)
+ 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',)
+ 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',)
+ 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!
+ 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!
+ 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,)
+ 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)))
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
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')
+ return ('1.','1.')
elif(nmatch==3 and lorentztag=="VVVV") :
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]
}
- 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.')
+ 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.)',)
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,)
+ 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(globalsign,lorentztag,lf,cf) :
- if(globalsign!=1.) :
- prefactors = '(%s) * (%s) * (%s)' \
- % (globalsign**(len(lorentztag)-2),lf,cf)
- else :
- prefactors = '(%s) * (%s)' \
- % (lf,cf)
- return prefactors
- # fact=[]
- # if(globalsign!=1.) :
- # fact.append(globalsign**(len(lorentztag)-2))
- # if(lf!="1") :
- # fact.append(lf)
- # if(cf!="1") :
- # fact.append(cf)
- # if(len(fact)==0) : return "1"
- # prefactor = '(%s)' % fact[0]
- # for ix in range(1,len(fact)) :
- # prefactor = '%s * (%s)' % (prefactor,fact[ix])
- # return prefactor
+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.ONE_EACH=True
self.verbose=False
self.vertex_skipped=False
self.ignore_skipped=False
self.model=model
self.all_vertices= []
self.modelname=""
- self.globalsign=self.global_sign()
self.no_generic_loop_vertices = False
self.parmsubs = parmsubs
-
- def global_sign(self):
- 'Initial pass to find global sign at the moment does nothing'
- return 1.0
- # for v in self.model.all_vertices:
- # pids = sorted([ p.pdg_code for p in v.particles ])
- # if pids != [-11,11,22]: continue
- # coup = v.couplings
- # assert( len(coup) == 1 )
- # val = coup.values()[0].value
- # val = evaluate(val)
- # assert( val.real == 0 )
- # return 1 if val.imag > 0 else -1
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)
- # check if we should merge vertices
- if(self.ONE_EACH) :
- self.all_vertices = self.model.all_vertices
- else:
- self.all_vertices = collapse_vertices(self.model.all_vertices)
+ # 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) :
# 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)
if(vertex.herwig_skip_vertex) :
return (True,"","")
# get the factor for the vertex
+ generic = False
try:
lf = lfactors[lorentztag]
except KeyError:
- 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,"","")
+ 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
- if self.ONE_EACH:
- plistarray = [ ','.join([ str(vertex.particles[o-1].pdg_code) for o in order ]) ]
- else:
- plistarray = [ ','.join([ str(p.pdg_code) for p in pl ])
- for pl in vertex.particles_list ]
+ 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 :
+ return self.extractGeneral(vertex,order,lorentztag,classname,plistarray,pos,cf)
+ else :
+ return self.extractGeneral(vertex,order,lorentztag,classname,plistarray,pos,cf)
+
+
+ def extractGeneric(self,vertex,order,lorentztag,classname,plistarray,pos,lf,cf) :
# try to extract the couplings
- try:
- (all_couplings,header,qcd,qed,prepend,append) = \
+ (all_couplings,header,qcd,qed,prepend,append) = \
self.extractCouplings(lorentztag,pos,lf,cf,vertex,order)
- 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,"","")
# set the coupling ptrs in the setCoupling call
couplingptrs = self.setCouplingPtrs(lorentztag,qcd,append != '',prepend != '')
# final processing of the couplings
- try :
- 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()
- 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,"","")
-
+ 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 ]
### assemble dictionary and fill template
subs = { 'lorentztag' : lorentztag, # ok
'classname' : classname, # 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
#################### need survey which different setter methods exist in base classes
'addToPlist' : '\n'.join([ 'addToList(%s);'%s for s in plistarray]),
'parameters' : '',
'setCouplings' : '',
'qedorder' : qed,
'qcdorder' : qcd,
'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 ))
return (False,VERTEXCLASS.substitute(subs),VERTEXHEADER.format(**subs))
+ def extractGeneral(self,vertex,order,lorentztag,classname,plistarray,pos,cf) :
+ defns=[]
+ vertexEval=[]
+ values=[]
+ for (color_idx,lorentz_idx),coupling in vertex.couplings.iteritems() :
+ 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,"","")
+ # 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([])
+ convertLorentz(vertex.lorentz[lorentz_idx],lorentztag,order,i,defns[i],vertexEval[i])
+
+ # we can now generate the evaluate member functions
+ headers=""
+ impls=""
+ imax = len(vertex.particles)+1
+ if lorentztag in genericVertices :
+ imax=1
+ for i in range(0,imax) :
+ (evalHeader,evalCC) = generateEvaluateFunction(self.model,vertex,i,values,defns[i],vertexEval[i],cf)
+ headers+=" "+evalHeader+";\n"
+ impls+=evalCC
+ impls=impls.replace("evaluate(", "FRModel%s::evaluate(" % classname)
+ ### assemble dictionary and fill template
+ subs = { 'lorentztag' : lorentztag,
+ 'classname' : classname,
+ 'addToPlist' : '\n'.join([ 'addToList(%s);'%s for s in plistarray]),
+ 'ModelName' : self.modelname,
+ 'evaldefs' : headers,
+ 'evalimpls' : impls}
+ return (False,GENERALVERTEXCLASS.substitute(subs),GENERALVERTEXHEADER.format(**subs))
+
+
+
def get_vertices(self,libname):
vlist = ['library %s\n' % libname]
for v in self.all_vertices:
if v.herwig_skip_vertex: continue
vlist.append( vertexline.format(modelname=self.modelname, vname=v.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)
def extractCouplings(self,lorentztag,pos,lf,cf,vertex,order) :
coup_left = []
coup_right = []
coup_norm = []
header = ""
qcd=0
qed=0
prepend=""
append=""
unique_qcd = CheckUnique()
unique_qed = CheckUnique()
maxColour=0
for (color_idx,lorentz_idx),coupling in vertex.couplings.iteritems():
maxColour=max(maxColour,color_idx)
all_couplings=[]
for ix in range(0,maxColour+1) :
all_couplings.append([])
for colour in range(0,maxColour+1) :
for (color_idx,lorentz_idx),coupling in vertex.couplings.iteritems() :
if(color_idx!=colour) : continue
qcd, qed = qcd_qed_orders(vertex, coupling)
try :
unique_qcd( qcd )
unique_qed( qed )
except :
msg = 'Different powers of QCD and QED couplings for the same vertex'\
' is not currently supported for {ps} in {name}.\n'.format(tag=lorentztag, name=vertex.name,
ps=' '.join(map(str,vertex.particles)))
sys.stderr.write(msg)
raise SkipThisVertex()
L = vertex.lorentz[lorentz_idx]
- prefactors = calculatePrefactor(self.globalsign,lorentztag,lf,cf[color_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,qcd,order)
else:
raise SkipThisVertex()
# return the result
return (all_couplings,header,qcd,qed,prepend,append)
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Sat, Dec 21, 5:19 PM (12 h, 6 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
4023613
Default Alt Text
(114 KB)
Attached To
rHERWIGHG herwighg
Event Timeline
Log In to Comment