Skip to content

Commit

Permalink
Merge pull request #759 from gdsfactory/connectivity
Browse files Browse the repository at this point in the history
Connectivity
  • Loading branch information
joamatab committed Oct 7, 2022
2 parents b03b68f + 7b3f54e commit b3f12d5
Show file tree
Hide file tree
Showing 16 changed files with 105 additions and 55 deletions.
8 changes: 5 additions & 3 deletions gdsfactory/add_labels.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
"""Add Label to each component port."""

from functools import partial
from typing import Callable, Dict, List, Optional, Union

import gdsfactory as gf
Expand Down Expand Up @@ -258,13 +259,13 @@ def add_labels_to_ports(
return component


add_labels_to_ports_electrical = gf.partial(
add_labels_to_ports_electrical = partial(
add_labels_to_ports, port_type="electrical", prefix="elec-"
)
add_labels_to_ports_optical = gf.partial(
add_labels_to_ports_optical = partial(
add_labels_to_ports, port_type="optical", prefix="opt-"
)
add_labels_to_ports_vertical_dc = gf.partial(
add_labels_to_ports_vertical_dc = partial(
add_labels_to_ports, port_type="vertical_dc", prefix="elec-"
)

Expand All @@ -284,6 +285,7 @@ def get_labels(
get_label_function: function to get label.
layer_label: layer_label.
gc: Optional grating coupler.
component_name: optional component name.
keyword Args:
layer: port GDS layer.
Expand Down
9 changes: 4 additions & 5 deletions gdsfactory/components/add_fidutials.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import gdsfactory as gf
from gdsfactory.cell import cell
from gdsfactory.component import Component
from gdsfactory.components.cross import cross
from gdsfactory.components.pad import pad_array
from gdsfactory.types import ComponentSpec, Coordinates, Float2, Optional

Expand All @@ -10,8 +9,8 @@
def add_fidutials(
component: ComponentSpec = pad_array,
gap: float = 50,
left: Optional[ComponentSpec] = cross,
right: Optional[ComponentSpec] = cross,
left: Optional[ComponentSpec] = "cross",
right: Optional[ComponentSpec] = "cross",
top: Optional[ComponentSpec] = None,
bottom: Optional[ComponentSpec] = None,
offset: Float2 = (0, 0),
Expand Down Expand Up @@ -62,7 +61,7 @@ def add_fidutials(
@cell
def add_fidutials_offsets(
component: ComponentSpec = pad_array,
fidutial: ComponentSpec = cross,
fidutial: ComponentSpec = "cross",
offsets: Coordinates = ((0, 100), (0, -100)),
) -> Component:
"""Returns new component with fidutials from a list of offsets.
Expand All @@ -87,6 +86,6 @@ def add_fidutials_offsets(


if __name__ == "__main__":
# c = add_fidutials(top=cross)
# c = add_fidutials(top='cross')
c = add_fidutials_offsets()
c.show(show_ports=True)
3 changes: 2 additions & 1 deletion gdsfactory/geometry/boolean_klayout.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,9 +73,10 @@ def boolean_klayout(


def _demo() -> None:
import gdsfactory as gf
import klayout.db as pya

import gdsfactory as gf

gdspath1 = gf.Component("ellipse1")
gdspath1.add_ref(gf.components.ellipse(radii=[10, 5], layer=(1, 0)))

Expand Down
1 change: 1 addition & 0 deletions gdsfactory/geometry/check_duplicated_cells.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ def check_duplicated_cells(gdspath: Union[Path, str]):
"""
import klayout.db as pya

from gdsfactory.component import Component

if isinstance(gdspath, Component):
Expand Down
1 change: 1 addition & 0 deletions gdsfactory/geometry/check_exclusion.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ def check_exclusion(
"""
import klayout.db as pya

from gdsfactory.component import Component

if isinstance(gdspath, Component):
Expand Down
1 change: 1 addition & 0 deletions gdsfactory/geometry/check_inclusion.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ def check_inclusion(
"""
import klayout.db as pya

from gdsfactory.component import Component

if isinstance(gdspath, Component):
Expand Down
3 changes: 2 additions & 1 deletion gdsfactory/geometry/check_space.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,9 +72,10 @@ def check_space(


if __name__ == "__main__":
import gdsfactory as gf
import klayout.db as pya

import gdsfactory as gf

space = 0.12
min_space = 0.1
dbu = 1000
Expand Down
1 change: 1 addition & 0 deletions gdsfactory/geometry/check_width.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ def check_width(
"""
import klayout.db as pya

from gdsfactory.component import Component

if isinstance(gdspath, Component):
Expand Down
4 changes: 3 additions & 1 deletion gdsfactory/klayout/tech/tech.lyt
Original file line number Diff line number Diff line change
Expand Up @@ -214,5 +214,7 @@
</src>
</d25>
<connectivity>
</connectivity>
<connection>41/0,44/0,45/0
</connection><connection>45/0,43/0,49/0
</connection></connectivity>
</technology>
74 changes: 58 additions & 16 deletions gdsfactory/klayout_tech.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,26 +4,32 @@
"""

import os
import pathlib
import re
from typing import Dict, Literal, Optional, Tuple, Union
from typing import Dict, List, Optional, Set, Tuple, Union

from lxml import etree
from pydantic import BaseModel, Field, validator
from typing_extensions import Literal

from gdsfactory.config import PATH
from gdsfactory.tech import LayerStack

Layer = Tuple[int, int]
ConductorViaConductorName = Tuple[str, str, str]


def append_file_extension(filename: str, extension: str) -> str:
def append_file_extension(filename: Union[str, pathlib.Path], extension: str) -> str:
"""Try appending extension to file."""
# Handle whether given with '.'
if "." not in extension:
extension = f".{extension}"

if not filename.endswith(extension):
if isinstance(filename, str) and not filename.endswith(extension):
filename += extension

if isinstance(filename, pathlib.Path) and not str(filename).endswith(extension):
filename = filename.with_suffix(extension)
return filename


Expand Down Expand Up @@ -384,7 +390,7 @@ def get_layer_view_groups(self) -> Dict[str, LayerView]:
if view.group_members is not None
}

def __str__(self):
def __str__(self) -> str:
"""Prints the number of LayerView objects in the LayerDisplayProperties object."""
return (
f"LayerDisplayProperties ({len(self.get_layer_views())} layers total, {len(self.get_layer_view_groups())} groups) \n"
Expand Down Expand Up @@ -437,7 +443,7 @@ def get_from_tuple(self, layer_tuple: Layer) -> LayerView:
name = tuple_to_name[layer_tuple]
return self.layer_views[name]

def get_layer_tuples(self):
def get_layer_tuples(self) -> Set[Layer]:
"""Returns a tuple for each layer."""
return {layer.layer for layer in self.get_layer_views().values()}

Expand All @@ -448,6 +454,7 @@ def to_lyp(self, filepath: str, overwrite: bool = True) -> None:
filepath: to write the .lyp file to (appends .lyp extension if not present).
overwrite: Whether to overwrite an existing file located at the filepath.
"""
filepath = pathlib.Path(filepath)
filepath = append_file_extension(filepath, ".lyp")

if os.path.exists(filepath) and not overwrite:
Expand Down Expand Up @@ -540,21 +547,23 @@ class KLayoutTechnology(BaseModel):
Properties:
layer_properties: Defines all the layer display properties needed for a .lyp file from LayerView objects.
technology: KLayout Technology object from the KLayout API. Set name, dbu, etc.
layer_stack: gdsfactory LayerStack for writing LayerLevels to the technology files for 2.5D view.
connectivity: List of layer names connectivity for netlist tracing.
"""

import klayout.db as db

name: str
layer_properties: Optional[LayerDisplayProperties] = None
technology: db.Technology = Field(default_factory=db.Technology)
connectivity: Optional[List[ConductorViaConductorName]] = None

def export_technology_files(
self,
tech_dir: str,
lyp_filename: str = "layers",
lyt_filename: str = "tech",
layer_stack: Optional[LayerStack] = None,
):
) -> None:
"""Write technology files into 'tech_dir'.
Args:
Expand All @@ -567,8 +576,9 @@ def export_technology_files(
lyp_filename = append_file_extension(lyp_filename, ".lyp")
lyt_filename = append_file_extension(lyt_filename, ".lyt")

lyp_path = f"{tech_dir}/{lyp_filename}"
lyt_path = f"{tech_dir}/{lyt_filename}"
tech_path = pathlib.Path(tech_dir)
lyp_path = tech_path / lyp_filename
lyt_path = tech_path / lyt_filename

# Specify relative file name for layer properties file
self.technology.layer_properties_file = lyp_filename
Expand All @@ -579,6 +589,8 @@ def export_technology_files(
self.layer_properties.to_lyp(lyp_path)

root = etree.XML(self.technology.to_xml().encode("utf-8"))
subelement = etree.SubElement(root, "name")
subelement.text = self.name

if layer_stack is not None:
# KLayout 0.27.x won't have a way to read/write the 2.5D info for technologies, so add manually
Expand All @@ -596,13 +608,38 @@ def export_technology_files(
for layer_level in layer_stack.layers.values():
src_element.text += f"{layer_level.layer[0]}/{layer_level.layer[1]}: {layer_level.zmin} {layer_level.thickness}\n"

# Write lyt to file
with open(lyt_path, "wb") as file:
file.write(
etree.tostring(
root, encoding="utf-8", pretty_print=True, xml_declaration=True
# root['connectivity']['connection']= '41/0,44/0,45/0'
if connectivity is not None:
src_element = [e for e in list(root) if e.tag == "connectivity"]
if len(src_element) != 1:
raise KeyError("Could not get a single index for the src element.")
src_element = src_element[0]
for layer_name_c1, layer_name_via, layer_name_c2 in self.connectivity:
layer_c1 = self.layer_properties.layer_views[layer_name_c1].layer
layer_via = self.layer_properties.layer_views[layer_name_via].layer
layer_c2 = self.layer_properties.layer_views[layer_name_c2].layer
connection = (
",".join(
[
f"{layer[0]}/{layer[1]}"
for layer in [layer_c1, layer_via, layer_c2]
]
)
+ "\n"
)
)

subelement = etree.SubElement(src_element, "connection")
subelement.text = connection

script = etree.tostring(
root,
encoding="utf-8",
pretty_print=True,
xml_declaration=True,
).decode("utf8")

# Write lyt to file
lyt_path.write_text(script)

class Config:
"""Allow db.Technology type."""
Expand All @@ -620,8 +657,13 @@ class Config:
# str_xml = open(PATH.klayout_tech / "tech.lyt").read()
# new_tech = db.Technology.technology_from_xml(str_xml)

generic_tech = KLayoutTechnology(layer_properties=lyp)
connectivity = [("M1", "VIA1", "M2"), ("M2", "VIA2", "M3")]

c = generic_tech = KLayoutTechnology(
name="generic", layer_properties=lyp, connectivity=connectivity
)
tech_dir = PATH.repo / "extra" / "test_tech"
# tech_dir = pathlib.Path("/home/jmatres/.klayout/salt/gdsfactory/tech/")
tech_dir.mkdir(exist_ok=True, parents=True)

generic_tech.export_technology_files(tech_dir=tech_dir, layer_stack=LAYER_STACK)
4 changes: 2 additions & 2 deletions gdsfactory/routing/add_electrical_pads_top.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@

@gf.cell
def add_electrical_pads_top(
direction: str = "top",
component: ComponentSpec = straight,
direction: str = "top",
spacing: Float2 = (0.0, 100.0),
pad_array: ComponentSpec = pad_array_function,
select_ports=select_ports_electrical,
Expand All @@ -19,8 +19,8 @@ def add_electrical_pads_top(
"""Returns new component with electrical ports connected to top pad array.
Args:
direction: 'top' or 'right', sets direction of the array.
component: to route.
direction: 'top' or 'right', sets direction of the array.
spacing: component to pad spacing.
pad_array: function for pad_array.
select_ports: function to select electrical ports.
Expand Down
3 changes: 2 additions & 1 deletion gdsfactory/samples/demo/pcell.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,5 @@ def mzi_with_bend(radius: float = 10):

if __name__ == "__main__":
c = mzi_with_bend(radius=100)
c.show(show_ports=True)
cc = gf.routing.add_fiber_array(c)
cc.show(show_ports=True)
11 changes: 11 additions & 0 deletions gdsfactory/schematic.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
from gdsfactory.types import ComponentModel, Dict, List, Optional


class Schematic:
instances: Optional[Dict[str, ComponentModel]] = None
nets: Optional[List[List[str]]] = None
ports: Optional[Dict[str, str]] = None


if __name__ == "__main__":
s = Schematic()
Original file line number Diff line number Diff line change
Expand Up @@ -33,26 +33,22 @@ settings:
component:
function: pad_array
gap: 50
left:
function: cross
left: cross
offset:
- 0
- 0
right:
function: cross
right: cross
top: null
full:
bottom: null
component:
function: pad_array
gap: 50
left:
function: cross
left: cross
offset:
- 0
- 0
right:
function: cross
right: cross
top: null
function_name: add_fidutials
info:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,7 @@ settings:
default:
component:
function: pad_array
fidutial:
function: cross
fidutial: cross
offsets:
- - 0
- 100
Expand All @@ -41,8 +40,7 @@ settings:
full:
component:
function: pad_array
fidutial:
function: cross
fidutial: cross
offsets:
- - 0
- 100
Expand Down

0 comments on commit b3f12d5

Please sign in to comment.