Skip to article frontmatterSkip to article content

Schematic

A schematic is a graph representation of your circuit.

For complex circuits, a schematic allows you to create symbols and hierarchy levels to represent your circuit.

Having a schematic allows you to also ensure that your layout matches you schematic (design intent).

There are many schematic capture tools out there:

  • Qucs-s: for RF.
  • Xschem: for analog circuits.
  • Lumerical interconnect: for photonic circuits.

These tools allow you to both create schematics with your mouse or by code.

gdsfactory also allows you to create complex Schematics directly from python with a very simple interface.

import gdsfactory as gf
import gdsfactory.schematic as gt
import yaml
c = gf.c.mzi()
c.plot_netlist_graphviz(interactive=False)
<IPython.core.display.Image object>
c.plot_netlist()
<networkx.classes.graph.Graph at 0x7f6a1813f890>
<Figure size 640x480 with 1 Axes>

Lets create a MZI lattice of 3 elements.

s = gt.Schematic()
s.add_instance("mzi1", gt.Instance(component=gf.c.mzi(delta_length=10)))
s.add_instance("mzi2", gt.Instance(component=gf.c.mzi(delta_length=100)))
s.add_instance("mzi3", gt.Instance(component=gf.c.mzi(delta_length=200)))
s.add_placement("mzi1", gt.Placement(x=000, y=0))
s.add_placement("mzi2", gt.Placement(x=100, y=100))
s.add_placement("mzi3", gt.Placement(x=200, y=0))
s.add_net(gt.Net(p1="mzi1,o2", p2="mzi2,o1"))
s.add_net(gt.Net(p1="mzi2,o2", p2="mzi3,o1"))
g = s.plot_graphviz()
<IPython.core.display.Image object>

You can also create a splitter tree.

s = gt.Schematic()
s.add_instance("s11", gt.Instance(component=gf.c.mmi1x2()))
s.add_instance("s21", gt.Instance(component=gf.c.mmi1x2()))
s.add_instance("s22", gt.Instance(component=gf.c.mmi1x2()))
s.add_placement("s11", gt.Placement(x=000, y=0))
s.add_placement("s21", gt.Placement(x=100, y=+50))
s.add_placement("s22", gt.Placement(x=100, y=-50))
s.add_net(gt.Net(p1="s11,o2", p2="s21,o1"))
s.add_net(gt.Net(p1="s11,o3", p2="s22,o1"))
g = s.plot_graphviz()
<IPython.core.display.Image object>

The nice thing is that you can abstract it to have as many levels as you need.

splitter = gf.components.mmi1x2()
n = 3
dx = 100
dy = 100
s = gt.Schematic()

for col in range(n):
    rows = 2**col
    for row in range(rows):
        s.add_instance(f"s{col}{row}", gt.Instance(component=splitter))
        s.add_placement(
            f"s{col}{row}", gt.Placement(x=col * dx, y=(row - rows / 2) * dy)
        )
        if col < n - 1:
            s.add_net(gt.Net(p1=f"s{col}{row},o2", p2=f"s{col+1}{2*row},o1"))
            s.add_net(gt.Net(p1=f"s{col}{row},o3", p2=f"s{col+1}{2*row+1},o1"))


g = s.plot_graphviz()
<IPython.core.display.Image object>
splitter = gf.components.mmi1x2()
n = 5
dx = 100
dy = 100
s = gt.Schematic()

for col in range(n):
    rows = 2**col
    for row in range(rows):
        s.add_instance(f"s{col}{row}", gt.Instance(component=splitter))
        s.add_placement(
            f"s{col}{row}", gt.Placement(x=col * dx, y=(row - rows / 2) * dy)
        )
        if col < n - 1:
            s.add_net(gt.Net(p1=f"s{col}{row},o2", p2=f"s{col+1}{2*row},o1"))
            s.add_net(gt.Net(p1=f"s{col}{row},o3", p2=f"s{col+1}{2*row+1},o1"))


g = s.plot_graphviz()
<IPython.core.display.Image object>
dict(s.netlist)
{'pdk': '', 'instances': {'s00': Instance(component='mmi1x2', settings={'width_taper': 1.0, 'length_taper': 10.0, 'length_mmi': 5.5, 'width_mmi': 2.5, 'gap_mmi': 0.25, 'taper': 'taper', 'straight': 'straight', 'cross_section': 'strip'}, info={}, array=None), 's10': Instance(component='mmi1x2', settings={'width_taper': 1.0, 'length_taper': 10.0, 'length_mmi': 5.5, 'width_mmi': 2.5, 'gap_mmi': 0.25, 'taper': 'taper', 'straight': 'straight', 'cross_section': 'strip'}, info={}, array=None), 's11': Instance(component='mmi1x2', settings={'width_taper': 1.0, 'length_taper': 10.0, 'length_mmi': 5.5, 'width_mmi': 2.5, 'gap_mmi': 0.25, 'taper': 'taper', 'straight': 'straight', 'cross_section': 'strip'}, info={}, array=None), 's20': Instance(component='mmi1x2', settings={'width_taper': 1.0, 'length_taper': 10.0, 'length_mmi': 5.5, 'width_mmi': 2.5, 'gap_mmi': 0.25, 'taper': 'taper', 'straight': 'straight', 'cross_section': 'strip'}, info={}, array=None), 's21': Instance(component='mmi1x2', settings={'width_taper': 1.0, 'length_taper': 10.0, 'length_mmi': 5.5, 'width_mmi': 2.5, 'gap_mmi': 0.25, 'taper': 'taper', 'straight': 'straight', 'cross_section': 'strip'}, info={}, array=None), 's22': Instance(component='mmi1x2', settings={'width_taper': 1.0, 'length_taper': 10.0, 'length_mmi': 5.5, 'width_mmi': 2.5, 'gap_mmi': 0.25, 'taper': 'taper', 'straight': 'straight', 'cross_section': 'strip'}, info={}, array=None), 's23': Instance(component='mmi1x2', settings={'width_taper': 1.0, 'length_taper': 10.0, 'length_mmi': 5.5, 'width_mmi': 2.5, 'gap_mmi': 0.25, 'taper': 'taper', 'straight': 'straight', 'cross_section': 'strip'}, info={}, array=None), 's30': Instance(component='mmi1x2', settings={'width_taper': 1.0, 'length_taper': 10.0, 'length_mmi': 5.5, 'width_mmi': 2.5, 'gap_mmi': 0.25, 'taper': 'taper', 'straight': 'straight', 'cross_section': 'strip'}, info={}, array=None), 's31': Instance(component='mmi1x2', settings={'width_taper': 1.0, 'length_taper': 10.0, 'length_mmi': 5.5, 'width_mmi': 2.5, 'gap_mmi': 0.25, 'taper': 'taper', 'straight': 'straight', 'cross_section': 'strip'}, info={}, array=None), 's32': Instance(component='mmi1x2', settings={'width_taper': 1.0, 'length_taper': 10.0, 'length_mmi': 5.5, 'width_mmi': 2.5, 'gap_mmi': 0.25, 'taper': 'taper', 'straight': 'straight', 'cross_section': 'strip'}, info={}, array=None), 's33': Instance(component='mmi1x2', settings={'width_taper': 1.0, 'length_taper': 10.0, 'length_mmi': 5.5, 'width_mmi': 2.5, 'gap_mmi': 0.25, 'taper': 'taper', 'straight': 'straight', 'cross_section': 'strip'}, info={}, array=None), 's34': Instance(component='mmi1x2', settings={'width_taper': 1.0, 'length_taper': 10.0, 'length_mmi': 5.5, 'width_mmi': 2.5, 'gap_mmi': 0.25, 'taper': 'taper', 'straight': 'straight', 'cross_section': 'strip'}, info={}, array=None), 's35': Instance(component='mmi1x2', settings={'width_taper': 1.0, 'length_taper': 10.0, 'length_mmi': 5.5, 'width_mmi': 2.5, 'gap_mmi': 0.25, 'taper': 'taper', 'straight': 'straight', 'cross_section': 'strip'}, info={}, array=None), 's36': Instance(component='mmi1x2', settings={'width_taper': 1.0, 'length_taper': 10.0, 'length_mmi': 5.5, 'width_mmi': 2.5, 'gap_mmi': 0.25, 'taper': 'taper', 'straight': 'straight', 'cross_section': 'strip'}, info={}, array=None), 's37': Instance(component='mmi1x2', settings={'width_taper': 1.0, 'length_taper': 10.0, 'length_mmi': 5.5, 'width_mmi': 2.5, 'gap_mmi': 0.25, 'taper': 'taper', 'straight': 'straight', 'cross_section': 'strip'}, info={}, array=None), 's40': Instance(component='mmi1x2', settings={'width_taper': 1.0, 'length_taper': 10.0, 'length_mmi': 5.5, 'width_mmi': 2.5, 'gap_mmi': 0.25, 'taper': 'taper', 'straight': 'straight', 'cross_section': 'strip'}, info={}, array=None), 's41': Instance(component='mmi1x2', settings={'width_taper': 1.0, 'length_taper': 10.0, 'length_mmi': 5.5, 'width_mmi': 2.5, 'gap_mmi': 0.25, 'taper': 'taper', 'straight': 'straight', 'cross_section': 'strip'}, info={}, array=None), 's42': Instance(component='mmi1x2', settings={'width_taper': 1.0, 'length_taper': 10.0, 'length_mmi': 5.5, 'width_mmi': 2.5, 'gap_mmi': 0.25, 'taper': 'taper', 'straight': 'straight', 'cross_section': 'strip'}, info={}, array=None), 's43': Instance(component='mmi1x2', settings={'width_taper': 1.0, 'length_taper': 10.0, 'length_mmi': 5.5, 'width_mmi': 2.5, 'gap_mmi': 0.25, 'taper': 'taper', 'straight': 'straight', 'cross_section': 'strip'}, info={}, array=None), 's44': Instance(component='mmi1x2', settings={'width_taper': 1.0, 'length_taper': 10.0, 'length_mmi': 5.5, 'width_mmi': 2.5, 'gap_mmi': 0.25, 'taper': 'taper', 'straight': 'straight', 'cross_section': 'strip'}, info={}, array=None), 's45': Instance(component='mmi1x2', settings={'width_taper': 1.0, 'length_taper': 10.0, 'length_mmi': 5.5, 'width_mmi': 2.5, 'gap_mmi': 0.25, 'taper': 'taper', 'straight': 'straight', 'cross_section': 'strip'}, info={}, array=None), 's46': Instance(component='mmi1x2', settings={'width_taper': 1.0, 'length_taper': 10.0, 'length_mmi': 5.5, 'width_mmi': 2.5, 'gap_mmi': 0.25, 'taper': 'taper', 'straight': 'straight', 'cross_section': 'strip'}, info={}, array=None), 's47': Instance(component='mmi1x2', settings={'width_taper': 1.0, 'length_taper': 10.0, 'length_mmi': 5.5, 'width_mmi': 2.5, 'gap_mmi': 0.25, 'taper': 'taper', 'straight': 'straight', 'cross_section': 'strip'}, info={}, array=None), 's48': Instance(component='mmi1x2', settings={'width_taper': 1.0, 'length_taper': 10.0, 'length_mmi': 5.5, 'width_mmi': 2.5, 'gap_mmi': 0.25, 'taper': 'taper', 'straight': 'straight', 'cross_section': 'strip'}, info={}, array=None), 's49': Instance(component='mmi1x2', settings={'width_taper': 1.0, 'length_taper': 10.0, 'length_mmi': 5.5, 'width_mmi': 2.5, 'gap_mmi': 0.25, 'taper': 'taper', 'straight': 'straight', 'cross_section': 'strip'}, info={}, array=None), 's410': Instance(component='mmi1x2', settings={'width_taper': 1.0, 'length_taper': 10.0, 'length_mmi': 5.5, 'width_mmi': 2.5, 'gap_mmi': 0.25, 'taper': 'taper', 'straight': 'straight', 'cross_section': 'strip'}, info={}, array=None), 's411': Instance(component='mmi1x2', settings={'width_taper': 1.0, 'length_taper': 10.0, 'length_mmi': 5.5, 'width_mmi': 2.5, 'gap_mmi': 0.25, 'taper': 'taper', 'straight': 'straight', 'cross_section': 'strip'}, info={}, array=None), 's412': Instance(component='mmi1x2', settings={'width_taper': 1.0, 'length_taper': 10.0, 'length_mmi': 5.5, 'width_mmi': 2.5, 'gap_mmi': 0.25, 'taper': 'taper', 'straight': 'straight', 'cross_section': 'strip'}, info={}, array=None), 's413': Instance(component='mmi1x2', settings={'width_taper': 1.0, 'length_taper': 10.0, 'length_mmi': 5.5, 'width_mmi': 2.5, 'gap_mmi': 0.25, 'taper': 'taper', 'straight': 'straight', 'cross_section': 'strip'}, info={}, array=None), 's414': Instance(component='mmi1x2', settings={'width_taper': 1.0, 'length_taper': 10.0, 'length_mmi': 5.5, 'width_mmi': 2.5, 'gap_mmi': 0.25, 'taper': 'taper', 'straight': 'straight', 'cross_section': 'strip'}, info={}, array=None), 's415': Instance(component='mmi1x2', settings={'width_taper': 1.0, 'length_taper': 10.0, 'length_mmi': 5.5, 'width_mmi': 2.5, 'gap_mmi': 0.25, 'taper': 'taper', 'straight': 'straight', 'cross_section': 'strip'}, info={}, array=None)}, 'placements': {'s00': Placement(x=0.0, y=-50.0, xmin=None, ymin=None, xmax=None, ymax=None, dx=0, dy=0, port=None, rotation=0, mirror=False), 's10': Placement(x=100.0, y=-100.0, xmin=None, ymin=None, xmax=None, ymax=None, dx=0, dy=0, port=None, rotation=0, mirror=False), 's11': Placement(x=100.0, y=0.0, xmin=None, ymin=None, xmax=None, ymax=None, dx=0, dy=0, port=None, rotation=0, mirror=False), 's20': Placement(x=200.0, y=-200.0, xmin=None, ymin=None, xmax=None, ymax=None, dx=0, dy=0, port=None, rotation=0, mirror=False), 's21': Placement(x=200.0, y=-100.0, xmin=None, ymin=None, xmax=None, ymax=None, dx=0, dy=0, port=None, rotation=0, mirror=False), 's22': Placement(x=200.0, y=0.0, xmin=None, ymin=None, xmax=None, ymax=None, dx=0, dy=0, port=None, rotation=0, mirror=False), 's23': Placement(x=200.0, y=100.0, xmin=None, ymin=None, xmax=None, ymax=None, dx=0, dy=0, port=None, rotation=0, mirror=False), 's30': Placement(x=300.0, y=-400.0, xmin=None, ymin=None, xmax=None, ymax=None, dx=0, dy=0, port=None, rotation=0, mirror=False), 's31': Placement(x=300.0, y=-300.0, xmin=None, ymin=None, xmax=None, ymax=None, dx=0, dy=0, port=None, rotation=0, mirror=False), 's32': Placement(x=300.0, y=-200.0, xmin=None, ymin=None, xmax=None, ymax=None, dx=0, dy=0, port=None, rotation=0, mirror=False), 's33': Placement(x=300.0, y=-100.0, xmin=None, ymin=None, xmax=None, ymax=None, dx=0, dy=0, port=None, rotation=0, mirror=False), 's34': Placement(x=300.0, y=0.0, xmin=None, ymin=None, xmax=None, ymax=None, dx=0, dy=0, port=None, rotation=0, mirror=False), 's35': Placement(x=300.0, y=100.0, xmin=None, ymin=None, xmax=None, ymax=None, dx=0, dy=0, port=None, rotation=0, mirror=False), 's36': Placement(x=300.0, y=200.0, xmin=None, ymin=None, xmax=None, ymax=None, dx=0, dy=0, port=None, rotation=0, mirror=False), 's37': Placement(x=300.0, y=300.0, xmin=None, ymin=None, xmax=None, ymax=None, dx=0, dy=0, port=None, rotation=0, mirror=False), 's40': Placement(x=400.0, y=-800.0, xmin=None, ymin=None, xmax=None, ymax=None, dx=0, dy=0, port=None, rotation=0, mirror=False), 's41': Placement(x=400.0, y=-700.0, xmin=None, ymin=None, xmax=None, ymax=None, dx=0, dy=0, port=None, rotation=0, mirror=False), 's42': Placement(x=400.0, y=-600.0, xmin=None, ymin=None, xmax=None, ymax=None, dx=0, dy=0, port=None, rotation=0, mirror=False), 's43': Placement(x=400.0, y=-500.0, xmin=None, ymin=None, xmax=None, ymax=None, dx=0, dy=0, port=None, rotation=0, mirror=False), 's44': Placement(x=400.0, y=-400.0, xmin=None, ymin=None, xmax=None, ymax=None, dx=0, dy=0, port=None, rotation=0, mirror=False), 's45': Placement(x=400.0, y=-300.0, xmin=None, ymin=None, xmax=None, ymax=None, dx=0, dy=0, port=None, rotation=0, mirror=False), 's46': Placement(x=400.0, y=-200.0, xmin=None, ymin=None, xmax=None, ymax=None, dx=0, dy=0, port=None, rotation=0, mirror=False), 's47': Placement(x=400.0, y=-100.0, xmin=None, ymin=None, xmax=None, ymax=None, dx=0, dy=0, port=None, rotation=0, mirror=False), 's48': Placement(x=400.0, y=0.0, xmin=None, ymin=None, xmax=None, ymax=None, dx=0, dy=0, port=None, rotation=0, mirror=False), 's49': Placement(x=400.0, y=100.0, xmin=None, ymin=None, xmax=None, ymax=None, dx=0, dy=0, port=None, rotation=0, mirror=False), 's410': Placement(x=400.0, y=200.0, xmin=None, ymin=None, xmax=None, ymax=None, dx=0, dy=0, port=None, rotation=0, mirror=False), 's411': Placement(x=400.0, y=300.0, xmin=None, ymin=None, xmax=None, ymax=None, dx=0, dy=0, port=None, rotation=0, mirror=False), 's412': Placement(x=400.0, y=400.0, xmin=None, ymin=None, xmax=None, ymax=None, dx=0, dy=0, port=None, rotation=0, mirror=False), 's413': Placement(x=400.0, y=500.0, xmin=None, ymin=None, xmax=None, ymax=None, dx=0, dy=0, port=None, rotation=0, mirror=False), 's414': Placement(x=400.0, y=600.0, xmin=None, ymin=None, xmax=None, ymax=None, dx=0, dy=0, port=None, rotation=0, mirror=False), 's415': Placement(x=400.0, y=700.0, xmin=None, ymin=None, xmax=None, ymax=None, dx=0, dy=0, port=None, rotation=0, mirror=False)}, 'connections': {}, 'routes': {'route_10': Bundle(links={'s00,o2': 's10,o1'}, settings={}, routing_strategy='route_bundle'), 'route_11': Bundle(links={'s00,o3': 's11,o1'}, settings={}, routing_strategy='route_bundle'), 'route_12': Bundle(links={'s10,o2': 's20,o1'}, settings={}, routing_strategy='route_bundle'), 'route_13': Bundle(links={'s10,o3': 's21,o1'}, settings={}, routing_strategy='route_bundle'), 'route_14': Bundle(links={'s11,o2': 's22,o1'}, settings={}, routing_strategy='route_bundle'), 'route_15': Bundle(links={'s11,o3': 's23,o1'}, settings={}, routing_strategy='route_bundle'), 'route_16': Bundle(links={'s20,o2': 's30,o1'}, settings={}, routing_strategy='route_bundle'), 'route_17': Bundle(links={'s20,o3': 's31,o1'}, settings={}, routing_strategy='route_bundle'), 'route_18': Bundle(links={'s21,o2': 's32,o1'}, settings={}, routing_strategy='route_bundle'), 'route_19': Bundle(links={'s21,o3': 's33,o1'}, settings={}, routing_strategy='route_bundle'), 'route_20': Bundle(links={'s22,o2': 's34,o1'}, settings={}, routing_strategy='route_bundle'), 'route_21': Bundle(links={'s22,o3': 's35,o1'}, settings={}, routing_strategy='route_bundle'), 'route_22': Bundle(links={'s23,o2': 's36,o1'}, settings={}, routing_strategy='route_bundle'), 'route_23': Bundle(links={'s23,o3': 's37,o1'}, settings={}, routing_strategy='route_bundle'), 'route_24': Bundle(links={'s30,o2': 's40,o1'}, settings={}, routing_strategy='route_bundle'), 'route_25': Bundle(links={'s30,o3': 's41,o1'}, settings={}, routing_strategy='route_bundle'), 'route_26': Bundle(links={'s31,o2': 's42,o1'}, settings={}, routing_strategy='route_bundle'), 'route_27': Bundle(links={'s31,o3': 's43,o1'}, settings={}, routing_strategy='route_bundle'), 'route_28': Bundle(links={'s32,o2': 's44,o1'}, settings={}, routing_strategy='route_bundle'), 'route_29': Bundle(links={'s32,o3': 's45,o1'}, settings={}, routing_strategy='route_bundle'), 'route_30': Bundle(links={'s33,o2': 's46,o1'}, settings={}, routing_strategy='route_bundle'), 'route_31': Bundle(links={'s33,o3': 's47,o1'}, settings={}, routing_strategy='route_bundle'), 'route_32': Bundle(links={'s34,o2': 's48,o1'}, settings={}, routing_strategy='route_bundle'), 'route_33': Bundle(links={'s34,o3': 's49,o1'}, settings={}, routing_strategy='route_bundle'), 'route_34': Bundle(links={'s35,o2': 's410,o1'}, settings={}, routing_strategy='route_bundle'), 'route_35': Bundle(links={'s35,o3': 's411,o1'}, settings={}, routing_strategy='route_bundle'), 'route_36': Bundle(links={'s36,o2': 's412,o1'}, settings={}, routing_strategy='route_bundle'), 'route_37': Bundle(links={'s36,o3': 's413,o1'}, settings={}, routing_strategy='route_bundle'), 'route_38': Bundle(links={'s37,o2': 's414,o1'}, settings={}, routing_strategy='route_bundle'), 'route_39': Bundle(links={'s37,o3': 's415,o1'}, settings={}, routing_strategy='route_bundle')}, 'name': None, 'info': {}, 'ports': {}, 'settings': {}, 'nets': [], 'warnings': {}}
yaml_component = yaml.dump(s.netlist.model_dump(exclude_none=True))
print(yaml_component)
connections: {}
info: {}
instances:
  s00:
    component: mmi1x2
    settings:
      cross_section: strip
      gap_mmi: 0.25
      length_mmi: 5.5
      length_taper: 10.0
      straight: straight
      taper: taper
      width_mmi: 2.5
      width_taper: 1.0
  s10:
    component: mmi1x2
    settings:
      cross_section: strip
      gap_mmi: 0.25
      length_mmi: 5.5
      length_taper: 10.0
      straight: straight
      taper: taper
      width_mmi: 2.5
      width_taper: 1.0
  s11:
    component: mmi1x2
    settings:
      cross_section: strip
      gap_mmi: 0.25
      length_mmi: 5.5
      length_taper: 10.0
      straight: straight
      taper: taper
      width_mmi: 2.5
      width_taper: 1.0
  s20:
    component: mmi1x2
    settings:
      cross_section: strip
      gap_mmi: 0.25
      length_mmi: 5.5
      length_taper: 10.0
      straight: straight
      taper: taper
      width_mmi: 2.5
      width_taper: 1.0
  s21:
    component: mmi1x2
    settings:
      cross_section: strip
      gap_mmi: 0.25
      length_mmi: 5.5
      length_taper: 10.0
      straight: straight
      taper: taper
      width_mmi: 2.5
      width_taper: 1.0
  s22:
    component: mmi1x2
    settings:
      cross_section: strip
      gap_mmi: 0.25
      length_mmi: 5.5
      length_taper: 10.0
      straight: straight
      taper: taper
      width_mmi: 2.5
      width_taper: 1.0
  s23:
    component: mmi1x2
    settings:
      cross_section: strip
      gap_mmi: 0.25
      length_mmi: 5.5
      length_taper: 10.0
      straight: straight
      taper: taper
      width_mmi: 2.5
      width_taper: 1.0
  s30:
    component: mmi1x2
    settings:
      cross_section: strip
      gap_mmi: 0.25
      length_mmi: 5.5
      length_taper: 10.0
      straight: straight
      taper: taper
      width_mmi: 2.5
      width_taper: 1.0
  s31:
    component: mmi1x2
    settings:
      cross_section: strip
      gap_mmi: 0.25
      length_mmi: 5.5
      length_taper: 10.0
      straight: straight
      taper: taper
      width_mmi: 2.5
      width_taper: 1.0
  s32:
    component: mmi1x2
    settings:
      cross_section: strip
      gap_mmi: 0.25
      length_mmi: 5.5
      length_taper: 10.0
      straight: straight
      taper: taper
      width_mmi: 2.5
      width_taper: 1.0
  s33:
    component: mmi1x2
    settings:
      cross_section: strip
      gap_mmi: 0.25
      length_mmi: 5.5
      length_taper: 10.0
      straight: straight
      taper: taper
      width_mmi: 2.5
      width_taper: 1.0
  s34:
    component: mmi1x2
    settings:
      cross_section: strip
      gap_mmi: 0.25
      length_mmi: 5.5
      length_taper: 10.0
      straight: straight
      taper: taper
      width_mmi: 2.5
      width_taper: 1.0
  s35:
    component: mmi1x2
    settings:
      cross_section: strip
      gap_mmi: 0.25
      length_mmi: 5.5
      length_taper: 10.0
      straight: straight
      taper: taper
      width_mmi: 2.5
      width_taper: 1.0
  s36:
    component: mmi1x2
    settings:
      cross_section: strip
      gap_mmi: 0.25
      length_mmi: 5.5
      length_taper: 10.0
      straight: straight
      taper: taper
      width_mmi: 2.5
      width_taper: 1.0
  s37:
    component: mmi1x2
    settings:
      cross_section: strip
      gap_mmi: 0.25
      length_mmi: 5.5
      length_taper: 10.0
      straight: straight
      taper: taper
      width_mmi: 2.5
      width_taper: 1.0
  s40:
    component: mmi1x2
    settings:
      cross_section: strip
      gap_mmi: 0.25
      length_mmi: 5.5
      length_taper: 10.0
      straight: straight
      taper: taper
      width_mmi: 2.5
      width_taper: 1.0
  s41:
    component: mmi1x2
    settings:
      cross_section: strip
      gap_mmi: 0.25
      length_mmi: 5.5
      length_taper: 10.0
      straight: straight
      taper: taper
      width_mmi: 2.5
      width_taper: 1.0
  s410:
    component: mmi1x2
    settings:
      cross_section: strip
      gap_mmi: 0.25
      length_mmi: 5.5
      length_taper: 10.0
      straight: straight
      taper: taper
      width_mmi: 2.5
      width_taper: 1.0
  s411:
    component: mmi1x2
    settings:
      cross_section: strip
      gap_mmi: 0.25
      length_mmi: 5.5
      length_taper: 10.0
      straight: straight
      taper: taper
      width_mmi: 2.5
      width_taper: 1.0
  s412:
    component: mmi1x2
    settings:
      cross_section: strip
      gap_mmi: 0.25
      length_mmi: 5.5
      length_taper: 10.0
      straight: straight
      taper: taper
      width_mmi: 2.5
      width_taper: 1.0
  s413:
    component: mmi1x2
    settings:
      cross_section: strip
      gap_mmi: 0.25
      length_mmi: 5.5
      length_taper: 10.0
      straight: straight
      taper: taper
      width_mmi: 2.5
      width_taper: 1.0
  s414:
    component: mmi1x2
    settings:
      cross_section: strip
      gap_mmi: 0.25
      length_mmi: 5.5
      length_taper: 10.0
      straight: straight
      taper: taper
      width_mmi: 2.5
      width_taper: 1.0
  s415:
    component: mmi1x2
    settings:
      cross_section: strip
      gap_mmi: 0.25
      length_mmi: 5.5
      length_taper: 10.0
      straight: straight
      taper: taper
      width_mmi: 2.5
      width_taper: 1.0
  s42:
    component: mmi1x2
    settings:
      cross_section: strip
      gap_mmi: 0.25
      length_mmi: 5.5
      length_taper: 10.0
      straight: straight
      taper: taper
      width_mmi: 2.5
      width_taper: 1.0
  s43:
    component: mmi1x2
    settings:
      cross_section: strip
      gap_mmi: 0.25
      length_mmi: 5.5
      length_taper: 10.0
      straight: straight
      taper: taper
      width_mmi: 2.5
      width_taper: 1.0
  s44:
    component: mmi1x2
    settings:
      cross_section: strip
      gap_mmi: 0.25
      length_mmi: 5.5
      length_taper: 10.0
      straight: straight
      taper: taper
      width_mmi: 2.5
      width_taper: 1.0
  s45:
    component: mmi1x2
    settings:
      cross_section: strip
      gap_mmi: 0.25
      length_mmi: 5.5
      length_taper: 10.0
      straight: straight
      taper: taper
      width_mmi: 2.5
      width_taper: 1.0
  s46:
    component: mmi1x2
    settings:
      cross_section: strip
      gap_mmi: 0.25
      length_mmi: 5.5
      length_taper: 10.0
      straight: straight
      taper: taper
      width_mmi: 2.5
      width_taper: 1.0
  s47:
    component: mmi1x2
    settings:
      cross_section: strip
      gap_mmi: 0.25
      length_mmi: 5.5
      length_taper: 10.0
      straight: straight
      taper: taper
      width_mmi: 2.5
      width_taper: 1.0
  s48:
    component: mmi1x2
    settings:
      cross_section: strip
      gap_mmi: 0.25
      length_mmi: 5.5
      length_taper: 10.0
      straight: straight
      taper: taper
      width_mmi: 2.5
      width_taper: 1.0
  s49:
    component: mmi1x2
    settings:
      cross_section: strip
      gap_mmi: 0.25
      length_mmi: 5.5
      length_taper: 10.0
      straight: straight
      taper: taper
      width_mmi: 2.5
      width_taper: 1.0
nets: []
pdk: ''
placements:
  s00:
    dx: 0
    dy: 0
    mirror: false
    rotation: 0
    x: 0.0
    y: -50.0
  s10:
    dx: 0
    dy: 0
    mirror: false
    rotation: 0
    x: 100.0
    y: -100.0
  s11:
    dx: 0
    dy: 0
    mirror: false
    rotation: 0
    x: 100.0
    y: 0.0
  s20:
    dx: 0
    dy: 0
    mirror: false
    rotation: 0
    x: 200.0
    y: -200.0
  s21:
    dx: 0
    dy: 0
    mirror: false
    rotation: 0
    x: 200.0
    y: -100.0
  s22:
    dx: 0
    dy: 0
    mirror: false
    rotation: 0
    x: 200.0
    y: 0.0
  s23:
    dx: 0
    dy: 0
    mirror: false
    rotation: 0
    x: 200.0
    y: 100.0
  s30:
    dx: 0
    dy: 0
    mirror: false
    rotation: 0
    x: 300.0
    y: -400.0
  s31:
    dx: 0
    dy: 0
    mirror: false
    rotation: 0
    x: 300.0
    y: -300.0
  s32:
    dx: 0
    dy: 0
    mirror: false
    rotation: 0
    x: 300.0
    y: -200.0
  s33:
    dx: 0
    dy: 0
    mirror: false
    rotation: 0
    x: 300.0
    y: -100.0
  s34:
    dx: 0
    dy: 0
    mirror: false
    rotation: 0
    x: 300.0
    y: 0.0
  s35:
    dx: 0
    dy: 0
    mirror: false
    rotation: 0
    x: 300.0
    y: 100.0
  s36:
    dx: 0
    dy: 0
    mirror: false
    rotation: 0
    x: 300.0
    y: 200.0
  s37:
    dx: 0
    dy: 0
    mirror: false
    rotation: 0
    x: 300.0
    y: 300.0
  s40:
    dx: 0
    dy: 0
    mirror: false
    rotation: 0
    x: 400.0
    y: -800.0
  s41:
    dx: 0
    dy: 0
    mirror: false
    rotation: 0
    x: 400.0
    y: -700.0
  s410:
    dx: 0
    dy: 0
    mirror: false
    rotation: 0
    x: 400.0
    y: 200.0
  s411:
    dx: 0
    dy: 0
    mirror: false
    rotation: 0
    x: 400.0
    y: 300.0
  s412:
    dx: 0
    dy: 0
    mirror: false
    rotation: 0
    x: 400.0
    y: 400.0
  s413:
    dx: 0
    dy: 0
    mirror: false
    rotation: 0
    x: 400.0
    y: 500.0
  s414:
    dx: 0
    dy: 0
    mirror: false
    rotation: 0
    x: 400.0
    y: 600.0
  s415:
    dx: 0
    dy: 0
    mirror: false
    rotation: 0
    x: 400.0
    y: 700.0
  s42:
    dx: 0
    dy: 0
    mirror: false
    rotation: 0
    x: 400.0
    y: -600.0
  s43:
    dx: 0
    dy: 0
    mirror: false
    rotation: 0
    x: 400.0
    y: -500.0
  s44:
    dx: 0
    dy: 0
    mirror: false
    rotation: 0
    x: 400.0
    y: -400.0
  s45:
    dx: 0
    dy: 0
    mirror: false
    rotation: 0
    x: 400.0
    y: -300.0
  s46:
    dx: 0
    dy: 0
    mirror: false
    rotation: 0
    x: 400.0
    y: -200.0
  s47:
    dx: 0
    dy: 0
    mirror: false
    rotation: 0
    x: 400.0
    y: -100.0
  s48:
    dx: 0
    dy: 0
    mirror: false
    rotation: 0
    x: 400.0
    y: 0.0
  s49:
    dx: 0
    dy: 0
    mirror: false
    rotation: 0
    x: 400.0
    y: 100.0
ports: {}
routes:
  route_10:
    links:
      s00,o2: s10,o1
    routing_strategy: route_bundle
    settings: {}
  route_11:
    links:
      s00,o3: s11,o1
    routing_strategy: route_bundle
    settings: {}
  route_12:
    links:
      s10,o2: s20,o1
    routing_strategy: route_bundle
    settings: {}
  route_13:
    links:
      s10,o3: s21,o1
    routing_strategy: route_bundle
    settings: {}
  route_14:
    links:
      s11,o2: s22,o1
    routing_strategy: route_bundle
    settings: {}
  route_15:
    links:
      s11,o3: s23,o1
    routing_strategy: route_bundle
    settings: {}
  route_16:
    links:
      s20,o2: s30,o1
    routing_strategy: route_bundle
    settings: {}
  route_17:
    links:
      s20,o3: s31,o1
    routing_strategy: route_bundle
    settings: {}
  route_18:
    links:
      s21,o2: s32,o1
    routing_strategy: route_bundle
    settings: {}
  route_19:
    links:
      s21,o3: s33,o1
    routing_strategy: route_bundle
    settings: {}
  route_20:
    links:
      s22,o2: s34,o1
    routing_strategy: route_bundle
    settings: {}
  route_21:
    links:
      s22,o3: s35,o1
    routing_strategy: route_bundle
    settings: {}
  route_22:
    links:
      s23,o2: s36,o1
    routing_strategy: route_bundle
    settings: {}
  route_23:
    links:
      s23,o3: s37,o1
    routing_strategy: route_bundle
    settings: {}
  route_24:
    links:
      s30,o2: s40,o1
    routing_strategy: route_bundle
    settings: {}
  route_25:
    links:
      s30,o3: s41,o1
    routing_strategy: route_bundle
    settings: {}
  route_26:
    links:
      s31,o2: s42,o1
    routing_strategy: route_bundle
    settings: {}
  route_27:
    links:
      s31,o3: s43,o1
    routing_strategy: route_bundle
    settings: {}
  route_28:
    links:
      s32,o2: s44,o1
    routing_strategy: route_bundle
    settings: {}
  route_29:
    links:
      s32,o3: s45,o1
    routing_strategy: route_bundle
    settings: {}
  route_30:
    links:
      s33,o2: s46,o1
    routing_strategy: route_bundle
    settings: {}
  route_31:
    links:
      s33,o3: s47,o1
    routing_strategy: route_bundle
    settings: {}
  route_32:
    links:
      s34,o2: s48,o1
    routing_strategy: route_bundle
    settings: {}
  route_33:
    links:
      s34,o3: s49,o1
    routing_strategy: route_bundle
    settings: {}
  route_34:
    links:
      s35,o2: s410,o1
    routing_strategy: route_bundle
    settings: {}
  route_35:
    links:
      s35,o3: s411,o1
    routing_strategy: route_bundle
    settings: {}
  route_36:
    links:
      s36,o2: s412,o1
    routing_strategy: route_bundle
    settings: {}
  route_37:
    links:
      s36,o3: s413,o1
    routing_strategy: route_bundle
    settings: {}
  route_38:
    links:
      s37,o2: s414,o1
    routing_strategy: route_bundle
    settings: {}
  route_39:
    links:
      s37,o3: s415,o1
    routing_strategy: route_bundle
    settings: {}
warnings: {}

yaml.dump(s.netlist.model_dump(exclude_none=True), open("schematic.yaml", "w"))

Python routing

n = 2**3
splitter = gf.components.splitter_tree(noutputs=n, spacing=(50, 50))
dbr_array = gf.components.array(
    component=gf.c.dbr, rows=n, columns=1, column_pitch=0, row_pitch=3, centered=True
)
s = gt.Schematic()
s.add_instance("s", gt.Instance(component=splitter))
s.add_instance("dbr", gt.Instance(component=dbr_array))
s.add_placement("s", gt.Placement(x=0, y=0))
s.add_placement("dbr", gt.Placement(x=300, y=0))

for i in range(n):
    s.add_net(
        gt.Net(
            p1=f"s,o2_2_{i+1}",
            p2=f"dbr,o1_{i+1}_1",
            name="splitter_to_dbr",
            settings=dict(radius=5, sort_ports=True, cross_section="strip"),
        )
    )

g = s.plot_graphviz()
Warning: node s, port o2_2_1 unrecognized
Warning: node dbr, port o1_1_1 unrecognized
Warning: node s, port o2_2_2 unrecognized
Warning: node dbr, port o1_2_1 unrecognized
Warning: node s, port o2_2_3 unrecognized
Warning: node dbr, port o1_3_1 unrecognized
Warning: node s, port o2_2_4 unrecognized
Warning: node dbr, port o1_4_1 unrecognized
Warning: node s, port o2_2_5 unrecognized
Warning: node dbr, port o1_5_1 unrecognized
Warning: node s, port o2_2_6 unrecognized
Warning: node dbr, port o1_6_1 unrecognized
Warning: node s, port o2_2_7 unrecognized
Warning: node dbr, port o1_7_1 unrecognized
Warning: node s, port o2_2_8 unrecognized
Warning: node dbr, port o1_8_1 unrecognized
<IPython.core.display.Image object>
dbr_array.pprint_ports()
Loading...
splitter.pprint_ports()
Loading...
yaml.dump(s.netlist.model_dump(exclude_none=True), open("schematic.yaml", "w"))
yaml_component = yaml.dump(s.netlist.model_dump(exclude_none=True))
print(yaml_component)
connections: {}
info: {}
instances:
  dbr:
    component: array
    settings:
      add_ports: true
      auto_rename_ports: false
      centered: true
      column_pitch: 0
      columns: 1
      component: dbr
      row_pitch: 3
      rows: 8
  s:
    component: splitter_tree
    settings:
      bend_s: bend_s
      coupler: mmi1x2
      cross_section: strip
      noutputs: 8
      spacing: !!python/tuple
      - 50
      - 50
nets: []
pdk: ''
placements:
  dbr:
    dx: 0
    dy: 0
    mirror: false
    rotation: 0
    x: 300.0
    y: 0.0
  s:
    dx: 0
    dy: 0
    mirror: false
    rotation: 0
    x: 0.0
    y: 0.0
ports: {}
routes:
  splitter_to_dbr:
    links:
      s,o2_2_1: dbr,o1_1_1
      s,o2_2_2: dbr,o1_2_1
      s,o2_2_3: dbr,o1_3_1
      s,o2_2_4: dbr,o1_4_1
      s,o2_2_5: dbr,o1_5_1
      s,o2_2_6: dbr,o1_6_1
      s,o2_2_7: dbr,o1_7_1
      s,o2_2_8: dbr,o1_8_1
    routing_strategy: route_bundle
    settings:
      cross_section: strip
      radius: 5
      sort_ports: true
warnings: {}

from gdsfactory.serialization import convert_tuples_to_lists

conf = s.netlist.model_dump(exclude_none=True)
conf = convert_tuples_to_lists(conf)
yaml_component = yaml.dump(conf)
print(yaml_component)
connections: {}
info: {}
instances:
  dbr:
    component: array
    settings:
      add_ports: true
      auto_rename_ports: false
      centered: true
      column_pitch: 0
      columns: 1
      component: dbr
      row_pitch: 3
      rows: 8
  s:
    component: splitter_tree
    settings:
      bend_s: bend_s
      coupler: mmi1x2
      cross_section: strip
      noutputs: 8
      spacing:
      - 50
      - 50
nets: []
pdk: ''
placements:
  dbr:
    dx: 0
    dy: 0
    mirror: false
    rotation: 0
    x: 300.0
    y: 0.0
  s:
    dx: 0
    dy: 0
    mirror: false
    rotation: 0
    x: 0.0
    y: 0.0
ports: {}
routes:
  splitter_to_dbr:
    links:
      s,o2_2_1: dbr,o1_1_1
      s,o2_2_2: dbr,o1_2_1
      s,o2_2_3: dbr,o1_3_1
      s,o2_2_4: dbr,o1_4_1
      s,o2_2_5: dbr,o1_5_1
      s,o2_2_6: dbr,o1_6_1
      s,o2_2_7: dbr,o1_7_1
      s,o2_2_8: dbr,o1_8_1
    routing_strategy: route_bundle
    settings:
      cross_section: strip
      radius: 5
      sort_ports: true
warnings: {}

c = gf.read.from_yaml(yaml_component)
c
<Figure size 800x600 with 1 Axes><Figure size 800x600 with 1 Axes>