Known changes and backwards incompatibilities in 2025.09

S-bend routing

The S-bend routing has been improved so that i3.ConnectBend and i3.RouteSBend will draw simpler bends in some cases when the in and out angles are not aligned.

import ipkiss3.all as i3

in_port = i3.OpticalPort(name="in", position=(5, 15), angle=15)
out_port = i3.OpticalPort(name="out", position=(100, 50), angle=150)

circ = i3.Circuit(specs=[i3.ConnectBend(in_port, out_port, start_straight=10, end_straight=30, bend_radius=10)])
lay = circ.get_default_view(i3.LayoutView)
lay.visualize()
../_images/luceda_2025090_connectBend_before.png

Before 2025.09

../_images/luceda_2025090_connectBend_after.png

Since 2025.09

GDSCell

i3.GDSCell is ported to new layout definition syntax hence PCells that inherit from it can use the new syntax as well. Instances will no longer be accessible in the .elements list.

import ipkiss3.all as i3

class MyCell(i3.PCell):
    class Layout(i3.LayoutView):
        def generate(self, layout):
            layout += i3.SRef(i3.Waveguide())
            return layout

MyCell().Layout().write_gdsii("layout.gds")
imported_layout = i3.GDSCell(filename="layout.gds").Layout()
print(len(imported_layout.elements))  # 1 on 2025.06, 0 on 2025.09
print(len(imported_layout.instances))  # 0 on 2025.06, 1 on 2025.09

Order of elements returned by flat_copy

Before 2025.09, i3.Label objects were all at the end of the list returned by flat_copy. Since 2025.09, the order is preserved.

import ipkiss3.all as i3

class BaseCell(i3.PCell):
    class Layout(i3.LayoutView):
        def generate(self, layout):
            layout += i3.Label(layer=i3.Layer(0), coordinate=(5, 0), text="my_label")
            layout += i3.Rectangle(layer=i3.Layer(0))
            return layout

# 2025.06: [<Boundary on Layer LAYER0>, <Label on Layer LAYER0>]
# 2025.09: [<Label on Layer LAYER0>, <Boundary on Layer LAYER0>]
print(i3.SRef(reference=BaseCell().Layout()).flat_copy())

ShapeStub limits the length of the stubs to the available space

i3.ShapeStub will now correctly reduce the stub width when not enough space is available for the specified stub width and raise a warning. Before 2025.09, it would create a wrong shape.

import ipkiss3.all as i3
import matplotlib.pyplot as plt

shape = i3.Shape(
    [
        (0.0, 0.0),
        (5.0, 5.0),
        (5.0, 7.0),
        (15.0, 7.0),
    ]
)
stubbed_shape = i3.ShapeStub(original_shape=shape, stub_width=20) # This will now generate a shape with the maximum stub width and raise a warning.
plt.plot(stubbed_shape.x_coords(), stubbed_shape.y_coords(), "r-", label="stubbed shape")
plt.plot(shape.x_coords(), shape.y_coords(), "bo-.", label="original_shape")
plt.show()

Before 2025.09, the stubbed shape would look like this:

../_images/luceda_2025090_shapestub_before.png

Since 2025.09, the stubbed shape will look like this:

../_images/luceda_2025090_shapestub_after.png

Change to the Circuit Analyzer configuration

The format now includes new keys: libraries and a cells section for each library, which helps distinguish them from global_parameters. It also contains a version number.

To migrate older Circuit Analyzer configurations:

  • please add the version: 1 entry,

  • then, move all libraries under the libraries section and insert a cells key for each, which will contain all cell specifications.

YAML Configuration Migration

Before 2025.09

After 2025.09

pteam_library_sifab:
  MyDC:
    # path relative to yaml file
    filename_format: "../dc_data/s{s}_t{t}_w{w}.s4p"

qteam_library_sifab:
  Bend:
    parameters:
      n_g:
        doc: "Effective index"
        default: 3.4
        corners: [3.35, 3.4, 3.45]
  generate_parameters: "models.bend_model"

si_fab:
  ConnectorStraight:
    generate_parameters: "models.wg_model"
  Straight:
    generate_parameters: "models.wg_model"

global_parameters:
  w:
    doc: "WG width"
    default: 0
    corners: [-1, 0, 1]
  t:
    doc: "SOI thickness"
    default: 0
    corners: [-1, 0, 1]
  s:
    doc: "Rib etch"
    default: 0
    corners: [-1, 0, 1]
  # New feature: fixed parameters are now supported (don't require a corners section)
  # standalone_fixed_parameter:
  #  doc: "Standalone param"
  #  default: 0
version: 1
libraries:
  pteam_library_sifab:
    cells:
      MyDC:
        # path relative to yaml file
        filename_format: "../dc_data/s{s}_t{t}_w{w}.s4p"

  qteam_library_sifab:
    cells:
      Bend:
        parameters:
          n_g:
            doc: "Effective index"
            default: 3.4
            corners: [3.35, 3.4, 3.45]
      generate_parameters: "models.bend_model"

  si_fab:
    cells:
      ConnectorStraight:
        generate_parameters: "models.wg_model"
      Straight:
        generate_parameters: "models.wg_model"

global_parameters:
  w:
    doc: "WG width"
    default: 0
    corners: [-1, 0, 1]
  t:
    doc: "SOI thickness"
    default: 0
    corners: [-1, 0, 1]
  s:
    doc: "Rib etch"
    default: 0
    corners: [-1, 0, 1]
  standalone_fixed_parameter:
    doc: "Standalone param"
    default: 0