193 lines
7.6 KiB
Python
193 lines
7.6 KiB
Python
import nazca as nd
|
|
import numpy as np
|
|
import math
|
|
import pandas as pd
|
|
|
|
from ...routing import Route
|
|
from ..geometry import _my_polygon,circle,Clothoid,hole
|
|
from ...basic import __cell_arg__
|
|
|
|
|
|
class GC_SiN_Si_Dual_Layer:
|
|
"""
|
|
GC SiN Si Dual Layer primitive component.
|
|
|
|
This component builds the GC SiN Si Dual Layer layout cell.
|
|
|
|
Parameters
|
|
----------
|
|
name : str, optional
|
|
Unique identifier for the device cell. Default is None.
|
|
w_teeth_SiN : list or float, optional
|
|
Width parameter in microns. Default is 0.5.
|
|
gap_teeth_SiN : list or float, optional
|
|
Spacing or gap parameter in microns. Default is 0.5.
|
|
w_teeth_Si : list or float, optional
|
|
Width parameter in microns. Default is 0.5.
|
|
gap_teeth_Si : list or float, optional
|
|
Spacing or gap parameter in microns. Default is 0.5.
|
|
ori_teeth_offset : float, optional
|
|
Value for the ori_teeth_offset parameter. Default is 5.0.
|
|
n_teeth_Si : float, optional
|
|
Value for the n_teeth_Si parameter. Default is 30.
|
|
n_teeth_SiN : float, optional
|
|
Value for the n_teeth_SiN parameter. Default is 30.
|
|
A_gc_taper : float, optional
|
|
Angle parameter in degrees. Default is 25.0.
|
|
R_teeth_ori_SiN : float, optional
|
|
Radius parameter in microns. Default is 40.0.
|
|
R_teeth_ori_Si : float, optional
|
|
Radius parameter in microns. Default is 40.0.
|
|
L_end_Si : float, optional
|
|
Length parameter in microns. Default is 0.2.
|
|
L_end_SiN : float, optional
|
|
Length parameter in microns. Default is 5.0.
|
|
w_port : float, optional
|
|
Width parameter in microns. Default is 0.9.
|
|
A_anti_rfl : float, optional
|
|
Angle parameter in degrees. Default is 4.0.
|
|
layer_SiN_slab : str, optional
|
|
Layer or cross-section name used by the device. Default is None.
|
|
layer_Si_slab : str, optional
|
|
Layer or cross-section name used by the device. Default is None.
|
|
layer_Si_teeth : str, optional
|
|
Layer or cross-section name used by the device. Default is None.
|
|
layer_SiN_teeth : str, optional
|
|
Layer or cross-section name used by the device. Default is None.
|
|
layer_SiN_etch : str, optional
|
|
Layer or cross-section name used by the device. Default is None.
|
|
layer_Si_etch : str, optional
|
|
Layer or cross-section name used by the device. Default is None.
|
|
layer_ox_open : str, optional
|
|
Layer or cross-section name used by the device. Default is None.
|
|
"""
|
|
def __init__(self,
|
|
name:str=None,
|
|
w_teeth_SiN:'list|float' = 0.5,
|
|
gap_teeth_SiN:'list|float' = 0.5,
|
|
w_teeth_Si:'list|float' = 0.5,
|
|
gap_teeth_Si:'list|float' = 0.5,
|
|
ori_teeth_offset:float = 5.0,
|
|
n_teeth_Si:float=30,
|
|
n_teeth_SiN:float=30,
|
|
A_gc_taper:float=25.0,
|
|
R_teeth_ori_SiN:float=40.0,
|
|
R_teeth_ori_Si:float=40.0,
|
|
L_end_Si:float=0.2,
|
|
L_end_SiN:float=5.0,
|
|
|
|
w_port : float = 0.9,
|
|
|
|
A_anti_rfl:float = 4.0,
|
|
layer_SiN_slab:str=None,
|
|
layer_Si_slab:str=None,
|
|
layer_Si_teeth:str=None,
|
|
layer_SiN_teeth:str=None,
|
|
layer_SiN_etch:str=None,
|
|
layer_Si_etch:str=None,
|
|
layer_ox_open:str=None,
|
|
):
|
|
|
|
self.name = name
|
|
self.w_teeth_SiN = w_teeth_SiN
|
|
self.gap_teeth_SiN = gap_teeth_SiN
|
|
self.w_teeth_Si = w_teeth_Si
|
|
self.gap_teeth_Si = gap_teeth_Si
|
|
self.ori_teeth_offset = ori_teeth_offset
|
|
|
|
self.n_teeth_SiN = n_teeth_SiN
|
|
self.n_teeth_Si = n_teeth_Si
|
|
|
|
self.A_gc_taper = A_gc_taper
|
|
|
|
self.w_port = w_port
|
|
|
|
self.L_end_Si = L_end_Si
|
|
self.L_end_SiN = L_end_SiN
|
|
|
|
self.A_anti_rfl = A_anti_rfl
|
|
|
|
self.R_teeth_ori_SiN = R_teeth_ori_SiN
|
|
self.R_teeth_ori_Si = R_teeth_ori_Si
|
|
|
|
self.layer_SiN_slab = layer_SiN_slab
|
|
self.layer_Si_slab = layer_Si_slab
|
|
self.layer_Si_teeth = layer_Si_teeth
|
|
self.layer_SiN_teeth = layer_SiN_teeth
|
|
self.layer_SiN_etch = layer_SiN_etch
|
|
self.layer_Si_etch = layer_Si_etch
|
|
self.layer_ox_open = layer_ox_open
|
|
|
|
self.cell = self.generate_gds()
|
|
|
|
def generate_gds(self):
|
|
""" creating instance cell or not """
|
|
if (self.name is None) : self.instantiate = False
|
|
else : self.instantiate = True
|
|
|
|
""" """
|
|
if (isinstance(self.w_teeth_SiN,list) or isinstance(self.w_teeth_SiN,np.ndarray)):
|
|
n_teeth_SiN = len(self.w_teeth_SiN)
|
|
elif (isinstance(self.w_teeth_SiN,float)):
|
|
n_teeth_SiN = self.n_teeth_SiN
|
|
w_teeth_SiN = [w_teeth_SiN]*n_teeth_SiN
|
|
|
|
""" """
|
|
if (isinstance(self.w_teeth_Si,list) or isinstance(self.w_teeth_Si,np.ndarray)):
|
|
n_teeth_Si = len(self.w_teeth_Si)
|
|
elif (isinstance(self.w_teeth_Si,float)):
|
|
n_teeth_Si = self.n_teeth_Si
|
|
w_teeth_Si = [w_teeth_Si]*n_teeth_Si
|
|
|
|
with nd.Cell(instantiate=self.instantiate, name=self.name) as C:
|
|
|
|
""" Creating SiN layer grating """
|
|
## whole area where the grating area covered
|
|
L_gc = self.R_teeth_ori_SiN + self.L_end_SiN + sum(self.w_teeth_SiN) + sum(self.gap_teeth_SiN)
|
|
|
|
w_box_gc = L_gc*np.sin(self.A_gc_taper/2*np.pi/180)*2
|
|
L_box_gc = L_gc*np.cos(self.A_gc_taper/2*np.pi/180)
|
|
x_slab = [0,L_box_gc,L_gc+w_box_gc*np.sin(self.A_anti_rfl*np.pi/180),L_gc,L_box_gc,0]
|
|
y_slab = [self.w_port/2,w_box_gc/2,w_box_gc/2,-w_box_gc/2,-w_box_gc/2,-self.w_port/2]
|
|
|
|
_my_polygon(layer_wg=self.layer_SiN_slab,vtx=np.c_[x_slab,y_slab]).put(0,0,0)
|
|
|
|
# circle(radius=self.R_teeth_ori_SiN/2,angle=self.A_gc_taper,layer=self.layer_SiN_slab,
|
|
# width=self.R_teeth_ori_SiN).cell.put(0,0,-self.A_gc_taper/2)
|
|
|
|
A_etch_ext = 4
|
|
## Placing teeth
|
|
r_in = self.R_teeth_ori_SiN
|
|
for idxT in range(0,n_teeth_SiN):
|
|
r_out = r_in + self.gap_teeth_SiN[idxT]
|
|
|
|
circle(radius=(r_out+r_in)/2,angle=self.A_gc_taper+A_etch_ext,layer=self.layer_SiN_etch,
|
|
width=self.gap_teeth_Si[idxT]).cell.put(0,0,-self.A_gc_taper/2-A_etch_ext/2)
|
|
|
|
r_in = r_out + self.w_teeth_SiN[idxT]
|
|
|
|
""" Creating Si layer grating """
|
|
|
|
w_Si_slab = sum(self.w_teeth_Si)+sum(self.gap_teeth_Si)
|
|
R_Si_slab = self.R_teeth_ori_Si+w_Si_slab/2
|
|
circle(radius=R_Si_slab,angle=self.A_gc_taper,layer=self.layer_Si_slab,
|
|
width=w_Si_slab).cell.put(0,0,-self.A_gc_taper/2)
|
|
|
|
## Placing teeth
|
|
r_in = self.R_teeth_ori_Si
|
|
for idxT in range(0,n_teeth_Si):
|
|
r_out = r_in + self.gap_teeth_Si[idxT]
|
|
|
|
if (self.layer_Si_etch is not None):
|
|
circle(radius=(r_out+r_in)/2,angle=self.A_gc_taper+A_etch_ext,layer=self.layer_Si_etch,
|
|
width=self.gap_teeth_Si[idxT]).cell.put(0,0,-self.A_gc_taper/2-A_etch_ext/2)
|
|
elif (self.layer_Si_teeth is not None):
|
|
circle(radius=r_out+(self.w_teeth_Si[idxT])/2,angle=self.A_gc_taper,layer=self.layer_Si_teeth,
|
|
width=self.w_teeth_Si[idxT]).cell.put(0,0,-self.A_gc_taper/2)
|
|
|
|
r_in = r_out + self.w_teeth_Si[idxT]
|
|
|
|
return C
|
|
|
|
|