Пример #1
0
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)
Пример #2
0
def test_top_level_3(tree):
    lib, c = tree
    c[7].add(gdstk.Reference(c[0]))
    c[3].add(gdstk.Reference(c[4]))
    c[2].add(gdstk.Reference(c[6]))
    c[1].add(gdstk.Reference(c[7]))
    assert lib.top_level() == []
Пример #3
0
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)
Пример #4
0
def mach_zehnder_interferometer(lib):
    cell = lib.new_cell("MZI")
    cell.add(gdstk.Reference("Directinal Coupler", (0, 0)))
    cell.add(gdstk.Reference("Directinal Coupler", (75, 0)))

    points = numpy.array([(5, 1), (25, 1), (25, 40), (55, 40), (55, 1),
                          (75, 1)])
    arm1 = gdstk.FlexPath(points,
                          0.5,
                          bend_radius=15,
                          gdsii_path=True,
                          layer=1)
    points[:, 1] *= -1
    arm2 = gdstk.FlexPath(points,
                          0.5,
                          bend_radius=15,
                          gdsii_path=True,
                          layer=1)
    points = numpy.array([(25, 20), (25, 40), (55, 40), (55, 20)])
    heater1 = gdstk.FlexPath(points,
                             2,
                             bend_radius=15,
                             gdsii_path=True,
                             layer=10)
    points[:, 1] *= -1
    heater2 = gdstk.FlexPath(points,
                             2,
                             bend_radius=15,
                             gdsii_path=True,
                             layer=10)
    cell.add(arm1, arm2, heater1, heater2)
Пример #5
0
def make_first_lib(filename):
    lib = gdstk.Library("First")
    main = lib.new_cell("Main")
    main.add(*gdstk.text("First library", 10, (0, 0)))
    ref1 = lib.new_cell("Square")
    ref1.add(gdstk.rectangle((-15, 0), (-5, 10)))
    main.add(gdstk.Reference(ref1))
    ref2 = lib.new_cell("Circle")
    ref2.add(gdstk.ellipse((0, 0), 4))
    ref1.add(gdstk.Reference(ref2, (-10, 5)))
    lib.write_gds(filename)
Пример #6
0
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
Пример #7
0
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)
Пример #8
0
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],
        ]
Пример #9
0
def make_second_lib(filename):
    lib = gdstk.Library("Second")
    main = lib.new_cell("Main")
    main.add(*gdstk.text("Second library", 10, (0, 0)))
    ref = lib.new_cell("Circle")
    ref.add(gdstk.ellipse((-10, 5), 5))
    main.add(gdstk.Reference(ref))
    lib.write_gds(filename)
Пример #10
0
def test_noreference():
    name = "ca_noreference"
    ref = gdstk.Reference(name, (1, -1), numpy.pi / 2, 2.1, True)
    assert ref.cell == name
    assert ref.bounding_box() is None
    assert ref.origin == (1, -1)
    assert ref.rotation == numpy.pi / 2
    assert ref.magnification == 2.1
    assert ref.x_reflection == True
Пример #11
0
def bench_gdstk(output=None):
    p = gdstk.Polygon([(0, 0), (1, 0), (0, 1)])
    fp = gdstk.FlexPath([(-1, 0.5), (1, 0), (0.5, -0.5)], [0.1, 0.1], 0.3, ends="round")
    rp = gdstk.RobustPath((0, 0), [0.1, 0.1], 0.3).interpolation(
        [(2, 0.5), (2, 1), (-1, 4)]
    )
    c1 = gdstk.Cell("REF")
    c1.add(p, fp, rp)
    r1 = gdstk.Reference(
        c1, columns=3, rows=2, spacing=(2, 2), rotation=30 * numpy.pi / 180
    )
    r2 = gdstk.Reference(c1, origin=(8, 0), columns=5, rows=4, spacing=(2, 2))
    r3 = gdstk.Reference(c1, origin=(9, 1), columns=4, rows=3, spacing=(2, 2))
    c2 = gdstk.Cell("MAIN")
    c2.add(r1, r2, r3)
    bb = c2.bounding_box()
    if output:
        c2.add(gdstk.rectangle(*bb, layer=1))
        c2.write_svg(output, 100)
Пример #12
0
def test_x_reflection():
    c = gdstk.Cell("test")
    ref = gdstk.Reference(c, x_reflection=False)
    assert not ref.x_reflection

    ref.x_reflection = True
    assert ref.x_reflection

    ref.x_reflection = False
    assert not ref.x_reflection
Пример #13
0
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,
    )
Пример #14
0
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)
Пример #15
0
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
Пример #16
0
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)
Пример #17
0
def test_gds_array(tmpdir):
    lib = gdstk.Library("Library")
    ref_cell = lib.new_cell("Base")
    ref_cell.add(*gdstk.text("F", 1, (0, 0)))

    for rect in (True, False):
        for cols in (1, 3):
            for rows in (1, 3):
                if cols * rows == 1:
                    continue
                for dx in (-3, 0, 3):
                    for dy in (-4, 0, 4):
                        if rect:
                            rep = gdstk.Repetition(columns=cols,
                                                   rows=rows,
                                                   spacing=(dx, dy))
                        else:
                            rep = gdstk.Repetition(columns=cols,
                                                   rows=rows,
                                                   v1=(dx, 0),
                                                   v2=(0, dy))
                        for rot in range(-3, 4):
                            for refl in (True, False):
                                cell = lib.new_cell(
                                    f"{'RECT' if rect else 'REGL'}"
                                    f"_{cols}_{rows}_{dx}_{dy}"
                                    f"_{rot}{'_X' if refl else ''}")
                                ref = gdstk.Reference(
                                    ref_cell,
                                    (-0.5, -1),
                                    0.5 * numpy.pi * rot,
                                    x_reflection=refl,
                                )
                                ref.repetition = rep
                                cell.add(ref)

    fname = str(tmpdir.join("aref_test.gds"))
    lib.write_gds(fname)
    lib2 = gdstk.read_gds(fname)

    cell_dict = {cell.name: cell for cell in lib.cells}
    for cell in lib2.cells:
        if len(cell.references) == 0:
            continue
        assert len(cell.references) == 1
        assert cell.references[0].repetition.size > 1
        assert cell.name in cell_dict
        polygons1 = cell_dict[cell.name].get_polygons()
        polygons2 = cell.get_polygons()
        assert len(polygons1) == len(polygons2)
        assert_same_shape(polygons1, polygons2)
Пример #18
0
def tree():
    c = [gdstk.Cell("tree_" + str(i)) for i in range(8)]
    lib = gdstk.Library()
    lib.add(*c)
    c[0].add(gdstk.Reference(c[1]))
    c[0].add(gdstk.Reference(c[3]))
    c[1].add(gdstk.Reference(c[2]))
    c[1].add(gdstk.Reference(c[2], columns=2, rows=1, spacing=(0, 0)))
    c[1].add(gdstk.Reference(c[3], columns=2, rows=1, spacing=(0, 0)))
    c[4].add(gdstk.Reference(c[3]))
    c[6].add(gdstk.Reference(c[5], columns=2, rows=1, spacing=(0, 0)))
    return lib, c
Пример #19
0
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"])
Пример #20
0
def sample_library():
    lib = gdstk.Library("lib", unit=2e-3, precision=1e-5)
    c1 = gdstk.Cell("gl_rw_gds_1")
    c1.add(gdstk.rectangle((0, -1), (1, 2), 2, 4))
    c1.add(gdstk.Label("label", (1, -1), "w", 10, 1.5, True, 5, 6))
    c2 = gdstk.Cell("gl_rw_gds_2")
    c2.add(gdstk.ellipse((0, 0), 1))
    c3 = gdstk.Cell("gl_rw_gds_3")
    c3.add(gdstk.Reference(c1, (0, 1), -90, 2, True))
    c4 = gdstk.Cell("gl_rw_gds_4")
    c4.add(
        gdstk.Reference(
            c2,
            (-1, -2),
            columns=2,
            rows=3,
            spacing=(1, 4),
            rotation=numpy.pi,
            magnification=0.5,
            x_reflection=True,
        ))
    lib.add(c1, c2, c3, c4)
    return lib
Пример #21
0
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)
Пример #22
0
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"]
Пример #23
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)
Пример #24
0
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)
Пример #25
0
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)))
Пример #26
0
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))
    path = gdstk.FlexPath([(-5, 0), (0, -5), (5, 0)], 1, gdsii_path=True)
    main_cell = gdstk.Cell("MAIN")
    main_cell.add(array_ref, path)
    bbox = main_cell.bounding_box()
    # print(bbox)
    polygon_bb = gdstk.rectangle(*bbox, datatype=1)
    main_cell.name = "bounding_box"
    return main_cell.add(polygon_bb)
Пример #27
0
def test_label_bounding_box():
    c = gdstk.Cell("CELL")
    l = gdstk.Label("Label", (2, 3))
    c.add(l)
    bb = c.bounding_box();
    assert bb[0][0] == 2 and bb[0][1] == 3
    assert bb[1][0] == 2 and bb[1][1] == 3
    ref = gdstk.Reference(c, (-1, 1))
    bb = ref.bounding_box()
    assert bb[0][0] == 1 and bb[0][1] == 4
    assert bb[1][0] == 1 and bb[1][1] == 4
    ang = numpy.pi / 4
    x = ref.origin[0] + l.origin[0] * numpy.cos(ang) - l.origin[1] * numpy.sin(ang)
    y = ref.origin[1] + l.origin[0] * numpy.sin(ang) + l.origin[1] * numpy.cos(ang)
    ref.rotation = ang
    bb = ref.bounding_box()
    assert_close(bb, ((x, y), (x, y)))
Пример #28
0
def test_bb_robustpath_repetition():
    pth = gdstk.RobustPath(0.5j, 1).segment((1, 0.5))
    pth.repetition = gdstk.Repetition(x_offsets=(1, 3, -2))
    c_pth = gdstk.Cell("G")
    c_pth.add(pth)
    assert_close(c_pth.bounding_box(), ((-2, 0), (4, 1)))
    ref = gdstk.Reference(c_pth)
    ref.repetition = gdstk.Repetition(y_offsets=(-1, 2, -4))
    c_ref = gdstk.Cell("H")
    c_ref.add(ref)
    assert_close(c_ref.bounding_box(), ((-2, -4), (4, 3)))
    ref.rotation = numpy.pi / 4
    a = (-2 + 1j) * numpy.exp(0.25j * numpy.pi)
    b = (-2 + 0j) * numpy.exp(0.25j * numpy.pi)
    c = (4 + 0j) * numpy.exp(0.25j * numpy.pi)
    d = (4 + 1j) * numpy.exp(0.25j * numpy.pi)
    assert_close(c_ref.bounding_box(),
                 ((a.real, b.imag - 4), (c.real, d.imag + 2)))
Пример #29
0
def test_bb_flexpath_repetition():
    pth = gdstk.FlexPath([0.5 + 0j, 0.5 + 1j], 1)
    pth.repetition = gdstk.Repetition(x_offsets=(1, 3, -2))
    c_pth = gdstk.Cell("E")
    c_pth.add(pth)
    assert_close(c_pth.bounding_box(), ((-2, 0), (4, 1)))
    ref = gdstk.Reference(c_pth)
    ref.repetition = gdstk.Repetition(y_offsets=(-1, 2, -4))
    c_ref = gdstk.Cell("F")
    c_ref.add(ref)
    assert_close(c_ref.bounding_box(), ((-2, -4), (4, 3)))
    ref.rotation = numpy.pi / 4
    a = (-2 + 1j) * numpy.exp(0.25j * numpy.pi)
    b = (-2 + 0j) * numpy.exp(0.25j * numpy.pi)
    c = (4 + 0j) * numpy.exp(0.25j * numpy.pi)
    d = (4 + 1j) * numpy.exp(0.25j * numpy.pi)
    assert_close(c_ref.bounding_box(),
                 ((a.real, b.imag - 4), (c.real, d.imag + 2)))
Пример #30
0
def test_bb_polygon_repetition():
    pol = gdstk.rectangle((0, 0), (1, 1))
    pol.repetition = gdstk.Repetition(x_offsets=(1, 3, -2))
    c_pol = gdstk.Cell("C")
    c_pol.add(pol)
    assert_close(c_pol.bounding_box(), ((-2, 0), (4, 1)))
    ref = gdstk.Reference(c_pol)
    ref.repetition = gdstk.Repetition(y_offsets=(-1, 2, -4))
    c_ref = gdstk.Cell("D")
    c_ref.add(ref)
    assert_close(c_ref.bounding_box(), ((-2, -4), (4, 3)))
    ref.rotation = numpy.pi / 4
    a = (-2 + 1j) * numpy.exp(0.25j * numpy.pi)
    b = (-2 + 0j) * numpy.exp(0.25j * numpy.pi)
    c = (4 + 0j) * numpy.exp(0.25j * numpy.pi)
    d = (4 + 1j) * numpy.exp(0.25j * numpy.pi)
    assert_close(c_ref.bounding_box(),
                 ((a.real, b.imag - 4), (c.real, d.imag + 2)))