Skip to article frontmatterSkip to article content

gdsfactory

You can import gdsfactory.as gf.

functions: - import_gds(): returns a Component from a GDS

classes:

- Component
- Port
- TECH

modules:

- c: components
- routing

gdsfactory

You can import gdsfactory.as gf.

functions: - import_gds(): returns a Component from a GDS

classes:

- Component
- Port
- TECH

modules:

- c: components
- routing

gdsfactory.add_labels

Add Label to each component port.

get_input_label_text_dash

def get_input_label_text_dash(port: Port,
                              gc: ComponentReference | Component,
                              gc_index: int | None = None,
                              component_name: str | None = None,
                              prefix: str = "",
                              suffix: str = "") -> str

Returns text with GratingName-ComponentName-PortName.

get_input_label_text_dash_loopback

def get_input_label_text_dash_loopback(port: Port,
                                       gc: ComponentReference | Component,
                                       gc_index: int | None = None,
                                       component_name: str | None = None,
                                       prefix: str = "") -> str

Returns text with GratingName-ComponentName-Loopback.

get_input_label_text

def get_input_label_text(port: Port,
                         gc: ComponentReference | Component,
                         gc_index: int | None = None,
                         component_name: str | None = None,
                         component_prefix: str = "",
                         prefix: str = "opt",
                         suffix: str = "") -> str

Returns text string for an optical port based on grating coupler.

{label_prefix}{polarization}{wavelength_nm}_({prefix}{component_name})

Arguments:

  • port - to label.
  • gc - grating coupler component or reference.
  • gc_index - grating_coupler index, which grating_coupler we are labelling.
  • component_name - optional name.
  • component_prefix - component prefix.
  • prefix - prefix to add to the label.

get_input_label

def get_input_label(
        port: Port,
        gc: ComponentReference,
        gc_index: int | None = None,
        gc_port_name: str = "o1",
        layer_label: LayerSpec = "LABEL",
        component_name: str | None = None,
        get_input_label_text_function=get_input_label_text) -> Label

Returns a label with component info for a given grating coupler.

Test equipment to extract grating coupler coordinates and match it to the component.

Arguments:

  • port - port to label.
  • gc - grating coupler reference.
  • gc_index - grating coupler index.
  • gc_port_name - name of grating coupler port.
  • layer_label - layer of the label.
  • component_name - for the label.
  • get_input_label_text_function - function to get input label.

get_input_label_electrical

def get_input_label_electrical(port: Port,
                               gc_index: int = 0,
                               component_name: str | None = None,
                               layer_label: LayerSpec = "LABEL",
                               gc: ComponentReference | None = None) -> Label

Returns a label to test component info for a given electrical port.

This is the label used by T&M to extract grating coupler coordinates and match it to the component.

Arguments:

  • port - to label.
  • gc_index - index of the label.
  • component_name - Optional component_name.
  • layer_label - for label.
  • gc - ignored.

add_labels

def add_labels(component: Component,
               get_label_function: Callable = get_input_label_electrical,
               layer_label: LayerSpec = "LABEL",
               gc: Component | None = None,
               **kwargs) -> Component

Returns component with labels on ports.

Arguments:

  • component - to add labels to.

  • get_label_function - function to get label.

  • layer_label - layer_label.

  • gc - Optional grating coupler.

    keyword Args:

  • layer - port GDS layer.

  • prefix - with in port name.

  • suffix - select ports with port name suffix.

  • orientation - in degrees.

  • width - for ports to add label.

  • layers_excluded - List of layers to exclude.

  • port_type - optical, electrical, ...

  • clockwise - if True, sort ports clockwise, False: counter-clockwise.

Returns:

original component with labels.

add_siepic_labels

def add_siepic_labels(component: Component,
                      model: str = "auto",
                      library: str = "auto",
                      label_layer: LayerSpec = "DEVREC",
                      spice_params: dict | list | str | None = None,
                      label_spacing: float = 0.2) -> Component

Adds labels and returns the same component.

Arguments:

  • component - component.
  • model - Lumerical Interconnect model. ‘auto’ attempts to extract this from the cross_section.
  • library - Lumerical Interconnect library. ‘auto’ attempts to extract this from the cross_section.
  • label_layer - layer for writing SiEPIC labels.
  • spice_params - spice parameters (in microns). Either pass in a dict with parameter, value pairs, or pass a list of values to extract from component info.
  • label_spacing - separation distance between labels in um.

add_labels_to_ports

def add_labels_to_ports(component: Component,
                        label_layer: LayerSpec = "LABEL",
                        port_type: str | None = None,
                        **kwargs) -> Component

Add labels to component ports.

Arguments:

  • component - to add labels.

  • label_layer - layer spec for the label.

  • port_type - to select ports.

    keyword Args:

  • layer - select ports with GDS layer.

  • prefix - select ports with prefix in port name.

  • suffix - select ports with port name suffix.

  • orientation - select ports with orientation in degrees.

  • width - select ports with port width.

  • layers_excluded - List of layers to exclude.

  • port_type - select ports with port_type (optical, electrical, vertical_te).

  • clockwise - if True, sort ports clockwise, False: counter-clockwise.

add_labels_to_ports_x_y

def add_labels_to_ports_x_y(component: Component,
                            label_layer: LayerSpec = "LABEL",
                            port_type: str | None = None,
                            **kwargs) -> Component

Add labels to component ports. Prepends -x-y coordinates

Arguments:

  • component - to add labels.

  • label_layer - layer spec for the label.

  • port_type - to select ports.

    keyword Args:

  • layer - select ports with GDS layer.

  • prefix - select ports with prefix in port name.

  • suffix - select ports with port name suffix.

  • orientation - select ports with orientation in degrees.

  • width - select ports with port width.

  • layers_excluded - List of layers to exclude.

  • port_type - select ports with port_type (optical, electrical, vertical_te).

  • clockwise - if True, sort ports clockwise, False: counter-clockwise.

get_labels

def get_labels(component: ComponentOrReference,
               get_label_function: Callable = get_input_label_electrical,
               layer_label: LayerSpec = "LABEL",
               gc: Component | None = None,
               component_name: str | None = None,
               **kwargs) -> list[Label]

Returns component labels on ports.

Arguments:

  • component - to add labels to.

  • 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.

  • prefix - look for prefix in port name.

  • suffix - select ports with port name suffix.

  • orientation - in degrees.

  • width - for ports to add label.

  • layers_excluded - List of layers to exclude.

  • port_type - optical, electrical, ...

  • clockwise - if True, sort ports clockwise, False: counter-clockwise.

Returns:

list of component labels.

gdsfactory.path

You can define a path with a list of points combined with a cross-section.

A path can be extruded using any CrossSection returning a Component The CrossSection defines the layer numbers, widths and offsets

Adapted from PHIDL https://github.com/amccaugh/phidl/ by Adam McCaughan

Path Objects

class Path(_GeometryHelper)

Path object for smooth Paths. You can extrude a Path with a CrossSection to create a Component.

Arguments:

  • path - array-like[N][2], Path, or list of Paths. Points or Paths to append() initially.

__init__

def __init__(path=None) -> None

Creates an empty path.

__repr__

def __repr__() -> str

Returns path points.

__len__

def __len__() -> int

Returns path points.

__iadd__

def __iadd__(path_or_points) -> Path

Adds points to current path.

__add__

def __add__(path) -> Path

Returns new path concatenating current and new path.

bbox

@property
def bbox()

Returns the bounding box of the Path.

append

def append(path)

Attach Path to the end of this Path.

The input path automatically rotates and translates such that it continues smoothly from the previous segment.

Arguments:

path : Path, array-like[N][2], or list of Paths The input path that will be appended.

offset

def offset(offset: float | Callable[..., float] = 0)

Offsets Path so that it follows the Path centerline plus an offset.

The offset can either be a fixed value, or a function of the form my_offset(t) where t goes from 0->1

Arguments:

  • offset - int or float, callable. Magnitude of the offset

move

def move(origin=(0, 0), destination=None, axis=None)

Moves the Path from the origin point to the destination.

Both origin and destination can be 1x2 array-like or a Port.

Arguments:

origin : array-like[2], Port Origin point of the move. destination : array-like[2], Port Destination point of the move. axis : {‘x’, ‘y’} Direction of move.

rotate

def rotate(angle: float = 45, center: Float2 | None = (0, 0))

Rotates all Polygons in the Component around the specified center point.

If no center point specified will rotate around (0,0).

Arguments:

  • angle - Angle to rotate the Component in degrees.
  • center - array-like[2] or None. component of the Component.

mirror

def mirror(p1: Float2 = (0, 1), p2: Float2 = (0, 0))

Mirrors the Path across the line formed between the two specified points.

points may be input as either single points [1,2] or array-like[N][2], and will return in kind.

Arguments:

  • p1 - First point of the line.
  • p2 - Second point of the line.

length

def length() -> float

Return cumulative length.

curvature

def curvature()

Calculates Path curvature.

The curvature is numerically computed so areas where the curvature jumps instantaneously (such as between an arc and a straight segment) will be slightly interpolated, and sudden changes in point density along the curve can cause discontinuities.

Returns:

s : array-like[N] The arc-length of the Path K : array-like[N] The curvature of the Path

hash_geometry

def hash_geometry(precision: float = 1e-4) -> str

Computes an SHA1 hash of the points in the Path and the start_angle and end_angle.

Arguments:

  • precision - Rounding precision for the the objects in the Component. For instance, a precision of 1e-2 will round a point at (0.124, 1.748) to (0.12, 1.75)

Returns:

str Hash result in the form of an SHA1 hex digest string.

.. code::

hash( hash(First layer information: [layer1, datatype1]), hash(Polygon 1 on layer 1 points: [(x1,y1),(x2,y2),(x3,y3)] ), hash(Polygon 2 on layer 1 points: [(x1,y1),(x2,y2),(x3,y3),(x4,y4)] ), hash(Polygon 3 on layer 1 points: [(x1,y1),(x2,y2),(x3,y3)] ), hash(Second layer information: [layer2, datatype2]), hash(Polygon 1 on layer 2 points: [(x1,y1),(x2,y2),(x3,y3),(x4,y4)] ), hash(Polygon 2 on layer 2 points: [(x1,y1),(x2,y2),(x3,y3)] ), )

__get_validators__

@classmethod
def __get_validators__(cls)

For pydantic.

plot

def plot() -> None

Plot path in matplotlib.

.. plot:: :include-source:

import gdsfactory as gf

p = gf.path.euler(radius=10)
p.plot()

extrude

def extrude(cross_section: CrossSectionSpec | None = None,
            layer: LayerSpec | None = None,
            width: float | None = None,
            widths: Float2 | None = None,
            simplify: float | None = None,
            shear_angle_start: float | None = None,
            shear_angle_end: float | None = None) -> Component

Returns Component by extruding a Path with a CrossSection.

A path can be extruded using any CrossSection returning a Component The CrossSection defines the layer numbers, widths and offsets.

Arguments:

  • p - a path is a list of points (arc, straight, euler).

  • cross_section - to extrude.

  • layer - optional layer.

  • width - optional width in um.

  • widths - tuple of starting and end width for a linear taper.

  • simplify - Tolerance value for the simplification algorithm. All points that can be removed without changing the resulting polygon by more than the value listed here will be removed.

  • shear_angle_start - an optional angle to shear the starting face by (in degrees).

  • shear_angle_end - an optional angle to shear the ending face by (in degrees).

    .. plot:: :include-source:

    import gdsfactory as gf

    p = gf.path.euler(radius=10) c = p.extrude(layer=(1, 0), width=0.5) c.plot()

copy

def copy()

Returns a copy of the Path.

transition_exponential

def transition_exponential(y1, y2, exp=0.5)

Returns the function for an exponential transition.

Arguments:

  • y1 - start width in um.
  • y2 - end width in um.
  • exp - exponent.

transition_adiabatic

def transition_adiabatic(w1: float,
                         w2: float,
                         neff_w,
                         wavelength: float = 1.55,
                         alpha: float = 1,
                         max_length: float = 200,
                         num_points_ODE: int = 2000)

Returns the points for an optimal adiabatic transition for well-guided modes.

Arguments:

  • w1 - start width in um.
  • w2 - end width in um.
  • neff_w - a callable that returns the effective index as a function of width By default, use a compact model of neff(y) for fundamental 1550 nm TE mode of 220nm-thick core with 3.45 index, fully clad with 1.44 index. Many coefficients are needed to capture the behaviour.
  • wavelength - wavelength, in same units as widths
  • alpha - parameter that scales the rate of width change
    • closer to 0 means longer and more adiabatic;
    • 1 is the intuitive limit beyond which higher order modes are excited;
    • [2] reports good performance up to 1.4 for fundamental TE in SOI (for multiple core thicknesses)
  • max_length - maximum length in um.
  • num_points_ODE - number of samplings points for the ODE solve.

References:

[1] Burns, W. K., et al. “Optical waveguide parabolic coupling horns.” Appl. Phys. Lett., vol. 30, no. 1, 1 Jan. 1977, pp. 28-30, doi:10.1063/1.89199. [2] Fu, Yunfei, et al. “Efficient adiabatic silicon-on-insulator waveguide taper.” Photonics Res., vol. 2, no. 3, 1 June 2014, pp. A41-A44, doi:10.1364/PRJ.2.000A41.

transition

def transition(cross_section1: CrossSection,
               cross_section2: CrossSection,
               width_type: WidthTypes = "sine",
               **kwargs) -> Transition

Returns a smoothly-transitioning between two CrossSections.

Only cross-sectional elements that have the name (as in X.add(..., name = ‘wg’) ) parameter specified in both input CrosSections will be created. Port names will be cloned from the input CrossSections in reverse.

Arguments:

  • cross_section1 - First CrossSection.
  • cross_section2 - Second CrossSection.
  • width_type - sine or linear. Sets the type of width transition used if any widths are different between the two input CrossSections.

along_path

@cell
def along_path(p: Path, component: ComponentSpec, spacing: float,
               padding: float) -> Component

Returns Component containing many copies of component along p.

Places as many copies of component along each segment of p as possible under the given constraints. spacing is always followed precisely, but actual padding may exceed the provided value to place components evenly.

Arguments:

  • p - Path to place components along.
  • component - Component to repeat along the path. The unrotated version of this object should be oriented for placement on a horizontal line.
  • spacing - distance between component placements.
  • padding - minimum distance from the path start to the first component.

extrude

@cell
def extrude(p: Path,
            cross_section: CrossSectionSpec | None = None,
            layer: LayerSpec | None = None,
            width: float | None = None,
            widths: Float2 | None = None,
            simplify: float | None = None,
            shear_angle_start: float | None = None,
            shear_angle_end: float | None = None) -> Component

Returns Component extruding a Path with a cross_section.

A path can be extruded using any CrossSection returning a Component The CrossSection defines the layer numbers, widths and offsets

Arguments:

  • p - a path is a list of points (arc, straight, euler).
  • cross_section - to extrude.
  • layer - optional layer to extrude.
  • width - optional width to extrude.
  • widths - tuple of starting and end width.
  • simplify - Tolerance value for the simplification algorithm. All points that can be removed without changing the resulting. polygon by more than the value listed here will be removed.
  • shear_angle_start - an optional angle to shear the starting face by (in degrees).
  • shear_angle_end - an optional angle to shear the ending face by (in degrees).

arc

def arc(radius: float = 10.0,
        angle: float = 90,
        npoints: int | None = None,
        start_angle: float | None = -90) -> Path

Returns a radial arc.

Arguments:

  • radius - minimum radius of curvature.

  • angle - total angle of the curve.

  • npoints - Number of points used per 360 degrees. Defaults to pdk.bend_points_distance.

  • start_angle - initial angle of the curve for drawing, default -90 degrees.

    .. plot:: :include-source:

    import gdsfactory as gf

    p = gf.path.arc(radius=10, angle=45) p.plot()

euler

def euler(radius: float = 10,
          angle: float = 90,
          p: float = 0.5,
          use_eff: bool = False,
          npoints: int | None = None) -> Path

Returns an euler bend that adiabatically transitions from straight to curved.

radius is the minimum radius of curvature of the bend. However, if use_eff is set to True, radius corresponds to the effective radius of curvature (making the curve a drop-in replacement for an arc). If p < 1.0, will create a “partial euler” curve as described in Vogelbacher et. al. Vogelbacher et al. (2019)

Arguments:

  • radius - minimum radius of curvature.

  • angle - total angle of the curve.

  • p - Proportion of the curve that is an Euler curve.

  • use_eff - If False: radius is the minimum radius of curvature of the bend. If True: The curve will be scaled such that the endpoints match an arc. with parameters radius and angle.

  • npoints - Number of points used per 360 degrees.

    .. plot:: :include-source:

    import gdsfactory as gf

    p = gf.path.euler(radius=10, angle=45, p=1, use_eff=True, npoints=720) p.plot()

straight

def straight(length: float = 10.0, npoints: int = 2) -> Path

Returns a straight path.

For transitions you should increase have at least 100 points

Arguments:

  • length - of straight.
  • npoints - number of points.

spiral_archimedean

def spiral_archimedean(min_bend_radius: float, separation: float,
                       number_of_loops: float, npoints: int) -> Path

Returns an Archimedean spiral.

Arguments:

  • radius - Inner radius of the spiral.

  • separation - Separation between the loops in um.

  • number_of_loops - number of loops.

  • npoints - number of Points.

    .. plot:: :include-source:

    import gdsfactory as gf

    p = gf.path.spiral_archimedean(min_bend_radius=5, separation=2, number_of_loops=3, npoints=200) p.plot()

smooth

def smooth(points: Coordinates,
           radius: float = 4.0,
           bend: PathFactory = euler,
           **kwargs) -> Path

Returns a smooth Path from a series of waypoints.

Arguments:

  • points - array-like[N][2] List of waypoints for the path to follow.

  • radius - radius of curvature, passed to bend.

  • bend - bend function that returns a path that round corners.

  • npoints - Number of points used per 360 degrees for the bend.

  • kwargs - Extra keyword arguments that will be passed to bend.

    .. plot:: :include-source:

    import gdsfactory as gf

    p = gf.path.smooth(([0, 0], [0, 10], [10, 10])) p.plot()

gdsfactory.pdk

PDK stores layers, cross_sections, cell functions ...

evanescent_coupler_sample

def evanescent_coupler_sample() -> None

Evanescent coupler example.

Arguments:

  • coupler_length - length of coupling (min: 0.0, max: 200.0, um).

extract_args_from_docstring

def extract_args_from_docstring(docstring: str) -> dict[str, Any] | None

This function extracts settings from a function’s docstring for uPDK format.

Arguments:

  • docstring - The function from which to extract YAML in the docstring.

Returns:

  • settings dict - The extracted YAML data as a dictionary.

GdsWriteSettings Objects

class GdsWriteSettings(BaseModel)

Settings to use when writing to GDS.

CellDecoratorSettings Objects

class CellDecoratorSettings(BaseModel)

Settings for cell_without_validator decorator function in gdsfactory.cell.

Pdk Objects

class Pdk(BaseModel)

Store layers, cross_sections, cell functions, simulation_settings ...

only one Pdk can be active at a given time.

Arguments:

  • name - PDK name.
  • cross_sections - dict of cross_sections factories.
  • cells - dict of parametric cells that return Components.
  • symbols - dict of symbols names to functions. default_symbol_factory:
  • base_pdk - a pdk to copy from and extend.
  • default_decorator - decorate all cells, if not otherwise defined on the cell.
  • layers - maps name to gdslayer/datatype. For example dict(si=(1, 0), sin=(34, 0)).
  • layer_stack - maps name to layer numbers, thickness, zmin, sidewall_angle. if can also contain material properties (refractive index, nonlinear coefficient, sheet resistance ...).
  • layer_views - includes layer name to color, opacity and pattern.
  • layer_transitions - transitions between different cross_sections.
  • sparameters_path - to store Sparameters simulations.
  • modes_path - to store Sparameters simulations.
  • interconnect_cml_path - path to interconnect CML (optional).
  • warn_off_grid_ports - raises warning when extruding paths with offgrid ports.
  • constants - dict of constants for the PDK.
  • materials_index - material spec names to material spec, which can be:
  • string - material name.
  • float - refractive index. float, float: refractive index real and imaginary part.
  • function - function of wavelength.
  • routing_strategies - functions enabled to route.
  • gds_write_settings - to write GDSII files.
  • oasis_settings - to write OASIS files.
  • cell_decorator_settings - settings for cell_without_validator decorator function in gdsfactory.cell.
  • bend_points_distance - default points distance for bends in um.

grid_size

@property
def grid_size()

The minimum unit resolvable on the layout grid, relative to the unit.

validate_layers

def validate_layers(layers_required: list[Layer] | None = None)

Raises ValueError if layers_required are not in Pdk.

activate

def activate() -> None

Set current pdk to the active pdk (if not already active).

register_cells

def register_cells(**kwargs) -> None

Register cell factories.

register_cross_sections

def register_cross_sections(**kwargs) -> None

Register cross_sections factories.

register_cells_yaml

def register_cells_yaml(dirpath: PathType | None = None,
                        update: bool = False,
                        **kwargs) -> None

Load *.pic.yml YAML files and register them as cells.

Arguments:

  • dirpath - directory to recursive search for YAML cells.
  • update - does not raise ValueError if cell already registered.

Arguments:

  • cell_name - cell function. To update cells dict.

remove_cell

def remove_cell(name: str)

Removes cell from a PDK.

get_cell

def get_cell(cell: CellSpec, **kwargs) -> ComponentFactory

Returns ComponentFactory from a cell spec.

get_component

def get_component(component: ComponentSpec, **kwargs) -> Component

Returns component from a component spec.

get_symbol

def get_symbol(component: ComponentSpec, **kwargs) -> Component

Returns a component’s symbol from a component spec.

get_cross_section

def get_cross_section(cross_section: CrossSectionSpec,
                      **kwargs) -> CrossSection | Transition

Returns cross_section from a cross_section spec.

get_layer

def get_layer(layer: LayerSpec) -> Layer

Returns layer from a layer spec.

to_updk

def to_updk() -> str

Export to uPDK YAML definition.

get_constant

def get_constant(constant_name: Any) -> Any

If constant_name is a string returns a the value from the dict.

get_routing_strategies

def get_routing_strategies() -> dict[str, Callable]

Gets a dictionary of named routing functions available to the PDK, if defined, or gdsfactory defaults otherwise.

gdsfactory.serialization

Serialize component settings into YAML or strings.

DEFAULT_SERIALIZATION_MAX_DIGITS

By default, the maximum number of digits retained when serializing float-like arrays

clean_value_json

def clean_value_json(
        value: Any) -> str | int | float | dict | list | bool | None

Return JSON serializable object.

clean_value_name

def clean_value_name(value: Any) -> str

Returns a string representation of an object.

gdsfactory.cell

Cell decorator for functions that return a Component.

clear_cache

def clear_cache() -> None

Clears Component CACHE.

Settings Objects

class Settings(BaseModel)

info

derived properties (length, resistance)

cell_without_validator

def cell_without_validator(func: _F) -> _F

Decorator for Component functions.

Similar to cell decorator, this one does not validate_arguments using type annotations

I recommend using cell instead

cell

def cell(func: _F) -> _F

Decorator for Component functions.

Wraps cell_without_validator Validates type annotations with pydantic.

Implements a cache so that if a component has already been build it will return the component from the cache directly. This avoids creating two exact Components that have the same name.

When decorate your functions with cell you get:

  • cache: avoids creating duplicated Components.
  • name: names Components uniquely name based on parameters.
  • metadata: adds Component.metadata with default, changed and full Args.

Note the cell decorator does not take any arguments. Keyword Args are applied the resulting Component.

Arguments:

  • autoname bool - True renames Component based on args and kwargs. True by default.

  • name str - Optional name.

  • cache bool - returns Component from the CACHE if it already exists. Avoids having duplicated cells with the same name. If False overrides CACHE creates a new Component.

  • flatten bool - False by default. True flattens component hierarchy.

  • info - updates Component.info dict.

  • prefix str - name_prefix, defaults to function name.

  • max_name_length int - truncates name beyond some characters with a hash.

  • decorator Callable - function to apply to Component.

    A decorator is a function that runs over a function, so when you do.

    .. code::

    import gdsfactory as gf

    gf.cell def mzi_with_bend(): c = gf.Component() mzi = c << gf.components.mzi() bend = c << gf.components.bend_euler() return c

    it’s equivalent to

    .. code::

    def mzi_with_bend(): c = gf.Component() mzi = c << gf.components.mzi() bend = c << gf.components.bend_euler(radius=radius) return c

    mzi_with_bend_decorated = gf.cell(mzi_with_bend)

declarative_cell

def declarative_cell(cls: type[Any]) -> Callable[..., Component]

Decorator to turn a dataclass into a cell. Work in progress.

wg

@cell
def wg(length: int = 3, layer: tuple[int, int] = (1, 0)) -> Component

Dummy component for testing.

wg2

@cell
def wg2(wg1=wg)

Dummy component for testing.

demo

@cell
def demo(length: int = 3, wg_width: float = 0.5) -> Component

Demo Dummy cell.

gdsfactory.component

Component is a canvas for geometry.

Adapted from PHIDL https://github.com/amccaugh/phidl/ by Adam McCaughan

valid_plotters

qt and holoviews are deprecated

Component Objects

class Component(_GeometryHelper)

A Component is an empty canvas where you add polygons, references and ports (to connect to other components).

  • stores settings that you use to build the component
  • stores info that you want to use
  • can return ports by type (optical, electrical ...)
  • can return netlist for circuit simulation
  • can write to GDS, OASIS
  • can show in KLayout, matplotlib, 3D
  • can return copy, mirror, flattened (no references)

Arguments:

  • name - component_name. Use cell decorator for auto-naming.

  • with_uuid - adds unique identifier.

    Properties:

  • info - dictionary that includes

    • derived properties
    • external metadata (test_protocol, docs, ...)
    • simulation_settings
    • function_name
    • name: for the component

    settings:

  • full - full settings passed to the function to create component.

  • changed - changed settings.

  • default - default component settings.

  • child - dict info from the children, if any.

__init__

def __init__(name: str = "Unnamed", with_uuid: bool = False) -> None

Initialize the Component object.

__iter__

def __iter__()

You can iterate over polygons, paths, labels and references.

get_polygon_bbox

def get_polygon_bbox(default: float = 0.0,
                     top: float | None = None,
                     bottom: float | None = None,
                     right: float | None = None,
                     left: float | None = None) -> shapely.Polygon

Returns shapely Polygon with bounding box.

Arguments:

  • default - default padding in um.
  • top - north padding in um.
  • bottom - south padding in um.
  • right - east padding in um.
  • left - west padding in um.

get_polygons

def get_polygons(
    by_spec: bool | tuple[int, int] = False,
    depth: int | None = None,
    include_paths: bool = True,
    as_array: bool = True,
    as_shapely: bool = False,
    as_shapely_merged: bool = False
) -> list[Polygon] | dict[tuple[int, int], list[Polygon]]

Return a list of polygons in this cell.

Arguments:

  • by_spec - bool or layer If True, the return value is a dictionary with the polygons of each individual pair (layer, datatype), which are used as keys. If set to a tuple of (layer, datatype), only polygons with that specification are returned.

  • depth - integer or None If not None, defines from how many reference levels to retrieve polygons. References below this level will result in a bounding box. If by_spec is True the key will be the name of this cell.

  • include_paths - If True, polygonal representation of paths are also included in the result.

  • as_array - when as_array=false, return the Polygon objects instead. polygon objects have more information (especially when by_spec=False) and are faster to retrieve.

  • as_shapely - returns shapely polygons.

  • as_shapely_merged - returns a shapely polygonize.

    Returns

  • out - list of array-like[N][2] or dictionary List containing the coordinates of the vertices of each polygon, or dictionary with with the list of polygons (if by_spec is True).

Notes:

Instances of FlexPath and RobustPath are also included in the result by computing their polygonal boundary.

get_dependencies

def get_dependencies(recursive: bool = False) -> list[Component]

Return a list of Components referenced by this Component.

Arguments:

  • recursive - If True returns dependencies recursively.

__getitem__

def __getitem__(key) -> Port

Access reference ports.

__lshift__

def __lshift__(element) -> ComponentReference

Convenience operator equivalent to add_ref().

unlock

def unlock() -> None

Only do this if you know what you are doing.

lock

def lock() -> None

Makes sure components can’t add new elements or move existing ones.

Components lock automatically when going into the CACHE to ensure one component does not change others

__setitem__

def __setitem__(key, element)

Allow adding polygons and cell references.

like D[‘arc3’] = pg.arc()

Arguments:

  • key - Alias name.
  • element - Object that will be accessible by alias name.

__get_validators__

@classmethod
def __get_validators__(cls)

Get validators for the Component object.

validate

@classmethod
def validate(cls, v, _info)

Pydantic assumes component is valid if the following are true.

  • name characters < pdk.cell_decorator_settings.max_name_length
  • is not empty (has references or polygons)

add_label

def add_label(text: str = "hello",
              position: tuple[float, float] = (0.0, 0.0),
              magnification: float = 1.0,
              rotation: float = 0,
              anchor: str = "o",
              layer: LayerSpec = "TEXT",
              x_reflection: bool = False) -> Label

Adds Label to the Component.

Arguments:

  • text - Label text.
  • position - x-, y-coordinates of the Label location.
  • magnification - Magnification factor for the Label text.
  • rotation - Angle rotation of the Label text.
  • anchor - {‘n’, ‘e’, ‘s’, ‘w’, ‘o’, ‘ne’, ‘nw’, ...} Position of the anchor relative to the text.
  • layer - Specific layer(s) to put Label on.
  • x_reflection - True reflects across the horizontal axis before rotation.

bbox

@property
def bbox()

Returns the bounding box of the ComponentReference.

ports_layer

@property
def ports_layer() -> dict[str, str]

Returns a mapping from layer0_layer1_E0: portName.

port_by_orientation_cw

def port_by_orientation_cw(key: str, **kwargs)

Returns port by indexing them clockwise.

port_by_orientation_ccw

def port_by_orientation_ccw(key: str, **kwargs)

Returns port by indexing them clockwise.

get_ports_xsize

def get_ports_xsize(**kwargs) -> float

Returns xdistance from east to west ports.

Arguments:

  • layer - port GDS layer.
  • prefix - with in port name.
  • orientation - in degrees.
  • width - port width.
  • layers_excluded - List of layers to exclude.
  • port_type - optical, electrical, ...

get_ports_ysize

def get_ports_ysize(**kwargs) -> float

Returns ydistance from east to west ports.

Arguments:

  • layer - port GDS layer.
  • prefix - with in port name.
  • orientation - in degrees.
  • width - port width (um).
  • layers_excluded - List of layers to exclude.
  • port_type - optical, electrical, ...

plot_netlist

def plot_netlist(with_labels: bool = True,
                 font_weight: str = "normal",
                 **kwargs)

Plots a netlist graph with networkx.

Arguments:

  • with_labels - add label to each node.
  • font_weight - normal, bold.
  • **kwargs - keyword arguments for the get_netlist function

plot_netlist_flat

def plot_netlist_flat(with_labels: bool = True,
                      font_weight: str = "normal",
                      **kwargs)

Plots a netlist graph with networkx.

Arguments:

  • flat - if true, will plot the flat netlist
  • with_labels - add label to each node.
  • font_weight - normal, bold.
  • **kwargs - keyword arguments for the get_netlist function

write_netlist

def write_netlist(filepath: str) -> None

Write netlist in YAML.

write_netlist_dot

def write_netlist_dot(filepath: str | None = None) -> None

Write netlist graph in DOT format.

get_netlist

def get_netlist(**kwargs) -> dict[str, Any]

From Component returns instances, connections and placements dict.

Arguments:

  • component - to extract netlist.
  • full_settings - True returns all, false changed settings.
  • tolerance - tolerance in nm to consider two ports connected.
  • exclude_port_types - optional list of port types to exclude from netlisting.
  • get_instance_name - function to get instance name.
  • allow_multiple - False to raise an error if more than two ports share the same connection. if True, will return key: [value] pairs with [value] a list of all connected instances.

Returns:

Netlist dict (instances, connections, placements, ports)

  • instances - Dict of instance name and settings.
  • connections - Dict of Instance1Name,portName: Instance2Name,portName.
  • placements - Dict of instance names and placements (x, y, rotation).
  • ports - Dict portName: ComponentName,port.
  • name - name of component.

get_netlist_recursive

def get_netlist_recursive(**kwargs) -> dict[str, DictConfig]

Returns recursive netlist for a component and subcomponents.

Arguments:

  • component - to extract netlist.
  • component_suffix - suffix to append to each component name. useful if to save and reload a back-annotated netlist.
  • get_netlist_func - function to extract individual netlists.
  • full_settings - True returns all, false changed settings.
  • tolerance - tolerance in nm to consider two ports connected.
  • exclude_port_types - optional list of port types to exclude from netlisting.
  • get_instance_name - function to get instance name.
  • allow_multiple - False to raise an error if more than two ports share the same connection. if True, will return key: [value] pairs with [value] a list of all connected instances.

Returns:

Dictionary of netlists, keyed by the name of each component.

get_netlist_flat

def get_netlist_flat(**kwargs) -> dict[str, DictConfig]

Returns a netlist where all subinstances are exposed and independently named.

Arguments:

  • component - to extract netlist.
  • component_suffix - suffix to append to each component name. useful if to save and reload a back-annotated netlist.
  • get_netlist_func - function to extract individual netlists.
  • full_settings - True returns all, false changed settings.
  • tolerance - tolerance in nm to consider two ports connected.
  • exclude_port_types - optional list of port types to exclude from netlisting.
  • get_instance_name - function to get instance name.
  • allow_multiple - False to raise an error if more than two ports share the same connection. if True, will return key: [value] pairs with [value] a list of all connected instances.

Returns:

Dictionary of netlists, keyed by the name of each component.

assert_ports_on_grid

def assert_ports_on_grid(nm: int = 1) -> None

Asserts that all ports are on grid.

get_ports

def get_ports(depth=None)

Returns copies of all the ports of the Component, rotated and translated so that they’re in their top-level position.

The Ports returned are copies of the originals, but each copy has the same uid as the original so that they can be traced back to the original if needed.

Arguments:

depth : int or None If not None, defines from how many reference levels to retrieve Ports from.

Returns:

port_list : list of Port List of all Ports in the Component.

get_ports_dict

def get_ports_dict(**kwargs) -> dict[str, Port]

Returns a dict of ports.

Arguments:

  • layer - port GDS layer.
  • prefix - select ports with prefix in port name.
  • suffix - select ports with port name suffix.
  • orientation - select ports with orientation in degrees.
  • width - select ports with port width.
  • layers_excluded - List of layers to exclude.
  • port_type - select ports with port_type (optical, electrical, vertical_te).
  • clockwise - if True, sort ports clockwise, False: counter-clockwise.

get_ports_list

def get_ports_list(**kwargs) -> list[Port]

Returns list of ports.

Arguments:

  • layer - select ports with GDS layer.
  • prefix - select ports with prefix in port name.
  • suffix - select ports with port name suffix.
  • orientation - select ports with orientation in degrees.
  • orientation - select ports with orientation in degrees.
  • width - select ports with port width.
  • layers_excluded - List of layers to exclude.
  • port_type - select ports with port_type (optical, electrical, vertical_te).
  • clockwise - if True, sort ports clockwise, False: counter-clockwise.

ref

def ref(position: Coordinate = (0, 0),
        port_id: str | None = None,
        rotation: float = 0,
        h_mirror: bool = False,
        v_mirror: bool = False) -> ComponentReference

Returns Component reference.

Arguments:

  • position - x, y position.
  • port_id - name of the port.
  • rotation - in degrees.
  • h_mirror - horizontal mirror using y axis (x, 1) (1, 0). This is the most common mirror.
  • v_mirror - vertical mirror using x axis (1, y) (0, y).

ref_center

def ref_center(position=(0, 0))

Returns a reference of the component centered at (x=0, y=0).

__repr__

def __repr__() -> str

Return a string representation of the object.

pprint

def pprint() -> None

Prints component info.

pprint_ports

def pprint_ports() -> None

Prints ports in a rich table.

metadata_child

@property
def metadata_child() -> dict

Returns metadata from child if any, Otherwise returns component own.

metadata Great to access the children metadata at the bottom of the hierarchy.

add_port

def add_port(name: str | object | None = None,
             center: tuple[float, float] | None = None,
             width: float | None = None,
             orientation: float | None = None,
             port: Port | None = None,
             layer: LayerSpec | None = None,
             port_type: str | None = None,
             cross_section: CrossSectionSpec | None = None,
             shear_angle: float | None = None) -> Port

Add port to component.

You can copy an existing port like add_port(port = existing_port) or create a new port add_port(myname, mycenter, mywidth, myorientation). You can also copy an existing port with a new name add_port(port = existing_port, name = new_name)

Arguments:

  • name - port name.
  • center - x, y.
  • width - in um.
  • orientation - in deg.
  • port - optional port.
  • layer - port layer.
  • port_type - optical, electrical, vertical_dc, vertical_te, vertical_tm. Defaults to optical.
  • cross_section - port cross_section.
  • shear_angle - an optional angle to shear port face in degrees.

add_ports

def add_ports(ports: Iterable[Port] | dict[str, Port],
              prefix: str = "",
              suffix: str = "",
              **kwargs) -> None

Add a list or dict of ports.

you can include a prefix to add to the new port names to avoid name conflicts.

Arguments:

  • ports - list or dict of ports.
  • prefix - to prepend to each port name.
  • suffix - to append to each port name.

remove_layers

def remove_layers(layers: list[LayerSpec],
                  include_labels: bool = True,
                  invert_selection: bool = False,
                  recursive: bool = True) -> Component

Remove a list of layers and returns the same Component.

Arguments:

  • layers - list of layers to remove.
  • include_labels - remove labels on those layers.
  • invert_selection - removes all layers except layers specified.
  • recursive - operate on the cells included in this cell.

extract

def extract(layers: list[tuple[int, int] | str]) -> Component

Extract polygons from a Component and returns a new Component.

add_polygon

def add_polygon(
        points,
        layer: str | int | tuple[int, int] | np.nan = np.nan) -> Polygon

Adds a Polygon to the Component.

Arguments:

  • points - Coordinates of the vertices of the Polygon.
  • layer - layer spec to add polygon on.

add_ref_container

def add_ref_container(component: Component) -> ComponentReference

Add reference, ports and copy_child_info.

copy_child_info

def copy_child_info(component: Component) -> None

Copy and settings info from child component into parent.

Parent components can access child cells settings.

size_info

@property
def size_info() -> SizeInfo

Size info of the component.

is_unlocked

def is_unlocked() -> None

Raises error if Component is locked.

add

def add(element) -> None

Add a new element or list of elements to this Component.

Arguments:

  • element - Polygon, ComponentReference or iterable The element or iterable of elements to be inserted in this cell.

Raises:

  • MutabilityError - if component is locked.

add_array

def add_array(component: Component,
              columns: int = 2,
              rows: int = 2,
              spacing: tuple[float, float] = (100, 100),
              alias: str | None = None) -> ComponentReference

Creates a ComponentReference reference to a Component.

Arguments:

  • component - The referenced component.

  • columns - Number of columns in the array.

  • rows - Number of rows in the array.

  • spacing - array-like[2] of int or float. Distance between adjacent columns and adjacent rows.

  • alias - str or None. Alias of the referenced Component.

    Returns

  • a - ComponentReference containing references to the Component.

distribute

def distribute(elements="all",
               direction="x",
               spacing=100,
               separation=True,
               edge="center")

Distributes the specified elements in the Component.

Arguments:

elements : array-like of objects or ‘all’ Elements to distribute. direction : {‘x’, ‘y’} Direction of distribution; either a line in the x-direction or y-direction. spacing : int or float Distance between elements. separation : bool If True, guarantees elements are separated with a fixed spacing between; if False, elements are spaced evenly along a grid. edge : {‘x’, ‘xmin’, ‘xmax’, ‘y’, ‘ymin’, ‘ymax’} Which edge to perform the distribution along (unused if separation == True)

align

def align(elements="all", alignment="ymax")

Align elements in the Component.

Arguments:

elements : array-like of objects, or ‘all’ Elements in the Component to align. alignment : {‘x’, ‘y’, ‘xmin’, ‘xmax’, ‘ymin’, ‘ymax’} Which edge to align along (e.g. ‘ymax’ will move the elements such that all of their topmost points are aligned).

flatten

def flatten(single_layer: LayerSpec | None = None)

Returns a flattened copy of the component.

Flattens the hierarchy of the Component such that there are no longer any references to other Components. All polygons and labels from underlying references are copied and placed in the top-level Component. If single_layer is specified, all polygons are moved to that layer.

Arguments:

  • single_layer - move all polygons are moved to the specified (optional).

flatten_reference

def flatten_reference(ref: ComponentReference) -> None

From existing cell replaces reference with a flatten reference which has the transformations already applied.

Transformed reference keeps the original name.

Arguments:

  • ref - the reference to flatten into a new cell.

flatten_invalid_refs

def flatten_invalid_refs(grid_size: float | None = None,
                         updated_components=None,
                         traversed_components=None) -> Component

Returns new component with flattened references.

add_ref

def add_ref(component: Component,
            alias: str | None = None,
            **kwargs) -> ComponentReference

Add ComponentReference to the current Component.

Arguments:

  • component - Component.
  • alias - named_references.

Arguments:

  • columns - Number of columns in the array.
  • rows - Number of rows in the array.
  • spacing - Distances between adjacent columns and adjacent rows.
  • origin - array-like[2] of int or float Position where the cell is inserted. rotation : int or float Angle of rotation of the reference (in degrees). magnification : int or float Magnification factor for the reference. x_reflection : bool If True, the reference is reflected parallel to the x direction before being rotated. name : str (optional) A name for the reference (if provided).

layers

@property
def layers() -> set[tuple[int, int]]

Returns a set of the Layers in the Component.

get_layers

def get_layers() -> set[tuple[int, int]]

Return a set of (layer, datatype).

.. code ::

import gdsfactory as gf
gf.components.straight().get_layers() == {(1, 0), (111, 0)}

get_layer_names

def get_layer_names() -> list[tuple[int, int]]

Return layer names used in the design.

.. code ::

import gdsfactory as gf
gf.components.straight().get_names() == ['WG']

_repr_html_

def _repr_html_()

Show geometry in KLayout and in matplotlib for Jupyter Notebooks.

add_pins_triangle

def add_pins_triangle(port_marker_layer: Layer = (1, 10),
                      layer_label: Layer = (1, 10),
                      make_copy: bool = True) -> Component

Returns component with triangular pins.

plot_widget

def plot_widget(show_ports: bool = True,
                port_marker_layer: Layer = (1, 10)) -> None

Returns ipython widget for klayout visualization.

Arguments:

  • show_ports - shows component with port markers and labels.
  • port_marker_layer - for the ports.

plot_klayout

def plot_klayout(show_ports: bool = True,
                 port_marker_layer: Layer = (1, 10),
                 show_labels: bool = False)

Returns klayout image.

If it fails to import klayout defaults to matplotlib.

Arguments:

  • show_ports - shows component with port markers and labels.
  • port_marker_layer - for the ports.
  • show_labels - shows labels.

plot_kweb

def plot_kweb()

Shows current gds in kweb.

plot_matplotlib

def plot_matplotlib(**kwargs) -> None

Plot component using matplotlib.

Arguments:

  • show_ports - Sets whether ports are drawn.
  • show_subports - Sets whether subports (ports that belong to references) are drawn.
  • label_aliases - Sets whether aliases are labeled with a text name.
  • new_window - If True, each call to quickplot() will generate a separate window.
  • blocking - If True, calling quickplot() will pause execution of (“block”) the remainder of the python code until the quickplot() window is closed. If False, the window will be opened and code will continue to run.
  • zoom_factor - Sets the scaling factor when zooming the quickplot window with the mousewheel/trackpad.
  • interactive_zoom - Enables using mousewheel/trackpad to zoom.
  • fontsize - for labels.
  • layers_excluded - list of layers to exclude.
  • layer_views - layer_views colors loaded from Klayout.
  • min_aspect - minimum aspect ratio.

plot

def plot(plotter: str | None = None, **kwargs)

Returns component plot using klayout, matplotlib, holoviews or qt.

We recommend using klayout.

Arguments:

  • plotter - plot backend (‘matplotlib’, ‘widget’, ‘klayout’, ‘kweb’).

show

def show(show_ports: bool = False,
         show_subports: bool = False,
         port_marker_layer: Layer = (1, 10),
         **kwargs) -> None

Show component in KLayout.

returns a copy of the Component, so the original component remains intact. with pins markers on each port show_ports = True, and optionally also the ports from the references (show_subports=True)

Arguments:

  • show_ports - shows component with port markers and labels.
  • show_subports - add ports markers and labels to references.
  • port_marker_layer - for the ports.

Arguments:

  • gdspath - GDS file path to write to.
  • gdsdir - directory for the GDS file. Defaults to /tmp/.
  • unit - unit size for objects in library. 1um by default.
  • precision - for object dimensions in the library (m). 1nm by default.
  • timestamp - Defaults to 2019-10-25. If None uses current time.

write_gds

def write_gds(gdspath: PathType | None = None,
              gdsdir: PathType | None = None,
              **kwargs) -> Path

Write component to GDS and returns gdspath.

Arguments:

  • gdspath - GDS file path to write to.
  • gdsdir - directory for the GDS file. Defaults to /tmp/randomFile/gdsfactory.

Arguments:

  • unit - unit size for objects in library. 1um by default.
  • precision - for dimensions in the library (m). 1nm by default.
  • logging - disable GDS path logging, for example for showing it in KLayout.
  • on_duplicate_cell - specify how to resolve duplicate-named cells. Choose one of the following:
  • "warn" default - overwrite all duplicate cells with one of the duplicates (arbitrarily).
  • "error" - throw a ValueError when attempting to write a gds with duplicate cells.
  • "overwrite" - overwrite all duplicate cells with one of the duplicates, without warning.
  • on_uncached_component - Literal[“warn”, “error”] = “warn”
  • flatten_invalid_refs - flattens component references which have invalid transformations.
  • max_points - Maximal number of vertices per polygon. Polygons with more vertices that this are automatically fractured.
  • with_metadata - writes metadata in YAML format.
  • with_netlist - writes a netlist in JSON format.
  • netlist_function - function to generate the netlist.

write_oas

def write_oas(gdspath: PathType | None = None,
              gdsdir: PathType | None = None,
              **kwargs) -> Path

Write component to GDS and returns gdspath.

Arguments:

  • gdspath - GDS file path to write to.
  • gdsdir - directory for the GDS file. Defaults to /tmp/randomFile/gdsfactory.

Arguments:

  • unit - unit size for objects in library. 1um by default.
  • precision - for dimensions in the library (m). 1nm by default.
  • logging - disable GDS path logging, for example for showing it in KLayout.
  • on_duplicate_cell - specify how to resolve duplicate-named cells. Choose one of the following:
  • "warn" default - overwrite all duplicate cells with one of the duplicates (arbitrarily).
  • "error" - throw a ValueError when attempting to write a gds with duplicate cells.
  • "overwrite" - overwrite all duplicate cells with one of the duplicates, without warning.
  • None - do not try to resolve (at your own risk!)
  • on_uncached_component - Literal[“warn”, “error”] = “warn”
  • flatten_invalid_refs - flattens component references which have invalid transformations.
  • compression_level - Level of compression for cells (between 0 and 9). Setting to 0 will disable cell compression, 1 gives the best speed and 9, the best compression.
  • detect_rectangles - Store rectangles in compressed format.
  • detect_trapezoids - Store trapezoids in compressed format.
  • circle_tolerance - Tolerance for detecting circles. If less or equal to 0, no detection is performed. Circles are stored in compressed format. validation (“crc32”, “checksum32”, None) – type of validation to include in the saved file.
  • standard_properties - Store standard OASIS properties in the file.

write_gds_with_metadata

def write_gds_with_metadata(*args, **kwargs) -> Path

Write component in GDS and metadata (component settings) in YAML.

to_dict

def to_dict(ignore_components_prefix: list[str] | None = None,
            ignore_functions_prefix: list[str] | None = None,
            with_cells: bool = False,
            with_ports: bool = True) -> dict[str, Any]

Returns Dict representation of a component.

Arguments:

  • ignore_components_prefix - for components to ignore when exporting.
  • ignore_functions_prefix - for functions to ignore when exporting.
  • with_cells - write cells recursively.
  • with_ports - write port information dict.

to_yaml

def to_yaml(**kwargs) -> str

Write Dict representation of a component in YAML format.

Arguments:

  • ignore_components_prefix - for components to ignore when exporting.
  • ignore_functions_prefix - for functions to ignore when exporting.
  • with_cells - write cells recursively.
  • with_ports - write port information.

auto_rename_ports

def auto_rename_ports(**kwargs) -> None

Rename ports by orientation NSEW (north, south, east, west).

Arguments:

  • function - to rename ports.

  • select_ports_optical - to select optical ports.

  • select_ports_electrical - to select electrical ports.

  • prefix_optical - prefix.

  • prefix_electrical - prefix.

    .. code::

    3 4 |__| 2 -| |- 5 | | 1 -|______|- 6 | | 8 7

auto_rename_ports_orientation

def auto_rename_ports_orientation(**kwargs) -> None

Rename ports by orientation NSEW (north, south, east, west).

Arguments:

  • function - to rename ports.

  • select_ports_optical - to select ports. select_ports_electrical: prefix_optical: prefix_electrical:

    .. code::

    N0 N1 || W1 -| |- E1 | | W0 -|____|- E0 | | S0 S1

move

def move(origin: Float2 = (0, 0),
         destination: Float2 | None = None,
         axis: Axis | None = None) -> Component

Returns new Component with a moved reference to the original.

component.

Arguments:

  • origin - of component.
  • destination - x, y.
  • axis - x or y.

mirror

def mirror(p1: Float2 = (0, 1), p2: Float2 = (0, 0), **kwargs) -> Component

Returns new Component with a mirrored reference.

Arguments:

  • p1 - first point to define mirror axis.
  • p2 - second point to define mirror axis.

rotate

def rotate(angle: float = 90, **kwargs) -> Component

Returns new component with a rotated reference to the original.

Arguments:

  • angle - in degrees.

add_padding

def add_padding(**kwargs) -> Component

Returns same component with padding.

Arguments:

  • component - for padding.
  • layers - list of layers. suffix for name.
  • default - default padding (50um).
  • top - north padding.
  • bottom - south padding.
  • right - east padding.
  • left - west padding.

absorb

def absorb(reference) -> Component

Absorbs polygons from ComponentReference into Component.

Destroys the reference in the process but keeping the polygon geometry.

Arguments:

  • reference - ComponentReference to be absorbed into the Component.

remove

def remove(items)

Removes items from a Component, which can include Ports, PolygonSets CellReferences, ComponentReferences and Labels.

Arguments:

  • items - list of Items to be removed from the Component.

hash_geometry

def hash_geometry(precision: float = 1e-4) -> str

Returns an SHA1 hash of the geometry in the Component.

For each layer, each polygon is individually hashed and then the polygon hashes are sorted, to ensure the hash stays constant regardless of the ordering the polygons. Similarly, the layers are sorted by (layer, datatype).

Arguments:

  • precision - Rounding precision for the the objects in the Component. For instance, a precision of 1e-2 will round a point at (0.124, 1.748) to (0.12, 1.75).

get_labels

def get_labels(apply_repetitions=True,
               depth: int | None = None,
               layer=None) -> list[Label]

Return labels.

Arguments:

apply_repetitions:.

  • depth - None returns all labels and 0 top level.
  • layer - layerspec.

remove_labels

def remove_labels() -> None

Remove labels.

get_info

def get_info()

Gathers the .info dictionaries from every sub-Component and returns them in a list.

Arguments:

  • depth - int or None If not None, defines from how many reference levels to retrieve Ports from.

Returns:

list of dictionaries List of the “.info” property dictionaries from all sub-Components

remap_layers

def remap_layers(layermap,
                 include_labels: bool = True,
                 include_paths: bool = True) -> Component

Returns a copy of the component with remapped layers.

Arguments:

  • 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.

to_3d

def to_3d(layer_views: LayerViews | None = None,
          layer_stack: LayerStack | None = None,
          exclude_layers: tuple[Layer, ...] | None = None)

Return Component 3D trimesh Scene.

Arguments:

  • component - to extrude in 3D.
  • layer_views - layer colors from Klayout Layer Properties file. Defaults to active PDK.layer_views.
  • layer_stack - contains thickness and zmin for each layer. Defaults to active PDK.layer_stack.
  • exclude_layers - layers to exclude.

to_np

def to_np(nm_per_pixel: int = 20,
          layers: Layers = ((1, 0), ),
          values: tuple[float, ...] | None = None,
          pad_width: int = 1) -> np.ndarray

Returns a pixelated numpy array from Component polygons.

Arguments:

  • component - Component.
  • nm_per_pixel - you can go from 20 (coarse) to 4 (fine).
  • layers - to convert. Order matters (latter overwrite former).
  • values - associated to each layer (defaults to 1).
  • pad_width - padding pixels around the image.

write_stl

def write_stl(filepath: str,
              layer_stack: LayerStack | None = None,
              exclude_layers: tuple[Layer, ...] | None = None,
              use_layer_name: bool = False,
              hull_invalid_polygons: bool = True,
              scale: float | None = None) -> None

Write a Component to STL for 3D printing.

Arguments:

  • filepath - to write STL to.
  • layer_stack - contains thickness and zmin for each layer.
  • exclude_layers - layers to exclude.
  • use_layer_name - If True, uses LayerLevel names in output filenames rather than gds_layer and gds_datatype.
  • hull_invalid_polygons - If True, replaces invalid polygons (determined by shapely.Polygon.is_valid) with its convex hull.
  • scale - Optional factor by which to scale meshes before writing.

write_gerber

def write_gerber(dirpath, layermap_to_gerber_layer, options) -> None

Arguments:

  • dirpath - directory to write gerber files to.
  • layermap_to_gerber_layer - dictionary of layermap to gerber layer.
  • options - dictionary of options for gerber export.
  • header - List[str] | None = None
  • mode - Literal[“mm”, “in”] = “mm”
  • resolution - float = 1e-6
  • int_size - int = 4

to_gmsh

def to_gmsh(type: str,
            layer_stack: LayerStack,
            z: float | None = None,
            xsection_bounds=None,
            wafer_padding: float = 0.0,
            wafer_layer: Layer = (99999, 0),
            *args,
            **kwargs)

Returns a gmsh mesh of the component for finite element simulation.

Arguments:

  • type - one of “xy”, “uz”, or “3D”. Determines the type of mesh to return.
  • layer_stack - LayerStack object containing layer information.
  • z - used to define z-slice for xy meshing.
  • xsection_bounds - used to define in-plane line for uz meshing.
  • wafer_padding - padding beyond bbox to add to WAFER layers.
  • wafer_layer - layer to use for WAFER padding.

Arguments:

Arguments for the target meshing function in gplugins.gmsh

offset

def offset(distance: float = 0.1,
           use_union: bool = True,
           precision: float = 1e-4,
           join: str = "miter",
           tolerance: int = 2,
           layer: LayerSpec = "WG") -> Component

Returns new Component with polygons eroded or dilated by an offset.

Arguments:

  • distance - Distance to offset polygons. Positive values expand, negative shrink.
  • use_union - If True, use union of all polygons to offset. If False, offset
  • precision - Desired precision for rounding vertex coordinates.
  • join - {‘miter’, ‘bevel’, ‘round’} Type of join used to create polygon offset
  • tolerance - For miter joints, this number must be at least 2 represents the maximal distance in multiples of offset between new vertices and their original position before beveling to avoid spikes at acute joints. For round joints, it indicates the curvature resolution in number of points per full circle.
  • layer - Specific layer to put polygon geometry on.

copy

def copy(D: Component,
         references=None,
         ports=None,
         polygons=None,
         paths=None,
         name=None,
         labels=None) -> Component

Returns a Component copy.

Arguments:

  • D - component to copy.

recurse_structures

def recurse_structures(
        component: Component,
        ignore_components_prefix: list[str] | None = None,
        ignore_functions_prefix: list[str] | None = None) -> dict[str, Any]

Recurse component and components references recursively.

Arguments:

  • component - component to recurse.
  • ignore_components_prefix - list of prefix to ignore.
  • ignore_functions_prefix - list of prefix to ignore.

flatten_invalid_refs_recursive

def flatten_invalid_refs_recursive(component: Component,
                                   grid_size: float | None = None,
                                   updated_components=None,
                                   traversed_components=None) -> Component

Recursively flattens component references which have invalid transformations (i.e. non-90 deg rotations or sub-grid translations) returns a copy if any subcells have been modified.

WARNING: this function will produce same-name copies of cells. It is strictly meant to be used on write of the GDS file and should not be mixed with other cells, or you will likely experience issues with duplicate cells

Arguments:

  • component - the component to fix (in place).
  • grid_size - the GDS grid size, in um, defaults to active PDK.get_grid_size() any translations with higher resolution than this are considered invalid.
  • updated_components - dict of components transformed. Should always be None, except for recursive.
  • traversed_components - the set of component names which have been traversed. Should always be None, except for recursive invocations.

gdsfactory.route_info

route_info

def route_info(cs_type: str,
               length: float,
               length_eff: float | None = None,
               taper: bool = False,
               **kwargs) -> dict[str, float | str]

Returns route info dict for pathlength analysis.

Arguments:

  • cs_type - cross section type.
  • length - length.
  • length_eff - effective length (i.e. an equivalent straight length of a bend).
  • taper - True if this component is a taper.
  • kwargs - other attributes to track.

Returns:

A dictionary of routing attributes.

route_info_from_cs

def route_info_from_cs(cs: CrossSectionSpec,
                       length: float,
                       length_eff: float | None = None,
                       **kwargs) -> dict[str, float | str]

Returns route info dict for pathlength analysis.

Arguments:

  • cs - cross section object or spec.
  • length - length.
  • length_eff - effective length (i.e. an equivalent straight length of a bend).
  • kwargs - other attributes to track.

Returns:

A dictionary of routing attributes.

gdsfactory.pack

pack a list of components into as few components as possible.

Adapted from PHIDL https://github.com/amccaugh/phidl/ by Adam McCaughan

pack

@validate_call
def pack(component_list: list[ComponentSpec],
         spacing: float = 10.0,
         aspect_ratio: Float2 = (1.0, 1.0),
         max_size: tuple[float | None, float | None] = (None, None),
         sort_by_area: bool = True,
         density: float = 1.1,
         precision: float = 1e-2,
         text: ComponentSpec | None = None,
         text_prefix: str = "",
         text_mirror: bool = False,
         text_rotation: int = 0,
         text_offsets: tuple[Float2, ...] = ((0, 0), ),
         text_anchors: tuple[Anchor, ...] = ("cc", ),
         name_prefix: str | None = None,
         rotation: int = 0,
         h_mirror: bool = False,
         v_mirror: bool = False,
         add_ports_prefix: bool = True,
         add_ports_suffix: bool = False) -> list[Component]

Pack a list of components into as few Components as possible.

Arguments:

  • component_list - list or tuple.

  • 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’ will produce ‘A1’, ‘A2’, ...

  • text_mirror - if True mirrors text.

  • text_rotation - Optional text rotation.

  • 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 - optional component rotation 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).

  • add_ports_prefix - adds port names with prefix.

  • add_ports_suffix - adds port names with suffix.

    .. plot:: :include-source:

    import gdsfactory as gf from functools import partial

    components = [gf.components.triangle(x=i) for i in range(1, 10)] c = gf.pack( components, spacing=20.0, max_size=(100, 100), text=partial(gf.components.text, justify=“center”), text_prefix=“R”, name_prefix=“demo”, text_anchors=[“nc”], text_offsets=[(-10, 0)], v_mirror=True, ) c[0].plot()

test_pack

def test_pack() -> None

Test packing function.

test_pack_with_settings

def test_pack_with_settings() -> None

Test packing function with custom settings.

gdsfactory.geometry.boolean_polygons

boolean_polygons

def boolean_polygons(operand1: ComponentReference | Component | gdstk.Polygon,
                     operand2: ComponentReference | Component | gdstk.Polygon,
                     operation: str,
                     output_layer: LayerSpec = (0, 0),
                     precision: float = 1e-3) -> list[gdstk.Polygon]

Perform a boolean operation and return the list of resulting Polygons. See gdstk docs for details.

Arguments:

  • operand1 - polygon set A.

  • operand2 - polygon set B.

  • operation - the name of the operation to perform, i.e. “or”, “and”, “not”, or “xor”.

  • output_layer - the layer to assign the resulting polygons.

  • precision - the precision used for the operation, in microns.

  • Returns - a list of gdstk Polygons on the specified output layer.

gdsfactory.geometry.maskprep

get_polygons_over_under

def get_polygons_over_under(component: ComponentOrReference,
                            layers: LayerSpecs,
                            distances: Floats,
                            use_union: bool = True,
                            precision: float = 1e-4,
                            join: str = "miter",
                            tolerance: int = 2) -> list[gdstk.Polygon]

Returns list polygons dilated and eroded by an offset. Cleans min width gap and acute angle DRC errors equal to distances.

Arguments:

  • component - Component containing polygons to offset.
  • layers - list of layers to remove min gap errors.
  • distances - Distance to offset polygons. By expanding and shrinking it merges polygons. If you want to fix min gaps of 0.5 use 0.5.
  • precision - Desired precision for rounding vertex coordinates.
  • join - {‘miter’, ‘bevel’, ‘round’} Type of join used to create polygon offset
  • tolerance - For miter joints, this number must be at least 2 represents the maximal distance in multiples of offset between new vertices and their original position before beveling to avoid spikes at acute joints. For round joints, it indicates the curvature resolution in number of points per full circle.
  • layer - Specific layer to put polygon geometry on.

Returns:

Component containing a polygon(s) with the specified offset applied.

over_under

@gf.cell
def over_under(component: ComponentSpec,
               layers: LayerSpecs,
               remove_original: bool = False,
               **kwargs) -> Component

Returns cleaned component.

Arguments:

component:

  • layers - list of layers.
  • remove_original - remove original layers.

gdsfactory.geometry.fillet

fillet

def fillet(operand: ComponentReference | Component | gdstk.Polygon
           | list[gdstk.Polygon],
           radius: float | list[float],
           tolerance: float = 0.01) -> list[gdstk.Polygon]

Perform a fillet operation and return the list of resulting Polygons.

Arguments:

  • operand - polygon, list of Polygons, Component, or ComponentReference.

  • radius - Fillet radius. You can also define a value for each vertex.

  • tolerance - for calculating the polygonal approximation of the filleted corners.

    .. plot:: :include-source:

    import gdstk import gdsfactory as gf

    points = [(0, 0), (1.2, 0), (1.2, 0.3), (1, 0.3), (1.5, 1), (0, 1.5)] p0 = gdstk.Polygon(points, datatype=1) p1 = gdstk.Polygon(points, datatype=1) p1 = gf.geometry.fillet(p1, radius=1.0)

    c = gf.Component(“demo”) c.add_polygon(p0, layer=(1, 0)) c.add_polygon(p1, layer=(2, 0)) c.plot_matplotlib() c.show()

gdsfactory.geometry

Geometric operations: Booleans, DRC checks.

gdsfactory.geometry.layer_priority

layer_priority

@gf.cell
def layer_priority(component: ComponentSpec,
                   layer_high_order: LayerSpec,
                   layer_low_order: LayerSpec,
                   remove_high_order: bool = False,
                   **kwargs) -> gf.Component

Returns new component after removing one layer from another.

Arguments:

  • component - spec.
  • layer_high_order - layer used to etch.
  • layer_low_order - layer etched into.
  • remove_high_order - whether to also remove the high order layer polygons. Useful if the higher order layer is purely logical.
  • kwargs - keyword arguments for boolean difference operation.

gdsfactory.geometry.fill_klayout

Dummy fill to keep density constant using klayout.

fill

def fill(gdspath,
         layer_to_fill: LayerSpec,
         layer_to_fill_margin: float = 0,
         layers_to_avoid: tuple[LayerSpec, float] | None = None,
         cell_name: str | None = None,
         fill_cell_name: str = "fill_cell",
         create_new_fill_cell: bool = False,
         include_original: bool = False,
         fill_layers: LayerSpecs | None = None,
         fill_size: tuple[float, float] = (10, 10),
         fill_spacing: tuple[float, float] = (20, 20),
         fill_name: str | None = None,
         gdspath_out: PathType | None = None) -> None

Write gds file with fill.

Arguments:

  • gdspath - GDS input.
  • layer_to_fill - Layer that defines the region to fill.
  • layer_to_fill_margin - in um.
  • layers_to_avoid - Layer to avoid to margin (((1, 0), 3.5), (LAYER.SLAB, 2)).
  • cell_name - Optional cell to fill. Defaults to top cell.
  • fill_cell_name - Optional cell name to use as fill.
  • create_new_fill_cell - creates new fill cell, otherwise uses fill_cell_name from gdspath.
  • include_original - True include original gdspath. False returns only fill.
  • fill_layers - if create_new_fill_cell=True, defines new fill layers.
  • fill_size - if create_new_fill_cell=True, defines new fill size.
  • fill_spacing - fill pitch in x and y.
  • fill_name - name of the cell containing all fill cells. Defaults to Cell_fill.
  • gdspath_out - Optional GDS output. Defaults to input.

gdsfactory.geometry.maskprep_flat

gdsfactory.geometry.functions

area

def area(pts: ndarray) -> float64

Returns the area.

manhattan_direction

def manhattan_direction(p0, p1, tol=1e-5)

Returns manhattan direction between 2 points.

curvature

def curvature(points: ndarray, t: ndarray) -> ndarray

Args are the points and the tangents at each point.

points : numpy.array shape (n, 2) t: numpy.array of size n

Returns:

The curvature at each point.

Computes the curvature at every point excluding the first and last point.

For a planar curve parametrized as P(t) = (x(t), y(t)), the curvature is given by (x’ y’’ - x’’ y’ ) / (x’ **2 + y’ 2)(3/2)

path_length

def path_length(points: ndarray) -> float64

Returns: The path length.

Arguments:

  • points - With shape (N, 2) representing N points with coordinates x, y.

snap_angle

def snap_angle(a: float64) -> int

Returns angle snapped along manhattan angle (0, 90, 180, 270).

a: angle in deg Return angle snapped along manhattan angle

angles_rad

def angles_rad(pts: ndarray) -> ndarray

Returns the angles (radians) of the connection between each point and the next.

angles_deg

def angles_deg(pts: ndarray) -> ndarray

Returns the angles (degrees) of the connection between each point and the next.

extrude_path

def extrude_path(points: ndarray,
                 width: float,
                 with_manhattan_facing_angles: bool = True,
                 spike_length: float64 | int | float = 0,
                 start_angle: int | None = None,
                 end_angle: int | None = None,
                 grid: float | None = None) -> ndarray

Deprecated. Use gdsfactory.path.Path.extrude() instead.

Extrude a path of width along a curve defined by points.

Arguments:

  • points - numpy 2D array of shape (N, 2).
  • width - of the path to extrude.
  • with_manhattan_facing_angles - snaps to manhattan angles.
  • spike_length - in um.
  • start_angle - in degrees.
  • end_angle - in degrees.
  • grid - in um.

Returns:

numpy 2D array of shape (2*N, 2).

polygon_grow

def polygon_grow(polygon: ndarray, offset: float) -> ndarray

Returns a grown closed shaped polygon by an offset.

gdsfactory.geometry.trim

Trim component.

Adapted from PHIDL https://github.com/amccaugh/phidl/ by Adam McCaughan

trim

@gf.cell
def trim(component: Component,
         domain: list[tuple[float, float]],
         precision: float = 1e-4,
         return_ports: bool | None = False) -> Component

Trim a component by another geometry, preserving the component’s layers and ports.

Useful to get a smaller component from a larger one for simulation.

Arguments:

  • component - Component(/Reference).

  • domain - list of array-like[N][2] representing the boundary of the component to keep.

  • precision - float Desired precision for rounding vertex coordinates.

  • return_ports - whether to return the included ports or not. Ports are always renamed to avoid inheritance conflicts.

  • Returns - New component with layers (and possibly ports) of the component restricted to the domain.

    .. plot:: :include-source:

    import gdsfactory as gf c = gf.components.straight_pin(length=10, taper=None) trimmed_c = gf.geometry.trim(component=c, domain=[[0, -5], [0, 5], [5, 5], [5, -5]]) trimmed_c.plot_matplotlib()

gdsfactory.geometry.boolean_klayout

boolean_klayout

@gf.cell
def boolean_klayout(gdspath1: ComponentOrPath,
                    gdspath2: ComponentOrPath,
                    layer1: tuple[int, int] = (1, 0),
                    layer2: tuple[int, int] = (1, 0),
                    layer3: tuple[int, int] = (2, 0),
                    operation: str = "xor") -> Component

Returns a boolean operation between two components Uses KLayout python API.

Arguments:

  • gdspath1 - path to GDS or Component.
  • gdspath2 - path to GDS or Component.
  • layer1 - tuple for gdspath1.
  • layer2 - tuple for gdspath2.
  • layer3 - for the result of the operation.

gdsfactory.geometry.boolean

Based on phidl.geometry.

boolean

@gf.cell
def boolean(A: ComponentOrReference | tuple[ComponentOrReference, ...],
            B: ComponentOrReference | tuple[ComponentOrReference, ...],
            operation: str,
            precision: float = 1e-4,
            layer: LayerSpec = (1, 0)) -> Component

Performs boolean operations between 2 Component/Reference/list objects.

operation should be one of {‘not’, ‘and’, ‘or’, ‘xor’, ‘A-B’, ‘B-A’, ‘A+B’}. Note that ‘A+B’ is equivalent to ‘or’, ‘A-B’ is equivalent to ‘not’, and ‘B-A’ is equivalent to ‘not’ with the operands switched

You can also use gdsfactory.drc.boolean_klayout

Arguments:

  • A - Component(/Reference) or list of Component(/References).

  • B - Component(/Reference) or list of Component(/References).

  • operation - {‘not’, ‘and’, ‘or’, ‘xor’, ‘A-B’, ‘B-A’, ‘A+B’}.

  • precision - float Desired precision for rounding vertex coordinates.

  • layer - Specific layer to put polygon geometry on.

  • Returns - Component with polygon(s) of the boolean operations between the 2 input Components performed.

    Notes

    • ‘A+B’ is equivalent to ‘or’.
    • ‘A-B’ is equivalent to ‘not’.
    • ‘B-A’ is equivalent to ‘not’ with the operands switched.

    .. plot:: :include-source:

    import gdsfactory as gf

    c1 = gf.components.circle(radius=10).ref() c2 = gf.components.circle(radius=9).ref() c2.movex(5)

    c = gf.geometry.boolean(c1, c2, operation=“xor”) c.plot_matplotlib()

gdsfactory.geometry.fill_tiled

gdsfactory.geometry.offset

Based on phidl.geometry.

offset

@gf.cell
def offset(elements: Component,
           distance: float = 0.1,
           use_union: bool = True,
           precision: float = 1e-4,
           join: str = "miter",
           tolerance: int = 2,
           layer: LayerSpec = "WG") -> Component

Returns new Component with polygons eroded or dilated by an offset.

Arguments:

  • elements - Component(/Reference), list of Component(/Reference), or Polygon Polygons to offset or Component containing polygons to offset.
  • distance - Distance to offset polygons. Positive values expand, negative shrink.
  • use_union - If True, use union of all polygons to offset. If False, offset
  • precision - Desired precision for rounding vertex coordinates.
  • join - {‘miter’, ‘bevel’, ‘round’} Type of join used to create polygon offset
  • tolerance - For miter joints, this number must be at least 2 represents the maximal distance in multiples of offset between new vertices and their original position before beveling to avoid spikes at acute joints. For round joints, it indicates the curvature resolution in number of points per full circle.
  • layer - Specific layer to put polygon geometry on.

Returns:

Component containing a polygon(s) with the specified offset applied.

.. plot:: :include-source:

import gdsfactory as gf c = gf.Component() layer_slab = (2, 0) c1 = gf.components.coupler_ring( cladding_layers=[layer_slab], cladding_offsets=[0.5] ) d = 0.8 c2 = gf.geometry.offset(c1, distance=+d, layer=layer_slab) c3 = gf.geometry.offset(c2, distance=-d, layer=layer_slab)

c << c1.extract(layers=(“WG”,)) c << c3 c.plot_matplotlib()

gdsfactory.geometry.union

union

@gf.cell
def union(component: Component,
          by_layer: bool = False,
          precision: float = 1e-4,
          join_first: bool = True,
          layer: Layer = (1, 0)) -> Component

Returns new Component with inverted union of Component polygons.

based on phidl.geometry.union

Arguments:

  • component - Component(/Reference), list of Component(/Reference), or Polygon A containing the polygons to perform union and inversion on.

  • by_Layer - performs the union operation layer-wise so each layer can be individually combined.

  • precision - Desired precision for rounding vertex coordinates.

  • join_first - before offsetting to avoid unnecessary joins in adjacent polygons.

  • layer - Specific layer to put polygon geometry on.

    .. plot:: :include-source:

    import gdsfactory as gf c = gf.Component() c << gf.components.ellipse(radii=(6, 6)) c << gf.components.ellipse(radii=(10, 4)) c2 = gf.geometry.union(c, join_first=False)

gdsfactory.geometry.outline

outline

@gf.cell
def outline(elements,
            distance=1,
            precision: float = 1e-3,
            join: str = "miter",
            tolerance: int = 2,
            join_first: bool = True,
            open_ports: bool | float = False,
            layer=0) -> Component

Returns Component containing the outlined polygon(s).

Creates an outline around all the polygons passed in the elements argument. elements may be a Component, Polygon, or list of Components.

Arguments:

  • elements - Component(/Reference), list of Component(/Reference), or Polygon Polygons to outline or Component containing polygons to outline.
  • distance - int or float Distance to offset polygons. Positive values expand, negative shrink.
  • precision - float Desired precision for rounding vertex coordinates.
  • join - {‘miter’, ‘bevel’, ‘round’} Type of join used to create the offset polygon.
  • tolerance - int or float For miter joints, this number must be at least 2 and it represents the maximal distance in multiples of offset between new vertices and their original position before beveling to avoid spikes at acute joints. For round joints, it indicates the curvature resolution in number of points per full circle.
  • open_ports - bool or float If not False, holes will be cut in the outline such that the Ports are not covered. If True, the holes will have the same width as the Ports. If a float, the holes will be be widened by that value (useful for fully clearing the outline around the Ports for positive-tone processes
  • layer - int, array-like[2], or set Specific layer(s) to put polygon geometry on.).

gdsfactory.geometry.xor_diff

xor_diff

@gf.cell
def xor_diff(A, B, precision: float = 1e-4) -> Component

Given two Components A and B, performs the layer-by-layer XOR difference between A and B and returns polygons representing the differences between A and B.

gdsfactory wrapper for phidl.geometry.xor_diff

Arguments:

  • A - Component(/Reference) or list of Component(/References).

  • B - Component(/Reference) or list of Component(/References).

  • precision - Desired precision for rounding vertex coordinates.

    Returns

  • Component - containing a polygon(s) defined by the XOR difference result between A and B.

gdsfactory.geometry.invert

Based on phidl.geometry.

invert

@gf.cell
def invert(elements,
           border: float = 10.0,
           precision: float = 1e-4,
           layer: LayerSpec = (1, 0)) -> Component

Creates an inverted version of the input shapes with an additional border around the edges.

Arguments:

elements : Component(/Reference), list of Component(/Reference), or Polygon A Component containing the polygons to invert.

  • border - Size of the border around the inverted shape (border value is the distance from the edges of the boundary box defining the inverted shape to the border, and is applied to all 4 sides of the shape).

  • precision - Desired precision for rounding vertex coordinates.

  • layer - Specific layer(s) to put polygon geometry on.

    Returns

  • D - A Component containing the inverted version of the input shape(s) and the corresponding border(s).

    .. plot:: :include-source:

    import gdsfactory as gf

    e1 = gf.components.ellipse(radii=(6, 6)) c = gf.geometry.invert(e1) c.plot_matplotlib()

gdsfactory.geometry.manhattanize

manhattanize_polygon

def manhattanize_polygon(p: Polygon, target_step: float = 0.05) -> Polygon

Return a Manhattanized version of the input polygon (where non-x and non-y parallel segments are decomposed into a staircase of small x and y-parallel segments)

Implemented in pure Python, and hence only suited to small polygons.

Arguments:

  • p - input polygon.
  • target_step - target staircase step size.

Returns:

manhattanized polygon

.. plot:: :include-source:

import gdsfactory as gf c = gf.Component()

poly = gdstk.rectangle((-2, -2), (2, 2)) poly.rotate(np.pi / 4) poly.scale(1, 0.5) init_poly = c.add_polygon(poly, layer=1) final_poly = gf.geometry.manhattanize_polygon(poly) c.add_polygon(final_poly, layer=2) c.plot_matplotlib()

gdsfactory.polygon

Polygon

Adapted from PHIDL https://github.com/amccaugh/phidl/ by Adam McCaughan

Polygon Objects

class Polygon(gdstk.Polygon, _GeometryHelper)

Polygonal geometric object.

Arguments:

  • points - array-like[N][2] Coordinates of the vertices of the Polygon.
  • gds_layer - int GDSII layer of the Polygon.
  • gds_datatype - int GDSII datatype of the Polygon.

__repr__

def __repr__() -> str

Returns path points.

bbox

@property
def bbox()

Returns the bounding box of the Polygon.

rotate

def rotate(angle: float = 45, center: tuple[float, float] = (0, 0)) -> Polygon

Rotates a Polygon by the specified angle.

Arguments:

  • angle - Angle to rotate the Polygon in degrees.
  • center - Midpoint of the Polygon.

move

def move(origin: tuple[float, float] = (0, 0),
         destination: tuple[float, float] | None = None,
         axis: str | None = None) -> Polygon

Moves elements of the Device from the origin point to the destination. Both origin and destination can be 1x2 array-like, Port, or a key corresponding to one of the Ports in this device.

Arguments:

  • origin - Origin point of the move. destination : Destination point of the move.
  • axis - {‘x’, ‘y’} Direction of move.

mirror

def mirror(p1=(0, 1), p2=(0, 0)) -> Polygon

Mirrors a Polygon across the line formed between the two specified points. points may be input as either single points [1,2] or array-like[N][2], and will return in kind.

Arguments:

  • p1 - First point of the line.
  • p2 - Second point of the line.

simplify

def simplify(tolerance: float = 1e-3) -> Polygon

Removes points from the polygon but does not change the polygon shape by more than tolerance from the original. Uses the Ramer-Douglas-Peucker algorithm.

Arguments:

snap

def snap(nm: int = 1) -> sp.Polygon

Returns new polygon snap points to grid

gdsfactory.font

Support for font rendering in GDS files.

Adapted from PHIDL https://github.com/amccaugh/phidl/ by Adam McCaughan

gdsfactory.get_factories

get_cells

def get_cells(modules, verbose: bool = False) -> dict[str, ComponentFactory]

Returns PCells (component functions) from a module or list of modules.

Arguments:

  • modules - module or iterable of modules.
  • verbose - prints in case any errors occur.

gdsfactory.get_netlist_flat

get_netlist_flat

def get_netlist_flat(component: Component, **kwargs) -> dict[str, Any]

Parses a recursive netlist for a component as if it was a single netlist with its lowest-level instances.

Procedure:

  • Recursively parse the recursive dict to generate a unique list of all instances even if they are reused Each entry is formatted as [(netlist, instance),...], and defines a unique flat_name = {top}{hierarchy_delimiter}{instance}{hierarchy_delimiter}{instance}{hierarchy_delimiter}...
  • Populate the flat netlist dict with similar entries as regular gdsfactory netlists:
  • instances: component, info, and settings from the original netlist, but keyed with flat_name
  • placements: For instance corresponding to each flat_name, accumulate placements across the hierarchy
  • ports and connections: each unique port of each flat_name instance is uniquely named as flat_name,port_name for each flat_name,port_name, starting at lowest hierarchy level:
  • list connections at that level (finding the proper other flat_name,port_name if non-leaf level)
  • if possible, maps the port to a port of that instance’s netlist, and repeat at a higher level
  • if the top level is reached, assign that flat_name,port_name to a top-level component port instead the returned ports dict has top level component portname: flat_name,port_name mappings the returned connections dict is sorted and flattened into a minimal (flat_name,port_name)_1: [(flat_name,port_name)] key: value pairs If allow_multiple flag in get_netlist is True, the values will be lists (to support multiple connections)
  • name: top_level_component name

Arguments:

  • component - to extract flat netlist.

Arguments:

  • component_suffix - suffix to append to each component name. useful if to save and reload a back-annotated netlist.
  • get_netlist_func - function to extract individual netlists.
  • full_settings - True returns all, false changed settings.
  • tolerance - tolerance in nm to consider two ports connected.
  • exclude_port_types - optional list of port types to exclude from netlisting.
  • get_instance_name - function to get instance name.

Returns:

  • instances - Dict of instance name and settings.
  • connections - Dict of Instance1Name,portName: Instance2Name,portName.
  • placements - Dict of instance names and placements (x, y, rotation).
  • port - Dict portName: ComponentName,port.
  • name - name of component.
  • warnings - warning messages (disconnected pins).

gdsfactory.port

We use Ports to connect Components with other Components.

we follow start from the bottom left and name the ports counter-clock-wise

.. code::

     3   4
     |___|_
 2 -|      |- 5
    |      |
 1 -|______|- 6
     |   |
     8   7

You can also rename them with W,E,S,N prefix (west, east, south, north).

.. code::

         N0  N1
         |___|_
    W1 -|      |- E1
        |      |
    W0 -|______|- E0
         |   |
        S0   S1

Adapted from PHIDL https://github.com/amccaugh/phidl/ by Adam McCaughan

Port Objects

class Port()

Ports are useful to connect Components with each other.

Arguments:

  • name - we name ports clock-wise starting from bottom left.
  • center - (x, y) port center coordinate.
  • width - of the port in um.
  • orientation - in degrees (0: east, 90: north, 180: west, 270: south).
  • parent - parent component (component to which this port belong to).
  • layer - layer tuple.
  • port_type - str (optical, electrical, vertical_te, vertical_tm).
  • parent - Component that port belongs to.
  • cross_section - cross_section spec.
  • shear_angle - an optional angle to shear port face in degrees.

__init__

def __init__(name: str,
             orientation: float | None,
             center: tuple[float, float],
             width: float | None = None,
             layer: tuple[int, int] | None = None,
             port_type: str = "optical",
             parent: Component | None = None,
             cross_section: CrossSection | None = None,
             shear_angle: float | None = None) -> None

Initializes Port object.

__repr__

def __repr__() -> str

Return a string representation of the object.

__get_validators__

@classmethod
def __get_validators__(cls)

Get validators.

validate

@classmethod
def validate(cls, v, _info)

For pydantic assumes Port is valid if has a name and a valid type.

move_polar_copy

def move_polar_copy(d: float, angle: float) -> Port

Returns a copy of the port with a distance (d) in um and angle (deg).

move_copy

def move_copy(x, y=None) -> Port

Returns a copy of the port moved by a vector or given x and y.

flip

def flip(**kwargs) -> Port

Flips port.

endpoints

@property
def endpoints() -> None

Returns the endpoints of the Port.

endpoints

@endpoints.setter
def endpoints(points: Float2) -> None

Sets the endpoints of a Port.

normal

@property
def normal() -> ndarray

Returns a vector normal to the Port.

x

@property
def x() -> float

Returns the x-coordinate of the Port center.

y

@property
def y() -> float

Returns the y-coordinate of the Port center.

rotate

def rotate(angle: float = 45, center: Float2 | None = None) -> Port

Rotates a Port around the specified center point, if no centerpoint specified will rotate around (0,0).

Arguments:

  • angle - Angle to rotate the Port in degrees.
  • center - array-like[2] or None center of the Port.

copy

def copy(name: str | None = None) -> Port

Returns a copy of the port.

Arguments:

  • name - optional new name.

get_extended_center

def get_extended_center(length: float = 1.0) -> ndarray

Returns an extended port center.

snap_to_grid

def snap_to_grid(nm: int = 1) -> None

Snap port center to nm grid.

assert_on_grid

def assert_on_grid(nm: int = 1) -> None

Ensures ports edges are on grid to avoid snap_to_grid errors.

assert_manhattan

def assert_manhattan(nm: int = 1) -> None

Ensures port has a valid manhattan orientation (0, 90, 180, 270).

port_array

def port_array(center: tuple[float, float] = (0.0, 0.0),
               width: float = 0.5,
               orientation: float = 0,
               pitch: tuple[float, float] = (10.0, 0.0),
               n: int = 2,
               **kwargs) -> list[Port]

Returns a list of ports placed in an array.

Arguments:

  • center - center point of the port.
  • width - port width.
  • orientation - angle in degrees.
  • pitch - period of the port array.
  • n - number of ports in the array.

read_port_markers

def read_port_markers(
    component: object, layers: LayerSpecs = ("PORT", )) -> Component

Returns extracted polygons from component layers.

Arguments:

  • component - Component to extract markers.
  • layers - GDS layer specs.

csv2port

def csv2port(csvpath) -> dict[str, Port]

Reads ports from a CSV file and returns a Dict.

sort_ports_clockwise

def sort_ports_clockwise(ports: dict[str, Port]) -> dict[str, Port]

Sort and return ports in the clockwise direction.

.. code::

    3   4
    |___|_
2 -|      |- 5
   |      |
1 -|______|- 6
    |   |
    8   7

sort_ports_counter_clockwise

def sort_ports_counter_clockwise(ports: dict[str, Port]) -> dict[str, Port]

Sort and return ports in the counter-clockwise direction.

.. code::

    4   3
    |___|_
5 -|      |- 2
   |      |
6 -|______|- 1
    |   |
    7   8

select_ports

def select_ports(ports: dict[str, Port],
                 layer: tuple[int, int] | None = None,
                 prefix: str | None = None,
                 suffix: str | None = None,
                 orientation: int | None = None,
                 width: float | None = None,
                 layers_excluded: tuple[tuple[int, int], ...] | None = None,
                 port_type: str | None = None,
                 names: list[str] | None = None,
                 clockwise: bool = True) -> dict[str, Port]

Returns a dict of ports from a dict of ports.

Arguments:

  • ports - Dict[str, Port] a port dict {port name: port}.
  • layer - select ports with port GDS layer.
  • prefix - select ports with port name prefix.
  • suffix - select ports with port name suffix.
  • orientation - select ports with orientation in degrees.
  • width - select ports with port width.
  • layers_excluded - List of layers to exclude.
  • port_type - select ports with port type (optical, electrical, vertical_te).
  • clockwise - if True, sort ports clockwise, False: counter-clockwise.

Returns:

Dict containing the selected ports {port name: port}.

rename_ports_by_orientation

def rename_ports_by_orientation(component: Component,
                                layers_excluded: LayerSpec | None = None,
                                select_ports: Callable = select_ports,
                                function=_rename_ports_facing_side,
                                prefix: str = "o",
                                **kwargs) -> Component

Returns Component with port names based on port orientation (E, N, W, S).

Arguments:

  • component - to rename ports.

  • layers_excluded - to exclude.

  • select_ports - function to select_ports.

  • function - to rename ports.

  • prefix - to add on each port name.

  • kwargs - select_ports settings.

    .. code::

    N0 N1 || W1 -| |- E1 | | W0 -|____|- E0 | | S0 S1

auto_rename_ports

def auto_rename_ports(component: Component,
                      function=_rename_ports_clockwise,
                      select_ports_optical: Callable
                      | None = select_ports_optical,
                      select_ports_electrical: Callable
                      | None = select_ports_electrical,
                      select_ports_placement: Callable
                      | None = select_ports_placement,
                      prefix: str = "",
                      prefix_optical: str = "o",
                      prefix_electrical: str = "e",
                      prefix_placement: str = "p",
                      port_type: str | None = None,
                      **kwargs) -> Component

Adds prefix for optical and electrical.

Arguments:

  • component - to auto_rename_ports.
  • function - to rename ports.
  • select_ports_optical - to select optical ports.
  • select_ports_electrical - to select electrical ports.
  • select_ports_placement - to select placement ports.
  • prefix_optical - prefix of optical ports.
  • prefix_electrical - prefix of electrical ports.
  • prefix_placement - prefix of electrical ports.
  • port_type - select ports with port type (optical, electrical, vertical_te).

Arguments:

  • prefix - select ports with port name prefix.
  • suffix - select ports with port name suffix.
  • orientation - select ports with orientation in degrees.
  • width - select ports with port width.
  • layers_excluded - List of layers to exclude.
  • clockwise - if True, sort ports clockwise, False: counter-clockwise.

map_ports_layer_to_orientation

def map_ports_layer_to_orientation(
        ports: dict[str, Port],
        function=_rename_ports_facing_side) -> dict[str, str]

Returns component or reference port mapping.

.. code::

     N0  N1
     |___|_
W1 -|      |- E1
    |      |
W0 -|______|- E0
     |   |
    S0   S1

map_ports_to_orientation_cw

def map_ports_to_orientation_cw(ports: dict[str, Port],
                                function=_rename_ports_facing_side,
                                **kwargs) -> dict[str, str]

Returns component or reference port mapping clockwise.

Arguments:

  • ports - dict of ports.

  • function - to rename ports.

  • kwargs - for the function to rename ports.

    .. code::

    N0 N1 || W1 -| |- E1 | | W0 -|____|- E0 | | S0 S1

auto_rename_ports_layer_orientation

def auto_rename_ports_layer_orientation(component: Component,
                                        function=_rename_ports_facing_side,
                                        prefix: str = "") -> None

Renames port names with layer_orientation (1_0_W0).

port orientation (E, N, W, S) numbering is clockwise

.. code::

     N0  N1
     |___|_
W1 -|      |- E1
    |      |
W0 -|______|- E0
     |   |
    S0   S1

gdsfactory.difftest_git

gdsdiff_git

def gdsdiff_git(path: str = "",
                curr_file: str = "",
                old_file: str = "",
                old_hex: str = "",
                old_mode: str = "",
                new_file: str = "",
                new_hex: str = "",
                new_mode: str = "") -> None

Show diffs for two files when running git diff.

Arguments:

  • path - script to run path.
  • curr_file - current GDS file.
  • old_file - old GDS.
  • old_hex - ignore.
  • old_mode - ignore.
  • new_file - new GDS file.
  • new_hex - ignore.
  • new_mode - ignore.

gdsfactory.read.from_gdspaths

from_gdspaths

def from_gdspaths(cells: tuple[ComponentOrPath, ...]) -> Component

Combine all GDS files or gf.components into a gf.component.

Arguments:

  • cells - List of gdspaths or Components.

from_gdsdir

def from_gdsdir(dirpath: PathType) -> Component

Merges GDS cells from a directory into a single Component.

gdsfactory.read.labels

read_labels_yaml

def read_labels_yaml(csvpath: PathType,
                     prefix: str | None = None) -> dict[str, DictConfig]

Read labels from csvfile in YAML format.

add_port_markers

def add_port_markers(gdspath,
                     csvpath,
                     marker_size: int = 20,
                     marker_layer: LayerSpec = (203, 0))

Add port markers from port info extracted from a gdspath and csvpath.

gdsfactory.read.import_gds

import_gds

@cell
def import_gds(gdspath: str | Path,
               cellname: str | None = None,
               gdsdir: str | Path | None = None,
               read_metadata: bool = False,
               keep_name_short: bool = False,
               unique_names: bool = True,
               **kwargs) -> Component

Returns a Component from a GDS file.

appends $ with a number to the name if the cell name is on CACHE

Arguments:

  • gdspath - path of GDS file.
  • cellname - cell of the name to import. None imports top cell.
  • gdsdir - optional GDS directory.
  • read_metadata - loads metadata (ports, settings) if it exists in YAML format.
  • 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.
  • kwargs - extra to add to component.info (polarization, wavelength ...).

gdsfactory.read.from_phidl

from_gdstk

@cache
def from_gdstk(cell: gdstk.Cell, **kwargs) -> Component

Returns gdsfactory Component from a gdstk cell.

Arguments:

  • cell - gdstk cell.

Arguments:

  • cellname - cell of the name to import (None) imports top cell.
  • snap_to_grid_nm - snap to different nm grid (does not snap if False).
  • gdsdir - optional GDS directory.
  • read_metadata - loads metadata if it exists.
  • hashed_name - appends a hash to a shortened component name.
  • kwargs - extra to add to component.info (polarization, wavelength ...).

from_phidl

@cache
def from_phidl(component, port_layer: Layer = (1, 0), **kwargs) -> Component

Returns gdsfactory Component from a phidl Device or function.

Arguments:

  • component - phidl component.
  • port_layer - to add to component ports.

Arguments:

  • cellname - cell of the name to import (None) imports top cell.
  • snap_to_grid_nm - snap to different nm grid (does not snap if False).
  • gdsdir - optional GDS directory.
  • read_metadata - loads metadata if it exists.
  • hashed_name - appends a hash to a shortened component name.
  • kwargs - extra to add to component.info (polarization, wavelength ...).

gdsfactory.read

gdsfactory.read.from_dphox

from_dphox

@cell_without_validator
def from_dphox(device, foundry) -> Component

Returns Gdsfactory Component from a dphox Device.

Note that you need to install dphox pip install dphox

https://dphox.readthedocs.io/en/latest/index.html

Arguments:

  • device - Dphox device.
  • foundry - Dphox foundry object.

gdsfactory.read.from_yaml_template

split_default_settings_from_yaml

def split_default_settings_from_yaml(
        yaml_lines: Iterable[str]) -> tuple[str, str]

Separates out the ‘default_settings’ block from the rest of the file body. Note: ‘default settings’ MUST be at the TOP of the file.

Arguments:

  • yaml_lines - the lines of text in the yaml file.

Returns:

a tuple of (main file contents), (setting block), both as multi-line strings.

cell_from_yaml_template

def cell_from_yaml_template(
        filename: str | IO[Any] | pathlib.Path,
        name: str,
        routing_strategy: dict[str, Callable] | None = None) -> Callable

Gets a PIC factory function from a yaml definition, which can optionally be a jinja template.

Arguments:

  • filename - the filepath of the pic yaml template.
  • name - the name of the component to create.
  • routing_strategy - a dictionary of routing functions.

Returns:

a factory function for the component.

yaml_cell

def yaml_cell(yaml_definition, name: str,
              routing_strategy) -> Callable[..., Component]

The “cell” decorator equivalent for yaml files. Generates a proper cell function for yaml-defined circuits.

Arguments:

  • yaml_definition - the filename to the pic yaml definition.
  • name - the name of the pic to create.
  • routing_strategy - a dictionary of routing strategies to use for pic generation.

Returns:

a dynamically-generated function for the yaml file.

gdsfactory.read.from_np

Read component from a numpy.ndarray.

compute_area_signed

def compute_area_signed(pr) -> float

Return the signed area enclosed by a ring using the linear time.

algorithm at http://www.cgafaq.info/wiki/Polygon_Area. A value >= 0 indicates a counter-clockwise oriented ring.

from_np

@cell_without_validator
def from_np(ndarray: np.ndarray,
            nm_per_pixel: int = 20,
            layer: tuple[int, int] = (1, 0),
            threshold: float = 0.99,
            invert: bool = True) -> Component

Returns Component from a np.ndarray.

Extracts contours skimage.measure.find_contours using threshold.

Arguments:

  • ndarray - 2D ndarray representing the device layout.
  • nm_per_pixel - scale_factor.
  • layer - layer tuple to output gds.
  • threshold - value along which to find contours in the array.
  • invert - invert the mask.

from_image

@cell_without_validator
def from_image(image_path: str, **kwargs) -> Component

Returns Component from a png image.

Arguments:

  • image_path - png file path.

Arguments:

  • nm_per_pixel - scale_factor.
  • layer - layer tuple to output gds.
  • threshold - value along which to find contours in the array.

gdsfactory.read.from_yaml

Returns Component from YAML syntax.

name: myComponent settings: length: 3

info: description: just a demo polarization: TE ...

instances: mzi: component: mzi_phase_shifter settings: delta_length: ${settings.length} length_x: 50

pads:
    component: pad_array
    settings:
        n: 2
        port_names:
            - e4

placements: mzi: x: 0 pads: y: 200 x: mzi,cc ports: o1: mzi,o1 o2: mzi,o2

routes: electrical: links: mzi,etop_e1: pads,e4_0 mzi,etop_e2: pads,e4_1

    settings:
        layer: [31, 0]
        width: 10
        radius: 10

place

def place(placements_conf: dict[str, dict[str, int | float | str]],
          connections_by_transformed_inst: dict[str, dict[str, str]],
          instances: dict[str, ComponentReference],
          encountered_insts: list[str],
          instance_name: str | None = None,
          all_remaining_insts: list[str] | None = None) -> None

Place instance_name based on placements_conf config.

Arguments:

  • placements_conf - Dict of instance_name to placement (x, y, rotation ...).
  • connections_by_transformed_inst - Dict of connection attributes. keyed by the name of the instance which should be transformed.
  • instances - Dict of references.
  • encountered_insts - list of encountered_instances.
  • instance_name - instance_name to place.
  • all_remaining_insts - list of all the remaining instances to place instances pop from this instance as they are placed.

transform_connections_dict

def transform_connections_dict(
        connections_conf: dict[str, str]) -> dict[str, dict]

Returns Dict with source_instance_name key and connection properties.

make_connection

def make_connection(instance_src_name: str, port_src_name: str,
                    instance_dst_name: str, port_dst_name: str,
                    instances: dict[str, ComponentReference]) -> None

Connect instance_src_name,port to instance_dst_name,port.

Arguments:

  • instance_src_name - source instance name.
  • port_src_name - from instance_src_name.
  • instance_dst_name - destination instance name.
  • port_dst_name - from instance_dst_name.
  • instances - dict of instances.

cell_from_yaml

def cell_from_yaml(yaml_str: str | pathlib.Path | IO[Any] | dict[str, Any]
                   | DictConfig,
                   routing_strategy: dict[str, Callable] | None = None,
                   label_instance_function: Callable = add_instance_label,
                   name: str | None = None,
                   prefix: str | None = None,
                   **kwargs) -> Callable

Returns Component factory from YAML string or file.

YAML includes instances, placements, routes, ports and connections.

Arguments:

  • yaml - YAML string or file.

  • routing_strategy - for each route.

  • label_instance_function - to label each instance.

  • name - Optional name.

  • prefix - name prefix.

  • kwargs - function settings for creating YAML PCells.

    .. code::

    valid variables:

  • name - Optional Component name

  • settings - Optional variables

  • pdk - overrides

  • info - Optional component info

  • description - just a demo

  • polarization - TE ... instances: name:

  • component - (ComponentSpec) settings (Optional)

  • length - 10 ... placements:

  • x - float, str | None str can be instanceName,portName

  • y - float, str | None

  • rotation - float | None

  • mirror - bool, float | None float is x mirror axis

  • port - str | None port anchor

  • connections Optional - between instances

  • ports Optional - ports to expose

  • routes Optional - bundles of routes routeName:

  • library - optical links:

  • instance1,port1 - instance2,port2

    .. code::

    settings:

  • length_mmi - 5

    instances: mmi_bot:

  • component - mmi1x2 settings:

  • width_mmi - 4.5

  • length_mmi - 10 mmi_top:

  • component - mmi1x2 settings:

  • width_mmi - 4.5

  • length_mmi - ${settings.length_mmi}

    placements: mmi_top:

  • port - o1

  • x - 0

  • y - 0 mmi_bot:

  • port - o1

  • x - mmi_top,o2

  • y - mmi_top,o2

  • dx - 30

  • dy - -30 routes: optical:

  • library - optical links:

  • mmi_top,o3 - mmi_bot,o1

from_yaml

def from_yaml(yaml_str: str | pathlib.Path | IO[Any] | dict[str, Any]
              | DictConfig,
              routing_strategy: dict[str, Callable] | None = None,
              label_instance_function: Callable = add_instance_label,
              name: str | None = None,
              prefix: str | None = None,
              **kwargs) -> Component

Returns Component from YAML string or file.

YAML includes instances, placements, routes, ports and connections.

Arguments:

  • yaml - YAML string or file.

  • routing_strategy - for each route.

  • label_instance_function - to label each instance.

  • name - Optional name.

  • prefix - name prefix.

  • kwargs - function settings for creating YAML PCells.

    .. code::

    valid variables:

  • name - Optional Component name

  • settings - Optional variables

  • pdk - overrides

  • info - Optional component info

  • description - just a demo

  • polarization - TE ... instances: name:

  • component - (ComponentSpec) settings (Optional)

  • length - 10 ... placements:

  • x - float, str | None str can be instanceName,portName

  • y - float, str | None

  • rotation - float | None

  • mirror - bool, float | None float is x mirror axis

  • port - str | None port anchor

  • connections Optional - between instances

  • ports Optional - ports to expose

  • routes Optional - bundles of routes routeName:

  • library - optical links:

  • instance1,port1 - instance2,port2

    .. code::

    settings:

  • length_mmi - 5

    instances: mmi_bot:

  • component - mmi1x2 settings:

  • width_mmi - 4.5

  • length_mmi - 10 mmi_top:

  • component - mmi1x2 settings:

  • width_mmi - 4.5

  • length_mmi - ${settings.length_mmi}

    placements: mmi_top:

  • port - o1

  • x - 0

  • y - 0 mmi_bot:

  • port - o1

  • x - mmi_top,o2

  • y - mmi_top,o2

  • dx - 30

  • dy - -30 routes: optical:

  • library - optical links:

  • mmi_top,o3 - mmi_bot,o1

gdsfactory.read.from_updk

Read uPDK YAML definition and returns a gdsfactory script.

https://openepda.org/index.html

from_updk

def from_updk(filepath: PathType,
              filepath_out: PathType | None = None,
              layer_bbox: tuple[int, int] = (68, 0),
              layer_bbmetal: tuple[int, int] | None = None,
              layer_label: tuple[int, int] | None = None,
              layer_pin_label: tuple[int, int] | None = None,
              layer_pin: tuple[int, int] | None = None,
              optical_xsections: list[str] | None = None,
              electrical_xsections: list[str] | None = None,
              layers_text: list[LayerSpec] | None = None,
              text_size: float = 2.0,
              activate_pdk: bool = False,
              read_xsections: bool = True,
              prefix: str = "",
              suffix: str = "") -> str

Read uPDK definition and returns a gdsfactory script.

Arguments:

  • filepath - uPDK filepath definition.
  • filepath_out - optional filepath to save script. if None only returns script and does not save it.
  • layer_bbox - layer to draw bounding boxes.
  • layer_bbmetal - layer to draw bounding boxes for metal.
  • optical_xsections - Optional list of names of xsections that will add optical ports.
  • electrical_xsections - Optional list of names of xsections that will add electrical ports.
  • layers_text - Optional list of layers to add text labels.
  • text_size - text size for labels.
  • activate_pdk - if True, activate the pdk after writing the script.
  • read_xsections - if True, read xsections from uPDK.
  • prefix - optional prefix to add to the script.
  • suffix - optional suffix to add to the script.

gdsfactory.export.to_gerber

Based on Gerber file spec: https://www.ucamco.com/files/downloads/file_en/456/gerber-layer-format-specification-revision-2022-02_en.pdf

See Also:

to_gerber

def to_gerber(
    component: Component,
    dirpath: Path,
    layermap_to_gerber_layer: dict[tuple[int, int], GerberLayer],
    options: GerberOptions = Field(default_factory=dict)
) -> None

Writes each layer to a different Gerber file.

Arguments:

  • component - to export.
  • dirpath - directory path.
  • layermap_to_gerber_layer - map of GDS layer to GerberLayer.
  • options - to save.
  • header - List[str] | None = None
  • mode - Literal[“mm”, “in”] = “mm”
  • resolution - float = 1e-6
  • int_size - int = 4

gdsfactory.export

gdsfactory.export.to_np

to_np

def to_np(component: Component,
          nm_per_pixel: int = 20,
          layers: Layers = ((1, 0), ),
          values: Floats | None = None,
          pad_width: int = 1) -> np.ndarray

Returns a pixelated numpy array from Component polygons.

Arguments:

  • component - Component.
  • nm_per_pixel - you can go from 20 (coarse) to 4 (fine).
  • layers - to convert. Order matters (latter overwrite former).
  • values - associated to each layer (defaults to 1).
  • pad_width - padding pixels around the image.

gdsfactory.export.to_stl

to_stl

def to_stl(component: Component,
           filepath: str,
           layer_stack: LayerStack | None = None,
           exclude_layers: tuple[Layer, ...] | None = None,
           use_layer_name: bool = False,
           hull_invalid_polygons: bool = True,
           scale: float | None = None) -> None

Exports a Component into STL.

Arguments:

  • component - to export.
  • filepath - filepath prefix to write STL to. Each file will have each exported layer as suffix.
  • layer_stack - contains thickness and zmin for each layer.
  • exclude_layers - layers to exclude.
  • use_layer_name - If True, uses LayerLevel names in output filenames rather than gds_layer and gds_datatype.
  • hull_invalid_polygons - If True, replaces invalid polygons (determined by shapely.Polygon.is_valid) with its convex hull.
  • scale - Optional factor by which to scale meshes before writing.

gdsfactory.export.to_3d

to_3d

def to_3d(component: Component,
          layer_views: LayerViews | None = None,
          layer_stack: LayerStack | None = None,
          exclude_layers: tuple[Layer, ...] | None = None)

Return Component 3D trimesh Scene.

Arguments:

  • component - to extrude in 3D.
  • layer_views - layer colors from Klayout Layer Properties file. Defaults to active PDK.layer_views.
  • layer_stack - contains thickness and zmin for each layer. Defaults to active PDK.layer_stack.
  • exclude_layers - layers to exclude.

gdsfactory.add_keepout

add_keepout

@cell
def add_keepout(component: Component,
                target_layers: Layers,
                keepout_layers: Layers,
                margin: float = 2.0) -> Component

Adds keepout after looking up all polygons in a cell.

You can also use add_padding for rectangular keepout.

Arguments:

  • component - to add keepout.
  • target_layers - list of layers to read.
  • keepout_layers - list of layers to add keepout.
  • margin - offset from target to keepout_layers.

gdsfactory.typings

In programming, a factory is a function that returns an object.

Functions are easy to understand because they have clear inputs and outputs. Most gdsfactory functions take some inputs and return a Component object. Some of these inputs parameters are also functions.

  • Component: Object with.
    • name.
    • references: to other components (x, y, rotation).
    • polygons in different layers.
    • ports dict.
  • Route: dataclass with 3 attributes.
    • references: list of references (straights, bends and tapers).
    • ports: dict(input=PortIn, output=PortOut).
    • length: how long is this route?

Factories:

  • ComponentFactory: function that returns a Component.
  • RouteFactory: function that returns a Route.

Specs:

  • ComponentSpec: Component, function, string or dict (component=mzi, settings=dict(delta_length=20)).
  • LayerSpec: (3, 0), 3 (assumes 0 as datatype) or string.

Step Objects

@dataclasses.dataclass
class Step()

Manhattan Step.

Arguments:

  • x - absolute.
  • y - absolute.
  • dx - x-displacement.
  • dy - y-displacement.

StepAllAngle Objects

@dataclasses.dataclass
class StepAllAngle()

separation

All angle Ste.

Arguments:

  • x - absolute.
  • y - absolute.
  • dx - x-displacement.
  • dy - y-displacement.
  • exit_angle - in degrees.
  • cross_section - spec.
  • connector - define transition.
  • separation - in um.

Layer

Tuple of integer (layer, datatype)

LayerSpec

tuple of integers (layer, datatype), a integer (layer, 0) or a string (layer_name)

ComponentSpec

PCell function, function name, dict or Component

CellSpec

PCell function, function name or dict

CrossSectionSpec

cross_section function, function name or dict

NetlistModel Objects

class NetlistModel(BaseModel)

Netlist defined component.

Arguments:

  • instances - dict of instances (name, settings, component).
  • placements - dict of placements.
  • connections - dict of connections.
  • routes - dict of routes.
  • name - component name.
  • info - information (polarization, wavelength ...).
  • settings - input variables.
  • ports - exposed component ports.

TypedArray Objects

class TypedArray(np.ndarray)

based on https://github.com/samuelcolvin/pydantic/issues/380.

gdsfactory.get_netlist

Extract netlist from component port connectivity.

Assumes two ports are connected when they have same width, x, y

.. code:: yaml

connections:
    - coupler,N0:bendLeft,W0
    - coupler,N1:bendRight,N0
    - bednLeft,N0:straight,W0
    - bendRight,N0:straight,E0

ports:
    - coupler,E0
    - coupler,W0

get_instance_name_from_alias

def get_instance_name_from_alias(component: Component,
                                 reference: ComponentReference) -> str

Returns the instance name from the label.

If no label returns to instanceName_x_y.

Arguments:

  • component - with labels.
  • reference - reference that needs naming.

get_instance_name_from_label

def get_instance_name_from_label(
        component: Component,
        reference: ComponentReference,
        layer_label: LayerSpec = "LABEL_INSTANCE") -> str

Returns the instance name from the label.

If no label returns to instanceName_x_y.

Arguments:

  • component - with labels.
  • reference - reference that needs naming.
  • layer_label - ignores layer_label[1].

get_netlist_yaml

def get_netlist_yaml(component: Component,
                     full_settings: bool = False,
                     tolerance: int = 5,
                     exclude_port_types: list | None = None,
                     **kwargs) -> str

Returns instances, connections and placements yaml string content.

get_netlist

def get_netlist(
        component: Component,
        full_settings: bool = False,
        tolerance: int = 5,
        exclude_port_types: list[str] | tuple[str] | None = ("placement", ),
        get_instance_name: Callable[..., str] = get_instance_name_from_alias,
        allow_multiple: bool = False) -> dict[str, Any]

From Component returns instances, connections and placements dict.

Does two sweeps over the connections:

  1. first tries to connect everything assuming perfect connections at each port.
  2. Then gathers ports which did not perfectly connect to anything and tries to find imperfect connections, by grouping ports on a coarse grid.

warnings collected during netlisting are reported back into the netlist. These include warnings about mismatched port widths, orientations, shear angles, excessive offsets, etc. You can also configure warning types which should throw an error when encountered by modifying DEFAULT_CRITICAL_CONNECTION_ERROR_TYPES. Validators, which will produce warnings for each port type, can be overridden with DEFAULT_CONNECTION_VALIDATORS A key difference in this algorithm is that we group each port type independently. This allows us to use different logic to determine i.e. if an electrical port is properly connected vs an optical port. In this function, the core logic is the same, but we employ extra validation for optical ports. snap_to_grid() allows a value of 0, which will return the original value, is more efficient when the value is 1, and will throw a more descriptive error when the value is <0 the default value of tolerance is 5nm because it should allow better performance with the two-grid-sweep approach.

Arguments:

  • component - to extract netlist.
  • full_settings - True returns all, false changed settings.
  • tolerance - tolerance in nm to consider two ports connected.
  • exclude_port_types - optional list of port types to exclude from netlisting.
  • get_instance_name - function to get instance name.
  • allow_multiple - False to raise an error if more than two ports share the same connection. if True, will return key: [value] pairs with [value] a list of all connected instances.

Returns:

  • instances - Dict of instance name and settings.
  • connections - Dict of Instance1Name,portName: Instance2Name,portName.
  • placements - Dict of instance names and placements (x, y, rotation).
  • port - Dict portName: ComponentName,port.
  • name - name of component.
  • warnings - warning messages (disconnected pins).

get_netlist_recursive

def get_netlist_recursive(component: Component,
                          component_suffix: str = "",
                          get_netlist_func: Callable = get_netlist,
                          get_instance_name: Callable[
                              ..., str] = get_instance_name_from_alias,
                          **kwargs) -> dict[str, Any]

Returns recursive netlist for a component and subcomponents.

Arguments:

  • component - to extract netlist.
  • component_suffix - suffix to append to each component name. useful if to save and reload a back-annotated netlist.
  • get_netlist_func - function to extract individual netlists.

Arguments:

  • full_settings - True returns all, false changed settings.
  • tolerance - tolerance in nm to consider two ports connected.
  • exclude_port_types - optional list of port types to exclude from netlisting.
  • get_instance_name - function to get instance name.

Returns:

Dictionary of netlists, keyed by the name of each component.

gdsfactory.decorators

is_valid_transformation

def is_valid_transformation(ref: ComponentReference,
                            grid_size: float | None = None) -> bool

Returns True if the component has valid transformations.

Arguments:

  • component - the component reference to check.
  • grid_size - the GDS grid size, in um, defaults to active PDK.get_grid_size() any translations with higher resolution than this are considered invalid.

has_valid_transformations

def has_valid_transformations(component: Component) -> bool

Returns True if the component has valid transformations.

flatten_invalid_refs

def flatten_invalid_refs(component: Component, grid_size: float | None = None)

Flattens component references which have invalid transformations.

(i.e. non-90 deg rotations or sub-grid translations).

This is an in-place operation, so you should use it as a decorator. flattens only individual references with invalid transformations.

Deprecated Use Component.write_gds(flatten_invalid_refs=True)

Arguments:

  • component - the component to fix (in place).
  • grid_size - the GDS grid size, in um, defaults to active PDK.get_grid_size() any translations with higher resolution than this are considered invalid.

gdsfactory.component_layout

Helper functions for layout.

Adapted from PHIDL https://github.com/amccaugh/phidl/ by Adam McCaughan

get_polygons

def get_polygons(
    instance,
    by_spec: bool | tuple[int, int] = False,
    depth: int | None = None,
    include_paths: bool = True,
    as_array: bool = True,
    as_shapely: bool = False,
    as_shapely_merged: bool = False
) -> list[Polygon] | dict[tuple[int, int], list[Polygon]]

Return a list of polygons in this cell.

Arguments:

  • by_spec - bool or layer If True, the return value is a dictionary with the polygons of each individual pair (layer, datatype), which are used as keys. If set to a tuple of (layer, datatype), only polygons with that specification are returned.

  • depth - integer or None If not None, defines from how many reference levels to retrieve polygons. References below this level will result in a bounding box. If by_spec is True the key will be the name of this cell.

  • include_paths - If True, polygonal representation of paths are also included in the result.

  • as_array - when as_array=false, return the Polygon objects instead. polygon objects have more information (especially when by_spec=False) and are faster to retrieve.

  • as_shapely - returns shapely polygons.

    Returns

  • out - list of array-like[N][2] or dictionary List containing the coordinates of the vertices of each polygon, or dictionary with with the list of polygons (if by_spec is True).

Notes:

Instances of FlexPath and RobustPath are also included in the result by computing their polygonal boundary.

_GeometryHelper Objects

class _GeometryHelper()

Helper class for a class with functions move() and the property bbox.

It uses that function+property to enable you to do things like check what the center of the bounding box is (self.center), and also to do things like move the bounding box such that its maximum x value is 5.2 (self.xmax = 5.2).

center

@property
def center()

Returns the center of the bounding box.

center

@center.setter
def center(destination) -> None

Sets the center of the bounding box.

Arguments:

destination : array-like[2] Coordinates of the new bounding box center.

x

@property
def x()

Returns the x-coordinate of the center of the bounding box.

x

@x.setter
def x(destination) -> None

Sets the x-coordinate of the center of the bounding box.

Arguments:

destination : int or float x-coordinate of the bbox center.

y

@property
def y()

Returns the y-coordinate of the center of the bounding box.

y

@y.setter
def y(destination) -> None

Sets the y-coordinate of the center of the bounding box.

Arguments:

destination : int or float y-coordinate of the bbox center.

xmax

@property
def xmax()

Returns the maximum x-value of the bounding box.

xmax

@xmax.setter
def xmax(destination) -> None

Sets the x-coordinate of the maximum edge of the bounding box.

Arguments:

destination : int or float x-coordinate of the maximum edge of the bbox.

ymax

@property
def ymax()

Returns the maximum y-value of the bounding box.

ymax

@ymax.setter
def ymax(destination) -> None

Sets the y-coordinate of the maximum edge of the bounding box.

Arguments:

destination : int or float y-coordinate of the maximum edge of the bbox.

xmin

@property
def xmin()

Returns the minimum x-value of the bounding box.

xmin

@xmin.setter
def xmin(destination) -> None

Sets the x-coordinate of the minimum edge of the bounding box.

Arguments:

destination : int or float x-coordinate of the minimum edge of the bbox.

ymin

@property
def ymin()

Returns the minimum y-value of the bounding box.

ymin

@ymin.setter
def ymin(destination) -> None

Sets the y-coordinate of the minimum edge of the bounding box.

Arguments:

destination : int or float y-coordinate of the minimum edge of the bbox.

size

@property
def size()

Returns the (x, y) size of the bounding box.

xsize

@property
def xsize()

Returns the horizontal size of the bounding box.

ysize

@property
def ysize()

Returns the vertical size of the bounding box.

movex

def movex(origin=0, destination=None)

Moves an object by a specified x-distance.

Arguments:

  • origin - array-like[2], Port, or key Origin point of the move.
  • destination - array-like[2], Port, key, or None Destination point of the move.

movey

def movey(origin=0, destination=None)

Moves an object by a specified y-distance.

Arguments:

origin : array-like[2], Port, or key Origin point of the move. destination : array-like[2], Port, or key Destination point of the move.

__add__

def __add__(element) -> Group

Adds an element to a Group.

Arguments:

  • element - Component, ComponentReference, Port, Polygon, Label, or Group to add.

Group Objects

class Group(_GeometryHelper)

Group objects together so you can manipulate them as a single object (move/rotate/mirror).

__init__

def __init__(*args) -> None

Initialize Group.

__repr__

def __repr__() -> str

Prints the number of elements in the Group.

__len__

def __len__() -> float

Returns the number of elements in the Group.

__iadd__

def __iadd__(element) -> Group

Adds an element to the Group.

Arguments:

  • element - Component, ComponentReference, Port, Polygon, Label, or Group to add.

bbox

@property
def bbox()

Returns the bounding boxes of the Group.

add

def add(element) -> Group

Adds an element to the Group.

Arguments:

  • element - Component, ComponentReference, Port, Polygon, Label, or Group to add.

rotate

def rotate(angle: float = 45, center=(0, 0)) -> Group

Rotates all elements in a Group around the specified centerpoint.

Arguments:

angle : int or float Angle to rotate the Group in degrees. center : array-like[2] or None center of the Group.

move

def move(origin=(0, 0), destination=None, axis=None) -> Group

Moves the Group from the origin point to the destination.

Both origin and destination can be 1x2 array-like, Port, or a key corresponding to one of the Ports in this Group.

Arguments:

origin : array-like[2], Port, or key Origin point of the move. destination : array-like[2], Port, or key Destination point of the move. axis : {‘x’, ‘y’} Direction of the move.

mirror

def mirror(p1=(0, 1), p2=(0, 0)) -> Group

Mirrors a Group across the line formed between the two specified points.

points may be input as either single points [1,2] or array-like[N][2], and will return in kind.

Arguments:

p1 : array-like[N][2] First point of the line. p2 : array-like[N][2] Second point of the line.

distribute

def distribute(direction="x",
               spacing=100,
               separation=True,
               edge="center") -> Group

Distributes the elements in the Group.

Arguments:

direction : {‘x’, ‘y’} Direction of distribution; either a line in the x-direction or y-direction. spacing : int or float Distance between elements. separation : bool If True, guarantees elements are separated with a fixed spacing between; if False, elements are spaced evenly along a grid. edge : {‘x’, ‘xmin’, ‘xmax’, ‘y’, ‘ymin’, ‘ymax’} Which edge to perform the distribution along (unused if separation == True)

align

def align(alignment="ymax") -> Group

Aligns the elements in the Group.

Arguments:

alignment : {‘x’, ‘y’, ‘xmin’, ‘xmax’, ‘ymin’, ‘ymax’} Which edge to align along (e.g. ‘ymax’ will align move the elements such that all of their topmost points are aligned)

gdsfactory.add_padding

get_padding_points

def get_padding_points(component: Component,
                       default: float = 50.0,
                       top: float | None = None,
                       bottom: float | None = None,
                       right: float | None = None,
                       left: float | None = None) -> list[float]

Returns padding points for a component outline.

Arguments:

  • component - to add padding.
  • default - default padding in um.
  • top - north padding in um.
  • bottom - south padding in um.
  • right - east padding in um.
  • left - west padding in um.

add_padding

def add_padding(component: ComponentSpec = "mmi2x2",
                layers: tuple[LayerSpec, ...] = ("PADDING", ),
                **kwargs) -> Component

Adds padding layers to component. Returns same component.

Arguments:

  • component - to add padding.

  • layers - list of layers.

    keyword Args:

  • default - default padding.

  • top - north padding in um.

  • bottom - south padding in um.

  • right - east padding in um.

  • left - west padding in um.

add_padding_container

@cell
def add_padding_container(component: ComponentSpec,
                          layers: tuple[LayerSpec, ...] = ("PADDING", ),
                          **kwargs) -> Component

Returns new component with padding added.

Arguments:

  • component - to add padding.
  • layers - list of layers.

Arguments:

  • default - default padding in um.
  • top - north padding in um.
  • bottom - south padding in um.
  • right - east padding in um.
  • left - west padding in um.

add_padding_to_size

def add_padding_to_size(component: ComponentSpec,
                        layers: tuple[LayerSpec, ...] = ("PADDING", ),
                        xsize: float | None = None,
                        ysize: float | None = None,
                        left: float = 0,
                        bottom: float = 0) -> Component

Returns component with padding layers on each side.

New size is multiple of grid size.

Arguments:

  • component - to add padding.
  • layers - list of layers.
  • xsize - x size to fill up in um.
  • ysize - y size to fill up in um.
  • left - left padding in um to fill up in um.
  • bottom - bottom padding in um to fill up in um.

add_padding_to_size_container

@cell
def add_padding_to_size_container(component: ComponentSpec,
                                  layers: tuple[LayerSpec,
                                                ...] = ("PADDING", ),
                                  xsize: float | None = None,
                                  ysize: float | None = None,
                                  left: float = 0,
                                  bottom: float = 0) -> Component

Returns new component with padding layers on each side. New size is.

multiple of grid size.

Arguments:

  • component - to add padding.
  • layers - list of layers.
  • xsize - x size to fill up in um.
  • ysize - y size to fill up in um.
  • left - left padding in um to fill up in um.
  • bottom - bottom padding in um to fill up in um.

gdsfactory.pixelate

pixelate_path

def pixelate_path(pts: Coordinates,
                  pixel_size: float = 0.55,
                  snap_res: float = 0.05,
                  middle_offset: float = 0.5,
                  theta_start: float = 0,
                  theta_end: float = 90) -> Coordinates

From a path add one pixel per point on the path.

Arguments:

  • pts - points.
  • pixel_size - in um.
  • snap_res - snap resolution.
  • middle_offset - in um.
  • theta_start - in degrees.
  • theta_end - in degrees.

pixelate

def pixelate(pts, N=100, margin=0.4, **kwargs)

Pixelate shape defined by points Return rectangles [Rect1, Rect2, ...] ready to go in the quad tree.

gdsfactory.show

show

def show(component: Component | str | pathlib.Path,
         technology: str | None = None,
         **kwargs) -> None

Write GDS and show Component in KLayout.

Arguments:

  • component - Component or GDS path.
  • technology - Name of KLayout technology to load when displaying component.

Arguments:

  • gdspath - GDS file path to write to.
  • gdsdir - directory for the GDS file. Defaults to /tmp/.
  • unit - unit size for objects in library. 1um by default.
  • precision - for object dimensions in the library (m). 1nm by default.
  • timestamp - Defaults to 2019-10-25. If None uses current time.

gdsfactory.cross_section

You can define a path as list of points.

To create a component you need to extrude the path with a cross-section.

Section Objects

class Section(BaseModel)

CrossSection to extrude a path with a waveguide.

Arguments:

  • width - of the section (um) or parameterized function from 0 to 1. the width at t==0 is the width at the beginning of the Path. the width at t==1 is the width at the end.

  • offset - center offset (um) or function parameterized function from 0 to 1. the offset at t==0 is the offset at the beginning of the Path. the offset at t==1 is the offset at the end.

  • insets - distance (um) in x to inset section relative to end of the Path (i.e. (start inset, stop_inset)).

  • layer - layer spec. If None does not draw the main section.

  • port_names - Optional port names.

  • port_types - optical, electrical, ...

  • name - Optional Section name.

  • hidden - hide layer.

  • simplify - Optional Tolerance value for the simplification algorithm. All points that can be removed without changing the resulting. polygon by more than the value listed here will be removed.

    .. code::

    0 offset |<-------------->| | _____ | | | | |layer| | |_____| | <----> width

ComponentAlongPath Objects

class ComponentAlongPath(BaseModel)

A ComponentAlongPath object to place along an extruded path.

Arguments:

  • component - Component to repeat along the path. The unrotated version of this object should be oriented for placement on a horizontal line.
  • spacing - distance between component placements
  • padding - minimum distance from the path start to the first component.
  • y_offset - offset in y direction (um).

CrossSection Objects

class CrossSection(BaseModel)

Waveguide information to extrude a path.

cladding_layers follow path shape, while bbox_layers are rectangular.

Arguments:

  • layer - main Section layer. Main section name = ‘_default’. If None does not draw the main section.

  • width - main Section width (um) or function parameterized from 0 to 1. the width at t==0 is the width at the beginning of the Path. the width at t==1 is the width at the end.

  • offset - main Section center offset (um) or function from 0 to 1. the offset at t==0 is the offset at the beginning of the Path. the offset at t==1 is the offset at the end.

  • radius - main Section bend radius (um).

  • simplify - main Section Optional Tolerance value for the simplification algorithm.

  • width_wide - wide waveguides width (um) for low loss routing.

  • auto_widen - taper to wide waveguides for low loss routing.

  • auto_widen_minimum_length - minimum straight length for auto_widen.

  • taper_length - taper_length for auto_widen.

  • bbox_layers - list of layers for rectangular bounding box.

  • bbox_offsets - list of bounding box offsets.

  • cladding_layers - list of layers to extrude.

  • cladding_offsets - list of offset from main Section edge.

  • cladding_simplify - Optional Tolerance value for the simplification algorithm. All points that can be removed without changing the resulting. polygon by more than the value listed here will be removed.

  • sections - list of Sections(width, offset, layer, ports).

  • port_names - for input and output (‘o1’, ‘o2’).

  • port_types - for input and output: electrical, optical, vertical_te ...

  • gap - edge to edge waveguide spacing for routing.

  • min_length - defaults to 1nm = 10e-3um for routing.

  • start_straight_length - straight length at the beginning of the route.

  • end_straight_length - end length at the beginning of the route.

  • snap_to_grid - Optional snap points to grid when extruding paths (um).

  • decorator - function when extruding component. For example add_pins.

  • add_pins - Optional function to add pins.

  • add_bbox - Optional function to add bounding box.

  • info - dict with extra settings or useful information.

  • name - cross_section name.

  • mirror - if True, reflects the offsets.

  • vias - list of ComponentAlongPaths(component, spacing, padding, offset).

    Properties:

  • aliases - dict of cross_section aliases.

copy

def copy(**kwargs)

Returns a CrossSection copy.

add_bbox_layers

def add_bbox_layers(component,
                    top: float | None = None,
                    bottom: float | None = None,
                    right: float | None = None,
                    left: float | None = None)

Add bounding box layers to a component.

Arguments:

  • component - to add layers.
  • top - top padding.
  • bottom - bottom padding.
  • right - right padding.
  • left - left padding.

get_xmin_xmax

def get_xmin_xmax()

Returns the min and max extent of the cross_section across all sections.

Transition Objects

class Transition(CrossSection)

Waveguide information to extrude a path between two CrossSection.

cladding_layers follow path shape, while bbox_layers are rectangular.

Arguments:

  • cross_section1 - input cross_section.
  • cross_section2 - output cross_section.
  • width_type - sine or linear. Sets the type of width transition used if any widths are different between the two input CrossSections.
  • sections - list of Sections(width, offset, layer, ports).
  • layer - main Section layer. Main section name = ‘_default’.
  • width - main Section width (um) or function parameterized from 0 to 1. the width at t==0 is the width at the beginning of the Path. the width at t==1 is the width at the end.
  • snap_to_grid - Optional snap points to grid when extruding paths (um).
  • radius - main Section bend radius (um).
  • width_wide - wide waveguides width (um) for low loss routing.
  • auto_widen - taper to wide waveguides for low loss routing.
  • auto_widen_minimum_length - minimum straight length for auto_widen.
  • taper_length - taper_length for auto_widen.
  • bbox_layers - list of layers for rectangular bounding box.
  • bbox_offsets - list of bounding box offsets.
  • cladding_layers - list of layers to extrude.
  • cladding_offsets - list of offset from main Section edge.
  • cladding_simplify - Optional Tolerance value for the simplification algorithm. All points that can be removed without changing the resulting. polygon by more than the value listed here will be removed.
  • sections - list of Sections(width, offset, layer, ports).
  • port_names - for input and output (‘o1’, ‘o2’).
  • port_types - for input and output: electrical, optical, vertical_te ...
  • gap - edge to edge waveguide spacing for routing.
  • min_length - defaults to 1nm = 10e-3um for routing.
  • start_straight_length - straight length at the beginning of the route.
  • end_straight_length - end length at the beginning of the route.
  • snap_to_grid - Optional snap points to grid when extruding paths (um).
  • decorator - function when extruding component. For example add_pins.
  • add_pins - Optional function to add pins.
  • add_bbox - Optional function to add bounding box.
  • info - dict with extra settings or useful information.
  • name - cross_section name.
  • mirror - if True, reflects the offsets.

xsection

def xsection(func: _F) -> _F

Decorator for CrossSection functions

Validates type annotations with pydantic.

.. plot:: :include-source:

import gdsfactory as gf

@gf.cross_section.xsection
def xs_sc(width=0.5, **kwargs):
    xs = gf.cross_section.cross_section(width=width, **kwargs)
    return xs

p = gf.path.arc(radius=10, angle=45)
c = p.extrude(xs_sc)
c.plot()

cross_section

@xsection
def cross_section(width: Callable | float = 0.5,
                  offset: float | Callable = 0,
                  layer: LayerSpec | None = "WG",
                  width_wide: float | None = None,
                  auto_widen: bool = False,
                  auto_widen_minimum_length: float = 200.0,
                  taper_length: float = 10.0,
                  radius: float | None = 10.0,
                  sections: tuple[Section, ...] | None = None,
                  port_names: tuple[str, str] = ("o1", "o2"),
                  port_types: tuple[str, str] = ("optical", "optical"),
                  gap: float = 3.0,
                  min_length: float = 10e-3,
                  start_straight_length: float = 10e-3,
                  end_straight_length: float = 10e-3,
                  snap_to_grid: float | None = None,
                  bbox_layers: list[LayerSpec] | None = None,
                  bbox_offsets: list[float] | None = None,
                  cladding_layers: LayerSpecs | None = None,
                  cladding_offsets: Floats | None = None,
                  cladding_simplify: Floats | None = cladding_simplify_optical,
                  info: dict[str, Any] | None = None,
                  decorator: Callable | None = None,
                  add_pins: Callable | None = None,
                  add_bbox: Callable | None = None,
                  mirror: bool = False,
                  name: str | None = None) -> CrossSection

Return CrossSection.

Arguments:

  • width - main Section width (um) or function parameterized from 0 to 1. the width at t==0 is the width at the beginning of the Path. the width at t==1 is the width at the end.

  • offset - main Section center offset (um) or function from 0 to 1. the offset at t==0 is the offset at the beginning of the Path. the offset at t==1 is the offset at the end.

  • layer - main section layer.

  • width_wide - wide waveguides width (um) for low loss routing.

  • auto_widen - taper to wide waveguides for low loss routing.

  • auto_widen_minimum_length - minimum straight length for auto_widen.

  • taper_length - taper_length for auto_widen.

  • radius - bend radius (um).

  • sections - list of Sections(width, offset, layer, ports).

  • port_names - for input and output (‘o1’, ‘o2’).

  • port_types - for input and output: electrical, optical, vertical_te ...

  • gap - edge to edge waveguide gap for routing.

  • min_length - defaults to 1nm = 10e-3um for routing.

  • start_straight_length - straight length at the beginning of the route.

  • end_straight_length - end length at the beginning of the route.

  • snap_to_grid - can snap points to grid when extruding the path.

  • bbox_layers - list of layers for rectangular bounding box.

  • bbox_offsets - list of bounding box offsets.

  • cladding_layers - list of layers to extrude.

  • cladding_offsets - list of offset from main Section edge.

  • cladding_simplify - Optional Tolerance value for the simplification algorithm. All points that can be removed without changing the resulting. polygon by more than the value listed here will be removed.

  • info - settings info.

  • decorator - function to run when converting path to component.

  • add_pins - optional function to add pins to component.

  • add_bbox - optional function to add bounding box to component.

  • mirror - if True, reflects the offsets.

  • name - cross_section name.

    .. plot:: :include-source:

    import gdsfactory as gf

    xs = gf.cross_section.cross_section(width=0.5, offset=0, layer=‘WG’) p = gf.path.arc(radius=10, angle=45) c = p.extrude(xs) c.plot()

slot

@xsection
def slot(width: float = 0.5,
         layer: LayerSpec = "WG",
         slot_width: float = 0.04,
         **kwargs) -> CrossSection

Return CrossSection Slot (with an etched region in the center).

Arguments:

  • width - main Section width (um) or function parameterized from 0 to 1. the width at t==0 is the width at the beginning of the Path. the width at t==1 is the width at the end.
  • layer - main section layer.
  • slot_width - in um.

Arguments:

  • offset - main Section center offset (um) or function from 0 to 1. the offset at t==0 is the offset at the beginning of the Path. the offset at t==1 is the offset at the end.

  • width_wide - wide waveguides width (um) for low loss routing.

  • auto_widen - taper to wide waveguides for low loss routing.

  • auto_widen_minimum_length - minimum straight length for auto_widen.

  • taper_length - taper_length for auto_widen.

  • radius - bend radius (um).

  • sections - list of Sections(width, offset, layer, ports).

  • port_names - for input and output (‘o1’, ‘o2’).

  • port_types - for input and output: electrical, optical, vertical_te ...

  • min_length - defaults to 1nm = 10e-3um for routing.

  • start_straight_length - straight length at the beginning of the route.

  • end_straight_length - end length at the beginning of the route.

  • snap_to_grid - can snap points to grid when extruding the path.

  • bbox_layers - list of layers for rectangular bounding box.

  • bbox_offsets - list of bounding box offsets.

  • cladding_layers - list of layers to extrude.

  • cladding_offsets - list of offset from main Section edge.

  • cladding_simplify - Optional Tolerance value for the simplification algorithm. All points that can be removed without changing the resulting. polygon by more than the value listed here will be removed.

  • info - settings info.

  • decorator - function to run when converting path to component.

  • add_pins - optional function to add pins to component.

  • add_bbox - optional function to add bounding box to component.

    .. plot:: :include-source:

    import gdsfactory as gf

    xs = gf.cross_section.slot(width=0.5, slot_width=0.05, layer=‘WG’) p = gf.path.arc(radius=10, angle=45) c = p.extrude(xs) c.plot()

rib_with_trenches

@xsection
def rib_with_trenches(width: float = 0.5,
                      width_trench: float = 2.0,
                      width_slab: float = 7.0,
                      simplify_slab: float | None = None,
                      layer: LayerSpec | None = "WG",
                      layer_trench: LayerSpec = "DEEP_ETCH",
                      wg_marking_layer: LayerSpec | None = None,
                      **kwargs) -> CrossSection

Return CrossSection of rib waveguide defined by trenches.

Arguments:

  • width - main Section width (um) or function parameterized from 0 to 1. the width at t==0 is the width at the beginning of the Path. the width at t==1 is the width at the end.

  • width_trench - in um.

  • width_slab - in um.

  • layer - ridge layer. None adds only ridge.

  • layer_trench - layer to etch trenches.

  • wg_marking_layer - layer to draw over the actual waveguide. This can be useful for booleans, routing, placement ...

  • kwargs - cross_section settings.

    .. code::


    | | | | || ||


    <-------> | width_trench | <----------------------------------------> width_slab

    .. plot:: :include-source:

    import gdsfactory as gf

    xs = gf.cross_section.rib_with_trenches(width=0.5) p = gf.path.arc(radius=10, angle=45) c = p.extrude(xs) c.plot()

l_with_trenches

@xsection
def l_with_trenches(width: float = 0.5,
                    width_trench: float = 2.0,
                    width_slab: float = 7.0,
                    layer: LayerSpec | None = "WG",
                    layer_trench: LayerSpec = "DEEP_ETCH",
                    mirror: bool = False,
                    wg_marking_layer: LayerSpec | None = None,
                    **kwargs) -> CrossSection

Return CrossSection of l waveguide defined by trenches.

Arguments:

  • width - main Section width (um) or function parameterized from 0 to 1. the width at t==0 is the width at the beginning of the Path. the width at t==1 is the width at the end.

  • width_slab - in um.

  • width_trench - in um.

  • layer - ridge layer. None adds only ridge.

  • layer_trench - layer to etch trenches.

  • mirror - this cross section is not symmetric and you can switch orientation.

  • kwargs - cross_section settings.

    .. code:: x = 0 | |


    | | | |________| |


    <-------> | width_trench <--------> width | <------------------------> width_slab

    .. plot:: :include-source:

    import gdsfactory as gf

    xs = gf.cross_section.l_with_trenches(width=0.5) p = gf.path.arc(radius=10, angle=45) c = p.extrude(xs) c.plot()

pin

@xsection
def pin(width: float = 0.5,
        layer: LayerSpec = "WG",
        layer_slab: LayerSpec = "SLAB90",
        layers_via_stack1: LayerSpecs = ("PPP", ),
        layers_via_stack2: LayerSpecs = ("NPP", ),
        bbox_offsets_via_stack1: tuple[float, ...] = (0, -0.2),
        bbox_offsets_via_stack2: tuple[float, ...] = (0, -0.2),
        via_stack_width: float = 9.0,
        via_stack_gap: float = 0.55,
        slab_gap: float = -0.2,
        layer_via: LayerSpec | None = None,
        via_width: float = 1,
        via_offsets: tuple[float, ...] | None = None,
        **kwargs) -> CrossSection

Rib PIN doped cross_section.

Arguments:

  • width - ridge width.

  • layer - ridge layer.

  • layer_slab - slab layer.

  • layers_via_stack1 - P++ layer.

  • layers_via_stack2 - N++ layer.

  • bbox_offsets_via_stack1 - for via left.

  • bbox_offsets_via_stack2 - for via right.

  • via_stack_width - in um.

  • via_stack_gap - offset from via_stack to ridge edge.

  • slab_gap - extra slab gap (negative: via_stack goes beyond slab).

  • layer_via - for via.

  • via_width - in um.

  • via_offsets - in um.

  • kwargs - other cross_section settings.

    Fatemi et al. (2018)

    .. code::

    layer |<----width--->| _______________ via_stack_gap slab_gap | |<----------->| <--> ___ | || | | | | | | | | P++ | undoped silicon | N++ | | |||_______________||| <-----------> via_stack_width <----------------------------------------------------------------------> slab_width

    .. plot:: :include-source:

    import gdsfactory as gf

    xs = gf.cross_section.pin(width=0.5, via_stack_gap=1, via_stack_width=1) p = gf.path.arc(radius=10, angle=45) c = p.extrude(xs) c.plot()

pn

@xsection
def pn(width: float = 0.5,
       layer: LayerSpec = "WG",
       layer_slab: LayerSpec = "SLAB90",
       gap_low_doping: float = 0.0,
       gap_medium_doping: float | None = 0.5,
       gap_high_doping: float | None = 1.0,
       offset_low_doping: float | None = 0.0,
       width_doping: float = 8.0,
       width_slab: float = 7.0,
       layer_p: LayerSpec | None = "P",
       layer_pp: LayerSpec | None = "PP",
       layer_ppp: LayerSpec | None = "PPP",
       layer_n: LayerSpec | None = "N",
       layer_np: LayerSpec | None = "NP",
       layer_npp: LayerSpec | None = "NPP",
       layer_via: LayerSpec | None = None,
       width_via: float = 1.0,
       layer_metal: LayerSpec | None = None,
       width_metal: float = 1.0,
       port_names: tuple[str, str] = ("o1", "o2"),
       bbox_layers: list[Layer] | None = None,
       bbox_offsets: list[float] | None = None,
       cladding_layers: Layers | None = cladding_layers_optical,
       cladding_offsets: Floats | None = cladding_offsets_optical,
       cladding_simplify: Floats | None = cladding_simplify_optical,
       mirror: bool = False,
       **kwargs) -> CrossSection

Rib PN doped cross_section.

Arguments:

  • width - width of the ridge in um.

  • layer - ridge layer.

  • layer_slab - slab layer.

  • gap_low_doping - from waveguide center to low doping. Only used for PIN.

  • gap_medium_doping - from waveguide center to medium doping. None removes medium doping.

  • gap_high_doping - from center to high doping. None removes it.

  • offset_low_doping - from center to junction center.

  • width_doping - in um.

  • width_slab - in um.

  • layer_p - p doping layer.

  • layer_pp - p+ doping layer.

  • layer_ppp - p++ doping layer.

  • layer_n - n doping layer.

  • layer_np - n+ doping layer.

  • layer_npp - n++ doping layer.

  • layer_via - via layer.

  • width_via - via width in um.

  • layer_metal - metal layer.

  • width_metal - metal width in um.

  • port_names - input and output port names.

  • bbox_layers - list of layers for rectangular bounding box.

  • bbox_offsets - list of bounding box offsets.

  • bbox_layers - list of layers for rectangular bounding box.

  • bbox_offsets - list of bounding box offsets.

  • cladding_layers - optional list of cladding layers.

  • cladding_offsets - optional list of cladding offsets.

  • cladding_simplify - Optional Tolerance value for the simplification algorithm. All points that can be removed without changing the resulting. polygon by more than the value listed here will be removed.

  • mirror - if True, reflects all doping sections.

    .. code::

    offset_low_doping <------> | | wg junction center center | | ______|_| | | | | | | | || P | | N | width_p | | width_n | <----------------------------->|<--------------------->| | | N+ | | | width_n | | |<------------->| |<------------->| gap_medium_doping

    .. plot:: :include-source:

    import gdsfactory as gf

    xs = gf.cross_section.pn(width=0.5, gap_low_doping=0, width_doping=2.) p = gf.path.arc(radius=10, angle=45) c = p.extrude(xs) c.plot()

pn_with_trenches

@xsection
def pn_with_trenches(width: float = 0.5,
                     layer: LayerSpec | None = None,
                     layer_trench: LayerSpec = "DEEP_ETCH",
                     gap_low_doping: float = 0.0,
                     gap_medium_doping: float | None = 0.5,
                     gap_high_doping: float | None = 1.0,
                     offset_low_doping: float | None = 0.0,
                     width_doping: float = 8.0,
                     width_slab: float = 7.0,
                     width_trench: float = 2.0,
                     layer_p: LayerSpec | None = "P",
                     layer_pp: LayerSpec | None = "PP",
                     layer_ppp: LayerSpec | None = "PPP",
                     layer_n: LayerSpec | None = "N",
                     layer_np: LayerSpec | None = "NP",
                     layer_npp: LayerSpec | None = "NPP",
                     layer_via: LayerSpec | None = None,
                     width_via: float = 1.0,
                     layer_metal: LayerSpec | None = None,
                     width_metal: float = 1.0,
                     port_names: tuple[str, str] = ("o1", "o2"),
                     bbox_layers: list[Layer] | None = None,
                     bbox_offsets: list[float] | None = None,
                     cladding_layers: Layers | None = cladding_layers_optical,
                     cladding_offsets: Floats
                     | None = cladding_offsets_optical,
                     cladding_simplify: Floats
                     | None = cladding_simplify_optical,
                     mirror: bool = False,
                     wg_marking_layer: LayerSpec | None = None,
                     **kwargs) -> CrossSection

Rib PN doped cross_section.

Arguments:

  • width - width of the ridge in um.

  • layer - ridge layer. None adds only ridge.

  • layer_trench - layer to etch trenches.

  • gap_low_doping - from waveguide center to low doping. Only used for PIN.

  • gap_medium_doping - from waveguide center to medium doping. None removes medium doping.

  • gap_high_doping - from center to high doping. None removes it.

  • offset_low_doping - from center to junction center.

  • width_doping - in um.

  • width_slab - in um.

  • width_trench - in um.

  • layer_p - p doping layer.

  • layer_pp - p+ doping layer.

  • layer_ppp - p++ doping layer.

  • layer_n - n doping layer.

  • layer_np - n+ doping layer.

  • layer_npp - n++ doping layer.

  • layer_via - via layer.

  • width_via - via width in um.

  • layer_metal - metal layer.

  • width_metal - metal width in um.

  • port_names - input and output port names.

  • bbox_layers - list of layers for rectangular bounding box.

  • bbox_offsets - list of bounding box offsets.

  • bbox_layers - list of layers for rectangular bounding box.

  • bbox_offsets - list of bounding box offsets.

  • cladding_layers - optional list of cladding layers.

  • cladding_offsets - optional list of cladding offsets.

  • cladding_simplify - Optional Tolerance value for the simplification algorithm. All points that can be removed without changing the resulting. polygon by more than the value listed here will be removed.

  • mirror - if True, reflects all doping sections.

  • kwargs - cross_section settings.

    .. code::

    offset_low_doping <------> | | wg junction center center | | _____ | ______ ________ | | | | | | | || | |________| | P | | N | width_p | width_n | <-------------------------------->|<--------------------->| <-------> | | N+ | width_trench | | width_n | | |<------------->| |<------------->| gap_medium_doping <------------------------------------------------------------> width_slab

    .. plot:: :include-source:

    import gdsfactory as gf

    xs = gf.cross_section.pn_with_trenches(width=0.5, gap_low_doping=0, width_doping=2.) p = gf.path.arc(radius=10, angle=45) c = p.extrude(xs) c.plot()

pn_with_trenches_asymmetric

@xsection
def pn_with_trenches_asymmetric(width: float = 0.5,
                                layer: LayerSpec | None = None,
                                layer_trench: LayerSpec = "DEEP_ETCH",
                                gap_low_doping: float
                                | tuple[float, float] = (0.0, 0.0),
                                gap_medium_doping: float | tuple[float, float]
                                | None = (0.5, 0.2),
                                gap_high_doping: float | tuple[float, float]
                                | None = (1.0, 0.8),
                                width_doping: float = 8.0,
                                width_slab: float = 7.0,
                                width_trench: float = 2.0,
                                layer_p: LayerSpec | None = "P",
                                layer_pp: LayerSpec | None = "PP",
                                layer_ppp: LayerSpec | None = "PPP",
                                layer_n: LayerSpec | None = "N",
                                layer_np: LayerSpec | None = "NP",
                                layer_npp: LayerSpec | None = "NPP",
                                layer_via: LayerSpec | None = None,
                                width_via: float = 1.0,
                                layer_metal: LayerSpec | None = None,
                                width_metal: float = 1.0,
                                port_names: tuple[str, str] = ("o1", "o2"),
                                bbox_layers: list[Layer] | None = None,
                                bbox_offsets: list[float] | None = None,
                                cladding_layers: Layers
                                | None = cladding_layers_optical,
                                cladding_offsets: Floats
                                | None = cladding_offsets_optical,
                                mirror: bool = False,
                                wg_marking_layer: LayerSpec | None = None,
                                **kwargs) -> CrossSection

Rib PN doped cross_section with asymmetric dimensions left and right.

Arguments:

  • width - width of the ridge in um.

  • layer - ridge layer. None adds only ridge.

  • layer_trench - layer to etch trenches.

  • gap_low_doping - from waveguide center to low doping. Only used for PIN. If a list, it considers the first element is [p_side, n_side]. If a number, it assumes the same for both sides.

  • gap_medium_doping - from waveguide center to medium doping. None removes medium doping. If a list, it considers the first element is [p_side, n_side]. If a number, it assumes the same for both sides.

  • gap_high_doping - from center to high doping. None removes it. If a list, it considers the first element is [p_side, n_side]. If a number, it assumes the same for both sides.

  • width_doping - in um.

  • width_slab - in um.

  • width_trench - in um.

  • layer_p - p doping layer.

  • layer_pp - p+ doping layer.

  • layer_ppp - p++ doping layer.

  • layer_n - n doping layer.

  • layer_np - n+ doping layer.

  • layer_npp - n++ doping layer.

  • layer_via - via layer.

  • width_via - via width in um.

  • layer_metal - metal layer.

  • width_metal - metal width in um.

  • port_names - input and output port names.

  • bbox_layers - list of layers for rectangular bounding box.

  • bbox_offsets - list of bounding box offsets.

  • bbox_layers - list of layers for rectangular bounding box.

  • bbox_offsets - list of bounding box offsets.

  • cladding_layers - optional list of cladding layers.

  • cladding_offsets - optional list of cladding offsets.

  • mirror - if True, reflects all doping sections.

  • kwargs - cross_section settings.

    .. code::

    gap_low_doping[1] <------> | | wg junction center center | | _____ | ______ ________ | | | | | | | || | |________| | P | | N | width_p | width_n | <-------------------------------->|<--------------------->| <-------> | | N+ | width_trench | | width_n | | |<------------->| |<------------->| gap_medium_doping[1] <------------------------------------------------------------> width_slab

    .. plot:: :include-source:

    import gdsfactory as gf

    xs = gf.cross_section.pn_with_trenches_assymmetric(width=0.5, gap_low_doping=0, width_doping=2.) p = gf.path.arc(radius=10, angle=45) c = p.extrude(xs) c.plot()

l_wg_doped_with_trenches

@xsection
def l_wg_doped_with_trenches(width: float = 0.5,
                             layer: LayerSpec | None = None,
                             layer_trench: LayerSpec = "DEEP_ETCH",
                             gap_low_doping: float = 0.0,
                             gap_medium_doping: float | None = 0.5,
                             gap_high_doping: float | None = 1.0,
                             width_doping: float = 8.0,
                             width_slab: float = 7.0,
                             width_trench: float = 2.0,
                             layer_low: LayerSpec = "P",
                             layer_mid: LayerSpec = "PP",
                             layer_high: LayerSpec = "PPP",
                             layer_via: LayerSpec | None = None,
                             width_via: float = 1.0,
                             layer_metal: LayerSpec | None = None,
                             width_metal: float = 1.0,
                             port_names: tuple[str, str] = ("o1", "o2"),
                             bbox_layers: list[Layer] | None = None,
                             bbox_offsets: list[float] | None = None,
                             cladding_layers: Layers
                             | None = cladding_layers_optical,
                             cladding_offsets: Floats
                             | None = cladding_offsets_optical,
                             mirror: bool = False,
                             wg_marking_layer: LayerSpec | None = None,
                             **kwargs) -> CrossSection

L waveguide PN doped cross_section.

Arguments:

  • width - width of the ridge in um.

  • layer - ridge layer. None adds only ridge.

  • layer_trench - layer to etch trenches.

  • gap_low_doping - from waveguide outer edge to low doping. Only used for PIN.

  • gap_medium_doping - from waveguide edge to medium doping. None removes medium doping.

  • gap_high_doping - from edge to high doping. None removes it.

  • width_doping - in um.

  • width_slab - in um.

  • width_trench - in um.

  • layer_low - low doping layer.

  • layer_mid - mid doping layer.

  • layer_high - high doping layer.

  • layer_via - via layer.

  • width_via - via width in um.

  • layer_metal - metal layer.

  • width_metal - metal width in um.

  • port_names - input and output port names.

  • bbox_layers - list of layers for rectangular bounding box.

  • bbox_offsets - list of bounding box offsets.

  • bbox_layers - list of layers for rectangular bounding box.

  • bbox_offsets - list of bounding box offsets.

  • cladding_layers - optional list of cladding layers.

  • cladding_offsets - optional list of cladding offsets.

  • mirror - if True, reflects all doping sections.

  • wg_marking_layer - layer to mark where the actual guiding section is.

  • kwargs - cross_section settings.

    .. code::

    gap_low_doping <------> | wg edge |


    | | | |_____________________| | | | <------------> width <---------------------> | width_trench | | | | |<----------------->| gap_medium_doping |<--------------------------->| gap_high_doping <-------------------------------------------> width_slab

    .. plot:: :include-source:

    import gdsfactory as gf

    xs = gf.cross_section.pn_with_trenches(width=0.5, gap_low_doping=0, width_doping=2.) p = gf.path.arc(radius=10, angle=45) c = p.extrude(xs) c.plot()

strip_heater_metal_undercut

@xsection
def strip_heater_metal_undercut(width: float = 0.5,
                                layer: LayerSpec = "WG",
                                heater_width: float = 2.5,
                                trench_width: float = 6.5,
                                trench_gap: float = 2.0,
                                layer_heater: LayerSpec = "HEATER",
                                layer_trench: LayerSpec = "DEEPTRENCH",
                                **kwargs) -> CrossSection

Returns strip cross_section with top metal and undercut trenches on both.

sides.

dimensions from Dong et al. (2010)

Arguments:

  • width - waveguide width.

  • layer - waveguide layer.

  • heater_width - of metal heater.

  • trench_width - in um.

  • trench_gap - from waveguide edge to trench edge.

  • layer_heater - heater layer.

  • layer_trench - tench layer.

  • kwargs - cross_section settings.

    .. code::

    |<-------heater_width--------->|


    | | | layer_heater | |______________________________|

    |<------width------>| ____________________ trench_gap | |<----------->| | | | | undercut | | width | | | | | |<------------>| |___________________| | trench_width | | | | |

    .. plot:: :include-source:

    import gdsfactory as gf

    xs = gf.cross_section.strip_heater_metal_undercut(width=0.5, heater_width=2, trench_width=4, trench_gap=4) p = gf.path.arc(radius=10, angle=45) c = p.extrude(xs) c.plot()

strip_heater_metal

@xsection
def strip_heater_metal(width: float = 0.5,
                       layer: LayerSpec = "WG",
                       heater_width: float = 2.5,
                       layer_heater: LayerSpec = "HEATER",
                       **kwargs) -> CrossSection

Returns strip cross_section with top heater metal.

dimensions from Dong et al. (2010)

Arguments:

  • width - waveguide width (um).

  • layer - waveguide layer.

  • heater_width - of metal heater.

  • layer_heater - for the metal.

    .. plot:: :include-source:

    import gdsfactory as gf

    xs = gf.cross_section.strip_heater_metal(width=0.5, heater_width=2) p = gf.path.arc(radius=10, angle=45) c = p.extrude(xs) c.plot()

strip_heater_doped

@xsection
def strip_heater_doped(width: float = 0.5,
                       layer: LayerSpec = "WG",
                       heater_width: float = 2.0,
                       heater_gap: float = 0.8,
                       layers_heater: LayerSpecs = ("WG", "NPP"),
                       bbox_offsets_heater: tuple[float, ...] = (0, 0.1),
                       **kwargs) -> CrossSection

Returns strip cross_section with N++ doped heaters on both sides.

Arguments:

  • width - in um.

  • layer - waveguide spec.

  • heater_width - in um.

  • heater_gap - in um.

  • layers_heater - for doped heater.

  • bbox_offsets_heater - for each layers_heater.

  • kwargs - cross_section settings.

    .. code::

    |<------width------>|


    | | | undoped Si | | | |layer_heater| | intrinsic region |<----------->| layer_heater | || |_______| |______________| <------------> heater_gap heater_width

    .. plot:: :include-source:

    import gdsfactory as gf

    xs = gf.cross_section.strip_heater_doped(width=0.5, heater_width=2, heater_gap=0.5) p = gf.path.arc(radius=10, angle=45) c = p.extrude(xs) c.plot()

rib_heater_doped

@xsection
def rib_heater_doped(width: float = 0.5,
                     layer: LayerSpec = "WG",
                     heater_width: float = 2.0,
                     heater_gap: float = 0.8,
                     layer_heater: LayerSpec = "NPP",
                     layer_slab: LayerSpec = "SLAB90",
                     slab_gap: float = 0.2,
                     with_top_heater: bool = True,
                     with_bot_heater: bool = True,
                     **kwargs) -> CrossSection

Returns rib cross_section with N++ doped heaters on both sides.

dimensions from Jacques et al. (2019)

.. code::

                            |<------width------>|
                             ____________________  heater_gap           slab_gap
                            |                   |<----------->|             <-->
 ___ _______________________|                   |__________________________|___
|   |            |                undoped Si                  |            |   |
|   |layer_heater|                intrinsic region            |layer_heater|   |
|___|____________|____________________________________________|____________|___|
                                                               <---------->
                                                                heater_width
<------------------------------------------------------------------------------>
                                slab_width

.. plot:: :include-source:

import gdsfactory as gf

xs = gf.cross_section.rib_heater_doped(width=0.5, heater_width=2, heater_gap=0.5, layer_heater='NPP')
p = gf.path.arc(radius=10, angle=45)
c = p.extrude(xs)
c.plot()

rib_heater_doped_via_stack

@xsection
def rib_heater_doped_via_stack(width: float = 0.5,
                               layer: LayerSpec = "WG",
                               heater_width: float = 1.0,
                               heater_gap: float = 0.8,
                               layer_slab: LayerSpec = "SLAB90",
                               layer_heater: LayerSpec = "NPP",
                               via_stack_width: float = 2.0,
                               via_stack_gap: float = 0.8,
                               layers_via_stack: LayerSpecs = ("NPP", "VIAC"),
                               bbox_offsets_via_stack: tuple[float,
                                                             ...] = (0, -0.2),
                               slab_gap: float = 0.2,
                               slab_offset: float = 0,
                               with_top_heater: bool = True,
                               with_bot_heater: bool = True,
                               **kwargs) -> CrossSection

Returns rib cross_section with N++ doped heaters on both sides.

dimensions from Jacques et al. (2019)

Arguments:

  • width - in um.

  • layer - for main waveguide section.

  • heater_width - in um.

  • heater_gap - in um.

  • layer_slab - for pedestal.

  • layer_heater - for doped heater.

  • via_stack_width - for the contact.

  • via_stack_gap - in um.

  • layers_via_stack - for the contact.

  • bbox_offsets_via_stack - for the contact.

  • slab_gap - from heater edge.

  • slab_offset - over the center of the slab.

  • with_top_heater - adds top/left heater.

  • with_bot_heater - adds bottom/right heater.

    .. code::

    |<----width------>| slab_gap __________________ via_stack_gap via_stack width <--> | |<------------>|<---------------> | | heater_gap | | |<---------->| ___ | |____ ____ | | | undoped Si | | | | |layer_heater| intrinsic region |layer_heater | | |||__________________||____| <------------> heater_width <------------------------------------------------------------------------------> slab_width

    .. plot:: :include-source:

    import gdsfactory as gf

    xs = gf.cross_section.rib_heater_doped_via_stack(width=0.5, heater_width=2, heater_gap=0.5, layer_heater=‘NPP’) p = gf.path.arc(radius=10, angle=45) c = p.extrude(xs) c.plot()

pn_ge_detector_si_contacts

@xsection
def pn_ge_detector_si_contacts(
    width_si: float = 6.0,
    layer_si: LayerSpec = "WG",
    width_ge: float = 3.0,
    layer_ge: LayerSpec = "GE",
    gap_low_doping: float = 0.6,
    gap_medium_doping: float | None = 0.9,
    gap_high_doping: float | None = 1.1,
    width_doping: float = 8.0,
    layer_p: LayerSpec = "P",
    layer_pp: LayerSpec = "PP",
    layer_ppp: LayerSpec = "PPP",
    layer_n: LayerSpec = "N",
    layer_np: LayerSpec = "NP",
    layer_npp: LayerSpec = "NPP",
    layer_via: LayerSpec | None = None,
    width_via: float = 1.0,
    layer_metal: LayerSpec | None = None,
    port_names: tuple[str, str] = ("o1", "o2"),
    bbox_layers: list[Layer] | None = None,
    bbox_offsets: list[float] | None = None,
    cladding_layers: Layers | None = cladding_layers_optical,
    cladding_offsets: Floats | None = cladding_offsets_optical
) -> CrossSection

Linear Ge detector cross section based on a lateral p(i)n junction.

It has silicon contacts (no contact on the Ge). The contacts need to be created in the component generating function (they can’t be created here).

See Chen et al., “High-Responsivity Low-Voltage 28-Gb/s Ge p-i-n Photodetector With Silicon Contacts”, Journal of Lightwave Technology 33(4), 2015.

Notice it is possible to have dopings going beyond the ridge waveguide. This is fine, and it is to account for the presence of the contacts. Such contacts can be subwavelength or not.

Arguments:

  • width_si - width of the full etch si in um.

  • layer_si - si ridge layer.

  • width_ge - width of the ge in um.

  • layer_ge - ge layer.

  • gap_low_doping - from waveguide center to low doping.

  • gap_medium_doping - from waveguide center to medium doping. None removes medium doping.

  • gap_high_doping - from center to high doping. None removes it.

  • width_doping - distance from the waveguide center to the edge of the p (or n) dopings in um.

  • layer_p - p doping layer.

  • layer_pp - p+ doping layer.

  • layer_ppp - p++ doping layer.

  • layer_n - n doping layer.

  • layer_np - n+ doping layer.

  • layer_npp - n++ doping layer.

  • layer_via - via layer.

  • width_via - via width in um.

  • layer_metal - metal layer.

  • bbox_layers - list of layers for rectangular bounding box.

  • bbox_offsets - list of bounding box offsets.

  • port_names - for input and output (‘o1’, ‘o2’).

  • bbox_layers - list of layers for rectangular bounding box.

  • bbox_offsets - list of bounding box offsets.

    .. code::

    layer_si |<------width_si---->|

    layer_ge |<--width_ge->|


    | | |__________| | | | | | | | | P | | | | N | width_p ||_______|__| width_n | <----------------------->| |<------------------------------>| |<->| gap_low_doping | | N+ | | | width_np | | |<------------------------>| |<------->| | gap_medium_doping | |<---------------------------------->| width_doping

    .. plot:: :include-source:

    import gdsfactory as gf

    xs = gf.cross_section.pn() p = gf.path.arc(radius=10, angle=45) c = p.extrude(xs) c.plot()

get_cross_section_factories

def get_cross_section_factories(modules,
                                verbose: bool = False
                                ) -> dict[str, CrossSectionFactory]

Returns cross_section factories from a module or list of modules.

Arguments:

  • modules - module or iterable of modules.
  • verbose - prints in case any errors occur.

gdsfactory.config

Gdsfactory loads configuration pydantic.

You can set environment variables.

def print_version_plugins() -> None

Print gdsfactory plugin versions and paths.

def print_version_plugins_raw() -> None

Print gdsfactory plugin versions and paths.

def print_version_pdks() -> None

Print gdsfactory PDK versions and paths.

get_number_of_cores

def get_number_of_cores() -> int

Get number of cores/threads available.

On (most) linux we can get it through the scheduling affinity. Otherwise, fall back to the multiprocessing cpu count.

tracing_formatter

def tracing_formatter(record: loguru.Record) -> str

Traceback filtering.

Filter out frames coming from Loguru internals.

Settings Objects

class Settings(BaseSettings)

GDSFACTORY settings object.

Attributes:

  • n_threads - Number of threads to use for multiprocessing.
  • display_type - Display type for components.
  • last_saved_files - List of last saved files.
  • max_name_length - Maximum length of component names.
  • model_config - Pydantic model configuration.
  • loglevel - Log level.
  • pdk - PDK to use. Defaults to generic.
  • difftest_ignore_cell_name_differences - Ignore cell name differences in difftest.

from_config

@classmethod
def from_config(cls) -> Settings

Load settings from YAML config file. Recursively search for a gfconfig.yml file in the current working directory.

Paths Objects

class Paths()

sparameters_repo

repo with some demo sparameters

rich_output

def rich_output() -> None

Enables rich output.

write_config

def write_config(config: Any, json_out_path: Path) -> None

Write config to a JSON file.

def print_config(key: str | None = None) -> None

Prints a key for the config or all the keys.

call_if_func

def call_if_func(f: Any, **kwargs) -> Any

Calls function if it’s a function Useful to create objects from.

functions if it’s an object it just returns the object.

get_git_hash

def get_git_hash()

Returns repository git hash.

set_plot_options

def set_plot_options(show_ports: bool = True,
                     show_subports: bool = False,
                     label_aliases: bool = False,
                     new_window: bool = False,
                     blocking: bool = False,
                     zoom_factor: float = 1.4) -> None

Set plot options for matplotlib.

gdsfactory.plugins

gdsfactory.name

Define names, clean values for names.

get_name_short

@pydantic.validate_call
def get_name_short(name: str, max_name_length=CONF.max_name_length) -> str

Returns a short name.

join_first_letters

def join_first_letters(name: str) -> str

Join the first letter of a name separated with underscores.

taper_length -> TL

get_component_name

def get_component_name(component_type: str, *args, **kwargs) -> str

Returns concatenated kwargs Key_Value.

dict2name

def dict2name(prefix: str = "", **kwargs) -> str

Returns name from a dict.

assert_first_letters_are_different

def assert_first_letters_are_different(**kwargs)

Assert that the first letters for each key are different.

Avoids different args that start with the same first letter getting the same hash.

def print_first_letters_warning(**kwargs) -> None

Prints kwargs that have same cell.

clean_name

def clean_name(name: str,
               remove_dots: bool = False,
               allowed_characters: list[str] | None = None) -> str

Return a string with correct characters for a cell name.

By default, the characters [a-zA-Z0-9] are allowed.

Arguments:

  • name str - The name to clean.
  • remove_dots bool, optional - Whether to remove dots from the name. Defaults to False.
  • allowed_characters list[str], optional - List of additional allowed characters. Defaults to an empty list.

Returns:

  • str - The cleaned name.

gdsfactory.watch

FileWatcher based on watchdog. Looks for changes in files with .pic.yml extension.

FileWatcher Objects

class FileWatcher(FileSystemEventHandler)

Captures *.py or *.pic.yml file change events.

__init__

def __init__(logger=None, path: str | None = None) -> None

Initialize the YAML event handler.

update_cell

def update_cell(src_path, update: bool = False) -> Callable

Parses a YAML file to a cell function and registers into active pdk.

Arguments:

  • src_path - the path to the file
  • update - if True, will update an existing cell function of the same name without raising an error

Returns:

The cell function parsed from the yaml file.

gdsfactory.klive

Stream GDS to Klayout. Requires gdsfactory KLayout integration.

show

def show(gds_filename: Path | str,
         keep_position: bool = True,
         technology: str | None = None,
         port: int = 8082,
         delete: bool = False) -> None

Show GDS in klayout.

Arguments:

  • gds_filename - to show.
  • keep_position - keep position and active layers.
  • technology - Name of the KLayout technology to use.
  • port - klayout server port.
  • delete - deletes file.

gdsfactory.simulation

gdsfactory.constants

gdsfactory.functions

All functions return a Component so you can easily pipe or compose them.

There are two types of functions:

  • decorators: return the original component
  • containers: return a new component that contains the old one.

add_port

def add_port(component: Component, **kwargs) -> Component

Return Component with a new port.

add_text

@cell
def add_text(
        component: ComponentSpec,
        text: str = "",
        text_offset: Float2 = (0, 0),
        text_anchor: Anchor = "cc",
        text_factory: ComponentSpec = text_rectangular_multi_layer
) -> Component

Return component inside a new component with text geometry.

Arguments:

  • component - component spec.
  • text - text string.
  • text_offset - relative to component anchor. Defaults to center (cc).
  • text_anchor - relative to component (ce cw nc ne nw sc se sw center cc).
  • text_factory - function to add text labels.

add_texts

def add_texts(components: list[ComponentSpec],
              prefix: str = "",
              index0: int = 0,
              **kwargs) -> list[Component]

Return a list of Component with text labels.

Arguments:

  • components - list of component specs.

  • prefix - Optional prefix for the labels.

  • index0 - defaults to 0 (0, for first component, 1 for second ...).

    keyword Args:

  • text_offset - relative to component size info anchor. Defaults to center.

  • text_anchor - relative to component (ce cw nc ne nw sc se sw center cc).

  • text_factory - function to add text labels.

rotate

@cell
def rotate(component: ComponentSpec,
           angle: float = 90,
           recenter: bool = False) -> Component

Return rotated component inside a new component.

Most times you just need to place a reference and rotate it. This rotate function just encapsulates the rotated reference into a new component.

Arguments:

  • component - spec.
  • angle - to rotate in degrees.
  • recenter - recenter component after rotating.

mirror

@cell
def mirror(
    component: ComponentSpec, p1: Float2 = (0, 1), p2: Float2 = (0, 0)
) -> Component

Return new Component with a mirrored reference.

Arguments:

  • component - component spec.
  • p1 - first point to define mirror axis.
  • p2 - second point to define mirror axis.

move

@cell
def move(component: Component,
         origin=(0, 0),
         destination=None,
         axis: Axis | None = None) -> Component

Return new Component with a moved reference to the original component.

Arguments:

  • component - to move.
  • origin - of component.
  • destination - Optional x, y.
  • axis - x or y axis.

transformed

@cell
def transformed(ref: ComponentReference)

Returns flattened cell with reference transformations applied.

Arguments:

  • ref - the reference to flatten into a new cell.

move_port_to_zero

def move_port_to_zero(component: Component, port_name: str = "o1")

Return a container that contains a reference to the original component.

The new component has port_name in (0, 0).

update_info

def update_info(component: Component, **kwargs) -> Component

Return Component with updated info.

add_settings_label

@validate_call
def add_settings_label(
    component: ComponentSpec = straight,
    layer_label: LayerSpec = (66, 0),
    settings: Strs | None = None,
    ignore: Strs | None = ("decorator", )
) -> Component

Add a settings label to a component. Use it as a decorator.

Arguments:

  • component - spec.
  • layer_label - for label.
  • settings - list of settings to include. if None, adds all changed settings.
  • ignore - list of settings to ignore.

gdsfactory.generic_tech.klayout.tech.layers

gdsfactory.generic_tech.klayout.lvs.drc_malformed.run_drc

Run GENERIC TECH DRC-malformed runset.

Usage: run_drc.py (--help| -h) run_drc.py (--path=<file_path>) [--verbose] [--mp=<num_cores>] [--run_dir=<run_dir_path>] [--topcell=<topcell_name>] [--thr=] [--run_mode=<run_mode>] [--offgrid]

Options: --help -h Print this help message. --path=<file_path> The input GDS file path. --topcell=<topcell_name> Topcell name to use. --mp=<num_cores> Run the rule deck in parts in parallel to speed up the run. [default: 1] --run_dir=<run_dir_path> Run directory to save all the results [default: pwd] --thr= The number of threads used in run. --run_mode=<run_mode> Select klayout mode Allowed modes (flat , deep, tiling). [default: deep] --verbose Detailed rule execution log for debugging.

get_rules_with_violations

def get_rules_with_violations(results_database)

This function will find all the rules that has violated in a database.

Parameters

results_database : string or Path object Path string to the results file

Returns

set A set that contains all rules in the database with violations

check_drc_results

def check_drc_results(results_db_files: list) -> None

check_drc_results Checks the results db generated from run and report at the end if the DRC run failed or passed. This function will exit with 1 if there are violations.

Parameters

results_db_files : list A list of strings that represent paths to results databases of all the DRC runs.

get_top_cell_names

def get_top_cell_names(gds_path)

get_top_cell_names get the top cell names from the GDS file.

Parameters

gds_path : string Path to the target GDS file.

Returns

List of string Names of the top cell in the layout.

get_run_top_cell_name

def get_run_top_cell_name(arguments, layout_path)

get_run_top_cell_name Get the top cell name to use for running. If it’s provided by the user, we use the user input. If not, we get it from the GDS file.

Parameters

arguments : dict Dictionary that holds the user inputs for the script generated by docopt. layout_path : string Path to the target layout.

Returns

string Name of the topcell to use in run.

generate_klayout_switches

def generate_klayout_switches(arguments, layout_path)

parse_switches Function that parse all the args from input to prepare switches for DRC run.

Parameters

arguments : dict Dictionary that holds the arguments used by user in the run command. This is generated by docopt library. layout_path : string Path to the layout file that we will run DRC on.

Returns

dict Dictionary that represent all run switches passed to klayout.

check_klayout_version

def check_klayout_version() -> None

check_klayout_version checks klayout version and makes sure it would work with the DRC.

check_layout_path

def check_layout_path(layout_path)

check_layout_type checks if the layout provided is GDS or OAS. Otherwise, kill the process. We only support GDS or OAS now.

Parameters

layout_path : string string that represent the path of the layout.

Returns

string string that represent full absolute layout path.

build_switches_string

def build_switches_string(sws: dict)

build_switches_string Build switches string from dictionary.

Parameters

sws : dict Dictionary that holds the Antenna switches.

run_check

def run_check(drc_file: str, drc_name: str, path: str, run_dir: str,
              sws: dict)

run_antenna_check run DRC check based on DRC file provided.

Parameters

drc_file : str String that has the file full path to run. path : str String that holds the full path of the layout. run_dir : str String that holds the full path of the run location. sws : dict Dictionary that holds all switches that needs to be passed to the antenna checks.

Returns

string string that represent the path to the results output database for this run.

run_single_processor

def run_single_processor(arguments: dict, rule_deck_full_path: str,
                         layout_path: str, switches: dict,
                         drc_run_dir: str) -> None

run_single_processor run the drc checks as single run.

Parameters

arguments : dict Dictionary that holds the arguments passed to the run_drc script. rule_deck_full_path : str String that holds the path of the rule deck files. layout_path : str Path to the target layout. switches : dict Dictionary that holds all the switches that will be passed to klayout run. drc_run_dir : str Path to the run location.

main

def main(drc_run_dir: str, now_str: str, arguments: dict) -> None

main function to run the DRC.

Parameters

drc_run_dir : str String with absolute path of the full run dir. now_str : str String with the run name for logs. arguments : dict Dictionary that holds the arguments used by user in the run command. This is generated by docopt library.

gdsfactory.generic_tech.klayout.lvs.run_lvs

Run GENERIC TECHs LVS.

Usage: run_lvs.py (--help| -h) run_lvs.py (--layout=<layout_path>) (--netlist=<netlist_path>) [--thr=] [--run_dir=<run_dir_path>] [--topcell=<topcell_name>] [--run_mode=<run_mode>] [--verbose] [--lvs_sub=<sub_name>] [--no_net_names] [--spice_comments] [--scale]

Options: --help -h Print this help message. --layout=<layout_path> The input GDS file path. --netlist=<netlist_path> The input netlist file path. --thr= The number of threads used in run. --run_dir=<run_dir_path> Run directory to save all the results [default: pwd] --topcell=<topcell_name> Topcell name to use. --run_mode=<run_mode> Select klayout mode Allowed modes (flat , deep, tiling). [default: deep ] --lvs_sub=<sub_name> Substrate name used in your design. --verbose Detailed rule execution log for debugging. --no_net_names Discard net names in extracted netlist. --spice_comments Enable netlist comments in extracted netlist. --scale Enable scale of 1e6 in extracted netlist.

check_klayout_version

def check_klayout_version() -> None

check_klayout_version checks klayout version and makes sure it would work with the LVS.

check_layout_type

def check_layout_type(layout_path)

check_layout_type checks if the layout provided is GDS or OAS. Otherwise, kill the process. We only support GDS or OAS now.

Parameters

layout_path : string string that represent the path of the layout.

Returns

string string that represent full absolute layout path.

get_top_cell_names

def get_top_cell_names(gds_path)

get_top_cell_names get the top cell names from the GDS file.

Parameters

gds_path : string Path to the target GDS file.

Returns

List of string Names of the top cell in the layout.

get_run_top_cell_name

def get_run_top_cell_name(arguments, layout_path)

get_run_top_cell_name Get the top cell name to use for running. If it’s provided by the user, we use the user input. If not, we get it from the GDS file.

Parameters

arguments : dict Dictionary that holds the user inputs for the script generated by docopt. layout_path : string Path to the target layout.

Returns

string Name of the topcell to use in run.

generate_klayout_switches

def generate_klayout_switches(arguments, layout_path, netlist_path)

parse_switches Function that parse all the args from input to prepare switches for LVS run.

Parameters

arguments : dict Dictionary that holds the arguments used by user in the run command. This is generated by docopt library. layout_path : string Path to the layout file that we will run LVS on. netlist_path : string Path to the netlist file that we will run LVS on.

Returns

dict Dictionary that represent all run switches passed to klayout.

build_switches_string

def build_switches_string(sws: dict)

build_switches_string Build switches string from dictionary.

Parameters

sws : dict Dictionary that holds the Antenna switches.

check_lvs_results

def check_lvs_results(results_db_files: list) -> None

check_lvs_results Checks the results db generated from run and report at the end if the LVS run failed or passed.

Parameters

results_db_files : list A list of strings that represent paths to results databases of all the LVS runs.

run_check

def run_check(lvs_file: str, path: str, run_dir: str, sws: dict)

run_check run LVS check.

Parameters

lvs_file : str String that has the file full path to run. path : str String that holds the full path of the layout. run_dir : str String that holds the full path of the run location. sws : dict Dictionary that holds all switches that needs to be passed to the antenna checks.

Returns

string string that represent the path to the results output database for this run.

main

def main(lvs_run_dir: str, arguments: dict) -> None

main function to run the LVS.

Parameters

lvs_run_dir : str String with absolute path of the full run dir. arguments : dict Dictionary that holds the arguments used by user in the run command. This is generated by docopt library.

gdsfactory.generic_tech.klayout.lvs.testing.testcases.unit.heater_devices.layout.straight_heater_metal

gdsfactory.generic_tech.klayout.drc.errors

enclosing

@gf.cell
def enclosing(
    enclosing: float = 0.1,
    layer1: Layer = (40, 0),
    layer2: Layer = (41, 0)
) -> Component

Layer1 must be enclosed by layer2 by value.

checks if layer1 encloses (is bigger than) layer2 by value

not_inside

@gf.cell
def not_inside(layer: Layer = (40, 0),
               not_inside: Layer = (24, 0)) -> Component

Layer must be inside by layer.

gdsfactory.generic_tech.klayout.drc

gdsfactory.generic_tech.klayout.python.kgdsfactory.shortcuts

Keybindings inspired by SiEPIC tools.

gdsfactory.generic_tech.klayout.python.kgdsfactory

gdsfactory.generic_tech.klayout.python

gdsfactory.generic_tech

gdsfactory.generic_tech.simulation_settings

SimulationSettingsLumericalFdtd Objects

class SimulationSettingsLumericalFdtd(BaseModel)

Lumerical FDTD simulation_settings.

Arguments:

  • background_material - for the background.
  • port_margin - on both sides of the port width (um).
  • port_height - port height (um).
  • port_extension - port extension (um).
  • mesh_accuracy - 2 (1: coarse, 2: fine, 3: superfine).
  • zmargin - for the FDTD region (um).
  • ymargin - for the FDTD region (um).
  • xmargin - for the FDTD region (um).
  • wavelength_start - 1.2 (um).
  • wavelength_stop - 1.6 (um).
  • wavelength_points - 500.
  • simulation_time - (s) related to max path length 3e8/2.410e-121e6 = 1.25mm.
  • simulation_temperature - in kelvin (default = 300).
  • frequency_dependent_profile - compute mode profiles for each wavelength.
  • field_profile_samples - number of wavelengths to compute field profile.

Config Objects

class Config()

pydantic basemodel config.

gdsfactory.generic_tech.layer_map

GenericLayerMap Objects

class GenericLayerMap(LayerMap)

Generic layermap based on book.

Lukas Chrostowski, Michael Hochberg, “Silicon Photonics Design”, Cambridge University Press 2015, page 353 You will need to create a new LayerMap with your specific foundry layers.

gdsfactory.generic_tech.containers

Containers are Pcells that contain another Pcell.

gdsfactory.generic_tech.layer_stack

LayerStackParameters Objects

class LayerStackParameters()

values used by get_layer_stack and get_process.

get_layer_stack

def get_layer_stack(
        thickness_wg=LayerStackParameters.thickness_wg,
        thickness_slab_deep_etch=LayerStackParameters.thickness_slab_deep_etch,
        thickness_slab_shallow_etch=LayerStackParameters.
    thickness_slab_shallow_etch,
        sidewall_angle_wg=LayerStackParameters.sidewall_angle_wg,
        thickness_clad=LayerStackParameters.thickness_clad,
        thickness_nitride=LayerStackParameters.thickness_nitride,
        thickness_ge=LayerStackParameters.thickness_ge,
        gap_silicon_to_nitride=LayerStackParameters.gap_silicon_to_nitride,
        zmin_heater=LayerStackParameters.zmin_heater,
        zmin_metal1=LayerStackParameters.zmin_metal1,
        thickness_metal1=LayerStackParameters.thickness_metal1,
        zmin_metal2=LayerStackParameters.zmin_metal2,
        thickness_metal2=LayerStackParameters.thickness_metal2,
        zmin_metal3=LayerStackParameters.zmin_metal3,
        thickness_metal3=LayerStackParameters.thickness_metal3,
        substrate_thickness=LayerStackParameters.substrate_thickness,
        box_thickness=LayerStackParameters.box_thickness,
        undercut_thickness=LayerStackParameters.undercut_thickness
) -> LayerStack

Returns generic LayerStack.

based on paper https://www.degruyter.com/document/doi/10.1515/nanoph-2013-0034/html

Arguments:

  • thickness_wg - waveguide thickness in um.
  • thickness_slab_deep_etch - for deep etched slab.
  • thickness_shallow_etch - thickness for the etch in um.
  • sidewall_angle_wg - waveguide side angle.
  • thickness_clad - cladding thickness in um.
  • thickness_nitride - nitride thickness in um.
  • thickness_ge - germanium thickness.
  • gap_silicon_to_nitride - distance from silicon to nitride in um.
  • zmin_heater - TiN heater.
  • zmin_metal1 - metal1.
  • thickness_metal1 - metal1 thickness.
  • zmin_metal2 - metal2.
  • thickness_metal2 - metal2 thickness.
  • zmin_metal3 - metal3.
  • thickness_metal3 - metal3 thickness.
  • substrate_thickness - substrate thickness in um.
  • box_thickness - bottom oxide thickness in um.
  • undercut_thickness - thickness of the silicon undercut.

get_process

def get_process()

Returns generic process to generate LayerStack.

Represents processing steps that will result in the GenericLayerStack, starting from the waferstack LayerStack.

based on paper https://www.degruyter.com/document/doi/10.1515/nanoph-2013-0034/html

gdsfactory.generic_tech.get_klayout_pyxs

write xsection script for KLayout plugin.

https://gdsfactory.github.io/klayout_pyxs/DocGrow.html

get_klayout_pyxs

def get_klayout_pyxs(t_box=1.0,
                     t_slab=90 * nm,
                     t_si=0.22,
                     t_ge=0.4,
                     t_nitride=0.4,
                     h_etch1=0.07,
                     h_etch2=0.06,
                     h_etch3=0.09,
                     t_clad=0.6,
                     t_m1=0.5,
                     t_m2=0.5,
                     t_m3=2.0,
                     gap_m1_m2=0.6,
                     gap_m2_m3=0.3,
                     t_heater=0.1,
                     gap_oxide_nitride=0.82,
                     t_m1_oxide=0.6,
                     t_m2_oxide=2.0,
                     t_m3_oxide=0.5,
                     layer_wg=LAYER.WG,
                     layer_fc=LAYER.SLAB150,
                     layer_rib=LAYER.SLAB90,
                     layer_n=LAYER.N,
                     layer_np=LAYER.NP,
                     layer_npp=LAYER.NPP,
                     layer_p=LAYER.P,
                     layer_pp=LAYER.PP,
                     layer_ppp=LAYER.PPP,
                     layer_PDPP=LAYER.GEP,
                     layer_nitride=LAYER.WGN,
                     layer_Ge=LAYER.GE,
                     layer_GePPp=LAYER.GEP,
                     layer_GeNPP=LAYER.GEN,
                     layer_viac=LAYER.VIAC,
                     layer_viac_slot=LAYER.VIAC,
                     layer_m1=LAYER.M1,
                     layer_mh=LAYER.HEATER,
                     layer_via1=LAYER.VIA1,
                     layer_m2=LAYER.M2,
                     layer_via2=LAYER.VIA2,
                     layer_m3=LAYER.M3,
                     layer_open=LAYER.PADOPEN) -> str

Returns klayout_pyxs plugin script to show chip cross-section in klayout.

https://gdsfactory.github.io/klayout_pyxs/DocGrow.html

gdsfactory.picmodel

gdsfactory.add_termination

add_termination

@cell
def add_termination(component: Component,
                    ports: list[Port] | None = None,
                    terminator: ComponentSpec = terminator_function,
                    port_name: str | None = None,
                    port_type: str = "optical",
                    **kwargs) -> Component

Returns component with terminator on some ports.

Arguments:

  • component - to add terminator.
  • ports - optional list of ports to terminate (defaults to all).
  • terminator - factory for the terminator.
  • port_name - for the terminator to connect to the component ports.
  • port_type - of the ports that you want to terminate.
  • kwargs - for the ports you want to terminate (orientation, width).

gdsfactory.add_tapers_cross_section

add_tapers

@cell
def add_tapers(component: Component,
               taper: ComponentSpec = taper_cross_section,
               select_ports: Callable | None = select_ports_optical,
               taper_port_name1: str = "o1",
               taper_port_name2: str = "o2",
               cross_section2: CrossSectionSpec = strip,
               **kwargs) -> Component

Returns new component with taper in all optical ports.

Arguments:

  • component - to add tapers.
  • taper - taper spec.
  • select_ports - function to select ports.
  • taper_port_name1 - name.
  • taper_port_name2 - name.
  • cross_section2 - end cross_section factory (cross_section).

Arguments:

  • cross_section1 - start cross_section factory.
  • length - transition length.
  • npoints - number of points.
  • linear - shape of the transition, sine when False.
  • kwargs - cross_section settings for section2.

gdsfactory.component_reference

Component references.

Adapted from PHIDL https://github.com/amccaugh/phidl/ by Adam McCaughan

SizeInfo Objects

class SizeInfo()

__init__

def __init__(bbox: ndarray) -> None

Initialize this object.

__str__

def __str__() -> str

Return a string representation of the object.

ComponentReference Objects

class ComponentReference(_GeometryHelper)

Pointer to a Component with x, y, rotation, mirror.

Arguments:

  • component - Component The referenced Component.
  • columns - Number of columns in the array.
  • rows - Number of rows in the array.
  • spacing - Distances between adjacent columns and adjacent rows.
  • origin - array-like[2] of int or float Position where the cell is inserted. rotation : int or float Angle of rotation of the reference (in degrees). magnification : int or float Magnification factor for the reference. x_reflection : bool If True, the reference is reflected parallel to the x direction before being rotated. name : str (optional) A name for the reference (if provided).

__init__

def __init__(component: Component,
             origin: Coordinate = (0, 0),
             rotation: float = 0,
             magnification: float = 1,
             x_reflection: bool = False,
             visual_label: str = "",
             columns: int = 1,
             rows: int = 1,
             spacing=None,
             name: str | None = None,
             v1: tuple[float, float] | None = None,
             v2: tuple[float, float] | None = None) -> None

Initialize the ComponentReference object.

get_polygon_bbox

def get_polygon_bbox(default: float = 0.0,
                     top: float | None = None,
                     bottom: float | None = None,
                     right: float | None = None,
                     left: float | None = None) -> shapely.Polygon

Returns shapely Polygon with padding.

Arguments:

  • default - default padding in um.
  • top - north padding in um.
  • bottom - south padding in um.
  • right - east padding in um.
  • left - west padding in um.

get_polygons

def get_polygons(
    by_spec: bool = False,
    depth: int | None = None,
    include_paths: bool = True,
    as_array: bool = True,
    as_shapely: bool = False,
    as_shapely_merged: bool = False
) -> list[Polygon] | dict[tuple[int, int], list[Polygon]]

Return the list of polygons created by this reference.

Arguments:

by_spec : bool or tuple If True, the return value is a dictionary with the polygons of each individual pair (layer, datatype). If set to a tuple of (layer, datatype), only polygons with that specification are returned. depth : integer or None If not None, defines from how many reference levels to retrieve polygons. References below this level will result in a bounding box. If by_spec is True the key will be the name of the referenced cell.

  • include_paths - If True, polygonal representation of paths are also included in the result.

  • as_array - when as_array=false, return the Polygon objects instead. polygon objects have more information (especially when by_spec=False) and are faster to retrieve.

  • as_shapely - returns shapely polygons.

  • as_shapely_merged - returns a shapely polygonize.

    Returns out : list of array-like[N][2] or dictionary List containing the coordinates of the vertices of each polygon, or dictionary with the list of polygons (if by_spec is True).

Notes:

Instances of FlexPath and RobustPath are also included in the result by computing their polygonal boundary.

get_labels

def get_labels(depth=None, set_transform=True)

Return the list of labels created by this reference.

Arguments:

depth : integer or None If not None, defines from how many reference levels to retrieve labels from. set_transform : bool If True, labels will include the transformations from the reference.

Returns:

out : list of Label List containing the labels in this cell and its references.

get_paths

def get_paths(depth=None)

Return the list of paths created by this reference.

Arguments:

depth : integer or None If not None, defines from how many reference levels to retrieve paths from.

Returns:

list of FlexPath or RobustPath List containing the paths in this cell and its references.

area

def area(by_spec=False)

Calculate total area.

Arguments:

by_spec : bool If True, the return value is a dictionary with the areas of each individual pair (layer, datatype).

Returns:

out : number, dictionary Area of this cell.

__repr__

def __repr__() -> str

Return a string representation of the object.

bbox

@property
def bbox()

Return the bounding box of the ComponentReference.

it snaps to 3 decimals in um (0.001um = 1nm precision)

__get_validators__

@classmethod
def __get_validators__(cls)

Get validators.

validate

@classmethod
def validate(cls, v, _info)

Check with pydantic ComponentReference valid type.

__getitem__

def __getitem__(key)

Access reference ports.

ports

@property
def ports() -> dict[str, Port]

This property allows you to access myref.ports, and receive a copy.

of the ports dict which is correctly rotated and translated.

pprint_ports

def pprint_ports() -> None

Pretty print component ports.

move

def move(origin: Port | Coordinate | str = (0, 0),
         destination: Port | Coordinate | str | None = None,
         axis: str | None = None) -> ComponentReference

Move the ComponentReference from origin point to destination.

Both origin and destination can be 1x2 array-like, Port, or a key corresponding to one of the Ports in this device_ref.

Arguments:

  • origin - Port, port_name or Coordinate.
  • destination - Port, port_name or Coordinate.
  • axis - for the movement.

Returns:

ComponentReference.

rotate

def rotate(
    angle: float = 45,
    center: Coordinate | str | int = (0.0, 0.0)
) -> ComponentReference

Return rotated ComponentReference.

Arguments:

  • angle - in degrees.
  • center - x, y.

mirror_x

def mirror_x(port_name: str | None = None,
             x0: Coordinate | None = None) -> ComponentReference

Perform horizontal mirror using x0 or port as axis (default, x0=0).

This is the default for mirror along X=x0 axis

mirror_y

def mirror_y(port_name: str | None = None,
             y0: float | None = None) -> ComponentReference

Perform vertical mirror using y0 as axis (default, y0=0).

mirror

def mirror(p1: Coordinate = (0.0, 1.0),
           p2: Coordinate = (0.0, 0.0)) -> ComponentReference

Mirrors.

Arguments:

  • p1 - point 1.
  • p2 - point 2.

connect

def connect(port: str | Port,
            destination: Port,
            overlap: float = 0.0,
            preserve_orientation: bool = False) -> ComponentReference

Return ComponentReference where port connects to a destination.

Arguments:

  • port - origin (port, or port name) to connect.
  • destination - destination port.
  • overlap - how deep does the port go inside.
  • preserve_orientation - True, does not rotate the reference to align port orientation and reference keep its orientation pre-connection.

Returns:

  • ComponentReference - with correct rotation to connect to destination.

get_ports_list

def get_ports_list(**kwargs) -> list[Port]

Return a list of ports.

Arguments:

  • layer - port GDS layer.
  • prefix - port name prefix.
  • orientation - in degrees.
  • width - port width.
  • layers_excluded - List of layers to exclude.
  • port_type - optical, electrical, ...
  • clockwise - if True, sort ports clockwise, False: counter-clockwise.

get_ports_dict

def get_ports_dict(**kwargs) -> dict[str, Port]

Return a dict of ports.

Arguments:

  • layer - port GDS layer.
  • prefix - port name prefix.
  • orientation - in degrees.
  • width - port width.
  • layers_excluded - List of layers to exclude.
  • port_type - optical, electrical, ...
  • clockwise - if True, sort ports clockwise, False: counter-clockwise.

ports_layer

@property
def ports_layer() -> dict[str, str]

Return a mapping from layer0_layer1_E0: portName.

port_by_orientation_cw

def port_by_orientation_cw(key: str, **kwargs)

Return port by indexing them clockwise.

port_by_orientation_ccw

def port_by_orientation_ccw(key: str, **kwargs)

Return port by indexing them clockwise.

get_ports_xsize

def get_ports_xsize(**kwargs) -> float

Return xdistance from east to west ports.

Arguments:

  • kwargs - orientation, port_type, layer.

get_ports_ysize

def get_ports_ysize(**kwargs) -> float

Returns ydistance from east to west ports.

gdsfactory.technology.xml_utils

gdsfactory.technology.yaml_utils

gdsfactory.technology.layer_views

A GDS layer is a tuple of two integers.

You can maintain LayerViews in YAML (.yaml) or Klayout XML file (.lyp)

HatchPattern Objects

class HatchPattern(BaseModel)

Custom dither pattern. See KLayout documentation for more info.

Attributes:

  • name - Name of the pattern.
  • order - Order of pattern.
  • custom_pattern - Pattern defining custom shape.

LineStyle Objects

class LineStyle(BaseModel)

Custom line style. See KLayout documentation for more info.

Attributes:

  • name - Name of the line style.
  • order - Order of line style.
  • custom_style - Line style to use.

LayerView Objects

class LayerView(BaseModel)

KLayout layer properties.

Docstrings adapted from KLayout documentation: https://www.klayout.de/lyp_format.html

Attributes:

  • name - Layer name.
  • info - Extra info to include in the LayerView.
  • layer - GDSII layer.
  • layer_in_name - Whether to display the name as ‘name layer/datatype’ rather than just the layer.
  • width - This is the line width of the frame in pixels (or empty for the default which is 1).
  • line_style - This is the number of the line style used to draw the shape boundaries. An empty string is “solid line”. The values are “Ix” for one of the built-in styles where “I0” is “solid”, “I1” is “dotted” etc.
  • hatch_pattern - This is the number of the dither pattern used to fill the shapes. The values are “Ix” for one of the built-in pattern where “I0” is “solid” and “I1” is “clear”.
  • fill_color - Display color of the layer fill.
  • frame_color - Display color of the layer frame. Accepts Pydantic Color types. See: https://docs.pydantic.dev/usage/types for more info.
  • fill_brightness - Brightness of the fill.
  • frame_brightness - Brightness of the frame.
  • animation - This is a value indicating the animation mode. 0 is “none”, 1 is “scrolling”, 2 is “blinking” and 3 is “inverse blinking”. (Only applies to KLayout layer properties)
  • xfill - Whether boxes are drawn with a diagonal cross. (Only applies to KLayout layer properties)
  • marked - Whether the entry is marked (drawn with small crosses). (Only applies to KLayout layer properties)
  • transparent - Whether the entry is transparent.
  • visible - Whether the entry is visible.
  • valid - Whether the entry is valid. Invalid layers are drawn but you can’t select shapes on those layers. (Only applies to KLayout layer properties)
  • group_members - Add a list of group members to the LayerView.

group_members

noqa: UP006

__init__

def __init__(gds_layer: int | None = None,
             gds_datatype: int | None = None,
             color: ColorType | None = None,
             brightness: int | None = None,
             **data) -> None

Initialize LayerView object.

dict

def dict(*,
         include: AbstractSetIntStr | MappingIntStrAny | None = None,
         exclude: AbstractSetIntStr | MappingIntStrAny | None = None,
         by_alias: bool = False,
         exclude_unset: bool = False,
         exclude_defaults: bool = False,
         exclude_none: bool = False,
         simplify: bool = True) -> DictStrAny

Generate a dictionary representation of the model, optionally specifying which fields to include or exclude.

Specify “simplify” to consolidate fill and frame color/brightness if they are the same.

Arguments:

  • mode - The mode in which to_python should run. If mode is ‘json’, the dictionary will only contain JSON serializable types. If mode is ‘python’, the dictionary may contain any Python objects.
  • include - A list of fields to include in the output.
  • exclude - A list of fields to exclude from the output.
  • by_alias - Whether to use the field’s alias in the dictionary key if defined.
  • exclude_unset - Whether to exclude fields that are unset or None from the output.
  • exclude_defaults - Whether to exclude fields that are set to their default value from the output.
  • exclude_none - Whether to exclude fields that have a value of None from the output.
  • simplify - Whether to consolidate fill and frame color/brightness if they are the same.

Returns:

A dictionary representation of the model.

__str__

def __str__() -> str

Returns a formatted view of properties and their values.

__repr__

def __repr__() -> str

Returns a formatted view of properties and their values.

to_klayout_xml

def to_klayout_xml(custom_hatch_patterns: dict,
                   custom_line_styles: dict) -> ET.Element

Return an XML representation of the LayerView.

from_xml_element

@classmethod
def from_xml_element(cls, element: ET.Element,
                     layer_pattern: str | re.Pattern) -> LayerView | None

Read properties from .lyp XML and generate LayerViews from them.

Arguments:

  • element - XML Element to iterate over.
  • layer_pattern - Regex pattern to match layers with.

LayerViews Objects

class LayerViews(BaseModel)

A container for layer properties for KLayout layer property (.lyp) files.

Attributes:

  • layer_views - Dictionary of LayerViews describing how to display gds layers.
  • custom_dither_patterns - Custom dither patterns.
  • custom_line_styles - Custom line styles.
  • layer_map - Specify a layer_map to get the layer tuple based on the name of the LayerView, rather than the ‘layer’ argument.

__init__

def __init__(filepath: PathLike | None = None,
             layer_map: dict[str, Layer] | BaseModel | None = None,
             **data) -> None

Initialize LayerViews object.

Arguments:

  • filepath - can be YAML or LYP.
  • layer_map - Optional layermap.

add_layer_view

def add_layer_view(name: str,
                   layer_view: LayerView | None = None,
                   **kwargs) -> None

Adds a layer to LayerViews.

Arguments:

  • name - Name of the LayerView.
  • layer_view - LayerView to add.

get_layer_views

def get_layer_views(exclude_groups: bool = False) -> dict[str, LayerView]

Return all LayerViews.

Arguments:

  • exclude_groups - Whether to exclude LayerViews that contain other LayerViews.

get_layer_view_groups

def get_layer_view_groups() -> dict[str, LayerView]

Return the LayerViews that contain other LayerViews.

__str__

def __str__() -> str

Prints the number of LayerView objects in the LayerViews object.

get

def get(name: str) -> LayerView

Returns Layer from name.

Arguments:

  • name - Name of layer.

__getitem__

def __getitem__(val: str)

Allows accessing to the layer names like ls[‘gold2’].

Arguments:

  • val - Layer name to access within the LayerViews.

Returns:

  • self.layers[val] - LayerView in the LayerViews.

get_from_tuple

def get_from_tuple(layer_tuple: Layer) -> LayerView

Returns LayerView from layer tuple.

Arguments:

  • layer_tuple - Tuple of (gds_layer, gds_datatype).

Returns:

LayerView.

get_layer_tuples

def get_layer_tuples() -> set[Layer]

Returns a tuple for each layer.

clear

def clear() -> None

Deletes all layers in the LayerViews.

preview_layerset

def preview_layerset(size: float = 100.0, spacing: float = 100.0) -> object

Generates a Component with all the layers.

Arguments:

  • size - square size in um.
  • spacing - spacing between each square in um.

to_lyp

def to_lyp(filepath: str | pathlib.Path,
           overwrite: bool = True) -> pathlib.Path

Write all layer properties to a KLayout .lyp file.

Arguments:

  • filepath - to write the .lyp file to (appends .lyp extension if not present).
  • overwrite - Whether to overwrite an existing file located at the filepath.

from_lyp

@staticmethod
def from_lyp(filepath: str | pathlib.Path,
             layer_pattern: str | re.Pattern | None = None) -> LayerViews

Write all layer properties to a KLayout .lyp file.

Arguments:

  • filepath - to write the .lyp file to (appends .lyp extension if not present).
  • layer_pattern - Regex pattern to match layers with. Defaults to r’(\d+|*)/(\d+|*)'.

to_yaml

def to_yaml(layer_file: str | pathlib.Path,
            prefer_named_color: bool = True) -> None

Export layer properties to a YAML file.

Arguments:

  • layer_file - Name of the file to write LayerViews to.
  • prefer_named_color - Write the name of a color instead of its hex representation when possible.

from_yaml

@staticmethod
def from_yaml(layer_file: str | pathlib.Path) -> LayerViews

Import layer properties from two yaml files.

Arguments:

  • layer_file - Name of the file to read LayerViews, CustomDitherPatterns, and CustomLineStyles from.

gdsfactory.technology.klayout_tech

Classes and utils for working with KLayout technology files (.lyp, .lyt).

This module enables conversion between gdsfactory settings and KLayout technology.

KLayoutTechnology Objects

class KLayoutTechnology(BaseModel)

A container for working with KLayout technologies (requires KLayout Python package).

Useful to import/export Layer Properties (.lyp) and Technology (.lyt) files.

Properties: name: technology name. layer_map: Maps names to GDS layer numbers. layer_views: 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. connectivity: List of layer names connectivity for netlist tracing.

write_tech

def write_tech(tech_dir: PathType,
               lyp_filename: str = "layers.lyp",
               lyt_filename: str = "tech.lyt",
               d25_filename: str | None = None,
               mebes_config: dict | None = None) -> None

Write technology files into ‘tech_dir’.

Arguments:

  • tech_dir - Where to write the technology files to.
  • lyp_filename - Name of the layer properties file.
  • lyt_filename - Name of the layer technology file.
  • d25_filename - Name of the 2.5D stack file (only works on KLayout >= 0.28). Defaults to self.name.
  • mebes_config - A dictionary specifying the KLayout mebes reader config.

gdsfactory.technology

gdsfactory.technology.processes

ProcessStep Objects

@dataclass(kw_only=True)
class ProcessStep()

Generic process step.

Lithography Objects

@dataclass(kw_only=True)
class Lithography(ProcessStep)

Simulates lithography by generating a logical on-wafer mask from one or many layers to be used in processing operations.

(1) First, a mask is created from the layer arguments:

if layer=None, behaviour should be:

mask opening <----------------> -----> || ||

0 1 2 3 0 1 2 3

if argument_layers is provided to layers_or, for those layers:

layer mask opening <----------------> <---------------------------> -----> || |||| |__________| 0 1 2 3 0 1 2 3 <------------------> layers_or

if argument_layers is provided to layers_and, for those layers:

layer mask opening <----------------> <---------> -----> || | || | |___________| 0 1 2 3 0 1 2 3 <------------------> layers_and

if argument_layers is provided to layers_diff, for those layers:

layer mask opening <----------------> <-------> -----> |______| || | | || 0 1 2 3 0 1 2 3 <------------------> layers_and

if argument_layers is provided to layers_xor, for those layers:

layer mask opening <----------------> <--------> <---------> -----> || || || |__________________| 0 1 2 3 0 1 2 3 <------------------> layers_xor

(2) Convert the logical mask into a wafer mask, opening up parts of the wafer for processing:

if positive_tone:

mask opening wafer mask opened <------> <------>


| | | | -----> | | | | mask_thickness ________________ ||||

else (negative tone):

mask opening wafer mask NOT opened <------> <------>


| | -----> | | mask_thickness ________________ ||__

(3) (Optional) Planarize the resist

Arguments:

  • layer - main layer to use as a mask for this lithography step
  • layers_union List[Layers] - other layers to use to form the mask (see diagram)
  • layers_diff List[Layers] - other layers to use to form a mask (see diagram)
  • layers_intersect List[Layers] - other layers to use to form a mask (see diagram)
  • positive_tone bool - whether to invert the resulting mask (False) or not (True)
  • resist_thickness float - resist mask thickness, used in some simulators
  • planarization_height float - height at which to “clip” the resist above the wafer

Grow Objects

@dataclass(kw_only=True)
class Grow(Lithography)

Simulates masking + addition of material + liftoff.

wafer mask opened wafer mask opened <------> <------>


| | -----> | mat | thickness ________________ ||__

Arguments:

  • material str - material tag of material to add
  • thickness float - thickness to add [nm]
  • type str - of growth/deposition (isotropic, anisotropic, etc.)
  • rate float - of growth [nm/s]

Etch Objects

@dataclass(kw_only=True)
class Etch(Lithography)

Simulates masking + removal of material + strip.

wafer mask opened wafer mask opened <------> <----->


| | | | | mat | -----> mat | etch | mat depth |____________| ||____

Arguments:

  • material str - material tag to etch into
  • thickness float - thickness to remove [nm]
  • type str - of etch (isotropic, anisotropic, etc.)
  • rate float - of removal [nm/s]

ImplantPhysical Objects

@dataclass(kw_only=True)
class ImplantPhysical(Lithography)

Simulates masking + physical ion implantation + strip.

wafer mask opened wafer mask opened <------> <----->


| | | | | | -----> | ------- <---- range (depends on energy) |______________| |________________|

Arguments:

  • ion str - ion tag
  • energy float - of the ions
  • dose float - in /cm^2
  • tilt float - ion angle from out-of-plane axis. in degrees. If None, uses simulator default
  • twist float - ion angle from wafer “x-axis”, in degrees. If None, uses simulator default
  • rotation float - if twist is None, toggle to split the dose 4-ways between 4 cardinal twist angles (simulates substrate rotation during implantation)

ImplantAnalytical Objects

@dataclass(kw_only=True)
class ImplantAnalytical(Lithography)

Simulates masking + physical ion implantation + strip.

wafer mask opened wafer mask opened <------> <----->


| | | | | | -----> | ------- <---- range (depends on energy) |______________| |________________|

Arguments:

  • ion str - ion tag
  • peak_conc float - peak concentration
  • range float - of the ions (center of distribution)
  • straggle float - of the ions (spread of distribution)

Anneal Objects

@dataclass(kw_only=True)
class Anneal(ProcessStep)

Simulates thermal diffusion of impurities and healing of defects.

Arguments:

time (float)

  • temperature float - temperature

  • TODO long term - heating/cooling time profiles

Planarize Objects

@dataclass(kw_only=True)
class Planarize(ProcessStep)

Simulates chip planarization, “clipping” the structure above some height. Does not use masking.

__ | |__ | |__ | | ___ _________________ | | | height -----> | | || | z=0 |_|

Arguments:

  • depth float - how much to remove

ArbitraryStep Objects

@dataclass(kw_only=True)
class ArbitraryStep(ProcessStep)

Arbitrary process step, used to handle all other cases.

gdsfactory.technology.color_utils

gdsfactory.technology.layer_map

LayerMap Objects

class LayerMap(BaseModel)

You will need to create a new LayerMap with your specific foundry layers.

lyp_to_dataclass

def lyp_to_dataclass(lyp_filepath: str | pathlib.Path,
                     overwrite: bool = True) -> str

Returns python LayerMap script from a klayout layer properties file lyp.

gdsfactory.technology.layer_stack

LayerLevel Objects

class LayerLevel(BaseModel)

Level for 3D LayerStack.

Arguments:

  • layer - (GDSII Layer number, GDSII datatype).
  • thickness - layer thickness in um.
  • thickness_tolerance - layer thickness tolerance in um.
  • zmin - height position where material starts in um.
  • zmin_tolerance - layer height tolerance in um.
  • material - material name.
  • sidewall_angle - in degrees with respect to normal.
  • sidewall_angle_tolerance - in degrees.
  • width_to_z - if sidewall_angle, relative z-position (0 --> zmin, 1 --> zmin + thickness).
  • z_to_bias - parametrizes shrinking/expansion of the design GDS layer when extruding from zmin (0) to zmin + thickness (1). Defaults no buffering [[0, 1], [0, 0]].
  • mesh_order - lower mesh order (1) will have priority over higher mesh order (2) in the regions where materials overlap.
  • refractive_index - refractive_index can be int, complex or function that depends on wavelength (um).
  • type - grow, etch, implant, or background.
  • mode - octagon, taper, round. https://gdsfactory.github.io/klayout_pyxs/DocGrow.html
  • into - etch into another layer. https://gdsfactory.github.io/klayout_pyxs/DocGrow.html
  • background_doping_concentration - uniform base doping level in the material (cm-3)
  • background_doping_ion - uniform base doping ion in the material
  • orientation - of the wafer (Miller indices of the plane)
  • resistivity - for metals.
  • bias - in um for the etch. Can be a single number or 2 numbers (bias_x, bias_y)
  • derived_layer - Optional derived layer, used for layer_type=‘etch’ to define the slab.
  • info - simulation_info and other types of metadata.

LayerStack Objects

class LayerStack(BaseModel)

For simulation and 3D rendering. Captures design intent of the chip layers after fabrication.

Arguments:

  • layers - dict of layer_levels.

__init__

def __init__(**data: Any) -> None

Add LayerLevels automatically for subclassed LayerStacks.

get_layer_to_thickness

def get_layer_to_thickness() -> dict[tuple[int, int], float]

Returns layer tuple to thickness (um).

get_component_with_derived_layers

def get_component_with_derived_layers(component, **kwargs)

Returns component with derived layers.

get_component_with_net_layers

def get_component_with_net_layers(component,
                                  portnames: list[str],
                                  delimiter: str = "#",
                                  new_layers_init: tuple[int,
                                                         int] = (10010, 0),
                                  add_to_layerstack: bool = True)

Returns component with new layers that combine port names and original layers, and modifies the layerstack accordingly.

Uses port’s “layer” attribute to decide which polygons need to be renamed. New layers are named “layername{delimiter}portname”.

Arguments component: to process portnames: list of portnames to process into new layers. delimiter: the new layer created is called “layername{delimiter}portname” new_layers_init: initial layer number for the temporary new layers. add_to_layerstack: True by default, but can be set to False to disable parsing of the layerstack

get_layer_to_zmin

def get_layer_to_zmin() -> dict[tuple[int, int], float]

Returns layer tuple to z min position (um).

get_layer_to_material

def get_layer_to_material() -> dict[tuple[int, int], str]

Returns layer tuple to material name.

get_layer_to_sidewall_angle

def get_layer_to_sidewall_angle() -> dict[tuple[int, int], str]

Returns layer tuple to material name.

get_layer_to_info

def get_layer_to_info() -> dict[tuple[int, int], dict]

Returns layer tuple to info dict.

get_layer_to_layername

def get_layer_to_layername() -> dict[tuple[int, int], str]

Returns layer tuple to layername.

__getitem__

def __getitem__(key) -> LayerLevel

Access layer stack elements.

get_klayout_3d_script

def get_klayout_3d_script(layer_views: LayerViews | None = None,
                          dbu: float | None = 0.001) -> str

Returns script for 2.5D view in KLayout.

You can include this information in your tech.lyt

Arguments:

  • layer_views - optional layer_views.
  • dbu - Optional database unit. Defaults to 1nm.

filtered

def filtered(layers) -> LayerStack

Filtered layerstack, given layer specs.

z_offset

def z_offset(dz) -> LayerStack

Translates the z-coordinates of the layerstack.

invert_zaxis

def invert_zaxis() -> LayerStack

Flips the zmin values about the origin.

gdsfactory.technology.read_from_layers_info

read_from_layers_info

def read_from_layers_info(filepath: PathType) -> str

Returns a layermap python script from layers.info file

gdsfactory.events

Event Objects

class Event()

__init__

def __init__() -> None

Initialize the object.

__iadd__

def __iadd__(handler: Callable)

Add item.

__isub__

def __isub__(handler: Callable)

Subtract item.

add_handler

def add_handler(handler: Callable) -> None

Adds a handler that will be executed when this event is fired.

Arguments:

  • handler - a function which matches the signature fired by this event

clear_handlers

def clear_handlers() -> None

Clear all handlers.

fire

def fire(*args, **kwargs) -> None

Fires an event, calling all handlers with the passed arguments.

gdsfactory.cli

layermap_to_dataclass

@app.command()
def layermap_to_dataclass(
    filepath: str,
    force: bool = typer.Option(False, "--force", "-f", help="Force deletion")
) -> None

Converts KLayout LYP to a dataclass.

write_cells

@app.command()
def write_cells(gdspath: str, dirpath: str = None) -> None

Write each all level cells into separate GDS files.

merge_gds

@app.command()
def merge_gds(dirpath: str = None, gdspath: str = None) -> None

Merges GDS cells from a directory into a single GDS.

web

@app.command()
def web(pdk: str = "generic",
        host: str = "localhost",
        port: int = 8765) -> None

Opens web viewer.

watch

@app.command()
def watch(path: str = str(pathlib.Path.cwd()), pdk: str = None) -> None

Filewatch a folder for changes in *.py or *.pic.yml files.

show

@app.command()
def show(filename: str) -> None

Show a GDS file using klive.

gds_diff

@app.command()
def gds_diff(gdspath1: str, gdspath2: str, xor: bool = False) -> None

Show boolean difference between two GDS files.

install_klayout_genericpdk

@app.command()
def install_klayout_genericpdk() -> None

Install Klayout generic PDK.

install_git_diff

@app.command()
def install_git_diff() -> None

Install git diff.

@app.command()
def print_plugins() -> None

Show installed plugin versions.

@app.command()
def print_pdks() -> None

Show installed PDK versions.

from_updk_command

@app.command(name="from_updk")
def from_updk_command(filepath: str, filepath_out: str = None) -> None

Writes a PDK in python from uPDK YAML spec.

text_from_pdf_command

@app.command(name="text_from_pdf")
def text_from_pdf_command(filepath: str) -> None

Converts a PDF to text.

gdsfactory.asserts

version

def version(requirement: str,
            current: str = __version__,
            package_name="gdsfactory") -> None

Raises error if current version does not match requirement.

gdsfactory.quickplotter

Plot gdsfactory Components in matplotlib.

based on phidl.quickplotter.

set_quickplot_options

def set_quickplot_options(show_ports: bool | None = None,
                          show_subports: bool | None = None,
                          label_aliases: bool | None = None,
                          new_window: bool | None = None,
                          blocking: bool | None = None,
                          zoom_factor: float | None = None,
                          interactive_zoom: bool | None = None,
                          fontsize: int | None = None) -> None

Sets plotting options for quickplot().

Arguments:

  • show_ports - Sets whether ports are drawn.
  • show_subports - Sets whether subports (ports that belong to references) are drawn.
  • label_aliases - Sets whether aliases are labeled with a text name.
  • new_window - If True, each call to quickplot() will generate a separate window.
  • blocking - If True, calling quickplot() will pause execution of (“block”) the remainder of the python code until the quickplot() window is closed. If False, the window will be opened and code will continue to run.
  • zoom_factor - Sets the scaling factor when zooming the quickplot window with the mousewheel/trackpad.
  • interactive_zoom - Enables using mousewheel/trackpad to zoom.
  • fontsize - for labels.

quickplot

def quickplot(items, **kwargs)

Takes a list of devices/references/polygons or single one of those, and plots them. Use set_quickplot_options() to modify the viewer behavior (e.g. displaying ports, creating new windows, etc).

Arguments:

  • items - object or list of objects to plot.

    Kwargs:

  • show_ports - Sets whether ports are drawn.

  • show_subports - Sets whether subports (ports that belong to references) are drawn.

  • label_aliases - Sets whether aliases are labeled with a text name.

  • new_window - If True, each call to quickplot() will generate a separate window.

  • blocking - If True, calling quickplot() will pause execution of (“block”) the remainder of the python code until the quickplot() window is closed. If False, the window will be opened and code will continue to run.

  • zoom_factor - Sets the scaling factor when zooming the quickplot window with the mousewheel/trackpad.

  • interactive_zoom - Enables using mousewheel/trackpad to zoom.

  • fontsize - for labels.

    Examples

    import gdsfactory as gf R = gf.components.rectangle() R.plot()

    E = gf.components.ellipse() E.plot()

ViewerWindow Objects

class ViewerWindow(QMainWindow)

__init__

def __init__() -> None

Initialize the object.

Viewer Objects

class Viewer(QGraphicsView)

__init__

def __init__(gridsize_label, position_label, help_label) -> None

Initialize the object.

quickplot2

def quickplot2(item_list, *args, **kwargs)

QT plot.

gdsfactory.add_pins

Add_pin adds a Pin to a port, add_pins adds Pins to all ports.

  • pins
  • outline

Some functions modify a component without changing its name. Make sure these functions are inside a new Component or called as a decorator They without modifying the cell name

add_bbox

def add_bbox(component: Component,
             bbox_layer: LayerSpec = "DEVREC") -> Component

Add bbox on outline.

Arguments:

  • component - component to add bbox.
  • bbox_layer - bbox layer.

add_bbox_siepic

def add_bbox_siepic(
    component: Component,
    bbox_layer: LayerSpec = "DEVREC",
    remove_layers: LayerSpecs = ("PORT", "PORTE")
) -> Component

Add bounding box device recognition layer.

Arguments:

  • component - to add bbox.
  • bbox_layer - bounding box.
  • remove_layers - remove other layers.

get_pin_triangle_polygon_tip

def get_pin_triangle_polygon_tip(
        port: Port) -> tuple[list[float], tuple[float, float]]

Returns triangle polygon and tip position.

add_pin_triangle

def add_pin_triangle(component: Component,
                     port: Port,
                     layer: LayerSpec = "PORT",
                     layer_label: LayerSpec = "TEXT") -> None

Add triangle pin with a right angle, pointing out of the port.

Arguments:

  • component - to add pin.
  • port - Port.
  • layer - for the pin marker.
  • layer_label - for the label.

add_pin_rectangle_inside

def add_pin_rectangle_inside(component: Component,
                             port: Port,
                             pin_length: float = 0.1,
                             layer: LayerSpec = "PORT",
                             layer_label: LayerSpec = "TEXT") -> None

Add square pin towards the inside of the port.

Arguments:

  • component - to add pins.

  • port - Port.

  • pin_length - length of the pin marker for the port.

  • layer - for the pin marker.

  • layer_label - for the label.

    .. code::


    | | | | | | || | || | | | | __ | |_______________|

add_pin_rectangle_double

def add_pin_rectangle_double(component: Component,
                             port: Port,
                             pin_length: float = 0.1,
                             layer: LayerSpec = "PORT",
                             layer_label: LayerSpec = "TEXT") -> None

Add two square pins: one inside with label, one outside.

Arguments:

  • component - to add pins.

  • port - Port.

  • pin_length - length of the pin marker for the port.

  • layer - for the pin marker.

  • layer_label - for the label.

    .. code::


    | | | | | | ||| | ||| | | | | __ | |_______________| __

add_pin_rectangle

def add_pin_rectangle(component: Component,
                      port: Port,
                      pin_length: float = 0.1,
                      layer: LayerSpec = "PORT",
                      layer_label: LayerSpec = "TEXT",
                      port_margin: float = 0.0) -> None

Add half out pin to a component.

Arguments:

  • component - to add pin.

  • port - Port.

  • pin_length - length of the pin marker for the port.

  • layer - for the pin marker.

  • layer_label - for the label.

  • port_margin - margin to port edge.

    .. code::


    | | | | | | ||| | ||| | | | | __ | |_______________| __

add_pin_path

def add_pin_path(component: Component,
                 port: Port,
                 pin_length: float = 2 * nm,
                 layer: LayerSpec = "PORT",
                 layer_label: LayerSpec | None = None) -> None

Add half out path pin to a component.

This port type is compatible with SiEPIC pdk.

Arguments:

  • component - to add pin.

  • port - Port.

  • pin_length - length of the pin marker for the port.

  • layer - for the pin marker.

  • layer_label - optional layer label. Defaults to layer.

    .. code::


    | | | | | | ||| | ||| | | | | __ | |_______________| __

add_outline

def add_outline(component: Component,
                reference: ComponentReference | None = None,
                layer: LayerSpec = "DEVREC",
                **kwargs) -> None

Adds devices outline bounding box in layer.

Arguments:

  • component - where to add the markers.
  • reference - to read outline from.
  • layer - to add padding.

Arguments:

  • default - default padding.
  • top - North padding.
  • bottom - padding.
  • right - padding.
  • left - padding.

add_pins_siepic

def add_pins_siepic(component: Component,
                    function: Callable = add_pin_path,
                    port_type: str = "optical",
                    layer_pin: LayerSpec = "PORT",
                    pin_length: float = 10 * nm) -> Component

Add pins.

Enables you to run SiEPIC verification tools: To Run verification install SiEPIC-tools KLayout package then hit V shortcut in KLayout to run verification

  • ensure no disconnected pins
  • netlist extraction

Arguments:

  • component - to add pins.
  • function - to add pin.
  • port_type - optical, electrical, ...
  • layer_pin - pin layer.
  • pin_length - length of the pin marker for the port.

add_pins

def add_pins(component: Component,
             reference: ComponentReference | None = None,
             function: Callable = add_pin_rectangle_inside,
             select_ports: Callable | None = None,
             **kwargs) -> Component

Add Pin port markers.

Be careful with this function as it modifies the component.

Arguments:

  • component - to add ports to.
  • reference - to add pins.
  • function - to add each pin.
  • select_ports - function to select_ports.

Arguments:

  • kwargs - add pins function settings.
  • pin_length - length of the pin marker for the port.
  • layer - layer for the pin marker.
  • layer_label - add label for the pin marker.

add_settings_label

def add_settings_label(component: Component,
                       reference: ComponentReference,
                       layer_label: LayerSpec = "LABEL_SETTINGS") -> None

Add settings in label.

Arguments:

  • component - to add pins.
  • reference - ComponentReference.
  • layer_label - layer spec.

add_instance_label

def add_instance_label(component: Component,
                       reference: ComponentReference,
                       instance_name: str | None = None,
                       layer: LayerSpec = "LABEL_INSTANCE") -> None

Adds label to a reference in a component.

add_pins_and_outline

def add_pins_and_outline(
        component: Component,
        reference: ComponentReference | None = None,
        add_outline_function: Callable | None = add_outline,
        add_pins_function: Callable | None = add_pins,
        add_settings_function: Callable | None = add_settings_label,
        add_instance_label_function: Callable | None = add_settings_label
) -> None

Add markers.

  • outline
  • pins for the ports
  • label for the name
  • label for the settings

Arguments:

  • component - where to add the markers.
  • reference - to add pins. add_outline_function.
  • add_pins_function - to add pins to ports.
  • add_settings_function - to add outline around the component.
  • add_instance_label_function - labels each instance.

gdsfactory.components.grating_coupler_elliptical_trenches

grating_coupler_elliptical_trenches

@gf.cell
def grating_coupler_elliptical_trenches(
        polarization: str = "te",
        taper_length: float = 16.6,
        taper_angle: float = 30.0,
        trenches_extra_angle: float = 9.0,
        wavelength: float = 1.53,
        fiber_angle: float = 15.0,
        grating_line_width: float = 0.343,
        neff: float = 2.638,
        ncladding: float = 1.443,
        layer_trench: LayerSpec | None = "SHALLOW_ETCH",
        p_start: int = 26,
        n_periods: int = 30,
        end_straight_length: float = 0.2,
        cross_section: CrossSectionSpec = "strip",
        **kwargs) -> Component

Returns Grating coupler with defined trenches.

Some foundries define the grating coupler by a shallow etch step (trenches) Others define the slab that they keep (see grating_coupler_elliptical)

Arguments:

  • polarization - ‘te’ or ‘tm’.

  • taper_length - taper length from straight I/O.

  • taper_angle - grating flare angle.

  • wavelength - grating transmission central wavelength.

  • fiber_angle - fibre polish angle in degrees.

  • grating_line_width - of the 220 ridge.

  • neff - tooth effective index.

  • ncladding - cladding index.

  • layer_trench - for the trench.

  • p_start - first tooth.

  • n_periods - number of grating teeth.

  • end_straight_length - at the end of straight.

  • cross_section - cross_section spec.

  • kwargs - cross_section settings.

    .. code::

    fiber

    / / / / / / / / |-||-||-|__ WG o1 ______________|

gdsfactory.components.cutback_2x2

bendu_double

@gf.cell
def bendu_double(component: ComponentSpec,
                 cross_section: CrossSectionSpec = "strip",
                 bend180: ComponentSpec = bend_circular180,
                 port1: str = "o1",
                 port2: str = "o2",
                 **kwargs) -> ComponentSpec

Returns double bend.

Arguments:

  • component - for cutback.
  • cross_section - specification (CrossSection, string or dict).
  • bend180 - ubend.
  • port1 - name of first optical port.
  • port2 - name of second optical port.
  • kwargs - cross_section settings.

straight_double

@gf.cell
def straight_double(component: ComponentSpec,
                    cross_section: CrossSectionSpec = "strip",
                    port1: str = "o1",
                    port2: str = "o2",
                    straight_length: float | None = None,
                    **kwargs) -> ComponentSpec

Returns double straight.

Arguments:

  • component - for cutback.
  • cross_section - specification (CrossSection, string or dict).
  • port1 - name of first optical port.
  • port2 - name of second optical port.
  • straight_length - length of straight.
  • kwargs - cross_section settings.

cutback_2x2

@gf.cell
def cutback_2x2(component: ComponentSpec = mmi2x2,
                cols: int = 4,
                rows: int = 5,
                port1: str = "o1",
                port2: str = "o2",
                port3: str = "o3",
                port4: str = "o4",
                bend180: ComponentSpec = bend_circular180,
                mirror: bool = False,
                straight_length: float | None = None,
                cross_section: CrossSectionSpec = "strip",
                **kwargs) -> Component

Returns a daisy chain of splitters for measuring their loss.

Arguments:

  • component - for cutback.
  • cols - number of columns.
  • rows - number of rows.
  • port1 - name of first optical port.
  • port2 - name of second optical port.
  • bend180 - ubend.
  • straight - waveguide spec to connect both sides.
  • mirror - Flips component. Useful when ‘o2’ is the port that you want to route to.
  • straight_length - length of the straight section between cutbacks.
  • cross_section - specification (CrossSection, string or dict).
  • kwargs - cross_section settings.

gdsfactory.components.bend_s

bend_s

@cell
def bend_s(size: Float2 = (11.0, 2.0),
           npoints: int = 99,
           cross_section: CrossSectionSpec = "strip",
           check_min_radius: bool = False,
           **kwargs) -> Component

Return S bend with bezier curve.

stores min_bend_radius property in self.info[‘min_bend_radius’] min_bend_radius depends on height and length

Arguments:

  • size - in x and y direction.
  • npoints - number of points.
  • cross_section - spec.
  • check_min_radius - raise ValueError if radius below min_bend_radius.
  • kwargs - cross_section settings.

get_min_sbend_size

def get_min_sbend_size(size: Float2 = (None, 10.0),
                       cross_section: CrossSectionSpec = "strip",
                       num_points: int = 100,
                       **kwargs)

Returns the minimum sbend size to comply with bend radius requirements.

Arguments:

  • size - in x and y direction. One of them is None, which is the size we need to figure out.
  • cross_section - spec.
  • num_points - number of points to iterate over between max_size and 0.1 * max_size
  • kwargs - cross_section settings.

gdsfactory.components.text_rectangular_font

pixel_array

@cell
def pixel_array(pixels: str = character_a,
                pixel_size: float = 10.0,
                layer: LayerSpec = "M1") -> Component

Returns a pixel component from a string representing the pixels.

Arguments:

  • pixels - string representing the pixels
  • pixel_size - width/height for each pixel
  • layer - layer for each pixel

rectangular_font

@cache
def rectangular_font() -> dict[str, str]

Returns a rectangular font dict The keys of the dictionary are the.

characters The values are the pixel representation of the character.

gdsfactory.components.coupler_bent

coupler_bent

@gf.cell
def coupler_bent(gap: float = 0.200,
                 radius: float = 26,
                 length: float = 8.6,
                 width1: float = 0.400,
                 width2: float = 0.400,
                 length_straight: float = 10) -> gf.Component

Returns Broadband SOI curved / straight directional coupler. based on: Chen et al. (2017)

Arguments:

  • gap - gap.
  • radius - radius coupling.
  • length - coupler_length.
  • width1 - width1.
  • width2 - width2.
  • length_straight - input and output straight length.

gdsfactory.components.snspd

snspd

@cell
def snspd(
    wire_width: float = 0.2,
    wire_pitch: float = 0.6,
    size: Float2 = (10, 8),
    num_squares: int | None = None,
    turn_ratio: float = 4,
    terminals_same_side: bool = False,
    layer: LayerSpec = (1, 0)) -> Component

Creates an optimally-rounded SNSPD.

Arguments:

  • width - Width of the wire.
  • pitch - Distance between two adjacent wires. Must be greater than width.
  • size - None or array-like[2] of int or float (width, height) of the rectangle formed by the outer boundary of the SNSPD. Must be none if num_squares is specified.
  • num_squares - int or None Total number of squares inside the SNSPD length. Must be none if size is specified.
  • turn_ratio - int or float Specifies how much of the SNSPD width is dedicated to the 180 degree turn. A turn_ratio of 10 will result in 20% of the width being comprised of the turn. terminals_same_side : bool If True, both ports will be located on the same side of the SNSPD.
  • layer - layer spec to put polygon geometry on.

gdsfactory.components.resistance_sheet

resistance_sheet

@cell
def resistance_sheet(width: float = 10,
                     layers: LayerSpecs = ("SLAB90", "NPP"),
                     layer_offsets: Floats = (0, 0.2),
                     pad: ComponentSpec = pad_via_stack_slab_npp,
                     pad_pitch: float = 100.0,
                     ohms_per_square: float | None = None,
                     port_orientation1: int = 180,
                     port_orientation2: int = 0) -> Component

Returns Sheet resistance.

keeps connectivity for pads and first layer in layers

Arguments:

  • width - in um.
  • layers - for the middle part.
  • layer_offsets - from edge, positive: over, negative: inclusion.
  • pad - function to create a pad.
  • pad_pitch - in um.
  • ohms_per_square - optional sheet resistance to compute info.resistance.
  • port_orientation1 - in degrees.
  • port_orientation2 - in degrees.

gdsfactory.components.taper

taper

@cell
def taper(length: float = 10.0,
          width1: float = 0.5,
          width2: float | None = None,
          port: Port | None = None,
          with_bbox: bool = True,
          with_two_ports: bool = True,
          cross_section: CrossSectionSpec = "strip",
          port_order_name: tuple | None = ("o1", "o2"),
          port_order_types: tuple | None = ("optical", "optical"),
          **kwargs) -> Component

Linear taper.

Deprecated, use gf.components.taper_cross_section instead

Arguments:

  • length - taper length.
  • width1 - width of the west port.
  • width2 - width of the east port.
  • port - can taper from a port instead of defining width1.
  • with_bbox - box in bbox_layers and bbox_offsets to avoid DRC sharp edges.
  • with_two_ports - includes a second port. False for terminator and edge coupler fiber interface.
  • cross_section - specification (CrossSection, string, CrossSectionFactory dict).
  • port_order_name(tuple) - Ordered tuple of port names. First port is default taper port, second name only if with_two_ports flags used.
  • port_order_types(tuple) - Ordered tuple of port types. First port is default taper port, second name only if with_two_ports flags used.
  • kwargs - cross_section settings.

taper_strip_to_ridge

@gf.cell
def taper_strip_to_ridge(length: float = 10.0,
                         width1: float = 0.5,
                         width2: float = 0.5,
                         w_slab1: float = 0.15,
                         w_slab2: float = 6.0,
                         layer_wg: LayerSpec = "WG",
                         layer_slab: LayerSpec = "SLAB90",
                         cross_section: CrossSectionSpec = "strip",
                         bbox_layers: list[LayerSpec] | None = None,
                         bbox_offsets: list[float] | None = None) -> Component

Linear taper from strip to rib.

Deprecated, use gf.components.taper_cross_section instead.

Arguments:

  • length - taper length (um).

  • width1 - in um.

  • width2 - in um.

  • w_slab1 - slab width in um.

  • w_slab2 - slab width in um.

  • layer_wg - for input waveguide.

  • layer_slab - for output waveguide with slab.

  • cross_section - for input waveguide.

    .. code::


    / | /|_________ / | width1 |w_slab1 | w_slab2 width2 _|________ \ | __________________________

taper_strip_to_ridge_trenches

@gf.cell
def taper_strip_to_ridge_trenches(length: float = 10.0,
                                  width: float = 0.5,
                                  slab_offset: float = 3.0,
                                  trench_width: float = 2.0,
                                  trench_layer: LayerSpec = "DEEP_ETCH",
                                  layer_wg: LayerSpec = "WG",
                                  trench_offset: float = 0.1) -> gf.Component

Defines taper using trenches to define the etch.

Arguments:

  • length - in um.
  • width - in um.
  • slab_offset - in um.
  • trench_width - in um.
  • trench_layer - trench layer.
  • layer_wg - waveguide layer.
  • trench_offset - after waveguide in um.

gdsfactory.components.extension

move_polar_rad_copy

def move_polar_rad_copy(pos: Coordinate, angle: float,
                        length: float) -> ndarray

Returns the points of a position (pos) with angle, shifted by length.

Arguments:

  • pos - position.
  • angle - in radians.
  • length - extension length in um.

extend_port

@cell
def extend_port(port: Port,
                length: float,
                layer: Layer | None = None) -> Component

Returns a straight extension component out of a port.

Arguments:

  • port - port to extend.
  • length - extension length in um.
  • layer - for the straight section.

extend_ports

@gf.cell
def extend_ports(component: ComponentSpec = mmi1x2,
                 port_names: tuple[str, ...] | None = None,
                 length: float = 5.0,
                 extension: ComponentSpec | None = None,
                 port1: str | None = None,
                 port2: str | None = None,
                 port_type: str = "optical",
                 centered: bool = False,
                 cross_section: CrossSectionSpec | None = None,
                 extension_port_names: list[str] | None = None,
                 **kwargs) -> Component

Returns a new component with some ports extended.

You can define extension Spec defaults to port cross_section of each port to extend.

Arguments:

  • component - component to extend ports.
  • port_names - list of ports names to extend, if None it extends all ports.
  • length - extension length.
  • extension - function to extend ports (defaults to a straight).
  • port1 - extension input port name.
  • port2 - extension output port name.
  • port_type - type of the ports to extend.
  • centered - if True centers rectangle at (0, 0).
  • cross_section - extension cross_section, defaults to port cross_section if port has no cross_section it creates one using width and layer.
  • extension_port_names - extension port names add to the new component.

Arguments:

  • layer - port GDS layer.
  • prefix - port name prefix.
  • orientation - in degrees.
  • width - port width.
  • layers_excluded - List of layers to exclude.
  • port_type - optical, electrical, ....
  • clockwise - if True, sort ports clockwise, False: counter-clockwise.

gdsfactory.components.coh_rx_dual_pol

coh_rx_dual_pol

@cell
def coh_rx_dual_pol(
        bend: ComponentSpec = bend_euler,
        cross_section: CrossSectionSpec = "strip",
        lo_splitter: ComponentSpec = "mmi1x2",
        signal_splitter: ComponentSpec | None = None,
        spol_coh_rx: ComponentSpec = coh_rx_single_pol,
        single_pol_rx_spacing: float = 50.0,
        splitter_coh_rx_spacing: float = 40.0,
        lo_input_coupler: ComponentSpec | None = None,
        signal_input_coupler: ComponentSpec | None = None) -> Component

Dual polarization coherent receiver.

Arguments:

  • bend - 90 degrees bend library.
  • cross_section - for routing (splitter to mzms and mzms to combiners).
  • lo_splitter - splitter function for the LO input.
  • signal_splitter - splitter function for the signal input.
  • spol_coh_rx - function generating a coherent rx for a single polarization.
  • single_pol_rx_spacing - vertical spacing between each single polarization coherent receiver.
  • splitter_coh_rx_spacing - horizontal spacing between the signal splitter and the single pol coh rxs.
  • lo_input_coupler - Optional coupler to add before the LO splitter.
  • signal_input_coupler - Optional coupler to add before the signal splitter.

gdsfactory.components.bezier

bezier_curve

def bezier_curve(t: ndarray, control_points: Coordinates) -> ndarray

Returns bezier coordinates.

Arguments:

  • t - 1D array of points varying between 0 and 1. control_points:

bezier

@gf.cell
def bezier(control_points: Coordinates = ((0.0, 0.0), (5.0, 0.0), (5.0, 2.0),
                                          (10.0, 2.0)),
           npoints: int = 201,
           with_manhattan_facing_angles: bool = True,
           start_angle: int | None = None,
           end_angle: int | None = None,
           cross_section: CrossSectionSpec = "strip",
           with_bbox: bool = True,
           **kwargs) -> Component

Returns Bezier bend.

Arguments:

  • control_points - list of points.
  • npoints - number of points varying between 0 and 1.
  • with_manhattan_facing_angles - bool.
  • start_angle - optional start angle in deg.
  • end_angle - optional end angle in deg.
  • cross_section - spec.
  • with_bbox - box in bbox_layers and bbox_offsets to avoid DRC sharp edges.

gdsfactory.components.delay_snake2

delay_snake2

@gf.cell
def delay_snake2(length: float = 1600.0,
                 length0: float = 0.0,
                 length2: float = 0.0,
                 n: int = 2,
                 bend180: ComponentSpec = "bend_euler180",
                 cross_section: CrossSectionSpec = "strip",
                 **kwargs) -> Component

Returns Snake with a starting straight and 180 bends.

Input faces west output faces east.

Arguments:

  • length - total length.

  • length0 - start length.

  • length2 - end length.

  • n - number of loops.

  • bend180 - ubend spec.

  • cross_section - cross_section spec.

  • kwargs - cross_section settings.

    .. code::

    | length0 | length1 |

    ---------| | bend180.length |-------------------| | |------------------->------- | length2 | delta_length | |

gdsfactory.components.grating_coupler_functions

get_grating_period_curved

def get_grating_period_curved(fiber_angle: float = 15.0,
                              wavelength: float = 1.55,
                              n_slab: float = (neff_ridge + neff_shallow) / 2,
                              n_clad: float = 1.0) -> tuple[float, float]

The following function calculates the confocal grating periods n_slab is.

the “average slab index” of the grating. For 220nm silicon it is 2.8, for 150nm it is 2.5. The average is approximately 2.65. n_clad is the cladding index in which the fiber is located, not the index of the layer above the straight. If the fiber is in air, then it is 1.0. If you use an index matching fluid or glue, then it should be 1.45.

Arguments:

  • fiber_angle - in degrees.
  • wavelength - um.
  • n_slab - slab refractive index.
  • n_clad - cladding refractive index.

get_grating_period

def get_grating_period(fiber_angle: float = 13.45,
                       wavelength: float = 1.55,
                       neff_high: float = neff_ridge,
                       neff_low: float = neff_shallow,
                       n_clad: float = 1.45) -> float

Return grating coupler period.

based on lumerical slides.

gdsfactory.components.cutback_loss

cutback_loss

def cutback_loss(cutback_function: ComponentFactory = cutback_component,
                 loss: tuple[float, ...] = (1 + 1 * i for i in range(3)),
                 loss_dB: float = 10e-3,
                 cols: int | None = 4,
                 rows: int | None = None,
                 **kwargs) -> list[gf.Component]

Returns a list of component cutbacks.

Arguments:

  • cutback_function - cutback function.
  • loss - list of target loss in dB.
  • loss_dB - loss per component.
  • cols - number of columns.
  • rows - number of rows.
  • kwargs - additional cutback arguments.

cutback_loss_spirals

def cutback_loss_spirals(spiral: ComponentFactory = spiral_inner_io,
                         loss: tuple[float,
                                     ...] = (4 + 3 * i for i in range(3)),
                         cross_section: CrossSectionSpec = "strip",
                         loss_dB_per_m: float = 300,
                         **kwargs) -> list[gf.Component]

Returns a list of spirals.

Arguments:

  • spiral - spiral factory.
  • loss - list of target loss in dB.
  • cross_section - strip or rib.
  • loss_dB_per_m - loss per meter.
  • **kwargs - additional spiral arguments.

gdsfactory.components.coupler_ring

coupler_ring

@gf.cell
def coupler_ring(gap: float = 0.2,
                 radius: float = 5.0,
                 length_x: float = 4.0,
                 coupler90: ComponentSpec = coupler90,
                 bend: ComponentSpec = bend_euler,
                 coupler_straight: ComponentSpec = coupler_straight,
                 cross_section: CrossSectionSpec = "strip",
                 bend_cross_section: CrossSectionSpec | None = None,
                 length_extension: float = 3,
                 **kwargs) -> Component

Coupler for ring.

Arguments:

  • gap - spacing between parallel coupled straight waveguides.

  • radius - of the bends.

  • length_x - length of the parallel coupled straight waveguides.

  • coupler90 - straight coupled to a 90deg bend.

  • bend - bend spec.

  • coupler_straight - two parallel coupled straight waveguides.

  • cross_section - cross_section spec.

  • bend_cross_section - optional bend cross_section spec.

  • length_extension - for the ports.

  • kwargs - cross_section settings for bend and coupler.

    .. code::

    2 3 | | \ / \ / ---=========--- 1 length_x 4

coupler_ring_point

@gf.cell
def coupler_ring_point(coupler_ring: ComponentFactory = coupler_ring,
                       open_layers: LayerSpecs = None,
                       open_sizes: Coordinates | None = None,
                       **kwargs) -> Component

Coupler ring that removes some layers at the coupling region.

This allows short interaction lengths (point couplers).

Arguments:

  • coupler_ring - coupler_ring component to process.
  • open_layers - layers to perform the boolean operations on.
  • open_sizes - sizes of the boxes to use to remove layers, centered at bus center.

Arguments:

  • gap - spacing between parallel coupled straight waveguides.
  • radius - of the bends.
  • length_x - length of the parallel coupled straight waveguides.
  • coupler90 - straight coupled to a 90deg bend.
  • bend - bend spec.
  • coupler_straight - two parallel coupled straight waveguides.
  • cross_section - cross_section spec.
  • bend_cross_section - optional bend cross_section spec.
  • length_extension - for the ports.
  • kwargs - cross_section settings for bend and coupler.

gdsfactory.components.nxn

nxn

@gf.cell
def nxn(west: int = 1,
        east: int = 4,
        north: int = 0,
        south: int = 0,
        xsize: float = 8.0,
        ysize: float = 8.0,
        wg_width: float = 0.5,
        layer: LayerSpec = "WG",
        wg_margin: float = 1.0,
        **kwargs) -> Component

Returns a nxn component with nxn ports (west, east, north, south).

Arguments:

  • west - number of west ports.

  • east - number of east ports.

  • north - number of north ports.

  • south - number of south ports.

  • xsize - size in X.

  • ysize - size in Y.

  • wg_width - width of the straight ports.

  • wg_margin - margin from straight to component edge.

  • kwargs - port_settings.

    .. code::

    3 4 || 2 -| |- 5 | | 1 -|____|- 6 | | 8 7

gdsfactory.components.text_freetype

text_freetype

@gf.cell
def text_freetype(text: str = "abcd",
                  size: int = 10,
                  justify: str = "left",
                  layer: LayerSpec = "WG",
                  font: str = "DEPLOF") -> Component

Returns text Component.

Arguments:

  • text - string.
  • size - in um.
  • position - x, y position.
  • justify - left, right, center.
  • layer - for the text.
  • font - Font face to use. Default DEPLOF does not require additional libraries, otherwise freetype load fonts. You can choose font by name (e.g. “Times New Roman”), or by file OTF or TTF filepath.

gdsfactory.components.ring_double

ring_double

@gf.cell
def ring_double(gap: float = 0.2,
                radius: float = 10.0,
                length_x: float = 0.01,
                length_y: float = 0.01,
                coupler_ring: ComponentSpec = coupler_ring_function,
                bend: ComponentSpec = bend_euler,
                cross_section: CrossSectionSpec = "strip",
                **kwargs) -> Component

Returns a double bus ring.

two couplers (ct: top, cb: bottom) connected with two vertical straights (sl: left, sr: right)

Arguments:

  • gap - gap between for coupler.

  • radius - for the bend and coupler.

  • length_x - ring coupler length.

  • length_y - vertical straight length.

  • coupler - ring coupler spec.

  • bend - bend spec.

  • cross_section - cross_section spec.

  • kwargs - cross_section settings.

    .. code::

    --==ct==-- | | sl sr length_y | | --==cb==-- gap

    length_x

gdsfactory.components.mmi

mmi

@gf.cell
def mmi(inputs: int = 1,
        outputs: int = 4,
        width: float | None = None,
        width_taper: float = 1.0,
        length_taper: float = 10.0,
        length_mmi: float = 5.5,
        width_mmi: float = 5,
        gap_input_tapers: float = 0.25,
        gap_output_tapers: float = 0.25,
        taper: ComponentFactory = taper_function,
        straight: ComponentFactory = straight_function,
        with_bbox: bool = True,
        cross_section: CrossSectionSpec = "strip",
        input_positions: list[float] | None = None,
        output_positions: list[float] | None = None) -> Component

mxn MultiMode Interferometer (MMI).

Arguments:

  • inputs - number of inputs.

  • outputs - number of outputs.

  • width - input and output straight width. Defaults to cross_section.

  • width_taper - interface between input straights and mmi region.

  • length_taper - into the mmi region.

  • length_mmi - in x direction.

  • width_mmi - in y direction.

  • gap_input_tapers - gap between input tapers from edge to edge.

  • gap_output_tapers - gap between output tapers from edge to edge.

  • taper - taper function.

  • straight - straight function.

  • with_bbox - add rectangular box in cross_section bbox_layers and bbox_offsets to avoid DRC sharp edges.

  • cross_section - specification (CrossSection, string or dict).

  • input_positions - optional positions of the inputs.

  • output_positions - optional positions of the outputs.

    .. code::

    length_mmi <------>


    | | / _ o2 __ __ o3 \ / _ _ _ | | _ _ _ _| gap_output_tapers / _ o1 __ __ o4 \ / |_______| | | <-> length_taper

gdsfactory.components.mzi_arms

mzi_arms

@cell
def mzi_arms(delta_length: float = 10.0,
             length_y: float = 0.8,
             length_x: float = 0.1,
             bend: ComponentSpec = bend_euler,
             straight: ComponentSpec = straight_function,
             straight_y: ComponentSpec | None = None,
             straight_x_top: ComponentSpec | None = None,
             straight_x_bot: ComponentSpec | None = None,
             splitter: ComponentSpec = mmi1x2,
             combiner: ComponentSpec | None = None,
             with_splitter: bool = True,
             delta_yright: float = 0,
             **kwargs) -> Component

Mzi made with arms.

This MZI code is slightly deprecated. You can find a more robust mzi in gf.components.mzi

Arguments:

  • delta_length - bottom arm vertical extra length.

  • length_y - vertical length for both and top arms.

  • length_x - horizontal length.

  • bend - 90 degrees bend library.

  • straight - straight spec.

  • straight_y - straight for length_y and delta_length.

  • straight_x_top - top straight for length_x.

  • straight_x_bot - bottom straight for length_x.

  • splitter - splitter spec.

  • combiner - combiner spec.

  • with_splitter - if False removes splitter.

  • delta_yright - extra length for right y-oriented waveguide.

  • kwargs - cross_section settings.

    .. code::

    Lx | | Ly Lyr (not a parameter) | | splitter==| |==combiner | | Ly Lyr (not a parameter) | | | delta_length/2 | | |Lx|


    | | | | | | | | | splitter d1 d2 combiner | ____ | | ____ | | | || |_______

gdsfactory.components.grating_coupler_tree

grating_coupler_tree

@gf.cell
def grating_coupler_tree(
        n: int = 4,
        straight_spacing: float = 4.0,
        grating_coupler: ComponentSpec = grating_coupler_elliptical_te,
        with_loopback: bool = False,
        bend: ComponentSpec = "bend_euler",
        fanout_length: float = 0.0,
        layer_label: LayerSpec = "TEXT",
        **kwargs) -> Component

Array of straights connected with grating couplers.

useful to align the 4 corners of the chip

Arguments:

  • n - number of gratings.
  • straight_spacing - in um.
  • grating_coupler - spec.
  • with_loopback - adds loopback.
  • bend - bend spec.
  • fanout_length - in um.
  • layer_label - for layer.
  • kwargs - cross_section settings.

gdsfactory.components.cdsem_all

CD SEM structures.

cdsem_all

@cell
def cdsem_all(widths: tuple[float, ...] = (0.4, 0.45, 0.5, 0.6, 0.8, 1.0),
              dense_lines_width: float | None = 0.3,
              dense_lines_width_difference: float = 20e-3,
              dense_lines_gap: float = 0.3,
              dense_lines_labels: tuple[str, ...] = ("DL", "DM", "DH"),
              straight: ComponentSpec = "straight",
              bend90: ComponentSpec | None = "bend_circular",
              cross_section: CrossSectionSpec = "strip",
              text: ComponentSpec = text_rectangular_mini) -> Component

Column with all optical PCMs.

Arguments:

  • widths - for straight lines.
  • dense_lines_width - in um.
  • dense_lines_width_difference - in um.
  • dense_lines_gap - in um.
  • dense_lines_labels - strings.
  • straight - spec.
  • bend90 - spec.
  • cross_section - spec.
  • text - spec.

gdsfactory.components.fiber

fiber

@gf.cell
def fiber(core_diameter: float = 10,
          cladding_diameter: float = 125,
          layer_core: LayerSpec = "WG",
          layer_cladding: LayerSpec = "WGCLAD") -> Component

Returns a fiber.

Arguments:

  • core_diameter - in um.
  • cladding_diameter - in um.
  • layer_core - layer spec for fiber core.
  • layer_cladding - layer spec for fiber cladding.

gdsfactory.components.grating_coupler_array

grating_coupler_array

@gf.cell
def grating_coupler_array(
        grating_coupler: ComponentSpec = grating_coupler_elliptical,
        pitch: float = 127.0,
        n: int = 6,
        port_name: str = "o1",
        rotation: int = 0,
        with_loopback: bool = False) -> Component

Array of grating couplers.

Arguments:

  • grating_coupler - ComponentSpec.
  • pitch - x spacing.
  • n - number of grating couplers.
  • port_name - port name.
  • rotation - rotation angle for each reference.
  • with_loopback - if True, adds a loopback between edge GCs. Only works for rotation = 90 for now.

gdsfactory.components.optimal_step

optimal_step

@cell
def optimal_step(
    start_width: float = 10,
    end_width: float = 22,
    num_pts: int = 50,
    width_tol: float = 1e-3,
    anticrowding_factor: float = 1.2,
    symmetric: bool = False,
    layer: LayerSpec = (1, 0)) -> Component

Returns an optimally-rounded step geometry.

Arguments:

  • start_width - Width of the connector on the left end of the step.

  • end_width - Width of the connector on the right end of the step.

  • num_pts - number of points comprising the entire step geometry.

  • width_tol - Point at which to terminate the calculation of the optimal step

  • anticrowding_factor - Factor to reduce current crowding by elongating the structure and reducing the curvature

  • symmetric - If True, adds a mirrored copy of the step across the x-axis to the geometry and adjusts the width of the ports.

  • layer - layer spec to put polygon geometry on.

    based on phidl.geometry

    Notes

    Optimal structure from Clem & Berggren (2011) Clem, J., & Berggren, K. (2011). Geometry-dependent critical currents in superconducting nanocircuits. Physical Review B, 84(17), 1–27.

gdsfactory.components.coupler90bend

coupler90bend

@gf.cell
def coupler90bend(
        radius: float = 10.0,
        gap: float = 0.2,
        bend: ComponentSpec = bend_euler,
        cross_section_inner: CrossSectionSpec = "strip",
        cross_section_outer: CrossSectionSpec = "strip") -> Component

Returns 2 coupled bends.

Arguments:

  • radius - um.

  • gap - um.

  • bend - for bend.

  • cross_section_inner - spec inner bend.

  • cross_section_outer - spec outer bend.

    .. code::

    r 3 4 | | | | / / | / / 2____/ / 1_____/

gdsfactory.components.awg

Sample AWG.

free_propagation_region

@gf.cell
def free_propagation_region(width1: float = 2.0,
                            width2: float = 20.0,
                            length: float = 20.0,
                            wg_width: float = 0.5,
                            inputs: int = 1,
                            outputs: int = 10,
                            cross_section: CrossSectionSpec = strip,
                            **kwargs) -> Component

Free propagation region.

Arguments:

  • width1 - width of the input region.

  • width2 - width of the output region.

  • length - length of the free propagation region.

  • wg_width - waveguide width.

  • inputs - number of inputs.

  • outputs - number of outputs.

  • cross_section - cross_section function.

  • **kwargs - cross_section parameters.

    .. code::

    length <--> /| / | width1| | width2 \ | |

awg

@gf.cell
def awg(arms: int = 10,
        outputs: int = 3,
        free_propagation_region_input_function=free_propagation_region_input,
        free_propagation_region_output_function=free_propagation_region_output,
        fpr_spacing: float = 50.0) -> Component

Returns a basic Arrayed Waveguide grating.

Arguments:

  • arms - number of arms.
  • outputs - number of outputs.
  • free_propagation_region_input_function - for input.
  • free_propagation_region_output_function - for output.
  • fpr_spacing - x separation between input/output free propagation region.

gdsfactory.components.ring_crow

ring_crow

@gf.cell
def ring_crow(
        gaps: list[float] = [0.2] * 4,
        radius: list[float] = [10.0] * 3,
        input_straight_cross_section: CrossSectionSpec = strip,
        output_straight_cross_section: CrossSectionSpec = strip,
        bends: list[ComponentSpec] = [bend_circular] * 3,
        ring_cross_sections: list[CrossSectionSpec] = [strip] * 3
) -> Component

Coupled ring resonators.

Arguments:

  • gap - gap between for coupler.

  • radius - for the bend and coupler.

  • length_x - ring coupler length.

  • length_y - vertical straight length.

  • coupler - ring coupler spec.

  • straight - straight spec.

  • bend - bend spec.

  • cross_section - cross_section spec.

  • kwargs - cross_section settings.

    .. code::

    --==ct==-- gap[N-1] | | sl sr ring[N-1] | | --==cb==-- gap[N-2]

    . . .

    --==ct==-- | | sl sr lengths_y[1], ring[1] | | --==cb==-- gap[1]

    --==ct==-- | | sl sr lengths_y[0], ring[0] | | --==cb==-- gap[0]

    length_x

gdsfactory.components.coupler_asymmetric

coupler_asymmetric

@gf.cell
def coupler_asymmetric(bend: ComponentSpec = bend_s,
                       gap: float = 0.234,
                       dy: float = 5.0,
                       dx: float = 10.0,
                       cross_section: CrossSectionSpec = "strip",
                       **kwargs) -> Component

Bend coupled to straight waveguide.

Arguments:

  • bend - spec.

  • gap - um.

  • dy - port to port vertical spacing.

  • dx - bend length in x direction.

  • cross_section - spec.

  • kwargs - cross_section settings.

    .. code::

    dx |-----| _____ o2 / | / | gap o1_______ | dy o3

gdsfactory.components.interdigital_capacitor_enclosed

interdigital_capacitor_enclosed

@gf.cell
def interdigital_capacitor_enclosed(
        enclosure_box: Sequence[Sequence[float | int]] = [[-200, -200],
                                                          [200, 200]],
        fingers: int = INTERDIGITAL_DEFAULTS["fingers"],
        finger_length: float | int = INTERDIGITAL_DEFAULTS["finger_length"],
        finger_gap: float | int = INTERDIGITAL_DEFAULTS["finger_gap"],
        thickness: float | int = INTERDIGITAL_DEFAULTS["thickness"],
        cpw_dimensions: tuple[float | int, float | int] = (10, 6),
        gap_to_ground: float | int = 5,
        metal_layer: LayerSpec = INTERDIGITAL_DEFAULTS["layer"],
        gap_layer: LayerSpec = "DEEPTRENCH") -> Component

Generates an interdigital capacitor surrounded by a ground plane and coplanar waveguides with ports on both ends. See for :func:~interdigital_capacitor for details.

Notes:

finger_length=0 effectively provides a plate capacitor.

Arguments:

  • enclosure_box - Bounding box dimensions for a ground metal enclosure.
  • fingers - total fingers of the capacitor.
  • finger_length - length of the probing fingers.
  • finger_gap - length of gap between the fingers.
  • thickness - Thickness of fingers and section before the fingers.
  • gap_to_ground - Size of gap from capacitor to ground metal.
  • cpw_dimensions - Dimensions for the trace width and gap width of connecting coplanar waveguides.
  • metal_layer - layer for metalization.
  • gap_layer - layer for trenching.

gdsfactory.components.version_stamp

qrcode

@gf.cell
def qrcode(data: str = "mask01",
           psize: int = 1,
           layer: LayerSpec = "WG") -> Component

Returns QRCode.

version_stamp

@gf.cell
def version_stamp(labels: tuple[str, ...] = ("demo_label", ),
                  with_qr_code: bool = False,
                  layer: LayerSpec = "WG",
                  pixel_size: int = 1,
                  version: str | None = None,
                  text_size: int = 10) -> Component

Component with module version and date.

Arguments:

  • labels - Iterable of labels

gdsfactory.components.component_sequence

SequenceGenerator Objects

class SequenceGenerator()

__init__

def __init__(start_sequence: str = "IL",
             repeated_sequence: str = "ASASBSBS",
             end_sequence: str = "LO") -> None

Sequence generator.

Main use case: any type of cascade of components with repeating patterns such as serpentine, cutbacks etc... Component sequences have two ports by default. it adds aliases for the components forming the sequence. They use the component symbol with a suffix index starting from 1, so you may access the ports from any subcomponent.

Usually we can break these components in 3 parts:

  • there is a starting pattern with input and possibly some special connections
  • then a repeating pattern
  • An ending pattern with an output

Example of symbol meaning

A: bend connected with input W0 B: bend connected with input N0 I: taper with input ‘1’ O: taper with input ‘2’ S: short straight waveguide L: long straight waveguide

parse_component_name

def parse_component_name(name: str) -> tuple[str, bool]

If the component name has more than one character and starts with “!”.

then we need to flip along the axis given by the input port angle.

component_sequence

@gf.cell
def component_sequence(sequence: str,
                       symbol_to_component: dict[str, tuple[ComponentSpec, str,
                                                            str]],
                       ports_map: dict[str, tuple[str, str]] | None = None,
                       port_name1: str = "o1",
                       port_name2: str = "o2",
                       start_orientation: float = 0.0) -> Component

Returns component from ASCII sequence.

if you prefix a symbol with ! it mirrors the component

Arguments:

  • sequence - a string or a list of symbols.
  • symbol_to_component - maps symbols to (component, input, output).
  • ports_map - (optional) extra port mapping using the convention.
  • {port_name - (alias_name, port_name)}
  • port_name1 - input port_name.
  • port_name2 - output port_name.
  • start_orientation - in degrees.

Returns:

  • component - containing the sequence of sub-components instantiated and connected together in the sequence order.

    .. plot:: :include-source:

    import gdsfactory as gf

    bend180 = gf.components.bend_circular180() wg_pin = gf.components.straight_pin(length=40) wg = gf.components.straight()

    Define a map between symbols and (component, input port, output port)

    symbol_to_component = {

  • "A" - (bend180, ‘o1’, ‘o2’),

  • "B" - (bend180, ‘o2’, ‘o1’),

  • "H" - (wg_pin, ‘o1’, ‘o2’),

  • "-" - (wg, ‘o1’, ‘o2’), }

    Each character in the sequence represents a component

    s = “AB-H-H-H-H-BA” c = gf.components.component_sequence(sequence=s, symbol_to_component=symbol_to_component) c.plot()

gdsfactory.components.text

text

@gf.cell
def text(text: str = "abcd",
         size: float = 10.0,
         position: Coordinate = (0, 0),
         justify: str = "left",
         layer: LayerSpec = "WG") -> Component

Text shapes.

Arguments:

  • text - string.
  • size - in um.
  • position - x, y position.
  • justify - left, right, center.
  • layer - for the text.

text_lines

@gf.cell
def text_lines(text: tuple[str, ...] = ("Chip", "01"),
               size: float = 0.4,
               layer: LayerSpec = "WG") -> Component

Returns a Component from a text lines.

Arguments:

  • text - list of strings.
  • size - text size.
  • layer - text layer.

gdsfactory.components.array_with_via

array_with_via

@cell
def array_with_via(component: ComponentSpec = pad,
                   columns: int = 3,
                   spacing: float = 150.0,
                   via_spacing: float = 10.0,
                   straight_length: float = 60.0,
                   cross_section: CrossSectionSpec | None = metal2,
                   via_stack: ComponentSpec = via_stack_factory,
                   via_stack_dy: float = 0,
                   port_orientation: float = 180,
                   port_offset: Float2 | None = None,
                   **kwargs) -> Component

Returns an array of vias in X axis with fanout waveguides facing west.

Arguments:

  • component - to replicate in the array.
  • columns - number of components.
  • spacing - for the array in um.
  • via_spacing - for fanout in um.
  • straight_length - length of the straight at the end in um.
  • waveguide - waveguide definition.
  • cross_section - spec.
  • via_stack - spec.
  • via_stack_dy - via_stack offset in um.
  • port_orientation - 180: facing west.
  • port_offset - Optional port movement in um.
  • kwargs - cross_section settings.

array_with_via_2d

@cell
def array_with_via_2d(spacing: Float2 = (150.0, 150.0),
                      columns: int = 3,
                      rows: int = 2,
                      **kwargs) -> Component

Returns 2D array with fanout waveguides facing west.

Arguments:

  • spacing - 2D spacing x,y in um.
  • columns - number of columns.
  • rows - number of rows.

Arguments:

  • component - to replicate
  • columns - number of components
  • spacing - float
  • via_spacing - for fanout
  • straight_length - length of the straight at the end via_stack_port_name:

gdsfactory.components.L

L

@gf.cell
def L(width: int | float = 1,
      size: tuple[int, int] = (10, 20),
      layer: LayerSpec = "M3",
      port_type: str = "electrical") -> Component

Generates an ‘L’ geometry with ports on both ends.

Based on phidl.

Arguments:

  • width - of the line.
  • size - length and height of the base.
  • layer - spec.
  • port_type - for port.

gdsfactory.components.cdsem_straight

CD SEM structures.

cdsem_straight

@cell
def cdsem_straight(widths: tuple[float, ...] = (0.4, 0.45, 0.5, 0.6, 0.8, 1.0),
                   length: float = LINE_LENGTH,
                   cross_section: CrossSectionSpec = "strip",
                   text: ComponentSpec | None = text_rectangular_mini,
                   spacing: float = 5) -> Component

Returns straight waveguide lines width sweep.

Arguments:

  • widths - for the sweep.
  • length - for the line.
  • cross_section - for the lines.
  • text - optional text for labels.
  • spacing - edge to edge spacing.

gdsfactory.components.die_bbox

based on phidl.geometry.

die_bbox

@gf.cell
def die_bbox(component: ComponentSpec = big_square,
             street_width: float = 100.0,
             street_length: float | None = None,
             die_name: str | None = None,
             text_size: float = 100.0,
             text_anchor: Anchor = "sw",
             layer: LayerSpec = "M3",
             padding: float = 10.0) -> gf.Component

Returns component with boundary box frame around it.

Perfect for defining the boundary of the chip/die it can also add a label with the name of the die. similar to die and bbox.

Arguments:

  • component - to frame.
  • street_width - Width of the boundary box.
  • street_length - length of the boundary box.
  • die_name - Label text.
  • text_size - Label text size.
  • text_anchor - {‘nw’, ‘nc’, ‘ne’, ‘sw’, ‘sc’, ‘se’} text location.
  • layer - Specific layer(s) to put polygon geometry on.
  • padding - adds padding.

gdsfactory.components.circle

circle

@gf.cell
def circle(radius: float = 10.0,
           angle_resolution: float = 2.5,
           layer: LayerSpec = "WG") -> Component

Generate a circle geometry.

Arguments:

  • radius - of the circle.
  • angle_resolution - number of degrees per point.
  • layer - layer.

gdsfactory.components.interdigital_capacitor

interdigital_capacitor

@gf.cell
def interdigital_capacitor(fingers: int = 4,
                           finger_length: float | int = 20.0,
                           finger_gap: float | int = 2.0,
                           thickness: float | int = 5.0,
                           layer: LayerSpec = "WG") -> Component

Generates an interdigital capacitor with ports on both ends.

See for example Zhu et al., Accurate circuit model of interdigital capacitor and its application to design of new uasi-lumped miniaturized filters with suppression of harmonic resonance, doi: 10.1109/22.826833.

Notes:

finger_length=0 effectively provides a plate capacitor.

Arguments:

  • fingers - total fingers of the capacitor.
  • finger_length - length of the probing fingers.
  • finger_gap - length of gap between the fingers.
  • thickness - Thickness of fingers and section before the fingers.
  • layer - spec.

gdsfactory.components.bend_circular_heater

bend_circular_heater

@gf.cell
def bend_circular_heater(radius: float = 10,
                         angle: float = 90,
                         npoints: int | None = None,
                         heater_to_wg_distance: float = 1.2,
                         heater_width: float = 0.5,
                         layer_heater: LayerSpec = "HEATER",
                         with_bbox: bool = True,
                         cross_section: CrossSectionSpec = "strip",
                         **kwargs) -> Component

Creates an arc of arclength theta starting at angle start_angle.

Arguments:

  • radius - in um.
  • angle - angle of arc (degrees).
  • npoints - Number of points used per 360 degrees.
  • heater_to_wg_distance - in um.
  • heater_width - in um.
  • layer_heater - for heater.
  • with_bbox - box in bbox_layers and bbox_offsets to avoid DRC sharp edges.
  • cross_section - specification (CrossSection, string, CrossSectionFactory dict).
  • kwargs - cross_section settings.

gdsfactory.components.straight

Straight waveguide.

straight

@gf.cell
def straight(length: float = 10.0,
             npoints: int = 2,
             with_bbox: bool = True,
             cross_section: CrossSectionSpec = "strip",
             **kwargs) -> Component

Returns a Straight waveguide.

Arguments:

  • length - straight length (um).

  • npoints - number of points.

  • with_bbox - box in bbox_layers and bbox_offsets to avoid DRC sharp edges.

  • cross_section - specification (CrossSection, string, CrossSectionFactory dict).

  • kwargs - cross_section settings.

    .. code::

    o1 -------------- o2 length

gdsfactory.components.seal_ring

seal_ring

@gf.cell_without_validator
def seal_ring(bbox: tuple[Coordinate, Coordinate] = ((-1.0, -1.0), (3.0, 4.0)),
              seal: gf.typings.ComponentSpec = via_stack,
              width: float = 10,
              padding: float = 10.0,
              with_north: bool = True,
              with_south: bool = True,
              with_east: bool = True,
              with_west: bool = True) -> gf.Component

Returns a continuous seal ring boundary at the chip/die.

Prevents cracks from spreading and shields when connected to ground.

Arguments:

  • bbox - to add seal ring around. You can pass Component.bbox.
  • seal - function for the seal.
  • width - of the seal.
  • padding - from component to seal.
  • with_north - includes seal.
  • with_south - includes seal.
  • with_east - includes seal.
  • with_west - includes seal.

gdsfactory.components.ellipse

ellipse

@gf.cell
def ellipse(radii: tuple[float, float] = (10.0, 5.0),
            angle_resolution: float = 2.5,
            layer: LayerSpec = "WG") -> Component

Returns ellipse component.

Arguments:

  • radii - Semimajor and semiminor axis lengths of the ellipse.

  • angle_resolution - number of degrees per point.

  • layer - Specific layer(s) to put polygon geometry on.

    The orientation of the ellipse is determined by the order of the radii variables; if the first element is larger, the ellipse will be horizontal and if the second element is larger, the ellipse will be vertical.

gdsfactory.components.align

align_wafer

@cell
def align_wafer(width: float = 10.0,
                spacing: float = 10.0,
                cross_length: float = 80.0,
                layer: LayerSpec = "WG",
                layer_cladding: tuple[int, int] | None = None,
                square_corner: str = "bottom_left") -> Component

Returns cross inside a frame to align wafer.

Arguments:

  • width - in um.
  • spacing - in um.
  • cross_length - for the cross.
  • layer - for the cross.
  • layer_cladding - optional.
  • square_corner - bottom_left, bottom_right, top_right, top_left.

add_frame

@cell
def add_frame(component: ComponentSpec = rectangle,
              width: float = 10.0,
              spacing: float = 10.0,
              layer: LayerSpec = "WG") -> Component

Returns component with a frame around it.

Arguments:

  • component - Component to frame.
  • width - of the frame.
  • spacing - of component to frame.
  • layer - frame layer.

gdsfactory.components.dicing_lane

dicing_lane

@gf.cell
def dicing_lane(size: Float2 = (50, 300),
                marker: ComponentSpec = triangle_metal,
                layer_dicing: LayerSpec = "DICING") -> Component

Dicing lane with triangular markers on both sides.

Arguments:

  • size - (tuple) Width and height of rectangle.
  • marker - function to generate the dicing lane markers.
  • layer_dicing - Specific layer to put polygon geometry on.

gdsfactory.components.mzit_lattice

mzit_lattice

@gf.cell
def mzit_lattice(coupler_lengths: tuple[float, ...] = (10.0, 20.0),
                 coupler_gaps: tuple[float, ...] = (0.2, 0.3),
                 delta_lengths: tuple[float, ...] = (10.0, ),
                 mzi: ComponentSpec = mzit) -> Component

Mzi fab tolerant lattice filter.

.. code::

                   cp1
   W3  W1 __                  __ E1___w0_t2   _w2___
            \                /                      \
             \    length1   /                        |
              ============== gap1                    |
             /              \                        |
          __/                \_____w0___t1   _w1     |
   W2  W0                       E0               \   | .
                    ...                          |   | .
   W1  W1                                        |   | .
          __                  __w0____t1____w1___/   |
            \                /                       |
             \    lengthN   /                        |
              ============== gapN                    |
             /               \                       |
          __/                 \_                     |
   W0  W0                      \ E0_w0__t2 __w1_____/
                   cpN

gdsfactory.components.delay_snake_sbend

delay_snake_sbend

@gf.cell
def delay_snake_sbend(length: float = 100.0,
                      length1: float = 0.0,
                      length4: float = 0.0,
                      radius: float = 5.0,
                      waveguide_spacing: float = 5.0,
                      bend: ComponentSpec = "bend_euler",
                      sbend: ComponentSpec = "bend_s",
                      sbend_xsize: float = 100.0,
                      cross_section: CrossSectionSpec = "strip",
                      **kwargs) -> Component

Returns compact Snake with sbend in the middle.

Input port faces west and output port faces east.

Arguments:

  • length - total length.

  • length1 - first straight section length in um.

  • length3 - third straight section length in um.

  • radius - u bend radius in um.

  • waveguide_spacing - waveguide pitch in um.

  • bend - bend spec.

  • sbend - sbend spec.

  • sbend_size - sbend size.

  • cross_section - cross_section spec.

  • kwargs - cross_section settings.

    .. code::

    length1 <---------------------------- length2 spacing | _______ | | \ | | \ | bend1 radius | \sbend | bend2| \ | | \ | | __| | ---------------------->-----------> length3 length4

    We adjust length2 and length3

gdsfactory.components.mmi1x2_with_sbend

mmi1x2_with_sbend

@gf.cell
def mmi1x2_with_sbend(with_sbend: bool = True,
                      s_bend: ComponentSpec = bend_s,
                      cross_section: CrossSectionSpec = "strip") -> Component

Returns 1x2 splitter for Cband.

https://opg.optica.org/oe/fulltext.cfm?uri=oe-21-1-1310&id=248418

Arguments:

  • with_sbend - add sbend.
  • s_bend - S-bend spec.
  • cross_section - spec.

gdsfactory.components.straight_rib

Straight Doped PIN waveguide.

gdsfactory.components.ring_single_heater

ring_single_heater

@gf.cell
def ring_single_heater(
        gap: float = 0.2,
        radius: float = 10.0,
        length_x: float = 4.0,
        length_y: float = 0.6,
        coupler_ring: ComponentSpec = _coupler_ring,
        bend: ComponentSpec = bend_euler,
        cross_section_waveguide_heater: CrossSectionSpec = "strip_heater_metal",
        cross_section: CrossSectionSpec = "strip",
        via_stack: ComponentSpec = via_stack_heater_mtop_mini,
        port_orientation: float | None = None,
        via_stack_offset: Float2 = (0, 0),
        **kwargs) -> gf.Component

Returns a single ring with heater on top.

ring coupler (cb: bottom) connects to two vertical straights (sl: left, sr: right), two bends (bl, br) and horizontal straight (wg: top)

Arguments:

  • gap - gap between for coupler.

  • radius - for the bend and coupler.

  • length_x - ring coupler length.

  • length_y - vertical straight length.

  • coupler_ring - ring coupler function.

  • bend - 90 degrees bend function.

  • cross_section_waveguide_heater - for heater.

  • cross_section - for regular waveguide.

  • via_stack - for heater to routing metal.

  • port_orientation - for electrical ports to promote from via_stack.

  • via_stack_offset - x,y offset for via_stack.

  • kwargs - cross_section settings.

    .. code::

    bl-st-br | | sl sr length_y | | --==cb==-- gap

    length_x

gdsfactory.components.text_rectangular

text_rectangular

@gf.cell
def text_rectangular(text: str = "abcd",
                     size: float = 10.0,
                     position: tuple[float, float] = (0.0, 0.0),
                     justify: str = "left",
                     layer: LayerSpec = "WG",
                     font: Callable = rectangular_font) -> Component

Pixel based font, guaranteed to be manhattan, without acute angles.

Arguments:

  • text - string.
  • size - pixel size.
  • position - coordinate.
  • justify - left, right or center.
  • layer - for text.
  • font - function that returns dictionary of characters.

text_rectangular_multi_layer

def text_rectangular_multi_layer(
        text: str = "abcd",
        layers: LayerSpecs = ("WG", "M1", "M2", "M3"),
        text_factory: ComponentSpec = text_rectangular,
        **kwargs) -> Component

Returns rectangular text in different layers.

Arguments:

  • text - string of text
  • layers - list of layers to replicate the text
  • text_factory - function to create the text Components

Arguments:

  • size - pixel size
  • position - coordinate
  • justify - left, right or center
  • font - function that returns dictionary of characters

gdsfactory.components.cavity

cavity

@cell
def cavity(component: ComponentSpec = dbr,
           coupler: ComponentSpec = "coupler",
           length: float = 0.1,
           gap: float = 0.2,
           **kwargs) -> Component

Returns cavity from a coupler and a mirror.

connects the W0 port of the mirror to E1 and W1 coupler ports creating a resonant cavity

Arguments:

  • component - mirror.

  • coupler - coupler library.

  • length - coupler length.

  • gap - coupler gap.

  • kwargs - coupler_settings.

    .. code::

    ml (mirror left) mr (mirror right) | | |o1 - o2__ __o3 - o1| | \ / | \ / ---=========--- o1 o1 length o4 o2

gdsfactory.components.pads_shorted

pads_shorted

@gf.cell
def pads_shorted(pad: ComponentSpec = pad_function,
                 columns: int = 8,
                 pad_spacing: float = 150.0,
                 layer_metal: LayerSpec = "M3",
                 metal_width: float = 10) -> Component

Returns a 1D array of shorted_pads.

Arguments:

  • pad - pad spec.
  • columns - number of columns.
  • pad_spacing - in um
  • layer_metal - for the short.
  • metal_width - for the short.

gdsfactory.components.grating_coupler_dual_pol

grating_coupler_dual_pol

@gf.cell
def grating_coupler_dual_pol(unit_cell: ComponentSpec = rectangle_unit_cell,
                             period_x: float = 0.58,
                             period_y: float = 0.58,
                             x_span: float = 11,
                             y_span: float = 11,
                             length_taper: float = 150.0,
                             width_taper: float = 10.0,
                             polarization: str = "dual",
                             wavelength: float = 1.55,
                             taper: ComponentSpec = taper_function,
                             base_layer: LayerSpec | None = "WG",
                             cross_section: CrossSectionSpec = "strip",
                             **kwargs) -> Component

2 dimensional, dual polarization grating coupler.

Based on a photonic crystal with a unit cell that is usually an ellipse, a rectangle or a circle.

Arguments:

  • unit_cell - component describing the unit cell of the photonic crystal.

  • period_x - spacing between unit cells in the x direction [um].

  • period_y - spacing between unit cells in the y direction [um].

  • x_span - full x span of the photonic crystal.

  • y_span - full y span of the photonic crystal.

  • length_taper - taper length [um].

  • width_taper - width of the taper at the grating coupler side [um].

  • polarization - polarization of the grating coupler.

  • wavelength - operation wavelength [um]

  • taper - function to generate the tapers.

  • base_layer - layer to draw over the whole photonic crystal (necessary if the unit cells are etched into a base layer).

  • cross_section - for the routing waveguides.

  • kwargs - cross_section settings.

    .. code::

    side view fiber

    / / / / / / / /

    |-||-||-|__ --> unit_cells base_layer | o1 ______________|

    top view


    // | o o o | o1 __ // | o o o | \ | o o o | \ | o o o |

    \ // \ // | o2

gdsfactory.components.ring_single_pn

ring_single_pn

@gf.cell
def ring_single_pn(gap: float = 0.3,
                   radius: float = 5.0,
                   doping_angle: float = 250,
                   cross_section: CrossSection = partial(
                       gf.cross_section.strip,
                       sections=(Section(width=2 * 2.425,
                                         layer="SLAB90",
                                         name="slab"), ),
                   ),
                   pn_cross_section: CrossSection = partial(
                       gf.cross_section.pn,
                       width_doping=2.425,
                       width_slab=2 * 2.425,
                       layer_via="VIAC",
                       width_via=0.5,
                       layer_metal="M1",
                       width_metal=0.5,
                   ),
                   doped_heater: bool = True,
                   doped_heater_angle_buffer: float = 10,
                   doped_heater_layer: LayerSpec = "NPP",
                   doped_heater_width: float = 0.5,
                   doped_heater_waveguide_offset: float = 2.175,
                   heater_vias: ComponentSpec = partial(
                       via_stack,
                       size=(0.5, 0.5),
                       layers=("M1", "M2"),
                       vias=(
                           partial(
                               via,
                               layer="VIAC",
                               size=(0.1, 0.1),
                               spacing=(0.2, 0.2),
                               enclosure=0.1,
                           ),
                           partial(
                               via,
                               layer="VIA1",
                               size=(0.1, 0.1),
                               spacing=(0.2, 0.2),
                               enclosure=0.1,
                           ),
                       ),
                   ),
                   **kwargs) -> gf.Component

Returns single pn ring with optional doped heater.

Arguments:

  • gap - gap between for coupler.
  • radius - for the bend and coupler.
  • doping_angle - angle in degrees representing portion of ring that is doped.
  • length_x - ring coupler length.
  • length_y - vertical straight length.
  • cross_section - cross_section spec for non-PN doped rib waveguide sections.
  • pn_cross_section - cross section of pn junction.
  • doped_heater - boolean for if we include doped heater or not.
  • doped_heater_angle_buffer - angle in degrees buffering heater from pn junction.
  • doped_heater_layer - doping layer for heater.
  • doped_heater_width - width of doped heater.
  • doped_heater_waveguide_offset - distance from the center of the ring waveguide to the center of the doped heater.
  • heater_vias - components specifications for heater vias.
  • kwargs - cross_section settings.

gdsfactory.components.pack_doe

generate_doe

def generate_doe(
        doe: ComponentSpec,
        settings: dict[str, list[Any]],
        do_permutations: bool = False,
        function: CellSpec | None = None
) -> tuple[list[Component], list[dict]]

Generates a component DOE (Design of Experiment).

which can then be packed, or used elsewhere.

Arguments:

  • doe - function to return Components.
  • settings - component settings.
  • do_permutations - for each setting.
  • function - for the component (add padding, grating couplers ...)

pack_doe

@cell
def pack_doe(doe: ComponentSpec = _doe,
             settings: dict[str, list[Any]] = _settings,
             do_permutations: bool = False,
             function: CellSpec | None = None,
             **kwargs) -> Component

Packs a component DOE (Design of Experiment) using pack.

Arguments:

  • doe - function to return Components.

  • settings - component settings.

  • do_permutations - for each setting.

  • function - to apply (add padding, grating couplers).

    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).

pack_doe_grid

@cell
def pack_doe_grid(doe: ComponentSpec = _doe,
                  settings: dict[str, list[Any]] = _settings,
                  do_permutations: bool = False,
                  function: CellSpec | None = None,
                  with_text: bool = False,
                  **kwargs) -> Component

Packs a component DOE (Design of Experiment) using grid.

Arguments:

  • component - 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.

    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).

gdsfactory.components.litho_ruler

litho_ruler

@gf.cell
def litho_ruler(height: float = 2,
                width: float = 0.5,
                spacing: float = 2.0,
                scale: tuple[float, ...] = (3, 1, 1, 1, 1, 2, 1, 1, 1, 1),
                num_marks: int = 21,
                layer: LayerSpec = "WG") -> gf.Component

Ruler structure for lithographic measurement.

Includes marks of varying scales to allow for easy reading by eye.

based on phidl.geometry

Arguments:

  • height - Height of the ruling marks in um.
  • width - Width of the ruling marks in um.
  • spacing - Center-to-center spacing of the ruling marks in um.
  • scale - Height scale pattern of marks.
  • num_marks - Total number of marks to generate.
  • layer - Specific layer to put the ruler geometry on.

gdsfactory.components.straight_heater_meander

straight_heater_meander

@gf.cell
def straight_heater_meander(
        length: float = 300.0,
        spacing: float = 2.0,
        cross_section: gf.typings.CrossSectionSpec = "strip",
        heater_width: float = 2.5,
        extension_length: float = 15.0,
        layer_heater: LayerSpec = "HEATER",
        radius: float = 5.0,
        via_stack: ComponentSpec | None = "via_stack_heater_mtop",
        port_orientation1: int | None = None,
        port_orientation2: int | None = None,
        heater_taper_length: float | None = 10.0,
        straight_widths: Floats = (0.8, 0.9, 0.8),
        taper_length: float = 10) -> Component

Returns a meander based heater.

based on SungWon Chung, Makoto Nakai, and Hossein Hashemi, Low-power thermo-optic silicon modulator for large-scale photonic integrated systems Opt. Express 27, 13430-13459 (2019) https://www.osapublishing.org/oe/abstract.cfm?URI=oe-27-9-13430

Arguments:

  • length - total length of the optical path.
  • spacing - waveguide spacing (center to center).
  • cross_section - for waveguide.
  • heater_width - for heater.
  • extension_length - of input and output optical ports.
  • layer_heater - for top heater, if None, it does not add a heater.
  • radius - for the meander bends.
  • via_stack - for the heater to via_stack metal.
  • port_orientation1 - in degrees. None adds all orientations.
  • port_orientation2 - in degrees. None adds all orientations.
  • heater_taper_length - minimizes current concentrations from heater to via_stack.
  • straight_width - width of the straight section.
  • taper_length - from the cross_section.

gdsfactory.components.mmi_90degree_hybrid

mmi_90degree_hybrid

@gf.cell
def mmi_90degree_hybrid(
        width: float = 0.5,
        width_taper: float = 1.7,
        length_taper: float = 40.0,
        length_mmi: float = 175.0,
        width_mmi: float = 10.0,
        gap_mmi: float = 0.8,
        taper: ComponentSpec = taper_function,
        straight: ComponentSpec = straight_function,
        with_bbox: bool = True,
        cross_section: CrossSectionSpec = "strip") -> Component

90 degree hybrid based on a 4x4 MMI.

Default values from Watanabe et al., “Coherent few mode demultiplexer realized as a 2D grating coupler array in silicon”, Optics Express 28(24), 2020

It could be interesting to consider the design in Guan et al., “Compact and low loss 90° optical hybrid on a silicon-on-insulator platform”, Optics Express 25(23), 2017

Arguments:

  • width - input and output straight width.

  • width_taper - interface between input straights and mmi region.

  • length_taper - into the mmi region.

  • length_mmi - in x direction.

  • width_mmi - in y direction.

  • gap_mmi - (width_taper + gap between tapered wg)/2.

  • taper - taper function.

  • straight - straight function.

  • with_bbox - box in bbox_layers and bbox_offsets avoid DRC sharp edges.

  • cross_section - spec.

    .. code::

    length_mmi <------>


    | | / _ signal_in __ __ I_out1 \ / _ _ _ | | _ _ _ | gap_mmi | _ | __ Q_out1 | / | | | / _ LO_in __ __ Q_out2 \ / _ _ _ | | _ _ _ | gap_mmi | _ | __ I_out2 | / | ________|

    <-> length_taper

gdsfactory.components.grating_coupler_loss

connect_loopback

def connect_loopback(port0: Port,
                     port1: Port,
                     a: float,
                     b: float,
                     y_bot_align_route: float,
                     cross_section: CrossSectionSpec = "strip",
                     **kwargs) -> list[ComponentReference]

Connects loopback structure.

loss_deembedding_ch13_24

@cell
def loss_deembedding_ch13_24(
        pitch: float = 127.0,
        grating_coupler: ComponentSpec = grating_coupler_te,
        input_port_indexes: tuple[int, ...] = (0, 1),
        cross_section: CrossSectionSpec = "strip",
        port_name: str = "o1",
        get_input_label: Callable = get_input_label_function,
        **kwargs) -> Component

Grating coupler test structure for fiber array.

Connects channel 1->3, 2->4

Arguments:

  • pitch - um.
  • grating_coupler - spec.
  • input_port_indexes - adds test labels.
  • cross_section - spec.
  • port_name - for the grating_coupler port.
  • kwargs - cross_section settings.

loss_deembedding_ch12_34

@cell
def loss_deembedding_ch12_34(
        pitch: float = 127.0,
        grating_coupler: ComponentSpec = grating_coupler_te,
        input_port_indexes: tuple[int, ...] = (0, 2),
        port_name: str = "o1",
        cross_section: CrossSectionSpec = "strip",
        get_input_label: Callable = get_input_label_function,
        **kwargs) -> Component

Grating coupler test structure for fiber array.

Connects channel 1->2, 3->4

Arguments:

  • pitch - um.
  • grating_coupler - spec.
  • input_port_indexes - for grating couplers.
  • port_name - for the grating_coupler port.
  • cross_section - spec.

Arguments:

  • kwargs - cross_section settings.

loss_deembedding_ch14_23

@cell
def loss_deembedding_ch14_23(
        pitch: float = 127.0,
        grating_coupler: ComponentSpec = grating_coupler_te,
        input_port_indexes: tuple[int, ...] = (0, 1),
        cross_section: CrossSectionSpec = "strip",
        port_name: str = "o1",
        get_input_label: Callable = get_input_label_function,
        **kwargs) -> Component

Grating coupler test structure for fiber array.

Connects channel 1->4, 2->3

Arguments:

  • pitch - um.
  • grating_coupler - spec.
  • input_port_indexes - for grating couplers.
  • cross_section - spec.
  • port_name - for the grating_coupler port.

Arguments:

  • kwargs - cross_section settings.

grating_coupler_loss_fiber_array

@cell
def grating_coupler_loss_fiber_array(
        pitch: float = 127.0,
        grating_coupler: ComponentSpec = grating_coupler_te,
        input_port_indexes: tuple[int, ...] = (0, 1),
        port_name: str = "o1",
        cross_section: CrossSectionSpec = "strip",
        get_input_label: Callable = get_input_label_function,
        **kwargs) -> Component

Returns Grating coupler fiber array loopback.

Arguments:

  • pitch - spacing.
  • grating_coupler - spec for grating coupler.
  • input_port_indexes - for grating couplers.
  • port_name - for the grating_coupler port.
  • cross_section - spec.

Arguments:

  • kwargs - cross_section settings.

grating_coupler_loss_fiber_array4

@cell
def grating_coupler_loss_fiber_array4(
        pitch: float = 127.0,
        grating_coupler: ComponentSpec = grating_coupler_te,
        **kwargs) -> Component

Returns a grating coupler test structure for fiber array.

Measures all combinations for a 4 fiber fiber_array

Connects channel 1->3, 2->4 Connects channel 1->4, 2->3 Connects channel 1->2, 3->4

Arguments:

  • pitch - grating_coupler_pitch.
  • grating_coupler - function.
  • kwargs - cross_section settings.

gdsfactory.components.ring_double_heater

ring_double_heater

@gf.cell
def ring_double_heater(
        gap: float = 0.2,
        radius: float = 10.0,
        length_x: float = 0.01,
        length_y: float = 0.01,
        coupler_ring: ComponentSpec = coupler_ring,
        coupler_ring_top: ComponentSpec | None = None,
        straight: ComponentSpec = straight,
        bend: ComponentSpec = bend_euler,
        cross_section_heater: CrossSectionSpec = "heater_metal",
        cross_section_waveguide_heater: CrossSectionSpec = "strip_heater_metal",
        cross_section: CrossSectionSpec = "strip",
        via_stack: ComponentSpec = via_stack_heater_m3_mini,
        port_orientation: float | None = None,
        via_stack_offset: Float2 = (0, 0),
        **kwargs) -> Component

Returns a double bus ring with heater on top.

two couplers (ct: top, cb: bottom) connected with two vertical straights (sl: left, sr: right)

Arguments:

  • gap - gap between for coupler.

  • radius - for the bend and coupler.

  • length_x - ring coupler length.

  • length_y - vertical straight length.

  • coupler_ring - ring coupler spec.

  • coupler_ring_top - ring coupler spec for coupler away from vias (defaults to coupler_ring)

  • straight - straight spec.

  • bend - bend spec.

  • cross_section_heater - for heater.

  • cross_section_waveguide_heater - for waveguide with heater.

  • cross_section - for regular waveguide.

  • via_stack - for heater to routing metal.

  • port_orientation - for electrical ports to promote from via_stack.

  • via_stack_offset - x,y offset for via_stack.

  • kwargs - cross_section settings.

    .. code::

    --==ct==-- | | sl sr length_y | | --==cb==-- gap

    length_x

gdsfactory.components.ring_single

ring_single

@gf.cell
def ring_single(gap: float = 0.2,
                radius: float = 10.0,
                length_x: float = 4.0,
                length_y: float = 0.6,
                coupler_ring: ComponentSpec = coupler_ring_function,
                bend: ComponentSpec = bend_euler,
                cross_section: CrossSectionSpec = "strip",
                **kwargs) -> gf.Component

Returns a single ring.

ring coupler (cb: bottom) connects to two vertical straights (sl: left, sr: right), two bends (bl, br) and horizontal straight (wg: top)

Arguments:

  • gap - gap between for coupler.

  • radius - for the bend and coupler.

  • length_x - ring coupler length.

  • length_y - vertical straight length.

  • coupler_ring - ring coupler spec.

  • bend - 90 degrees bend spec.

  • cross_section - cross_section spec.

  • kwargs - cross_section settings.

    .. code::

    bl-st-br | | sl sr length_y | | --==cb==-- gap

    length_x

gdsfactory.components.terminator

terminator

@gf.cell
def terminator(length: float | None = 50,
               cross_section_input: CrossSectionSpec = "strip",
               cross_section_tip: CrossSectionSpec | None = None,
               tapered_width: float = 0.2,
               doping_layers: LayerSpecs = ("NPP", ),
               doping_offset: float = 1) -> gf.Component

Returns doped taper to terminate waveguides.

Arguments:

  • length - distance between input and narrow tapered end.
  • cross_section_input - input cross-section.
  • cross_section_tip - cross-section at the end of the termination.
  • tapered_width - width of the default cross-section at the end of the termination. Only used if cross_section_tip is not None.
  • doping_layers - doping layers to superimpose on the taper. Default N++.
  • doping_offset - offset of the doping layer beyond the bbox

gdsfactory.components.cutback_splitter

cutback_splitter

@gf.cell
def cutback_splitter(component: ComponentSpec = mmi1x2,
                     cols: int = 4,
                     rows: int = 5,
                     port1: str = "o1",
                     port2: str = "o2",
                     port3: str = "o3",
                     bend180: ComponentSpec = bend_euler180,
                     mirror: bool = False,
                     straight_length: float | None = None,
                     cross_section: CrossSectionSpec = "strip",
                     **kwargs) -> Component

Returns a daisy chain of splitters for measuring their loss.

Arguments:

  • component - for cutback.
  • cols - number of columns.
  • rows - number of rows.
  • port1 - name of first optical port.
  • port2 - name of second optical port.
  • bend180 - ubend.
  • straight - waveguide spec to connect both sides.
  • mirror - Flips component. Useful when ‘o2’ is the port that you want to route to.
  • straight_length - length of the straight section between cutbacks.
  • cross_section - specification (CrossSection, string or dict).
  • kwargs - cross_section settings.

gdsfactory.components

Each component factory component returns a component.

Make sure your components get imported here so the PDK registers them.

gdsfactory.components.verniers

gdsfactory.components.bend_circular

bend_circular

@gf.cell
def bend_circular(angle: float = 90.0,
                  npoints: int | None = None,
                  with_bbox: bool = True,
                  cross_section: CrossSectionSpec = "strip",
                  **kwargs) -> Component

Returns a radial arc.

Arguments:

  • angle - angle of arc (degrees).

  • npoints - number of points.

  • with_bbox - box in bbox_layers and bbox_offsets to avoid DRC sharp edges.

  • cross_section - spec (CrossSection, string or dict).

  • kwargs - cross_section settings.

    .. code::

    o2 | / / / o1_____/

gdsfactory.components.grating_coupler_elliptical_arbitrary

grating_coupler_elliptical_arbitrary

@gf.cell
def grating_coupler_elliptical_arbitrary(
        gaps: Floats = _gaps,
        widths: Floats = _widths,
        taper_length: float = 16.6,
        taper_angle: float = 60.0,
        wavelength: float = 1.554,
        fiber_angle: float = 15.0,
        nclad: float = 1.443,
        layer_slab: LayerSpec | None = "SLAB150",
        layer_grating: LayerSpec | None = None,
        taper_to_slab_offset: float = -3.0,
        polarization: str = "te",
        spiked: bool = True,
        bias_gap: float = 0,
        cross_section: CrossSectionSpec = "strip",
        **kwargs) -> Component

Grating coupler with parametrization based on Lumerical FDTD simulation.

The ellipticity is derived from Lumerical knowledge base it depends on fiber_angle (degrees), neff, and nclad

Arguments:

  • gaps - list of gaps.

  • widths - list of widths.

  • taper_length - taper length from input.

  • taper_angle - grating flare angle.

  • wavelength - grating transmission central wavelength (um).

  • fiber_angle - fibre angle in degrees determines ellipticity.

  • nclad - cladding effective index to compute ellipticity.

  • layer_slab - Optional slab.

  • layer_grating - Optional layer for grating. by default None uses cross_section.layer. if different from cross_section.layer expands taper.

  • taper_to_slab_offset - 0 is where taper ends.

  • polarization - te or tm.

  • spiked - grating teeth have spikes to avoid drc errors.

  • bias_gap - etch gap (um). Positive bias increases gap and reduces width to keep period constant.

  • cross_section - cross_section spec for waveguide port.

  • kwargs - cross_section settings.

    https://en.wikipedia.org/wiki/Ellipse c = (a1 ** 2 - b1 ** 2) ** 0.5 e = (1 - (b1 / a1) ** 2) ** 0.5 print(e)

    .. code::

    fiber

    / / / / / / / /

    |-||-||-|__ layer layer_slab | o1 ______________|

grating_coupler_elliptical_uniform

@gf.cell
def grating_coupler_elliptical_uniform(n_periods: int = 20,
                                       period: float = 0.75,
                                       fill_factor: float = 0.5,
                                       **kwargs) -> Component

Grating coupler with parametrization based on Lumerical FDTD simulation.

The ellipticity is derived from Lumerical knowledge base it depends on fiber_angle (degrees), neff, and nclad

Arguments:

  • n_periods - number of grating periods.
  • period - grating pitch in um.
  • fill_factor - ratio of grating width vs gap.

Arguments:

  • taper_length - taper length from input.

  • taper_angle - grating flare angle.

  • wavelength - grating transmission central wavelength (um).

  • fiber_angle - fibre angle in degrees determines ellipticity.

  • neff - tooth effective index to compute ellipticity.

  • nclad - cladding effective index to compute ellipticity.

  • layer_slab - Optional slab.

  • taper_to_slab_offset - where 0 is at the start of the taper.

  • polarization - te or tm.

  • spiked - grating teeth have spikes to avoid drc errors..

  • bias_gap - etch gap (um). Positive bias increases gap and reduces width to keep period constant.

  • cross_section - cross_section spec for waveguide port.

  • kwargs - cross_section settings.

    .. code::

    fiber

    / / / / / / / /

    |-||-||-|__ layer layer_slab | o1 ______________|

gdsfactory.components.spiral_external_io

Bends with grating couplers inside the spiral.

maybe: need to add grating coupler loopback as well

get_bend_port_distances

def get_bend_port_distances(bend: Component) -> tuple[float64, float64]

Returns distance between bend ports.

spiral_external_io

@cell
def spiral_external_io(N: int = 6,
                       x_inner_length_cutback: float = 300.0,
                       x_inner_offset: float = 0.0,
                       y_straight_inner_top: float = 0.0,
                       xspacing: float = 3.0,
                       yspacing: float = 3.0,
                       bend: ComponentSpec = bend_euler,
                       length: float | None = None,
                       cross_section: CrossSectionSpec = "strip",
                       with_inner_ports: bool = False,
                       y_straight_outer_offset: float = 0.0,
                       inner_loop_spacing_offset: float = 0.0,
                       **kwargs) -> Component

Returns spiral with input and output ports outside the spiral.

Arguments:

  • N - number of loops.
  • x_inner_length_cutback - x inner length.
  • x_inner_offset - x inner offset.
  • y_straight_inner_top - y straight inner top.
  • xspacing - center to center x-spacing.
  • yspacing - center to center y-spacing.
  • bend - function.
  • length - length in um, it is the approximates total length.
  • cross_section - spec.
  • with_inner_ports - if True, removes the internal S-bend and exposes new ports
  • y_straight_outer_offset - amount to add/remove to the last points at the outer output of the spiral
  • inner_loop_spacing_offset - extra difference between the inner ports
  • kwargs - cross_section settings.

gdsfactory.components.crossing_waveguide

snap_to_grid

def snap_to_grid(p: float, grid_per_unit: int = 1000) -> float64

Round.

crossing_arm

@cell
def crossing_arm(r1: float = 3.0,
                 r2: float = 1.1,
                 w: float = 1.2,
                 L: float = 3.4,
                 layer_slab: LayerSpec = "SLAB150",
                 cross_section: CrossSectionSpec = "strip") -> Component

Returns crossing arm.

Arguments:

  • r1 - ellipse radius1.
  • r2 - ellipse radius2.
  • w - width in um.
  • L - length in um.
  • layer_slab - for the shallow etch.
  • cross_section - spec.

crossing

@cell
def crossing(arm: ComponentSpec = crossing_arm,
             cross_section: CrossSectionSpec = "strip") -> Component

Waveguide crossing.

Arguments:

  • arm - arm spec.
  • cross_section - spec.

crossing_from_taper

@cell
def crossing_from_taper(taper=lambda: taper(width2=2.5, length=3.0)
                        ) -> Component

Returns Crossing based on a taper.

The default is a dummy taper.

Arguments:

  • taper - taper function.

crossing_etched

@cell
def crossing_etched(width: float = 0.5,
                    r1: float = 3.0,
                    r2: float = 1.1,
                    w: float = 1.2,
                    L: float = 3.4,
                    layer_wg: LayerSpec = "WG",
                    layer_slab: LayerSpec = "SLAB150") -> Component

Waveguide crossing.

Full crossing has to be on WG layer (to start with a 220nm slab). Then we etch the ellipses down to 150nm slabs and we keep linear taper at 220nm.

Arguments:

  • width - input waveguides width.
  • r1 - radii.
  • r2 - radii.
  • w - wide width.
  • L - length.
  • layer_wg - waveguide layer.
  • layer_slab - shallow etch layer.

crossing45

@cell
def crossing45(
        crossing: ComponentSpec = crossing,
        port_spacing: float = 40.0,
        dx: float | None = None,
        alpha: float = 0.08,
        npoints: int = 101,
        cross_section: CrossSectionSpec = "strip",
        cross_section_bends: CrossSectionSpec = "strip_no_pins") -> Component

Returns 45deg crossing with bends.

Arguments:

  • crossing - crossing function.

  • port_spacing - target I/O port spacing.

  • dx - target length.

  • alpha - optimization parameter. diminish it for tight bends, increase it if raises assertion angle errors

  • npoints - number of points.

    The 45 Degree crossing CANNOT be kept as an SRef since we only allow for multiples of 90Deg rotations in SRef.

    .. code::


    \ / X / \


compensation_path

@cell
def compensation_path(crossing45: ComponentSpec = crossing45_pins,
                      crossing: ComponentSpec = crossing,
                      direction: str = "top",
                      cross_section: CrossSectionSpec = "strip") -> Component

Returns Component Path with same path length as the crossing.

with input and output ports having same y coordinates

Arguments:

  • crossing45 - component that we want to match in path length. needs to have .info[“components”] with bends and crossing.

  • direction - the direction in which the bend should go “top” / “bottom”.

    .. code::


    \ / \ / \ / X /
    /
    / \


    Compensation path:

    .. code::

    --+-- _/ _ --/ --

gdsfactory.components.dbr

DBR gratings.

wavelength = 2periodneff period = wavelength/2/neff

dbr default parameters are from Stephen Lin thesis https://open.library.ubc.ca/cIRcle/collections/ubctheses/24/items/1.0388871

Period: 318nm, width: 500nm, dw: 20 ~ 120 nm.

dbr_cell

@cell
def dbr_cell(w1: float = w1,
             w2: float = w2,
             l1: float = period / 2,
             l2: float = period / 2,
             cross_section: CrossSectionSpec = "strip",
             **kwargs) -> Component

Distributed Bragg Reflector unit cell.

Arguments:

  • w1 - thin width in um.

  • l1 - thin length in um.

  • w2 - thick width in um.

  • l2 - thick length in um.

  • n - number of periods.

  • cross_section - cross_section spec.

  • kwargs - cross_section settings.

    .. code::

    l1 l2 <-----><-------->


    _______|

    w1 w2


    |_________

dbr

@cell
def dbr(w1: float = w1,
        w2: float = w2,
        l1: float = period / 2,
        l2: float = period / 2,
        n: int = 10,
        cross_section: CrossSectionSpec = "strip",
        **kwargs) -> Component

Distributed Bragg Reflector.

Arguments:

  • w1 - thin width in um.

  • l1 - thin length in um.

  • w2 - thick width in um.

  • l2 - thick length in um.

  • n - number of periods.

  • cross_section - cross_section spec.

  • kwargs - cross_section settings.

    .. code::

    l1 l2 <-----><-------->


    _______|

    w1 w2 ... n times


    |_________

gdsfactory.components.taper_parabolic

taper_parabolic

@gf.cell
def taper_parabolic(length: float = 20,
                    width1: float = 0.5,
                    width2: float = 5.0,
                    exp: float = 0.5,
                    npoints: int = 100,
                    layer: LayerSpec = "WG") -> gf.Component

Returns a parabolic_taper.

Arguments:

  • length - in um.
  • width1 - in um.
  • width2 - in um.
  • exp - exponent.
  • npoints - number of points.
  • layer - layer spec.

gdsfactory.components.via_stack_slot

via_stack_slot

@gf.cell
def via_stack_slot(size=(11.0, 11.0),
                   layers: LayerSpecs = ("M1", "M2"),
                   layer_offsets: Floats | None = (0, 1.0),
                   layer_offsetsx: Floats | None = None,
                   layer_offsetsy: Floats | None = None,
                   layer_port: LayerSpec | None = None,
                   via: ComponentSpec = via1,
                   enclosure: float = 1.0,
                   ysize: float = 0.5,
                   yspacing: float = 2.0) -> Component

Rectangular via_stack with slotted via in X direction.

Arguments:

  • size - of the layers.

  • layers - layers on which to draw rectangles.

  • layer_offsets - cladding_offset for each layer.

  • layer_offsetsx - optional xoffset for layers, defaults to layer_offsets.

  • layer_offsetsy - optional yoffset for layers, defaults to layer_offsets.

  • layer_port - if None assumes port is on the last layer.

  • via - via to use to fill the rectangles.

  • enclosure - of the via by rectangle.

  • ysize - via height in y.

  • yspacing - via spacing pitch in y.

    .. code::


    | | | | | layer_offsetsy[1] | | |________ | | |<---> |<>| | |enclosure | layer_offsetsx[1] | | ______________________ | | | | | | | | | | | via | ysize| | | | || | | | | | | | | | | yspacing size[1]| | | | | | | | | | ______________________ | | | | | | | | | | | | | via | ysize| | | | | || | | | | | | | | | | | || | | size[0] | | | |______|

gdsfactory.components.cutback_bend

cutback_bend

@cell
def cutback_bend(bend90: ComponentSpec = bend_euler,
                 straight: ComponentSpec = straight,
                 straight_length: float = 5.0,
                 rows: int = 6,
                 columns: int = 5,
                 **kwargs) -> Component

Deprecated.

Use cutback_bend90 instead with smaller footprint.

Arguments:

  • bend90 - bend spec.

  • straight - straight spec.

  • straight_length - in um.

  • rows - number of rows.

  • columns - number of columns.

  • kwargs - cross_section settings.

    .. code::

    this is a column _ _| _|

    _ this is a row

cutback_bend90

@cell
def cutback_bend90(bend90: ComponentSpec = bend_euler,
                   straight: ComponentSpec = straight,
                   straight_length: float = 5.0,
                   rows: int = 6,
                   columns: int = 6,
                   spacing: int = 5,
                   **kwargs) -> Component

Returns bend90 cutback.

Arguments:

  • bend90 - bend spec.

  • straight - straight spec.

  • straight_length - in um.

  • rows - number of rows.

  • columns - number of columns.

  • kwargs - cross_section settings.

    .. code::

    _ |_| |

staircase

@cell
def staircase(bend90: ComponentSpec = bend_euler,
              straight: ComponentSpec = straight,
              length_v: float = 5.0,
              length_h: float = 5.0,
              rows: int = 4,
              **kwargs) -> Component

Returns staircase.

Arguments:

  • bend90 - bend spec.
  • straight - straight spec.
  • length_v - vertical length.
  • length_h - vertical length.
  • rows - number of rows.
  • columns - number of columns.
  • kwargs - cross_section settings.

cutback_bend180

@cell
def cutback_bend180(bend180: ComponentSpec = bend_euler180,
                    straight: ComponentSpec = straight,
                    straight_length: float = 5.0,
                    rows: int = 6,
                    columns: int = 6,
                    spacing: int = 3,
                    **kwargs) -> Component

Returns cutback to measure u bend loss.

Arguments:

  • bend180 - bend spec.

  • straight - straight spec.

  • straight_length - in um.

  • rows - number of rows.

  • columns - number of columns.

  • spacing - in um.

  • kwargs - cross_section settings.

    .. code::

    _ | | this is a row

    _ this is a column

gdsfactory.components.straight_pin_slot

Straight Doped PIN waveguide.

straight_pin_slot

@gf.cell
def straight_pin_slot(length: float = 500.0,
                      cross_section: CrossSectionSpec = pin,
                      via_stack: ComponentSpec | None = via_stack_m1_m3,
                      via_stack_width: float = 10.0,
                      via_stack_slab: ComponentSpec
                      | None = via_stack_slot_slab_m1,
                      via_stack_slab_top: ComponentSpec | None = None,
                      via_stack_slab_bot: ComponentSpec | None = None,
                      via_stack_slab_width: float | None = None,
                      via_stack_spacing: float = 3.0,
                      via_stack_slab_spacing: float = 2.0,
                      taper: ComponentSpec | None = taper_strip_to_ridge,
                      **kwargs) -> Component

Returns a PIN straight waveguide with slotted via.

Fatemi et al. (2018)

500um length for PI phase shift https://ieeexplore.ieee.org/document/8268112

to go beyond 2PI, you will need at least 1mm https://ieeexplore.ieee.org/document/8853396/

Arguments:

  • length - of the waveguide.
  • cross_section - for the waveguide.
  • via_stack - for via_stacking the metal.
  • via_stack_width - in um.
  • via_stack_slab - function for the component via_stacking the slab.
  • via_stack_slab_top - Optional, defaults to via_stack_slab.
  • via_stack_slab_bot - Optional, defaults to via_stack_slab.
  • via_stack_slab_width - defaults to via_stack_width.
  • via_stack_spacing - spacing between via_stacks.
  • via_stack_slab_spacing - spacing between via_stacks slabs.
  • taper - optional taper.
  • kwargs - cross_section settings.

gdsfactory.components.grating_coupler_rectangular

grating_coupler_rectangular

@gf.cell
def grating_coupler_rectangular(n_periods: int = 20,
                                period: float = 0.75,
                                fill_factor: float = 0.5,
                                width_grating: float = 11.0,
                                length_taper: float = 150.0,
                                polarization: str = "te",
                                wavelength: float = 1.55,
                                taper: ComponentSpec = taper_function,
                                layer_slab: LayerSpec | None = "SLAB150",
                                fiber_angle: float = 15,
                                slab_xmin: float = -1.0,
                                slab_offset: float = 1.0,
                                cross_section: CrossSectionSpec = "strip",
                                **kwargs) -> Component

Grating coupler with rectangular shapes (not elliptical).

Needs longer taper than elliptical. Grating teeth are straight. For a focusing grating take a look at grating_coupler_elliptical.

Arguments:

  • n_periods - number of grating teeth.

  • period - grating pitch.

  • fill_factor - ratio of grating width vs gap.

  • width_grating - 11.

  • length_taper - 150.

  • polarization - ‘te’ or ‘tm’.

  • wavelength - in um.

  • taper - function.

  • layer_slab - layer that protects the slab under the grating.

  • fiber_angle - in degrees.

  • slab_xmin - where 0 is at the start of the taper.

  • slab_offset - from edge of grating to edge of the slab.

  • cross_section - for input waveguide port.

  • kwargs - cross_section settings.

    .. code::

    side view fiber

    / / / / / / / /

    |-||-||-|__ layer layer_slab | o1 ______________|

    top view _________ /| | | | | / | | | | | /taper_angle /_ | | | | | wg_width | | | | | | \ | | | | | \ | | | | | \ | | | | | ||||_| <--> taper_length

gdsfactory.components.rectangle_with_slits

rectangle_with_slits

@cell
def rectangle_with_slits(size: tuple[float, float] = (100.0, 200.0),
                         layer: LayerSpec = "WG",
                         layer_slit: LayerSpec = "SLAB150",
                         centered: bool = False,
                         port_type: str | None = None,
                         slit_size: tuple[float, float] = (1.0, 1.0),
                         slit_spacing: Float2 = (20, 20),
                         slit_enclosure: float = 10) -> Component

Returns a rectangle with slits.

Metal slits reduce stress.

Arguments:

  • size - (tuple) Width and height of rectangle.

  • layer - Specific layer to put polygon geometry on.

  • layer_slit - does a boolean NOT when None.

  • centered - True sets center to (0, 0), False sets south-west to (0, 0)

  • port_type - for the rectangle.

  • slit_size - x, y slit size.

  • slit_spacing - pitch_x, pitch_y for slits.

  • slit_enclosure - from slit to rectangle edge.

    .. code::

    slit_enclosure


    |<---> | | | | ______________________ | | | | | | | | slit_size[1] | || | | | | | | slit_spacing | | | | size[1] | | ______________________ | | | | | | | | | | | | | || | | <---------------------> | | slit_size[0] | |___________________________________| size[0]

gdsfactory.components.litho_calipers

litho_calipers

@cell
def litho_calipers(notch_size: tuple[float, float] = (2.0, 5.0),
                   notch_spacing: float = 2.0,
                   num_notches: int = 11,
                   offset_per_notch: float = 0.1,
                   row_spacing: float = 0.0,
                   layer1: LayerSpec = "WG",
                   layer2: LayerSpec = "SLAB150") -> Component

Vernier caliper structure to test lithography alignment.

Only the middle finger is aligned and the rest are offset.

based on phidl

Arguments:

  • notch_size - [xwidth, yheight].
  • notch_spacing - in um.
  • num_notches - number of notches.
  • offset_per_notch - in um.
  • row_spacing - 0
  • layer1 - layer.
  • layer2 - layer.

gdsfactory.components.array_component

array

@cell
def array(component: ComponentSpec = "pad",
          spacing: tuple[float, float] = (150.0, 150.0),
          columns: int = 6,
          rows: int = 1,
          add_ports: bool = True,
          size: Float2 | None = None) -> Component

Returns an array of components.

Arguments:

  • component - to replicate.
  • spacing - x, y spacing.
  • columns - in x.
  • rows - in y.
  • add_ports - add ports from component into the array.
  • size - Optional x, y size. Overrides columns and rows.

Raises:

  • ValueError - If columns > 1 and spacing[0] = 0.

  • ValueError - If rows > 1 and spacing[1] = 0.

    .. code::

    2 rows x 4 columns


    | | | | | | | | || || || ||


    | | | | | | | | || || || ||

gdsfactory.components.mzit

mzit

@gf.cell
def mzit(w0: float = 0.5,
         w1: float = 0.45,
         w2: float = 0.55,
         dy: float = 2.0,
         delta_length: float = 10.0,
         length: float = 1.0,
         coupler_length1: float = 5.0,
         coupler_length2: float = 10.0,
         coupler_gap1: float = 0.2,
         coupler_gap2: float = 0.3,
         taper: ComponentSpec = taper_function,
         taper_length: float = 5.0,
         bend90: ComponentSpec = bend_euler,
         straight: ComponentSpec = straight_function,
         coupler1: ComponentSpec | None = coupler_function,
         coupler2: ComponentSpec = coupler_function,
         **kwargs) -> Component

Mzi tolerant to fabrication variations.

based on Yufei Xing thesis http://photonics.intec.ugent.be/publications/PhD.asp?ID=250

Arguments:

  • w1 - narrow waveguide width (um).

  • w2 - wide waveguide width (um).

  • dy - port to port vertical spacing.

  • delta_length - length difference between arms (um).

  • length - shared length for w1 and w2.

  • coupler_length1 - length of coupler1.

  • coupler_length2 - length of coupler2.

  • coupler_gap1 - coupler1.

  • coupler_gap2 - coupler2.

  • taper - taper spec.

  • taper_length - from w0 to w1.

  • bend90 - bend spec.

  • straight - spec.

  • coupler1 - coupler1 spec (optional).

  • coupler2 - coupler2 spec.

  • kwargs - cross_section settings.

    .. code::

    cp1 4 2 __ __ 3___w0_t2 w2__ \ /
    \ length1 / | ============== gap1 | / \ | __/ ___w0___t1 w1 | 3 1 4 \ | | | 2 2 | | __ w0____t1____w1/ | \ / | \ length2 / | ============== gap2 | / \ | | / \ E0_w0__t2 w1/ 1 1 cp2

gdsfactory.components.disk

disk

@gf.cell
def disk(radius: float = 10.0,
         gap: float = 0.2,
         wrap_angle_deg: float = 180.0,
         parity: int = 1,
         cross_section: CrossSectionSpec = "strip",
         **kwargs) -> Component

Disk Resonator.

Arguments:

  • radius - disk resonator radius.
  • gap - Distance between the bus straight and resonator.
  • wrap_angle_deg - Angle in degrees between 0 and 180. determines how much the bus straight wraps along the resonator. 0 corresponds to a straight bus straight. 180 corresponds to a bus straight wrapped around half of the resonator.
  • parity 1 or -1 - 1, resonator left from bus straight, -1 resonator to the right.
  • cross_section - cross_section spec.
  • kwargs - cross_section settings.

disk_heater

@gf.cell
def disk_heater(radius: float = 10.0,
                gap: float = 0.2,
                wrap_angle_deg: float = 180.0,
                parity: int = 1,
                cross_section: CrossSectionSpec = "strip",
                heater_layer: LayerSpec = "HEATER",
                via_stack: ComponentSpec = "via_stack_heater_mtop",
                heater_width: float = 5.0,
                heater_extent: float = 2.0,
                via_width: float = 10.0,
                port_orientation: float | None = 90,
                **kwargs) -> Component

Disk Resonator with top metal heater.

Arguments:

  • radius - disk resonator radius.
  • gap - Distance between the bus straight and resonator.
  • wrap_angle_deg - Angle in degrees between 0 and 180. determines how much the bus straight wraps along the resonator. 0 corresponds to a straight bus straight. 180 corresponds to a bus straight wrapped around half of the resonator.
  • parity 1 or -1 - 1, resonator left from bus straight, -1 resonator to the right.
  • cross_section - cross_section spec.
  • heater_layer - layer of the heater.
  • heater_width - width of the heater.
  • heater_extent - length of heater beyond disk.
  • via_width - size of the square via at the end of the heater.
  • port_orientation - in degrees.
  • kwargs - cross_section settings.

gdsfactory.components.grating_coupler_elliptical

ellipse_arc

def ellipse_arc(a: float,
                b: float,
                x0: float,
                theta_min: float,
                theta_max: float,
                angle_step: float = 0.5) -> ndarray

Returns an elliptical arc.

b = a *sqrt(1-e**2)

An ellipse with a = b has zero eccentricity (is a circle)

Arguments:

  • a - ellipse semi-major axis.
  • b - semi-minor axis.
  • x0 - in um.
  • theta_min - in rad.
  • theta_max - in rad.
  • angle_step - in rad.

grating_coupler_elliptical

@gf.cell
def grating_coupler_elliptical(polarization: str = "te",
                               taper_length: float = 16.6,
                               taper_angle: float = 40.0,
                               wavelength: float = 1.554,
                               fiber_angle: float = 15.0,
                               grating_line_width: float = 0.343,
                               neff: float = 2.638,
                               nclad: float = 1.443,
                               n_periods: int = 30,
                               big_last_tooth: bool = False,
                               layer_slab: LayerSpec | None = "SLAB150",
                               slab_xmin: float = -1.0,
                               slab_offset: float = 2.0,
                               spiked: bool = True,
                               cross_section: CrossSectionSpec = "strip",
                               **kwargs) -> Component

Grating coupler with parametrization based on Lumerical FDTD simulation.

Arguments:

  • polarization - te or tm.

  • taper_length - taper length from input.

  • taper_angle - grating flare angle.

  • wavelength - grating transmission central wavelength (um).

  • fiber_angle - fibre angle in degrees determines ellipticity.

  • grating_line_width - in um.

  • neff - tooth effective index.

  • nclad - cladding effective index.

  • n_periods - number of periods.

  • big_last_tooth - adds a big_last_tooth.

  • layer_slab - layer that protects the slab under the grating.

  • slab_xmin - where 0 is at the start of the taper.

  • slab_offset - in um.

  • spiked - grating teeth have sharp spikes to avoid non-manhattan drc errors.

  • cross_section - specification (CrossSection, string or dict).

  • kwargs - cross_section settings.

    .. code::

    fiber

    / / / / / / / /

    |-||-||-|__ layer layer_slab | o1 ______________|

gdsfactory.components.greek_cross

Greek cross test structure.

greek_cross

@gf.cell
def greek_cross(length: float = 30,
                layers: LayerSpecs = (
                    "WG",
                    "N",
                ),
                widths: Floats = (2.0, 3.0),
                offsets: Floats | None = None,
                via_stack: ComponentSpec = via_stack_npp_m1) -> gf.Component

Simple greek cross with via stacks at the endpoints.

Process control monitor for dopant sheet resistivity and linewidth variation.

Arguments:

  • length - length of cross arms.

  • layers - list of layers.

  • widths - list of widths (same order as layers).

  • offsets - how much to extend each layer beyond the cross length negative shorter, positive longer.

  • via - via component to attach to the cross.

    .. code::

    via_stack <-------> _________ length ________ | |<-------------------->| 2x | | | ↓ |<-->| | |======== width =======| |_______|<--> | ↑ |<-->|________ offset offset

References:

  • Walton, Anthony J.. “MICROELECTRONIC TEST STRUCTURES.” (1999).
  • W. Versnel, Analysis of the Greek cross, a Van der Pauw structure with finite contacts, Solid-State Electronics, Volume 22, Issue 11, 1979, Pages 911-914, ISSN 0038-1101, Versnel (1979).
  • S. Enderling et al., “Sheet resistance measurement of non-standard cleanroom materials using suspended Greek cross test structures,” IEEE Transactions on Semiconductor Manufacturing, vol. 19, no. 1, pp. 2-9, Feb. 2006,
  • doi - 10.1109/TSM.2005.863248.

greek_cross_with_pads

@gf.cell
def greek_cross_with_pads(pad: ComponentSpec = pad,
                          pad_spacing: float = 150.0,
                          greek_cross_component: ComponentSpec = greek_cross,
                          pad_via: ComponentSpec = via_stack_m1_m3,
                          xs_metal: CrossSectionSpec = metal1) -> gf.Component

Greek cross under 4 DC pads, ready to test.

Arguments:

  • pad - component to use for probe pads
  • pad_spacing - spacing between pads
  • greek_cross_component - component to use for greek cross
  • pad_via - via to add to the pad
  • xs_metal - cross-section for cross via to pad via wiring

greek_cross_offset_pads

@gf.cell
def greek_cross_offset_pads(cross_struct_length: float = 30.0,
                            cross_struct_width: float = 1.0,
                            cross_struct_layers: LayerSpecs = ("WG", ),
                            cross_implant_length: float = 30.0,
                            cross_implant_width: float = 2.0,
                            cross_implant_layers: LayerSpecs = ("N", ),
                            contact_layers: LayerSpecs = ("WG", "NPP"),
                            contact_offset: float = 10,
                            contact_buffer: float = 10,
                            pad_width: float = 50) -> gf.Component

Greek cross, with silicon islands on each side of the cross to place larger contacting regions.

Arguments:

  • cross_struct_length - length of structural part of cross e.g. silicon core.

  • cross_struct_width - width of structural part of cross e.g. silicon core.

  • cross_struct_layers - layers to be considered “structural”.

  • cross_implant_length - length of implantation part of cross.

  • cross_implant_width - width of implantation part of cross.

  • cross_implant_layers - layers to be considered “implants”.

  • contact_layers - layers to include under and around the pad.

  • contact_offset - fudge factor to move pad relative to cross.

  • contact_buffer - amount of dopants around pad in contact.

  • pad_width - pad size.

    .. code::

    pad_width <-------> _________ cross_implant_length, cross_struct_length | |<-------> 4x | | ↓ | |======== cross_implant_width, cross_struct_width |_______| ↑ <--------------> contact_offset (fudge)

References:

  • Walton, Anthony J.. “MICROELECTRONIC TEST STRUCTURES.” (1999).
  • W. Versnel, Analysis of the Greek cross, a Van der Pauw structure with finite contacts, Solid-State Electronics, Volume 22, Issue 11, 1979, Pages 911-914, ISSN 0038-1101, Versnel (1979).
  • S. Enderling et al., “Sheet resistance measurement of non-standard cleanroom materials using suspended Greek cross test structures,” IEEE Transactions on Semiconductor Manufacturing, vol. 19, no. 1, pp. 2-9, Feb. 2006,
  • doi - 10.1109/TSM.2005.863248.

gdsfactory.components.splitter_tree

splitter_tree

@gf.cell
def splitter_tree(coupler: ComponentSpec = mmi1x2,
                  noutputs: int = 4,
                  spacing: Float2 = (90.0, 50.0),
                  bend_s: ComponentSpec | None = bend_s_function,
                  bend_s_xsize: float | None = None,
                  cross_section: CrossSectionSpec = "strip") -> gf.Component

Tree of power splitters.

Arguments:

  • coupler - coupler factory.

  • noutputs - number of outputs.

  • spacing - x, y spacing between couplers.

  • bend_s - Sbend function for termination.

  • bend_s_xsize - xsize for the sbend.

  • cross_section - cross_section.

    .. code::

    | | | | | |_ dy

    dx

gdsfactory.components.regular_polygon

regular_polygon

@cell
def regular_polygon(sides: int = 6,
                    side_length: float = 10,
                    layer: LayerSpec = "WG",
                    port_type: str | None = "placement") -> Component

Returns a regular N-sided polygon, with ports on each edge.

Arguments:

  • sides - number of sides for the polygon.
  • side_length - of the edges.
  • layer - Specific layer to put polygon geometry on.
  • port_type - optical, electrical.

gdsfactory.components.component_lattice_generic

In a multiple-topology Clements Scheme we can implement any universal photonic function.

component_lattice_generic

@cell
def component_lattice_generic(network: list[list] | None = None) -> Component

The shape of the network matrix determines the physical interconnection. Note that there should be at least S+1=N modes based on this formalism of interconnection, and the position of the component implements a connectivity in between the modes, and assumes a 2x2 network encoding. One nice functionality by this component is that it can generate a component lattice for generic variable components with different x and y pitches. Initially this will maximise the surface area required but different placement algorithms can compact the size.

Arguments:

  • network - A list of lists of components that are to be placed in the lattice.

Returns:

  • Component - A component lattice that implements the physical network.

    The placement matrix is in this form: .. math::

    M = X & 0 & X 0 & P & 0 X & 0 & X

    :include-source: import gdsfactory as gf from gdsfactory.components.mzi import mzi2x2_2x2

    example_component_lattice = [ [mzi2x2_2x2(), 0, mzi2x2_2x2()], [0, mzi2x2_2x2(delta_length=30.0), 0], [mzi2x2_2x2(), 0, mzi2x2_2x2()], ] c = gf.components.component_lattice_generic(example_component_lattice)

    Another example that demonstrates the generic-nature of this component lattice algorithm can be with an mixed set of actively driven and passiver interferometers. The placement matrix is in this form:

    .. math::

    M = Y & 0 & A 0 & B & 0 C & 0 & Y

    :include-source: import gdsfactory as gf from gdsfactory.components import mzi2x2_2x2_phase_shifter, mzi2x2_2x2

    example_mixed_component_lattice = [ [mzi2x2_2x2_phase_shifter(), 0, mzi2x2_2x2(delta_length=20.0)], [0, mzi2x2_2x2(delta_length=30.0), 0], [mzi2x2_2x2(delta_length=15.0), 0, mzi2x2_2x2_phase_shifter()], ] c = gf.components.component_lattice_generic( network=example_mixed_component_lattice )

    TODO implement balanced waveguide paths function per stage

    TODO automatic electrical fanout?

    TODO multiple placement optimization algorithms.

gdsfactory.components.bbox

bbox

@gf.cell_without_validator
def bbox(bbox: tuple[Coordinate, Coordinate] = ((-1.0, -1.0), (3.0, 4.0)),
         layer: tuple[int, int] = (1, 0),
         top: float = 0,
         bottom: float = 0,
         left: float = 0,
         right: float = 0) -> gf.Component

Returns bounding box rectangle from coordinates.

Arguments:

  • bbox - Coordinates of the box [(x1, y1), (x2, y2)].
  • layer - for bbox.
  • top - north offset.
  • bottom - south offset.
  • left - west offset.
  • right - east offset.

gdsfactory.components.wafer

wafer

@gf.cell
def wafer(reticle: ComponentFactory = die,
          cols: tuple[int, ...] = _cols_200mm_wafer,
          xspacing: float | None = None,
          yspacing: float | None = None,
          die_name_col_row: bool = False) -> Component

Returns complete wafer. Useful for mask aligner steps.

Arguments:

  • reticle - spec for each wafer reticle.
  • cols - how many columns per row.
  • xspacing - optional spacing, defaults to reticle.xsize.
  • yspacing - optional spacing, defaults to reticle.ysize.
  • die_name_col_row - if True, die name is row_col, otherwise is a number

gdsfactory.components.hline

hline

@gf.cell
def hline(length: float = 10.0,
          width: float = 0.5,
          layer: LayerSpec = "WG",
          port_type: str = "optical") -> Component

Horizontal line straight, with ports on east and west sides.

gdsfactory.components.via_stack

via_stack

@gf.cell
def via_stack(size=(11.0, 11.0),
              layers: LayerSpecs = ("M1", "M2", "M3"),
              layer_offsets: Floats | None = None,
              vias: tuple[ComponentSpec | None, ...] | None = (via1, via2,
                                                               None),
              layer_port: LayerSpec | None = None,
              correct_size: bool = True) -> Component

Rectangular via array stack.

You can use it to connect different metal layers or metals to silicon. You can use the naming convention via_stack_layerSource_layerDestination contains 4 ports (e1, e2, e3, e4)

also know as Via array http://www.vlsi-expert.com/2017/12/vias.html

spacing = via.info[‘spacing’] enclosure = via.info[‘enclosure’]

Arguments:

  • size - of the layers.
  • layers - layers on which to draw rectangles.
  • layer_offsets - Optional offsets for each layer with respect to size. positive grows, negative shrinks the size.
  • vias - vias to use to fill the rectangles.
  • layer_port - if None assumes port is on the last layer.
  • correct_size - if True, if the specified dimensions are too small it increases them to the minimum possible to fit a via.

via_stack_circular

@gf.cell
def via_stack_circular(radius: float = 10.0,
                       angular_extent: float = 45,
                       center_angle: float = 0,
                       width: float = 5.0,
                       layers: LayerSpecs = ("M1", "M2", "M3"),
                       vias: tuple[ComponentSpec | None, ...] = (via1, via2),
                       layer_port: LayerSpec | None = None) -> Component

Circular via array stack.

FIXME! does not work.

Constructs a circular via array stack. It does so by stacking rectangular via stacks offset by a small amount along the specified circumference.

Arguments:

  • radius - of the via stack (center).
  • angular_extent - of the via stack.
  • center_angle - of the via stack.
  • width - of the via stack.
  • layers - layers to draw
  • vias - vias to use to fill the rectangles.
  • layer_port - if None assumes port is on the last layer.

via_stack_from_rules

@gf.cell
def via_stack_from_rules(size: Float2 = (1.2, 1.2),
                         layers: LayerSpecs = ("M1", "M2", "M3"),
                         layer_offsets: tuple[float, ...] | None = None,
                         vias: tuple[ComponentSpec | None, ...]
                         | None = (via1, via2),
                         via_min_size: tuple[Float2,
                                             ...] = ((0.2, 0.2), (0.2, 0.2)),
                         via_min_gap: tuple[Float2,
                                            ...] = ((0.1, 0.1), (0.1, 0.1)),
                         via_min_enclosure: Float2 = (0.15, 0.25),
                         layer_port: LayerSpec | None = None) -> Component

Rectangular via array stack, with optimized dimension for vias.

Uses inclusion, minimum width, and minimum spacing rules to place the maximum number of individual vias, each with maximum via area.

Arguments:

  • size - of the layers, len(size).
  • layers - layers on which to draw rectangles.
  • layer_offsets - Optional offsets for each layer with respect to size. positive grows, negative shrinks the size.
  • vias - list of base via components to modify.
  • via_min_size - via minimum x, y dimensions.
  • via_min_gap - via minimum x, y distances.
  • via_min_enclosure - via minimum inclusion into connecting layers.
  • layer_port - if None assumes port is on the last layer.

optimized_via

def optimized_via(base_via: ComponentSpec = "VIAC",
                  size: tuple[float, float] = (11.0, 11.0),
                  min_via_size: tuple[float, float] = (0.3, 0.3),
                  min_via_gap: tuple[float, float] = (0.1, 0.1),
                  min_via_enclosure: float = 0.2) -> Component

Given a target total inclusion size, returns an optimized dimension for the via.

Uses inclusion, minimum width, and minimum spacing rules to place the maximum number of individual vias, with maximum via area.

Arguments:

  • base_via - to modify.
  • size - of the target enclosing medium.
  • min_via_size - minimum size the vias can take.
  • min_via_gap - minimum distance between vias.
  • min_via_enclosure - minimum distance between edge of enclosing medium and nearest via edge.

gdsfactory.components.resistance_meander

resistance_meander

@cell
def resistance_meander(pad_size: tuple[float, float] = (50.0, 50.0),
                       num_squares: int = 1000,
                       width: float = 1.0,
                       res_layer: LayerSpec = "MTOP",
                       pad_layer: LayerSpec = "MTOP",
                       gnd_layer: LayerSpec = "MTOP") -> Component

Return meander to test resistance.

based on phidl.geometry

Arguments:

  • pad_size - Size of the two matched impedance pads (microns).
  • num_squares - Number of squares comprising the resonator wire.
  • width - The width of the squares (microns).
  • res_layer - resistance layer.
  • pad_layer - pad layer.
  • gnd_layer - ground layer.

gdsfactory.components.taper_cross_section

taper_cross_section

@cell
def taper_cross_section(cross_section1: CrossSectionSpec = strip_rib_tip,
                        cross_section2: CrossSectionSpec = rib_conformal,
                        length: float = 10,
                        npoints: int = 100,
                        linear: bool = False,
                        width_type: str = "sine",
                        **kwargs) -> Component

Returns taper transition between cross_section1 and cross_section2.

Arguments:

  • cross_section1 - start cross_section factory.

  • cross_section2 - end cross_section factory.

  • 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.

    .. code::


    / /_______________ / cross_section1 | cross_section2 _________________
    _____________________

gdsfactory.components.mmi2x2_with_sbend

mmi2x2_with_sbend

@gf.cell
def mmi2x2_with_sbend(with_sbend: bool = True,
                      s_bend: ComponentSpec = bend_s,
                      cross_section: CrossSectionSpec = "strip") -> Component

Returns mmi2x2 for Cband.

C_band 2x2MMI in 220nm thick silicon https://opg.optica.org/oe/fulltext.cfm?uri=oe-25-23-28957&id=376719

Arguments:

  • with_sbend - add sbend.
  • s_bend - S-bend spec.
  • cross_section - spec.

gdsfactory.components.mmi2x2

mmi2x2

@gf.cell
def mmi2x2(width: float | None = None,
           width_taper: float = 1.0,
           length_taper: float = 10.0,
           length_mmi: float = 5.5,
           width_mmi: float = 2.5,
           gap_mmi: float = 0.25,
           taper: ComponentFactory = taper_function,
           straight: ComponentFactory = straight_function,
           with_bbox: bool = True,
           cross_section: CrossSectionSpec = "strip") -> Component

Mmi 2x2.

Arguments:

  • width - input and output straight width.

  • width_taper - interface between input straights and mmi region.

  • length_taper - into the mmi region.

  • length_mmi - in x direction.

  • width_mmi - in y direction.

  • gap_mmi - (width_taper + gap between tapered wg)/2.

  • taper - taper function.

  • straight - straight function.

  • with_bbox - box in bbox_layers and bbox_offsets to avoid DRC sharp edges.

  • cross_section - spec.

    .. code::

    length_mmi <------>


    | | / _ o2 __ __ o3 \ / _ _ _ | | _ _ _ _| gap_mmi / _ o1 __ __ o4 \ / |_______|

    <-> length_taper

gdsfactory.components.spiral_double

spiral_double

@gf.cell
def spiral_double(
        min_bend_radius: float = 10.0,
        separation: float = 2.0,
        number_of_loops: float = 3,
        npoints: int = 1000,
        cross_section: gf.typings.CrossSectionSpec = "strip",
        bend: gf.typings.ComponentSpec = bend_circular) -> gf.Component

Returns a spiral double (spiral in, and then out).

Arguments:

  • min_bend_radius - inner radius of the spiral.
  • separation - separation between the loops.
  • number_of_loops - number of loops per spiral.
  • npoints - points for the spiral.
  • cross_section - cross-section to extrude the structure with.
  • bend - factory for the bends in the middle of the double spiral.

gdsfactory.components.fiber_array

fiber_array

@gf.cell
def fiber_array(n: int = 8,
                pitch: float = 127.0,
                core_diameter: float = 10,
                cladding_diameter: float = 125,
                layer_core: LayerSpec = "WG",
                layer_cladding: LayerSpec = "WGCLAD") -> Component

Returns a fiber array.

Arguments:

  • n - number of fibers.

  • pitch - spacing.

  • core_diameter - 10um.

  • cladding_diameter - in um.

  • layer_core - layer spec for fiber core.

  • layer_cladding - layer spec for fiber cladding.

    .. code::

    pitch <->


    | | lid | o o o o | | | base |_________| length

gdsfactory.components.via_corner

via_corner

@gf.cell
def via_corner(cross_section: MultiCrossSectionAngleSpec = (
    (metal2, (0, 180)),
    (metal3, (90, 270)),
),
               vias: tuple[ComponentSpec] = (via1, ),
               layers_labels: tuple[str, ...] = ("m2", "m3"),
               **kwargs) -> gf.Component

Returns Corner via.

Use in place of wire_corner to route between two layers.

Arguments:

  • cross_section - list of cross_section, orientation pairs.
  • vias - vias to use to fill the rectangles.
  • layers_labels - Labels to use for each layer.
  • kwargs - cross_section settings.

gdsfactory.components.pad

pad

@cell
def pad(size: str | Float2 = (100.0, 100.0),
        layer: LayerSpec = "MTOP",
        bbox_layers: tuple[LayerSpec, ...] | None = None,
        bbox_offsets: tuple[float, ...] | None = None,
        port_inclusion: float = 0,
        port_orientation: float | None = None) -> Component

Returns rectangular pad with ports.

Arguments:

  • size - x, y size.
  • layer - pad layer.
  • bbox_layers - list of layers.
  • bbox_offsets - Optional offsets for each layer with respect to size. positive grows, negative shrinks the size.
  • port_inclusion - from edge.
  • port_orientation - in degrees.

pad_array

@cell
def pad_array(pad: ComponentSpec = "pad",
              spacing: tuple[float, float] = (150.0, 150.0),
              columns: int = 6,
              rows: int = 1,
              orientation: float | None = 270) -> Component

Returns 2D array of pads.

Arguments:

  • pad - pad element.
  • spacing - x, y pitch.
  • columns - number of columns.
  • rows - number of rows.
  • orientation - port orientation in deg. None for low speed DC ports.

gdsfactory.components.ge_detector_straight_si_contacts

Straight Ge photodetector.

ge_detector_straight_si_contacts

@gf.cell
def ge_detector_straight_si_contacts(
        length: float = 80.0,
        cross_section: CrossSectionSpec = pn_ge_detector_si_contacts,
        via_stack: ComponentSpec
    | tuple[ComponentSpec, ComponentSpec] = via_stack_slab_m3,
        via_stack_width: float = 10.0,
        via_stack_spacing: float = 5.0,
        via_stack_offset: float = 0.0,
        taper: ComponentSpec | None = default_taper,
        **kwargs) -> Component

Returns a straight Ge on Si detector with silicon contacts.

There are no contacts on the Ge. These detectors could have lower dark current and sensitivity compared to those with contacts in the Ge. See Chen et al., “High-Responsivity Low-Voltage 28-Gb/s Ge p-i-n Photodetector With Silicon Contacts”, Journal of Lightwave Technology 33(4), 2015.

Chen et al. (2015)

Arguments:

  • length - total length of the waveguide including the tapers.
  • cross_section - for the waveguide.
  • via_stack - for the via_stacks. First element
  • via_stack_width - width of the via_stack.
  • via_stack_spacing - spacing between via_stacks.
  • via_stack_offset - with respect to the detector
  • taper - optional taper to transition from the input waveguide into the absorption region.
  • kwargs - cross_section settings.

gdsfactory.components.mzi

mzi

@cell
def mzi(delta_length: float = 10.0,
        length_y: float = 2.0,
        length_x: float | None = 0.1,
        bend: ComponentSpec = bend_euler,
        straight: ComponentSpec = straight_function,
        straight_y: ComponentSpec | None = None,
        straight_x_top: ComponentSpec | None = None,
        straight_x_bot: ComponentSpec | None = None,
        splitter: ComponentSpec = "mmi1x2",
        combiner: ComponentSpec | None = None,
        with_splitter: bool = True,
        port_e1_splitter: str = "o2",
        port_e0_splitter: str = "o3",
        port_e1_combiner: str = "o2",
        port_e0_combiner: str = "o3",
        nbends: int = 2,
        cross_section: CrossSectionSpec = "strip",
        cross_section_x_top: CrossSectionSpec | None = None,
        cross_section_x_bot: CrossSectionSpec | None = None,
        mirror_bot: bool = False,
        add_optical_ports_arms: bool = False) -> Component

Mzi.

Arguments:

  • delta_length - bottom arm vertical extra length.

  • length_y - vertical length for both and top arms.

  • length_x - horizontal length. None uses to the straight_x_bot/top defaults.

  • bend - 90 degrees bend library.

  • straight - straight function.

  • straight_y - straight for length_y and delta_length.

  • straight_x_top - top straight for length_x.

  • straight_x_bot - bottom straight for length_x.

  • splitter - splitter function.

  • combiner - combiner function.

  • with_splitter - if False removes splitter.

  • port_e1_splitter - east top splitter port.

  • port_e0_splitter - east bot splitter port.

  • port_e1_combiner - east top combiner port.

  • port_e0_combiner - east bot combiner port.

  • nbends - from straight top/bot to combiner (at least 2).

  • cross_section - for routing (sxtop/sxbot to combiner).

  • cross_section_x_top - optional top cross_section (defaults to cross_section).

  • cross_section_x_bot - optional bottom cross_section (defaults to cross_section).

  • mirror_bot - if true, mirrors the bottom arm.

  • add_optical_ports_arms - add all other optical ports in the arms with top_ and bot_ prefix.

    .. code::

    b2______b3 | sxtop | straight_y | | | b1 b4 splitter==| |==combiner b5 b8 | | straight_y | | | delta_length/2 | | | b6__sxbot__b7 Lx

gdsfactory.components.optimal_90deg

optimal_90deg

@cell
def optimal_90deg(
    width: float = 100,
    num_pts: int = 15,
    length_adjust: float = 1,
    layer: LayerSpec = (1, 0)) -> Component

Returns optimally-rounded 90 degree bend that is sharp on the outer corner.

Arguments:

  • width - Width of the ports on either side of the bend.
  • num_pts - The number of points comprising the curved section of the bend.
  • length_adjust - Adjusts the length of the non-curved portion of the bend.
  • layer - Specific layer(s) to put polygon geometry on.

Notes:

Optimal structure from Clem & Berggren (2011) Clem, J., & Berggren, K. (2011). Geometry-dependent critical currents in superconducting nanocircuits. Physical Review B, 84(17), 1–27.

gdsfactory.components.switch_tree

Returns a switch_tree.

      __
    _|  |_

__ | | |_ _ | || || | | |_ |dy || | __ | || | | | |_ - ||

|<-dx->|

gdsfactory.components.bend_euler

bend_euler

@gf.cell
def bend_euler(angle: float = 90.0,
               p: float = 0.5,
               with_arc_floorplan: bool = True,
               npoints: int | None = None,
               direction: str = "ccw",
               with_bbox: bool = True,
               cross_section: CrossSectionSpec = "strip",
               **kwargs) -> Component

Euler bend with changing bend radius.

By default, radius corresponds to the minimum radius of curvature of the bend. However, if with_arc_floorplan is True, radius corresponds to the effective radius of curvature (making the curve a drop-in replacement for an arc). If p < 1.0, will create a “partial euler” curve as described in Vogelbacher et. al. Vogelbacher et al. (2019)

default p = 0.5 based on this paper https://www.osapublishing.org/oe/fulltext.cfm?uri=oe-25-8-9150&id=362937

Arguments:

  • angle - total angle of the curve.

  • p - Proportion of the curve that is an Euler curve.

  • with_arc_floorplan - If False: radius is the minimum radius of curvature If True: The curve scales such that the endpoints match a bend_circular with parameters radius and angle.

  • npoints - Number of points used per 360 degrees.

  • direction - cw (clock-wise) or ccw (counter clock-wise).

  • with_bbox - add bbox_layers and bbox_offsets to avoid DRC sharp edges.

  • cross_section - specification (CrossSection, string, CrossSectionFactory dict).

  • kwargs - cross_section settings.

    .. code::

    o2 | / / / o1_____/

bend_euler_s

@gf.cell
def bend_euler_s(**kwargs) -> Component

Sbend made of 2 euler bends.

Arguments:

  • angle - total angle of the curve.

  • p - Proportion of the curve that is an Euler curve.

  • with_arc_floorplan - If False: radius is the minimum radius of curvature If True: The curve scales such that the endpoints match a bend_circular with parameters radius and angle.

  • npoints - Number of points used per 360 degrees.

  • direction - cw (clock-wise) or ccw (counter clock-wise).

  • with_bbox - add bbox_layers and bbox_offsets to avoid DRC sharp edges.

  • cross_section - specification (CrossSection, string, CrossSectionFactory dict).

  • kwargs - cross_section settings.

    .. code::

    _____ o2 / / / / | / / / o1_____/

bend_straight_bend

@gf.cell
def bend_straight_bend(straight_length: float = 10.0,
                       angle: float = 90,
                       p: float = 0.5,
                       with_arc_floorplan: bool = True,
                       npoints: int = 720,
                       direction: str = "ccw",
                       cross_section: CrossSectionSpec = strip,
                       **kwargs) -> Component

Sbend made of 2 euler bends and straight section in between.

Arguments:

  • straight_length - in um.
  • angle - total angle of the curve.
  • p - Proportion of the curve that is an Euler curve.
  • with_arc_floorplan - If False: radius is the minimum radius of curvature If True: The curve scales such that the endpoints match a bend_circular with parameters radius and angle.
  • npoints - Number of points used per 360 degrees.
  • direction - cw (clock-wise) or ccw (counter clock-wise).
  • cross_section - specification (CrossSection, string, CrossSectionFactory dict).
  • kwargs - cross_section settings.

gdsfactory.components.polarization_splitter_rotator

polarization_splitter_rotator

@gf.cell
def polarization_splitter_rotator(width_taper_in: Float3 = (0.54, 0.69, 0.83),
                                  length_taper_in: Float2 | Float3 = (4.0,
                                                                      44.0),
                                  width_coupler: Float2 = (0.9, 0.405),
                                  length_coupler: float = 7.0,
                                  gap: float = 0.15,
                                  width_out: float = 0.54,
                                  length_out: float = 14.33,
                                  dy: float = 5.0,
                                  cross_section: CrossSectionSpec = "strip",
                                  **kwargs) -> Component

Returns polarization splitter rotator

“Novel concept for ultracompact polarization splitter-rotator based on silicon nanowires.” By D. Dai, and J. E. Bowers (Optics express vol 19, no. 11 pp. 10940-10949 (2011)).

Arguments:

  • width_taper_in - Three west widths of the input tapers in um.
  • length_taper_in - Two or three length of the bend regions in um.
  • width_coupler - Top and bottom widths of the coupling region in um.
  • length_coupler - Length of the coupling region in um.
  • gap - Distance between the coupler in um.
  • width_out - Width of the splitter region in um.
  • length_out - Length of the splitter region in um.
  • dy - Port-to-port distance between the splitter region in um.
  • cross_section - cross-section spec.

Arguments:

cross_section kwargs.

Notes:

The length of third input taper is automatically determined if only two lengths are in arguments.

gdsfactory.components.die_bbox_frame

die_bbox_frame

@gf.cell_without_validator
def die_bbox_frame(bbox: tuple[Coordinate,
                               Coordinate] = ((-1.0, -1.0), (3.0, 4.0)),
                   street_width: float = 100.0,
                   street_length: float = 1000.0,
                   die_name: str | None = None,
                   text_size: float = 100.0,
                   text_anchor: Anchor = "sw",
                   layer: LayerSpec = "M3",
                   padding: float = 10.0) -> gf.Component

Return boundary box frame.

The chip/die boundary can include a label with the name of the die.

Arguments:

  • bbox - bounding box to frame.
  • street_width - Width of the boundary box.
  • street_length - length of the boundary box.
  • die_name - Label text.
  • text_size - Label text size.
  • text_anchor - {‘nw’, ‘nc’, ‘ne’, ‘sw’, ‘sc’, ‘se’} text location.
  • layer - Specific layer(s) to put polygon geometry on.
  • padding - adds padding.

gdsfactory.components.delay_snake

delay_snake

@gf.cell
def delay_snake(length: float = 1600.0,
                L0: float = 5.0,
                n: int = 2,
                bend: ComponentSpec = "bend_euler",
                cross_section: CrossSectionSpec = "strip",
                **kwargs) -> Component

Returns Snake with a starting straight and 90 bends.

Input faces west output faces east.

Arguments:

  • length - delay length in um.

  • L0 - initial xoffset in um.

  • n - number of loops.

  • bend - bend spec.

  • cross_section - cross_section spec.

  • kwargs - cross_section settings.

    .. code::

    | L0 | L2 |

    ->-------------|

    pi * radius
    ------------------->

    | DL |

gdsfactory.components.coh_tx_single_pol

coh_tx_single_pol

@cell
def coh_tx_single_pol(balanced_phase_shifters: bool = False,
                      mzm_y_spacing: float = 50.0,
                      phase_shifter: ComponentSpec = "straight_pin",
                      phase_shifter_length: float = 100.0,
                      mzm_ps_spacing: float = 40.0,
                      splitter: ComponentSpec = "mmi1x2",
                      combiner: ComponentSpec | None = None,
                      mzm: ComponentSpec = default_mzm,
                      mzm_length: float = 200.0,
                      with_pads: bool = False,
                      xspacing: float = 40.0,
                      input_coupler: ComponentSpec | None = None,
                      output_coupler: ComponentSpec | None = None,
                      pad_array: ComponentSpec = "pad_array",
                      cross_section: CrossSectionSpec = "strip",
                      **kwargs) -> Component

MZM-based single polarization coherent transmitter.

Arguments:

  • balanced_phase_shifters - True adds phase sifters after the MZM at both the I and Q arms. False, only adds Q arm has a phase shifter.

  • mzm_y_spacing - vertical spacing between the bottom of the I MZM and the top of the Q MZM.

  • phase_shifter - phase_shifter spec.

  • phase_shifter_length - length of the phase shifter.

  • mzm_ps_spacing - spacing between the end of the mzm and the phase shifter.

  • splitter - splitter spec.

  • combiner - combiner spec.

  • mzm - Mach-Zehnder modulator spec.

  • mzm_length - length of the MZMs.

  • xspacing - horizontal spacing between the splitter and combiner and the mzm.

  • input_coupler - Optional coupler to add before the splitter.

  • output_coupler - Optional coupler to add after the combiner.

  • pad_array - array of pads spec.

  • cross_section - for routing (splitter to mzms and mzms to combiners).

  • kwargs - cross_section settings.

    .. code::

    ___ mzm_i __ ps_i__ | | | | | | (in_coupler)---splitter==| |==combiner---(out_coupler) | | | | |___ mzm_q __ ps_q_|

gdsfactory.components.grating_coupler_loss_fiber_single

grating_coupler_loss_fiber_single

@cell
def grating_coupler_loss_fiber_single(
        grating_coupler: ComponentSpec = grating_coupler_te,
        cross_section: CrossSectionSpec = "strip",
        **kwargs) -> Component

Returns grating coupler test structure.

for testing with single fiber input/output

Arguments:

  • grating_coupler - function.
  • cross_section - spec.

Arguments:

  • layer_label - for test and measurement label.
  • min_input_to_output_spacing - spacing from input to output fiber.
  • max_y0_optical - None.
  • get_input_labels_function - function to get input labels for grating couplers.
  • optical_routing_type - None: autoselection, 0: no extension.
  • get_input_label_text_function - for the grating couplers input label.
  • get_input_label_text_loopback_function - for the loopbacks input label.

gdsfactory.components.litho_steps

litho_steps

@gf.cell
def litho_steps(line_widths: tuple[float, ...] = (1.0, 2.0, 4.0, 8.0, 16.0),
                line_spacing: float = 10.0,
                height: float = 100.0,
                layer: LayerSpec = "WG") -> Component

Positive + negative tone linewidth test.

used for lithography resolution test patterning based on phidl

Arguments:

  • line_widths - in um.
  • line_spacing - in um.
  • height - in um.
  • layer - Specific layer to put the ruler geometry on.

gdsfactory.components.rectangle

rectangle

@cell
def rectangle(
    size=(4.0, 2.0),
    layer: LayerSpec = "WG",
    centered: bool = False,
    port_type: str | None = "electrical",
    port_orientations: Ints | None = (180, 90, 0, -90)
) -> Component

Returns a rectangle.

Arguments:

  • size - (tuple) Width and height of rectangle.
  • layer - Specific layer to put polygon geometry on.
  • centered - True sets center to (0, 0), False sets south-west to (0, 0).
  • port_type - optical, electrical.
  • port_orientations - list of port_orientations to add.

rectangles

@cell
def rectangles(size=(4.0, 2.0),
               offsets=(0, 1),
               layers=("WG", "SLAB150"),
               centered: bool = True,
               **kwargs) -> Component

Returns overimposed rectangles.

Arguments:

  • size - (tuple) Width and height of rectangle.
  • layers - Specific layer to put polygon geometry on.
  • offsets - list of offsets.
  • centered - True sets center to (0, 0), False sets south-west of first rectangle to (0, 0).

Arguments:

  • port_type - optical, electrical.

  • port_orientations - list of port_orientations to add.

    .. code::

    ┌──────────────┐ │ │ │ ┌──────┐ │ │ │ │ │ │ │ ├───► │ │ │offset │ └──────┘ │ │ │ └──────────────┘

gdsfactory.components.straight_heater_doped_rib

straight_heater_doped_rib

@gf.cell
def straight_heater_doped_rib(
        length: float = 320.0,
        nsections: int = 3,
        cross_section: CrossSectionSpec = strip_rib_tip,
        cross_section_heater: CrossSectionSpec = rib_heater_doped,
        via_stack: ComponentSpec | None = via_stack_slab_npp_m3,
        via_stack_metal: ComponentSpec | None = via_stack_metal_function,
        via_stack_metal_size: tuple[float, float] = (10.0, 10.0),
        via_stack_size: tuple[float, float] = (10.0, 10.0),
        taper: ComponentSpec | None = taper_cross_section,
        with_taper1: bool = True,
        with_taper2: bool = True,
        heater_width: float = 2.0,
        heater_gap: float = 0.8,
        via_stack_gap: float = 0.0,
        width: float = 0.5,
        xoffset_tip1: float = 0.2,
        xoffset_tip2: float = 0.4,
        **kwargs) -> Component

Returns a doped thermal phase shifter.

dimensions from Jacques et al. (2019)

Arguments:

  • length - of the waveguide in um.

  • nsections - between via_stacks.

  • cross_section - for the input/output ports.

  • cross_section_heater - for the heater.

  • via_stack - optional function to connect the heater strip.

  • via_stack_metal - function to connect the metal area.

  • via_stack_metal_size - x, y size in um.

  • via_stack_size - x, y size in um.

  • taper - optional taper spec.

  • heater_width - in um.

  • heater_gap - in um.

  • via_stack_gap - from edge of via_stack to waveguide.

  • width - waveguide width on the ridge.

  • xoffset_tip1 - distance in um from input taper to via_stack.

  • xoffset_tip2 - distance in um from output taper to via_stack.

  • kwargs - cross_section settings.

    .. code::

    length |<--------------------------------------------->| | length_section | | <---------------------------> | | length_via_stack | | <-------> taper| | __________ _________ | | | | | | | | | via_stack|| | | | | size | heater width | | | | /||||\ | | / | heater_gap | \ | |/ |________________| \ | \ |width| / \ | | / |heater_gap |/ | | | | | |heater_width| | | | | | || ||

    taper cross_section_heater

    |<------width------>| ____________________ heater_gap slab_gap top_via_stack | |<---------->| bot_via_stack <--> ___ | || | | | undoped Si | | | | |layer_heater| intrinsic region |layer_heater | | |||______________||| <------------> heater_width <------------------------------------------------------------------------------> slab_width

gdsfactory.components.mmi1x2

mmi1x2

@gf.cell
def mmi1x2(width: float | None = None,
           width_taper: float = 1.0,
           length_taper: float = 10.0,
           length_mmi: float = 5.5,
           width_mmi: float = 2.5,
           gap_mmi: float = 0.25,
           taper: ComponentFactory = taper_function,
           straight: ComponentFactory = straight_function,
           with_bbox: bool = True,
           cross_section: CrossSectionSpec = "strip") -> Component

1x2 MultiMode Interferometer (MMI).

Arguments:

  • width - input and output straight width. Defaults to cross_section width.

  • width_taper - interface between input straights and mmi region.

  • length_taper - into the mmi region.

  • length_mmi - in x direction.

  • width_mmi - in y direction.

  • gap_mmi - gap between tapered wg.

  • taper - taper function.

  • straight - straight function.

  • with_bbox - add rectangular box in cross_section bbox_layers and bbox_offsets to avoid DRC sharp edges.

  • cross_section - specification (CrossSection, string or dict).

    .. code::

    length_mmi <------>


    | | | __ | __ o2 / / _ _ _ o1 __ | _ _ _ | gap_mmi \ _ | __ o3 | / |_______|

    <-> length_taper

gdsfactory.components.rectangular_ring

rectangular_ring

@gf.cell
def rectangular_ring(enclosed_size=(4.0, 2.0),
                     width: float = 0.5,
                     layer: LayerSpec = "WG",
                     centered: bool = False) -> Component

Returns a Rectangular Ring

Arguments:

  • enclosed_size - (width, height) of the enclosed area.
  • width - width of the ring.
  • layer - Specific layer to put polygon geometry on.
  • centered - True sets center to (0,0), False sets south-west to (0,0).

gdsfactory.components.pad_gsg

High speed GSG pads.

pad_gsg_short

@gf.cell
def pad_gsg_short(via_stack: ComponentSpec = rectangle_m3,
                  size: Float2 = (22, 7),
                  layer_metal: LayerSpec = "M3",
                  metal_spacing: float = 5.0,
                  short: bool = True,
                  pad: ComponentSpec = pad_function,
                  pad_spacing: float = 150) -> gf.Component

Returns high speed GSG pads for calibrating the RF probes.

Arguments:

  • via_stack - where the RF pads connect to.
  • size - for the via_stack.
  • layer_metal - for the short.
  • metal_spacing - in um.
  • short - if False returns an open.
  • pad - function for pad.
  • pad_spacing - in um.

gdsfactory.components.cutback_component

cutback_component

@gf.cell
def cutback_component(component: ComponentSpec = taper_0p5_to_3_l36,
                      cols: int = 4,
                      rows: int = 5,
                      port1: str = "o1",
                      port2: str = "o2",
                      bend180: ComponentSpec = bend_euler180,
                      mirror: bool = False,
                      mirror1: bool = False,
                      mirror2: bool = False,
                      straight_length: float | None = None,
                      straight_length_pair: float | None = None,
                      cross_section: CrossSectionSpec = "strip",
                      **kwargs) -> Component

Returns a daisy chain of components for measuring their loss.

Works only for components with 2 ports (input, output).

Arguments:

  • component - for cutback.
  • cols - number of columns.
  • rows - number of rows.
  • port1 - name of first optical port.
  • port2 - name of second optical port.
  • bend180 - ubend.
  • mirror - Flips component. Useful when ‘o2’ is the port that you want to route to.
  • mirror1 - mirrors first component.
  • mirror2 - mirrors second component.
  • straight_length - length of the straight section between cutbacks.
  • straight_length_pair - length of the straight section between each component pair.
  • cross_section - specification (CrossSection, string or dict).
  • kwargs - component settings.

gdsfactory.components.mzi_phase_shifter

gdsfactory.components.fiducial_squares

fiducial_squares

@gf.cell
def fiducial_squares(layers: Layers = ((1, 0), ),
                     size: Float2 = (5, 5),
                     offset: float = 0.14) -> gf.Component

Returns fiducials with two squares.

Arguments:

  • layers - list of layers.
  • size - in um.
  • offset - in um.

gdsfactory.components.coh_rx_single_pol

coh_rx_single_pol

@cell
def coh_rx_single_pol(
        bend: ComponentSpec = "bend_euler",
        cross_section: CrossSectionSpec = "strip",
        hybrid_90deg: ComponentSpec = mmi_90degree_hybrid,
        detector: ComponentSpec = ge_detector_straight_si_contacts,
        det_spacing: tuple[float, float] = (60.0, 50.0),
        with_pads: bool = True,
        pad_det_spacing: float = 80.0,
        in_wg_length: float = 20.0,
        lo_input_coupler: ComponentSpec | None = None,
        signal_input_coupler: ComponentSpec | None = None) -> Component

Single polarization coherent receiver.

Arguments:

  • bend - 90 degrees bend library.

  • cross_section - for routing.

  • hybrid_90deg - generates the 90 degree hybrid.

  • detector - generates the detector.

  • det_spacing - spacing between 90 degree hybrid and detector and vertical spacing between detectors.

  • with_pads - if True, it draws pads for the balanced detectors.

  • pad_det_spacing - spacing between the pads and the detectors (if with_pads=True).

  • in_wg_length - length of the straight waveguides at the input of the 90 deg hybrid.

  • lo_input_coupler - Optional coupler for the LO.

  • signal_input_coupler - Optional coupler for the signal.

    .. code::


    (lo_in_coupler)---| |--- detI1 \ __ i signal | 90 deg |--- detI2 // (signal_in_coupler)---| hybrid |--- detQ1 \ __ q signal |__________|--- detQ2 //

gdsfactory.components.ring_double_bend_coupler

ring_double_bend_coupler

@gf.cell
def ring_double_bend_coupler(radius: float = 5.0,
                             gap: float = 0.2,
                             coupling_angle_coverage: float = 70.0,
                             bend: ComponentSpec = bend_circular,
                             length_x: float = 0.6,
                             length_y: float = 0.6,
                             cross_section_inner: CrossSectionSpec = "strip",
                             cross_section_outer: CrossSectionSpec = "strip",
                             **kwargs) -> Component

Returns ring with double curved couplers.

TODO: enable euler bends.

Arguments:

  • radius - um.
  • gap - um.
  • angle_inner - of the inner bend, from beginning to end. Depending on the bend chosen, gap may not be preserved.
  • angle_outer - of the outer bend, from beginning to end. Depending on the bend chosen, gap may not be preserved.
  • bend - for bend.
  • length_y - vertical straight length.
  • cross_section_inner - spec inner bend.
  • cross_section_outer - spec outer bend.
  • kwargs - cross_section settings.

gdsfactory.components.mode_converter

mode_converter

@gf.cell
def mode_converter(gap: float = 0.3,
                   length: float = 10,
                   coupler_straight_asymmetric:
                   ComponentSpec = coupler_straight_asymmetric_function,
                   bend: ComponentSpec = partial(bend_euler_s, angle=45),
                   taper: ComponentSpec = taper_function,
                   mm_width: float = 1.2,
                   mc_mm_width: float = 1,
                   sm_width: float = 0.5,
                   taper_length: float = 25,
                   cross_section: CrossSectionSpec = "strip",
                   **kwargs) -> Component

Returns Mode converter from TE0 to TE1.

By matching the effective indices of two waveguides with different widths, light can couple from different transverse modes e.g. TE0 <-> TE1. Shu et al. (2019)

Arguments:

  • gap - directional coupler gap.

  • length - coupler length interaction.

  • coupler_straight_asymmetric - spec.

  • mm_width - input/output multimode waveguide width.

  • mc_mm_width - mode converter multimode waveguide width

  • sm_width - single mode waveguide width.

  • cross_section - cross_section spec.

  • kwargs - cross_section settings.

    .. code::

    o2 --- --- o4 \ / \ /

    o1 -----=======----- o3 |-----| length

    = : multimode width

    • : singlemode width

gdsfactory.components.coupler_full

coupler_full

@gf.cell
def coupler_full(coupling_length: float = 40.0,
                 dx: float = 10.0,
                 dy: float = 5.0,
                 gap: float = 0.5,
                 dw: float = 0.1,
                 cross_section: CrossSectionSpec = "strip",
                 **kwargs) -> Component

Adiabatic Full coupler.

Design based on asymmetric adiabatic full coupler designs, such as the one reported in ‘Integrated Optic Adiabatic Devices on Silicon’ by Y. Shani, et al (IEEE Journal of Quantum Electronics, Vol. 27, No. 3 March 1991).

  1. is the first half of the input S-bend straight where the input straights widths taper by +dw and -dw,
  2. is the second half of the S-bend straight with constant, unbalanced widths,
  3. is the coupling region where the straights from unbalanced widths to balanced widths to reverse polarity unbalanced widths,
  4. is the fixed width straight that curves away from the coupling region, 5.is the final curve where the straights taper back to the regular width specified in the straight template.

Arguments:

  • coupling_length - Length of the coupling region in um.
  • dx - Length of the bend regions in um.
  • dy - Port-to-port distance between the bend regions in um.
  • gap - Distance between the two straights in um.
  • dw - delta width. Top arm tapers to width - dw, bottom to width + dw in um.
  • cross_section - cross-section spec.

Arguments:

cross_section kwargs.

gdsfactory.components.edge_coupler_array

edge_coupler_array

@gf.cell
def edge_coupler_array(edge_coupler: ComponentSpec = edge_coupler_silicon,
                       n: int = 5,
                       pitch: float = 127.0,
                       x_reflection: bool = False,
                       text: ComponentSpec | None = text_rectangular,
                       text_offset: Float2 = (10, 20),
                       text_rotation: float = 0) -> Component

Fiber array edge coupler based on an inverse taper.

Each edge coupler adds a ruler for polishing.

Arguments:

  • edge_coupler - edge coupler spec.
  • n - number of channels.
  • pitch - Fiber pitch.
  • x_reflection - horizontal mirror.
  • text - text spec.
  • text_offset - from edge coupler.
  • text_rotation - text rotation in degrees.

edge_coupler_array_with_loopback

@gf.cell
def edge_coupler_array_with_loopback(
        edge_coupler: ComponentSpec = edge_coupler_silicon,
        cross_section: CrossSectionSpec = "strip",
        radius: float = 30,
        n: int = 8,
        pitch: float = 127.0,
        extension_length: float = 1.0,
        right_loopback: bool = True,
        x_reflection: bool = False,
        text: ComponentSpec | None = text_rectangular,
        text_offset: Float2 = (0, 0),
        text_rotation: float = 0) -> Component

Fiber array edge coupler.

Arguments:

  • edge_coupler - edge coupler.
  • cross_section - spec.
  • radius - bend radius loopback (um).
  • n - number of channels.
  • pitch - Fiber pitch (um).
  • extension_length - in um.
  • right_loopback - adds right loopback.
  • x_reflection - horizontal mirror.
  • text - Optional text spec.
  • text_offset - x, y.
  • text_rotation - text rotation in degrees.

gdsfactory.components.spiral_inner_io

Spiral with grating couplers inside to save space.

spiral_inner_io

@gf.cell
def spiral_inner_io(N: int = 6,
                    x_straight_inner_right: float = 150.0,
                    x_straight_inner_left: float = 50.0,
                    y_straight_inner_top: float = 50.0,
                    y_straight_inner_bottom: float = 10.0,
                    grating_spacing: float = 127.0,
                    waveguide_spacing: float = 3.0,
                    bend90: ComponentSpec = bend_euler,
                    bend180: ComponentSpec = bend_euler180,
                    straight: ComponentSpec = straight_function,
                    length: float | None = None,
                    cross_section: CrossSectionSpec = "strip",
                    cross_section_bend: CrossSectionSpec | None = None,
                    cross_section_bend180: CrossSectionSpec | None = None,
                    asymmetric_cross_section: bool = False,
                    **kwargs) -> Component

Returns Spiral with ports inside the spiral loop.

You can add grating couplers inside.

Arguments:

  • N - number of loops.
  • x_straight_inner_right - xlength.
  • x_straight_inner_left - x length left.
  • y_straight_inner_top - x inner top.
  • y_straight_inner_bottom - y length.
  • grating_spacing - defaults to 127 for fiber array.
  • waveguide_spacing - center to center spacing.
  • bend90 - bend90 spec.
  • bend180 - bend180 spec.
  • straight - straight spec.
  • length - spiral target length (um), overrides x_straight_inner_left. to match the length by a simple 1D interpolation.
  • cross_section - spec.
  • cross_section_bend - for the bends.
  • cross_section_bend180 - for 180 bend.
  • asymmetric_cross_section - if the cross_section is asymmetric, it needs to be mirrored at the halfway point
  • kwargs - cross_section settings.

spiral_inner_io_fiber_single

@gf.cell
def spiral_inner_io_fiber_single(cross_section: CrossSectionSpec = "strip",
                                 cross_section_bend: CrossSectionSpec
                                 | None = None,
                                 cross_section_ports: CrossSectionSpec
                                 | None = None,
                                 x_straight_inner_right: float = 40.0,
                                 x_straight_inner_left: float = 75.0,
                                 y_straight_inner_top: float = 10.0,
                                 y_straight_inner_bottom: float = 0.0,
                                 grating_spacing: float = 200.0,
                                 **kwargs) -> Component

Returns Spiral with 90 and 270 degree ports.

You can add single fiber north and south grating couplers inside the spiral to save space

Arguments:

  • cross_section - for the straight sections in the spiral.
  • cross_section_bend - for the bends in the spiral.
  • cross_section_ports - for input/output ports.
  • x_straight_inner_right - in um.
  • x_straight_inner_left - in um.
  • y_straight_inner_top - in um.
  • y_straight_inner_bottom - in um.
  • grating_spacing - in um.

Arguments:

  • N - number of loops.
  • waveguide_spacing - center to center spacing.
  • bend90 - bend90 spec.
  • bend180 - bend180 spec.
  • straight - straight spec.
  • length - computes spiral length from simple interpolation.
  • kwargs - cross_section settings.

get_straight_length

def get_straight_length(length: float, spiral_function: ComponentSpec,
                        **kwargs) -> float

Returns y_spiral to achieve a particular spiral length.

gdsfactory.components.taper_adiabatic

taper_adiabatic

@gf.cell
def taper_adiabatic(width1: float = 0.5,
                    width2: float = 5.0,
                    length: float = 0,
                    neff_w: Callable = lambda w: np.poly1d(
                        adiabatic_polyfit_TE1550SOI_220nm)(w),
                    alpha: float = 1,
                    wavelength: float = 1.55,
                    npoints: int = 200,
                    cross_section: CrossSectionSpec = "strip",
                    **kwargs) -> gf.Component

Returns a straight adiabatic_taper from an effective index callable.

Arguments:

  • width1 - initial width.
  • width2 - final width.
  • length - 0 uses the optimized length, and otherwise the optimal shape is compressed/stretched to the specified length.
  • neff_y - a callable that returns the effective index as a function of width
    • By default, will use a compact model of neff(y) for fundamental 1550 nm TE mode of 220nm-thick core with 3.45 index, fully clad with 1.44 index. Many coefficients are needed to capture the behaviour.
  • alpha - parameter that scales the rate of width change.
    • closer to 0 means longer and more adiabatic;
    • 1 is the intuitive limit beyond which higher order modes are excited;
    • [2] reports good performance up to 1.4 for fundamental TE in SOI (for multiple core thicknesses)

References:

[1] Burns, W. K., et al. “Optical waveguide parabolic coupling horns.” Appl. Phys. Lett., vol. 30, no. 1, 1 Jan. 1977, pp. 28-30, doi:10.1063/1.89199. [2] Fu, Yunfei, et al. “Efficient adiabatic silicon-on-insulator waveguide taper.” Photonics Res., vol. 2, no. 3, 1 June 2014, pp. A41-A44, doi:10.1364/PRJ.2.000A41.

  • npoints - number of points for sampling

gdsfactory.components.coupler

coupler

@gf.cell
def coupler(gap: float = 0.236,
            length: float = 20.0,
            coupler_symmetric: ComponentSpec = coupler_symmetric_function,
            coupler_straight: ComponentSpec = coupler_straight_function,
            dy: float = 4.0,
            dx: float = 10.0,
            cross_section: CrossSectionSpec = "strip",
            **kwargs) -> Component

Symmetric coupler.

Arguments:

  • gap - between straights in um.

  • length - of coupling region in um.

  • coupler_symmetric - spec for bend coupler.

  • coupler_straight - spec for straight coupler.

  • dy - port to port vertical spacing in um.

  • dx - length of bend in x direction in um.

  • cross_section - spec (CrossSection, string or dict).

  • kwargs - cross_section settings.

    .. code::

    dx dx |------| |------| o2 ________ ______o3 \ / | \ length / | ======================= gap | dy / \ | __/ _ | o1 o4

    coupler_straight coupler_symmetric

gdsfactory.components.via_stack_with_offset

via_stack_with_offset

@gf.cell
def via_stack_with_offset(
        layers: LayerSpecs = ("PPP", "M1"),
        size: Float2 = (10, 10),
        sizes: tuple[Float2, ...] | None = None,
        layer_offsets: Floats | None = None,
        vias: tuple[ComponentSpec | None, ...] = (None, viac),
        offsets: tuple[float, ...] | None = None) -> Component

Rectangular layer transition with offset between layers.

Arguments:

  • layers - layer specs between vias.

  • size - for all vias array.

  • sizes - Optional size for each via array. Overrides size.

  • layer_offsets - Optional offsets for each layer with respect to size. positive grows, negative shrinks the size.

  • vias - via spec for previous layer. None for no via.

  • offsets - optional offset for each layer relatively to the previous one. By default it only offsets by size[1] if there is a via.

    .. code::

    side view


    | | | | layers[2] || vias[2] = None | | | layer_offsets[1]+size | layers[1] || | | vias[1] || | | | sizes[0] | layers[0] |____________|

    vias[0] = None

gdsfactory.components.dbr_tapered

dbr_tapered

@gf.cell
def dbr_tapered(length: float = 10.0,
                period: float = 0.85,
                dc: float = 0.5,
                w1: float = 0.4,
                w2: float = 1.0,
                taper_length: float = 20.0,
                fins: bool = False,
                fin_size: tuple[float, float] = (0.2, 0.05),
                cross_section: CrossSectionSpec = "strip",
                **kwargs) -> Component

Distributed Bragg Reflector Cell class.

Tapers the input straight to a periodic straight structure with varying width (1-D photonic crystal).

Arguments:

  • length - Length of the DBR region.
  • period - Period of the repeated unit.
  • dc - Duty cycle of the repeated unit (must be a float between 0 and 1.0).
  • w1 - thin section width. w1 = 0 corresponds to disconnected periodic blocks.
  • w2 - wide section width.
  • taper_length - between the input/output straight and the DBR region.
  • fins - If True, adds fins to the input/output straights.
  • fin_size - Specifies the x- and y-size of the fins. Defaults to 200 nm x 50 nm
  • cross_section - cross_section spec.

Arguments:

cross_section kwargs.

.. code::

period <-----><-------->


_______|

w1 w2 ... n times


|_________

gdsfactory.components.cdsem_straight_density

CD SEM structures.

cdsem_straight_density

@cell
def cdsem_straight_density(
        widths: Floats = widths,
        gaps: Floats = gaps,
        length: float = 420.0,
        label: str = "",
        cross_section: CrossSectionSpec = "strip",
        text: ComponentSpec | None = text_rectangular_mini) -> Component

Returns sweep of dense straight lines.

Arguments:

  • widths - list of widths.
  • gaps - list of gaps.
  • length - of the lines.
  • label - defaults to widths[0] gaps[0].
  • cross_section - spec.
  • text - optional function for text.

gdsfactory.components.add_trenches

add_trenches

@gf.cell
def add_trenches(component: ComponentSpec = coupler,
                 cross_section: CrossSectionSpec = "rib_with_trenches",
                 top: bool = True,
                 bot: bool = True,
                 right: bool = False,
                 left: bool = False,
                 **kwargs) -> gf.Component

Return component with trenches.

Arguments:

  • component - component to add to the trenches.
  • cross_section - spec (CrossSection, string or dict).
  • top - add top trenches.
  • bot - add bot trenches.
  • right - add right trenches.
  • left - add left trenches.
  • kwargs - component settings.

gdsfactory.components.wire_sbend

wire_sbend

@gf.cell
def wire_sbend(dx: float = 20.0, dy: float = 10.0, **kwargs) -> Component

Sbend corner with manhattan wires.

Arguments:

  • dx - xsize.
  • dy - ysize.
  • kwargs - cross_section settings.

gdsfactory.components.coupler_symmetric

coupler_symmetric

@gf.cell
def coupler_symmetric(bend: ComponentSpec = bend_s,
                      gap: float = 0.234,
                      dy: float = 5.0,
                      dx: float = 10.0,
                      cross_section: CrossSectionSpec = "strip",
                      **kwargs) -> Component

Two coupled straights with bends.

Arguments:

  • bend - bend spec.

  • gap - in um.

  • dy - port to port vertical spacing.

  • dx - bend length in x direction.

  • cross_section - section.

  • **kwargs - cross_section settings.

    .. code::

    dx |-----| ___ E1 / | ___/ | gap _____ | dy \ | _ | E0

gdsfactory.components.mzm

mzm

@cell
def mzm(phase_shifter: ComponentSpec = straight_pin,
        length_x: float = 500,
        length_y: float = 2.0,
        delta_length: float = 0.0,
        bend: ComponentSpec = bend_euler,
        straight: ComponentSpec = straight_function,
        splitter: ComponentSpec = "mmi1x2",
        combiner: ComponentSpec | None = "mmi1x2",
        with_splitter: bool = True,
        port_e1_splitter: str = "o2",
        port_e0_splitter: str = "o3",
        port_e1_combiner: str = "o2",
        port_e0_combiner: str = "o3",
        nbends: int = 2,
        cross_section: CrossSectionSpec = "strip",
        mirror_bot: bool = False) -> Component

Mzm modulator.

Arguments:

  • phase_shifter - for bottom and top arms.

  • length_x - horizontal length. None uses to the straight_x_bot/top defaults.

  • length_y - vertical length for both and top arms.

  • delta_length - bottom arm vertical extra length.

  • bend - 90 degrees bend spec.

  • straight - straight function for vertical.

  • splitter - splitter function.

  • combiner - combiner function. Optional adds ports.

  • with_splitter - if False removes splitter.

  • port_e1_splitter - east top splitter port.

  • port_e0_splitter - east bot splitter port.

  • port_e1_combiner - east top combiner port.

  • port_e0_combiner - east bot combiner port.

  • nbends - from straight top/bot to combiner (at least 2).

  • cross_section - for routing (sxtop/sxbot to combiner).

  • mirror_bot - mirrors bottom arm.

    .. code::

    b2______b3 | sxtop | straight_y | | | b1 b4 splitter==| |==combiner b5 b8 | | straight_y | | | delta_length/2 | | | b6__sxbot__b7 Lx

gdsfactory.components.die

based on phidl.geometry.

die

@gf.cell
def die(size: tuple[float, float] = (10000.0, 10000.0),
        street_width: float = 100.0,
        street_length: float = 1000.0,
        die_name: str | None = "chip99",
        text_size: float = 100.0,
        text_location: str | Float2 = "SW",
        layer: LayerSpec | None = "FLOORPLAN",
        bbox_layer: LayerSpec | None = "FLOORPLAN",
        text: ComponentFactory = text,
        draw_corners: bool = False) -> gf.Component

Returns die with optional markers marking the boundary of the die.

Arguments:

  • size - x, y dimensions of the die.
  • street_width - Width of the corner marks for die-sawing.
  • street_length - Length of the corner marks for die-sawing.
  • die_name - Label text. If None, no label is added.
  • text_size - Label text size.
  • text_location - {‘NW’, ‘N’, ‘NE’, ‘SW’, ‘S’, ‘SE’} or (x, y) coordinate.
  • layer - For street widths. None to not draw the street widths.
  • bbox_layer - optional bbox layer drawn bounding box around the die.
  • text - function use for generating text. Needs to accept text, size, layer.
  • draw_corners - True draws only corners. False draws a square die.

gdsfactory.components.array_with_fanout

array_with_fanout

@cell
def array_with_fanout(component: ComponentSpec = "pad",
                      columns: int = 3,
                      pitch: float = 150.0,
                      waveguide_pitch: float = 10.0,
                      start_straight_length: float = 5.0,
                      end_straight_length: float = 40.0,
                      radius: float = 5.0,
                      component_port_name: str = "e4",
                      bend: ComponentSpec = "bend_euler",
                      bend_port_name1: str | None = None,
                      bend_port_name2: str | None = None,
                      cross_section: CrossSectionSpec = "strip",
                      **kwargs) -> Component

Returns component array in X axis with west facing waveguides.

Arguments:

  • component - to replicate.
  • columns - number of components.
  • pitch - for waveguides.
  • waveguide_pitch - for output waveguides.
  • start_straight_length - length of the start of the straight.
  • end_straight_length - length of the straight at the end.
  • radius - bend radius.
  • component_port_name - for fanout.
  • bend - spec.
  • bend_port_name1 - optional port name.
  • bend_port_name2 - optional port name.
  • cross_section - cross_section spec.
  • kwargs - cross_section settings.

array_with_fanout_2d

@cell
def array_with_fanout_2d(pitch: float = 150.0,
                         pitch_x: float | None = None,
                         pitch_y: float | None = None,
                         columns: int = 3,
                         rows: int = 2,
                         **kwargs) -> Component

Returns 2D array with fanout waveguides facing west.

Arguments:

  • pitch - 2D pitch.

  • pitch_x - defaults to pitch.

  • pitch_y - defaults to pitch.

  • columns - number of columns.

  • rows - number of rows.

    keyword args:

  • component - to replicate.

  • pitch - in um.

  • waveguide_pitch - for fanout in um.

  • start_straight_length - length of the start of the straight in um.

  • end_straight_length - length of the straight at the end in um.

  • radius - bend radius in um.

  • cross_section - cross_section factory. component_port_name: bend_port_name1: bend_port_name2:

gdsfactory.components.grating_coupler_rectangular_arbitrary

grating_coupler_rectangular_arbitrary

@gf.cell
def grating_coupler_rectangular_arbitrary(
        gaps: Floats = _gaps,
        widths: Floats = _widths,
        width_grating: float = 11.0,
        length_taper: float = 150.0,
        polarization: str = "te",
        wavelength: float = 1.55,
        taper: ComponentSpec | None = taper_function,
        layer_grating: LayerSpec | None = None,
        layer_slab: LayerSpec = "SLAB150",
        slab_xmin: float = -1.0,
        slab_offset: float = 1.0,
        fiber_angle: float = 15,
        cross_section: CrossSectionSpec = "strip",
        **kwargs) -> Component

Grating coupler uniform with rectangular shape (not elliptical). Therefore it needs a longer taper. Grating teeth are straight instead of elliptical.

Arguments:

  • gaps - list of gaps between grating teeth.

  • widths - list of grating widths.

  • width_grating - grating teeth width.

  • length_taper - taper length (um).

  • polarization - ‘te’ or ‘tm’.

  • wavelength - in um.

  • taper - function.

  • layer_grating - Optional layer for grating. by default None uses cross_section.layer. if different from cross_section.layer expands taper.

  • layer_slab - layer that protects the slab under the grating.

  • slab_xmin - where 0 is at the start of the taper.

  • slab_offset - from edge of grating to edge of the slab.

  • fiber_angle - in degrees.

  • cross_section - for input waveguide port.

  • kwargs - cross_section settings.

    .. code::

    fiber

    / / / / / / / /

    |-||-||-|__ layer layer_slab | o1 ______________|

    top view _________ /| | | | | / | | | | | /taper_angle /_ | | | | | wg_width | | | | | | \ | | | | | \ | | | | | \ | | | | | ||||_| <--> taper_length

gdsfactory.components.C

C

@gf.cell
def C(width: float = 1.0,
      size: tuple[float, float] = (10.0, 20.0),
      layer: LayerSpec = "WG") -> Component

C geometry with ports on both ends.

based on phidl.

Arguments:

  • width - of the line.

  • size - length and height of the base.

  • layer - layer spec.

    .. code::


    | o1 | ___ | | | |___ ||<---> size[0] |______ o2

gdsfactory.components.coupler_straight

coupler_straight

@gf.cell
def coupler_straight(length: float = 10.0,
                     gap: float = 0.27,
                     **kwargs) -> Component

Coupler_straight with two parallel straights.

Arguments:

  • length - of straight.
  • gap - between straights.
  • kwargs - cross_section settings.

gdsfactory.components.coupler_adiabatic

coupler_adiabatic

@gf.cell
def coupler_adiabatic(length1: float = 20.0,
                      length2: float = 50.0,
                      length3: float = 30.0,
                      wg_sep: float = 1.0,
                      input_wg_sep: float = 3.0,
                      output_wg_sep: float = 3.0,
                      dw: float = 0.1,
                      cross_section: CrossSectionSpec = "strip",
                      **kwargs) -> Component

Returns 50/50 adiabatic coupler.

Design based on asymmetric adiabatic 3dB coupler designs, such as those.

input Bezier curves, with poles set to half of the x-length of the S-bend.

  1. is the first half of input S-bend where input widths taper by +dw and -dw
  2. is the second half of the S-bend straight with constant, unbalanced widths
  3. is the region where the two asymmetric straights gradually come together
  4. straights taper back to the original width at a fixed distance from one another
  5. is the output S-bend straight.

Arguments:

  • length1 - region that gradually brings the two asymmetric straights together. In this region the straight widths gradually change to be different by dw.
  • length2 - coupling region, where asymmetric straights gradually become the same width.
  • length3 - output region where the two straights separate.
  • wg_sep - Distance between center-to-center in the coupling region (Region 2).
  • input_wg_sep - Separation of the two straights at the input, center-to-center.
  • output_wg_sep - Separation of the two straights at the output, center-to-center.
  • dw - Change in straight width. In Region 1, top arm tapers to width+dw/2.0, bottom taper to width-dw/2.0.
  • cross_section - cross_section spec.

Arguments:

cross_section kwargs.

gdsfactory.components.cross

cross

@gf.cell
def cross(length: float = 10.0,
          width: float = 3.0,
          layer: LayerSpec = "WG",
          port_type: str | None = None) -> Component

Returns a cross from two rectangles of length and width.

Arguments:

  • length - float Length of the cross from one end to the other.
  • width - float Width of the arms of the cross.
  • layer - layer for geometry.
  • port_type - None, optical, electrical.

gdsfactory.components.cdsem_bend180

CD SEM structures.

cdsem_bend180

@cell
def cdsem_bend180(width: float = 0.5,
                  radius: float = 10.0,
                  wg_length: float = LINE_LENGTH,
                  straight: ComponentSpec = "straight",
                  bend90: ComponentSpec = "bend_circular",
                  cross_section: CrossSectionSpec = "strip",
                  text: ComponentSpec = text_rectangular_mini) -> Component

Returns CDSEM structures.

Arguments:

  • width - of the line.
  • radius - um.
  • wg_length - in um.
  • straight - spec.
  • bend90 - spec.
  • cross_section - spec.
  • text - spec.

gdsfactory.components.copy_layers

copy_layers

@cell
def copy_layers(factory: ComponentSpec = cross,
                layers: LayerSpecs = ((1, 0), (2, 0)),
                **kwargs) -> Component

Returns a component with the geometry copied in different layers.

Arguments:

  • factory - component spec.
  • layers - iterable of layers.
  • kwargs - keyword arguments.

gdsfactory.components.grating_coupler_elliptical_lumerical

grating_coupler_elliptical_lumerical

@cell
def grating_coupler_elliptical_lumerical(parameters: Floats = parameters,
                                         layer: LayerSpec = "WG",
                                         layer_slab: LayerSpec
                                         | None = "SLAB150",
                                         taper_angle: float = 55,
                                         taper_length: float = 12.24 + 0.36,
                                         fiber_angle: float = 5,
                                         info: dict[str, Any] | None = None,
                                         bias_gap: float = 0,
                                         **kwargs) -> Component

Returns a grating coupler from lumerical inverse design 3D optimization.

this is a wrapper of components.grating_coupler_elliptical_arbitrary https://support.lumerical.com/hc/en-us/articles/1500000306621 https://support.lumerical.com/hc/en-us/articles/360042800573

Here are the simulation settings used in lumerical

n_bg=1.44401 # Refractive index of the background material (cladding) wg=3.47668 # Refractive index of the waveguide material (core) lambda0=1550e-9 bandwidth = 0e-9 polarization = ‘TE’ wg_width=500e-9 # Waveguide width wg_height=220e-9 # Waveguide height etch_depth=80e-9 # etch depth theta_fib_mat = 5 # Angle of the fiber mode in material theta_taper=30 efficiency=0.55 # 5.2 dB

Arguments:

  • parameters - xinput, gap1, width1, gap2, width2 ...

  • layer - for waveguide.

  • layer_slab - for slab.

  • taper_angle - in deg.

  • taper_length - in um.

  • fiber_angle - used to compute ellipticity.

  • info - optional simulation settings.

  • bias_gap - gap/trenches bias (um) to compensate for etching bias.

    keyword Args:

  • taper_length - taper length from input in um.

  • taper_angle - grating flare angle in degrees.

  • wavelength - grating transmission central wavelength (um).

  • fiber_angle - fibre angle in degrees determines ellipticity.

  • neff - tooth effective index.

  • nclad - cladding effective index.

  • polarization - te or tm.

  • spiked - grating teeth include sharp spikes to avoid non-manhattan drc errors.

  • cross_section - cross_section spec for waveguide port.

gdsfactory.components.bend_port

bend_port

@gf.cell
def bend_port(component: ComponentSpec = straight_heater_metal,
              port_name: str = "l_e1",
              port_name2: str = "r_e1",
              port_name1_bend: str | None = None,
              port_name2_bend: str | None = None,
              cross_section: CrossSectionSpec = "metal3_with_bend",
              bend: ComponentSpec = bend_circular,
              angle: float = 180,
              extension_length: float | None = None,
              **kwargs) -> gf.Component

Returns a component with a bend and a straight extension.

Arguments:

  • component - to bend.
  • port_name - of the component port origin.
  • port_name2 - of the component port destination.
  • port_name1_bend - for bend port.
  • port_name2_bend - for bend port.
  • cross_section - for the bend.
  • bend - factory for the bend.
  • angle - for the bend.
  • extension_length - for the straight after the bend.
  • kwargs - cross_section settings.

gdsfactory.components.straight_heater_meander_doped

straight_heater_meander_doped

@gf.cell
def straight_heater_meander_doped(
        length: float = 300.0,
        spacing: float = 2.0,
        cross_section: gf.typings.CrossSectionSpec = "strip",
        heater_width: float = 1.5,
        extension_length: float = 15.0,
        layers_doping: LayerSpecs = ("P", "PP", "PPP"),
        radius: float = 5.0,
        via_stack: ComponentSpec | None = via_stack,
        port_orientation1: int | None = None,
        port_orientation2: int | None = None,
        straight_widths: Floats = (0.8, 0.9, 0.8),
        taper_length: float = 10) -> Component

Returns a meander based heater.

based on SungWon Chung, Makoto Nakai, and Hossein Hashemi, Low-power thermo-optic silicon modulator for large-scale photonic integrated systems Opt. Express 27, 13430-13459 (2019) https://www.osapublishing.org/oe/abstract.cfm?URI=oe-27-9-13430

Arguments:

  • length - total length of the optical path.
  • spacing - waveguide spacing (center to center).
  • cross_section - for waveguide.
  • heater_width - for heater.
  • extension_length - of input and output optical ports.
  • layers_doping - doping layers to be used for heater.
  • radius - for the meander bends.
  • via_stack - for the heater to via_stack metal.
  • port_orientation1 - in degrees. None adds all orientations.
  • port_orientation2 - in degrees. None adds all orientations.
  • straight_width - width of the straight section.
  • taper_length - from the cross_section.

gdsfactory.components.ring_crow_couplers

ring_crow_couplers

@gf.cell
def ring_crow_couplers(
        radius: list[float] = [10.0] * 3,
        bends: list[ComponentSpec] = [bend_circular] * 3,
        ring_cross_sections: list[CrossSectionSpec] = [strip] * 3,
        couplers: list[ComponentSpec] = [coupler_full] * 4) -> Component

Coupled ring resonators with coupler components between gaps.

Arguments:

  • gap - gap between for coupler.

  • radius - for the bend and coupler.

  • length_x - ring coupler length.

  • length_y - vertical straight length.

  • coupler - ring coupler spec.

  • straight - straight spec.

  • bend - bend spec.

  • cross_section - cross_section spec.

  • couplers - coupling component between rings and bus.

    .. code::

    --==ct==-- gap[N-1] <------- couplers[N-1] | | sl sr ring[N-1] | | --==cb==-- gap[N-2] <------- couplers[N-2]

    . . .

    --==ct==-- | | sl sr lengths_y[1], ring[1] | | --==cb==-- gap[1] <------- couplers[1] --==ct==-- | | sl sr lengths_y[0], ring[0] | | --==cb==-- gap[0] <------- couplers[0]

    length_x

gdsfactory.components.mzi_pads_center

mzi_pads_center

@gf.cell
def mzi_pads_center(ps_top: ComponentSpec = straight_heater_metal,
                    ps_bot: ComponentSpec = straight_heater_metal,
                    mzi: ComponentSpec = mzi_function,
                    pad: ComponentSpec = pad_small,
                    length_x: float = 500,
                    length_y: float = 40,
                    mzi_sig_top: str = "top_r_e2",
                    mzi_gnd_top: str = "top_l_e2",
                    mzi_sig_bot: str = "bot_l_e2",
                    mzi_gnd_bot: str = "bot_r_e2",
                    pad_sig_bot: str = "e1_1_1",
                    pad_sig_top: str = "e3_1_3",
                    pad_gnd_bot: str = "e4_1_2",
                    pad_gnd_top: str = "e2_1_2",
                    delta_length: float = 40.0,
                    cross_section: CrossSectionSpec = "strip",
                    cross_section_metal: CrossSectionSpec = "metal_routing",
                    pad_spacing: float | str = "pad_spacing",
                    **kwargs) -> gf.Component

Return Mzi phase shifter with pads in the middle.

GND is the middle pad and is shared between top and bottom phase shifters.

Arguments:

  • ps_top - phase shifter top.
  • ps_bot - phase shifter bottom.
  • mzi - interferometer.
  • pad - pad function.
  • length_x - horizontal length.
  • length_y - vertical length.
  • mzi_sig_top - port name for top phase shifter signal.
  • mzi_gnd_top - port name for top phase shifter GND.
  • mzi_sig_bot - port name for top phase shifter signal.
  • mzi_gnd_bot - port name for top phase shifter GND.
  • pad_sig_bot - port name for top pad.
  • pad_sig_top - port name for top pad.
  • pad_gnd_bot - port name for top pad.
  • pad_gnd_top - port name for top pad.
  • delta_length - mzi length imbalance.
  • cross_section - for the mzi.
  • cross_section_metal - for routing metal.
  • pad_spacing - pad pitch in um.
  • kwargs - routing settings.

gdsfactory.components.optimal_hairpin

optimal_hairpin

@cell
def optimal_hairpin(width: float = 0.2,
                    pitch: float = 0.6,
                    length: float = 10,
                    turn_ratio: float = 4,
                    num_pts: int = 50,
                    layer: LayerSpec = (1, 0)) -> Component

Returns an optimally-rounded hairpin geometry, with a 180 degree turn on the right end of the polygon connected to two prongs extending towards ports on the left end.

based on phidl.geometry

Arguments:

width : int or float Width of the hairpin leads. pitch : int or float Distance between the two hairpin leads. Must be greater than width. length : int or float Length of the hairpin from the connectors to the opposite end of the curve.

  • turn_ratio - int or float Specifies how much of the hairpin is dedicated to the 180 degree turn. A turn_ratio of 10 will result in 20% of the hairpin being comprised of the turn. num_pts : int Number of points constituting the 180 degree turn. layer : int, array-like[2], or set Specific layer(s) to put polygon geometry on.

Notes:

Hairpin pitch must be greater than width.

Optimal structure from Clem & Berggren (2011) Clem, J., & Berggren, K. (2011). Geometry-dependent critical currents in superconducting nanocircuits. Physical Review B, 84(17), 1–27.

gdsfactory.components.coh_tx_dual_pol

coh_tx_dual_pol

@cell
def coh_tx_dual_pol(splitter: ComponentSpec = "mmi1x2",
                    combiner: ComponentSpec | None = None,
                    spol_coh_tx: ComponentSpec = "coh_tx_single_pol",
                    yspacing: float = 10.0,
                    xspacing: float = 40.0,
                    input_coupler: ComponentSpec | None = None,
                    output_coupler: ComponentSpec | None = None,
                    cross_section: CrossSectionSpec = "strip",
                    **kwargs) -> Component

Dual polarization coherent transmitter.

Arguments:

  • splitter - splitter function.

  • combiner - combiner function.

  • spol_coh_tx - function generating a coherent tx for a single polarization.

  • yspacing - vertical spacing between each single polarization coherent tx.

  • xspacing - horizontal spacing between splitter and combiner.

  • input_coupler - Optional coupler to add before the splitter.

  • output_coupler - Optional coupler to add after the combiner.

  • cross_section - for routing (splitter to mzms and mzms to combiners).

  • kwargs - cross_section settings.

    .. code::

    ___ single_pol_tx__ | | | | | | (in_coupler)---splitter==| |==combiner---(out_coupler) | | | | |___ single_pol_tx_|

gdsfactory.components.ring_single_dut

ring_single_dut

@gf.cell
def ring_single_dut(component: ComponentSpec = taper2,
                    gap: float = 0.2,
                    length_x: float = 4,
                    length_y: float = 0,
                    radius: float = 5.0,
                    coupler: ComponentSpec = coupler_ring,
                    bend: ComponentSpec = bend_euler,
                    with_component: bool = True,
                    port_name: str = "o1",
                    **kwargs) -> Component

Single bus ring made of two couplers (ct: top, cb: bottom) connected.

with two vertical straights (wyl: left, wyr: right) (Component Under Test) in the middle to extract loss from quality factor.

Arguments:

  • component - device under test.
  • gap - in um.
  • length - in um.
  • length_y - in um.
  • radius - in um.
  • coupler - coupler function.
  • bend - bend function.
  • with_component - True adds component. False adds waveguide.
  • port_name - for component input.
  • kwargs - cross_section settings.

Arguments:

  • with_component - if False changes component for just a straight.

    .. code::

    bl-wt-br | | length_y wl component | | --==cb==-- gap

    length_x

gdsfactory.components.ring_single_array

ring_single_array

@gf.cell
def ring_single_array(ring: ComponentFactory = ring_single,
                      spacing: float = 5.0,
                      list_of_dicts: tuple[dict[str, float], ...]
                      | None = None,
                      cross_section: CrossSectionSpec = "strip",
                      **kwargs) -> Component

Ring of single bus connected with straights.

Arguments:

  • ring - ring function.

  • spacing - between rings.

  • list_of_dicts - settings for each ring.

  • cross_section - spec.

  • kwargs - cross_section settings.

    .. code::


    | | | | | | length_y | | | | | | --======-- spacing ----==gap==--

    length_x

gdsfactory.components.add_grating_couplers

Add grating_couplers to a component.

add_grating_couplers

@cell
def add_grating_couplers(
        component: ComponentSpec = straight,
        grating_coupler: ComponentSpec = grating_coupler_te,
        layer_label: tuple[int, int] = (200, 0),
        gc_port_name: str = "o1",
        get_input_labels_function: LabelListFactory | None = get_input_labels,
        select_ports: Callable[..., PortsDict] = select_ports_optical,
        component_name: str | None = None) -> Component

Returns new component with grating couplers and labels.

Arguments:

  • component - to add grating_couplers.
  • grating_coupler - grating_coupler spec.
  • layer_label - for label.
  • gc_port_name - where to add label.
  • get_input_labels_function - function to get label.
  • select_ports - for selecting optical_ports.
  • component_name - optional component name.

add_grating_couplers_with_loopback_fiber_single

@cell
def add_grating_couplers_with_loopback_fiber_single(
        component: ComponentSpec = spiral_inner_io_fiber_single,
        grating_coupler: ComponentSpec = grating_coupler_te,
        layer_label: tuple[int, int] | None = (200, 0),
        gc_port_name: str = "o1",
        get_input_labels_function: LabelListFactory | None = get_input_labels,
        get_input_label_text_loopback_function:
    Callable = get_input_label_text_loopback,
        select_ports: Callable[..., PortsDict] = select_ports_optical,
        with_loopback: bool = True,
        cross_section: CrossSectionSpec = strip,
        component_name: str | None = None,
        loopback_xspacing: float = 5.0,
        rotation: int = 90) -> Component

Returns new component with all ports terminated with grating couplers.

Arguments:

  • component - to add grating_couplers.
  • grating_coupler - grating_coupler spec function, string or dict.
  • layer_label - optional layer_label for the ports.
  • gc_port_name - grating_coupler port name.
  • get_input_labels_function - function to get grating_coupler labels. get_input_label_text_loopback_function:
  • select_ports - function to select ports.
  • with_loopback - adds a reference loopback.
  • cross_section - for routing.
  • component_name - optional component name.
  • loopback_xspacing - in um.
  • rotation - in degrees, 90 for North South devices, 0 for East-West.

add_grating_couplers_with_loopback_fiber_array

@cell
def add_grating_couplers_with_loopback_fiber_array(
        component: ComponentSpec = spiral_inner_io,
        grating_coupler: ComponentSpec = grating_coupler_te,
        excluded_ports: list[str] | None = None,
        grating_separation: float = 127.0,
        bend_radius_loopback: float | None = None,
        gc_port_name: str = "o1",
        gc_rotation: int = -90,
        straight_separation: float = 5.0,
        bend: ComponentSpec = bend_euler,
        layer_label: tuple[int, int] = (200, 0),
        layer_label_loopback: tuple[int, int] | None = None,
        component_name: str | None = None,
        with_loopback: bool = False,
        nlabels_loopback: int = 2,
        get_input_labels_function: LabelListFactory | None = get_input_labels,
        cross_section: CrossSectionSpec = strip,
        select_ports: Callable = select_ports_optical,
        loopback_yspacing: float = 4.0,
        **kwargs) -> Component

Returns a component with grating_couplers and loopback.

Arguments:

  • component - to add grating_couplers.
  • grating_coupler - grating_coupler.
  • excluded_ports - list of ports to exclude.
  • grating_separation - in um.
  • bend_radius_loopback - um.
  • gc_port_name - optional grating coupler name.
  • gc_rotation - grating coupler rotation in degrees.
  • straight_separation - in um.
  • bend - bend spec.
  • layer_label - for testing label.
  • layer_label_loopback - for testing label alignment loopback.
  • component_name - optional component name.
  • with_loopback - If True, add compact loopback alignment ports.
  • nlabels_loopback - number of ports to label
  • (0 - no labels, 1: first port, 2: both ports).
  • get_input_labels_function - for getting test labels.
  • cross_section - CrossSectionSpec.
  • select_ports - function to select ports.
  • loopback_yspacing - in um.
  • kwargs - cross_section settings.

gdsfactory.components.extend_ports_list

extend_ports_list

@cell
def extend_ports_list(ports: list[Port],
                      extension: ComponentSpec,
                      extension_port_name: str | None = None,
                      ignore_ports: Strs | None = None) -> Component

Returns a component with the extensions for a list of ports.

Arguments:

  • ports - list of ports.
  • extension - function for extension.
  • extension_port_name - to connect extension.
  • ignore_ports - list of port names to ignore.

gdsfactory.components.coupler_straight_asymmetric

coupler_straight_asymmetric

@gf.cell
def coupler_straight_asymmetric(length: float = 10.0,
                                gap: float = 0.27,
                                width_top: float = 0.5,
                                width_bot: float = 1,
                                **kwargs) -> Component

Coupler with two parallel straights of different widths.

Arguments:

  • length - of straight.
  • gap - between straights.
  • width_top - of top straight.
  • width_bot - of bottom straight.
  • kwargs - cross_section settings.

gdsfactory.components.ring_single_bend_coupler

coupler_bend

@gf.cell
def coupler_bend(radius: float = 10.0,
                 coupler_gap: float = 0.2,
                 coupling_angle_coverage: float = 120.0,
                 cross_section_inner: CrossSectionSpec = "strip",
                 cross_section_outer: CrossSectionSpec = "strip",
                 bend: ComponentSpec = bend_circular) -> Component

Compact curved coupler with bezier escape.

TODO: fix for euler bends.

Arguments:

  • radius - um.

  • gap - um.

  • angle_inner - of the inner bend, from beginning to end. Depending on the bend chosen, gap may not be preserved.

  • angle_outer - of the outer bend, from beginning to end. Depending on the bend chosen, gap may not be preserved.

  • bend - for bend.

  • cross_section_inner - spec inner bend.

  • cross_section_outer - spec outer bend.

    .. code::

    r 4 | | | / 3 | / / 2_/ / 1_____/

coupler_ring_bend

@gf.cell
def coupler_ring_bend(radius: float = 10.0,
                      coupler_gap: float = 0.2,
                      coupling_angle_coverage: float = 90.0,
                      length_x: float = 0.0,
                      cross_section_inner: CrossSectionSpec = "strip",
                      cross_section_outer: CrossSectionSpec = "strip",
                      bend: ComponentSpec = bend_circular) -> Component

Two back-to-back coupler_bend.

Arguments:

  • radius - um.
  • gap - um.
  • angle_inner - of the inner bend, from beginning to end. Depending on the bend chosen, gap may not be preserved.
  • angle_outer - of the outer bend, from beginning to end. Depending on the bend chosen, gap may not be preserved.
  • bend - for bend.
  • length_x - horizontal straight length.
  • cross_section_inner - spec inner bend.
  • cross_section_outer - spec outer bend. kwargs:

ring_single_bend_coupler

@gf.cell
def ring_single_bend_coupler(radius: float = 5.0,
                             gap: float = 0.2,
                             coupling_angle_coverage: float = 180.0,
                             bend: ComponentSpec = bend_circular,
                             length_x: float = 0.6,
                             length_y: float = 0.6,
                             cross_section_inner: CrossSectionSpec = "strip",
                             cross_section_outer: CrossSectionSpec = "strip",
                             **kwargs) -> Component

Returns ring with curved coupler.

TODO: enable euler bends.

Arguments:

  • radius - um.
  • gap - um.
  • angle_inner - of the inner bend, from beginning to end. Depending on the bend chosen, gap may not be preserved.
  • angle_outer - of the outer bend, from beginning to end. Depending on the bend chosen, gap may not be preserved.
  • bend - for bend.
  • length_x - horizontal straight length.
  • length_y - vertical straight length.
  • cross_section_inner - spec inner bend.
  • cross_section_outer - spec outer bend.
  • kwargs - cross_section settings.

gdsfactory.components.compass

compass

@cell
def compass(
    size=(4.0, 2.0),
    layer: LayerSpec = "WG",
    port_type: str | None = "electrical",
    port_inclusion: float = 0.0,
    port_orientations: Ints | None = (180, 90, 0, -90)
) -> Component

Rectangle with ports on each edge (north, south, east, and west).

Arguments:

  • size - rectangle size.
  • layer - tuple (int, int).
  • port_type - optical, electrical.
  • port_inclusion - from edge.
  • port_orientations - list of port_orientations to add. None add one port only.

gdsfactory.components.via_cutback

Via cutback.

via_cutback

@gf.cell
def via_cutback(num_vias: float = 100.0,
                wire_width: float = 10.0,
                via_width: float = 5.0,
                via_spacing: float = 40.0,
                min_pad_spacing: float = 0.0,
                pad: ComponentSpec = via_stack_heater_m3,
                pad_size: Float2 = (150, 150),
                layer1: LayerSpec = "HEATER",
                layer2: LayerSpec = "M1",
                via_layer: LayerSpec = "VIAC",
                wire_pad_inclusion: float = 12.0) -> Component

Via cutback to extract via resistance.

based on phidl.geometry

Arguments:

  • num_vias - total requested vias needs to be even.
  • wire_width - width of wire.
  • via_width - width of via.
  • via_spacing - via_spacing.
  • pad_size - (width, height). min_pad_spacing. pad_layer.
  • layer1 - top wiring.
  • layer2 - bottom wiring.
  • via_layer - via.
  • wire_pad_inclusion - in um.

gdsfactory.components.spiral_heater

spiral_racetrack

@gf.cell
def spiral_racetrack(min_radius: float = 5,
                     straight_length: float = 10.0,
                     spacings: Floats = (2, 2, 3, 3, 2, 2),
                     straight_factory: ComponentFactory = straight,
                     bend_factory: ComponentFactory = bend_euler,
                     bend_s_factory: ComponentFactory = bend_s,
                     cross_section: CrossSectionSpec = "strip",
                     cross_section_s: CrossSectionSpec | None = None,
                     n_bend_points: int | None = None,
                     with_inner_ports: bool = False,
                     extra_90_deg_bend: bool = False) -> Component

Returns Racetrack-Spiral.

Arguments:

  • min_radius - smallest radius in um.
  • straight_length - length of the straight segments in um.
  • spacings - space between the center of neighboring waveguides in um.
  • straight_factory - factory to generate the straight segments.
  • bend_factory - factory to generate the bend segments.
  • bend_s_factory - factory to generate the s-bend segments.
  • cross_section - cross-section of the waveguides.
  • n_bend_points - optional bend points.
  • with_inner_ports - if True, will build the spiral, but expose the inner ports where the S-bend would be.
  • extra_90_deg_bend - if True, we add an additional straight + 90 degree bent at the output, so the output port is looking down.

spiral_racetrack_fixed_length

@gf.cell
def spiral_racetrack_fixed_length(
        length: float = 1000,
        in_out_port_spacing: float = 150,
        n_straight_sections: int = 8,
        min_radius: float = 5,
        min_spacing: float = 5.0,
        straight_factory: ComponentFactory = straight,
        bend_factory: ComponentFactory = bend_euler,
        bend_s_factory: ComponentFactory = bend_s,
        cross_section: CrossSectionSpec = "strip",
        cross_section_s: CrossSectionSpec | None = None,
        n_bend_points: int | None = None,
        with_inner_ports: bool = False) -> Component

Returns Racetrack-Spiral with a specified total length.

The input and output ports are aligned in y. This class is meant to be used for generating interferometers with long waveguide lengths, where the most important parameter is the length difference between the arms.

Arguments:

  • length - total length of the spiral from input to output ports in um.
  • in_out_port_spacing - spacing between input and output ports of the spiral in um.
  • n_straight_sections - total number of straight sections for the racetrack spiral. Has to be even.
  • min_radius - smallest radius in um.
  • min_spacing - minimum center-center spacing between adjacent waveguides.
  • straight_factory - factory to generate the straight segments.
  • bend_factory - factory to generate the bend segments.
  • bend_s_factory - factory to generate the s-bend segments.
  • cross_section - cross-section of the waveguides.
  • cross_section_s - cross-section of the s bend waveguide (optional).
  • n_bend_points - optional bend points.
  • with_inner_ports - if True, will build the spiral, but expose the inner ports where the S-bend would be.

spiral_racetrack_heater_metal

@gf.cell
def spiral_racetrack_heater_metal(
        min_radius: float | None = None,
        straight_length: float = 30,
        spacing: float = 2,
        num: int = 8,
        straight_factory: ComponentFactory = straight,
        bend_factory: ComponentFactory = bend_euler,
        bend_s_factory: ComponentFactory = bend_s,
        waveguide_cross_section: CrossSectionSpec = "strip",
        heater_cross_section: CrossSectionSpec = "heater_metal") -> Component

Returns spiral racetrack with a heater above.

based on Qiu et al. (2020) .

Arguments:

  • min_radius - smallest radius.
  • straight_length - length of the straight segments.
  • spacing - space between the center of neighboring waveguides.
  • num - number.
  • straight_factory - factory to generate the straight segments.
  • bend_factory - factory to generate the bend segments.
  • bend_s_factory - factory to generate the s-bend segments.
  • waveguide_cross_section - cross-section of the waveguides.
  • heater_cross_section - cross-section of the heater.

spiral_racetrack_heater_doped

@gf.cell
def spiral_racetrack_heater_doped(
        min_radius: float | None = None,
        straight_length: float = 30,
        spacing: float = 2,
        num: int = 8,
        straight_factory: ComponentFactory = straight,
        bend_factory: ComponentFactory = bend_euler,
        bend_s_factory: ComponentFactory = bend_s,
        waveguide_cross_section: CrossSectionSpec = "strip",
        heater_cross_section: CrossSectionSpec = "npp") -> Component

Returns spiral racetrack with a heater between the loops.

based on Qiu et al. (2020) but with the heater between the loops.

Arguments:

  • min_radius - smallest radius in um.
  • straight_length - length of the straight segments in um.
  • spacing - space between the center of neighboring waveguides in um.
  • num - number.
  • straight_factory - factory to generate the straight segments.
  • bend_factory - factory to generate the bend segments.
  • bend_s_factory - factory to generate the s-bend segments.
  • waveguide_cross_section - cross-section of the waveguides.
  • heater_cross_section - cross-section of the heater.

gdsfactory.components.ramp

ramp

@gf.cell
def ramp(length: float = 10.0,
         width1: float = 5.0,
         width2: float | None = 8.0,
         layer: LayerSpec = "WG") -> Component

Return a ramp component.

Based on phidl.

Arguments:

  • length - Length of the ramp section.
  • width1 - Width of the start of the ramp section.
  • width2 - Width of the end of the ramp section (defaults to width1).
  • layer - Specific layer to put polygon geometry on.

gdsfactory.components.via

via

@gf.cell
def via(size: tuple[float, float] = (0.7, 0.7),
        spacing: tuple[float, float] | None = (2.0, 2.0),
        gap: tuple[float, float] | None = None,
        enclosure: float = 1.0,
        layer: LayerSpec = "VIAC",
        bbox_layers: tuple[tuple[int, int], ...] | None = None,
        bbox_offset: float = 0) -> Component

Rectangular via.

Defaults to a square via.

Arguments:

  • size - in x, y direction.

  • spacing - pitch_x, pitch_y.

  • gap - edge to edge via gap in x, y.

  • enclosure - inclusion of via.

  • layer - via layer.

  • bbox_layers - layers for the bounding box.

  • bbox_offset - in um.

    .. code::

    enclosure


    |<---> | | gap[0] size[0] | | <------> <-----> | | ______ ______ | | | | | | | | | | | | size[1] | | || || | | <-------------> | | spacing[0] | |_______________________________________|

gdsfactory.components.delay_snake3

delay_snake3

@gf.cell
def delay_snake3(length: float = 1600.0,
                 length0: float = 0.0,
                 length2: float = 0.0,
                 n: int = 2,
                 bend180: ComponentSpec = bend_euler180,
                 cross_section: CrossSectionSpec = "strip",
                 **kwargs) -> Component

Returns Snake with a starting bend and 180 bends.

Arguments:

  • length - total length.

  • length0 - start length.

  • length2 - end length.

  • n - number of loops.

  • bend180 - ubend spec.

  • cross_section - cross_section spec.

  • kwargs - cross_section settings.

    .. code::

    | length0 |

    ---------
    \bend180.info[‘length’] / |-------------------/ | |------------------->------->| length2 | delta_length | |

gdsfactory.components.coupler90

coupler90

@gf.cell
def coupler90(gap: float = 0.2,
              radius: float = 10.0,
              bend: ComponentSpec = bend_euler,
              straight: ComponentSpec = straight,
              cross_section: CrossSectionSpec = "strip",
              bend_cross_section: CrossSectionSpec | None = None,
              **kwargs) -> Component

Straight coupled to a bend.

Arguments:

  • gap - um.

  • radius - um.

  • straight - for straight.

  • bend - bend spec.

  • cross_section - cross_section spec.

  • bend_cross_section - optional bend cross_section spec.

  • kwargs - cross_section settings.

    .. code::

    3 | / / 2_/ 1____4

gdsfactory.components.wire

Wires for electrical manhattan routes.

wire_corner

@gf.cell
def wire_corner(cross_section: CrossSectionSpec = "metal_routing",
                with_bbox: bool = False,
                **kwargs) -> Component

Returns 45 degrees electrical corner wire.

Arguments:

  • cross_section - spec.
  • with_bbox - if True, includes the bbox layer and bbox offsets of the cross_section
  • kwargs - cross_section settings.

wire_corner45

@gf.cell
def wire_corner45(cross_section: CrossSectionSpec = "metal_routing",
                  radius: float = 10,
                  with_bbox: bool = False,
                  **kwargs) -> Component

Returns 90 degrees electrical corner wire.

Arguments:

  • cross_section - spec.
  • with_bbox - if True, includes the bbox layer and bbox offsets of the cross_section
  • kwargs - cross_section settings.

wire_corner_sections

@gf.cell
def wire_corner_sections(cross_section: CrossSectionSpec = "metal_routing",
                         with_bbox: bool = False,
                         **kwargs) -> Component

Returns 90 degrees electrical corner wire, where all cross_section sections properly represented.

Works well with symmetric cross_sections, not quite ready for asymmetric.

Arguments:

  • cross_section - spec.
  • with_bbox - if True, includes the bbox layer and bbox offsets of the cross_section
  • kwargs - cross_section settings.

gdsfactory.components.component_lattice

get_sequence_cross

def get_sequence_cross(straights_start,
                       straights_end,
                       iter_max: int = 100,
                       symbols=("X", "-"))

Returns sequence of crossings to achieve the permutations between two columns of I/O.

Arguments:

  • straights_start - list of the input port indices.
  • straights_end - list of the output port indices.
  • iter_max - maximum iterations.
  • symbols - [X , S].

Notes:

symbols to be used in the returned sequence:

  • X:represents the crossing symbol: two Xs next to each-other means that the two modes have to be swapped
  • S:Straight straight, or compensation path typically

component_sequence_to_str

def component_sequence_to_str(sequence)

Transform a sequence of components (such as the one obtained from.

get_sequence_cross_str) into an ASCII block which can be used either as a cartoon or as an input for component_lattice(lattice = ...)

component_lattice

@gf.cell
def component_lattice(lattice: str = """
        C-X
        CXX
        CXX
        C-X
        """,
                      symbol_to_component: dict[str, Component] | None = None,
                      grid_per_unit: int = 1000) -> Component

Return a lattice Component of N inputs and outputs Columns must have.

components with the same x spacing between input/output ports Lines must have components with the same y spacing between input/output ports.

Arguments:

  • lattice - ASCII map with character.

  • symbol_to_component - dict of ASCII character to component.

  • grid_per_unit - int.

    Lattice example:

    .. code::

    X-X XCX XCX X-X

    .. plot:: :include-source:

    import gdsfactory as gf from gdsfactory.components.crossing_waveguide import crossing45 from gdsfactory.components.crossing_waveguide import compensation_path

    symbol_to_component = {

  • "C" - gf.routing.fanout2x2(component=gf.components.coupler(), port_spacing=40.0),

  • "X" - crossing45(port_spacing=40.0),

  • "-" - compensation_path(crossing45=crossing45(port_spacing=40.0)), } c = gf.components.component_lattice(symbol_to_component=symbol_to_component) c.plot()

parse_lattice

def parse_lattice(
    lattice: str, symbol_to_component: dict[str, Component]
) -> tuple[dict[int, list[str]], dict[int, float64]]

Extract each column.

Arguments:

  • lattice - string describing lattice.
  • symbol_to_component - dict of ASCII character to component.

gdsfactory.components.taper_from_csv

Adiabatic tapers from CSV files.

taper_from_csv

@gf.cell
def taper_from_csv(filepath: Path = data / "taper_strip_0p5_3_36.csv",
                   cross_section: CrossSectionSpec = "strip") -> Component

Returns taper from CSV file.

Arguments:

  • filepath - for CSV file.
  • cross_section - specification (CrossSection, string, CrossSectionFactory dict).

gdsfactory.components.coupler_broadband

coupler_broadband

@gf.cell
def coupler_broadband(w_sc: float = 0.5,
                      gap_sc: float = 0.2,
                      w_top: float = 0.6,
                      gap_pc: float = 0.3,
                      legnth_taper: float = 1.0,
                      bend: ComponentFactory = bend_euler,
                      coupler_straight: ComponentFactory = coupler_straight,
                      length_coupler_straight: float = 12.4,
                      lenght_coupler_big_gap: float = 4.7,
                      cross_section: CrossSectionSpec = "strip",
                      radius: float = 10.0) -> Component

Returns broadband coupler component.

https://docs.flexcompute.com/projects/tidy3d/en/latest/notebooks/BroadbandDirectionalCoupler.html proposed in Zeqin Lu, Han Yun, Yun Wang, Zhitian Chen, Fan Zhang, Nicolas A. F. Jaeger, and Lukas Chrostowski, “Broadband silicon photonic directional coupler using asymmetric-waveguide based phase control,” Opt. Express 23, 3795-3808 (2015), DOI: 10.1364/OE.23.003795.

Arguments:

  • w_sc - width of waveguides in the symmetric coupler section.
  • gap_sc - gap size between the waveguides in the symmetric coupler section.
  • w_top - width of the top waveguide in the phase control section.
  • gap_pc - gap size in the phase control section.
  • legnth_taper - length of the tapers.
  • bend - bend factory.
  • coupler_straight - coupler_straight factory.
  • length_coupler_straight - optimal L_1 from the 3d fdtd analysis.
  • lenght_coupler_big_gap - optimal L_2 from the 3d fdtd analysis.
  • cross_section - cross_section of the waveguides.
  • radius - bend radius.

gdsfactory.components.ring_section_based

Generates a ring resonator based on a series of given cross sections.

This is useful to generate interleaved junction rings or rings with relatively complex junction profiles

ring_section_based

@cell_without_validator
def ring_section_based(gap: float | Floats = 0.3,
                       radius: float = 5.0,
                       add_drop: bool = False,
                       cross_sections: dict[str, str] = def_dict,
                       cross_sections_sequence: str | list[str]
                       | tuple[str, ...] = "AB",
                       cross_sections_angles: dict[str, float]
                       | None = def_ang_dict,
                       start_cross_section: CrossSectionSpec | None = None,
                       start_angle: float | None = 10.0,
                       drop_cross_section: CrossSectionSpec | None = None,
                       bus_cross_section: CrossSectionSpec = "strip",
                       ang_res: float | None = 0.1) -> gf.Component

Returns a ring made of the specified cross sections.

We start with start_cross section if indicated, then repeat the sequence in cross_section_sequence until the whole ring is filled.

Arguments:

  • gap - bus waveguide - ring gap.
  • radius - ring radius.
  • add_drop - if True, we draw an add-drop ring
  • cross_sections - dictionary of cross sections to add consecutively to the ring until the ring is filled. Keys should be single character.
  • cross_sections_sequence - sequence to follow filling the ring.
  • Ex - “AB” means we will put first section A, then section B, then section A again... until the ring is filled If we have a drop, then this can be a list of two strings, where the first sequence is for one side of the ring and the second for the other side of the ring
  • cross_sections_angles - angular extent of each cross section in the cross_sections dictionary (deg). If not indicated, then we assume that the sequence is only repeated once and calculate the necessary angular length
  • start_cross_section - it is likely that the cross section at the ring-bus junction is different than the sequence we want to repeat. If that’s the case, then here you indicate the initial cross section.
  • start_angle - angular extent of the initial cross section (deg)
  • drop_cross_section - cross section for the drop port. If not indicated, we assume it is the same as init_cross_section.
  • bus_cross_section - cross section for the bus waveguide.
  • ang_res - angular resolution to draw the bends for each section.

gdsfactory.components.add_fiducials

add_fiducials

@cell
def add_fiducials(component: ComponentSpec = pad_array,
                  gap: float = 50,
                  left: ComponentSpec | None = "cross",
                  right: ComponentSpec | None = "cross",
                  top: ComponentSpec | None = None,
                  bottom: ComponentSpec | None = None,
                  offset: Float2 = (0, 0),
                  **kwargs) -> Component

Return component with fiducials.

Arguments:

  • component - component to add to the new component.
  • gap - from component to fiducial edge.
  • left - optional left fiducial.
  • right - optional right fiducial.
  • top - optional top fiducial.
  • bottom - optional bottom fiducial.
  • offset - component offset coordinate (x, y).
  • kwargs - fiducial settings.

add_fiducials_offsets

@cell
def add_fiducials_offsets(
    component: ComponentSpec = pad_array,
    fiducial: ComponentSpec = "cross",
    offsets: Coordinates = ((0, 100), (0, -100))
) -> Component

Returns new component with fiducials from a list of offsets.

Arguments:

  • component - add reference to component to the new Component.
  • fiducial - function to return fiducial.
  • offsets - list of offsets.

gdsfactory.components.ring

ring

@gf.cell
def ring(radius: float = 10.0,
         width: float = 0.5,
         angle_resolution: float = 2.5,
         layer: LayerSpec = "WG",
         angle: float | None = 360) -> Component

Returns a ring.

Arguments:

  • radius - ring radius.
  • width - of the ring.
  • angle_resolution - number of points per degree.
  • layer - layer.
  • angle - angular coverage of the ring

gdsfactory.components.straight_heater_metal

straight_heater_metal_undercut

@cell
def straight_heater_metal_undercut(
        length: float = 320.0,
        length_undercut_spacing: float = 6.0,
        length_undercut: float = 30.0,
        length_straight_input: float = 15.0,
        heater_width: float = 2.5,
        cross_section_heater: CrossSectionSpec = "heater_metal",
        cross_section_waveguide_heater: CrossSectionSpec = "strip_heater_metal",
        cross_section_heater_undercut:
    CrossSectionSpec = "strip_heater_metal_undercut",
        with_undercut: bool = True,
        via_stack: ComponentSpec | None = "via_stack_heater_mtop",
        port_orientation1: int | None = None,
        port_orientation2: int | None = None,
        heater_taper_length: float | None = 5.0,
        ohms_per_square: float | None = None,
        **kwargs) -> Component

Returns a thermal phase shifter.

dimensions from Jacques et al. (2019)

Arguments:

  • length - of the waveguide.
  • length_undercut_spacing - from undercut regions.
  • length_undercut - length of each undercut section.
  • length_straight_input - from input port to where trenches start.
  • heater_width - in um.
  • cross_section_heater - for heated sections. heater metal only.
  • cross_section_waveguide_heater - for heated sections.
  • cross_section_heater_undercut - for heated sections with undercut.
  • with_undercut - isolation trenches for higher efficiency.
  • via_stack - via stack.
  • port_orientation1 - left via stack port orientation.
  • port_orientation2 - right via stack port orientation.
  • heater_taper_length - minimizes current concentrations from heater to via_stack.
  • ohms_per_square - to calculate resistance.
  • cross_section - for waveguide ports.
  • kwargs - cross_section common settings.

straight_heater_metal_simple

@cell
def straight_heater_metal_simple(
        length: float = 320.0,
        length_straight_input: float = 15.0,
        heater_width: float = 2.5,
        cross_section_heater: CrossSectionSpec = "heater_metal",
        cross_section_waveguide_heater: CrossSectionSpec = "strip_heater_metal",
        via_stack: ComponentSpec | None = "via_stack_heater_mtop",
        port_orientation1: int | None = None,
        port_orientation2: int | None = None,
        heater_taper_length: float | None = 5.0,
        ohms_per_square: float | None = None,
        **kwargs) -> Component

Returns a thermal phase shifter that has properly fixed electrical connectivity to extract a suitable electrical netlist and models. dimensions from Jacques et al. (2019)

Arguments:

  • length - of the waveguide.
  • length_undercut_spacing - from undercut regions.
  • length_undercut - length of each undercut section.
  • length_straight_input - from input port to where trenches start.
  • heater_width - in um.
  • cross_section_heater - for heated sections. heater metal only.
  • cross_section_waveguide_heater - for heated sections.
  • cross_section_heater_undercut - for heated sections with undercut.
  • with_undercut - isolation trenches for higher efficiency.
  • via_stack - via stack.
  • port_orientation1 - left via stack port orientation.
  • port_orientation2 - right via stack port orientation.
  • heater_taper_length - minimizes current concentrations from heater to via_stack.
  • ohms_per_square - to calculate resistance.
  • cross_section - for waveguide ports.
  • kwargs - cross_section common settings.

gdsfactory.components.mzi_arm

mzi_arm

@cell
def mzi_arm(length_y_left: float = 0.8,
            length_y_right: float = 0.8,
            length_x: float = 0.1,
            bend: ComponentSpec = bend_euler,
            straight: ComponentSpec = straight_function,
            straight_x: ComponentSpec | None = None,
            straight_y: ComponentSpec | None = None,
            **kwargs) -> Component

Mzi.

Arguments:

  • length_y_left - vertical length.

  • length_y_right - vertical length.

  • length_x - horizontal length.

  • bend - 90 degrees bend library.

  • straight - straight function.

  • straight_x - straight for length_x.

  • straight_y - straight for length_y.

  • kwargs - cross_section settings.

    .. code::

    B__Lx__B | | Ly Lyr | | B B

gdsfactory.components.straight_array

straight_array

@gf.cell
def straight_array(n: int = 4,
                   spacing: float = 4.0,
                   straight: ComponentSpec = straight_function,
                   **kwargs) -> Component

Array of straights connected with grating couplers.

useful to align the 4 corners of the chip

Arguments:

  • n - number of straights.
  • spacing - edge to edge straight spacing.
  • straight - straight straight Component or library.
  • kwargs - straight settings.

gdsfactory.components.splitter_chain

splitter_chain

@gf.cell
def splitter_chain(splitter: ComponentSpec = mmi1x2,
                   columns: int = 3,
                   bend: ComponentSpec = bend_s) -> Component

Chain of splitters.

Arguments:

  • splitter - splitter to chain.

  • columns - number of splitters to chain.

  • bend - bend to connect splitters.

    .. code::

    __o5 __| __| |__o4 o1 _| |__o3 |__o2

    __o2 o1 _| |__o3

gdsfactory.components.straight_pin

Straight Doped PIN waveguide.

straight_pin

@gf.cell
def straight_pin(length: float = 500.0,
                 cross_section: CrossSectionSpec = pin,
                 via_stack: ComponentSpec = via_stack_slab_m3,
                 via_stack_width: float = 10.0,
                 via_stack_spacing: float = 2,
                 taper: ComponentSpec | None = taper_strip_to_ridge,
                 **kwargs) -> Component

Returns rib waveguide with doping and via_stacks used for PN and PIN modulators.

For PIN: Fatemi et al. (2018)

500um length for PI phase shift https://ieeexplore.ieee.org/document/8268112

to go beyond 2PI, you will need at least 1mm https://ieeexplore.ieee.org/document/8853396/

For PN: Typical lengths in practice are 2-5mm depending on doping,engineering and application: https://opg.optica.org/oe/fulltext.cfm?uri=oe-21-25-30350&id=275107 https://opg.optica.org/oe/fulltext.cfm?uri=oe-20-11-12014&id=233271

Arguments:

  • length - of the waveguide.
  • cross_section - for the waveguide.
  • via_stack - for the via_stacks.
  • via_stack_width - width of the via_stack.
  • via_stack_spacing - spacing between via_stacks.
  • taper - optional taper.
  • kwargs - cross_section settings.

gdsfactory.components.straight_heater_doped_strip

Top view.

.. code::

                      length
  <-|--------|--------------------------------->
    |        | length_section
    |<--------------------------->
   length_via_stack
    |<------>|
    |________|_______________________________
   /|        |____________________|          |
  / |viastack|                    |via_stack |
  \ | size   |____________________|          |
   \|________|____________________|__________|
                                  |          |
              cross_section_heater|          |
                                  |          |
                                  |          |
                                  |__________|

cross_section

.. code::

                          |<------width------>|
  ____________             ___________________               ______________
 |            |           |     undoped Si    |             |              |
 |layer_heater|           |  intrinsic region |<----------->| layer_heater |
 |____________|           |___________________|             |______________|
                                                             <------------>
                                                heater_gap     heater_width

gdsfactory.components.cdc

cdc

@gf.cell
def cdc(length: float = 30.0,
        gap: float = 0.5,
        period: float = 0.220,
        dc: float = 0.5,
        dx: float = 10.0,
        dy: float = 5.0,
        width_top: float = 2.0,
        width_bot: float = 0.75,
        fins: bool = False,
        fin_size: tuple[float, float] = (0.2, 0.05),
        cross_section: CrossSectionSpec = strip,
        **kwargs) -> Component

Grating-Assisted Contra-Directional Coupler.

Arguments:

length : Length of the coupling region.

  • gap - Distance between the two straights.

  • period - Period of the grating.

  • dc - Duty cycle of the grating. Must be between 0 and 1.

  • width_top - Width of the top straight in the coupling region.

  • width_bot - Width of the bottom straight in the coupling region.

  • dx - size of bends in x-direction.

  • dy - size of bends in y-direction.

  • fins - If True, adds fins to the input/output straights. In this case a different template for the component must be specified. This feature is useful when performing electron-beam lithography and using different beam currents for fine features (helps to reduce stitching errors).

  • fin_size - Specifies the x- and y-size of the fins. Defaults to 200 nm x 50 nm.

  • cross_section - CrossSection spec.

    kwargs: cross_section kwargs.

gdsfactory.components.mzi_lattice

mzi_lattice

@cell
def mzi_lattice(coupler_lengths: tuple[float, ...] = (10.0, 20.0),
                coupler_gaps: tuple[float, ...] = (0.2, 0.3),
                delta_lengths: tuple[float, ...] = (10.0, ),
                mzi: ComponentSpec = mzi_coupler,
                splitter: ComponentSpec = coupler_function,
                **kwargs) -> Component

Mzi lattice filter.

Arguments:

  • coupler_lengths - list of length for each coupler.

  • coupler_gaps - list of coupler gaps.

  • delta_lengths - list of length differences.

  • mzi - function for the mzi.

  • splitter - splitter function.

    keyword Args:

  • length_y - vertical length for both and top arms.

  • length_x - horizontal length.

  • bend - 90 degrees bend library.

  • straight - straight function.

  • straight_y - straight for length_y and delta_length.

  • straight_x_top - top straight for length_x.

  • straight_x_bot - bottom straight for length_x.

  • cross_section - for routing (sxtop/sxbot to combiner).

    .. code::


    | | | | | | | | cp1==| |===cp2=====| |=== .... ===cp_last=== | | | | | | | | DL1 | DL2 | | | | | || | | ||

mzi_lattice_mmi

@cell
def mzi_lattice_mmi(coupler_widths=(None, None),
                    coupler_widths_tapers: tuple[float, ...] = (
                        1.0,
                        1.0,
                    ),
                    coupler_lengths_tapers: tuple[float, ...] = (
                        10.0,
                        10.0,
                    ),
                    coupler_lengths_mmis: tuple[float, ...] = (
                        5.5,
                        5.5,
                    ),
                    coupler_widths_mmis: tuple[float, ...] = (
                        2.5,
                        2.5,
                    ),
                    coupler_gaps_mmis: tuple[float, ...] = (
                        0.25,
                        0.25,
                    ),
                    taper_functions_mmis=(
                        taper_function,
                        taper_function,
                    ),
                    straight_functions_mmis=(straight_function,
                                             straight_function),
                    cross_sections_mmis=("strip", "strip"),
                    delta_lengths: tuple[float, ...] = (10.0, ),
                    mzi=mmi_coupler_function,
                    splitter=mmi_splitter_function,
                    **kwargs) -> Component

Mzi lattice filter, with MMI couplers.

Arguments:

  • coupler_widths - (for each MMI coupler, list of) input and output straight width.

  • coupler_widths_tapers - (for each MMI coupler, list of) interface between input straights and mmi region.

  • coupler_lengths_tapers - (for each MMI coupler, list of) into the mmi region.

  • coupler_lengths_mmis - (for each MMI coupler, list of) in x direction.

  • coupler_widths_mmis - (for each MMI coupler, list of) in y direction.

  • coupler_gaps_mmis - (for each MMI coupler, list of) (width_taper + gap between tapered wg)/2.

  • taper_functions_mmis - (for each MMI coupler, list of) taper function.

  • straight_functions_mmis - (for each MMI coupler, list of) straight function.

  • cross_sections_mmis - (for each MMI coupler, list of) spec.

  • delta_lengths - list of length differences.

  • mzi - function for the mzi.

  • splitter - splitter function.

    keyword Args:

  • length_y - vertical length for both and top arms.

  • length_x - horizontal length.

  • bend - 90 degrees bend library.

  • straight - straight function.

  • straight_y - straight for length_y and delta_length.

  • straight_x_top - top straight for length_x.

  • straight_x_bot - bottom straight for length_x.

  • cross_section - for routing (sxtop/sxbot to combiner).

    .. code::


    | | | | | | | | cp1==| |===cp2=====| |=== .... ===cp_last=== | | | | | | | | DL1 | DL2 | | | | | || | | ||

gdsfactory.components.cdsem_coupler

CD SEM structures.

cdsem_coupler

@cell
def cdsem_coupler(width: float = 0.45,
                  length: float = 420.0,
                  gaps: tuple[float, ...] = (0.15, 0.2, 0.25),
                  cross_section: CrossSectionSpec = "strip",
                  text: ComponentSpec | None = text_rectangular_mini,
                  spacing: float = 3) -> Component

Returns 2 coupled waveguides gap sweep.

Arguments:

  • width - for the waveguide.
  • length - for the line.
  • gaps - list of gaps for the sweep.
  • cross_section - for the lines.
  • text - optional text for labels.
  • spacing - edge to edge spacing.

gdsfactory.components.ring_double_pn

ring_double_pn

@gf.cell
def ring_double_pn(add_gap: float = 0.3,
                   drop_gap: float = 0.3,
                   radius: float = 5.0,
                   doping_angle: float = 85,
                   cross_section: CrossSectionFactory = cross_section_rib,
                   pn_cross_section: CrossSectionFactory = cross_section_pn,
                   doped_heater: bool = True,
                   doped_heater_angle_buffer: float = 10,
                   doped_heater_layer: LayerSpec = "NPP",
                   doped_heater_width: float = 0.5,
                   doped_heater_waveguide_offset: float = 2.175,
                   heater_vias: ComponentSpec = heater_vias,
                   **kwargs) -> gf.Component

Returns add-drop pn ring with optional doped heater.

Arguments:

  • add_gap - gap to add waveguide.
  • drop_gap - gap to drop waveguide.
  • radius - for the bend and coupler.
  • doping_angle - angle in degrees representing portion of ring that is doped.
  • length_x - ring coupler length.
  • length_y - vertical straight length.
  • cross_section - cross_section spec for non-PN doped rib waveguide sections.
  • pn_cross_section - cross section of pn junction.
  • doped_heater - boolean for if we include doped heater or not.
  • doped_heater_angle_buffer - angle in degrees buffering heater from pn junction.
  • doped_heater_layer - doping layer for heater.
  • doped_heater_width - width of doped heater.
  • doped_heater_waveguide_offset - distance from the center of the ring waveguide to the center of the doped heater.
  • heater_vias - components specifications for heater vias
  • kwargs - cross_section settings.

gdsfactory.components.logo

@cell
def logo(text: str = "GDSFACTORY") -> Component

Returns GDSfactory logo.

gdsfactory.components.triangles

triangle

@cell
def triangle(x: float = 10,
             xtop: float = 0,
             y: float = 20,
             ybot: float = 0,
             layer: LayerSpec = "WG") -> Component

Return triangle.

Arguments:

  • x - base xsize.

  • xtop - top xsize.

  • y - ysize.

  • ybot - bottom ysize.

  • layer - layer.

    .. code::

    xtop _ |
    |
    |
    y|
    |
    |
    |______|ybot x

triangle2

@cell
def triangle2(spacing: float = 3, **kwargs)

Return 2 triangles (bot, top).

Arguments:

  • spacing - between top and bottom.

Arguments:

  • x - base xsize.

  • xtop - top xsize.

  • y - ysize.

  • ybot - bottom ysize.

  • layer - layer.

    .. code:: _ |
    |
    |
    |
    |
    |
    |
    | | spacing | / | / | / | / | / |_/

triangle4

@cell
def triangle4(**kwargs)

Return 4 triangles.

Arguments:

  • x - base xsize.

  • xtop - top xsize.

  • y - ysize.

  • ybot - bottom ysize.

  • layer - layer.

    .. code::

    / |
    / |
    / |
    / |
    / |
    / |
    / |
    | | | \ | / \ | / \ | / \ | / \ | / \ |_/

gdsfactory.components.loop_mirror

Sagnac loop_mirror.

loop_mirror

@gf.cell
def loop_mirror(component: ComponentSpec = mmi1x2,
                bend90: ComponentSpec = "bend_euler") -> Component

Returns Sagnac loop_mirror.

Arguments:

  • component - 1x2 splitter.
  • bend90 - 90 deg bend.

loop_mirror_with_delay

@gf.cell
def loop_mirror_with_delay(
        loop_mirror: ComponentSpec = loop_mirror,
        spiral: ComponentSpec = spiral_external_io) -> Component

Returns loop_mirror with spiral for delay.

Arguments:

  • loop_mirror - loop_mirror spec.
  • spiral - for delay.

Notes:

Delay = 13e-12.

delay = length/speed

length=delay*speed

13e-123e8/4.21e6

gdsfactory.components.grating_coupler_rectangular_arbitrary_slab

grating_coupler_rectangular_arbitrary_slab

@gf.cell
def grating_coupler_rectangular_arbitrary_slab(
        gaps: Floats = _gaps,
        widths: Floats = _widths,
        width_grating: float = 11.0,
        length_taper: float = 150.0,
        polarization: str = "te",
        wavelength: float = 1.55,
        taper: ComponentSpec = taper_strip_to_slab150,
        layer_slab: LayerSpec | None = "SLAB150",
        slab_offset: float = 2.0,
        fiber_angle: float = 15,
        cross_section: CrossSectionSpec = "strip",
        **kwargs) -> Component

Grating coupler uniform (grating with rectangular shape not elliptical). Therefore it needs a longer taper. Grating teeth are straight instead of elliptical.

Arguments:

  • gaps - list of gaps.

  • widths - list of widths.

  • width_grating - um.

  • length_taper - um.

  • polarization - ‘te’ or ‘tm’.

  • wavelength - in um.

  • taper - function.

  • layer_slab - for pedestal.

  • slab_offset - from edge.

  • fiber_angle - in degrees.

  • cross_section - for input waveguide port.

  • kwargs - cross_section settings.

    .. code::

    side view fiber

    / / / / / / / /

    |-||-||-|__ layer layer_slab | o1 ______________|

    top view _________ /| | | | | / | | | | | /taper_angle /_ | | | | | wg_width | | | | | | \ | | | | | \ | | | | | \ | | | | | ||||_| <--> taper_length

gdsfactory.labels.write_labels

Find GDS labels and write them to a CSV file.

find_labels

def find_labels(gdspath: PathType,
                layer_label: LayerSpec = "LABEL",
                prefix: str = "opt_") -> Iterator[tuple[str, float, float]]

Return text label and locations iterator from a GDS file.

Klayout does not support label rotations.

Arguments:

  • gdspath - for the gds.

  • layer_label - for the labels.

  • prefix - for the labels to select.

    Returns

  • string - for the label.

  • x - x position (um).

  • y - y position (um).

  • angle - in degrees.

write_labels_klayout

def write_labels_klayout(gdspath: PathType,
                         layer_label: LayerSpec = "LABEL",
                         filepath: PathType | None = None,
                         prefix: str = "opt_") -> Path

Load GDS and extracts labels in KLayout text and coordinates.

Returns CSV filepath with each row:

  • Text
  • x
  • y
  • rotation (degrees)

Arguments:

  • gdspath - for the mask.
  • layer_label - for labels to write.
  • filepath - for CSV file. Defaults to gdspath with CSV suffix.
  • prefix - for the labels to write.

write_labels_gdstk

def write_labels_gdstk(gdspath: Path,
                       prefixes: list[str] = ("opt", "elec"),
                       layer_label: LayerSpec = "LABEL",
                       filepath: PathType | None = None,
                       debug: bool = False) -> Path

Load GDS and extracts label text and coordinates.

Returns CSV filepath with each row:

  • Text
  • x
  • y
  • rotation (degrees)

Arguments:

  • gdspath - for the mask.
  • prefix - for the labels to write.
  • layer_label - for labels to write.
  • filepath - for CSV file. Defaults to gdspath with CSV suffix.
  • debug - prints the label.

gdsfactory.labels.add_label_yaml

Add label YAML.

add_label_yaml

@pydantic.validate_call
def add_label_yaml(
        component: gf.Component,
        port_prefixes: list[str] = ("opt_", "_elec"),
        layer: LayerSpec = "LABEL",
        metadata_ignore: list[str] | None = ignore,
        metadata_include_parent: list[str] | None = None,
        metadata_include_child: list[str] | None = None) -> gf.Component

Returns Component with measurement label.

Arguments:

  • component - to add labels to.
  • port_types - list of port types to label.
  • layer - text label layer.
  • metadata_ignore - list of settings keys to ignore. Works with flatdict setting:subsetting.
  • metadata_include_parent - parent metadata keys to include. Works with flatdict setting:subsetting.
  • metadata_include_child - child metadata keys to include.

gdsfactory.labels

Design For Testing module includes test protocols.

gdsfactory.labels.merge_test_metadata

Merge mask metadata with test labels to return test_metadata.

parse_csv_data

def parse_csv_data(csv_labels_path: Path,
                   ignore_prefix: str = "METR_") -> list[list[str]]

Returns CSV labels as a list of strings.

get_cell_from_label_brackets

def get_cell_from_label_brackets(label: str) -> str

Get cell name from the label (cell_name is in parenthesis).

component_name_from_string_with_dashes

def component_name_from_string_with_dashes(label: str) -> str

Returns cell_name assuming opt-GratingName-ComponentName-PortName

merge_test_metadata

def merge_test_metadata(labels_path: PathType,
                        mask_metadata: dict[str, Any],
                        component_name_from_string:
                        Callable = component_name_from_string_with_dashes,
                        filepath: PathType | None = None) -> DictConfig

Returns a test metadata dict config of labeled cells by merging GDS labels in CSV and YAML mask metadata.

Arguments:

  • labels_path - for test labels in CSV.

  • mask_metadata - dict with test metadata.

  • component_name_from_string - returns label string.

  • filepath - Optional path to write test metadata.

    .. code::

    CSV labels ------- |--> merge_test_metadata dict | YAML metadata ----

gdsfactory.labels.ehva

add_label_ehva

@pydantic.validate_call
def add_label_ehva(
        component: gf.Component,
        die: str = "demo",
        prefix_to_type: dict[str, str] = prefix_to_type_default,
        layer: Layer = (66, 0),
        metadata_ignore: list[str] | None = None,
        metadata_include_parent: list[str] | None = None,
        metadata_include_child: list[str] | None = None) -> gf.Component

Returns Component with measurement labels.

Arguments:

  • component - to add labels to.
  • die - string.
  • port_types - list of port types to label.
  • layer - text label layer.
  • metadata_ignore - list of settings keys to ignore. Works with flatdict setting:subsetting.
  • metadata_include_parent - includes parent metadata. Works with flatdict setting:subsetting.

gdsfactory.labels.siepic

SiEPIC labels one grating coupler from the fiber array using a GDS label.

get_input_label_text

def get_input_label_text(port: Port,
                         gc: ComponentReference,
                         gc_index: int | None = None,
                         component_name: str | None = None,
                         username: str = "YourUserName") -> str

Return label for port and a grating coupler.

Arguments:

  • port - component port.
  • gc - grating coupler reference.
  • gc_index - grating coupler index.
  • component_name - optional component name.
  • username - for the label.

get_input_labels

def get_input_labels(
    io_gratings: list[ComponentReference],
    ordered_ports: list[Port],
    component_name: str,
    layer_label: tuple[int, int] = (10, 0),
    gc_port_name: str = "o1",
    port_index: int = 1,
    get_input_label_text_function: Callable = get_input_label_text
) -> list[Label]

Return list of labels for all component ports.

Arguments:

  • io_gratings - list of grating_coupler references.
  • ordered_ports - list of ports.
  • component_name - name.
  • layer_label - for the label.
  • gc_port_name - grating_coupler port.
  • port_index - index of the port.
  • get_input_label_text_function - function.

add_fiber_array_siepic

@cell
def add_fiber_array_siepic(
        component: ComponentSpec = straight,
        component_name: str | None = None,
        gc_port_name: str = "o1",
        get_input_labels_function: Callable = get_input_labels,
        with_loopback: bool = False,
        optical_routing_type: int = 0,
        fanout_length: float = 0.0,
        grating_coupler: ComponentSpec = grating_coupler_te,
        cross_section: CrossSectionSpec = "strip",
        layer_label: LayerSpec = (10, 0),
        **kwargs) -> Component

Returns component with grating couplers and labels on each port.

Routes all component ports south. Can add align_ports loopback reference structure on the edges.

Arguments:

  • component - to connect.
  • component_name - for the label.
  • gc_port_name - grating coupler input port name ‘o1’.
  • get_input_labels_function - function to get input labels for grating couplers.
  • with_loopback - True, adds loopback structures.
  • optical_routing_type - None: autoselection, 0: no extension.
  • fanout_length - None # if None, automatic calculation of fanout length.
  • grating_coupler - grating coupler instance, function or list of functions.
  • cross_section - spec.
  • layer_label - for label.

gdsfactory.routing.sort_ports

sort_ports

def sort_ports(ports1: list[Port], ports2: list[Port],
               enforce_port_ordering: bool) -> tuple[list[Port], list[Port]]

Returns two lists of sorted ports.

Arguments:

  • ports1 - the starting ports
  • ports2 - the ending ports
  • enforce_port_ordering - if True, only ports2 will be sorted in accordance with ports1. If False, the two lists will be sorted independently.

gdsfactory.routing.get_bundle

Routes bundles of ports (river routing).

get bundle is the generic river routing function get_bundle calls different function depending on the port orientation.

  • get_bundle_same_axis: ports facing each other with arbitrary pitch on each side
  • get_bundle_corner: 90Deg / 270Deg between ports with arbitrary pitch
  • get_bundle_udirect: ports with direct U-turns
  • get_bundle_uindirect: ports with indirect U-turns

get_bundle

def get_bundle(ports1: list[Port],
               ports2: list[Port],
               separation: float | None = None,
               extension_length: float = 0.0,
               straight: ComponentSpec = straight_function,
               bend: ComponentSpec = bend_euler,
               with_sbend: bool = False,
               sort_ports: bool = True,
               cross_section: CrossSectionSpec
               | MultiCrossSectionAngleSpec = "strip",
               start_straight_length: float | None = None,
               end_straight_length: float | None = None,
               path_length_match_loops: int | None = None,
               path_length_match_extra_length: float = 0.0,
               path_length_match_modify_segment_i: int = -2,
               enforce_port_ordering: bool = True,
               **kwargs) -> list[Route]

Returns list of routes to connect two groups of ports.

Routes connect a bundle of ports with a river router. Chooses the correct routing function depending on port angles.

Arguments:

  • ports1 - list of starting ports.
  • ports2 - list of end ports.
  • separation - bundle separation (center to center). Defaults to cross_section.width + cross_section.gap
  • extension_length - adds straight extension.
  • bend - function for the bend. Defaults to euler.
  • with_sbend - use s_bend routing when there is no space for manhattan routing.
  • sort_ports - sort port coordinates.
  • cross_section - CrossSection or function that returns a cross_section.
  • start_straight_length - straight length at the beginning of the route. If None, uses default value for the routing CrossSection.
  • end_straight_length - end length at the beginning of the route. If None, uses default value for the routing CrossSection.
  • path_length_match_loops - Integer number of loops to add to bundle for path length matching. Path-length matching won’t be attempted if this is set to None.
  • path_length_match_extra_length - Extra length to add to path length matching loops (requires path_length_match_loops != None).
  • path_length_match_modify_segment_i - Index of straight segment to add path length matching loops to (requires path_length_match_loops != None).
  • enforce_port_ordering - If True, enforce that the ports are connected in the specific order.

Arguments:

  • width - main layer waveguide width (um).

  • layer - main layer for waveguide.

  • width_wide - wide waveguides width (um) for low loss routing.

  • auto_widen - taper to wide waveguides for low loss routing.

  • auto_widen_minimum_length - minimum straight length for auto_widen.

  • taper_length - taper_length for auto_widen.

  • bbox_layers - list of layers for rectangular bounding box.

  • bbox_offsets - list of bounding box offsets.

  • cladding_layers - list of layers to extrude.

  • cladding_offsets - list of offset from main Section edge.

  • radius - bend radius (um).

  • sections - list of Sections(width, offset, layer, ports).

  • port_names - for input and output (‘o1’, ‘o2’).

  • port_types - for input and output: electrical, optical, vertical_te ...

  • min_length - defaults to 1nm = 10e-3um for routing.

  • snap_to_grid - can snap points to grid when extruding the path.

  • steps - specify waypoint steps to route using get_bundle_from_steps.

  • waypoints - specify waypoints to route using get_bundle_from_steps.

    .. plot:: :include-source:

    import gdsfactory as gf

    gf.cell def test_north_to_south(): dy = 200.0 xs1 = [-500, -300, -100, -90, -80, -55, -35, 200, 210, 240, 500, 650]

    pitch = 10.0 N = len(xs1) xs2 = [-20 + i * pitch for i in range(N // 2)] xs2 += [400 + i * pitch for i in range(N // 2)]

    a1 = 90 a2 = a1 + 180

    ports1 = [gf.Port(f"top_{i}“, center=(xs1[i], +0), width=0.5, orientation=a1, layer=(1,0)) for i in range(N)] ports2 = [gf.Port(f"bot_{i}”, center=(xs2[i], dy), width=0.5, orientation=a2, layer=(1,0)) for i in range(N)]

    c = gf.Component() routes = gf.routing.get_bundle(ports1, ports2) for route in routes: c.add(route.references)

    return c

    gf.config.set_plot_options(show_subports=False) c = test_north_to_south() c.plot()

get_bundle_same_axis

def get_bundle_same_axis(ports1: list[Port],
                         ports2: list[Port],
                         separation: float = 5.0,
                         end_straight_length: float = 0.0,
                         start_straight_length: float = 0.0,
                         bend: ComponentSpec = bend_euler,
                         sort_ports: bool = True,
                         path_length_match_loops: int | None = None,
                         path_length_match_extra_length: float = 0.0,
                         path_length_match_modify_segment_i: int = -2,
                         cross_section: CrossSectionSpec
                         | MultiCrossSectionAngleSpec = "strip",
                         enforce_port_ordering: bool = True,
                         **kwargs) -> list[Route]

Semi auto-routing for two lists of ports.

Arguments:

  • ports1 - first list of ports.
  • ports2 - second list of ports.
  • separation - minimum separation between two straights.
  • end_straight_length - offset to add at the end of each straight.
  • start_straight_length - in um.
  • bend - spec.
  • sort_ports - sort the ports according to the axis.
  • path_length_match_loops - Integer number of loops to add to bundle for path length matching (won’t try to match if None).
  • path_length_match_extra_length - Extra length to add to path length matching loops (requires path_length_match_loops != None).
  • path_length_match_modify_segment_i - Index of straight segment to add path length matching loops to (requires path_length_match_loops != None).
  • cross_section - CrossSection or function that returns a cross_section.
  • enforce_port_ordering - If True, will enforce that the ports are conneceted as ordered.
  • kwargs - cross_section settings.

Returns:

[route_filter(r) for r in routes] list of lists of coordinates e.g with default get_route_from_waypoints, returns a list of elements which can be added to a component

The routing assumes manhattan routing between the different ports. The strategy is to modify start_straight and end_straight for each straight such that straights do not collide.

.. code::

1 X X X X X X |-----------| | | | | |-----------------------| | |-----| | | |---------------| | | | || |------| | | 2 X X X X X X

  • ports1 - at the top

  • ports2 - at the bottom

    The general strategy is: Group tracks which would collide together and apply the following method on each group:

    if x2 >= x1, increase end_straight (as seen on the right 3 ports) otherwise, decrease end_straight (as seen on the first 2 ports)

    We deal with negative end_straight by doing at the end end_straights = end_straights - min(end_straights)

    This method deals with different metal track/wg/wire widths too.

get_min_spacing

def get_min_spacing(ports1: list[Port],
                    ports2: list[Port],
                    sep: float = 5.0,
                    radius: float = 5.0,
                    sort_ports: bool = True) -> float

Returns the minimum amount of spacing in um required to create a fanout.

get_bundle_same_axis_no_grouping

def get_bundle_same_axis_no_grouping(ports1: list[Port],
                                     ports2: list[Port],
                                     sep: float = 5.0,
                                     route_filter: Callable = get_route,
                                     start_straight_length: float
                                     | None = None,
                                     end_straight_length: float | None = None,
                                     sort_ports: bool = True,
                                     cross_section: CrossSectionSpec = "strip",
                                     **kwargs) -> list[Route]

Returns a list of route elements.

Compared to get_bundle_same_axis, this function does not do any grouping. It is not as smart for the routing, but it can fall back on arclinarc connection if needed. We can also specify longer start_straight and end_straight

Semi auto routing for optical ports The routing assumes manhattan routing between the different ports. The strategy is to modify start_straight and end_straight for each straight such that straights do not collide.

We want to connect something like this:

::

2 X X X X X X |-----------| | | | | |-----------------------| | |-----| | | |---------------| | | | || |------| | | 1 X X X X X X

start is at the bottom end is at the top

The general strategy is:

if x2 < x1, decrease start straight, and increase end_straight (as seen on left two ports) otherwise, decrease start_straight, and increase end_straight (as seen on the last 3 right ports)

Arguments:

  • ports1 - first list of optical ports.
  • ports2 - second list of optical ports.
  • axis - specifies “X” or “Y” direction along which the port is going.
  • route_filter - ManhattanExpandedWgConnector or ManhattanWgConnector. or any other connector function with the same input.
  • radius - bend radius. If unspecified, uses the default radius.
  • start_straight_length - offset on the starting length before the first bend.
  • end_straight_length - offset on the ending length after the last bend.
  • sort_ports - True -> sort the ports according to the axis. False -> no sort applied.
  • cross_section - CrossSection or function that returns a cross_section.

Returns:

a list of routes the connecting straights.

gdsfactory.routing.add_fiber_single

add_fiber_single

@cell
def add_fiber_single(component: ComponentSpec = straight_function,
                     grating_coupler=grating_coupler_te,
                     layer_label: LayerSpec | None = "LABEL",
                     fiber_spacing: float = 50,
                     bend: ComponentSpec = bend_euler,
                     straight: ComponentSpec = straight_function,
                     route_filter: Callable = get_route_from_waypoints,
                     min_input_to_output_spacing: float = 200.0,
                     optical_routing_type: int = 2,
                     with_loopback: bool = True,
                     loopback_xspacing: float = 50.0,
                     component_name: str | None = None,
                     gc_port_name: str = "o1",
                     zero_port: str | None = "o1",
                     get_input_label_text_loopback_function: None
                     | (Callable) = get_input_label_text_dash_loopback,
                     get_input_label_text_function: Callable
                     | None = get_input_label_text_dash,
                     select_ports: Callable = select_ports_optical,
                     cross_section: CrossSectionSpec = "strip",
                     **kwargs) -> Component

Returns component with grating couplers and labels on each port.

It returns grating couplers in north-south orientation. First routes input port gc_port_name south, and other ports north. You can always rotate it for East-West orientation.

Arguments:

  • component - component or component function to connect to grating couplers.
  • grating_coupler - grating coupler instance, function or list of functions.
  • layer_label - for test and measurement label.
  • fiber_spacing - between outputs.
  • bend - bend spec.
  • straight - straight sepc.
  • route_filter - function to get route waypoints.
  • min_input_to_output_spacing - spacing from input to output fiber (um).
  • optical_routing_type - None: autoselection, 0: no extension.
  • with_loopback - True, adds loopback reference straight waveguide.
  • loopback_xspacing - spacing from loopback xmin to component.xmin.
  • component_name - optional name of component.
  • gc_port_name - grating coupler waveguide port name.
  • zero_port - name of the port to move to (0, 0) for the routing to work correctly.
  • get_input_label_text_loopback_function - for the loopbacks input label.
  • get_input_label_text_function - for the grating couplers input label.
  • get_input_labels_function - function to get input labels for grating couplers.
  • select_ports - function to select ports.
  • cross_section - cross_section spec.

Arguments:

  • max_y0_optical - in um.

  • straight_separation - spacing between waveguides.

  • list_port_labels - None, add labels to port indices in this list.

  • connected_port_list_ids - None # only for type 0 optical routing.

  • nb_optical_ports_lines - 1.

  • force_manhattan - False.

  • excluded_ports - list of ports to exclude.

  • grating_indices - None.

  • routing_method - function to ge the route.

  • gc_rotation - grating_coupler rotation (deg).

  • kwargs - cross_section settings.

    .. code::

    assumes grating coupler has o1 input port facing west at xmin = 0


    /| | | | | | / | | | | | | o1| | | | | | | \ | | | | | | | |||||_|

    | xmin = 0

    .. plot:: :include-source:

    import gdsfactory as gf

    c = gf.components.crossing() cc = gf.routing.add_fiber_single( component=c, optical_routing_type=0, grating_coupler=gf.components.grating_coupler_elliptical_te, ) cc.plot()

gdsfactory.routing.add_fiber_array

add_fiber_array

@gf.cell
def add_fiber_array(component: ComponentSpec = straight_function,
                    grating_coupler: ComponentSpecOrList = grating_coupler_te,
                    gc_port_name: str = "o1",
                    gc_port_labels: tuple[str, ...] | None = None,
                    component_name: str | None = None,
                    select_ports: Callable = select_ports_optical,
                    cross_section: CrossSectionSpec = "strip",
                    get_input_labels_function: Callable
                    | None = get_input_labels_dash,
                    layer_label: LayerSpec | None = "LABEL",
                    **kwargs) -> Component

Returns component with south routes and grating_couplers.

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

Arguments:

  • component - component spec to connect to grating couplers.
  • grating_coupler - spec for route terminations.
  • gc_port_name - grating coupler input port name.
  • gc_port_labels - grating coupler list of labels.
  • component_name - optional for the label.
  • select_ports - function to select ports.
  • cross_section - cross_section function.
  • get_input_labels_function - function to get input labels. None skips labels.
  • layer_label - optional layer for grating coupler label.

Arguments:

  • bend - bend spec.

  • straight - straight spec.

  • taper - taper spec.

  • get_input_label_text_loopback_function - function to get input label test.

  • get_input_label_text_function - for labels.

  • 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 - get_route.

  • 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()

gdsfactory.routing.manhattan

gen_sref

def gen_sref(structure: Component, rotation_angle: float, x_reflection: bool,
             port_name: str, position: Coordinate) -> ComponentReference

Place reference of port_name of structure at position.

Keep this convention, otherwise phidl port transform won’t work

  • 1 Mirror
  • 2 Rotate
  • 3 Move

transform

def transform(points: ndarray,
              translation: ndarray,
              angle_deg: int = 0,
              x_reflection: bool = False) -> ndarray

Transform points.

Arguments:

points (np.array of shape (N,2) ): points to be transformed.

  • translation 2d like array - translation vector.
  • angle_deg - rotation angle.
  • x_reflection bool - if True, mirror the shape across the x axis (y -> -y).

reverse_transform

def reverse_transform(points: ndarray,
                      translation: Coordinate = (0, 0),
                      angle_deg: int = 0,
                      x_reflection: bool = False) -> ndarray

Args are the following.

points (np.array of shape (N,2) ): points to be transformed. translation (2d like array): translation vector. angle_deg: rotation angle. x_reflection: if True, mirror the shape across the x axis (y -> -y).

get_route_error

def get_route_error(points,
                    cross_section: CrossSection | None = None,
                    layer_path: LayerSpec = (208, 0),
                    layer_label: LayerSpec = (66, 0),
                    layer_marker: LayerSpec = (207, 0),
                    references: list[ComponentReference] | None = None,
                    with_sbend: bool = False) -> Route

Returns route with error markers.

Arguments:

  • points - route waypoints.
  • cross_section - Optional cross_section.
  • layer_path - for the error.
  • layer_label - for the labels.
  • layer_marker - for point markers.
  • references - optional list of references.
  • with_sbend - if True raises Error so we can use it in try, except if False raises Warning.

round_corners

def round_corners(points: Coordinates,
                  straight: ComponentSpec = straight_function,
                  bend: ComponentSpec = bend_euler,
                  taper: ComponentSpec | None = None,
                  straight_fall_back_no_taper: ComponentSpec | None = None,
                  mirror_straight: bool = False,
                  straight_ports: list[str] | None = None,
                  cross_section: CrossSectionSpec
                  | MultiCrossSectionAngleSpec = strip,
                  on_route_error: Callable = get_route_error,
                  with_point_markers: bool = False,
                  with_sbend: bool = False,
                  **kwargs) -> Route

Returns Route.

  • reference list with rounded straight route from a list of manhattan points.
  • ports: Tuple of ports.
  • length: route length (float).

Arguments:

  • points - manhattan route defined by waypoints.
  • bend90 - the bend to use for 90Deg turns.
  • straight - the straight library to use to generate straight portions.
  • taper - taper for straight portions. If None, no tapering.
  • straight_fall_back_no_taper - in case there is no space for two tapers.
  • mirror_straight - mirror_straight waveguide.
  • straight_ports - port names for straights. If None finds them automatically.
  • cross_section - spec.
  • on_route_error - function to run when route fails.
  • with_point_markers - add route points markers (easy for debugging).
  • with_sbend - add sbend in case there are routing errors.
  • kwargs - cross_section settings.

generate_manhattan_waypoints

def generate_manhattan_waypoints(input_port: Port,
                                 output_port: Port,
                                 start_straight_length: float | None = None,
                                 end_straight_length: float | None = None,
                                 min_straight_length: float | None = None,
                                 bend: ComponentSpec = bend_euler,
                                 cross_section: CrossSectionSpec
                                 | MultiCrossSectionAngleSpec = strip,
                                 **kwargs) -> ndarray

Return waypoints for a Manhattan route between two ports.

Arguments:

  • input_port - source port.
  • output_port - destination port.
  • start_straight_length - Optional start length.
  • end_straight_length - in um.
  • min_straight_length - in um.
  • bend - bend spec.
  • cross_section - spec.
  • kwargs - cross_section settings.

route_manhattan

def route_manhattan(input_port: Port,
                    output_port: Port,
                    straight: ComponentSpec = straight_function,
                    taper: ComponentSpec | None = None,
                    start_straight_length: float | None = None,
                    end_straight_length: float | None = None,
                    min_straight_length: float | None = None,
                    bend: ComponentSpec = bend_euler,
                    with_sbend: bool = True,
                    cross_section: CrossSectionSpec
                    | MultiCrossSectionAngleSpec = strip,
                    with_point_markers: bool = False,
                    on_route_error: Callable = get_route_error,
                    **kwargs) -> Route

Generates the Manhattan waypoints for a route.

Then creates the straight, taper and bend references that define the route, or create an SBend route.

Arguments:

  • input_port - input.
  • output_port - output.
  • straight - function.
  • taper - add taper.
  • start_straight_length - in um.
  • end_straight_length - in um.
  • min_straight_length - min length of straight for any intermediate segment.
  • bend - bend spec.
  • with_sbend - add sbend in case there are routing errors.
  • cross_section - spec.
  • with_point_markers - add point markers in the route.
  • kwargs - cross_section settings.

gdsfactory.routing.add_pads

add_pads_bot

@cell
def add_pads_bot(component: ComponentSpec = straight_heater_metal,
                 select_ports: Callable = select_ports_electrical,
                 port_names: Strs | None = None,
                 component_name: str | None = None,
                 cross_section: CrossSectionSpec = "metal_routing",
                 get_input_labels_function: Callable | None = None,
                 layer_label: LayerSpec = "TEXT",
                 pad_port_name: str = "e1",
                 pad_port_labels: tuple[str, ...] | None = None,
                 pad: ComponentSpec = pad_rectangular,
                 bend: ComponentSpec = "wire_corner",
                 straight_separation: float | None = None,
                 pad_spacing: float | str = "pad_spacing",
                 optical_routing_type: int | None = 1,
                 **kwargs) -> Component

Returns new component with ports connected bottom pads.

Arguments:

  • component - component spec to connect to.
  • select_ports - function to select_ports.
  • port_names - optional port names. Overrides select_ports.
  • component_name - optional for the label.
  • cross_section - cross_section spec.
  • get_input_labels_function - function to get input labels. None skips labels.
  • layer_label - optional layer for grating coupler label.
  • pad_port_name - pad input port name.
  • pad_port_labels - pad list of labels.
  • pad - spec for route terminations.
  • bend - bend spec.
  • straight_separation - from wire edge to edge. Defaults to xs.width+xs.gap
  • pad_spacing - in um. Defaults to pad_spacing constant from the PDK.
  • optical_routing_type - None: auto, 0: no extension, 1: standard, 2: check.

Arguments:

  • straight - straight spec.

  • taper - taper spec.

  • get_input_label_text_loopback_function - function to get input label test.

  • get_input_label_text_function - for labels.

  • fanout_length - if None, automatic calculation of fanout length.

  • max_y0_optical - in um.

  • with_loopback - True, adds loopback structures.

  • 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 - get_route.

  • 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.pad() cc = gf.routing.add_pads_bot(component=c, port_names=(“e1”, “e4”), fanout_length=50) cc.plot()

add_pads_top

@gf.cell
def add_pads_top(component: ComponentSpec = straight_heater_metal,
                 **kwargs) -> Component

Returns new component with ports connected top pads.

Arguments:

  • component - component spec to connect to.

Arguments:

  • select_ports - function to select_ports.

  • port_names - optional port names. Overrides select_ports.

  • component_name - optional for the label.

  • cross_section - cross_section function.

  • get_input_labels_function - function to get input labels. None skips labels.

  • layer_label - optional layer for grating coupler label.

  • pad_port_name - pad input port name.

  • pad_port_labels - pad list of labels.

  • pad - spec for route terminations.

  • bend - bend spec.

  • straight_separation - from edge to edge.

  • straight - straight spec.

  • taper - taper spec.

  • get_input_label_text_loopback_function - function to get input label test.

  • get_input_label_text_function - for labels.

  • fanout_length - if None, automatic calculation of fanout length.

  • max_y0_optical - in um.

  • with_loopback - True, adds loopback structures.

  • 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 - get_route.

  • 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.pad() cc = gf.routing.add_pads_top(component=c, port_names=(“e1”, “e4”), fanout_length=50) cc.plot()

gdsfactory.routing.route_south

route_south

def route_south(component: Component,
                optical_routing_type: int = 1,
                excluded_ports: tuple[str, ...] | None = None,
                straight_separation: Number = 4.0,
                io_gratings_lines: list[list[ComponentReference]]
                | None = None,
                gc_port_name: str = "o1",
                bend: ComponentSpec = bend_euler,
                straight: ComponentSpec = straight_function,
                taper: ComponentSpec | None = taper_function,
                select_ports: Callable = select_ports_optical,
                port_names: Strs | None = None,
                cross_section: CrossSectionSpec = strip,
                **kwargs) -> Routes

Returns Routes to route a component ports to the south.

Arguments:

  • component - component to route.

  • optical_routing_type - routing heuristic 1 or 2 1 uses the component size info to estimate the box size. 2 only looks at the optical port positions to estimate the size.

  • excluded_ports - list of port names to NOT route.

  • straight_separation - in um.

  • io_gratings_lines - list of ports to which the ports produced by this function will be connected. Supplying this information helps avoiding straight collisions.

  • gc_port_name - grating coupler port name.

  • bend - spec.

  • straight - spec.

  • taper - spec.

  • select_ports - function to select_ports.

  • port_names - optional port names. Overrides select_ports.

  • cross_section - cross_section spec.

  • kwargs - cross_section settings.

    Works well if the component looks roughly like a rectangular box with: north ports on the north of the box. south ports on the south of the box. east ports on the east of the box. west ports on the west of the box.

    .. plot:: :include-source:

    import gdsfactory as gf

    c = gf.components.ring_double() c = gf.Component() ref = c << gf.components.ring_double() r = gf.routing.route_south(ref) for e in r.references: c.add(e) c.plot()

gdsfactory.routing.route_sharp

based on phidl.routing.

path_straight

def path_straight(port1: Port, port2: Port) -> Path

Return waypoint path between port1 and port2 in a straight line.

Useful when ports point directly at each other.

Arguments:

  • port1 - start port.
  • port2 - end port.

path_L

def path_L(port1: Port, port2: Port) -> Path

Return waypoint path between port1 and port2 in an L shape.

Useful when orthogonal ports can be directly connected with one turn.

Arguments:

  • port1 - start port.
  • port2 - end port.

path_U

def path_U(port1: Port, port2: Port, length1=200) -> Path

Return waypoint path between port1 and port2 in a U shape.

Useful when ports face the same direction or toward each other.

Arguments:

  • port1 - start port.
  • port2 - end port.
  • length1 - Length of segment exiting port1. Should be larger than bend radius.

path_J

def path_J(port1: Port, port2: Port, length1=200, length2=200) -> Path

Return waypoint path between port1 and port2 in a J shape. Useful when orthogonal ports cannot be connected directly with an L shape.

Arguments:

  • port1 - start port.
  • port2 - end port.
  • length1 - Length of segment exiting port1. Should be larger than bend radius.
  • length2 - Length of segment exiting port2. Should be larger than bend radius.

path_C

def path_C(port1: Port,
           port2: Port,
           length1=100,
           left1=100,
           length2=100) -> Path

Return waypoint path between port1 and port2 in a C shape. Useful when ports are parallel and face away from each other.

Arguments:

  • port1 - start port.
  • port2 - end port.
  • length1 - Length of route segment coming out of port1. Should be at larger than bend radius.
  • left1 - Length of route segment that turns left (or right if negative) from port1. Should be larger than twice the bend radius.
  • length2 - Length of route segment coming out of port2. Should be larger than bend radius.

path_manhattan

def path_manhattan(port1: Port, port2: Port, radius: float) -> Path

Return waypoint path between port1 and port2 using manhattan routing. Routing uses straight, L, U, J, or C waypoint path as needed. Ports must face orthogonal or parallel directions.

Arguments:

  • port1 - start port.
  • port2 - end port.
  • radius - Bend radius for 90 degree bend.

path_Z

def path_Z(port1: Port, port2: Port, length1=100, length2=100) -> Path

Return waypoint path between port1 and port2 in a Z shape. Ports can have any relative orientation.

Arguments:

  • port1 - start port.
  • port2 - end port.
  • length1 - Length of route segment coming out of port1.
  • length2 - Length of route segment coming out of port2.

path_V

def path_V(port1: Port, port2: Port) -> Path

Return waypoint path between port1 and port2 in a V shape. Useful when ports point to a single connecting point.

Arguments:

  • port1 - start port.
  • port2 - end port.

route_sharp

@gf.cell
def route_sharp(port1: Port,
                port2: Port,
                width: float | None = None,
                path_type: str = "manhattan",
                manual_path=None,
                layer: LayerSpec | None = None,
                cross_section: CrossSectionSpec | None = None,
                port_names: tuple[str, str] = ("o1", "o2"),
                **kwargs) -> Component

Returns Component route between ports.

Arguments:

  • port1 - start port.

  • port2 - end port.

  • width - None, int, float, array-like[2], or CrossSection. If None, the route linearly tapers between the widths the ports If set to a single number (e.g. width=1.7): makes a fixed-width route If set to a 2-element array (e.g. width=[1.8,2.5]): makes a route whose width varies linearly from width[0] to width[1] If set to a CrossSection: uses the CrossSection parameters for the route. path_type : {‘manhattan’, ‘L’, ‘U’, ‘J’, ‘C’, ‘V’, ‘Z’, ‘straight’, ‘manual’}.

  • manual_path - array-like[N][2] or Path Waypoint for manual route.

  • layer - Layer to put route on.

  • kwargs - Keyword arguments passed to the waypoint path function.

    Method of waypoint path creation. Should be one of:

    • manhattan: automatic manhattan routing (see path_manhattan() ).
    • L: L-shaped path for orthogonal ports that can be directly connected.
    • U: U-shaped path for parallel or facing ports.
    • J: J-shaped path for orthogonal ports that cannot be directly connected.
    • C: C-shaped path for ports that face away from each other.
    • Z: Z-shaped path with three segments for ports at any angles.
    • V: V-shaped path with two segments for ports at any angles.
    • straight: straight path for ports that face each other.
    • manual: use an explicit waypoint path provided in manual_path.

    .. plot:: :include-source:

    import gdsfactory as gf

    c = gf.Component(“pads”) c1 = c << gf.components.pad(port_orientation=None) c2 = c << gf.components.pad(port_orientation=None)

    c2.movex(400) c2.movey(-200)

    route = c << gf.routing.route_sharp(c1.ports[“e4”], c2.ports[“e1”], path_type=“L”) c.plot()

gdsfactory.routing.get_bundle_from_steps

get_bundle_from_steps

def get_bundle_from_steps(ports1: list[Port],
                          ports2: list[Port],
                          steps: list[Step] | None = None,
                          bend: ComponentSpec = bend_euler,
                          straight: ComponentSpec = straight_function,
                          taper: ComponentSpec | None = taper_function,
                          cross_section: CrossSectionSpec
                          | MultiCrossSectionAngleSpec = "strip",
                          sort_ports: bool = True,
                          separation: float | None = None,
                          path_length_match_loops: int | None = None,
                          path_length_match_extra_length: float = 0.0,
                          path_length_match_modify_segment_i: int = -2,
                          enforce_port_ordering: bool = True,
                          **kwargs) -> list[Route]

Returns a list of routes formed by the given waypoints steps.

Can add bends instead of corners and optionally tapers in straight sections. Tapering to wider straights reduces the optical loss and phase errors. get_bundle_from_steps is a manual version of get_bundle and a more convenient version of get_bundle_from_waypoints.

Arguments:

  • port1 - start ports (list or dict).

  • port2 - end ports (list or dict).

  • steps - that define the route (x, y, dx, dy) [{‘dx’: 5}, {‘dy’: 10}].

  • bend - function that returns bends.

  • straight - function that returns straight waveguides.

  • taper - function that returns tapers.

  • cross_section - for routes.

  • sort_ports - if True sort ports.

  • separation - center to center, defaults to ports1 separation.

  • kwargs - cross_section settings.

    .. plot:: :include-source:

    from functools import partial import gdsfactory as gf

    c = gf.Component(“get_route_from_steps_sample”) w = gf.components.array( partial(gf.components.straight, layer=(2, 0)), rows=3, columns=1, spacing=(0, 50), )

    left = c << w right = c << w right.move((200, 100)) p1 = left.get_ports_list(orientation=0) p2 = right.get_ports_list(orientation=180)

    routes = gf.routing.get_bundle_from_steps( p1, p2,

  • steps=[{"x" - 150}], )

    for route in routes: c.add(route.references) c.plot() c.show(show_ports=True)

gdsfactory.routing.get_route_from_steps

get_route_from_steps

def get_route_from_steps(port1: Port,
                         port2: Port,
                         steps: list[Step] | None = None,
                         bend: ComponentSpec = "bend_euler",
                         taper: ComponentSpec | None = "taper",
                         cross_section: CrossSectionSpec
                         | MultiCrossSectionAngleSpec = "strip",
                         **kwargs) -> Route

Returns a route formed by the given waypoints steps.

Uses smooth euler bends instead of corners and optionally tapers in straight sections. Tapering to wider straights reduces the optical loss when auto_widen=True. get_route_from_steps is a manual version of get_route and a more concise and convenient version of get_route_from_waypoints

Arguments:

  • port1 - start port.

  • port2 - end port.

  • steps - that define the route (x, y, dx, dy) [{‘dx’: 5}, {‘dy’: 10}].

  • bend - function that returns bends.

  • straight - straight spec.

  • taper - taper spec.

  • cross_section - cross_section spec.

  • kwargs - cross_section settings.

    .. plot:: :include-source:

    import gdsfactory as gf

    c = gf.Component(“get_route_from_steps_sample”) w = gf.components.straight() left = c << w right = c << w right.move((100, 80))

    obstacle = gf.components.rectangle(size=(100, 10), port_type=None) obstacle1 = c << obstacle obstacle2 = c << obstacle obstacle1.ymin = 40 obstacle2.xmin = 25

    p1 = left.ports[‘o2’] p2 = right.ports[‘o2’] route = gf.routing.get_route_from_steps( port1=p1, port2=p2, steps=[

  • {"x" - 20},

  • {"y" - 20},

  • {"x" - 120},

  • {"y" - 80}, ], ) c.add(route.references) c.plot() c.show(show_ports=True)

gdsfactory.routing.get_route_astar

Node Objects

class Node()

__init__

def __init__(parent=None, position: tuple = ()) -> None

Initializes a node. A node is a point on the grid.

get_route_astar

def get_route_astar(component: Component,
                    port1: Port,
                    port2: Port,
                    resolution: float = 1,
                    avoid_layers: list[LayerSpec] | None = None,
                    distance: float = 1,
                    cross_section: CrossSectionSpec = "strip",
                    **kwargs) -> Route

A* routing function. Finds a route between two ports avoiding obstacles.

Arguments:

  • component - Component the route, and ports belong to.
  • port1 - input.
  • port2 - output.
  • resolution - discretization resolution in um. Lower resolution can help avoid accidental overlapping between route and components but adds more bends. The resolution decides how many “leaps/hops” the algorithm has to do.
  • avoid_layers - list of layers to avoid.
  • distance - distance from obstacles in um.
  • cross_section - spec.
  • kwargs - cross_section settings.

gdsfactory.routing.route_fiber_single

route_fiber_single

def route_fiber_single(
    component: Component,
    fiber_spacing: float = 50.0,
    grating_coupler: ComponentSpec = grating_coupler_te,
    min_input_to_output_spacing: float = 200.0,
    optical_routing_type: int = 1,
    port_names: tuple[str, ...] | None = None,
    excluded_ports: tuple[str, ...] | None = None,
    component_name: str | None = None,
    select_ports: Callable = select_ports_optical,
    cross_section: CrossSectionSpec = strip,
    **kwargs
) -> tuple[list[ComponentReference | Label], list[ComponentReference]]

Returns route Tuple(references, grating couplers) for single fiber input/output.

Arguments:

  • component - to add grating couplers.
  • fiber_spacing - between grating couplers.
  • grating_coupler - grating coupler Spec
  • min_input_to_output_spacing - so opposite fibers do not touch
  • optical_routing_type - 0 (basic), 1 (standard), 2 (looks at ports)
  • port_names - port labels that need connection
  • excluded_ports - ports excluded from routing
  • component_name - Optional component name.
  • select_ports - function to select ports.
  • cross_section - spec.
  • kwargs - cross_section settings

Returns:

  • elements - list of ComponentReferences for routes and labels

  • grating_couplers - list of grating_couplers references

    .. code::


    | |E1 W0| | | |E0 |________|

    rotates +90 deg and routes West ports to South

    the rest of the original ports (East, North, South) will route south

    it calls route_fiber_array twice

    route_fiber_array is designed to route ports south

    E1 E0 || | | | | | | | | | | | | |______| | W0 1st part routes West ports south

    then rotates 180 and routes the rest of the ports North

gdsfactory.routing.route_quad

Route for electrical based on phidl.routing.route_quad.

route_quad

@gf.cell
def route_quad(port1: Port,
               port2: Port,
               width1: float | None = None,
               width2: float | None = None,
               layer: gf.typings.LayerSpec = "M1",
               manhattan_target_step: float | None = None) -> gf.Component

Routes a basic quadrilateral polygon directly between two ports.

Arguments:

  • port1 - Port to start route. port2 : Port objects to end route.

  • width1 - Width of quadrilateral at ports. If None, uses port widths.

  • width2 - Width of quadrilateral at ports. If None, uses port widths.

  • layer - Layer to put the route on.

  • manhattan - if not none, min step to manhattanize the polygon

    .. plot:: :include-source:

    import gdsfactory as gf

    c = gf.Component() pad1 = c << gf.components.pad(size=(50, 50)) pad2 = c << gf.components.pad(size=(10, 10)) pad2.movex(100) pad2.movey(50) route_gnd = c << gf.routing.route_quad( pad1.ports[“e2”], pad2.ports[“e4”], width1=None, width2=None, ) c.show() c.plot()

gdsfactory.routing

Functions to create routes between components.

gdsfactory.routing.get_bundle_path_length_match

Routes bundles of ports (river routing).

get_bundle_path_length_match

def get_bundle_path_length_match(
        ports1: list[Port],
        ports2: list[Port],
        separation: float = 30.0,
        end_straight_length: float | None = None,
        extra_length: float = 0.0,
        nb_loops: int = 1,
        modify_segment_i: int = -2,
        bend: ComponentSpec = bend_euler,
        straight: ComponentSpec = _straight,
        taper: ComponentSpec | None = taper_function,
        start_straight_length: float = 0.0,
        route_filter: Callable = get_route_from_waypoints,
        sort_ports: bool = True,
        cross_section: CrossSectionSpec | MultiCrossSectionAngleSpec = strip,
        enforce_port_ordering: bool = True,
        **kwargs) -> list[Route]

Returns list of routes that are path length matched.

Arguments:

  • ports1 - list of ports.

  • ports2 - list of ports.

  • separation - between the loops.

  • end_straight_length - if None tries to determine it.

  • extra_length - distance added to all path length compensation. Useful is we want to add space for extra taper on all branches.

  • nb_loops - number of extra loops added in the path.

  • modify_segment_i - index of the segment that accommodates the new turns default is next to last segment.

  • bend - for bends.

  • straight - for straights.

  • taper - spec.

  • start_straight_length - in um.

  • route_filter - get_route_from_waypoints.

  • sort_ports - sorts ports before routing.

  • cross_section - factory.

  • kwargs - cross_section settings.

    Tips:

    • If path length matches the wrong segments, change modify_segment_i arguments.
    • Adjust nb_loops to avoid too short or too long segments
    • Adjust separation and end_straight_offset to avoid compensation collisions

    .. plot:: :include-source:

    import gdsfactory as gf

    c = gf.Component(“path_length_match_sample”)

    dy = 2000.0 xs1 = [-500, -300, -100, -90, -80, -55, -35, 200, 210, 240, 500, 650] pitch = 100.0 N = len(xs1) xs2 = [-20 + i * pitch for i in range(N)]

    a1 = 90 a2 = a1 + 180 ports1 = [gf.Port(name=f"top_{i}“, center=(xs1[i], +0), width=0.5, orientation=a1, layer=“WG”) for i in range(N)] ports2 = [gf.Port(name=f"bot_{i}”, center=(xs2[i], dy), width=0.5, orientation=a2, layer=“WG”) for i in range(N)]

    routes = gf.routing.get_bundle_path_length_match(ports1, ports2, extra_length=44) for route in routes: c.add(route.references)

    gf.config.set_plot_options(show_subports=False) c.plot()

gdsfactory.routing.add_electrical_pads_top

add_electrical_pads_top

@gf.cell
def add_electrical_pads_top(component: ComponentSpec = straight,
                            direction: str = "top",
                            spacing: Float2 = (0.0, 100.0),
                            pad_array: ComponentSpec = pad_array_function,
                            select_ports: Callable = select_ports_electrical,
                            port_names: Strs | None = None,
                            layer: gf.typings.LayerSpec = "MTOP",
                            **kwargs) -> Component

Returns new component with electrical ports connected to top pad array.

Arguments:

  • 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.

  • port_names - optional port names. Overrides select_ports.

  • layer - for the routes.

  • **kwargs - extra kwargs for select ports.

    .. plot:: :include-source:

    import gdsfactory as gf

    c = gf.components.straight_heater_metal() cc = gf.routing.add_electrical_pads_top(component=c, spacing=(-150, 30)) cc.plot()

gdsfactory.routing.route_ports_to_side

route_ports_to_side

def route_ports_to_side(ports: dict[str, Port] | list[Port] | Component
                        | ComponentReference,
                        side: str = "north",
                        x: float | None = None,
                        y: float | None = None,
                        routing_func: Callable = get_route,
                        **kwargs) -> tuple[list[Route], list[Port]]

Routes ports to a given side.

Arguments:

  • ports - list/dict/Component/ComponentReference to route to a side.
  • side - ‘north’, ‘south’, ‘east’ or ‘west’.
  • x - position to route ports for east/west. None, uses most east/west value.
  • y - position to route ports for south/north. None, uses most north/south value.
  • routing_func - the routing function. By default uses get_route.

Arguments:

  • radius - in um.
  • separation - in um. extend_bottom/extend_top for east/west routing. extend_left, extend_right for south/north routing.

Returns:

List of routes: with routing elements. List of ports: of the new ports.

.. plot:: :include-source:

import gdsfactory as gf

c = gf.Component(‘sample_route_sides’) dummy = gf.components.nxn(north=2, south=2, west=2, east=2) sides = [“north”, “south”, “east”, “west”] d = 100 positions = [(0, 0), (d, 0), (d, d), (0, d)]

for pos, side in zip(positions, sides): dummy_ref = dummy.ref(position=pos) c.add(dummy_ref) routes, ports = gf.routing.route_ports_to_side(dummy_ref, side, layer=(1, 0)) for route in routes: c.add(route.references) for i, p in enumerate(ports): c.add_port(name=f"{side[0]}{i}", port=p)

c.plot()

route_ports_to_x

def route_ports_to_x(list_ports: list[Port],
                     x: float | str = "east",
                     separation: float = 10.0,
                     radius: float = 10.0,
                     extend_bottom: float = 0.0,
                     extend_top: float = 0.0,
                     extension_length: float = 0.0,
                     y0_bottom: float | None = None,
                     y0_top: float | None = None,
                     routing_func: RouteFactory = get_route,
                     backward_port_side_split_index: int = 0,
                     start_straight_length: float = 0.01,
                     dx_start: float | None = None,
                     dy_start: float | None = None,
                     **routing_func_args) -> tuple[list[Route], list[Port]]

Returns route to x.

Arguments:

  • list_ports - reasonably well behaved list of ports. ports facing north ports are norther than any other ports ports facing south ports are souther ... ports facing west ports are the wester ... ports facing east ports are the easter ...
  • x - float or string. if float: x coordinate to which the ports will be routed if string: “east” -> route to east if string: “west” -> route to west
  • separation - in um.
  • radius - in um.
  • extend_bottom - in um.
  • extend_top - in um.
  • extension_length - in um.
  • y0_bottom - in um.
  • y0_top - in um.
  • routing_func - to route.
  • backward_port_side_split_index - integer represents and index in the list of backwards ports (bottom to top) all ports with an index strictly lower or equal are routed bottom all ports with an index larger or equal are routed top
  • dx_start - override minimum starting x distance.
  • dy_start - override minimum starting y distance.

Returns:

  • routes - list of routes

  • ports - list of the new optical ports

    1. routes the bottom-half of the ports facing opposite side of x
    2. routes the south ports
    3. front ports
    4. north ports

route_ports_to_y

def route_ports_to_y(
        list_ports: list[Port],
        y: float | str = "north",
        separation: float = 10.0,
        radius: float = 10.0,
        x0_left: float | None = None,
        x0_right: float | None = None,
        extension_length: float = 0.0,
        extend_left: float = 0.0,
        extend_right: float = 0.0,
        routing_func: RouteFactory = get_route,
        backward_port_side_split_index: int = 0,
        start_straight_length: float = 0.01,
        dx_start: float | None = None,
        dy_start: float | None = None,
        **routing_func_args: dict[Any, Any]) -> tuple[list[Route], list[Port]]

Args are the following.

list_ports: reasonably well behaved list of ports. ports facing north ports are norther than any other ports ports facing south ports are souther ... ports facing west ports are the wester ... ports facing east ports are the easter ...

y: float or string. if float: y coordinate to which the ports will be routed if string: “north” -> route to north if string: “south” -> route to south

backward_port_side_split_index: integer this integer represents and index in the list of backwards ports (sorted from left to right) all ports with an index strictly larger are routed right all ports with an index lower or equal are routed left separation: in um. radius: in um.

Returns:

  • a list of Routes
  • a list of the new optical ports

First route the bottom-half of the back ports (back ports are the one facing opposite side of x) Then route the south ports then the front ports then the north ports

gdsfactory.routing.validation

validate_connections

def validate_connections(ports1: list[Port], ports2: list[Port],
                         routes: list[Route]) -> list[Route]

Validates that a set of Routes indeed connects the port-pairs listed in ports1 and ports2. If the Routes form valid connections between ports1 and ports2, the original Routes will be returned. If not, a RouteWarning will be raised, and a set of error traces will be returned instead.

Arguments:

  • ports1 - the list of starting ports.
  • ports2 - the list of ending ports.
  • routes - the list of Route objects, purportedly between ports1 and ports2.

Returns:

A list of Routes. If the input routes are valid, they will be returned as-is. Otherwise, a list of error traces will be returned and a RouteWarning will be raised.

make_error_traces

def make_error_traces(ports1: list[Port], ports2: list[Port],
                      message: str) -> list[Route]

Creates a set of error traces showing the intended connectivity between ports1 and ports2. The specified message will be included in the RouteWarning that is raised.

Arguments:

  • ports1 - the list of starting ports.
  • ports2 - the list of ending ports.
  • message - a message to include in the RouteWarning that is raised.

Returns:

A list of Routes (the error traces).

is_invalid_bundle_topology

def is_invalid_bundle_topology(ports1: list[Port], ports2: list[Port]) -> bool

Returns True if the bundle is topologically unroutable without introducing crossings.

Arguments:

  • ports1 - the starting ports of the bundle
  • ports2 - the ending ports of the bundle

Returns:

True if the bundle is unroutable. False otherwise.

gdsfactory.routing.fanout

fanout_component

@cell
def fanout_component(component: ComponentSpec,
                     port_names: tuple[str, ...],
                     pitch: tuple[float, float] = (0.0, 20.0),
                     dx: float = 20.0,
                     sort_ports: bool = True,
                     auto_rename_ports: bool = True,
                     enforce_port_ordering: bool = True,
                     **kwargs) -> Component

Returns component with Sbend fanout routes.

Arguments:

  • component - to fanout ports.

  • port_names - list of port names.

  • pitch - target port spacing for new component.

  • dx - how far the fanout in x direction.

  • sort_ports - sort ports.

  • auto_rename_ports - auto_rename_ports.

  • kwargs - for get_route_sbend.

    .. plot:: :include-source:

    import gdsfactory as gf c = gf.components.mmi2x2()

    cc = gf.routing.fanout_component( component=c, port_names=tuple(c.get_ports_dict(orientation=0).keys()) ) cc.plot()

fanout_ports

def fanout_ports(ports: list[gf.Port],
                 pitch: tuple[float, float] = (0.0, 20.0),
                 dx: float = 20.0,
                 **kwargs) -> list[gf.typings.Route]

Returns fanout Sbend routes.

Arguments:

  • ports - list of ports.
  • pitch - target port spacing for new component.
  • dx - how far the fanout.
  • kwargs - for route_basic.

gdsfactory.routing.utils

flip

def flip(port: Port) -> Port

Returns port copy with Flip Port orientation.

direction_ports_from_list_ports

def direction_ports_from_list_ports(
        optical_ports: list[Port]) -> dict[str, list[Port]]

Returns a dict of WENS ports.

check_ports_have_equal_spacing

def check_ports_have_equal_spacing(list_ports: list[Port]) -> float64

Returns port separation.

Raises error if not constant.

get_list_ports_angle

def get_list_ports_angle(list_ports: list[Port]) -> float64 | int

Returns the orientation/angle (in degrees) of a list of ports.

gdsfactory.routing.get_route

get_route returns a Manhattan route between two ports.

get_route only works for an individual routes. For routing groups of ports you need to use get_bundle instead

To make a route, you need to supply:

  • input port
  • output port
  • bend
  • straight
  • taper to taper to wider straights and reduce straight loss (Optional)

To generate a straight route:

  1. Generate the backbone of the route. This is a list of manhattan coordinates that the route would pass through if it used only sharp bends (right angles)

  2. Replace the corners by bend references (with rotation and position computed from the manhattan backbone)

  3. Add tapers if needed and if space permits

  4. generate straight portions in between tapers or bends

A Route is a dataclass with:

  • references: list of references for tapers, bends and straight waveguides
  • ports: a dict of port name to Port, usually two ports “input” and “output”
  • length: a float with the length of the route

get_route

@validate_call
def get_route(input_port: Port,
              output_port: Port,
              bend: ComponentSpec = bend_euler,
              with_sbend: bool = False,
              straight: ComponentSpec = straight_function,
              taper: ComponentSpec | None = None,
              start_straight_length: float | None = None,
              end_straight_length: float | None = None,
              min_straight_length: float | None = None,
              cross_section: CrossSectionSpec
              | MultiCrossSectionAngleSpec = "strip",
              **kwargs) -> Route

Returns a Manhattan Route between 2 ports.

The references are straights, bends and tapers. get_route is an automatic version of get_route_from_steps.

Arguments:

  • input_port - start port.

  • output_port - end port.

  • bend - bend spec.

  • with_sbend - add sbend in case there are routing errors.

  • straight - straight spec.

  • taper - taper spec.

  • start_straight_length - length of starting straight.

  • end_straight_length - length of end straight.

  • min_straight_length - min length of straight for any intermediate segment.

  • cross_section - spec.

  • kwargs - cross_section settings.

    .. plot:: :include-source:

    import gdsfactory as gf

    c = gf.Component(‘sample_connect’) mmi1 = c << gf.components.mmi1x2() mmi2 = c << gf.components.mmi1x2() mmi2.move((40, 20)) route = gf.routing.get_route(mmi1.ports[“o2”], mmi2.ports[“o1”], radius=5) c.add(route.references) c.plot()

get_route_from_waypoints

def get_route_from_waypoints(waypoints: Coordinates,
                             bend: Callable = bend_euler,
                             straight: Callable = straight_function,
                             taper: Callable | None = taper_function,
                             cross_section: CrossSectionSpec = "strip",
                             **kwargs) -> Route

Returns a route formed by the given waypoints with bends instead of corners and optionally tapers in straight sections. Tapering to wider straights reduces the optical loss. get_route_from_waypoints is a manual version of get_route get_route_from_steps is a more concise and convenient version of get_route_from_waypoints also available in gf.routing.

Arguments:

  • waypoints - Coordinates that define the route.

  • bend - function that returns bends.

  • straight - function that returns straight waveguides.

  • taper - function that returns tapers.

  • cross_section - spec.

  • kwargs - cross_section settings.

    .. plot:: :include-source:

    import gdsfactory as gf

    c = gf.Component(“waypoints_sample”)

    w = gf.components.straight() left = c << w right = c << w right.move((100, 80))

    obstacle = gf.components.rectangle(size=(100, 10)) obstacle1 = c << obstacle obstacle2 = c << obstacle obstacle1.ymin = 40 obstacle2.xmin = 25

    p0x, p0y = left.ports[“o2”].center p1x, p1y = right.ports[“o2”].center o = 10 # vertical offset to overcome bottom obstacle ytop = 20

    routes = gf.routing.get_route_from_waypoints( [ (p0x, p0y), (p0x + o, p0y), (p0x + o, ytop), (p1x + o, ytop), (p1x + o, p1y), (p1x, p1y), ], ) c.add(routes.references) c.plot()

gdsfactory.routing.get_input_labels

get_input_labels

def get_input_labels(
        io_gratings: list[ComponentReference],
        ordered_ports: list[Port],
        component_name: str,
        layer_label: LayerSpec,
        gc_port_name: str,
        get_input_label_text_function=get_input_label_text) -> list[Label]

Returns list of labels for a list of grating coupler references.

Arguments:

  • io_gratings - grating coupler references.
  • ordered_ports - list of ordered_ports.
  • component_name - component name.
  • layer_label - layer spec for the label.
  • gc_port_name - gc_port_name port name.
  • get_input_label_function - function to get input label.

gdsfactory.routing.factories

gdsfactory.routing.path_length_matching

path_length_matched_points

def path_length_matched_points(list_of_waypoints: list[ndarray],
                               margin: float = 0.0,
                               modify_segment_i: int = -2,
                               extra_length: float = 0.0,
                               nb_loops: int = 1,
                               bend: ComponentSpec = bend_euler,
                               cross_section: CrossSectionSpec
                               | MultiCrossSectionAngleSpec = "strip",
                               **kwargs) -> list[ndarray]

Several types of paths won’t match correctly. We do not try to handle all the corner cases here. You will need to modify the input list of waypoints in some cases.

Arguments:

  • list_of_waypoints - [[p1, p2, p3,...], [q1, q2, q3,...], ...] the number of turns have to be identical (usually means same number of points. exception is if there are some flat angles)

  • margin - some extra space to budget for in addition to the bend radius in most cases, the default is fine

  • modify_segment_i - index of the segment which accommodates the new turns default is next to last segment (-2)

  • extra_length - distance added to all path length compensation. Useful is we want to add space for extra taper on all branches

  • nb_loops - number of extra loops added in the path if nb_loops==0, no extra loop is added, instead, in each route, the segment indexed by modify_segment_i is elongated to match the longest route in list_of_waypoints

  • bend - bend function

  • cross_section - cross_section factory **kwargs

  • Returns - another list of waypoints where

    • the path_length of each waypoints list are identical
    • the number of turns are identical

path_length_matched_points_add_waypoints

def path_length_matched_points_add_waypoints(
        list_of_waypoints: list[ndarray],
        modify_segment_i: int = -2,
        bend: ComponentSpec = bend_euler,
        margin: float = 0.0,
        extra_length: float = 0.0,
        nb_loops: int = 1,
        cross_section: CrossSectionSpec | MultiCrossSectionAngleSpec = "strip",
        **kwargs) -> list[ndarray]

Args are the following.

list_of_waypoints: a list of list_of_points:
    [[p1, p2, p3,...], [q1, q2, q3,...], ...]
    - the number of turns have to be identical
        (usually means same number of points. exception is if there are
        some flat angles)
modify_segment_i: index of the segment which accommodates the new turns
    default is next to last segment
bend: for bends
margin: some extra space to budget for in addition to the bend radius
    in most cases, the default is fine
extra_length: distance added to all path length compensation.
    Useful is we want to add space for extra taper on all branches
nb_loops: number of extra loops added in the path
cross_section: factory
**kwargs: cross_section settings

returns: another list of waypoints where: - the path_length of each waypoints list are identical - the number of turns are identical

Several types of paths won’t match correctly. We do not try to handle all the corner cases here. If the paths are not well behaved, the input list_of_waypoints needs to be modified.

To have flexibility in the path length, we need to add 4 bends One path has to be converted in this way:

.. code::

     __
    |  |
    |  |  This length is adjusted to make all path with the same length
    |  |
 ___|  |___

gdsfactory.routing.add_electrical_pads_top_dc

add_electrical_pads_top_dc

@cell
def add_electrical_pads_top_dc(
        component: ComponentSpec = straight_heater_metal,
        spacing: Float2 = (0.0, 100.0),
        pad_array: ComponentSpec = "pad_array",
        select_ports: Callable = select_ports_electrical,
        get_bundle_function: Callable = get_bundle_electrical,
        port_names: Strs | None = None,
        **kwargs) -> Component

Returns new component with electrical ports connected to top pad array.

Arguments:

  • component - component spec to connect to.

  • spacing - component to pad spacing.

  • pad_array - component spec for pad_array.

  • select_ports - function to select_ports.

  • get_bundle_function - function to route bundle of ports.

  • port_names - optional port names. Overrides select_ports.

  • kwargs - route settings.

    .. plot:: :include-source:

    import gdsfactory as gf c = gf.components.straight_heater_metal(length=100) c = gf.routing.add_electrical_pads_top_dc(c, width=10) c.plot()

gdsfactory.routing.get_route_sbend

get_route_sbend

def get_route_sbend(port1: Port, port2: Port, **kwargs) -> Route

Returns an Sbend Route to connect two ports.

Arguments:

  • port1 - start port.

  • port2 - end port.

    keyword Args:

  • npoints - number of points.

  • with_cladding_box - square bounding box to avoid DRC errors.

  • cross_section - function.

  • kwargs - cross_section settings.

    .. plot:: :include-source:

    import gdsfactory as gf

    c = gf.Component(“demo_route_sbend”) mmi1 = c << gf.components.mmi1x2() mmi2 = c << gf.components.mmi1x2() mmi2.movex(50) mmi2.movey(5) route = gf.routing.get_route_sbend(mmi1.ports[‘o2’], mmi2.ports[‘o1’]) c.add(route.references) c.plot()

gdsfactory.routing.get_bundle_sbend

get_bundle_sbend

def get_bundle_sbend(ports1: Port,
                     ports2: Port,
                     sort_ports: bool = True,
                     enforce_port_ordering: bool = True,
                     **kwargs) -> list[Route]

Returns a list of routes from ports1 to ports2.

Arguments:

  • ports1 - start ports.
  • ports2 - end ports.
  • sort_ports - sort ports.
  • kwargs - cross_section settings.

Returns:

list of routes.

gdsfactory.routing.auto_taper

taper_to_cross_section

def taper_to_cross_section(
        port: Port,
        cross_section: CrossSectionSpec) -> ComponentReference | None

Returns taper ComponentReference from a port to a given cross-section placed so that it connects to the input port.

Assumes that the taper component has width1 and width2 which map to the input and output port widths.

Arguments:

  • port - a port to connect to, usually from a ComponentReference

  • cross_section - a cross-section to transition to

    .. plot:: :include-source:

    from gdsfactory.routing.auto_taper import taper_to_cross_section from gdsfactory.cross_section import strip import gdsfactory as gf

    c = gf.Component()

    create a component reference to connect to

    wg = c << gf.components.straight()

    create a taper reference transitioning to strip from the rib waveguide

    taper = taper_to_cross_section(wg.ports[‘o1’], strip(width=2.0))

    add the taper reference to the parent component

    c.add(taper) c.plot()

gdsfactory.routing.get_bundle_from_waypoints

get_bundle_from_waypoints

def get_bundle_from_waypoints(ports1: list[Port],
                              ports2: list[Port],
                              waypoints: Coordinates,
                              straight: ComponentSpec = straight_function,
                              taper: ComponentSpec = taper_function,
                              bend: ComponentSpec = bend_euler,
                              sort_ports: bool = True,
                              cross_section: CrossSectionSpec
                              | MultiCrossSectionAngleSpec = strip,
                              separation: float | None = None,
                              on_route_error: Callable = get_route_error,
                              path_length_match_loops: int | None = None,
                              path_length_match_extra_length: float = 0.0,
                              path_length_match_modify_segment_i: int = -2,
                              **kwargs) -> list[Route]

Returns list of routes that connect bundle of ports with bundle of routes.

Routes follow a list of waypoints. Take a look at get_bundle_from_steps for easier definition.

Arguments:

  • ports1 - list of ports.
  • ports2 - list of ports.
  • waypoints - list of points defining a route.
  • straight - function that returns straights.
  • taper - function that returns tapers.
  • bend - function that returns bends.
  • sort_ports - sorts ports.
  • cross_section - cross_section.
  • separation - center to center, defaults to ports1 separation.
  • on_route_error - function to call for routing errors.
  • path_length_match_loops - Integer number of loops to add to bundle for path length matching (won’t try to match if None).
  • path_length_match_extra_length - Extra length to add to path length matching loops (requires path_length_match_loops != None).
  • path_length_match_modify_segment_i - Index of straight segment to add path length matching loops to (requires path_length_match_loops != None).
  • kwargs - cross_section settings.

gdsfactory.routing.route_fiber_array

route_fiber_array

def route_fiber_array(
    component: Component,
    fiber_spacing: str | float = "fiber_array_spacing",
    grating_coupler: ComponentSpecOrList = grating_coupler_te,
    bend: ComponentSpec = bend_euler,
    straight: ComponentSpec = straight_function,
    taper: ComponentSpec = taper_function,
    fanout_length: float | None = None,
    max_y0_optical: None = None,
    with_loopback: bool = True,
    nlabels_loopback: int = 2,
    straight_separation: float = 6.0,
    straight_to_grating_spacing: float = 5.0,
    optical_routing_type: int | None = None,
    connected_port_names: None = None,
    nb_optical_ports_lines: int = 1,
    force_manhattan: bool = False,
    excluded_ports: list[str] | None = None,
    grating_indices: list[int] | None = None,
    route_filter: Callable = get_route_from_waypoints,
    gc_port_name: str = "o1",
    gc_rotation: int = -90,
    layer_label: LayerSpec = "TEXT",
    layer_label_loopback: LayerSpec = "TEXT",
    component_name: str | None = None,
    x_grating_offset: int = 0,
    port_names: Strs | None = None,
    get_input_label_text_loopback_function:
    Callable = get_input_label_text_dash_loopback,
    get_input_label_text_function: Callable | None = get_input_label_text_dash,
    get_input_labels_function: Callable | None = get_input_labels_dash,
    select_ports: Callable = select_ports_optical,
    cross_section: CrossSectionSpec = strip,
    **kwargs
) -> tuple[
        list[ComponentReference | Label],
        list[list[ComponentReference]],
        list[Port],
        list[Port],
]

Returns component I/O elements for adding grating couplers with a fiber array Many components are fine with the defaults.

Arguments:

  • component - component spec to connect to.
  • fiber_spacing - spacing between the optical fibers.
  • grating_coupler - grating coupler instance, function or list of functions.
  • bend - for bends.
  • straight - straight.
  • fanout_length - target distance between gratings and the southmost component port. If None, automatically calculated.
  • max_y0_optical - Maximum y coordinate at which the intermediate optical ports can be set. Usually fine to leave at None.
  • with_loopback - If True, add compact loopback alignment ports.
  • nlabels_loopback - number of labels of align ports (0: no labels, 1: first port, 2: both ports2)
  • straight_separation - min separation between routing straights.
  • straight_to_grating_spacing - from align ports.
  • optical_routing_type - There are three options for optical routing.
    • 0 is very basic but can be more compact. Can also be used in combination with connected_port_names. or to route some components which otherwise fail with type 1.
    • 1 is the standard routing.
    • 2 uses the optical ports as a guideline for the component’s physical size (instead of using the actual component size). Useful where the component is large due to metal tracks
    • ``None: leads to an automatic decision based on size and number of I/O of the component.
  • connected_port_names - only for type 0 optical routing. Can specify which ports goes to which grating assuming the gratings are ordered from left to right. e.g [‘N0’, ‘W1’,‘W0’,‘E0’,‘E1’, ‘N1’ ] or [4,1,7,3]
  • nb_optical_ports_lines - number of lines with I/O grating couplers. One line by default.
  • WARNING - Only works properly if:
    • nb_optical_ports_lines divides the total number of ports.
    • the components have an equal number of inputs and outputs.
  • force_manhattan - sometimes port linker defaults to an S-bend due to lack of space to do manhattan. Force manhattan offsets all the ports to replace the s-bend by a straight link. This fails if multiple ports have the same issue.
  • excluded_ports - ports excluded from routing.
  • grating_indices - allows to fine skip some grating slots. e.g [0,1,4,5] will put two gratings separated by the pitch. Then there will be two empty grating slots, and after that an additional two gratings.
  • route_filter - straight and bend factories
  • gc_port_name - grating_coupler port name, where to route straights.
  • gc_rotation - grating_coupler rotation (deg).
  • layer_label - for measurement labels.
  • component_name - name of component.
  • x_grating_offset - x offset.
  • port_names - port labels to route_to_fiber_array.
  • get_input_label_text_loopback_function - function to get input labels for grating couplers.
  • get_input_label_text_function - for the label.
  • get_input_labels_function - for the label.
  • select_ports - function to select ports for which to add grating couplers.
  • kwargs - cross_section settings.

Returns:

  • elements - list of references and labels.
  • gratings - grating coupler reference list.
  • ports_grating_input_waveguide - grating coupler input waveguide ports.
  • ports_loopback - list of grating coupler input waveguide ports.
  • ports_component - list of optical ports.

gdsfactory.routing.all_angle

get_connector

def get_connector(name: str) -> Connector

Gets a connector function by name.

Arguments:

  • name - the name of the connector function to retrieve.

Returns:

The specified connector function.

vector_intersection

def vector_intersection(p0,
                        a0,
                        p1,
                        a1,
                        max_distance=100000,
                        raise_error=True) -> np.ndarray | None

Gets the intersection point between two vectors, specified by (point, angle) pairs, (p0, a0) and (p1, a1).

Arguments:

  • p0 - x,y location of vector 0
  • a0 - angle of vector 0 [degrees]
  • p1 - x,y location of vector 1
  • a1 - angle of vector 1 [degrees]
  • max_distance - maximum search distance for an intersection [um]
  • raise_error - if True, raises an error if no intersection is found. Otherwise, returns None in that case.

Returns:

The (x,y) point of intersection, if one is found. Otherwise None.

low_loss_connector

def low_loss_connector(port1: Port,
                       port2: Port,
                       prioritized_cross_sections: list[CrossSectionSpec]
                       | None = None,
                       **kwargs) -> list[ComponentReference]

Routes between two ports, using the lowest-loss cross-section which will fit.

Arguments:

  • port1 - the starting port
  • port2 - the ending port
  • prioritized_cross_sections - a list of cross-sections, sorted by preference (starting with most preferred). If None, uses the global variable LOW_LOSS_CROSS_SECTIONS

Arguments:

kwargs are added for API compatibility, but they are ignored.

Returns:

A list of component references comprising the connection

straight_connector

def straight_connector(
        port1: Port,
        port2: Port,
        cross_section: CrossSectionSpec = "strip") -> list[ComponentReference]

Connects between the two ports with a straight of the given cross-section.

Arguments:

  • port1 - the starting port.
  • port2 - the ending port.
  • cross_section - the cross-section to use.

Returns:

A list of component references comprising the connection.

auto_taper_connector

def auto_taper_connector(
    port1: Port,
    port2: Port,
    cross_section: CrossSectionSpec = "strip",
    inner_connector: Connector = straight_connector
) -> list[ComponentReference]

Connects the two ports with a straight in the specified cross_section, adding tapers at either end if necessary.

Arguments:

  • port1 - the first port.
  • port2 - the final port.
  • cross_section - the primary cross section to use for the route.
  • inner_connector - the connector to use after attaching tapers.

Returns:

A list of references comprising the connection.

CONNECTORS

A dictionary of named connectors which can be used for all-angle routing

get_bundle_all_angle

def get_bundle_all_angle(ports1: list[Port],
                         ports2: list[Port],
                         steps: list[StepAllAngle] | None = None,
                         cross_section: CrossSectionSpec = "strip",
                         bend: ComponentSpec = "bend_euler",
                         connector: str = "low_loss",
                         start_angle: float | None = None,
                         end_angle: float | None = None,
                         end_connector: str | None = None,
                         end_cross_section: CrossSectionSpec | None = None,
                         separation: float | None = None,
                         **kwargs) -> list[Route]

Connects a bundle of ports, allowing steps which create waypoints at arbitrary, non-manhattan angles.

Arguments:

  • ports1 - ports at the start of the bundle.
  • ports2 - ports at the end of the bundle.
  • steps - a list of steps, which contain directives on how to proceed with the route. “x”, “y”, “dx”, “dy”, “ds”, “exit_angle”, “cross_section”, “connector”, “separation”. The first route, between ports1[0] and ports2[0] will take on the role of the primary route, and other routes will follow, given the bundling logic. It is assume that both ports1 and ports2 are sorted.
  • cross_section - the default cross-section of the bends. Then the specified connector may also use this information for straights in between.
  • bend - the default component to use for the bends.
  • connector - the default connector to use to connect between two ports.
  • start_angle - if defined and different from the angle of port1, will cap the starting port with a bend, as to exit with this angle.
  • end_angle - if defined, and different from the angle of port2, will cap the ending port with a bend, as to exit with this angle.
  • end_connector - specifies the connector to use for the final straight segment of the route.
  • end_cross_section - specifies the cross section to use for the final straight segment of the route.
  • separation - specifies the separation between adjacent routes. If None, will query each segment’s cross-section’s and choose the largest value.
  • kwargs - added for compatibility, but in general, kwargs will be ignored with a warning.

Returns:

List of Routes between ports1 and ports2.

.. plot:: :include-source:

import gdsfactory as gf c = gf.Component(“demo”)

mmi = gf.components.mmi2x2(width_mmi=10, gap_mmi=3) mmi1 = c << mmi mmi2 = c << mmi

mmi2.move((100, 30)) mmi2.rotate(30)

routes = gf.routing.get_bundle_all_angle( mmi1.get_ports_list(orientation=0), [mmi2.ports[“o2”], mmi2.ports[“o1”]], connector=None, ) for route in routes: c.add(route.references) c.plot()

gdsfactory.routing.fanout2x2

fanout2x2

@gf.cell
def fanout2x2(component: ComponentSpec = straight,
              port_spacing: float = 20.0,
              bend_length: float | None = None,
              npoints: int = 101,
              select_ports: Callable = select_ports_optical,
              cross_section: CrossSectionSpec = "strip",
              **kwargs) -> Component

Returns component with Sbend fanout routes.

Arguments:

  • component - to fanout.

  • port_spacing - for the returned component.

  • bend_length - length of the bend (defaults to port_spacing).

  • npoints - for sbend.

  • select_ports - function to select optical_ports ports.

  • cross_section - cross_section spec.

  • kwargs - cross_section settings.

    .. plot:: :include-source:

    import gdsfactory as gf c = gf.components.nxn(west=2, east=2)

    cc = gf.routing.fanout2x2(component=c, port_spacing=20) cc.plot()

gdsfactory.routing.get_bundle_corner

get_bundle_corner

def get_bundle_corner(ports1: list[Port],
                      ports2: list[Port],
                      route_filter: Callable[...,
                                             Route] = get_route_from_waypoints,
                      separation: float = 5.0,
                      path_length_match_loops: int | None = None,
                      path_length_match_extra_length: float = 0.0,
                      path_length_match_modify_segment_i: int = -2,
                      enforce_port_ordering: bool = True,
                      **kwargs) -> list[Route]

Connect banks of ports with either 90Deg or 270Deg angle between them.

Arguments:

  • ports1 - list of start ports.
  • ports2 - list of end ports.
  • route_filter - filter to apply to the manhattan waypoints e.g get_route_from_waypoints for deep etch strip straight.
  • separation - in um.
  • path_length_match_loops - optional number of loops for path length matching.
  • path_length_match_extra_length - extra length (um) for path length matching.
  • path_length_match_modify_segment_i - segment to increase length.
  • enforce_port_ordering - If True, enforce that the ports are connected in the specific order.

Returns:

returns a list of elements which can be added to a component. [route_filter(r) for r in routes] where routes is a list of coordinates list e.g with default get_route_from_waypoints.

::

Bend-types

90 Deg bend A1 A2 AN | | ... | | | / / / / / / / B1 ----/ / _/ B2 -----/ / / ... _/ BN --------/

270 Deg bend /------------
/
/ /-------\
/ / \
| / /--\ | | | / / | | ...| | | / B1 B2 BN | | | | \ --- A1 | ----- A2 | ... ------ AN

gdsfactory.routing.get_bundle_u

get_bundle_udirect

def get_bundle_udirect(ports1: list[Port],
                       ports2: list[Port],
                       route_filter: Callable = get_route_from_waypoints,
                       separation: float = 5.0,
                       start_straight_length: float = 0.01,
                       end_straight_length: float = 0.01,
                       bend: ComponentSpec = bend_euler,
                       path_length_match_loops: int | None = None,
                       path_length_match_extra_length: float = 0.0,
                       path_length_match_modify_segment_i: int = -2,
                       enforce_port_ordering: bool = True,
                       **kwargs) -> list[Route]

Returns list of routes.

Arguments:

  • ports1 - list of start ports.
  • ports2 - list of end ports.
  • route_filter - filter to apply to the manhattan waypoints e.g get_route_from_waypoints for deep etch strip straight.
  • separation - between straights.
  • start_straight_length - in um.
  • end_straight_length - in um.
  • bend - bend spec.
  • path_length_match_loops - Integer number of loops to add to bundle for path length matching (won’t try to match if None).
  • path_length_match_extra_length - Extra length to add to path length matching loops (requires path_length_match_loops != None).
  • path_length_match_modify_segment_i - Index of straight segment to add path length matching loops to (requires path_length_match_loops != None).
  • enforce_port_ordering - If True, enforce that the ports are connected in the specific order.

Returns:

[route_filter(r) for r in routes] where routes is a list of lists of coordinates e.g with default get_route_from_waypoints, returns list of elements which can be added to a component

Used for routing multiple ports back to a bundled input in a component

::

  • X - start ports

  • D - End ports

    On this example below, the axis is along X

    X------
    | X----\ | ... | | X--\ | | | | | D-------------------/ | | ... | | D---------------------/ | D----------------------- D-----------------------
    D---------------------\ | ... | | D-------------------\ | | | | | X--/ | | ... | | X----/ | | X------/

get_bundle_uindirect

def get_bundle_uindirect(ports1: list[Port],
                         ports2: list[Port],
                         route_filter: Callable = get_route_from_waypoints,
                         separation: float = 5.0,
                         extension_length: float = 0.0,
                         start_straight_length: float = 0.01,
                         end_straight_length: float = 0.01,
                         enforce_port_ordering: bool = True,
                         **routing_params) -> list[Route]

Returns list of routes.

Arguments:

  • ports1 - list of start ports.
  • ports2 - list of end ports.
  • route_filter - filter to apply to the manhattan waypoints e.g get_route_from_waypoints for deep etch strip straight
  • separation - center to center waveguide spacing.
  • extension_length - in um.
  • start_straight_length - extends in um.
  • end_straight_length - in um.

Returns:

list of routes, where each route has references, ports and length.

Used for routing multiple ports back to a bundled input in a component

::

  • X - start ports

  • D - End ports

    X------ X---- | ... | | X--\ | | | | | /--------------------------/ | | | | | | /--------------------------/ | | | | | | /--------------------------/ | | | | | --D | ----D | ... ------D /------D | ... | /----D | | /--D | | | | | -------------------------- | | | | --------------------------\ | | | | --------------------------\ | | | | | X--/ | | ... | | X----/ | X------/ ‘’’

gdsfactory.routing.add_electrical_pads_shortest

add_electrical_pads_shortest

@gf.cell
def add_electrical_pads_shortest(
        component: ComponentSpec = straight,
        pad: ComponentSpec = "pad",
        pad_port_spacing: float = 50.0,
        select_ports: Callable = select_ports_electrical,
        port_names: Strs | None = None,
        port_orientation: float = 90,
        layer: gf.typings.LayerSpec = "M3") -> Component

Returns new Component with a pad by each electrical port.

Arguments:

  • component - to route.

  • pad - pad element or function.

  • pad_port_spacing - spacing between pad and port.

  • select_ports - function to select ports.

  • port_orientation - in degrees.

  • port_names - optional port names. Overrides select_ports.

  • layer - for the routing.

    .. plot:: :include-source:

    import gdsfactory as gf c = gf.components.straight_heater_metal(length=100) c = gf.routing.add_electrical_pads_shortest(c, port_orientation=270) c.plot()

gdsfactory.routing.get_routes_bend180

get_routes_bend180

def get_routes_bend180(ports: list[Port] | dict[str, Port],
                       bend: ComponentSpec = bend_euler,
                       cross_section: CrossSectionSpec = strip,
                       bend_port1: str | None = None,
                       bend_port2: str | None = None,
                       **kwargs) -> Routes

Returns routes made by 180 degree bends.

Arguments:

  • ports - List or dict of ports.

  • bend - function for bend.

  • cross_section - spec.

  • bend_port1 - name.

  • bend_port2 - name.

  • kwargs - bend settings.

    .. plot:: :include-source:

    import gdsfactory as gf

    c = gf.Component(“get_routes_bend180”) pad_array = gf.components.pad_array(orientation=270) c1 = c << pad_array c2 = c << pad_array c2.rotate(90) c2.movex(1000) c2.ymax = -200

    routes_bend180 = gf.routing.get_routes_bend180( ports=c2.get_ports_list(), radius=75 / 2, ) c.add(routes_bend180.references)

    routes = gf.routing.get_bundle( c1.get_ports_list(), routes_bend180.ports, ) for route in routes: c.add(route.references) c.plot()

gdsfactory.routing.get_routes_straight

get_routes_straight

def get_routes_straight(ports: list[Port] | dict[str, Port],
                        straight: ComponentSpec = straight,
                        **kwargs) -> Routes

Returns routes made by 180 degree straights.

Arguments:

  • ports - List or dict of ports.

  • straight - function for straight.

  • kwargs - waveguide settings.

    .. plot:: :include-source:

    import gdsfactory as gf

    c = gf.Component(“get_routes_straight”) pad_array = gf.components.pad_array() c1 = c << pad_array c2 = c << pad_array c2.ymax = -200

    routes = gf.routing.get_routes_straight(ports=c1.get_ports_list(), length=200) c.add(routes.references) c.plot()

gdsfactory.difftest

GDS regression test. Inspired by lytest.

diff

def diff(ref_file: PathType,
         run_file: PathType,
         xor: bool = True,
         test_name: str = "") -> bool

Returns True if files are different, prints differences and shows them in klayout.

Arguments:

  • ref_file - reference (old) file.
  • run_file - run (new) file.
  • xor - runs xor on every layer between ref and run files.
  • test_name - prefix for the new cell.

difftest

def difftest(component: gf.Component,
             test_name: gf.Component | None = None,
             dirpath: pathlib.Path = PATH.gds_ref,
             xor: bool = True,
             dirpath_run: pathlib.Path = PATH.gds_run) -> None

Avoids GDS regressions tests on the GeometryDifference.

If files are the same it returns None. If files are different runs XOR between new component and the GDS reference stored in dirpath and raises GeometryDifference if there are differences and show differences in KLayout.

If it runs for the fist time it just stores the GDS reference.

Arguments:

  • component - to test if it has changed.
  • test_name - used to store the GDS file.
  • dirpath - directory where reference files are stored.
  • xor - runs XOR.
  • dirpath_run - directory to store gds file generated by the test.

gdsfactory.symbols

symbol

def symbol(func: _F, *args, **kwargs) -> _F

Decorator for Component symbols.

Wraps cell_without_validator Validates type annotations with pydantic.

Implements a cache so that if a symbol has already been built it will return the component from the cache directly. This avoids 2 exact cells that are not references of the same cell You can always over-ride this with cache = False.

When decorate your functions with cell you get:

  • CACHE: avoids creating duplicated cells.
  • name: gives Components a unique name based on parameters.
  • adds Component.info with default, changed and full component settings.

Arguments:

  • autoname bool - if True renames component based on args and kwargs.
  • name str - Optional (ignored when autoname=True).
  • cache bool - returns component from the cache if it already exists. if False creates a new component. by default True avoids having duplicated cells with the same name.
  • info - updates component.info dict.
  • prefix - name_prefix, defaults to function name.
  • max_name_length - truncates name beyond some characters (32) with a hash.
  • decorator - function to run over the component.

symbol_from_cell

def symbol_from_cell(func: _F, to_symbol: Callable[[Component, ...],
                                                   Component]) -> _F

Creates a symbol function from a component function.

Arguments:

  • func - the cell function
  • to_symbol - the function that transforms the output of the cell function into a symbol

Returns:

a symbol function

floorplan_with_block_letters

@symbol
def floorplan_with_block_letters(
    component: Component, copy_layers: LayerSpecs = ("WG", )) -> Component

Returns symbol with same floorplan as component layout, function name and optionally shapes on layers copied from the original layout.

Arguments:

  • component - the layout component.
  • copy_layers - if specified, copies layers from the layout into the symbol.

Returns:

A component representing the symbol.

gdsfactory.write_cells

Generate the code from a GDS file based PDK.

get_script

def get_script(gdspath: PathType, module: str | None = None) -> str

Returns script for importing a fixed cell.

Arguments:

  • gdspath - fixed cell gdspath.
  • module - if any includes plot directive.

get_import_gds_script

def get_import_gds_script(dirpath: PathType, module: str | None = None) -> str

Returns import_gds script from a directory with all the GDS files.

Arguments:

  • dirpath - fixed cell directory path.
  • module - Optional plot directive to plot imported component.

write_cells_recursively

def write_cells_recursively(
        cell: gdstk.Cell,
        unit: float = 1e-6,
        precision: float = 1e-9,
        timestamp: datetime.datetime | None = _timestamp2019,
        dirpath: pathlib.Path | None = None) -> dict[str, Path]

Write gdstk cells recursively.

Arguments:

  • cell - gdstk cell.
  • unit - unit size for objects in library. 1um by default.
  • precision - for library dimensions (m). 1nm by default.
  • timestamp - Defaults to 2019-10-25. If None uses current time.
  • dirpath - directory for the GDS file to write to.

Returns:

  • gdspaths - dict of cell name to gdspath.

write_cells

def write_cells(gdspath: PathType | None = None,
                dirpath: PathType | None = None,
                unit: float = 1e-6,
                precision: float = 1e-9,
                timestamp: datetime.datetime | None = _timestamp2019,
                recursively: bool = False,
                flatten: bool = False) -> dict[str, Path]

Writes cells into separate GDS files.

Arguments:

  • gdspath - GDS file to write cells.
  • dirpath - directory path to write GDS files to. Defaults to current working directory.
  • unit - unit size for objects in library. 1um by default.
  • precision - for object dimensions in the library (m). 1nm by default.
  • timestamp - Defaults to 2019-10-25. If None uses current time.
  • recursively - writes all cells recursively. If False writes only top cells.
  • flatten - flatten cell.

Returns:

  • gdspaths - dict of cell name to gdspath.

gdsfactory.grid

pack a list of components into a grid.

Adapted from PHIDL https://github.com/amccaugh/phidl/ by Adam McCaughan

grid

@cell
def grid(components: tuple[ComponentSpec, ...] | None = None,
         spacing: tuple[float, float] = (5.0, 5.0),
         separation: bool = True,
         shape: tuple[int, int] | None = None,
         align_x: str = "x",
         align_y: str = "y",
         edge_x: str = "x",
         edge_y: str = "ymax",
         rotation: int = 0,
         h_mirror: bool = False,
         v_mirror: bool = False,
         add_ports_prefix: bool = True,
         add_ports_suffix: bool = False) -> Component

Returns Component with a 1D or 2D grid of components.

Arguments:

  • components - Iterable to be placed onto a grid. (can be 1D or 2D).
  • 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) along (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).
  • add_ports_prefix - adds port names with prefix.
  • add_ports_suffix - adds port names with suffix.

Returns:

Component containing components grid.

.. plot:: :include-source:

import gdsfactory as gf

components = [gf.components.triangle(x=i) for i in range(1, 10)] c = gf.grid( components, shape=(1, len(components)), rotation=0, h_mirror=False, v_mirror=True, spacing=(100, 100), ) c.plot()

grid_with_text

@cell
def grid_with_text(components: tuple[ComponentSpec, ...] | None = None,
                   text_prefix: str = "",
                   text_offsets: tuple[Float2, ...] = ((0, 0), ),
                   text_anchors: tuple[Anchor, ...] = ("cc", ),
                   text_mirror: bool = False,
                   text_rotation: int = 0,
                   text: ComponentSpec | None = text_rectangular,
                   labels: tuple[str, ...] | None = None,
                   **kwargs) -> Component

Returns Component with 1D or 2D grid of components with text labels.

Arguments:

  • components - Iterable to be placed onto a grid. (can be 1D or 2D).

  • text_prefix - for labels. For example. ‘A’ will produce ‘A1’, ‘A2’, ...

  • text_offsets - relative to component anchor. Defaults to center.

  • text_anchors - relative to component (ce cw nc ne nw sc se sw center cc).

  • text_mirror - if True mirrors text.

  • text_rotation - Optional text rotation.

  • text - function to add text labels.

  • labels - optional, specify a tuple of labels rather than using a text_prefix.

    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’} to perform the x (column) alignment along.

  • align_y - {‘y’, ‘ymin’, ‘ymax’} to perform the y (row) alignment along.

  • edge_x - {‘x’, ‘xmin’, ‘xmax’} to perform the x (column) distribution ignored if separation = True.

  • edge_y - {‘y’, ‘ymin’, ‘ymax’} to perform the y (row) distribution along ignored if separation = True.

  • rotation - for each reference in degrees.

    .. plot:: :include-source:

    import gdsfactory as gf

    components = [gf.components.triangle(x=i) for i in range(1, 10)] c = gf.grid_with_text( components, shape=(1, len(components)), rotation=0, h_mirror=False, v_mirror=True, spacing=(100, 100), text_offsets=((0, 100), (0, -100)), text_anchors=(“nc”, “sc”), ) c.plot()

gdsfactory.snap

snaps values and coordinates to the GDS grid in nm.

gdsfactory.samples.pdk

gdsfactory.samples.pdk.fab_d

gdsfactory.samples.pdk.fab_d.phase_shifters

gdsfactory.samples.pdk.test_fab_c

Test all the components in fab_c.

In gdsfactory we use gdslib as a place to store the GDS files.

For your PDK i recommend that you store the store the reference GDS files on the same repo as you store the code. See code below

from __future__ import annotations
from functools import partial
import pathlib

dirpath = pathlib.Path(__file__).absolute().with_suffix(".gds")

def test_gds(component_name: str) -> None:
    component = cells[component_name]()
    test_name = f"fabc_{component_name}"
    difftest(component, test_name=test_name, dirpath=dirpath)

test_gds

def test_gds(component_name: str) -> None

Avoid regressions in GDS names, shapes and layers.

Runs XOR and computes the area.

test_settings

def test_settings(component_name: str,
                  data_regression: DataRegressionFixture) -> None

Avoid regressions in component settings and ports.

test_assert_ports_on_grid

def test_assert_ports_on_grid(component_name: str) -> None

Ensures all ports are on grid to avoid 1nm gaps.

gdsfactory.samples.pdk.fab_c_to_updk

Write FabC example PDK into uPDK YAML format.

gdsfactory.samples.pdk.fab_c

FabC example.

get_layer_stack_fab_c

def get_layer_stack_fab_c(thickness: float = 350.0) -> LayerStack

Returns generic LayerStack.

gdsfactory.samples.13_component_netlist

netlist_yaml

@gf.cell
def netlist_yaml() -> Component

Test netlist yaml.

.. code::

arm_top
 _____
|     |

CP1= =CP2= |_____|

 arm_bot

gdsfactory.samples.17_ports

Ports define where each port has the follow properties.

  • name
  • center: (x, y)
  • width:
  • orientation: (deg) 0, 90, 180, 270. where 0 faces east, 90 (north), 180 (west), 270 (south)

component_with_port

@gf.cell
def component_with_port(length: float = 5.0,
                        width: float = 0.5,
                        layer: LayerSpec = "WG") -> Component

Returns a component with one port on the west side.

Arguments:

  • length - in um.
  • width - waveguide width in um.
  • layer - layer.

gdsfactory.samples.30_lidar_pcell

LiDAR demo.

Exercise1. increase the number of elements of the phase array.

Exercise2. Make a PCell.

lidar

@gf.cell
def lidar(
    noutputs=2**2,
    antenna_pitch=2.0,
    splitter_tree_spacing=(50.0, 70.0)) -> gf.Component

LiDAR demo.

Arguments:

  • noutputs - number of outputs.
  • antenna_pitch - pitch of the antennas.
  • splitter_tree_spacing - spacing of the splitter tree.

gdsfactory.samples.23_reticle

Sample of a reticle top level Component.

gdsfactory.samples.30_lidar_with_pads

LiDAR demo with pads.

Exercise1. increase the number of elements of the phase array.

Exercise2. Make a PCell.

gdsfactory.samples.23_reticle_passives_pack

mzi_te

def mzi_te(**kwargs) -> Component

Returns MZI with TE grating couplers.

demo_pack

@gf.cell
def demo_pack() -> Component

Sample reticle.

gdsfactory.samples.19_references

gdsfactory.samples.all_angle_routing

demo_all_angle_routing

@cell
def demo_all_angle_routing() -> Component

Demonstrate all-angle routing.

gdsfactory.samples.big_device

big_device

@gf.cell
def big_device(size: tuple[float, float] = (400.0, 400.0),
               nports: int = 16,
               spacing: float = 15.0,
               layer: tuple[int, int] = (1, 0),
               wg_width: float = 0.5,
               cross_section: CrossSectionSpec = "strip") -> Component

Big component with N ports on each side.

Arguments:

  • size - x, y.
  • nports - number of ports.
  • spacing - in um.
  • layer - spec.
  • wg_width - waveguide width in um.
  • cross_section - spec.

gdsfactory.samples.23_reticle_passives_grid

mzi_te

def mzi_te(**kwargs) -> Component

Returns MZI with TE grating couplers.

gdsfactory.samples.01_component_pcell_with_pins

You can add pins in a pin layer to clearly see the component ports.

straight_narrow

@gf.cell
def straight_narrow(length: float = 5.0,
                    width: float = 0.3,
                    layer: LayerSpec = (2, 0)) -> gf.Component

Returns straight Component.

Arguments:

  • length - of the straight.
  • width - in um.
  • layer - layer spec

gdsfactory.samples.30_lidar

LiDAR demo.

Exercise1. increase the number of elements of the phase array.

Exercise2. Make a PCell.

gdsfactory.samples.06_remapping_layers

You can remap layers.

gdsfactory.samples.demo.drc_errors

Write GDS with sample errors.

enclosing

@gf.cell
def enclosing(
    enclosing: float = 0.1,
    layer1: Layer = (40, 0),
    layer2: Layer = (41, 0)
) -> Component

Layer1 must be enclosed by layer2 by value.

checks if layer1 encloses (is bigger than) layer2 by value

gdsfactory.samples.demo

gdsfactory.samples.demo.layers_sky130

gdsfactory.samples.demo.lvs

LVS demo.

pads_correct

@gf.cell
def pads_correct(pad=gf.components.pad,
                 cross_section="metal3") -> gf.Component

Returns 2 pads connected with metal wires.

pads_shorted

@gf.cell
def pads_shorted(pad=gf.components.pad,
                 cross_section="metal3") -> gf.Component

Returns 2 pads connected with metal wires.

gdsfactory.samples.demo.layers_xsection

gdsfactory.samples.demo.pcell

PCell demo.

mzi_with_bend

@gf.cell
def mzi_with_bend(radius: float = 10)

Returns MZI interferometer with bend.

gdsfactory.samples.demo.benchmark.snap_demo_phidl

gdsfactory.samples.demo.benchmark.fill_demo

fill is now slower.

This code takes now 5 seconds to run.

in version 5.18.6 it was taking 0.66 seconds to run

gdsfactory.samples

gdsfactory.samples.18_port_markers

You can define a function to add pins.

gdsfactory.samples.01_component_pcell

Based on phidl tutorial.

We’ll start by assuming we have a function straight() which already exists and makes us a simple straight waveguide. Many functions like this exist in the gdsfactory.components library and are ready-for-use. We write this one out fully just so it’s explicitly clear what’s happening

straight_wide

@gf.cell
def straight_wide(length: float = 5.0,
                  width: float = 1.0,
                  layer: LayerSpec = (2, 0)) -> gf.Component

Returns straight Component.

Arguments:

  • length - of the straight.
  • width - in um.
  • layer - layer spec

gdsfactory.samples.12_component_refs

Lets create a crossing component with two references to other components (crossing_arm).

  • add references to a component (one of the arm references rotated)
  • add ports from the child references into the parent cell
  • use Component.auto_rename_ports() to rename ports according to their location

crossing_arm

@gf.cell
def crossing_arm(
    wg_width: float = 0.5,
    r1: float = 3.0,
    r2: float = 1.1,
    taper_width: float = 1.2,
    taper_length: float = 3.4,
    layer_wg: Layer = (1, 0),
    layer_slab: Layer = (2, 0)
) -> Component

Crossing arm.

Arguments:

  • wg_width - waveguide width.
  • r1 - radius of the ellipse.
  • r2 - radius of the ellipse.
  • taper_width - width of the taper.
  • taper_length - length of the taper.
  • layer_wg - waveguide layer.
  • layer_slab - slab layer.

gdsfactory.samples.08_group

Group references. Distribute them as you want.

Distribute different references in the X direction.

gdsfactory.samples.15_component_sequence1

You can use component_sequence as a convenient function for cascading components, where you need to keep track of multiple tapers, doped sections, heaters etc...

The idea is to associate one symbol per type of section. A section is uniquely defined by the component, input port name and output port name.

The mapping between symbols and components is supplied by a dictionary. The actual chain of components is supplied by a string or a list

gdsfactory.samples.25_slot_cross_section

Small demonstration of the slot cross_section utilizing add_center_section=False.

gdsfactory.samples.snap_issue

snap issue

gdsfactory.samples.11_component_layout

Lets create a new component.

We create a function which returns a gf.Component.

Lets build straight crossing out of a vertical and horizontal arm

  • Create a component using a function with the cell decorator to define the name automatically and uniquely.
  • Define the polygons in the component
  • Add ports to the component so you can connect it with other components

crossing_arm

@gf.cell
def crossing_arm(wg_width: float = 0.5,
                 r1: float = 3.0,
                 r2: float = 1.1,
                 taper_width: float = 1.2,
                 taper_length: float = 3.4) -> Component

Returns a crossing arm.

Arguments:

  • wg_width - waveguide width.
  • r1 - radius of the ellipse.
  • r2 - radius of the ellipse.
  • taper_width - width of the taper.
  • taper_length - length of the taper.

gdsfactory.samples.07_flattening_device

From phidl tutorial.

Flattening a Component

Sometimes you want to remove cell structure from a Component while keeping all of the shapes/polygons intact and in place.

The Component.flatten() method returns a new flatten Component with all the polygons inside the Component, and removes all the underlying references. Also, if you specify the single_layer argument it will move all of the polygons to that single layer.

gdsfactory.samples.04_connect

based on phidl tutorial.

Connecting devices with connect()

The connect command allows you to connect ComponentReference ports together like Lego blocks.

There is an optional parameter called overlap which is useful if you have shapes you want to intersect with some overlap, or with a negative number if you want to separate the ports.

gdsfactory.samples.03_move

based on phidl tutorial.

Manipulating geometry 1 - Basic movement and rotation

There are several actions we can take to move and rotate the geometry. These actions include movement, rotation, and reflection.

gdsfactory.samples.21_add_fiber_array

You can route all component optical ports to a fiber array.

gdsfactory.samples.snap_bends

Snap bends together.

gdsfactory.samples.02_component_autoname

When you create components you have to make sure they have unique names.

the cell decorator gives unique names to components that depend on their parameters.

gdsfactory.samples.16_component_sequence2

cutback_phase

@gf.cell
def cutback_phase(straight_length: float = 100.0,
                  bend_radius: float = 12.0,
                  n: int = 2) -> Component

Modulator sections connected by bends.

Arguments:

  • straight_length - length of the straight waveguides.
  • bend_radius - radius of the bends.
  • n - number of modulator sections.

gdsfactory.samples.24_doe_2

Design of Experiment (DOE) with custom add_fiber_array function.

In this case add_fiber_array does not add labels.

You can use gf.add_labels.add_labels_to_ports.

gdsfactory.samples.24_doe_3

Design of Experiment (DOE) with custom add_fiber_array function.

In this case add_fiber_array does not add labels.

You can use gf.add_labels.add_labels_to_ports.

gdsfactory.samples.05_remove_layers

You can remove a list of layers from a component.

gdsfactory.samples.14_component_connectivity

ring_single_sample

@gf.cell
def ring_single_sample(gap: float = 0.2,
                       radius: float = 10.0,
                       length_x: float = 4.0,
                       length_y: float = 0.010,
                       coupler_ring: ComponentSpec = "coupler_ring",
                       straight: ComponentSpec = "straight",
                       bend: ComponentSpec = "bend_euler",
                       cross_section: CrossSectionSpec = "strip",
                       **kwargs) -> Component

Single bus ring made of a ring coupler.

(cb: bottom) connected with two vertical straights (wl: left, wr: right) two bends (bl, br) and horizontal straight (wg: top).

Arguments:

  • gap - gap between for coupler.

  • radius - for the bend and coupler.

  • length_x - ring coupler length.

  • length_y - vertical straight length.

  • coupler_ring - ring coupler function.

  • straight - straight function.

  • bend - 90 degrees bend function.

  • cross_section - spec.

  • kwargs - cross_section settings.

    .. code::

    bl-wt-br | | wl wr length_y | | --==cb==-- gap

    length_x

gdsfactory.samples.22_add_pads

You can also use the fiber array routing functions for connecting to pads.

gdsfactory.samples.20_components

Components. You can adapt some component functions from the gdsfactory.components module. Each function there returns a Component object. Here are two equivalent functions.

gdsfactory.samples.22_add_fiber_single

You can also connect a component with single fiber INPUT and OUTPUTS (no fiber array).

gdsfactory.samples.24_doe

Lets pack a doe and export it with metadata.

gdsfactory.install

Install Klayout and GIT plugins.

install_gdsdiff

def install_gdsdiff() -> None

Install gdsdiff tool for GIT.

get_klayout_path

def get_klayout_path() -> pathlib.Path

Returns KLayout path.

copy

def copy(src: pathlib.Path, dest: pathlib.Path) -> None

Copy overwriting file or directory.

install_klayout_package

def install_klayout_package() -> None

Install gdsfactory KLayout package.

Equivalent to using KLayout package manager.

install_klayout_technology

def install_klayout_technology(tech_dir: pathlib.Path,
                               tech_name: str | None = None) -> None

Install technology to KLayout.

convert_py_to_ipynb

def convert_py_to_ipynb(files=py_files,
                        output_folder=PATH.cwd / "notebooks") -> None

Convert notebooks from markdown to ipynb.

gdsfactory.add_tapers

get_ports_and_tapers

def get_ports_and_tapers(
    component: ComponentSpec,
    taper: ComponentSpec = taper_function,
    select_ports: Callable | None = select_ports_optical
) -> tuple[list[Port], list[ComponentReference]]

Returns ports and taper elements for a component.

add_tapers

@cell
def add_tapers(component: ComponentSpec,
               taper: ComponentFactory = taper_function,
               select_ports: Callable | None = select_ports_optical,
               ports: list[Port] | None = None,
               taper_port_name1: str = "o1",
               taper_port_name2: str = "o2") -> Component

Returns new component with taper in all optical ports.

Arguments:

  • component - spec for the component to add tap ers to.
  • taper - taper spec for each port.
  • select_ports - function to select ports.
  • ports - Optional list of ports to add tapers to. Defaults to select_ports(component.ports).
  • taper_port_name1 - for input.
  • taper_port_name2 - for output.

gdsfactory.add_ports

Add ports from pin markers or labels.

add_ports_from_markers_square

def add_ports_from_markers_square(component: Component,
                                  pin_layer: LayerSpec = "DEVREC",
                                  port_layer: LayerSpec | None = None,
                                  orientation: int | None = 90,
                                  min_pin_area_um2: float = 0,
                                  max_pin_area_um2: float = 150 * 150,
                                  pin_extra_width: float = 0.0,
                                  port_names: tuple[str, ...] | None = None,
                                  port_name_prefix: str | None = None,
                                  port_type: str = "optical") -> Component

Add ports from square markers at the port center in port_layer.

Arguments:

  • component - to read polygons from and to write ports to.
  • pin_layer - for port markers.
  • port_layer - for the new created port.
  • orientation - in degrees 90 north, 0 east, 180 west, 270 south.
  • min_pin_area_um2 - ignores pins with area smaller than min_pin_area_um2.
  • max_pin_area_um2 - ignore pins for area above certain size.
  • pin_extra_width - 2*offset from pin to straight.
  • port_names - names of the ports (defaults to {i}).
  • port_name_prefix - defaults to ‘o’ for optical and ‘e’ for electrical.
  • port_type - optical, electrical.

add_ports_from_markers_center

def add_ports_from_markers_center(component: Component,
                                  pin_layer: LayerSpec = "PORT",
                                  port_layer: LayerSpec | None = None,
                                  inside: bool = False,
                                  tol: float = 0.1,
                                  pin_extra_width: float = 0.0,
                                  min_pin_area_um2: float | None = None,
                                  max_pin_area_um2: float = 150.0 * 150.0,
                                  skip_square_ports: bool = False,
                                  xcenter: float | None = None,
                                  ycenter: float | None = None,
                                  port_name_prefix: str | None = None,
                                  port_type: str = "optical",
                                  short_ports: bool = False,
                                  auto_rename_ports: bool = True,
                                  debug: bool = False) -> Component

Add ports from pins guessing port orientation from component boundary.

Arguments:

  • component - to read polygons from and to write ports to.

  • pin_layer - GDS layer for maker [int, int].

  • port_layer - for the new created port.

  • inside - True-> markers inside. False-> markers at center.

  • tol - tolerance area to search ports at component boundaries xmin, ymin, xmax, xmax.

  • pin_extra_width - 2*offset from pin to straight.

  • min_pin_area_um2 - ignores pins with area smaller than min_pin_area_um2.

  • max_pin_area_um2 - ignore pins for area above certain size.

  • skip_square_ports - skips square ports (hard to guess orientation).

  • xcenter - for guessing orientation of rectangular ports.

  • ycenter - for guessing orientation of rectangular ports.

  • port_name_prefix - defaults to ‘o’ for optical and ‘e’ for electrical ports.

  • port_type - type of port (optical, electrical ...).

  • short_ports - if the port is on the short side rather than the long side auto_rename_ports:

  • debug - if True prints ports that are skipped.

    For inside=False the port location is at the middle of the PIN

    .. code::


    | | | | ||| |||____ | pin_extra_width/2 > 0 ||| ||| ||| |||____ ||| ||| | __ | |||_| ||

    For inside=True all the pin is inside the port

    .. code::


    | | | | |_ | | | | || | | | | __ | |||__|

    dx < dy: port is east or west x > xc: east x < xc: west

    dx > dy: port is north or south y > yc: north y < yc: south

    dx = dy x > xc: east x < xc: west

add_ports_from_labels

def add_ports_from_labels(component: Component,
                          port_width: float,
                          port_layer: LayerSpec,
                          xcenter: float | None = None,
                          port_name_prefix: str | None = None,
                          port_type: str = "optical",
                          get_name_from_label: bool = False,
                          layer_label: LayerSpec | None = None,
                          fail_on_duplicates: bool = False,
                          port_orientation: float | None = None,
                          guess_port_orientation: bool = True) -> Component

Add ports from labels.

Assumes that all ports have a label at the port center. because labels do not have width, you have to manually specify the ports width

Arguments:

  • component - to read polygons from and to write ports to.
  • port_width - for ports.
  • port_layer - for the new created port.
  • xcenter - center of the component, for guessing port orientation.
  • port_name_prefix - defaults to ‘o’ for optical and ‘e’ for electrical.
  • port_type - optical, electrical. layer_label:
  • fail_on_duplicates - raises ValueError for duplicated port names. if False adds incremental suffix (1, 2 ...) to port name.
  • port_orientation - None for electrical ports.
  • guess_port_orientation - assumes right: 0, left: 180, top: 90, bot: 270.

add_ports_from_siepic_pins

def add_ports_from_siepic_pins(
        component: Component,
        pin_layer_optical: LayerSpec = "PORT",
        port_layer_optical: LayerSpec | None = None,
        pin_layer_electrical: LayerSpec = "PORTE",
        port_layer_electrical: LayerSpec | None = None) -> Component

Add ports from SiEPIC-type cells, where the pins are defined as paths.

Looks for label, path pairs.

Arguments:

  • component - component.
  • pin_layer_optical - layer for optical pins.
  • port_layer_optical - layer for optical ports.
  • pin_layer_electrical - layer for electrical pins.
  • port_layer_electrical - layer for electrical ports.

gdsfactory.add_loopback

Add loopback reference for a grating coupler array.

add_loopback

def add_loopback(port1: Port,
                 port2: Port,
                 grating: ComponentSpec,
                 grating_separation: float = 127.0,
                 grating_rotation: int = -90,
                 grating_port_name: str = "o1",
                 bend: ComponentSpec = gf.components.bend_euler,
                 south_waveguide_spacing: float | None = None,
                 inside: bool = True,
                 **kwargs) -> list[ComponentReference]

Return loopback (grating coupler align reference) references.

Input grating generated on the left of port1 Output grating generated on the right of port2

Arguments:

  • port1 - start port.

  • port2 - end port.

  • grating - fiber coupler.

  • grating_separation - grating pitch.

  • grating_rotation - in degrees.

  • grating_port_name - fiber port name for grating coupler.

  • bend - bend spec.

  • south_waveguide_spacing - spacing from loopback to grating_coupler.ymin

  • inside - add loopback inside.

  • kwargs - cross_section settings.

    .. code::

    inside = True


    |<-separation | | | | | | | | | | GC | port1 port2 | GC___ | | | | | | south_waveguide_spacing |____________________| |

    inside = False


    | | | | | | | | | | | GC port1 port2 GC | ___ | | | | | | south_waveguide_spacing |________________________________| |

gdsfactory.fill

Dummy fill to keep density constant.

Adapted from PHIDL https://github.com/amccaugh/phidl/ by Adam McCaughan

fill_cell_rectangle

@cell
def fill_cell_rectangle(size: Float2 = (20.0, 20.0),
                        layers: LayerSpecs = (0, 1, 3),
                        densities: Floats = (0.5, 0.25, 0.7),
                        inverted=(False, False, False)) -> Component

Returns Component on multiple layers to be used as fill.

based on phidl.geometry

Arguments:

  • size - x, y dimensions of the fill area for all layers.
  • layers - Specific layer(s) to put fill cell rectangle geometry on.
  • densities - Fill densities for each layer specified in layers. Must be the same size as layers.
  • inverted - array-like or bool If true, inverts the fill area for corresponding layer. Must be the same size as layers.

fill_rectangle

@cell
def fill_rectangle(component: ComponentOrReference,
                   fill_layers: LayerSpecs,
                   fill_size=(5.0, 5.0),
                   avoid_layers: LayerSpecs | None = None,
                   include_layers: LayerSpecs | None = None,
                   margin: float = 5.0,
                   fill_densities: float | Floats = (0.5, 0.25, 0.7),
                   fill_inverted: list[float] | None = None,
                   bbox: object | None = None) -> Component

Returns rectangular fill pattern and fills all empty areas.

In the input component and returns a component that contains just the fill Dummy fill keeps density constant during fabrication

Arguments:

  • component - Component to fill.
  • fill_layers - list of layers. fill pattern layers.
  • fill_size - Rectangular size of the fill element.
  • avoid_layers - Layers to be avoided (not filled) in D.
  • include_layers - Layers to be filled, supersedes avoid_layers.
  • margin - Margin spacing around avoided areas.
  • fill_densities - defines the fill pattern density (1.0 == fully filled).
  • fill_inverted - inverts the fill pattern.
  • bbox - x, y limit the fill pattern to the area defined by this bounding box.

fill_rectangle_custom

@cell
def fill_rectangle_custom(component: Component,
                          fill_cell: ComponentSpec,
                          spacing: tuple[float, float],
                          avoid_layers: LayerSpecs | None = None,
                          margin: float = 5.0,
                          bbox: object | None = None) -> Component

Returns custom fill pattern to fill all empty areas.

In the input component and returns a component that contains just the fill Dummy fill keeps density constant during fabrication.

Arguments:

  • component - Component to fill.
  • fill_cell - Component to use as fill cell.
  • spacing - x, y pitch for fill.
  • avoid_layers - Layers to be avoided (not filled) in D.
  • margin - Margin spacing around avoided areas.
  • bbox - x, y limit the fill pattern to the area defined by this bounding box.
References
  1. Vogelbacher, F., Nevlacsil, S., Sagmeister, M., Kraft, J., Unterrainer, K., & Hainberger, R. (2019). Analysis of silicon nitride partial Euler waveguide bends. Optics Express, 27(22), 31394. 10.1364/oe.27.031394
  2. Fatemi, R., Abiri, B., Khachaturian, A., & Hajimiri, A. (2018). High sensitivity active flat optics optical phased array receiver with a two-dimensional aperture. Optics Express, 26(23), 29983. 10.1364/oe.26.029983
  3. Dong, P., Qian, W., Liang, H., Shafiiha, R., Feng, D., Li, G., Cunningham, J. E., Krishnamoorthy, A. V., & Asghari, M. (2010). Thermally tunable silicon racetrack resonators with ultralow tuning power. Optics Express, 18(19), 20298. 10.1364/oe.18.020298
  4. Jacques, M., Samani, A., El-Fiky, E., Patel, D., Xing, Z., & Plant, D. V. (2019). Optimization of thermo-optic phase-shifter design and mitigation of thermal crosstalk on the SOI platform. Optics Express, 27(8), 10456. 10.1364/oe.27.010456
  5. Novack, A., Streshinsky, M., Ding, R., Liu, Y., Lim, A. E.-J., Lo, G.-Q., Baehr-Jones, T., & Hochberg, M. (2014). Progress in silicon platforms for integrated optics. Nanophotonics, 3(4–5), 205–214. 10.1515/nanoph-2013-0034