Example #1
0
def add_keepout(
    component: Component,
    target_layers: Layers,
    keepout_layers: Layers,
    margin: float = 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
Example #2
0
def get_input_label_electrical(port,
                               index=0,
                               component_name=None,
                               layer_label=LAYER.LABEL):
    """
    Generate a label to test component info for a given grating coupler.
    This is the label used by T&M to extract grating coupler coordinates
    and match it to the component.
    """

    if component_name:
        name = component_name

    elif type(port.parent) == pp.Component:
        name = port.parent.name
    else:
        name = port.parent.ref_cell.name

    text = "elec_{}_({})_{}".format(index, name, port.name)

    gds_layer_label, gds_datatype_label = pd._parse_layer(layer_label)

    label = pd.Label(
        text=text,
        position=port.midpoint,
        anchor="o",
        layer=gds_layer_label,
        texttype=gds_datatype_label,
    )
    return label
Example #3
0
File: add_gc.py Project: tvt173/ubc
def get_input_labels(
    io_gratings,
    ordered_ports,
    component_name,
    layer_label=layer_label,
    gc_port_name=gc_port_name,
    port_index=1,
):
    """ get labels for all component ports """
    if port_index == -1:
        return get_input_labels_all(
            io_gratings=io_gratings,
            ordered_ports=ordered_ports,
            component_name=component_name,
            gc_port_name=gc_port_name,
            port_index=port_index,
        )
    gc = io_gratings[port_index]
    port = ordered_ports[1]

    text = get_optical_text(port=port,
                            gc=gc,
                            gc_index=port_index,
                            component_name=component_name)
    print(text)
    layer, texttype = pd._parse_layer(layer_label)
    label = pd.Label(
        text=text,
        position=gc.ports[gc_port_name].midpoint,
        anchor="o",
        layer=layer,
        texttype=texttype,
    )
    return [label]
Example #4
0
def get_input_labels(
    io_gratings: List[ComponentReference],
    ordered_ports: List[Port],
    component_name: str,
    layer_label: Tuple[int, int] = LAYER.LABEL,
    gc_port_name: str = "W0",
    port_index: int = 1,
) -> List[Label]:
    """Return labels (elements list) for all component ports."""
    if port_index == -1:
        return get_input_labels_all(
            io_gratings=io_gratings,
            ordered_ports=ordered_ports,
            component_name=component_name,
            layer_label=layer_label,
            gc_port_name=gc_port_name,
        )
    gc = io_gratings[port_index]
    port = ordered_ports[1]

    text = get_optical_text(port=port,
                            gc=gc,
                            gc_index=port_index,
                            component_name=component_name)
    layer, texttype = pd._parse_layer(layer_label)
    label = pd.Label(
        text=text,
        position=gc.ports[gc_port_name].midpoint,
        anchor="o",
        layer=layer,
        texttype=texttype,
    )
    return [label]
Example #5
0
def get_input_label(
    port: Port,
    gc: ComponentReference,
    gc_index: Optional[int] = None,
    gc_port_name: str = "W0",
    layer_label: ListConfig = pp.LAYER.LABEL,
    component_name: Optional[str] = None,
) -> Label:
    """
    Generate a label with component info for a given grating coupler.
    This is the label used by T&M to extract grating coupler coordinates
    and match it to the component.
    """
    text = get_optical_text(port=port,
                            gc=gc,
                            gc_index=gc_index,
                            component_name=component_name)

    if gc_port_name is None:
        gc_port_name = list(gc.ports.values())[0].name

    layer, texttype = pd._parse_layer(layer_label)
    label = pd.Label(
        text=text,
        position=gc.ports[gc_port_name].midpoint,
        anchor="o",
        layer=layer,
        texttype=texttype,
    )
    return label
Example #6
0
def add_keepout(c, target_layers, keepout_layers, margin=2.0):
    """
    Lookup all polygons in this cell
    """
    all_cells = list(c.get_dependencies(True)) + [c]
    for _c in all_cells:
        for _layer in target_layers:
            polys_by_layer = _c.get_polygons(by_spec=True)
            layer = _parse_layer(_layer)
            for ko_layer in keepout_layers:
                ko_layer = _parse_layer(ko_layer)
                polys = polys_by_layer[
                    layer] if layer in polys_by_layer else []
                if not polys:
                    continue

                ko_polys_pts = [polygon_grow(poly, margin) for poly in polys]
                _c.add_polygon(ko_polys_pts, ko_layer)
Example #7
0
    def extract(
        self,
        layers: Union[List[Tuple[int, int]], Tuple[int, int]] = (),
    ) -> Device:
        """Extract polygons from a Component.
        adapted from phidl.geometry.
        """
        from gdsfactory.name import clean_value

        component = Component(f"{self.name}_{clean_value(layers)}")
        if type(layers) not in (list, tuple):
            raise ValueError("layers needs to be a list or tuple")
        poly_dict = self.get_polygons(by_spec=True)
        parsed_layer_list = [_parse_layer(layer) for layer in layers]
        for layer, polys in poly_dict.items():
            if _parse_layer(layer) in parsed_layer_list:
                component.add_polygon(polys, layer=layer)
        return component
Example #8
0
    def remove_layers(
        self,
        layers: Union[List[Tuple[int, int]], Tuple[int, int]] = (),
        include_labels: bool = True,
        invert_selection: bool = False,
        recursive: bool = True,
    ) -> Device:
        """Remove a list of layers."""
        layers = [_parse_layer(layer) for layer in layers]
        all_D = list(self.get_dependencies(recursive))
        all_D += [self]
        for D in all_D:
            for polygonset in D.polygons:
                polygon_layers = zip(polygonset.layers, polygonset.datatypes)
                polygons_to_keep = [(pl in layers) for pl in polygon_layers]
                if not invert_selection:
                    polygons_to_keep = [(not p) for p in polygons_to_keep]
                polygonset.polygons = [
                    p for p, keep in zip(polygonset.polygons, polygons_to_keep)
                    if keep
                ]
                polygonset.layers = [
                    p for p, keep in zip(polygonset.layers, polygons_to_keep)
                    if keep
                ]
                polygonset.datatypes = [
                    p
                    for p, keep in zip(polygonset.datatypes, polygons_to_keep)
                    if keep
                ]

            if include_labels:
                new_labels = []
                for label in D.labels:
                    original_layer = (label.layer, label.texttype)
                    original_layer = _parse_layer(original_layer)
                    if invert_selection:
                        keep_layer = original_layer in layers
                    else:
                        keep_layer = original_layer not in layers
                    if keep_layer:
                        new_labels += [label]
                D.labels = new_labels
        return self
Example #9
0
    def remove_layers(self,
                      layers=(),
                      include_labels=True,
                      invert_selection=False,
                      recursive=True):
        """ remove a list of layers """
        layers = [_parse_layer(l) for l in layers]
        all_D = list(self.get_dependencies(recursive))
        all_D += [self]
        for D in all_D:
            for polygonset in D.polygons:
                polygon_layers = zip(polygonset.layers, polygonset.datatypes)
                polygons_to_keep = [(pl in layers) for pl in polygon_layers]
                if invert_selection == False:
                    polygons_to_keep = [(not p) for p in polygons_to_keep]
                polygonset.polygons = [
                    p for p, keep in zip(polygonset.polygons, polygons_to_keep)
                    if keep
                ]
                polygonset.layers = [
                    p for p, keep in zip(polygonset.layers, polygons_to_keep)
                    if keep
                ]
                polygonset.datatypes = [
                    p
                    for p, keep in zip(polygonset.datatypes, polygons_to_keep)
                    if keep
                ]

            if include_labels == True:
                new_labels = []
                for l in D.labels:
                    original_layer = (l.layer, l.texttype)
                    original_layer = _parse_layer(original_layer)
                    if invert_selection:
                        keep_layer = original_layer in layers
                    else:
                        keep_layer = original_layer not in layers
                    if keep_layer:
                        new_labels += [l]
                D.labels = new_labels
        return self
Example #10
0
def add_label(component, text, position=(0, 0), layer=pp.LAYER.LABEL):
    gds_layer_label, gds_datatype_label = pd._parse_layer(layer)
    label = pd.Label(
        text=text,
        position=position,
        anchor="o",
        layer=gds_layer_label,
        texttype=gds_datatype_label,
    )
    component.add(label)
    return component
Example #11
0
def label(text, position=(0, 0), layer=66):

    gds_layer_label, gds_datatype_label = pd._parse_layer(layer)

    label_ref = pd.Label(
        text=text,
        position=position,
        anchor="o",
        layer=gds_layer_label,
        texttype=gds_datatype_label,
    )
    return label_ref
Example #12
0
def write_component(
    component: Component,
    gdspath: Optional[PosixPath] = None,
    path_library: PosixPath = CONFIG["gds_directory"],
    precision: float = 1e-9,
    settings: None = None,
    with_settings_label: bool = conf.tech.with_settings_label,
) -> str:
    """write component GDS and metadata:

    - gds
    - ports
    - properties

    Args:
        component:
        gdspath:
        path_library
        precision: to save GDS points
        settings: dict of settings
    """

    gdspath = gdspath or path_library / (component.name + ".gds")
    gdspath = pathlib.Path(gdspath)
    ports_path = gdspath.with_suffix(".ports")
    json_path = gdspath.with_suffix(".json")
    """ write GDS """
    gdspath = write_gds(
        component=component,
        gdspath=str(gdspath),
        precision=precision,
        with_settings_label=with_settings_label,
    )
    """ write .ports in CSV"""
    if len(component.ports) > 0:
        with open(ports_path, "w") as fw:
            for _, port in component.ports.items():
                layer, texttype = pd._parse_layer(port.layer)

                fw.write("{}, {:.3f}, {:.3f}, {}, {:.3f}, {}, {}\n".format(
                    port.name,
                    port.x,
                    port.y,
                    int(port.orientation),
                    port.width,
                    layer,
                    texttype,
                ))
    """ write JSON """
    with open(json_path, "w+") as fw:
        fw.write(json.dumps(component.get_json(), indent=2))
    return gdspath
Example #13
0
def label(
    text: str = "abc",
    position: Tuple[float, float] = (0.0, 0.0),
    layer: Tuple[int, int] = pp.LAYER.TEXT,
) -> Label:

    gds_layer_label, gds_datatype_label = pd._parse_layer(layer)

    label_ref = pd.Label(
        text=text,
        position=position,
        anchor="o",
        layer=gds_layer_label,
        texttype=gds_datatype_label,
    )
    return label_ref
Example #14
0
def write_component(
    component: Component,
    gdspath: Optional[PosixPath] = None,
    gdsdir: PosixPath = tmp,
    precision: float = 1e-9,
) -> PosixPath:
    """write component GDS and metadata:

    - gds
    - ports
    - properties

    Args:
        component:
        gdspath:
        path_library
        precision: to save GDS points
    """

    gdspath = gdspath or gdsdir / (component.name + ".gds")
    gdspath = pathlib.Path(gdspath)
    ports_path = gdspath.with_suffix(".ports")
    json_path = gdspath.with_suffix(".json")

    gdspath = write_gds(
        component=component,
        gdspath=str(gdspath),
        precision=precision,
    )

    # component.ports CSV
    if len(component.ports) > 0:
        with open(ports_path, "w") as fw:
            for port in component.ports.values():
                layer, purpose = pd._parse_layer(port.layer)
                fw.write(
                    f"{port.name}, {port.x:.3f}, {port.y:.3f}, {int(port.orientation)}, {port.width:.3f}, {layer}, {purpose}\n"
                )

    # component.json metadata dict
    with open(json_path, "w+") as fw:
        fw.write(json.dumps(component.get_json(), indent=2))
    return gdspath
def get_input_label_electrical(
    port: Port,
    gc_index: int = 0,
    component_name: Optional[str] = None,
    layer_label: Layer = pp.LAYER.LABEL,
    gc: Optional[ComponentReference] = None,
):
    """
    Generate a label to test component info for a given electrical port.
    This is the label used by T&M to extract grating coupler coordinates
    and match it to the component.

    Args:
        port:
        gc_index: index of the label
        component_name:
        layer_label:
        gc: ignored
    """

    if component_name:
        name = component_name

    elif isinstance(port.parent, pp.Component):
        name = port.parent.name
    else:
        name = port.parent.ref_cell.name

    text = f"elec_{gc_index}_({name})_{port.name}"
    layer, texttype = pd._parse_layer(layer_label)
    label = pd.Label(
        text=text,
        position=port.midpoint,
        anchor="o",
        layer=layer,
        texttype=texttype,
    )
    return label
Example #16
0
def get_input_label(
    port: Port,
    gc: ComponentReference,
    gc_index: Optional[int] = None,
    gc_port_name: str = "o1",
    layer_label: Layer = gf.LAYER.LABEL,
    component_name: Optional[str] = None,
    get_input_label_text_function=get_input_label_text,
) -> Label:
    """Returns a label with component info for a given grating coupler.
    Test equipment to extract grating coupler coordinates and match it to the component.

    Args:
        port: port to label
        gc: grating coupler reference
        gc_index: grating coupler index
        gc_port_name: name of grating coupler port
        layer_label: layer of the label
        component_name: for the label
        get_input_label_text_function: function to get input label
    """
    text = get_input_label_text_function(port=port,
                                         gc=gc,
                                         gc_index=gc_index,
                                         component_name=component_name)

    if gc_port_name is None:
        gc_port_name = list(gc.ports.values())[0].name

    layer, texttype = pd._parse_layer(layer_label)
    return Label(
        text=text,
        position=gc.ports[gc_port_name].midpoint,
        anchor="o",
        layer=layer,
        texttype=texttype,
    )
def add_fiber_single(
    component: Component,
    grating_coupler: Callable = grating_coupler_te,
    layer_label: Tuple[int, int] = LAYER.LABEL,
    optical_io_spacing: int = 50,
    bend_factory: Callable = bend_circular,
    straight_factory: Callable = waveguide,
    taper_factory: Callable = taper,
    taper_length: float = 10.0,
    route_filter: Callable = connect_strip_way_points,
    min_input2output_spacing: int = 127,
    optical_routing_type: int = 2,
    with_align_ports: bool = True,
    component_name: Optional[str] = None,
    gc_port_name: str = "W0",
    **kwargs,
) -> Component:
    r"""returns component with grating ports and labels on each port
    can add align_ports reference structure

    Args:
        component: to connect
        grating_coupler: grating coupler instance, function or list of functions
        layer_label: LAYER.LABEL
        optical_io_spacing: SPACING_GC
        bend_factory: bend_circular
        straight_factory: waveguide
        fanout_length: None  # if None, automatic calculation of fanout length
        max_y0_optical: None
        with_align_ports: True, adds loopback structures
        waveguide_separation: 4.0
        bend_radius: BEND_RADIUS
        list_port_labels: None, adds TM labels to port indices in this list
        connected_port_list_ids: None # only for type 0 optical routing
        nb_optical_ports_lines: 1
        force_manhattan: False
        excluded_ports:
        grating_indices: None
        routing_method: connect_strip
        gc_port_name: W0
        optical_routing_type: None: autoselection, 0: no extension
        gc_rotation: -90
        component_name: name of component
        taper_factory: taper

    .. code::

              fiber
             ______
            /| | |
           / | | |
        W0|  | | |
           \ | | |
          | \|_|_|_

          |
         xmin = 0

    .. plot::
      :include-source:

       import pp
       from pp.routing import add_fiber_array

       c = pp.c.crossing()
       cc = add_fiber_array(c)
       pp.plotgds(cc)

    """
    component = component() if callable(component) else component
    gc = grating_coupler = (grating_coupler()
                            if callable(grating_coupler) else grating_coupler)
    gc_port_to_edge = abs(gc.xmax - gc.ports[gc_port_name].midpoint[0])
    port_width_gc = grating_coupler.ports[gc_port_name].width
    optical_ports = component.get_ports_list(port_type="optical")
    port_width_component = optical_ports[0].width

    if port_width_component != port_width_gc:
        component = add_tapers(
            component,
            taper_factory(length=taper_length,
                          width1=port_width_gc,
                          width2=port_width_component),
        )

    component_name = component_name or component.name
    name = f"{component_name}_{grating_coupler.name}"

    elements, grating_couplers = route_fiber_single(
        component,
        component_name=component_name,
        optical_io_spacing=optical_io_spacing,
        bend_factory=bend_factory,
        straight_factory=straight_factory,
        route_filter=route_filter,
        grating_coupler=grating_coupler,
        layer_label=layer_label,
        optical_routing_type=optical_routing_type,
        min_input2output_spacing=min_input2output_spacing,
        gc_port_name=gc_port_name,
        **kwargs,
    )

    c = Component(name=name)
    cr = c << component
    cr.rotate(90)

    for e in elements:
        c.add(e)
    for gc in grating_couplers:
        c.add(gc)

    for pname, p in component.ports.items():
        if p.port_type != "optical":
            c.add_port(pname, port=p)

    if isinstance(grating_coupler, list):
        grating_couplers = [call_if_func(g) for g in grating_coupler]
        grating_coupler = grating_couplers[0]
    else:
        grating_coupler = call_if_func(grating_coupler)
        grating_couplers = [grating_coupler]

    if with_align_ports:
        length = c.ysize - 2 * gc_port_to_edge
        wg = c << straight_factory(length=length)
        wg.rotate(90)
        wg.xmax = (c.xmin - optical_io_spacing
                   if abs(c.xmin) > abs(optical_io_spacing) else c.xmin -
                   optical_io_spacing)
        wg.ymin = c.ymin + gc_port_to_edge

        gci = c << grating_coupler
        gco = c << grating_coupler
        gci.connect(gc_port_name, wg.ports["W0"])
        gco.connect(gc_port_name, wg.ports["E0"])

        gds_layer_label, gds_datatype_label = pd._parse_layer(layer_label)

        port = wg.ports["E0"]
        text = get_optical_text(port,
                                grating_coupler,
                                0,
                                component_name=f"loopback_{component.name}")

        label = pd.Label(
            text=text,
            position=port.midpoint,
            anchor="o",
            layer=gds_layer_label,
            texttype=gds_datatype_label,
        )
        c.add(label)

        port = wg.ports["W0"]
        text = get_optical_text(port,
                                grating_coupler,
                                1,
                                component_name=f"loopback_{component.name}")
        label = pd.Label(
            text=text,
            position=port.midpoint,
            anchor="o",
            layer=gds_layer_label,
            texttype=gds_datatype_label,
        )
        c.add(label)

    return c