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)
```

"""
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