Route

Waypoint-based waveguide route.

Route connects an ordered sequence of waypoints with straight segments, inserting circular bends at corners and tapers for width transitions. It is not an auto-router — you must supply intermediate waypoints to create the path shape you want.

Waypoints create the shape

When connecting two ports, always add intermediate (x, y) waypoints so the route departs and arrives along each port's axis. Two ports alone produce a straight diagonal line between them, ignoring port directions.

# Connecting two ports with an S-bend:
route = Route(Layer(1, 0), width=0.5, bend_radius=5.0)
route.start_at_port(port_a)                    # departs along port_a's axis
route.to(mid_x, port_a.position.y)             # horizontal segment out
route.to(mid_x, port_b.position.y)             # vertical transition
route.end_at_port(port_b)                      # arrives along port_b's axis
cell = route.to_cell("my_route")

# Manual waypoints:
route = Route(Layer(1, 0), width=0.5, bend_radius=5.0)
route.start_at(0, 0, angle=0)
route.to(50, 0)
route.to(50, 30)
route.end_at(100, 30, angle=0)
cell = route.to_cell("my_route")  # Returns Cell with .at()

Attributes

attributepath_lengthfloat

Total optical path length.

attributewarningslist[str]

Warnings from route generation (e.g., auto-reduced bend radii).

Methods

func__init__(layer, width=0.5, bend_radius=5.0, auto_taper=True, taper_length=10.0) -> None

Create a new Route.

paramlayerLayer | int | tuple[int, int]

The layer for the route geometry.

paramwidthfloat
= 0.5

Default waveguide width.

parambend_radiusfloat
= 5.0

Default bend radius.

paramauto_taperbool
= True

Whether to automatically add tapers for width changes.

paramtaper_lengthfloat
= 10.0

Length of auto-generated tapers.

Returns

None
funcstart_at(x, y, angle=0.0) -> None

Start the route at a specific position and angle (degrees).

paramxfloat

X coordinate.

paramyfloat

Y coordinate.

paramanglefloat
= 0.0

Departure angle in degrees (0 = +X direction).

Returns

None
funcstart_at_port(port) -> None

Start the route at a port's position, heading into the port.

The port's outward-facing direction is flipped 180 degrees so the route departs in the correct direction (away from the component). The port's width is used as the starting width.

The first waypoint after this should continue along the port's axis (e.g., same y for a horizontal port) before turning.

paramportPort

The port to start at.

Returns

None
functo(x, y, width=None, bend_radius=None) -> None

Add a waypoint to the route.

The route draws a straight segment from the previous waypoint to (x, y), inserting a circular bend at the corner if the direction changes. Provide intermediate waypoints to create L-bends and S-bends — the router does not infer turns on its own.

paramxfloat

X coordinate of the waypoint.

paramyfloat

Y coordinate of the waypoint.

paramwidthfloat | None
= None

Override width at this waypoint. If set and auto_taper is enabled, a taper is inserted.

parambend_radiusfloat | None
= None

Override bend radius at this corner.

Returns

None
funcend_at(x, y, angle=0.0) -> None

End the route at a specific position and angle (degrees).

paramxfloat

X coordinate.

paramyfloat

Y coordinate.

paramanglefloat
= 0.0

Arrival angle in degrees.

Returns

None
funcend_at_port(port) -> None

End the route arriving into a port.

The port's outward-facing direction is flipped 180 degrees so the route arrives heading into the component. The port's width is used as the ending width.

The last waypoint before this should approach along the port's axis (e.g., same y for a horizontal port) to ensure a flush connection.

paramportPort

The port to end at.

Returns

None
functo_cell(name) -> Cell

Convert the route to a Cell.

Warnings are printed to stderr if the route had to auto-reduce bend radii or encountered other issues. This provides immediate feedback to both users and AI agents about potential design problems.

paramnamestr

Name for the generated cell.

Returns

Cell

A Cell containing the route geometry, with path_length set.

functhrough(*waypoints, layer, width=0.5, bend_radius=5.0) -> Route

Create a route through a series of waypoints (static method).

A convenience method that creates a Route, adds all waypoints, and returns the result. You must include intermediate waypoints to create turns — two ports alone produce a straight diagonal line regardless of port directions.

Port directions are used only for the first and last waypoint (to set departure/arrival angle). Intermediate ports are treated as plain (x, y) positions — their direction is ignored.

Example

# S-bend between two component ports:
route = Route.through(
    port_a,                        # start at port_a, depart along its axis
    (25, port_a.position.y),       # extend horizontally
    (25, port_b.position.y),       # shift vertically
    port_b,                        # arrive at port_b along its axis
    layer=Layer(1, 0),
    bend_radius=10.0,
)
cell = route.to_cell("my_route")
param*waypointsPort | Point | tuple[float, float] | tuple[float, float, float]

Sequence of waypoints. Each can be a Port (position + width; direction used only if first/last), a Point (position only), an (x, y) tuple, or an (x, y, angle) tuple (for first/last waypoint).

paramlayerLayer | int | tuple[int, int]

The layer for the route.

paramwidthfloat
= 0.5

Default waveguide width.

parambend_radiusfloat
= 5.0

Default bend radius.

Returns

Route

A Route that can be converted to a Cell with to_cell().

On this page