Routing#
Optical and high-speed RF ports have specific orientation requirements to ensure that routes avoid sharp turns, which can cause signal reflections.
We offer routing functions tailored for these requirements:
route_single
: Routes a single connection between two ports.route_bundle
: Routes multiple connections between two port groups using a bundle/river/bus router. It also accommodates waypoints and routing steps.
The most versatile function is route_bundle
, as it handles both single and grouped routes with length matching, ensuring all routes are of equal length.
import gdsfactory as gf
from gdsfactory.component import Component
from gdsfactory.port import Port
c = gf.Component()
mmi1 = c << gf.components.mmi1x2()
mmi2 = c << gf.components.mmi1x2()
mmi2.move((100, 50))
c
route_single#
route_single
returns a Manhattan route between 2 ports
help(gf.routing.route_single)
Help on function route_single in module gdsfactory.routing.route_single:
route_single(component: 'Component', port1: 'Port', port2: 'Port', cross_section: 'CrossSectionSpec | None' = None, layer: 'LayerSpec | None' = None, bend: 'ComponentSpec' = 'bend_euler', straight: 'ComponentSpec' = 'straight', start_straight_length: 'float' = 0.0, end_straight_length: 'float' = 0.0, waypoints: 'WayPoints | None' = None, steps: "Sequence[Mapping[Literal['x', 'y', 'dx', 'dy'], int | float]] | None" = None, port_type: 'str | None' = None, allow_width_mismatch: 'bool' = False, radius: 'float | None' = None, route_width: 'float | None' = None, auto_taper: 'bool' = True) -> 'ManhattanRoute'
Returns a Manhattan Route between 2 ports.
The references are straights, bends and tapers.
`route_single` is an automatic version of `route_single_from_steps`.
Args:
component: to place the route into.
port1: start port.
port2: end port.
cross_section: spec.
layer: layer spec.
bend: bend spec.
straight: straight spec.
start_straight_length: length of starting straight.
end_straight_length: length of end straight.
waypoints: optional list of points to pass through.
steps: optional list of steps to pass through.
port_type: port type to route.
allow_width_mismatch: allow different port widths.
radius: bend radius. If None, defaults to cross_section.radius.
route_width: width of the route in um. If None, defaults to cross_section.width.
auto_taper: add auto tapers.
.. plot::
:include-source:
import gdsfactory as gf
c = gf.Component()
mmi1 = c << gf.components.mmi1x2()
mmi2 = c << gf.components.mmi1x2()
mmi2.dmove((40, 20))
gf.routing.route_single(c, mmi1.ports["o2"], mmi2.ports["o1"], radius=5, cross_section="strip")
c.plot()
c = gf.Component()
mmi1 = c << gf.components.mmi1x2()
mmi2 = c << gf.components.mmi1x2()
mmi2.move((100, 50))
route = gf.routing.route_single(
c,
port1=mmi1.ports["o2"],
port2=mmi2.ports["o1"],
cross_section=gf.cross_section.strip,
)
c
route
ManhattanRoute(backbone=[15500,625, 25500,625, 25500,50000, 90000,50000], start_port=Port(, dwidth: 0.5, trans: r180 *1 15.5,0.625, layer: WG (1/0), port_type: optical), end_port=Port(, dwidth: 0.5, trans: r0 *1 90,50, layer: WG (1/0), port_type: optical), instances=[Unnamed_4: ports ['o1', 'o2'], vinsts=[] info=Info(length=16.637, dy=10.0, min_bend_radius=7.061, radius=10.0, width=0.5, route_info_type='strip', route_info_length=16.637, route_info_weight=16.637, route_info_strip_length=16.637, route_info_n_bend_90=1.0, route_info_min_bend_radius=7.061) kcl=KCLayout(name='DEFAULT', layout=<klayout.dbcore.Layout object at 0x7f8a5c114b90>, layer_enclosures=LayerEnclosureModel(root={'78687732': LayerEnclosure(layer_sections={}, main_layer=WG (1/0), yaml_tag='!Enclosure')}), cross_sections={'78687732_500': SymmetricalCrossSection(width=500, enclosure=LayerEnclosure(layer_sections={}, main_layer=WG (1/0), yaml_tag='!Enclosure'), name='78687732_500'), '78687732_1000': SymmetricalCrossSection(width=1000, enclosure=LayerEnclosure(layer_sections={}, main_layer=WG (1/0), yaml_tag='!Enclosure'), name='78687732_1000'), '78687732_2500': SymmetricalCrossSection(width=2500, enclosure=LayerEnclosure(layer_sections={}, main_layer=WG (1/0), yaml_tag='!Enclosure'), name='78687732_2500')}, enclosure=KCellEnclosure(enclosures=LayerEnclosureCollection(enclosures=[])), library=<klayout.dbcore.Library object at 0x7f8a5c114910>, factories={'taper': <function taper at 0x7f8a46cd3e20>, 'bend_s_bezier': <function bend_s_bezier_factory.<locals>.bend_s_bezier at 0x7f8a50e5e700>, 'bend_circular': <function bend_circular at 0x7f8a46cd22a0>, 'bend_euler': <function bend_euler at 0x7f8a46cd2ca0>, 'bend_s_euler': <function bend_s_euler_factory.<locals>.bend_s_euler at 0x7f8a50e74cc0>, 'straight': <function straight at 0x7f8a46b57600>, 'rotate': <function rotate at 0x7f8a47370e00>, 'from_image': <function from_image at 0x7f8a472622a0>, 'floorplan_with_block_letters': <function floorplan_with_block_letters at 0x7f8a46c4d8a0>, 'bend_circular_heater': <function bend_circular_heater at 0x7f8a46cd2520>, 'bend_euler_s': <function bend_euler_s at 0x7f8a46cd2b60>, 'bezier': <function bezier at 0x7f8a46cd3240>, 'bend_s': <function bend_s at 0x7f8a46cd3420>, 'add_fiber_array_optical_south_electrical_north': <function add_fiber_array_optical_south_electrical_north at 0x7f8a46cd36a0>, 'ramp': <function ramp at 0x7f8a46cd3ba0>, 'taper_strip_to_ridge': <function taper_strip_to_ridge at 0x7f8a46cd3ec0>, 'taper_strip_to_ridge_trenches': <function taper_strip_to_ridge_trenches at 0x7f8a46cf8180>, 'taper_sc_nc': <function taper_sc_nc at 0x7f8a46cf82c0>, 'taper_adiabatic': <function taper_adiabatic at 0x7f8a46cf85e0>, 'taper_cross_section': <function taper_cross_section at 0x7f8a46cf87c0>, 'taper_from_csv': <function taper_from_csv at 0x7f8a46cf89a0>, 'taper_parabolic': <function taper_parabolic at 0x7f8a46cf8ae0>, 'add_termination': <function add_termination at 0x7f8a46cd37e0>, 'add_trenches': <function add_trenches at 0x7f8a46cf8900>, 'array': <function array at 0x7f8a46cf8cc0>, 'copy_layers': <function copy_layers at 0x7f8a46cf91c0>, 'extend_ports_list': <function extend_ports_list at 0x7f8a46cf9300>, 'extend_ports': <function extend_ports at 0x7f8a46cf9620>, 'pack_doe': <function pack_doe at 0x7f8a46cf9e40>, 'pack_doe_grid': <function pack_doe_grid at 0x7f8a46cf9f80>, 'splitter_chain': <function splitter_chain at 0x7f8a46cfa0c0>, 'mzi': <function mzi at 0x7f8a46cfa660>, 'mzi_lattice': <function mzi_lattice at 0x7f8a46cfa980>, 'mzi_lattice_mmi': <function mzi_lattice_mmi at 0x7f8a46cfaac0>, 'mzi_pads_center': <function mzi_pads_center at 0x7f8a46cfad40>, 'mzit': <function mzit at 0x7f8a46cfaf20>, 'mzit_lattice': <function mzit_lattice at 0x7f8a46cfb060>, 'splitter_tree': <function splitter_tree at 0x7f8a46cfac00>, 'coupler_symmetric': <function coupler_symmetric at 0x7f8a46cfb240>, 'coupler_straight': <function coupler_straight at 0x7f8a46cfb380>, 'coupler': <function coupler at 0x7f8a46cfb4c0>, 'coupler90': <function coupler90 at 0x7f8a46cfb6a0>, 'coupler90bend': <function coupler90bend at 0x7f8a46cfb740>, 'coupler_adiabatic': <function coupler_adiabatic at 0x7f8a46cfba60>, 'coupler_asymmetric': <function coupler_asymmetric at 0x7f8a46cfbce0>, 'coupler_bent_half': <function coupler_bent_half at 0x7f8a46cfbf60>, 'coupler_bent': <function coupler_bent at 0x7f8a46b24180>, 'coupler_broadband': <function coupler_broadband at 0x7f8a46b24400>, 'coupler_full': <function coupler_full at 0x7f8a46b245e0>, 'coupler_ring': <function coupler_ring at 0x7f8a46b24860>, 'coupler_straight_asymmetric': <function coupler_straight_asymmetric at 0x7f8a46b24ae0>, 'align_wafer': <function align_wafer at 0x7f8a46b24ea0>, 'add_frame': <function add_frame at 0x7f8a46b24f40>, 'die': <function die at 0x7f8a46b25260>, 'die_with_pads': <function die_with_pads at 0x7f8a46b25440>, 'seal_ring': <function seal_ring at 0x7f8a46b25620>, 'seal_ring_segmented': <function seal_ring_segmented at 0x7f8a46b25760>, 'wafer': <function wafer at 0x7f8a46b25940>, 'free_propagation_region': <function free_propagation_region at 0x7f8a46b25da0>, 'awg': <function awg at 0x7f8a46b25e40>, 'dbr_cell': <function dbr_cell at 0x7f8a46b26160>, 'dbr': <function dbr at 0x7f8a46b262a0>, 'dbr_tapered': <function dbr_tapered at 0x7f8a46b26520>, 'bbox': <function bbox at 0x7f8a46b26ca0>, 'C': <function C at 0x7f8a46b26e80>, 'circle': <function circle at 0x7f8a46b27060>, 'compass': <function compass at 0x7f8a46b272e0>, 'cross': <function cross at 0x7f8a46b274c0>, 'ellipse': <function ellipse at 0x7f8a46b276a0>, 'fiducial_squares': <function fiducial_squares at 0x7f8a46b277e0>, 'L': <function L at 0x7f8a46b279c0>, 'nxn': <function nxn at 0x7f8a46b27ba0>, 'rectangle': <function rectangle at 0x7f8a46b27d80>, 'rectangles': <function rectangles at 0x7f8a46b27ec0>, 'regular_polygon': <function regular_polygon at 0x7f8a46b27f60>, 'triangle': <function triangle at 0x7f8a46b54220>, 'triangle2': <function triangle2 at 0x7f8a46b54360>, 'triangle4': <function triangle4 at 0x7f8a46b544a0>, 'fiber': <function fiber at 0x7f8a46b27e20>, 'fiber_array': <function fiber_array at 0x7f8a46b54540>, 'crossing_arm': <function crossing_arm at 0x7f8a46b56f20>, 'crossing': <function crossing at 0x7f8a46b57060>, 'crossing_linear_taper': <function crossing_linear_taper at 0x7f8a46b571a0>, 'crossing_etched': <function crossing_etched at 0x7f8a46b572e0>, 'crossing45': <function crossing45 at 0x7f8a46b57420>, 'straight_array': <function straight_array at 0x7f8a46b57880>, 'wire_straight': <function wire_straight at 0x7f8a46b579c0>, 'straight_heater_doped_rib': <function straight_heater_doped_rib at 0x7f8a46b57d80>, 'straight_heater_doped_strip': <function straight_heater_doped_strip at 0x7f8a46b8c040>, 'straight_heater_meander': <function straight_heater_meander at 0x7f8a46b8c2c0>, 'via': <function via at 0x7f8a46b8cae0>, 'via_circular': <function via_circular at 0x7f8a46b8cc20>, 'via_chain': <function via_chain at 0x7f8a46b8cf40>, 'via_corner': <function via_corner at 0x7f8a46b8d120>, 'via_stack': <function via_stack at 0x7f8a46b8d300>, 'via_stack_corner45': <function via_stack_corner45 at 0x7f8a46b8d440>, 'via_stack_corner45_extended': <function via_stack_corner45_extended at 0x7f8a46b8d580>, 'via_stack_with_offset': <function via_stack_with_offset at 0x7f8a46b8d6c0>, 'straight_heater_meander_doped': <function straight_heater_meander_doped at 0x7f8a46b8c7c0>, 'straight_heater_metal_undercut': <function straight_heater_metal_undercut at 0x7f8a46b8d620>, 'straight_heater_metal_simple': <function straight_heater_metal_simple at 0x7f8a46b8d940>, 'straight_piecewise': <function straight_piecewise at 0x7f8a46b8da80>, 'straight_pin': <function straight_pin at 0x7f8a46b8db20>, 'straight_pin_slot': <function straight_pin_slot at 0x7f8a46b8dda0>, 'wire_corner': <function wire_corner at 0x7f8a46b8e020>, 'wire_corner45': <function wire_corner45 at 0x7f8a46b8e160>, 'wire_corner_sections': <function wire_corner_sections at 0x7f8a46b8e200>, 'loop_mirror': <function loop_mirror at 0x7f8a46b54720>, 'mode_converter': <function mode_converter at 0x7f8a46b8fc40>, 'polarization_splitter_rotator': <function polarization_splitter_rotator at 0x7f8a46b8ff60>, 'terminator': <function terminator at 0x7f8a46bb8540>, 'grating_coupler_array': <function grating_coupler_array at 0x7f8a46bb87c0>, 'grating_coupler_dual_pol': <function grating_coupler_dual_pol at 0x7f8a46bb8ae0>, 'grating_coupler_elliptical': <function grating_coupler_elliptical at 0x7f8a46bb9120>, 'grating_coupler_elliptical_arbitrary': <function grating_coupler_elliptical_arbitrary at 0x7f8a46bb93a0>, 'grating_coupler_elliptical_uniform': <function grating_coupler_elliptical_uniform at 0x7f8a46bb9620>, 'grating_coupler_elliptical_lumerical': <function grating_coupler_elliptical_lumerical at 0x7f8a46bb9760>, 'grating_coupler_elliptical_trenches': <function grating_coupler_elliptical_trenches at 0x7f8a46bb8b80>, 'grating_coupler_loss': <function grating_coupler_loss at 0x7f8a46bb9940>, 'grating_coupler_rectangular': <function grating_coupler_rectangular at 0x7f8a46bb9b20>, 'grating_coupler_rectangular_arbitrary': <function grating_coupler_rectangular_arbitrary at 0x7f8a46bb9da0>, 'grating_coupler_tree': <function grating_coupler_tree at 0x7f8a46bba020>, 'mmi': <function mmi at 0x7f8a46bba340>, 'mmi1x2': <function mmi1x2 at 0x7f8a46bba660>, 'mmi1x2_with_sbend': <function mmi1x2_with_sbend at 0x7f8a46bba840>, 'mmi2x2': <function mmi2x2 at 0x7f8a46bbab60>, 'mmi2x2_with_sbend': <function mmi2x2_with_sbend at 0x7f8a46bbaca0>, 'mmi_90degree_hybrid': <function mmi_90degree_hybrid at 0x7f8a46bbae80>, 'mmi_tapered': <function mmi_tapered at 0x7f8a46bbb1a0>, 'pad': <function pad at 0x7f8a46bbb420>, 'pad_array': <function pad_array at 0x7f8a46bbb6a0>, 'pad_gsg_short': <function pad_gsg_short at 0x7f8a46bbb920>, 'pads_shorted': <function pads_shorted at 0x7f8a46bbbba0>, 'rectangle_with_slits': <function rectangle_with_slits at 0x7f8a46bbbce0>, 'cavity': <function cavity at 0x7f8a46bbbf60>, 'cdsem_all': <function cdsem_all at 0x7f8a46bdc220>, 'cdsem_bend180': <function cdsem_bend180 at 0x7f8a46bdc400>, 'cdsem_coupler': <function cdsem_coupler at 0x7f8a46bdc540>, 'cdsem_straight': <function cdsem_straight at 0x7f8a46bdc860>, 'cdsem_straight_density': <function cdsem_straight_density at 0x7f8a46bdc9a0>, 'bendu_double': <function bendu_double at 0x7f8a46bdcc20>, 'straight_double': <function straight_double at 0x7f8a46bdcd60>, 'cutback_2x2': <function cutback_2x2 at 0x7f8a46bdcea0>, 'cutback_bend': <function cutback_bend at 0x7f8a46bdd260>, 'cutback_bend90': <function cutback_bend90 at 0x7f8a46bdd3a0>, 'staircase': <function staircase at 0x7f8a46bdd4e0>, 'cutback_bend180': <function cutback_bend180 at 0x7f8a46bdd620>, 'cutback_component': <function cutback_component at 0x7f8a46bdd760>, 'cutback_splitter': <function cutback_splitter at 0x7f8a46bddb20>, 'greek_cross': <function greek_cross at 0x7f8a46bddc60>, 'greek_cross_with_pads': <function greek_cross_with_pads at 0x7f8a46bddee0>, 'litho_calipers': <function litho_calipers at 0x7f8a46bde0c0>, 'litho_ruler': <function litho_ruler at 0x7f8a46bde3e0>, 'litho_steps': <function litho_steps at 0x7f8a46bde5c0>, 'resistance_meander': <function resistance_meander at 0x7f8a46bde700>, 'resistance_sheet': <function resistance_sheet at 0x7f8a46bde8e0>, 'verniers': <function verniers at 0x7f8a46bdeac0>, 'text': <function text at 0x7f8a46bdf7e0>, 'text_lines': <function text_lines at 0x7f8a46bdf9c0>, 'text_klayout': <function text_klayout at 0x7f8a46bdfb00>, 'text_freetype': <function text_freetype at 0x7f8a46bdfe20>, 'pixel_array': <function pixel_array at 0x7f8a467280e0>, 'text_rectangular': <function text_rectangular at 0x7f8a46728220>, 'text_rectangular_multi_layer': <function text_rectangular_multi_layer at 0x7f8a46728360>, 'pixel': <function pixel at 0x7f8a46bdede0>, 'qrcode': <function qrcode at 0x7f8a46bdfa60>, 'version_stamp': <function version_stamp at 0x7f8a46728400>, 'disk': <function disk at 0x7f8a467289a0>, 'disk_heater': <function disk_heater at 0x7f8a46728ae0>, 'ring': <function ring at 0x7f8a46728d60>, 'ring_crow': <function ring_crow at 0x7f8a46728f40>, 'ring_crow_couplers': <function ring_crow_couplers at 0x7f8a46729080>, 'ring_double': <function ring_double at 0x7f8a46729260>, 'ring_double_bend_coupler': <function ring_double_bend_coupler at 0x7f8a46729580>, 'ring_double_heater': <function ring_double_heater at 0x7f8a467296c0>, 'ring_double_pn': <function ring_double_pn at 0x7f8a467299e0>, 'ring_single_pn': <function ring_single_pn at 0x7f8a46729b20>, 'ring_single': <function ring_single at 0x7f8a46729d00>, 'ring_single_array': <function ring_single_array at 0x7f8a46729e40>, 'coupler_bend': <function coupler_bend at 0x7f8a46729f80>, 'coupler_ring_bend': <function coupler_ring_bend at 0x7f8a4672a0c0>, 'ring_single_bend_coupler': <function ring_single_bend_coupler at 0x7f8a4672a200>, 'ring_single_dut': <function ring_single_dut at 0x7f8a4672a3e0>, 'delay_snake': <function delay_snake at 0x7f8a4672a660>, 'delay_snake2': <function delay_snake2 at 0x7f8a4672a840>, 'delay_snake_sbend': <function delay_snake_sbend at 0x7f8a4672aac0>, 'spiral': <function spiral at 0x7f8a4672ad40>, 'spiral_double': <function spiral_double at 0x7f8a4672af20>, 'spiral_racetrack': <function spiral_racetrack at 0x7f8a4672b1a0>, 'spiral_racetrack_fixed_length': <function spiral_racetrack_fixed_length at 0x7f8a4672b2e0>, 'spiral_racetrack_heater_metal': <function spiral_racetrack_heater_metal at 0x7f8a4672b4c0>, 'spiral_racetrack_heater_doped': <function spiral_racetrack_heater_doped at 0x7f8a4672b600>, 'spiral_inductor': <function spiral_inductor at 0x7f8a4672b740>, 'hline': <function hline at 0x7f8a4672b9c0>, 'optimal_90deg': <function optimal_90deg at 0x7f8a4672bb00>, 'optimal_hairpin': <function optimal_hairpin at 0x7f8a4672be20>, 'optimal_step': <function optimal_step at 0x7f8a4672bf60>, 'snspd': <function snspd at 0x7f8a46754180>, 'interdigital_capacitor': <function interdigital_capacitor at 0x7f8a46754360>, 'ge_detector_straight_si_contacts': <function ge_detector_straight_si_contacts at 0x7f8a467545e0>, 'edge_coupler_silicon': <function edge_coupler_silicon at 0x7f8a46754860>, 'edge_coupler_array': <function edge_coupler_array at 0x7f8a467549a0>, 'edge_coupler_array_with_loopback': <function edge_coupler_array_with_loopback at 0x7f8a46754ae0>}, virtual_factories={'virtual_bend_circular': <function virtual_bend_circular_factory.<locals>.virtual_bend_circular at 0x7f8a50e75bc0>, 'bend_euler': <function virtual_bend_euler_factory.<locals>.bend_euler at 0x7f8a50e75e40>, 'virtual_straight': <function virtual_straight_factory.<locals>.virtual_straight at 0x7f8a50e760c0>, 'bend_circular_all_angle': <function bend_circular_all_angle at 0x7f8a46cd23e0>, 'bend_euler_all_angle': <function bend_euler_all_angle at 0x7f8a46cd2f20>, 'straight_all_angle': <function straight_all_angle at 0x7f8a46b57740>}, kcells={0: Unnamed_0: ports [], 2 instances, 1: mmi1x2_WNone_WT1_LT10_L_4e0f7121: ports ['o1', 'o2', 'o3'], 0 instances, 2: taper_L10_W0p5_W1_LNone_456c7208: ports ['o1', 'o2'], 0 instances, 3: straight_L5p5_N2_CSxs_5_d3ec67bc: ports ['o1', 'o2'], 0 instances, 4: Unnamed_4: ports [], 6 instances, 5: bend_euler_R10_A90_P0p5_2f1f5c6d: ports ['o1', 'o2'], 0 instances, 6: straight_L29p375_N2_CSs_6ed2bfdd: ports ['o1', 'o2'], 0 instances, 7: straight_L54p5_N2_CSstrip_WNone: ports ['o1', 'o2'], 0 instances}, layers=<aenum 'LAYER'>, infos=LayerInfos(), layer_stack=LayerStack(layers={}), netlist_layer_mapping={}, sparameters_path=None, interconnect_cml_path=None, constants=Constants(), rename_function=<function rename_clockwise_multi at 0x7f8a5c3aef20>, info=Info(), settings=KCellSettings(version='0.23.1', klayout_version='0.29.11', meta_format='v3'), future_cell_name=None, decorators=<kfactory.decorators.Decorators object at 0x7f8a5c3895d0>) function_name='bend_euler' basename=None boundary=None insts=<gdsfactory.component.ComponentReferences object at 0x7f8a3ffcdf90> size_info=<kfactory.kcell.SizeInfo object at 0x7f8a2e1e53d0> dsize_info=<kfactory.kcell.DSizeInfo object at 0x7f8a2f3206d0> routes={}, Unnamed_4: ports ['o1', 'o2'], vinsts=[] info=Info(length=29.375, width=0.5, route_info_type='strip', route_info_length=29.375, route_info_weight=29.375, route_info_strip_length=29.375) kcl=KCLayout(name='DEFAULT', layout=<klayout.dbcore.Layout object at 0x7f8a5c114b90>, layer_enclosures=LayerEnclosureModel(root={'78687732': LayerEnclosure(layer_sections={}, main_layer=WG (1/0), yaml_tag='!Enclosure')}), cross_sections={'78687732_500': SymmetricalCrossSection(width=500, enclosure=LayerEnclosure(layer_sections={}, main_layer=WG (1/0), yaml_tag='!Enclosure'), name='78687732_500'), '78687732_1000': SymmetricalCrossSection(width=1000, enclosure=LayerEnclosure(layer_sections={}, main_layer=WG (1/0), yaml_tag='!Enclosure'), name='78687732_1000'), '78687732_2500': SymmetricalCrossSection(width=2500, enclosure=LayerEnclosure(layer_sections={}, main_layer=WG (1/0), yaml_tag='!Enclosure'), name='78687732_2500')}, enclosure=KCellEnclosure(enclosures=LayerEnclosureCollection(enclosures=[])), library=<klayout.dbcore.Library object at 0x7f8a5c114910>, factories={'taper': <function taper at 0x7f8a46cd3e20>, 'bend_s_bezier': <function bend_s_bezier_factory.<locals>.bend_s_bezier at 0x7f8a50e5e700>, 'bend_circular': <function bend_circular at 0x7f8a46cd22a0>, 'bend_euler': <function bend_euler at 0x7f8a46cd2ca0>, 'bend_s_euler': <function bend_s_euler_factory.<locals>.bend_s_euler at 0x7f8a50e74cc0>, 'straight': <function straight at 0x7f8a46b57600>, 'rotate': <function rotate at 0x7f8a47370e00>, 'from_image': <function from_image at 0x7f8a472622a0>, 'floorplan_with_block_letters': <function floorplan_with_block_letters at 0x7f8a46c4d8a0>, 'bend_circular_heater': <function bend_circular_heater at 0x7f8a46cd2520>, 'bend_euler_s': <function bend_euler_s at 0x7f8a46cd2b60>, 'bezier': <function bezier at 0x7f8a46cd3240>, 'bend_s': <function bend_s at 0x7f8a46cd3420>, 'add_fiber_array_optical_south_electrical_north': <function add_fiber_array_optical_south_electrical_north at 0x7f8a46cd36a0>, 'ramp': <function ramp at 0x7f8a46cd3ba0>, 'taper_strip_to_ridge': <function taper_strip_to_ridge at 0x7f8a46cd3ec0>, 'taper_strip_to_ridge_trenches': <function taper_strip_to_ridge_trenches at 0x7f8a46cf8180>, 'taper_sc_nc': <function taper_sc_nc at 0x7f8a46cf82c0>, 'taper_adiabatic': <function taper_adiabatic at 0x7f8a46cf85e0>, 'taper_cross_section': <function taper_cross_section at 0x7f8a46cf87c0>, 'taper_from_csv': <function taper_from_csv at 0x7f8a46cf89a0>, 'taper_parabolic': <function taper_parabolic at 0x7f8a46cf8ae0>, 'add_termination': <function add_termination at 0x7f8a46cd37e0>, 'add_trenches': <function add_trenches at 0x7f8a46cf8900>, 'array': <function array at 0x7f8a46cf8cc0>, 'copy_layers': <function copy_layers at 0x7f8a46cf91c0>, 'extend_ports_list': <function extend_ports_list at 0x7f8a46cf9300>, 'extend_ports': <function extend_ports at 0x7f8a46cf9620>, 'pack_doe': <function pack_doe at 0x7f8a46cf9e40>, 'pack_doe_grid': <function pack_doe_grid at 0x7f8a46cf9f80>, 'splitter_chain': <function splitter_chain at 0x7f8a46cfa0c0>, 'mzi': <function mzi at 0x7f8a46cfa660>, 'mzi_lattice': <function mzi_lattice at 0x7f8a46cfa980>, 'mzi_lattice_mmi': <function mzi_lattice_mmi at 0x7f8a46cfaac0>, 'mzi_pads_center': <function mzi_pads_center at 0x7f8a46cfad40>, 'mzit': <function mzit at 0x7f8a46cfaf20>, 'mzit_lattice': <function mzit_lattice at 0x7f8a46cfb060>, 'splitter_tree': <function splitter_tree at 0x7f8a46cfac00>, 'coupler_symmetric': <function coupler_symmetric at 0x7f8a46cfb240>, 'coupler_straight': <function coupler_straight at 0x7f8a46cfb380>, 'coupler': <function coupler at 0x7f8a46cfb4c0>, 'coupler90': <function coupler90 at 0x7f8a46cfb6a0>, 'coupler90bend': <function coupler90bend at 0x7f8a46cfb740>, 'coupler_adiabatic': <function coupler_adiabatic at 0x7f8a46cfba60>, 'coupler_asymmetric': <function coupler_asymmetric at 0x7f8a46cfbce0>, 'coupler_bent_half': <function coupler_bent_half at 0x7f8a46cfbf60>, 'coupler_bent': <function coupler_bent at 0x7f8a46b24180>, 'coupler_broadband': <function coupler_broadband at 0x7f8a46b24400>, 'coupler_full': <function coupler_full at 0x7f8a46b245e0>, 'coupler_ring': <function coupler_ring at 0x7f8a46b24860>, 'coupler_straight_asymmetric': <function coupler_straight_asymmetric at 0x7f8a46b24ae0>, 'align_wafer': <function align_wafer at 0x7f8a46b24ea0>, 'add_frame': <function add_frame at 0x7f8a46b24f40>, 'die': <function die at 0x7f8a46b25260>, 'die_with_pads': <function die_with_pads at 0x7f8a46b25440>, 'seal_ring': <function seal_ring at 0x7f8a46b25620>, 'seal_ring_segmented': <function seal_ring_segmented at 0x7f8a46b25760>, 'wafer': <function wafer at 0x7f8a46b25940>, 'free_propagation_region': <function free_propagation_region at 0x7f8a46b25da0>, 'awg': <function awg at 0x7f8a46b25e40>, 'dbr_cell': <function dbr_cell at 0x7f8a46b26160>, 'dbr': <function dbr at 0x7f8a46b262a0>, 'dbr_tapered': <function dbr_tapered at 0x7f8a46b26520>, 'bbox': <function bbox at 0x7f8a46b26ca0>, 'C': <function C at 0x7f8a46b26e80>, 'circle': <function circle at 0x7f8a46b27060>, 'compass': <function compass at 0x7f8a46b272e0>, 'cross': <function cross at 0x7f8a46b274c0>, 'ellipse': <function ellipse at 0x7f8a46b276a0>, 'fiducial_squares': <function fiducial_squares at 0x7f8a46b277e0>, 'L': <function L at 0x7f8a46b279c0>, 'nxn': <function nxn at 0x7f8a46b27ba0>, 'rectangle': <function rectangle at 0x7f8a46b27d80>, 'rectangles': <function rectangles at 0x7f8a46b27ec0>, 'regular_polygon': <function regular_polygon at 0x7f8a46b27f60>, 'triangle': <function triangle at 0x7f8a46b54220>, 'triangle2': <function triangle2 at 0x7f8a46b54360>, 'triangle4': <function triangle4 at 0x7f8a46b544a0>, 'fiber': <function fiber at 0x7f8a46b27e20>, 'fiber_array': <function fiber_array at 0x7f8a46b54540>, 'crossing_arm': <function crossing_arm at 0x7f8a46b56f20>, 'crossing': <function crossing at 0x7f8a46b57060>, 'crossing_linear_taper': <function crossing_linear_taper at 0x7f8a46b571a0>, 'crossing_etched': <function crossing_etched at 0x7f8a46b572e0>, 'crossing45': <function crossing45 at 0x7f8a46b57420>, 'straight_array': <function straight_array at 0x7f8a46b57880>, 'wire_straight': <function wire_straight at 0x7f8a46b579c0>, 'straight_heater_doped_rib': <function straight_heater_doped_rib at 0x7f8a46b57d80>, 'straight_heater_doped_strip': <function straight_heater_doped_strip at 0x7f8a46b8c040>, 'straight_heater_meander': <function straight_heater_meander at 0x7f8a46b8c2c0>, 'via': <function via at 0x7f8a46b8cae0>, 'via_circular': <function via_circular at 0x7f8a46b8cc20>, 'via_chain': <function via_chain at 0x7f8a46b8cf40>, 'via_corner': <function via_corner at 0x7f8a46b8d120>, 'via_stack': <function via_stack at 0x7f8a46b8d300>, 'via_stack_corner45': <function via_stack_corner45 at 0x7f8a46b8d440>, 'via_stack_corner45_extended': <function via_stack_corner45_extended at 0x7f8a46b8d580>, 'via_stack_with_offset': <function via_stack_with_offset at 0x7f8a46b8d6c0>, 'straight_heater_meander_doped': <function straight_heater_meander_doped at 0x7f8a46b8c7c0>, 'straight_heater_metal_undercut': <function straight_heater_metal_undercut at 0x7f8a46b8d620>, 'straight_heater_metal_simple': <function straight_heater_metal_simple at 0x7f8a46b8d940>, 'straight_piecewise': <function straight_piecewise at 0x7f8a46b8da80>, 'straight_pin': <function straight_pin at 0x7f8a46b8db20>, 'straight_pin_slot': <function straight_pin_slot at 0x7f8a46b8dda0>, 'wire_corner': <function wire_corner at 0x7f8a46b8e020>, 'wire_corner45': <function wire_corner45 at 0x7f8a46b8e160>, 'wire_corner_sections': <function wire_corner_sections at 0x7f8a46b8e200>, 'loop_mirror': <function loop_mirror at 0x7f8a46b54720>, 'mode_converter': <function mode_converter at 0x7f8a46b8fc40>, 'polarization_splitter_rotator': <function polarization_splitter_rotator at 0x7f8a46b8ff60>, 'terminator': <function terminator at 0x7f8a46bb8540>, 'grating_coupler_array': <function grating_coupler_array at 0x7f8a46bb87c0>, 'grating_coupler_dual_pol': <function grating_coupler_dual_pol at 0x7f8a46bb8ae0>, 'grating_coupler_elliptical': <function grating_coupler_elliptical at 0x7f8a46bb9120>, 'grating_coupler_elliptical_arbitrary': <function grating_coupler_elliptical_arbitrary at 0x7f8a46bb93a0>, 'grating_coupler_elliptical_uniform': <function grating_coupler_elliptical_uniform at 0x7f8a46bb9620>, 'grating_coupler_elliptical_lumerical': <function grating_coupler_elliptical_lumerical at 0x7f8a46bb9760>, 'grating_coupler_elliptical_trenches': <function grating_coupler_elliptical_trenches at 0x7f8a46bb8b80>, 'grating_coupler_loss': <function grating_coupler_loss at 0x7f8a46bb9940>, 'grating_coupler_rectangular': <function grating_coupler_rectangular at 0x7f8a46bb9b20>, 'grating_coupler_rectangular_arbitrary': <function grating_coupler_rectangular_arbitrary at 0x7f8a46bb9da0>, 'grating_coupler_tree': <function grating_coupler_tree at 0x7f8a46bba020>, 'mmi': <function mmi at 0x7f8a46bba340>, 'mmi1x2': <function mmi1x2 at 0x7f8a46bba660>, 'mmi1x2_with_sbend': <function mmi1x2_with_sbend at 0x7f8a46bba840>, 'mmi2x2': <function mmi2x2 at 0x7f8a46bbab60>, 'mmi2x2_with_sbend': <function mmi2x2_with_sbend at 0x7f8a46bbaca0>, 'mmi_90degree_hybrid': <function mmi_90degree_hybrid at 0x7f8a46bbae80>, 'mmi_tapered': <function mmi_tapered at 0x7f8a46bbb1a0>, 'pad': <function pad at 0x7f8a46bbb420>, 'pad_array': <function pad_array at 0x7f8a46bbb6a0>, 'pad_gsg_short': <function pad_gsg_short at 0x7f8a46bbb920>, 'pads_shorted': <function pads_shorted at 0x7f8a46bbbba0>, 'rectangle_with_slits': <function rectangle_with_slits at 0x7f8a46bbbce0>, 'cavity': <function cavity at 0x7f8a46bbbf60>, 'cdsem_all': <function cdsem_all at 0x7f8a46bdc220>, 'cdsem_bend180': <function cdsem_bend180 at 0x7f8a46bdc400>, 'cdsem_coupler': <function cdsem_coupler at 0x7f8a46bdc540>, 'cdsem_straight': <function cdsem_straight at 0x7f8a46bdc860>, 'cdsem_straight_density': <function cdsem_straight_density at 0x7f8a46bdc9a0>, 'bendu_double': <function bendu_double at 0x7f8a46bdcc20>, 'straight_double': <function straight_double at 0x7f8a46bdcd60>, 'cutback_2x2': <function cutback_2x2 at 0x7f8a46bdcea0>, 'cutback_bend': <function cutback_bend at 0x7f8a46bdd260>, 'cutback_bend90': <function cutback_bend90 at 0x7f8a46bdd3a0>, 'staircase': <function staircase at 0x7f8a46bdd4e0>, 'cutback_bend180': <function cutback_bend180 at 0x7f8a46bdd620>, 'cutback_component': <function cutback_component at 0x7f8a46bdd760>, 'cutback_splitter': <function cutback_splitter at 0x7f8a46bddb20>, 'greek_cross': <function greek_cross at 0x7f8a46bddc60>, 'greek_cross_with_pads': <function greek_cross_with_pads at 0x7f8a46bddee0>, 'litho_calipers': <function litho_calipers at 0x7f8a46bde0c0>, 'litho_ruler': <function litho_ruler at 0x7f8a46bde3e0>, 'litho_steps': <function litho_steps at 0x7f8a46bde5c0>, 'resistance_meander': <function resistance_meander at 0x7f8a46bde700>, 'resistance_sheet': <function resistance_sheet at 0x7f8a46bde8e0>, 'verniers': <function verniers at 0x7f8a46bdeac0>, 'text': <function text at 0x7f8a46bdf7e0>, 'text_lines': <function text_lines at 0x7f8a46bdf9c0>, 'text_klayout': <function text_klayout at 0x7f8a46bdfb00>, 'text_freetype': <function text_freetype at 0x7f8a46bdfe20>, 'pixel_array': <function pixel_array at 0x7f8a467280e0>, 'text_rectangular': <function text_rectangular at 0x7f8a46728220>, 'text_rectangular_multi_layer': <function text_rectangular_multi_layer at 0x7f8a46728360>, 'pixel': <function pixel at 0x7f8a46bdede0>, 'qrcode': <function qrcode at 0x7f8a46bdfa60>, 'version_stamp': <function version_stamp at 0x7f8a46728400>, 'disk': <function disk at 0x7f8a467289a0>, 'disk_heater': <function disk_heater at 0x7f8a46728ae0>, 'ring': <function ring at 0x7f8a46728d60>, 'ring_crow': <function ring_crow at 0x7f8a46728f40>, 'ring_crow_couplers': <function ring_crow_couplers at 0x7f8a46729080>, 'ring_double': <function ring_double at 0x7f8a46729260>, 'ring_double_bend_coupler': <function ring_double_bend_coupler at 0x7f8a46729580>, 'ring_double_heater': <function ring_double_heater at 0x7f8a467296c0>, 'ring_double_pn': <function ring_double_pn at 0x7f8a467299e0>, 'ring_single_pn': <function ring_single_pn at 0x7f8a46729b20>, 'ring_single': <function ring_single at 0x7f8a46729d00>, 'ring_single_array': <function ring_single_array at 0x7f8a46729e40>, 'coupler_bend': <function coupler_bend at 0x7f8a46729f80>, 'coupler_ring_bend': <function coupler_ring_bend at 0x7f8a4672a0c0>, 'ring_single_bend_coupler': <function ring_single_bend_coupler at 0x7f8a4672a200>, 'ring_single_dut': <function ring_single_dut at 0x7f8a4672a3e0>, 'delay_snake': <function delay_snake at 0x7f8a4672a660>, 'delay_snake2': <function delay_snake2 at 0x7f8a4672a840>, 'delay_snake_sbend': <function delay_snake_sbend at 0x7f8a4672aac0>, 'spiral': <function spiral at 0x7f8a4672ad40>, 'spiral_double': <function spiral_double at 0x7f8a4672af20>, 'spiral_racetrack': <function spiral_racetrack at 0x7f8a4672b1a0>, 'spiral_racetrack_fixed_length': <function spiral_racetrack_fixed_length at 0x7f8a4672b2e0>, 'spiral_racetrack_heater_metal': <function spiral_racetrack_heater_metal at 0x7f8a4672b4c0>, 'spiral_racetrack_heater_doped': <function spiral_racetrack_heater_doped at 0x7f8a4672b600>, 'spiral_inductor': <function spiral_inductor at 0x7f8a4672b740>, 'hline': <function hline at 0x7f8a4672b9c0>, 'optimal_90deg': <function optimal_90deg at 0x7f8a4672bb00>, 'optimal_hairpin': <function optimal_hairpin at 0x7f8a4672be20>, 'optimal_step': <function optimal_step at 0x7f8a4672bf60>, 'snspd': <function snspd at 0x7f8a46754180>, 'interdigital_capacitor': <function interdigital_capacitor at 0x7f8a46754360>, 'ge_detector_straight_si_contacts': <function ge_detector_straight_si_contacts at 0x7f8a467545e0>, 'edge_coupler_silicon': <function edge_coupler_silicon at 0x7f8a46754860>, 'edge_coupler_array': <function edge_coupler_array at 0x7f8a467549a0>, 'edge_coupler_array_with_loopback': <function edge_coupler_array_with_loopback at 0x7f8a46754ae0>}, virtual_factories={'virtual_bend_circular': <function virtual_bend_circular_factory.<locals>.virtual_bend_circular at 0x7f8a50e75bc0>, 'bend_euler': <function virtual_bend_euler_factory.<locals>.bend_euler at 0x7f8a50e75e40>, 'virtual_straight': <function virtual_straight_factory.<locals>.virtual_straight at 0x7f8a50e760c0>, 'bend_circular_all_angle': <function bend_circular_all_angle at 0x7f8a46cd23e0>, 'bend_euler_all_angle': <function bend_euler_all_angle at 0x7f8a46cd2f20>, 'straight_all_angle': <function straight_all_angle at 0x7f8a46b57740>}, kcells={0: Unnamed_0: ports [], 2 instances, 1: mmi1x2_WNone_WT1_LT10_L_4e0f7121: ports ['o1', 'o2', 'o3'], 0 instances, 2: taper_L10_W0p5_W1_LNone_456c7208: ports ['o1', 'o2'], 0 instances, 3: straight_L5p5_N2_CSxs_5_d3ec67bc: ports ['o1', 'o2'], 0 instances, 4: Unnamed_4: ports [], 6 instances, 5: bend_euler_R10_A90_P0p5_2f1f5c6d: ports ['o1', 'o2'], 0 instances, 6: straight_L29p375_N2_CSs_6ed2bfdd: ports ['o1', 'o2'], 0 instances, 7: straight_L54p5_N2_CSstrip_WNone: ports ['o1', 'o2'], 0 instances}, layers=<aenum 'LAYER'>, infos=LayerInfos(), layer_stack=LayerStack(layers={}), netlist_layer_mapping={}, sparameters_path=None, interconnect_cml_path=None, constants=Constants(), rename_function=<function rename_clockwise_multi at 0x7f8a5c3aef20>, info=Info(), settings=KCellSettings(version='0.23.1', klayout_version='0.29.11', meta_format='v3'), future_cell_name=None, decorators=<kfactory.decorators.Decorators object at 0x7f8a5c3895d0>) function_name='straight' basename=None boundary=None insts=<gdsfactory.component.ComponentReferences object at 0x7f8a2cf50050> size_info=<kfactory.kcell.SizeInfo object at 0x7f8a2e1d7710> dsize_info=<kfactory.kcell.DSizeInfo object at 0x7f8a389d4750> routes={}, Unnamed_4: ports ['o1', 'o2'], vinsts=[] info=Info(length=16.637, dy=10.0, min_bend_radius=7.061, radius=10.0, width=0.5, route_info_type='strip', route_info_length=16.637, route_info_weight=16.637, route_info_strip_length=16.637, route_info_n_bend_90=1.0, route_info_min_bend_radius=7.061) kcl=KCLayout(name='DEFAULT', layout=<klayout.dbcore.Layout object at 0x7f8a5c114b90>, layer_enclosures=LayerEnclosureModel(root={'78687732': LayerEnclosure(layer_sections={}, main_layer=WG (1/0), yaml_tag='!Enclosure')}), cross_sections={'78687732_500': SymmetricalCrossSection(width=500, enclosure=LayerEnclosure(layer_sections={}, main_layer=WG (1/0), yaml_tag='!Enclosure'), name='78687732_500'), '78687732_1000': SymmetricalCrossSection(width=1000, enclosure=LayerEnclosure(layer_sections={}, main_layer=WG (1/0), yaml_tag='!Enclosure'), name='78687732_1000'), '78687732_2500': SymmetricalCrossSection(width=2500, enclosure=LayerEnclosure(layer_sections={}, main_layer=WG (1/0), yaml_tag='!Enclosure'), name='78687732_2500')}, enclosure=KCellEnclosure(enclosures=LayerEnclosureCollection(enclosures=[])), library=<klayout.dbcore.Library object at 0x7f8a5c114910>, factories={'taper': <function taper at 0x7f8a46cd3e20>, 'bend_s_bezier': <function bend_s_bezier_factory.<locals>.bend_s_bezier at 0x7f8a50e5e700>, 'bend_circular': <function bend_circular at 0x7f8a46cd22a0>, 'bend_euler': <function bend_euler at 0x7f8a46cd2ca0>, 'bend_s_euler': <function bend_s_euler_factory.<locals>.bend_s_euler at 0x7f8a50e74cc0>, 'straight': <function straight at 0x7f8a46b57600>, 'rotate': <function rotate at 0x7f8a47370e00>, 'from_image': <function from_image at 0x7f8a472622a0>, 'floorplan_with_block_letters': <function floorplan_with_block_letters at 0x7f8a46c4d8a0>, 'bend_circular_heater': <function bend_circular_heater at 0x7f8a46cd2520>, 'bend_euler_s': <function bend_euler_s at 0x7f8a46cd2b60>, 'bezier': <function bezier at 0x7f8a46cd3240>, 'bend_s': <function bend_s at 0x7f8a46cd3420>, 'add_fiber_array_optical_south_electrical_north': <function add_fiber_array_optical_south_electrical_north at 0x7f8a46cd36a0>, 'ramp': <function ramp at 0x7f8a46cd3ba0>, 'taper_strip_to_ridge': <function taper_strip_to_ridge at 0x7f8a46cd3ec0>, 'taper_strip_to_ridge_trenches': <function taper_strip_to_ridge_trenches at 0x7f8a46cf8180>, 'taper_sc_nc': <function taper_sc_nc at 0x7f8a46cf82c0>, 'taper_adiabatic': <function taper_adiabatic at 0x7f8a46cf85e0>, 'taper_cross_section': <function taper_cross_section at 0x7f8a46cf87c0>, 'taper_from_csv': <function taper_from_csv at 0x7f8a46cf89a0>, 'taper_parabolic': <function taper_parabolic at 0x7f8a46cf8ae0>, 'add_termination': <function add_termination at 0x7f8a46cd37e0>, 'add_trenches': <function add_trenches at 0x7f8a46cf8900>, 'array': <function array at 0x7f8a46cf8cc0>, 'copy_layers': <function copy_layers at 0x7f8a46cf91c0>, 'extend_ports_list': <function extend_ports_list at 0x7f8a46cf9300>, 'extend_ports': <function extend_ports at 0x7f8a46cf9620>, 'pack_doe': <function pack_doe at 0x7f8a46cf9e40>, 'pack_doe_grid': <function pack_doe_grid at 0x7f8a46cf9f80>, 'splitter_chain': <function splitter_chain at 0x7f8a46cfa0c0>, 'mzi': <function mzi at 0x7f8a46cfa660>, 'mzi_lattice': <function mzi_lattice at 0x7f8a46cfa980>, 'mzi_lattice_mmi': <function mzi_lattice_mmi at 0x7f8a46cfaac0>, 'mzi_pads_center': <function mzi_pads_center at 0x7f8a46cfad40>, 'mzit': <function mzit at 0x7f8a46cfaf20>, 'mzit_lattice': <function mzit_lattice at 0x7f8a46cfb060>, 'splitter_tree': <function splitter_tree at 0x7f8a46cfac00>, 'coupler_symmetric': <function coupler_symmetric at 0x7f8a46cfb240>, 'coupler_straight': <function coupler_straight at 0x7f8a46cfb380>, 'coupler': <function coupler at 0x7f8a46cfb4c0>, 'coupler90': <function coupler90 at 0x7f8a46cfb6a0>, 'coupler90bend': <function coupler90bend at 0x7f8a46cfb740>, 'coupler_adiabatic': <function coupler_adiabatic at 0x7f8a46cfba60>, 'coupler_asymmetric': <function coupler_asymmetric at 0x7f8a46cfbce0>, 'coupler_bent_half': <function coupler_bent_half at 0x7f8a46cfbf60>, 'coupler_bent': <function coupler_bent at 0x7f8a46b24180>, 'coupler_broadband': <function coupler_broadband at 0x7f8a46b24400>, 'coupler_full': <function coupler_full at 0x7f8a46b245e0>, 'coupler_ring': <function coupler_ring at 0x7f8a46b24860>, 'coupler_straight_asymmetric': <function coupler_straight_asymmetric at 0x7f8a46b24ae0>, 'align_wafer': <function align_wafer at 0x7f8a46b24ea0>, 'add_frame': <function add_frame at 0x7f8a46b24f40>, 'die': <function die at 0x7f8a46b25260>, 'die_with_pads': <function die_with_pads at 0x7f8a46b25440>, 'seal_ring': <function seal_ring at 0x7f8a46b25620>, 'seal_ring_segmented': <function seal_ring_segmented at 0x7f8a46b25760>, 'wafer': <function wafer at 0x7f8a46b25940>, 'free_propagation_region': <function free_propagation_region at 0x7f8a46b25da0>, 'awg': <function awg at 0x7f8a46b25e40>, 'dbr_cell': <function dbr_cell at 0x7f8a46b26160>, 'dbr': <function dbr at 0x7f8a46b262a0>, 'dbr_tapered': <function dbr_tapered at 0x7f8a46b26520>, 'bbox': <function bbox at 0x7f8a46b26ca0>, 'C': <function C at 0x7f8a46b26e80>, 'circle': <function circle at 0x7f8a46b27060>, 'compass': <function compass at 0x7f8a46b272e0>, 'cross': <function cross at 0x7f8a46b274c0>, 'ellipse': <function ellipse at 0x7f8a46b276a0>, 'fiducial_squares': <function fiducial_squares at 0x7f8a46b277e0>, 'L': <function L at 0x7f8a46b279c0>, 'nxn': <function nxn at 0x7f8a46b27ba0>, 'rectangle': <function rectangle at 0x7f8a46b27d80>, 'rectangles': <function rectangles at 0x7f8a46b27ec0>, 'regular_polygon': <function regular_polygon at 0x7f8a46b27f60>, 'triangle': <function triangle at 0x7f8a46b54220>, 'triangle2': <function triangle2 at 0x7f8a46b54360>, 'triangle4': <function triangle4 at 0x7f8a46b544a0>, 'fiber': <function fiber at 0x7f8a46b27e20>, 'fiber_array': <function fiber_array at 0x7f8a46b54540>, 'crossing_arm': <function crossing_arm at 0x7f8a46b56f20>, 'crossing': <function crossing at 0x7f8a46b57060>, 'crossing_linear_taper': <function crossing_linear_taper at 0x7f8a46b571a0>, 'crossing_etched': <function crossing_etched at 0x7f8a46b572e0>, 'crossing45': <function crossing45 at 0x7f8a46b57420>, 'straight_array': <function straight_array at 0x7f8a46b57880>, 'wire_straight': <function wire_straight at 0x7f8a46b579c0>, 'straight_heater_doped_rib': <function straight_heater_doped_rib at 0x7f8a46b57d80>, 'straight_heater_doped_strip': <function straight_heater_doped_strip at 0x7f8a46b8c040>, 'straight_heater_meander': <function straight_heater_meander at 0x7f8a46b8c2c0>, 'via': <function via at 0x7f8a46b8cae0>, 'via_circular': <function via_circular at 0x7f8a46b8cc20>, 'via_chain': <function via_chain at 0x7f8a46b8cf40>, 'via_corner': <function via_corner at 0x7f8a46b8d120>, 'via_stack': <function via_stack at 0x7f8a46b8d300>, 'via_stack_corner45': <function via_stack_corner45 at 0x7f8a46b8d440>, 'via_stack_corner45_extended': <function via_stack_corner45_extended at 0x7f8a46b8d580>, 'via_stack_with_offset': <function via_stack_with_offset at 0x7f8a46b8d6c0>, 'straight_heater_meander_doped': <function straight_heater_meander_doped at 0x7f8a46b8c7c0>, 'straight_heater_metal_undercut': <function straight_heater_metal_undercut at 0x7f8a46b8d620>, 'straight_heater_metal_simple': <function straight_heater_metal_simple at 0x7f8a46b8d940>, 'straight_piecewise': <function straight_piecewise at 0x7f8a46b8da80>, 'straight_pin': <function straight_pin at 0x7f8a46b8db20>, 'straight_pin_slot': <function straight_pin_slot at 0x7f8a46b8dda0>, 'wire_corner': <function wire_corner at 0x7f8a46b8e020>, 'wire_corner45': <function wire_corner45 at 0x7f8a46b8e160>, 'wire_corner_sections': <function wire_corner_sections at 0x7f8a46b8e200>, 'loop_mirror': <function loop_mirror at 0x7f8a46b54720>, 'mode_converter': <function mode_converter at 0x7f8a46b8fc40>, 'polarization_splitter_rotator': <function polarization_splitter_rotator at 0x7f8a46b8ff60>, 'terminator': <function terminator at 0x7f8a46bb8540>, 'grating_coupler_array': <function grating_coupler_array at 0x7f8a46bb87c0>, 'grating_coupler_dual_pol': <function grating_coupler_dual_pol at 0x7f8a46bb8ae0>, 'grating_coupler_elliptical': <function grating_coupler_elliptical at 0x7f8a46bb9120>, 'grating_coupler_elliptical_arbitrary': <function grating_coupler_elliptical_arbitrary at 0x7f8a46bb93a0>, 'grating_coupler_elliptical_uniform': <function grating_coupler_elliptical_uniform at 0x7f8a46bb9620>, 'grating_coupler_elliptical_lumerical': <function grating_coupler_elliptical_lumerical at 0x7f8a46bb9760>, 'grating_coupler_elliptical_trenches': <function grating_coupler_elliptical_trenches at 0x7f8a46bb8b80>, 'grating_coupler_loss': <function grating_coupler_loss at 0x7f8a46bb9940>, 'grating_coupler_rectangular': <function grating_coupler_rectangular at 0x7f8a46bb9b20>, 'grating_coupler_rectangular_arbitrary': <function grating_coupler_rectangular_arbitrary at 0x7f8a46bb9da0>, 'grating_coupler_tree': <function grating_coupler_tree at 0x7f8a46bba020>, 'mmi': <function mmi at 0x7f8a46bba340>, 'mmi1x2': <function mmi1x2 at 0x7f8a46bba660>, 'mmi1x2_with_sbend': <function mmi1x2_with_sbend at 0x7f8a46bba840>, 'mmi2x2': <function mmi2x2 at 0x7f8a46bbab60>, 'mmi2x2_with_sbend': <function mmi2x2_with_sbend at 0x7f8a46bbaca0>, 'mmi_90degree_hybrid': <function mmi_90degree_hybrid at 0x7f8a46bbae80>, 'mmi_tapered': <function mmi_tapered at 0x7f8a46bbb1a0>, 'pad': <function pad at 0x7f8a46bbb420>, 'pad_array': <function pad_array at 0x7f8a46bbb6a0>, 'pad_gsg_short': <function pad_gsg_short at 0x7f8a46bbb920>, 'pads_shorted': <function pads_shorted at 0x7f8a46bbbba0>, 'rectangle_with_slits': <function rectangle_with_slits at 0x7f8a46bbbce0>, 'cavity': <function cavity at 0x7f8a46bbbf60>, 'cdsem_all': <function cdsem_all at 0x7f8a46bdc220>, 'cdsem_bend180': <function cdsem_bend180 at 0x7f8a46bdc400>, 'cdsem_coupler': <function cdsem_coupler at 0x7f8a46bdc540>, 'cdsem_straight': <function cdsem_straight at 0x7f8a46bdc860>, 'cdsem_straight_density': <function cdsem_straight_density at 0x7f8a46bdc9a0>, 'bendu_double': <function bendu_double at 0x7f8a46bdcc20>, 'straight_double': <function straight_double at 0x7f8a46bdcd60>, 'cutback_2x2': <function cutback_2x2 at 0x7f8a46bdcea0>, 'cutback_bend': <function cutback_bend at 0x7f8a46bdd260>, 'cutback_bend90': <function cutback_bend90 at 0x7f8a46bdd3a0>, 'staircase': <function staircase at 0x7f8a46bdd4e0>, 'cutback_bend180': <function cutback_bend180 at 0x7f8a46bdd620>, 'cutback_component': <function cutback_component at 0x7f8a46bdd760>, 'cutback_splitter': <function cutback_splitter at 0x7f8a46bddb20>, 'greek_cross': <function greek_cross at 0x7f8a46bddc60>, 'greek_cross_with_pads': <function greek_cross_with_pads at 0x7f8a46bddee0>, 'litho_calipers': <function litho_calipers at 0x7f8a46bde0c0>, 'litho_ruler': <function litho_ruler at 0x7f8a46bde3e0>, 'litho_steps': <function litho_steps at 0x7f8a46bde5c0>, 'resistance_meander': <function resistance_meander at 0x7f8a46bde700>, 'resistance_sheet': <function resistance_sheet at 0x7f8a46bde8e0>, 'verniers': <function verniers at 0x7f8a46bdeac0>, 'text': <function text at 0x7f8a46bdf7e0>, 'text_lines': <function text_lines at 0x7f8a46bdf9c0>, 'text_klayout': <function text_klayout at 0x7f8a46bdfb00>, 'text_freetype': <function text_freetype at 0x7f8a46bdfe20>, 'pixel_array': <function pixel_array at 0x7f8a467280e0>, 'text_rectangular': <function text_rectangular at 0x7f8a46728220>, 'text_rectangular_multi_layer': <function text_rectangular_multi_layer at 0x7f8a46728360>, 'pixel': <function pixel at 0x7f8a46bdede0>, 'qrcode': <function qrcode at 0x7f8a46bdfa60>, 'version_stamp': <function version_stamp at 0x7f8a46728400>, 'disk': <function disk at 0x7f8a467289a0>, 'disk_heater': <function disk_heater at 0x7f8a46728ae0>, 'ring': <function ring at 0x7f8a46728d60>, 'ring_crow': <function ring_crow at 0x7f8a46728f40>, 'ring_crow_couplers': <function ring_crow_couplers at 0x7f8a46729080>, 'ring_double': <function ring_double at 0x7f8a46729260>, 'ring_double_bend_coupler': <function ring_double_bend_coupler at 0x7f8a46729580>, 'ring_double_heater': <function ring_double_heater at 0x7f8a467296c0>, 'ring_double_pn': <function ring_double_pn at 0x7f8a467299e0>, 'ring_single_pn': <function ring_single_pn at 0x7f8a46729b20>, 'ring_single': <function ring_single at 0x7f8a46729d00>, 'ring_single_array': <function ring_single_array at 0x7f8a46729e40>, 'coupler_bend': <function coupler_bend at 0x7f8a46729f80>, 'coupler_ring_bend': <function coupler_ring_bend at 0x7f8a4672a0c0>, 'ring_single_bend_coupler': <function ring_single_bend_coupler at 0x7f8a4672a200>, 'ring_single_dut': <function ring_single_dut at 0x7f8a4672a3e0>, 'delay_snake': <function delay_snake at 0x7f8a4672a660>, 'delay_snake2': <function delay_snake2 at 0x7f8a4672a840>, 'delay_snake_sbend': <function delay_snake_sbend at 0x7f8a4672aac0>, 'spiral': <function spiral at 0x7f8a4672ad40>, 'spiral_double': <function spiral_double at 0x7f8a4672af20>, 'spiral_racetrack': <function spiral_racetrack at 0x7f8a4672b1a0>, 'spiral_racetrack_fixed_length': <function spiral_racetrack_fixed_length at 0x7f8a4672b2e0>, 'spiral_racetrack_heater_metal': <function spiral_racetrack_heater_metal at 0x7f8a4672b4c0>, 'spiral_racetrack_heater_doped': <function spiral_racetrack_heater_doped at 0x7f8a4672b600>, 'spiral_inductor': <function spiral_inductor at 0x7f8a4672b740>, 'hline': <function hline at 0x7f8a4672b9c0>, 'optimal_90deg': <function optimal_90deg at 0x7f8a4672bb00>, 'optimal_hairpin': <function optimal_hairpin at 0x7f8a4672be20>, 'optimal_step': <function optimal_step at 0x7f8a4672bf60>, 'snspd': <function snspd at 0x7f8a46754180>, 'interdigital_capacitor': <function interdigital_capacitor at 0x7f8a46754360>, 'ge_detector_straight_si_contacts': <function ge_detector_straight_si_contacts at 0x7f8a467545e0>, 'edge_coupler_silicon': <function edge_coupler_silicon at 0x7f8a46754860>, 'edge_coupler_array': <function edge_coupler_array at 0x7f8a467549a0>, 'edge_coupler_array_with_loopback': <function edge_coupler_array_with_loopback at 0x7f8a46754ae0>}, virtual_factories={'virtual_bend_circular': <function virtual_bend_circular_factory.<locals>.virtual_bend_circular at 0x7f8a50e75bc0>, 'bend_euler': <function virtual_bend_euler_factory.<locals>.bend_euler at 0x7f8a50e75e40>, 'virtual_straight': <function virtual_straight_factory.<locals>.virtual_straight at 0x7f8a50e760c0>, 'bend_circular_all_angle': <function bend_circular_all_angle at 0x7f8a46cd23e0>, 'bend_euler_all_angle': <function bend_euler_all_angle at 0x7f8a46cd2f20>, 'straight_all_angle': <function straight_all_angle at 0x7f8a46b57740>}, kcells={0: Unnamed_0: ports [], 2 instances, 1: mmi1x2_WNone_WT1_LT10_L_4e0f7121: ports ['o1', 'o2', 'o3'], 0 instances, 2: taper_L10_W0p5_W1_LNone_456c7208: ports ['o1', 'o2'], 0 instances, 3: straight_L5p5_N2_CSxs_5_d3ec67bc: ports ['o1', 'o2'], 0 instances, 4: Unnamed_4: ports [], 6 instances, 5: bend_euler_R10_A90_P0p5_2f1f5c6d: ports ['o1', 'o2'], 0 instances, 6: straight_L29p375_N2_CSs_6ed2bfdd: ports ['o1', 'o2'], 0 instances, 7: straight_L54p5_N2_CSstrip_WNone: ports ['o1', 'o2'], 0 instances}, layers=<aenum 'LAYER'>, infos=LayerInfos(), layer_stack=LayerStack(layers={}), netlist_layer_mapping={}, sparameters_path=None, interconnect_cml_path=None, constants=Constants(), rename_function=<function rename_clockwise_multi at 0x7f8a5c3aef20>, info=Info(), settings=KCellSettings(version='0.23.1', klayout_version='0.29.11', meta_format='v3'), future_cell_name=None, decorators=<kfactory.decorators.Decorators object at 0x7f8a5c3895d0>) function_name='bend_euler' basename=None boundary=None insts=<gdsfactory.component.ComponentReferences object at 0x7f8a3ffcdf90> size_info=<kfactory.kcell.SizeInfo object at 0x7f8a2e1e53d0> dsize_info=<kfactory.kcell.DSizeInfo object at 0x7f8a2f3206d0> routes={}, Unnamed_4: ports ['o1', 'o2'], vinsts=[] info=Info(length=54.5, width=0.5, route_info_type='strip', route_info_length=54.5, route_info_weight=54.5, route_info_strip_length=54.5) kcl=KCLayout(name='DEFAULT', layout=<klayout.dbcore.Layout object at 0x7f8a5c114b90>, layer_enclosures=LayerEnclosureModel(root={'78687732': LayerEnclosure(layer_sections={}, main_layer=WG (1/0), yaml_tag='!Enclosure')}), cross_sections={'78687732_500': SymmetricalCrossSection(width=500, enclosure=LayerEnclosure(layer_sections={}, main_layer=WG (1/0), yaml_tag='!Enclosure'), name='78687732_500'), '78687732_1000': SymmetricalCrossSection(width=1000, enclosure=LayerEnclosure(layer_sections={}, main_layer=WG (1/0), yaml_tag='!Enclosure'), name='78687732_1000'), '78687732_2500': SymmetricalCrossSection(width=2500, enclosure=LayerEnclosure(layer_sections={}, main_layer=WG (1/0), yaml_tag='!Enclosure'), name='78687732_2500')}, enclosure=KCellEnclosure(enclosures=LayerEnclosureCollection(enclosures=[])), library=<klayout.dbcore.Library object at 0x7f8a5c114910>, factories={'taper': <function taper at 0x7f8a46cd3e20>, 'bend_s_bezier': <function bend_s_bezier_factory.<locals>.bend_s_bezier at 0x7f8a50e5e700>, 'bend_circular': <function bend_circular at 0x7f8a46cd22a0>, 'bend_euler': <function bend_euler at 0x7f8a46cd2ca0>, 'bend_s_euler': <function bend_s_euler_factory.<locals>.bend_s_euler at 0x7f8a50e74cc0>, 'straight': <function straight at 0x7f8a46b57600>, 'rotate': <function rotate at 0x7f8a47370e00>, 'from_image': <function from_image at 0x7f8a472622a0>, 'floorplan_with_block_letters': <function floorplan_with_block_letters at 0x7f8a46c4d8a0>, 'bend_circular_heater': <function bend_circular_heater at 0x7f8a46cd2520>, 'bend_euler_s': <function bend_euler_s at 0x7f8a46cd2b60>, 'bezier': <function bezier at 0x7f8a46cd3240>, 'bend_s': <function bend_s at 0x7f8a46cd3420>, 'add_fiber_array_optical_south_electrical_north': <function add_fiber_array_optical_south_electrical_north at 0x7f8a46cd36a0>, 'ramp': <function ramp at 0x7f8a46cd3ba0>, 'taper_strip_to_ridge': <function taper_strip_to_ridge at 0x7f8a46cd3ec0>, 'taper_strip_to_ridge_trenches': <function taper_strip_to_ridge_trenches at 0x7f8a46cf8180>, 'taper_sc_nc': <function taper_sc_nc at 0x7f8a46cf82c0>, 'taper_adiabatic': <function taper_adiabatic at 0x7f8a46cf85e0>, 'taper_cross_section': <function taper_cross_section at 0x7f8a46cf87c0>, 'taper_from_csv': <function taper_from_csv at 0x7f8a46cf89a0>, 'taper_parabolic': <function taper_parabolic at 0x7f8a46cf8ae0>, 'add_termination': <function add_termination at 0x7f8a46cd37e0>, 'add_trenches': <function add_trenches at 0x7f8a46cf8900>, 'array': <function array at 0x7f8a46cf8cc0>, 'copy_layers': <function copy_layers at 0x7f8a46cf91c0>, 'extend_ports_list': <function extend_ports_list at 0x7f8a46cf9300>, 'extend_ports': <function extend_ports at 0x7f8a46cf9620>, 'pack_doe': <function pack_doe at 0x7f8a46cf9e40>, 'pack_doe_grid': <function pack_doe_grid at 0x7f8a46cf9f80>, 'splitter_chain': <function splitter_chain at 0x7f8a46cfa0c0>, 'mzi': <function mzi at 0x7f8a46cfa660>, 'mzi_lattice': <function mzi_lattice at 0x7f8a46cfa980>, 'mzi_lattice_mmi': <function mzi_lattice_mmi at 0x7f8a46cfaac0>, 'mzi_pads_center': <function mzi_pads_center at 0x7f8a46cfad40>, 'mzit': <function mzit at 0x7f8a46cfaf20>, 'mzit_lattice': <function mzit_lattice at 0x7f8a46cfb060>, 'splitter_tree': <function splitter_tree at 0x7f8a46cfac00>, 'coupler_symmetric': <function coupler_symmetric at 0x7f8a46cfb240>, 'coupler_straight': <function coupler_straight at 0x7f8a46cfb380>, 'coupler': <function coupler at 0x7f8a46cfb4c0>, 'coupler90': <function coupler90 at 0x7f8a46cfb6a0>, 'coupler90bend': <function coupler90bend at 0x7f8a46cfb740>, 'coupler_adiabatic': <function coupler_adiabatic at 0x7f8a46cfba60>, 'coupler_asymmetric': <function coupler_asymmetric at 0x7f8a46cfbce0>, 'coupler_bent_half': <function coupler_bent_half at 0x7f8a46cfbf60>, 'coupler_bent': <function coupler_bent at 0x7f8a46b24180>, 'coupler_broadband': <function coupler_broadband at 0x7f8a46b24400>, 'coupler_full': <function coupler_full at 0x7f8a46b245e0>, 'coupler_ring': <function coupler_ring at 0x7f8a46b24860>, 'coupler_straight_asymmetric': <function coupler_straight_asymmetric at 0x7f8a46b24ae0>, 'align_wafer': <function align_wafer at 0x7f8a46b24ea0>, 'add_frame': <function add_frame at 0x7f8a46b24f40>, 'die': <function die at 0x7f8a46b25260>, 'die_with_pads': <function die_with_pads at 0x7f8a46b25440>, 'seal_ring': <function seal_ring at 0x7f8a46b25620>, 'seal_ring_segmented': <function seal_ring_segmented at 0x7f8a46b25760>, 'wafer': <function wafer at 0x7f8a46b25940>, 'free_propagation_region': <function free_propagation_region at 0x7f8a46b25da0>, 'awg': <function awg at 0x7f8a46b25e40>, 'dbr_cell': <function dbr_cell at 0x7f8a46b26160>, 'dbr': <function dbr at 0x7f8a46b262a0>, 'dbr_tapered': <function dbr_tapered at 0x7f8a46b26520>, 'bbox': <function bbox at 0x7f8a46b26ca0>, 'C': <function C at 0x7f8a46b26e80>, 'circle': <function circle at 0x7f8a46b27060>, 'compass': <function compass at 0x7f8a46b272e0>, 'cross': <function cross at 0x7f8a46b274c0>, 'ellipse': <function ellipse at 0x7f8a46b276a0>, 'fiducial_squares': <function fiducial_squares at 0x7f8a46b277e0>, 'L': <function L at 0x7f8a46b279c0>, 'nxn': <function nxn at 0x7f8a46b27ba0>, 'rectangle': <function rectangle at 0x7f8a46b27d80>, 'rectangles': <function rectangles at 0x7f8a46b27ec0>, 'regular_polygon': <function regular_polygon at 0x7f8a46b27f60>, 'triangle': <function triangle at 0x7f8a46b54220>, 'triangle2': <function triangle2 at 0x7f8a46b54360>, 'triangle4': <function triangle4 at 0x7f8a46b544a0>, 'fiber': <function fiber at 0x7f8a46b27e20>, 'fiber_array': <function fiber_array at 0x7f8a46b54540>, 'crossing_arm': <function crossing_arm at 0x7f8a46b56f20>, 'crossing': <function crossing at 0x7f8a46b57060>, 'crossing_linear_taper': <function crossing_linear_taper at 0x7f8a46b571a0>, 'crossing_etched': <function crossing_etched at 0x7f8a46b572e0>, 'crossing45': <function crossing45 at 0x7f8a46b57420>, 'straight_array': <function straight_array at 0x7f8a46b57880>, 'wire_straight': <function wire_straight at 0x7f8a46b579c0>, 'straight_heater_doped_rib': <function straight_heater_doped_rib at 0x7f8a46b57d80>, 'straight_heater_doped_strip': <function straight_heater_doped_strip at 0x7f8a46b8c040>, 'straight_heater_meander': <function straight_heater_meander at 0x7f8a46b8c2c0>, 'via': <function via at 0x7f8a46b8cae0>, 'via_circular': <function via_circular at 0x7f8a46b8cc20>, 'via_chain': <function via_chain at 0x7f8a46b8cf40>, 'via_corner': <function via_corner at 0x7f8a46b8d120>, 'via_stack': <function via_stack at 0x7f8a46b8d300>, 'via_stack_corner45': <function via_stack_corner45 at 0x7f8a46b8d440>, 'via_stack_corner45_extended': <function via_stack_corner45_extended at 0x7f8a46b8d580>, 'via_stack_with_offset': <function via_stack_with_offset at 0x7f8a46b8d6c0>, 'straight_heater_meander_doped': <function straight_heater_meander_doped at 0x7f8a46b8c7c0>, 'straight_heater_metal_undercut': <function straight_heater_metal_undercut at 0x7f8a46b8d620>, 'straight_heater_metal_simple': <function straight_heater_metal_simple at 0x7f8a46b8d940>, 'straight_piecewise': <function straight_piecewise at 0x7f8a46b8da80>, 'straight_pin': <function straight_pin at 0x7f8a46b8db20>, 'straight_pin_slot': <function straight_pin_slot at 0x7f8a46b8dda0>, 'wire_corner': <function wire_corner at 0x7f8a46b8e020>, 'wire_corner45': <function wire_corner45 at 0x7f8a46b8e160>, 'wire_corner_sections': <function wire_corner_sections at 0x7f8a46b8e200>, 'loop_mirror': <function loop_mirror at 0x7f8a46b54720>, 'mode_converter': <function mode_converter at 0x7f8a46b8fc40>, 'polarization_splitter_rotator': <function polarization_splitter_rotator at 0x7f8a46b8ff60>, 'terminator': <function terminator at 0x7f8a46bb8540>, 'grating_coupler_array': <function grating_coupler_array at 0x7f8a46bb87c0>, 'grating_coupler_dual_pol': <function grating_coupler_dual_pol at 0x7f8a46bb8ae0>, 'grating_coupler_elliptical': <function grating_coupler_elliptical at 0x7f8a46bb9120>, 'grating_coupler_elliptical_arbitrary': <function grating_coupler_elliptical_arbitrary at 0x7f8a46bb93a0>, 'grating_coupler_elliptical_uniform': <function grating_coupler_elliptical_uniform at 0x7f8a46bb9620>, 'grating_coupler_elliptical_lumerical': <function grating_coupler_elliptical_lumerical at 0x7f8a46bb9760>, 'grating_coupler_elliptical_trenches': <function grating_coupler_elliptical_trenches at 0x7f8a46bb8b80>, 'grating_coupler_loss': <function grating_coupler_loss at 0x7f8a46bb9940>, 'grating_coupler_rectangular': <function grating_coupler_rectangular at 0x7f8a46bb9b20>, 'grating_coupler_rectangular_arbitrary': <function grating_coupler_rectangular_arbitrary at 0x7f8a46bb9da0>, 'grating_coupler_tree': <function grating_coupler_tree at 0x7f8a46bba020>, 'mmi': <function mmi at 0x7f8a46bba340>, 'mmi1x2': <function mmi1x2 at 0x7f8a46bba660>, 'mmi1x2_with_sbend': <function mmi1x2_with_sbend at 0x7f8a46bba840>, 'mmi2x2': <function mmi2x2 at 0x7f8a46bbab60>, 'mmi2x2_with_sbend': <function mmi2x2_with_sbend at 0x7f8a46bbaca0>, 'mmi_90degree_hybrid': <function mmi_90degree_hybrid at 0x7f8a46bbae80>, 'mmi_tapered': <function mmi_tapered at 0x7f8a46bbb1a0>, 'pad': <function pad at 0x7f8a46bbb420>, 'pad_array': <function pad_array at 0x7f8a46bbb6a0>, 'pad_gsg_short': <function pad_gsg_short at 0x7f8a46bbb920>, 'pads_shorted': <function pads_shorted at 0x7f8a46bbbba0>, 'rectangle_with_slits': <function rectangle_with_slits at 0x7f8a46bbbce0>, 'cavity': <function cavity at 0x7f8a46bbbf60>, 'cdsem_all': <function cdsem_all at 0x7f8a46bdc220>, 'cdsem_bend180': <function cdsem_bend180 at 0x7f8a46bdc400>, 'cdsem_coupler': <function cdsem_coupler at 0x7f8a46bdc540>, 'cdsem_straight': <function cdsem_straight at 0x7f8a46bdc860>, 'cdsem_straight_density': <function cdsem_straight_density at 0x7f8a46bdc9a0>, 'bendu_double': <function bendu_double at 0x7f8a46bdcc20>, 'straight_double': <function straight_double at 0x7f8a46bdcd60>, 'cutback_2x2': <function cutback_2x2 at 0x7f8a46bdcea0>, 'cutback_bend': <function cutback_bend at 0x7f8a46bdd260>, 'cutback_bend90': <function cutback_bend90 at 0x7f8a46bdd3a0>, 'staircase': <function staircase at 0x7f8a46bdd4e0>, 'cutback_bend180': <function cutback_bend180 at 0x7f8a46bdd620>, 'cutback_component': <function cutback_component at 0x7f8a46bdd760>, 'cutback_splitter': <function cutback_splitter at 0x7f8a46bddb20>, 'greek_cross': <function greek_cross at 0x7f8a46bddc60>, 'greek_cross_with_pads': <function greek_cross_with_pads at 0x7f8a46bddee0>, 'litho_calipers': <function litho_calipers at 0x7f8a46bde0c0>, 'litho_ruler': <function litho_ruler at 0x7f8a46bde3e0>, 'litho_steps': <function litho_steps at 0x7f8a46bde5c0>, 'resistance_meander': <function resistance_meander at 0x7f8a46bde700>, 'resistance_sheet': <function resistance_sheet at 0x7f8a46bde8e0>, 'verniers': <function verniers at 0x7f8a46bdeac0>, 'text': <function text at 0x7f8a46bdf7e0>, 'text_lines': <function text_lines at 0x7f8a46bdf9c0>, 'text_klayout': <function text_klayout at 0x7f8a46bdfb00>, 'text_freetype': <function text_freetype at 0x7f8a46bdfe20>, 'pixel_array': <function pixel_array at 0x7f8a467280e0>, 'text_rectangular': <function text_rectangular at 0x7f8a46728220>, 'text_rectangular_multi_layer': <function text_rectangular_multi_layer at 0x7f8a46728360>, 'pixel': <function pixel at 0x7f8a46bdede0>, 'qrcode': <function qrcode at 0x7f8a46bdfa60>, 'version_stamp': <function version_stamp at 0x7f8a46728400>, 'disk': <function disk at 0x7f8a467289a0>, 'disk_heater': <function disk_heater at 0x7f8a46728ae0>, 'ring': <function ring at 0x7f8a46728d60>, 'ring_crow': <function ring_crow at 0x7f8a46728f40>, 'ring_crow_couplers': <function ring_crow_couplers at 0x7f8a46729080>, 'ring_double': <function ring_double at 0x7f8a46729260>, 'ring_double_bend_coupler': <function ring_double_bend_coupler at 0x7f8a46729580>, 'ring_double_heater': <function ring_double_heater at 0x7f8a467296c0>, 'ring_double_pn': <function ring_double_pn at 0x7f8a467299e0>, 'ring_single_pn': <function ring_single_pn at 0x7f8a46729b20>, 'ring_single': <function ring_single at 0x7f8a46729d00>, 'ring_single_array': <function ring_single_array at 0x7f8a46729e40>, 'coupler_bend': <function coupler_bend at 0x7f8a46729f80>, 'coupler_ring_bend': <function coupler_ring_bend at 0x7f8a4672a0c0>, 'ring_single_bend_coupler': <function ring_single_bend_coupler at 0x7f8a4672a200>, 'ring_single_dut': <function ring_single_dut at 0x7f8a4672a3e0>, 'delay_snake': <function delay_snake at 0x7f8a4672a660>, 'delay_snake2': <function delay_snake2 at 0x7f8a4672a840>, 'delay_snake_sbend': <function delay_snake_sbend at 0x7f8a4672aac0>, 'spiral': <function spiral at 0x7f8a4672ad40>, 'spiral_double': <function spiral_double at 0x7f8a4672af20>, 'spiral_racetrack': <function spiral_racetrack at 0x7f8a4672b1a0>, 'spiral_racetrack_fixed_length': <function spiral_racetrack_fixed_length at 0x7f8a4672b2e0>, 'spiral_racetrack_heater_metal': <function spiral_racetrack_heater_metal at 0x7f8a4672b4c0>, 'spiral_racetrack_heater_doped': <function spiral_racetrack_heater_doped at 0x7f8a4672b600>, 'spiral_inductor': <function spiral_inductor at 0x7f8a4672b740>, 'hline': <function hline at 0x7f8a4672b9c0>, 'optimal_90deg': <function optimal_90deg at 0x7f8a4672bb00>, 'optimal_hairpin': <function optimal_hairpin at 0x7f8a4672be20>, 'optimal_step': <function optimal_step at 0x7f8a4672bf60>, 'snspd': <function snspd at 0x7f8a46754180>, 'interdigital_capacitor': <function interdigital_capacitor at 0x7f8a46754360>, 'ge_detector_straight_si_contacts': <function ge_detector_straight_si_contacts at 0x7f8a467545e0>, 'edge_coupler_silicon': <function edge_coupler_silicon at 0x7f8a46754860>, 'edge_coupler_array': <function edge_coupler_array at 0x7f8a467549a0>, 'edge_coupler_array_with_loopback': <function edge_coupler_array_with_loopback at 0x7f8a46754ae0>}, virtual_factories={'virtual_bend_circular': <function virtual_bend_circular_factory.<locals>.virtual_bend_circular at 0x7f8a50e75bc0>, 'bend_euler': <function virtual_bend_euler_factory.<locals>.bend_euler at 0x7f8a50e75e40>, 'virtual_straight': <function virtual_straight_factory.<locals>.virtual_straight at 0x7f8a50e760c0>, 'bend_circular_all_angle': <function bend_circular_all_angle at 0x7f8a46cd23e0>, 'bend_euler_all_angle': <function bend_euler_all_angle at 0x7f8a46cd2f20>, 'straight_all_angle': <function straight_all_angle at 0x7f8a46b57740>}, kcells={0: Unnamed_0: ports [], 2 instances, 1: mmi1x2_WNone_WT1_LT10_L_4e0f7121: ports ['o1', 'o2', 'o3'], 0 instances, 2: taper_L10_W0p5_W1_LNone_456c7208: ports ['o1', 'o2'], 0 instances, 3: straight_L5p5_N2_CSxs_5_d3ec67bc: ports ['o1', 'o2'], 0 instances, 4: Unnamed_4: ports [], 6 instances, 5: bend_euler_R10_A90_P0p5_2f1f5c6d: ports ['o1', 'o2'], 0 instances, 6: straight_L29p375_N2_CSs_6ed2bfdd: ports ['o1', 'o2'], 0 instances, 7: straight_L54p5_N2_CSstrip_WNone: ports ['o1', 'o2'], 0 instances}, layers=<aenum 'LAYER'>, infos=LayerInfos(), layer_stack=LayerStack(layers={}), netlist_layer_mapping={}, sparameters_path=None, interconnect_cml_path=None, constants=Constants(), rename_function=<function rename_clockwise_multi at 0x7f8a5c3aef20>, info=Info(), settings=KCellSettings(version='0.23.1', klayout_version='0.29.11', meta_format='v3'), future_cell_name=None, decorators=<kfactory.decorators.Decorators object at 0x7f8a5c3895d0>) function_name='straight' basename=None boundary=None insts=<gdsfactory.component.ComponentReferences object at 0x7f8a2cf43d50> size_info=<kfactory.kcell.SizeInfo object at 0x7f8a2cf43450> dsize_info=<kfactory.kcell.DSizeInfo object at 0x7f8a2cf43490> routes={}], n_bend90=2, n_taper=0, bend90_radius=10000, taper_length=0, length=83875, length_straights=83875, polygons={})
⚠️ Note: You can also get the route length, but keep the following in mind:
The route length is in DBU (Database Units). Usually, 1 DBU = 1 nm.
It only accounts for straight segments, not bends.
For the total length, including bends and straights, you can use Component.info['length']
or Instance.cell.info['length]
print(f"route length = {route.length} DBU, {route.length/1000} um")
route length = 83875 DBU, 83.875 um
route_length = 0
for instance in route.instances:
route_length += instance.info['length']
print(f"total route length = {route_length} um")
total route length = 117.149 um
c = gf.Component()
mmi1 = c << gf.components.mmi1x2()
mmi2 = c << gf.components.mmi1x2()
mmi2.move((100, 50))
route = gf.routing.route_single(
c, port1=mmi1.ports["o2"], port2=mmi2.ports["o1"], layer=(1, 0), route_width=2
)
c
Problem: route_single with obstacles
sometimes there are obstacles that connect strip does not see!
c = gf.Component()
mmi1 = c << gf.components.mmi1x2()
mmi2 = c << gf.components.mmi1x2()
mmi2.move((110, 50))
x = c << gf.components.cross(length=20)
x.move((135, 20))
route = gf.routing.route_single(
c, mmi1.ports["o2"], mmi2.ports["o2"], cross_section="strip"
)
c
Solution: specify the route steps
route_single
allows you to define relative or absolute steps x
or y
for the route as well as with increments dx
or dy
.
c = gf.Component()
w = gf.components.straight()
left = c << w
right = c << w
right.move((100, 80))
obstacle = gf.components.rectangle(size=(100, 10))
obstacle1 = c << obstacle
obstacle2 = c << obstacle
obstacle1.ymin = 40
obstacle2.xmin = 25
port1 = left.ports["o2"]
port2 = right.ports["o2"]
routes = gf.routing.route_single(
c,
port1=port1,
port2=port2,
cross_section="strip",
steps=[
{"x": 20, "y": 0},
{"x": 20, "y": 20},
{"x": 120, "y": 20},
{"x": 120, "y": 80},
],
)
c
c = gf.Component()
w = gf.components.straight()
left = c << w
right = c << w
right.move((100, 80))
obstacle = gf.components.rectangle(size=(100, 10))
obstacle1 = c << obstacle
obstacle2 = c << obstacle
obstacle1.ymin = 40
obstacle2.xmin = 25
port1 = left.ports["o2"]
port2 = right.ports["o2"]
routes = gf.routing.route_single(
c,
port1=port1,
port2=port2,
cross_section="strip",
steps=[
{"x": 20},
{"y": 20},
{"x": 120},
{"y": 80},
],
)
c
route_bundle#
To route groups of ports avoiding waveguide collisions, you should use route_bundle
instead of route_single
.
route_bundle
uses a river/bundle/bus router.
At the moment it works only when each group of ports have the same orientation.
ys_right = [0, 10, 20, 40, 50, 80]
pitch = 127.0
N = len(ys_right)
ys_left = [(i - N / 2) * pitch for i in range(N)]
layer = (1, 0)
right_ports = [
gf.Port(f"R_{i}", center=(0, ys_right[i]), width=0.5, orientation=180, layer=layer)
for i in range(N)
]
left_ports = [
gf.Port(f"L_{i}", center=(-200, ys_left[i]), width=0.5, orientation=0, layer=layer)
for i in range(N)
]
# you can also mess up the port order and it will sort them by default
left_ports.reverse()
c = gf.Component()
routes = gf.routing.route_bundle(
c,
left_ports,
right_ports,
start_straight_length=50,
sort_ports=True,
cross_section="strip",
)
c.add_ports(left_ports)
c.add_ports(right_ports)
c
xs_top = [0, 10, 20, 40, 50, 80]
pitch = 127.0
N = len(xs_top)
xs_bottom = [(i - N / 2) * pitch for i in range(N)]
layer = (1, 0)
top_ports = [
gf.Port(f"top_{i}", center=(xs_top[i], 0), width=0.5, orientation=270, layer=layer)
for i in range(N)
]
bot_ports = [
gf.Port(
f"bot_{i}",
center=(xs_bottom[i], -300),
width=0.5,
orientation=90,
layer=layer,
)
for i in range(N)
]
c = gf.Component()
routes = gf.routing.route_bundle(
c,
top_ports,
bot_ports,
separation=5.0,
end_straight_length=100,
cross_section="strip",
)
c
route_bundle
can also route bundles through corners
@gf.cell(cache={})
def test_connect_corner(N=6, config="A"):
d = 10.0
sep = 5.0
c = gf.Component()
layer = (1, 0)
if config in ["A", "B"]:
a = 100.0
ports_A_TR = [
Port(
f"A_TR_{i}",
center=(d, a / 2 + i * sep),
width=0.5,
orientation=0,
layer=layer,
)
for i in range(N)
]
ports_A_TL = [
Port(
f"A_TL_{i}",
center=(-d, a / 2 + i * sep),
width=0.5,
orientation=180,
layer=layer,
)
for i in range(N)
]
ports_A_BR = [
Port(
f"A_BR_{i}",
center=(d, -a / 2 - i * sep),
width=0.5,
orientation=0,
layer=layer,
)
for i in range(N)
]
ports_A_BL = [
Port(
f"A_BL_{i}",
center=(-d, -a / 2 - i * sep),
width=0.5,
orientation=180,
layer=layer,
)
for i in range(N)
]
ports_A = [ports_A_TR, ports_A_TL, ports_A_BR, ports_A_BL]
ports_B_TR = [
Port(
f"B_TR_{i}",
center=(a / 2 + i * sep, d),
width=0.5,
orientation=90,
layer=layer,
)
for i in range(N)
]
ports_B_TL = [
Port(
f"B_TL_{i}",
center=(-a / 2 - i * sep, d),
width=0.5,
orientation=90,
layer=layer,
)
for i in range(N)
]
ports_B_BR = [
Port(
f"B_BR_{i}",
center=(a / 2 + i * sep, -d),
width=0.5,
orientation=270,
layer=layer,
)
for i in range(N)
]
ports_B_BL = [
Port(
f"B_BL_{i}",
center=(-a / 2 - i * sep, -d),
width=0.5,
orientation=270,
layer=layer,
)
for i in range(N)
]
ports_B = [ports_B_TR, ports_B_TL, ports_B_BR, ports_B_BL]
elif config in ["C", "D"]:
a = N * sep + 2 * d
ports_A_TR = [
Port(
f"A_TR_{i}",
center=(a, d + i * sep),
width=0.5,
orientation=0,
layer=layer,
)
for i in range(N)
]
ports_A_TL = [
Port(
f"A_TL_{i}",
center=(-a, d + i * sep),
width=0.5,
orientation=180,
layer=layer,
)
for i in range(N)
]
ports_A_BR = [
Port(
f"A_BR_{i}",
center=(a, -d - i * sep),
width=0.5,
orientation=0,
layer=layer,
)
for i in range(N)
]
ports_A_BL = [
Port(
f"A_BL_{i}",
center=(-a, -d - i * sep),
width=0.5,
orientation=180,
layer=layer,
)
for i in range(N)
]
ports_A = [ports_A_TR, ports_A_TL, ports_A_BR, ports_A_BL]
ports_B_TR = [
Port(
f"B_TR_{i}",
center=(d + i * sep, a),
width=0.5,
orientation=90,
layer=layer,
)
for i in range(N)
]
ports_B_TL = [
Port(
f"B_TL_{i}",
center=(-d - i * sep, a),
width=0.5,
orientation=90,
layer=layer,
)
for i in range(N)
]
ports_B_BR = [
Port(
f"B_BR_{i}",
center=(d + i * sep, -a),
width=0.5,
orientation=270,
layer=layer,
)
for i in range(N)
]
ports_B_BL = [
Port(
f"B_BL_{i}",
center=(-d - i * sep, -a),
width=0.5,
orientation=270,
layer=layer,
)
for i in range(N)
]
ports_B = [ports_B_TR, ports_B_TL, ports_B_BR, ports_B_BL]
if config in ["A", "C"]:
for ports1, ports2 in zip(ports_A, ports_B):
gf.routing.route_bundle(
c, ports1, ports2, radius=5, sort_ports=True, cross_section="strip"
)
elif config in ["B", "D"]:
for ports1, ports2 in zip(ports_A, ports_B):
gf.routing.route_bundle(
c, ports2, ports1, radius=5, sort_ports=True, cross_section="strip"
)
return c
c = test_connect_corner(config="A")
c
c = test_connect_corner(config="C")
c
@gf.cell(cache={})
def test_connect_bundle_udirect(dy=200, orientation=270, layer=(1, 0)):
xs1 = [-100, -90, -80, -55, -35, 24, 0] + [200, 210, 240]
axis = "X" if orientation in [0, 180] else "Y"
pitch = 10.0
N = len(xs1)
xs2 = [70 + i * pitch for i in range(N)]
if axis == "X":
ports1 = [
Port(
f"top_{i}",
center=(0, xs1[i]),
width=0.5,
orientation=orientation,
layer=layer,
)
for i in range(N)
]
ports2 = [
Port(
f"bottom_{i}",
center=(dy, xs2[i]),
width=0.5,
orientation=orientation,
layer=layer,
)
for i in range(N)
]
else:
ports1 = [
Port(
f"top_{i}",
center=(xs1[i], 0),
width=0.5,
orientation=orientation,
layer=layer,
)
for i in range(N)
]
ports2 = [
Port(
f"bottom_{i}",
center=(xs2[i], dy),
width=0.5,
orientation=orientation,
layer=layer,
)
for i in range(N)
]
c = Component()
gf.routing.route_bundle(
c, ports1, ports2, radius=10.0, sort_ports=True, cross_section="strip"
)
return c
c = test_connect_bundle_udirect()
c
@gf.cell
def test_connect_bundle_u_indirect(dy=-200, orientation=180, layer=(1, 0)):
xs1 = [-100, -90, -80, -55, -35] + [200, 210, 240]
axis = "X" if orientation in [0, 180] else "Y"
pitch = 10.0
N = len(xs1)
xs2 = [50 + i * pitch for i in range(N)]
a1 = orientation
a2 = a1 + 180
if axis == "X":
ports1 = [
Port(f"top_{i}", center=(0, xs1[i]), width=0.5, orientation=a1, layer=layer)
for i in range(N)
]
ports2 = [
Port(
f"bot_{i}",
center=(dy, xs2[i]),
width=0.5,
orientation=a2,
layer=layer,
)
for i in range(N)
]
else:
ports1 = [
Port(f"top_{i}", center=(xs1[i], 0), width=0.5, orientation=a1, layer=layer)
for i in range(N)
]
ports2 = [
Port(
f"bot_{i}",
center=(xs2[i], dy),
width=0.5,
orientation=a2,
layer=layer,
)
for i in range(N)
]
c = Component()
gf.routing.route_bundle(
c,
ports1,
ports2,
bend=gf.components.bend_euler,
radius=5,
cross_section="strip",
)
return c
c = test_connect_bundle_u_indirect(orientation=0)
c
@gf.cell
def test_north_to_south(layer=(1, 0)):
dy = 200.0
xs1 = [-500, -300, -100, -90, -80, -55, -35, 200, 210, 240, 500, 650]
pitch = 10.0
N = len(xs1)
xs2 = [-20 + i * pitch for i in range(N // 2)]
xs2 += [400 + i * pitch for i in range(N // 2)]
a1 = 90
a2 = a1 + 180
ports1 = [
gf.Port(f"top_{i}", center=(xs1[i], 0), width=0.5, orientation=a1, layer=layer)
for i in range(N)
]
ports2 = [
gf.Port(f"bot_{i}", center=(xs2[i], dy), width=0.5, orientation=a2, layer=layer)
for i in range(N)
]
c = gf.Component()
gf.routing.route_bundle(c, ports1, ports2, cross_section="strip")
return c
c = test_north_to_south()
c
@gf.cell
def demo_connect_bundle():
"""Combines all the connect_bundle tests."""
y = 400.0
x = 500
y0 = 900
dy = 200.0
c = gf.Component()
for j, s in enumerate([-1, 1]):
for i, orientation in enumerate([0, 90, 180, 270]):
ref = c << test_connect_bundle_u_indirect(
dy=s * dy, orientation=orientation
)
ref.dcenter = (i * x, j * y)
ref = c << test_connect_bundle_udirect(dy=s * dy, orientation=orientation)
ref.dcenter = (i * x, j * y + y0)
for i, config in enumerate(["A", "B", "C", "D"]):
ref = c << test_connect_corner(config=config)
ref.dcenter = (i * x, 1700)
return c
c = demo_connect_bundle()
c.show()
c
import gdsfactory as gf
c = gf.Component()
c1 = c << gf.components.mmi2x2()
c2 = c << gf.components.mmi2x2()
c2.move((100, 50))
routes = gf.routing.route_bundle(
c,
[c1.ports["o4"], c1.ports["o3"]],
[c2.ports["o1"], c2.ports["o2"]],
radius=5,
cross_section="strip",
)
c
c = gf.Component()
c1 = c << gf.components.pad()
c2 = c << gf.components.pad()
c2.move((200, 100))
routes = gf.routing.route_bundle_electrical(
c,
[c1.ports["e3"]],
[c2.ports["e1"]],
cross_section=gf.cross_section.metal3,
)
c
Problem
Sometimes 90 degrees routes do not have enough space for a Manhattan route
c = gf.Component()
c1 = c << gf.components.nxn(east=3, ysize=20)
c2 = c << gf.components.nxn(west=3)
c2.move((80, 0))
c
c = gf.Component()
c1 = c << gf.components.nxn(east=3, ysize=20)
c2 = c << gf.components.nxn(west=3)
c2.move((80, 0))
routes = gf.routing.route_bundle(
c,
list(c1.ports.filter(orientation=0)),
list(c2.ports.filter(orientation=180)),
on_collision=None,
cross_section="strip",
)
c
c = gf.Component()
pitch = 2.0
ys_left = [0, 10, 20]
N = len(ys_left)
ys_right = [(i - N / 2) * pitch for i in range(N)]
layer = (1, 0)
right_ports = [
gf.Port(f"R_{i}", center=(0, ys_right[i]), width=0.5, orientation=180, layer=layer)
for i in range(N)
]
left_ports = [
gf.Port(f"L_{i}", center=(-50, ys_left[i]), width=0.5, orientation=0, layer=layer)
for i in range(N)
]
left_ports.reverse()
routes = gf.routing.route_bundle(
c, right_ports, left_ports, radius=5, on_collision=None, cross_section="strip"
)
c
Solution
Add Sbend routes using route_bundle_sbend
c = gf.Component()
c1 = c << gf.components.nxn(east=3, ysize=20)
c2 = c << gf.components.nxn(west=3)
c2.move((80, 0))
routes = gf.routing.route_bundle_sbend(
c,
c1.ports.filter(orientation=0),
c2.ports.filter(orientation=180),
enforce_port_ordering=False,
)
c
import gdsfactory as gf
from gdsfactory.samples.big_device import big_device
c = gf.Component()
c1 = big_device()
c2 = gf.routing.add_fiber_array(c1)
c2.plot()
c = gf.Component()
w = gf.components.straight()
left = c << w
right = c << w
right.move((100, 80))
obstacle = gf.components.rectangle(size=(100, 10))
obstacle1 = c << obstacle
obstacle2 = c << obstacle
obstacle1.ymin = 40
obstacle2.xmin = 25
port1 = left.ports["o2"]
port2 = right.ports["o2"]
routes = gf.routing.route_bundle(
c,
[port1],
[port2],
cross_section="strip",
steps=[
{"dy": 30, "dx": 50},
{"dx": 100},
],
)
c
c = gf.Component()
w = gf.components.array(gf.c.straight, columns=1, rows=3, row_pitch=3)
left = c << w
right = c << w
right.move((100, 100))
obstacle = gf.components.rectangle(size=(100, 10))
obstacle1 = c << obstacle
obstacle2 = c << obstacle
obstacle1.ymin = 40
obstacle2.xmin = 35
ports1 = left.ports.filter(orientation=0)
ports2 = right.ports.filter(orientation=180)
routes = gf.routing.route_bundle(
c,
ports1,
ports2,
cross_section="strip",
sort_ports=True,
steps=[
{"dy": 30, "dx": 50},
{"dx": 90},
],
)
c
route_astar#
You can navigate around bounding boxes when routing if you pass the bboxes of all the objects that you want to avoid.
Currently the router only respects any (merged) bounding boxes which overlap with start or end port bundles
import gdsfactory as gf
c = gf.Component()
cross_section = "strip"
port_prefix = "o"
bend = gf.components.bend_euler
cross_section = gf.get_cross_section(cross_section, radius=5)
w = gf.components.straight(cross_section=cross_section)
left = c << w
right = c << w
right.rotate(90)
right.move((168, 63))
obstacle = gf.components.rectangle(size=(250, 3), layer="M2")
obstacle1 = c << obstacle
obstacle2 = c << obstacle
obstacle3 = c << obstacle
obstacle4 = c << obstacle
obstacle4.rotate(90)
obstacle1.ymin = 50
obstacle1.xmin = -10
obstacle2.xmin = 35
obstacle3.ymin = 42
obstacle3.xmin = 72.23
obstacle4.xmin = 200
obstacle4.ymin = 55
port1 = left.ports[f"{port_prefix}1"]
port2 = right.ports[f"{port_prefix}2"]
route = gf.routing.route_astar(
component=c,
port1=port1,
port2=port2,
cross_section=cross_section,
resolution=15,
distance=12,
avoid_layers=("M2",),
bend=bend,
)
c
route_bundle with collisions#
The route bundle with collision avoidance is not yet supported.
import gdsfactory as gf
c = gf.Component()
columns = 2
ptop = c << gf.components.pad_array(columns=columns, port_orientation=270)
pbot = c << gf.components.pad_array(port_orientation=270, columns=columns)
ptop.movex(300)
ptop.movey(300)
obstacle = c << gf.c.rectangle(size=(300, 100), layer="M3")
obstacle.ymin = pbot.ymax - 10
obstacle.xmin = pbot.xmax - 10
routes = gf.routing.route_bundle_electrical(
c,
pbot.ports,
ptop.ports,
start_straight_length=100,
separation=20,
cross_section="metal_routing",
bboxes=[
obstacle.bbox(),
pbot.bbox(),
ptop.bbox(),
], # obstacles to avoid
sort_ports=True,
)
c
import gdsfactory as gf
c = gf.Component()
columns = 2
ptop = c << gf.components.pad_array(columns=columns, port_orientation=270)
pbot = c << gf.components.pad_array(port_orientation=270, columns=columns)
ptop.movex(300)
ptop.movey(300)
obstacle = c << gf.c.rectangle(size=(300, 100), layer="M3", centered=True)
obstacle.ymin = pbot.ymax - 10
obstacle.xmin = pbot.xmax + 10
c2 = gf.Component() # create a dummy component to get the size of the obstacle
obstacle_sized = c2 << gf.c.rectangle(size=(340, 140), layer="M3", centered=True)
obstacle_sized.dcenter = obstacle.dcenter
routes = gf.routing.route_bundle_electrical(
c,
pbot.ports,
ptop.ports,
start_straight_length=100,
separation=20,
cross_section="metal_routing",
bboxes=[
obstacle_sized.bbox(),
pbot.bbox(),
ptop.bbox(),
], # obstacles to avoid not working yet
sort_ports=True,
)
c
route_bundle_all_angle#
You can also route using diagonal routes.
import gdsfactory as gf
c = gf.Component()
rows = 3
straight = gf.c.straight
w1 = c << gf.c.array(straight, rows=rows, columns=1, row_pitch=10)
w2 = c << gf.c.array(straight, rows=rows, columns=1, row_pitch=10)
w2.drotate(-30)
w2.movex(140)
p1 = list(w1.ports.filter(orientation=0))
p2 = list(w2.ports.filter(orientation=150))
p1.reverse()
p2.reverse()
gf.routing.route_bundle_all_angle(
c,
p1,
p2,
separation=3,
)
c
You can also use it to connect rotated components that do not have a manhattan orientation (0, 90, 180, 270)
c = gf.Component()
mmi = gf.components.mmi2x2(width_mmi=10, gap_mmi=3)
mmi1 = c.create_vinst(mmi) # create a virtual instance
mmi2 = c.create_vinst(mmi) # create a virtual instance
mmi2.move((100, 10))
mmi2.drotate(30)
routes = gf.routing.route_bundle_all_angle(
c,
mmi1.ports.filter(orientation=0),
[mmi2.ports["o2"], mmi2.ports["o1"]],
)
c.show()
c
Dubin paths#
If you’re working with PIC layouts and looking for a straightforward way to optimize waveguide paths, Dubins paths offer an effective solution by ensuring the shortest path with minimal bending and loss.
Using Dubins paths for waveguide routing can simplify your design process significantly. Compared to traditional interconnects, Dubins paths offer shorter, more reliable routes that avoid unnecessary bending and intersections. For PIC layouts, this translates into denser, cleaner designs with improved performance.
c = gf.Component()
# Create two straight waveguides with different orientations
wg1 = c << gf.components.straight(length=100, width=3.2)
wg2 = c << gf.components.straight(length=100, width=3.2)
# Move and rotate the second waveguide
wg2.move((300, 50))
wg2.rotate(45)
# Route between the output of wg1 and input of wg2
route = gf.routing.route_dubin(
c,
port1=wg1.ports["o2"],
port2=wg2.ports["o1"],
cross_section=gf.cross_section.strip(width=3.2, radius=100),
)
c
c = gf.Component()
# Create two multi-port components
comp1 = c << gf.components.nxn(west=0, east=10, xsize=10, ysize=100, wg_width=3.2)
comp2 = c << gf.components.nxn(west=0, east=10, xsize=10, ysize=100, wg_width=3.2)
# Position second component
comp2.drotate(30)
comp2.move((500, -100))
# Route between corresponding ports
for i in range(10):
port1_name = f"o{10-i}" # Inverted port id for port1
port2_name = f"o{i+1}" # Adjusted to match available ports
gf.routing.route_dubin(
c,
port1=comp1.ports[port1_name],
port2=comp2.ports[port2_name],
cross_section=gf.cross_section.strip(width=3.2, radius=100 + i * 10),
)
c
auto_taper#
Both route_single
and route_bundle
have a auto_taper
parameter.
For auto_taper to work you need to define how to transition different between different layers and widths.
layer_transitions = {
LAYER.WG: partial(gf.c.taper, cross_section="strip", length=10),
(LAYER.WG, LAYER.WGN): "taper_sc_nc",
(LAYER.WGN, LAYER.WG): "taper_nc_sc",
LAYER.M3: "taper_electrical",
}
return Pdk(
name="generic",
cells=cells,
cross_sections=cross_sections,
layers=LAYER,
layer_stack=LAYER_STACK,
layer_views=LAYER_VIEWS,
layer_transitions=layer_transitions,
materials_index=materials_index,
constants=constants,
connectivity=LAYER_CONNECTIVITY,
)
For example, in the code below if you have a width mismatch between two ports, the router will automatically add a taper to transition between the two widths, only if auto_taper=True
, otherwise it will raise an error.
c = gf.Component()
s1 = c << gf.components.straight()
s2 = c << gf.components.straight(width=2)
s2.move((40, 50))
route = gf.routing.route_single(
c,
port1=s1.ports["o2"],
port2=s2.ports["o1"],
cross_section="strip",
auto_taper=True,
)
c
import gdsfactory as gf
from gdsfactory.routing.auto_taper import auto_taper_to_cross_section
@gf.cell
def silicon_nitride_strip(width_nitride: float = 1) -> gf.Component:
c = gf.Component()
ref = c << gf.c.straight(
cross_section=gf.cross_section.nitride, width=width_nitride
)
port1 = auto_taper_to_cross_section(
c, port=ref["o1"], cross_section=gf.cross_section.strip
)
c.add_port(name="o1", port=port1)
c.add_port(name="o2", port=ref["o2"])
return c
c = silicon_nitride_strip(width_nitride=1)
c
c = silicon_nitride_strip(width_nitride=4)
c