示例#1
0
def test_no_ports() -> gf.Component:
    c = gf.Component()
    w = h = 1
    layer = (1, 0)
    points = [
        [-w / 2.0, -h / 2.0],
        [-w / 2.0, h / 2],
        [w / 2, h / 2],
        [w / 2, -h / 2.0],
    ]
    c.add_polygon(points, layer=layer)
    return c
示例#2
0
def get_device(
    space: float,
    width: float = 0.5,
    layer1: Tuple[int, int] = (1, 0),
    layer2: Tuple[int, int] = (2, 0),
) -> Component:
    c = gf.Component()
    r1 = c << gf.components.rectangle(size=(width, width), layer=layer1)
    r2 = c << gf.components.rectangle(size=(width, width), layer=layer2)
    r1.xmax = 0
    r2.xmin = space
    return c
示例#3
0
def test_get_routes_straight(check: bool = True):
    c = gf.Component("get_routes_straight")
    pad_array = gf.components.pad_array()
    c1 = c << pad_array
    c2 = c << pad_array
    c2.ymax = -200

    routes = get_routes_straight(ports=c1.get_ports_list(), length=200)
    c.add(routes.references)
    if check:
        difftest(c)
    return c
示例#4
0
def cross(
    length: float = 10.0,
    width: float = 3.0,
    layer: Tuple[int, int] = LAYER.WG,
) -> Component:
    """Generates a right-angle cross from two rectangles of specified length and width.

    Args:
        length: float Length of the cross from one end to the other
        width: float Width of the arms of the cross
        layer: int, array-like[2], or set Specific layer(s) to put polygon geometry on

    """

    c = gf.Component()
    R = gf.components.rectangle(size=(width, length), layer=layer)
    r1 = c.add_ref(R).rotate(90)
    r2 = c.add_ref(R)
    r1.center = (0, 0)
    r2.center = (0, 0)
    c.add_port(
        1,
        width=width,
        layer=layer,
        orientation=0,
        midpoint=(+length / 2, 0),
    )
    c.add_port(
        2,
        width=width,
        layer=layer,
        orientation=180,
        midpoint=(-length / 2, 0),
    )
    c.add_port(
        3,
        width=width,
        layer=layer,
        orientation=90,
        midpoint=(0, length / 2),
    )
    c.add_port(
        4,
        width=width,
        layer=layer,
        orientation=270,
        midpoint=(0, -length / 2),
    )
    c.absorb(r1)
    c.absorb(r2)
    c.auto_rename_ports()
    return c
示例#5
0
def loss_deembedding_ch13_24(
        pitch: float = 127.0,
        R: float = 10.0,
        grating_coupler_factory: ComponentFactory = grating_coupler_te,
        input_port_indexes: Tuple[int, ...] = (0, 1),
        cross_section: CrossSectionFactory = strip,
        **kwargs) -> Component:

    gc = grating_coupler_factory()
    c = gf.Component()
    dx = pitch
    gcs = [
        gc.ref(position=(i * dx, 0), port_id="o1", rotation=-90)
        for i in range(4)
    ]

    gc_ports = [g.ports["o1"] for g in gcs]
    c.add(gcs)

    c.add(
        get_route(gc_ports[0],
                  gc_ports[2],
                  start_straight=40.0,
                  taper_factory=None,
                  cross_section=cross_section,
                  **kwargs).references)

    gsi = gc.size_info
    p1 = gc_ports[1]
    p3 = gc_ports[3]
    a = R + 5.0  # 0.5
    b = max(2 * a, pitch / 2)
    y_bot_align_route = -gsi.width - 5.0

    c.add(
        connect_loopback(p1,
                         p3,
                         a,
                         b,
                         R,
                         y_bot_align_route,
                         cross_section=cross_section,
                         **kwargs))
    for i, index in enumerate(input_port_indexes):
        label = get_input_label(gc_ports[index],
                                gc,
                                i,
                                component_name=inspect.stack()[0][3])
        label.position = gc_ports[index].position
        c.add(label)

    return c
示例#6
0
def litho_calipers(
        notch_size: Tuple[float, float] = (2.0, 5.0),
        notch_spacing: float = 2.0,
        num_notches: int = 11,
        offset_per_notch: float = 0.1,
        row_spacing: float = 0.0,
        layer1: Tuple[int, int] = (1, 0),
        layer2: Tuple[int, int] = (2, 0),
) -> Component:
    """Vernier caliper structure to test lithography alignment
    Only the middle finger is aligned and the rest are offset.

    adapted from phidl

    Args:
        notch_size: [xwidth, yheight]
        notch_spacing: 2
        num_notches: 11
        offset_per_notch: 0.1
        row_spacing: 0
        layer1: 1
        layer2:2

    .. plot::
      :include-source:

      import gdsfactory as gf

      c = gf.components.litho_calipers()
      c.plot()
    """

    D = gf.Component()
    num_notches_total = num_notches * 2 + 1
    centre_notch = num_notches
    R1 = pc.rectangle(size=(notch_size), layer=layer1)
    R2 = pc.rectangle(size=(notch_size), layer=layer2)
    for i in range(num_notches_total):
        if i == centre_notch:
            D.add_ref(R1).movex(i * (notch_size[0] + notch_spacing)).movey(
                notch_size[1])
            D.add_ref(R2).movex(i * (notch_size[0] + notch_spacing) +
                                offset_per_notch *
                                (centre_notch - i)).movey(-2 * notch_size[1] -
                                                          row_spacing)
        D.add_ref(R1).movex(i * (notch_size[0] + notch_spacing))
        D.add_ref(R2).movex(i * (notch_size[0] + notch_spacing) +
                            offset_per_notch *
                            (centre_notch - i)).movey(-notch_size[1] -
                                                      row_spacing)

    return D
示例#7
0
def straight_sample(length=5, width=1):
    wg = gf.Component("straight_sample")
    wg.add_polygon([(0, 0), (length, 0), (length, width), (0, width)],
                   layer=(2, 0))
    wg.add_port(name="o1",
                midpoint=[0, width / 2],
                width=width,
                orientation=180)
    wg.add_port(name="o2",
                midpoint=[length, width / 2],
                width=width,
                orientation=0)
    return wg
def straight(width: Union[float, int] = 10, height: int = 1) -> Component:
    """Returns straight with automatic name."""
    wg = gf.Component("straight")
    wg.add_polygon([(0, 0), (width, 0), (width, height), (0, height)])
    wg.add_port(name="wgport1",
                midpoint=[0, height / 2],
                width=height,
                orientation=180)
    wg.add_port(name="wgport2",
                midpoint=[width, height / 2],
                width=height,
                orientation=0)
    return wg
示例#9
0
def test_remove_layers() -> Component:
    c = gf.Component("test_remove_layers")

    c.add_ref(gf.components.rectangle(size=(10, 1), layer=gf.LAYER.WG))
    c.add_ref(gf.components.rectangle(size=(10, 2), layer=gf.LAYER.SLAB90))
    c.add_ref(gf.components.rectangle(size=(10, 3), layer=gf.LAYER.SLAB150))

    assert len(c.layers) == 3

    c.remove_layers(layers=[gf.LAYER.SLAB90, gf.LAYER.SLAB150])

    assert len(c.layers) == 1
    return c
示例#10
0
def demo_te_and_tm():
    c = gf.Component()
    w = gf.components.straight()
    wte = add_fiber_array(
        component=w,
        grating_coupler=gf.components.grating_coupler_elliptical_te)
    wtm = add_fiber_array(
        component=w,
        grating_coupler=gf.components.grating_coupler_elliptical_tm)
    c.add_ref(wte)
    wtm_ref = c.add_ref(wtm)
    wtm_ref.movey(wte.size_info.height)
    return c
示例#11
0
def version_stamp(
    labels: Tuple[str, ...] = ("demo_label", ),
    with_qr_code: bool = False,
    layer: Tuple[int, int] = LAYER.WG,
    pixel_size: int = 1,
    version: Optional[str] = __version__,
    text_size: int = 10,
) -> Component:
    """Component with module version and date.

    Args:
        labels: Iterable of labels
    """

    now = datetime.datetime.now()
    timestamp = "{:%Y-%m-%d %H:%M:%S}".format(now)
    short_stamp = "{:%y.%m.%d.%H.%M.%S}".format(now)

    c = gf.Component()
    if with_qr_code:
        data = f"{timestamp}/{platform.node()}"
        q = qrcode(layer=layer, data=data, psize=pixel_size).ref_center()
        c.add(q)
        c.absorb(q)

        x = q.size_info.width * 0.5 + 10

    else:
        x = 0

    txt_params = {"layer": layer, "justify": "left", "size": text_size}
    date = text(position=(x, text_size + 2 * pixel_size),
                text=short_stamp,
                **txt_params).ref()
    c.add(date)
    c.absorb(date)

    if version:
        t = text(position=(x, 0), text=version, **txt_params).ref()
        c.add(t)
        c.absorb(t)

    for i, line in enumerate(labels):
        t = c << text(
            position=(x, -(i + 1) * (text_size + 2 * pixel_size)),
            text=line,
            **txt_params,
        )
        c.absorb(t)

    return c
示例#12
0
def cavity(component: Component = dbr,
           coupler: ComponentFactory = coupler_function,
           length: float = 0.1,
           gap: float = 0.2,
           **kwargs) -> Component:
    r"""Returns  cavity from a coupler and a mirror.

    connects the W0 port of the mirror to E1 and W1 coupler ports
    creating a resonant cavity

    Args:
        component: mirror
        coupler: coupler library
        length: coupler length
        gap: coupler gap
        kwargs: coupler_settings

    .. code::

      ml (mirror left)              mr (mirror right)
       |                               |
       |o1 - o2__             __o3 - o1|
       |         \           /         |
                  \         /
                ---=========---
         o1  o1    length      o4    o2

    .. plot::
      :include-source:

      import gdsfactory as gf

      c = gf.components.cavity(component=gf.components.dbr())
      c.plot()
    """
    mirror = component() if callable(component) else component
    coupler = (coupler(length=length, gap=gap, **kwargs)
               if callable(coupler) else coupler)

    c = gf.Component()
    c.component = mirror
    cr = c << coupler
    ml = c << mirror
    mr = c << mirror

    ml.connect("o1", destination=cr.ports["o2"])
    mr.connect("o1", destination=cr.ports["o3"])
    c.add_port("o1", port=cr.ports["o1"])
    c.add_port("o2", port=cr.ports["o4"])
    c.copy_child_info(mirror)
    return c
示例#13
0
def splitter_chain(
    splitter: ComponentFactory = mmi1x2,
    columns: int = 3,
    bend: ComponentFactory = bend_s,
) -> Component:
    """Chain of splitters

    Args:
        splitter: splitter to chain
        columns: number of splitters to chain
        bend: bend to connect splitters

    .. code::

                 __o5
              __|
           __|  |__o4
      o1 _|  |__o3
          |__o2


           __o2
      o1 _|
          |__o3

    """
    c = gf.Component()
    splitter_component = gf.call_if_func(splitter)
    cref = c.add_ref(splitter_component)

    splitter_ports_east = cref.get_ports_list(port_type="optical", orientation=0)
    e1_port_name = splitter_ports_east[0].name
    e0_port_name = splitter_ports_east[1].name

    bend = bend() if callable(bend) else bend
    c.add_port(name="o1", port=cref.ports["o1"])
    c.add_port(name="o2", port=cref.ports[e0_port_name])

    for i in range(1, columns):
        bref = c.add_ref(bend)
        bref.connect(port="o1", destination=cref.ports[e1_port_name])

        cref = c.add_ref(splitter_component)

        cref.connect(port="o1", destination=bref.ports["o2"])
        c.add_port(name=f"o{i+2}", port=cref.ports[e0_port_name])

    c.add_port(name=f"o{i+3}", port=cref.ports[e1_port_name])
    c.copy_child_info(splitter_component)
    return c
示例#14
0
def manhattan_text(
        text: str = "abcd",
        size: float = 10.0,
        position: Tuple[float, float] = (0.0, 0.0),
        justify: str = "left",
        layer: Tuple[int, int] = (1, 0),
) -> Component:
    """Pixel based font, guaranteed to be manhattan, without accute angles.

    Args:
        text:
        size: pixel size
        position: coordinate
        justify
        layer:

    """
    pixel_size = size
    xoffset = position[0]
    yoffset = position[1]
    component = gf.Component()

    for line in text.split("\n"):
        for character in line:
            if character == " ":
                xoffset += pixel_size * 6
            elif character.upper() not in CHARAC_MAP:
                print(f"skipping character {character} not part of dictionary")
            else:
                pixels = CHARAC_MAP[character.upper()]
                ref = component.add_ref(
                    pixel_array(pixels=pixels,
                                pixel_size=pixel_size,
                                layer=layer))
                ref.move((xoffset, yoffset))
                component.absorb(ref)
                xoffset += pixel_size * 6

        yoffset -= pixel_size * 6
        xoffset = position[0]
    justify = justify.lower()
    for ref in component.references:
        if justify == "left":
            pass
        if justify == "right":
            ref.xmax = position[0]
        if justify == "center":
            ref.move(origin=ref.center, destination=position, axis="x")

    return component
示例#15
0
def wg(size=(1, 0.5), layer=(1, 0)):
    """Dummy component"""
    c = gf.Component("wg")
    dx, dy = size

    points = [
        [-dx / 2.0, -dy / 2.0],
        [-dx / 2.0, dy / 2],
        [dx / 2, dy / 2],
        [dx / 2, -dy / 2.0],
    ]

    c.add_polygon(points, layer=layer)
    return c
示例#16
0
def loss_deembedding_ch14_23(
        pitch: float = 127.0,
        grating_coupler: ComponentFactory = grating_coupler_te,
        input_port_indexes: Tuple[int, ...] = (0, 1),
        **kwargs) -> Component:
    """Grating coupler test structure for fiber array.

    Connects channel 1->4, 2->3

    Args:
        pitch:
        grating_coupler:
        input_port_indexes:

    Keyword Args:
        cross_section settings
    """
    gc = grating_coupler()

    c = gf.Component()
    dx = pitch
    gcs = [
        gc.ref(position=(i * dx, 0), port_id="o1", rotation=-90)
        for i in range(4)
    ]

    gc_ports = [g.ports["o1"] for g in gcs]
    c.add(gcs)

    c.add(
        get_route(gc_ports[0],
                  gc_ports[3],
                  start_straight_length=40.0,
                  taper=None,
                  **kwargs).references)
    c.add(
        get_route(gc_ports[1],
                  gc_ports[2],
                  start_straight_length=30.0,
                  taper=None,
                  **kwargs).references)
    for i, index in enumerate(input_port_indexes):
        label = get_input_label(gc_ports[index],
                                gc,
                                i,
                                component_name=inspect.stack()[0][3])
        label.position = gc_ports[index].position
        c.add(label)
    return c
示例#17
0
def test_get_bundle_u_indirect(data_regression: DataRegressionFixture,
                               angle,
                               check: bool = True,
                               dy=-200):

    xs1 = [-100, -90, -80, -55, -35] + [200, 210, 240]

    axis = "X" if angle in [0, 180] else "Y"

    pitch = 10.0
    N = len(xs1)
    xs2 = [50 + i * pitch for i in range(N)]

    a1 = angle
    a2 = a1 + 180

    if axis == "X":
        ports1 = [
            Port("top_{}".format(i), (0, xs1[i]), 0.5, a1) for i in range(N)
        ]

        ports2 = [
            Port("bottom_{}".format(i), (dy, xs2[i]), 0.5, a2)
            for i in range(N)
        ]

    else:
        ports1 = [
            Port("top_{}".format(i), (xs1[i], 0), 0.5, a1) for i in range(N)
        ]

        ports2 = [
            Port("bottom_{}".format(i), (xs2[i], dy), 0.5, a2)
            for i in range(N)
        ]

    c = gf.Component(f"test_get_bundle_u_indirect_{angle}_{dy}")

    routes = get_bundle(ports1, ports2, bend=gf.components.bend_circular)
    lengths = {}
    for i, route in enumerate(routes):
        c.add(route.references)
        lengths[i] = route.length

    if check:
        data_regression.check(lengths)
        difftest(c)

    return c
示例#18
0
def test_get_bundle_small() -> Component:
    c = gf.Component()
    c1 = c << gf.components.mmi2x2()
    c2 = c << gf.components.mmi2x2()
    c2.move((100, 40))
    routes = get_bundle(
        [c1.ports["o3"], c1.ports["o4"]],
        [c2.ports["o1"], c2.ports["o2"]],
        radius=5,
        separation=5.0,
    )
    for route in routes:
        assert np.isclose(route.length, 111.136), route.length
        c.add(route.references)
    return c
示例#19
0
def get_device(
        inclusion: float,
        width: float = 0.5,
        layer1: Tuple[int, int] = (1, 0),
        layer2: Tuple[int, int] = (2, 0),
) -> Component:
    c = gf.Component()
    r1 = c << gf.components.rectangle(size=(width, width), layer=layer1)
    r2 = c << gf.components.rectangle(
        size=(width - 2 * inclusion, width - 2 * inclusion), layer=layer2)
    r1.x = 0
    r1.y = 0
    r2.x = 0
    r2.y = 0
    return c
示例#20
0
def _compare_bend_euler90():
    """Compare bend euler with 90deg circular bend."""
    import gdsfactory as gf

    c = gf.Component()
    radius = 10
    b1 = bend_euler(radius=radius)
    b2 = gf.c.bend_circular(radius=radius)

    print(b1.info.length)
    print(b2.info.length)

    c << b1
    c << b2
    return c
示例#21
0
def splitter_chain(
    splitter: ComponentFactory = mmi1x2,
    n_devices: int = 3,
    bend: ComponentFactory = bend_s,
    **kwargs,
) -> Component:
    """Chain of splitters

    .. code::

                __5
             __|
          __|  |__4
      1 _|  |__3
         |__2


          __E1
      1 _|
         |__E0

    """
    c = gf.Component()
    splitter_component = gf.call_if_func(splitter, **kwargs)
    cref = c.add_ref(splitter_component)

    splitter_ports_east = cref.get_ports_list(port_type="optical",
                                              orientation=0)
    e1_port_name = splitter_ports_east[0].name
    e0_port_name = splitter_ports_east[1].name

    bend = bend() if callable(bend) else bend
    c.add_port(name="o1", port=cref.ports["o1"])
    c.add_port(name="o2", port=cref.ports[e0_port_name])

    for i in range(1, n_devices):
        bref = c.add_ref(bend)
        bref.connect(port="o1", destination=cref.ports[e1_port_name])

        cref = c.add_ref(splitter_component)

        cref.connect(port="o1", destination=bref.ports["o2"])
        c.add_port(name=f"o{i+2}", port=cref.ports[e0_port_name])

    c.add_port(name=f"o{i+3}", port=cref.ports[e1_port_name])
    c.copy_child_info(splitter_component)
    return c
示例#22
0
def test_remap_layers() -> Component:
    c = gf.Component("test_remap_layers_sample_device")

    wg1 = c << gf.components.straight(length=11, width=1, layer=gf.LAYER.WG)
    wg2 = c << gf.components.straight(
        length=11, width=2, layer=gf.LAYER.SLAB90)
    wg3 = c << gf.components.straight(
        length=11, width=3, layer=gf.LAYER.SLAB150)

    wg2.connect(port="o1", destination=wg1.ports["o2"])
    wg3.connect(port="o1", destination=wg2.ports["o2"], overlap=1)

    nlayers = len(c.layers)
    assert len(c.layers) == nlayers
    c.remap_layers({gf.LAYER.WG: gf.LAYER.SLAB150})
    assert len(c.layers) == nlayers - 1
    return c
示例#23
0
def verniers(
    widths: Floats = (0.1, 0.2, 0.3, 0.4, 0.5),
    gap: float = 0.1,
    xsize: int = 100,
    layer_label: Layer = LAYER.LABEL,
    **kwargs
) -> Component:
    c = gf.Component()
    y = 0

    for width in widths:
        w = c << gf.components.straight(width=width, length=xsize, **kwargs)
        y += width / 2
        w.y = y
        c.add_label(text=str(int(width * 1e3)), position=(0, y), layer=layer_label)
        y += width / 2 + gap

    return c
示例#24
0
def qrcode(data: str = "mask01",
           psize: int = 1,
           layer: Tuple[int, int] = LAYER.WG) -> Component:
    """Returns QRCode."""
    import qrcode

    pix = pixel(size=psize, layer=layer)
    q = qrcode.QRCode()
    q.add_data(data)
    matrix = q.get_matrix()
    c = gf.Component()
    for i, row in enumerate(matrix):
        for j, value in enumerate(row):
            if value:
                pix_ref = pix.ref((i * psize, j * psize))
                c.add(pix_ref)
                c.absorb(pix_ref)
    return c
示例#25
0
def taper_cross_section(cross_section1: CrossSectionOrFactory = strip_rib_tip,
                        cross_section2: CrossSectionOrFactory = rib,
                        length: float = 10,
                        npoints: int = 100,
                        linear: bool = False,
                        **kwargs) -> Component:
    r"""Returns taper transition between cross_section1 and cross_section2

    Args:
        cross_section1: start cross_section factory
        cross_section2: end cross_section factory
        length: transition length
        npoints: number of points
        linear: shape of the transition, sine when False
        kwargs: cross_section settings for section2



    .. code::

                           _____________________
                          /
                  _______/______________________
                        /
       cross_section1  |        cross_section2
                  ______\_______________________
                         \
                          \_____________________


    """
    transition = gf.path.transition(
        cross_section1=cross_section1()
        if callable(cross_section1) else cross_section1,
        cross_section2=cross_section2(
            **kwargs) if callable(cross_section2) else cross_section2,
        width_type="linear" if linear else "sine",
    )
    taper_path = gf.path.straight(length=length, npoints=npoints)

    c = gf.Component()
    ref = c << gf.path.extrude(taper_path, transition)
    c.add_ports(ref.ports)
    return c
def test_get_bundle_u_direct_different_x(
        data_regression: DataRegressionFixture,
        check: bool = True) -> Component:
    """

    .. code::

       4----5
                    ________
       3----6     4|        |
                  3|  nxn   |
       2----7     2|        |
                  1|________|
       1----8
    """

    c = gf.Component("test_get_bundle_u_direct_different_x")
    w = c << gf.components.straight_array(n=4, spacing=200)
    d = c << gf.components.nxn(west=4, east=0, north=0, south=0)
    d.y = w.y
    d.xmin = w.xmax + 200

    ports1 = w.get_ports_list(orientation=0)
    ports2 = d.get_ports_list(orientation=0)

    ports1 = [
        w.ports["o7"],
        w.ports["o8"],
    ]
    ports2 = [
        d.ports["o2"],
        d.ports["o1"],
    ]

    routes = gf.routing.get_bundle(ports1, ports2)

    lengths = {}
    for i, route in enumerate(routes):
        c.add(route.references)
        lengths[i] = route.length

    if check:
        data_regression.check(lengths)
    return c
示例#27
0
def preview_layerset(
    ls: LayerSetPhidl, size: float = 100.0, spacing: float = 100.0
) -> object:
    """Generates a preview Device with representations of all the layers,
    used for previewing LayerSet color schemes in quickplot or saved .gds
    files

    Args:
        ls: LayerSet

    """
    import numpy as np

    import gdsfactory as gf

    D = gf.Component(name="layerset")
    scale = size / 100
    num_layers = len(ls._layers)
    matrix_size = int(np.ceil(np.sqrt(num_layers)))
    sorted_layers = sorted(
        ls._layers.values(), key=lambda x: (x.gds_layer, x.gds_datatype)
    )
    for n, layer in enumerate(sorted_layers):
        gds_layer, gds_datatype = layer.gds_layer, layer.gds_datatype
        layer_tuple = (gds_layer, gds_datatype)
        R = gf.components.rectangle(size=(100 * scale, 100 * scale), layer=layer_tuple)
        T = gf.components.text(
            text="%s\n%s / %s" % (layer.name, layer.gds_layer, layer.gds_datatype),
            size=20 * scale,
            position=(50 * scale, -20 * scale),
            justify="center",
            layer=layer_tuple,
        )

        xloc = n % matrix_size
        yloc = int(n // matrix_size)
        D.add_ref(R).movex((100 + spacing) * xloc * scale).movey(
            -(100 + spacing) * yloc * scale
        )
        D.add_ref(T).movex((100 + spacing) * xloc * scale).movey(
            -(100 + spacing) * yloc * scale
        )
    return D
def test_route_error2():
    """Ensures that an impossible route raises value Error"""
    c = gf.Component("pads_route_from_steps")
    pt = c << gf.c.pad_array(orientation=270, columns=3)
    pb = c << gf.c.pad_array(orientation=90, columns=3)
    pt.move((100, 200))
    route = gf.routing.get_route_from_steps(
        pt.ports["e11"],
        pb.ports["e11"],
        steps=[
            {
                "y": 100
            },
        ],
        cross_section=gf.cross_section.metal3,
        bend=gf.components.wire_corner,
    )
    c.add(route.references)
    return c
示例#29
0
def litho_steps(
    line_widths: List[float] = (1.0, 2.0, 4.0, 8.0, 16.0),
    line_spacing: float = 10.0,
    height: float = 100.0,
    layer: Tuple[int, int] = gf.LAYER.WG,
) -> Component:
    """Produces a positive + negative tone linewidth test, used for
    lithography resolution test patterning
    adapted from phidl

    Args:
        line_widths:
        line_spacing:
        height:
        layer:

    .. plot::
      :include-source:

      import gdsfactory as gf

      c = gf.components.litho_steps()
      c.plot()

    """
    D = gf.Component()

    height = height / 2
    T1 = pc.text(text="%s" % str(line_widths[-1]),
                 size=height,
                 justify="center",
                 layer=layer)
    D.add_ref(T1).rotate(90).movex(-height / 10)
    R1 = pc.rectangle(size=(line_spacing, height), layer=layer)
    D.add_ref(R1).movey(-height)
    count = 0
    for i in reversed(line_widths):
        count += line_spacing + i
        R2 = pc.rectangle(size=(i, height), layer=layer)
        D.add_ref(R1).movex(count).movey(-height)
        D.add_ref(R2).movex(count - i)

    return D
def test_get_bundle_from_waypointsB(
    data_regression: DataRegressionFixture,
    check: bool = True,
) -> Component:

    ys1 = np.array([0, 5, 10, 15, 30, 40, 50, 60]) + 0.0
    ys2 = np.array([0, 10, 20, 30, 70, 90, 110, 120]) + 500.0
    N = ys1.size

    ports1 = [
        Port(name=f"A_{i}", midpoint=(0, ys1[i]), width=0.5, orientation=0)
        for i in range(N)
    ]
    ports2 = [
        Port(
            name=f"B_{i}",
            midpoint=(500, ys2[i]),
            width=0.5,
            orientation=180,
        ) for i in range(N)
    ]

    p0 = ports1[0].position

    c = gf.Component("B")
    c.add_ports(ports1)
    c.add_ports(ports2)
    waypoints = [
        p0 + (200, 0),
        p0 + (200, -200),
        p0 + (400, -200),
        (p0[0] + 400, ports2[0].y),
    ]

    routes = get_bundle_from_waypoints(ports1, ports2, waypoints)
    lengths = {}
    for i, route in enumerate(routes):
        c.add(route.references)
        lengths[i] = route.length

    if check:
        data_regression.check(lengths)
    return c