Exemplo n.º 1
0
def component_lattice(
    lattice="""
        C-X
        CXX
        CXX
        C-X
        """,
    components={
        "C": package_optical2x2(component=coupler, port_spacing=40.0),
        "X": crossing45(port_spacing=40.0),
        "-": compensation_path(crossing45=crossing45(port_spacing=40.0)),
    },
):
    """
    A lattice of N inputs and outputs with components at given locations
    Columns must have components with the same x spacing between ports input/output ports
    Lines must have components with the same y spacing between input and output ports
    
    Lattice example:
    
    .. code::

        X-X
        XCX
        XCX
        X-X
    
    .. plot::
      :include-source:

      import pp

      c = pp.c.component_lattice()
      pp.plotgds(c)
    """

    # Find y spacing and check that all components have same y spacing

    y_spacing = None
    for cmp in components.values():
        # cmp = pp.call_if_func(cmp)

        for direction in ["W", "E"]:
            ports_dir = get_ports_facing(cmp.ports, direction)
            ports_dir.sort(key=lambda p: p.y)
            nb_ports = len(ports_dir)
            if nb_ports > 1:
                _y_spacing = (ports_dir[-1].y - ports_dir[0].y) / (nb_ports - 1)
                if y_spacing is None:
                    y_spacing = _y_spacing
                else:
                    assert (
                        abs(y_spacing - _y_spacing) < 0.1 / GRID_PER_UNIT
                    ), "All component must have the same y port spacing. Got {}, {}\
                    ".format(
                        y_spacing, _y_spacing
                    )

    a = y_spacing
    columns, columns_to_length = parse_lattice(lattice, components)
    keys = sorted(columns.keys())

    components_to_nb_input_ports = {}
    for c in components.keys():
        components_to_nb_input_ports[c] = len(get_ports_facing(components[c], "W"))

    component = pp.Component()
    x = 0
    for i in keys:
        col = columns[i]
        j = 0
        L = columns_to_length[i]
        skip = 0  # number of lines to skip depending on the number of ports
        for c in col:
            y = -j * a
            if skip == 1:
                j += skip
                skip = 0
                continue

            if c in components.keys():
                # Compute the number of ports to skip: They will already be
                # connected since they belong to this component

                nb_inputs = components_to_nb_input_ports[c]
                skip = nb_inputs - 1
                _cmp = components[c].ref((x, y), port_id="W{}".format(skip))
                component.add(_cmp)

                if i == 0:
                    _ports = get_ports_facing(_cmp, "W")
                    for _p in _ports:
                        component.add_port(gen_tmp_port_name(), port=_p)

                if i == keys[-1]:
                    _ports = get_ports_facing(_cmp, "E")
                    for _p in _ports:
                        component.add_port(gen_tmp_port_name(), port=_p)

            else:
                raise ValueError(
                    "component symbol {} is not part of \
                components dictionnary".format(
                        c
                    )
                )

            j += 1
        x += L

    component = pp.ports.port_naming.rename_ports_by_orientation(component)
    return component
Exemplo n.º 2
0
    # extract each column
    lines = lattice.replace(" ", "").split("\n")
    columns = {}
    columns_to_length = {}
    for line in lines:
        if len(line) > 0:
            i = 0
            for c in line:
                if i not in columns.keys():
                    columns[i] = []

                columns[i].append(c)
                if c in components.keys():
                    cmp = components[c]
                    columns_to_length[
                        i] = cmp.ports["E0"].x - cmp.ports["W0"].x

                i += 1

    return columns, columns_to_length


if __name__ == "__main__":
    components = {
        "C": package_optical2x2(component=pp.c.coupler, port_spacing=40.0),
        "X": crossing45(port_spacing=40.0),
        "-": compensation_path(crossing45=crossing45(port_spacing=40.0)),
    }
    c = pp.c.component_lattice(components=components)
    pp.show(c)