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
def CP2x2(gap=0.3, length=10.0): c = coupler(gap=gap, length=length) return add_fiber_array(c)
def CP2x2(gap=0.3, length=10.0): c = coupler(gap=gap, length=length) return add_io_optical(c)