Skip to content

Commit

Permalink
Merge pull request #733 from bradley-w-snyder/flexgrid
Browse files Browse the repository at this point in the history
Read grid from PDK
  • Loading branch information
joamatab committed Sep 26, 2022
2 parents d7043fb + 55210a1 commit f01ed86
Show file tree
Hide file tree
Showing 15 changed files with 64 additions and 31 deletions.
6 changes: 5 additions & 1 deletion gdsfactory/component.py
Expand Up @@ -1096,7 +1096,7 @@ def write_gds(
gdspath: Optional[PathType] = None,
gdsdir: Optional[PathType] = None,
unit: float = 1e-6,
precision: float = 1e-9,
precision: Optional[float] = None,
timestamp: Optional[datetime.datetime] = _timestamp2019,
logging: bool = True,
on_duplicate_cell: Optional[str] = "warn",
Expand All @@ -1117,6 +1117,10 @@ def write_gds(
"overwrite": overwrite all duplicate cells with one of the duplicates, without warning.
None: do not try to resolve (at your own risk!)
"""
from gdsfactory.pdk import get_grid_size

precision = precision or get_grid_size() * 1e-6

gdsdir = (
gdsdir or pathlib.Path(tempfile.TemporaryDirectory().name) / "gdsfactory"
)
Expand Down
2 changes: 2 additions & 0 deletions gdsfactory/components/__init__.py
Expand Up @@ -220,6 +220,7 @@
)
from gdsfactory.components.taper_cross_section import (
taper_cross_section_linear,
taper_cross_section_parabolic,
taper_cross_section_sine,
)
from gdsfactory.components.taper_from_csv import (
Expand Down Expand Up @@ -270,6 +271,7 @@
crossing45=crossing45,
taper_cross_section_linear=taper_cross_section_linear,
taper_cross_section_sine=taper_cross_section_sine,
taper_cross_section_parabolic=taper_cross_section_parabolic,
taper=taper,
taper2=taper2,
taper_0p5_to_3_l36=taper_0p5_to_3_l36,
Expand Down
3 changes: 1 addition & 2 deletions gdsfactory/components/bend_circular.py
@@ -1,7 +1,6 @@
import gdsfactory as gf
from gdsfactory.add_padding import get_padding_points
from gdsfactory.component import Component
from gdsfactory.cross_section import strip
from gdsfactory.path import arc, extrude
from gdsfactory.snap import snap_to_grid
from gdsfactory.types import CrossSectionSpec
Expand All @@ -12,7 +11,7 @@ def bend_circular(
angle: float = 90.0,
npoints: int = 720,
with_bbox: bool = True,
cross_section: CrossSectionSpec = strip,
cross_section: CrossSectionSpec = "strip",
**kwargs
) -> Component:
"""Returns a radial arc.
Expand Down
2 changes: 2 additions & 0 deletions gdsfactory/components/grating_coupler_elliptical.py
Expand Up @@ -33,7 +33,9 @@ def ellipse_arc(
"""
theta = np.arange(theta_min, theta_max + angle_step, angle_step) * DEG2RAD
xs = a * np.cos(theta) + x0
xs = gf.snap.snap_to_grid(xs)
ys = b * np.sin(theta)
ys = gf.snap.snap_to_grid(ys)
return np.column_stack([xs, ys])


Expand Down
25 changes: 13 additions & 12 deletions gdsfactory/components/grating_coupler_rectangular_arbitrary.py
Expand Up @@ -4,7 +4,6 @@

import gdsfactory as gf
from gdsfactory.component import Component
from gdsfactory.components.rectangle import rectangle
from gdsfactory.components.taper import taper as taper_function
from gdsfactory.types import ComponentSpec, CrossSectionSpec, Floats, LayerSpec

Expand Down Expand Up @@ -96,18 +95,20 @@ def grating_coupler_rectangular_arbitrary(
gaps = gf.snap.snap_to_grid(gaps)

for width, gap in zip(widths, gaps):
xi += gap + width / 2
cgrating = c.add_ref(
rectangle(
size=(width, width_grating),
layer=layer,
port_type=None,
centered=True,
)
xi += gap
cgrating = c.add_polygon(
[
(0.0, 0.0),
(0.0, width_grating),
(width, width_grating),
(width, 0.0),
],
layer,
)
cgrating.move(
(gf.snap.snap_to_grid(xi), gf.snap.snap_to_grid(-0.5 * width_grating))
)
cgrating.x = gf.snap.snap_to_grid(xi)
cgrating.y = 0
xi += width / 2
xi += width

if layer_slab:
slab_xmin += length_taper
Expand Down
7 changes: 6 additions & 1 deletion gdsfactory/components/taper_cross_section.py
Expand Up @@ -12,6 +12,7 @@ def taper_cross_section(
length: float = 10,
npoints: int = 100,
linear: bool = False,
width_type: str = "sine",
**kwargs
) -> Component:
r"""Returns taper transition between cross_section1 and cross_section2.
Expand All @@ -22,6 +23,7 @@ def taper_cross_section(
length: transition length.
npoints: number of points.
linear: shape of the transition, sine when False.
width_type: shape of the transition ONLY IF linear is False
kwargs: cross_section settings for section2.
Expand All @@ -42,7 +44,7 @@ def taper_cross_section(
transition = gf.path.transition(
cross_section1=gf.get_cross_section(cross_section1),
cross_section2=gf.get_cross_section(cross_section2, **kwargs),
width_type="linear" if linear else "sine",
width_type="linear" if linear else width_type,
)
taper_path = gf.path.straight(length=length, npoints=npoints)

Expand All @@ -54,6 +56,9 @@ def taper_cross_section(

taper_cross_section_linear = gf.partial(taper_cross_section, linear=True, npoints=2)
taper_cross_section_sine = gf.partial(taper_cross_section, linear=False, npoints=101)
taper_cross_section_parabolic = gf.partial(
taper_cross_section, linear=False, width_type="parabolic", npoints=101
)


if __name__ == "__main__":
Expand Down
4 changes: 2 additions & 2 deletions gdsfactory/cross_section.py
Expand Up @@ -19,14 +19,14 @@
LAYER = TECH.layer
Layer = Tuple[int, int]
Layers = Tuple[Layer, ...]
WidthTypes = Literal["sine", "linear"]
WidthTypes = Literal["sine", "linear", "parabolic"]

LayerSpec = Union[Layer, int, str, None]
LayerSpecs = Union[List[LayerSpec], Tuple[LayerSpec, ...]]
Floats = Tuple[float, ...]
port_names_electrical = ("e1", "e2")
port_types_electrical = ("electrical", "electrical")
cladding_layers_optical = ((68, 0),) # for SiEPIC verification
cladding_layers_optical = ("DEVREC",) # for SiEPIC verification
cladding_offsets_optical = (0,) # for SiEPIC verification


Expand Down
5 changes: 3 additions & 2 deletions gdsfactory/geometry/boolean.py
Expand Up @@ -8,7 +8,7 @@
import gdsfactory as gf
from gdsfactory.component import Component
from gdsfactory.component_reference import ComponentReference
from gdsfactory.types import ComponentOrReference, Int2, Layer
from gdsfactory.types import ComponentOrReference, Int2, LayerSpec


@gf.cell
Expand All @@ -19,7 +19,7 @@ def boolean(
precision: float = 1e-4,
num_divisions: Union[int, Int2] = (1, 1),
max_points: int = 4000,
layer: Layer = (1, 0),
layer: LayerSpec = (1, 0),
) -> Component:
"""Performs boolean operations between 2 Component/Reference/list objects.
Expand Down Expand Up @@ -64,6 +64,7 @@ def boolean(
elif isinstance(e, Polygon):
polys.extend(e.polygons)

layer = gf.pdk.get_layer(layer)
gds_layer, gds_datatype = _parse_layer(layer)

operation = operation.lower().replace(" ", "")
Expand Down
2 changes: 1 addition & 1 deletion gdsfactory/geometry/functions.py
Expand Up @@ -165,7 +165,7 @@ def extrude_path(
spike_length: Union[float64, int, float] = 0,
start_angle: Optional[int] = None,
end_angle: Optional[int] = None,
grid: float = 0.001,
grid: float = 0.005,
) -> ndarray:
"""Deprecated. Use gf.path.Path.extrude() instead.
Expand Down
15 changes: 14 additions & 1 deletion gdsfactory/path.py
Expand Up @@ -137,6 +137,15 @@ def sine(t):
return sine


def _parabolic_transition(y1, y2):
dy = y2 - y1

def parabolic(t):
return y1 + np.sqrt(t) * dy

return parabolic


def _linear_transition(y1, y2):
dy = y2 - y1

Expand Down Expand Up @@ -225,8 +234,12 @@ def transition(
width_fun = _linear_transition(width1, width2)
elif width_type == "sine":
width_fun = _sinusoidal_transition(width1, width2)
elif width_type == "parabolic":
width_fun = _parabolic_transition(width1, width2)
else:
raise ValueError(f"width_type={width_type!r} must be {'sine','linear'}")
raise ValueError(
f"width_type={width_type!r} must be {'sine','linear','parabolic'}"
)

if section1.layer != section2.layer:
hidden = True
Expand Down
4 changes: 2 additions & 2 deletions gdsfactory/port.py
Expand Up @@ -401,8 +401,8 @@ def port_array(
]


def read_port_markers(component: object, layers: LayerSpecs = ((1, 10),)) -> Component:
"""Loads a GDS and returns the extracted ports from layer markers.
def read_port_markers(component: object, layers: LayerSpecs = ("PORT",)) -> Component:
"""Loads a GDS and returns the extracted ports from layer markers
Args:
component: or Component
Expand Down
1 change: 1 addition & 0 deletions gdsfactory/read/from_picwriter.py
Expand Up @@ -79,6 +79,7 @@ def from_picwriter(
datatypes = poly.datatypes

for polygon, layer, datatype in zip(polygons, layers, datatypes):
polygon = gf.snap.snap_to_grid(polygon)
c.add_polygon(polygon, layer=(layer, datatype))

c2 = Component(c.name)
Expand Down
3 changes: 1 addition & 2 deletions gdsfactory/routing/get_route_from_steps.py
Expand Up @@ -4,7 +4,6 @@

import gdsfactory as gf
from gdsfactory.components.via_corner import via_corner
from gdsfactory.cross_section import strip
from gdsfactory.port import Port
from gdsfactory.routing.manhattan import round_corners
from gdsfactory.types import (
Expand All @@ -21,7 +20,7 @@ def get_route_from_steps(
steps: Optional[List[Dict[str, float]]] = None,
bend: ComponentSpec = "bend_euler",
taper: Optional[ComponentSpec] = "taper",
cross_section: Union[CrossSectionSpec, MultiCrossSectionAngleSpec] = strip,
cross_section: Union[CrossSectionSpec, MultiCrossSectionAngleSpec] = "strip",
**kwargs
) -> Route:
"""Returns a route formed by the given waypoints steps.
Expand Down
14 changes: 10 additions & 4 deletions gdsfactory/snap.py
@@ -1,5 +1,5 @@
"""snaps values and coordinates to the GDS grid in nm."""
from typing import Tuple, Union
from typing import Optional, Tuple, Union

import numpy as np

Expand All @@ -21,13 +21,19 @@ def assert_on_2nm_grid(x: float) -> None:


def snap_to_grid(
x: Union[float, Tuple, np.ndarray], nm: int = 1
x: Union[float, Tuple, np.ndarray], nm: Optional[int] = None
) -> Union[float, Tuple, np.ndarray]:
if nm == 0:

if nm is None:
from gdsfactory.pdk import get_grid_size

nm = int(get_grid_size() * 1000)
elif nm == 0:
return x
elif nm < 0:
raise ValueError("nm must be an integer tolerance value greater than zero")
elif nm == 1:

if nm == 1:
y = np.round(np.asarray(x, dtype=float), 3)
else:
y = nm * np.round(np.asarray(x, dtype=float) * 1e3 / nm) / 1e3
Expand Down
2 changes: 1 addition & 1 deletion gdsfactory/types.py
Expand Up @@ -58,7 +58,7 @@
]
Axis = Literal["x", "y"]
NSEW = Literal["N", "S", "E", "W"]
WidthTypes = Literal["sine", "linear"]
WidthTypes = Literal["sine", "linear", "parabolic"]


class Label(LabelPhidl):
Expand Down

0 comments on commit f01ed86

Please sign in to comment.