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
+15 -5
View File
@@ -50,10 +50,16 @@ class LoopMirror():
if (BS==None):
BS = DC(w_cp=0.45,gap=0.2,w_wg=w_wg,L_cp=10,R0=10,angle=20,xs=xs_wg,sharp_patch=True)
BS_Inst = BS.cell.put(0,0,0) ## middle
D_port = np.abs(BS_Inst.pin['b1'].y - BS_Inst.pin['b2'].y)
## revised in 2026.06.07 by Qin Yue
# legacy: D_port = np.abs(BS_Inst.pin['b1'].y - BS_Inst.pin['b2'].y)
D_port = np.abs(BS_Inst.pin['opt_b1'].y - BS_Inst.pin['opt_b2'].y)
pic = Route(radius=Radius,width=w_wg,xs=xs_wg)
BU = nd.bend(radius=Radius,width=w_wg,xs=xs_wg,angle=angle).put('a0',BS_Inst.pin['b1'],flip=0)
BD = nd.bend(radius=Radius,width=w_wg,xs=xs_wg,angle=angle).put('a0',BS_Inst.pin['b2'],flip=1)
## revised in 2026.06.07 by Qin Yue
# legacy: BU = nd.bend(radius=Radius,width=w_wg,xs=xs_wg,angle=angle).put('a0',BS_Inst.pin['b1'],flip=0)
BU = nd.bend(radius=Radius,width=w_wg,xs=xs_wg,angle=angle).put('a0',BS_Inst.pin['opt_b1'],flip=0)
## revised in 2026.06.07 by Qin Yue
# legacy: BD = nd.bend(radius=Radius,width=w_wg,xs=xs_wg,angle=angle).put('a0',BS_Inst.pin['b2'],flip=1)
BD = nd.bend(radius=Radius,width=w_wg,xs=xs_wg,angle=angle).put('a0',BS_Inst.pin['opt_b2'],flip=1)
R_loop = (Radius+D_port/2)/np.cos(angle/180*np.pi) - Radius
@@ -64,8 +70,12 @@ class LoopMirror():
(a1,b1), (a2,b2),c1,c2 = growx
if (layers.find('CLD')!=-1):
### middle patch
nd.strt(length=(R_loop+w_wg*a1+b1)*(1+np.sin((180-angle)/180*np.pi))+(Radius)*np.sin(angle/180*np.pi),width=2*(R_loop+w_wg*a1+b1),layer=layers).put(BS_Inst.pin['b1'].x,0,0)
## revised in 2026.06.07 by Qin Yue
# legacy: nd.strt(length=(R_loop+w_wg*a1+b1)*(1+np.sin((180-angle)/180*np.pi))+(Radius)*np.sin(angle/180*np.pi),width=2*(R_loop+w_wg*a1+b1),layer=layers).put(BS_Inst.pin['b1'].x,0,0)
nd.strt(length=(R_loop+w_wg*a1+b1)*(1+np.sin((180-angle)/180*np.pi))+(Radius)*np.sin(angle/180*np.pi),width=2*(R_loop+w_wg*a1+b1),layer=layers).put(BS_Inst.pin['opt_b1'].x,0,0)
nd.Pin(name='a1',pin=BS_Inst.pin['a1']).put()
## revised in 2026.06.07 by Qin Yue
# legacy: nd.Pin(name='a1',pin=BS_Inst.pin['a1']).put()
nd.Pin(name='opt_a1',pin=BS_Inst.pin['opt_a1'],type="optical:").put()
self.cell = C
+528 -176
View File
@@ -179,12 +179,20 @@ class MZI:
cell_BS = __BS_generate__(BS=BS,xs=xs_wg,func_name="mxpic::functional::MZI")
cell_BS2 = __BS_generate__(BS=BS2,xs=xs_wg,func_name="mxpic::functional::MZI")
dY1 = np.abs(cell_BS.pin['b1'].y - cell_BS.pin['b2'].y)
dY2 = np.abs(cell_BS2.pin['b1'].y - cell_BS2.pin['b2'].y)
## revised in 2026.06.07 by Qin Yue
# legacy: dY1 = np.abs(cell_BS.pin['b1'].y - cell_BS.pin['b2'].y)
dY1 = np.abs(cell_BS.pin['opt_b1'].y - cell_BS.pin['opt_b2'].y)
## revised in 2026.06.07 by Qin Yue
# legacy: dY2 = np.abs(cell_BS2.pin['b1'].y - cell_BS2.pin['b2'].y)
dY2 = np.abs(cell_BS2.pin['opt_b1'].y - cell_BS2.pin['opt_b2'].y)
# dX = np.abs(cell_BS.pin['a1'].x - cell_BS.pin['b1'].x)
BS1 = cell_BS.put('b1',-L_arm/2-R_bend*2-2.5,dY1/2,180)
BS2 = cell_BS2.put('b2', L_arm/2+R_bend*2+2.5,dY2/2,0,flip=0)
## revised in 2026.06.07 by Qin Yue
# legacy: BS1 = cell_BS.put('b1',-L_arm/2-R_bend*2-2.5,dY1/2,180)
BS1 = cell_BS.put('opt_b1',-L_arm/2-R_bend*2-2.5,dY1/2,180)
## revised in 2026.06.07 by Qin Yue
# legacy: BS2 = cell_BS2.put('b2', L_arm/2+R_bend*2+2.5,dY2/2,0,flip=0)
BS2 = cell_BS2.put('opt_b2', L_arm/2+R_bend*2+2.5,dY2/2,0,flip=0)
pic = Route(width=w_wg,radius=R_bend,xs=xs_wg,adapt_width=True,adapt_xs=True)
@@ -197,53 +205,93 @@ class MZI:
# print("DEBUG - A")
if ('a2' in pin_in_name):
## revised in 2026.06.07 by Qin Yue
# legacy: if ('a2' in pin_in_name):
if ('opt_a2' in pin_in_name):
if (D_port==None):
nd.Pin(name='a2',pin=BS1.pin['a2']).put()
nd.strt(length=0.005,width=BS1.pin['a2'].width,xs=self.xs_wg).put(BS1.pin['a2'])
nd.Pin(name='a1',pin=BS1.pin['a1']).put()
nd.strt(length=0.005,width=BS1.pin['a2'].width,xs=self.xs_wg).put(BS1.pin['a1'])
## revised in 2026.06.07 by Qin Yue
# legacy: nd.Pin(name='a2',pin=BS1.pin['a2']).put()
nd.Pin(name='opt_a2',pin=BS1.pin['opt_a2'],type="optical:").put()
## revised in 2026.06.07 by Qin Yue
# legacy: nd.strt(length=0.005,width=BS1.pin['a2'].width,xs=self.xs_wg).put(BS1.pin['a2'])
nd.strt(length=0.005,width=BS1.pin['opt_a2'].width,xs=self.xs_wg).put(BS1.pin['opt_a2'])
## revised in 2026.06.07 by Qin Yue
# legacy: nd.Pin(name='a1',pin=BS1.pin['a1']).put()
nd.Pin(name='opt_a1',pin=BS1.pin['opt_a1'],type="optical:").put()
## revised in 2026.06.07 by Qin Yue
# legacy: nd.strt(length=0.005,width=BS1.pin['a2'].width,xs=self.xs_wg).put(BS1.pin['a1'])
nd.strt(length=0.005,width=BS1.pin['opt_a2'].width,xs=self.xs_wg).put(BS1.pin['opt_a1'])
elif(isinstance(D_port,int) or isinstance(D_port,float)):
temp = pic.sbend_route(radius=R_bend,width=w_wg,pin=BS1.pin['a1'],length1=L_patch/4,length2=L_patch/4,offset=abs(D_port/2-abs(BS1.pin['a1'].y)),
## revised in 2026.06.07 by Qin Yue
# legacy: temp = pic.sbend_route(radius=R_bend,width=w_wg,pin=BS1.pin['a1'],length1=L_patch/4,length2=L_patch/4,offset=abs(D_port/2-abs(BS1.pin['a1'].y)),
temp = pic.sbend_route(radius=R_bend,width=w_wg,pin=BS1.pin['opt_a1'],length1=L_patch/4,length2=L_patch/4,offset=abs(D_port/2-abs(BS1.pin['opt_a1'].y)),
original_function=not sharp_patch).put(flip=1)
nd.Pin(name='a1',pin=temp.pin['b0'].move(-0.05,0,0)).put()
## revised in 2026.06.07 by Qin Yue
# legacy: nd.Pin(name='a1',pin=temp.pin['b0'].move(-0.05,0,0)).put()
nd.Pin(name='opt_a1',pin=temp.pin['b0'].move(-0.05,0,0),type="optical:").put()
temp = pic.sbend_route(radius=R_bend,width=w_wg,pin=BS1.pin['a2'],length1=L_patch/4,length2=L_patch/4,offset=abs(D_port/2-abs(BS1.pin['a2'].y)),
## revised in 2026.06.07 by Qin Yue
# legacy: temp = pic.sbend_route(radius=R_bend,width=w_wg,pin=BS1.pin['a2'],length1=L_patch/4,length2=L_patch/4,offset=abs(D_port/2-abs(BS1.pin['a2'].y)),
temp = pic.sbend_route(radius=R_bend,width=w_wg,pin=BS1.pin['opt_a2'],length1=L_patch/4,length2=L_patch/4,offset=abs(D_port/2-abs(BS1.pin['opt_a2'].y)),
original_function=not sharp_patch).put(flip=0)
nd.Pin(name='a2',pin=temp.pin['b0'].move(-0.05,0,0)).put()
## revised in 2026.06.07 by Qin Yue
# legacy: nd.Pin(name='a2',pin=temp.pin['b0'].move(-0.05,0,0)).put()
nd.Pin(name='opt_a2',pin=temp.pin['b0'].move(-0.05,0,0),type="optical:").put()
else:
raise Exception("ERROR:: In <mxpic::functionalll::MZI>, <D_port> type error")
else :
nd.Pin(name='a1',pin=BS1.pin['a1']).put()
## revised in 2026.06.07 by Qin Yue
# legacy: nd.Pin(name='a1',pin=BS1.pin['a1']).put()
nd.Pin(name='opt_a1',pin=BS1.pin['opt_a1'],type="optical:").put()
pin_out_name = []
for str,Pin in cell_BS2.ic_pins():
pin_out_name = pin_out_name+[str]
if ('a2' in pin_out_name):
## revised in 2026.06.07 by Qin Yue
# legacy: if ('a2' in pin_out_name):
if ('opt_a2' in pin_out_name):
if (D_port==None):
nd.Pin(name='b2',pin=BS2.pin['a1']).put()
nd.strt(length=0.005,width=BS2.pin['a2'].width,xs=self.xs_wg).put(BS2.pin['a2'])
nd.Pin(name='b1',pin=BS2.pin['a2']).put()
nd.strt(length=0.005,width=BS2.pin['a2'].width,xs=self.xs_wg).put(BS2.pin['a1'])
## revised in 2026.06.07 by Qin Yue
# legacy: nd.Pin(name='b2',pin=BS2.pin['a1']).put()
nd.Pin(name='opt_b2',pin=BS2.pin['opt_a1'],type="optical:").put()
## revised in 2026.06.07 by Qin Yue
# legacy: nd.strt(length=0.005,width=BS2.pin['a2'].width,xs=self.xs_wg).put(BS2.pin['a2'])
nd.strt(length=0.005,width=BS2.pin['opt_a2'].width,xs=self.xs_wg).put(BS2.pin['opt_a2'])
## revised in 2026.06.07 by Qin Yue
# legacy: nd.Pin(name='b1',pin=BS2.pin['a2']).put()
nd.Pin(name='opt_b1',pin=BS2.pin['opt_a2'],type="optical:").put()
## revised in 2026.06.07 by Qin Yue
# legacy: nd.strt(length=0.005,width=BS2.pin['a2'].width,xs=self.xs_wg).put(BS2.pin['a1'])
nd.strt(length=0.005,width=BS2.pin['opt_a2'].width,xs=self.xs_wg).put(BS2.pin['opt_a1'])
elif(isinstance(D_port,int) or isinstance(D_port,float)):
temp = pic.sbend_route(radius=R_bend,width=w_wg,pin=BS2.pin['a2'],length1=L_patch/4,length2=L_patch/4,offset=abs(D_port/2-abs(BS2.pin['a1'].y)),
## revised in 2026.06.07 by Qin Yue
# legacy: temp = pic.sbend_route(radius=R_bend,width=w_wg,pin=BS2.pin['a2'],length1=L_patch/4,length2=L_patch/4,offset=abs(D_port/2-abs(BS2.pin['a1'].y)),
temp = pic.sbend_route(radius=R_bend,width=w_wg,pin=BS2.pin['opt_a2'],length1=L_patch/4,length2=L_patch/4,offset=abs(D_port/2-abs(BS2.pin['opt_a1'].y)),
original_function=not sharp_patch).put(flip=0)
nd.Pin(name='b1',pin=temp.pin['b0'].move(-0.05,0,0)).put()
## revised in 2026.06.07 by Qin Yue
# legacy: nd.Pin(name='b1',pin=temp.pin['b0'].move(-0.05,0,0)).put()
nd.Pin(name='opt_b1',pin=temp.pin['b0'].move(-0.05,0,0),type="optical:").put()
temp = pic.sbend_route(radius=R_bend,width=w_wg,pin=BS2.pin['a1'],length1=L_patch/4,length2=L_patch/4,offset=abs(D_port/2-abs(BS2.pin['a2'].y)),
## revised in 2026.06.07 by Qin Yue
# legacy: temp = pic.sbend_route(radius=R_bend,width=w_wg,pin=BS2.pin['a1'],length1=L_patch/4,length2=L_patch/4,offset=abs(D_port/2-abs(BS2.pin['a2'].y)),
temp = pic.sbend_route(radius=R_bend,width=w_wg,pin=BS2.pin['opt_a1'],length1=L_patch/4,length2=L_patch/4,offset=abs(D_port/2-abs(BS2.pin['opt_a2'].y)),
original_function=not sharp_patch).put(flip=1)
nd.Pin(name='b2',pin=temp.pin['b0'].move(-0.05,0,0)).put()
## revised in 2026.06.07 by Qin Yue
# legacy: nd.Pin(name='b2',pin=temp.pin['b0'].move(-0.05,0,0)).put()
nd.Pin(name='opt_b2',pin=temp.pin['b0'].move(-0.05,0,0),type="optical:").put()
else:
raise Exception("ERROR:: In <mxpic::functionalll::MZI>, <D_port> type error")
else :
nd.Pin(name='b1',pin=BS2.pin['a1']).put()
## revised in 2026.06.07 by Qin Yue
# legacy: nd.Pin(name='b1',pin=BS2.pin['a1']).put()
nd.Pin(name='opt_b1',pin=BS2.pin['opt_a1'],type="optical:").put()
@@ -277,10 +325,18 @@ class MZI:
Ltp=self.Ltp
).cell.put(0,-D_arm/2,0)
pic.sbend_p2p(pin1=BS1.pin['b1'],pin2=arm_upper.pin['a1'],arrow=False,original_function=not sharp_patch).put()
pic.sbend_p2p(pin1=BS1.pin['b2'],pin2=arm_down.pin['a1'],arrow=False,original_function=not sharp_patch).put()
pic.sbend_p2p(pin1=BS2.pin['b2'],pin2=arm_upper.pin['b1'],arrow=False,original_function=not sharp_patch).put()
pic.sbend_p2p(pin1=BS2.pin['b1'],pin2=arm_down.pin['b1'],arrow=False,original_function=not sharp_patch).put()
## revised in 2026.06.07 by Qin Yue
# legacy: pic.sbend_p2p(pin1=BS1.pin['b1'],pin2=arm_upper.pin['a1'],arrow=False,original_function=not sharp_patch).put()
pic.sbend_p2p(pin1=BS1.pin['opt_b1'],pin2=arm_upper.pin['opt_a1'],arrow=False,original_function=not sharp_patch).put()
## revised in 2026.06.07 by Qin Yue
# legacy: pic.sbend_p2p(pin1=BS1.pin['b2'],pin2=arm_down.pin['a1'],arrow=False,original_function=not sharp_patch).put()
pic.sbend_p2p(pin1=BS1.pin['opt_b2'],pin2=arm_down.pin['opt_a1'],arrow=False,original_function=not sharp_patch).put()
## revised in 2026.06.07 by Qin Yue
# legacy: pic.sbend_p2p(pin1=BS2.pin['b2'],pin2=arm_upper.pin['b1'],arrow=False,original_function=not sharp_patch).put()
pic.sbend_p2p(pin1=BS2.pin['opt_b2'],pin2=arm_upper.pin['opt_b1'],arrow=False,original_function=not sharp_patch).put()
## revised in 2026.06.07 by Qin Yue
# legacy: pic.sbend_p2p(pin1=BS2.pin['b1'],pin2=arm_down.pin['b1'],arrow=False,original_function=not sharp_patch).put()
pic.sbend_p2p(pin1=BS2.pin['opt_b1'],pin2=arm_down.pin['opt_b1'],arrow=False,original_function=not sharp_patch).put()
for str,Pin in arm_upper.ic_pins():
@@ -296,7 +352,9 @@ class MZI:
nd.put_stub()
self.cell = C
self.L = np.abs(self.cell.pin['a1'].x-self.cell.pin['b1'].x)
## revised in 2026.06.07 by Qin Yue
# legacy: self.L = np.abs(self.cell.pin['a1'].x-self.cell.pin['b1'].x)
self.L = np.abs(self.cell.pin['opt_a1'].x-self.cell.pin['opt_b1'].x)
class MZI_NS:
"""Nested-straight MZI composite with taperable arm widths.
@@ -392,9 +450,13 @@ class MZI_NS:
pic_strip = Route(radius=R_bend,width=w_wg,xs=xs_wg)
_L_ = abs(BS.pin['a1'].x-BS.pin['b1'].x)
## revised in 2026.06.07 by Qin Yue
# legacy: _L_ = abs(BS.pin['a1'].x-BS.pin['b1'].x)
_L_ = abs(BS.pin['opt_a1'].x-BS.pin['opt_b1'].x)
_W_ = abs(BS.pin['b1'].y-BS.pin['b2'].y)
## revised in 2026.06.07 by Qin Yue
# legacy: _W_ = abs(BS.pin['b1'].y-BS.pin['b2'].y)
_W_ = abs(BS.pin['opt_b1'].y-BS.pin['opt_b2'].y)
@@ -403,10 +465,16 @@ class MZI_NS:
via_h2m=via_h2m,
isl=isl,
L_ht=L_ht)
PS_U = PS.cell.put('a1',-PS.L_arm/2,D_arm/2,0)
## revised in 2026.06.07 by Qin Yue
# legacy: PS_U = PS.cell.put('a1',-PS.L_arm/2,D_arm/2,0)
PS_U = PS.cell.put('opt_a1',-PS.L_arm/2,D_arm/2,0)
BS1 = BS.put('b1',-R_bend*2-L_patch-PS.L_arm/2,_W_/2,180)
BS2 = BS.put('b2', R_bend*2+L_patch+PS.L_arm/2,_W_/2,0,flip=0)
## revised in 2026.06.07 by Qin Yue
# legacy: BS1 = BS.put('b1',-R_bend*2-L_patch-PS.L_arm/2,_W_/2,180)
BS1 = BS.put('opt_b1',-R_bend*2-L_patch-PS.L_arm/2,_W_/2,180)
## revised in 2026.06.07 by Qin Yue
# legacy: BS2 = BS.put('b2', R_bend*2+L_patch+PS.L_arm/2,_W_/2,0,flip=0)
BS2 = BS.put('opt_b2', R_bend*2+L_patch+PS.L_arm/2,_W_/2,0,flip=0)
pic = Route(width=w_wg,radius=R_bend,xs=xs_wg,adapt_width=True,adapt_xs=True)
@@ -416,39 +484,73 @@ class MZI_NS:
pin_in_name = pin_in_name+[str]
# pin_in_name.append(str)
if ('a2' in pin_in_name):
## revised in 2026.06.07 by Qin Yue
# legacy: if ('a2' in pin_in_name):
if ('opt_a2' in pin_in_name):
if (D_port==None):
nd.Pin(name='a2',pin=BS1.pin['a2']).put()
nd.Pin(name='a1',pin=BS1.pin['a1']).put()
## revised in 2026.06.07 by Qin Yue
# legacy: nd.Pin(name='a2',pin=BS1.pin['a2']).put()
nd.Pin(name='opt_a2',pin=BS1.pin['opt_a2'],type="optical:").put()
## revised in 2026.06.07 by Qin Yue
# legacy: nd.Pin(name='a1',pin=BS1.pin['a1']).put()
nd.Pin(name='opt_a1',pin=BS1.pin['opt_a1'],type="optical:").put()
nd.Pin(name='b2',pin=BS2.pin['a2']).put()
nd.Pin(name='b1',pin=BS2.pin['a1']).put()
## revised in 2026.06.07 by Qin Yue
# legacy: nd.Pin(name='b2',pin=BS2.pin['a2']).put()
nd.Pin(name='opt_b2',pin=BS2.pin['opt_a2'],type="optical:").put()
## revised in 2026.06.07 by Qin Yue
# legacy: nd.Pin(name='b1',pin=BS2.pin['a1']).put()
nd.Pin(name='opt_b1',pin=BS2.pin['opt_a1'],type="optical:").put()
elif(isinstance(D_port,int) or isinstance(D_port,float)):
temp = pic.sbend_route(radius=R_bend,width=w_wg,pin=BS1.pin['a1'],length1=L_patch/4,length2=L_patch/4,offset=abs(D_port/2-abs(BS1.pin['a1'].y)),
## revised in 2026.06.07 by Qin Yue
# legacy: temp = pic.sbend_route(radius=R_bend,width=w_wg,pin=BS1.pin['a1'],length1=L_patch/4,length2=L_patch/4,offset=abs(D_port/2-abs(BS1.pin['a1'].y)),
temp = pic.sbend_route(radius=R_bend,width=w_wg,pin=BS1.pin['opt_a1'],length1=L_patch/4,length2=L_patch/4,offset=abs(D_port/2-abs(BS1.pin['opt_a1'].y)),
original_function=not sharp_patch).put(flip=1)
nd.Pin(name='a1',pin=temp.pin['b0'].move(-0.05,0,0)).put()
## revised in 2026.06.07 by Qin Yue
# legacy: nd.Pin(name='a1',pin=temp.pin['b0'].move(-0.05,0,0)).put()
nd.Pin(name='opt_a1',pin=temp.pin['b0'].move(-0.05,0,0),type="optical:").put()
temp = pic.sbend_route(radius=R_bend,width=w_wg,pin=BS1.pin['a2'],length1=L_patch/4,length2=L_patch/4,offset=abs(D_port/2-abs(BS1.pin['a2'].y)),
## revised in 2026.06.07 by Qin Yue
# legacy: temp = pic.sbend_route(radius=R_bend,width=w_wg,pin=BS1.pin['a2'],length1=L_patch/4,length2=L_patch/4,offset=abs(D_port/2-abs(BS1.pin['a2'].y)),
temp = pic.sbend_route(radius=R_bend,width=w_wg,pin=BS1.pin['opt_a2'],length1=L_patch/4,length2=L_patch/4,offset=abs(D_port/2-abs(BS1.pin['opt_a2'].y)),
original_function=not sharp_patch).put(flip=0)
nd.Pin(name='a2',pin=temp.pin['b0'].move(-0.05,0,0)).put()
## revised in 2026.06.07 by Qin Yue
# legacy: nd.Pin(name='a2',pin=temp.pin['b0'].move(-0.05,0,0)).put()
nd.Pin(name='opt_a2',pin=temp.pin['b0'].move(-0.05,0,0),type="optical:").put()
temp = pic.sbend_route(radius=R_bend,width=w_wg,pin=BS2.pin['a2'],length1=L_patch/4,length2=L_patch/4,offset=abs(D_port/2-abs(BS2.pin['a1'].y)),
## revised in 2026.06.07 by Qin Yue
# legacy: temp = pic.sbend_route(radius=R_bend,width=w_wg,pin=BS2.pin['a2'],length1=L_patch/4,length2=L_patch/4,offset=abs(D_port/2-abs(BS2.pin['a1'].y)),
temp = pic.sbend_route(radius=R_bend,width=w_wg,pin=BS2.pin['opt_a2'],length1=L_patch/4,length2=L_patch/4,offset=abs(D_port/2-abs(BS2.pin['opt_a1'].y)),
original_function=not sharp_patch).put(flip=0)
nd.Pin(name='b1',pin=temp.pin['b0'].move(-0.05,0,0)).put()
## revised in 2026.06.07 by Qin Yue
# legacy: nd.Pin(name='b1',pin=temp.pin['b0'].move(-0.05,0,0)).put()
nd.Pin(name='opt_b1',pin=temp.pin['b0'].move(-0.05,0,0),type="optical:").put()
temp = pic.sbend_route(radius=R_bend,width=w_wg,pin=BS2.pin['a1'],length1=L_patch/4,length2=L_patch/4,offset=abs(D_port/2-abs(BS2.pin['a2'].y)),
## revised in 2026.06.07 by Qin Yue
# legacy: temp = pic.sbend_route(radius=R_bend,width=w_wg,pin=BS2.pin['a1'],length1=L_patch/4,length2=L_patch/4,offset=abs(D_port/2-abs(BS2.pin['a2'].y)),
temp = pic.sbend_route(radius=R_bend,width=w_wg,pin=BS2.pin['opt_a1'],length1=L_patch/4,length2=L_patch/4,offset=abs(D_port/2-abs(BS2.pin['opt_a2'].y)),
original_function=not sharp_patch).put(flip=1)
nd.Pin(name='b2',pin=temp.pin['b0'].move(-0.05,0,0)).put()
## revised in 2026.06.07 by Qin Yue
# legacy: nd.Pin(name='b2',pin=temp.pin['b0'].move(-0.05,0,0)).put()
nd.Pin(name='opt_b2',pin=temp.pin['b0'].move(-0.05,0,0),type="optical:").put()
else:
raise Exception("ERROR:: In <mxpic::functionalll::MZI>, <D_port> type error")
else :
nd.Pin(name='a1',pin=BS1.pin['a1']).put()
nd.Pin(name='b1',pin=BS2.pin['a1']).put()
## revised in 2026.06.07 by Qin Yue
# legacy: nd.Pin(name='a1',pin=BS1.pin['a1']).put()
nd.Pin(name='opt_a1',pin=BS1.pin['opt_a1'],type="optical:").put()
## revised in 2026.06.07 by Qin Yue
# legacy: nd.Pin(name='b1',pin=BS2.pin['a1']).put()
nd.Pin(name='opt_b1',pin=BS2.pin['opt_a1'],type="optical:").put()
# print("SEGEMENT")
pic_strip.sbend_p2p(pin1=PS_U.pin['a1'],pin2=BS1.pin['b1'],Lstart=L_patch/4).put()
pic_strip.sbend_p2p(pin1=PS_U.pin['b1'],pin2=BS2.pin['b2'],Lstart=L_patch/4).put()
## revised in 2026.06.07 by Qin Yue
# legacy: pic_strip.sbend_p2p(pin1=PS_U.pin['a1'],pin2=BS1.pin['b1'],Lstart=L_patch/4).put()
pic_strip.sbend_p2p(pin1=PS_U.pin['opt_a1'],pin2=BS1.pin['opt_b1'],Lstart=L_patch/4).put()
## revised in 2026.06.07 by Qin Yue
# legacy: pic_strip.sbend_p2p(pin1=PS_U.pin['b1'],pin2=BS2.pin['b2'],Lstart=L_patch/4).put()
pic_strip.sbend_p2p(pin1=PS_U.pin['opt_b1'],pin2=BS2.pin['opt_b2'],Lstart=L_patch/4).put()
if (dual_ht==False):
w_ht_D = 0
@@ -458,10 +560,16 @@ class MZI_NS:
via_h2m=via_h2m,
isl=isl,
L_ht=L_ht)
PS_D = PS.cell.put('a1',-PS.L_arm/2,-D_arm/2,0)
## revised in 2026.06.07 by Qin Yue
# legacy: PS_D = PS.cell.put('a1',-PS.L_arm/2,-D_arm/2,0)
PS_D = PS.cell.put('opt_a1',-PS.L_arm/2,-D_arm/2,0)
pic_strip.sbend_p2p(pin1=PS_D.pin['a1'],pin2=BS1.pin['b2'],Lstart=L_patch/4).put()
pic_strip.sbend_p2p(pin1=PS_D.pin['b1'],pin2=BS2.pin['b1'],Lstart=L_patch/4).put()
## revised in 2026.06.07 by Qin Yue
# legacy: pic_strip.sbend_p2p(pin1=PS_D.pin['a1'],pin2=BS1.pin['b2'],Lstart=L_patch/4).put()
pic_strip.sbend_p2p(pin1=PS_D.pin['opt_a1'],pin2=BS1.pin['opt_b2'],Lstart=L_patch/4).put()
## revised in 2026.06.07 by Qin Yue
# legacy: pic_strip.sbend_p2p(pin1=PS_D.pin['b1'],pin2=BS2.pin['b1'],Lstart=L_patch/4).put()
pic_strip.sbend_p2p(pin1=PS_D.pin['opt_b1'],pin2=BS2.pin['opt_b1'],Lstart=L_patch/4).put()
if (w_heater>0):
nd.Pin(name='ep1',pin=PS_U.pin['ep1']).put()
@@ -566,15 +674,27 @@ class MZI_NS_ubend:
pic = Route(radius=R_bend,width=w_wg,xs=xs_wg)
_L_ = abs(BS.pin['a1'].x-BS.pin['b1'].x)
## revised in 2026.06.07 by Qin Yue
# legacy: _L_ = abs(BS.pin['a1'].x-BS.pin['b1'].x)
_L_ = abs(BS.pin['opt_a1'].x-BS.pin['opt_b1'].x)
_W_ = abs(BS.pin['b1'].y-BS.pin['b2'].y)
## revised in 2026.06.07 by Qin Yue
# legacy: _W_ = abs(BS.pin['b1'].y-BS.pin['b2'].y)
_W_ = abs(BS.pin['opt_b1'].y-BS.pin['opt_b2'].y)
BS1 = BS.put('b1',-R_bend*2-L_patch/2,_W_/2,180)
BS2 = BS.put('b2', R_bend*2+L_patch/2,_W_/2,0)
## revised in 2026.06.07 by Qin Yue
# legacy: BS1 = BS.put('b1',-R_bend*2-L_patch/2,_W_/2,180)
BS1 = BS.put('opt_b1',-R_bend*2-L_patch/2,_W_/2,180)
## revised in 2026.06.07 by Qin Yue
# legacy: BS2 = BS.put('b2', R_bend*2+L_patch/2,_W_/2,0)
BS2 = BS.put('opt_b2', R_bend*2+L_patch/2,_W_/2,0)
nd.Pin(name='a1',pin=BS1.pin['a1']).put()
nd.Pin(name='b1',pin=BS2.pin['a1']).put()
## revised in 2026.06.07 by Qin Yue
# legacy: nd.Pin(name='a1',pin=BS1.pin['a1']).put()
nd.Pin(name='opt_a1',pin=BS1.pin['opt_a1'],type="optical:").put()
## revised in 2026.06.07 by Qin Yue
# legacy: nd.Pin(name='b1',pin=BS2.pin['a1']).put()
nd.Pin(name='opt_b1',pin=BS2.pin['opt_a1'],type="optical:").put()
""" Plcaing b2 pin """
pin_in_name = []
@@ -582,37 +702,75 @@ class MZI_NS_ubend:
pin_in_name = pin_in_name+[str]
# pin_in_name.append(str)
if ('a2' in pin_in_name):
nd.Pin(name='a2',pin=BS1.pin['a2']).put()
nd.Pin(name='b2',pin=BS2.pin['a2']).put()
## revised in 2026.06.07 by Qin Yue
# legacy: if ('a2' in pin_in_name):
if ('opt_a2' in pin_in_name):
## revised in 2026.06.07 by Qin Yue
# legacy: nd.Pin(name='a2',pin=BS1.pin['a2']).put()
nd.Pin(name='opt_a2',pin=BS1.pin['opt_a2'],type="optical:").put()
## revised in 2026.06.07 by Qin Yue
# legacy: nd.Pin(name='b2',pin=BS2.pin['a2']).put()
nd.Pin(name='opt_b2',pin=BS2.pin['opt_a2'],type="optical:").put()
if (D_port==None):
nd.Pin(name='b2',pin=BS2.pin['a1']).put()
nd.strt(length=0.005,width=BS2.pin['a2'].width,xs=xs_wg).put(BS2.pin['a2'])
nd.Pin(name='b1',pin=BS2.pin['a2']).put()
nd.strt(length=0.005,width=BS2.pin['a2'].width,xs=xs_wg).put(BS2.pin['a1'])
nd.Pin(name='a2',pin=BS1.pin['a2']).put()
nd.strt(length=0.005,width=BS1.pin['a2'].width,xs=xs_wg).put(BS1.pin['a2'])
nd.Pin(name='a1',pin=BS1.pin['a1']).put()
nd.strt(length=0.005,width=BS1.pin['a2'].width,xs=xs_wg).put(BS1.pin['a1'])
## revised in 2026.06.07 by Qin Yue
# legacy: nd.Pin(name='b2',pin=BS2.pin['a1']).put()
nd.Pin(name='opt_b2',pin=BS2.pin['opt_a1'],type="optical:").put()
## revised in 2026.06.07 by Qin Yue
# legacy: nd.strt(length=0.005,width=BS2.pin['a2'].width,xs=xs_wg).put(BS2.pin['a2'])
nd.strt(length=0.005,width=BS2.pin['opt_a2'].width,xs=xs_wg).put(BS2.pin['opt_a2'])
## revised in 2026.06.07 by Qin Yue
# legacy: nd.Pin(name='b1',pin=BS2.pin['a2']).put()
nd.Pin(name='opt_b1',pin=BS2.pin['opt_a2'],type="optical:").put()
## revised in 2026.06.07 by Qin Yue
# legacy: nd.strt(length=0.005,width=BS2.pin['a2'].width,xs=xs_wg).put(BS2.pin['a1'])
nd.strt(length=0.005,width=BS2.pin['opt_a2'].width,xs=xs_wg).put(BS2.pin['opt_a1'])
## revised in 2026.06.07 by Qin Yue
# legacy: nd.Pin(name='a2',pin=BS1.pin['a2']).put()
nd.Pin(name='opt_a2',pin=BS1.pin['opt_a2'],type="optical:").put()
## revised in 2026.06.07 by Qin Yue
# legacy: nd.strt(length=0.005,width=BS1.pin['a2'].width,xs=xs_wg).put(BS1.pin['a2'])
nd.strt(length=0.005,width=BS1.pin['opt_a2'].width,xs=xs_wg).put(BS1.pin['opt_a2'])
## revised in 2026.06.07 by Qin Yue
# legacy: nd.Pin(name='a1',pin=BS1.pin['a1']).put()
nd.Pin(name='opt_a1',pin=BS1.pin['opt_a1'],type="optical:").put()
## revised in 2026.06.07 by Qin Yue
# legacy: nd.strt(length=0.005,width=BS1.pin['a2'].width,xs=xs_wg).put(BS1.pin['a1'])
nd.strt(length=0.005,width=BS1.pin['opt_a2'].width,xs=xs_wg).put(BS1.pin['opt_a1'])
elif(isinstance(D_port,int) or isinstance(D_port,float)):
temp = pic.sbend_route(radius=R_bend,width=w_wg,pin=BS2.pin['a2'],length1=L_patch/4,length2=L_patch/4,offset=abs(D_port/2-abs(BS2.pin['a1'].y)),
## revised in 2026.06.07 by Qin Yue
# legacy: temp = pic.sbend_route(radius=R_bend,width=w_wg,pin=BS2.pin['a2'],length1=L_patch/4,length2=L_patch/4,offset=abs(D_port/2-abs(BS2.pin['a1'].y)),
temp = pic.sbend_route(radius=R_bend,width=w_wg,pin=BS2.pin['opt_a2'],length1=L_patch/4,length2=L_patch/4,offset=abs(D_port/2-abs(BS2.pin['opt_a1'].y)),
original_function=not sharp_patch).put(flip=0)
nd.Pin(name='b1',pin=temp.pin['b0'].move(-0.05,0,0)).put()
## revised in 2026.06.07 by Qin Yue
# legacy: nd.Pin(name='b1',pin=temp.pin['b0'].move(-0.05,0,0)).put()
nd.Pin(name='opt_b1',pin=temp.pin['b0'].move(-0.05,0,0),type="optical:").put()
temp = pic.sbend_route(radius=R_bend,width=w_wg,pin=BS2.pin['a1'],length1=L_patch/4,length2=L_patch/4,offset=abs(D_port/2-abs(BS2.pin['a2'].y)),
## revised in 2026.06.07 by Qin Yue
# legacy: temp = pic.sbend_route(radius=R_bend,width=w_wg,pin=BS2.pin['a1'],length1=L_patch/4,length2=L_patch/4,offset=abs(D_port/2-abs(BS2.pin['a2'].y)),
temp = pic.sbend_route(radius=R_bend,width=w_wg,pin=BS2.pin['opt_a1'],length1=L_patch/4,length2=L_patch/4,offset=abs(D_port/2-abs(BS2.pin['opt_a2'].y)),
original_function=not sharp_patch).put(flip=1)
nd.Pin(name='b2',pin=temp.pin['b0'].move(-0.05,0,0)).put()
## revised in 2026.06.07 by Qin Yue
# legacy: nd.Pin(name='b2',pin=temp.pin['b0'].move(-0.05,0,0)).put()
nd.Pin(name='opt_b2',pin=temp.pin['b0'].move(-0.05,0,0),type="optical:").put()
temp = pic.sbend_route(radius=R_bend,width=w_wg,pin=BS1.pin['a1'],length1=L_patch/4,length2=L_patch/4,offset=abs(D_port/2-abs(BS1.pin['a1'].y)),
## revised in 2026.06.07 by Qin Yue
# legacy: temp = pic.sbend_route(radius=R_bend,width=w_wg,pin=BS1.pin['a1'],length1=L_patch/4,length2=L_patch/4,offset=abs(D_port/2-abs(BS1.pin['a1'].y)),
temp = pic.sbend_route(radius=R_bend,width=w_wg,pin=BS1.pin['opt_a1'],length1=L_patch/4,length2=L_patch/4,offset=abs(D_port/2-abs(BS1.pin['opt_a1'].y)),
original_function=not sharp_patch).put(flip=1)
nd.Pin(name='a1',pin=temp.pin['b0'].move(-0.05,0,0)).put()
## revised in 2026.06.07 by Qin Yue
# legacy: nd.Pin(name='a1',pin=temp.pin['b0'].move(-0.05,0,0)).put()
nd.Pin(name='opt_a1',pin=temp.pin['b0'].move(-0.05,0,0),type="optical:").put()
temp = pic.sbend_route(radius=R_bend,width=w_wg,pin=BS1.pin['a2'],length1=L_patch/4,length2=L_patch/4,offset=abs(D_port/2-abs(BS1.pin['a2'].y)),
## revised in 2026.06.07 by Qin Yue
# legacy: temp = pic.sbend_route(radius=R_bend,width=w_wg,pin=BS1.pin['a2'],length1=L_patch/4,length2=L_patch/4,offset=abs(D_port/2-abs(BS1.pin['a2'].y)),
temp = pic.sbend_route(radius=R_bend,width=w_wg,pin=BS1.pin['opt_a2'],length1=L_patch/4,length2=L_patch/4,offset=abs(D_port/2-abs(BS1.pin['opt_a2'].y)),
original_function=not sharp_patch).put(flip=0)
nd.Pin(name='a2',pin=temp.pin['b0'].move(-0.05,0,0)).put()
## revised in 2026.06.07 by Qin Yue
# legacy: nd.Pin(name='a2',pin=temp.pin['b0'].move(-0.05,0,0)).put()
nd.Pin(name='opt_a2',pin=temp.pin['b0'].move(-0.05,0,0),type="optical:").put()
else:
raise Exception("ERROR:: In <mxpic::functionalll::MZI>, <D_port> type error")
@@ -621,9 +779,15 @@ class MZI_NS_ubend:
L12=L12,L_tp=Ltp,w_heater=w_ht,
via_h2m=via_h2m,
isl=isl,
L_ht=L_ht).cell.put('a1',BS1.pin['b1'].x+L_patch/4+R_bend,BS1.pin['b1'].y+L_patch/4+R_bend,90)
pic.bend_route_p2p(pin1=PS_L1.pin['a1'],pin2=BS1.pin['b1']).put()
pic.bend_route_p2p(pin1=PS_L1.pin['b1'],pin2=BS2.pin['b2']).put()
## revised in 2026.06.07 by Qin Yue
# legacy: L_ht=L_ht).cell.put('a1',BS1.pin['b1'].x+L_patch/4+R_bend,BS1.pin['b1'].y+L_patch/4+R_bend,90)
L_ht=L_ht).cell.put('opt_a1',BS1.pin['opt_b1'].x+L_patch/4+R_bend,BS1.pin['opt_b1'].y+L_patch/4+R_bend,90)
## revised in 2026.06.07 by Qin Yue
# legacy: pic.bend_route_p2p(pin1=PS_L1.pin['a1'],pin2=BS1.pin['b1']).put()
pic.bend_route_p2p(pin1=PS_L1.pin['opt_a1'],pin2=BS1.pin['opt_b1']).put()
## revised in 2026.06.07 by Qin Yue
# legacy: pic.bend_route_p2p(pin1=PS_L1.pin['b1'],pin2=BS2.pin['b2']).put()
pic.bend_route_p2p(pin1=PS_L1.pin['opt_b1'],pin2=BS2.pin['opt_b2']).put()
if (dual_ht):
w_ht_d=w_ht
@@ -633,9 +797,15 @@ class MZI_NS_ubend:
L12=L12,L_tp=Ltp,w_heater=w_ht_d,
via_h2m=via_h2m,
isl=isl,
L_ht=L_ht).cell.put('a1',BS1.pin['b1'].x+L_patch/4+R_bend,BS1.pin['b2'].y-L_patch/4-R_bend,-90,flip=1)
pic.bend_route_p2p(pin1=PS_L2.pin['a1'],pin2=BS1.pin['b2']).put()
pic.bend_route_p2p(pin1=PS_L2.pin['b1'],pin2=BS2.pin['b1']).put()
## revised in 2026.06.07 by Qin Yue
# legacy: L_ht=L_ht).cell.put('a1',BS1.pin['b1'].x+L_patch/4+R_bend,BS1.pin['b2'].y-L_patch/4-R_bend,-90,flip=1)
L_ht=L_ht).cell.put('opt_a1',BS1.pin['opt_b1'].x+L_patch/4+R_bend,BS1.pin['opt_b2'].y-L_patch/4-R_bend,-90,flip=1)
## revised in 2026.06.07 by Qin Yue
# legacy: pic.bend_route_p2p(pin1=PS_L2.pin['a1'],pin2=BS1.pin['b2']).put()
pic.bend_route_p2p(pin1=PS_L2.pin['opt_a1'],pin2=BS1.pin['opt_b2']).put()
## revised in 2026.06.07 by Qin Yue
# legacy: pic.bend_route_p2p(pin1=PS_L2.pin['b1'],pin2=BS2.pin['b1']).put()
pic.bend_route_p2p(pin1=PS_L2.pin['opt_b1'],pin2=BS2.pin['opt_b1']).put()
if (w_ht>0):
nd.Pin(name='ep1',pin=PS_L1.pin['ep1']).put()
@@ -723,47 +893,97 @@ class MZI_2st_ubend:
pic_strip = Route(radius=R_bend,width=w_wg,xs=xs_wg)
_L1_ = abs(BS1.pin['a1'].x-BS1.pin['b1'].x)
_L2_ = abs(BS2.pin['a1'].x-BS2.pin['b1'].x)
_L3_ = abs(BS3.pin['a1'].x-BS3.pin['b1'].x)
## revised in 2026.06.07 by Qin Yue
# legacy: _L1_ = abs(BS1.pin['a1'].x-BS1.pin['b1'].x)
_L1_ = abs(BS1.pin['opt_a1'].x-BS1.pin['opt_b1'].x)
## revised in 2026.06.07 by Qin Yue
# legacy: _L2_ = abs(BS2.pin['a1'].x-BS2.pin['b1'].x)
_L2_ = abs(BS2.pin['opt_a1'].x-BS2.pin['opt_b1'].x)
## revised in 2026.06.07 by Qin Yue
# legacy: _L3_ = abs(BS3.pin['a1'].x-BS3.pin['b1'].x)
_L3_ = abs(BS3.pin['opt_a1'].x-BS3.pin['opt_b1'].x)
_W1_ = abs(BS1.pin['b1'].y-BS1.pin['b2'].y)
_W2_ = abs(BS2.pin['b1'].y-BS2.pin['b2'].y)
_W3_ = abs(BS3.pin['b1'].y-BS3.pin['b2'].y)
## revised in 2026.06.07 by Qin Yue
# legacy: _W1_ = abs(BS1.pin['b1'].y-BS1.pin['b2'].y)
_W1_ = abs(BS1.pin['opt_b1'].y-BS1.pin['opt_b2'].y)
## revised in 2026.06.07 by Qin Yue
# legacy: _W2_ = abs(BS2.pin['b1'].y-BS2.pin['b2'].y)
_W2_ = abs(BS2.pin['opt_b1'].y-BS2.pin['opt_b2'].y)
## revised in 2026.06.07 by Qin Yue
# legacy: _W3_ = abs(BS3.pin['b1'].y-BS3.pin['b2'].y)
_W3_ = abs(BS3.pin['opt_b1'].y-BS3.pin['opt_b2'].y)
BSM = BS2.put('a1',-_L2_/2,_W2_/2,0)
BS1 = BS1.put('b1',-_L2_/2-R_bend*4-L_patch,_W2_/2,180)
BS2 = BS3.put('a1', _L2_/2+R_bend*4+L_patch,_W2_/2,0)
## revised in 2026.06.07 by Qin Yue
# legacy: BSM = BS2.put('a1',-_L2_/2,_W2_/2,0)
BSM = BS2.put('opt_a1',-_L2_/2,_W2_/2,0)
## revised in 2026.06.07 by Qin Yue
# legacy: BS1 = BS1.put('b1',-_L2_/2-R_bend*4-L_patch,_W2_/2,180)
BS1 = BS1.put('opt_b1',-_L2_/2-R_bend*4-L_patch,_W2_/2,180)
## revised in 2026.06.07 by Qin Yue
# legacy: BS2 = BS3.put('a1', _L2_/2+R_bend*4+L_patch,_W2_/2,0)
BS2 = BS3.put('opt_a1', _L2_/2+R_bend*4+L_patch,_W2_/2,0)
nd.Pin(name='a1',pin=BS1.pin['a1']).put()
nd.Pin(name='a2',pin=BS1.pin['a2']).put()
## revised in 2026.06.07 by Qin Yue
# legacy: nd.Pin(name='a1',pin=BS1.pin['a1']).put()
nd.Pin(name='opt_a1',pin=BS1.pin['opt_a1'],type="optical:").put()
## revised in 2026.06.07 by Qin Yue
# legacy: nd.Pin(name='a2',pin=BS1.pin['a2']).put()
nd.Pin(name='opt_a2',pin=BS1.pin['opt_a2'],type="optical:").put()
nd.Pin(name='b1',pin=BS2.pin['b1']).put()
nd.Pin(name='b2',pin=BS2.pin['b2']).put()
## revised in 2026.06.07 by Qin Yue
# legacy: nd.Pin(name='b1',pin=BS2.pin['b1']).put()
nd.Pin(name='opt_b1',pin=BS2.pin['opt_b1'],type="optical:").put()
## revised in 2026.06.07 by Qin Yue
# legacy: nd.Pin(name='b2',pin=BS2.pin['b2']).put()
nd.Pin(name='opt_b2',pin=BS2.pin['opt_b2'],type="optical:").put()
PS_L1 = PS_2st(xs_wg=xs_wg,w_wg=w_wg,w1=w1,w2=w2,L1=Ln1/2+L0,L2=L0,R_bend=R_bend,L_wg=0.25,
via_h2m=via_h2m,isl=isl,
L12=L12,L_tp=Ltp,w_heater=0).cell.put('a1',BS1.pin['b1'].x+L_patch/4+R_bend,BS1.pin['b1'].y+L_patch/4+R_bend,90)
pic_strip.bend_route_p2p(pin1=PS_L1.pin['a1'],pin2=BS1.pin['b1']).put()
pic_strip.bend_route_p2p(pin1=PS_L1.pin['b1'],pin2=BSM.pin['a1']).put()
## revised in 2026.06.07 by Qin Yue
# legacy: L12=L12,L_tp=Ltp,w_heater=0).cell.put('a1',BS1.pin['b1'].x+L_patch/4+R_bend,BS1.pin['b1'].y+L_patch/4+R_bend,90)
L12=L12,L_tp=Ltp,w_heater=0).cell.put('opt_a1',BS1.pin['opt_b1'].x+L_patch/4+R_bend,BS1.pin['opt_b1'].y+L_patch/4+R_bend,90)
## revised in 2026.06.07 by Qin Yue
# legacy: pic_strip.bend_route_p2p(pin1=PS_L1.pin['a1'],pin2=BS1.pin['b1']).put()
pic_strip.bend_route_p2p(pin1=PS_L1.pin['opt_a1'],pin2=BS1.pin['opt_b1']).put()
## revised in 2026.06.07 by Qin Yue
# legacy: pic_strip.bend_route_p2p(pin1=PS_L1.pin['b1'],pin2=BSM.pin['a1']).put()
pic_strip.bend_route_p2p(pin1=PS_L1.pin['opt_b1'],pin2=BSM.pin['opt_a1']).put()
PS_L2 = PS_2st(xs_wg=xs_wg,w_wg=w_wg,w1=w2,w2=w1,L1=Ls1/2+L0,L2=L0,R_bend=R_bend,L_wg=0.25,
via_h2m=via_h2m,isl=isl,
L12=L12,L_tp=Ltp,w_heater=0).cell.put('a1',BS1.pin['b1'].x+L_patch/4+R_bend,BS1.pin['b2'].y-L_patch/4-R_bend,-90,flip=1)
pic_strip.bend_route_p2p(pin1=PS_L2.pin['a1'],pin2=BS1.pin['b2']).put()
pic_strip.bend_route_p2p(pin1=PS_L2.pin['b1'],pin2=BSM.pin['a2']).put()
## revised in 2026.06.07 by Qin Yue
# legacy: L12=L12,L_tp=Ltp,w_heater=0).cell.put('a1',BS1.pin['b1'].x+L_patch/4+R_bend,BS1.pin['b2'].y-L_patch/4-R_bend,-90,flip=1)
L12=L12,L_tp=Ltp,w_heater=0).cell.put('opt_a1',BS1.pin['opt_b1'].x+L_patch/4+R_bend,BS1.pin['opt_b2'].y-L_patch/4-R_bend,-90,flip=1)
## revised in 2026.06.07 by Qin Yue
# legacy: pic_strip.bend_route_p2p(pin1=PS_L2.pin['a1'],pin2=BS1.pin['b2']).put()
pic_strip.bend_route_p2p(pin1=PS_L2.pin['opt_a1'],pin2=BS1.pin['opt_b2']).put()
## revised in 2026.06.07 by Qin Yue
# legacy: pic_strip.bend_route_p2p(pin1=PS_L2.pin['b1'],pin2=BSM.pin['a2']).put()
pic_strip.bend_route_p2p(pin1=PS_L2.pin['opt_b1'],pin2=BSM.pin['opt_a2']).put()
PS_R1 = PS_2st(xs_wg=xs_wg,w_wg=w_wg,w1=w2,w2=w1,L1=Ln2/2+L0,L2=L0,R_bend=R_bend,L_wg=0.25,
via_h2m=via_h2m,isl=isl,
L12=L12,L_tp=Ltp,w_heater=0).cell.put('a1',BSM.pin['b1'].x+L_patch/4+R_bend,BSM.pin['b1'].y+L_patch/4+R_bend,90)
pic_strip.bend_route_p2p(pin1=PS_R1.pin['b1'],pin2=BS2.pin['a1']).put()
pic_strip.bend_route_p2p(pin1=PS_R1.pin['a1'],pin2=BSM.pin['b1']).put()
## revised in 2026.06.07 by Qin Yue
# legacy: L12=L12,L_tp=Ltp,w_heater=0).cell.put('a1',BSM.pin['b1'].x+L_patch/4+R_bend,BSM.pin['b1'].y+L_patch/4+R_bend,90)
L12=L12,L_tp=Ltp,w_heater=0).cell.put('opt_a1',BSM.pin['opt_b1'].x+L_patch/4+R_bend,BSM.pin['opt_b1'].y+L_patch/4+R_bend,90)
## revised in 2026.06.07 by Qin Yue
# legacy: pic_strip.bend_route_p2p(pin1=PS_R1.pin['b1'],pin2=BS2.pin['a1']).put()
pic_strip.bend_route_p2p(pin1=PS_R1.pin['opt_b1'],pin2=BS2.pin['opt_a1']).put()
## revised in 2026.06.07 by Qin Yue
# legacy: pic_strip.bend_route_p2p(pin1=PS_R1.pin['a1'],pin2=BSM.pin['b1']).put()
pic_strip.bend_route_p2p(pin1=PS_R1.pin['opt_a1'],pin2=BSM.pin['opt_b1']).put()
PS_R2 = PS_2st(xs_wg=xs_wg,w_wg=w_wg,w1=w1,w2=w2,L1=Ls2/2+L0,L2=L0,R_bend=R_bend,L_wg=0.25,
via_h2m=via_h2m,isl=isl,
L12=L12,L_tp=Ltp,w_heater=0).cell.put('a1',BSM.pin['b1'].x+L_patch/4+R_bend,BSM.pin['b2'].y-L_patch/4-R_bend,-90,flip=1)
pic_strip.bend_route_p2p(pin1=PS_R2.pin['b1'],pin2=BS2.pin['a2']).put()
pic_strip.bend_route_p2p(pin1=PS_R2.pin['a1'],pin2=BSM.pin['b2']).put()
## revised in 2026.06.07 by Qin Yue
# legacy: L12=L12,L_tp=Ltp,w_heater=0).cell.put('a1',BSM.pin['b1'].x+L_patch/4+R_bend,BSM.pin['b2'].y-L_patch/4-R_bend,-90,flip=1)
L12=L12,L_tp=Ltp,w_heater=0).cell.put('opt_a1',BSM.pin['opt_b1'].x+L_patch/4+R_bend,BSM.pin['opt_b2'].y-L_patch/4-R_bend,-90,flip=1)
## revised in 2026.06.07 by Qin Yue
# legacy: pic_strip.bend_route_p2p(pin1=PS_R2.pin['b1'],pin2=BS2.pin['a2']).put()
pic_strip.bend_route_p2p(pin1=PS_R2.pin['opt_b1'],pin2=BS2.pin['opt_a2']).put()
## revised in 2026.06.07 by Qin Yue
# legacy: pic_strip.bend_route_p2p(pin1=PS_R2.pin['a1'],pin2=BSM.pin['b2']).put()
pic_strip.bend_route_p2p(pin1=PS_R2.pin['opt_a1'],pin2=BSM.pin['opt_b2']).put()
self.cell = C
@@ -841,28 +1061,56 @@ class MZI_Eubend:
R90_eff = EUB_90.sz[0]
R180_eff = EUB_180.sz[1]
BS1 = BS.put('b1',-R90_eff-R180_eff/2-L_patch/2,BS.pin['b1'].y,180)
BS2 = BS.put('b1', R90_eff+R180_eff/2+L_patch/2,BS.pin['b1'].y,0,flip=1)
## revised in 2026.06.07 by Qin Yue
# legacy: BS1 = BS.put('b1',-R90_eff-R180_eff/2-L_patch/2,BS.pin['b1'].y,180)
BS1 = BS.put('opt_b1',-R90_eff-R180_eff/2-L_patch/2,BS.pin['opt_b1'].y,180)
## revised in 2026.06.07 by Qin Yue
# legacy: BS2 = BS.put('b1', R90_eff+R180_eff/2+L_patch/2,BS.pin['b1'].y,0,flip=1)
BS2 = BS.put('opt_b1', R90_eff+R180_eff/2+L_patch/2,BS.pin['opt_b1'].y,0,flip=1)
tl = nd.strt(length=L_patch/2,xs=xs_wg,width=BS1.pin['b1'].width).put(BS1.pin['b1'])
EUB_90.cell.put('a1',tl.pin['b0'],flip=0)
## revised in 2026.06.07 by Qin Yue
# legacy: tl = nd.strt(length=L_patch/2,xs=xs_wg,width=BS1.pin['b1'].width).put(BS1.pin['b1'])
tl = nd.strt(length=L_patch/2,xs=xs_wg,width=BS1.pin['opt_b1'].width).put(BS1.pin['opt_b1'])
## revised in 2026.06.07 by Qin Yue
# legacy: EUB_90.cell.put('a1',tl.pin['b0'],flip=0)
EUB_90.cell.put('opt_a1',tl.pin['b0'],flip=0)
nd.strt(length=L_arm/2+dL_Amzi/2,xs=xs_wg,width=w_arm).put()
tl = EUB_180.cell.put(flip=1)
tr = nd.strt(length=abs(tl.pin['b1'].x-BS2.pin['b1'].x)-R90_eff,xs=xs_wg,width=BS2.pin['b1'].width).put(BS2.pin['b1'])
tr = EUB_90.cell.put('a1',tr.pin['b0'],flip=1)
nd.strt(length=abs(tr.pin['b1'].y - tl.pin['b1'].y),xs=xs_wg,width=w_arm).put(tr.pin['b1'])
## revised in 2026.06.07 by Qin Yue
# legacy: tr = nd.strt(length=abs(tl.pin['b1'].x-BS2.pin['b1'].x)-R90_eff,xs=xs_wg,width=BS2.pin['b1'].width).put(BS2.pin['b1'])
tr = nd.strt(length=abs(tl.pin['opt_b1'].x-BS2.pin['opt_b1'].x)-R90_eff,xs=xs_wg,width=BS2.pin['opt_b1'].width).put(BS2.pin['opt_b1'])
## revised in 2026.06.07 by Qin Yue
# legacy: tr = EUB_90.cell.put('a1',tr.pin['b0'],flip=1)
tr = EUB_90.cell.put('opt_a1',tr.pin['b0'],flip=1)
## revised in 2026.06.07 by Qin Yue
# legacy: nd.strt(length=abs(tr.pin['b1'].y - tl.pin['b1'].y),xs=xs_wg,width=w_arm).put(tr.pin['b1'])
nd.strt(length=abs(tr.pin['opt_b1'].y - tl.pin['opt_b1'].y),xs=xs_wg,width=w_arm).put(tr.pin['opt_b1'])
tl = nd.strt(length=L_patch/2,xs=xs_wg,width=BS1.pin['b2'].width).put(BS1.pin['b2'])
EUB_90.cell.put('a1',tl.pin['b0'],flip=1)
## revised in 2026.06.07 by Qin Yue
# legacy: tl = nd.strt(length=L_patch/2,xs=xs_wg,width=BS1.pin['b2'].width).put(BS1.pin['b2'])
tl = nd.strt(length=L_patch/2,xs=xs_wg,width=BS1.pin['opt_b2'].width).put(BS1.pin['opt_b2'])
## revised in 2026.06.07 by Qin Yue
# legacy: EUB_90.cell.put('a1',tl.pin['b0'],flip=1)
EUB_90.cell.put('opt_a1',tl.pin['b0'],flip=1)
nd.strt(length=L_arm/2,xs=xs_wg,width=w_arm).put()
tl = EUB_180.cell.put(flip=0)
tr = nd.strt(length=abs(tl.pin['b1'].x-BS2.pin['b2'].x)-R90_eff,xs=xs_wg,width=BS2.pin['b2'].width).put(BS2.pin['b2'])
tr = EUB_90.cell.put('a1',tr.pin['b0'],flip=0)
nd.strt(length=abs(tr.pin['b1'].y - tl.pin['b1'].y),xs=xs_wg,width=w_arm).put(tr.pin['b1'])
## revised in 2026.06.07 by Qin Yue
# legacy: tr = nd.strt(length=abs(tl.pin['b1'].x-BS2.pin['b2'].x)-R90_eff,xs=xs_wg,width=BS2.pin['b2'].width).put(BS2.pin['b2'])
tr = nd.strt(length=abs(tl.pin['opt_b1'].x-BS2.pin['opt_b2'].x)-R90_eff,xs=xs_wg,width=BS2.pin['opt_b2'].width).put(BS2.pin['opt_b2'])
## revised in 2026.06.07 by Qin Yue
# legacy: tr = EUB_90.cell.put('a1',tr.pin['b0'],flip=0)
tr = EUB_90.cell.put('opt_a1',tr.pin['b0'],flip=0)
## revised in 2026.06.07 by Qin Yue
# legacy: nd.strt(length=abs(tr.pin['b1'].y - tl.pin['b1'].y),xs=xs_wg,width=w_arm).put(tr.pin['b1'])
nd.strt(length=abs(tr.pin['opt_b1'].y - tl.pin['opt_b1'].y),xs=xs_wg,width=w_arm).put(tr.pin['opt_b1'])
nd.Pin(name='a1',pin=BS1.pin['a1']).put()
nd.Pin(name='b1',pin=BS2.pin['a1']).put()
## revised in 2026.06.07 by Qin Yue
# legacy: nd.Pin(name='a1',pin=BS1.pin['a1']).put()
nd.Pin(name='opt_a1',pin=BS1.pin['opt_a1'],type="optical:").put()
## revised in 2026.06.07 by Qin Yue
# legacy: nd.Pin(name='b1',pin=BS2.pin['a1']).put()
nd.Pin(name='opt_b1',pin=BS2.pin['opt_a1'],type="optical:").put()
""" Plcaing b2 pin """
pin_in_name = []
@@ -870,9 +1118,15 @@ class MZI_Eubend:
pin_in_name = pin_in_name+[str]
# pin_in_name.append(str)
if ('a2' in pin_in_name):
nd.Pin(name='a2',pin=BS1.pin['a2']).put()
nd.Pin(name='b2',pin=BS2.pin['a2']).put()
## revised in 2026.06.07 by Qin Yue
# legacy: if ('a2' in pin_in_name):
if ('opt_a2' in pin_in_name):
## revised in 2026.06.07 by Qin Yue
# legacy: nd.Pin(name='a2',pin=BS1.pin['a2']).put()
nd.Pin(name='opt_a2',pin=BS1.pin['opt_a2'],type="optical:").put()
## revised in 2026.06.07 by Qin Yue
# legacy: nd.Pin(name='b2',pin=BS2.pin['a2']).put()
nd.Pin(name='opt_b2',pin=BS2.pin['opt_a2'],type="optical:").put()
self.cell = C
@@ -1081,11 +1335,19 @@ class MZI_Butterfly:
pic_strip = Route(radius=self.R_bend,width=self.w_wg,width2_mm=self.w_arm,sharp_patch=self.sharp_patch,
xs=self.xs_wg)
dY_BS1 = abs(self.BS.pin['b1'].y - self.BS.pin['b2'].y)
BS1 = self.BS.put('b1',-self.R_bend-self.L_inner/2,dY_BS1/2,180)
## revised in 2026.06.07 by Qin Yue
# legacy: dY_BS1 = abs(self.BS.pin['b1'].y - self.BS.pin['b2'].y)
dY_BS1 = abs(self.BS.pin['opt_b1'].y - self.BS.pin['opt_b2'].y)
## revised in 2026.06.07 by Qin Yue
# legacy: BS1 = self.BS.put('b1',-self.R_bend-self.L_inner/2,dY_BS1/2,180)
BS1 = self.BS.put('opt_b1',-self.R_bend-self.L_inner/2,dY_BS1/2,180)
dY_BS2 = abs(self.BS2.pin['b1'].y - self.BS2.pin['b2'].y)
BS2 = self.BS2.put('b2',self.R_bend+self.L_inner/2,dY_BS2/2,0)
## revised in 2026.06.07 by Qin Yue
# legacy: dY_BS2 = abs(self.BS2.pin['b1'].y - self.BS2.pin['b2'].y)
dY_BS2 = abs(self.BS2.pin['opt_b1'].y - self.BS2.pin['opt_b2'].y)
## revised in 2026.06.07 by Qin Yue
# legacy: BS2 = self.BS2.put('b2',self.R_bend+self.L_inner/2,dY_BS2/2,0)
BS2 = self.BS2.put('opt_b2',self.R_bend+self.L_inner/2,dY_BS2/2,0)
# print("BS1=%.3f BS2=%.3f" %(dY_BS1,dY_BS2))
@@ -1093,13 +1355,23 @@ class MZI_Butterfly:
HT_U = waveguide(w_heater=self.w_heater,L_wg=LU,L_heater=LU,
w_wg=self.w_arm,Ltp=self.Ltp,w_port=self.w_wg,
isl=self.isl,w_metal=self.w_metal,
via_h2m=self.via_h2m).cell.put('a1',-LU/2,dY_BS1/2+self.R_bend*4+self.L_patch,0)
## revised in 2026.06.07 by Qin Yue
# legacy: via_h2m=self.via_h2m).cell.put('a1',-LU/2,dY_BS1/2+self.R_bend*4+self.L_patch,0)
via_h2m=self.via_h2m).cell.put('opt_a1',-LU/2,dY_BS1/2+self.R_bend*4+self.L_patch,0)
pic_strip.ubend_route(pin=BS1.pin['b1'],length=self.L_patch/2,offset=self.R_bend*2).put()
pic_strip.ubend_p2p(pin2=HT_U.pin['a1'],length=self.L_patch/2).put()
## revised in 2026.06.07 by Qin Yue
# legacy: pic_strip.ubend_route(pin=BS1.pin['b1'],length=self.L_patch/2,offset=self.R_bend*2).put()
pic_strip.ubend_route(pin=BS1.pin['opt_b1'],length=self.L_patch/2,offset=self.R_bend*2).put()
## revised in 2026.06.07 by Qin Yue
# legacy: pic_strip.ubend_p2p(pin2=HT_U.pin['a1'],length=self.L_patch/2).put()
pic_strip.ubend_p2p(pin2=HT_U.pin['opt_a1'],length=self.L_patch/2).put()
pic_strip.ubend_route(pin=BS2.pin['b2'],length=self.L_patch/2,offset=self.R_bend*2).put(flip=1)
pic_strip.ubend_p2p(pin2=HT_U.pin['b1'],length=self.L_patch/2).put()
## revised in 2026.06.07 by Qin Yue
# legacy: pic_strip.ubend_route(pin=BS2.pin['b2'],length=self.L_patch/2,offset=self.R_bend*2).put(flip=1)
pic_strip.ubend_route(pin=BS2.pin['opt_b2'],length=self.L_patch/2,offset=self.R_bend*2).put(flip=1)
## revised in 2026.06.07 by Qin Yue
# legacy: pic_strip.ubend_p2p(pin2=HT_U.pin['b1'],length=self.L_patch/2).put()
pic_strip.ubend_p2p(pin2=HT_U.pin['opt_b1'],length=self.L_patch/2).put()
if (self.w_heater>0):
nd.Pin(name="ep1",pin=HT_U.pin['ep1']).put()
@@ -1113,17 +1385,27 @@ class MZI_Butterfly:
HT_D = waveguide(w_heater=w_ht_d,L_wg=LD,L_heater=LD,
w_wg=self.w_arm,Ltp=self.Ltp,w_port=self.w_wg,
isl=self.isl,
via_h2m=self.via_h2m).cell.put('a1',-LD/2,-dY_BS1/2-self.R_bend*4-self.L_patch,0)
## revised in 2026.06.07 by Qin Yue
# legacy: via_h2m=self.via_h2m).cell.put('a1',-LD/2,-dY_BS1/2-self.R_bend*4-self.L_patch,0)
via_h2m=self.via_h2m).cell.put('opt_a1',-LD/2,-dY_BS1/2-self.R_bend*4-self.L_patch,0)
if (w_ht_d>0 and self.dual_ht):
nd.Pin(name="ep2",pin=HT_D.pin['ep1']).put()
nd.Pin(name="en2",pin=HT_D.pin['en1']).put()
pic_strip.ubend_route(pin=BS1.pin['b2'],length=self.L_patch/2,offset=self.R_bend*2).put(flip=1)
pic_strip.ubend_p2p(pin2=HT_D.pin['a1'],length=self.L_patch/2).put()
## revised in 2026.06.07 by Qin Yue
# legacy: pic_strip.ubend_route(pin=BS1.pin['b2'],length=self.L_patch/2,offset=self.R_bend*2).put(flip=1)
pic_strip.ubend_route(pin=BS1.pin['opt_b2'],length=self.L_patch/2,offset=self.R_bend*2).put(flip=1)
## revised in 2026.06.07 by Qin Yue
# legacy: pic_strip.ubend_p2p(pin2=HT_D.pin['a1'],length=self.L_patch/2).put()
pic_strip.ubend_p2p(pin2=HT_D.pin['opt_a1'],length=self.L_patch/2).put()
pic_strip.ubend_route(pin=BS2.pin['b1'],length=self.L_patch/2,offset=self.R_bend*2).put()
pic_strip.ubend_p2p(pin2=HT_D.pin['b1'],length=self.L_patch/2).put()
## revised in 2026.06.07 by Qin Yue
# legacy: pic_strip.ubend_route(pin=BS2.pin['b1'],length=self.L_patch/2,offset=self.R_bend*2).put()
pic_strip.ubend_route(pin=BS2.pin['opt_b1'],length=self.L_patch/2,offset=self.R_bend*2).put()
## revised in 2026.06.07 by Qin Yue
# legacy: pic_strip.ubend_p2p(pin2=HT_D.pin['b1'],length=self.L_patch/2).put()
pic_strip.ubend_p2p(pin2=HT_D.pin['opt_b1'],length=self.L_patch/2).put()
""" Placing Input and Output ports """
@@ -1132,53 +1414,101 @@ class MZI_Butterfly:
for str,Pin in self.BS.ic_pins():
pin_in_name = pin_in_name+[str]
if ('a2' in pin_in_name):
## revised in 2026.06.07 by Qin Yue
# legacy: if ('a2' in pin_in_name):
if ('opt_a2' in pin_in_name):
if (self.D_port==None):
nd.Pin(name='a2',pin=BS1.pin['a2']).put()
nd.strt(length=0.005,width=BS1.pin['a2'].width,xs=self.xs_wg).put(BS1.pin['a2'])
nd.Pin(name='a1',pin=BS1.pin['a1']).put()
nd.strt(length=0.005,width=BS1.pin['a2'].width,xs=self.xs_wg).put(BS1.pin['a1'])
## revised in 2026.06.07 by Qin Yue
# legacy: nd.Pin(name='a2',pin=BS1.pin['a2']).put()
nd.Pin(name='opt_a2',pin=BS1.pin['opt_a2'],type="optical:").put()
## revised in 2026.06.07 by Qin Yue
# legacy: nd.strt(length=0.005,width=BS1.pin['a2'].width,xs=self.xs_wg).put(BS1.pin['a2'])
nd.strt(length=0.005,width=BS1.pin['opt_a2'].width,xs=self.xs_wg).put(BS1.pin['opt_a2'])
## revised in 2026.06.07 by Qin Yue
# legacy: nd.Pin(name='a1',pin=BS1.pin['a1']).put()
nd.Pin(name='opt_a1',pin=BS1.pin['opt_a1'],type="optical:").put()
## revised in 2026.06.07 by Qin Yue
# legacy: nd.strt(length=0.005,width=BS1.pin['a2'].width,xs=self.xs_wg).put(BS1.pin['a1'])
nd.strt(length=0.005,width=BS1.pin['opt_a2'].width,xs=self.xs_wg).put(BS1.pin['opt_a1'])
elif(isinstance(self.D_port,int) or isinstance(self.D_port,float)):
temp = pic_strip.sbend_route(pin=BS1.pin['a1'],length1=self.L_patch/4,length2=self.L_patch/4,
offset=abs(self.D_port/2-abs(BS1.pin['a1'].y))).put(flip=1)
nd.Pin(name='a1',pin=temp.pin['b0'].move(-0.05,0,0)).put()
## revised in 2026.06.07 by Qin Yue
# legacy: temp = pic_strip.sbend_route(pin=BS1.pin['a1'],length1=self.L_patch/4,length2=self.L_patch/4,
temp = pic_strip.sbend_route(pin=BS1.pin['opt_a1'],length1=self.L_patch/4,length2=self.L_patch/4,
## revised in 2026.06.07 by Qin Yue
# legacy: offset=abs(self.D_port/2-abs(BS1.pin['a1'].y))).put(flip=1)
offset=abs(self.D_port/2-abs(BS1.pin['opt_a1'].y))).put(flip=1)
## revised in 2026.06.07 by Qin Yue
# legacy: nd.Pin(name='a1',pin=temp.pin['b0'].move(-0.05,0,0)).put()
nd.Pin(name='opt_a1',pin=temp.pin['b0'].move(-0.05,0,0),type="optical:").put()
temp = pic_strip.sbend_route(pin=BS1.pin['a2'],length1=self.L_patch/4,length2=self.L_patch/4,
offset=abs(self.D_port/2-abs(BS1.pin['a2'].y))).put(flip=0)
nd.Pin(name='a2',pin=temp.pin['b0'].move(-0.05,0,0)).put()
## revised in 2026.06.07 by Qin Yue
# legacy: temp = pic_strip.sbend_route(pin=BS1.pin['a2'],length1=self.L_patch/4,length2=self.L_patch/4,
temp = pic_strip.sbend_route(pin=BS1.pin['opt_a2'],length1=self.L_patch/4,length2=self.L_patch/4,
## revised in 2026.06.07 by Qin Yue
# legacy: offset=abs(self.D_port/2-abs(BS1.pin['a2'].y))).put(flip=0)
offset=abs(self.D_port/2-abs(BS1.pin['opt_a2'].y))).put(flip=0)
## revised in 2026.06.07 by Qin Yue
# legacy: nd.Pin(name='a2',pin=temp.pin['b0'].move(-0.05,0,0)).put()
nd.Pin(name='opt_a2',pin=temp.pin['b0'].move(-0.05,0,0),type="optical:").put()
else:
raise Exception("ERROR:: In <mxpic::functionalll::MZI>, <D_port> type error")
else :
nd.Pin(name='a1',pin=BS1.pin['a1']).put()
## revised in 2026.06.07 by Qin Yue
# legacy: nd.Pin(name='a1',pin=BS1.pin['a1']).put()
nd.Pin(name='opt_a1',pin=BS1.pin['opt_a1'],type="optical:").put()
pin_out_name = []
for str,Pin in self.BS2.ic_pins():
pin_out_name = pin_out_name+[str]
if ('a2' in pin_out_name):
## revised in 2026.06.07 by Qin Yue
# legacy: if ('a2' in pin_out_name):
if ('opt_a2' in pin_out_name):
if (self.D_port==None):
nd.Pin(name='b2',pin=BS2.pin['a1']).put()
nd.strt(length=0.005,width=BS2.pin['a2'].width,xs=self.xs_wg).put(BS2.pin['a2'])
nd.Pin(name='b1',pin=BS2.pin['a2']).put()
nd.strt(length=0.005,width=BS2.pin['a2'].width,xs=self.xs_wg).put(BS2.pin['a1'])
## revised in 2026.06.07 by Qin Yue
# legacy: nd.Pin(name='b2',pin=BS2.pin['a1']).put()
nd.Pin(name='opt_b2',pin=BS2.pin['opt_a1'],type="optical:").put()
## revised in 2026.06.07 by Qin Yue
# legacy: nd.strt(length=0.005,width=BS2.pin['a2'].width,xs=self.xs_wg).put(BS2.pin['a2'])
nd.strt(length=0.005,width=BS2.pin['opt_a2'].width,xs=self.xs_wg).put(BS2.pin['opt_a2'])
## revised in 2026.06.07 by Qin Yue
# legacy: nd.Pin(name='b1',pin=BS2.pin['a2']).put()
nd.Pin(name='opt_b1',pin=BS2.pin['opt_a2'],type="optical:").put()
## revised in 2026.06.07 by Qin Yue
# legacy: nd.strt(length=0.005,width=BS2.pin['a2'].width,xs=self.xs_wg).put(BS2.pin['a1'])
nd.strt(length=0.005,width=BS2.pin['opt_a2'].width,xs=self.xs_wg).put(BS2.pin['opt_a1'])
elif(isinstance(self.D_port,int) or isinstance(self.D_port,float)):
temp = pic_strip.sbend_route(pin=BS2.pin['a2'],length1=self.L_patch/4,length2=self.L_patch/4,
offset=abs(self.D_port/2-abs(BS2.pin['a1'].y))).put(flip=0)
nd.Pin(name='b1',pin=temp.pin['b0'].move(-0.05,0,0)).put()
## revised in 2026.06.07 by Qin Yue
# legacy: temp = pic_strip.sbend_route(pin=BS2.pin['a2'],length1=self.L_patch/4,length2=self.L_patch/4,
temp = pic_strip.sbend_route(pin=BS2.pin['opt_a2'],length1=self.L_patch/4,length2=self.L_patch/4,
## revised in 2026.06.07 by Qin Yue
# legacy: offset=abs(self.D_port/2-abs(BS2.pin['a1'].y))).put(flip=0)
offset=abs(self.D_port/2-abs(BS2.pin['opt_a1'].y))).put(flip=0)
## revised in 2026.06.07 by Qin Yue
# legacy: nd.Pin(name='b1',pin=temp.pin['b0'].move(-0.05,0,0)).put()
nd.Pin(name='opt_b1',pin=temp.pin['b0'].move(-0.05,0,0),type="optical:").put()
temp = pic_strip.sbend_route(pin=BS2.pin['a1'],length1=self.L_patch/4,length2=self.L_patch/4,
offset=abs(self.D_port/2-abs(BS2.pin['a2'].y))).put(flip=1)
nd.Pin(name='b2',pin=temp.pin['b0'].move(-0.05,0,0)).put()
## revised in 2026.06.07 by Qin Yue
# legacy: temp = pic_strip.sbend_route(pin=BS2.pin['a1'],length1=self.L_patch/4,length2=self.L_patch/4,
temp = pic_strip.sbend_route(pin=BS2.pin['opt_a1'],length1=self.L_patch/4,length2=self.L_patch/4,
## revised in 2026.06.07 by Qin Yue
# legacy: offset=abs(self.D_port/2-abs(BS2.pin['a2'].y))).put(flip=1)
offset=abs(self.D_port/2-abs(BS2.pin['opt_a2'].y))).put(flip=1)
## revised in 2026.06.07 by Qin Yue
# legacy: nd.Pin(name='b2',pin=temp.pin['b0'].move(-0.05,0,0)).put()
nd.Pin(name='opt_b2',pin=temp.pin['b0'].move(-0.05,0,0),type="optical:").put()
else:
raise Exception("ERROR:: In <mxpic::functionalll::MZI>, <D_port> type error")
else :
nd.Pin(name='b1',pin=BS2.pin['a1']).put()
## revised in 2026.06.07 by Qin Yue
# legacy: nd.Pin(name='b1',pin=BS2.pin['a1']).put()
nd.Pin(name='opt_b1',pin=BS2.pin['opt_a1'],type="optical:").put()
return C
@@ -1204,29 +1534,51 @@ class MZI_Butterfly:
GC2Instr = gc_cell.put(pin_gc,dXgc2gc,0,0)
""" Placing GC inputs """
if ("a2" in self.cell.pin):
## revised in 2026.06.07 by Qin Yue
# legacy: if ("a2" in self.cell.pin):
if ("opt_a2" in self.cell.pin):
GC3Instr = gc_cell.put(pin_gc,0,dYgc2gc,180)
if ("b2" in self.cell.pin):
## revised in 2026.06.07 by Qin Yue
# legacy: if ("b2" in self.cell.pin):
if ("opt_b2" in self.cell.pin):
GC4Instr = gc_cell.put(pin_gc,dXgc2gc,dYgc2gc,0)
dYcell = abs(self.cell.pin['b1'].y - self.cell.pin['b2'].y)
## revised in 2026.06.07 by Qin Yue
# legacy: dYcell = abs(self.cell.pin['b1'].y - self.cell.pin['b2'].y)
dYcell = abs(self.cell.pin['opt_b1'].y - self.cell.pin['opt_b2'].y)
dYoffset = -(dYcell - dYgc2gc)/2
else:
dYoffset = 0
dXcell = abs(self.cell.pin['a1'].x - self.cell.pin['b1'].x)
## revised in 2026.06.07 by Qin Yue
# legacy: dXcell = abs(self.cell.pin['a1'].x - self.cell.pin['b1'].x)
dXcell = abs(self.cell.pin['opt_a1'].x - self.cell.pin['opt_b1'].x)
dXoffset = -(dXcell - dXgc2gc)/2
cellInstr = self.cell.put('a1',dXoffset,dYoffset,0,flip=1)
## revised in 2026.06.07 by Qin Yue
# legacy: cellInstr = self.cell.put('a1',dXoffset,dYoffset,0,flip=1)
cellInstr = self.cell.put('opt_a1',dXoffset,dYoffset,0,flip=1)
pic = Route(xs=self.xs_wg,width=w_wg,radius=R_bend,sharp_patch=self.sharp_patch)
pic.sbend_p2p(pin1=cellInstr.pin['a1'],pin2=GC1Instr.pin[pin_gc]).put()
pic.sbend_p2p(pin1=cellInstr.pin['b1'],pin2=GC2Instr.pin[pin_gc]).put()
## revised in 2026.06.07 by Qin Yue
# legacy: pic.sbend_p2p(pin1=cellInstr.pin['a1'],pin2=GC1Instr.pin[pin_gc]).put()
pic.sbend_p2p(pin1=cellInstr.pin['opt_a1'],pin2=GC1Instr.pin[pin_gc]).put()
## revised in 2026.06.07 by Qin Yue
# legacy: pic.sbend_p2p(pin1=cellInstr.pin['b1'],pin2=GC2Instr.pin[pin_gc]).put()
pic.sbend_p2p(pin1=cellInstr.pin['opt_b1'],pin2=GC2Instr.pin[pin_gc]).put()
if ("a2" in cellInstr.pin):
pic.sbend_p2p(pin1=cellInstr.pin['a2'],pin2=GC3Instr.pin[pin_gc]).put()
if ("b2" in cellInstr.pin):
pic.sbend_p2p(pin1=cellInstr.pin['b2'],pin2=GC4Instr.pin[pin_gc]).put()
## revised in 2026.06.07 by Qin Yue
# legacy: if ("a2" in cellInstr.pin):
if ("opt_a2" in cellInstr.pin):
## revised in 2026.06.07 by Qin Yue
# legacy: pic.sbend_p2p(pin1=cellInstr.pin['a2'],pin2=GC3Instr.pin[pin_gc]).put()
pic.sbend_p2p(pin1=cellInstr.pin['opt_a2'],pin2=GC3Instr.pin[pin_gc]).put()
## revised in 2026.06.07 by Qin Yue
# legacy: if ("b2" in cellInstr.pin):
if ("opt_b2" in cellInstr.pin):
## revised in 2026.06.07 by Qin Yue
# legacy: pic.sbend_p2p(pin1=cellInstr.pin['b2'],pin2=GC4Instr.pin[pin_gc]).put()
pic.sbend_p2p(pin1=cellInstr.pin['opt_b2'],pin2=GC4Instr.pin[pin_gc]).put()
return C
+345 -115
View File
@@ -175,11 +175,19 @@ class W_waveguide:
# ISL(xs=self.xs_isl,width=self.w_isl,length=L_isl_side).cell.put('a1',self.L_wg,self.w_metal/2+self.sp_isl_xs,90)
if (self.reverse):
nd.Pin(name='b1',pin=wg_begin.pin['a0']).put()
nd.Pin(name='a1',pin=wg_end.pin['b0']).put()
## revised in 2026.06.07 by Qin Yue
# legacy: nd.Pin(name='b1',pin=wg_begin.pin['a0']).put()
nd.Pin(name='opt_b1',pin=wg_begin.pin['a0'],type="optical:").put()
## revised in 2026.06.07 by Qin Yue
# legacy: nd.Pin(name='a1',pin=wg_end.pin['b0']).put()
nd.Pin(name='opt_a1',pin=wg_end.pin['b0'],type="optical:").put()
else :
nd.Pin(name='a1',pin=wg_begin.pin['a0']).put()
nd.Pin(name='b1',pin=wg_end.pin['b0']).put()
## revised in 2026.06.07 by Qin Yue
# legacy: nd.Pin(name='a1',pin=wg_begin.pin['a0']).put()
nd.Pin(name='opt_a1',pin=wg_begin.pin['a0'],type="optical:").put()
## revised in 2026.06.07 by Qin Yue
# legacy: nd.Pin(name='b1',pin=wg_end.pin['b0']).put()
nd.Pin(name='opt_b1',pin=wg_end.pin['b0'],type="optical:").put()
return C
@@ -324,13 +332,21 @@ class UMat_2x2_S:
with nd.Cell(name=self.name,instantiate=instantiate) as MZI_Unit:
pic_strip = Route(radius=self.R_bend,width=self.w_wg,xs=self.xs_wg)
self.dL_BS = np.abs(self.BS.pin['a1'].x - self.BS.pin['b1'].x)
## revised in 2026.06.07 by Qin Yue
# legacy: self.dL_BS = np.abs(self.BS.pin['a1'].x - self.BS.pin['b1'].x)
self.dL_BS = np.abs(self.BS.pin['opt_a1'].x - self.BS.pin['opt_b1'].x)
## 2023.1.21 modified
dY_BS = abs(self.BS.pin['b1'].y - self.BS.pin['b2'].y)
## revised in 2026.06.07 by Qin Yue
# legacy: dY_BS = abs(self.BS.pin['b1'].y - self.BS.pin['b2'].y)
dY_BS = abs(self.BS.pin['opt_b1'].y - self.BS.pin['opt_b2'].y)
BS_L = self.BS.put('b1',-2*self.R_bend - self.L_arm/2-1,dY_BS/2,180)
BS_R = self.BS.put('a2', 2*self.R_bend + self.L_arm/2+1,dY_BS/2,0,flip=1)
## revised in 2026.06.07 by Qin Yue
# legacy: BS_L = self.BS.put('b1',-2*self.R_bend - self.L_arm/2-1,dY_BS/2,180)
BS_L = self.BS.put('opt_b1',-2*self.R_bend - self.L_arm/2-1,dY_BS/2,180)
## revised in 2026.06.07 by Qin Yue
# legacy: BS_R = self.BS.put('a2', 2*self.R_bend + self.L_arm/2+1,dY_BS/2,0,flip=1)
BS_R = self.BS.put('opt_a2', 2*self.R_bend + self.L_arm/2+1,dY_BS/2,0,flip=1)
if (self.bend_heaters):
wg_ht = W_waveguide(L_wg=self.L_arm,w_wg=self.w_wg,xs_wg=self.xs_wg,dL=self.dL_ht,R_bend=self.R_bend,
@@ -361,35 +377,75 @@ class UMat_2x2_S:
xs_heater=self.xs_heater,xs_metal=self.xs_metal).cell
if (self.ht_same_side):
wg_U = wg_oht.put('a1',-self.L_arm/2,self.D_arm/2,0)
wg_D = wg_ht.put('a1',-self.L_arm/2,-self.D_arm/2,0,flip=1)
## revised in 2026.06.07 by Qin Yue
# legacy: wg_U = wg_oht.put('a1',-self.L_arm/2,self.D_arm/2,0)
wg_U = wg_oht.put('opt_a1',-self.L_arm/2,self.D_arm/2,0)
## revised in 2026.06.07 by Qin Yue
# legacy: wg_D = wg_ht.put('a1',-self.L_arm/2,-self.D_arm/2,0,flip=1)
wg_D = wg_ht.put('opt_a1',-self.L_arm/2,-self.D_arm/2,0,flip=1)
else:
wg_U = wg_ht.put('a1',-self.L_arm/2,self.D_arm/2,0)
wg_D = wg_oht.put('a1',-self.L_arm/2,-self.D_arm/2,0,flip=1)
## revised in 2026.06.07 by Qin Yue
# legacy: wg_U = wg_ht.put('a1',-self.L_arm/2,self.D_arm/2,0)
wg_U = wg_ht.put('opt_a1',-self.L_arm/2,self.D_arm/2,0)
## revised in 2026.06.07 by Qin Yue
# legacy: wg_D = wg_oht.put('a1',-self.L_arm/2,-self.D_arm/2,0,flip=1)
wg_D = wg_oht.put('opt_a1',-self.L_arm/2,-self.D_arm/2,0,flip=1)
pic_strip.sbend_p2p(pin1=BS_L.pin['b1'],pin2=wg_U.pin['a1']).put()
pic_strip.sbend_p2p(pin1=BS_L.pin['b2'],pin2=wg_D.pin['a1']).put()
pic_strip.sbend_p2p(pin1=BS_R.pin['a2'],pin2=wg_U.pin['b1']).put()
pic_strip.sbend_p2p(pin1=BS_R.pin['a1'],pin2=wg_D.pin['b1']).put()
## revised in 2026.06.07 by Qin Yue
# legacy: pic_strip.sbend_p2p(pin1=BS_L.pin['b1'],pin2=wg_U.pin['a1']).put()
pic_strip.sbend_p2p(pin1=BS_L.pin['opt_b1'],pin2=wg_U.pin['opt_a1']).put()
## revised in 2026.06.07 by Qin Yue
# legacy: pic_strip.sbend_p2p(pin1=BS_L.pin['b2'],pin2=wg_D.pin['a1']).put()
pic_strip.sbend_p2p(pin1=BS_L.pin['opt_b2'],pin2=wg_D.pin['opt_a1']).put()
## revised in 2026.06.07 by Qin Yue
# legacy: pic_strip.sbend_p2p(pin1=BS_R.pin['a2'],pin2=wg_U.pin['b1']).put()
pic_strip.sbend_p2p(pin1=BS_R.pin['opt_a2'],pin2=wg_U.pin['opt_b1']).put()
## revised in 2026.06.07 by Qin Yue
# legacy: pic_strip.sbend_p2p(pin1=BS_R.pin['a1'],pin2=wg_D.pin['b1']).put()
pic_strip.sbend_p2p(pin1=BS_R.pin['opt_a1'],pin2=wg_D.pin['opt_b1']).put()
ps_U = wg_oht.put('b1',BS_L.pin['a1'].x-self.R_bend*2-1,self.D_arm/2,180,flip=1)
## revised in 2026.06.07 by Qin Yue
# legacy: ps_U = wg_oht.put('b1',BS_L.pin['a1'].x-self.R_bend*2-1,self.D_arm/2,180,flip=1)
ps_U = wg_oht.put('opt_b1',BS_L.pin['opt_a1'].x-self.R_bend*2-1,self.D_arm/2,180,flip=1)
ps_D = wg_ht.put('b1',BS_L.pin['a1'].x-self.R_bend*2-1,-self.D_arm/2,180,flip=0)
## revised in 2026.06.07 by Qin Yue
# legacy: ps_D = wg_ht.put('b1',BS_L.pin['a1'].x-self.R_bend*2-1,-self.D_arm/2,180,flip=0)
ps_D = wg_ht.put('opt_b1',BS_L.pin['opt_a1'].x-self.R_bend*2-1,-self.D_arm/2,180,flip=0)
pic_strip.sbend_p2p(pin1=ps_U.pin['b1'],pin2=BS_L.pin['a1']).put()
pic_strip.sbend_p2p(pin1=ps_D.pin['b1'],pin2=BS_L.pin['a2']).put()
## revised in 2026.06.07 by Qin Yue
# legacy: pic_strip.sbend_p2p(pin1=ps_U.pin['b1'],pin2=BS_L.pin['a1']).put()
pic_strip.sbend_p2p(pin1=ps_U.pin['opt_b1'],pin2=BS_L.pin['opt_a1']).put()
## revised in 2026.06.07 by Qin Yue
# legacy: pic_strip.sbend_p2p(pin1=ps_D.pin['b1'],pin2=BS_L.pin['a2']).put()
pic_strip.sbend_p2p(pin1=ps_D.pin['opt_b1'],pin2=BS_L.pin['opt_a2']).put()
patch_U = nd.strt(length=0.5,width=self.w_wg,xs=self.xs_wg).put('a0',BS_R.pin['b2'].x+self.R_bend*2+1, self.D_arm/2,0)
patch_D = nd.strt(length=0.5,width=self.w_wg,xs=self.xs_wg).put('a0',BS_R.pin['b1'].x+self.R_bend*2+1,-self.D_arm/2,0)
## revised in 2026.06.07 by Qin Yue
# legacy: patch_U = nd.strt(length=0.5,width=self.w_wg,xs=self.xs_wg).put('a0',BS_R.pin['b2'].x+self.R_bend*2+1, self.D_arm/2,0)
patch_U = nd.strt(length=0.5,width=self.w_wg,xs=self.xs_wg).put('a0',BS_R.pin['opt_b2'].x+self.R_bend*2+1, self.D_arm/2,0)
## revised in 2026.06.07 by Qin Yue
# legacy: patch_D = nd.strt(length=0.5,width=self.w_wg,xs=self.xs_wg).put('a0',BS_R.pin['b1'].x+self.R_bend*2+1,-self.D_arm/2,0)
patch_D = nd.strt(length=0.5,width=self.w_wg,xs=self.xs_wg).put('a0',BS_R.pin['opt_b1'].x+self.R_bend*2+1,-self.D_arm/2,0)
pic_strip.sbend_p2p(pin1=patch_U.pin['a0'],pin2=BS_R.pin['b2']).put()
pic_strip.sbend_p2p(pin1=patch_D.pin['a0'],pin2=BS_R.pin['b1']).put()
## revised in 2026.06.07 by Qin Yue
# legacy: pic_strip.sbend_p2p(pin1=patch_U.pin['a0'],pin2=BS_R.pin['b2']).put()
pic_strip.sbend_p2p(pin1=patch_U.pin['a0'],pin2=BS_R.pin['opt_b2']).put()
## revised in 2026.06.07 by Qin Yue
# legacy: pic_strip.sbend_p2p(pin1=patch_D.pin['a0'],pin2=BS_R.pin['b1']).put()
pic_strip.sbend_p2p(pin1=patch_D.pin['a0'],pin2=BS_R.pin['opt_b1']).put()
nd.Pin(name='a1',pin=ps_U.pin['a1'].move(-0.05,0,0),width=self.w_wg).put()
nd.Pin(name='a2',pin=ps_D.pin['a1'].move(-0.05,0,0),width=self.w_wg).put()
nd.Pin(name='b1',pin=patch_U.pin['b0'].move(-0.05,0,0),width=self.w_wg).put()
nd.Pin(name='b2',pin=patch_D.pin['b0'].move(-0.05,0,0),width=self.w_wg).put()
## revised in 2026.06.07 by Qin Yue
# legacy: nd.Pin(name='a1',pin=ps_U.pin['a1'].move(-0.05,0,0),width=self.w_wg).put()
nd.Pin(name='opt_a1',pin=ps_U.pin['opt_a1'].move(-0.05,0,0),width=self.w_wg,type="optical:").put()
## revised in 2026.06.07 by Qin Yue
# legacy: nd.Pin(name='a2',pin=ps_D.pin['a1'].move(-0.05,0,0),width=self.w_wg).put()
nd.Pin(name='opt_a2',pin=ps_D.pin['opt_a1'].move(-0.05,0,0),width=self.w_wg,type="optical:").put()
## revised in 2026.06.07 by Qin Yue
# legacy: nd.Pin(name='b1',pin=patch_U.pin['b0'].move(-0.05,0,0),width=self.w_wg).put()
nd.Pin(name='opt_b1',pin=patch_U.pin['b0'].move(-0.05,0,0),width=self.w_wg,type="optical:").put()
## revised in 2026.06.07 by Qin Yue
# legacy: nd.Pin(name='b2',pin=patch_D.pin['b0'].move(-0.05,0,0),width=self.w_wg).put()
nd.Pin(name='opt_b2',pin=patch_D.pin['b0'].move(-0.05,0,0),width=self.w_wg,type="optical:").put()
nd.Pin(name='ep1',pin=ps_D.pin['ep1']).put()
nd.Pin(name='en1',pin=ps_D.pin['en1']).put()
@@ -401,8 +457,12 @@ class UMat_2x2_S:
nd.Pin(name='ep2',pin=wg_U.pin['ep1']).put()
nd.Pin(name='en2',pin=wg_U.pin['en1']).put()
dX_unit = abs(ps_U.pin['a1'].x - patch_U.pin['b0'].x)
dY_unit = abs(ps_U.pin['a1'].y - ps_D.pin['a1'].y)
## revised in 2026.06.07 by Qin Yue
# legacy: dX_unit = abs(ps_U.pin['a1'].x - patch_U.pin['b0'].x)
dX_unit = abs(ps_U.pin['opt_a1'].x - patch_U.pin['b0'].x)
## revised in 2026.06.07 by Qin Yue
# legacy: dY_unit = abs(ps_U.pin['a1'].y - ps_D.pin['a1'].y)
dY_unit = abs(ps_U.pin['opt_a1'].y - ps_D.pin['opt_a1'].y)
return MZI_Unit
@@ -569,8 +629,12 @@ class MZI_mesh_U:
strip.bend_route(radius=R_compensate,angle=90).put()
strip_output = strip.strt(length=0.2).put()
nd.Pin(name='a1',width=self.w_wg).put(strip_input.pin['a0'])
nd.Pin(name='b1',width=self.w_wg).put(strip_output.pin['b0'])
## revised in 2026.06.07 by Qin Yue
# legacy: nd.Pin(name='a1',width=self.w_wg).put(strip_input.pin['a0'])
nd.Pin(name='opt_a1',width=self.w_wg,type="optical:").put(strip_input.pin['a0'])
## revised in 2026.06.07 by Qin Yue
# legacy: nd.Pin(name='b1',width=self.w_wg).put(strip_output.pin['b0'])
nd.Pin(name='opt_b1',width=self.w_wg,type="optical:").put(strip_output.pin['b0'])
nd.Pin(name='a0',width=self.w_wg).put(strip_input.pin['a0'])
nd.Pin(name='b0',width=self.w_wg).put(strip_output.pin['b0'])
return ICell
@@ -583,8 +647,12 @@ class MZI_mesh_U:
rows = self.n_ports-1
pic_strip = Route(radius=self.R_bend,width=self.w_wg,xs='strip')
dX_unit = abs(self.MZI_unit.pin['a1'].x-self.MZI_unit.pin['b1'].x)
dY_unit = abs(self.MZI_unit.pin['a1'].y-self.MZI_unit.pin['a2'].y)
## revised in 2026.06.07 by Qin Yue
# legacy: dX_unit = abs(self.MZI_unit.pin['a1'].x-self.MZI_unit.pin['b1'].x)
dX_unit = abs(self.MZI_unit.pin['opt_a1'].x-self.MZI_unit.pin['opt_b1'].x)
## revised in 2026.06.07 by Qin Yue
# legacy: dY_unit = abs(self.MZI_unit.pin['a1'].y-self.MZI_unit.pin['a2'].y)
dY_unit = abs(self.MZI_unit.pin['opt_a1'].y-self.MZI_unit.pin['opt_a2'].y)
x_spacing = dX_unit ## incase of overlapping
y_spacing = dY_unit ## incase of overlapping
x_list = []
@@ -622,10 +690,16 @@ class MZI_mesh_U:
if (c_idx>=1 and r_idx==1): ### This will not happen in Triangle cases
# pic_strip.sbend_p2p(pin1=pin_up_pre,pin2=INSTR.pin['a1']).put()
pic_strip.strt(pin=pin_up_pre,length=self.L_arm).put()
bend_compensate = self.cell_compensate.put('a1',nd.Pin().put(),flip=True)
## revised in 2026.06.07 by Qin Yue
# legacy: bend_compensate = self.cell_compensate.put('a1',nd.Pin().put(),flip=True)
bend_compensate = self.cell_compensate.put('opt_a1',nd.Pin().put(),flip=True)
pic_strip.sbend_p2p(
pin1=bend_compensate.pin['b1'],
pin2=INSTR.pin['a1']
## revised in 2026.06.07 by Qin Yue
# legacy: pin1=bend_compensate.pin['b1'],
pin1=bend_compensate.pin['opt_b1'],
## revised in 2026.06.07 by Qin Yue
# legacy: pin2=INSTR.pin['a1']
pin2=INSTR.pin['opt_a1']
).put()
# self.cell_offset.put(flip=1)
# self.cell_offset.put(flip=0)
@@ -636,10 +710,16 @@ class MZI_mesh_U:
if (c_idx>=1 and r_idx==rows):
if self.mesh_type=='parallelogram':
pic_strip.strt(pin=pin_down_pre,length=self.L_arm).put()
bend_compensate = self.cell_compensate.put('a1',nd.Pin().put())
## revised in 2026.06.07 by Qin Yue
# legacy: bend_compensate = self.cell_compensate.put('a1',nd.Pin().put())
bend_compensate = self.cell_compensate.put('opt_a1',nd.Pin().put())
pic_strip.sbend_p2p(
pin1=bend_compensate.pin['b1'],
pin2=INSTR.pin['a2']
## revised in 2026.06.07 by Qin Yue
# legacy: pin1=bend_compensate.pin['b1'],
pin1=bend_compensate.pin['opt_b1'],
## revised in 2026.06.07 by Qin Yue
# legacy: pin2=INSTR.pin['a2']
pin2=INSTR.pin['opt_a2']
).put()
# self.cell_offset.put(flip=1)
# self.cell_offset.put(flip=0)
@@ -649,77 +729,151 @@ class MZI_mesh_U:
# pic_strip.sbend_p2p(pin2=pin_down_pre).put()
elif self.mesh_type=='triangle':
pic_strip.strt(pin=pin_down_pre,length=self.L_arm).put()
bend_compensate = self.cell_compensate.put('a1',nd.Pin().put())
## revised in 2026.06.07 by Qin Yue
# legacy: bend_compensate = self.cell_compensate.put('a1',nd.Pin().put())
bend_compensate = self.cell_compensate.put('opt_a1',nd.Pin().put())
pic_strip.sbend_p2p(
pin1=bend_compensate.pin['b1'],
pin2=INSTR.pin['a2']
## revised in 2026.06.07 by Qin Yue
# legacy: pin1=bend_compensate.pin['b1'],
pin1=bend_compensate.pin['opt_b1'],
## revised in 2026.06.07 by Qin Yue
# legacy: pin2=INSTR.pin['a2']
pin2=INSTR.pin['opt_a2']
).put()
# pic_strip.sbend_p2p(pin1=pin_down_pre,pin2=INSTR.pin['a2']).put()
pin_down_pre = INSTR.pin['b2']
pin_up_pre = INSTR.pin['b1']
## revised in 2026.06.07 by Qin Yue
# legacy: pin_down_pre = INSTR.pin['b2']
pin_down_pre = INSTR.pin['opt_b2']
## revised in 2026.06.07 by Qin Yue
# legacy: pin_up_pre = INSTR.pin['b1']
pin_up_pre = INSTR.pin['opt_b1']
""" recongizing pins """
if (self.mesh_type=='triangle'):
if (c_idx==0):
pin_a_list.append(INSTR.pin['a1'])
x_list.append(INSTR.pin['a1'].x)
## revised in 2026.06.07 by Qin Yue
# legacy: pin_a_list.append(INSTR.pin['a1'])
pin_a_list.append(INSTR.pin['opt_a1'])
## revised in 2026.06.07 by Qin Yue
# legacy: x_list.append(INSTR.pin['a1'].x)
x_list.append(INSTR.pin['opt_a1'].x)
if (c_idx==cols-1):
pin_b_list.append(INSTR.pin['b1'])
x_list.append(INSTR.pin['b1'].x)
## revised in 2026.06.07 by Qin Yue
# legacy: pin_b_list.append(INSTR.pin['b1'])
pin_b_list.append(INSTR.pin['opt_b1'])
## revised in 2026.06.07 by Qin Yue
# legacy: x_list.append(INSTR.pin['b1'].x)
x_list.append(INSTR.pin['opt_b1'].x)
if (r_idx==rows):
if (c_idx==0):
pin_a_list.append(INSTR.pin['a2'])
x_list.append(INSTR.pin['a2'].x)
## revised in 2026.06.07 by Qin Yue
# legacy: pin_a_list.append(INSTR.pin['a2'])
pin_a_list.append(INSTR.pin['opt_a2'])
## revised in 2026.06.07 by Qin Yue
# legacy: x_list.append(INSTR.pin['a2'].x)
x_list.append(INSTR.pin['opt_a2'].x)
elif (c_idx==cols-1):
pin_b_list.append(INSTR.pin['b2'])
x_list.append(INSTR.pin['b2'].x)
## revised in 2026.06.07 by Qin Yue
# legacy: pin_b_list.append(INSTR.pin['b2'])
pin_b_list.append(INSTR.pin['opt_b2'])
## revised in 2026.06.07 by Qin Yue
# legacy: x_list.append(INSTR.pin['b2'].x)
x_list.append(INSTR.pin['opt_b2'].x)
else :
if (np.mod(self.n_ports,2)==1):
if (np.mod(r_idx,2)==1):
if (c_idx==0):
pin_a_list.append(INSTR.pin['a1'])
x_list.append(INSTR.pin['a1'].x)
pin_a_list.append(INSTR.pin['a2'])
x_list.append(INSTR.pin['a2'].x)
## revised in 2026.06.07 by Qin Yue
# legacy: pin_a_list.append(INSTR.pin['a1'])
pin_a_list.append(INSTR.pin['opt_a1'])
## revised in 2026.06.07 by Qin Yue
# legacy: x_list.append(INSTR.pin['a1'].x)
x_list.append(INSTR.pin['opt_a1'].x)
## revised in 2026.06.07 by Qin Yue
# legacy: pin_a_list.append(INSTR.pin['a2'])
pin_a_list.append(INSTR.pin['opt_a2'])
## revised in 2026.06.07 by Qin Yue
# legacy: x_list.append(INSTR.pin['a2'].x)
x_list.append(INSTR.pin['opt_a2'].x)
if (c_idx==cols-1):
pin_b_list.append(INSTR.pin['b1'])
x_list.append(INSTR.pin['b1'].x)
pin_b_list.append(INSTR.pin['b2'])
x_list.append(INSTR.pin['b2'].x)
## revised in 2026.06.07 by Qin Yue
# legacy: pin_b_list.append(INSTR.pin['b1'])
pin_b_list.append(INSTR.pin['opt_b1'])
## revised in 2026.06.07 by Qin Yue
# legacy: x_list.append(INSTR.pin['b1'].x)
x_list.append(INSTR.pin['opt_b1'].x)
## revised in 2026.06.07 by Qin Yue
# legacy: pin_b_list.append(INSTR.pin['b2'])
pin_b_list.append(INSTR.pin['opt_b2'])
## revised in 2026.06.07 by Qin Yue
# legacy: x_list.append(INSTR.pin['b2'].x)
x_list.append(INSTR.pin['opt_b2'].x)
elif (r_idx==rows):
if (c_idx==0):
pin_a_list.append(INSTR.pin['a2'])
x_list.append(INSTR.pin['a2'].x)
## revised in 2026.06.07 by Qin Yue
# legacy: pin_a_list.append(INSTR.pin['a2'])
pin_a_list.append(INSTR.pin['opt_a2'])
## revised in 2026.06.07 by Qin Yue
# legacy: x_list.append(INSTR.pin['a2'].x)
x_list.append(INSTR.pin['opt_a2'].x)
elif (c_idx==cols-1):
pin_b_list.append(INSTR.pin['b2'])
x_list.append(INSTR.pin['b2'].x)
## revised in 2026.06.07 by Qin Yue
# legacy: pin_b_list.append(INSTR.pin['b2'])
pin_b_list.append(INSTR.pin['opt_b2'])
## revised in 2026.06.07 by Qin Yue
# legacy: x_list.append(INSTR.pin['b2'].x)
x_list.append(INSTR.pin['opt_b2'].x)
else :
if (np.mod(r_idx,2)==0 and c_idx==cols-1):
pin_b_list.append(INSTR.pin['b1'])
x_list.append(INSTR.pin['b1'].x)
pin_b_list.append(INSTR.pin['b2'])
x_list.append(INSTR.pin['b2'].x)
## revised in 2026.06.07 by Qin Yue
# legacy: pin_b_list.append(INSTR.pin['b1'])
pin_b_list.append(INSTR.pin['opt_b1'])
## revised in 2026.06.07 by Qin Yue
# legacy: x_list.append(INSTR.pin['b1'].x)
x_list.append(INSTR.pin['opt_b1'].x)
## revised in 2026.06.07 by Qin Yue
# legacy: pin_b_list.append(INSTR.pin['b2'])
pin_b_list.append(INSTR.pin['opt_b2'])
## revised in 2026.06.07 by Qin Yue
# legacy: x_list.append(INSTR.pin['b2'].x)
x_list.append(INSTR.pin['opt_b2'].x)
if (np.mod(r_idx,2)==1 and c_idx==0):
pin_a_list.append(INSTR.pin['a1'])
x_list.append(INSTR.pin['a1'].x)
pin_a_list.append(INSTR.pin['a2'])
x_list.append(INSTR.pin['a2'].x)
## revised in 2026.06.07 by Qin Yue
# legacy: pin_a_list.append(INSTR.pin['a1'])
pin_a_list.append(INSTR.pin['opt_a1'])
## revised in 2026.06.07 by Qin Yue
# legacy: x_list.append(INSTR.pin['a1'].x)
x_list.append(INSTR.pin['opt_a1'].x)
## revised in 2026.06.07 by Qin Yue
# legacy: pin_a_list.append(INSTR.pin['a2'])
pin_a_list.append(INSTR.pin['opt_a2'])
## revised in 2026.06.07 by Qin Yue
# legacy: x_list.append(INSTR.pin['a2'].x)
x_list.append(INSTR.pin['opt_a2'].x)
if (r_idx==rows and c_idx==cols-1):
pin_b_list.append(INSTR.pin['b2'])
x_list.append(INSTR.pin['b2'].x)
## revised in 2026.06.07 by Qin Yue
# legacy: pin_b_list.append(INSTR.pin['b2'])
pin_b_list.append(INSTR.pin['opt_b2'])
## revised in 2026.06.07 by Qin Yue
# legacy: x_list.append(INSTR.pin['b2'].x)
x_list.append(INSTR.pin['opt_b2'].x)
if (r_idx==1 and c_idx==cols-1):
pin_b_list.append(INSTR.pin['b1'])
x_list.append(INSTR.pin['b1'].x)
## revised in 2026.06.07 by Qin Yue
# legacy: pin_b_list.append(INSTR.pin['b1'])
pin_b_list.append(INSTR.pin['opt_b1'])
## revised in 2026.06.07 by Qin Yue
# legacy: x_list.append(INSTR.pin['b1'].x)
x_list.append(INSTR.pin['opt_b1'].x)
xmax = np.max(x_list)
xmin = np.min(x_list)
@@ -735,10 +889,14 @@ class MZI_mesh_U:
for _num_ in range(num_compensate_cell) :
self.cell_compensate.put()
nd.strt(
length=abs(self.MZI_unit.pin['a1'].x-self.MZI_unit.pin['b1'].x)-abs(self.cell_compensate.pin['a1'].x-self.cell_compensate.pin['b1'].x),
## revised in 2026.06.07 by Qin Yue
# legacy: length=abs(self.MZI_unit.pin['a1'].x-self.MZI_unit.pin['b1'].x)-abs(self.cell_compensate.pin['a1'].x-self.cell_compensate.pin['b1'].x),
length=abs(self.MZI_unit.pin['opt_a1'].x-self.MZI_unit.pin['opt_b1'].x)-abs(self.cell_compensate.pin['opt_a1'].x-self.cell_compensate.pin['opt_b1'].x),
width=self.w_wg, xs=self.xs_wg
).put()
nd.Pin(name='a'+str(itn+1),pin=nd.Pin().put(),width=0.45).put()
## revised in 2026.06.07 by Qin Yue
# legacy: nd.Pin(name='a'+str(itn+1),pin=nd.Pin().put(),width=0.45).put()
nd.Pin(name='opt_a'+str(itn+1),pin=nd.Pin().put(),width=0.45,type="optical:").put()
nd.strt(length=0.2,width=self.w_wg,xs=self.xs_wg).put(pin_b_list[itn])
num_compensate_cell = len(pin_a_list)-2-itn
@@ -746,10 +904,14 @@ class MZI_mesh_U:
for _num_ in range(num_compensate_cell) :
self.cell_compensate.put(flip=True)
nd.strt(
length=abs(self.MZI_unit.pin['a1'].x-self.MZI_unit.pin['b1'].x)-abs(self.cell_compensate.pin['a1'].x-self.cell_compensate.pin['b1'].x),
## revised in 2026.06.07 by Qin Yue
# legacy: length=abs(self.MZI_unit.pin['a1'].x-self.MZI_unit.pin['b1'].x)-abs(self.cell_compensate.pin['a1'].x-self.cell_compensate.pin['b1'].x),
length=abs(self.MZI_unit.pin['opt_a1'].x-self.MZI_unit.pin['opt_b1'].x)-abs(self.cell_compensate.pin['opt_a1'].x-self.cell_compensate.pin['opt_b1'].x),
width=self.w_wg, xs=self.xs_wg
).put()
nd.Pin(name='b'+str(itn+1),pin=nd.Pin().put(),width=0.45).put()
## revised in 2026.06.07 by Qin Yue
# legacy: nd.Pin(name='b'+str(itn+1),pin=nd.Pin().put(),width=0.45).put()
nd.Pin(name='opt_b'+str(itn+1),pin=nd.Pin().put(),width=0.45,type="optical:").put()
elif self.mesh_type == "parallelogram" :
for itn in range(0,len(pin_a_list)):
@@ -757,17 +919,25 @@ class MZI_mesh_U:
nd.strt(length=self.L_arm,width=self.w_wg,xs=self.xs_wg).put(pin_a_list[itn])
temp = self.cell_compensate.put()
temp = nd.strt(length=abs(xmin-temp.pin['b0'].x),width=self.w_wg,xs=self.xs_wg).put()
nd.Pin(name='a'+str(itn+1) ,width=0.45, pin=temp.pin['b0'].move(-0.05,0,0)).put()
## revised in 2026.06.07 by Qin Yue
# legacy: nd.Pin(name='a'+str(itn+1) ,width=0.45, pin=temp.pin['b0'].move(-0.05,0,0)).put()
nd.Pin(name='opt_a'+str(itn+1) ,width=0.45, pin=temp.pin['b0'].move(-0.05,0,0),type="optical:").put()
else :
nd.Pin(name='a'+str(itn+1) ,width=0.45).put(pin_a_list[itn])
## revised in 2026.06.07 by Qin Yue
# legacy: nd.Pin(name='a'+str(itn+1) ,width=0.45).put(pin_a_list[itn])
nd.Pin(name='opt_a'+str(itn+1) ,width=0.45,type="optical:").put(pin_a_list[itn])
if np.abs(xmax-pin_b_list[itn].x)>0.001 :
nd.strt(length=self.L_arm,width=self.w_wg,xs=self.xs_wg).put(pin_b_list[itn])
temp = self.cell_compensate.put(flip=(itn==0))
temp = nd.strt(length=abs(xmax-temp.pin['b0'].x)+0.001,width=self.w_wg,xs=self.xs_wg).put()
nd.Pin(name='b'+str(itn+1) ,width=0.45, pin=temp.pin['b0'].move(-0.05,0,0)).put()
## revised in 2026.06.07 by Qin Yue
# legacy: nd.Pin(name='b'+str(itn+1) ,width=0.45, pin=temp.pin['b0'].move(-0.05,0,0)).put()
nd.Pin(name='opt_b'+str(itn+1) ,width=0.45, pin=temp.pin['b0'].move(-0.05,0,0),type="optical:").put()
else :
nd.Pin(name='b'+str(itn+1) ,width=0.45).put(pin_b_list[itn])
## revised in 2026.06.07 by Qin Yue
# legacy: nd.Pin(name='b'+str(itn+1) ,width=0.45).put(pin_b_list[itn])
nd.Pin(name='opt_b'+str(itn+1) ,width=0.45,type="optical:").put(pin_b_list[itn])
print("## ===== %s mesh DONE ===== ##" % (self.mesh_type))
@@ -922,18 +1092,28 @@ class AMZI_W:
pic_strip = Route(radius=self.R_bend,width=self.w_wg,xs=self.xs_wg)
self.dL_BS = np.abs(self.BS.pin['a1'].x - self.BS.pin['b1'].x)
## revised in 2026.06.07 by Qin Yue
# legacy: self.dL_BS = np.abs(self.BS.pin['a1'].x - self.BS.pin['b1'].x)
self.dL_BS = np.abs(self.BS.pin['opt_a1'].x - self.BS.pin['opt_b1'].x)
dY_BS = abs(self.BS.pin['b1'].y - self.BS.pin['b2'].y)
## revised in 2026.06.07 by Qin Yue
# legacy: dY_BS = abs(self.BS.pin['b1'].y - self.BS.pin['b2'].y)
dY_BS = abs(self.BS.pin['opt_b1'].y - self.BS.pin['opt_b2'].y)
dYarm = self.D_arm/2 - self.BS.pin['b1'].y
## revised in 2026.06.07 by Qin Yue
# legacy: dYarm = self.D_arm/2 - self.BS.pin['b1'].y
dYarm = self.D_arm/2 - self.BS.pin['opt_b1'].y
dLmin = np.sqrt(abs(self.R_bend**2 - (self.R_bend-dYarm)**2))*2
if (dLmin>2*self.R_bend):
dLmin = 2*self.R_bend
BS_L = self.BS.put('b1',-dLmin - self.L_arm/2-1,dY_BS/2,180)
BS_R = self.BS.put('a2', dLmin + self.L_arm/2+1,dY_BS/2,0,flip=1)
## revised in 2026.06.07 by Qin Yue
# legacy: BS_L = self.BS.put('b1',-dLmin - self.L_arm/2-1,dY_BS/2,180)
BS_L = self.BS.put('opt_b1',-dLmin - self.L_arm/2-1,dY_BS/2,180)
## revised in 2026.06.07 by Qin Yue
# legacy: BS_R = self.BS.put('a2', dLmin + self.L_arm/2+1,dY_BS/2,0,flip=1)
BS_R = self.BS.put('opt_a2', dLmin + self.L_arm/2+1,dY_BS/2,0,flip=1)
wg_ht = W_waveguide(L_wg=self.L_arm,w_wg=self.w_wg,xs_wg=self.xs_wg,
dL=self.dL_ht+self.dL_AMZI/2/self.n_bend,R_bend=self.R_bend,
@@ -953,32 +1133,68 @@ class AMZI_W:
).cell
wg_U = wg_ht.put('a1',-self.L_arm/2,self.D_arm/2,0)
wg_D = wg_oht.put('a1',-self.L_arm/2,-self.D_arm/2,0,flip=1)
## revised in 2026.06.07 by Qin Yue
# legacy: wg_U = wg_ht.put('a1',-self.L_arm/2,self.D_arm/2,0)
wg_U = wg_ht.put('opt_a1',-self.L_arm/2,self.D_arm/2,0)
## revised in 2026.06.07 by Qin Yue
# legacy: wg_D = wg_oht.put('a1',-self.L_arm/2,-self.D_arm/2,0,flip=1)
wg_D = wg_oht.put('opt_a1',-self.L_arm/2,-self.D_arm/2,0,flip=1)
pic_strip.sbend_p2p(pin1=BS_L.pin['b1'],pin2=wg_U.pin['a1']).put()
pic_strip.sbend_p2p(pin1=BS_L.pin['b2'],pin2=wg_D.pin['a1']).put()
pic_strip.sbend_p2p(pin1=BS_R.pin['a2'],pin2=wg_U.pin['b1']).put()
pic_strip.sbend_p2p(pin1=BS_R.pin['a1'],pin2=wg_D.pin['b1']).put()
## revised in 2026.06.07 by Qin Yue
# legacy: pic_strip.sbend_p2p(pin1=BS_L.pin['b1'],pin2=wg_U.pin['a1']).put()
pic_strip.sbend_p2p(pin1=BS_L.pin['opt_b1'],pin2=wg_U.pin['opt_a1']).put()
## revised in 2026.06.07 by Qin Yue
# legacy: pic_strip.sbend_p2p(pin1=BS_L.pin['b2'],pin2=wg_D.pin['a1']).put()
pic_strip.sbend_p2p(pin1=BS_L.pin['opt_b2'],pin2=wg_D.pin['opt_a1']).put()
## revised in 2026.06.07 by Qin Yue
# legacy: pic_strip.sbend_p2p(pin1=BS_R.pin['a2'],pin2=wg_U.pin['b1']).put()
pic_strip.sbend_p2p(pin1=BS_R.pin['opt_a2'],pin2=wg_U.pin['opt_b1']).put()
## revised in 2026.06.07 by Qin Yue
# legacy: pic_strip.sbend_p2p(pin1=BS_R.pin['a1'],pin2=wg_D.pin['b1']).put()
pic_strip.sbend_p2p(pin1=BS_R.pin['opt_a1'],pin2=wg_D.pin['opt_b1']).put()
patch_U = nd.strt(length=0.5,width=self.w_wg,xs=self.xs_wg).put('a0',BS_L.pin['a2'].x-self.R_bend*2-1, self.D_port/2,180)
patch_D = nd.strt(length=0.5,width=self.w_wg,xs=self.xs_wg).put('a0',BS_L.pin['a1'].x-self.R_bend*2-1,-self.D_port/2,180)
## revised in 2026.06.07 by Qin Yue
# legacy: patch_U = nd.strt(length=0.5,width=self.w_wg,xs=self.xs_wg).put('a0',BS_L.pin['a2'].x-self.R_bend*2-1, self.D_port/2,180)
patch_U = nd.strt(length=0.5,width=self.w_wg,xs=self.xs_wg).put('a0',BS_L.pin['opt_a2'].x-self.R_bend*2-1, self.D_port/2,180)
## revised in 2026.06.07 by Qin Yue
# legacy: patch_D = nd.strt(length=0.5,width=self.w_wg,xs=self.xs_wg).put('a0',BS_L.pin['a1'].x-self.R_bend*2-1,-self.D_port/2,180)
patch_D = nd.strt(length=0.5,width=self.w_wg,xs=self.xs_wg).put('a0',BS_L.pin['opt_a1'].x-self.R_bend*2-1,-self.D_port/2,180)
pic_strip.sbend_p2p(pin1=patch_U.pin['a0'],pin2=BS_L.pin['a1']).put()
pic_strip.sbend_p2p(pin1=patch_D.pin['a0'],pin2=BS_L.pin['a2']).put()
## revised in 2026.06.07 by Qin Yue
# legacy: pic_strip.sbend_p2p(pin1=patch_U.pin['a0'],pin2=BS_L.pin['a1']).put()
pic_strip.sbend_p2p(pin1=patch_U.pin['a0'],pin2=BS_L.pin['opt_a1']).put()
## revised in 2026.06.07 by Qin Yue
# legacy: pic_strip.sbend_p2p(pin1=patch_D.pin['a0'],pin2=BS_L.pin['a2']).put()
pic_strip.sbend_p2p(pin1=patch_D.pin['a0'],pin2=BS_L.pin['opt_a2']).put()
nd.Pin(name='a1',pin=patch_U.pin['b0'].move(-0.05,0,0),width=self.w_wg).put()
nd.Pin(name='a2',pin=patch_D.pin['b0'].move(-0.05,0,0),width=self.w_wg).put()
## revised in 2026.06.07 by Qin Yue
# legacy: nd.Pin(name='a1',pin=patch_U.pin['b0'].move(-0.05,0,0),width=self.w_wg).put()
nd.Pin(name='opt_a1',pin=patch_U.pin['b0'].move(-0.05,0,0),width=self.w_wg,type="optical:").put()
## revised in 2026.06.07 by Qin Yue
# legacy: nd.Pin(name='a2',pin=patch_D.pin['b0'].move(-0.05,0,0),width=self.w_wg).put()
nd.Pin(name='opt_a2',pin=patch_D.pin['b0'].move(-0.05,0,0),width=self.w_wg,type="optical:").put()
patch_U = nd.strt(length=0.5,width=self.w_wg,xs=self.xs_wg).put('a0',BS_R.pin['b2'].x+self.R_bend*2+1, self.D_port/2,0)
patch_D = nd.strt(length=0.5,width=self.w_wg,xs=self.xs_wg).put('a0',BS_R.pin['b1'].x+self.R_bend*2+1,-self.D_port/2,0)
## revised in 2026.06.07 by Qin Yue
# legacy: patch_U = nd.strt(length=0.5,width=self.w_wg,xs=self.xs_wg).put('a0',BS_R.pin['b2'].x+self.R_bend*2+1, self.D_port/2,0)
patch_U = nd.strt(length=0.5,width=self.w_wg,xs=self.xs_wg).put('a0',BS_R.pin['opt_b2'].x+self.R_bend*2+1, self.D_port/2,0)
## revised in 2026.06.07 by Qin Yue
# legacy: patch_D = nd.strt(length=0.5,width=self.w_wg,xs=self.xs_wg).put('a0',BS_R.pin['b1'].x+self.R_bend*2+1,-self.D_port/2,0)
patch_D = nd.strt(length=0.5,width=self.w_wg,xs=self.xs_wg).put('a0',BS_R.pin['opt_b1'].x+self.R_bend*2+1,-self.D_port/2,0)
pic_strip.sbend_p2p(pin1=patch_U.pin['a0'],pin2=BS_R.pin['b2']).put()
pic_strip.sbend_p2p(pin1=patch_D.pin['a0'],pin2=BS_R.pin['b1']).put()
## revised in 2026.06.07 by Qin Yue
# legacy: pic_strip.sbend_p2p(pin1=patch_U.pin['a0'],pin2=BS_R.pin['b2']).put()
pic_strip.sbend_p2p(pin1=patch_U.pin['a0'],pin2=BS_R.pin['opt_b2']).put()
## revised in 2026.06.07 by Qin Yue
# legacy: pic_strip.sbend_p2p(pin1=patch_D.pin['a0'],pin2=BS_R.pin['b1']).put()
pic_strip.sbend_p2p(pin1=patch_D.pin['a0'],pin2=BS_R.pin['opt_b1']).put()
nd.Pin(name='b1',pin=patch_U.pin['b0'].move(-0.05,0,0),width=self.w_wg).put()
nd.Pin(name='b2',pin=patch_D.pin['b0'].move(-0.05,0,0),width=self.w_wg).put()
## revised in 2026.06.07 by Qin Yue
# legacy: nd.Pin(name='b1',pin=patch_U.pin['b0'].move(-0.05,0,0),width=self.w_wg).put()
nd.Pin(name='opt_b1',pin=patch_U.pin['b0'].move(-0.05,0,0),width=self.w_wg,type="optical:").put()
## revised in 2026.06.07 by Qin Yue
# legacy: nd.Pin(name='b2',pin=patch_D.pin['b0'].move(-0.05,0,0),width=self.w_wg).put()
nd.Pin(name='opt_b2',pin=patch_D.pin['b0'].move(-0.05,0,0),width=self.w_wg,type="optical:").put()
if (self.w_ht>0):
nd.Pin(name='ep1',pin=wg_U.pin['ep1']).put()
@@ -1003,23 +1219,37 @@ class AMZI_W:
GC3Instr = gc_cell.put('g1',0,-dYgc2gc,180)
GC4Instr = gc_cell.put('g1',dXgc2gc,-dYgc2gc,0)
dYcell = abs(self.cell.pin['a1'].y - self.cell.pin['a2'].y)
## revised in 2026.06.07 by Qin Yue
# legacy: dYcell = abs(self.cell.pin['a1'].y - self.cell.pin['a2'].y)
dYcell = abs(self.cell.pin['opt_a1'].y - self.cell.pin['opt_a2'].y)
dYoffset = (dYcell - dYgc2gc)/2
dXcell = abs(self.cell.pin['a1'].x - self.cell.pin['b1'].x)
## revised in 2026.06.07 by Qin Yue
# legacy: dXcell = abs(self.cell.pin['a1'].x - self.cell.pin['b1'].x)
dXcell = abs(self.cell.pin['opt_a1'].x - self.cell.pin['opt_b1'].x)
dXoffset = -(dXcell - dXgc2gc)/2
cellInstr = self.cell.put('a1',dXoffset,dYoffset,0)
## revised in 2026.06.07 by Qin Yue
# legacy: cellInstr = self.cell.put('a1',dXoffset,dYoffset,0)
cellInstr = self.cell.put('opt_a1',dXoffset,dYoffset,0)
pic = Route(xs=self.xs_wg,width=w_wg,radius=R_bend)
pic.sbend_p2p(pin1=cellInstr.pin['a1'],pin2=GC1Instr.pin['g1']).put()
pic.sbend_p2p(pin1=cellInstr.pin['b1'],pin2=GC2Instr.pin['g1']).put()
pic.sbend_p2p(pin1=cellInstr.pin['a2'],pin2=GC3Instr.pin['g1']).put()
pic.sbend_p2p(pin1=cellInstr.pin['b2'],pin2=GC4Instr.pin['g1']).put()
## revised in 2026.06.07 by Qin Yue
# legacy: pic.sbend_p2p(pin1=cellInstr.pin['a1'],pin2=GC1Instr.pin['g1']).put()
pic.sbend_p2p(pin1=cellInstr.pin['opt_a1'],pin2=GC1Instr.pin['g1']).put()
## revised in 2026.06.07 by Qin Yue
# legacy: pic.sbend_p2p(pin1=cellInstr.pin['b1'],pin2=GC2Instr.pin['g1']).put()
pic.sbend_p2p(pin1=cellInstr.pin['opt_b1'],pin2=GC2Instr.pin['g1']).put()
## revised in 2026.06.07 by Qin Yue
# legacy: pic.sbend_p2p(pin1=cellInstr.pin['a2'],pin2=GC3Instr.pin['g1']).put()
pic.sbend_p2p(pin1=cellInstr.pin['opt_a2'],pin2=GC3Instr.pin['g1']).put()
## revised in 2026.06.07 by Qin Yue
# legacy: pic.sbend_p2p(pin1=cellInstr.pin['b2'],pin2=GC4Instr.pin['g1']).put()
pic.sbend_p2p(pin1=cellInstr.pin['opt_b2'],pin2=GC4Instr.pin['g1']).put()
+46 -16
View File
@@ -44,9 +44,13 @@ class SplittingTree():
# self.yb_length = ybranch.length
self.yb_length = np.abs(self.yb_cell.pin['a1'].x - self.yb_cell.pin['b1'].x)
## revised in 2026.06.07 by Qin Yue
# legacy: self.yb_length = np.abs(self.yb_cell.pin['a1'].x - self.yb_cell.pin['b1'].x)
self.yb_length = np.abs(self.yb_cell.pin['opt_a1'].x - self.yb_cell.pin['opt_b1'].x)
# self.yb_width = ybranch.width
self.yb_width = np.abs(self.yb_cell.pin['b1'].y - self.yb_cell.pin['b2'].y)
## revised in 2026.06.07 by Qin Yue
# legacy: self.yb_width = np.abs(self.yb_cell.pin['b1'].y - self.yb_cell.pin['b2'].y)
self.yb_width = np.abs(self.yb_cell.pin['opt_b1'].y - self.yb_cell.pin['opt_b2'].y)
self.w_wg = ybranch.w_wg
self.output_number = output_number
@@ -85,29 +89,49 @@ class SplittingTree():
for yb_index in range(np.power(2, level_index)):
y_cur = y_pitch * ((np.power(2, level_index)-1)/2 - yb_index)
# Put the Y-branch
cell_dic[str(level_index)+str(yb_index)] = self.yb_cell.put('a1', x_cur, y_cur)
## revised in 2026.06.07 by Qin Yue
# legacy: cell_dic[str(level_index)+str(yb_index)] = self.yb_cell.put('a1', x_cur, y_cur)
cell_dic[str(level_index)+str(yb_index)] = self.yb_cell.put('opt_a1', x_cur, y_cur)
# Do the routing
stripe_class.sbend_p2p(
pin1=cell_dic[str(level_index-1)+str(yb_index//2)].pin['b'+str(yb_index%2+1)],
pin2=cell_dic[str(level_index)+str(yb_index)].pin['a1'],
## revised in 2026.06.07 by Qin Yue
# legacy: pin1=cell_dic[str(level_index-1)+str(yb_index//2)].pin['b'+str(yb_index%2+1)],
pin1=cell_dic[str(level_index-1)+str(yb_index//2)].pin['opt_b'+str(yb_index%2+1)],
## revised in 2026.06.07 by Qin Yue
# legacy: pin2=cell_dic[str(level_index)+str(yb_index)].pin['a1'],
pin2=cell_dic[str(level_index)+str(yb_index)].pin['opt_a1'],
Lstart=1,
arrow=False
).put()
## Put pins
nd.Pin(name="a0").put(0, 0, 180)
nd.Pin(name="a1",width=self.w_wg).put(0, 0, 180)
## revised in 2026.06.07 by Qin Yue
# legacy: nd.Pin(name="a1",width=self.w_wg).put(0, 0, 180)
nd.Pin(name="opt_a1",width=self.w_wg,type="optical:").put(0, 0, 180)
level_index = int(self.level_number-1)
for yb_index in range(np.power(2, level_index)):
nd.Pin(
name="b"+str(2*yb_index+1),
width=self.w_wg
).put(cell_dic[str(level_index)+str(yb_index)].pin['b1'])
## revised in 2026.06.07 by Qin Yue
# legacy: name="b"+str(2*yb_index+1),
name="opt_b"+str(2*yb_index+1),
width=self.w_wg,
type="optical:"
## revised in 2026.06.07 by Qin Yue
# legacy: ).put(cell_dic[str(level_index)+str(yb_index)].pin['b1'])
).put(cell_dic[str(level_index)+str(yb_index)].pin['opt_b1'])
nd.Pin(
name="b"+str(2*yb_index+2),
width=self.w_wg
).put(cell_dic[str(level_index)+str(yb_index)].pin['b2'])
## revised in 2026.06.07 by Qin Yue
# legacy: name="b"+str(2*yb_index+2),
name="opt_b"+str(2*yb_index+2),
width=self.w_wg,
type="optical:"
## revised in 2026.06.07 by Qin Yue
# legacy: ).put(cell_dic[str(level_index)+str(yb_index)].pin['b2'])
).put(cell_dic[str(level_index)+str(yb_index)].pin['opt_b2'])
nd.Pin(name="b0").put(
cell_dic[str(level_index)+str(yb_index)].pin['b2'].x,
## revised in 2026.06.07 by Qin Yue
# legacy: cell_dic[str(level_index)+str(yb_index)].pin['b2'].x,
cell_dic[str(level_index)+str(yb_index)].pin['opt_b2'].x,
0,
0
)
@@ -130,7 +154,13 @@ class SplittingTree():
nd.strt(length=0.2, width=self.w_wg, layer=(1001, 2)).put(self.yb_length, -self.yb_width/2, 180)
## Put pins
nd.Pin(name="a0", width=self.w_wg).put(0, 0, 180)
nd.Pin(name="a1", width=self.w_wg).put(0, 0, 180)
nd.Pin(name="b1", width=self.w_wg).put(self.yb_length, self.yb_width/2, 0)
nd.Pin(name="b2", width=self.w_wg).put(self.yb_length, -self.yb_width/2, 0)
## revised in 2026.06.07 by Qin Yue
# legacy: nd.Pin(name="a1", width=self.w_wg).put(0, 0, 180)
nd.Pin(name="opt_a1", width=self.w_wg,type="optical:").put(0, 0, 180)
## revised in 2026.06.07 by Qin Yue
# legacy: nd.Pin(name="b1", width=self.w_wg).put(self.yb_length, self.yb_width/2, 0)
nd.Pin(name="opt_b1", width=self.w_wg,type="optical:").put(self.yb_length, self.yb_width/2, 0)
## revised in 2026.06.07 by Qin Yue
# legacy: nd.Pin(name="b2", width=self.w_wg).put(self.yb_length, -self.yb_width/2, 0)
nd.Pin(name="opt_b2", width=self.w_wg,type="optical:").put(self.yb_length, -self.yb_width/2, 0)
self.yb_cell = C