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/673ff3d8ebbf887ec40028b7976ea5bfe9344f006cb858a5c6b99c891d114e38.png](../_images/673ff3d8ebbf887ec40028b7976ea5bfe9344f006cb858a5c6b99c891d114e38.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()
2025-01-19 23:49:07.161 | WARNING | gdsfactory.component:plot_klayout:1646 - UserWarning: Unnamed cells, 1 in 'Unnamed_31cf5b43'
![../_images/f03448670aef3d9182b903dfcdc92a436b2c4c4640180f67aa323c5ae9c6994a.png](../_images/f03448670aef3d9182b903dfcdc92a436b2c4c4640180f67aa323c5ae9c6994a.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/a0726a4c194f97816514e2475dd86a090c6dffc48de9b06ca906cb1a647531ee.png](../_images/a0726a4c194f97816514e2475dd86a090c6dffc48de9b06ca906cb1a647531ee.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/f717d6f0811e063b393b804e105dd67e5176ed3c028a09a9891a3e61578f3faf.png](../_images/f717d6f0811e063b393b804e105dd67e5176ed3c028a09a9891a3e61578f3faf.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/320ab8d7e842ffd47c901d3d1c29c3695cf1305379c5446cc75eb9495aa62b47.png](../_images/320ab8d7e842ffd47c901d3d1c29c3695cf1305379c5446cc75eb9495aa62b47.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/1d9739ea5e11819ed473bce4dfc22bc8f3e28925eb0615a7b2aee2ddcc7b1f6b.png](../_images/1d9739ea5e11819ed473bce4dfc22bc8f3e28925eb0615a7b2aee2ddcc7b1f6b.png)
c = gf.components.ring_single(gap=0.2, radius=10, length_x=4, length_y=2)
c.plot()
![../_images/842455aeb39e2684373dc4a7253ad370356cb02959219f6a4af5420426fffd1e.png](../_images/842455aeb39e2684373dc4a7253ad370356cb02959219f6a4af5420426fffd1e.png)
import gdsfactory as gf
c = gf.components.ring_double(gap=0.2, radius=10, length_x=4, length_y=2)
c.plot()
![../_images/e51266e7c60ed47fe6aa88b85b5f62aeb64c79709ac950b99913518501e76ed4.png](../_images/e51266e7c60ed47fe6aa88b85b5f62aeb64c79709ac950b99913518501e76ed4.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/cd86e540a01e206acecdd524f1a60d913ed6a9562e02d1073925947ac8cd1883.png](../_images/cd86e540a01e206acecdd524f1a60d913ed6a9562e02d1073925947ac8cd1883.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()
2025-01-19 23:49:08.471 | WARNING | gdsfactory.cross_section:validate_radius:223 - UserWarning: min_bend_radius 2.0 < CrossSection.radius_min 5.0.
![../_images/2baceef9079cb496a38c4baa5911cf4956c12b6ce62cdce198adc36dd792f7ab.png](../_images/2baceef9079cb496a38c4baa5911cf4956c12b6ce62cdce198adc36dd792f7ab.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/14c65608199be2e27801371fc701c2d7ea5b9917a2c949430fc89f632aa65936.png](../_images/14c65608199be2e27801371fc701c2d7ea5b9917a2c949430fc89f632aa65936.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/196b9f85962e122646d71f03f0864d22200361e417e350bc3623559939cbf15b.png](../_images/196b9f85962e122646d71f03f0864d22200361e417e350bc3623559939cbf15b.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/9f26d3e151e8b58190411dcfa2e6c6a237584837dc9324175f98a50b294321db.png](../_images/9f26d3e151e8b58190411dcfa2e6c6a237584837dc9324175f98a50b294321db.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/1bfdfea4be2a30846c00068996aaa003d561110d33a1aacef865cbc1cb2d00a4.png](../_images/1bfdfea4be2a30846c00068996aaa003d561110d33a1aacef865cbc1cb2d00a4.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/88ae8402ea4f0b321caea870dbb2e02e7f85ab72bfef9509ebe05ee5f68280fb.png](../_images/88ae8402ea4f0b321caea870dbb2e02e7f85ab72bfef9509ebe05ee5f68280fb.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/814a67c3fd77706ae0a94b6aa1a169e3d245ddbc760ad417ea3b698ef573daf0.png](../_images/814a67c3fd77706ae0a94b6aa1a169e3d245ddbc760ad417ea3b698ef573daf0.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/71aff9a838bd41a5304afc95c0e97a9cf172950e3007418d346e67ae28162d1b.png](../_images/71aff9a838bd41a5304afc95c0e97a9cf172950e3007418d346e67ae28162d1b.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/4b426a8a551f69b462287e99b922fab1dbdda6409139b2125b6ba7c193dc5396.png](../_images/4b426a8a551f69b462287e99b922fab1dbdda6409139b2125b6ba7c193dc5396.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()
Ignoring fixed x limits to fulfill fixed data aspect with adjustable data limits.
![../_images/096d208ea58026df62b30317de8d71463a39439dace0c8e779ef9f7c7cc6acf4.png](../_images/096d208ea58026df62b30317de8d71463a39439dace0c8e779ef9f7c7cc6acf4.png)
Straight#
import gdsfactory as gf
P = gf.path.straight(length=5, npoints=100)
f = P.plot()
Ignoring fixed y limits to fulfill fixed data aspect with adjustable data limits.
![../_images/d3ecbfe31d6a42c05ad7eea06d4bc73ab5fb6e11f4ef0b46ca34044d19ccacfa.png](../_images/d3ecbfe31d6a42c05ad7eea06d4bc73ab5fb6e11f4ef0b46ca34044d19ccacfa.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()
Ignoring fixed x limits to fulfill fixed data aspect with adjustable data limits.
![../_images/dde9f98a0a819fadc6af821803ad83ca52e912e38a9915ef3e6207d6d0872df1.png](../_images/dde9f98a0a819fadc6af821803ad83ca52e912e38a9915ef3e6207d6d0872df1.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()
Ignoring fixed y limits to fulfill fixed data aspect with adjustable data limits.
![../_images/0f4de0131d3601786bfaa45a06ab905cd27a46016a180499d599b85460239db5.png](../_images/0f4de0131d3601786bfaa45a06ab905cd27a46016a180499d599b85460239db5.png)
Delay spiral#
c = gf.components.spiral_double()
c.plot()
![../_images/3230cd34965ff9f68b51cd16907fc806ff527b10746fd73f0dca08959b1f10e3.png](../_images/3230cd34965ff9f68b51cd16907fc806ff527b10746fd73f0dca08959b1f10e3.png)
c = gf.components.spiral_inner_io()
c.plot()
![../_images/63515a0a3b9e5946c41960f5d828b6bdb721f09997b6356aaf9ea60403b12fb8.png](../_images/63515a0a3b9e5946c41960f5d828b6bdb721f09997b6356aaf9ea60403b12fb8.png)
c = gf.components.spiral_external_io()
c.plot()
![../_images/f9e0f13490b33a727a4e76b36594bcb6017170757cf44c7b42d73fdb9f912558.png](../_images/f9e0f13490b33a727a4e76b36594bcb6017170757cf44c7b42d73fdb9f912558.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/f2180692c5b113b2a9aa2c623ef73bd89b819fcbed183c4e25f676d2fc41d6d8.png](../_images/f2180692c5b113b2a9aa2c623ef73bd89b819fcbed183c4e25f676d2fc41d6d8.png)
c = gf.components.nxn(north=3, south=4, east=0, west=0)
c.plot()
![../_images/1676306ddaa2a60abf4ae93b6e11a22f8df4483d73274b30671fb936ac67afe4.png](../_images/1676306ddaa2a60abf4ae93b6e11a22f8df4483d73274b30671fb936ac67afe4.png)
c = gf.components.pad()
c.plot()
![../_images/036cab32b0badff57bcf011febaa3305c9700266d9231bf815a7679198c66334.png](../_images/036cab32b0badff57bcf011febaa3305c9700266d9231bf815a7679198c66334.png)
c = gf.components.pad_array90(columns=3)
c.plot()
![../_images/a122f43b2cd811cabf2cfbbe4b6a20809afa3feffe05cd869d836fabd0084361.png](../_images/a122f43b2cd811cabf2cfbbe4b6a20809afa3feffe05cd869d836fabd0084361.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/ab2062c2a5f4b47bd079e1fe0e2dadf41e2d98e7b5e63289c6ebeb1a433584ce.png](../_images/ab2062c2a5f4b47bd079e1fe0e2dadf41e2d98e7b5e63289c6ebeb1a433584ce.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/ba60b4c8e16f73529fc1e26eb9b77c133062691b5f26722a43ad3e49cf7dd63e.png](../_images/ba60b4c8e16f73529fc1e26eb9b77c133062691b5f26722a43ad3e49cf7dd63e.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/e3ea605e2025e0c8cfaa3361cfb55d8b8e556bed7c2204980215e3e768eee617.png](../_images/e3ea605e2025e0c8cfaa3361cfb55d8b8e556bed7c2204980215e3e768eee617.png)
c = gf.components.optimal_90deg(width=100.0, num_pts=15, length_adjust=1, layer=(2, 0))
c.plot()
![../_images/34a7742cc53e8889f7ef0dd1d02169ba72ebff2b4b0a25fa69263c6932313b5b.png](../_images/34a7742cc53e8889f7ef0dd1d02169ba72ebff2b4b0a25fa69263c6932313b5b.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/905ac63bf4bc968cc08030c37af307680ef847ee2efdae7cccc37a7c585bcf94.png](../_images/905ac63bf4bc968cc08030c37af307680ef847ee2efdae7cccc37a7c585bcf94.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.