Ejemplo n.º 1
0
def cutback_phase(straight_length=100.0, bend_radius=10.0, n=2):
    # Define sub components
    bend180 = bend_circular(radius=bend_radius, start_angle=-90, theta=180)
    pm_wg = phase_modulator_waveguide(length=straight_length)
    wg_short = waveguide(length=1.0)
    wg_short2 = waveguide(length=2.0)
    wg_heater = waveguide_heater(length=10.0)
    taper = _taper()

    # Define a map between symbols and (component, input port, output port)
    string_to_device_in_out_ports = {
        "I": (taper, "1", "wg_2"),
        "O": (taper, "wg_2", "1"),
        "S": (wg_short, "W0", "E0"),
        "P": (pm_wg, "W0", "E0"),
        "A": (bend180, "W0", "W1"),
        "B": (bend180, "W1", "W0"),
        "H": (wg_heater, "W0", "E0"),
        "-": (wg_short2, "W0", "E0"),
    }

    # Generate a sequence
    # This is simply a chain of characters. Each of them represents a component
    # with a given input and and a given output

    repeated_sequence = "SIPOSASIPOSB"
    heater_seq = "-H-H-H-H-"
    sequence = repeated_sequence * n + "SIPO" + heater_seq
    component = component_sequence(sequence, string_to_device_in_out_ports)

    return component
Ejemplo n.º 2
0
def cutback_bend(bend90, straight_length=5.0, n_steps=6, n_stairs=5):
    """ Deprecated! use cutback_bend90 instead!
    this is a stair

    .. code::
            _
          _|
        _|

        _ this is a step

    """

    wg = waveguide(length=straight_length, width=bend90.ports["W0"].width)

    # Define a map between symbols and (component, input port, output port)
    string_to_device_in_out_ports = {
        "A": (bend90, "W0", "N0"),
        "B": (bend90, "N0", "W0"),
        "S": (wg, "W0", "E0"),
    }

    # Generate the sequence of staircases
    s = ""
    for i in range(n_stairs):
        s += "ASBS" * n_steps
        s += "ASAS" if i % 2 == 0 else "BSBS"
    s = s[:-4]

    # Create the component from the sequence
    c = component_sequence(s,
                           string_to_device_in_out_ports,
                           start_orientation=90)
    c.update_settings(n_bends=n_steps * n_stairs * 2 + n_stairs * 2 - 2)
    return c
Ejemplo n.º 3
0
def test_add_keepout():
    from pp.components.waveguide import waveguide

    c = waveguide()
    target_layers = [LAYER.WG]
    keepout_layers = [LAYER.NO_TILE_SI]
    # print(len(c.get_polygons()))
    assert len(c.get_polygons()) == 2
    c = add_keepout(c,
                    target_layers=target_layers,
                    keepout_layers=keepout_layers)
    # print(len(c.get_polygons()))
    assert len(c.get_polygons()) == 3
def test_cutback_heater():
    # Define subcomponents
    bend_radius = 10.0
    bend180 = bend_circular(radius=bend_radius, start_angle=-90, theta=180)
    wg = waveguide(length=5.0)
    wg_heater = waveguide_heater(length=20.0)

    # Define a map between symbols and (component, input port, output port)
    string_to_device_in_out_ports = {
        "A": (bend180, "W0", "W1"),
        "B": (bend180, "W1", "W0"),
        "H": (wg_heater, "W0", "E0"),
        "-": (wg, "W0", "E0"),
    }

    # Generate a sequence
    # This is simply a chain of characters. Each of them represents a component
    # with a given input and and a given output

    sequence = "AB-H-H-H-H-BA"
    component = component_sequence(sequence, string_to_device_in_out_ports)
    assert component
    return component
Ejemplo n.º 5
0
def coupler90(bend_radius=10.0, width=0.5, gap=0.2):
    """ Waveguide coupled to a bend with gap

    Args:
        bend_radius: um
        width: waveguide width (um)
        gap: um

    .. plot::
      :include-source:

      import pp
      c = pp.c.coupler90()
      pp.plotgds(c)

    """
    y = width + gap
    _bend = bend_circular(radius=bend_radius, width=width).ref((0, y))
    c = Component()

    _wg = c.add_ref(waveguide(length=bend_radius, width=width))
    c.add(_bend)

    # This component is a leaf cell => using absorb
    c.absorb(_wg)
    c.absorb(_bend)

    port_width = 2 * width + gap

    c.add_port(port=_wg.ports["E0"], name="E0")
    c.add_port(port=_bend.ports["N0"], name="N0")
    c.add_port(name="W0",
               midpoint=[0, y / 2],
               width=port_width,
               orientation=180)
    c.y = y
    return c
Ejemplo n.º 6
0
def cdsem_uturn(
    width=0.5,
    radius=10.0,
    symbol_bot="S",
    symbol_top="U",
    wg_length=LINE_LENGTH,
    waveguide=pp.c.waveguide,
    layer=pp.layer("wgcore"),
    layer_cladding=pp.layer("wgclad"),
    cladding_offset=3,
):
    """

    Args:
        width: of the line
        cladding_offset: 
        radius: bend radius
        wg_length

    """
    c = pp.Component()
    r = radius
    bend90 = bend_circular(
        width=width, radius=r, layer=layer, cladding_layer=layer_cladding
    )
    if wg_length is None:
        wg_length = 2 * r
    wg = waveguide(
        width=width,
        length=wg_length,
        layer=layer,
        layer_cladding=layer_cladding,
        cladding_offset=cladding_offset,
    )

    # bend90.ports()
    rename_ports_by_orientation(bend90)

    # Add the U-turn on waveguide layer
    b1 = c.add_ref(bend90)
    b2 = c.add_ref(bend90)

    b2.connect("N0", b1.ports["W0"])

    wg1 = c.add_ref(wg)
    wg1.connect("W0", b1.ports["N0"])

    wg2 = c.add_ref(wg)
    wg2.connect("W0", b2.ports["W0"])

    # Add symbols

    sym1 = c.add_ref(CENTER_SHAPES_MAP[symbol_bot]())
    sym1.rotate(-90)
    sym1.movey(r)
    sym2 = c.add_ref(CENTER_SHAPES_MAP[symbol_top]())
    sym2.rotate(-90)
    sym2.movey(2 * r)
    c.absorb(sym1)
    c.absorb(sym2)

    c.rotate(angle=90)
    # print(c._bb_valid)
    # print(c.size_info)
    c.move(c.size_info.cc, (0, 0))
    return c
Ejemplo n.º 7
0
def splitter_tree(
    coupler: Callable = mmi1x2,
    n_o_outputs: int = 4,
    bend_radius: float = 10.0,
    spacing: float = 50.0,
    termination_component=None,
):
    """tree of 1x2 splitters

    Args:
        coupler: 1x2 coupler factory
        n_o_outputs:
        bend_radius: for routing
        spacing: 2X spacing
        termination_component: factory or component for EAST termination

    .. code::

             __|
          __|  |__
        _|  |__
         |__       spacing


    .. plot::
      :include-source:

      import pp

      c = pp.c.splitter_tree(coupler=pp.c.mmi1x2(), n_o_outputs=4, spacing=50, bend_radius=10)
      pp.plotgds(c)

    """
    n_o_outputs = n_o_outputs
    c = pp.Component()

    coupler = pp.call_if_func(coupler)
    _coupler = c.add_ref(coupler)
    coupler_sep = coupler.ports["E1"].y - coupler.ports["E0"].y

    if n_o_outputs > 2:
        _cmp = splitter_tree(
            coupler=coupler,
            n_o_outputs=n_o_outputs // 2,
            bend_radius=bend_radius,
            spacing=spacing / 2,
        )
    else:
        termination_component = (termination_component if termination_component
                                 is not None else waveguide(length=0.1))
        _cmp = pp.call_if_func(termination_component)

    spacing = (spacing if spacing is not None else _cmp.ports["W0"].y -
               _coupler.size_info.south)
    if spacing < coupler_sep:
        tree_top = _cmp.ref(port_id="W0", position=_coupler.ports["E1"])
        tree_bot = _cmp.ref(
            port_id="W0",
            position=_coupler.ports["E0"],
            v_mirror=False  # True
        )

    else:
        d = 2 * bend_radius + 1
        spacing = max(spacing, d)

        tree_top = _cmp.ref(port_id="W0",
                            position=_coupler.ports["E1"].position +
                            (d, spacing))
        tree_bot = _cmp.ref(
            port_id="W0",
            position=_coupler.ports["E0"].position + (d, -spacing),
            v_mirror=False,  # True,
        )

        c.add(connect_strip(coupler.ports["E1"], tree_top.ports["W0"]))
        c.add(connect_strip(coupler.ports["E0"], tree_bot.ports["W0"]))

    i = 0
    for p in get_ports_facing(tree_bot, "E"):
        c.add_port(name="{}".format(i), port=p)
        i += 1

    for p in get_ports_facing(tree_top, "E"):
        c.add_port(name="{}".format(i), port=p)
        i += 1

    c.add(tree_bot)
    c.add(tree_top)
    c.add_port(name="W0", port=_coupler.ports["W0"])

    return c