コード例 #1
0
ファイル: add_keepout.py プロジェクト: flaport/gdsfactory
def add_keepout(component,
                target_layers,
                keepout_layers,
                margin=2.0) -> Component:
    """Adds keepout after Looking up all polygons in a cell.
    You can also use add_padding

    Args:
        component
        target_layers: list of layers to read
        keepout_layers: list of layers to add keepout
        margin: offset from tareget to keepout_layers
    """
    c = Component(f"{component.name}_ko")
    c << component
    for layer in target_layers:
        polygons = component.get_polygons(by_spec=layer)
        if polygons:
            for ko_layer in keepout_layers:
                ko_layer = _parse_layer(ko_layer)
                polygon_keepout = [
                    polygon_grow(polygon, margin) for polygon in polygons
                ]
                c.add_polygon(polygon_keepout, ko_layer)
    return c
コード例 #2
0
def containerize(component: Component, function: Callable, **kwargs):
    """Returns a containerize component after applying a function.
    This is an alternative of using the @container decorator.
    However I recommend using the decorator when possible

    Args:
        component: to containerize
        function: that applies to component
        **kwargs: for the function

    .. code::

        import pp

        def add_label(component, text='hi'):
            return component.add_label(text)

        c = pp.c.waveguide()
        cc = pp.containerize(c, function=add_label, text='hi')

    """
    c = Component()
    component_type = f"{component.name}_{function.__name__}"
    name = get_component_name(component_type, **kwargs)
    if len(name) > MAX_NAME_LENGTH:
        c.name_long = name
        name = f"{component_type}_{hashlib.md5(name.encode()).hexdigest()[:8]}"
    c.name = name
    c << component
    function(c, **kwargs)
    return c
コード例 #3
0
def add_electrical_pads_top(component, **kwargs):
    """connects component electrical ports with pad array at the top

    Args:
        component:
        pad: pad element
        spacing: pad array (x, y) spacing
        width: pad width
        height: pad height
        layer: pad layer
    """
    c = Component(f"{component.name}_e")
    ports = component.get_ports_list(port_type="dc")
    c << component
    pads = c << pad_array(n=len(ports), port_list=["S"], **kwargs)
    pads.x = component.x
    pads.y = component.ymax + 100
    ports_pads = list(pads.ports.values())
    for p1, p2 in zip(ports_pads, ports):
        c.add(connect_electrical_shortest_path(p1, p2))

    c.ports = component.ports
    for port in ports:
        c.ports.pop(port.name)
    return c
コード例 #4
0
def demo_connect_bundle():
    """ combines all the connect_bundle tests """

    y = 400.0
    x = 500
    y0 = 900
    dy = 200.0
    c = Component("connect_bundle")
    for j, s in enumerate([-1, 1]):
        for i, angle in enumerate([0, 90, 180, 270]):
            c2 = test_connect_bundle_u_indirect(dy=s * dy, angle=angle)
            c2ref = c2.ref(position=(i * x, j * y))
            c.add(c2ref)

            c2 = test_connect_bundle_udirect(dy=s * dy, angle=angle)
            c2ref = c2.ref(position=(i * x, j * y + y0))
            c.add(c2ref)

    for i, config in enumerate(["A", "B", "C", "D"]):
        c2 = test_connect_corner(config=config)
        c2ref = c2.ref(position=(i * x, 1700))
        c.add(c2ref)

    c2 = test_facing_ports()
    c2ref = c2.ref(position=(800, 1820))
    c.add(c2ref)

    return c
コード例 #5
0
def add_labels(
    component: Component,
    port_type: str = "dc",
    get_label_function: Callable = get_input_label_electrical,
    layer_label: Layer = pp.LAYER.LABEL,
    gc: Optional[Component] = None,
) -> Component:
    """Add labels a particular type of ports

    Args:
        component: to add labels to
        port_type: type of port ('dc', 'optical', 'electrical')
        get_label_function: function to get label
        layer_label: layer_label

    Returns:
        original component with labels

    """
    ports = component.get_ports_list(port_type=port_type)

    for i, port in enumerate(ports):
        label = get_label_function(
            port=port,
            gc=gc,
            gc_index=i,
            component_name=component.name,
            layer_label=layer_label,
        )
        component.add(label)

    return component
コード例 #6
0
def write_gds(
    component: Component,
    gdspath: Optional[PosixPath] = None,
    gdsdir: PosixPath = tmp,
    unit: float = 1e-6,
    precision: float = 1e-9,
    auto_rename: bool = False,
) -> PosixPath:
    """Write component to GDS and returs gdspath

    Args:
        component: gdsfactory Component.
        gdspath: GDS file path to write to.
        unit unit size for objects in library.
        precision: for the dimensions of the objects in the library (m).
        remove_previous_markers: clear previous ones to avoid duplicates.
        auto_rename: If True, fixes any duplicate cell names.

    Returns:
        gdspath
    """

    gdsdir = pathlib.Path(gdsdir)
    gdspath = gdspath or gdsdir / (component.name + ".gds")
    gdspath = pathlib.Path(gdspath)
    gdsdir = gdspath.parent
    gdsdir.mkdir(exist_ok=True, parents=True)

    component.write_gds(
        str(gdspath), unit=unit, precision=precision, auto_rename=auto_rename,
    )
    component.path = gdspath
    return gdspath
コード例 #7
0
def add_trenches(
    c: Component,
    sstw: float = 2.0,
    trench_width: float = 0.5,
    trench_keep_out: float = 2.0,
    trenches: List[Dict[str, int]] = [
        {
            "nb_segments": 2,
            "lane": 1,
            "x_start_offset": 0
        },
        {
            "nb_segments": 2,
            "lane": -1,
            "x_start_offset": 0
        },
    ],
    layer_trench: Tuple[int, int] = LAYER.DEEPTRENCH,
) -> Component:
    """
    Add trenches to a waveguide-heater-like component
    """

    heater_width = c.settings["heater_width"]
    heater_spacing = c.settings["heater_spacing"]
    width = c.settings["width"]
    length = c.settings["length"]

    a = heater_spacing + (width + heater_width) / 2

    # Add trenches
    if trench_width and trench_width > 0:
        tko = trench_keep_out

        for trench in trenches:
            lane = trench["lane"]
            td = tko + a + (trench_width + heater_width) / 2
            y = np.sign(lane) * (td + (abs(lane) - 1) * (trench_width + tko))
            x_start_offset = trench["x_start_offset"]

            if "segments" not in trench:
                nb_segments = trench["nb_segments"]
                trench_length = (length -
                                 (nb_segments - 1) * sstw) / nb_segments
                segments = [trench_length] * nb_segments
            else:
                segments = trench["segments"]
            x = x_start_offset
            for i, trench_length in enumerate(segments):
                trench = hline(length=trench_length,
                               width=trench_width,
                               layer=layer_trench)
                _trench = trench.ref(port_id="W0",
                                     position=c.ports["W0"].position + (x, y))
                c.add(_trench)
                c.absorb(_trench)
                x += trench_length + sstw

    return c
コード例 #8
0
def _add_pin_square(
    component: Component,
    port: Port,
    pin_length: float = 0.1,
    layer: Tuple[int, int] = LAYER.PORT,
    label_layer: Optional[Tuple[int, int]] = LAYER.PORT,
    port_margin: float = 0.0,
) -> None:
    """Add half out pin to a component.

    Args:
        component:
        port: Port
        pin_length: length of the pin marker for the port
        layer: for the pin marker
        label_layer: for the label
        port_margin: margin to port edge


    .. code::

           _______________
          |               |
          |               |
          |               |
         |||              |
         |||              |
          |               |
          |      __       |
          |_______________|
                 __

    """
    p = port
    a = p.orientation
    ca = np.cos(a * np.pi / 180)
    sa = np.sin(a * np.pi / 180)
    rot_mat = np.array([[ca, -sa], [sa, ca]])

    d = p.width / 2 + port_margin

    dbot = np.array([pin_length / 2, -d])
    dtop = np.array([pin_length / 2, d])
    dbotin = np.array([-pin_length / 2, -d])
    dtopin = np.array([-pin_length / 2, +d])

    p0 = p.position + _rotate(dbot, rot_mat)
    p1 = p.position + _rotate(dtop, rot_mat)
    ptopin = p.position + _rotate(dtopin, rot_mat)
    pbotin = p.position + _rotate(dbotin, rot_mat)
    polygon = [p0, p1, ptopin, pbotin]
    component.add_polygon(polygon, layer=layer)

    if label_layer:
        component.add_label(
            text=str(p.name),
            position=p.midpoint,
            layer=label_layer,
        )
コード例 #9
0
ファイル: rotate.py プロジェクト: flaport/gdsfactory
def rotate(component: Component, angle: int = 90) -> Component:
    """ returns rotated component
    """
    c = Component(f"{component.name}_r")
    cr = c.add_ref(component)
    cr.rotate(angle)
    c.ports = cr.ports
    return c
コード例 #10
0
def write_gds(
    component: Component,
    gdspath: Optional[PosixPath] = None,
    unit: float = 1e-6,
    precision: float = 1e-9,
    remove_previous_markers: bool = False,
    auto_rename: bool = False,
    with_settings_label: bool = conf.tech.with_settings_label,
) -> str:
    """write component to GDS and returs gdspath

    Args:
        component (required)
        gdspath: by default saves it into CONFIG['gds_directory']
        auto_rename: False by default (otherwise it calls it top_cell)
        unit
        precission

    Returns:
        gdspath
    """

    gdspath = gdspath or CONFIG["gds_directory"] / (component.name + ".gds")
    gdspath = pathlib.Path(gdspath)
    gdsdir = gdspath.parent
    gdspath = str(gdspath)
    gdsdir.mkdir(parents=True, exist_ok=True)

    if remove_previous_markers:
        # If the component HAS ports AND markers and we want to
        # avoid duplicate port markers, then we clear the previous ones
        port_layer = (LAYER.PORT, )
        label_layer = (LAYER.TEXT, )
        component.remove_layers([port_layer])
        component.remove_layers([label_layer])

    # write component settings into text layer
    if with_settings_label:
        settings = component.get_settings()

        for i, k in enumerate(sorted(list(settings.keys()))):
            v = clean_value(settings.get(k))
            text = f"{k} = {clean_value(v)}"
            # print(text)
            component.add_label(
                text=text,
                position=component.center - [0, i * 1],
                layer=CONFIG["layers"]["TEXT"],
            )

    component.write_gds(
        gdspath,
        precision=precision,
        auto_rename=auto_rename,
    )
    component.path = gdspath
    return gdspath
コード例 #11
0
def corner(width=WIRE_WIDTH, radius=None, layer=LAYER.M3):
    """ 90 degrees electrical bend

    Args:
        width: wire width
        radius ignore (passed for consistency with other types of bends)
        layer: layer

    .. plot::
      :include-source:

      import pp

      c = pp.c.corner(width=10., layer=pp.LAYER.M3)
      pp.plotgds(c)
    """
    c = Component()
    a = width / 2
    xpts = [-a, a, a, -a]
    ypts = [-a, -a, a, a]

    c.add_polygon([xpts, ypts], layer=layer)
    c.add_port(name="W0", midpoint=(-a, 0), width=width, orientation=180)
    c.add_port(name="N0", midpoint=(0, a), width=width, orientation=90)
    c.info["length"] = width
    return c
コード例 #12
0
def _add_settings_label(
    component: Component,
    reference: ComponentReference,
    label_layer: Tuple[int, int] = LAYER.LABEL_SETTINGS,
) -> None:
    """Add settings in label, ignores component.ignore keys."""
    settings = reference.get_settings()
    settings_string = f"settings={json.dumps(settings, indent=2)}"
    component.add_label(
        position=reference.center, text=settings_string, layer=label_layer
    )
コード例 #13
0
ファイル: pads_shorted.py プロジェクト: smartalecH/gdsfactory
def pads_shorted(width=100, n_pads=8, pad_spacing=150, layer=LAYER.M1):
    c = Component(name="shorted_pads")
    pad = rectangle_centered(x=width, y=width, layer=layer)
    for i in range(n_pads):
        pad_ref = c.add_ref(pad)
        pad_ref.movex(i * pad_spacing - n_pads / 2 * pad_spacing +
                      pad_spacing / 2)

    short = rectangle_centered(x=pad_spacing * (n_pads - 1), y=10, layer=layer)
    c.add_ref(short)
    return c
コード例 #14
0
ファイル: rotate.py プロジェクト: jaspreetj/gdsfactory
def rotate(component, angle=90):
    """ returns rotated component
    """
    c = Component(
        settings=component.get_settings(),
        test_protocol=component.test_protocol,
        data_analysis_protocol=component.data_analysis_protocol,
    )
    cr = c.add_ref(component)
    cr.rotate(angle)
    c.ports = cr.ports
    c.name = component.name + "_r"
    return c
コード例 #15
0
def pads_shorted(width=100, n_pads=8, pad_spacing=150, layer=LAYER.M1):
    c = Component(name="shorted_pads")
    pad = rectangle(size=(width, width), layer=layer, centered=True)
    for i in range(n_pads):
        pad_ref = c.add_ref(pad)
        pad_ref.movex(i * pad_spacing - n_pads / 2 * pad_spacing +
                      pad_spacing / 2)

    short = rectangle(size=(pad_spacing * (n_pads - 1), 10),
                      layer=layer,
                      centered=True)
    c.add_ref(short)
    return c
コード例 #16
0
def test_connect_bundle_u_indirect(dy=-200, angle=180):
    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)
        ]

    top_cell = Component("connect_bundle_u_indirect")
    routes = connect_bundle(ports1, ports2)
    lengths = [
        341.41592653589794,
        341.41592653589794,
        341.41592653589794,
        326.41592653589794,
        316.41592653589794,
        291.41592653589794,
        291.41592653589794,
        311.41592653589794,
    ]

    for route, length in zip(routes, lengths):
        # print(route.parent.length)
        assert np.isclose(route.parent.length, length)

    top_cell.add(routes)

    return top_cell
コード例 #17
0
def bbox(bbox=[(-1, -1), (3, 4)], layer=(1, 0)):
    """ Creates a bounding box rectangle from coordinates, to allow
    creation of a rectangle bounding box directly form another shape.

    Args:
        bbox: Coordinates of the box [(x1, y1), (x2, y2)].
        layer:

    """
    D = Component(name="bbox")
    (a, b), (c, d) = bbox
    points = ((a, b), (c, b), (c, d), (a, d))
    D.add_polygon(points, layer=layer)
    return D
コード例 #18
0
def L(
    width: Union[int, float] = 1,
    size: Tuple[int, int] = (10, 20),
    layer: Tuple[int, int] = LAYER.M3,
) -> Component:
    """Generates an 'L' geometry with ports on both ends. Based on phidl.

    Args:
        width: of the line
        size: length and height of the base
        layer:

    .. plot::
      :include-source:

      import pp

      c = pp.c.L(width1=1, size=(10, 20), layer=pp.LAYER.M3)
      pp.plotgds(c)

    """
    D = Component()
    w = width / 2
    s1, s2 = size
    points = [(-w, -w), (s1, -w), (s1, w), (w, w), (w, s2), (-w, s2), (-w, -w)]
    D.add_polygon(points, layer=layer)
    D.add_port(name=1, midpoint=(0, s2), width=width, orientation=90)
    D.add_port(name=2, midpoint=(s1, 0), width=width, orientation=0)
    return D
コード例 #19
0
def add_grating_couplers(
    component: Component,
    grating_coupler=grating_coupler_te,
    layer_label=pp.LAYER.LABEL,
    gc_port_name: str = "W0",
    get_input_labels_function=get_input_labels,
):
    """Return component with grating couplers and labels."""

    cnew = Component(name=component.name + "_c")
    cnew.add_ref(component)
    grating_coupler = pp.call_if_func(grating_coupler)

    io_gratings = []
    for port in component.ports.values():
        gc_ref = grating_coupler.ref()
        gc_ref.connect(list(gc_ref.ports.values())[0], port)
        io_gratings.append(gc_ref)
        cnew.add(gc_ref)

    labels = get_input_labels_function(
        io_gratings,
        list(component.ports.values()),
        component_name=component.name,
        layer_label=layer_label,
        gc_port_name=gc_port_name,
    )
    cnew.add(labels)
    return cnew
コード例 #20
0
def _add_pin_square_inside(
    component: Component,
    port: Port,
    pin_length: float = 0.1,
    layer: Tuple[int, int] = LAYER.PORT,
    label_layer: Tuple[int, int] = LAYER.TEXT,
) -> None:
    """Add square pin towards the inside of the port

    Args:
        component:
        port: Port
        pin_length: length of the pin marker for the port
        layer: for the pin marker
        label_layer: for the label
        port_margin: margin to port edge

    .. code::

           _______________
          |               |
          |               |
          |               |
          ||              |
          ||              |
          |               |
          |      __       |
          |_______________|


    """
    p = port
    a = p.orientation
    ca = np.cos(a * np.pi / 180)
    sa = np.sin(a * np.pi / 180)
    rot_mat = np.array([[ca, -sa], [sa, ca]])

    d = p.width / 2

    dbot = np.array([0, -d])
    dtop = np.array([0, d])
    dbotin = np.array([-pin_length, -d])
    dtopin = np.array([-pin_length, +d])

    p0 = p.position + _rotate(dbot, rot_mat)
    p1 = p.position + _rotate(dtop, rot_mat)
    ptopin = p.position + _rotate(dtopin, rot_mat)
    pbotin = p.position + _rotate(dbotin, rot_mat)
    polygon = [p0, p1, ptopin, pbotin]
    component.add_polygon(polygon, layer=layer)
コード例 #21
0
def test_connect_bundle_udirect(dy=200, angle=270):

    xs1 = [-100, -90, -80, -55, -35, 24, 0] + [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)]

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

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

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

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

    top_cell = Component(name="connect_bundle_udirect")
    routes = connect_bundle(ports1, ports2)
    lengths = [
        237.4359265358979,
        281.4359265358979,
        336.4359265358979,
        376.4359265358979,
        421.4359265358979,
        451.4359265358979,
        481.4359265358979,
        271.4359265358979,
    ]

    for route, length in zip(routes, lengths):
        # print(route.parent.length)
        assert np.isclose(route.parent.length, length)

    top_cell.add(routes)
    return top_cell
コード例 #22
0
def _add_padding(component, x=50, y=50, layers=(LAYER.PADDING), suffix="p"):
    """Adds padding layers to component.
    This is just an example. For the real function see pp.add_padding.
    """
    c = Component(name=f"{component.name}_{suffix}")
    c << component
    points = [
        [c.xmin - x, c.ymin - y],
        [c.xmax + x, c.ymin - y],
        [c.xmax + x, c.ymax + y],
        [c.xmin - x, c.ymax + y],
    ]
    for layer in layers:
        c.add_polygon(points, layer=layer)
    return c
コード例 #23
0
def read_yaml(yaml: Union[str, pathlib.Path, IO[Any]]) -> Component:
    """ Loads Components settings from yaml file and writes the GDS into build_directory

    Args:
        yaml: YAML IO describing DOE

    Returns:
        Component
    """
    c = Component()

    yaml = io.StringIO(yaml) if isinstance(yaml,
                                           str) and "\n" in yaml else yaml
    conf = OmegaConf.load(yaml)

    for component_name in conf:
        component_conf = conf[component_name]
        component_type = component_conf["component"]
        component_settings = component_conf["settings"]
        ci = component_factory[component_type](**component_settings)
        component_properties = component_conf["properties"]
        for k, v in component_properties.items():
            setattr(ci, k, v)
        ci.name = component_name
        c << ci
    return c
コード例 #24
0
def get_sparameters_path(
    component: Component,
    dirpath: PosixPath = CONFIG["sp"],
    layer2material: Dict[Tuple[int, int], str] = layer2material_default,
    layer2nm: Dict[Tuple[int, int], int] = layer2nm_default,
    **kwargs,
) -> PosixPath:
    """Returns Sparameters filepath.

    Args:
        component:
        dirpath
        layer2material: GDSlayer to material alias (see aliases in pp.sp.write)
        layer2nm: GDSlayer to thickness (nm)
    """
    dirpath = pathlib.Path(dirpath)
    dirpath = dirpath / component.function_name if component.function_name else dirpath
    dirpath.mkdir(exist_ok=True, parents=True)
    material2nm = {
        layer2material[layer]: layer2nm[layer]
        for layer in layer2nm.keys() if layer in component.get_layers()
    }
    suffix = dict2name(**material2nm)
    if kwargs:
        suffix += "_" + dict2name(**kwargs)
    return dirpath / f"{component.get_name_long()}_{suffix}.dat"
コード例 #25
0
def _add_instance_label(
    component: Component,
    reference: ComponentReference,
    instance_name: Optional[str] = None,
    layer: Tuple[int, int] = LAYER.LABEL_INSTANCE,
) -> None:
    """Adds label to a reference in a component."""

    instance_name = (
        instance_name
        or f"{reference.parent.name},{int(reference.x)},{int(reference.y)}")
    component.add_label(
        text=instance_name,
        position=pp.drc.snap_to_1nm_grid((reference.x, reference.y)),
        layer=layer,
    )
コード例 #26
0
ファイル: cell.py プロジェクト: flaport/gdsfactory
def wg3(length=3, width=0.5):
    from pp.component import Component

    c = Component("waveguide")
    w = width / 2
    layer = (1, 0)
    c.add_polygon([(0, -w), (length, -w), (length, w), (0, w)], layer=layer)
    c.add_port(name="W0", midpoint=[0, 0], width=width, orientation=180, layer=layer)
    c.add_port(name="E0", midpoint=[length, 0], width=width, orientation=0, layer=layer)
    return c
コード例 #27
0
def pad(
    width: int = 100, height: int = 100, layer: Tuple[int, int] = LAYER.M3
) -> Component:
    """rectangular pad with 4 ports (N, S, E, W)

    Args:
        width: pad width
        height: pad height
        layer: pad layer


    .. plot::
      :include-source:

      import pp

      c = pp.c.pad(width=100, height=100, layer=pp.LAYER.M3)
      pp.plotgds(c)

    """
    c = Component()
    _c = compass(size=(width, height), layer=layer).ref()
    c.add(_c)
    c.absorb(_c)
    c.ports = _c.ports
    return c
コード例 #28
0
def connect_electrical_shortest_path(port1, port2):
    """connects two ports with a polygon that takes the shortest path"""
    points = [port1.midpoint, port2.midpoint]
    name = f"zz_conn_{hash_points(points)}"
    c = Component(name=name)
    layer = port1.layer
    p1x0 = port1.endpoints[0][0]
    p1y0 = port1.endpoints[0][1]
    p1x1 = port1.endpoints[1][0]
    p1y1 = port1.endpoints[1][1]

    p2x0 = port2.endpoints[0][0]
    p2y0 = port2.endpoints[0][1]
    p2x1 = port2.endpoints[1][0]
    p2y1 = port2.endpoints[1][1]

    if port1.orientation in [90, 270]:
        c.add_polygon(
            ([(p1x1, p1y0), (p1x0, p1y1), (p2x1, p2y1), (p2x0, p2y0)]), layer=layer
        )
    else:
        c.add_polygon(
            ([(p1x0, p1y1), (p1x1, p1y0), (p2x1, p2y1), (p2x0, p2y0)]), layer=layer
        )
    return c.ref()
コード例 #29
0
def wg_heater_connected(waveguide_heater: Callable = waveguide_heater,
                        wg_heater_connector: Callable = wg_heater_connector,
                        tlm_layers: List[Tuple[int, int]] = [
                            LAYER.VIA1,
                            LAYER.M1,
                            LAYER.VIA2,
                            LAYER.M2,
                            LAYER.VIA3,
                            LAYER.M3,
                        ],
                        **kwargs) -> Component:
    """
    .. plot::
      :include-source:

      import pp

      c = pp.c.wg_heater_connected()
      pp.plotgds(c)

    """
    wg_heater = waveguide_heater(**kwargs)
    # print(wg_heater.ports.keys())
    conn1 = wg_heater_connector(
        heater_ports=[wg_heater.ports["HBE0"], wg_heater.ports["HTE0"]],
        tlm_layers=tlm_layers,
    )

    conn2 = wg_heater_connector(
        heater_ports=[wg_heater.ports["HBW0"], wg_heater.ports["HTW0"]],
        tlm_layers=tlm_layers,
    )

    cmp = Component()
    for c in [wg_heater, conn1, conn2]:
        _c = cmp.add_ref(c)
        cmp.absorb(_c)

    for port_name, p in wg_heater.ports.items():
        cmp.add_port(name=port_name, port=p)

    cmp.add_port(name=1, port=conn1.ports["0"])
    cmp.add_port(name=2, port=conn2.ports["0"])
    cmp.ports[1].orientation = 90
    cmp.ports[2].orientation = 90

    return cmp
コード例 #30
0
def add_ports_from_markers_square(
    component: Component,
    layer: Layer = pp.LAYER.PORTE,
    port_type: "str" = "dc",
    orientation: int = 90,
    min_pin_area_um2: float = 0,
    pin_extra_width: float = 0.0,
    port_names: Optional[Iterable[str]] = None,
):
    """add ports from markers in port_layer

    adds ports at the marker center

    Args:
        component: to read polygons from and to write ports to
        layer: for port markers
        port_type: electrical, dc, optical
        orientation: orientation in degrees
            90: north, 0: east, 180: west, 270: south
        pin_extra_width: 2*offset from pin to waveguide
        min_pin_area_um2: ignores pins with area smaller than min_pin_area_um2
        port_names: names of the ports (defaults to f"{port_type}_{i}")

    """
    port_markers = read_port_markers(component, [layer])

    port_names = None or [f"{port_type}_{i}" for i in range(len(port_markers.polygons))]

    for port_name, p in zip(port_names, port_markers.polygons):
        dy = snap_to_1nm_grid(p.ymax - p.ymin)
        dx = snap_to_1nm_grid(p.xmax - p.xmin)
        x = p.x
        y = p.y
        if dx == dy and dx * dy > min_pin_area_um2:
            component.add_port(
                port_name,
                midpoint=(x, y),
                width=dx - pin_extra_width,
                orientation=orientation,
                port_type=port_type,
                layer=layer,
            )