from typing import Any, Optional import nazca as nd import numpy as np from .couplers import ring_bus_wg from .taper import taper_xs2xs from ...geometry import Racetrack,Clothoid,circle,Elipse_dual from . import ring_bus_wg from ...electronics import Vias import nazca.interconnects as IC from ...basic import __cell_arg__ class Route(IC.Interconnect): pass # from ...routing import * class RacetrackResonator: """ RacetrackResonator primitive component. This component builds the RacetrackResonator layout cell. Parameters ---------- R0 : Any Radius parameter in microns. w0 : float Width parameter in microns. R1 : Any Radius parameter in microns. w1 : float Width parameter in microns. dLy : float Value for the dLy parameter. dLx : float Value for the dLx parameter. name : Optional[str], optional Unique identifier for the device cell. Default is None. xs : str, optional Layer or cross-section name used by the device. Default is 'strip'. gap1 : float, optional Spacing or gap parameter in microns. Default is 0.2. gap2 : float, optional Spacing or gap parameter in microns. Default is 0.2. w1_bus : float, optional Value for the w1_bus parameter. Default is 0.45. w2_bus : float, optional Value for the w2_bus parameter. Default is 0.45. R1_cp : Any, optional Radius parameter in microns. Default is None. R2_cp : Any, optional Radius parameter in microns. Default is None. A1_cp : int, optional Angle parameter in degrees. Default is 0. A2_cp : int, optional Angle parameter in degrees. Default is 0. w_wg : float, optional Width parameter in microns. Default is 0.45. R1_att : float, optional Radius parameter in microns. Default is 20. R2_att : float, optional Radius parameter in microns. Default is 20. R2_att_min : float, optional Radius parameter in microns. Default is 10. R1_att_min : float, optional Radius parameter in microns. Default is 10. A1_att : float, optional Angle parameter in degrees. Default is 30. A2_att : float, optional Angle parameter in degrees. Default is 20. Ltp_bus : int, optional Length parameter in microns. Default is 10. dL_p2p : Optional[float], optional Value for the dL_p2p parameter. Default is None. L_tilt : int, optional Length parameter in microns. Default is 10. sharp_patch : bool, optional Whether to add geometry patches for sharp corners or cladding continuity. Default is True. cell_xs_transition : Any, optional Cell or component dependency used by this device. Default is None. Euler_trasition : bool, optional Value for the Euler_trasition parameter. Default is False. res : float, optional Value for the res parameter. Default is 0.01. show_pins : bool, optional Whether to draw pin markers in the generated layout. Default is False. """ def __init__(self, R0: Any, w0: float, R1: Any, w1: float, dLy: float, dLx: float, name: Optional[str] = None, xs: str='strip', gap1: float = 0.2, gap2: float = 0.2, w1_bus: float = 0.45, w2_bus: float = 0.45, R1_cp: Any = None, R2_cp: Any = None, A1_cp: int = 0, A2_cp: int = 0, w_wg: float = 0.45, R1_att: float = 20, R2_att: float = 20, R2_att_min: float= 10, R1_att_min: float = 10, A1_att: float = 30, A2_att: float = 20, Ltp_bus: int = 10, dL_p2p: Optional[float] = None, L_tilt: int = 10, sharp_patch: bool=True, cell_xs_transition: Any=None, Euler_trasition: bool = False, res: float = 0.01, ## default to 1nm accurancy show_pins: bool=False ) -> None: self.name = name if (name==None): self.instantiate = False else: self.instantiate = True self.R0 = R0 self.R1 = R1 self.w0 = w0 self.w1 = w1 self.dLy = dLy self.dLx = dLx self.gap1 = gap1 self.gap2 = gap2 self.w1_bus = w1_bus self.w2_bus = w2_bus if (R1_cp==None): self.R1_cp = self.R0+self.w0/2+self.gap1+self.w1_bus/2 else : self.R1_cp = R1_cp if (R2_cp==None): self.R2_cp = self.R0+self.w0/2+self.gap2+self.w2_bus/2 else : self.R2_cp = R2_cp self.A1_cp = A1_cp self.A2_cp = A2_cp self.w_wg = w_wg self.R1_att = R1_att self.R2_att = R2_att self.R2_att_min = R2_att_min self.R1_att_min = R1_att_min self.A1_att = A1_att self.A2_att = A2_att self.Ltp_bus = Ltp_bus self.dL_p2p = dL_p2p self.L_tilt = L_tilt self.xs = xs self.Euler_trasition = Euler_trasition self.res = res self.cell = self.generate_gds(sharp_patch=sharp_patch,show_pins=show_pins) def generate_gds(self,sharp_patch=True,show_pins=False): with nd.Cell(name=self.name,instantiate=self.instantiate) as C: bend_cell = Clothoid(R=[self.R1,self.R0],A=[0,90],width_type='sine', w=[self.w0,self.w1], xs=self.xs, dL_wg=self.res) self.RCK = Racetrack(bend_cell=bend_cell, xs=self.xs, w=self.w1, dLx=self.dLx, dLy=self.dLy, res=self.res) RCK_INSTR = self.RCK.cell.put(0,0,0) bus = ring_bus_wg(xs=self.xs, R_cp=self.R1_cp, w_bus=self.w1_bus, dAc=self.A1_cp, wg_Ltp=self.Ltp_bus, dA_trans=self.A1_att, R_max_trans=self.R1_att, R_max_anti=self.R1_att, R_min_anti=self.R1_att_min, dL_p2p=self.dL_p2p, sharp_patch=sharp_patch, dL_trans=self.L_tilt, euler_anti_bend=self.Euler_trasition, euler_transistion=self.Euler_trasition) self.cell_bus = bus.cell bus_instr = bus.cell.put(0,-self.dLy/2-bend_cell.sz[1]-self.w0/2-self.w1_bus/2-self.gap1,0) ## revised in 2026.06.07 by Qin Yue # legacy: bus_instr.raise_pins(['a1','b1'],['a1','b1']) bus_instr.raise_pins(['opt_a1','opt_b1'],['opt_a1','opt_b1']) if (self.w2_bus > 0): bus_instr = bus.cell.put(0, self.dLy/2+bend_cell.sz[1]+self.w0/2+self.w2_bus/2+self.gap2,0,flip=1) ## revised in 2026.06.07 by Qin Yue # legacy: bus_instr.raise_pins(['a1','b1'],['a2','b2']) bus_instr.raise_pins(['opt_a1','opt_b1'],['opt_a2','opt_b2']) return C class Racetrack_STD_Allpass(RacetrackResonator): """ Racetrack STD Allpass primitive component. This component builds the Racetrack STD Allpass layout cell. Parameters ---------- r_rck : float Radius parameter in microns. w_rck : float Width parameter in microns. dLy : float Value for the dLy parameter. name : Optional[str], optional Unique identifier for the device cell. Default is None. xs : str, optional Layer or cross-section name used by the device. Default is 'strip'. gap : float, optional Spacing or gap parameter in microns. Default is 0.2. w_bus : float, optional Width parameter in microns. Default is 0.45. A_cp : int, optional Angle parameter in degrees. Default is 0. w_wg : float, optional Width parameter in microns. Default is 0.45. Ltp_bus : int, optional Length parameter in microns. Default is 10. dL_p2p : Optional[float], optional Value for the dL_p2p parameter. Default is None. L_tilt : int, optional Length parameter in microns. Default is 0. Ratt : int, optional Radius parameter in microns. Default is 10. w_ht : float, optional Width parameter in microns. Default is 0. w_mt : float, optional Width parameter in microns. Default is 10. via_h2m : Any, optional Via definition used between heater and metal layers. Default is None. xs_ht : str, optional Layer or cross-section name used by the device. Default is 'heater'. xs_mt : str, optional Layer or cross-section name used by the device. Default is 'metal'. sharp_patch : bool, optional Whether to add geometry patches for sharp corners or cladding continuity. Default is True. cell_xs_transition : Any, optional Cell or component dependency used by this device. Default is None. res : float, optional Value for the res parameter. Default is 0.01. show_pins : bool, optional Whether to draw pin markers in the generated layout. Default is False. """ def __init__(self, r_rck: float, w_rck: float, dLy: float, name: Optional[str]=None, xs: str='strip', gap: float=0.2, w_bus: float=0.45, A_cp: int=0, w_wg: float=0.45, Ltp_bus: int=10, dL_p2p: Optional[float]=None, L_tilt: int=0, Ratt: int = 10, w_ht: float=0, w_mt: float=10, via_h2m: Any=None, xs_ht: str = "heater", xs_mt: str = "metal", sharp_patch: bool=True, cell_xs_transition: Any=None, res: float=0.01, show_pins: bool=False) -> None: if (w_ht>0): name_pic = None else: name_pic = name super().__init__(R0=r_rck, w0=w_rck, R1=r_rck, w1=w_rck, dLy=dLy, dLx=0, name=name_pic, xs=xs, gap1=gap, gap2=0, w1_bus=w_bus, w2_bus=0, R1_cp=None, R2_cp=None, A1_cp=A_cp, A2_cp=0, w_wg=w_wg, R1_att=Ratt, R2_att=Ratt, R2_att_min=Ratt, R1_att_min=Ratt, A1_att=A_cp/2, A2_att=A_cp/2, Ltp_bus=Ltp_bus, dL_p2p=dL_p2p, L_tilt=L_tilt, sharp_patch=sharp_patch, cell_xs_transition=cell_xs_transition, Euler_trasition=False, res=res, show_pins=show_pins) self.w_rck = w_rck self.r_rck = r_rck self.w_bus = w_bus self.gap = gap self.xs_ht = xs_ht self.xs_mt = xs_mt self.w_ht = w_ht self.w_mt = w_mt self.via_h2m = via_h2m if (self.w_ht > 0): self.cell_pic = self.cell with nd.Cell(instantiate=True, name=name) as C: INSTR = self.cell.put() INSTR.raise_pins() eic_cell = self.generate_eic_gds().put() eic_cell.raise_pins(["ep1","en1"],["ep1","en1"]) self.cell = C def generate_eic_gds(self, sharp_patch=True, show_pins=False): with nd.Cell(instantiate=False) as C: HT_L = nd.strt(length=self.dLy/2,width=self.w_ht,xs=self.xs_ht).put(self.RCK.sz[0]/2,0,90) HT = nd.bend(radius=self.r_rck,width=self.w_ht,xs=self.xs_ht,angle=180).put() HT_R = nd.strt(length=self.dLy/2,width=self.w_ht,xs=self.xs_ht).put(-self.RCK.sz[0]/2,0,90) if (self.via_h2m is None): self.VIA = Vias(xs=None,xs_l1=self.xs_ht,xs_l2=self.xs_mt,sz=self.w_ht,area=self.w_mt,spacing=0) else : self.VIA = __cell_arg__(arg=self.via_h2m,arg_name="via_h2m",func_name="Racetrack_STD_Allpass::generate_eic_gds") HT_L = nd.strt(length=self.w_ht/2,width=self.w_ht,xs=self.xs_ht).put(self.RCK.sz[0]/2,0,-90) HT_R = nd.strt(length=self.w_ht/2,width=self.w_ht,xs=self.xs_ht).put(-self.RCK.sz[0]/2,0,-90) VIAL = self.VIA.put(HT_L.pin['b0']) VIAR = self.VIA.put(HT_R.pin['b0'],flip=1) VIAL.raise_pins(['b0'],["en1"]) VIAR.raise_pins(['b0'],["ep1"]) return C class Racetrack_MM_Allpass(RacetrackResonator): """ Racetrack MM Allpass primitive component. This component builds the Racetrack MM Allpass layout cell. Parameters ---------- r1_rck : float Value for the r1_rck parameter. w1_rck : float Value for the w1_rck parameter. r0_rck : float Value for the r0_rck parameter. w0_rck : float Value for the w0_rck parameter. dLy : float Value for the dLy parameter. name : Optional[str], optional Unique identifier for the device cell. Default is None. xs : str, optional Layer or cross-section name used by the device. Default is 'strip'. gap : float, optional Spacing or gap parameter in microns. Default is 0.2. w_bus : float, optional Width parameter in microns. Default is 0.45. A_cp : int, optional Angle parameter in degrees. Default is 0. w_wg : float, optional Width parameter in microns. Default is 0.45. R_att : int, optional Radius parameter in microns. Default is 50. R_att_min : int, optional Radius parameter in microns. Default is 10. A_att : int, optional Angle parameter in degrees. Default is 15. Ltp_bus : int, optional Length parameter in microns. Default is 10. dL_p2p : Optional[float], optional Value for the dL_p2p parameter. Default is None. sharp_patch : bool, optional Whether to add geometry patches for sharp corners or cladding continuity. Default is True. cell_xs_transition : Any, optional Cell or component dependency used by this device. Default is None. res : float, optional Value for the res parameter. Default is 0.01. show_pins : bool, optional Whether to draw pin markers in the generated layout. Default is False. """ def __init__(self, r1_rck: float, w1_rck: float, r0_rck: float, w0_rck: float, dLy: float, name: Optional[str]=None, xs: str='strip', gap: float=0.2, w_bus: float=0.45, A_cp: int=0, w_wg: float=0.45, R_att: int=50, R_att_min: int=10, A_att: int = 15, Ltp_bus: int=10, dL_p2p: Optional[float]=None, sharp_patch: bool=True, cell_xs_transition: Any=None, res: float=0.01, show_pins: bool=False) -> None: super().__init__(R0=r0_rck, w0=w0_rck, R1=r1_rck, w1=w1_rck, dLy=dLy, dLx=0, name=name, xs=xs, gap1=gap, gap2=0, w1_bus=w_bus, w2_bus=0, R1_cp=None, R2_cp=None, A1_cp=A_cp, A2_cp=0, w_wg=w_wg, R1_att=R_att, R2_att=R_att, R2_att_min=R_att_min, R1_att_min=R_att_min, A1_att=A_att, A2_att=A_att, Ltp_bus=Ltp_bus, dL_p2p=dL_p2p, L_tilt=0, sharp_patch=sharp_patch, cell_xs_transition=cell_xs_transition, Euler_trasition=True, res=res, show_pins=show_pins) class Racetrack_MM_Adddrop(RacetrackResonator): """ Racetrack MM Adddrop primitive component. This component builds the Racetrack MM Adddrop layout cell. Parameters ---------- r1_rck : float Value for the r1_rck parameter. w1_rck : float Value for the w1_rck parameter. r0_rck : float Value for the r0_rck parameter. w0_rck : float Value for the w0_rck parameter. dLy : float Value for the dLy parameter. name : Optional[str], optional Unique identifier for the device cell. Default is None. xs : str, optional Layer or cross-section name used by the device. Default is 'strip'. gap : float, optional Spacing or gap parameter in microns. Default is 0.2. w_bus : float, optional Width parameter in microns. Default is 0.45. A_cp : int, optional Angle parameter in degrees. Default is 0. w_wg : float, optional Width parameter in microns. Default is 0.45. R_att : int, optional Radius parameter in microns. Default is 50. R_att_min : int, optional Radius parameter in microns. Default is 10. A_att : int, optional Angle parameter in degrees. Default is 15. Ltp_bus : int, optional Length parameter in microns. Default is 10. dL_p2p : Optional[float], optional Value for the dL_p2p parameter. Default is None. sharp_patch : bool, optional Whether to add geometry patches for sharp corners or cladding continuity. Default is True. cell_xs_transition : Any, optional Cell or component dependency used by this device. Default is None. res : float, optional Value for the res parameter. Default is 0.01. show_pins : bool, optional Whether to draw pin markers in the generated layout. Default is False. """ def __init__(self, r1_rck: float, w1_rck: float, r0_rck: float, w0_rck: float, dLy: float, name: Optional[str]=None, xs: str='strip', gap: float=0.2, w_bus: float=0.45, A_cp: int=0, w_wg: float=0.45, R_att: int=50, R_att_min: int=10, A_att: int = 15, Ltp_bus: int=10, dL_p2p: Optional[float]=None, sharp_patch: bool=True, cell_xs_transition: Any=None, res: float=0.01, show_pins: bool=False) -> None: super().__init__(R0=r0_rck, w0=w0_rck, R1=r1_rck, w1=w1_rck, dLy=dLy, dLx=0, name=name, xs=xs, gap1=gap, gap2=gap, w1_bus=w_bus, w2_bus=w_bus, R1_cp=None, R2_cp=None, A1_cp=A_cp, A2_cp=A_cp, w_wg=w_wg, R1_att=R_att, R2_att=R_att, R2_att_min=R_att_min, R1_att_min=R_att_min, A1_att=A_att, A2_att=A_att, Ltp_bus=Ltp_bus, dL_p2p=dL_p2p, L_tilt=0, sharp_patch=sharp_patch, cell_xs_transition=cell_xs_transition, Euler_trasition=True, res=res, show_pins=show_pins)