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
ComponentorReference.include_port_references_as_obstacles (bool | None) – If
True, add the references used by routed ports toobstacles. IfNone, defaults toTrue.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_costapplied 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 toTruewhenbend45is provided, andFalseotherwise.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 toFalse.collapse_s_bends (bool | None) – Controls post-routing removal of unnecessary access S bends. If
None, defaults toTrue.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_offsetshould be the center-to-center distance between parallel waveguides. IfNone, 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 toTrue.allow_partial (bool | None) – If
False, raise when any net fails. IfNone, defaults toFalse.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. IfNone, defaults toTrue.diagnostics (bool | None) – If
True, JSON-encoded diagnostic information from the routing algorithm is stored incomponent.properties.route_auto. IfNone, defaults toFalse.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
Noneaphotonforge.CircuitModelis used.bundle_model (Model | None) – Model to be used with the top-level route component. If
Noneaphotonforge.CircuitModelis used.
- Return type:
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:
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)