Common mistakes#

1. Creating cells without cell decorator#

The cell decorator names cells deterministically and uniquely based on the name of the functions and its parameters.

It also uses a caching mechanisms that improves performance and guards against duplicated names.

1.a naming cells manually#

Naming cells manually is susceptible to name colisions

in GDS you can’t have two cells with the same name.

For example: this code will raise a duplicated cell name ValueError

import gdsfactory as gf

c1 = gf.Component('wg')
c1 << gf.components.straight(length = 5)


c2 = gf.Component('wg')
c2 << gf.components.straight(length = 50)


c3 = gf.Component('waveguides')
wg1 = c3 << c1
wg2 = c3 << c2
wg2.movey(10)
c3

Solution: Use the gf.cell decorator for automatic naming your components.

[1]:
import gdsfactory as gf


@gf.cell
def wg(length: float = 3):
    return gf.components.straight(length=length)


print(wg(length=5))
print(wg(length=50))
2022-06-28 17:03:04.898 | INFO     | gdsfactory.config:<module>:52 - Load '/home/runner/work/gdsfactory/gdsfactory/gdsfactory' 5.11.4
wg_length5: uid 2, ports ['o1', 'o2'], aliases [], 4 polygons, 0 references
wg_length50: uid 5, ports ['o1', 'o2'], aliases [], 4 polygons, 0 references

1.b Not naming components with a unique and deterministic name#

In the case of not wrapping the function with cell you will get unique names thanks to the unique identifier uuid.

This name will be different and non-deterministic for different invocations of the script.

However it will be hard for you to know where that cell came from.

[2]:
c1 = gf.Component()
c2 = gf.Component()

print(c1.name)
print(c2.name)
Unnamed_4d9d9df2
Unnamed_47fb7d35

Notice how gdsfactory raises a Warning when you save this Unnamed Components

[3]:
c1.write_gds()
/home/runner/work/gdsfactory/gdsfactory/gdsfactory/component.py:1054: UserWarning: Component 'Unnamed_4d9d9df2' contains 1 Unnamed cells
  warnings.warn(
2022-06-28 17:03:05.774 | INFO     | gdsfactory.component:write_gds:1062 - Write GDS to '/tmp/tmp_adtai9k/gdsfactory/Unnamed_4d9d9df2.gds'
[3]:
PosixPath('/tmp/tmp_adtai9k/gdsfactory/Unnamed_4d9d9df2.gds')

1.c Intermediate Unnamed cells#

While creating a cell, you should not create intermediate cells, because they won’t get a name.

[4]:
@gf.cell
def die_bad():
    """c1 is an intermediate Unnamed cell"""
    c1 = gf.Component()
    c1 << gf.components.straight(length=10)
    c2 = gf.components.die_bbox(c1, street_width=10)
    return c2


c = die_bad(cache=False)
print(c.references)
c
[ComponentReference (parent Component "Unnamed_1781a6ee", ports [], origin [-5.  0.], rotation 0, x_reflection False)]
/home/runner/work/gdsfactory/gdsfactory/gdsfactory/component.py:1054: UserWarning: Component 'die_bad' contains 1 Unnamed cells
  warnings.warn(
../_images/notebooks_common_mistakes_7_2.png
[4]:
die_bad: uid 12, ports [], aliases [], 4 polygons, 1 references

Solution1 Don’t use intermediate cells

[5]:
@gf.cell
def die_good():
    c = gf.Component()
    c << gf.components.straight(length=10)
    c << gf.components.die_bbox_frame(c.bbox, street_width=10)
    return c


c = die_good(cache=False)
print(c.references)
c
[ComponentReference (parent Component "straight_length10", ports ['o1', 'o2'], origin (0, 0), rotation 0, x_reflection False), ComponentReference (parent Component "die_bbox_frame_d6368d3a", ports [], origin (0, 0), rotation 0, x_reflection False)]
../_images/notebooks_common_mistakes_9_1.png
[5]:
die_good: uid 13, ports [], aliases [], 0 polygons, 2 references

Solution2 You can flatten the cell, but you will lose the memory savings from cell references. Solution1 is more elegant.

[6]:
@gf.cell
def die_flat():
    """c will be an intermediate unnamed cell"""
    c = gf.Component()
    c << gf.components.straight(length=10)
    c2 = gf.components.die_bbox(c, street_width=10)
    c2 = c2.flatten()
    return c2


c = die_flat(cache=False)
print(c.references)
c
[]
../_images/notebooks_common_mistakes_11_1.png
[6]:
die_flat: uid 19, ports [], aliases [], 10 polygons, 0 references
[ ]: