Horizontalization of device ports ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ In the case where the device port needs to be kept horizontal, you can use the ``Horizontalized`` class to achieve the horizontalization of the device port, the specific schematic of this function definition is given in ``gpdk``>``routing``>``horizontalized.py``, please refer to the explanatory notes in the ``horizontalized.py`` script, the core usage of which is as follows. Horizontalized ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Full script ----------------- :: import math from typing import List, Optional, Tuple from fnpcell import all as fp from gpdk.technology import get_technology from gpdk.util import all as util class Horizontalized(fp.PCell): """ Attributes: device: device whose ports need to be horizontalized bend_factory: Optional, bend waveguide factory straight_type: Optional, type of final short straight straight_length: defaults to 0.1, length of final short straight Examples: ```python TECH = get_technology() device = Horizontalized(device=BendCircular(radius=30, waveguide_type=TECH.WG.FWG.C.WIRE, transform=fp.rotate(degrees=30))) fp.plot(device) ``` ![Horizontalized](images/horizontalized.png) """ device: fp.IDevice = fp.DeviceParam() bend_factory: Optional[fp.IBendWaveguideFactory] = fp.Param(required=False) straight_type: Optional[fp.IWaveguideType] = fp.WaveguideTypeParam(required=False) straight_length: float = fp.PositiveFloatParam(default=0.1) def build(self) -> Tuple[fp.InstanceSet, fp.ElementSet, fp.PortSet]: insts, elems, ports = super().build() TECH = get_technology() bend_factory = self.bend_factory straight_type = self.straight_type straight_length = self.straight_length PI = math.pi HALF_PI = PI / 2 content: List[fp.IDevice] = [self.device] for port in self.device.ports: if isinstance(port, fp.IOwnedPort) and not port.disabled: port_name = port.name port_orientation = fp.normalize_angle(port.orientation) final_orientation = None if -HALF_PI < port_orientation < HALF_PI: final_orientation = 0 elif HALF_PI < port_orientation < PI or -PI < port_orientation < -HALF_PI: final_orientation = PI if final_orientation is not None: turning_angle = fp.normalize_angle(final_orientation - port_orientation) if fp.is_nonzero(turning_angle): port = util.links.bend(TECH, content, start=port, radians=turning_angle, bend_factory=bend_factory) if straight_length is not None: port = util.links.straight(TECH, content, start=port, length=straight_length, end_type=straight_type) port = port.with_name(port_name) ports += port insts += content return insts, elems, ports if __name__ == "__main__": from gpdk.util.path import local_output_file gds_file = local_output_file(__file__).with_suffix(".gds") library = fp.Library() TECH = get_technology() # ============================================================= # fmt: off from gpdk.components.bend.bend_circular import BendCircular from gpdk.technology.waveguide_factory import EulerBendFactory library += Horizontalized(device=BendCircular(radius=30, waveguide_type=TECH.WG.FWG.C.WIRE, transform=fp.rotate(degrees=30))) library += Horizontalized(device=BendCircular(radius=30, waveguide_type=TECH.WG.FWG.C.WIRE, transform=fp.rotate(degrees=30)), bend_factory=EulerBendFactory(radius_min=25, l_max=25, waveguide_type=TECH.WG.FWG.C.WIRE)) # fmt: on # ============================================================= fp.export_gds(library, file=gds_file) # fp.plot(library) Section Script Definition ------------------------------------- Create horizontalized components ports and export layouts ============================================================ :: if __name__ == "__main__": from gpdk.util.path import local_output_file gds_file = local_output_file(__file__).with_suffix(".gds") library = fp.Library() TECH = get_technology() # ============================================================= # fmt: off from gpdk.components.bend.bend_circular import BendCircular from gpdk.technology.waveguide_factory import EulerBendFactory library += Horizontalized(device=BendCircular(radius=30, waveguide_type=TECH.WG.FWG.C.WIRE, transform=fp.rotate(degrees=30))) library += Horizontalized(device=BendCircular(radius=30, waveguide_type=TECH.WG.FWG.C.WIRE, transform=fp.rotate(degrees=30)), bend_factory=EulerBendFactory(radius_min=25, l_max=25, waveguide_type=TECH.WG.FWG.C.WIRE)) # fmt: on # ============================================================= fp.export_gds(library, file=gds_file) # fp.plot(library) Here, we use the ``Horizontalized`` class to horizontalize the port during the transition, where the device parameter input is used to receive the device that needs to be horizontalized, it is the device that will be horizontalized by the port. ``straight_type`` receives the type of straight waveguide used in the horizontalization process. ``straight_length`` receives the length of the straight waveguide after horizontalization, and ``bend_factory`` receives the curve type of the waveguide. In the following figure, we can see the device after port horizontalization. GDS Layout ------------------------ .. image:: ../images/horizontalized1.png