Page MenuHomeHEPForge

No OneTemporary

Index: pyfeyn/trunk/pyfeyn/hepnames.py
===================================================================
--- pyfeyn/trunk/pyfeyn/hepnames.py (revision 1923)
+++ pyfeyn/trunk/pyfeyn/hepnames.py (revision 1924)
Property changes on: pyfeyn/trunk/pyfeyn/hepnames.py
___________________________________________________________________
Added: svn:keywords
## -0,0 +1 ##
+Id Date
\ No newline at end of property
Index: pyfeyn/trunk/pyfeyn/utils.py
===================================================================
--- pyfeyn/trunk/pyfeyn/utils.py (revision 1923)
+++ pyfeyn/trunk/pyfeyn/utils.py (revision 1924)
@@ -1,52 +1,53 @@
"""Utility functions and classes for PyFeyn"""
import pyx
from pyfeyn.diagrams import FeynDiagram
+from pyfeyn import options
## Default units
defunit = pyx.unit.cm
todefunit = pyx.unit.tocm
def sign(x):
"""Get the sign of a numeric type"""
if x < 0:
return -1
if x > 0:
return 1
if x == 0:
return 0
class Visible:
def isVisible(self):
return True
def getPath(self):
return None
def getVisiblePath(self):
return self.getPath()
def setDepth(self, depth):
self.depth = depth
return self
def getDepth(self):
if self.__dict__.has_key("depth"):
return self.depth
else:
return None
def __cmp__(self, other):
"""Compare with another visible class, just using layers."""
if other is None:
return -1
- if FeynDiagram.options.DEBUG:
+ if options.options.DEBUG:
print "Comparing visible classes: ", \
self.__class__, "->", self.getDepth(), "vs.", \
other.__class__, "->", other.getDepth()
else:
return cmp(self.getDepth(), other.getDepth())
Property changes on: pyfeyn/trunk/pyfeyn/utils.py
___________________________________________________________________
Added: svn:keywords
## -0,0 +1 ##
+Id Date
\ No newline at end of property
Index: pyfeyn/trunk/pyfeyn/blobs.py
===================================================================
--- pyfeyn/trunk/pyfeyn/blobs.py (revision 1923)
+++ pyfeyn/trunk/pyfeyn/blobs.py (revision 1924)
@@ -1,231 +1,232 @@
"""Various blob shapes to represent generic interactions."""
import pyx
from pyfeyn.diagrams import FeynDiagram
from pyfeyn.points import Point
from pyfeyn.utils import Visible
from pyfeyn.deco import PointLabel
+from pyfeyn import options
## Blob base class
class Blob(Point, Visible):
"Base class for all blob-like objects in Feynman diagrams"
def __init__(self):
"""Dysfunctional constructor, since this is an abstract base class."""
self.trafos = []
self.strokestyles = []
self.fillstyles = []
self.layeroffset = 1000
raise Exception("Blobs are an abstract base class: you can't make them!")
def setStrokeStyle(self, strokestyle):
"""Set the stroke style."""
self.strokestyles = [strokestyle]
return self
def clearStrokeStyles(self):
"""Remove all the current stroke styles."""
self.strokestyles = []
return self
def setFillStyle(self, fillstyle):
"""Set the fill style."""
self.fillstyles = [fillstyle]
return self
def clearFillStyles(self):
"""Remove all the current fill styles."""
self.fillstyles = []
return self
def addTrafo(self, trafo):
"""Add a transformation."""
self.trafos.append(trafo)
return self
def clearTrafos(self):
"""Remove transformations."""
self.trafos = []
return self
def setPoints(self, points):
"""Set the points to which this blob is attached."""
if points:
self.points = points
for p in self.points:
p.blob = self
else:
self.points = []
def addLabel(self, text, displace=-0.15, angle = 0):
"""Add a label."""
- if FeynDiagram.options.DEBUG:
+ if options.options.DEBUG:
print "Adding label: " + text
self.labels.append(PointLabel(text=text, point=self,
displace=displace, angle=angle))
- if FeynDiagram.options.DEBUG:
+ if options.options.DEBUG:
print "Labels = " + str(self.labels)
return self
def clearLabels(self):
"""Remove all current labels."""
self.labels = []
return self
## Circle class (a kind of Blob)
class Circle(Blob):
"""A circular blob"""
blobshape = "circle"
def __init__(self,
x = None, y = None,
center = None,
radius = None,
fill = [pyx.color.rgb.white],
stroke = [pyx.color.rgb.black],
points = None):
"""Constructor."""
if radius:
self.radius = float(radius)
else:
raise Exception("No (or zero) radius specified for blob.")
if x is not None and y is not None:
self.setXY(x, y)
elif center is not None:
self.setXY(center.getX(), center.getY())
else:
raise Exception("No center specified for blob.")
self.setPoints(points)
self.fillstyles = fill
self.strokestyles = stroke
self.layeroffset = 1000
self.trafos = []
self.labels = []
## Add this to the current diagram automatically
FeynDiagram.currentDiagram.add(self)
def getPath(self):
"""Get the path of this circle blob."""
return pyx.path.circle(self.getX(), self.getY(), self.radius)
def draw(self, canvas):
"""Draw this circle blob."""
canvas.fill(self.getPath(), [pyx.color.rgb.white])
canvas.fill(self.getPath(), self.fillstyles)
canvas.stroke(self.getPath(), self.strokestyles)
for l in self.labels:
l.draw(canvas)
## Ellipse class (a kind of Blob)
class Ellipse(Blob):
"An elliptical blob"
blobshape = "ellipse"
def __init__(self,
x = None, y = None,
center = None,
xradius = None, yradius = None,
fill = [pyx.color.rgb.white],
stroke = [pyx.color.rgb.black],
points = None):
"""Constructor."""
self.layeroffset = 1000
if x is not None and y is not None:
self.setXY(x, y)
elif center is not None:
self.setXY(center.getX(), center.getY())
else:
raise Exception("No center specified for blob.")
self.xrad = None
if xradius:
self.setXRadius(xradius)
elif yradius:
self.setXRadius(yradius)
else:
raise Exception("No viable candidate for x-radius")
self.yrad = None
if yradius:
self.setYRadius(yradius)
elif xradius:
self.setYRadius(xradius)
else:
raise Exception("No viable candidate for y-radius")
self.setPoints(points)
self.fillstyles = fill
self.strokestyles = stroke
self.trafos = []
self.labels = []
## Add this to the current diagram automatically
FeynDiagram.currentDiagram.add(self)
def getXRadius(self):
"""Get the component of the radius in the x-direction."""
return self.xrad
def setXRadius(self, xrad):
"""Set the component of the radius in the x-direction."""
self.xrad = float(xrad)
return self
def getYRadius(self):
"""Get the component of the radius in the y-direction."""
return self.yrad
def setYRadius(self, yrad):
"""Set the component of the radius in the y-direction."""
self.yrad = float(yrad)
return self
def getXYRadius(self):
"""Get the components of the radius in the x and y
directions at the same time."""
return self.getXRadius(), self.getYRadius()
def setXYRadius(self, xrad, yrad):
"""Get the components of the radius in the x and y
directions at the same time."""
self.setXRadius(xrad)
self.setYRadius(yrad)
return self
def getPath(self):
"""Get the path for this blob."""
ucircle = pyx.path.circle(self.xpos, self.ypos, 1.0)
mytrafo = pyx.trafo.scale(self.xrad, self.yrad, self.xpos, self.ypos)
epath = ucircle.transformed(mytrafo)
return epath
def draw(self, canvas):
"""Draw this blob on the given canvas."""
canvas.fill(self.getPath(), [pyx.color.rgb.white])
canvas.fill(self.getPath(), self.fillstyles)
#canvas.stroke(self.getPath(), [pyx.color.rgb.white])
canvas.stroke(self.getPath(), self.strokestyles)
for l in self.labels:
l.draw(canvas)
## A dictionary to map feynML blob shape choices to blob classes
NamedBlob = {
"circle" : Circle,
"ellipse" : Ellipse
}
Property changes on: pyfeyn/trunk/pyfeyn/blobs.py
___________________________________________________________________
Added: svn:keywords
## -0,0 +1 ##
+Id Date
\ No newline at end of property
Index: pyfeyn/trunk/pyfeyn/diagrams.py
===================================================================
--- pyfeyn/trunk/pyfeyn/diagrams.py (revision 1923)
+++ pyfeyn/trunk/pyfeyn/diagrams.py (revision 1924)
@@ -1,80 +1,69 @@
"""Classes for the actual diagram containers."""
import pyx
-
-class OptionSet:
- """A container for options."""
- def __init__(self):
- self.DEBUG = None
- self.VDEBUG = None
- self.DRAFT = None
-
+from pyfeyn import options
## Diagram class
class FeynDiagram:
"""The main PyFeyn diagram class."""
currentDiagram = None
currentCanvas = pyx.canvas.canvas()
- options = OptionSet()
- options.DEBUG = None
- options.VDEBUG = None
-
def __init__(self, objects=None):
"""Objects for holding a set of Feynman diagram components."""
self.__objs = objects
if self.__objs is None:
self.__objs = []
self.highestautolayer = 0
FeynDiagram.currentCanvas = pyx.canvas.canvas()
FeynDiagram.currentDiagram = self
def add(self, *objs):
"""Add an object to the diagram."""
for obj in objs:
- if FeynDiagram.options.DEBUG:
+ if options.options.DEBUG:
print "#objs = %d" % len(self.__objs)
offset = 0
if obj.__dict__.has_key("layeroffset"):
#print "offset =", obj.layeroffset
offset = obj.layeroffset
self.highestautolayer += 1
obj.setDepth(self.highestautolayer + offset)
- if FeynDiagram.options.DEBUG:
+ if options.options.DEBUG:
print "Object %s layer = %d + %d = %d" % \
(obj.__class__, self.highestautolayer, offset,
self.highestautolayer + offset)
self.__objs.append(obj)
def drawToCanvas(self):
"""Draw the components of this diagram in a well-defined order."""
- if FeynDiagram.options.DEBUG:
+ if options.options.DEBUG:
print "Final #objs = %d" % len(self.__objs)
- if FeynDiagram.options.VDEBUG:
+ if options.options.VDEBUG:
print "Running in visual debug mode"
## Sort drawing objects by layer
drawingobjs = self.__objs
try:
drawingobjs.sort()
except:
pass
## Draw each object
for obj in drawingobjs:
- if FeynDiagram.options.DEBUG:
+ if options.options.DEBUG:
print "Depth = ", obj.getDepth()
obj.draw(FeynDiagram.currentCanvas)
return FeynDiagram.currentCanvas
def draw(self, outfile):
"""Draw the diagram to a file, with the filetype (EPS or PDF)
derived from the file extension."""
c = self.drawToCanvas()
if c is not None and outfile is not None:
c.writetofile(outfile)
Property changes on: pyfeyn/trunk/pyfeyn/diagrams.py
___________________________________________________________________
Added: svn:keywords
## -0,0 +1 ##
+Id Date
\ No newline at end of property
Index: pyfeyn/trunk/pyfeyn/deco.py
===================================================================
--- pyfeyn/trunk/pyfeyn/deco.py (revision 1923)
+++ pyfeyn/trunk/pyfeyn/deco.py (revision 1924)
@@ -1,267 +1,268 @@
"""A couple of classes for decorating diagram elements."""
import pyx, math
from pyfeyn.diagrams import FeynDiagram
from pyfeyn.utils import Visible
+from pyfeyn import options
## Arrow decorator class
class Arrow(pyx.deco.deco, pyx.attr.attr):
"""Arrow for Feynman diagram lines"""
def __init__(self, pos=0.5, size=6*pyx.unit.v_pt,
angle=45, constriction=0.8):
self.pos = pos
self.size = size
self.angle = angle
self.constriction = constriction
def decorate(self, dp, texrunner):
"""Attach arrow to a path (usually a line)."""
dp.ensurenormpath()
constrictionlen = self.size * self.constriction * \
math.cos(self.angle*math.pi/360.0)
arrowtopos = self.pos * dp.path.arclen()+0.5*self.size
arrowtopath = dp.path.split(arrowtopos)[0]
arrowpath = pyx.deco._arrowhead(arrowtopath, self.pos*dp.path.arclen(),
1, self.size, 45, constrictionlen)
dp.ornaments.fill(arrowpath)
return dp
class FreeArrow(Visible):
"""Arrow not attached to any line in a diagram."""
def __init__(self, length=0.5*pyx.unit.v_cm, size=6*pyx.unit.v_pt,
angle=45, constriction=0.8, pos=None, x=None, y=None,
direction=0):
self.x, self.y = 0, 0
if x is not None:
self.x = x
if y is not None:
self.y = y
if pos is not None:
self.x, self.y = pos.getXY()
self.direction = direction
self.length = length
self.size = size
self.angle = angle
self.constriction = constriction
## Add this to the current diagram automatically
FeynDiagram.currentDiagram.add(self)
def draw(self, canvas):
"""Draw this arrow on the supplied canvas."""
endx, endy = self.x-self.length*math.sin(self.direction*math.pi/180.), \
self.y-self.length*math.cos(self.direction*math.pi/180.)
linepath = pyx.deco.decoratedpath(
pyx.path.path(pyx.path.moveto(endx,endy),
pyx.path.lineto(self.x,self.y)))
styles = [pyx.deco.earrow(size=self.size, angle=self.angle,
constriction=self.constriction)]
canvas.stroke(linepath.path,styles)
class ParallelArrow(Visible):
"""Arrow running parallel to a line, for momenta, helicities etc."""
def __init__(self, line, pos=0.5, displace=0.3, length=0.5*pyx.unit.v_cm,
size=6*pyx.unit.v_pt, angle=45, constriction=0.8, sense=+1):
self.line = line
self.pos = pos
self.displace = pyx.unit.length(displace)
self.length = length
self.size = size
self.angle = angle
self.constriction = constriction
self.sense = sense
def draw(self, canvas):
"""Draw this arrow on the supplied canvas."""
p = self.line.getPath()
posparam = p.begin() + self.pos * p.arclen()
x, y = self.line.fracpoint(self.pos).getXY()
arrx, arry = self.line.fracpoint(self.pos+self.length/2./p.arclen()).getXY()
endx, endy = self.line.fracpoint(self.pos-self.length/2./p.arclen()).getXY()
## Calculate the displacement from the line
displacement = self.displace
intrinsicwidth = pyx.unit.length(0.1)
if hasattr(self.line, "arcradius"):
intrinsicwidth = self.line.arcradius
if displacement > 0:
displacement += intrinsicwidth
else:
displacement -= intrinsicwidth
- if FeynDiagram.options.DEBUG:
+ if options.options.DEBUG:
print "Displacement = ", displacement
## Position the arrow on the right hand side of lines
tangent = p.tangent(posparam, displacement)
normal = tangent.transformed(pyx.trafo.rotate(90, x, y))
nx, ny = normal.atend()
nxcm, nycm = pyx.unit.tocm(nx - x), pyx.unit.tocm(ny - y)
vx, vy = p.atbegin()
vxcm, vycm = pyx.unit.tocm(x - vx), pyx.unit.tocm(y - vy)
## If the arrow is on the left, flip it by 180 degrees
if (vxcm * nycm - vycm * nxcm) > 0:
normal = normal.transformed(pyx.trafo.rotate(180, x, y))
nx, ny = normal.atend()
if displacement < 0:
normal = normal.transformed(pyx.trafo.rotate(180, x, y))
nx, ny = normal.atend()
- if FeynDiagram.options.VDEBUG:
+ if options.options.VDEBUG:
FeynDiagram.currentCanvas.stroke(normal)
## Displace the arrow by this normal vector
endx, endy = endx + (nx-x), endy + (ny-y)
arrx, arry = arrx + (nx-x), arry + (ny-y)
if self.sense<0.:
arrx, arry, endx, endy = endx, endy, arrx, arry
linepath = pyx.deco.decoratedpath(
pyx.path.path(pyx.path.moveto(endx,endy),
pyx.path.lineto(arrx,arry)))
styles = [pyx.deco.earrow(size=self.size, angle=self.angle,
constriction=self.constriction)]
canvas.stroke(linepath.path,styles)
## Label
class Label(Visible):
"""General label, unattached to any diagram elements"""
def __init__(self, text, pos=None, x=None, y=None):
self.x, self.y = 0, 0
if x is not None:
self.x = x
if y is not None:
self.y = y
self.size = pyx.text.size.normalsize
self.text = text
self.textattrs = []
self.pos = pos
## Add this to the current diagram automatically
FeynDiagram.currentDiagram.add(self)
def draw(self, canvas):
"""Draw this label on the supplied canvas."""
textattrs = pyx.attr.mergeattrs([pyx.text.halign.center,
pyx.text.vshift.mathaxis,
self.size] + self.textattrs)
t = pyx.text.defaulttexrunner.text(self.x, self.y, self.text, textattrs)
canvas.insert(t)
## PointLabel
class PointLabel(Label):
"""Label attached to points on the diagram"""
def __init__(self, point, text, displace=0.3, angle=0):
self.size = pyx.text.size.normalsize
self.displace = pyx.unit.length(displace)
self.angle = angle
self.text = text
self.point = point
self.textattrs = []
def getPoint(self):
"""Get the point associated with this label."""
return self.point
def setPoint(self, point):
"""Set the point associated with this label."""
self.point = point
return self
def draw(self, canvas):
"""Draw this label on the supplied canvas."""
- if FeynDiagram.options.VDEBUG:
+ if options.options.VDEBUG:
canvas.fill(pyx.path.circle(self.point.getX(),
self.point.getY(), 0.05), [pyx.color.rgb.green])
x = self.point.getX() + self.displace * math.cos(math.radians(self.angle))
y = self.point.getY() + self.displace * math.sin(math.radians(self.angle))
textattrs = pyx.attr.mergeattrs([pyx.text.halign.center,
pyx.text.vshift.mathaxis,
self.size] + self.textattrs)
t = pyx.text.defaulttexrunner.text(x, y, self.text, textattrs)
canvas.insert(t)
## LineLabel
class LineLabel(Label):
"""Label for Feynman diagram lines"""
def __init__(self, line, text, pos=0.5, displace=0.3, angle=0):
self.pos = pos
self.size = pyx.text.size.normalsize
self.displace = pyx.unit.length(displace)
self.angle = angle
self.text = text
self.line = line
self.textattrs = []
def getLine(self):
"""Get the associated line."""
return self.line
def setLine(self, line):
"""Set the associated line."""
self.line = line
return self
def draw(self, canvas):
"""Draw this label on the supplied canvas."""
p = self.line.getPath()
#x, y = self.line.fracPoint(self.pos).getXY()
posparam = p.begin() + self.pos * p.arclen()
x, y = p.at(posparam)
## Calculate the displacement from the line
displacement = self.displace
intrinsicwidth = pyx.unit.length(0.1)
if hasattr(self.line, "arcradius"):
intrinsicwidth = self.line.arcradius
if displacement > 0:
displacement += intrinsicwidth
else:
displacement -= intrinsicwidth
- if FeynDiagram.options.DEBUG:
+ if options.options.DEBUG:
print "Displacement = ", displacement
## Position the label on the right hand side of lines
tangent = p.tangent(posparam, displacement)
normal = tangent.transformed(pyx.trafo.rotate(90, x, y))
nx, ny = normal.atend()
nxcm, nycm = pyx.unit.tocm(nx - x), pyx.unit.tocm(ny - y)
vx, vy = p.atbegin()
vxcm, vycm = pyx.unit.tocm(x - vx), pyx.unit.tocm(y - vy)
## If the label is on the left, flip it by 180 degrees
if (vxcm * nycm - vycm * nxcm) > 0:
normal = normal.transformed(pyx.trafo.rotate(180, x, y))
nx, ny = normal.atend()
if displacement < 0:
normal = normal.transformed(pyx.trafo.rotate(180, x, y))
nx, ny = normal.atend()
- if FeynDiagram.options.VDEBUG:
+ if options.options.VDEBUG:
FeynDiagram.currentCanvas.stroke(normal)
## Displace the label by this normal vector
x, y = nx, ny
textattrs = pyx.attr.mergeattrs([pyx.text.halign.center,
pyx.text.vshift.mathaxis,
self.size] + self.textattrs)
t = pyx.text.defaulttexrunner.text(x, y, self.text, textattrs)
#t.linealign(self.displace,
# math.cos(self.angle * math.pi/180),
# math.sin(self.angle * math.pi/180))
canvas.insert(t)
Property changes on: pyfeyn/trunk/pyfeyn/deco.py
___________________________________________________________________
Added: svn:keywords
## -0,0 +1 ##
+Id Date
\ No newline at end of property
Index: pyfeyn/trunk/pyfeyn/feynml.py
===================================================================
--- pyfeyn/trunk/pyfeyn/feynml.py (revision 1923)
+++ pyfeyn/trunk/pyfeyn/feynml.py (revision 1924)
Property changes on: pyfeyn/trunk/pyfeyn/feynml.py
___________________________________________________________________
Added: svn:keywords
## -0,0 +1 ##
+Id Date
\ No newline at end of property
Index: pyfeyn/trunk/pyfeyn/lines.py
===================================================================
--- pyfeyn/trunk/pyfeyn/lines.py (revision 1923)
+++ pyfeyn/trunk/pyfeyn/lines.py (revision 1924)
@@ -1,946 +1,947 @@
"""Various particle line types."""
import pyx, math
from pyx import color
from pyfeyn.diagrams import FeynDiagram
from pyfeyn.points import Point
from pyfeyn.deco import Arrow, ParallelArrow, LineLabel
from pyfeyn.utils import Visible, defunit
+from pyfeyn import options
## Line base class
class Line(Visible):
"Base class for all objects which connect points in Feynman diagrams"
def __init__(self, point1, point2):
self.p1 = point1
self.p2 = point2
self.styles = []
self.arcthrupoint = None
self.is3D = False
self.arrows = []
self.labels = []
## Add this to the current diagram automatically
FeynDiagram.currentDiagram.add(self)
def addLabel(self, text, pos=0.5, displace=-0.25, angle = 0):
"""Add a LaTeX label to this line, either via parameters or actually as
a TeXLable object."""
- if FeynDiagram.options.DEBUG:
+ if options.options.DEBUG:
print "Adding label: " + text
#if text.__class__ == "Label":
# self.labels.append(label)
#else:
self.labels.append(LineLabel(text=text, line=self, pos=pos, displace=displace, angle=angle))
- if FeynDiagram.options.DEBUG:
+ if options.options.DEBUG:
print "Labels = " + str(self.labels)
return self
def addParallelArrow(self, pos=0.5, displace=0.3, length=0.5*pyx.unit.v_cm,
size=6*pyx.unit.v_pt, angle=45, constriction=0.8, sense=+1):
self.labels.append(ParallelArrow(self, pos=pos, displace=displace,
length=length, size=size, angle=angle,
constriction=constriction,
sense=sense))
return self
def removeLabels(self):
"""Remove the labels from this line."""
self.labels = []
return self
def fracpoint(self, frac):
"""
Get a new Point representing the point at the given fraction along
the fundamental line (i.e. no truncation or deformation).
TODO: Handle units properly.
"""
p = self.getPath() ## no truncation or deformation
x, y = p.at(p.begin() + frac * p.arclen())
return Point(x/defunit, y/defunit)
def setArrows(self, arrows):
"""Define the arrows on this line."""
## TODO: Check that the arg is a list
self.arrows = []
for i in arrows:
if i.__class__ == "deco.Arrow":
self.arrows.append(i)
else:
self.arrows.append(Arrow(pos = i))
return self
def addArrow(self, position = 0.53, arrow = None):
"""Add an arrow to the line at the specified position, which is a number
between 0 and 1, representing the fraction along the line at which the
arrow should be placed. The default arrow style can be overridden by
explicitly supplying an arrow object as the 'arrow' argument, in which
case the position argument will be ignored."""
if arrow:
self.arrows.append(arrow)
else:
self.arrows.append(Arrow(pos=position))
return self
def removeArrows(self):
"""Remove all arrows from this line."""
self.arrows = []
return self
def arcThru(self, arcpoint = None, x = None, y = None):
"""Set the point through which this line will arc. Either pass a Point
or set x, y as floats."""
if arcpoint is not None:
self.arcthrupoint = arcpoint
elif x is not None and y is not None:
self.arcthrupoint = Point(x, y)
else:
raise Exception("Tried to set an arcpoint with invalid arguments")
return self
def straighten(self):
"""Make this line a straight line between start and end."""
self.arcthrupoint = None
def bend(self, amount):
"""Bend the line to the right by a given distance."""
middle = self.p1.midpoint(self.p2)
nx = (middle.y() - self.p1.y()) / abs(self.p1.distance(middle))
ny = (self.p1.x() - middle.x()) / abs(self.p1.distance(middle))
vx = middle.x() - self.p1.x()
vy = middle.y() - self.p1.y()
if (vx * ny - vy * nx) > 0:
nx *= -1
ny *= -1
arcpoint = Point(middle.x() + amount * nx, middle.y() + amount * ny)
- if FeynDiagram.options.VDEBUG:
+ if options.options.VDEBUG:
FeynDiagram.currentCanvas.stroke(
pyx.path.line(middle.x(), middle.y(), arcpoint.x(),
arcpoint.y()), [color.rgb.blue] )
self.arcThru(arcpoint)
- if FeynDiagram.options.DEBUG:
+ if options.options.DEBUG:
print self.getVisiblePath()
- if FeynDiagram.options.VDEBUG:
+ if options.options.VDEBUG:
FeynDiagram.currentCanvas.stroke(self.getVisiblePath(), [color.rgb.blue])
return self
def set3D(self, choice):
"""Make this line display in '3D'."""
self.is3D = choice
return self
def getStyles(self, stylelist):
"""Get the styles associated with this line."""
return self.styles
def setStyles(self, stylelist):
"""Set the styles associated with this line."""
self.styles = stylelist
return self
def addStyle(self, style):
"""Add a style to this line."""
self.styles.append(style)
return self
def addStyles(self, stylelist):
"""Add some styles to this line."""
self.styles = self.styles + stylelist
return self
def getPath(self):
"""Get the path taken by this line."""
if self.arcthrupoint is None:
## This is a simple straight line
return pyx.path.path( pyx.path.moveto( *(self.p1.getXY()) ),
pyx.path.lineto( *(self.p2.getXY()) ) )
elif (self.p1.x() == self.p2.x() and self.p1.y() == self.p2.y()):
## This is a tadpole-type loop and needs special care;
## We shall assume that the arcthrupoint is meant to be
## the antipode of the basepoint
arccenter = self.p1.midpoint(self.arcthrupoint)
arcradius = self.p1.distance(self.arcthrupoint) / 2.0
## TODO Why does a circle work and an arc doesn't?
cargs = (arccenter.x(), arccenter.y(), arcradius)
circle = pyx.path.circle(*cargs)
line = pyx.path.line( self.p1.x(), self.p1.y(), arccenter.x(), arccenter.y())
- if FeynDiagram.options.VDEBUG:
+ if options.options.VDEBUG:
FeynDiagram.currentCanvas.stroke(line, [color.rgb.green])
as, bs = circle.intersect(line)
subpaths = circle.split(as[0])
cpath = subpaths[0]
return cpath
## or, with an arc...
arcangle1 = arccenter.arg(self.p1)
arcangle2 = arccenter.arg(self.p1) + 360
arcargs = (arccenter.x(), arccenter.y(), arcradius, arcangle1, arcangle2)
return pyx.path.path( pyx.path.arc(*arcargs) )
else:
n13, n23 = None, None
## Work out line gradients
try:
n13 = (self.p1.y() - self.arcthrupoint.y()) / (self.p1.x() - self.arcthrupoint.x())
except ZeroDivisionError:
- if FeynDiagram.options.DEBUG:
+ if options.options.DEBUG:
print "Grad 1 diverges"
n13 = 1e100
try:
n23 = (self.p2.y() - self.arcthrupoint.y()) / (self.p2.x() - self.arcthrupoint.x())
except ZeroDivisionError:
- if FeynDiagram.options.DEBUG:
+ if options.options.DEBUG:
print "Grad 2 diverges"
n23 = 1e100
## If gradients match,
## then we have a straight line, so bypass the complexity
if n13 == n23:
return pyx.path.path( pyx.path.moveto(*(self.p1.getXY())),
pyx.path.lineto(*(self.p2.getXY())) )
## Otherwise work out conjugate gradients and midpoints
m13, m23 = None, None
try:
m13 = -1.0 / n13
except ZeroDivisionError:
m13 = 1e100
try:
m23 = -1.0 / n23
except ZeroDivisionError:
m23 = 1e100
mid13 = self.p1.midpoint(self.arcthrupoint)
mid23 = self.p2.midpoint(self.arcthrupoint)
## Line y-intercepts
c13 = mid13.y() - m13 * mid13.x()
c23 = mid23.y() - m23 * mid23.x()
## Find the centre of the arc
xcenter = - (c23 - c13) / (m23 - m13)
ycenter = m13 * xcenter + c13
arccenter = Point(xcenter, ycenter)
## Get the angles required for drawing the arc
arcradius = arccenter.distance(self.arcthrupoint)
arcangle1 = arccenter.arg(self.p1)
arcangle2 = arccenter.arg(self.p2)
arcangle3 = arccenter.arg(self.arcthrupoint)
arcargs = (arccenter.x(), arccenter.y(), arcradius, arcangle1, arcangle2)
- if FeynDiagram.options.DEBUG and arcangle1 == arcangle2:
+ if options.options.DEBUG and arcangle1 == arcangle2:
print "Arc angles are the same - not drawing anything"
## Calculate cross product to determine direction of arc
vec12 = [self.p2.x()-self.p1.x(), self.p2.y()-self.p1.y(), 0.0]
vec13 = [self.arcthrupoint.x()-self.p1.x(), self.arcthrupoint.y()-self.p1.y(), 0.0]
crossproductZcoord = vec12[0]*vec13[1] - vec12[1]*vec13[0]
if crossproductZcoord < 0:
return pyx.path.path( pyx.path.moveto(*(self.p1.getXY())),
pyx.path.arc(*arcargs))
else:
return pyx.path.path( pyx.path.moveto(*(self.p1.getXY())),
pyx.path.arcn(*arcargs))
def getVisiblePath(self):
"""Find the subpath between the endpoints which isn't overshadowed by a blob of some kind"""
p1path = self.p1.getPath()
p2path = self.p2.getPath()
vispath = self.getPath()
- if FeynDiagram.options.VDEBUG:
+ if options.options.VDEBUG:
FeynDiagram.currentCanvas.stroke(vispath, [color.rgb.green])
if p1path:
as, bs = p1path.intersect(vispath)
for b in bs:
subpaths = vispath.split(b)
if len(subpaths) > 1:
- if FeynDiagram.options.DEBUG:
+ if options.options.DEBUG:
print "Num subpaths 1 = %d" % len(subpaths)
subpaths.sort(
lambda x, y :
int(pyx.unit.tocm(x.arclen() - y.arclen()) /
math.fabs(pyx.unit.tocm(x.arclen() - y.arclen()))) )
vispath = subpaths[-1]
- if FeynDiagram.options.VDEBUG:
+ if options.options.VDEBUG:
FeynDiagram.currentCanvas.stroke(subpaths[0], [color.rgb.blue])
- if FeynDiagram.options.VDEBUG:
+ if options.options.VDEBUG:
for a in as:
ix, iy = p1path.at(a)
FeynDiagram.currentCanvas.fill(pyx.path.circle(ix, iy, 0.05),
[color.rgb.green])
if p2path:
as, bs = p2path.intersect(vispath)
for b in bs:
subpaths = vispath.split(b)
if len(subpaths) > 1:
- if FeynDiagram.options.DEBUG:
+ if options.options.DEBUG:
print "Num subpaths 2 = %d" % len(subpaths)
subpaths.sort(
lambda x, y :
int(pyx.unit.tocm(x.arclen() - y.arclen()) /
math.fabs(pyx.unit.tocm(x.arclen() - y.arclen()))) )
vispath = subpaths[-1]
- if FeynDiagram.options.VDEBUG:
+ if options.options.VDEBUG:
FeynDiagram.currentCanvas.stroke(subpaths[0], [color.rgb.red])
- if FeynDiagram.options.VDEBUG:
+ if options.options.VDEBUG:
for a in as:
ix, iy = p2path.at(a)
FeynDiagram.currentCanvas.fill(pyx.path.circle(ix, iy, 0.05),
[color.rgb.blue])
- if FeynDiagram.options.VDEBUG:
+ if options.options.VDEBUG:
FeynDiagram.currentCanvas.stroke(vispath, [color.rgb.red])
#return pyx.path.circle(-2,-1,0.2)
return vispath
def draw(self, canvas):
"""Drwa this line on the given canvas."""
path = self.getVisiblePath()
styles = self.styles + self.arrows
- if FeynDiagram.options.DEBUG:
+ if options.options.DEBUG:
print "Drawing " + str(self.__class__) + " with styles = " + str(styles)
print path
canvas.stroke(path, styles)
for l in self.labels:
l.draw(canvas)
## Fermion is an alias for Line
Fermion = Line
class MultiLine(Line):
"""A class for drawing multiple parallel straight lines."""
def __init__(self, point1, point2, n=5, dist=0.2):
self.p1 = point1
self.p2 = point2
self.styles = []
self.arcthrupoint = None
self.is3D = False
self.arrows = []
self.labels = []
self.n = n
self.dist = dist
## Add this to the current diagram automatically
FeynDiagram.currentDiagram.add(self)
def draw(self, canvas):
"""Draw this multiline on the supplied canvas."""
dist = self.dist
n = self.n
path = pyx.deformer.parallel(-n/2.0 * dist).deform(self.getPath())
paths = [path]
defo = pyx.deformer.parallel(dist)
for m in range(0, n):
path = defo.deform(path)
paths.append(path)
styles = self.styles + self.arrows
for p in paths:
canvas.stroke(p, styles)
class Scalar(Line):
"""A scalar particle line, like a Higgs boson."""
def draw(self, canvas):
"""Draw this scalar line on the given canvas."""
path = self.getVisiblePath()
styles = self.styles + [pyx.style.linestyle.dashed] + self.arrows
## TODO: call base class method?
- if FeynDiagram.options.DEBUG:
+ if options.options.DEBUG:
print "Drawing " + str(self.__class__) + " with styles = " + str(styles)
print path
canvas.stroke(path, styles)
for l in self.labels:
l.draw(canvas)
## Higgs is an alias for Scalar
Higgs = Scalar
## Sfermion is also an alias for Scalar
Sfermion = Scalar
## DecoratedLine base class
class DecoratedLine(Line):
"""Base class for spring and sine-like lines"""
def invert(self):
"""Reflect the line decoration about the line."""
pass
def getNumHalfCycles(self):
"""Get the number of half cycles in this line."""
pass
def getDeformedPath(self):
"""Get the deformed path."""
return getVisiblePath()
class Gluon(DecoratedLine):
"""A line with a cycloid deformation"""
def __init__(self, point1, point2):
self.p1 = point1
self.p2 = point2
self.styles = []
self.arcthrupoint = None
self.is3D = False
self.skipsize3D = pyx.unit.length(0.04)
self.parity3D = 0
self.arrows = []
self.labels = []
self.arcradius = pyx.unit.length(0.25)
self.frequency = 1.3
self.extras = 0
self.inverted = False
self.linetype = "gluon"
## Add this to the current diagram automatically
FeynDiagram.currentDiagram.add(self)
def set3D(self, is3D=True, skipsize=pyx.unit.length(0.04), parity=0):
self.is3D = is3D
self.skipsize3D = skipsize
self.parity3D = parity
return self
def invert(self):
"""Flip the line decoration around the line."""
self.inverted = not self.inverted
return self
def getFrequency(self):
"""Get the rate of occurence of the coil decoration."""
return self.frequency
def setFrequency(self, freq):
"""Set the rate of occurence of the coil decoration."""
self.frequency = freq
return self
def getAmplitude(self):
"""Get the radius of the coil decoration."""
return self.arcradius
def setAmplitude(self, amplitude):
"""Set the radius of the coil decoration."""
self.arcradius = amplitude
return self
def setExtraCycles(self, extras):
"""Add some extra (possibly negative) oscillations to the coil decoration."""
self.extras = extras
return self
def getDeformedPath(self):
"""Get the path modified by the coil warping."""
needwindings = self.frequency * \
pyx.unit.tocm(self.getVisiblePath().arclen()) / \
pyx.unit.tocm(self.arcradius)
## Get the whole number of windings and make sure that it's odd so we
## don't get a weird double-back thing
intwindings = int(needwindings)
intwindings += 2 * self.extras
if intwindings % 2 == 0:
intwindings -= 1
deficit = needwindings - intwindings
sign = 1
if self.inverted: sign = -1
defo = pyx.deformer.cycloid(self.arcradius, intwindings, curvesperhloop=10,
skipfirst = 0.0, skiplast = 0.0, sign = sign)
return defo.deform(self.getVisiblePath())
def draw(self, canvas):
"""Draw the line on the supplied canvas."""
styles = self.styles + self.arrows
- if FeynDiagram.options.DEBUG:
+ if options.options.DEBUG:
print "Drawing " + str(self.__class__) + " with styles = " + str(styles)
mypath = self.getDeformedPath()
- if FeynDiagram.options.DRAFT or not self.is3D:
+ if options.options.DRAFT or not self.is3D:
canvas.stroke(mypath, styles)
else:
para = pyx.deformer.parallel(0.001)
as, bs, cs = para.normpath_selfintersections(mypath.normpath(), epsilon=0.01)
coil_params = []
for b in bs:
coil_params.append(b[self.parity3D] - self.skipsize3D)
coil_params.append(b[self.parity3D] + self.skipsize3D)
pathbits = mypath.split(coil_params)
on = True
for pathbit in pathbits:
if on:
canvas.stroke(pathbit, styles)
on = not on
## Labels
for l in self.labels:
l.draw(canvas)
class Vector(DecoratedLine):
"""A line with a sinoid deformation"""
def __init__(self, point1, point2, amplitude=0.25, frequency=1.0):
self.p1 = point1
self.p2 = point2
self.styles = []
self.arcthrupoint = None
self.is3D = False
self.arrows = []
self.labels = []
self.inverted = False
self.arcradius = amplitude #pyx.unit.length(0.25)
self.linetype = "photon"
self.frequency = frequency
self.extrahalfs = 0
## Add this to the current diagram automatically
FeynDiagram.currentDiagram.add(self)
def invert(self):
"""Reflect the decoration in the line itself."""
self.inverted = not self.inverted
return self
def getFrequency(self):
"""Get the rate of occurance of the oscillation."""
return self.frequency
def setFrequency(self, freq):
"""Set the rate of occurance of the oscillation."""
self.frequency = freq
return self
def getAmplitude(self):
"""Get the size of the oscillation."""
return self.arcradius
def setAmplitude(self, amplitude):
"""Set the size of the oscillation."""
self.arcradius = amplitude
return self
def setExtraHalfCycles(self, extras):
"""Add some extra half cycles to the oscillation on top of those
determined from the frequency."""
self.extrahalfs = extras
return self
def getDeformedPath(self):
"""Get the path with the decorative deformation."""
intwindings = int(self.frequency * pyx.unit.tocm(self.getVisiblePath().arclen()) /
pyx.unit.tocm(self.arcradius))
intwindings += self.extrahalfs
sign = 1
if self.inverted: sign = -1
defo = pyx.deformer.cycloid(self.arcradius, intwindings, curvesperhloop=5,
skipfirst=0.0, skiplast=0.0, turnangle=0, sign=sign)
return defo.deform(self.getVisiblePath())
def draw(self, canvas):
"""Draw the line on the supplied canvas."""
styles = self.styles + self.arrows
- if FeynDiagram.options.DEBUG:
+ if options.options.DEBUG:
print "Drawing " + str(self.__class__) + " with styles = " + str(styles)
canvas.stroke(self.getDeformedPath(), styles)
for l in self.labels:
l.draw(canvas)
## Photon is an alias for Vector
Photon = Vector
class Graviton(DecoratedLine):
"""A line with a double sinoid deformation"""
def __init__(self, point1, point2):
self.p1 = point1
self.p2 = point2
self.styles = []
self.arcthrupoint = None
self.is3D = False
self.skipsize3D = pyx.unit.length(0.04)
self.parity3D = 0
self.inverted = False
self.arrows = []
self.labels = []
self.arcradius = pyx.unit.length(0.25)
self.linetype = "graviton"
## Add this to the current diagram automatically
FeynDiagram.currentDiagram.add(self)
def set3D(self, is3D=True, skipsize=pyx.unit.length(0.04), parity=0):
self.is3D = is3D
self.skipsize3D = skipsize
self.parity3D = parity
return self
def invert(self):
"""Reflect the decoration in the line itself."""
self.inverted = not self.inverted
return self
def getDeformedPath(self, sign = 1):
"""Get the path with the decorative deformation."""
intwindings = int(0.6 * pyx.unit.tocm(self.getVisiblePath().arclen()) /
pyx.unit.tocm(self.arcradius))
vispath = self.getVisiblePath()
curvatures = vispath.curveradius([i/10.0 for i in range(0,11)])
maxcurvature = None
for curvature in curvatures:
if curvature is not None:
curvature = abs(curvature/pyx.unit.m)
- #if FeynDiagram.options.DEBUG:
+ #if options.options.DEBUG:
# print self.__class__, "- curvature = ", curvature
if (maxcurvature is None or curvature > maxcurvature):
maxcurvature = curvature
numhloopcurves = 5 + int(0.1/maxcurvature)
- if FeynDiagram.options.DEBUG:
+ if options.options.DEBUG:
print self.__class__, "- max curvature = ", maxcurvature, "->", numhloopcurves, "curves/hloop"
defo = pyx.deformer.cycloid(self.arcradius, intwindings, curvesperhloop=numhloopcurves,
skipfirst=0.0, skiplast=0.0, turnangle=0, sign=sign)
return defo.deform(vispath)
def draw(self, canvas):
"""Draw the line on the supplied canvas."""
styles = self.styles + self.arrows
- if FeynDiagram.options.DEBUG:
+ if options.options.DEBUG:
print "Drawing " + str(self.__class__) + " with styles = " + str(styles)
mypath1 = self.getDeformedPath(+1)
mypath2 = self.getDeformedPath(-1)
if self.inverted:
mypathtmp = mypath1
mypath1 = mypath2
mypath2 = mypathtmp
- if FeynDiagram.options.DRAFT or not self.is3D:
+ if options.options.DRAFT or not self.is3D:
canvas.stroke(mypath1, styles)
canvas.stroke(mypath2, styles)
else:
as, bs = mypath1.intersect(mypath2)
params1, params2 = [], []
parity1 = True
if self.parity3D == 0:
parity1 = False
for a in as[1:]: ## TODO: better endpoint cut vetoing
if parity1:
params1.append(a - self.skipsize3D)
params1.append(a + self.skipsize3D)
parity1 = not parity1
pathbits1 = mypath1.split(params1)
on = True
for pathbit in pathbits1:
if on:
canvas.stroke(pathbit, styles)
on = not on
parity2 = False
if self.parity3D == 0:
parity2 = True
for b in bs[1:]: ## TODO: better endpoint cut vetoing
if parity2:
params2.append(b - self.skipsize3D)
params2.append(b + self.skipsize3D)
parity2 = not parity2
pathbits2 = mypath2.split(params2)
on = True
for pathbit in pathbits2:
if on:
canvas.stroke(pathbit, styles)
on = not on
for l in self.labels:
l.draw(canvas)
class Gaugino(DecoratedLine):
"""A line with a sinoid deformation and a normal line"""
def __init__(self, point1, point2):
self.p1 = point1
self.p2 = point2
self.styles = []
self.arcthrupoint = None
self.is3D = False
self.skipsize3D = pyx.unit.length(0.04)
self.parity3D = 0
self.inverted = False
self.arrows = []
self.labels = []
self.arcradius = pyx.unit.length(0.25)
self.linetype = "gaugino"
## Add this to the current diagram automatically
FeynDiagram.currentDiagram.add(self)
def set3D(self, is3D=True, skipsize=pyx.unit.length(0.04), parity=0):
"""Make the line look 3-dimensional by 'cutting' one line where self-intersections occur."""
self.is3D = is3D
self.skipsize3D = skipsize
self.parity3D = parity
return self
def invert(self):
"""Reflect the decoration in the line itself."""
self.inverted = not self.inverted
return self
def getDeformedPath(self):
"""Get the path with the decorative deformation."""
intwindings = int(pyx.unit.tocm(self.getVisiblePath().arclen()) /
pyx.unit.tocm(self.arcradius))
sign = 1
if self.inverted: sign = -1
vispath = self.getVisiblePath()
curvatures = vispath.curveradius([i/10.0 for i in range(0,11)])
maxcurvature = None
for curvature in curvatures:
if curvature is not None:
curvature = abs(curvature/pyx.unit.m)
- #if FeynDiagram.options.DEBUG:
+ #if options.options.DEBUG:
# print self.__class__, "- curvature = ", curvature
if (maxcurvature is None or curvature > maxcurvature):
maxcurvature = curvature
numhloopcurves = 5 + int(0.1/maxcurvature)
- if FeynDiagram.options.DEBUG:
+ if options.options.DEBUG:
print self.__class__, "- max curvature = ", maxcurvature, "->", numhloopcurves, "curves/hloop"
defo = pyx.deformer.cycloid(self.arcradius, intwindings, curvesperhloop=numhloopcurves,
skipfirst=0.0, skiplast=0.0, turnangle=0, sign=sign)
return defo.deform(vispath)
def draw(self, canvas):
"""Draw the line on the supplied canvas."""
styles = self.styles + self.arrows
- if FeynDiagram.options.DEBUG:
+ if options.options.DEBUG:
print "Drawing " + str(self.__class__) + " with styles = " + str(styles)
mypath1 = self.getVisiblePath()
mypath2 = self.getDeformedPath()
- if FeynDiagram.options.DRAFT or not self.is3D:
+ if options.options.DRAFT or not self.is3D:
canvas.stroke(mypath1, styles)
canvas.stroke(mypath2, styles)
else:
as, bs = mypath1.intersect(mypath2)
params1, params2 = [], []
parity1 = True
if self.parity3D == 0:
parity1 = False
for a in as:
if parity1:
params1.append(a - self.skipsize3D)
params1.append(a + self.skipsize3D)
parity1 = not parity1
pathbits1 = mypath1.split(params1)
on = True
for pathbit in pathbits1:
if on:
canvas.stroke(pathbit, styles)
on = not on
parity2 = False
if self.parity3D == 0:
parity2 = True
for b in bs:
if parity2:
params2.append(b - self.skipsize3D)
params2.append(b + self.skipsize3D)
parity2 = not parity2
pathbits2 = mypath2.split(params2)
on = True
for pathbit in pathbits2:
if on:
canvas.stroke(pathbit, styles)
on = not on
for l in self.labels:
l.draw(canvas)
class Gluino(DecoratedLine):
"""A line with a cycloid deformation and a normal line"""
def __init__(self, point1, point2):
self.p1 = point1
self.p2 = point2
self.styles = []
self.arcthrupoint = None
self.is3D = False
self.skipsize3D = pyx.unit.length(0.04)
self.parity3D = 0
self.inverted = False
self.arrows = []
self.labels = []
self.arcradius = pyx.unit.length(0.25)
self.linetype = "susygluon"
## Add this to the current diagram automatically
FeynDiagram.currentDiagram.add(self)
def set3D(self, is3D=True, skipsize=pyx.unit.length(0.04), parity=0):
self.is3D = is3D
self.skipsize3D = skipsize
self.parity3D = parity
return self
def invert(self):
"""Reflect the decoration in the line itself."""
self.inverted = not self.inverted
return self
def getDeformedPath(self):
"""Get the path with the decorative deformation."""
needwindings = 1.2 * \
pyx.unit.tocm(self.getVisiblePath().arclen()) / \
pyx.unit.tocm(self.arcradius)
## Get the whole number of windings and make sure that it's odd so we
## don't get a weird double-back thing
intwindings = int(needwindings)
if intwindings % 2 == 0:
intwindings -= 1
deficit = needwindings - intwindings
sign = 1
if self.inverted: sign = -1
vispath = self.getVisiblePath()
curvatures = vispath.curveradius([i/10.0 for i in range(0,11)])
maxcurvature = None
for curvature in curvatures:
if curvature is not None:
curvature = abs(curvature/pyx.unit.m)
- #if FeynDiagram.options.DEBUG:
+ #if options.options.DEBUG:
# print self.__class__, "- curvature = ", curvature
if (maxcurvature is None or curvature > maxcurvature):
maxcurvature = curvature
numhloopcurves = 10 + int(0.2/maxcurvature)
- if FeynDiagram.options.DEBUG:
+ if options.options.DEBUG:
print self.__class__, "- max curvature = ", maxcurvature, "->", numhloopcurves, "curves/hloop"
defo = pyx.deformer.cycloid(self.arcradius, intwindings, curvesperhloop=numhloopcurves,
skipfirst=0.0, skiplast=0.0, sign=sign)
return defo.deform(vispath)
def draw(self, canvas):
"""Draw the line on the supplied canvas."""
styles = self.styles + self.arrows
- if FeynDiagram.options.DEBUG:
+ if options.options.DEBUG:
print "Drawing " + str(self.__class__) + " with styles = " + str(styles)
mypath1 = self.getVisiblePath()
mypath2 = self.getDeformedPath()
- if FeynDiagram.options.DRAFT or not self.is3D:
+ if options.options.DRAFT or not self.is3D:
canvas.stroke(mypath1, styles)
canvas.stroke(mypath2, styles)
else:
as, bs = mypath1.intersect(mypath2)
params1, params2 = [], []
parity1 = True
if self.parity3D == 0:
parity1 = False
for a in as:
if parity1:
params1.append(a - self.skipsize3D)
params1.append(a + self.skipsize3D)
parity1 = not parity1
pathbits1 = mypath1.split(params1)
on = True
for pathbit in pathbits1:
if on:
canvas.stroke(pathbit, styles)
on = not on
parity2 = False
if self.parity3D == 0:
parity2 = True
for b in bs:
if parity2:
params2.append(b - self.skipsize3D)
params2.append(b + self.skipsize3D)
parity2 = not parity2
para = pyx.deformer.parallel(0.001)
sas, sbs, scs = para.normpath_selfintersections(mypath2.normpath(), epsilon=0.01)
coil_params = []
for b in sbs:
coil_params.append(b[self.parity3D] - self.skipsize3D)
coil_params.append(b[self.parity3D] + self.skipsize3D)
params2 += coil_params
params2.sort()
pathbits2 = mypath2.split(params2)
on = True
for pathbit in pathbits2:
if on:
canvas.stroke(pathbit, styles)
on = not on
for l in self.labels:
l.draw(canvas)
# A dictionary for mapping FeynML line types to line classes
NamedLine = { "higgs" : Higgs,
"photon" : Photon,
"gluon" : Gluon,
"fermion" : Fermion,
"graviton" : Graviton,
"gaugino" : Gaugino,
"gluino" : Gluino }
Property changes on: pyfeyn/trunk/pyfeyn/lines.py
___________________________________________________________________
Added: svn:keywords
## -0,0 +1 ##
+Id Date
\ No newline at end of property
Index: pyfeyn/trunk/pyfeyn/options.py
===================================================================
--- pyfeyn/trunk/pyfeyn/options.py (revision 0)
+++ pyfeyn/trunk/pyfeyn/options.py (revision 1924)
@@ -0,0 +1,33 @@
+"""Handle runtime options and command line option parsing."""
+
+from optparse import OptionParser
+
+
+def addPyfeynOptions(parser):
+ parser.add_option("-V", "--visual-debug", dest="VDEBUG", action = "store_true",
+ default = False, help="produce visual debug output")
+ parser.add_option("-D", "--debug", dest="DEBUG", action = "store_true",
+ default = False, help="produce debug output")
+ parser.add_option("-d", "--draft", dest="DRAFT", action = "store_true",
+ default = False, help="produce draft output, skipping time-consuming calculations")
+ return parser
+
+
+def processOptions(parser=None):
+ if parser is None:
+ parser = OptionParser()
+ addOptions(parser)
+ (_options, _args) = parser.parse_args()
+ options = _options
+ return _options, _args
+
+
+class OptionSet:
+ """A container for options."""
+ def __init__(self):
+ self.DEBUG = None
+ self.VDEBUG = None
+ self.DRAFT = None
+
+
+options = OptionSet()
Property changes on: pyfeyn/trunk/pyfeyn/options.py
___________________________________________________________________
Added: svn:keywords
## -0,0 +1 ##
+Id Date
\ No newline at end of property
Index: pyfeyn/trunk/pyfeyn/paint.py
===================================================================
--- pyfeyn/trunk/pyfeyn/paint.py (revision 1923)
+++ pyfeyn/trunk/pyfeyn/paint.py (revision 1924)
Property changes on: pyfeyn/trunk/pyfeyn/paint.py
___________________________________________________________________
Added: svn:keywords
## -0,0 +1 ##
+Id Date
\ No newline at end of property
Index: pyfeyn/trunk/pyfeyn/points.py
===================================================================
--- pyfeyn/trunk/pyfeyn/points.py (revision 1923)
+++ pyfeyn/trunk/pyfeyn/points.py (revision 1924)
@@ -1,286 +1,287 @@
"""Various types of points for vertices etc."""
import pyx
from copy import copy
import math
from pyfeyn.diagrams import FeynDiagram
from pyfeyn.utils import Visible
from pyfeyn.deco import PointLabel
+from pyfeyn import options
def midpoint(point1, point2):
"Return the point midway between this point and the argument."
return Point( (point1.getX() + point2.getX()) / 2.0,
(point1.getY() + point2.getY()) / 2.0 )
def distance(point1, point2):
"Calculate the distance between this point and the argument."
return math.hypot(point1.x()-point2.x(), point1.y()-point2.y())
## Point base class
class Point:
"""Base class for all pointlike objects in Feynman diagrams."""
def __init__(self, x, y, blob = None):
self.setXY(x, y)
self.setBlob(blob)
self.labels = []
def addLabel(self, text, displace=0.3, angle = 0):
"""Add a LaTeX label to this point, either via parameters or actually as
a PointLable object."""
- if FeynDiagram.options.DEBUG:
+ if options.options.DEBUG:
print "Adding label: " + text
self.labels.append(PointLabel(text=text, point=self, displace=displace, angle=angle))
- if FeynDiagram.options.DEBUG:
+ if options.options.DEBUG:
print "Labels = " + str(self.labels)
return self
def removeLabels(self):
self.labels = []
return self
def draw(self, canvas):
"Do nothing (abstract base class)."
pass
def getPath(self):
"Return the path of the attached blob path, if there is one, otherwise None."
if self.getBlob() and hasattr(self.getBlob(), "getPath"):
return self.getBlob().getPath()
else:
return None
def midpoint(self, otherpoint):
"Return the point midway between this point and the argument."
return midpoint(self, otherpoint)
def distance(self, otherpoint):
"Calculate the distance between this point and the argument."
return distance(self, otherpoint)
def intercept(self, otherpoint):
"Return the y-intercept of the straight line defined by this point and the argument."
return self.y() - self.tangent(otherpoint) * self.x()
def tangent(self,otherpoint):
"Return the tangent of the straight line defined by this point and the argument."
if otherpoint.x() != self.x():
return (otherpoint.y() - self.y()) / (otherpoint.x() - self.x())
else:
return float(10000) ## An arbitrary large number to replace infinity
def arg(self, otherpoint):
"""Return the angle between the x-axis and the straight line defined
by this point and the argument (cf. complex numbers)."""
arg = None
if otherpoint.x() == self.x():
if otherpoint.y() > self.y():
arg = math.pi / 2.0
elif otherpoint.y() < self.y():
arg = 3 * math.pi / 2.0 # this will be reset to 0 if the points are the same
if otherpoint.y() == self.y():
if otherpoint.x() < self.x():
arg = math.pi
else:
arg = 0.0
if otherpoint.x() != self.x() and otherpoint.y() != self.y():
arg = math.atan( (otherpoint.y() - self.y()) / (otherpoint.x() - self.x()) )
if otherpoint.x() < self.x():
arg += math.pi
elif otherpoint.y() < self.y():
arg += 2 * math.pi
## Convert to degrees
argindegs = math.degrees(arg)
return argindegs
def getBlob(self):
"Get the attached blob."
return self.blob
def setBlob(self, blob):
"Set the attached blob."
self.blob = blob
return self
def getX(self):
"Return the x-coordinate of this point."
return self.xpos
def setX(self, x):
"Set the x-coordinate of this point."
self.xpos = x
return self
def getY(self):
"Return the y-coordinate of this point."
return self.ypos
def setY(self, y):
"Set the y-coordinate of this point."
self.ypos = y
return self
def getXY(self):
"Return the x and y coordinates of this point as a 2-tuple."
return self.getX(), self.getY()
def setXY(self, xpos, ypos):
"Set the x and y coordinates of this point."
self.setX(float(xpos))
self.setY(float(ypos))
return self
def x(self):
"Alias for getX()."
return self.getX()
def y(self):
"Alias for getY()."
return self.getY()
def xy(self):
"Alias for getXY()."
return self.getXY()
## Decorated point class
class DecoratedPoint(Point, Visible):
"Class for a point drawn with a marker"
def __init__(self, xpos, ypos,
mark = None,
blob = None,
fill = [pyx.color.rgb.black],
stroke = [pyx.color.rgb.black]):
self.setXY(xpos, ypos)
self.labels = []
self.setMark(copy(mark))
self.setBlob(blob)
self.layeroffset = 1000
self.fillstyles = copy(fill) # lists are mutable --
self.strokestyles = copy(stroke) # hence make a copy!
## Add this to the current diagram automatically
FeynDiagram.currentDiagram.add(self)
def getPath(self):
if self.blob:
return self.getBlob().getPath()
elif self.marker:
return self.getMark().getPath()
else:
return None
def getMark(self):
return self.marker
def setMark(self, mark):
self.marker = mark
if self.marker is not None:
self.marker.setPoint(self)
# if size is None and self.radius == 0: # change shape of a true point?
# self.radius = 4*unit.t_pt # probably want to use default size
return self
def getBlob(self):
return self.blob
def setBlob(self, blob):
self.blob = blob
if self.blob is not None:
self.blob.setPoint(self)
return self
def getFillstyles(self):
return self.fillstyles
def setFillstyles(self, styles):
self.fillstyles = styles
return self
def addFillstyles(self, styles):
self.fillstyles.add(styles)
return self
def addFillstyle(self, style):
self.fillstyles.append(style)
return self
def getStrokestyles(self):
return self.strokestyles
def setStrokestyles(self, styles):
self.strokestyles = styles
return self
def addStrokestyles(self, styles):
self.strokestyles.add(styles)
return self
def addStrokestyle(self, style):
self.strokestyles.append(style)
return self
def draw(self, canvas):
if self.getPath():
canvas.fill(self.getPath(), self.fillstyles)
canvas.stroke(self.getPath(), self.strokestyles)
for l in self.labels:
l.draw(canvas)
## Vertex is an alias for DecoratedPoint
Vertex = DecoratedPoint
class Mark:
def getPoint(self):
return self.point
def setPoint(self, point):
self.point = point
return self
class SquareMark(Mark):
def __init__(self,
size = 0.075):
self.size = size
self.point = None
def getPath(self):
if self.getPoint() is not None:
x, y = self.point.getXY()
return pyx.box.rect(x-self.size, y-self.size, 2*self.size, 2*self.size).path()
return None
class CircleMark(Mark):
def __init__(self,
size = 0.075):
self.radius = size
self.point = None
def getPath(self):
if self.point is not None:
x, y = self.point.getXY()
return pyx.path.circle(x, y, self.radius).path()
return None
## Convenience constants
CIRCLE = CircleMark()
SQUARE = SquareMark()
Property changes on: pyfeyn/trunk/pyfeyn/points.py
___________________________________________________________________
Added: svn:keywords
## -0,0 +1 ##
+Id Date
\ No newline at end of property
Index: pyfeyn/trunk/pyfeyn/user.py
===================================================================
--- pyfeyn/trunk/pyfeyn/user.py (revision 1923)
+++ pyfeyn/trunk/pyfeyn/user.py (revision 1924)
@@ -1,9 +1,10 @@
"""Convenience imports to make things easier for typical users."""
from pyfeyn.diagrams import *
from pyfeyn.points import *
from pyfeyn.lines import *
from pyfeyn.blobs import *
from pyfeyn.deco import *
#from pyfeyn.utils import *
from pyfeyn.paint import *
+from pyfeyn.options import *
Property changes on: pyfeyn/trunk/pyfeyn/user.py
___________________________________________________________________
Added: svn:keywords
## -0,0 +1 ##
+Id Date
\ No newline at end of property
Index: pyfeyn/trunk/pyfeyn/__init__.py
===================================================================
--- pyfeyn/trunk/pyfeyn/__init__.py (revision 1923)
+++ pyfeyn/trunk/pyfeyn/__init__.py (revision 1924)
@@ -1,48 +1,33 @@
"""
-PyFeyn - a simple Python interface for making Feynman
-diagrams (pre-release version >= 0.2.0b1).
+PyFeyn - a simple Python interface for making Feynman diagrams.
"""
__author__ = "Andy Buckley (andy@insectnation.org)"
-__version__ = "0.3.0b3"
-__date__ = "$Date: 2006/08/05 00:14:20 $"
+__version__ = "0.3.0"
+__date__ = "$Date$"
__copyright__ = "Copyright (c) 2007 Andy Buckley"
__license__ = "GPL"
-import pyx
-## Version check
-import re
+## Import PyX and check the version
+import pyx, re
_majorversionstr = re.sub(r"(\d+\.\d+).*", r"\1", pyx.version.version)
if float(_majorversionstr) < 0.9:
print "Warning: PyFeyn may not work with PyX versions older than 0.9!"
## Units
pyx.unit.set(uscale = 4, vscale = 4, wscale = 4, xscale = 4)
pyx.unit.set(defaultunit = "cm")
## TeX stuff
pyx.text.defaulttexrunner.set(mode="latex")
if pyx.pykpathsea.find_file("hepnicenames.sty", pyx.pykpathsea.kpse_tex_format):
pyx.text.defaulttexrunner.preamble(r"\usepackage{hepnicenames}")
else:
print "Warning: hepnames LaTeX package not found!"
## Set __all__ (for "import * from pyfeyn")
-__all__ = ["diagrams", "points", "blobs", "lines", "deco", "utils"]
-
-
-## Option parsing
-from optparse import OptionParser
-_parser = OptionParser()
-_parser.add_option("-V", "--visual-debug", dest="VDEBUG", action = "store_true",
- default = False, help="produce visual debug output")
-_parser.add_option("-D", "--debug", dest="DEBUG", action = "store_true",
- default = False, help="produce debug output")
-_parser.add_option("-d", "--draft", dest="DRAFT", action = "store_true",
- default = False, help="produce draft output, skipping time-consuming calculations")
-from pyfeyn.diagrams import FeynDiagram
-(FeynDiagram.options, args) = _parser.parse_args()
+__all__ = ["diagrams", "points", "blobs", "lines", "deco", "utils", "options"]
Property changes on: pyfeyn/trunk/pyfeyn/__init__.py
___________________________________________________________________
Added: svn:keywords
## -0,0 +1 ##
+Id Date
\ No newline at end of property
Index: pyfeyn/trunk/mkfeyndiag
===================================================================
--- pyfeyn/trunk/mkfeyndiag (revision 1923)
+++ pyfeyn/trunk/mkfeyndiag (revision 1924)
@@ -1,54 +1,55 @@
#! /usr/bin/env python
-from pyfeyn import _parser, __version__
+from pyfeyn import __version__
+from pyfeyn.options import *
from pyfeyn.feynml import *
from optparse import OptionParser
import sys, re
## Parse command line options
_usage = "Usage: %prog [options] hepmlfile"
_version = "%prog " + __version__
_parser = OptionParser(usage=_usage, version=_version)
+options.addPyfeynOptions(_parser)
#_parser.add_option("-V", "--verbose", action="store_true", dest="VERBOSE",
# default=False, help="print status messages")
#_parser.add_option("-D", "--debug", action="store_true", dest="DEBUG",
# default=False, help="print debug (very verbose) messages")
#_parser.add_option("-Q", "--quiet", action="store_true", dest="QUIET",
# default=False, help="be very quiet (overrides verbose and debug)")
_parser.add_option("--pdf", action="store_true", dest="PDF_OUTPUT",
default=True, help="write output in PDF format")
_parser.add_option("--eps", action="store_false", dest="PDF_OUTPUT",
default=True, help="write output in EPS format")
_parser.add_option("-o", "--out", dest="OUTPUT_FILE",
default=None, help="file to write the output to. An appropriate file extension will be appended if needed")
-
(_opts, _args) = _parser.parse_args()
## Check right number of arguments
if len(_args) != 2:
sys.stderr.write("Wrong number of arguments... exiting.\n")
_parser.print_help()
sys.exit(1)
## Select input and output files
_infile = _args[0]
_outfile = _infile
if _opts.OUTPUT_FILE:
_outfile = _opts.OUTPUT_FILE
## Get the output file suffix right
_suffix = ".pdf"
if not _opts.PDF_OUTPUT:
_suffix = ".eps"
if not re.search(r'%s$' % _suffix, _outfile):
_outfile += _suffix
## Read the file and write out to the chosen filename
reader = FeynMLReader(_infile)
_f = reader.get_diagram(0)
_f.draw(_outfile)

File Metadata

Mime Type
text/x-python
Expires
Sat, Oct 12, 10:33 AM (1 d, 23 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
3502590
Default Alt Text
(74 KB)

Event Timeline