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](../_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](../_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](../_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](../_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](../_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](../_images/15bed24ffa1da1a0bd77932ea63e4860713a8306d8a04102aff29cbf71ec9477.png)
c = gf.components.ring_single(gap=0.2, radius=10, length_x=4, length_y=2)
c.plot()
![../_images/e5ab4fae3c8cd518ac19d91ff30dbca956f72b5c1ba8f91f06a5c16d5d6e5d30.png](../_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](../_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](../_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](../_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](../_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](../_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](../_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](../_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](../_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](../_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](../_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](../_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](../_images/b2eb25cc6b0f7cf3c97a230c28137308a1ba11985971ce39ce7304b9acea8acc.png)
Straight#
import gdsfactory as gf
P = gf.path.straight(length=5, npoints=100)
f = P.plot()
![../_images/1ae9b411c943a32bf53db4fc8d1e654517d4a3ddb339ce08821f3095d33cab26.png](../_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](../_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](../_images/1fa2b414d625c7e97f659bcdd93f671bc96c116df2a0164b63623fcbc073faa4.png)
Delay spiral#
c = gf.components.spiral_double()
c.plot()
![../_images/bd928d74afffdad70a3c0512e4918a5df45dc60768f76713f15e4e0025775198.png](../_images/bd928d74afffdad70a3c0512e4918a5df45dc60768f76713f15e4e0025775198.png)
c = gf.components.spiral()
c.plot()
![../_images/57ec77d44e4f953a1d9a8e02875f72191e6b9b9864238e4a5e438609fe3eb2cd.png](../_images/57ec77d44e4f953a1d9a8e02875f72191e6b9b9864238e4a5e438609fe3eb2cd.png)
c = gf.components.spiral_racetrack_fixed_length()
c.plot()
![../_images/153dc4165aa6738ecfc4173d5936227f207f24a900a882782419600676fc950a.png](../_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](../_images/452958f91dafa588b8f86849bbff7b93363e5e380c59789fbe1585ba01553569.png)
c = gf.components.nxn(north=3, south=4, east=0, west=0)
c.plot()
![../_images/8f9abc887d0dac21e1036a0e7122de91f799bec142b22242f145ce485b423869.png](../_images/8f9abc887d0dac21e1036a0e7122de91f799bec142b22242f145ce485b423869.png)
c = gf.components.pad()
c.plot()
![../_images/4186e45e90795894bf73c5b29bfb2346dec90c1a9855b982dea380d9fd7572ae.png](../_images/4186e45e90795894bf73c5b29bfb2346dec90c1a9855b982dea380d9fd7572ae.png)
c = gf.components.pad_array90(columns=3)
c.plot()
![../_images/aead3714e396dd2d5d69dac183b72f1375ad0193ec1360515c72f707a6821423.png](../_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](../_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](../_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](../_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](../_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](../_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.