def component_lattice(
    lattice="""
        C-X
        CXX
        CXX
        C-X
        """,
    components=None,
    name="lattice",
):
    """
    Returns a lattice Component 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
      from pp.routing.repackage import package_optical2x2
      from pp.components.crossing_waveguide import crossing45
      from pp.components.crossing_waveguide import compensation_path

      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.plotgds(c)

    """
    components = components or {
        "C": package_optical2x2(component=coupler(), port_spacing=40.0),
        "X": crossing45(port_spacing=40.0),
        "-": compensation_path(crossing45=crossing45(port_spacing=40.0)),
    }

    # 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"
                        f" {y_spacing}, {_y_spacing} for {cmp.name}")

    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(name)
    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.port.rename_ports_by_orientation(component)
    return component
Exemple #2
0
def CP2x2(gap=0.3, length=10.0):
    c = coupler(gap=gap, length=length)
    return add_fiber_array(c)
Exemple #3
0
def CP2x2(gap=0.3, length=10.0):
    c = coupler(gap=gap, length=length)
    return add_io_optical(c)