Routing Functions
High-level functions for routing waveguide bundles between ports.
These wrap the Router class with a one-call interface.
route_bundle
route_bundle(
start_ports,
end_ports,
*,
min_radius: float | None = None,
obstacles: list | None = None,
obstacle_layers: Any = None,
collision_check_layers: Any = None,
obstacle_margin: float | None = None,
cross_section: Any = None,
context_component: Any = None,
finetune: FinetuneConfig | bool | None = None,
fallback_to_iterative: bool = False,
iterative_bundle_routing: bool = False,
negotiated_bundle_routing: bool = False,
backbone_bundle_routing: bool = False,
route_spacing: float = 3.0,
route_width: float | None = None,
sort_ports: bool = False,
polylines: Any = None,
waypoints: Any = None,
scheduler: Any = None,
max_steps: int = 2000,
tol: float = 0.0001,
patience: int | None = None,
pbar: bool = True,
**router_kwargs: Any,
) -> Router
Route a bundle of waveguides between port pairs.
Ports are gf.Port objects with center, orientation,
layer, and width attributes. Accepts a single Port or a
list; nested lists [[p1], [p2, p3]] create independent routing
groups.
By default, uses manhattan routing only (fast, no optimization).
Pass finetune=FinetuneConfig(...) to run gradient-based
optimization afterwards.
When cross_section is provided, routing parameters are derived from it automatically (explicit kwargs override with a warning):
min_radius←xs.radius_mintarget_radius←xs.radiusroute_width←xs.widthroute_collision_width←xs.widthroute_collision_margin← PDK separation (default 3.0)obstacle_margin← PDK separation (default 3.0)
Without cross_section, the defaults are: min_radius=5.0,
obstacle_margin=3.0, route_width=2.0, route_collision_width=2.0,
route_collision_margin=3.0.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
start_ports
|
Start port(s) — |
required | |
end_ports
|
End port(s) — |
required | |
min_radius
|
float | None
|
Minimum bend radius (um). Derived from
|
None
|
obstacles
|
list | None
|
Keep-out zones. Any objects with |
None
|
obstacle_layers
|
Any
|
Layer spec or list of layer specs to extract from
|
None
|
collision_check_layers
|
Any
|
Alias for |
None
|
obstacle_margin
|
float | None
|
Clearance from obstacles (um). Derived from PDK separation when cross_section is given. |
None
|
cross_section
|
Any
|
|
None
|
context_component
|
Any
|
Component to merge with when using
|
None
|
finetune
|
FinetuneConfig | bool | None
|
|
None
|
fallback_to_iterative
|
bool
|
If True, validate shared-backbone bundle initialization and retry with iterative bundle routing when it collides. |
False
|
iterative_bundle_routing
|
bool
|
If True, use iterative bundle routing directly instead of shared-backbone bundle initialization. |
False
|
backbone_bundle_routing
|
bool
|
If True, force raw shared-backbone bundle initialization with NO fallback ladder. For debugging/isolating the backbone method — it may produce crossing routes on non-offsettable bundles (the no-flag default escalates past such failures instead). |
False
|
route_spacing
|
float
|
Center-to-center spacing used by the Manhattan bundle initializer when routing around prior routes. |
3.0
|
route_width
|
float | None
|
Physical route width used by the Manhattan initializer
when converting already-routed skeletons to temporary keepouts.
Derived from |
None
|
polylines
|
Any
|
Complete routes to use instead of running the initializer —
one Supplied straights and L-routes are held fixed by finetune, since
they own no tunable rail and playdough will not invent a detour you
did not draw. If you handed in a sketch and want it reshaped, pass
This is only the input half of a cache: nothing is stored or
invalidated for you. Stale geometry is caught at the ports — an
endpoint that no longer reaches its port, or a terminal segment no
longer leaving along the port axis, raises |
None
|
waypoints
|
Any
|
Incomplete positional hints the manhattan initializer routes
through — the middle of the family. The nesting mirrors A hint costs no extra bend when the route can run straight through it: the initializer tries a pass-through first and only turns at the point when that does not work. So hinting somewhere a route already goes leaves it unchanged. A hint shared by several routes belongs to the bundle: the representative route is routed through it and the others are derived as parallel offsets, so the group cannot cross itself. Use per-route hints when a specific route must hit a specific point. Hints are honoured exactly by the initializer. |
None
|
sort_ports
|
bool
|
If True, reorder each port list using the same
KFactory/gdsfactory bundle sorting convention used by
|
False
|
**router_kwargs
|
Any
|
Forwarded to
|
{}
|
Returns:
| Type | Description |
|---|---|
Router
|
A |
Router
|
|
Router
|
|
Router
|
|
Signature examples::
pld.route_bundle(start_ports, end_ports)
pld.route_bundle(start_ports, end_ports, cross_section="strip")
pld.route_bundle(start_ports, end_ports, obstacles=[obs], finetune=pld.FinetuneConfig(lr=1.0))
route_polylines
Route a bundle and return polyline coordinates as numpy arrays.
Lightweight alternative to route_bundle() — returns polyline
coordinates directly without building GDS components. Accepts all
the same keyword arguments as route_bundle() (obstacles,
cross_section, finetune, min_radius, etc.).
Passing polylines= round-trips: the returned list can be handed
straight back on a later call to redraw the same routes without
re-running the router. Note the returned coordinates are snapped and
collinear-reduced, so they can differ from the first call's internal
pivots by a few database units; from the second call on it is a fixed
point.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
start_ports
|
Start port(s) — |
required | |
end_ports
|
End port(s) — |
required | |
smooth
|
bool
|
If True, return dense smooth paths through euler/arc
bends instead of raw corner-tip pivots. Only the
|
False
|
**kwargs
|
Any
|
Forwarded to |
{}
|
Returns:
| Type | Description |
|---|---|
list
|
List of |
list
|
contains the corner-point coordinates in um. |
Signature examples::
pld.route_polylines(start_ports, end_ports)
pld.route_polylines(start_ports, end_ports, cross_section=xs, obstacles=[obs])
pld.route_polylines(start_ports, end_ports, finetune=pld.FinetuneConfig(non_manhattan=0.0))
add_route_bundle
add_route_bundle(
component,
start_ports,
end_ports,
*,
as_single: bool = True,
add_overlays: bool = False,
include_context: bool = False,
**kwargs: Any,
) -> Router
Route a bundle and add the result to an existing component.
In-place API: routes are added to component as instances.
Returns the Router for inspection and optional finetuning.
Accepts all the same keyword arguments as route_bundle()
(obstacles, cross_section, finetune, etc.).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
component
|
The gdsfactory |
required | |
start_ports
|
Start port(s) — |
required | |
end_ports
|
End port(s) — |
required | |
as_single
|
bool
|
Combine all routes into one sub-component. |
True
|
add_overlays
|
bool
|
Whether to include diagnostic polyline/smooth-path overlay layers in the inserted route geometry. |
False
|
include_context
|
bool
|
Deprecated for this in-place API. Use
|
False
|
**kwargs
|
Any
|
Forwarded to |
{}
|
Returns:
| Type | Description |
|---|---|
Router
|
The |
Router
|
refine, then |
Signature examples::
pld.add_route_bundle(c, start_ports, end_ports, obstacles=[obs])
pld.add_route_bundle(c, start_ports, end_ports, cross_section="strip")
pld.add_route_bundle(c, start_ports, end_ports, finetune=pld.FinetuneConfig(lr=1.0))