from typing import Any, Optional from turtle import ht import nazca as nd import numpy as np import nazca.interconnects as IC from ...geometry import * from ...routing import * from .unit import * from .rings import * from ..pic import * from ...electronics import Vias from ...basic import __array_convert__,__list_convert__,__xs_exist__,__cell_arg__ class STD_CROW_V: """ STD CROW V primitive component. This component builds the STD CROW V layout cell. Parameters ---------- ring : Any Ring cell or component used by this composite. bus : Any Bus waveguide cell or component used by this composite. w_bus : float or list Width parameter in microns. w_ring : float or list Width parameter in microns. sz_ring : float or list Value for the sz_ring parameter. sz_bus : float or list Value for the sz_bus parameter. name : str, optional Unique identifier for the device cell. Default is None. gap_crows : float or list, optional Spacing or gap parameter in microns. Default is [0.4]. gap_cp : float or list, optional Spacing or gap parameter in microns. Default is [0.45, 0.45]. w_heater : float or list, optional Width parameter in microns. Default is 0. xs_heater : str, optional Layer or cross-section name used by the device. Default is 'heater'. connected : bool, optional Value for the connected parameter. Default is True. w_metal : float, optional Width parameter in microns. Default is 8. xs_metal : str, optional Layer or cross-section name used by the device. Default is 'metal'. via_h2m : Any, optional Via definition used between heater and metal layers. Default is None. isl : Any, optional Isolation-trench definition used by the electrical layout. Default is None. ht_shift : int, optional Value for the ht_shift parameter. Default is 0. A_ht : int, optional Angle parameter in degrees. Default is 45. ISL_LEFT : bool, optional Value for the ISL_LEFT parameter. Default is True. ISL_RIGHT : bool, optional Value for the ISL_RIGHT parameter. Default is True. show_pins : bool, optional Whether to draw pin markers in the generated layout. Default is False. """ def __init__(self, ring: Any, bus: Any, w_bus:'float|list', w_ring:'float|list', sz_ring:'float|list', sz_bus:'float|list', name:str=None, gap_crows:'float|list'=[0.4], gap_cp:'float|list'=[0.45,0.45], w_heater:'float|list'=0, xs_heater:'str'='heater', connected:'bool'=True, w_metal:'float'=8, xs_metal:'str'='metal', via_h2m: Any = None, isl: Any = None, ht_shift: int=0, A_ht: int = 45, ISL_LEFT:'bool'=True,ISL_RIGHT:'bool'=True, show_pins:'bool'=False) -> None: """ """ self.ht_shift = ht_shift ## temporary variable self.A_ht = A_ht """ """ self.sz_ring = sz_ring self.w_ring = w_ring self.w_bus = w_bus self.sz_bus = sz_bus self.via_h2m = via_h2m self.isl = isl ## refreshed 2022.12.28 self.gap_crows = __array_convert__(gap_crows,'gap_crows','mxpic::passive::STD_CROW_V') self.gap_cp = __array_convert__(gap_cp,'gap_cp','mxpic::passive::STD_CROW_V') self.name = name if (name is None): self.instantiate = False else: self.instantiate = True self.connected = connected if (isinstance(ring,list)): self.ring_uniform = False self.ring_cell = ring self.connected = False if (len(ring)!=len(self.gap_crows)+1): raise Exception("ERROR: In , ring list does not match gap list") else : self.ring_uniform = True self.ring_cell = [ring]*(len(self.gap_crows)+1) if (isinstance(bus,list)): self.bus_uniform = False self.bus_cell = bus else : self.bus_uniform = True self.bus_cell = [bus]*(len(self.gap_cp)) ### standard input rules [[sz0,sz1],[sz0,sz1],....[sz0,sz1]] if (isinstance(self.sz_ring,int) or isinstance(self.sz_ring,float)): self.sz_ring=[[self.sz_ring,self.sz_ring]]*len(self.ring_cell) elif (isinstance(self.sz_ring,list)): _sz_ = np.shape(self.sz_ring) if (len(_sz_)==1): self.sz_ring=[[self.sz_ring[0],self.sz_ring[1]]]*len(self.ring_cell) ## y axis elif (_sz_[0]!=len(self.ring_cell)): raise Exception("ERROR: In , ring list does not match sz_ring list") if (isinstance(self.w_ring,int) or isinstance(self.w_ring,float)): self.w_ring=[[self.w_ring,self.w_ring]]*len(self.ring_cell) ## y axis elif (isinstance(self.w_ring,list)): _sz_ = np.shape(self.w_ring) if (len(_sz_)==1): self.w_ring=[[self.w_ring[0],self.w_ring[1]]]*len(self.ring_cell) ## y axis elif (_sz_[0]!=len(self.ring_cell)): raise Exception("ERROR: In , ring list does not match w_ring list") # print(type(w_heater)) if (isinstance(w_heater,int) or isinstance(w_heater,float)): self.w_heater = [w_heater]*len(self.ring_cell) else: self.w_heater = w_heater if (isinstance(self.w_bus,list) or isinstance(self.w_bus,np.ndarray)): self.w_bus=self.w_bus[1] ## y axis if (isinstance(self.sz_bus,int) or isinstance(self.sz_bus,float)): self.sz_bus=[[self.sz_bus,self.sz_bus]] ## y axis elif (isinstance(self.sz_bus,list)): if (len(np.shape(self.sz_bus))==1): ## only one dimension self.sz_bus=[self.sz_bus] ## y axis self.cell_pic = self.generate_pic_gds() ### ================== ### self.w_metal = w_metal self.ISL_LEFT = ISL_LEFT self.ISL_RIGHT = ISL_RIGHT try : nd.get_xsection(xs_heater) nd.get_xsection(xs_metal) self.xs_heater=xs_heater self.xs_metal=xs_metal try : if (w_heater>0): self.cell_eic = self.generate_eic_gds() else : self.cell_eic = None except : raise Exception("ERROR: In , func [generate_eic_gds] errors") except : self.xs_heater=None self.xs_metal=None self.cell_eic = None ### ======================== ### ### Building Final GDS ### if (self.cell_eic!=None and self.cell_pic!=None): with nd.Cell(instantiate=self.instantiate,name=self.name) as C: try : C_eic = self.cell_eic.put(0,0,0) C_pic = self.cell_pic.put(0,0,0) ## transporting pins for str,Pin in C_eic.ic_pins(): nd.Pin(name=str,pin=Pin).put() for str,Pin in C_pic.ic_pins(): nd.Pin(name=str,pin=Pin).put() if (show_pins): nd.put_stub(pinsize=2) except Exception as ex: print("ERROR :: ",ex) self.cell = C elif (self.cell_eic==None and self.cell_pic!=None): self.cell = self.cell_pic def generate_pic_gds(self): if (self.name is not None): instantiate = True name_pic = self.name + "_pic" else: instantiate = False name_pic = None with nd.Cell(instantiate=instantiate,name=name_pic) as C: try : instr = __cell_arg__(arg=self.ring_cell[0],arg_name="ring_cell[0]",func_name="STD_CROW_V::generate_pic_gds").put(0,0,0) # instr.raise_pins(['r1','r2','r3','r4'],['ra1','ra2','ra3','ra4']) # print(self.sz_ring,self.w_ring,self.gap_cp[0]) BUS_d = self.bus_cell[0].put(0,-self.sz_ring[0][1]/2-self.w_ring[0][1]/2-self.w_bus/2-self.gap_cp[0]) ## revised in 2026.06.07 by Qin Yue # legacy: nd.Pin(name='a1',pin=BUS_d.pin['a1']).put() nd.Pin(name='opt_a1',pin=BUS_d.pin['opt_a1'],type="optical:").put() ## revised in 2026.06.07 by Qin Yue # legacy: nd.Pin(name='b1',pin=BUS_d.pin['b1']).put() nd.Pin(name='opt_b1',pin=BUS_d.pin['opt_b1'],type="optical:").put() dy = 0 for _idx_ in range(0,len(self.gap_crows)): # print(self.sz_ring) dy = dy + self.sz_ring[_idx_][1]/2 + self.sz_ring[_idx_+1][1]/2 + self.w_ring[_idx_][1]/2+self.w_ring[_idx_+1][1]/2 + self.gap_crows[_idx_] # instr = self.ring_cell[_idx_+1].put(0,dy,0) instr = __cell_arg__(arg=self.ring_cell[_idx_+1],arg_name="ring_cell[_idx_+1]",func_name="STD_CROW_V::generate_pic_gds").put(0,dy,0) # if (_idx_==0): # instr.raise_pins(['r1','r2','r3','r4'],['rb1','rb2','rb3','rb4']) if (len(self.gap_cp)==2): BUS_u = self.bus_cell[1].put(0,dy+self.sz_ring[-1][1]/2+self.w_ring[-1][1]/2+self.w_bus/2+self.gap_cp[1],flip=1) ## revised in 2026.06.07 by Qin Yue # legacy: nd.Pin(name='a2',pin=BUS_u.pin['a1']).put() nd.Pin(name='opt_a2',pin=BUS_u.pin['opt_a1'],type="optical:").put() ## revised in 2026.06.07 by Qin Yue # legacy: nd.Pin(name='b2',pin=BUS_u.pin['b1']).put() nd.Pin(name='opt_b2',pin=BUS_u.pin['opt_b1'],type="optical:").put() except Exception as ex: print("ERROR :: ",ex) return C def generate_eic_gds(self): with nd.Cell(instantiate=False) as C: ht_box = [self.sz_ring[0][0],self.sz_ring[0][1]] """ BUG : Revised 2023.04.01 """ if (self.via_h2m is None): # self.via_h2m = Vias(xs=None,area=self.w_metal,sz=0,spacing=0,xs_l1=self.xs_heater,xs_l2=self.xs_metal) ## only putting metal blocks VIA = Vias(xs=None,area=self.w_metal,sz=0,spacing=0,xs_l1=self.xs_heater,xs_l2=self.xs_metal) ## only putting metal blocks else: if (hasattr(self.via_h2m,"cell")): # self.via_h2m = self.via_h2m VIA = self.via_h2m else : # self.via_h2m = Vias(xs=self.via_h2m.xs,area=self.w_metal,sz=self.via_h2m.sz,spacing=self.via_h2m.spacing,xs_l1=self.xs_heater,xs_l2=self.xs_metal) ## placing vias VIA = Vias(xs=self.via_h2m.xs,area=self.w_metal,sz=self.via_h2m.sz,spacing=self.via_h2m.spacing,xs_l1=self.xs_heater,xs_l2=self.xs_metal) ## placing vias # VIA = self.via_h2m HT,r_ht,Large_crow = self._generate_HT_box_cell_(ht_box=ht_box,w_heater=self.w_heater[0]) cell_pre = HT.put(0,0,0) dy = 0 eic_mt = IC.Interconnect(radius=10,width=self.w_metal,xs=self.xs_metal) eic_ht = IC.Interconnect(radius=10,width=self.w_heater[0],xs=self.xs_heater) """ Generating heaters """ if (self.connected==True and Large_crow==False): if (self.via_h2m is None): temp_L = eic_ht.strt(length=self.w_metal+self.w_heater[0],pin=cell_pre.pin['ed1'],arrow=False).put() eic_ht.strt(length=self.w_metal/2+self.ht_shift/2,width=self.w_metal).put(temp_L.pin['b0'].x,temp_L.pin['b0'].y+self.w_metal/2,180) temp_L = VIA.cell.put(temp_L.pin['b0'].x-self.w_metal/2-self.w_heater[0]/2,temp_L.pin['b0'].y+self.w_metal/2,-90) nd.Pin(name='ep1',pin=temp_L.pin['b0']).put() temp_R = eic_ht.strt(length=self.w_metal+self.w_heater[0],pin=cell_pre.pin['ed2'],arrow=False).put() eic_ht.strt(length=self.w_metal/2+self.ht_shift/2,width=self.w_metal).put(temp_R.pin['b0'].x,temp_R.pin['b0'].y+self.w_metal/2,0) temp_R = VIA.cell.put(temp_R.pin['b0'].x+self.w_metal/2+self.w_heater[0]/2,temp_R.pin['b0'].y+self.w_metal/2,-90) nd.Pin(name='en1',pin=temp_R.pin['b0']).put() else: temp_L = VIA.cell.put(cell_pre.pin['ed1'],flip=1) nd.Pin(name='ep1',pin=temp_L.pin['b0']).put() temp_R = VIA.cell.put(cell_pre.pin['ed2']) nd.Pin(name='en1',pin=temp_R.pin['b0']).put() else : nd.Pin(name='ep1',pin=cell_pre.pin['ed1']).put() nd.Pin(name='en1',pin=cell_pre.pin['ed2'].move(0,0,180)).put() for _idx_ in range(0,len(self.gap_crows)): eic_mt = IC.Interconnect(radius=10,width=self.w_metal,xs=self.xs_metal) eic_ht = IC.Interconnect(radius=10,width=self.w_heater[_idx_],xs=self.xs_heater) dy = dy + self.sz_ring[_idx_][1]/2 + self.sz_ring[_idx_+1][1]/2 + self.w_ring[_idx_][1]/2+self.w_ring[_idx_+1][1]/2 + self.gap_crows[_idx_] ht_box = [self.sz_ring[_idx_+1][0],self.sz_ring[_idx_+1][1]] HT,r_ht,Large_crow = self._generate_HT_box_cell_(ht_box=ht_box,w_heater=self.w_heater[_idx_]) cell_cur = HT.put(0,dy,0) if (self.connected==True): if (Large_crow==True): eic_mt.strt_p2p(pin1=cell_pre.pin['eu1'],pin2=cell_cur.pin['ed1'],arrow=False).put() eic_mt.strt_p2p(pin1=cell_pre.pin['eu2'],pin2=cell_cur.pin['ed2'],arrow=False).put() else : eic_ht.strt_p2p(pin1=cell_pre.pin['eu1'],pin2=cell_cur.pin['ed1'],arrow=False).put() eic_ht.strt_p2p(pin1=cell_pre.pin['eu2'],pin2=cell_cur.pin['ed2'],arrow=False).put() else : # print(_idx_) nd.Pin(name='ep'+str(_idx_+2),pin=cell_cur.pin['ed1']).put() nd.Pin(name='en'+str(_idx_+2),pin=cell_cur.pin['ed2'].move(0,0,180)).put() cell_pre = cell_cur if (self.connected==True and Large_crow==False): ## revised in 2022.09.23, it cannot work in single ring VIA = Vias(xs=VIA.xs,area=self.w_metal,sz=VIA.sz,spacing=VIA.spacing,xs_l1=self.xs_heater,xs_l2=self.xs_metal, sp_via_xs=VIA.sp_via_xs) temp_L = eic_ht.strt(length=self.w_metal+self.w_heater[-1],pin=cell_pre.pin['eu1'],arrow=False).put() temp_L = VIA.cell.put(temp_L.pin['b0'].x-self.w_metal/2,temp_L.pin['b0'].y-self.w_metal/2,90) temp_R = eic_ht.strt(length=self.w_metal+self.w_heater[-1],pin=cell_pre.pin['eu2'],arrow=False).put() temp_R = VIA.cell.put(temp_R.pin['b0'].x+self.w_metal/2,temp_R.pin['b0'].y-self.w_metal/2,-90) eic_mt.strt_p2p(pin1=temp_L.pin['b0'],pin2=temp_R.pin['b0'],arrow=False).put() elif (self.connected==True): eic_mt.strt_p2p(pin1=cell_pre.pin['eu1'],pin2=cell_pre.pin['eu2'],arrow=False).put() if (self.isl is not None): # print(dy,self.sz_ring,self.sz_bus) L_isl = dy+self.sz_ring[0][1]/2+self.sz_ring[-1][1]/2 - self.sz_bus[0][1] - self.sz_bus[-1][1] - self.isl.sp_isl_wg*2 if (L_isl>0): _x_ = [] for _sz_ in self.sz_ring: _x_.append(_sz_[0]) x_isl = max(_x_)/2 + max(self.w_heater) + self.isl.sp_isl_metal if (self.ISL_RIGHT): ISL(xs=self.isl.xs,width=self.isl.width,length=L_isl,Lmax=self.isl.Lmax,spacing=self.isl.spacing).cell.put(x_isl,dy/2-L_isl/2,90) if (self.ISL_LEFT): ISL(xs=self.isl.xs,width=self.isl.width,length=L_isl,Lmax=self.isl.Lmax,spacing=self.isl.spacing).cell.put(-x_isl,dy/2-L_isl/2,90) return C def _generate_HT_box_cell_(self,ht_box,w_heater): r_ht = min(ht_box)/2 l_ht = ht_box[1]-r_ht*2 if (hasattr(self,'A_ht')): A_ht = self.A_ht else : A_ht = 45 Arc_ht = A_ht/180*np.pi Large_crow = r_ht*np.sin(Arc_ht)>=self.w_metal ## generate heater unit cell ### if heater side-side distance is larger than w_metal, vias will be added with nd.Cell(instantiate=False) as HT: x_ht = ht_box[0]/2-r_ht+self.ht_shift/2 y_ht = ht_box[1]/2-r_ht circle(radius=r_ht,width=w_heater,theta_start=0 ,theta_stop=A_ht,res=0.05, xs=self.xs_heater).cell.put(x_ht,y_ht,0) circle(radius=r_ht,width=w_heater,theta_start=180-A_ht,theta_stop=180,res=0.05, xs=self.xs_heater).cell.put(-x_ht,y_ht,0) nd.strt(length=l_ht,width=w_heater,xs=self.xs_heater).put(-(x_ht+r_ht),-l_ht/2,90) nd.strt(length=l_ht,width=w_heater,xs=self.xs_heater).put( (x_ht+r_ht),-l_ht/2,90) """ Revised in 2023.2.2, """ circle(radius=r_ht,width=w_heater,theta_start=180,theta_stop=180+A_ht,res=0.05, xs=self.xs_heater).cell.put(-x_ht,-y_ht,0) ## revised : 2023.2.2, -> circle(radius=r_ht,width=w_heater,theta_start=360-A_ht,theta_stop=360,res=0.05, xs=self.xs_heater).cell.put(x_ht,-y_ht,0) ## used to see whether crow is large """ Generate VIAS, two situations: 1. Heaters not connected, 2.Side-Side distance larger than w_metal """ if (self.connected==False or Large_crow==True): VIA_MT = Vias(xs=self.via_h2m.xs,area=self.w_metal,sz=self.via_h2m.sz,spacing=self.via_h2m.spacing,xs_l1=self.xs_heater,xs_l2=self.xs_metal) _x_via_ = x_ht-r_ht*(1-np.cos(Arc_ht))+r_ht temp = VIA_MT.cell.put( _x_via_, y_ht+r_ht*np.sin(Arc_ht),0) nd.Pin(name='eu1',pin=temp.pin['a0'].rot(180)).put() if (self.connected==False): nd.strt(length=r_ht*np.cos(Arc_ht)*2,width=self.w_metal,xs=self.xs_metal).put(temp.pin['a0'].x,temp.pin['a0'].y,180) temp = VIA_MT.cell.put( _x_via_,-y_ht-r_ht*np.sin(Arc_ht),0) nd.Pin(name='ed1',pin=temp.pin['a0'].rot(180)).put() temp = VIA_MT.cell.put( -_x_via_, y_ht+r_ht*np.sin(Arc_ht),0) nd.Pin(name='eu2',pin=temp.pin['a0'].rot(180)).put() temp = VIA_MT.cell.put( -_x_via_,-y_ht-r_ht*np.sin(Arc_ht),0) nd.Pin(name='ed2',pin=temp.pin['a0'].rot(180)).put() else: L_cnt = w_heater x_ht_cnt = (r_ht-w_heater/2)*np.cos(Arc_ht)+w_heater/2+x_ht y_ht_cnt = y_ht+(r_ht-w_heater/2)*np.sin(Arc_ht) temp = nd.strt(length=L_cnt,width=w_heater,xs=self.xs_heater).put(-x_ht_cnt, y_ht_cnt,90) nd.Pin(name='eu1',pin=temp.pin['b0']).put() temp = nd.strt(length=L_cnt,width=w_heater,xs=self.xs_heater).put( x_ht_cnt, y_ht_cnt,90) nd.Pin(name='eu2',pin=temp.pin['b0']).put() temp = nd.strt(length=L_cnt,width=w_heater,xs=self.xs_heater).put(-x_ht_cnt,-y_ht_cnt,-90) nd.Pin(name='ed1',pin=temp.pin['b0']).put() temp = nd.strt(length=L_cnt,width=w_heater,xs=self.xs_heater).put( x_ht_cnt,-y_ht_cnt,-90) nd.Pin(name='ed2',pin=temp.pin['b0']).put() return HT,r_ht,Large_crow class CROW_Eul_Ring(STD_CROW_V) : """ CROW Eul Ring primitive component. This component builds the CROW Eul Ring layout cell. Parameters ---------- name : str Unique identifier for the device cell. R0 : int, optional Radius parameter in microns. Default is 10. R1 : int, optional Radius parameter in microns. Default is 3. w0 : float, optional Width parameter in microns. Default is 0.38. w1 : float, optional Width parameter in microns. Default is 0.65. w_bus : float, optional Width parameter in microns. Default is 0.35. R_att : int, optional Radius parameter in microns. Default is 15. R_att_min : int, optional Radius parameter in microns. Default is 3. A_att : int, optional Angle parameter in degrees. Default is 30. w_wg : float, optional Width parameter in microns. Default is 0.45. dLx : float, optional Value for the dLx parameter. Default is 0. dLy : float, optional Value for the dLy parameter. Default is 0. xs_wg : str, optional Layer or cross-section name used by the device. Default is 'strip'. gap_crows : list, optional Spacing or gap parameter in microns. Default is [0.4]. gap_cp : float, optional Spacing or gap parameter in microns. Default is 0.45. w_heater : float, optional Width parameter in microns. Default is 0. xs_heater : str, optional Layer or cross-section name used by the device. Default is 'heater'. connected : bool, optional Value for the connected parameter. Default is True. w_metal : float, optional Width parameter in microns. Default is 8. xs_metal : str, optional Layer or cross-section name used by the device. Default is 'metal'. via_h2m : Any, optional Via definition used between heater and metal layers. Default is None. isl : Any, optional Isolation-trench definition used by the electrical layout. Default is None. ISL_LEFT : bool, optional Value for the ISL_LEFT parameter. Default is True. ISL_RIGHT : bool, optional Value for the ISL_RIGHT parameter. Default is True. show_pins : bool, optional Whether to draw pin markers in the generated layout. Default is False. sharp_patch : bool, optional Whether to add geometry patches for sharp corners or cladding continuity. Default is True. dL_p2p : Optional[float], optional Value for the dL_p2p parameter. Default is None. Ltp_bus : int, optional Length parameter in microns. Default is 0. ht_shift : int, optional Value for the ht_shift parameter. Default is 0. A_ht : int, optional Angle parameter in degrees. Default is 45. R_cp : Any, optional Radius parameter in microns. Default is None. bus_order : float, optional Value for the bus_order parameter. Default is 1.0. width_type : str, optional Width parameter in microns. Default is 'crow_customize'. A_cp : int, optional Angle parameter in degrees. Default is 0. """ def __init__(self, name: str, R0: int = 10, R1: int=3, w0: float = 0.38,w1: float=0.65, w_bus: float=0.35, R_att: int=15, R_att_min: int = 3, A_att: int=30,w_wg: float=0.45, dLx: float = 0, dLy: float=0, xs_wg: str='strip', gap_crows: list=[0.4], gap_cp: float=0.45, w_heater: float=0, xs_heater: str='heater', connected: bool=True, w_metal: float=8, xs_metal: str='metal', via_h2m: Any = None, isl: Any = None, ISL_LEFT: bool=True, ISL_RIGHT: bool=True, show_pins: bool=False, sharp_patch: bool=True, dL_p2p: Optional[float] = None, Ltp_bus: int = 0, ht_shift: int = 0, A_ht: int=45, R_cp: Any = None, bus_order: float = 1.0, width_type: str = 'crow_customize', A_cp: int=0,) -> None: if (R_cp==None): if (isinstance(gap_cp,int) or isinstance(gap_cp,float)): R_cp = R0+w0/2+gap_cp+w_bus/2 else: R_cp = R0+w0/2+gap_cp[0]+w_bus/2 """ Revised in 2022.11.25 """ self.w0 = w0 self.w1 = w1 self.R0 = R0 self.R1 = R1 self.xs_wg = xs_wg self.R_att = R_att self.A_att = A_att self.width_type = width_type euler = Clothoid(R = [R0,R1],w=[w0,w1],Rmax=max([R0,R1])*10,A=[0,90],xs=xs_wg,width_type=width_type,dL_wg=0.05) ring = Racetrack(bend_cell=euler,xs=xs_wg,layer=None,dLx=dLx,dLy=dLy) sz_ring = ring.sz w_ring = ring.w # ring = ring.cell ring = ring bus = ring_bus_wg(xs=xs_wg, R_cp=R_cp, ### Revise 2022.11.25 w_bus=w_bus,bend_DC=True, w_wg=w_wg, dAc=A_cp, euler_anti_bend=True,euler_transistion=True, R_max_trans=R_att,dA_trans=A_att,dL_trans=0, w_trans=w_bus, R_max_anti=R_att,R_min_anti=R_att_min,sharp_patch=sharp_patch, show_pins=False, dL_p2p=dL_p2p, wg_Ltp=Ltp_bus, res=0.05, clothoid_order=bus_order ) self.bus = bus super().__init__(ring=ring, name= name, bus=bus.cell, w_bus=bus.w, w_ring=w_ring, sz_ring=sz_ring, sz_bus=bus.sz, gap_crows=gap_crows, gap_cp=gap_cp, w_heater=w_heater, xs_heater=xs_heater, connected=connected, w_metal=w_metal, xs_metal=xs_metal, via_h2m=via_h2m, isl=isl, ISL_LEFT=ISL_LEFT, ISL_RIGHT=ISL_RIGHT, show_pins=show_pins, ht_shift=ht_shift, A_ht=A_ht) class CROW_Eul_RCK(STD_CROW_V) : """ CROW Eul RCK primitive component. This component builds the CROW Eul RCK layout cell. Parameters ---------- R0 : int, optional Radius parameter in microns. Default is 10. R1 : int, optional Radius parameter in microns. Default is 3. R2 : int, optional Radius parameter in microns. Default is 20. w0 : float, optional Width parameter in microns. Default is 0.38. w1 : float, optional Width parameter in microns. Default is 0.65. w_bus : float, optional Width parameter in microns. Default is 0.35. R_att : int, optional Radius parameter in microns. Default is 15. R_att_min : int, optional Radius parameter in microns. Default is 3. A_att : int, optional Angle parameter in degrees. Default is 30. w_wg : float, optional Width parameter in microns. Default is 0.45. dAc : float, optional Value for the dAc parameter. Default is 0. dLx : float, optional Value for the dLx parameter. Default is 0. dLy : float, optional Value for the dLy parameter. Default is 0. xs_wg : str, optional Layer or cross-section name used by the device. Default is 'strip'. gap_crows : list, optional Spacing or gap parameter in microns. Default is [0.4]. gap_cp : float, optional Spacing or gap parameter in microns. Default is 0.45. w_heater : float, optional Width parameter in microns. Default is 0. xs_heater : str, optional Layer or cross-section name used by the device. Default is 'heater'. connected : bool, optional Value for the connected parameter. Default is True. w_metal : float, optional Width parameter in microns. Default is 8. xs_metal : str, optional Layer or cross-section name used by the device. Default is 'metal'. via_h2m : Any, optional Via definition used between heater and metal layers. Default is None. isl : Any, optional Isolation-trench definition used by the electrical layout. Default is None. ISL_LEFT : bool, optional Value for the ISL_LEFT parameter. Default is True. ISL_RIGHT : bool, optional Value for the ISL_RIGHT parameter. Default is True. show_pins : bool, optional Whether to draw pin markers in the generated layout. Default is False. sharp_patch : bool, optional Whether to add geometry patches for sharp corners or cladding continuity. Default is True. dL_p2p : Optional[float], optional Value for the dL_p2p parameter. Default is None. Ltp_bus : int, optional Length parameter in microns. Default is 0. ht_shift : int, optional Value for the ht_shift parameter. Default is 0. A_ht : int, optional Angle parameter in degrees. Default is 45. """ def __init__(self, R0: int = 10, R1: int=3,R2: int=20, w0: float = 0.38,w1: float=0.65, w_bus: float=0.35, R_att: int=15, R_att_min: int = 3, A_att: int=30,w_wg: float=0.45,dAc: float=0, dLx: float = 0, dLy: float=0, xs_wg: str='strip', gap_crows: list=[0.4], gap_cp: float=0.45, w_heater: float=0, xs_heater: str='heater', connected: bool=True, w_metal: float=8, xs_metal: str='metal', via_h2m: Any = None, isl: Any = None, ISL_LEFT: bool=True, ISL_RIGHT: bool=True, show_pins: bool=False, sharp_patch: bool=True, dL_p2p: Optional[float] = None, Ltp_bus: int = 0, ht_shift: int = 0, A_ht: int=45) -> None: if (isinstance(gap_cp,int) or isinstance(gap_cp,float)): R_cp = R0+w0/2+gap_cp+w_bus/2 else: R_cp = R0+w0/2+gap_cp[0]+w_bus/2 # euler = spiral_dual(R0=R0,R1=R1,R2=R2,w0=w0,w1=w1,Rmax=max([R0,R1,R2])*10,xs=xs_wg,width_type='sine') """ Revised in 2022.11.25 """ euler = Clothoid(R = [R0,R1,R2],w=[w0,w1],Rmax=max([R0,R1,R2])*10,A=[0,45,90],xs=xs_wg,width_type='sine' ) ring = Racetrack(bend_cell=euler,xs=xs_wg,layer=None,dLx=dLx,dLy=dLy) sz_ring = ring.sz w_ring = ring.w ring = ring.cell # ring,sz_ring,w_ring = euler.racetrack(dLy=dLy,dLx=dLx) bus = ring_bus_wg(xs=xs_wg, R_cp=R_cp, ### Revise 2022.11.25 w_bus=w_bus,bend_DC=True, w_wg=w_wg, dAc=dAc, euler_anti_bend=True,euler_transistion=True, R_max_trans=R_att,dA_trans=A_att,dL_trans=0, w_trans=w_bus, R_max_anti=R_att,R_min_anti=R_att_min,sharp_patch=sharp_patch, show_pins=False, dL_p2p=dL_p2p, wg_Ltp=Ltp_bus, ) super().__init__(ring=ring, bus=bus.cell, w_bus=bus.w, w_ring=w_ring, sz_ring=sz_ring, sz_bus=bus.sz, gap_crows=gap_crows, gap_cp=gap_cp, w_heater=w_heater, xs_heater=xs_heater, connected=connected, w_metal=w_metal, xs_metal=xs_metal, via_h2m=via_h2m, isl=isl, ISL_LEFT=ISL_LEFT, ISL_RIGHT=ISL_RIGHT, show_pins=show_pins, ht_shift=ht_shift, A_ht=A_ht) """ Circular ring """ class CROW_Circular_ring(STD_CROW_V): """ CROW Circular ring primitive component. This component builds the CROW Circular ring layout cell. Parameters ---------- r_ring : float, optional Radius parameter in microns. Default is 10. w_ring : float, optional Width parameter in microns. Default is 0.45. xs_ring : str, optional Layer or cross-section name used by the device. Default is 'strip'. w1_bus : float, optional Value for the w1_bus parameter. Default is 0.45. A1_cp : int, optional Angle parameter in degrees. Default is 10. w2_bus : float, optional Value for the w2_bus parameter. Default is 0.45. A2_cp : int, optional Angle parameter in degrees. Default is 10. gap1 : float, optional Spacing or gap parameter in microns. Default is 0.45. gap2 : float, optional Spacing or gap parameter in microns. Default is 0.45. w_wg : float, optional Width parameter in microns. Default is 0.45. Euler_trasition : bool, optional Value for the Euler_trasition parameter. Default is True. R1_cp : Any, optional Radius parameter in microns. Default is None. R2_cp : Any, optional Radius parameter in microns. Default is None. R1_att : float, optional Radius parameter in microns. Default is 10. R2_att : float, optional Radius parameter in microns. Default is 10. R1_att_min : float, optional Radius parameter in microns. Default is 5. R2_att_min : float, optional Radius parameter in microns. Default is 5. A1_att : int, optional Angle parameter in degrees. Default is 45. A2_att : int, optional Angle parameter in degrees. Default is 45. gap_crows : float or list, optional Spacing or gap parameter in microns. Default is [0.4]. w_heater : float or list, optional Width parameter in microns. Default is 0. xs_heater : str, optional Layer or cross-section name used by the device. Default is 'heater'. connected : bool, optional Value for the connected parameter. Default is True. w_metal : float, optional Width parameter in microns. Default is 8. xs_metal : str, optional Layer or cross-section name used by the device. Default is 'metal'. via_h2m : Any, optional Via definition used between heater and metal layers. Default is None. isl : Any, optional Isolation-trench definition used by the electrical layout. Default is None. ISL_LEFT : bool, optional Value for the ISL_LEFT parameter. Default is True. ISL_RIGHT : bool, optional Value for the ISL_RIGHT parameter. Default is True. show_pins : bool, optional Whether to draw pin markers in the generated layout. Default is False. sharp_patch : bool, optional Whether to add geometry patches for sharp corners or cladding continuity. Default is True. dL_p2p : Optional[float], optional Value for the dL_p2p parameter. Default is None. Ltp_bus : int, optional Length parameter in microns. Default is 0. ht_shift : int, optional Value for the ht_shift parameter. Default is 0. A_ht : int, optional Angle parameter in degrees. Default is 45. """ def __init__(self, r_ring: float = 10, w_ring:float = 0.45,xs_ring: str='strip', w1_bus: float = 0.45,A1_cp: int = 10, w2_bus: float = 0.45,A2_cp: int = 10, gap1: float = 0.45, gap2: float = 0.45, w_wg: float = 0.45, Euler_trasition: bool=True, R1_cp: Any = None, R2_cp: Any = None, R1_att:float = 10, R2_att:float = 10, R1_att_min: float = 5, R2_att_min: float = 5, A1_att: int = 45, A2_att: int = 45, gap_crows: 'float|list' = [0.4], w_heater: 'float|list' = 0, xs_heater: 'str' = 'heater', connected: 'bool' = True, w_metal: 'float' = 8, xs_metal: 'str' = 'metal', via_h2m: Any = None, isl: Any = None, ISL_LEFT: 'bool' = True, ISL_RIGHT: 'bool' = True, show_pins: 'bool' = False, sharp_patch: bool = True, dL_p2p: Optional[float] = None, Ltp_bus: int = 0, ht_shift: int=0, A_ht: int = 45) -> None: ## defining ring list if (isinstance(r_ring,int) or isinstance(r_ring,float)): ring = circle(radius=r_ring,width=w_ring, # n_points=128, res=0.05, xs=xs_ring) ring_cell = ring.cell ring_sz = ring.sz ring_w = ring.w r_ring = [r_ring] w_ring = [w_ring] elif (isinstance(r_ring,list) or isinstance(r_ring,np.ndarray)): if (len(r_ring)!=len(w_ring)): raise Exception("ERROR: In , does not match ") ring_cell = [] ring_sz = [] ring_w = [] for _idx_ in range(0,len(r_ring)): _ring_ = circle(radius=r_ring[_idx_],width=w_ring[_idx_],res=0.05, # n_points=128, xs=xs_ring) ring_cell.append(_ring_.cell) ring_sz.append(_ring_.sz) ring_w.append(_ring_.w) ## expand to N*2 dimension list, [[sz0,sz1],[sz0,sz1]] # ring_sz = [ring_sz,ring_sz] # ring_w = [ring_w,ring_w] else : raise Exception("ERROR: In , is not recongized, please input type ") if (w1_bus<=0): raise Exception("ERROR: In , should larger than 0") if (R1_cp==None): R1_cp = w1_bus/2 + r_ring[0] + w_ring[0]/2 + gap1 BUS_U = ring_bus_wg(xs=xs_ring, R_cp=R1_cp, ### Revise 2022.11.25 w_bus=w1_bus,bend_DC=True, w_wg=w_wg, dAc=A1_cp, euler_anti_bend=Euler_trasition,euler_transistion=Euler_trasition, R_max_trans=R1_att,dA_trans=A1_att,dL_trans=0, w_trans=w1_bus, R_max_anti=R1_att,R_min_anti=R1_att_min,sharp_patch=sharp_patch, show_pins=False, dL_p2p=dL_p2p, wg_Ltp=Ltp_bus, res=0.05, ) bus_cell = [BUS_U.cell] bus_w = BUS_U.w bus_sz = BUS_U.sz gap_cp = [gap1] """ Add-drop CROW """ if (w2_bus>0): if (R2_cp==None): R2_cp = w2_bus/2 + r_ring[-1] + w_ring[-1]/2 + gap2 BUS_D = ring_bus_wg(xs=xs_ring, R_cp=R2_cp, ### Revise 2022.11.25 w_bus=w2_bus,bend_DC=True, w_wg=w_wg, dAc=A2_cp, euler_anti_bend=Euler_trasition,euler_transistion=Euler_trasition, R_max_trans=R2_att,dA_trans=A2_att,dL_trans=0, w_trans=w2_bus, R_max_anti=R2_att,R_min_anti=R2_att_min,sharp_patch=sharp_patch, show_pins=False, dL_p2p=dL_p2p, wg_Ltp=Ltp_bus, ) bus_cell = [BUS_U.cell,BUS_D.cell] bus_w = [BUS_U.w,BUS_D.w] bus_sz = [BUS_U.sz,BUS_D.sz] gap_cp = [gap1,gap2] super().__init__(ring=ring_cell, bus=bus_cell, w_bus=bus_w, w_ring=ring_w, sz_ring=ring_sz, sz_bus=bus_sz, gap_crows=gap_crows, gap_cp=gap_cp, w_heater=w_heater, xs_heater=xs_heater, connected=connected, w_metal=w_metal, xs_metal=xs_metal, via_h2m=via_h2m, isl=isl, ISL_LEFT=ISL_LEFT, ISL_RIGHT=ISL_RIGHT, show_pins=show_pins, ht_shift=ht_shift, A_ht=A_ht) """ CROW with standard identical ring """ class CROW_STD_Allpass(CROW_Circular_ring): """ CROW STD Allpass primitive component. This component builds the CROW STD Allpass layout cell. Parameters ---------- r_ring : float, optional Radius parameter in microns. Default is 10. w_ring : float, optional Width parameter in microns. Default is 0.45. xs_ring : str, optional Layer or cross-section name used by the device. Default is 'strip'. w_bus : float, optional Width parameter in microns. Default is 0.45. A_cp : int, optional Angle parameter in degrees. Default is 10. gap_bus : float, optional Spacing or gap parameter in microns. Default is 0.45. w_wg : float, optional Width parameter in microns. Default is 0.45. Euler_trasition : bool, optional Value for the Euler_trasition parameter. Default is True. R_att : float, optional Radius parameter in microns. Default is 10. R_att_min : float, optional Radius parameter in microns. Default is 5. A_att : int, optional Angle parameter in degrees. Default is 45. gap_crows : float or list, optional Spacing or gap parameter in microns. Default is [0.4]. w_heater : float or list, optional Width parameter in microns. Default is 0. xs_heater : str, optional Layer or cross-section name used by the device. Default is 'heater'. connected : bool, optional Value for the connected parameter. Default is True. w_metal : float, optional Width parameter in microns. Default is 8. xs_metal : str, optional Layer or cross-section name used by the device. Default is 'metal'. via_h2m : Any, optional Via definition used between heater and metal layers. Default is None. isl : Any, optional Isolation-trench definition used by the electrical layout. Default is None. show_pins : bool, optional Whether to draw pin markers in the generated layout. Default is False. sharp_patch : bool, optional Whether to add geometry patches for sharp corners or cladding continuity. Default is True. dL_p2p : Optional[float], optional Value for the dL_p2p parameter. Default is None. Ltp_bus : int, optional Length parameter in microns. Default is 0. ht_shift : int, optional Value for the ht_shift parameter. Default is 0. A_ht : int, optional Angle parameter in degrees. Default is 45. """ def __init__(self, r_ring: float=10, w_ring: float = 0.45, xs_ring: str='strip', w_bus: float=0.45, A_cp: int=10, gap_bus: float=0.45, w_wg: float=0.45, Euler_trasition: bool=True, R_att: float = 10, R_att_min: float = 5, A_att: int=45, gap_crows: 'float|list' = [0.4], w_heater: 'float|list' = 0, xs_heater: 'str' = 'heater', connected: 'bool' = True, w_metal: 'float' = 8, xs_metal: 'str' = 'metal', via_h2m: Any=None, isl: Any=None, show_pins: 'bool' = False, sharp_patch: bool=True, dL_p2p: Optional[float]=None, Ltp_bus: int=0, ht_shift: int=0, A_ht: int=45) -> None: super().__init__(r_ring=r_ring, w_ring=w_ring, xs_ring=xs_ring, w1_bus=w_bus, A1_cp=A_cp, w2_bus=0, A2_cp=0, gap1=gap_bus, gap2=gap_bus, w_wg=w_wg, Euler_trasition=Euler_trasition, R1_cp=None, R2_cp=None, R1_att=R_att, R2_att=R_att, R1_att_min=R_att_min, R2_att_min=R_att_min, A1_att=A_att, A2_att=A_att, gap_crows=gap_crows, w_heater=w_heater, xs_heater=xs_heater, connected=connected, w_metal=w_metal, xs_metal=xs_metal, via_h2m=via_h2m, isl=isl, ISL_LEFT=True, ISL_RIGHT=True, show_pins=show_pins, sharp_patch=sharp_patch, dL_p2p=dL_p2p, Ltp_bus=Ltp_bus, ht_shift=ht_shift, A_ht=A_ht) class CROW_STD_Adddrop(CROW_Circular_ring): """ CROW STD Adddrop primitive component. This component builds the CROW STD Adddrop layout cell. Parameters ---------- r_ring : float, optional Radius parameter in microns. Default is 10. w_ring : float, optional Width parameter in microns. Default is 0.45. xs_ring : str, optional Layer or cross-section name used by the device. Default is 'strip'. w_bus : float, optional Width parameter in microns. Default is 0.45. A_cp : int, optional Angle parameter in degrees. Default is 10. gap_bus : float, optional Spacing or gap parameter in microns. Default is 0.45. w_wg : float, optional Width parameter in microns. Default is 0.45. Euler_trasition : bool, optional Value for the Euler_trasition parameter. Default is True. R_att : float, optional Radius parameter in microns. Default is 10. R_att_min : float, optional Radius parameter in microns. Default is 5. A_att : int, optional Angle parameter in degrees. Default is 45. gap_crows : float or list, optional Spacing or gap parameter in microns. Default is [0.4]. w_heater : float or list, optional Width parameter in microns. Default is 0. xs_heater : str, optional Layer or cross-section name used by the device. Default is 'heater'. connected : bool, optional Value for the connected parameter. Default is True. w_metal : float, optional Width parameter in microns. Default is 8. xs_metal : str, optional Layer or cross-section name used by the device. Default is 'metal'. via_h2m : Any, optional Via definition used between heater and metal layers. Default is None. isl : Any, optional Isolation-trench definition used by the electrical layout. Default is None. show_pins : bool, optional Whether to draw pin markers in the generated layout. Default is False. sharp_patch : bool, optional Whether to add geometry patches for sharp corners or cladding continuity. Default is True. dL_p2p : Optional[float], optional Value for the dL_p2p parameter. Default is None. Ltp_bus : int, optional Length parameter in microns. Default is 0. ht_shift : int, optional Value for the ht_shift parameter. Default is 0. A_ht : int, optional Angle parameter in degrees. Default is 45. """ def __init__(self, r_ring: float=10, w_ring: float = 0.45, xs_ring: str='strip', w_bus: float=0.45, A_cp: int=10, gap_bus: float=0.45, w_wg: float=0.45, Euler_trasition: bool=True, R_att: float = 10, R_att_min: float = 5, A_att: int=45, gap_crows: 'float|list' = [0.4], w_heater: 'float|list' = 0, xs_heater: 'str' = 'heater', connected: 'bool' = True, w_metal: 'float' = 8, xs_metal: 'str' = 'metal', via_h2m: Any=None, isl: Any=None, show_pins: 'bool' = False, sharp_patch: bool=True, dL_p2p: Optional[float]=None, Ltp_bus: int=0, ht_shift: int=0, A_ht: int=45) -> None: super().__init__(r_ring=r_ring, w_ring=w_ring, xs_ring=xs_ring, w1_bus=w_bus, A1_cp=A_cp, w2_bus=w_bus, A2_cp=A_cp, gap1=gap_bus, gap2=gap_bus, w_wg=w_wg, Euler_trasition=Euler_trasition, R1_cp=None, R2_cp=None, R1_att=R_att, R2_att=R_att, R1_att_min=R_att_min, R2_att_min=R_att_min, A1_att=A_att, A2_att=A_att, gap_crows=gap_crows, w_heater=w_heater, xs_heater=xs_heater, connected=connected, w_metal=w_metal, xs_metal=xs_metal, via_h2m=via_h2m, isl=isl, ISL_LEFT=True, ISL_RIGHT=True, show_pins=show_pins, sharp_patch=sharp_patch, dL_p2p=dL_p2p, Ltp_bus=Ltp_bus, ht_shift=ht_shift, A_ht=A_ht) """ Adiabatic Elipse Diameter """ class CROW_AED(STD_CROW_V): """ CROW AED primitive component. This component builds the CROW AED layout cell. Parameters ---------- r_outer : float, optional Radius parameter in microns. Default is 10. wa : float, optional Width parameter in microns. Default is 0.45. wb : float, optional Width parameter in microns. Default is 0.45. xs_ring : str, optional Layer or cross-section name used by the device. Default is 'strip'. w1_bus : float, optional Value for the w1_bus parameter. Default is 0.45. A1_cp : int, optional Angle parameter in degrees. Default is 10. w2_bus : float, optional Value for the w2_bus parameter. Default is 0.45. A2_cp : int, optional Angle parameter in degrees. Default is 10. gap1 : float, optional Spacing or gap parameter in microns. Default is 0.45. gap2 : float, optional Spacing or gap parameter in microns. Default is 0.45. w_wg : float, optional Width parameter in microns. Default is 0.45. Euler_trasition : bool, optional Value for the Euler_trasition parameter. Default is True. R1_cp : float, optional Radius parameter in microns. Default is None. R2_cp : float, optional Radius parameter in microns. Default is None. R1_att : float, optional Radius parameter in microns. Default is 15. R2_att : float, optional Radius parameter in microns. Default is 15. R1_att_min : float, optional Radius parameter in microns. Default is 5. R2_att_min : float, optional Radius parameter in microns. Default is 5. L_tilt : int, optional Length parameter in microns. Default is 0. A1_att : int, optional Angle parameter in degrees. Default is 45. A2_att : int, optional Angle parameter in degrees. Default is 45. Ltp_bus : int, optional Length parameter in microns. Default is 0. dL_p2p : Optional[float], optional Value for the dL_p2p parameter. Default is None. gap_crows : float or list, optional Spacing or gap parameter in microns. Default is [0.4]. gap_cp : float or list, optional Spacing or gap parameter in microns. Default is [0.45, 0.45]. w_heater : float or list, optional Width parameter in microns. Default is 0. xs_heater : str, optional Layer or cross-section name used by the device. Default is 'heater'. connected : bool, optional Value for the connected parameter. Default is True. w_metal : float, optional Width parameter in microns. Default is 8. xs_metal : str, optional Layer or cross-section name used by the device. Default is 'metal'. via_h2m : Any, optional Via definition used between heater and metal layers. Default is None. isl : Any, optional Isolation-trench definition used by the electrical layout. Default is None. ISL_LEFT : bool, optional Value for the ISL_LEFT parameter. Default is True. ISL_RIGHT : bool, optional Value for the ISL_RIGHT parameter. Default is True. show_pins : bool, optional Whether to draw pin markers in the generated layout. Default is False. sharp_patch : bool, optional Whether to add geometry patches for sharp corners or cladding continuity. Default is True. ht_shift : int, optional Value for the ht_shift parameter. Default is 0. A_ht : int, optional Angle parameter in degrees. Default is 45. """ def __init__(self, r_outer: float = 10, wa: float = 0.45, wb: float = 0.45, xs_ring: str='strip', w1_bus: float = 0.45,A1_cp: int = 10, w2_bus: float = 0.45,A2_cp: int = 10, gap1: float = 0.45, gap2: float = 0.45, w_wg: float = 0.45, Euler_trasition: bool=True, R1_cp:float = None, R2_cp:float = None, R1_att:float = 15, R2_att:float = 15, R1_att_min:float = 5, R2_att_min:float = 5, L_tilt: int = 0, A1_att: int = 45, A2_att: int = 45, Ltp_bus: int = 0, dL_p2p: Optional[float]=None, gap_crows: 'float|list' = [0.4], gap_cp: 'float|list' = [0.45, 0.45], w_heater: 'float|list' = 0, xs_heater: 'str' = 'heater', connected: 'bool' = True, w_metal: 'float' = 8, xs_metal: 'str' = 'metal', via_h2m: Any = None, isl: Any = None, ISL_LEFT: 'bool' = True, ISL_RIGHT: 'bool' = True, show_pins: 'bool' = False, sharp_patch: bool=True, ht_shift: int = 0, A_ht: int=45) -> None: ## defining ring list if (isinstance(r_outer,int) or isinstance(r_outer,float)): ring = Elipse_dual(ORx=r_outer,ORy=r_outer,IRx=r_outer-wa,IRy=r_outer-wb, # n_points=128, xs=xs_ring) ring_cell = ring.cell ring_sz = ring.sz ring_w = ring.wb r_outer = [r_outer] wa = [wa] wb = [wb] elif (isinstance(r_outer,list) or isinstance(r_outer,np.ndarray)): if (len(r_outer)!=len(wa)): raise Exception("ERROR: In , does not match ") ring_cell = [] ring_sz = [] ring_w = [] for _idx_ in range(0,len(r_outer)): _ring_ = Elipse_dual(ORx=r_outer[_idx_],ORy=r_outer[_idx_],IRx=r_outer[_idx_]-wa[_idx_],IRy=r_outer[_idx_]-wb[_idx_], # n_points=128, xs=xs_ring) ring_cell.append(_ring_.cell) ring_sz.append(_ring_.sz) ring_w.append(_ring_.wb) ## expand to N*2 dimension list, [[sz0,sz1],[sz0,sz1]] # ring_sz = [ring_sz,ring_sz] # ring_w = [ring_w,ring_w] else : raise Exception("ERROR: In , is not recongized, please input type ") if (w1_bus<=0): raise Exception("ERROR: In , should larger than 0") R1_cp = w1_bus/2 + r_outer[0] + wb[0]/2 + gap1 ### generating coupling BUS waveguide BUS_U = ring_bus_wg(xs=xs_ring, R_cp=R1_cp, w_bus=w1_bus,bend_DC=True, w_wg=w_wg, dAc=A1_cp, euler_anti_bend=Euler_trasition,euler_transistion=Euler_trasition, R_max_trans=R1_att,dA_trans=A1_att,dL_trans=L_tilt, w_trans=w1_bus, R_max_anti=R1_att,R_min_anti=R1_att_min,sharp_patch=sharp_patch,show_pins=show_pins, dL_p2p=dL_p2p, wg_Ltp=Ltp_bus, ) bus_cell = [BUS_U.cell] bus_w = BUS_U.w bus_sz = BUS_U.sz if (w2_bus>0): R2_cp = w2_bus/2 + r_outer[-1] + wb[-1]/2 + gap2 BUS_D = ring_bus_wg(xs=xs_ring, R_cp=R2_cp, w_bus=w2_bus,bend_DC=True, w_wg=w_wg, dAc=A2_cp, euler_anti_bend=Euler_trasition,euler_transistion=Euler_trasition, R_max_trans=R2_att,dA_trans=A2_att,dL_trans=L_tilt, w_trans=w2_bus, R_max_anti=R2_att,R_min_anti=R2_att_min,sharp_patch=sharp_patch,show_pins=show_pins, dL_p2p=dL_p2p, wg_Ltp=Ltp_bus,) bus_cell = [BUS_U.cell,BUS_D.cell] bus_w = [BUS_U.w,BUS_D.w] bus_sz = [BUS_U.sz,BUS_D.sz] super().__init__(ring=ring_cell, bus=bus_cell, w_bus=bus_w, w_ring=ring_w, sz_ring=ring_sz, sz_bus=bus_sz, gap_crows=gap_crows, gap_cp=gap_cp, w_heater=w_heater, xs_heater=xs_heater, connected=connected, w_metal=w_metal, xs_metal=xs_metal, via_h2m=via_h2m, isl=isl, ISL_LEFT=ISL_LEFT, ISL_RIGHT=ISL_RIGHT, show_pins=show_pins, ht_shift=ht_shift, A_ht=A_ht)