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

Faster remap layers #2168

Merged
merged 3 commits into from Oct 9, 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
2 changes: 1 addition & 1 deletion .github/release-drafter.yml
@@ -1,6 +1,6 @@
name-template: 'v$RESOLVED_VERSION'
tag-template: 'v$RESOLVED_VERSION'
change-template: '- $TITLE [#$NUMBER](https://github.com/gdsfactory/gdsfactory/pull/#$NUMBER)'
change-template: '- $TITLE [#$NUMBER](https://github.com/$OWNER/$REPOSITORY/pull/#$NUMBER)'
template: |
# What's Changed

Expand Down
93 changes: 41 additions & 52 deletions gdsfactory/component.py
Expand Up @@ -166,10 +166,12 @@ def __init__(
self,
name: str = "Unnamed",
with_uuid: bool = False,
max_name_length: int | None = None,
) -> None:
"""Initialize the Component object."""

self.uid = str(uuid.uuid4())[:8]
self.max_name_length = max_name_length or CONF.max_name_length
if with_uuid or name == "Unnamed":
name += f"_{self.uid}"

Expand Down Expand Up @@ -214,10 +216,10 @@ def name(self) -> str:
@name.setter
def name(self, name) -> None:
name = clean_name(name)
if len(name) > CONF.max_name_length:
name_short = get_name_short(name)
if len(name) > self.max_name_length:
name_short = get_name_short(name, max_name_length=self.max_name_length)
warnings.warn(
f" {name} is too long. Max length is {CONF.max_name_length}. Renaming to {name_short}",
f" {name} is too long. Max length is {self.max_name_length}. Renaming to {name_short}",
stacklevel=2,
)
name = name_short
Expand Down Expand Up @@ -2223,51 +2225,22 @@ def get_info(self):
D_list = self.get_dependencies(recursive=True)
return [D.info.copy() for D in D_list]

def remap_layers(
self, layermap, include_labels: bool = True, include_paths: bool = True
) -> Component:
def remap_layers(self, layermap, **kwargs) -> Component:
"""Returns a copy of the component with remapped layers.

Args:
layermap: Dictionary of values in format {layer_from: layer_to}.
include_labels: Selects whether to move Labels along with polygons.
include_paths: Selects whether to move Paths along with polygons.
"""
component = self.copy()
if kwargs:
warnings.warn("{kwargs.keys} is deprecated.", DeprecationWarning)

component = self
layermap = {_parse_layer(k): _parse_layer(v) for k, v in layermap.items()}

all_D = list(component.get_dependencies(True))
all_D.append(component)
for D in all_D:
for p in D.polygons:
layer = (p.layer, p.datatype)
if layer in layermap:
new_layer = layermap[layer]
p.layer = new_layer[0]
p.datatype = new_layer[1]
if include_labels:
for label in D.labels:
original_layer = (label.layer, label.texttype)
original_layer = _parse_layer(original_layer)
if original_layer in layermap:
new_layer = layermap[original_layer]
label.layer = new_layer[0]
label.texttype = new_layer[1]

if include_paths:
for path in D.paths:
new_layers = list(path.layers)
new_datatypes = list(path.datatypes)
for layer_number in range(len(new_layers)):
original_layer = _parse_layer(
(new_layers[layer_number], new_datatypes[layer_number])
)
if original_layer in layermap:
new_layer = layermap[original_layer]
new_layers[layer_number] = new_layer[0]
new_datatypes[layer_number] = new_layer[1]
path.set_layers(*new_layers)
path.set_datatypes(*new_datatypes)
cells = list(component.get_dependencies(True))
cells.append(component)
for cell in cells:
cell._cell.remap(layermap)
return component

def to_3d(
Expand Down Expand Up @@ -2691,23 +2664,39 @@ def _check_uncached_components(component, mode):


if __name__ == "__main__":
from functools import partial

import gdsfactory as gf

gf.config.enable_off_grid_ports()
custom_padding = partial(gf.add_padding, layers=("WG",))
c = gf.c.mzi(decorator=custom_padding)

c = gf.Component("bend")
b = c << gf.components.bend_circular(angle=30)
s = c << gf.components.straight(length=5)
s.connect("o1", b.ports["o2"])
p_shapely = c.get_polygons(as_shapely_merged=True)
c2 = gf.Component("bend_fixed")
c2.add_polygon(p_shapely, layer=(1, 0))
c2.plot()
# c = c.copy()
c = c.remap_layers({(1, 0): (3, 0)})

c = gf.c.mzi(flatten=True, decorator=gf.routing.add_fiber_single)
# print(c.name)
# c._cell.remap({(1, 0): (3, 0)})
# lib = gdstk.Library()
# lib.add(c._cell)
# lib.remap({(1, 0): (2, 0)})
# c2 = lib[c.name]
# c._cell = c2
c.show()

# gf.config.enable_off_grid_ports()

# c = gf.Component("bend")
# b = c << gf.components.bend_circular(angle=30)
# s = c << gf.components.straight(length=5)
# s.connect("o1", b.ports["o2"])
# p_shapely = c.get_polygons(as_shapely_merged=True)
# c2 = gf.Component("bend_fixed")
# c2.add_polygon(p_shapely, layer=(1, 0))
# c2.plot()

# c = gf.c.mzi(flatten=True, decorator=gf.routing.add_fiber_single)
# # print(c.name)
# c.show()

# c = gf.c.mzi()
# fig = c.plot_klayout()
# fig.savefig("mzi.png")
Expand Down
15 changes: 9 additions & 6 deletions gdsfactory/read/import_gds.py
Expand Up @@ -21,6 +21,7 @@ def import_gds(
read_metadata: bool = False,
keep_name_short: bool = False,
unique_names: bool = True,
max_name_length: int = 250,
**kwargs,
) -> Component:
"""Returns a Component from a GDS file.
Expand All @@ -35,6 +36,7 @@ def import_gds(
keep_name_short: appends a hash to a shortened component name.
unique_names: appends $ with a number to the name if the cell name is on CACHE. \
This avoids name collisions when importing multiple times the same cell name.
max_name_length: maximum length of the name.
kwargs: extra to add to component.info (polarization, wavelength ...).
"""
gdspath = Path(gdsdir) / Path(gdspath) if gdsdir else Path(gdspath)
Expand Down Expand Up @@ -62,7 +64,7 @@ def import_gds(

# create a new Component for each gdstk Cell
for c in gdsii_lib.cells:
D = Component(name=c.name)
D = Component(name=c.name, max_name_length=max_name_length)
D._cell = c
if not unique_names:
D._cell.name = c.name
Expand Down Expand Up @@ -153,14 +155,15 @@ def import_gds_raw(gdspath, top_cellname: str | None = None):


if __name__ == "__main__":
import gdsfactory as gf
# import gdsfactory as gf
# gf.CONF.max_name_length = 250

c = gf.components.mzi()
gdspath = c.write_gds()
# c.show(show_ports=True)
# c = gf.Component(name='a'*250)
# _ = c << gf.components.mzi()
# gdspath = c.write_gds('a.gds')

# c = import_gds(gdspath)
c = import_gds(gdspath, cellname="straight_length7p0")
c = import_gds("a.gds")
c.show(show_ports=False)

# gdspath = PATH.gdsdir / "mzi2x2.gds"
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Expand Up @@ -13,7 +13,7 @@ classifiers = [
]
dependencies = [
"flatdict",
"gdstk<1",
"gdstk>=0.9.44,<0.10",
"jinja2",
"loguru<1",
"matplotlib",
Expand Down