Ejemplo n.º 1
0
def ring_double_bus(**kwargs):
    """ Ring double bus

    Args:
        bend_radius=5
        length_x=1
        length_y=1
        gap=0.2
        coupler90_factory=coupler90
        straight_factory=waveguide
        cpl_straight_factory=coupler_straight
        wg_width=0.5


    .. code::

        -CTL==CTS==CTR-
         |          |
         VL         VR
         |          |
        -CBL==CBS==CBR-

    .. plot::
      :include-source:

      import pp

      c = pp.c.ring_double_bus(gap=0.2, length_x=10, length_y=5, bend_radius=5)
      pp.plotgds(c)


    """
    components, connections, ports_map = ring_double_bus_netlist(**kwargs)
    component = netlist_to_component(components, connections, ports_map)
    return component
Ejemplo n.º 2
0
def ring_single_bus(**kwargs):
    """ Ring single bus

    Args:
        bend_radius=5
        length_x=1
        length_y=1
        gap=0.2
        bend90_factory=bend_circular
        coupler90_factory=coupler90
        straight_factory=waveguide
        cpl_straight_factory=coupler_straight
        wg_width=0.5


    .. code::

         --length_x-
         |         |
         |       length_y
         |         |
       ---===gap===---

    .. plot::
      :include-source:

      import pp

      c = pp.c.ring_single_bus(gap=0.2, length_x=10, length_y=5, bend_radius=5)
      pp.plotgds(c)

    """
    components, connections, ports_map = ring_single_bus_netlist(**kwargs)
    component = netlist_to_component(components, connections, ports_map)
    return component
Ejemplo n.º 3
0
def coupler(**kwargs) -> Component:
    """ symmetric coupler

    Args:
        gap
        length
        coupler_symmetric_factory
        coupler_straight

    .. code::

       W1 __             __ E1
            \           /
             \         /
              ========= gap
             /          \
           _/            \_
        W0      length    E0

            coupler_straight  coupler_symmetric_factory

    .. plot::
      :include-source:

      import pp

      c = pp.c.coupler(gap=0.2, length=10)
      pp.plotgds(c)

    """
    components, connections, ports_map = coupler_netlist(**kwargs)
    component = netlist_to_component(components, connections, ports_map)
    return component
Ejemplo n.º 4
0
def coupler_biased(**kwargs):
    """symmetric coupler"""
    components, connections, ports_map = coupler_netlist(
        coupler_symmetric_factory=coupler_symmetric_biased,
        coupler_straight=coupler_straight_biased,
        **kwargs)
    component = netlist_to_component(components, connections, ports_map)
    return component
Ejemplo n.º 5
0
def simple_mzi2x2(coupler_length=20.147,
                  arm_length=40,
                  gap=0.234,
                  waveguide_factory=pp.c.waveguide):
    """
        arm_top
       /-----\
   CP1=       =CP2=
       \-----/
        arm_bot
   """

    # Define the components to use
    coupler = pp.c.coupler(length=coupler_length, gap=gap)
    arm = waveguide_factory(length=arm_length)

    # Create component references and give them unique names {name : (component, transform)}
    # Transform can be either "None", "mirror_x", "mirror_y", "R90", "R180", "R270"

    components = {
        "CP1": (coupler, "None"),
        "CP2": (coupler, "None"),
        "arm_top": (arm, "None"),
        "arm_bot": (arm, "mirror_x"),
    }

    # Provide how components are connected (component 1, port A, component 2, port B)
    # means that port B from component 2 is positioned at port A from component 1

    connections = [
        ## Top arm
        ("CP1", "E1", "arm_top", "W0"),
        ("arm_top", "E0", "CP2", "W1"),
        ## Bottom arm
        ("CP1", "E0", "arm_bot", "W0"),
        ("arm_bot", "E0", "CP2", "W0"),
    ]

    # Create the ports for this component, choosing which ports from the subcomponents should be exposed
    # {port name: (subcomponent, subcomponent port name)}

    ports_map = {
        "W0": ("CP1", "W0"),
        "W1": ("CP1", "W1"),
        "E0": ("CP2", "E0"),
        "E1": ("CP2", "E1"),
    }

    component = netlist_to_component(components, connections, ports_map)
    return component
Ejemplo n.º 6
0
def ring_single_bus_deprecated(**kwargs):
    """ Ring single bus

    use single_bus instead as this one can have snaping issues that create gaps between waveguides of the ring

    Args:
        bend_radius=5
        length_x=1
        length_y=1
        gap=0.2
        bend90_factory=bend_circular
        coupler90_factory=coupler90
        straight_factory=waveguide
        cpl_straight_factory=coupler_straight
        wg_width=0.5


    .. code::

         --length_x-
         |         |
         |       length_y
         |         |
       ---===gap===---

    .. plot::
      :include-source:

      import pp

      c = pp.c.ring_single_bus(gap=0.2, length_x=10, length_y=5, bend_radius=5)
      pp.plotgds(c)

    """
    components, connections, ports_map = ring_single_bus_netlist(**kwargs)
    component = netlist_to_component(components, connections, ports_map)
    return component
Ejemplo n.º 7
0
def mzi1x2(
    L0: float = 0.1,
    DL: float = 9.0,
    L2: float = 10.0,
    bend_radius: float = 10.0,
    bend90_factory: Callable = bend_circular,
    straight_heater_factory: Callable = waveguide_heater,
    straight_factory: Callable = waveguide,
    coupler_factory: Callable = mmi1x2,
    with_elec_connections: bool = False,
) -> Component:
    """ Mzi 1x2

    Args:
        L0: vertical length for both and top arms
        DL: bottom arm extra length
        L2: L_top horizontal length
        bend_radius: 10.0
        bend90_factory: bend_circular
        straight_heater_factory: waveguide_heater or waveguide
        straight_factory: waveguide
        coupler_factory: coupler

    .. code::

             __L2__
            |      |
            L0     L0
            |      |
          --|      |--
            |      |
            L0     L0
            |      |
            DL     DL
            |      |
            |__L2__|


             top_arm
        -CP1=       =CP2-
             bot_arm


    .. plot::
      :include-source:

      import pp

      c = pp.c.mzi1x2(L0=0.1, DL=0, L2=10)
      pp.plotgds(c)

    """
    if not with_elec_connections:
        straight_heater_factory = straight_factory

    cpl = pp.call_if_func(coupler_factory)

    arm_defaults = {
        "L_top": L2,
        "bend_radius": bend_radius,
        "bend90_factory": bend90_factory,
        "straight_heater_factory": straight_heater_factory,
        "straight_factory": straight_factory,
        "with_elec_connections": with_elec_connections,
    }

    arm_top = mzi_arm(L0=L0, **arm_defaults)
    arm_bot = mzi_arm(L0=L0 + DL, **arm_defaults)

    components = {
        "CP1": (cpl, "None"),
        "CP2": (cpl, "mirror_y"),
        "arm_top": (arm_top, "None"),
        "arm_bot": (arm_bot, "mirror_x"),
    }

    connections = [
        # Bottom arm
        ("CP1", "E0", "arm_bot", "W0"),
        ("arm_bot", "E0", "CP2", "E0"),
        # Top arm
        ("CP1", "E1", "arm_top", "W0"),
        ("arm_top", "E0", "CP2", "E0"),
    ]

    if with_elec_connections:
        ports_map = {
            "W0": ("CP1", "W0"),
            "E0": ("CP2", "W0"),
            "E_TOP_0": ("arm_top", "E_0"),
            "E_TOP_1": ("arm_top", "E_1"),
            "E_TOP_2": ("arm_top", "E_2"),
            "E_TOP_3": ("arm_top", "E_3"),
            "E_BOT_0": ("arm_bot", "E_0"),
            "E_BOT_1": ("arm_bot", "E_1"),
            "E_BOT_2": ("arm_bot", "E_2"),
            "E_BOT_3": ("arm_bot", "E_3"),
        }

        component = netlist_to_component(components, connections, ports_map)
        # Need to connect common ground and redefine electrical ports

        ports = component.ports
        y_elec = ports["E_TOP_0"].y
        for ls, le in [
            ("E_BOT_0", "E_BOT_1"),
            ("E_TOP_0", "E_TOP_1"),
            ("E_BOT_2", "E_TOP_2"),
        ]:
            component.add_polygon(line(ports[ls], ports[le]),
                                  layer=ports[ls].layer)

        # Add GND
        ("E_BOT_2", "E_TOP_2")
        component.add_port(
            name="GND",
            midpoint=0.5 *
            (ports["E_BOT_2"].midpoint + ports["E_TOP_2"].midpoint),
            orientation=180,
            width=ports["E_BOT_2"].width,
            layer=ports["E_BOT_2"].layer,
        )

        component.ports["E_TOP_3"].orientation = 0
        component.ports["E_BOT_3"].orientation = 0

        # Remove the eletrical ports that we have just used internally
        for lbl in [
                "E_BOT_0", "E_BOT_1", "E_TOP_0", "E_TOP_1", "E_BOT_2",
                "E_TOP_2"
        ]:
            component.ports.pop(lbl)

        # Reroute electrical ports
        _e_ports = select_electrical_ports(component)
        conn, e_ports = route_elec_ports_to_side(_e_ports,
                                                 side="north",
                                                 y=y_elec)

        for c in conn:
            component.add(c)

        for p in e_ports:
            component.ports[p.name] = p

        # Create nice electrical port names
        component.ports["HT1"] = component.ports["E_TOP_3"]
        component.ports.pop("E_TOP_3")

        component.ports["HT2"] = component.ports["E_BOT_3"]
        component.ports.pop("E_BOT_3")

    else:
        ports_map = {"W0": ("CP1", "W0"), "E0": ("CP2", "W0")}
        component = netlist_to_component(components, connections, ports_map)

    return component
Ejemplo n.º 8
0
def mzi2x2(
    CL_1=20.147,
    L0=60,
    L1=7.38,
    L2=10.0,
    gap=0.234,
    bend_radius=10.0,
    bend90_factory=bend_circular,
    straight_heater_factory=waveguide_heater,
    straight_factory=waveguide,
    coupler_factory=coupler,
    with_elec_connections=True,
):
    """ Mzi 2x2

    Args:
        CL_1: coupler length
        L0: vertical length for both and top arms
        L1: bottom arm extra length
        L2: L_top horizontal length
        gap: 0.235
        bend_radius: 10.0
        bend90_factory: bend_circular
        straight_heater_factory: waveguide_heater or waveguide
        straight_factory: waveguide
        coupler_factory: coupler


    .. code::

         __L2__
        |      |
        L0     L0
        |      |
      ==|      |==
        |      |
        L0     L0
        |      |
        L1     L1
        |      |
        |__L2__|


    .. code::
        
               top_arm
        ==CL_1=       =CL_1===
               bot_arm


    .. plot::
      :include-source:

      import pp

      c = pp.c.mzi2x2(CL_1=10, gap=0.2)
      pp.plotgds(c)

    """

    if callable(coupler_factory):
        cpl = coupler_factory(length=CL_1, gap=gap)
    else:
        cpl = coupler_factory

    arm_defaults = {
        "L_top": L2,
        "bend_radius": bend_radius,
        "bend90_factory": bend90_factory,
        "straight_heater_factory": straight_heater_factory,
        "straight_factory": straight_factory,
        "with_elec_connections": with_elec_connections,
    }

    arm_top = mzi_arm(L0=L0, **arm_defaults)
    arm_bot = mzi_arm(L0=L0, L1=L1, **arm_defaults)

    components = {
        "CP1": (cpl, "None"),
        "CP2": (cpl, "None"),
        "arm_top": (arm_top, "None"),
        "arm_bot": (arm_bot, "mirror_x"),
    }

    connections = [
        ## Top arm
        ("CP1", "E1", "arm_top", "W0"),
        ("arm_top", "E0", "CP2", "W1"),
        ## Bottom arm
        ("CP1", "E0", "arm_bot", "W0"),
        ("arm_bot", "E0", "CP2", "W0"),
    ]

    if with_elec_connections:

        ports_map = {
            "W0": ("CP1", "W0"),
            "W1": ("CP1", "W1"),
            "E0": ("CP2", "E0"),
            "E1": ("CP2", "E1"),
            "E_TOP_0": ("arm_top", "E_0"),
            "E_TOP_1": ("arm_top", "E_1"),
            "E_TOP_2": ("arm_top", "E_2"),
            "E_TOP_3": ("arm_top", "E_3"),
            "E_BOT_0": ("arm_bot", "E_0"),
            "E_BOT_1": ("arm_bot", "E_1"),
            "E_BOT_2": ("arm_bot", "E_2"),
            "E_BOT_3": ("arm_bot", "E_3"),
        }

        component = netlist_to_component(components, connections, ports_map)
        # Need to connect common ground and redefine electrical ports

        ports = component.ports
        y_elec = ports["E_TOP_0"].y
        for ls, le in [
            ("E_BOT_0", "E_BOT_1"),
            ("E_TOP_0", "E_TOP_1"),
            ("E_BOT_2", "E_TOP_2"),
        ]:
            component.add_polygon(line(ports[ls], ports[le]), layer=ports[ls].layer)

        # Add GND
        component.add_port(
            name="GND",
            midpoint=0.5 * (ports["E_BOT_2"].midpoint + ports["E_TOP_2"].midpoint),
            orientation=180,
            width=ports["E_BOT_2"].width,
            layer=ports["E_BOT_2"].layer,
        )

        component.ports["E_TOP_3"].orientation = 0
        component.ports["E_BOT_3"].orientation = 0

        # Remove the eletrical ports that we have just used internally
        for lbl in ["E_BOT_0", "E_BOT_1", "E_TOP_0", "E_TOP_1", "E_BOT_2", "E_TOP_2"]:
            component.ports.pop(lbl)

        # Reroute electrical ports
        _e_ports = select_electrical_ports(component)
        conn, e_ports = route_elec_ports_to_side(_e_ports, side="north", y=y_elec)

        for c in conn:
            component.add(c)

        for p in e_ports:
            component.ports[p.name] = p

        # Create nice electrical port names
        component.ports["HT1"] = component.ports["E_TOP_3"]
        component.ports.pop("E_TOP_3")

        component.ports["HT2"] = component.ports["E_BOT_3"]
        component.ports.pop("E_BOT_3")

        # Make sure each port knows its name
        for k, p in component.ports.items():
            p.name = k

    elif straight_heater_factory == waveguide:
        ports_map = {
            "W0": ("CP1", "W0"),
            "W1": ("CP1", "W1"),
            "E0": ("CP2", "E0"),
            "E1": ("CP2", "E1"),
        }

        component = netlist_to_component(components, connections, ports_map)

    return component
Ejemplo n.º 9
0
def netlist_from_yaml(
    yaml: Union[str, pathlib.Path, IO[Any]],
    component_factory=None,
) -> Component:
    """ Loads Component settings from YAML file, and connections

    Deprecated! use component_from_yaml instead

    Args:
        netlist: YAML IO describing instances, connections and ports_map

    Returns:
        Component

    .. code-block:: yaml

        instances:
            CP1:
              component: mmi1x2
              settings:
                  width_mmi: 4.5
                  length_mmi: 10
            CP2:
                component: mmi1x2
                settings:
                    width_mmi: 4.5
                    length_mmi: 5
                transformations: mirror_y
            arm_top:
                component: mzi_arm
                settings:
                    L0: 10
                    DL: 0
            arm_bot:
                component: mzi_arm
                settings:
                    L0: 100
                    DL: 0
                transformations: mirror_x

        ports_map:
            W0: [CP1, W0]
            E0: [CP2, W0]
            E_TOP_0: [arm_top, E_0]
            E_TOP_1: [arm_top, E_1]
            E_TOP_2: [arm_top, E_2]
            E_TOP_3: [arm_top, E_3]
            E_BOT_0: [arm_bot, E_0]
            E_BOT_1: [arm_bot, E_1]
            E_BOT_2: [arm_bot, E_2]
            E_BOT_3: [arm_bot, E_3]

        connections:
            - [CP1, E0, arm_bot, W0]
            - [arm_bot, E0, CP2, E0]
            - [CP1, E1, arm_top, W0]
            - [arm_top, E0, CP2, E0]

    """

    yaml = io.StringIO(yaml) if isinstance(yaml,
                                           str) and "\n" in yaml else yaml
    conf = OmegaConf.load(yaml)
    component_factory = component_factory or component_factory_default

    instances = {}
    for instance_name in conf.instances:
        instance_conf = conf.instances[instance_name]
        component_type = instance_conf["component"]
        component_settings = instance_conf["settings"] or {}
        instance = component_factory[component_type](**component_settings)
        instance_transformations = instance_conf["transformations"] or "None"
        instance_properties = instance_conf["properties"] or {}
        for k, v in instance_properties.items():
            setattr(instance, k, v)
        instance.name = instance_name
        instances[instance_name] = (instance, instance_transformations)

    connections = conf.connections
    ports_map = conf.ports_map
    return netlist_to_component(instances, connections, ports_map)