Shapes and generic cells#

gdsfactory provides some generic parametric cells in gf.components that you can customize for your application.

Basic shapes#

Rectangle#

To create a simple rectangle, there are two functions:

gf.components.rectangle() can create a basic rectangle:

import gdsfactory as gf
from gdsfactory.generic_tech import get_generic_pdk

gf.config.rich_output()

PDK = get_generic_pdk()
PDK.activate()

r1 = gf.components.rectangle(size=(4.5, 2), layer=(1, 0))
r1.plot()

../_images/bde8f081e47e9664033b267aa01a6e8f8f74d02bed987095e78437152c98e01e.png

gf.components.bbox() can also create a rectangle based on a bounding box. This is useful if you want to create a rectangle which exactly surrounds a piece of existing geometry. For example, if we have an arc geometry and we want to define a box around it, we can use gf.components.bbox():

c = gf.Component()
arc = c << gf.components.bend_circular(radius=10, width=0.5, angle=90, layer=(1, 0))
arc.rotate(90)
# Draw a rectangle around the arc we created by using the arc's bounding box
rect = c << gf.components.bbox(bbox=arc.bbox, layer=(0, 0))
c.plot()
2024-12-09 17:20:43.909 | WARNING  | gdsfactory.component:plot_klayout:1646 - UserWarning: Unnamed cells, 1 in 'Unnamed_1029b526'

../_images/ed26ec26e7064d5992dd4d1fb8b984161c4bd7bb1c04bb53ace76f67ceaabf7c.png

Cross#

The gf.components.cross() function creates a cross structure:

c = gf.components.cross(length=10, width=0.5, layer=(1, 0))
c.plot()

../_images/48f786ac695f78d996dfc47f436f2214fd163f63a551bdcb23d05c2516702702.png

Ellipse#

The gf.components.ellipse() function creates an ellipse by defining the major and minor radii:

c = gf.components.ellipse(radii=(10, 5), angle_resolution=2.5, layer=(1, 0))
c.plot()

../_images/7ae8eabd2937da7edb22c934aff57e5851ee176945fdf922a263c552fc09d4b2.png

Circle#

The gf.components.circle() function creates a circle:

c = gf.components.circle(radius=10, angle_resolution=2.5, layer=(1, 0))
c.plot()

../_images/de4227bdd28ebd36bd9b553723301f5ab3ab192211504d75a26ff00bb72c90cf.png

Ring#

The gf.components.ring() function creates a ring. The radius refers to the center radius of the ring structure (halfway between the inner and outer radius).

c = gf.components.ring(radius=5, width=0.5, angle_resolution=2.5, layer=(1, 0))
c.plot()

../_images/168083e09af46029c8f50111eb5baa368f92b097f2208d7dad1bfe8d0c7bd6ad.png
c = gf.components.ring_single(gap=0.2, radius=10, length_x=4, length_y=2)
c.plot()

../_images/263cbde177ec15eddb0c138e89db6f3a52833cb3c1daf05df4f34c06bdb0aeeb.png
import gdsfactory as gf

c = gf.components.ring_double(gap=0.2, radius=10, length_x=4, length_y=2)
c.plot()

../_images/9143a3bf90893fc50d678f379b44217828a611c13d2f05f91cf6964fc4df68d5.png
c = gf.components.ring_double(
    gap=0.2,
    radius=10,
    length_x=4,
    length_y=2,
    bend=gf.components.bend_circular,
)
c.plot()

../_images/38fb14397037429f0c93cd7f06c112d1850e3648d41565f902664939a2f68f20.png

Bend circular#

The gf.components.bend_circular() function creates an arc. The radius refers to the center radius of the arc (halfway between the inner and outer radius).

c = gf.components.bend_circular(
    radius=2.0, width=0.5, angle=90, npoints=720, layer=(1, 0)
)
c.plot()
2024-12-09 17:20:45.591 | WARNING  | gdsfactory.cross_section:validate_radius:223 - UserWarning: min_bend_radius 2.0 < CrossSection.radius_min 5.0. 

../_images/ab0d30c9896f918647726468f3d70717f4ed2b0d179b4b046526fde5c5862182.png

Bend euler#

The gf.components.bend_euler() function creates an adiabatic bend in which the bend radius changes gradually. Euler bends have lower loss than circular bends.

c = gf.components.bend_euler(radius=2.0, width=0.5, angle=90, npoints=720, layer=(1, 0))
c.plot()

../_images/4402fb776cabce126ff7b605e0ad0cafdfbf5e1f90de03d50c75b574ba472dc1.png

Tapers#

gf.components.taper()is defined by setting its length and its start and end length. It has two ports, 1 and 2, on either end, allowing you to easily connect it to other structures.

c = gf.components.taper(length=10, width1=6, width2=4, port=None, layer=(1, 0))
c.plot()

../_images/6ac0b8d60b41968ad1359bba7361fe734fdc597dd13cfca0c986df7521c01aec.png

gf.components.ramp() is a structure is similar to taper() except it is asymmetric. It also has two ports, 1 and 2, on either end.

c = gf.components.ramp(length=10, width1=4, width2=8, layer=(1, 0))
c.plot()

../_images/4963d178bcbf8cff1c5e1e13ff0d7353c524c7e4bcec52d9c879e3ffab35e439.png

Common compound shapes#

The gf.components.L() function creates a “L” shape with ports on either end named 1 and 2.

c = gf.components.L(width=7, size=(10, 20), layer=(1, 0))
c.plot()

../_images/3d7c9abceecb3e499e89870b911e068c0b18069c1990cd8916853cc496f5c738.png

The gf.components.C() function creates a “C” shape with ports on either end named 1 and 2.

c = gf.components.C(width=7, size=(10, 20), layer=(1, 0))
c.plot()

../_images/1187e6f1e87473c9a9c4db6367c24cc5cbf8b2179fed4aba85adccf5ea3a41e5.png

Text#

Gdsfactory has an implementation of the DEPLOF font with the majority of english ASCII characters represented (thanks to phidl)

c = gf.components.text(
    text="Hello world!\nMultiline text\nLeft-justified",
    size=10,
    justify="left",
    layer=(1, 0),
)
c.plot()
# `justify` should be either 'left', 'center', or 'right'

../_images/107061e7e65c2fcacaeda920701efc7f2553fe26413b95641ab23796ebfd3aa3.png

Lithography structures#

Step-resolution#

The gf.components.litho_steps() function creates lithographic test structure that is useful for measuring resolution of photoresist or electron-beam resists. It provides both positive-tone and negative-tone resolution tests.

c = gf.components.litho_steps(
    line_widths=[1, 2, 4, 8, 16], line_spacing=10, height=100, layer=(1, 0)
)
c.plot()

../_images/4f1dabff4e0908b9bf70ce49693452a5a017fee0f93cec8b95d234f2ecf531f6.png

Calipers (inter-layer alignment)#

The gf.components.litho_calipers() function is used to detect offsets in multilayer fabrication. It creates a two sets of notches on different layers. When an fabrication error/offset occurs, it is easy to detect how much the offset is because both center-notches are no longer aligned.

D = gf.components.litho_calipers(
    notch_size=[1, 5],
    notch_spacing=2,
    num_notches=7,
    offset_per_notch=0.1,
    row_spacing=0,
    layer1=(1, 0),
    layer2=(2, 0),
)
D.plot()

../_images/b988cee610f2ba90908c3b206c48869f9706ca773eeeb08b85f693abbf5ebde9.png

Paths#

See Path tutorial for more details – this is just an enumeration of the available built-in Path functions

Circular arc#

P = gf.path.arc(radius=10, angle=135, npoints=720)
f = P.plot()

../_images/482a1f005fd4347fbaeb1ff2c59cc6ee4cc92ecd754a6a546de60656dde525c0.png

Straight#

import gdsfactory as gf

P = gf.path.straight(length=5, npoints=100)
f = P.plot()

../_images/11a78a38e3fc0e20da06a7759edecc6695ed149655397cb6bacdab199302ed64.png

Euler curve#

Also known as a straight-to-bend, clothoid, racetrack, or track transition, this Path tapers adiabatically from straight to curved. Often used to minimize losses in photonic straights. If p < 1.0, will create a “partial euler” curve as described in Vogelbacher et. al. https://dx.doi.org/10.1364/oe.27.031394. If the use_eff argument is false, radius corresponds to minimum radius of curvature of the bend. If use_eff is true, radius corresponds to the “effective” radius of the bend– The curve will be scaled such that the endpoints match an arc with parameters radius and angle.

P = gf.path.euler(radius=3, angle=90, p=1.0, use_eff=False, npoints=720)
f = P.plot()

../_images/91ff1adc28043749875a86105e38e29a101c54262a687ec0062ff730e11222ad.png

Smooth path from waypoints#

import numpy as np

import gdsfactory as gf

points = np.array([(20, 10), (40, 10), (20, 40), (50, 40), (50, 20), (70, 20)])

P = gf.path.smooth(
    points=points,
    radius=2,
    bend=gf.path.euler,
    use_eff=False,
)
f = P.plot()

../_images/80b9f8ad50a0e1631d4dded9926861f704f81158f93fd3e5fe28a593098f1332.png

Delay spiral#

c = gf.components.spiral_double()
c.plot()

../_images/cc61e1b8e25504901a244ffe535a1a2bd6f3a4ff682181d90446ca819621e883.png
c = gf.components.spiral_inner_io()
c.plot()

../_images/73c32f9ec4d30e691076c7a92d05cc729493732d8916f76201c5f17aff574840.png
c = gf.components.spiral_external_io()
c.plot()

../_images/629a9712d0ded8d8d1d392688646fbe5dddf4c54ab2f1d2b187304cdb2f66a37.png

Useful contact pads / connectors#

These functions are common shapes with ports, often used to make contact pads

c = gf.components.compass(size=(4, 2), layer=(1, 0))
c.plot()

../_images/b17175c87babbc0423338251ec7a35fa9ead0080b7313560a45ba2875b3c809a.png
c = gf.components.nxn(north=3, south=4, east=0, west=0)
c.plot()

../_images/35739de2c2f0bfb87c5804fd95a06de2ee686e00fbde2d175a3ce96992df8a77.png
c = gf.components.pad()
c.plot()

../_images/1390b34cf85372883b49f554d2b0f60056726a3314fa57d605700830c37370ac.png
c = gf.components.pad_array90(columns=3)
c.plot()

../_images/de751a76c4a2f967b78fae1e5dfcecaeeae4be9e5d109cdcea4909fb236a0694.png

Chip / die template#

import gdsfactory as gf

c = gf.components.die(
    size=(10000, 5000),  # Size of die
    street_width=100,  # Width of corner marks for die-sawing
    street_length=1000,  # Length of corner marks for die-sawing
    die_name="chip99",  # Label text
    text_size=500,  # Label text size
    text_location="SW",  # Label text compass location e.g. 'S', 'SE', 'SW'
    layer=(2, 0),
    bbox_layer=(3, 0),
)
c.plot()

../_images/a48810d32547c6f72e021765c5a2f1e9908f4319c99e4594914a068ee9e71707.png

Optimal superconducting curves#

The following structures are meant to reduce “current crowding” in superconducting thin-film structures (such as superconducting nanowires). They are the result of conformal mapping equations derived in Clem, J. & Berggren, K. “Geometry-dependent critical currents in superconducting nanocircuits.” Phys. Rev. B 84, 1–27 (2011).

import gdsfactory as gf

c = gf.components.optimal_hairpin(
    width=0.2, pitch=0.6, length=10, turn_ratio=4, num_pts=50, layer=(2, 0)
)
c.plot()

../_images/ff414e0e1cc1abdfdc2082602894c99cf73b1b8f48a07355d20999a37c314d89.png
c = gf.components.optimal_step(
    start_width=10,
    end_width=22,
    num_pts=50,
    width_tol=1e-3,
    anticrowding_factor=1.2,
    symmetric=False,
    layer=(2, 0),
)
c.plot()

../_images/36e1a1bbcd59483805e608f6495d9055e36816e9ff65ddbffc28ccd3fb415b79.png
c = gf.components.optimal_90deg(width=100.0, num_pts=15, length_adjust=1, layer=(2, 0))
c.plot()

../_images/edd79260e569e916c164a09774e5f1fee3eb6fe41aac2510f1072646521696f8.png
c = gf.components.snspd(
    wire_width=0.2,
    wire_pitch=0.6,
    size=(10, 8),
    num_squares=None,
    turn_ratio=4,
    terminals_same_side=False,
    layer=(2, 0),
)
c.plot()

../_images/712d729faa81378c871e17e99c26937d421fb90ebe79191428b59e7129b5d728.png

Generic library#

gdsfactory comes with a generic library that you can customize it to your needs or even modify the internal code to create the Components that you need.