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

r1 = gf.components.rectangle(size=(4.5, 2), layer=(1, 0))
r1.plot()
../_images/915a46c7aeb8cdcfd3c1932de428c7fee5b879da0afd47dfc61c139f62d3f624.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(arc, layer=(2, 0))
c.plot()
../_images/15edc255a5284e3152b24f7a160d396764e0939405137a78efd7dff94bfe11fe.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/d8ac0ad85d46e007d490e54f9b7c408573626009e68ceb412bf84afeefe79ca3.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/56fe964beaef550de1cf82d5c729e753346ba5ca2fcf01bc04b2c3c5a64c8928.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/9d1c4b775d884e324354ba14437e15e317d81f5ee9b66f4009d87b76bc108d0c.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/a1449bf197642da751cf74899cdc0382104a0821f993e3656e02614833ffa2f7.png
c = gf.components.ring_single(gap=0.2, radius=10, length_x=4, length_y=2)
c.plot()
../_images/76c69e184a3dfea2a5e2e72dc1b25768ab9d56da271f50cd27971336c6bafe64.png
import gdsfactory as gf

c = gf.components.ring_double(gap=0.2, radius=10, length_x=4, length_y=2)
c.plot()
../_images/69428cb862f86e2cdab0e16df7f3a3c8959e7b4d799e8584c536ab2a0b02d8e3.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/6bfbf6b6f57efe2d1d9ce18f79dba57c47a588d5582c7af4094c1d6182676848.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=5.0, width=0.5, angle=90, npoints=720, layer=(1, 0)
)
c.plot()
../_images/1f0d1a08a4163ed2cc53b8cd298989832a6af8010c3353c54dc939319ebec0fe.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=5.0, width=0.5, angle=90, npoints=720, layer=(1, 0))
c.plot()
../_images/5b315ae12c4a22a11397b1e5cced32854088c25573ff4d41dfd67ac787cb2ae9.png

Tapers#

gf.components.taper()is defined by setting its length as well as 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/5453d5ce1b133e26541106d24e113e2e1221031045068ca73d0694a2743fbd42.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/722c6eae97884312b61a63da19be20593960ddab2800d5f6ee7bacab304ca4a3.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/2392b4e24e7c16f8d07e7f28530173245508d7b1af8b3a954f6a7abbfc67694d.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/ae4112274bcd9213fb23d85f32210e940b18b4accb2fbe4d2bba44ec3d609b6a.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/2e3a42de95c183219ce084c4244090f01eb7741d12864502cc081adafb20b125.png

Lithography Structures#

Step-resolution#

The gf.components.litho_steps() function creates a lithographic test structure that is useful for measuring the 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/633c7587b1b0ed34f016d7a0d8d9c82a4711ccf4e76a42b38ac3210f66c2192a.png

Calipers (inter-layer alignment)#

The gf.components.litho_calipers() function is used to detect offsets in multilayer fabrications. It creates a set of two notches on different layers. When a fabrication error/offset occurs, it is easy to detect the magnitude of the offset 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/681595410238f216e78ef955f65d53209e513677c45c5f5c3b161f6f2e05a169.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/df565192bdf77a7f3c003cf0962ac0cf1eb65b90c2eb36a2498b4e398ff0dcc7.png

Straight#

import gdsfactory as gf

P = gf.path.straight(length=5, npoints=100)
f = P.plot()
../_images/6ac8430ce41b18e1c422c75cf6a52092c8bcf4f684807cade579bf09bd24631c.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, it 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/9243a240909ed670425fc6d68184f41ac0e5d37bd50123ab6f81a60e567ea717.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/967f14a521b787c14e9ff5e2c29cfff1fd18cb219514d27fcbd135d4ed64b740.png

Delay spiral#

c = gf.components.spiral_double()
c.plot()
../_images/1ea2f66d6196f0dd312ff2c28e84133a792f74f9fc82f2cd17320245ac9f5509.png
c = gf.components.spiral()
c.plot()
../_images/4938f38b85174b44139d4e4c0dea2dc8d9254e70ae55f72fa417eac2ca82fcbe.png
c = gf.components.spiral_racetrack_fixed_length()
c.plot()
/home/runner/work/gdsfactory/gdsfactory/gdsfactory/components/bends/bend_circular.py:84: UserWarning: {'width': 0.5} ignored for cross_section 'strip'
  x = gf.get_cross_section(cross_section, width=width or x.width)
../_images/6dbd15ecdcc33b16b1bfabb79b92744d6e915ac3c2427feb3a203cfe1d196ed9.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/15d67b59aa89ed7f2ef84bc1089750e70b9ee954c4ebe22411433277a0a919ae.png
c = gf.components.nxn(north=3, south=4, east=0, west=0)
c.plot()
../_images/338f61e3c298c640890e0ca9752dadc302880c25844deb2d7a3558029ef80956.png
c = gf.components.pad()
c.plot()
../_images/e75970305472dd135227ef45e352e9052b50bf7ef25fb143c9af53f672e6978b.png
c = gf.components.pad_array90(columns=3)
c.plot()
../_images/48208bc53a687175a1db033f09e17d1ad340f76277d6846fc469465dbba7187d.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/a84ecb803ed50b58b7bdf69a40033c34b7bd2c73965d0aca32f12c35e69ba1a9.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/03957cfc6f3d86f5c5768e6a9ee60673121ecb290b46d5073becb953a7c0827f.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/47f76a8adf738b611583db7d2cccf1ec62752fd89a4f338ab85cb26ceccb48d5.png
c = gf.components.optimal_90deg(width=100.0, num_pts=15, length_adjust=1, layer=(2, 0))
c.plot()
../_images/59ce534c7191f08a5fd7667a29ce9260e197c7a6ec4938de9afb41eab6279a78.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/d1d26d671debd15c9825d94f43fc3c704c4477504f1993270a922b9f97ec8208.png

Generic library#

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