def render_negative(self, positive_layers, negative_layer, slices=20, apply_restrict=True): box = self.total_cell.get_bounding_box() slices_x = np.linspace(box[0][0], box[1][0], slices, endpoint=False)[1:].tolist() slices_y = np.linspace(box[0][1], box[1][1], slices, endpoint=False)[1:].tolist() polygons = { layer_id: gdspy.slice(self.total_cell.get_polygons((layer_id, 0)), slices_x, 0) for layer_id in positive_layers } if apply_restrict: polygons_restrict = gdspy.slice( self.restricted_cell.get_polygons( (self.layer_configuration.restricted_area_layer, 0)), slices_x, 0) for i in range(slices): polygons_slice = { layer_id: gdspy.slice(polygons[layer_id][i], slices_y, 1) for layer_id in positive_layers } if apply_restrict: polygons_restrict_slice = gdspy.slice(polygons_restrict[i], slices_y, 1) for j in range(slices): if apply_restrict: negative = polygons_restrict_slice[j] else: negative = gdspy.Rectangle( (box[0][0] + (box[1][0] - box[0][0]) * i / slices, box[0][1] + (box[1][0] - box[0][0]) * j / slices), (box[0][0] + (box[1][0] - box[0][0]) * (i + 1) / slices, box[0][1] + (box[1][0] - box[0][0]) * (j + 1) / slices)) for layer_id, polygons_slice_y in polygons_slice.items(): negative = gdspy.boolean(negative, polygons_slice_y[j], 'not', layer=negative_layer) negative_filtered = [] if negative is not None: for poly in negative.polygons: if gdspy.Polygon(poly).area() > 0.05: negative_filtered.append(poly) if negative_filtered is not None: self.total_cell.add( gdspy.PolygonSet(negative_filtered, layer=negative_layer))
def test_slice(): poly = gdspy.Path(1, (1, 0), 2, 3).segment(2, "-x") left = gdspy.Path(1, (0, 0), 2, 3).segment(1, "-x") right = gdspy.Path(1, (1, 0), 2, 3).segment(1, "-x") result = gdspy.slice(poly, 0, 0) assert equals(result[0], left) assert equals(result[1], right) bot = gdspy.Path(1, (1, -1.5)).segment(2, "-x") top = gdspy.Path(1, (1, 1.5)).segment(2, "-x") result = gdspy.slice(poly, [0.1, -0.1], 1) assert equals(result[0], bot) assert equals(result[2], top) assert result[1] is None
def cut(ply, position, axis): import spira.all as spira plys = spira.ElementList() gp = ply.commit_to_gdspy() pl = gdspy.slice(objects=[gp], position=position, axis=axis) for p in pl: if len(p.polygons) > 0: plys += spira.Polygon(shape=p.polygons[0]) return plys
def qubitLead(conf: DefaultConfig, test=False): sizes = conf.qubitLeadSizes if test: sizes[2][1] = conf.qubitTestSize gaps = conf.qubitLeadGaps layers = conf.qubitLeadLayers curve = gdspy.Curve(0) for i, size in enumerate(sizes): w1, h1 = size if i == 0: dx = dy = w1 / 2 curve.c(dx, 0, dx, 0, dx, dy).v(h1 - dy) else: dx, dy = (w1 - sizes[i - 1][0]) / 2, gaps[i - 1] curve.c(0, dy / 2, dx, dy / 2, dx, dy).v(h1) curve.h(-sizes[-1][0] / 2) halfLead = gdspy.Polygon(curve.get_points()) lead = join([halfLead, copy(halfLead).mirror([0, 1])]) slice1 = sizes[0][1] + gaps[0] slice2 = slice1 + conf.qubitLeadOverlap coarseLead = gdspy.slice(lead, slice1, 1, layer=layers)[1] fineLead = gdspy.slice(lead, slice2, 1, layer=layers)[0] return coarseLead, fineLead
# Create a rectangle extending the text's bounding box by 1 bb = numpy.array(text.get_bounding_box()) rect = gdspy.Rectangle(bb[0] - 1, bb[1] + 1) # Subtract the text from the rectangle inv = gdspy.boolean(rect, text, "not") draw(gdspy.Cell("boolean_operations").add(inv)) # Slice Operation ring1 = gdspy.Round((-6, 0), 6, inner_radius=4) ring2 = gdspy.Round((0, 0), 6, inner_radius=4) ring3 = gdspy.Round((6, 0), 6, inner_radius=4) # Slice the first ring across x=-3, the second ring across x=-3 # and x=3, and the third ring across x=3 slices1 = gdspy.slice(ring1, -3, axis=0) slices2 = gdspy.slice(ring2, [-3, 3], axis=0) slices3 = gdspy.slice(ring3, 3, axis=0) slices = gdspy.Cell("SLICES") # Keep only the left side of slices1, the center part of slices2 # and the right side of slices3 slices.add(slices1[0]) slices.add(slices2[1]) slices.add(slices3[1]) draw(slices, "slice_operation") # Offset Operation rect1 = gdspy.Rectangle((-4, -4), (1, 1))
# Offset the path shape by 0.5 and add it to the cell. oper_cell.add(gdspy.offset(merged, 1, layer=8)) # ------------------------------------------------------------------ # # SLICING POLYGONS # ------------------------------------------------------------------ # # If there is the need to cut a polygon or set of polygons, it's better # to use the slice function than set up a boolean operation, since it # runs much faster. Slices are multiple cuts perpendicular to an axis. slice_cell = gdspy.Cell('SLICE') original = gdspy.Round((0, 0), 10, inner_radius=5) # Slice the original ring along x = -7 and x = 7. result = gdspy.slice(original, [-7, 7], 0, layer=1) # The result is a tuple of polygon sets, one for each slice. To keep # add the region betwen our 2 cuts, we chose result[1]. slice_cell.add(result[1]) # If the cut needs to be at an angle we can rotate the geometry, slice # it, and rotate back. original = gdspy.PolyPath([(12, 0), (12, 8), (28, 8), (28, -8), (12, -8), (12, 0)], 1, 3, 2) original.rotate(numpy.pi / 3, center=(20, 0)) result = gdspy.slice(original, 7, 1, layer=2) result[0].rotate(-numpy.pi / 3, center=(20, 0)) slice_cell.add(result[0]) # ------------------------------------------------------------------ #
def wafer(conf: DefaultConfig): circle = gdspy.Round([0, 0], 1, layer=conf.waferLayer, tolerance=1e-3).scale(conf.waferRadius) wafer = gdspy.slice(circle, conf.waferSliceAt, 0)[1] return [wafer]
oper_cell.add(gdspy.offset(merged, 1, layer=8)) ## ------------------------------------------------------------------ ## ## SLICING POLYGONS ## ------------------------------------------------------------------ ## ## If there is the need to cut a polygon or set of polygons, it's better ## to use the slice function than set up a boolean operation, since it ## runs much faster. Slices are multiple cuts perpendicular to an axis. slice_cell = gdspy.Cell('SLICE') original = gdspy.Round((0, 0), 10, inner_radius=5) ## Slice the original ring along x = -7 and x = 7. result = gdspy.slice(original, [-7, 7], 0, layer=1) ## The result is a tuple of polygon sets, one for each slice. To keep ## add the region betwen our 2 cuts, we chose result[1]. slice_cell.add(result[1]) ## If the cut needs to be at an angle we can rotate the geometry, slice ## it, and rotate back. original = gdspy.PolyPath([(12, 0), (12, 8), (28, 8), (28, -8), (12, -8), (12, 0)], 1, 3, 2) original.rotate(numpy.pi / 3, center=(20, 0)) result = gdspy.slice(original, 7, 1, layer=2) result[0].rotate(-numpy.pi / 3, center=(20, 0)) slice_cell.add(result[0])
c=gdsii.extract(layout.cell_dict.keys()[0]) #filter the polygons by their layer. Result is a dictionary of form {Material:[polygons]} #probably fails if one layer cotains more than one polygon filtered=gdsm.filter_elements_by_layer(c.elements) #define an output cell cut=gdspy.Cell('Fractured') #define an x array of 25nm sampling width for the tip. Omit the last sample, where width would = 0 tipArray=np.linspace(139., 149.950, 439) layernum={'SiN':0,'Au':1,'Pd':2,'Au passive':3,'Pd passive':4} #for all materials, perform a slice operation every 1um along the polygon. #Three polygons result per slice operation, (left, slice, right), we only care #about the slice (element[1]) for key, val in filtered.iteritems(): for n in range(0,139): cut.add(gdspy.slice(val, [n,n+1], 0, layer=layernum[key])[1]) #as above but with 25nm segments for key, val in filtered.iteritems(): for n in tipArray: cut.add(gdspy.slice(val, [n,n+0.025], 0, layer=layernum[key])[1]) OutputCell=gdspy.GdsLibrary() OutputCell.add(cut) OutputCell.write_gds(theDir+theFile)
SiN_poly=[] Au_poly=[] Pd_poly=[] for n in c.elements: if n.layer==0: SiN_poly.append(n) if n.layer==1: Au_poly.append(n) if n.layer==2: Pd_poly.append(n) cut=gdspy.Cell('GAH') for n in range(0,139): SiN_cut=gdspy.slice(SiN_poly, [n,n+1], 0, layer=0) Au_cut=gdspy.slice(Au_poly, [n,n+1], 0, layer=1) Pd_cut=gdspy.slice(Pd_poly, [n,n+1], 0, layer=2) cut.add(SiN_cut[1]) cut.add(Au_cut[1]) cut.add(Pd_cut[1]) tipArray=np.linspace(139., 150., 441) for n in tipArray: SiN_cut=gdspy.slice(SiN_poly, [n,n+0.025], 0, layer=0) Au_cut=gdspy.slice(Au_poly, [n,n+0.025], 0, layer=1) Pd_cut=gdspy.slice(Pd_poly, [n,n+0.025], 0, layer=2) cut.add(SiN_cut[1]) cut.add(Au_cut[1]) cut.add(Pd_cut[1])