def test_flexpath3(target): cell = gdspy.Cell("test") pts = numpy.array([ (0, 0), (0.5, 0), (1, 0), (1, 2), (3, 0), (2, -1), (2, -2), (0, -1), (1, -2), (1, -3), ]) fp = gdspy.FlexPath( pts + numpy.array((0, 5)), [0.1, 0.1, 0.1], 0.15, layer=[1, 2, 3], corners=["natural", "miter", "bevel"], ends=(0.5, 0), ) cell.add(fp) fp = gdspy.FlexPath( pts + numpy.array((5, 0)), [0.1, 0.1, 0.1], 0.15, layer=[4, 5, 6], corners=["round", "smooth", broken], ends=[pointy, "smooth", (0, 0.5)], ) cell.add(fp) assertsame(target["FlexPath3"], cell)
def bench_gdspy(output=None): sp1 = gdspy.FlexPath([(0, 0), (3, 0), (3, 2), (5, 3), (3, 4), (0, 4)], 1, gdsii_path=True, datatype=1) sp1.smooth([(0, 2), (2, 2), (4, 3), (5, 1)], relative=True) sp2 = gdspy.FlexPath( [(12, 0), (8, 0), (8, 3), (10, 2)], [0.3, 0.2, 0.4], 0.5, ends=["extended", "flush", "round"], corners=["bevel", "miter", "round"], datatype=2, ) sp2.arc(2, -0.5 * numpy.pi, 0.5 * numpy.pi) sp2.arc(1, 0.5 * numpy.pi, 1.5 * numpy.pi) points = [(0, 0), (0, 10), (20, 0), (18, 15), (8, 15)] sp3 = gdspy.FlexPath(points, 0.5, corners="circular bend", bend_radius=5, gdsii_path=True, datatype=4) sp4 = gdspy.FlexPath(points, 0.5, layer=1, gdsii_path=True, datatype=5) if output: cell = gdspy.Cell("MAIN", exclude_from_current=True) cell.add([sp1, sp2, sp3, sp4]) cell.write_svg(output, 30)
def connect_LShape(cell, pos_start=(0, 0), pos_stop=(0, 0)): x_ext = 30 y_ext = 30 # Path defined by a sequence of points and stored as a GDSII path if pos_stop[1] < pos_start[1]: sp1 = gdspy.FlexPath([ pos_start, (pos_stop[0], pos_start[1]), pos_stop, (pos_stop[0] - x_ext, pos_stop[1]), (pos_stop[0] - x_ext, pos_stop[1] - y_ext) ], w_Al, 0, gdsii_path=True, ends="flush", **layer_M1) else: sp1 = gdspy.FlexPath([ pos_start, (pos_stop[0], pos_start[1]), pos_stop, (pos_stop[0] - x_ext, pos_stop[1]), (pos_stop[0] - x_ext, pos_stop[1] + y_ext) ], w_Al, 0, gdsii_path=True, ends="flush", **layer_M1) cell.add(sp1)
def test_flexpath1(target): cell = gdspy.Cell("test") fp = gdspy.FlexPath([(0, 0), (1, 1)], 0.1, layer=[1], gdsii_path=True) cell.add(fp) fp = gdspy.FlexPath( [(1, 0), (2, 1)], 0.1, [-0.1, 0.1], tolerance=1e-5, ends=["round", "extended"], layer=[2, 3], max_points=6, ) cell.add(fp) fp = gdspy.FlexPath([(2, 0), (3, 1)], [0.1, 0.2], 0.2, ends=(0.2, 0.1), layer=4, datatype=[1, 1]) cell.add(fp) fp = gdspy.FlexPath( [(3, 0), (4, 1)], [0.1, 0.2, 0.1], [-0.2, 0, 0.2], ends=[(0.2, 0.1), "smooth", pointy], datatype=5, ) cell.add(fp) assertsame(target["FlexPath1"], cell)
def test_flexpath_warnings(): f = lambda *args: None for ends in ['smooth', f]: with pytest.warns(UserWarning): gdspy.FlexPath([(0, 0)], 1, ends=ends, gdsii_path=True) for corners in ['miter', 'bevel', 'round', 'smooth', f]: with pytest.warns(UserWarning): gdspy.FlexPath([(0, 0)], 1, corners=corners, gdsii_path=True)
def test_flexpath_warnings(): f = lambda *args: None for ends in ["smooth", f]: with pytest.warns(UserWarning): gdspy.FlexPath([(0, 0)], 1, ends=ends, gdsii_path=True) for corners in ["miter", "bevel", "round", "smooth", f]: with pytest.warns(UserWarning): gdspy.FlexPath([(0, 0)], 1, corners=corners, gdsii_path=True)
def test_flexpath_duplicates(): fp = gdspy.FlexPath([(1.1, 2), (1.1, 2.0)], 0.1) poly = fp.get_polygons() assert isinstance(poly, list) and len(poly) == 0 poly = fp.get_polygons(True) assert isinstance(poly, dict) and len(poly) == 0 fp1 = gdspy.FlexPath([(1.1, 2), (1.1, 2.0), (1, 1), (1, 1), (1, 1.0), (0, 1), (0.0, 1.0)], 0.1) fp2 = gdspy.FlexPath([(1.1, 2), (1, 1.0), (0.0, 1.0)], 0.1) assertsame(gdspy.Cell("DUPS").add(fp1), gdspy.Cell("SNGL").add(fp2))
def draw(self, cell, origin, layer=0, datatype=0, start_overlap=0, end_overlap=0, max_points=MAX_POINTS, gdsii_path=False): """Draw this trace into the given cell as a GDSII polygon (or path) and return the drawn object. By default, :class:`gdspy.FlexPath` draws a polygon; to draw a path (including a zero-width path), use `gdsii_path=True`. The overlap regions, whose length is not counted by :meth:`Segment.length`, are passed to :class:`gdspy.FlexPath` as `ends=(start_overlap, end_overlap)`. :param cell: the cell into which to draw the trace, if not None. :type cell: gdspy.Cell or None :param point origin: the point at which to place the start of the trace. :param int layer: the GDSII layer. :param int datatype: the GDSII datatype. :param float start_overlap: the overlap length at the start. :param float end_overlap: the overlap length at the end. :param int max_points: polygons with more than this number of points are fractured. :param bool gdsii_path: passed to :class:`gdspy.FlexPath`; if True, create and return a GDSII path; if False, convert the path to a Polygon. :return: the drawn object. :rtype: tuple[gdspy.PolygonSet or gdspy.FlexPath] """ points = [to_point(origin) + point for point in self.points] if gdsii_path: element = gdspy.FlexPath(points=points, width=self.trace, layer=layer, datatype=datatype, max_points=max_points, ends=(start_overlap, end_overlap), gdsii_path=True) else: element = gdspy.FlexPath(points=points, width=self.trace, layer=layer, datatype=datatype, max_points=max_points, ends=(start_overlap, end_overlap)).to_polygonset() if cell is not None: cell.add(element=element) return (element, )
def bench_gdspy(output=None): def broken(p0, v0, p1, v1, p2, w): den = v1[1] * v0[0] - v1[0] * v0[1] lim = 1e-12 * (v0[0] ** 2 + v0[1] ** 2) * (v1[0] ** 2 + v1[1] ** 2) if den ** 2 < lim: u0 = u1 = 0 p = 0.5 * (p0 + p1) else: dx = p1[0] - p0[0] dy = p1[1] - p0[1] u0 = (v1[1] * dx - v1[0] * dy) / den u1 = (v0[1] * dx - v0[0] * dy) / den p = 0.5 * (p0 + v0 * u0 + p1 + v1 * u1) if u0 <= 0 and u1 >= 0: return [p] return [p0, p2, p1] def pointy(p0, v0, p1, v1): r = 0.5 * numpy.sqrt(numpy.sum((p0 - p1) ** 2)) v0 /= numpy.sqrt(numpy.sum(v0 ** 2)) v1 /= numpy.sqrt(numpy.sum(v1 ** 2)) return [p0, 0.5 * (p0 + p1) + 0.5 * (v0 - v1) * r, p1] sp0 = gdspy.FlexPath( [(0, 0), (0, 1)], [0.1, 0.3, 0.5], offset=[-0.2, 0, 0.4], layer=[0, 1, 2], corners=broken, ends=pointy, datatype=3, ) sp0.segment((3, 3), offset=[-0.5, -0.1, 0.5]) sp0.segment((4, 1), width=[0.2, 0.2, 0.2], offset=[-0.2, 0, 0.2]) sp0.segment((0, -1), relative=True) def spiral(u): r = 2 - u theta = 5 * u * numpy.pi return (r * numpy.cos(theta) - 2, r * numpy.sin(theta)) sp1 = gdspy.FlexPath([(2, 6)], 0.2, layer=2, max_points=8190) sp1.parametric(spiral) if output: cell = gdspy.Cell("MAIN", exclude_from_current=True) cell.add([sp0, sp1]) cell.write_svg(output, 50)
def connect_zShape_(pos_start, pos_end, len_port=5, w=0.5, radius=10, layer=1, datatype=1): # Path defined by a sequence of points and stored as a GDSII path path = gdspy.FlexPath( [pos_start, (pos_start[0]+len_port+radius, pos_start[1]), (pos_start[0]+len_port+radius, pos_end[1]), pos_end], w, 0, ends="flush", layer=layer, datatype=datatype, bend_radius=radius, corners='circular bend', tolerance=0.001 ) return path
def DrawReflectionFeedline( FeedlineCellName = 'Feedline', MainlineLength = 3000, LineWidth = 10, #width of feedline SpaceWidth = 6, #space between feedline and ground plane BigWidth = 96, #maximum launcher-lines width LauncherWidth = 352, #total launcher width layer = 2): """ This function returns a feedline cell (in a list) that contains references to one curved mainline cell and one launcher cell, placed on one end of the main line. The cell origin is defined at the center of the mainline. """ '''launcher''' launcher = DrawLauncher( LauncherCellName = 'Launcher', LineWidth = LineWidth, #width of each parallel line SpaceWidth = SpaceWidth, #space between parallel lines BigWidth = 96, #maximum launcher-lines width LauncherWidth = 352, #total launcher width layer = 2) '''main line''' mainline = gds.Cell(FeedlineCellName+'Mainline', exclude_from_current=True) path = gds.FlexPath([(0,0),(MainlineLength,0)], [SpaceWidth, SpaceWidth], SpaceWidth + LineWidth , layer=layer) path.turn(LauncherWidth, 'r') path.segment((0,-MainlineLength/4), relative=True) mainline.add(path) #Adds cell references to main cell Feedline = gds.Cell(FeedlineCellName, exclude_from_current=True) Feedline.add(gds.CellReference(launcher, origin=(-MainlineLength/2, 0))) Feedline.add(gds.CellReference(mainline, origin=(-MainlineLength/2,0))) return [Feedline]
def DrawTransmissionFeedline( FeedlineCellName = 'Feedline', MainlineLength = 2000, LineWidth = 10, #width of transmission line SpaceWidth = 6, #space between transmission line and grounding plane BigWidth = 96, #maximum launcher-lines width LauncherWidth = 352, #total launcher width layer = 2): """ This function returns a symmetrical feedline cell (in a list) that contains references to one mainline cell and one launcher cell, placed on both sides of the main line. The cell origin is defined at the center of the mainline. """ '''launcher''' launcher = DrawLauncher( LauncherCellName = 'Launcher', LineWidth = 10, #width of feedline SpaceWidth = 6, #space between feedline and ground plane BigWidth = 96, #maximum launcher-lines width LauncherWidth = 352, #total launcher width layer = 2) '''main line''' mainline = gds.Cell(FeedlineCellName+'Mainline', exclude_from_current=True) mainline.add(gds.FlexPath([(0,0),(MainlineLength,0)], [SpaceWidth, SpaceWidth], SpaceWidth + LineWidth , layer=layer)) #Adds cell references to main cell Feedline = gds.Cell(FeedlineCellName, exclude_from_current=True) Feedline.add(gds.CellReference(launcher, origin=(-MainlineLength/2, 0))) Feedline.add(gds.CellReference(mainline, origin=(-MainlineLength/2,0))) Feedline.add(gds.CellReference(launcher, origin=(MainlineLength/2, 0), rotation=180 , x_reflection=True)) return [Feedline]
def ShapeEdge(original_shape, edge_width, edge_extend=0, edge_type=constants.EDGE_TYPE_NORMAL, **kwargs): """ Adapter class to modify the edge shape. The original shape must be a box. """ points = original_shape.points[0] params = { 'points': points, 'width': edge_width, 'offset': 0, 'ends': 'flush' } if edge_type == constants.EDGE_TYPE_INSIDE: params['offset'] = 0.5 * edge_width elif edge_type == constants.EDGE_TYPE_OUTSIDE: params['offset'] = -0.5 * edge_width elif edge_type == constants.EDGE_TYPE_SQUARE: params['ends'] = 'extended' path = gdspy.FlexPath(**params) pts = path.get_polygons()[0] new_shape = Shape(points=pts) return new_shape
def zigzag_wire(w, L, l_each, angle=30, orientation=0, layer=1): """ makes a zigzag wire with total length ~= L and each segment having length l_each :param w: float, width in um :param L: float, total length of the straight line before zigzag-ification :param l_each: float, chop the straight line into segments each having length l_each :param angle: float in degrees, the angle formed between the new zigzag lines and the original straight line :param orientation: float in degrees, that of the original straight line :param layer: int, 1 by default for shapes :return: gdspy shape containing the zigzag line """ if l_each <= 0 or l_each >= L: print('Length of each segment must be 0 < l_each < L') raise ValueError # make segments line_coordinates = [(-L / 2, 0)] # beginning point x = -L / 2 even_count = True while x < L / 2: x += l_each even_count = not even_count if even_count: line_coordinates.append((x, 0)) else: line_coordinates.append( (x, -l_each * math.sin(angle * math.pi / 180))) zigzag_line = gp.FlexPath(line_coordinates, w, layer=layer) return zigzag_line.rotate(orientation * math.pi / 180)
def path(self, points, port, fillet, name=''): #TODO, this is a dirty fixe cause of Vector3D points_2D = [] for point in points: points_2D.append([point[0], point[1]]) # use dummy layers to recover the right elements layers = [ii for ii in range(len(port.widths))] cable = gdspy.FlexPath( points_2D, port.widths, offset=port.offsets, corners="circular bend", bend_radius=fillet, gdsii_path=False, tolerance=TOLERANCE, layer=layers, max_points=0 ) # tolerance (meter) is highly important here should be smaller than the smallest dim typ. 100nm polygons = cable.get_polygons() names = [] layers = [] for ii in range(len(polygons)): poly = gdspy.Polygon(polygons[ii]) poly.layers = [port.layers[ii]] current_name = name + '_' + port.subnames[ii] names.append(current_name) layers.append(port.layers[ii]) self.gds_object_instances[current_name] = poly self.cell.add(poly) return names, layers
def test_robustpath_transform(target): rp = gdspy.FlexPath([(0, 0)], [2, 1, 1], 5) rp.segment((15, 20)) rp.scale(0.7) rp.turn(10, "r") rp.transform((10, 0), -1.5, 1.5, x_reflection=True) rp.segment((10, -10), relative=True) rp.rotate(-0.7) rp.translate(50, 30) rp.segment((-10, 0)) assertsame(target["RobustPath4"], gdspy.Cell("FP5").add(rp)) rp = gdspy.RobustPath((0, 0), [2, 1, 1], 5) rp.segment((15, 20)) rp.turn(10, "r") rp.segment((10, -10), relative=True) poly = rp.to_polygonset() rp.rotate(-0.7) rp.scale(0.7) rp.translate(50, 30) rp.transform((10, 0), numpy.pi / 4, 1.5, True) poly.rotate(-0.7) poly.scale(0.7) poly.translate(50, 30) c0 = gdspy.Cell("POLY") c0.add(poly) ref = gdspy.CellReference(c0, (10, 0), 45, 1.5, True) assertsame(gdspy.Cell("RP").add(rp), gdspy.Cell("REF").add(ref), tolerance=1e-2)
def test_flexpath3(target): cell = gdspy.Cell('test', True) pts = numpy.array([(0, 0), (0.5, 0), (1, 0), (1, 2), (3, 0), (2, -1), (2, -2), (0, -1), (1, -2), (1, -3)]) fp = gdspy.FlexPath(pts + numpy.array((0, 5)), [0.1, 0.1, 0.1], 0.15, layer=[1, 2, 3], corners=['natural', 'miter', 'bevel'], ends=(0.5, 0)) cell.add(fp) fp = gdspy.FlexPath(pts + numpy.array((5, 0)), [0.1, 0.1, 0.1], 0.15, layer=[4, 5, 6], corners=['round', 'smooth', broken], ends=[pointy, 'smooth', (0, 0.5)]) cell.add(fp) assertsame(target['FlexPath3'], cell)
def markerL(conf: DefaultConfig, text='', rotation=0): dx, w, ts = conf.markerLSize[0], conf.markerLWidth, conf.markerLTextSize markerL = gdspy.FlexPath([(0, -dx), (0, 0), (dx, 0)], w, layer=conf.markerLayer).to_polygonset() text = gdspy.Text(text, ts, [w, w], layer=conf.markerLayer).rotate(-pi / 2) if rotation == -pi / 2: text.translate(-dx, 0) return [markerL.rotate(rotation), text]
def DrawFourJJgroundedLoop( FourJJloopCellName = '4JJloop', FourJJloopLength = 10.5, FourJJloopWidth = 0, #Square loop, unless width is specified LineWidth = 2, #width of the loop wire JJparameters= {'FingerWidth': 0.36, #Dictionary with the Josephson junction parameters 'FingerLength': 1, # 'TaperWidth': 0.5, # 'BridgeWidth': 0.14}, JJRelations = [1,1,1,1], #Relations between Josephson junction sizes eBeamLayer = 5): #Layer for eBeam deposition """ This function returns a Four Josephson-junctions loop cell. The cell origin is defined at the center of the loop. """ if (FourJJloopWidth==0): FourJJloopWidth = FourJJloopLength #If width is not specifically defined make a square loop FourJJloop = gds.Cell(FourJJloopCellName, exclude_from_current=True) '''Josephson Junctions''' JosephsonJunctionOrigins = [(-FourJJloopWidth/2,(4/10)*FourJJloopLength),(-FourJJloopWidth/2,FourJJloopLength/10), (-FourJJloopWidth/2,-(2/10)*FourJJloopLength),(FourJJloopWidth/2,0)] JosephsonJunctionTotalLengths = [] for i, JJrelation in enumerate(JJRelations): JosephsonJunction = DrawJosephsonJunction(JosephsonJunctionCellName ='JosephsonJunction'+str(i+1), LineWidth = LineWidth, #width of line connected to the junction FingerWidth = JJrelation*JJparameters['FingerWidth'], # FingerLength = JJparameters['FingerLength'], # TaperWidth = JJparameters['TaperWidth'], # BridgeWidth = JJrelation*JJparameters['BridgeWidth'], # layer = eBeamLayer) JosephsonJunctionTotalLengths.append(JJparameters['FingerLength']+JJparameters['TaperWidth']+JJrelation*JJparameters['BridgeWidth']) FourJJloop.add(gds.CellReference(JosephsonJunction, origin=JosephsonJunctionOrigins[i], rotation=-90)) '''Loop line (with JJ spacings)''' FourJJloopLine = gds.Cell(FourJJloopCellName+'LoopLine', exclude_from_current=True) FourJJloopLine.add(gds.FlexPath([(-FourJJloopWidth/2,(4/10)*FourJJloopLength-JosephsonJunctionTotalLengths[0]), (-FourJJloopWidth/2,(1/10)*FourJJloopLength)], LineWidth, layer=eBeamLayer)) FourJJloopLine.add(gds.FlexPath([(-FourJJloopWidth/2,(1/10)*FourJJloopLength-JosephsonJunctionTotalLengths[1]), (-FourJJloopWidth/2,-(2/10)*FourJJloopLength)], LineWidth, layer=eBeamLayer)) FourJJloopLine.add(gds.FlexPath([(-FourJJloopWidth/2,-(2/10)*FourJJloopLength-JosephsonJunctionTotalLengths[2]), (-FourJJloopWidth/2,-FourJJloopLength/2)], LineWidth, corners = "natural", layer=eBeamLayer)) #corners="circular bend", bend_radius=LineWidth FourJJloopLine.add(gds.FlexPath([(FourJJloopWidth/2,-FourJJloopLength/2), (FourJJloopWidth/2,-JosephsonJunctionTotalLengths[3])], LineWidth, corners = "natural", layer=eBeamLayer)) FourJJloopLine.add(gds.FlexPath([(FourJJloopWidth/2,0),(FourJJloopWidth/2,FourJJloopLength/2), (-FourJJloopWidth/2,FourJJloopLength/2),(-FourJJloopWidth/2,(4/10)*FourJJloopLength)], LineWidth, corners="natural", layer=eBeamLayer)) #corners="circular bend", bend_radius=LineWidth FourJJloop.add(gds.CellReference(FourJJloopLine, origin=(0,0))) return FourJJloop
def DrawRFsquid( RFsquidCellName='RFsquid', RFsquidLength=155.5, RFsquidWidth=12, LineWidth=2, #width of the RFsquid line JJparameters={ 'FingerWidth': 0.36, #Dictionary with the Josephson junction parameters 'FingerLength': 1.36, # 'TaperWidth': 0.5, # 'BridgeWidth': 0.14 }, layer=2): """ This function returns an RFsquid cell (in a list) that contains references to a line cell and a Josephson junction cell. The cell origin is defined at the center of the RFsquid loop. """ '''Josephson Junctions''' RFsquidJJ = DrawJosephsonJunction( JosephsonJunctionCellName=RFsquidCellName + 'JosephsonJunction', LineWidth=LineWidth, #width of line connected to the junction FingerWidth=JJparameters['FingerWidth'], # FingerLength=JJparameters['FingerLength'], # TaperWidth=JJparameters['TaperWidth'], # BridgeWidth=JJparameters['BridgeWidth'], # layer=layer) '''line''' JosephsonJunctionTotalLength = JJparameters['FingerLength'] + JJparameters[ 'TaperWidth'] + JJparameters['BridgeWidth'] RFsquidLine = gds.Cell(RFsquidCellName + 'Line', exclude_from_current=True) RFsquidLineCoordinates = [ (0, (-RFsquidWidth + LineWidth) / 2), ((RFsquidLength - LineWidth) / 2, (-RFsquidWidth + LineWidth) / 2), ((RFsquidLength - LineWidth) / 2, (RFsquidWidth - LineWidth) / 2), ((-RFsquidLength + LineWidth) / 2, (RFsquidWidth - LineWidth) / 2), ((-RFsquidLength + LineWidth) / 2, (-RFsquidWidth + LineWidth) / 2), (-JosephsonJunctionTotalLength, (-RFsquidWidth + LineWidth) / 2) ] RFsquidLine.add( gds.FlexPath(RFsquidLineCoordinates, LineWidth, corners="circular bend", bend_radius=LineWidth, layer=layer)) #Adds cell references to main cell RFsquid = gds.Cell(RFsquidCellName, exclude_from_current=True) RFsquid.add(gds.CellReference(RFsquidLine, origin=(0, 0))) RFsquid.add( gds.CellReference(RFsquidJJ, origin=(-JosephsonJunctionTotalLength, (-RFsquidWidth + LineWidth) / 2))) return [RFsquid]
def render(self): bend_radius = self.g precision = 0.001 # create CPW line under airbridge cpw_line = gdspy.FlexPath( points=[self.position - self.p, self.position + self.p], width=[self.g, self.w, self.g], offset=[ -self.w / 2 - self.s - self.g / 2, 0, self.w / 2 + self.s + self.g / 2 ], ends='flush', corners='natural', bend_radius=bend_radius, precision=precision, layer=self.geometry.layer_configuration.total_layer) # create pads of bridge pad1 = gdspy.Rectangle( (self.position[0] + self.geometry.pad_width / 2, self.position[1] + self.geometry.pad_distance / 2), (self.position[0] - self.geometry.pad_width / 2, self.position[1] + self.geometry.pad_distance / 2 + self.geometry.pad_length), layer=self.geometry.layer_configuration.airbridges_pad_layer) pad2 = gdspy.Rectangle( (self.position[0] - self.geometry.pad_width / 2, self.position[1] - self.geometry.pad_distance / 2), (self.position[0] + self.geometry.pad_width / 2, self.position[1] - self.geometry.pad_distance / 2 - self.geometry.pad_length), layer=self.geometry.layer_configuration.airbridges_pad_layer) contacts = gdspy.boolean( pad1, pad2, 'or', layer=self.geometry.layer_configuration.airbridges_pad_layer) contacts.rotate(self.orientation, self.position) # create bridge bridge = gdspy.Rectangle( (self.position[0] - self.geometry.bridge_width / 2, self.position[1] + self.geometry.bridge_length / 2), (self.position[0] + self.geometry.bridge_width / 2, self.position[1] - self.geometry.bridge_length / 2), layer=self.geometry.layer_configuration.airbridges_layer) bridge.rotate(self.orientation, self.position) return { 'positive': cpw_line, 'airbridges_pads': contacts, 'airbridges': bridge }
def test_flexpath_transform(target): fp = gdspy.FlexPath([(0, 0)], [2, 1, 1], 5) fp.segment((15, 20)) fp.scale(0.7) fp.turn(10, "r") fp.transform((10, 0), -1.5, 1.5, x_reflection=True) fp.segment((10, -10), relative=True) fp.rotate(-0.7) fp.translate(50, 30) fp.segment((-10, 0)) assertsame(target["FlexPath5"], gdspy.Cell("FP5").add(fp))
def test_flexpath_getpolygons(): fp = gdspy.FlexPath([(0, 0), (0.5, 0), (1, 0), (1, 1), (0, 1), (-1, -2), (-2, 0)], 0.05, [-0.1, 0.1], corners=['natural', 'circular bend'], ends=['extended', (0.1, 0.2)], bend_radius=[0, 0.3], layer=[0, 1], datatype=[1, 0]) d = fp.get_polygons(True) l = fp.get_polygons() assert len(d) == 2 assert (1, 0) in d assert (0, 1) in d assert sum(len(p) for p in d.values()) == len(l) assert sum(sum(len(x) for x in p) for p in d.values()) == sum(len(x) for x in l) ps = fp.to_polygonset() assert len(ps.layers) == len(ps.datatypes) == len(ps.polygons) assert gdspy.FlexPath([(0, 0)], 1).to_polygonset() == None
def Route180(port1, port2, layer, width=None, corners='miter', bend_radius=1): """ """ if port1.orientation == 0: p1 = [port1.midpoint[0], port1.midpoint[1]] p2 = [port2.midpoint[0], port2.midpoint[1]] if port1.orientation == 90: p1 = [port1.midpoint[1], -port1.midpoint[0]] p2 = [port2.midpoint[1], -port2.midpoint[0]] if port1.orientation == 180: p1 = [-port1.midpoint[0], -port1.midpoint[1]] p2 = [-port2.midpoint[0], -port2.midpoint[1]] if port1.orientation == 270: p1 = [-port1.midpoint[1], port1.midpoint[0]] p2 = [-port2.midpoint[1], port2.midpoint[0]] if width is None: width = port1.width dx = (p2[0] - p1[0]) / 2 p3 = np.array(p2) - np.array(p1) - np.array([dx, 0]) p4 = np.array(p2) - np.array(p1) path = gdspy.FlexPath([(0, 0), (dx, 0)], width=width, corners=corners, bend_radius=bend_radius) path.segment(end_point=p3) path.segment(end_point=p4) if ug.angle_diff(port2.orientation, port1.orientation) != 180: raise ValueError( "Route error: Ports do not face each other (orientations must be 180 apart)" ) else: pl = PortList() pl += Port(name='I1', midpoint=(0, 0), width=port1.width, orientation=180, process=layer.process) pl += Port(name='I2', midpoint=list(np.subtract(p2, p1)), width=port2.width, orientation=0, process=layer.process) route_shape = RouteShape(path=path) R = Route(shape=route_shape, p1=pl[0], p2=pl[1], layer=layer) T = vector_match_transform(v1=R.ports[0], v2=port1) R.transform(T) return R
def bench_gdspy(output=None): p = gdspy.Polygon([(0, 0), (1, 0), (0, 1)]) fp = gdspy.FlexPath([(0, 0), (1, 0), (0.5, -0.5)], 0.1, ends="round") c1 = gdspy.Cell("REF", exclude_from_current=True) c1.add([p, fp]) r = gdspy.CellArray(c1, columns=3, rows=2, spacing=(2, 2), rotation=30) c2 = gdspy.Cell("MAIN", exclude_from_current=True) c2.add(r) bb = c2.get_bounding_box() if output: c2.add(gdspy.Rectangle(*bb, layer=1)) c2.write_svg(output, 100)
def test_flexpath1(target): cell = gdspy.Cell('test', True) fp = gdspy.FlexPath([(0, 0), (1, 1)], 0.1, layer=[1], gdsii_path=True) cell.add(fp) fp = gdspy.FlexPath([(1, 0), (2, 1)], 0.1, [-0.1, 0.1], tolerance=1e-5, ends=['round', 'extended'], layer=[2, 3], max_points=6) cell.add(fp) fp = gdspy.FlexPath([(2, 0), (3, 1)], [0.1, 0.2], 0.2, ends=(0.2, 0.1), layer=4, datatype=[1, 1]) cell.add(fp) fp = gdspy.FlexPath([(3, 0), (4, 1)], [0.1, 0.2, 0.1], [-0.2, 0, 0.2], ends=[(0.2, 0.1), 'smooth', pointy], datatype=5) cell.add(fp) assertsame(target['FlexPath1'], cell)
def connection_to_ground(self, length, width): """ This function generate a connection from JJ rectangulars to a flux line output. Should be changed if you want to use another type of JJ or a flux line """ result = None for point in [self.JJ.rect1, self.JJ.rect2]: orientation = np.arctan2(-(self.center[1] - (point[1]-length)), -(self.center[0] - point[0])) points =[point, (point[0], point[1] - length), (self.center[0]+self.R2*np.cos(orientation), self.center[1]+self.R2*np.sin(orientation))] path = gdspy.FlexPath(deepcopy(points), width, offset=0, layer=self.layer_configuration.total_layer) result = gdspy.boolean(path, result, 'or', layer=self.layer_configuration.total_layer) orientation = np.arctan2(-(self.center[1] - (self.JJ.rect1[1] - length)), -(self.center[0] - self.JJ.rect1[0])) #to fix rounding bug bug=5 connection = (self.center[0]+(self.R2-bug)*np.cos(orientation),self.center[1]+(self.R2-bug)*np.sin(orientation)) # add cpw from flux_line_output=(connection[0]+(self.outer_ground-self.R2+bug)*np.cos(orientation), connection[1]+(self.outer_ground-self.R2+bug)*np.sin(orientation)) # to fix rounding bug bug = 1 flux_line_output_connection = (flux_line_output[0]+bug*np.cos(np.pi+orientation), flux_line_output[1]+bug*np.sin(np.pi+orientation)) remove = gdspy.FlexPath(deepcopy([connection,flux_line_output]), [self.core, self.core], offset=[-self.gap,self.gap], layer=self.layer_configuration.total_layer) if 'mirror' in self.transformations: flux_line_output_connection = mirror_point(flux_line_output_connection, self.transformations['mirror'][0], self.transformations['mirror'][1]) orientation = np.arctan2(flux_line_output_connection[1] - self.center[1], flux_line_output_connection[0] - self.center[0])+np.pi if 'rotate' in self.transformations: flux_line_output_connection = rotate_point(flux_line_output_connection, self.transformations['rotate'][0], self.transformations['rotate'][1]) orientation = np.arctan2(flux_line_output_connection[1] - self.center[1],flux_line_output_connection[0] - self.center[0])+np.pi if self.transformations == {}: orientation=orientation+np.pi self.terminals['flux_line'] = DesignTerminal(flux_line_output_connection, orientation, g=self.grounded.w, s=self.grounded.g, w=self.grounded.w, type='cpw') return {'positive': result, 'remove': remove, }
def test_flexpath2(target): cell = gdspy.Cell('test', True) fp = gdspy.FlexPath( [(0, 0), (0.5, 0), (1, 0), (1, 1), (0, 1), (-1, -2), (-2, 0)], 0.05, [0, -0.1, 0, 0.1], corners=['natural', 'circular bend', 'circular bend', 'circular bend'], ends=['flush', 'extended', (0.1, 0.2), 'round'], tolerance=1e-4, layer=[0, 1, 1, 2], bend_radius=[0, 0.3, 0.3, 0.2], max_points=10) cell.add(fp) assertsame(target['FlexPath2'], cell) cell = gdspy.Cell('test2', True)
def test_flexpath2(target): cell = gdspy.Cell("test") fp = gdspy.FlexPath( [(0, 0), (0.5, 0), (1, 0), (1, 1), (0, 1), (-1, -2), (-2, 0)], 0.05, [0, -0.1, 0, 0.1], corners=["natural", "circular bend", "circular bend", "circular bend"], ends=["flush", "extended", (0.1, 0.2), "round"], tolerance=1e-4, layer=[0, 1, 1, 2], bend_radius=[0, 0.3, 0.3, 0.2], max_points=10, ) cell.add(fp) assertsame(target["FlexPath2"], cell)
def test_flexpath_gdsiipath(): cells = [] for gdsii_path in [True, False]: cells.append(gdspy.Cell(str(gdsii_path))) fp = gdspy.FlexPath( [(0, 0), (0.5, 0), (1, 0), (1, 1), (0, 1), (-1, -2), (-2, 0)], 0.05, [-0.1, 0.1], corners=["natural", "circular bend"], ends=["extended", (0.1, 0.2)], layer=[0, 1], bend_radius=[0, 0.3], gdsii_path=gdsii_path, ) cells[-1].add(fp) assertsame(*cells)