Source code for gdsfactory.components.coh_tx_dual_pol

from __future__ import annotations

import gdsfactory as gf
from gdsfactory.cell import cell
from gdsfactory.component import Component
from gdsfactory.routing.get_route import get_route
from gdsfactory.typings import ComponentSpec, CrossSectionSpec


[docs] @cell def coh_tx_dual_pol( splitter: ComponentSpec = "mmi1x2", combiner: ComponentSpec | None = None, spol_coh_tx: ComponentSpec = "coh_tx_single_pol", yspacing: float = 10.0, xspacing: float = 40.0, input_coupler: ComponentSpec | None = None, output_coupler: ComponentSpec | None = None, cross_section: CrossSectionSpec = "xs_sc", **kwargs, ) -> Component: """Dual polarization coherent transmitter. Args: splitter: splitter function. combiner: combiner function. spol_coh_tx: function generating a coherent tx for a single polarization. yspacing: vertical spacing between each single polarization coherent tx. xspacing: horizontal spacing between splitter and combiner. input_coupler: Optional coupler to add before the splitter. output_coupler: Optional coupler to add after the combiner. cross_section: for routing (splitter to mzms and mzms to combiners). kwargs: cross_section settings. .. code:: ___ single_pol_tx__ | | | | | | (in_coupler)---splitter==| |==combiner---(out_coupler) | | | | |___ single_pol_tx_| """ spol_coh_tx = gf.get_component(spol_coh_tx) # ----- Draw single pol coherent transmitters ----- # Add MZM 1 c = Component() single_tx_1 = c << spol_coh_tx single_tx_2 = c << spol_coh_tx # Separate the two receivers single_tx_2.movey(single_tx_1.ymin - yspacing - single_tx_2.ymax) # ------------ Splitters and combiners --------------- splitter = gf.get_component(splitter) sp = c << splitter sp.x = single_tx_1.xmin - xspacing sp.y = (single_tx_1.ports["o1"].y + single_tx_2.ports["o1"].y) / 2 route = get_route( sp.ports["o2"], single_tx_1.ports["o1"], cross_section=cross_section, with_sbend=False, **kwargs, ) c.add(route.references) route = get_route( sp.ports["o3"], single_tx_2.ports["o1"], cross_section=cross_section, with_sbend=False, **kwargs, ) c.add(route.references) if combiner: combiner = gf.get_component(combiner) comb = c << combiner comb.mirror() comb.x = single_tx_1.xmax + xspacing comb.y = (single_tx_1.ports["o2"].y + single_tx_2.ports["o2"].y) / 2 route = get_route( comb.ports["o2"], single_tx_1.ports["o2"], cross_section=cross_section, with_sbend=False, **kwargs, ) c.add(route.references) route = get_route( comb.ports["o3"], single_tx_2.ports["o2"], cross_section=cross_section, with_sbend=False, **kwargs, ) c.add(route.references) if input_coupler: in_coupler = gf.get_component(input_coupler) in_coup = c << in_coupler in_coup.connect("o1", sp.ports["o1"]) else: c.add_port("o1", port=sp.ports["o1"]) if output_coupler: output_coupler = gf.get_component(output_coupler) out_coup = c << output_coupler if combiner: # Add output coupler out_coup.connect("o1", comb.ports["o1"]) else: # Directly connect the output coupler to the branches. # Assumes the output couplers has ports "o1" and "o2" out_coup.y = (single_tx_1.y + single_tx_2.y) / 2 out_coup.xmin = single_tx_1.xmax + 40.0 route = get_route( single_tx_1.ports["o2"], out_coup.ports["o1"], cross_section=cross_section, with_sbend=False, **kwargs, ) c.add(route.references) route = get_route( single_tx_2.ports["o2"], out_coup.ports["o2"], cross_section=cross_section, with_sbend=False, **kwargs, ) c.add(route.references) else: c.add_port("o2", port=single_tx_1.ports["o2"]) c.add_port("o3", port=single_tx_2.ports["o2"]) c.add_ports(single_tx_1.get_ports_list(port_type="electrical"), prefix="pol1_") c.add_ports(single_tx_2.get_ports_list(port_type="electrical"), prefix="pol2_") return c
if __name__ == "__main__": c = coh_tx_dual_pol() c.show(show_ports=True)