Esempio n. 1
0
def test_transforms(proof_cells):
    for scale_width in [True, False]:
        path0 = gdstk.RobustPath(
            0j,
            [0.1, 0.2],
            0.3,
            tolerance=1e-4,
            scale_width=scale_width,
        )
        path0.vertical(1).horizontal(0.5).turn(0.4, -numpy.pi,
                                               [0.2, 0.1]).segment(
                                                   (-0.2, 0), relative=True)
        paths = [
            path0,
            path0.copy().mirror((1.5, 0)),
            path0.copy().mirror((1.5, 0), (1.5, 1)),
            path0.copy().scale(2, (3, 0)),
            path0.copy().scale(-2, (-1, 0)),
            path0.copy().rotate(numpy.pi / 2, (2, 1)).translate(0.2, -0.3),
        ]
        assert_same_shape(
            proof_cells[f"RobustPath: scale_width {scale_width}"].polygons,
            paths, 3e-3)
Esempio n. 2
0
def make_proof_lib():
    lib = gdstk.Library("Test Library", unit=1e-6, precision=1e-12)

    cell = lib.new_cell("Polygon.fillet")
    p1 = gdstk.Polygon([(0, 0), (1.2, 0), (1.2, 0.3), (1, 0.3), (1.5, 1),
                        (0, 1.5)])
    p2 = p1.copy().translate(2, 0)
    cell.add(p1.fillet(0.3, tolerance=1e-3))
    cell.add(p2.fillet([0.3, 0, 0.1, 0, 0.5, 10], tolerance=1e-3))

    for scale_width in [True, False]:
        cell = lib.new_cell(f"FlexPath: scale_width {scale_width}")
        path0 = gdstk.FlexPath(
            (0j, 1j, 0.5 + 1j),
            [0.1, 0.2],
            0.3,
            tolerance=1e-4,
            scale_width=scale_width,
        )
        path0.turn(0.4, -numpy.pi, [0.2, 0.1]).segment((-0.2, 0),
                                                       relative=True)
        path1 = path0.copy().mirror((1.5, 0))
        path1.set_layers(1, 1)
        path2 = path0.copy().mirror((1.5, 0), (1.5, 1))
        path2.set_layers(2, 2)
        path3 = path0.copy().scale(2, (3, 0))
        path3.set_layers(3, 3)
        path4 = path0.copy().scale(-2, (-1, 0))
        path4.set_layers(4, 4)
        path5 = path0.copy().rotate(numpy.pi / 2, (2, 1)).translate(0.2, -0.3)
        path5.set_layers(5, 5)
        cell.add(path0, path1, path2, path3, path4, path5)

    for scale_width in [True, False]:
        cell = lib.new_cell(f"RobustPath: scale_width {scale_width}")
        path0 = gdstk.RobustPath(
            0j,
            [0.1, 0.2],
            0.3,
            tolerance=1e-4,
            scale_width=scale_width,
        )
        path0.vertical(1).horizontal(0.5).turn(0.4, -numpy.pi,
                                               [0.2, 0.1]).segment(
                                                   (-0.2, 0), relative=True)
        path1 = path0.copy().mirror((1.5, 0))
        path1.set_layers(1, 1)
        path2 = path0.copy().mirror((1.5, 0), (1.5, 1))
        path2.set_layers(2, 2)
        path3 = path0.copy().scale(2, (3, 0))
        path3.set_layers(3, 3)
        path4 = path0.copy().scale(-2, (-1, 0))
        path4.set_layers(4, 4)
        path5 = path0.copy().rotate(numpy.pi / 2, (2, 1)).translate(0.2, -0.3)
        path5.set_layers(5, 5)
        cell.add(path0, path1, path2, path3, path4, path5)

    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, layer=3).arc(2, 0, numpy.pi / 2))
    ref_cell1.add(
        gdstk.RobustPath(7.5 + 7j, 1,
                         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()
    lib.add(cell_copy)

    gds_outfile = pathlib.Path(__file__).parent / "proof_lib.gds"
    if gds_outfile.exists():
        print(f"Test library {str(gds_outfile)} already exists.")
    else:
        lib.write_gds(gds_outfile)
        print(f"Test library saved as {str(gds_outfile)}.")

    oas_outfile = pathlib.Path(__file__).parent / "proof_lib.oas"
    if oas_outfile.exists():
        print(f"Test library {str(oas_outfile)} already exists.")
    else:
        lib.write_oas(oas_outfile)
        print(f"Test library saved as {str(oas_outfile)}.")
Esempio n. 3
0
def memory_benchmark():
    proc = psutil.Process()
    total = 100000
    print(f"\nMemory usage per object for {total} objects:\n")

    def print_row(*vals, hsep=False):
        columns = [20, 16, 16, 9]
        print(
            "|",
            vals[0].ljust(columns[0]),
            "|",
            " | ".join(v.center(c) for v, c in zip(vals[1:], columns[1:])),
            "|",
        )
        if hsep:
            print(
                "|",
                ":" + "-" * (columns[0] - 1),
                "|",
                " | ".join(":" + "-" * (c - 2) + ":" for c in columns[1:]),
                "|",
            )

    print_row(
        "Object",
        "Gdspy " + gdspy.__version__,
        "Gdstk " + gdstk.__version__,
        "Reduction",
        hsep=True,
    )

    def mem_test(func):
        start_mem = proc.memory_info()
        r = [func(i) for i in range(total)]
        end_mem = proc.memory_info()
        return (end_mem.vms - start_mem.vms) / total, r

    data = []
    gdspy_cell = gdspy.Cell("TEMP", exclude_from_current=True)
    gdstk_cell = gdstk.Cell("TEMP")
    for obj, gdspy_func, gdstk_func in [
        (
            "Rectangle",
            lambda i: gdspy.Rectangle((i, i), (i + 1, i + 1)),
            lambda i: gdstk.rectangle((i, i), (i + 1, i + 1)),
        ),
        (
            "Circle (r = 10)",
            lambda i: gdspy.Round((0, 10 * i), 10),
            lambda i: gdstk.ellipse((0, 10 * i), 10),
        ),
        (
            "FlexPath segment",
            lambda i: gdspy.FlexPath([(i, i + 1), (i + 1, i)], 0.1),
            lambda i: gdstk.FlexPath([(i, i + 1), (i + 1, i)], 0.1),
        ),
        (
            "FlexPath arc",
            lambda i: gdspy.FlexPath([(10 * i, 0)], 0.1).arc(10, 0, numpy.pi),
            lambda i: gdstk.FlexPath([(10 * i, 0)], 0.1).arc(10, 0, numpy.pi),
        ),
        (
            "RobustPath segment",
            lambda i: gdspy.RobustPath((i, i + 1), 0.1).segment((i + 1, i)),
            lambda i: gdstk.RobustPath((i, i + 1), 0.1).segment((i + 1, i)),
        ),
        (
            "RobustPath arc",
            lambda i: gdspy.RobustPath((10 * i, 0), 0.1).arc(10, 0, numpy.pi),
            lambda i: gdstk.RobustPath((10 * i, 0), 0.1).arc(10, 0, numpy.pi),
        ),
        (
            "Label",
            lambda i: gdspy.Label(str(i), (i, i)),
            lambda i: gdstk.Label(str(i), (i, i)),
        ),
        (
            "Reference",
            lambda i: gdspy.CellReference(gdspy_cell, (0, 0)),
            lambda i: gdstk.Reference(gdstk_cell, (0, 0)),
        ),
        (
            "Reference (array)",
            lambda i: gdspy.CellArray(gdspy_cell, (0, 0), 1, 1, (0, 0)),
            lambda i: gdstk.Reference(gdstk_cell, (0, 0), rows=1, columns=1),
        ),
        (
            "Cell",
            lambda i: gdspy.Cell(str(i), exclude_from_current=True),
            lambda i: gdstk.Cell(str(i)),
        ),
    ]:
        gdspy_mem, gdspy_data = mem_test(gdspy_func)
        data.append(gdspy_data)
        gdstk_mem, gdstk_data = mem_test(gdstk_func)
        data.append(gdstk_data)
        print_row(
            obj,
            prefix_format(gdspy_mem, unit="B", base="bin"),
            prefix_format(gdstk_mem, unit="B", base="bin"),
            f"{100 - 100 * gdstk_mem / gdspy_mem:.0f}%",
        )
Esempio n. 4
0
    draw(gdstk.Cell("flexible_paths_2").add(fp3, fp4), path)

    # Flexible Paths 2
    # Straight segment showing the possibility of width and offset changes
    fp5 = gdstk.FlexPath((0, 0), [0.5, 0.5], 1)
    fp5.horizontal(2)
    fp5.horizontal(4, width=0.8, offset=1.8)
    fp5.horizontal(6)
    draw(gdstk.Cell("flexible_paths_3").add(fp5), path)

    # Robust Paths
    # Create 4 parallel paths in different layers
    rp = gdstk.RobustPath(
        (0, 50),
        [2, 0.5, 1, 1],
        [0, 0, -1, 1],
        ends=["extended", "round", "flush", "flush"],
        layer=[1, 0, 2, 2],
    )
    rp.segment((0, 45))
    rp.segment(
        (0, 5),
        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))
Esempio n. 5
0

if __name__ == "__main__":
    # Rectangular repetition
    square = gdstk.regular_polygon((0, 0), 0.2, 4)
    square.repetition = gdstk.Repetition(3, 2, spacing=(1, 1))

    # Regular repetition
    triangle = gdstk.regular_polygon((0, 2.5), 0.2, 3)
    triangle.repetition = gdstk.Repetition(3, 5, v1=(0.4, -0.3), v2=(0.4, 0.2))

    # Explicit repetition
    circle = gdstk.ellipse((3.5, 0), 0.1)
    circle.repetition = gdstk.Repetition(offsets=[(0.5, 1), (2, 0), (1.5, 0.5)])

    # X-explicit repetition
    vline = gdstk.FlexPath([(3, 2), (3, 3.5)], 0.1, gdsii_path=True)
    vline.repetition = gdstk.Repetition(x_offsets=[0.2, 0.6, 1.4, 3.0])

    # Y-explicit repetition
    hline = gdstk.RobustPath((3, 2), 0.05, gdsii_path=True)
    hline.segment((6, 2))
    hline.repetition = gdstk.Repetition(y_offsets=[0.1, 0.3, 0.7, 1.5])

    main = gdstk.Cell("Main")
    main.add(square, triangle, circle, vline, hline)
    main.name = "repetitions"
    path = pathlib.Path(__file__).parent.absolute() / "how-tos"
    path.mkdir(parents=True, exist_ok=True)
    draw(main, path)
Esempio n. 6
0
def arc_image():
    path = gdstk.RobustPath((0, 0), [0.2, 0.3], 0.4, tolerance=1e-3)
    path.vertical(5)
    path.arc(2.5, numpy.pi, 0)
    path.arc((3, 5), -numpy.pi, -numpy.pi / 2)
    return gdstk.Cell("arc").add(path)
Esempio n. 7
0
def cubic_smooth_image():
    path = gdstk.RobustPath((0, 0), 0.2, tolerance=1e-3)
    path.cubic([(0.5, 0.8), (0.5, 2.2), (0, 3)])
    path.cubic_smooth([(3.5, 0.8), (3, 0)], relative=True)
    path.cubic_smooth([(-0.5, -2.2), (0, -3)], relative=True)
    return gdstk.Cell("cubic_smooth").add(path)
Esempio n. 8
0
# Copyright 2020 Lucas Heitzmann Gabrielli.
# This file is part of gdstk, distributed under the terms of the
# Boost Software License - Version 1.0.  See the accompanying
# LICENSE file or <http://www.boost.org/LICENSE_1_0.txt>

import pathlib
from tutorial_images import draw
import numpy
import gdstk

if __name__ == "__main__":
    main = gdstk.Cell("Main")

    # Create a path
    path = gdstk.RobustPath((0, 0), 0.5)
    path.segment((8, 0))
    path.interpolation(
        [(2, -4), (-2, -6), (-5, -8), (-4, -12)],
        angles=[0, None, None, None, -numpy.pi / 4],
        relative=True,
    )
    path.segment((3, -3), relative=True)
    main.add(path)

    # Major and minor markers
    major = gdstk.regular_polygon((0, 0), 0.5, 6, layer=1)
    minor = gdstk.rectangle((-0.1, -0.5), (0.1, 0.5), layer=1)
    for s in range(path.size):
        # A major marker is added at the start of each path section
        m = major.copy()
        m.translate(path.position(s))
Esempio n. 9
0
# This file is part of gdstk, distributed under the terms of the
# Boost Software License - Version 1.0.  See the accompanying
# LICENSE file or <http://www.boost.org/LICENSE_1_0.txt>

import pathlib
from tutorial_images import draw
import numpy
import gdstk

if __name__ == "__main__":
    # X-explicit repetition
    vline = gdstk.FlexPath([(3, 2), (3, 3.5)], 0.1, simple_path=True)
    vline.repetition = gdstk.Repetition(x_offsets=[0.2, 0.6, 1.4, 3.0])

    # Y-explicit repetition
    hline = gdstk.RobustPath((3, 2), 0.05, simple_path=True)
    hline.segment((6, 2))
    hline.repetition = gdstk.Repetition(y_offsets=[0.1, 0.3, 0.7, 1.5])

    # Create all copies
    vlines = vline.apply_repetition()
    hlines = hline.apply_repetition()

    # Include original elements for boolean operation
    vlines.append(vline)
    hlines.append(hline)

    result = gdstk.boolean(vlines, hlines, "or")

    main = gdstk.Cell("Main")
    main.add(*result)
Esempio n. 10
0
#  Boost Software License - Version 1.0.  See the accompanying       #
#  LICENSE file or <http://www.boost.org/LICENSE_1_0.txt>            #
#                                                                    #
######################################################################

import pathlib
from tutorial_images import draw
import numpy
import gdstk


if __name__ == "__main__":
    main = gdstk.Cell("Main")

    # Create a path
    path = gdstk.RobustPath((0, 0), 0.5, layer=2)
    path.segment((8, 0))
    path.interpolation(
        [(2, -4), (-2, -6), (-5, -8), (-4, -12)],
        angles=[0, None, None, None, -numpy.pi / 4],
        relative=True,
    )
    path.segment((3, -3), relative=True)
    main.add(path)

    # Major and minor markers
    major = gdstk.regular_polygon((0, 0), 0.5, 6, layer=1)
    minor = gdstk.rectangle((-0.1, -0.5), (0.1, 0.5), layer=1)
    for s in range(path.size):
        # A major marker is added at the start of each path section
        m = major.copy()