Definition of each component class in **fnpcell** ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ In the **PhotoCAD** platform, each parameterizable component is generated by a Python script, which first defines the component as a class containing parameters that can be adjusted by the user, who generates the component by creating an instance of it using the class. Then the design of the component is customized by adjusting the parameter settings. The following code is intercepted from ``gpdk`` > ``components`` > ``bend`` > ``bend_bezier.py`` and belongs to the ``BendBezier`` class definition part of the Pcell ``bend_bezier``. Full script ---------------- :: from functools import cached_property from typing import Sequence, Tuple from fnpcell import all as fp from gpdk.technology import get_technology class BendBezier(fp.IWaveguideLike, fp.PCell): """ Attributes: start: start point of bezier curve controls: control points of bezier, 1 for Quadratic Bezier, 2 for Cubic Bezier, ... end: end point of bezier curve waveguide_type: type of waveguide of the bend port_names: defaults to ["op_0", "op_1"] Examples: ```python TECH = get_technology() bend = BendBezier(name="q", start=(0, 0), controls=[(31, 30)], end=(60, 0), waveguide_type=TECH.WG.FWG.C.WIRE) fp.plot(bend) ``` ![BendBezier](images/bend_bezier_q.png) """ start: fp.Point2D = fp.PositionParam(default=(0, 0), doc="position where bend start, eg. (x, y)") controls: Sequence[fp.Point2D] = fp.PointsParam(default=[(10, 0)], min_count=1, doc="control points, count >= 1, eg. [(x1, y1), (x2, y2)]") end: fp.Point2D = fp.PositionParam(default=(10, 10), doc="position where bend end, eg. (x, y)") waveguide_type: fp.IWaveguideType = fp.WaveguideTypeParam(doc="Waveguide parameters") port_names: fp.IPortOptions = fp.PortOptionsParam(count=2, default=["op_0", "op_1"]) def _default_waveguide_type(self): return get_technology().WG.FWG.C.WIRE @cached_property def raw_curve(self): return fp.g.Bezier( start=self.start, controls=self.controls, end=self.end, ) def build(self) -> Tuple[fp.InstanceSet, fp.ElementSet, fp.PortSet]: insts, elems, ports = super().build() wg = self.waveguide_type(curve=self.raw_curve).with_ports(self.port_names) insts += wg ports += wg.ports return insts, elems, ports Section Script Description ---------------------------------- The script firstly imports python function modules such as ``cached_property``, ``Sequence``, ``Tuple``, etc. (users can temporarily ignore their specific meaning). Secondly, it imports the process information in the function modules ``fnpcell`` and ``gpdk.technology`` module:: from functools import cached_property from typing import Sequence, Tuple from fnpcell import all as fp from gpdk.technology import get_technology The BendBezier class is defined by ``class BendBezier( )``. The BendBezier class contains several parameters for the cell layout: ``start``, ``controls``, ``end``, ``waveguide_type``, ``ports_names``. Please refer to the source code and its comments for detailed information about the parameters and how to use them. Some of the parameters have default values, so if users do not make special settings when using them, then they will be treated as default values. Secondly, users can modify the parameters to generate specific layout units. :: class BendBezier(fp.IWaveguideLike, fp.PCell): start: fp.Point2D = fp.PositionParam(default=(0, 0), doc="position where bend start, eg. (x, y)") controls: Sequence[fp.Point2D] = fp.PointsParam(default=[(10, 0)], min_count=1, doc="control points, count >= 1, eg. [(x1, y1), (x2, y2)]") end: fp.Point2D = fp.PositionParam(default=(10, 10), doc="position where bend end, eg. (x, y)") waveguide_type: fp.IWaveguideType = fp.WaveguideTypeParam(doc="Waveguide parameters") port_names: fp.IPortOptions = fp.PortOptionsParam(count=2, default=["op_0", "op_1"]) If no waveguide type is given, the default waveguide type will be returned:: def _default_waveguide_type( ): return get_technology().WG.FWG.C.WIRE This function is used to control the bezier curve design using user-defined parameters, and the return value is the new bezier curve generated:: def raw_curve(self): return fp.g.Bezier( start=self.start, controls=self.controls, end=self.end, ) Define the method to build user-defined parametric design to generate bezier bend, return the graphical unit and the port information of the device. Then generate the device according to the set parameters, i.e., a customized ``bend_bezier`` layout unit:: def build(self) -> Tuple[fp.InstanceSet, fp.ElementSet, fp.PortSet]: insts, elems, ports = super().build() wg = self.waveguide_type(curve=self.raw_curve).with_ports(self.port_names) insts += wg ports += wg.ports return insts, elems, ports