optical pins name revised. Pin type added

This commit is contained in:
=
2026-06-07 22:56:33 +08:00
parent a4ac88f002
commit 8462c3397f
262 changed files with 3251 additions and 1134 deletions
+209 -8
View File
@@ -241,8 +241,12 @@ class Taper() :
linear_taper = strip.taper(
length=self.length,width1=self.width1,width2=self.width2,patch=True).put(0,0,0)
output_strt = strip.strt(length=0.5,width=self.width2).put()
nd.Pin(name="a1",width=self.width1).put(linear_taper.pin['a0'])
nd.Pin(name="b1",width=self.width2).put(output_strt.pin['b0'])
## revised in 2026.06.07 by Qin Yue
# legacy: nd.Pin(name="a1",width=self.width1).put(linear_taper.pin['a0'])
nd.Pin(name="opt_a1",width=self.width1,type="optical:").put(linear_taper.pin['a0'])
## revised in 2026.06.07 by Qin Yue
# legacy: nd.Pin(name="b1",width=self.width2).put(output_strt.pin['b0'])
nd.Pin(name="opt_b1",width=self.width2,type="optical:").put(output_strt.pin['b0'])
else :
c2 = self.width1/2
c1 = (c2 - self.width2/2) / np.power(self.length, self.order)
@@ -273,8 +277,12 @@ class Taper() :
nd.strt(length=0.5, width=self.width2, xs='strip').put(self.length,0,0)
nd.Pin(name='a1',width=self.width1).put(0,0,180)
nd.Pin(name="b1",width=self.width2).put(self.length+0.5,0,0)
## revised in 2026.06.07 by Qin Yue
# legacy: nd.Pin(name='a1',width=self.width1).put(0,0,180)
nd.Pin(name='opt_a1',width=self.width1,type="optical:").put(0,0,180)
## revised in 2026.06.07 by Qin Yue
# legacy: nd.Pin(name="b1",width=self.width2).put(self.length+0.5,0,0)
nd.Pin(name="opt_b1",width=self.width2,type="optical:").put(self.length+0.5,0,0)
if self.show_pins :
nd.put_stub()
return ic
@@ -366,8 +374,12 @@ class Grating_2D_Hole() :
)
'''Generate the taper output.'''
taper = Taper(width1=self.w_gt, width2=self.w_wg, length=self.l_taper, type=self.type_taper)
taper_horizontal = taper.cell.put('a1', self.w_gt/2,0,0)
taper_vertical = taper.cell.put('a1',0,self.w_gt/2,90)
## revised in 2026.06.07 by Qin Yue
# legacy: taper_horizontal = taper.cell.put('a1', self.w_gt/2,0,0)
taper_horizontal = taper.cell.put('opt_a1', self.w_gt/2,0,0)
## revised in 2026.06.07 by Qin Yue
# legacy: taper_vertical = taper.cell.put('a1',0,self.w_gt/2,90)
taper_vertical = taper.cell.put('opt_a1',0,self.w_gt/2,90)
'''Generate the diffraction etched region.'''
theta_list = np.linspace(0, 2*np.pi, 32)
gt_ring_poly = [
@@ -383,8 +395,12 @@ class Grating_2D_Hole() :
polygon=polysi_ring_poly, vector=self.polysi_vector, layer=self.polysi_layer
).put(self.w_gt/2, self.w_gt/2)
'''Put the pin location'''
nd.Pin(name='g1').put(taper_horizontal.pin['b1'])
nd.Pin(name='g2').put(taper_vertical.pin['b1'])
## revised in 2026.06.07 by Qin Yue
# legacy: nd.Pin(name='g1').put(taper_horizontal.pin['b1'])
nd.Pin(name='g1').put(taper_horizontal.pin['opt_b1'])
## revised in 2026.06.07 by Qin Yue
# legacy: nd.Pin(name='g2').put(taper_vertical.pin['b1'])
nd.Pin(name='g2').put(taper_vertical.pin['opt_b1'])
# nd.put_stub()
return ic
@@ -1257,6 +1273,191 @@ class GC_STD_1D:
nd.strt(xs=self.xs_wg,width=self.w_wg,length=dX_gc2gc).put(-dX_gc2gc/2,0,0)
return C
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
class FA:
"""
FA primitive component.