Package pyfeyn :: Module feynml
[hide private]
[frames] | no frames]

Source Code for Module pyfeyn.feynml

  1  """PyFeyn interface to the proposed FeynML XML dialect.""" 
  2   
  3  import math, pyx, md5 
  4  from xml.dom.minidom import * 
  5   
  6   
7 -class FeynMLWriter:
8 """Class to write a FeynML representation of a Feynman diagram.""" 9
10 - def __init__(self, filename):
11 """Write FeynML to a file.""" 12 pass
13 14
15 - def diagramToXML(self):
16 root = xml.Element("diagram") 17 for obj in self.__objs: 18 root.append(obj.to_xml()) 19 return xml.tostring(root).replace(">",">\n")
20
21 - def blobToXML(self):
22 ele = xml.Element("blob", 23 {"id" : "V%s" % md5.md5(str(self.xpos, self.ypos)).hexdigest(), 24 "x" : str(self.xpos), "y" : str(self.ypos), 25 "shape" : hasattr(self,"blobshape") and self.blobshape or "circle"}) 26 return ele
27
28 - def lineToXML(self):
29 attribs = {"id":"P%s"%md5.md5(str((self.p1.xpos,self.p1.ypos,self.p2.xpos,self.p2.ypos,self.__arcthrupoint and (self.__arcthrupoint.xpos,self.__arcthrupoint.ypos)))).hexdigest(), 30 "source":"V%s"%md5.md5(str((self.p1.xpos,self.p1.ypos))).hexdigest(), 31 "target":"V%s"%md5.md5(str((self.p2.xpos,self.p2.ypos))).hexdigest(), 32 "type":hasattr(self,"linetype") and self.linetype or "fermion"} 33 if self.bendamount: 34 attribs["bend"] = str(self.bendamount) 35 ele = xml.Element("propagator",attribs) 36 return ele
37
38 - def pointToXML(self):
39 ele = xml.Element("vertex",{"id":"V%s"%md5.md5(str((self.xpos,self.ypos))).hexdigest(),"x":str(self.xpos), "y":str(self.ypos)}) 40 return ele
41
42 - def decopointToXML(self):
43 ele = Point.to_xml(self) 44 fills = "" 45 for x in self.fillstyles: 46 if isinstance(x,pyx.color.rgb): 47 fills = fills + " #%02x%02x%02x"%(255*x.color["r"], 255*x.color["g"], 255*x.color["b"]) 48 strokes = "" 49 for x in self.strokestyles: 50 if isinstance(x,pyx.color.rgb): 51 strokes = strokes + " #%02x%02x%02x"%(255*x.color["r"], 255*x.color["g"],255*x.color["b"]) 52 s = "mark-shape:%s;mark-size:%s;fill-style:%s;line-style:%s;" % \ 53 (MarkedName[self.marker],pyx.unit.tocm(self.radius), fills,strokes ) 54 ele.attrib["style"] = s 55 return ele
56 57 58 59 ############################################## 60 61 62
63 -class FeynMLReader:
64 """Class to construct a Feynman diagram from its FeynML representation.""" 65
66 - def __init__(self, filename):
67 """Read FeynML from a file.""" 68 self.root = elementtree.parse(filename).getroot() 69 self.diagrams = [] 70 self.dicts = [] 71 if self.root.tag != "feynml": 72 raise "FeynML Error: <Feynml> must be root element"%self.root.tag 73 for element in self.root: 74 if element.tag == "head": 75 pass # ignore header for now 76 elif element.tag == "diagram": 77 self.diagrams.append(element) 78 self.dicts.append({}) 79 else: 80 raise "FeynML Error: invalid top-level tag <%s>"%element.tag
81
82 - def get_diagram(self,n):
83 """Return the nth Feynman diagram represented by file contents.""" 84 fd = feyn.FeynDiagram() 85 thediagram = self.diagrams[n] 86 thedict = self.dicts[n] 87 for element in thediagram: 88 if element.tag == "propagator": 89 fd.add( self.get_line(element,thedict) ) 90 elif element.tag == "vertex": 91 fd.add( self.get_vertex(element,thedict) ) 92 elif element.tag == "leg": 93 fd.add( self.get_leg(element,thedict) ) 94 elif element.tag == "blob": 95 fd.add( self.get_blob(element,thedict) ) 96 elif element.tag == "connect": 97 fd.add( self.get_connect(element,thedict) ) 98 elif element.tag == "label": 99 pass # no labels yet 100 else: 101 raise "FeynML Error: invalid tag <%s> in <diagram>"%element.tag 102 return fd
103
104 - def get_vertex(self,element,thedict):
105 """Build a vertex from its FeynML representation.""" 106 107 try: 108 x = float(element.attrib["x"]) 109 y = float(element.attrib["y"]) 110 except: 111 raise "FeynML Error: invalid x,y attributes for <vertex> element" 112 v = feyn.DecoratedPoint(x,y) 113 if "style" in element.attrib: 114 v = self.apply_layout(element.attrib["style"],v) 115 if "label" in element.attrib: 116 v = v.fillstyle(feyn.FreeTeXLabel(element.attrib["label"],x,y,displace=3*pyx.unit.t_pt,angle=90)) 117 try: 118 thedict[element.attrib["id"]] = v 119 except: 120 raise "FeynML Error: missing id attribute in <vertex> element" 121 return v
122
123 - def get_line(self,element,thedict):
124 """Build a line from its feynML representation.""" 125 126 try: 127 type = element.attrib["type"] 128 p1 = thedict[element.attrib["source"]] 129 p2 = thedict[element.attrib["target"]] 130 except: 131 raise "FeynML Error: invalid attribute for <propagator> element" 132 l = feyn.NamedLine[type](p1,p2) 133 if "bend" in element.attrib: 134 l.bend(float(element.attrib["bend"])) 135 if "style" in element.attrib: 136 l = self.apply_layout(element.attrib["style"],l) 137 if "label" in element.attrib: 138 l = l.style(feyn.TeXLabel(element.attrib["label"])) 139 try: 140 thedict[element.attrib["id"]] = l 141 except: 142 raise "FeynML Error: missing id attribute in <propagator> element" 143 return l
144
145 - def get_leg(self,element,thedict):
146 """Build a leg from its FeynML representation.""" 147 148 try: 149 type = element.attrib["type"] 150 x = float(element.attrib["x"]) 151 y = float(element.attrib["y"]) 152 p2 = thedict[element.attrib["target"]] 153 except: 154 raise "FeynML Error: invalid attribute for <leg> element" 155 l = feyn.NamedLine[type](feyn.Point(x,y),p2) 156 if "style" in element.attrib: 157 l = self.apply_layout(element.attrib["style"],l) 158 if "label" in element.attrib: 159 l = l.style(feyn.TeXLabel(element.attrib["label"])) 160 try: 161 thedict[element.attrib["id"]] = l 162 except: 163 raise "FeynML Error: missing id attribute in <leg> element" 164 return l
165
166 - def get_blob(self,element,thedict):
167 """Build a blob from its FeynML representation.""" 168 try: 169 x = float(element.attrib["x"]) 170 y = float(element.attrib["y"]) 171 shape = element.attrib["shape"] 172 radius = float(element.attrib["radius"]) 173 except: 174 raise "FeynML Error: invalid attribute for <blob> element" 175 b = feyn.NamedBlob[shape](x,y,radius) 176 if "style" in element.attrib: 177 b = self.apply_layout(element.attrib["style"],b) 178 if "label" in element.attrib: 179 b = b.strokestyle(feyn.FreeTeXLabel(element.attrib["label"],x,y)) 180 try: 181 thedict[element.attrib["id"]] = b 182 except: 183 raise "FeynML Error: missing id attribute in <blob> element" 184 return b
185
186 - def get_connect(self,element,thedict):
187 """Build a blob's connect-point from its FeynML representation.""" 188 try: 189 parent = thedict[element.attrib["blob"]] 190 direction = element.attrib["dir"] 191 except: 192 raise "feynML Error: invalid attribute for <connect> element" 193 try: 194 angle = float(direction) * math.pi/180. 195 except: 196 winds = {"n":90,"s":-90,"e":0,"w":180, "ne":45,"se":-45,"nw":135,"sw":-135} 197 try: 198 angle = winds[direction] * math.pi/180. 199 except: 200 raise "FeynML Error: invalid direction %s"%direction 201 if parent.blobshape == "circle": 202 x = parent.centre.x() + parent.radius*math.cos(angle) 203 y = parent.centre.y() + parent.radius*math.sin(angle) 204 else: 205 raise "*** TODO *** connecting to non-circles not yet implemented !!" 206 p = feyn.Point(x,y) 207 try: 208 thedict[element.attrib["id"]] = p 209 except: 210 raise "FeynML Error: missing id attribute in <connect> element" 211 return p
212
213 - def apply_layout(self,stylestring,object):
214 """Apply the decorators encoded in a style string to an object.""" 215 styleelements = stylestring.split(";") 216 for styling in styleelements: 217 if styling[:10] == "mark-shape" and isinstance(object,feyn.DecoratedPoint): 218 object.mark(feyn.NamedMark[styling[11:]]) 219 elif styling[:9] == "mark-size" and isinstance(object,feyn.DecoratedPoint): 220 object.size(float(styling[10:])) 221 else: 222 pass 223 return object
224 225 226 227 ##################################################### 228 229 230 231 if __name__=="__main__": 232 import sys 233 reader = FeynMLReader(sys.argv[1]) 234 _f = reader.get_diagram(0) 235 _c = pyx.canvas.canvas() 236 _f.draw(_c) 237 c.writeEPSfile(sys.argv[1]) 238