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/5350a044343c8db1a421a05dc7940462115c81dca78cc99f25f029a5cd1faa16.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.drotate(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()
/opt/hostedtoolcache/Python/3.11.9/x64/lib/python3.11/site-packages/kfactory/kcell.py:6035: UserWarning: Getting `bend_circular_R10_A90_N_d4f4737b_-4875_5125.x` in um is deprecated and will change to DataBaseUnits in gdsfactory9. Please use `bend_circular_R10_A90_N_d4f4737b_-4875_5125.dx` instead.
  return str(prop) if prop is not None else f"{self.cell.name}_{self.x}_{self.y}"
/opt/hostedtoolcache/Python/3.11.9/x64/lib/python3.11/site-packages/kfactory/kcell.py:6035: UserWarning: Getting `bend_circular_R10_A90_N_d4f4737b_-4875_5125.y` in um is deprecated and will change to DataBaseUnits in gdsfactory9. Please use `bend_circular_R10_A90_N_d4f4737b_-4875_5125.dy` instead.
  return str(prop) if prop is not None else f"{self.cell.name}_{self.x}_{self.y}"
../_images/56ac772c9089a6eb1544659dc20c43aec948e192e9a98301361068d0929b7278.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/107fa76553105b96a02dc7a97b96c8864d1ecc84725f5444c1a36c93833d7e51.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/2c9dad8cbe8f161752225235ba8f59429e4120d68c2bb1a1d7bda172fa2ba21f.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/da22704408533ce2a9fbbe77c38fbfaf20e1f291c120b00a98bd211501bccc8b.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/15bed24ffa1da1a0bd77932ea63e4860713a8306d8a04102aff29cbf71ec9477.png
c = gf.components.ring_single(gap=0.2, radius=10, length_x=4, length_y=2)
c.plot()
../_images/e5ab4fae3c8cd518ac19d91ff30dbca956f72b5c1ba8f91f06a5c16d5d6e5d30.png
import gdsfactory as gf

c = gf.components.ring_double(gap=0.2, radius=10, length_x=4, length_y=2)
c.plot()
../_images/66d90335374bff2f27253502d37de9081ab1b825d0d97781113732f3c601c299.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/c4a28814157ca14a53e53c37f9a54f46152221e81efdf0d09263d445db18f97d.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/e758a0dd2d563c58242de285a88e16b523cbe9f53670351bc63a70ee0ddfc34e.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/71f8dbf8fef0a35aeed8e8d9b496684af0b0cd62925185a3bc57771c3ed835e8.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/ea6b70c10ef526b946f06b8c2820d30d15c68711e41f2f808e7122fe54848a59.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/335c8adf1cf638b172d86869749b62d422fc9a4ee3eabf3675d65d890c8e4755.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/2b0ec9e1d580dfa3cb3c890230fedaf3b8f693bf0c50809029bd860a5a5ec0c6.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/818216f52afff376900069aab70861e7d2c40540887b9e14f11528ddd59f4524.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/0f20e00c6d9b2fdd56a88b552b7d1df8da1a3f52016fe320c9becf0deb6e66e7.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/70f873f9f1dad87705c237930afe8d3a236021ee95c46aca41ed2c95518b977d.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/17ec0b2b567c08eba92fbc0e7290d4890fa4471b3064022b4a238d8c4f688aae.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/b2eb25cc6b0f7cf3c97a230c28137308a1ba11985971ce39ce7304b9acea8acc.png

Straight#

import gdsfactory as gf

P = gf.path.straight(length=5, npoints=100)
f = P.plot()
../_images/1ae9b411c943a32bf53db4fc8d1e654517d4a3ddb339ce08821f3095d33cab26.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/c2593040db80faec63fe78e08b45a30458503452b3c624fe7b83029f8f3f6005.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/1fa2b414d625c7e97f659bcdd93f671bc96c116df2a0164b63623fcbc073faa4.png

Delay spiral#

c = gf.components.spiral_double()
c.plot()
../_images/bd928d74afffdad70a3c0512e4918a5df45dc60768f76713f15e4e0025775198.png
c = gf.components.spiral()
c.plot()
../_images/57ec77d44e4f953a1d9a8e02875f72191e6b9b9864238e4a5e438609fe3eb2cd.png
c = gf.components.spiral_racetrack_fixed_length()
c.plot()
../_images/153dc4165aa6738ecfc4173d5936227f207f24a900a882782419600676fc950a.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/452958f91dafa588b8f86849bbff7b93363e5e380c59789fbe1585ba01553569.png
c = gf.components.nxn(north=3, south=4, east=0, west=0)
c.plot()
../_images/8f9abc887d0dac21e1036a0e7122de91f799bec142b22242f145ce485b423869.png
c = gf.components.pad()
c.plot()
../_images/4186e45e90795894bf73c5b29bfb2346dec90c1a9855b982dea380d9fd7572ae.png
c = gf.components.pad_array90(columns=3)
c.plot()
../_images/aead3714e396dd2d5d69dac183b72f1375ad0193ec1360515c72f707a6821423.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/78d2c7563a00d9c4f88423ee5609efa290e7365c5d036aa66106cf44eecec4fc.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/ce394e7630d1e33403545c0a84a870d523cb30346550f43c15ecd054a09a9ff7.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/6fde91c82b20bf9c9085ebc14c2b85c5c510204aea166673132498576fb543c9.png
c = gf.components.optimal_90deg(width=100.0, num_pts=15, length_adjust=1, layer=(2, 0))
c.plot()
../_images/e56e59c24725b3d0639b8d37d3bbb3f7e020bbc01f09f50db377328b0967441a.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/4e6be2ee27cd704c073940c3deb2d919fe65cbda4a8f4453c084cca6d53ab8d7.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.