Exemplo n.º 1
0
def gc_tm1550():
    c = import_gds("ebeam_gc_tm1550")
    c = rotate(component=c, angle=180)
    c.polarization = "tm"
    c.wavelength = 1550
    auto_rename_ports(c)
    return c
Exemplo n.º 2
0
def gc_te1550_broadband():
    c = import_gds("ebeam_gc_te1550_broadband")
    c = rotate(component=c, angle=180)
    c.polarization = "te"
    c.wavelength = 1550
    auto_rename_ports(c)
    return c
Exemplo n.º 3
0
def import_gds(gdsname: str, rename_ports: bool = False) -> Component:
    """import gds from SIEPIC PDK"""
    c = pp.import_gds(gds / f"{gdsname}.gds")
    c.function_name = gdsname

    n = 0
    for label in c.get_labels():
        if label.text.startswith("opt"):
            n += 1

    for label in c.get_labels():
        if label.text.startswith("opt"):
            port = pp.Port(
                name=label.text,
                midpoint=label.position,
                width=port_width,
                orientation=guess_port_orientaton(
                    position=label.position,
                    name=gdsname,
                    label=label.text,
                    n=n,
                ),
                layer=layer,
            )
            c.add_port(port)

    if rename_ports:
        auto_rename_ports(c)

    return c
Exemplo n.º 4
0
def demo_optical():
    """Demo. See equivalent test in tests/import_gds_markers.py"""
    # c  =  pp.c.mmi1x2()
    # for p in c.ports.values():
    #     print(p)
    # pp.show(c)

    gdspath = pp.CONFIG["gdsdir"] / "mmi1x2.gds"
    c = import_gds(gdspath)
    add_ports_from_markers_center(c)
    auto_rename_ports(c)
Exemplo n.º 5
0
def test_import_gds_with_port_markers_optical():
    """ """
    # c  =  pp.c.mmi1x2()
    # for p in c.ports.values():
    #     print(p)
    # pp.show(c)

    gdspath = pp.CONFIG["gdsdir"] / "mmi1x2.gds"
    c = import_gds(gdspath)
    add_ports_from_markers_center(c)
    auto_rename_ports(c)
Exemplo n.º 6
0
def demo_electrical():
    """Demo. See equivalent test in tests/import_gds_markers.py"""
    # c  =  pp.c.mzi2x2(with_elec_connections=True)
    # for p in c.ports.values():
    #     print(p)
    # pp.show(c)

    gdspath = pp.CONFIG["gdsdir"] / "mzi2x2.gds"
    c = import_gds(gdspath)
    add_ports_from_markers_center(c)
    auto_rename_ports(c)
    pp.show(c)

    for p in c.ports.values():
        print(p)
Exemplo n.º 7
0
def test_import_gds_with_port_markers_optical_electrical():
    """"""
    # c  =  pp.c.mzi2x2(with_elec_connections=True)
    # for p in c.ports.values():
    #     print(p)
    # pp.show(c)

    gdspath = pp.CONFIG["gdsdir"] / "mzi2x2.gds"
    c = import_gds(gdspath)
    add_ports_from_markers_center(c)
    auto_rename_ports(c)
    pp.show(c)

    for p in c.ports.values():
        print(p)
Exemplo n.º 8
0
def coupler_adiabatic(length1: float = 20.0,
                      length2: float = 50.0,
                      length3: float = 30.0,
                      wg_sep: float = 1.0,
                      input_wg_sep: float = 3.0,
                      output_wg_sep: float = 3.0,
                      dw: float = 0.1,
                      port: Tuple[int, int] = (0, 0),
                      direction: str = "EAST",
                      waveguide_template: Callable = wg_strip,
                      **kwargs) -> Component:
    """ 50/50 adiabatic coupler
    Adiabatic Coupler Cell class.  Design based on asymmetric adiabatic 3dB coupler designs, such as those from https://doi.org/10.1364/CLEO.2010.CThAA2, https://doi.org/10.1364/CLEO_SI.2017.SF1I.5, and https://doi.org/10.1364/CLEO_SI.2018.STh4B.4.  Uses Bezier curves for the input, with poles set to half of the x-length of the S-bend.

    In this design, Region I is the first half of the input S-bend waveguide where the input waveguides widths taper by +dw and -dw, Region II is the second half of the S-bend waveguide with constant, unbalanced widths, Region III is the region where the two asymmetric waveguides gradually come together, Region IV is the coupling region where the waveguides taper back to the original width at a fixed distance from one another, and Region IV is the  output S-bend waveguide.

    Args:
        length1 (float): Length of the region that gradually brings the two assymetric waveguides together.  In this region the waveguide widths gradually change to be different by `dw`.
        length2 (float): Length of the coupling region, where the asymmetric waveguides gradually become the same width.
        length3 (float): Length of the output region where the two waveguides separate.
        wg_sep (float): Distance between the two waveguides, center-to-center, in the coupling region (Region 2).
        input_wg_sep (float): Separation of the two waveguides at the input, center-to-center.
        output_wg_sep (float): Separation of the two waveguides at the output, center-to-center.
        dw (float): Change in waveguide width.  In Region 1, the top arm tapers to the waveguide width+dw/2.0, bottom taper to width-dw/2.0.
        port (tuple): Cartesian coordinate of the input port (top left).  Defaults to (0,0).
        direction (string): Direction that the component will point *towards*, can be of type `'NORTH'`, `'WEST'`, `'SOUTH'`, `'EAST'`, OR an angle (float, in radians).  Defaults to 'EAST'.
        waveguide_template: object or function

    Other Parameters:
       wg_width: 0.5
       wg_layer: pp.LAYER.WG[0]
       wg_datatype: pp.LAYER.WG[1]
       clad_layer: pp.LAYER.WGCLAD[0]
       clad_datatype: pp.LAYER.WGCLAD[1]
       bend_radius: 10
       cladding_offset: 3

    """

    c = pc.AdiabaticCoupler(
        pp.call_if_func(waveguide_template, **kwargs),
        length1=length1,
        length2=length2,
        length3=length3,
        wg_sep=wg_sep,
        input_wg_sep=input_wg_sep,
        output_wg_sep=output_wg_sep,
        dw=dw,
        port=port,
        direction=direction,
    )

    c = picwriter2component(c)
    c = auto_rename_ports(c)
    return c
Exemplo n.º 9
0
def bend_euler90_biased(radius=10.0,
                        width=0.5,
                        resolution=150.0,
                        layer=LAYER.WG):
    width = pp.bias.width(width)
    c = _bend_euler(theta=90,
                    radius=radius,
                    width=width,
                    resolution=resolution,
                    layer=layer)
    return auto_rename_ports(c)
Exemplo n.º 10
0
def spiral(width: float = 500.0,
           length: float = 10e3,
           spacing: Optional[float] = None,
           parity: int = 1,
           port: Tuple[int, int] = (0, 0),
           direction: str = "NORTH",
           waveguide_template: Callable = wg_strip,
           **kwargs) -> Component:
    """ Picwriter Spiral

    Args:
       width (float): width of the spiral (i.e. distance between input/output ports)
       length (float): desired length of the waveguide (um)
       spacing (float): distance between parallel waveguides
       parity (int): If 1 spiral on right side, if -1 spiral on left side (mirror flip)
       port (tuple): Cartesian coordinate of the input port
       direction (string): Direction that the component will point *towards*, can be of type `'NORTH'`, `'WEST'`, `'SOUTH'`, `'EAST'`, OR an angle (float, in radians)
       waveguide_template (WaveguideTemplate): Picwriter WaveguideTemplate object
       wg_width: 0.5
       wg_layer: pp.LAYER.WG[0]
       wg_datatype: pp.LAYER.WG[1]
       clad_layer: pp.LAYER.WGCLAD[0]
       clad_datatype: pp.LAYER.WGCLAD[1]
       bend_radius: 10
       cladding_offset: 3

    .. plot::
      :include-source:

      import pp

      c = pp.c.spiral(width=500, length=10e3)
      pp.plotgds(c)

    """
    c = pc.Spiral(
        pp.call_if_func(waveguide_template, **kwargs),
        width=width,
        length=length,
        spacing=spacing,
        parity=parity,
        port=port,
        direction=direction,
    )
    # print(f'length = {length/1e4:.2f}cm')
    c = picwriter2component(c)
    c = auto_rename_ports(c)
    return c
Exemplo n.º 11
0
def bend_euler180(
    radius: Union[int, float] = 10.0,
    width: float = 0.5,
    resolution: float = 150.0,
    layer: Tuple[int, int] = LAYER.WG,
) -> Component:
    """
    .. plot::
      :include-source:

      import pp

      c = pp.c.bend_euler180()
      pp.plotgds(c)

    """
    c = _bend_euler(theta=180,
                    radius=radius,
                    width=width,
                    resolution=resolution,
                    layer=layer)
    return auto_rename_ports(c)
Exemplo n.º 12
0
def test_components_ports(gdspath, num_regression):
    c = import_gds(gdspath)
    add_ports_from_markers_center(c)
    auto_rename_ports(c)
    num_regression.check(c.get_ports_array())
Exemplo n.º 13
0
import pp
from pp.import_gds import add_ports_from_markers_center, import_gds
from pp.port import auto_rename_ports

gdspaths = [
    pp.CONFIG["gdsdir"] / name for name in ["mmi1x2.gds", "mzi2x2.gds"]
]


@pytest.mark.parametrize("gdspath", gdspaths)
def test_components_ports(gdspath, num_regression):
    c = import_gds(gdspath)
    add_ports_from_markers_center(c)
    auto_rename_ports(c)
    num_regression.check(c.get_ports_array())


if __name__ == "__main__":
    c = import_gds(gdspaths[0])
    add_ports_from_markers_center(c)
    auto_rename_ports(c)
    print(c.ports.keys())
    print(c.name)

    c = import_gds(gdspaths[1])
    add_ports_from_markers_center(c)
    auto_rename_ports(c)
    print(c.ports.keys())
    print(c.name)