route_auto

photonforge.parametric.route_auto(*, port1=None, port2=None, radius=None, obstacles=None, include_port_references_as_obstacles=None, collision_layers=None, collision_offset=None, straight_kwargs=None, s_bend_kwargs=None, bend90=None, bend45=None, cross=None, propagation_cost=None, bend90_cost=None, bend45_cost=None, cross_cost=None, cross_space_cost=None, congestion_cost=None, congestion_radius=None, allow_diagonals=None, allow_s_bend=None, collapse_s_bends=None, max_crossings=None, grid_size=None, search_margin=None, net_reorder=None, allow_partial=None, max_iterations=None, max_reroute_rounds=None, reroute_history_cost=None, show_progress=None, diagnostics=None, technology=None, name=None, route_model=None, bundle_model=None)[source]

Automatic optical routing between reference ports.

The automatic router performs grid-based multi-net routing. Ports must be specified as reference-port tuples so device-aware access preprocessing can use the surrounding component geometry.

Parameters:
  • port1 (tuple[Reference, str] | tuple[Reference, str, int] | Sequence[tuple[Reference, str] | tuple[Reference, str, int]] | None) – First port for single-net routing. The port must be specified as a tuple including a photonforge.Reference, the port name, and the repetition index (optional, only for array references). For bundle routing, a sequence of ports can be used.

  • port2 (tuple[Reference, str] | tuple[Reference, str, int] | Sequence[tuple[Reference, str] | tuple[Reference, str, int]] | None) – Second port for single-net routing, or sequence of ports for bundle routing (with the same length as port1).

  • radius (Annotated[float, exclusiveMinimum=0, units='μm'] | None) – Radius used to generate S-bend sections.

  • obstacles (Sequence[Rectangle | Circle | Polygon | Path | Component | Reference] | Component | Reference | None) – Additional routing obstacles. Use a sequence of 2D structures, or a Component or Reference.

  • include_port_references_as_obstacles (bool | None) – If True, add the references used by routed ports to obstacles. If None, defaults to True.

  • collision_layers (Sequence[Annotated[str | tuple[int, int], _]] | None) – Layers used for route-section collision stamps and for collecting obstacle polygons from a component or reference.

  • collision_offset (Annotated[float, minimum=0, units='μm'] | None) – Offset applied to route collision layers.

  • straight_kwargs (Annotated[dict[str, Any], _] | None) – Keyword arguments for straight().

  • s_bend_kwargs (Annotated[dict[str, Any], _] | None) – Keyword arguments for s_bend().

  • bend90 (Component | None) – 90° bend to be used for routing.

  • bend45 (Component | None) – Optional 45° bend to be used for routing.

  • cross (Component | None) – Optional crossing to be used for routing.

  • propagation_cost (Annotated[float, minimum=0, units='dB/μm'] | None) – Straight section cost (per μm). Defaults to 1e-5.

  • bend90_cost (Annotated[float, minimum=0, units='dB'] | None) – Cost of a 90° bend. Defaults to 2.1 * radius * propagation_cost (5% penalty on the Manhattan distance).

  • bend45_cost (Annotated[float, minimum=0, units='dB'] | None) – Cost of a 45° bend. Defaults to 0.51 * bend90_cost.

  • cross_cost (Annotated[float, minimum=0, units='dB'] | None) – Cost of a crossing. Defaults to twice the propagation_cost applied to the crossing length.

  • cross_space_cost (Annotated[float, minimum=0, units='dB/μm'] | None) – Cost multiplier for nearby crossing spacing. Defaults to propagation_cost.

  • congestion_cost (Annotated[float, minimum=0, units='dB/μm'] | None) – Cost multiplier for nearby routed occupancy. Defaults to propagation_cost.

  • congestion_radius (Annotated[int, minimum=0] | None) – Congestion search radius in grid cells. Defaults to 1.

  • allow_diagonals (bool | None) – Controls whether 45° bends are allowed. If None, defaults to True when bend45 is provided, and False otherwise.

  • allow_s_bend (bool | None) – Controls whether the router may use S bends to reach an aligned goal directly. Port access for grid alignment use S bends regardless of this flag. If None, defaults to False.

  • collapse_s_bends (bool | None) – Controls post-routing removal of unnecessary access S bends. If None, defaults to True.

  • max_crossings (int | None) – Maximum crossings per net. Use a negative value for no explicit limit. Defaults to -1.

  • grid_size (Annotated[float, exclusiveMinimum=0, units='μm'] | None) – Router grid size. grid_size + collision_offset should be the center-to-center distance between parallel waveguides. If None, defaults to the routed port spec width.

  • search_margin (Annotated[float, minimum=0, units='μm'] | None) – Extra search margin around the routing bounds. If None, uses an automatic margin based on endpoint separation and bend size.

  • net_reorder (bool | None) – Allow net reordering before routing. If None, defaults to True.

  • allow_partial (bool | None) – If False, raise when any net fails. If None, defaults to False.

  • max_iterations (int | None) – Maximum search iterations per route. If None, defaults to 500000.

  • max_reroute_rounds (Annotated[int, minimum=0] | None) – Maximum route conflict-recovery rounds. If None, defaults to the number of nets clipped to [3; 16].

  • reroute_history_cost (Annotated[float, minimum=0] | None) – History cost scale used in bundle rerouting. If None, defaults to 5.

  • show_progress (bool | None) – If True, show routing progress for long-running routes. If None, defaults to True.

  • diagnostics (bool | None) – If True, JSON-encoded diagnostic information from the routing algorithm is stored in component.properties.route_auto. If None, defaults to False.

  • technology (Technology | None) – Component technology. If None, the default technology is used.

  • name (str | None) – Component name.

  • route_model (Model | None) – Model to be used with each route sub-component. If None a photonforge.CircuitModel is used.

  • bundle_model (Model | None) – Model to be used with the top-level route component. If None a photonforge.CircuitModel is used.

Return type:

Component

Note

The costs of S bends are based on the computed length multiplied by the propagation cost.

Returns:

Component with emitted route geometry.

Parameters:
  • port1 (tuple[Reference, str] | tuple[Reference, str, int] | Sequence[tuple[Reference, str] | tuple[Reference, str, int]] | None)

  • port2 (tuple[Reference, str] | tuple[Reference, str, int] | Sequence[tuple[Reference, str] | tuple[Reference, str, int]] | None)

  • radius (Annotated[float, exclusiveMinimum=0, units='μm'] | None)

  • obstacles (Sequence[Rectangle | Circle | Polygon | Path | Component | Reference] | Component | Reference | None)

  • include_port_references_as_obstacles (bool | None)

  • collision_layers (Sequence[Annotated[str | tuple[int, int], _]] | None)

  • collision_offset (Annotated[float, minimum=0, units='μm'] | None)

  • straight_kwargs (Annotated[dict[str, Any], _] | None)

  • s_bend_kwargs (Annotated[dict[str, Any], _] | None)

  • bend90 (Component | None)

  • bend45 (Component | None)

  • cross (Component | None)

  • propagation_cost (Annotated[float, minimum=0, units='dB/μm'] | None)

  • bend90_cost (Annotated[float, minimum=0, units='dB'] | None)

  • bend45_cost (Annotated[float, minimum=0, units='dB'] | None)

  • cross_cost (Annotated[float, minimum=0, units='dB'] | None)

  • cross_space_cost (Annotated[float, minimum=0, units='dB/μm'] | None)

  • congestion_cost (Annotated[float, minimum=0, units='dB/μm'] | None)

  • congestion_radius (Annotated[int, minimum=0] | None)

  • allow_diagonals (bool | None)

  • allow_s_bend (bool | None)

  • collapse_s_bends (bool | None)

  • max_crossings (int | None)

  • grid_size (Annotated[float, exclusiveMinimum=0, units='μm'] | None)

  • search_margin (Annotated[float, minimum=0, units='μm'] | None)

  • net_reorder (bool | None)

  • allow_partial (bool | None)

  • max_iterations (int | None)

  • max_reroute_rounds (Annotated[int, minimum=0] | None)

  • reroute_history_cost (Annotated[float, minimum=0] | None)

  • show_progress (bool | None)

  • diagnostics (bool | None)

  • technology (Technology | None)

  • name (str | None)

  • route_model (Model | None)

  • bundle_model (Model | None)

Return type:

Component

component1 = pf.Component("1")
component1.add("WG_CORE", pf.Rectangle(size=(8, 12)))
component1.add_port(
    [
        pf.Port((4, 0), 180, "Strip"),
        pf.Port((4, 4), 180, "Strip"),
        pf.Port((4, -4), 180, "Strip"),
    ]
)

component2 = pf.Component("2")
component2.add("WG_CORE", pf.Rectangle(size=(12, 4)))
component2.add_port(
    [
        pf.Port((-4, -2), 90, "Strip"),
        pf.Port((4, 2), -90, "Strip"),
        pf.Port((4, -2), 90, "Strip"),
    ]
)

# Example of bundle routing with collision avoidance
routed = pf.Component("ROUTED")
routed.add("METAL", pf.Rectangle((0, -40), (15, 10)))

ref0 = routed.add_reference(component1).translate((-50, -10))
ref1 = routed.add_reference(component2).translate((50, 10))

route = pf.parametric.route_auto(
    port1=[(ref0, "P0"), (ref0, "P1"), (ref0, "P2")],
    port2=[(ref1, "P0"), (ref1, "P1"), (ref1, "P2")],
    obstacles=routed,
    collision_layers=["METAL", "WG_CORE"],
    radius=10,
)
routed.add(route)

# Example using a crossing component
routed_x = pf.Component("ROUTED_CROSSING")
routed_x.add("METAL", pf.Rectangle((0, -40), (15, 10)))

ref0 = routed_x.add_reference(component1).translate((-50, -10))
ref1 = routed_x.add_reference(component2).translate((50, 10))
crossing = pf.parametric.crossing(port_spec="Strip", arm_length=2, added_width=0.5)

route_with_crossing = pf.parametric.route_auto(
    port1=[(ref0, "P0"), (ref0, "P1"), (ref0, "P2")],
    port2=[(ref1, "P0"), (ref1, "P2"), (ref1, "P1")],
    cross=crossing,
    obstacles=routed_x,
    collision_layers=["METAL", "WG_CORE"],
    radius=10,
)
routed_x.add(route_with_crossing)
route_auto