Gdsfactory v8 Upgrade#

Gdsfactory v8, based on KFactory, offers enhanced routing functions and additional features from KLayout, including DRC, dummy fill, and connectivity checks.

For those still using gdsfactory v7, it is hosted in gdsfactory/gdsfactory7, along with the documentation.

Benefits of Migrating:#

  • Integrated Data: Ports, information, and settings are stored within the GDS file, eliminating the need for separate files.

  • Improved Booleans: Booleans are more robust with integer-based polygons, removing slivers of less than 1nm.

  • Enhanced Features: More robust booleans, DRC, LVS, and connectivity checks.

  • Active Maintenance: More actively maintained with frequent updates.

  • Advanced Routing Algorithms: Better routing algorithms for efficient design.

  • Grid Alignment: Ports and polygons snap to grid by default, reducing the likelihood of 1nm gaps.

Drawbacks of Migrating:#

  • Potential Errors: As with any code changes, undesired errors may be introduced. It is recommended to have regression tests for all your components.

  • Non-Manhattan Placement: Slightly more challenging.

  • Incomplete Functionality: Some features, such as route_path_length_match, are not yet implemented.

Major Differences:#

  • Coordinate System: xmin, xmax, ymin, and ymax are deprecated and will change to Database Units (1nm by default) in gdsfactory9. To set/get them in um, use d (decimal) e.g., Instance.dxmin which is in float.

  • LayerMap: Now an Enum of integers.

  • Routing Functions: New functions do not require starting ports to be in the same orientation and monitor for self-intersections. get_route is now route_single, and get_bundle is now route_bundle.

  • Grid Snapping: All polygon points snap to grid, mitigating 1nm gaps.

Minor Differences:#

  • Replace from gdsfactory.cell import cell with from gdsfactory import cell.

How to Migrate:#

We provide a migration script to assist with migrating your code. Ensure to verify any automatic migrations, and ideally, write regression tests for your code before migrating to ensure accuracy.

gf migrate -i --migration 7to8 <input_folder/file> 
# or 
gf migrate --inplace --migration 7to8 <input_folder/file>

Use dxmin, dcenter, dmove, dsize_info#

This is the biggest difference. By default xmin, ymin, move and size_info will change from um (Decimals) to Database units in the next major gdsfactory release.

import gdsfactory as gf

c = gf.Component()
ref = c << gf.components.bend_euler(radius=5)
c
../_images/6e09cb03a1cb54bf78edae9040aef4316db9b57f4ce73bbfb1326f5ba229aaf3.png
print(ref.dxmax)
5.25

As you can see you can still use ref.xmax but you will get a deprecation warning.

print(ref.xmax)
5.25
/tmp/ipykernel_2678/398276457.py:1: UserWarning: Getting `bend_euler_R5_A90_P0p5__c7bd5c45_2625_2375.xmax` in um is deprecated and will change to DataBaseUnits in gdsfactory9. Please use `bend_euler_R5_A90_P0p5__c7bd5c45_2625_2375.dxmax` instead.
  print(ref.xmax)
print(ref.dsize_info.width)
5.25

Use instance.drotate#

For setting arbitrary rotation angles you can use Instance.drotate(30) to rotate 30deg as an example.

c = gf.Component()
ref = c << gf.components.bend_euler(radius=5)
ref.drotate(45)
c
../_images/bc7ffdca7eed78336638b38b28f6ca44b12af90198673d6501ea7749d6486f89.png

LayerMap#

In v7 or below, a LayerMap needs to be called


from gdsfactory.technology import LayerMap

class LayerMapFab(LayerMap):
    WG = (1, 0)

LAYER = LayerMapFab()

However in v8 it has a different type and does not need to be called


from gdsfactory.technology import LayerMap

class LayerMapFab(LayerMap):
    WG = (1, 0)

LAYER = LayerMapFab

See below:

from gdsfactory.technology import LayerMap


class LayerMapFab(LayerMap):
    WG = (1, 0)


LAYER = LayerMapFab
type(LAYER)
aenum._enum.EnumType
LAYER.WG
<LayerMapFab.WG: 1>
tuple(LAYER.WG)
(1, 0)
str(LAYER.WG)
'WG'

Component.bbox is now a function#

Both Components and Instances have a bbox and dbbox that are now functions.

c = gf.c.straight(length=10)
c.bbox()
(0,-250;10000,250)
c.dbbox()
(0,-0.25;10,0.25)

For the old bbox behavior you can use c.bbox_np which returns the bbox as a numpy array.

c.bbox_np()
array([[ 0.  , -0.25],
       [10.  ,  0.25]])

Routing functions#

Routing functions do no longer return the route Instances but they place the instances in a Component, so you have to pass a Component.

c = gf.Component()
w = gf.components.straight(cross_section="rib")
top = c << w
bot = c << w
bot.dmove((0, -2))

p0 = top.ports["o2"]
p1 = bot.ports["o2"]

r = gf.routing.route_single(
    c,
    p0,
    p1,
    cross_section="rib",
)
c
../_images/9a2d9d775a384f3a6b1d1436be3e4638c6ee7b16380f4ace1d60811672038ce4.png

🚀 The new routing functions allow the starting ports ports1 to have different orientations.

The end ports still require to have the same orientation.

c = gf.Component()
top = c << gf.components.nxn(north=8, south=0, east=0, west=0)
bot = c << gf.components.nxn(north=2, south=2, east=2, west=2, xsize=10, ysize=10)
top.dmovey(100)

routes = gf.routing.route_bundle(
    c,
    ports1=bot.ports,
    ports2=top.ports,
    radius=5,
    sort_ports=True,
)
c
../_images/8e5c21cc0408114513f1b80cfc9c2860b4cc63b0591d17a3d59cf540760103e5.png

Built in connectivity checks#

gdsfactory8 includes connectivity checks to ensure things are properly connected.

c = gf.Component()
s = c << gf.components.straight(width=1)

b1 = c << gf.components.bend_euler()
b1.connect("o1", s["o2"], allow_width_mismatch=True)

b2 = c << gf.components.bend_euler(radius=5)
b2.connect("o1", s["o1"], allow_width_mismatch=True)

gc = gf.components.grating_coupler_elliptical_te()
gc1 = c << gc
gc2 = c << gc

gc1.connect("o1", b1.ports["o2"])
gc2.connect("o1", b2.ports["o2"])

c.plot()
../_images/166c8ea6338a4abc1860a9d887e99ab10f9b163af3ef94eeed52d58852003af2.png
lyrdb = c.connectivity_check(port_types=("optical", "electrical"))
filepath = gf.config.home / "errors.lyrdb"
lyrdb.save(filepath)
gf.show(c, lyrdb=filepath)