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

fix route_info #2130

Merged
merged 2 commits into from Sep 27, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
43 changes: 43 additions & 0 deletions gdsfactory/component.py
Expand Up @@ -55,6 +55,7 @@
from gdsfactory.technology import LayerStack, LayerViews
from gdsfactory.typings import (
Coordinate,
CrossSection,
CrossSectionSpec,
Float2,
Layer,
Expand Down Expand Up @@ -2434,6 +2435,48 @@
layer=layer,
)

def add_route_info(
self,
cross_section: CrossSection | str,
length: float,
length_eff: float | None = None,
taper: bool = False,
**kwargs,
) -> None:
"""Adds route information to a component.

Args:
cross_section: CrossSection or name of the cross_section.
length: length of the route.
length_eff: effective length of the route.
taper: if True adds taper information.
**kwargs: extra information to add to the component.
"""
from gdsfactory.pdk import get_active_pdk

pdk = get_active_pdk()

length_eff = length_eff or length
xs_name = (
cross_section
if isinstance(cross_section, str)
else pdk.get_cross_section_name(cross_section)
)

d = {
"type": xs_name,
"length": length_eff,
f"{xs_name}_length": length_eff,
"weight": length_eff,
}
if taper:
d[f"{xs_name}_taper_length"] = length

Check warning on line 2473 in gdsfactory/component.py

View check run for this annotation

Codecov / codecov/patch

gdsfactory/component.py#L2473

Added line #L2473 was not covered by tests
d |= kwargs
self.info["route_info"] = d


# Component methods


def copy(
D: Component,
Expand Down
3 changes: 3 additions & 0 deletions gdsfactory/components/bend_circular.py
Expand Up @@ -58,6 +58,9 @@ def bend_circular(
x.add_bbox(c)
if add_pins:
x.add_pins(c)
c.add_route_info(
cross_section=x, length=c.info["length"], n_bend_90=abs(angle / 90.0)
)
return c


Expand Down
3 changes: 3 additions & 0 deletions gdsfactory/components/bend_euler.py
Expand Up @@ -89,6 +89,9 @@ def bend_euler(
if add_pins:
x.add_pins(c)
c.absorb(ref)
c.add_route_info(
cross_section=x, length=c.info["length"], n_bend_90=abs(angle / 90.0)
)
return c


Expand Down
4 changes: 4 additions & 0 deletions gdsfactory/components/straight.py
Expand Up @@ -47,6 +47,8 @@ def straight(
c.info["length"] = length
c.info["width"] = x.sections[0].width
c.info["cross_section"] = cross_section

c.add_route_info(cross_section=x, length=length)
c.absorb(ref)
return c

Expand All @@ -56,4 +58,6 @@ def straight(

xs = gf.cross_section.strip()
c = straight(layer=(2, 0))
# c = straight()
print(c.info)
c.show(show_ports=True)
3 changes: 1 addition & 2 deletions gdsfactory/components/taper_cross_section.py
Expand Up @@ -6,7 +6,6 @@
from gdsfactory.cell import cell
from gdsfactory.component import Component
from gdsfactory.cross_section import strip_rib_tip
from gdsfactory.route_info import route_info
from gdsfactory.typings import CrossSectionSpec


Expand Down Expand Up @@ -59,7 +58,7 @@
c.add_ports(ref.ports)
c.absorb(ref)
if "type" in x1.info and x1.info["type"] == x2.info.get("type"):
c.info["route_info"] = route_info(x1.info["type"], length=length, taper=True)
c.add_route_info(cross_section=x1, length=length, taper=True)

Check warning on line 61 in gdsfactory/components/taper_cross_section.py

View check run for this annotation

Codecov / codecov/patch

gdsfactory/components/taper_cross_section.py#L61

Added line #L61 was not covered by tests
return c


Expand Down
2 changes: 1 addition & 1 deletion gdsfactory/cross_section.py
Expand Up @@ -287,7 +287,7 @@ def add_bbox(
c.add_polygon(points, layer=layer)
return c

def get_xmin_xmax(self):
def get_xmin_xmax(self) -> tuple[float, float]:
"""Returns the min and max extent of the cross_section across all sections."""
main_width = self.width
main_offset = self.sections[0].offset
Expand Down
11 changes: 11 additions & 0 deletions gdsfactory/pdk.py
Expand Up @@ -686,6 +686,17 @@ def to_updk(self) -> str:
# def on_cross_section_registered(self) -> Event:
# return self._on_cross_section_registered

def get_cross_section_name(self, cross_section: CrossSection) -> str:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

in this case, we are getting the name of a specific cross section (i.e. rib of width 0.5 um) rather than the type of cross section, right? i suppose this should be ok, but just noting it's different from what i was doing before for pathlength extraction. it comes down to if you want to group all rib as rib or break them out based on particular widths, etc. ideally, i think you probably want to be able to do it either way

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the CrossSections are uniquely identified by name,

it will try to get name from the PDK, and if it does not exist it will name them with a hash

what do you think?

xs_name = next(
(
key
for key, value in self.cross_sections.items()
if value == cross_section
),
None,
)
return xs_name or cross_section.name


_ACTIVE_PDK = None

Expand Down
57 changes: 0 additions & 57 deletions gdsfactory/route_info.py

This file was deleted.

Expand Up @@ -124,6 +124,12 @@ settings:
length: 16.637
radius: 10.0
radius_min: 7.061
route_info:
length: 16.637
n_bend_90: 1.0
type: xs_e757d4e7
weight: 16.637
xs_e757d4e7_length: 16.637
width: 1.0
info_version: 2
module: gdsfactory.components.bend_euler
Expand Down
Expand Up @@ -148,6 +148,11 @@ settings:
taper_length: 10.0
width_wide: null
length: 10.0
route_info:
length: 10.0
type: xs_e757d4e7
weight: 10.0
xs_e757d4e7_length: 10.0
width: 1.0
info_version: 2
module: gdsfactory.components.straight
Expand Down
52 changes: 27 additions & 25 deletions gdsfactory/serialization.py
Expand Up @@ -6,7 +6,6 @@
import inspect
import pathlib
from collections.abc import KeysView as dict_keys
from functools import partial
from typing import Any

import gdstk
Expand Down Expand Up @@ -72,22 +71,7 @@
return orjson.loads(orjson.dumps(value, option=orjson.OPT_SERIALIZE_NUMPY))

elif callable(value) and isinstance(value, functools.partial):
sig = inspect.signature(value.func)
args_as_kwargs = dict(zip(sig.parameters.keys(), value.args))
args_as_kwargs.update(value.keywords)
args_as_kwargs = clean_dict(args_as_kwargs)

func = value.func
while hasattr(func, "func"):
func = func.func
v = {
"function": func.__name__,
"settings": args_as_kwargs,
}
if include_module:
v.update(module=func.__module__)
return v

return clean_value_partial(value, include_module)
elif hasattr(value, "to_dict"):
return clean_dict(value.to_dict())

Expand Down Expand Up @@ -132,6 +116,24 @@
raise e


def clean_value_partial(value, include_module):
sig = inspect.signature(value.func)
args_as_kwargs = dict(zip(sig.parameters.keys(), value.args))
args_as_kwargs |= value.keywords
args_as_kwargs = clean_dict(args_as_kwargs)

func = value.func
while hasattr(func, "func"):
func = func.func

Check warning on line 127 in gdsfactory/serialization.py

View check run for this annotation

Codecov / codecov/patch

gdsfactory/serialization.py#L127

Added line #L127 was not covered by tests
v = {
"function": func.__name__,
"settings": args_as_kwargs,
}
if include_module:
v.update(module=func.__module__)

Check warning on line 133 in gdsfactory/serialization.py

View check run for this annotation

Codecov / codecov/patch

gdsfactory/serialization.py#L133

Added line #L133 was not covered by tests
return v


def clean_value_name(value: Any) -> str:
"""Returns a string representation of an object."""
# value1 = clean_value_json(value)
Expand All @@ -153,13 +155,13 @@
# d = clean_value_json(c)
# print(d, d)

xs = partial(
gf.cross_section.strip,
width=3,
add_pins=gf.partial(gf.add_pins.add_pins_inside1nm, pin_length=0.1),
)
f = partial(gf.routing.add_fiber_array, cross_section=xs)
c = f()
# xs = partial(
# gf.cross_section.strip,
# width=3,
# add_pins=gf.partial(gf.add_pins.add_pins_inside1nm, pin_length=0.1),
# )
# f = partial(gf.routing.add_fiber_array, cross_section=xs)
# c = f()
c = gf.cross_section.strip(width=3)
d = clean_value_json(c)
print(get_hash(d))
print(d, d)