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/0fd6444679e8961b53fbe127111527302ab166bc93227b44c2fce669f6fc4f2e.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-04-27 01:04:53.574 | WARNING  | gdsfactory.component:plot_klayout:1645 - UserWarning: Unnamed cells, 1 in 'Unnamed_1a6312a9'

../_images/569065a1534b85356a420972d18aa1c24f7a55d71b98f0b2ed22769de56cab10.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/13a6d1f2f4814d285325811948b7684a51557dd916aeef3ff782b7fd25966a9a.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/2609997ae333c59f28bf61449041a4eddc9e80fc43132eeee0a4464aa3369d0a.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/d4766b31f2749b9580dfaf052843bd573910e34d37da00ae63086f59715f3b24.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/d1083b4151947167cce1454e0304b5dfb61c3de6e277a2987be0eea0afab22fd.png
c = gf.components.ring_single(gap=0.2, radius=10, length_x=4, length_y=2)
c.plot()

../_images/6f0e0c0fc5eb368badae3f8b1c489f901a3d4d97ba5223fc3711035138386f26.png
import gdsfactory as gf

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

../_images/c84ad75deae33e24c50f0b8623698c876e138a2107637f97b6811fa94982cf90.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/f2a91f480bcf670a45f1fc18f9892db3a972c25158917c34d179e4d634d02f3d.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-04-27 01:04:55.206 | WARNING  | gdsfactory.cross_section:validate_radius:223 - UserWarning: min_bend_radius 2.0 < CrossSection.radius_min 5.0. 

../_images/5feb84e1ceb20700dc19e77735a38c1740c9892b1fa3d56190323929918bec21.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/3fdba666016117777f666a6756c7c4c44029410f46d0eb2c7db209a2f455d320.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/5a26c12bcd12be96d5c7bf28cd3e838bdc099e33493bb406bfba186d88d7cc50.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/1bcd10a1944747aa0534077da3b0d9e9e701eb0ead42a7a7db2492092144d175.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/e09fcf3e1615987a842ddc98c2594c96af90e94b10b3b1315b046a93ca57563a.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/c9e02ad7570feffe3eb52ec4500c7edd6bdefd6c21856057802f8d2374299262.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/6e1fc73a14fc17f06907bd408c1e69f7f5b20f81d759bf608a7b4168ec5e2719.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/8a62a05a0ca0c1a00311f3b3b342c0d6dcd12bccab52367d6eb664f1cc2ef324.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/e1c3ca70330cd74873a038c1813fff4ca30707278859fc55a620351a58604b50.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/1dc6f7e8ab191943bd40e6f8acbf457937157258e8adf78fc6a58c6c3b36ad3e.png

Straight#

import gdsfactory as gf

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

../_images/3e53ef5822c8449f3028eb3b1ec8da78a95ddd59ae05f29749ed9e1cc9cbb9ca.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/f53e658e6b1d04b8e8c53444aee6fbe1b41b628d985eefc2bbe7d994394ad8f8.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/2a59f03a017f8ac30409fa1673555e5bdc468bb648642aaf6a655ea5501d8296.png

Delay spiral#

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

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

../_images/5adb880c5578faf27408e0120f8abdd3c8a1cfd13ddfaf9c13bf8e12a9f6f0a1.png
c = gf.components.spiral_external_io()
c.plot()

../_images/ef90b94997eddbb3eb72a161767383b6971a15fdfa0eadbe89813a301153efb6.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/5ba9985b99b9bd5cb7a9415f7ba33511fcf3c01c2a874093a016d555ebac022d.png
c = gf.components.nxn(north=3, south=4, east=0, west=0)
c.plot()

../_images/839061faad8cc7582bafacdbc025c9028823c5a970ef83db73a1400adb769bf5.png
c = gf.components.pad()
c.plot()

../_images/5039e4b8bb622243e45bcd7f7b102eaf2e064206c8ef04e194a6d231f529c0a6.png
c = gf.components.pad_array90(columns=3)
c.plot()

../_images/b7252c864326093690d6ed5c5e75b82130e3b39a160a2cba10f73a1c1dd9d66f.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/7be78852178489a7d426b296d146974c4c3d16d612bf08aea2a805928d7012f4.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/75c837a080adb2f7a8f14c912506966d0b8c1b3666413e66e061dfe7765185c4.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/b2c4bd0a812ae13a2c01979050074ca881f88c792da9f2c427faae34b5c60087.png
c = gf.components.optimal_90deg(width=100.0, num_pts=15, length_adjust=1, layer=(2, 0))
c.plot()

../_images/a0d771c34674179c1caecf7165e27e656e91e02e136220df9521e26eaeadd9db.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/c27ac0d2a3383b2a0ab81e8518c514b021c4b53f4716a5a456b42c5dc29db79e.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.