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

Add rings #58

Merged
merged 6 commits into from
Aug 9, 2024
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions cspdk/si220/cells/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
"""Cells."""

from .containers import *
from .primitives import *
351 changes: 351 additions & 0 deletions cspdk/si220/cells/containers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,351 @@
"""This module contains cells that contain other cells."""

from functools import partial

import gdsfactory as gf
from gdsfactory.typings import (
Any,
CellSpec,
Component,
ComponentSpec,
CrossSectionSpec,
Strs,
)

gc_sc = "grating_coupler_elliptical_sc"
gc_so = "grating_coupler_elliptical_so"


def add_fiber_array_sc(
component: ComponentSpec = "straight_sc",
grating_coupler=gc_sc,
gc_port_name: str = "o1",
component_name: str | None = None,
cross_section: CrossSectionSpec = "xs_sc",
gc_rotation: float = -90,
**kwargs,
) -> Component:
"""Returns component with south routes and grating_couplers.

You can also use pads or other terminations instead of grating couplers.

Args:
component: component spec to connect to grating couplers.
grating_coupler: spec for route terminations.
gc_port_name: grating coupler input port name.
component_name: optional for the label.
cross_section: cross_section function.
gc_rotation: fiber coupler rotation in degrees. Defaults to -90.
kwargs: additional arguments.

Keyword Args:
bend: bend spec.
straight: straight spec.
fanout_length: if None, automatic calculation of fanout length.
max_y0_optical: in um.
with_loopback: True, adds loopback structures.
with_loopback_inside: True, adds loopback structures inside the component.
straight_separation: from edge to edge.
list_port_labels: None, adds TM labels to port indices in this list.
connected_port_list_ids: names of ports only for type 0 optical routing.
nb_optical_ports_lines: number of grating coupler lines.
force_manhattan: False
excluded_ports: list of port names to exclude when adding gratings.
grating_indices: list of grating coupler indices.
routing_straight: function to route.
routing_method: route_single.
optical_routing_type: None: auto, 0: no extension, 1: standard, 2: check.
input_port_indexes: to connect.
fiber_spacing: in um.
radius: optional radius of the bend. Defaults to the cross_section.
radius_loopback: optional radius of the loopback bend. Defaults to the cross_section.
route_backwards: route from component to grating coupler or vice-versa.

.. plot::
:include-source:

import gdsfactory as gf

c = gf.components.crossing()
cc = gf.routing.add_fiber_array(
component=c,
optical_routing_type=2,
grating_coupler=gf.components.grating_coupler_elliptical_te,
with_loopback=False
)
cc.plot()

"""
return gf.routing.add_fiber_array(
component=component,
grating_coupler=grating_coupler,
gc_port_name=gc_port_name,
gc_rotation=gc_rotation,
component_name=component_name,
cross_section=cross_section,
**kwargs,
)


add_fiber_array_so = partial(
add_fiber_array_sc,
component="straight_so",
grating_coupler=gc_so,
cross_section="xs_so",
)


def add_fiber_single_sc(
component: ComponentSpec = "straight_sc",
grating_coupler=gc_sc,
gc_port_name: str = "o1",
component_name: str | None = None,
cross_section: CrossSectionSpec = "xs_sc",
taper: ComponentSpec | None = None,
input_port_names: list[str] | tuple[str, ...] | None = None,
fiber_spacing: float = 70,
with_loopback: bool = True,
loopback_spacing: float = 100.0,
**kwargs,
) -> Component:
"""Returns component with south routes and grating_couplers.

You can also use pads or other terminations instead of grating couplers.

Args:
component: component spec to connect to grating couplers.
grating_coupler: spec for route terminations.
gc_port_name: grating coupler input port name.
component_name: optional for the label.
cross_section: cross_section function.
taper: taper spec.
input_port_names: list of input port names to connect to grating couplers.
fiber_spacing: spacing between fibers.
with_loopback: adds loopback structures.
loopback_spacing: spacing between loopback and test structure.
kwargs: additional arguments.

Keyword Args:
bend: bend spec.
straight: straight spec.
fanout_length: if None, automatic calculation of fanout length.
max_y0_optical: in um.
with_loopback: True, adds loopback structures.
straight_separation: from edge to edge.
list_port_labels: None, adds TM labels to port indices in this list.
connected_port_list_ids: names of ports only for type 0 optical routing.
nb_optical_ports_lines: number of grating coupler lines.
force_manhattan: False
excluded_ports: list of port names to exclude when adding gratings.
grating_indices: list of grating coupler indices.
routing_straight: function to route.
routing_method: route_single.
optical_routing_type: None: auto, 0: no extension, 1: standard, 2: check.
gc_rotation: fiber coupler rotation in degrees. Defaults to -90.
input_port_indexes: to connect.

.. plot::
:include-source:

import gdsfactory as gf

c = gf.components.crossing()
cc = gf.routing.add_fiber_array(
component=c,
optical_routing_type=2,
grating_coupler=gf.components.grating_coupler_elliptical_te,
with_loopback=False
)
cc.plot()

"""
return gf.routing.add_fiber_single(
component=component,
grating_coupler=grating_coupler,
gc_port_name=gc_port_name,
component_name=component_name,
cross_section=cross_section,
taper=taper,
input_port_names=input_port_names,
fiber_spacing=fiber_spacing,
with_loopback=with_loopback,
loopback_spacing=loopback_spacing,
**kwargs,
)


add_fiber_single_so = partial(
add_fiber_single_sc,
component="straight_so",
grating_coupler=gc_so,
cross_section="xs_so",
)


def add_pads_top(
component: ComponentSpec = "straight_heater_metal",
port_names: Strs | None = None,
component_name: str | None = None,
cross_section: CrossSectionSpec = "metal_routing",
pad_port_name: str = "e1",
pad: ComponentSpec = "pad",
bend: ComponentSpec = "wire_corner",
straight_separation: float = 15.0,
pad_spacing: float | str = "pad_spacing",
taper: ComponentSpec | None = None,
port_type: str = "electrical",
allow_width_mismatch: bool = True,
fanout_length: float | None = 80,
route_width: float | list[float] | None = 0,
**kwargs,
) -> Component:
"""Returns new component with ports connected top pads.

Args:
component: component spec to connect to.
port_names: list of port names to connect to pads.
component_name: optional for the label.
cross_section: cross_section function.
pad_port_name: pad port name.
pad: pad function.
bend: bend function.
straight_separation: from edge to edge.
pad_spacing: spacing between pads.
taper: taper function.
port_type: port type.
allow_width_mismatch: if True, allows width mismatch.
fanout_length: length of the fanout.
route_width: width of the route.
kwargs: additional arguments.

.. plot::
:include-source:

import gdsfactory as gf
c = gf.c.nxn(
xsize=600,
ysize=200,
north=2,
south=3,
wg_width=10,
layer="M3",
port_type="electrical",
)
cc = gf.routing.add_pads_top(component=c, port_names=("e1", "e4"), fanout_length=50)
cc.plot()

"""
return gf.routing.add_pads_top(
component=component,
port_names=port_names,
component_name=component_name,
cross_section=cross_section,
pad_port_name=pad_port_name,
pad=pad,
bend=bend,
straight_separation=straight_separation,
pad_spacing=pad_spacing,
taper=taper,
port_type=port_type,
allow_width_mismatch=allow_width_mismatch,
fanout_length=fanout_length,
route_width=route_width,
**kwargs,
)


def pack_doe(
doe: ComponentSpec,
settings: dict[str, tuple[Any, ...]],
do_permutations: bool = False,
function: CellSpec | None = None,
**kwargs,
) -> Component:
"""Packs a component DOE (Design of Experiment) using pack.

Args:
doe: function to return Components.
settings: component settings.
do_permutations: for each setting.
function: to apply (add padding, grating couplers).
kwargs: for pack.

Keyword Args:
spacing: Minimum distance between adjacent shapes.
aspect_ratio: (width, height) ratio of the rectangular bin.
max_size: Limits the size into which the shapes will be packed.
sort_by_area: Pre-sorts the shapes by area.
density: Values closer to 1 pack tighter but require more computation.
precision: Desired precision for rounding vertex coordinates.
text: Optional function to add text labels.
text_prefix: for labels. For example. 'A' for 'A1', 'A2'...
text_offsets: relative to component size info anchor. Defaults to center.
text_anchors: relative to component (ce cw nc ne nw sc se sw center cc).
name_prefix: for each packed component (avoids the Unnamed cells warning).
Note that the suffix contains a uuid so the name will not be deterministic.
rotation: for each component in degrees.
h_mirror: horizontal mirror in y axis (x, 1) (1, 0). This is the most common.
v_mirror: vertical mirror using x axis (1, y) (0, y).
"""
return gf.components.pack_doe(
doe=doe,
settings=settings,
do_permutations=do_permutations,
function=function,
**kwargs,
)


def pack_doe_grid(
doe: ComponentSpec,
settings: dict[str, tuple[Any, ...]],
do_permutations: bool = False,
function: CellSpec | None = None,
with_text: bool = False,
**kwargs,
) -> Component:
"""Packs a component DOE (Design of Experiment) using grid.

Args:
doe: function to return Components.
settings: component settings.
do_permutations: for each setting.
function: to apply to component (add padding, grating couplers).
with_text: includes text label.
kwargs: for grid.

Keyword Args:
spacing: between adjacent elements on the grid, can be a tuple for
different distances in height and width.
separation: If True, guarantees elements are separated with fixed spacing
if False, elements are spaced evenly along a grid.
shape: x, y shape of the grid (see np.reshape).
If no shape and the list is 1D, if np.reshape were run with (1, -1).
align_x: {'x', 'xmin', 'xmax'} for x (column) alignment along.
align_y: {'y', 'ymin', 'ymax'} for y (row) alignment along.
edge_x: {'x', 'xmin', 'xmax'} for x (column) (ignored if separation = True).
edge_y: {'y', 'ymin', 'ymax'} for y (row) (ignored if separation = True).
rotation: for each component in degrees.
h_mirror: horizontal mirror y axis (x, 1) (1, 0). most common mirror.
v_mirror: vertical mirror using x axis (1, y) (0, y).
"""
return gf.components.pack_doe_grid(
doe=doe,
settings=settings,
do_permutations=do_permutations,
function=function,
with_text=with_text,
**kwargs,
)


if __name__ == "__main__":
from cspdk.si220 import PDK

PDK.activate()

c = add_fiber_single_sc()
# c =gf.get_component(gc_sc)
# c = pack_doe()
c.pprint_ports()
c.show()
Loading
Loading