Esempio n. 1
0
def layout_donut(cell, layer, center, r1, r2):
    """ Layout donut shape.
    cell: layout cell to place the layout
    layer: which layer to use
    center: origin DPoint (not affected by ex)
    r1: internal radius
    r2: external radius
    """

    assert r2 > r1

    arc_function = lambda t: np.array(
        [center.x + r2 * np.cos(t), center.y + r2 * np.sin(t)])
    t, coords = sample_function(arc_function, [0, 2 * np.pi - 0.001],
                                tol=0.002 / r2)

    external_points = [pya.DPoint(x, y) for x, y in zip(*coords)]

    arc_function = lambda t: np.array(
        [center.x + r1 * np.cos(-t), center.y + r1 * np.sin(-t)])
    t, coords = sample_function(arc_function, [0, 2 * np.pi - 0.001],
                                tol=0.002 / r1)

    internal_points = [pya.DPoint(x, y) for x, y in zip(*coords)]

    dpoly = pya.DPolygon(external_points)
    dpoly.insert_hole(internal_points)
    insert_shape(cell, layer, dpoly)
    return dpoly
Esempio n. 2
0
def layout_circle(cell,
                  layer,
                  center,
                  r,
                  ex=None,
                  x_bounds=(-np.inf, np.inf),
                  y_bounds=(-np.inf, np.inf)):
    """
    function to produce the layout of a filled circle
    cell: layout cell to place the layout
    layer: which layer to use
    center: origin DPoint
    r: radius
    x_bounds and y_bounds relative to the center, before rotation by ex.
    units in microns
    optimal sampling
    """

    arc_function = lambda t: np.array([r * np.cos(t), r * np.sin(t)])
    t, coords = sample_function(arc_function, [0, 2 * np.pi - 0.001],
                                tol=0.002 / r)

    # dbu = cell.layout().dbu
    dpolygon = pya.DSimplePolygon([pya.DPoint(x, y) for x, y in zip(*coords)])
    # clip dpolygon to bounds
    dpolygon.clip(x_bounds=x_bounds, y_bounds=y_bounds)
    # Transform points (translation + rotation)
    dpolygon.transform_and_rotate(center, ex)
    dpolygon.compress(True)
    insert_shape(cell, layer, dpolygon)
    return dpolygon
Esempio n. 3
0
def layout_section(
        cell,
        layer,
        center,
        r2,
        theta_start,
        theta_end,
        ex=None,
        x_bounds=(-np.inf, np.inf),
        y_bounds=(-np.inf, np.inf),
):
    """ Layout section of a circle.
    cell: layout cell to place the layout
    layer: which layer to use
    center: origin DPoint (not affected by ex)
    r2: radius
    theta_start, theta_end: angle in radians
    x_bounds and y_bounds relative to the center, before rotation by ex.
    units in microns
    returns a dpolygon
    """

    assert r2 > 0

    # optimal sampling
    arc_function = lambda t: np.array([r2 * np.cos(t), r2 * np.sin(t)])
    t, coords = sample_function(arc_function, [theta_start, theta_end],
                                tol=0.002 / r2)

    # # This yields a better polygon
    if theta_end < theta_start:
        theta_start, theta_end = theta_end, theta_start

    coords = np.insert(coords, 0, arc_function(theta_start - 0.001),
                       axis=1)  # start the waveguide a little bit before
    coords = np.append(coords,
                       np.atleast_2d(arc_function(theta_end + 0.001)).T,
                       axis=1)  # finish the waveguide a little bit after

    # create original waveguide poligon prior to clipping and rotation
    dpoints_list = [pya.DPoint(x, y) for x, y in zip(*coords)]
    dpolygon = pya.DSimplePolygon(dpoints_list + [pya.DPoint(0, 0)])

    # clip dpolygon to bounds
    dpolygon.clip(x_bounds=x_bounds, y_bounds=y_bounds)
    # Transform points (translation + rotation)
    dpolygon.transform_and_rotate(center, ex)
    dpolygon.compress(True)
    dpolygon.layout(cell, layer)
    return dpolygon
Esempio n. 4
0
def layout_ring(cell, layer, center, r, w):
    """
    function to produce the layout of a ring
    cell: layout cell to place the layout
    layer: which layer to use
    center: origin DPoint
    r: radius
    w: waveguide width
    units in microns

    """

    # outer arc
    # optimal sampling
    assert r - w / 2 > 0
    radius = r + w / 2
    arc_function = lambda t: np.array([radius * np.cos(t), radius * np.sin(t)])
    t, coords = sample_function(arc_function, [0, 2 * pi], tol=0.002 / radius)

    # create original waveguide poligon prior to clipping and rotation
    points_hull = [center + pya.DPoint(x, y) for x, y in zip(*coords)]
    del points_hull[-1]

    radius = r - w / 2
    arc_function = lambda t: np.array([radius * np.cos(t), radius * np.sin(t)])
    t, coords = sample_function(arc_function, [0, 2 * pi], tol=0.002 / radius)

    # create original waveguide poligon prior to clipping and rotation
    points_hole = [center + pya.DPoint(x, y) for x, y in zip(*coords)]
    del points_hole[-1]

    dpoly = pya.DPolygon(list(reversed(points_hull)))
    dpoly.insert_hole(points_hole)
    dpoly.compress(True)
    insert_shape(cell, layer, dpoly)
    return dpoly
Esempio n. 5
0
def layout_circle(cell, layer, center, r):
    """
    function to produce the layout of a filled circle
    cell: layout cell to place the layout
    layer: which layer to use
    center: origin DPoint
    r: radius
    w: waveguide width
    theta_start, theta_end: angle in radians
    units in microns
    optimal sampling
    """

    arc_function = lambda t: np.array(
        [center.x + r * np.cos(t), center.y + r * np.sin(t)])
    t, coords = sample_function(arc_function, [0, 2 * np.pi - 0.001],
                                tol=0.002 / r)

    # dbu = cell.layout().dbu
    dpoly = pya.DSimplePolygon([pya.DPoint(x, y) for x, y in zip(*coords)])
    # cell.shapes(layer).insert(dpoly.to_itype(dbu))
    insert_shape(cell, layer, dpoly)
    return dpoly
Esempio n. 6
0
def layout_arc(
        cell,
        layer,
        center,
        r,
        w,
        theta_start,
        theta_end,
        ex=None,
        x_bounds=(-np.inf, np.inf),
        y_bounds=(-np.inf, np.inf),
):
    """ function to produce the layout of an arc
    cell: layout cell to place the layout
    layer: which layer to use
    center: origin DPoint (not affected by ex)
    r: radius
    w: waveguide width
    theta_start, theta_end: angle in radians
    x_bounds and y_bounds relative to the center, before rotation by ex.
    units in microns
    returns a dpolygon

    """
    # fetch the database parameters

    if r <= 0:
        raise RuntimeError(f"Please give me a positive radius. Bad r={r}")

    # optimal sampling
    if theta_end < theta_start:
        theta_start, theta_end = theta_end, theta_start

    arc_function = lambda t: np.array([r * np.cos(t), r * np.sin(t)])
    t, coords = sample_function(arc_function, [theta_start, theta_end],
                                tol=0.002 / r)

    dt = 0.0001
    # # This yields a better polygon
    insert_at = np.argmax(theta_start + dt < t)
    t = np.insert(t, insert_at, theta_start + dt)
    coords = np.insert(
        coords, insert_at, arc_function(theta_start + dt),
        axis=1)  # start the second point a little bit after the first

    insert_at = np.argmax(theta_end - dt < t)
    t = np.insert(t, insert_at, theta_end - dt)
    coords = np.insert(
        coords, insert_at, arc_function(theta_end - dt),
        axis=1)  # start the second to last point a little bit before the final

    # create original waveguide poligon prior to clipping and rotation
    dpoints_list = [pya.DPoint(x, y) for x, y in zip(*coords)]
    from zeropdk.layout import waveguide_dpolygon

    dpolygon = waveguide_dpolygon(dpoints_list, w, cell.layout().dbu)

    # clip dpolygon to bounds
    dpolygon.clip(x_bounds=x_bounds, y_bounds=y_bounds)
    # Transform points (translation + rotation)
    dpolygon.transform_and_rotate(center, ex)
    dpolygon.compress(True)
    dpolygon.layout(cell, layer)
    return dpolygon