Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improvements to path length code #461

Merged
merged 2 commits into from
Aug 6, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 47 additions & 5 deletions gplugins/path_length_analysis/path_length_analysis_from_gds.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import numpy as np
import shapely as sh
import shapely.ops as ops
from gdsfactory.typings import List, Optional, Tuple
from klayout.db import DPoint, Polygon
from scipy.signal import savgol_filter
from scipy.spatial import distance
Expand Down Expand Up @@ -240,6 +241,8 @@ def extract_paths(
filter_function: Callable = None,
under_sampling: int = 1,
evanescent_coupling: bool = False,
consider_ports: Optional[List[str]] = None,
port_positions: Optional[List[Tuple]] = None,
) -> dict:
"""Extracts the centerline of a component or instance from a GDS file.

Expand All @@ -254,11 +257,41 @@ def extract_paths(
under_sampling: under sampling factor of the polygon points.
evanescent_coupling: if True, it assumes that there is evanescent coupling
between ports not physically connected.
consider_ports: if specified, it only considers paths between the specified port names
and ignores all other existing ports. Note - this will not work in cases where the
specified ports are only coupled evanescently. In this case, it is better to
run the function with consider_ports = None and then filter the returned dict.
port_positions: if specified, we ignore the existing ports on the component and instead
create new ports at the specified positions. Overrides the parameter consider_ports.
Note - this will not work in cases where the specified port positions are only coupled
evanescently. A workaround for this limitation is to specify one additional port that is
physically connected to the ports of interest, for each port of interest.
"""

ev_paths = None

n_ports = len(component.ports)
if port_positions is not None:
# Create ports at the specified positions
consider_ports = []
new_component = component.copy()
for i, pos in enumerate(port_positions):
pname = f"pl{i}"
# The port width and orientation are irrelevant but need to be specified
new_component.add_port(
name=pname, center=pos, layer=layer, width=0.3, orientation=0
)
consider_ports.append(pname)

component = new_component

if consider_ports is not None:
# Only ports in the specified list
consider_ports = [component.ports[port_name] for port_name in consider_ports]
else:
# All ports
consider_ports = component.ports

n_ports = len(consider_ports)
if n_ports == 0:
raise ValueError(
"The specified component does not have ports - path length extraction will not work."
Expand All @@ -284,12 +317,12 @@ def extract_paths(
if n_ports == 2:
# This is the simplest case - a straight or a bend
centerline = centerline_single_poly_2_ports(
poly, under_sampling, component.ports
poly, under_sampling, consider_ports
)
if filter_function is not None:
centerline = filter_function(centerline)
p = gf.Path(centerline)
paths[f"{component.ports[0].name};{component.ports[1].name}"] = p
paths[f"{consider_ports[0].name};{consider_ports[1].name}"] = p

else:
# Single polygon and more than 2 ports - MMI
Expand Down Expand Up @@ -332,7 +365,7 @@ def extract_paths(
# Need to check how many ports does that specific polygon contain
ports_poly = list()

for port in component.ports:
for port in consider_ports:
if poly.sized(0.005).inside(DPoint(port.center[0], port.center[1])):
ports_poly.append(port)

Expand All @@ -346,6 +379,10 @@ def extract_paths(
p = gf.Path(centerline)
paths[f"{ports_poly[0].name};{ports_poly[1].name}"] = p

elif len(ports_poly) == 0:
# No ports in the polygon - continue
continue

else:
# More than 2 ports and multiple polygons
# We will assume that means that we are trying to get path
Expand Down Expand Up @@ -626,7 +663,12 @@ def _demo_routes():
# c = gf.import_gds(gdspath)
# p = extract_path(c, plot=False, window_length=None, polyorder=None)
path_dict, ev_path_dict = extract_paths(
c0, plot=True, under_sampling=1, evanescent_coupling=ev_coupling
c0,
plot=True,
under_sampling=1,
evanescent_coupling=ev_coupling,
# consider_ports=["o2", "o3"],
port_positions=[(-10.0, -1.6), (30.0, -1.6)],
)
r_and_l_dict = get_min_radius_and_length_path_dict(path_dict)
for ports, (min_radius, length) in r_and_l_dict.items():
Expand Down
Loading