component_from_yaml

You can define a component using a YAML netlist.

YAML -> Component

instances

Lets start by defining the instances in YAML

[1]:
import gdsfactory as gf

yaml = """
instances:
    mmi_long:
      component: mmi1x2
      settings:
        width_mmi: 4.5
        length_mmi: 10
    mmi_short:
      component: mmi1x2
      settings:
        width_mmi: 4.5
        length_mmi: 5
"""

c = gf.component_from_yaml(yaml)
c
2021-09-25 16:20:10.555 | INFO     | gdsfactory.config:<module>:51 - 3.2.9
../_images/notebooks_07_yaml_component_1_1.png
[1]:
Unnamed_08aff039: uid 1, ports [], aliases [], 0 polygons, 2 references
[2]:
c.instances
[2]:
{'mmi_long': DeviceReference (parent Device "mmi1x2_length_mmi10_width_mmi4p5", ports ['o3', 'o2', 'o1'], origin (0, 0), rotation 0, x_reflection False),
 'mmi_short': DeviceReference (parent Device "mmi1x2_length_mmi5_width_mmi4p5", ports ['o3', 'o2', 'o1'], origin (0, 0), rotation 0, x_reflection False)}

You can modify the instances later (not recommended).

I recommend that you define that using placements in the YAML file

[3]:
c.instances["mmi_long"].x = 100
c.show()
c.plot()
../_images/notebooks_07_yaml_component_4_0.png

placements

Lets define the placecemts of each instance by defining a placements section in YAML

Lets place an mmi_long where you can place the W0 port at x=20, y=10

[4]:
import gdsfactory as gf

yaml = """
instances:
    mmi_long:
      component: mmi1x2
      settings:
        width_mmi: 4.5
        length_mmi: 5
placements:
    mmi_long:
        port: o1
        x: 20
        y: 10
"""

c = gf.component_from_yaml(yaml)
c.show()
c.plot()
../_images/notebooks_07_yaml_component_6_0.png

You can also mirror it

[5]:
import gdsfactory as gf

yaml = """
instances:
    mmi_long:
      component: mmi1x2
      settings:
        width_mmi: 4.5
        length_mmi: 5
placements:
    mmi_long:
        port: o1
        x: 20
        y: 10
        mirror: True
"""

c = gf.component_from_yaml(yaml)
c
../_images/notebooks_07_yaml_component_8_0.png
[5]:
Unnamed_c12bc908: uid 13, ports [], aliases [], 0 polygons, 1 references

ports

You can export the ports of any instance to the new component_from_yaml Component.

You will need to define a ports section in YAML

Lets expose all the ports from mmi_long into the new component.

Ports are exposed as new_port_name: instance_name, port_name

[6]:
import gdsfactory as gf

yaml = """
instances:
    mmi_long:
      component: mmi1x2
      settings:
        width_mmi: 4.5
        length_mmi: 5
placements:
    mmi_long:
        port: o1
        x: 20
        y: 10
        mirror: True

ports:
    o3: mmi_long,o3
    o2: mmi_long,o2
    o1: mmi_long,o1
"""

c = gf.component_from_yaml(yaml)
c.show()
c.plot()
../_images/notebooks_07_yaml_component_10_0.png

You can also define a mirror placement using a port

[7]:
import gdsfactory as gf

yaml = """
instances:
    mmi_long:
      component: mmi1x2
      settings:
        width_mmi: 4.5
        length_mmi: 5
placements:
    mmi_long:
        x: 0
        y: 0
        mirror: o1
"""

c = gf.component_from_yaml(yaml)
c
../_images/notebooks_07_yaml_component_12_0.png
[7]:
Unnamed_231ad8fd: uid 22, ports [], aliases [], 0 polygons, 1 references
[8]:
import gdsfactory as gf

yaml = """
instances:
    mmi_long:
      component: mmi1x2
      settings:
        width_mmi: 4.5
        length_mmi: 5
placements:
    mmi_long:
        x: 0
        y: 0
"""

c = gf.component_from_yaml(yaml)
c.show()
c.plot()
../_images/notebooks_07_yaml_component_13_0.png
[9]:
import gdsfactory as gf

yaml = """
instances:
    mmi_long:
      component: mmi1x2
      settings:
        width_mmi: 4.5
        length_mmi: 5
placements:
    mmi_long:
        x: 0
        y: 0
        mirror: 25
ports:
    o1: mmi_long,o3
    o2: mmi_long,o2
    o3: mmi_long,o1
"""

c = gf.component_from_yaml(yaml)
c.show()
c.plot()
../_images/notebooks_07_yaml_component_14_0.png
[10]:
import gdsfactory as gf

yaml = """
instances:
    mmi_long:
      component: mmi1x2
      settings:
        width_mmi: 4.5
        length_mmi: 5
placements:
    mmi_long:
        port: o1
        x: 10
        y: 20
        rotation: 90
"""

c = gf.component_from_yaml(yaml)
c.show()
c.plot()
../_images/notebooks_07_yaml_component_15_0.png
[11]:
import gdsfactory as gf

yaml = """
instances:
    mmi_long:
      component: mmi1x2
      settings:
        width_mmi: 4.5
        length_mmi: 5
placements:
    mmi_long:
        port: o1
        x: 10
        y: 20
        rotation: 90
ports:
    o1: mmi_long,o2
    o2: mmi_long,o3
    o3: mmi_long,o1
"""

c = gf.component_from_yaml(yaml)
c.show()
c.plot()
../_images/notebooks_07_yaml_component_16_0.png
[12]:
c.size_info.north
[12]:
45.0
[13]:
c.size_info.east
[13]:
12.25

connections

You can connect any two instances by defining a connections section in the YAML file.

it follows the syntax.

instance_source,port : instance_destination,port

[14]:
import gdsfactory as gf

yaml = """
instances:
    b:
      component: bend_circular
    mmi_long:
      component: mmi1x2
      settings:
        width_mmi: 4.5
        length_mmi: 10
    mmi_short:
      component: mmi1x2
      settings:
        width_mmi: 4.5
        length_mmi: 5
placements:
    mmi_short:
        port: o1
        x: 10
        y: 20
connections:
    b,o1 : mmi_short,o2
    mmi_long,o1: b, o2

ports:
    o1: mmi_short,o1
    o2: mmi_long,o2
    o3: mmi_long,o3
"""


c = gf.component_from_yaml(yaml)
c.show()
c.plot()
../_images/notebooks_07_yaml_component_20_0.png
[15]:
from omegaconf import OmegaConf
import io
[16]:
d = OmegaConf.load(
    io.StringIO(
        """
x: mmi_short,o3 10
dx: 10
"""
    )
)
d
[16]:
{'x': 'mmi_short,o3 10', 'dx': 10}
[17]:
d.keys()
[17]:
dict_keys(['x', 'dx'])

Relative port placing

You can also place a component with respect to another instance port

You can also define an x and y offset with dx and dy

[18]:
import gdsfactory as gf

yaml = """
instances:
    mmi_long:
      component: mmi1x2
      settings:
        width_mmi: 4.5
        length_mmi: 10
    mmi_short:
      component: mmi1x2
      settings:
        width_mmi: 4.5
        length_mmi: 5

placements:
    mmi_short:
        port: o1
        x: 0
        y: 0
    mmi_long:
        port: o1
        x: mmi_short,o2
        y: mmi_short,o2
        dx : 10
        dy: -10
"""


c = gf.component_from_yaml(yaml)
c.show()
c.plot()
../_images/notebooks_07_yaml_component_25_0.png

Cicular reference warning

You have to be careful not doing a circuilar reference

[19]:
import gdsfactory as gf

yaml = """
instances:
    mmi_long:
      component: mmi1x2
      settings:
        width_mmi: 4.5
        length_mmi: 10
    mmi_short:
      component: mmi1x2
      settings:
        width_mmi: 4.5
        length_mmi: 5

placements:
    mmi_short:
        port: o1
        x: mmi_long,o2
        y: mmi_long,o2
    mmi_long:
        port: o1
        x: mmi_short,o2
        y: mmi_short,o2
        dx : 10
        dy: 20
"""

gf.component_from_yaml(yaml)
../_images/notebooks_07_yaml_component_27_0.png
[19]:
Unnamed_aeace8c8: uid 61, ports [], aliases [], 0 polygons, 2 references

routes

You can define routes between two instanes by defining a routes section in YAML

it follows the syntax

routes:
    route_name:
        links:
            instance_source,port: instance_destination,port
        settings:  # for the route (optional)
            waveguide: strip
            width: 1.2
[20]:
import gdsfactory as gf

yaml = """
instances:
    mmi_long:
      component: mmi1x2
      settings:
        width_mmi: 4.5
        length_mmi: 10
    mmi_short:
      component: mmi1x2
      settings:
        width_mmi: 4.5
        length_mmi: 5
placements:
    mmi_long:
        x: 100
        y: 100
routes:
    optical:
        links:
            mmi_short,o2: mmi_long,o1
        settings:
            layer: [2, 0]
"""


c = gf.component_from_yaml(yaml)
c.show()
c.plot()
../_images/notebooks_07_yaml_component_29_0.png

You can rotate and instance specifying the angle in degrees

You can also define ports for the component

[21]:
import gdsfactory as gf

yaml = """
instances:
    mmi_long:
      component: mmi1x2
      settings:
        width_mmi: 4.5
        length_mmi: 10
    mmi_short:
      component: mmi1x2
      settings:
        width_mmi: 4.5
        length_mmi: 5

placements:
    mmi_long:
        rotation: 180
        x: 100
        y: 100

routes:
    optical:
        links:
            mmi_short,o2: mmi_long,o3

ports:
    o1: mmi_short,o1
    o2: mmi_long,o1

"""

c = gf.component_from_yaml(yaml)
c.show()
c.plot()
../_images/notebooks_07_yaml_component_32_0.png

You can also access the routes in the newly created component

[22]:
r = c.routes["mmi_short,o2:mmi_long,o3"]
r
[22]:
166.098

As well as the instances

[23]:
c.instances
[23]:
{'mmi_long': DeviceReference (parent Device "mmi1x2_length_mmi10_width_mmi4p5", ports ['o3', 'o2', 'o1'], origin [100. 100.], rotation 180, x_reflection False),
 'mmi_short': DeviceReference (parent Device "mmi1x2_length_mmi5_width_mmi4p5", ports ['o3', 'o2', 'o1'], origin (0, 0), rotation 0, x_reflection False)}

instances, placements, connections, ports, routes

Lets combine all you learned so far.

You can define the netlist connections of a component by a netlist in YAML format

Note that you define the connections as instance_source.port -> instance_destination.port so the order is important and therefore you can only change the position of the instance_destination

For example, this coupler has the center coupling region at (100, 0)

[24]:
gf.components.coupler_symmetric()
../_images/notebooks_07_yaml_component_38_0.png
[24]:
coupler_symmetric: uid 92, ports ['o1', 'o2', 'o3', 'o4'], aliases [], 2 polygons, 0 references
[25]:
import gdsfactory as gf

gap = 0.2
wg_width = 0.5
length = 10

yaml = f"""
instances:
    left:
      component: coupler_symmetric
      settings:
        gap: {gap}
        width: {wg_width}
    right:
      component: coupler_symmetric
      settings:
        gap: {gap}
        width: {wg_width}
    center:
      component: coupler_straight
      settings:
        gap: {gap}
        width: {wg_width}
        length: {length}

placements:
    center:
        x: 100
        y: 0
    left:
        mirror: True

connections:
    center,o1: left,o1
    right,o1: center,o4

ports:
    o1: left,o4
    o2: left,o3
    o3: right,o3
    o4: right,o4

"""

c = gf.component_from_yaml(yaml)
c
/home/docs/checkouts/readthedocs.org/user_builds/gdsfactory/checkouts/latest/gdsfactory/component_from_yaml.py:536: UserWarning: YAML defined: (center) with both connection and placement. Please use one or the other.
  warnings.warn(
../_images/notebooks_07_yaml_component_39_1.png
[25]:
Unnamed_a2655e28: uid 93, ports ['o1', 'o2', 'o3', 'o4'], aliases [], 0 polygons, 3 references

While this one has the sbend_left_coupler sl centered at (100, 0)

[26]:
import gdsfactory as gf

yaml = """
instances:
    mmi_long:
      component: mmi1x2
      settings:
        width_mmi: 4.5
        length_mmi: 10
    mmi_short:
      component: mmi1x2
      settings:
        width_mmi: 4.5
        length_mmi: 5
placements:
    mmi_long:
        x: 100
        y: 100
routes:
    route1:
        links:
            mmi_short,o2: mmi_long,o1
"""


c = gf.component_from_yaml(yaml)
c
../_images/notebooks_07_yaml_component_41_0.png
[26]:
Unnamed_fc0009bb: uid 98, ports [], aliases [], 0 polygons, 7 references

You can rotate and instance specifying the angle in degrees

[27]:
import gdsfactory as gf

yaml = """
instances:
    mmi_long:
      component: mmi1x2
      settings:
        width_mmi: 4.5
        length_mmi: 10
    mmi_short:
      component: mmi1x2
      settings:
        width_mmi: 4.5
        length_mmi: 5

placements:
    mmi_long:
        rotation: 180
        x: 100
        y: 100
routes:
    mmi_connect:
        links:
            mmi_short,o2: mmi_long,o3
"""


c = gf.component_from_yaml(yaml)
c
../_images/notebooks_07_yaml_component_43_0.png
[27]:
Unnamed_c05bf8ed: uid 109, ports [], aliases [], 0 polygons, 7 references

You can also define ports for the component

[28]:
import gdsfactory as gf

yaml = """
instances:
    mmi_long:
      component: mmi1x2
      settings:
        width_mmi: 4.5
        length_mmi: 10
    mmi_short:
      component: mmi1x2
      settings:
        width_mmi: 4.5
        length_mmi: 5

placements:
    mmi_long:
        rotation: 180
        x: 100
        y: 100

routes:
    optical:
        links:
            mmi_short,o2: mmi_long,o3

ports:
    o1: mmi_short,o1
    o2: mmi_long,o1
"""

c = gf.component_from_yaml(yaml)
c
../_images/notebooks_07_yaml_component_45_0.png
[28]:
Unnamed_2bb4f8d2: uid 120, ports ['o1', 'o2'], aliases [], 0 polygons, 7 references
[29]:
c.routes
[29]:
{'mmi_short,o2:mmi_long,o3': 166.098}
[30]:
r = c.routes["mmi_short,o2:mmi_long,o3"]
r
[30]:
166.098
[31]:
c.instances
[31]:
{'mmi_long': DeviceReference (parent Device "mmi1x2_length_mmi10_width_mmi4p5", ports ['o3', 'o2', 'o1'], origin [100. 100.], rotation 180, x_reflection False),
 'mmi_short': DeviceReference (parent Device "mmi1x2_length_mmi5_width_mmi4p5", ports ['o3', 'o2', 'o1'], origin (0, 0), rotation 0, x_reflection False)}
[32]:
c.routes
[32]:
{'mmi_short,o2:mmi_long,o3': 166.098}

You can define several routes that will be connected using gf.routing.get_bundle

[33]:
import gdsfactory as gf

sample_2x2_connections_solution = """
name:
    connections_2x2_problem

instances:
    mmi_bottom:
      component: mmi2x2
    mmi_top:
      component: mmi2x2

placements:
    mmi_top:
        x: 100
        y: 100

routes:
    optical:
        links:
            mmi_bottom,o4: mmi_top,o1
            mmi_bottom,o3: mmi_top,o2

"""

c = gf.component_from_yaml(sample_2x2_connections_solution)
c
../_images/notebooks_07_yaml_component_51_0.png
[33]:
connections_2x2_problem: uid 131, ports [], aliases [], 0 polygons, 12 references

You can also add custom component_factories to gf.component_from_yaml

[34]:
@gf.cell
def pad_new(size=(100, 100), layer=gf.LAYER.WG):
    c = gf.Component()
    compass = c << gf.components.compass(size=size, layer=layer)
    c.ports = compass.ports
    return c


c = pad_new(cache=False)
c
../_images/notebooks_07_yaml_component_53_0.png
[34]:
pad_new: uid 142, ports ['e1', 'e2', 'e3', 'e4'], aliases [], 0 polygons, 1 references
[35]:
import gdsfactory as gf


factory = gf.components.factory

factory["pad_new"] = pad_new

sample_custom_component = """
name:
    connections_2x2_problem

instances:
    bot:
      component: pad_new
    top:
      component: pad_new

placements:
    top:
        x: 0
        y: 200
"""

c = gf.component_from_yaml(sample_custom_component, component_factory=factory)
c
../_images/notebooks_07_yaml_component_54_0.png
[35]:
connections_2x2_problem: uid 145, ports [], aliases [], 0 polygons, 2 references
[36]:
sample_custom_component = """
name:
    custom_routes

instances:
    t:
      component: pad_array
      settings:
          orientation: 270
          columns: 3
    b:
      component: pad_array
      settings:
          orientation: 90
          columns: 3

placements:
    t:
        x: 200
        y: 400
routes:
    electrical:
        settings:
            layer: [31, 0]
            width: 10.
            end_straight_offset: 150
        links:
            t,e11: b,e11
            t,e13: b,e13
"""


c = gf.component_from_yaml(sample_custom_component)
c
../_images/notebooks_07_yaml_component_55_0.png
[36]:
custom_routes: uid 149, ports [], aliases [], 0 polygons, 12 references

Also, you can define route aliases, that have different settings and specify the route factory as a parameter as well as the settings for that particular route alias.

[37]:
import gdsfactory as gf

sample_settings = """
name: sample_settings

instances:
    bl:
      component: pad
    tl:
      component: pad
    br:
      component: pad
    tr:
      component: pad

placements:
    tl:
        x: 0
        y: 200

    br:
        x: 400
        y: 400

    tr:
        x: 400
        y: 600

routes:
    optical_r100:
        settings:
            radius: 100
            layer: [31, 0]
            width: 50
        links:
            tl,e2: tr,e2
    optical_r200:
        settings:
            radius: 200
            width: 10
            layer: [31, 0]
        links:
            bl,e3: br,e3
"""
gf.component_from_yaml(sample_settings)
../_images/notebooks_07_yaml_component_57_0.png
[37]:
sample_settings: uid 160, ports [], aliases [], 0 polygons, 18 references
[38]:
sample_custom_component = """

instances:
    t:
      component: pad_array
      settings:
          orientation: 270
          columns: 3
    b:
      component: pad_array
      settings:
          orientation: 90
          columns: 3

placements:
    t:
        x: 200
        y: 500
routes:
    optical:
        settings:
            radius: 50
            width: 40
            layer: [31,0]
            end_straight_offset: 150
            separation: 50
        links:
            t,e11: b,e11
            t,e12: b,e12
            t,e13: b,e13
"""

gf.component_from_yaml(sample_custom_component)
../_images/notebooks_07_yaml_component_58_0.png
[38]:
Unnamed_cf2bf32a: uid 174, ports [], aliases [], 0 polygons, 17 references
[39]:
import gdsfactory as gf

sample = """

instances:
    t:
      component: pad_array
      settings:
          orientation: 270
          columns: 3
    b:
      component: pad_array
      settings:
          orientation: 90
          columns: 3

placements:
    t:
        x: 100
        y: 1000
routes:
    route1:
        routing_strategy: get_bundle_path_length_match
        settings:
            extra_length: 500
            width: 2
            layer: [31,0]
            end_straight_offset: 500
        links:
            t,e11: b,e11
            t,e12: b,e12
"""

c = gf.component_from_yaml(sample)
print(c.routes["t,e11:b,e11"])
c
1620.794
../_images/notebooks_07_yaml_component_59_1.png
[39]:
Unnamed_8e2299ae: uid 186, ports [], aliases [], 0 polygons, 24 references
[40]:
import gdsfactory as gf

sample = """
instances:
    t:
      component: pad_array
      settings:
          orientation: 270
          columns: 3
    b:
      component: pad_array
      settings:
          orientation: 90
          columns: 3

placements:
    t:
        x: -250
        y: 1000
routes:
    route1:
        routing_strategy: get_bundle_from_waypoints
        settings:
            waypoints:
                - [0, 300]
                - [400, 300]
                - [400, 400]
                - [-250, 400]
            auto_widen: False
        links:
            b,e11: t,e11
            b,e12: t,e12

"""

c = gf.component_from_yaml(sample)
c
../_images/notebooks_07_yaml_component_60_0.png
[40]:
Unnamed_e4ea102c: uid 199, ports [], aliases [], 0 polygons, 20 references
[41]:
from omegaconf import OmegaConf
import io

d = OmegaConf.load(
    io.StringIO(
        """
way_points:
    - [0,0]
    - [0, 600]
    - [-250, 600]
    - [-250, 1000]

demo: a
"""
    )
)
[42]:
d = OmegaConf.load(
    io.StringIO("way_points:  [[0,0], [0, 600], [-250, 600], [-250, 1000]]")
)
[43]:
d
[43]:
{'way_points': [[0, 0], [0, 600], [-250, 600], [-250, 1000]]}
[44]:
import numpy as np

c = gf.Component("waypoints_sample")
route = gf.routing.get_route_from_waypoints(waypoints=np.array(d["way_points"]))

c.add(route.references)
c
../_images/notebooks_07_yaml_component_64_0.png
[44]:
waypoints_sample: uid 214, ports [], aliases [], 0 polygons, 5 references

Note that you define the connections as instance_source.port -> instance_destination.port so the order is important and therefore you can only change the position of the instance_destination

Custom factories

You can leverage netlist defined components to define more complex circuits

[45]:
import gdsfactory as gf


@gf.cell
def mzi_custom(length_x=0):
    netlist = f"""
instances:
    mzi:
        component: mzi_phase_shifter_90_90
        settings:
            length_x: 50

    pads:
        component: pad_array
        settings:
            columns: 2

placements:
    mzi:
        x: 0
    pads:
        y: 200
        x: 0
ports:
    o1: mzi,o1
    o2: mzi,o2


routes:
    electrical:
        links:
            mzi,e1: pads,e11
            mzi,e2: pads,e12

        settings:
            layer: [31, 0]
            width: 10
            radius: 10

"""
    return gf.component_from_yaml(netlist)


c = mzi_custom(length_x=10, cache=False)
c.show()
c.plot()
../_images/notebooks_07_yaml_component_67_0.png
[46]:
c = gf.components.mzi()
[47]:
c.plot_netlist()
[47]:
<networkx.classes.graph.Graph at 0x7f0dc8ff3400>
../_images/notebooks_07_yaml_component_69_1.png
[48]:
n = c.get_netlist()
[49]:
print(c.get_netlist_yaml())
connections:
  mmi1x2_0p0_0p0,o2: mzi_arm_bendbend_euler__4dd4d8f3_32p8_11p025,o1
  mmi1x2_0p0_0p0,o3: mzi_arm_bendbend_euler__f75c4604_32p8_m13p525,o1
  mmi1x2_65p6_0p0,o2: mzi_arm_bendbend_euler__f75c4604_32p8_m13p525,o2
  mmi1x2_65p6_0p0,o3: mzi_arm_bendbend_euler__4dd4d8f3_32p8_11p025,o2
instances:
  mmi1x2_0p0_0p0:
    component: mmi1x2
    settings: {}
  mmi1x2_65p6_0p0:
    component: mmi1x2
    settings: {}
  mzi_arm_bendbend_euler__4dd4d8f3_32p8_11p025:
    component: mzi_arm
    settings:
      straight_x: straight
      straight_y: straight
      length_x: 0.1
      length_y_left: 0.8
      length_y_right: 0.8
      bend: bend_euler
  mzi_arm_bendbend_euler__f75c4604_32p8_m13p525:
    component: mzi_arm
    settings:
      straight_x: straight
      straight_y: straight
      length_x: 0.1
      length_y_left: 5.8
      length_y_right: 5.8
      bend: bend_euler
placements:
  mmi1x2_0p0_0p0:
    x: 0.0
    'y': 0.0
    rotation: 0
    mirror: false
  mmi1x2_65p6_0p0:
    x: 65.6
    'y': 0.0
    rotation: 180
    mirror: false
  mzi_arm_bendbend_euler__4dd4d8f3_32p8_11p025:
    x: 12.75
    'y': 0.625
    rotation: 0
    mirror: false
  mzi_arm_bendbend_euler__f75c4604_32p8_m13p525:
    x: 12.75
    'y': -0.625
    rotation: 0
    mirror: true
ports:
  o1: mmi1x2_0p0_0p0,o1
  o2: mmi1x2_65p6_0p0,o1
name: mzi

get_netlist (Component -> YAML)

Any component exports its netlist get_netlist and returns an OmegaConf dict that can be easily converted into JSON and YAML.

While component_from_yaml converts YAML -> Component

get_netlist converts Component -> YAML

[50]:
import io
from omegaconf import OmegaConf
import gdsfactory
[51]:
c = gf.components.ring_single()
c
../_images/notebooks_07_yaml_component_74_0.png
[51]:
ring_single: uid 278, ports ['o2', 'o1'], aliases [], 0 polygons, 6 references
[52]:
c.plot_netlist()
[52]:
<networkx.classes.graph.Graph at 0x7f0dc9110af0>
../_images/notebooks_07_yaml_component_75_1.png
[53]:
netlist = c.get_netlist()
[54]:
c.write_netlist("ring.yml", full_settings=True)
[55]:
n = OmegaConf.load("ring.yml")
[56]:
i = list(n["instances"].keys())
i
[56]:
['bend_euler_cross_sectio_2b3226cd_5p125_16p425',
 'bend_euler_cross_sectio_2b3226cd_m9p125_16p425',
 'coupler_ring_bendbend_e_560275ce_m2p0_5p225',
 'straight_cross_sectionc_14dffc3c_10p0_11p0',
 'straight_cross_sectionc_14dffc3c_m14p0_11p0',
 'straight_cross_sectionc_2d7fbccb_m2p0_21p3']
[57]:
n["instances"][i[0]]["settings"]
[57]:
{'angle': 90, 'p': 1, 'with_arc_floorplan': True, 'npoints': 720, 'direction': 'ccw', 'with_cladding_box': True, 'cross_section': {'function': 'cross_section'}, 'radius': 10}
import gdsfactory as gf
from omegaconf import OmegaConf
import pathlib

c1 = gf.component_from_yaml('ring.yml')
c1
n = c1.get_netlist(full_settings=True)
connections = n['connections']
len(connections)

Plot netlist

You can plot the netlist of components.

Every gdsfactory component can either be defined by its netlist or using layout friendly functions such as component sequence to define it and then get_netlist() method.

Connections are determined by extracting all the ports of a component, and asuming that ports with the same (x, y) are connected.

When you do get_netlist() for a component it will only show connections for the instances that belong to that component (it trims the netlist). So despite having  a lot of connections, it will show only the meaningful connections for that component. For example, a ring has a ring_coupler. but if you want to digg deeper, the connections that made that ring coupler are still available.

[58]:
import gdsfactory as gf
[59]:
c = gf.components.mzi()
c
../_images/notebooks_07_yaml_component_85_0.png
[59]:
mzi: uid 304, ports ['o1', 'o2'], aliases [], 0 polygons, 4 references
[60]:
c = gf.components.mzi()
n = c.get_netlist()
print(c.get_netlist_yaml())
connections:
  mmi1x2_0p0_0p0,o2: mzi_arm_bendbend_euler__4dd4d8f3_32p8_11p025,o1
  mmi1x2_0p0_0p0,o3: mzi_arm_bendbend_euler__f75c4604_32p8_m13p525,o1
  mmi1x2_65p6_0p0,o2: mzi_arm_bendbend_euler__f75c4604_32p8_m13p525,o2
  mmi1x2_65p6_0p0,o3: mzi_arm_bendbend_euler__4dd4d8f3_32p8_11p025,o2
instances:
  mmi1x2_0p0_0p0:
    component: mmi1x2
    settings: {}
  mmi1x2_65p6_0p0:
    component: mmi1x2
    settings: {}
  mzi_arm_bendbend_euler__4dd4d8f3_32p8_11p025:
    component: mzi_arm
    settings:
      straight_x: straight
      straight_y: straight
      length_x: 0.1
      length_y_left: 0.8
      length_y_right: 0.8
      bend: bend_euler
  mzi_arm_bendbend_euler__f75c4604_32p8_m13p525:
    component: mzi_arm
    settings:
      straight_x: straight
      straight_y: straight
      length_x: 0.1
      length_y_left: 5.8
      length_y_right: 5.8
      bend: bend_euler
placements:
  mmi1x2_0p0_0p0:
    x: 0.0
    'y': 0.0
    rotation: 0
    mirror: false
  mmi1x2_65p6_0p0:
    x: 65.6
    'y': 0.0
    rotation: 180
    mirror: false
  mzi_arm_bendbend_euler__4dd4d8f3_32p8_11p025:
    x: 12.75
    'y': 0.625
    rotation: 0
    mirror: false
  mzi_arm_bendbend_euler__f75c4604_32p8_m13p525:
    x: 12.75
    'y': -0.625
    rotation: 0
    mirror: true
ports:
  o1: mmi1x2_0p0_0p0,o1
  o2: mmi1x2_65p6_0p0,o1
name: mzi

[61]:
c.plot_netlist()
[61]:
<networkx.classes.graph.Graph at 0x7f0dc92880d0>
../_images/notebooks_07_yaml_component_87_1.png
[62]:
n.keys()
[62]:
dict_keys(['connections', 'instances', 'placements', 'ports', 'name'])
[63]:
import gdsfactory as gf

yaml = """
instances:

    mmi1x2_12_0:
        component: mmi1x2

    bend_circular_R10p00_32_4:
      component: bend_circular

    straight_L1p00_35_11:
        component: straight
        settings:
            length: 10
            layer: [2, 0]

connections:
    bend_circular_R10p00_32_4,o1: mmi1x2_12_0,o2
    straight_L1p00_35_11,o1: bend_circular_R10p00_32_4,o2
"""

c = gf.component_from_yaml(yaml)
c.show()
c.plot()
c.name = "mmi_with_bend_circular"
print(c.name)
../_images/notebooks_07_yaml_component_89_0.png
mmi_with_bend_circular
[64]:
n = c.get_netlist()
[65]:
print(c.get_netlist_yaml())
connections:
  bend_circular_R10p00_32_4,o1: mmi1x2_12_0,o2
  bend_circular_R10p00_32_4,o2: straight_L1p00_35_11,o1
instances:
  bend_circular_R10p00_32_4:
    component: bend_circular
    settings: {}
  mmi1x2_12_0:
    component: mmi1x2
    settings: {}
  straight_L1p00_35_11:
    component: straight
    settings:
      length: 10
      layer:
      - 2
      - 0
placements:
  bend_circular_R10p00_32_4:
    x: 12.75
    'y': 0.625
    rotation: 0
    mirror: false
  mmi1x2_12_0:
    x: 0.0
    'y': 0.0
    rotation: 0
    mirror: false
  straight_L1p00_35_11:
    x: 22.75
    'y': 10.625
    rotation: 90
    mirror: false
ports: {}
name: mmi_with_bend_circular

[66]:
n["connections"]
[66]:
{'bend_circular_R10p00_32_4,o1': 'mmi1x2_12_0,o2',
 'bend_circular_R10p00_32_4,o2': 'straight_L1p00_35_11,o1'}
[67]:
c.plot_netlist()
[67]:
<networkx.classes.graph.Graph at 0x7f0dc96cc310>
../_images/notebooks_07_yaml_component_93_1.png
[68]:
c = gf.components.mzi()
c.plot()
c.plot_netlist()
../_images/notebooks_07_yaml_component_94_0.png
[68]:
<networkx.classes.graph.Graph at 0x7f0dc96cc5b0>
../_images/notebooks_07_yaml_component_94_2.png
[69]:
c = gf.components.ring_single()
c
../_images/notebooks_07_yaml_component_95_0.png
[69]:
ring_single: uid 363, ports ['o2', 'o1'], aliases [], 0 polygons, 6 references
[70]:
c.plot_netlist()
[70]:
<networkx.classes.graph.Graph at 0x7f0dc915d6d0>
../_images/notebooks_07_yaml_component_96_1.png
[71]:
c = gf.components.ring_double()
c
../_images/notebooks_07_yaml_component_97_0.png
[71]:
ring_double: uid 383, ports ['o1', 'o2', 'o3', 'o4'], aliases [], 0 polygons, 4 references
[72]:
c.plot_netlist()
[72]:
<networkx.classes.graph.Graph at 0x7f0dc93977c0>
../_images/notebooks_07_yaml_component_98_1.png
[73]:
import gdsfactory as gf

c = gf.components.ring_single()
c
../_images/notebooks_07_yaml_component_99_0.png
[73]:
ring_single: uid 388, ports ['o2', 'o1'], aliases [], 0 polygons, 6 references
[74]:
c.plot_netlist()
[74]:
<networkx.classes.graph.Graph at 0x7f0dc951bd30>
../_images/notebooks_07_yaml_component_100_1.png
[75]:
c = gf.components.ring_double()
c
../_images/notebooks_07_yaml_component_101_0.png
[75]:
ring_double: uid 408, ports ['o1', 'o2', 'o3', 'o4'], aliases [], 0 polygons, 4 references
[76]:
c.plot_netlist()
[76]:
<networkx.classes.graph.Graph at 0x7f0dc8fee3d0>
../_images/notebooks_07_yaml_component_102_1.png
[77]:
print(c.get_netlist_yaml())
connections:
  coupler_ring_bendNone_c_912186db_m0p005_16p185,o2: straight_cross_sectionc_aca44847_10p0_10p705,o2
  coupler_ring_bendNone_c_912186db_m0p005_16p185,o3: straight_cross_sectionc_aca44847_m10p01_10p705,o2
  coupler_ring_bendNone_c_912186db_m0p005_5p225,o2: straight_cross_sectionc_aca44847_m10p01_10p705,o1
  coupler_ring_bendNone_c_912186db_m0p005_5p225,o3: straight_cross_sectionc_aca44847_10p0_10p705,o1
instances:
  coupler_ring_bendNone_c_912186db_m0p005_16p185:
    component: coupler_ring
    settings:
      gap: 0.2
      radius: 10
      length_x: 0.01
      bend: null
      cross_section:
        function: cross_section
  coupler_ring_bendNone_c_912186db_m0p005_5p225:
    component: coupler_ring
    settings:
      gap: 0.2
      radius: 10
      length_x: 0.01
      bend: null
      cross_section:
        function: cross_section
  straight_cross_sectionc_aca44847_10p0_10p705:
    component: straight
    settings:
      length: 0.01
      cross_section:
        function: cross_section
  straight_cross_sectionc_aca44847_m10p01_10p705:
    component: straight
    settings:
      length: 0.01
      cross_section:
        function: cross_section
placements:
  coupler_ring_bendNone_c_912186db_m0p005_16p185:
    x: -0.01
    'y': 21.41
    rotation: 180
    mirror: false
  coupler_ring_bendNone_c_912186db_m0p005_5p225:
    x: 0.0
    'y': 0.0
    rotation: 0
    mirror: false
  straight_cross_sectionc_aca44847_10p0_10p705:
    x: 10.0
    'y': 10.7
    rotation: 90
    mirror: false
  straight_cross_sectionc_aca44847_m10p01_10p705:
    x: -10.01
    'y': 10.7
    rotation: 90
    mirror: false
ports:
  o1: coupler_ring_bendNone_c_912186db_m0p005_5p225,o1
  o2: coupler_ring_bendNone_c_912186db_m0p005_5p225,o4
  o3: coupler_ring_bendNone_c_912186db_m0p005_16p185,o4
  o4: coupler_ring_bendNone_c_912186db_m0p005_16p185,o1
name: ring_double

[78]:
c = gf.components.mzi()
c
../_images/notebooks_07_yaml_component_104_0.png
[78]:
mzi: uid 417, ports ['o1', 'o2'], aliases [], 0 polygons, 4 references
[79]:
c.plot_netlist()
[79]:
<networkx.classes.graph.Graph at 0x7f0dc9552640>
../_images/notebooks_07_yaml_component_105_1.png
[80]:
c = gf.components.mzit()
c
../_images/notebooks_07_yaml_component_106_0.png
[80]:
mzit: uid 431, ports ['o4', 'o3', 'o2', 'o1'], aliases [], 0 polygons, 17 references
[81]:
c.plot_netlist()
[81]:
<networkx.classes.graph.Graph at 0x7f0dc94eed90>
../_images/notebooks_07_yaml_component_107_1.png
[82]:
c = gf.components.mzi_lattice()
c
../_images/notebooks_07_yaml_component_108_0.png
[82]:
mzi_lattice: uid 471, ports ['o1', 'o2', 'o3', 'o4'], aliases [], 0 polygons, 1 references
[83]:
import gdsfactory as gf

coupler_lengths = [10, 20, 30]
coupler_gaps = [0.1, 0.2, 0.3]
delta_lengths = [10, 100]

c = gf.components.mzi_lattice(
    coupler_lengths=coupler_lengths,
    coupler_gaps=coupler_gaps,
    delta_lengths=delta_lengths,
)
c
../_images/notebooks_07_yaml_component_109_0.png
[83]:
mzi_lattice_coupler_gap_9d409350: uid 491, ports ['o1', 'o2', 'o3', 'o4'], aliases [], 0 polygons, 2 references
[84]:
print(c.get_netlist_yaml())
connections:
  mzi_combinercoupler_com_2f4c888f_165p15_m24p75,o1: mzi_combinercoupler_com_8c357570_45p05_m2p25,o4
  mzi_combinercoupler_com_2f4c888f_165p15_m24p75,o2: mzi_combinercoupler_com_8c357570_45p05_m2p25,o3
instances:
  mzi_combinercoupler_com_2f4c888f_165p15_m24p75:
    component: mzi
    settings:
      splitter: coupler
      combiner: coupler
      with_splitter: false
      delta_length: 100
      straight: straight
      splitter_settings:
        gap: 0.2
        length: 20
      combiner_settings:
        length: 30
        gap: 0.3
  mzi_combinercoupler_com_8c357570_45p05_m2p25:
    component: mzi
    settings:
      splitter: coupler
      combiner: coupler
      with_splitter: true
      delta_length: 10
      straight: straight
      combiner_settings:
        gap: 0.2
        length: 20
      splitter_settings:
        gap: 0.1
        length: 10
placements:
  mzi_combinercoupler_com_2f4c888f_165p15_m24p75:
    x: 110.1
    'y': 0.0
    rotation: 0
    mirror: false
  mzi_combinercoupler_com_8c357570_45p05_m2p25:
    x: 0.0
    'y': 0.0
    rotation: 0
    mirror: false
ports:
  o3: mzi_combinercoupler_com_2f4c888f_165p15_m24p75,o3
  o4: mzi_combinercoupler_com_2f4c888f_165p15_m24p75,o4
name: mzi_lattice_coupler_gap_9d409350

[85]:
c.plot_netlist()
[85]:
<networkx.classes.graph.Graph at 0x7f0dc949aaf0>
../_images/notebooks_07_yaml_component_111_1.png
[86]:
coupler_lengths = [10, 20, 30, 40]
coupler_gaps = [0.1, 0.2, 0.4, 0.5]
delta_lengths = [10, 100, 200]

c = gf.components.mzi_lattice(
    coupler_lengths=coupler_lengths,
    coupler_gaps=coupler_gaps,
    delta_lengths=delta_lengths,
)
c
../_images/notebooks_07_yaml_component_112_0.png
[86]:
mzi_lattice_coupler_gap_6a57921e: uid 521, ports ['o1', 'o2', 'o3', 'o4'], aliases [], 0 polygons, 3 references
[87]:
n = c.get_netlist()
[88]:
c.plot_netlist()
[88]:
<networkx.classes.graph.Graph at 0x7f0dc8bf1250>
../_images/notebooks_07_yaml_component_114_1.png
[ ]: