def convex_hull_image(): polygons = gdstk.text("F", 10, (0, 0)) f_cell = gdstk.Cell("F_CELL") f_cell.add(*polygons) array_ref = gdstk.Reference( f_cell, rotation=numpy.pi / 4, columns=3, rows=2, spacing=(8, 10) ) path = gdstk.FlexPath([(-5, 0), (0, -5), (5, 0)], 1, simple_path=True) main_cell = gdstk.Cell("MAIN") main_cell.add(array_ref, path) hull = main_cell.convex_hull() error = hull - numpy.array( [ [1.14904852, 27.66555281], [-12.81631041, 13.70019389], [-5.35355339, -0.35355339], [0.0, -5.70710678], [5.35355339, -0.35355339], [11.3137085, 13.96535893], [9.98788328, 17.94283457], [8.66205807, 20.15254326], ] ) assert numpy.abs(error).max() < 1e-8 polygon_hull = gdstk.Polygon(hull, datatype=1) main_cell.name = "convex_hull" return main_cell.add(polygon_hull)
def test_copy_transform(proof_cells): ref_cell1 = gdstk.Cell("Reference 1") ref_cell1.add(*gdstk.text("F.", 10, (0, 0))) ref_cell1.add(gdstk.Label("LaBeL", (2.4, 8.7), "s")) ref_cell1.add( gdstk.FlexPath(8 + 4j, 1, simple_path=True, layer=3).arc(2, 0, numpy.pi / 2)) ref_cell1.add( gdstk.RobustPath(7.5 + 7j, 1, simple_path=True, layer=4).bezier([-2 + 1j, -2 + 3j, 4j, 6j, -3 + 6j], relative=True)) ref_cell2 = gdstk.Cell("Reference 2") ref_cell2.add(*gdstk.text("^", 10, (0, 5), layer=1)) ref_cell2.add(gdstk.Reference(ref_cell1)) cell = gdstk.Cell("Original cell") cell.add(gdstk.rectangle((-1, -0.5), (1, 0.5), layer=2)) cell.add(gdstk.Reference(ref_cell2)) cell.add(gdstk.Reference(ref_cell1, (10, 7), numpy.pi / 4, 0.5, True)) cell.add( gdstk.Reference(ref_cell1, (-7, 15), -numpy.pi / 3, 0.5, True, 3, 2, (5, 4))) cell.add( gdstk.Reference(ref_cell2, (-7, 23), numpy.pi / 3, 0.5, True, 3, 2, (5, 8))) cell_copy = cell.copy("Cell.copy", (-10, -10), numpy.pi / 2, 2, True).flatten() for path in cell_copy.paths: cell_copy.add(*path.to_polygons()) assert_same_shape(proof_cells["Cell.copy"].polygons, cell_copy.polygons)
def init_image(): polygons = gdstk.text("F", 10, (0, 0)) f_cell = gdstk.Cell("F_CELL") f_cell.add(*polygons) ref = gdstk.Reference(f_cell, rotation=numpy.pi / 2) array_ref = gdstk.Reference(f_cell, columns=3, rows=2, spacing=(8, 10)) return gdstk.Cell("init").add(ref, array_ref)
def bench_gdstk(output=None): poly = gdstk.regular_polygon((0, 0), 1.5, 6, layer=1) orig = gdstk.Cell("OFF") orig.add(poly) ref = gdstk.Reference(orig, (-3, 5), columns=4, spacing=(2, 0)) off = gdstk.offset([poly, ref], 0.2, "bevel", layer=0) boo = gdstk.boolean(off, [poly, ref], "not", layer=2) if output: cell = gdstk.Cell("MAIN") cell.add(ref, poly, *off, *boo) cell.write_svg(output, 50)
def test_notempty(): name = "ca_notempty" c = gdstk.Cell(name) ref = gdstk.Reference(c, (1, -1), numpy.pi / 2, 2, True, 2, 3, (3, 2)) ref.origin = (0, 0) c.add(gdstk.rectangle((0, 0), (1, 2), 2, 3)) assert_close(ref.bounding_box(), ((0, 0), (8, 5))) assert_same_shape( [gdstk.rectangle((0, 0), (8, 2)), gdstk.rectangle((0, 3), (8, 5))], gdstk.Cell("TMP").add(ref).flatten().polygons, )
def flatten_image(): poly1 = gdstk.Polygon([(0, 0), (1, 0), (0.5, 1)]) cell1 = gdstk.Cell("CELL_1") cell1.add(poly1) poly2 = gdstk.Polygon([(1, 0), (1.5, 1), (0.5, 1)], layer=1) ref = gdstk.Reference(cell1, columns=2, rows=2, spacing=(1, 1)) cell2 = gdstk.Cell("CELL_2") cell2.add(poly2, ref) # print(len(cell2.polygons), len(cell2.references), len(cell2.dependencies(True))) cell2.flatten() # print(len(cell2.polygons), len(cell2.references), len(cell2.dependencies(True))) cell2.name = "flatten" return cell2
def bounding_box_image(): polygons = gdstk.text("F", 10, (0, 0)) f_cell = gdstk.Cell("F_CELL") f_cell.add(*polygons) array_ref = gdstk.Reference(f_cell, rotation=numpy.pi / 4, columns=3, rows=2, spacing=(8, 10)) bbox = array_ref.bounding_box() # print(bbox) polygon_bb = gdstk.rectangle(*bbox, datatype=1) return gdstk.Cell("bounding_box").add(array_ref, polygon_bb)
def read_rawcells_example(): cell1 = gdstk.Cell("CELL_1") cell1.add(gdstk.rectangle((0, 0), (2, 1))) cell2 = gdstk.Cell("CELL_2") cell2.add(gdstk.Reference(cell1, (-1, 0))) library = gdstk.Library() library.add(cell1, cell2) library.write_gds("test.gds") raw_cells = gdstk.read_rawcells("test.gds") assert tuple(sorted(raw_cells.keys())) == ("CELL_1", "CELL_2") assert len(raw_cells["CELL_1"].dependencies(True)) == 0 assert len(raw_cells["CELL_2"].dependencies(True)) == 1 deps = raw_cells["CELL_2"].dependencies(True) assert deps[0] is raw_cells["CELL_1"]
def bench_gdstk(output=None): c1 = gdstk.Cell("REF") c1.add(gdstk.rectangle((0, 0), (10, 10))) c1.add( gdstk.FlexPath([(0, 0), (10, 0), (10, 10), (0, 10)], [0.1, 0.1], 0.3, layer=1)) c1.add(gdstk.Label("Label", (5, 5), anchor='o')) c2 = gdstk.Cell("MAIN") c2.add(gdstk.Reference(c1, columns=3, rows=2, spacing=(20, 20))) c2.flatten() c1.remove(*c1.polygons, *c1.paths, *c1.labels) if output: c2.write_svg(output, 10)
def read_rawcells_example(): cell1 = gdstk.Cell("CELL_1") cell1.add(gdstk.rectangle((0, 0), (2, 1))) cell2 = gdstk.Cell("CELL_2") cell2.add(gdstk.Reference(cell1, (-1, 0))) library = gdstk.Library() library.add(cell1, cell2) library.write_gds("test.gds") raw_cells = gdstk.read_rawcells("test.gds") print(raw_cells.keys()) print(len(raw_cells["CELL_1"].dependencies(True))) print(len(raw_cells["CELL_2"].dependencies(True))) deps = raw_cells["CELL_2"].dependencies(True) print(deps[0] is raw_cells["CELL_1"])
def tree(): p1 = gdstk.Polygon(((0, 0), (0, 1), (1, 0)), 0, 0) p2 = gdstk.Polygon(((2, 0), (2, 1), (1, 0)), 1, 1) l1 = gdstk.Label("label1", (0, 0), layer=11) l2 = gdstk.Label("label2", (2, 1), layer=12) c1 = gdstk.Cell("tree1") c1.add(p1) c1.add(l1) c2 = gdstk.Cell("tree2") c2.add(l2) c2.add(p2) c2.add(gdstk.Reference(c1)) c3 = gdstk.Cell("tree3") c3.add(gdstk.Reference(c2, (0, 0), columns=3, rows=2, spacing=(3, 3))) return c3, c2, c1
def horizontal_image(): path = gdstk.FlexPath((0, 0), 0.2) path.horizontal(2, width=0.4, relative=True) path.horizontal(2, offset=[0.4], relative=True) path.horizontal(2, relative=True) # print(path.spine()) return gdstk.Cell("horizontal").add(path)
def grating(period, fill_frac=0.5, length=20, width=25, layer=0, datatype=0, cell_name="Grating"): """ Straight grating: Args: period: Grating period. fill_frac: Filling fraction of the teeth (wrt period). length: Length of the grating. width: Width of the grating. layer: GDSII layer number datatype: GDSII data type number Return: gdstk.Cell """ result = gdstk.Cell(cell_name) x = width / 2 w = period * fill_frac result.add( gdstk.rectangle((-x, y * period), (x, y * period + w), layer=layer, datatype=datatype) for y in range(int(length / period))) return result
def bounding_box_image(): polygons = gdstk.text("F", 10, (0, 0)) f_cell = gdstk.Cell("F_CELL") f_cell.add(*polygons) array_ref = gdstk.Reference(f_cell, rotation=numpy.pi / 4, columns=3, rows=2, spacing=(8, 10)) bbox = array_ref.bounding_box() assert bbox == ( (-12.816310409006173, 1.7677669529663689), (11.313708498984761, 27.66555281392367), ) polygon_bb = gdstk.rectangle(*bbox, datatype=1) return gdstk.Cell("bounding_box").add(array_ref, polygon_bb)
def slice_image(): triangle = gdstk.regular_polygon((-10, 0), 8, 3) ring = gdstk.ellipse((10, 0), 8, 5, layer=1) result = gdstk.slice([triangle, ring], (-10, -5, 0, 6, 14), "x") assert len(result) == 6 assert all(len(polys) == s for polys, s in zip(result, [1, 1, 0, 1, 2, 1])) return gdstk.Cell("slice").add(*[p for polys in result for p in polys])
def test_properties(): for obj in [ gdstk.Polygon([-1 + 0j, -2j, 3 + 0j, 4j]), gdstk.FlexPath((0j, 1j), 0.1), gdstk.RobustPath(0j, 0.1), gdstk.Label("Label", 0j), gdstk.Reference("EMPTY"), gdstk.Cell("CELL"), gdstk.Library("Name"), ]: assert len(obj.properties) == 0 assert obj.get_property("None") is None obj.set_property("FIRST", 1) obj.set_property("SECOND", 2.0) obj.set_property("THIRD", -3) obj.set_property("FOURTH", [1, 2.0, -3, "FO", b"UR\x00TH\x00"]) obj.set_property("FIRST", -1) assert obj.get_property("FIRST") == [-1] obj.delete_property("THIRD") assert obj.properties == [ ["FIRST", -1], ["FOURTH", 1, 2.0, -3, b"FO", b"UR\x00TH\x00"], ["SECOND", 2.0], ["FIRST", 1], ] obj.properties = ( ("ONE", -1), ("TWO", -2.3e-4, "two"), ("Three", b"\xFF\xEE", 0), ) assert obj.properties == [ ["ONE", -1], ["TWO", -2.3e-4, b"two"], ["Three", b"\xFF\xEE", 0], ]
def bench_gdstk(output=None): p = gdstk.Polygon([(0, 0), (1, 0), (0, 1)]) fp = gdstk.FlexPath([(0, 0), (1, 0), (0.5, -0.5)], 0.1, ends="round") c1 = gdstk.Cell("REF") c1.add(p, fp) r = gdstk.Reference(c1, columns=3, rows=2, spacing=(2, 2), rotation=30 * numpy.pi / 180) c2 = gdstk.Cell("MAIN") c2.add(r) bb = c2.bounding_box() if output: c2.add(gdstk.rectangle(*bb, layer=1)) c2.write_svg(output, 100)
def segment_image(): path = gdstk.RobustPath((0, 0), 0.2, tolerance=1e-3) path.segment((5, 0), 1.0) path.segment((5, 3), (0.2, "constant")) path.segment((0, 3), (1.2, "smooth")) path.segment((0, 7), lambda u: 0.2 + 0.8 * numpy.cos(2 * numpy.pi * u)**2) return gdstk.Cell("segment").add(path)
def bench_gdstk(output=None): # Offset signs must be inverted to be compatible with gdspy! rp = gdstk.RobustPath( (50, 0), [2, 0.5, 1, 1], [0, 0, 1, -1], ends=["extended", "round", "flush", "flush"], layer=[0, 2, 1, 1], datatype=[0, 1, 2, 3], ) rp.segment((45, 0)) rp.segment( (5, 0), width=[lambda u: 2 + 16 * u * (1 - u), 0.5, 1, 1], offset=[ 0, lambda u: -8 * u * (1 - u) * numpy.cos(12 * numpy.pi * u), lambda u: 1 + 8 * u * (1 - u), lambda u: -1 - 8 * u * (1 - u), ], ) rp.segment((0, 0)) rp.interpolation( [(5, 10)], angles=[0.5 * numpy.pi, 0], width=0.5, offset=[0.25, -0.25, 0.75, -0.75], ) rp.bezier([(0, 10), (10, 10), (10, -10), (20, -10), (20, 0), (30, 0)], relative=True) if output: cell = gdstk.Cell("MAIN") cell.add(rp) cell.write_svg(output, 10)
def bezier_image(): path = gdstk.RobustPath((0, 0), 0.2, tolerance=1e-3) path.bezier( [(4, 1), (4, 3), (0, 5), (-4, 3), (-4, -2), (0, -4)], width=lambda u: 0.2 + 0.8 * u**2, ) return gdstk.Cell("bezier").add(path)
def segment_image(): points = [(1, 0), (1, 1), (-1, 1), (-1, -1), (1, -1)] path_1 = gdstk.FlexPath((0, 0), 0.2) path_1.segment(points, 0.6) path_2 = gdstk.FlexPath((3, 0), [0.1, 0.1], 0.2) path_2.segment(points, offset=0.6, relative=True) return gdstk.Cell("segment").add(path_1, path_2)
def slice_image(): triangle = gdstk.regular_polygon((-10, 0), 8, 3) ring = gdstk.ellipse((10, 0), 8, 5, layer=1) result = gdstk.slice([triangle, ring], (-10, -5, 0, 6, 14), "x") # print(len(result)) # print([len(polys) for polys in result]) return gdstk.Cell("slice").add(*[p for polys in result for p in polys])
def cubic_image(): curve = gdstk.Curve((0, 0), tolerance=1e-3) curve.cubic([(1, -2), (2, -2), (3, 0)]) curve.cubic([(2.7, 1), (1.8, 1), (1.5, 0), (1.3, -0.2), (0.3, -0.2), (0, 0)]) polygon = gdstk.Polygon(curve.points()) return gdstk.Cell("cubic").add(polygon)
def segment_image(): curve = gdstk.Curve((1, 0)) curve.segment((0, 1)) curve.segment([0j, -1 + 0j]) curve.segment([(0, -1), (2, -1)], True) polygon = gdstk.Polygon(curve.points()) return gdstk.Cell("segment").add(polygon)
def fracture_image(): polygon = gdstk.racetrack((0, 0), 30, 60, 40, tolerance=1e-3) poly_list = polygon.fracture() assert len(poly_list) == 10 assert all(p.size == s for p, s in zip( poly_list, [102, 103, 103, 101, 101, 102, 102, 103, 103, 102])) return gdstk.Cell("fracture").add(*poly_list)
def init_image(): curve = gdstk.Curve((3, 4), tolerance=1e-3) curve.segment((1, 1), True) curve.turn(1, -numpy.pi / 2) curve.segment((1, -1), True) polygon = gdstk.Polygon(curve.points()) return gdstk.Cell("init").add(polygon)
def bench_gdstk(output=None): r = 0.15 c1 = gdstk.Curve((1 / 2 - r, -(3**0.5) / 6), 1e-3) c1.arc(r, numpy.pi, numpy.pi * 2 / 3) c1.segment((1 - 2 * r) * numpy.exp(1j * numpy.pi * 2 / 3), relative=True) c1.arc(r, -numpy.pi / 3, -numpy.pi * 2 / 3) c1.segment((1 - 2 * r) * numpy.exp(-1j * numpy.pi * 2 / 3), relative=True) c1.arc(r, numpy.pi / 3, 0) p1 = gdstk.Polygon(c1.points()) c2 = gdstk.Curve((0, -r), 1e-3) c2.interpolation( [ 2 * r * numpy.exp(-1j * numpy.pi / 6), r * numpy.exp(1j * numpy.pi / 6), (0, 2 * r), r * numpy.exp(1j * numpy.pi * 5 / 6), 2 * r * numpy.exp(-1j * numpy.pi * 5 / 6), ], cycle=True, ) p2 = gdstk.Polygon(c2.points(), layer=1) if output: cell = gdstk.Cell("MAIN") cell.add(p1, p2) cell.write_svg(output, 300)
def bench_gdstk(output=None): sp1 = gdstk.FlexPath([(0, 0), (3, 0), (3, 2), (5, 3), (3, 4), (0, 4)], 1, gdsii_path=True, datatype=1) sp1.interpolation([(0, 2), (2, 2), (4, 3), (5, 1)], relative=True) sp2 = gdstk.FlexPath( [(12, 0), (8, 0), (8, 3), (10, 2)], [0.3, 0.2, 0.4], 0.5, ends=["extended", "flush", "round"], joins=["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 = gdstk.FlexPath(points, 0.5, bend_radius=5, gdsii_path=True, datatype=4) sp4 = gdstk.FlexPath(points, 0.5, gdsii_path=True, layer=1, datatype=5) if output: cell = gdstk.Cell("MAIN") cell.add(sp1, sp2, sp3, sp4) cell.write_svg(output, 30)
def test_bb_label_repetition(): lbl = gdstk.Label("label", (1, 2)) lbl.repetition = gdstk.Repetition(x_offsets=(1, 3, -2)) c_lbl = gdstk.Cell("A") c_lbl.add(lbl) assert_close(c_lbl.bounding_box(), ((-1, 2), (4, 2))) ref = gdstk.Reference(c_lbl) ref.repetition = gdstk.Repetition(y_offsets=(-1, 2, -4)) c_ref = gdstk.Cell("B") c_ref.add(ref) assert_close(c_ref.bounding_box(), ((-1, -2), (4, 4))) ref.rotation = numpy.pi / 4 a = (-1 + 2j) * numpy.exp(0.25j * numpy.pi) b = (4 + 2j) * numpy.exp(0.25j * numpy.pi) assert_close(c_ref.bounding_box(), ((a.real, a.imag - 4), (b.real, b.imag + 2)))
def test_filter(): polys = [ gdstk.rectangle((0, 0), (1, 1), layer=l, datatype=t) for t in range(3) for l in range(3) ] labels = [ gdstk.Label("FILTER", (1, 1), layer=l, texttype=t) for t in range(3) for l in range(3) ] paths = [ gdstk.FlexPath([0j, 1j], [0.1, 0.1, 0.1], 0.5, layer=[0, 1, 2], datatype=t) for t in range(3) ] + [ gdstk.RobustPath(0j, [0.1, 0.1], 0.5, layer=[1, 2], datatype=t) for t in range(3) ] layers = [1, 2] types = [0] for op, test in [ ("and", lambda a, b: a and b), ("or", lambda a, b: a or b), ("xor", lambda a, b: (a and not b) or (b and not a)), ("nand", lambda a, b: not (a and b)), ("nor", lambda a, b: not (a or b)), ("nxor", lambda a, b: not ((a and not b) or (b and not a))), ]: path_results = [ [test(a in layers, b in types) for a, b in zip(path.layers, path.datatypes)] for path in paths ] cell = gdstk.Cell(op) cell.add(*polys, *labels, *paths) cell.filter(layers, types, op) cell_polys = cell.polygons for poly in polys: if test(poly.layer in layers, poly.datatype in types): assert poly not in cell_polys else: assert poly in cell_polys cell_labels = cell.labels for label in labels: if test(label.layer in layers, label.texttype in types): assert label not in cell_labels else: assert label in cell_labels cell_paths = cell.paths for path, results in zip(paths, path_results): if all(results): assert path not in cell_paths else: assert path in cell_paths assert len(path.layers) == len(results) - sum(results) assert all( not test(a in layers, b in types) for a, b in zip(path.layers, path.datatypes) )