Skip to content

Commit

Permalink
Merge branch 'main' into 138-improve-fix-docs-for-logger-loguru
Browse files Browse the repository at this point in the history
  • Loading branch information
sebastian-goeldi authored May 31, 2023
2 parents 027d9a0 + 752f2ec commit f36fbd1
Show file tree
Hide file tree
Showing 6 changed files with 140 additions and 17 deletions.
File renamed without changes.
1 change: 1 addition & 0 deletions changelog.d/92.added.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Added `mirror_x/mirror_y` to Instance, `xmin/xmax/ymin/ymax` getter & setter to Instance, `xmin/xmax/ymin/ymax` getter to KCell, `polygon_from_array`, `dpolygon_from_arry`
35 changes: 34 additions & 1 deletion docs/source/notebooks/00_geometry.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@

# %%
import kfactory as kf
import numpy as np

# %%
# Create a blank cell (essentially an empty GDS cell with some special features)
Expand Down Expand Up @@ -60,6 +61,14 @@
#
# Make a cell similar to the one above that has a second polygon in layer (1, 1)

# %%
c = kf.KCell()
points = np.array([(-8, -6), (6, 8), (7, 17), (9, 5)])
poly = kf.polygon_from_array(points)
c.shapes(c.kcl.layer(1, 0)).insert(poly1)
c.shapes(c.kcl.layer(1, 1)).insert(poly1)
c

# %%
import kfactory as kf

Expand Down Expand Up @@ -265,9 +274,33 @@ def straight(length=10, width=1, layer=(1, 0)):
# %%
c2

# %%
c = kf.KCell()
bend = kf.cells.euler.bend_euler(radius=10, width=1, layer=0)
b1 = c << bend
b2 = c << bend
b2.mirror_x(x=0)
c

# %%
c = kf.KCell()
bend = kf.cells.euler.bend_euler(radius=10, width=1, layer=0)
b1 = c << bend
b2 = c << bend
b2.mirror_y(y=0)
c

# %%
c = kf.KCell()
bend = kf.cells.euler.bend_euler(radius=10, width=1, layer=0)
b1 = c << bend
b2 = c << bend
b2.mirror_y(y=0)
b1.ymin = b2.ymax
c

# %% [markdown]
#
# self.layout_view.active_cellview().layout().cell(event["owner"].name)
# ## Labels
#
# You can add abstract GDS labels (annotate) to your Cells, in order to record information
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ exclude = [
"src/kfactory/technology",
"src/kfactory/pdk.py",
]
plugins = "pydantic.mypy"
plugins = "pydantic.mypy, numpy.typing.mypy_plugin"

[tool.pylsp-mypy]
enabled = true
Expand Down
4 changes: 4 additions & 0 deletions src/kfactory/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
default_save,
LayerEnum,
show,
polygon_from_array,
dpolygon_from_array,
)
from . import cells, placer, routing, utils, port, pdk
from .conf import config
Expand Down Expand Up @@ -50,4 +52,6 @@
"LayerEnum",
"logger",
"pdk",
"polygon_from_array",
"dpolygon_from_array",
]
115 changes: 100 additions & 15 deletions src/kfactory/kcell.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,23 +14,13 @@
import json
import socket
from collections.abc import Callable, Hashable, Iterable, Iterator

# from enum import IntEnum
from enum import Enum, IntEnum
from hashlib import sha3_512
from inspect import Parameter, signature
from pathlib import Path
from tempfile import gettempdir
from typing import ( # ParamSpec, # >= python 3.10
TYPE_CHECKING,
Any,
Literal,
TypeVar,
cast,
overload,
)
from typing import TYPE_CHECKING, Any, Literal, TypeVar, cast, overload

# from cachetools import Cache, cached
import cachetools.func
import numpy as np
import ruamel.yaml
Expand All @@ -40,9 +30,6 @@
from .conf import config
from .port import rename_clockwise

# import struct
# from abc import abstractmethod

if TYPE_CHECKING:
from .pdk import Pdk

Expand Down Expand Up @@ -193,7 +180,8 @@ class KCLayout(kdb.Layout):
Attributes:
editable: Whether the layout should be opened in editable mode (default: True)
rename_function: function that takes an iterable object of ports and renames them
rename_function: function that takes an iterable object of ports and renames
them
"""

def __init__(self, editable: bool = True, pdk: "Pdk | None" = None) -> None:
Expand Down Expand Up @@ -1633,6 +1621,11 @@ def transform(
no_warn: bool = False,
) -> "Instance | None":
"""Transforms the instance or cell with the transformation given."""
config.logger.warning(
"You are transforming the KCell {}. It is highly discouraged to do this."
" You probably want to transform an instance instead.",
self.name,
)
if self._locked:
raise LockedError(self)
if trans:
Expand All @@ -1645,6 +1638,26 @@ def transform(
else:
return self._kdb_cell.transform(inst_or_trans) # type:ignore[arg-type]

@property
def xmin(self) -> int:
"""Returns the x-coordinate of the left edge of the bounding box."""
return self._kdb_cell.bbox().left

@property
def ymin(self) -> int:
"""Returns the x-coordinate of the left edge of the bounding box."""
return self._kdb_cell.bbox().bottom

@property
def xmax(self) -> int:
"""Returns the x-coordinate of the left edge of the bounding box."""
return self._kdb_cell.bbox().right

@property
def ymax(self) -> int:
"""Returns the x-coordinate of the left edge of the bounding box."""
return self._kdb_cell.bbox().top


class Instance:
"""An Instance of a KCell.
Expand Down Expand Up @@ -1996,6 +2009,54 @@ def __repr__(self) -> str:
f"{self.parent_cell.name}: ports {port_names}, {self.kcl[self.cell_index]}"
)

def mirror_x(self, x: int = 0) -> None:
"""Mirror the instance at an x-axis."""
self.transform(kdb.Trans(2, True, 2 * x, 0))

def mirror_y(self, y: int = 0) -> None:
"""Mirror the instance at an y-axis."""
self.transform(kdb.Trans(0, True, 0, 2 * y))

@property
def xmin(self) -> int:
"""Returns the x-coordinate of the left edge of the bounding box."""
return self._instance.bbox().left

@xmin.setter
def xmin(self, __val: int) -> None:
"""Moves the instance so that the bbox's left x-coordinate."""
self.transform(kdb.Trans(__val - self.bbox().left, 0))

@property
def ymin(self) -> int:
"""Returns the x-coordinate of the left edge of the bounding box."""
return self._instance.bbox().bottom

@ymin.setter
def ymin(self, __val: int) -> None:
"""Moves the instance so that the bbox's left x-coordinate."""
self.transform(kdb.Trans(0, __val - self._instance.bbox().bottom))

@property
def xmax(self) -> int:
"""Returns the x-coordinate of the left edge of the bounding box."""
return self._instance.bbox().right

@xmax.setter
def xmax(self, __val: int) -> None:
"""Moves the instance so that the bbox's left x-coordinate."""
self.transform(kdb.Trans(__val - self.bbox().right, 0))

@property
def ymax(self) -> int:
"""Returns the x-coordinate of the left edge of the bounding box."""
return self._instance.bbox().top

@ymax.setter
def ymax(self, __val: int) -> None:
"""Moves the instance so that the bbox's left x-coordinate."""
self.transform(kdb.Trans(0, __val - self._instance.bbox().top))


class UMInstance:
"""Make the port able to dynamically give um based info."""
Expand Down Expand Up @@ -2082,6 +2143,14 @@ def move(
)
)

def mirror_x(self, x: float = 0) -> None:
"""Mirror the instance at an x-axis."""
self.parent.transform(kdb.DTrans(2, True, 2 * x, 0))

def mirror_y(self, y: float = 0) -> None:
"""Mirror the instance at an y-axis."""
self.parent.transform(kdb.DTrans(0, True, 0, 2 * y))


class Instances:
"""Holder for instances.
Expand Down Expand Up @@ -2784,6 +2853,22 @@ def show(
Path(gds_file).unlink()


def polygon_from_array(array: Iterable[tuple[int, int]]) -> kdb.Polygon:
"""Create a DPolygon from a 2D array-like structure. (dbu version).
Array-like: `[[x1,y1],[x2,y2],...]`
"""
return kdb.Polygon([kdb.Point(int(x), int(y)) for (x, y) in array])


def dpolygon_from_array(array: Iterable[tuple[float, float]]) -> kdb.DPolygon:
"""Create a DPolygon from a 2D array-like structure. (um version).
Array-like: `[[x1,y1],[x2,y2],...]`
"""
return kdb.DPolygon([kdb.DPoint(int(x), int(y)) for (x, y) in array])


__all__ = [
"KCell",
"Instance",
Expand Down

0 comments on commit f36fbd1

Please sign in to comment.