routecheck takes a set of route centerlines (or a gdsfactory Component) and audits them: where routes
cross, where they run closer than a minimum spacing, and how long and how manhattan each route is.
gdsfactory's router can avoid collisions while it builds a bundle (route_bundle(..., collision_check_layers=...));
routecheck is the verification side, the audit you run on an existing or imported routed layout.
pip install -r requirements.txt
numpy and matplotlib are the dependencies. gdsfactory is optional and used only to read routes from a
Component; a list of centerlines or a JSON file works without it.
| Check | Rule | Severity |
|---|---|---|
| two routes cross | crossing |
error |
| a route crosses itself (opt-in) | self_crossing |
warning |
| two routes are closer than the minimum spacing | spacing |
error |
A crossing pair already has zero separation, so it is reported once as a crossing; spacing only adds pairs that come close without crossing.
From Python, on a list of centerlines (or a gdsfactory Component):
import routes, report
rs = routes.from_polylines(
[[[0, 0], [20, 0]], [[10, -5], [10, 5]], [[0, 2], [20, 2]]],
names=["r0", "r1", "r2"])
rep = report.build(rs, min_spacing=3.0)
print(report.to_markdown(rep))
report.figure(rs, rep, "routes.png")
# from a gdsfactory Component:
# report.build(routes.from_component(component), min_spacing=3.0)From the command line, on a JSON routes file:
python cli.py routes.json -o out/
The JSON holds the route centerlines and the optional settings:
{"routes": [[[0, 0], [20, 0]], [[10, -5], [10, 5]]], "names": ["r0", "r1"],
"min_spacing": 3.0, "self_crossings": false}It writes report.json, report.md, and routes.png (the routes with crossings marked). A runnable example
is in examples/quickstart.py.
# routecheck
## Summary
- routes: 3
- total length: 50.000
- manhattan fraction: 1.000
## Routes
| route | length | bends | manhattan |
|---|---|---|---|
| r0 | 20.000 | 0 | 1.000 |
| r1 | 10.000 | 0 | 1.000 |
| r2 | 20.000 | 0 | 1.000 |
## Issues (3 error(s), 0 warning(s))
- [crossing] routes 'r0' and 'r1' cross at (10, 0)
- [crossing] routes 'r1' and 'r2' cross at (10, 2)
- [spacing] routes 'r0' and 'r2' are 2 apart, under the 3 minimum
| Module | What it does |
|---|---|
routes.py |
normalise a list / JSON / Component into route centerlines |
geom.py |
segment intersection, point-segment distance, polyline length and min distance |
crossings.py |
crossing points between distinct routes (and self-crossings) |
spacing.py |
route-to-route minimum spacing |
metrics.py |
per-route length, bends, and manhattan fraction |
report.py |
JSON, Markdown, and a routes figure |
cli.py |
python cli.py routes.json end to end |
python run_checks.py validate <name> # one module's self-check
python run_checks.py validate-all # every module's self-check
python run_checks.py suite # pytest tests/
Every primitive is validated against an analytic case: two segments forming an X intersect at their centre, parallel routes 3 apart report a separation of 3, and an L-shaped route reports a length of 7 with one bend.
routecheck audits route centerlines; it complements the gdsfactory router rather than replacing its build-time collision check, and it is not a layout DRC. Crossing and spacing use a bounding-box pre-filter so that route pairs too far apart to interact are skipped, which keeps a realistic localized routing layout fast (a few hundred routes in about a tenth of a second). A pathological layout where every route overlaps every other falls back to the exact all-pairs comparison.