Path-length Analysis#

This notebook demonstrates how to extract path-length and curvature from layout components.

Extract Path-length and Curvature from Components#

In this section, we’ll extract the centerline from components and compute key metrics:

  • Path-length between ports

  • Minimum radius of curvature, \(R\)

  • Maximum curvature (radius⁻¹), \(\kappa = \frac{1}{R}\)

For details on the curvature calculation, see Ref.\(~\)[1].

Hide code cell source
from IPython.display import display
import gdsfactory as gf
import matplotlib.pyplot as plt
import textwrap

from gplugins.path_length_analysis.path_length_analysis_from_gds import (
    extract_paths,
    get_min_radius_and_length_path_dict,
    plot_curvature,
)

Basic Example: Circular Bend#

We start with a simple circular bend component to demonstrate the process.

c = gf.components.bend_circular()
path_dict, ev_path_dict = extract_paths(c, plot=True)
r_and_l_dict = get_min_radius_and_length_path_dict(path_dict)
for ports, (min_radius, length) in r_and_l_dict.items():
    print(
        textwrap.dedent(
            f"""
            Ports: {ports}
            Maximum curvature: {1 / min_radius:.2f}
            Minimum radius of curvature: {min_radius:.2f}
            Length: {length:.2f}
            """
        )
    )
    fig = plot_curvature(path_dict[ports])
    plt.show()
display(c.info)
difference_in_min_radius = abs(c.info["radius"] - min_radius) / c.info["radius"]
print(f"Relative difference in min radius: {difference_in_min_radius:.2%}")
../_images/df57c5c91d44d4112b64f7487ffe66cc2ac1033d60cde36b1cfb51b4132273ee.png
Ports: o1;o2
Maximum curvature: 0.11
Minimum radius of curvature: 9.35
Length: 15.71
../_images/841f7f95d850dd252449b798181ea14d177f97993f15f0d3a55b8ed94fea215e.png
Info(length=15.708, dy=10.0, radius=10.0, width=0.5, route_info_type='strip', route_info_length=15.708, route_info_weight=15.708, route_info_strip_length=15.708, route_info_n_bend_90=1.0, route_info_min_bend_radius=10.0)
Relative difference in min radius: 6.53%

Results for Different Number of Points#

The accuracy of curvature calculations depends on the number of points used to define the component. Here, we show an Euler bend with varying number of polygon points (10, 50, 100 points) to observe how the calculated metrics change.

The smooth curvature transition of Euler bends should be better captured with higher point counts.

for npoints in [10, 50, 100]:
    c = gf.components.bend_euler(npoints=npoints)
    path_dict, ev_path_dict = extract_paths(c, plot=True)
    r_and_l_dict = get_min_radius_and_length_path_dict(path_dict)
    for ports, (min_radius, length) in r_and_l_dict.items():
        print(
            textwrap.dedent(
                f"""
                Ports: {ports}
                Maximum curvature: {1 / min_radius:.2f}
                Minimum radius of curvature: {min_radius:.2f}
                Length: {length:.2f}
                """
            )
        )
        fig = plot_curvature(path_dict[ports])
        plt.title(f"{npoints=}")
        plt.show()
    display(c.info)
    difference_in_min_radius = (
        abs(c.info["min_bend_radius"] - min_radius) / c.info["min_bend_radius"]
    )
    print(f"Relative difference in min radius: {difference_in_min_radius:.2%}")
../_images/b65e2dfdac2a5a17ab1bbe803b6a49ae6c68cae58c657cefe355a5ecebe13c77.png
Ports: o1;o2
Maximum curvature: 0.15
Minimum radius of curvature: 6.88
Length: 16.59
../_images/db0970e19acdb18d2595a78803e4c1758a3bc2465c9d7fc24bb44db79b468378.png
Info(length=16.625, dy=10.0, min_bend_radius=7.061, radius=10.0, width=0.5, route_info_type='strip', route_info_length=16.625, route_info_weight=16.625, route_info_strip_length=16.625, route_info_n_bend_90=1.0, route_info_min_bend_radius=7.061)
Relative difference in min radius: 2.55%
../_images/fa27f51f2ae4796bf420b8b4056da96068c035dd74f9b083730832760c300f72.png
Ports: o1;o2
Maximum curvature: 0.15
Minimum radius of curvature: 6.75
Length: 16.64
../_images/75f1b2eda214e9d1c2009ab477c4ae6b17b5f08c5f1b6c71648318ec98db9c26.png
Info(length=16.637, dy=10.0, min_bend_radius=7.061, radius=10.0, width=0.5, route_info_type='strip', route_info_length=16.637, route_info_weight=16.637, route_info_strip_length=16.637, route_info_n_bend_90=1.0, route_info_min_bend_radius=7.061)
Relative difference in min radius: 4.45%
../_images/ef90d9d775c3faa7fb0e8afcdd707304fdd1eb325b04e93aa1bce4f8d720a675.png
Ports: o1;o2
Maximum curvature: 0.15
Minimum radius of curvature: 6.62
Length: 16.64
../_images/5bbaadbfc07e676ed659ed6a5683227760b1ce51fbf17a8118bf6e8a65d96604.png
Info(length=16.637, dy=10.0, min_bend_radius=7.061, radius=10.0, width=0.5, route_info_type='strip', route_info_length=16.637, route_info_weight=16.637, route_info_strip_length=16.637, route_info_n_bend_90=1.0, route_info_min_bend_radius=7.061)
Relative difference in min radius: 6.20%

4-port component: directional Coupler#

We can also handle components with:

  • Multiple input/output ports

  • An evanescent coupling region where light transfers between waveguides

The evanescent_coupling=True parameter enables analysis of the coupling regions.

c = gf.components.coupler()
path_dict, ev_path_dict = extract_paths(c, plot=True, evanescent_coupling=True)
r_and_l_dict = get_min_radius_and_length_path_dict(path_dict)
for ports, (min_radius, length) in r_and_l_dict.items():
    print(
        textwrap.dedent(
            f"""
            Ports: {ports}
            Maximum curvature: {1 / min_radius:.2f}
            Minimum radius of curvature: {min_radius:.2f}
            Length: {length:.2f}
            """
        )
    )
    fig = plot_curvature(path_dict[ports])
    plt.title(f"Ports: {ports}")
    plt.show()
display(c.info)
difference_in_min_radius = (
    abs(c.info["min_bend_radius"] - min_radius) / c.info["min_bend_radius"]
)
print(f"Relative difference in min radius: {difference_in_min_radius:.2%}")
../_images/131a3e29e08361f9ddedd8d78d0d69c29b813571f2543247531502ffdd1cf8f1.png ../_images/d2ffd46a5cef045d44e42cf11a3b3301e37bcf9b7051171c19b0b021841090f9.png
Ports: o1;o4
Maximum curvature: 0.09
Minimum radius of curvature: 11.04
Length: 40.37
../_images/19ada205ea96252fb0e8a809a85503cf1d0e378a1a7a381fbb8d3b10ff8f91b2.png
Ports: o2;o3
Maximum curvature: 0.09
Minimum radius of curvature: 11.09
Length: 40.37
../_images/451d97d97e0521e115996aae0c89baf72748dc33939cfd15319cc24df8c7ae04.png
Info(length=10.186, min_bend_radius=11.857)
Relative difference in min radius: 6.43%

Conclusion#

This notebook demonstrates how to:

  1. Extract path information from layout photonic components

  2. Calculate important metrics (length, curvature)

  3. Visualize the results

Bibliography#

[1]

Eric W. Weisstein. Radius of Curvature. URL: https://mathworld.wolfram.com/RadiusofCurvature.html (visited on 2025-06-25).