def cutback_phase(straight_length=100.0, bend_radius=10.0, n=2): # Define sub components bend180 = bend_circular(radius=bend_radius, start_angle=-90, theta=180) pm_wg = phase_modulator_waveguide(length=straight_length) wg_short = waveguide(length=1.0) wg_short2 = waveguide(length=2.0) wg_heater = waveguide_heater(length=10.0) taper = _taper() # Define a map between symbols and (component, input port, output port) string_to_device_in_out_ports = { "I": (taper, "1", "wg_2"), "O": (taper, "wg_2", "1"), "S": (wg_short, "W0", "E0"), "P": (pm_wg, "W0", "E0"), "A": (bend180, "W0", "W1"), "B": (bend180, "W1", "W0"), "H": (wg_heater, "W0", "E0"), "-": (wg_short2, "W0", "E0"), } # Generate a sequence # This is simply a chain of characters. Each of them represents a component # with a given input and and a given output repeated_sequence = "SIPOSASIPOSB" heater_seq = "-H-H-H-H-" sequence = repeated_sequence * n + "SIPO" + heater_seq component = component_sequence(sequence, string_to_device_in_out_ports) return component
def cutback_bend(bend90, straight_length=5.0, n_steps=6, n_stairs=5): """ Deprecated! use cutback_bend90 instead! this is a stair .. code:: _ _| _| _ this is a step """ wg = waveguide(length=straight_length, width=bend90.ports["W0"].width) # Define a map between symbols and (component, input port, output port) string_to_device_in_out_ports = { "A": (bend90, "W0", "N0"), "B": (bend90, "N0", "W0"), "S": (wg, "W0", "E0"), } # Generate the sequence of staircases s = "" for i in range(n_stairs): s += "ASBS" * n_steps s += "ASAS" if i % 2 == 0 else "BSBS" s = s[:-4] # Create the component from the sequence c = component_sequence(s, string_to_device_in_out_ports, start_orientation=90) c.update_settings(n_bends=n_steps * n_stairs * 2 + n_stairs * 2 - 2) return c
def staircase( bend90=pp.c.bend_euler90, length_v=5.0, length_h=5.0, n_steps=4, waveguide_factory=waveguide, ): bend90 = pp.call_if_func(bend90) wgh = waveguide_factory(length=length_h, width=bend90.ports["W0"].width) wgv = waveguide_factory(length=length_v, width=bend90.ports["W0"].width) # Define a map between symbols and (component, input port, output port) string_to_device_in_out_ports = { "A": (bend90, "W0", "N0"), "B": (bend90, "N0", "W0"), "-": (wgh, "W0", "E0"), "|": (wgv, "W0", "E0"), } # Generate the sequence of staircases s = "-A|B" * n_steps + "-" # Create the component from the sequence c = component_sequence(s, string_to_device_in_out_ports, start_orientation=0) c.update_settings(n_bends=2 * n_steps) return c
def cutback_bend90( bend90=pp.c.bend_euler90, straight_length=5.0, n_steps=6, cols=6, spacing=5, wg_loop_length=None, waveguide_factory=waveguide, ): """ .. code:: _ |_| | """ bend90 = pp.call_if_func(bend90) wg = waveguide_factory(length=straight_length, width=bend90.ports["W0"].width) if wg_loop_length is None: wg_loop_length = 2 * _get_bend_size(bend90) + spacing + straight_length wg_loop = waveguide_factory( length=wg_loop_length, width=bend90.ports["W0"].width, ) # Define a map between symbols and (component, input port, output port) string_to_device_in_out_ports = { "A": (bend90, "W0", "N0"), "B": (bend90, "N0", "W0"), "-": (wg, "W0", "E0"), "|": (wg_loop, "W0", "E0"), } # Generate the sequence of staircases s = "" for i in range(cols): if i % 2 == 0: # even row s += "A-A-B-B-" * n_steps + "|" else: s += "B-B-A-A-" * n_steps + "|" s = s[:-1] # Create the component from the sequence c = component_sequence(s, string_to_device_in_out_ports, start_orientation=0) c.update_settings(n_bends=n_steps * cols * 4) return c
def cutback_bend180( bend180=pp.c.bend_euler180, straight_length=5.0, n_steps=6, cols=6, spacing=3, waveguide_factory=waveguide, ): """ .. code:: _ _| |_| this is a stair _ this is a step """ bend180 = pp.call_if_func(bend180) wg = waveguide_factory(length=straight_length, width=bend180.ports["W0"].width) wg_vertical = waveguide_factory( length=2 * bend180.size_info.width + straight_length + spacing, width=bend180.ports["W0"].width, ) # Define a map between symbols and (component, input port, output port) string_to_device_in_out_ports = { "D": (bend180, "W0", "W1"), "C": (bend180, "W1", "W0"), "-": (wg, "W0", "E0"), "|": (wg_vertical, "W0", "E0"), } # Generate the sequence of staircases s = "" for i in range(cols): if i % 2 == 0: # even row s += "D-C-" * n_steps + "|" else: s += "C-D-" * n_steps + "|" s = s[:-1] # Create the component from the sequence c = component_sequence(s, string_to_device_in_out_ports, start_orientation=0) c.update_settings(n_bends=n_steps * cols * 2 + cols * 2 - 2) return c
def cutback_component( component=taper_0p5_to_3_l36, cols=4, rows=5, bend_radius=10, port1_id="W0", port2_id="E0", middle_couples=2, ): """Flips the component, good for tapers that end in wide waveguides Args: component cols rows """ component = component() if callable(component) else component bend180 = bend_euler180(radius=bend_radius) # Define a map between symbols and (component, input port, output port) string_to_device_in_out_ports = { "A": (component, port1_id, port2_id), "B": (component, port2_id, port1_id), "D": (bend180, "W0", "W1"), "C": (bend180, "W1", "W0"), } # Generate the sequence of staircases s = "" for i in range(rows): s += "AB" * cols s += "D" if i % 2 == 0 else "C" s = s[:-1] s += "AB" * middle_couples for i in range(rows): s += "AB" * cols s += "D" if (i + rows) % 2 == 0 else "C" s = s[:-1] # Create the component from the sequence c = component_sequence(s, string_to_device_in_out_ports) c.update_settings(n_devices=len(s)) return c
def cutback_component_flipped( component, cols=4, rows=5, bend_radius=10, port1_id="E0", port2_id="W0", middle_couples=2, ): bend180 = bend_euler180(radius=bend_radius) # Define a map between symbols and (component, input port, output port) string_to_device_in_out_ports = { "A": (component, port1_id, port2_id), "B": (component, port2_id, port1_id), "D": (bend180, "W0", "W1"), "C": (bend180, "W1", "W0"), } # Generate the sequence of staircases s = "" for i in range(rows): s += "AB" * cols s += "C" if i % 2 == 0 else "D" s = s[:-1] s += "AB" * middle_couples for i in range(rows): s += "AB" * cols s += "D" if (i + rows + 1) % 2 == 0 else "C" s = s[:-1] # Create the component from the sequence c = component_sequence(s, string_to_device_in_out_ports) c.update_settings(n_devices=len(s)) return c
def test_cutback_heater(): # Define subcomponents bend_radius = 10.0 bend180 = bend_circular(radius=bend_radius, start_angle=-90, theta=180) wg = waveguide(length=5.0) wg_heater = waveguide_heater(length=20.0) # Define a map between symbols and (component, input port, output port) string_to_device_in_out_ports = { "A": (bend180, "W0", "W1"), "B": (bend180, "W1", "W0"), "H": (wg_heater, "W0", "E0"), "-": (wg, "W0", "E0"), } # Generate a sequence # This is simply a chain of characters. Each of them represents a component # with a given input and and a given output sequence = "AB-H-H-H-H-BA" component = component_sequence(sequence, string_to_device_in_out_ports) assert component return component
def mzi_arm( L0=60, L1=0, L_top=10.0, bend_radius=10.0, bend90_factory=bend_circular, straight_heater_factory=waveguide_heater, straight_factory=waveguide, with_elec_connections=True, ): """ Args: L0: vertical length with heater L1: extra vertical length without heater L_top: 10.0, horizontal length bend_radius: 10.0 bend90_factory: bend_circular straight_heater_factory: waveguide_heater straight_factory: waveguide :: L_top | | L1 L1 | | L0 L0 | | -| |- B2-Sh1-B3 | | Sv1 Sv2 | | H1 H2 | | -B1 B4- .. plot:: :include-source: import pp c = pp.c.mzi_arm() pp.plotgds(c) """ _bend = bend90_factory(radius=bend_radius) straight_vheater = straight_heater_factory(length=L0) straight_h = straight_factory(length=L_top) straight_v = straight_factory(length=L1) if L1 > 0 else None string_to_device_in_out_ports = { "A": (_bend, "W0", "N0"), "B": (_bend, "N0", "W0"), "H": (straight_vheater, "W0", "E0"), "Sh": (straight_h, "W0", "E0"), "Sv": (straight_v, "W0", "E0"), } sequence = ["A", "Sv", "H", "B", "Sh", "B", "H", "Sv", "A"] if with_elec_connections: ports_map = { "E_0": ("H2", "E_1"), "E_1": ("H1", "E_0"), "E_2": ("H1", "E_1"), "E_3": ("H2", "E_0"), } else: ports_map = {} component = component_sequence( sequence, string_to_device_in_out_ports, ports_map, input_port_name="W0", output_port_name="E0", ) return component
def mzi_arm( L0: float = 60.0, DL: float = 0.0, L_top: float = 10.0, bend_radius: float = 10.0, bend90_factory: Callable = bend_circular, straight_heater_factory: Callable = waveguide_heater, straight_factory: Callable = waveguide, with_elec_connections: bool = True, ) -> Component: """ Args: L0: vertical length with heater DL: extra vertical length without heater (delat_length=2*DL) L_top: 10.0, horizontal length bend_radius: 10.0 bend90_factory: bend_circular straight_heater_factory: waveguide_heater straight_factory: waveguide :: L_top | | DL DL | | L0 L0 | | -| |- B2-Sh1-B3 | | Sv1 Sv2 | | H1 H2 | | -B1 B4- .. plot:: :include-source: import pp c = pp.c.mzi_arm() pp.plotgds(c) """ if not with_elec_connections: straight_heater_factory = straight_factory _bend = bend90_factory(radius=bend_radius) straight_vheater = straight_heater_factory(length=L0) straight_h = straight_factory(length=L_top) straight_v = straight_factory(length=DL) if DL > 0 else None port_number = 1 if with_elec_connections else 0 string_to_device_in_out_ports = { "A": (_bend, "W0", "N0"), "B": (_bend, "N0", "W0"), "H": (straight_vheater, f"W{port_number}", f"E{port_number}"), "Sh": (straight_h, "W0", "E0"), "Sv": (straight_v, "W0", "E0"), } sequence = ["A", "Sv", "H", "B", "Sh", "B", "H", "Sv", "A"] if with_elec_connections: ports_map = { "E_0": ("H2", "E_1"), "E_1": ("H1", "E_0"), "E_2": ("H1", "E_1"), "E_3": ("H2", "E_0"), } else: ports_map = {} component = component_sequence( sequence, string_to_device_in_out_ports, ports_map, input_port_name="W0", output_port_name="E0", ) return component