def __init__(self, **options): Group.__init__(self, **options) p = Group() self.fg = options.get("fg", self.fg) self.bg = options.get("bg", self.bg) if self.width > self.height: p.append( Path(P(0, 0), P(0, self.height), P(self.width - self.height / 2.0, self.height), C(90, 0), P(self.width, self.height / 2.0), C(180, 90), P(self.width - self.height / 2.0, 0), fg=self.fg, bg=self.bg, closed=1)) else: p.append( Path(P(0, 0), P(0, self.height), C(90, 0), P(self.width, self.height / 2.0), C(180, 90), closed=1)) # rotate if necessary self.angle = options.get("angle", self.angle) p.rotate(self.angle, p=p.bbox().c) self.append(p)
def Rail(w=P(0, 0), length=1.0, labelIn=None, labelOut=None, buff=0.05): """ A Rail of a quantum circuit diagram @param length: length of the rail @type length: float @param labelIn: input label @type labelIn: string @param labelOut: output label @type labelOut: string @param buff: buffer of space between the end of the rail and the label @type buff: float """ if labelIn is not None and labelOut is not None: return Group(Path(w + P(0, 0), w + P(length, 0)), TeX(labelIn, e=w - P(buff, 0)), TeX(labelOut, w=w + P(buff + length, 0))) elif labelIn is not None and labelOut is None: return Group(Path(w + P(0, 0), w + P(length, 0)), TeX(labelIn, e=w - P(buff, 0))) elif labelIn is None and labelOut is not None: return Group(Path(w + P(0, 0), w + P(length, 0)), TeX(labelOut, w=w + P(buff + length, 0))) else: return Group(Path(w + P(0, 0), w + P(length, 0)))
def CZGate(c=P(0, 0), controlDist=1.0, direction="up", side=0.5): """ Controlled Z gate @param controlDist: distance to the control @type controlDist: float @param direction: in which direction is the control? up/down @type direction: string @param side: length of the box side @type side: float """ if direction is "up": return Group( Circle(c=c + P(0, controlDist), r=0.065, bg=Color("black")), Path(c + P(0, side / 2.), c + P(0, controlDist)), Rectangle(width=side, height=side, c=c, bg=Color("white")), TeX(r'Z', c=c)) elif direction is "down": return Group( Circle(c=c - P(0, controlDist), r=0.65, bg=Color("black")), Path(c - P(0, side / 2.), c - P(0, controlDist)), Rectangle(width=side, height=side, c=c, bg=Color("white")), TeX(r'Z', c=c))
def BS(sw=P(0, 0), label=None, h=1.0): """ Beam splitter; displayed as a line possibly more useful in linear optics quantum computation diagrams @param sw: location of the south-west corner of the object @type sw: L{P} object @param label: beam splitter label @type label: string @param h: beam splitter height @type h: float """ buff = P(0, 0.1) b = Path(sw - buff, sw + P(0, h) + buff, sw + P(h, h) + buff, sw + P(h, 0) - buff, sw - buff, fg=None, bg=Color("white")) p1 = Path(sw, sw + P(h, h)) p2 = Path(sw + P(0, h), sw + P(h, 0)) p3 = Path(sw + P(h / 4, h / 2), sw + P(h, 0) + P(-h / 4, h / 2), linewidth=1) if label is not None: label['w'] = sw + P(h, 0) + P(-h / 4, h / 2) return Group(b, p1, p2, p3, label) else: return Group(b, p1, p2, p3)
def SWAP(**options): """ Swap gate """ x = Group(Path(P(-.1, .1), P(.1, -.1)), Path(P(-.1, -.1), P(.1, .1))) options['controlobj'] = options.get('controlobj', x) return Gate(x, **options)
def NOT(**options): """ NOT gate """ r = .2 return Gate( Group(Circle(r=r), Path(P(0, r), P(0, -r)), Path(P(-r, 0), P(r, 0))), **options)
def __init__(self, **options): # initialise the base class Gate.__init__(self, **options) # process the options if any self.height = options.get("height", self.height) self.width = options.get("width", self.width) self.angle = options.get("angle", self.angle) self.pinLength = options.get("pinLength", self.pinLength) self.fg = options.get("fg", self.fg) self.bg = options.get("bg", self.bg) # now draw the gate pinEdgeDist = 0.1*self.height pinBackDist = -0.08*self.width xBit = 0.2 pl = self.pinLength bodyHeight = self.height bodyWidth = self.width - 2.0*pl gateBody = Group( Path( P(-pinBackDist+xBit, -pinEdgeDist), C(90, 225), P(1.4*bodyWidth, bodyHeight/2.), C(-45, 90), P(-pinBackDist+xBit, bodyHeight+pinEdgeDist), C(140, 40), P(-pinBackDist+xBit, -pinEdgeDist), ), Path( P(-pinBackDist, bodyHeight+pinEdgeDist), C(140, 40), P(-pinBackDist, -pinEdgeDist) ), ) gatePinIn1 = Path( P(0, bodyHeight-pinEdgeDist), P(pl, bodyHeight-pinEdgeDist)) gatePinIn2 = Path( P(0, pinEdgeDist), P(pl, pinEdgeDist)) gatePinOut = Path( gateBody.e, gateBody.e+P(pl, 0)) # collect the objects together obj = Group(gateBody, gatePinIn1, gatePinIn2, gatePinOut) # apply the colours obj.apply(fg=self.fg, bg=self.bg) # rotate if necessary if self.angle != 0.0: obj.rotate(self.angle, p=obj.c) # now set the object to myself self.append(obj)
def __init__(self, **options): # initialise the base class Gate.__init__(self, **options) # process the options if any self.height = options.get("height", self.height) self.width = options.get("width", self.width) self.angle = options.get("angle", self.angle) self.pinLength = options.get("pinLength", self.pinLength) self.fg = options.get("fg", self.fg) self.bg = options.get("bg", self.bg) # now draw the gate buff = 0.0 pinEdgeDist = 0.1*self.height pl = self.pinLength bodyHeight = self.height bodyWidth = self.width - 2.0*pl rad = 0.1 gateBody = Group( Path( P(pl, buff+0), P(pl, buff+bodyHeight), P(pl+bodyWidth/2., buff+bodyHeight)), Circle(c=P(pl+bodyWidth/2., buff+bodyHeight/2.), r=bodyHeight/2., start=0, end=180), Path( P(pl+bodyWidth/2., buff+0), P(pl, buff+0))) gatePinIn1 = Path( P(0, bodyHeight-pinEdgeDist), P(pl, bodyHeight-pinEdgeDist)) gatePinIn2 = Path( P(0, pinEdgeDist), P(pl, pinEdgeDist)) gatePinOut = Group( Circle(c=P(bodyWidth+pl+rad, bodyHeight/2.), r=rad), Path( P(bodyWidth+pl+2.*rad, bodyHeight/2.), P(bodyWidth+2.*rad+2.*pl, bodyHeight/2.))) # collect the objects together obj = Group(gateBody, gatePinIn1, gatePinIn2, gatePinOut) # apply the colours obj.apply(fg=self.fg, bg=self.bg) # rotate if necessary if self.angle != 0.0: obj.rotate(self.angle, p=obj.c) # now set the object to myself self.append(obj)
def __init__(self, **options): # inherit from the base class Group.__init__(self, **options) # process the options if any self.fg = options.get("fg", self.fg) self.bg = options.get("bg", self.bg) self.height = options.get("height", self.height) self.width = options.get("width", self.width) self.angle = options.get("angle", self.angle) # make the free space fs = Group() fs.append( Path(P(0, 0), P(0, self.height), P(self.width, self.height), P(self.width, 0), closed=1, fg=self.fg, bg=self.bg, dash=Dash())) # rotate if necessary fs.rotate(self.angle, p=fs.bbox().c) self.append(fs)
def __init__(self, **options): # inherit from base class Group.__init__(self, **options) # process the options if any self.width = options.get("width", self.width) self.height = options.get("height", self.height) self.angle = options.get("angle", self.angle) self.fg = options.get("fg", self.fg) self.bg = options.get("bg", self.bg) # now make the phase shifter ps = Path( P(0, 0), P(self.width / 2.0, self.height), P(self.width, 0), closed=1, fg=self.fg, bg=self.bg, ) # rotate if necessary if self.angle != 0: ps.rotate(self.angle, p=ps.bbox().c) self.append(ps)
def __init__(self, **options): # inherit from the base class Group.__init__(self, **options) # process the options if any self.fg = options.get("fg", self.fg) self.bg = options.get("bg", self.bg) self.height = options.get("height", self.height) self.width = options.get("width", self.width) self.angle = options.get("angle", self.angle) # make the beam splitter lp = Group() lp.append( Path(P(0, 0), P(-self.width, 0), P(-self.width, self.height), P(0, self.height), P(0, 0), P(-self.width, self.height), fg=self.fg, bg=self.bg)) # rotate if necessary lp.rotate(self.angle, p=lp.bbox().c) self.append(lp)
def __init__(self, **options): # inherit from the base class Group.__init__(self, **options) # process the options if any self.fg = options.get("fg", self.fg) self.bg = options.get("bg", self.bg) self.height = options.get("height", self.height) self.angle = options.get("angle", self.angle) # make the beam splitter bs = Group() bs.append( Path(P(0, 0), P(0, self.height), P(self.height, self.height), P(self.height, 0), P(0, 0), P(self.height, self.height), fg=self.fg, bg=self.bg)) # rotate if necessary bs.rotate(self.angle, p=bs.bbox().c) self.append(bs)
def Detector(e=P(0, 0), height=1.0, label=None): """ Detector @param height: height of detector @type height: float @param label: detector label @type label: string """ if label is not None: return Group(Path(e - P(0, height / 2.0), e + P(0, height / 2.0)), Circle(c=e, r=height / 2.0, start=0, end=180), label) else: return Group(Path(e - P(0, height / 2.0), e + P(0, height / 2.0)), Circle(c=e, r=height / 2.0, start=0, end=180))
def _make(self): """ Makes the gate """ self.clear() # calc average target point tp = self.target[0] if len(self.target) > 1: for tt in self.target[1:]: tp = tp + tt tp = tp / float(len(self.target)) self.targetobj.c = tp #XXX should target adjust height here # add controls for cc in self.control: self.append(Path(tp, cc)) self.controlobj.c = cc self.append(self.controlobj.copy()) self.append(self.targetobj)
def __init__(self, **options): # intitialise base class Group.__init__(self, **options) self.sep = 0.25 self.width = 1.0 self.angle = 0.0 self.pinLength = 0.5 self.fg = Color(0) self.bg = Color(1) # process the options if any self.sep = options.get("sep", self.sep) self.width = options.get("width", self.width) self.angle = options.get("angle", self.angle) self.pinLength = options.get("pinLength", self.pinLength) self.fg = options.get("fg", self.fg) self.bg = options.get("bg", self.bg) pinIn = Group( Path( P(0, 0), P(self.pinLength, 0), ) ) cap = Group( Path(pinIn.e+P(0, -self.width/2.0), pinIn.e+P(0, self.width/2.0)), Path(pinIn.e+P(self.sep, -self.width/2.0), pinIn.e+P(self.sep, self.width/2.0)), ) pinOut = Path( cap.e, cap.e+P(self.pinLength, 0)) # group the objects together obj = Group(pinIn, pinOut, cap) # apply the colours obj.apply(fg=self.fg, bg=self.bg) # rotate if necessary if self.angle != 0.0: obj.rotate(self.angle, p=obj.c) # set the object to myself self.append(obj)
def Cnot(c=P(0, 0), targetDist=1.0, direction="up"): """ Controlled NOT gate @param targetDist: distance to the target rail @type targetDist: float @param direction: in which direction is the target rail? up/down @type direction: string """ if direction is "up": return Group(Circle(r=0.06, bg=Color("black"), c=c), Circle(r=0.2, c=c + P(0, targetDist)), Path(c, c + P(0, targetDist + 0.2))) elif direction is "down": return Group(Circle(r=0.06, bg=Color("black"), c=c), Circle(r=0.2, c=c + P(0, -targetDist)), Path(c, c + P(0, -targetDist - 0.2)))
def __init__(self, **options): # intitialise base class Group.__init__(self, **options) self.length = 3.0 self.width = 1.0 self.angle = 0.0 self.pinLength = 0.5 self.fg = Color(0) self.bg = Color(1) # process the options if any self.length = options.get("length", self.length) self.width = options.get("width", self.width) self.angle = options.get("angle", self.angle) self.pinLength = options.get("pinLength", self.pinLength) self.fg = options.get("fg", self.fg) self.bg = options.get("bg", self.bg) pinIn = Group( Path( P(0, 0), P(self.pinLength, 0) ) ) resistor = Rectangle(w=pinIn.e, width=self.length, height=self.width) pinOut = Path( resistor.e, resistor.e+P(self.pinLength, 0)) # collect the objects together obj = Group(pinIn, pinOut, resistor) # apply the colours obj.apply(fg=self.fg, bg=self.bg) # rotate if necessary if self.angle != 0.0: obj.rotate(self.angle, p=obj.c) # return object to myself self.append(obj)
def __init__(self, **options): # inherit from the base class Group.__init__(self, **options) # process the options if any self.fg = options.get("fg", self.fg) self.bg = options.get("bg", self.bg) self.length = options.get("length", self.length) self.thickness = options.get("thickness", self.thickness) self.angle = options.get("angle", self.thickness) self.flicks = options.get("flicks", self.flicks) # make the mirror itself mirror = Group() mirror.append( Path(P(0, 0), P(0, self.length), P(self.thickness, self.length), P(self.thickness, 0), closed=1, fg=self.fg, bg=self.bg)) if self.flicks: # make the flicks on the back of the mirror flickLen = 0.15 flicksObj = Group() for i in range(10): flicksObj.append( Path(P((i + 1.0) * self.length / 10.0, self.thickness), P(i * self.length / 10.0, self.thickness + flickLen), fg=self.fg, bg=self.bg)) mirror.append(flicksObj) # rotate the mirror if necessary if self.angle != 0.0: mirror.rotate(self.angle, p=mirror.bbox().c) # make the mirror the current object self.append(mirror)
def __init__(self, **options): # inherit from the base class Group.__init__(self, **options) # process the options if any self.fg = options.get("fg", self.fg) self.bg = options.get("bg", self.bg) self.height = options.get("height", self.height) self.width = options.get("width", self.width) self.angle = options.get("angle", self.angle) # make the modulator modulator = Group() modulator.append( Path( P(0, 0), P(0, self.height), P(self.width, self.height), P(self.width, 0), closed=1, fg=self.fg, bg=self.bg, )) modulator.append( Path( P(0, -self.buf), P(self.width, -self.buf), fg=self.fg, bg=self.bg, )) modulator.append( Path( P(0, self.height + self.buf), P(self.width, self.height + self.buf), fg=self.fg, bg=self.bg, )) # rotate if necessary modulator.rotate(self.angle, p=modulator.bbox().c) self.append(modulator)
def set(self, y, e, w): """ Set the east, west and y postions of the QWire """ path = Path(P(w, y), P(e, y), fg=self.fg, linewidth=self.linewidth, dash=self.dash) self.append(path) return self
def __init__(self, **args): Group.__init__(self, **args) h = self.height w = self.width self.append(Rectangle(width=1.8 * h, height=h, bg=self.bg)) p = Path(P(.1, .1), C(0, 0), P(w - .1, .1), P(w - .2, .1), C(0, 0), P(.2, .1), closed=1, bg=self.mcolor, fg=None) self.append( p, Path(P(w / 2., .1), U(self.angle, h * .9)), )
def __init__(self, object=None, **options): if object is not None: # use the object's boundingbox when width and height not supplied bb = object.bbox() w = bb.width + 2 * self.pad h = bb.height + 2 * self.pad self.width = options.get("width", max(w, self.width)) self.height = options.get("height", max(h, self.height)) Group.__init__(self, **options) if self.width > self.height: p = Path(P(0, 0), P(0, self.height), P(self.width - self.height / 2., self.height), C(90, 0), P(self.width, self.height / 2.), C(180, 90), P(self.width - self.height / 2., 0), closed=1) else: p = Path(P(0, 0), P(0, self.height), C(90, 0), P(self.width, self.height / 2.), C(180, 90), closed=1) p(bg=options.get("bg", self.bg), fg=options.get("fg", self.fg)) self.append(p) if object is not None: # object looks better if it's slightly off centre # since one side is curved. pad/3 is about right object.c = P(self.width / 2. - self.pad / 3., self.height / 2.) self.append(object)
def __init__(self, **options): # inherit from the base class Group.__init__(self, **options) # process the options if any self.fg = options.get("fg", self.fg) self.bg = options.get("bg", self.bg) self.height = options.get("height", self.height) self.thickness = options.get("thickness", self.thickness) self.angle = options.get("angle", self.angle) self.type = options.get("type", self.type) # determine what type of lens to make if self.type == "convex": leftCurveAngle = -30 rightCurveAngle = -30 elif self.type == "concave": leftCurveAngle = 30 rightCurveAngle = 30 else: print "Unknown lens type, defaulting to concave" leftCurveAngle = 30 rightCurveAngle = 30 # make the lens lens = Group() lens.append( Path( P(0, 0), C(leftCurveAngle, 180 - leftCurveAngle), P(0, self.height), P(self.thickness, self.height), C(-180 + rightCurveAngle, -rightCurveAngle), P(self.thickness, 0), closed=1, fg=self.fg, bg=self.bg, )) # rotate if necessary lens.rotate(self.angle, p=lens.bbox().c) self.append(lens)
def cbox(obj, x, yt, yc): ''' @param obj: the object to put a box around @type obj: object @param x: x position of line and centre of box @type x: float @param yt: y position of target @type yt: float @param yc: y position of control @type yc: float @return: a controlled box ''' g = Group( Path(P(x, yt), P(x, yc)), Boxed(obj, c=P(x, yt), bg=Color(1)), Dot(P(x, yc)), ) return g