Files

104 lines
5.1 KiB
Python

"""Racetrack geometry primitive."""
from typing import Any, Optional
import nazca as nd
import numpy as np
from .rings import circle
class Racetrack:
def __init__(self,
bend_cell: Any=None,
xs: str = 'strip',
layer: Optional[str] = None,
R_bend: int = 10,
w: float = 0.5,
dLx: float = 100,
dLy: float = 100,
# n_points = 128,
res: float = 0.001,
) -> None:
if (bend_cell==None):
bend_cell = circle(xs=xs,theta_start=0,theta_stop=90,res=res,
# n_points=n_points,
radius=R_bend,width=w).cell
if (isinstance(bend_cell,nd.Cell)):
bend_cell = bend_cell
elif (hasattr(bend_cell,'cell')) :
bend_cell = bend_cell.cell
else:
raise Exception("ERROR: In <mxpic::structure::Racetrack>, <bend_cell> not a regonizable class, please input [nd.Cell] or class with [nd.Cell]")
self.dLx = dLx
self.R_bend =R_bend
self.dLy = dLy
self.xs = xs
self.layer = layer
self.bend_cell = bend_cell
## revised in 2026.06.07 by Qin Yue
# legacy: self.A_bend = np.abs(bend_cell.pin['a1'].a - bend_cell.pin['b1'].a)
self.A_bend = np.abs(bend_cell.pin['opt_a1'].a - bend_cell.pin['opt_b1'].a)
## revised in 2026.06.07 by Qin Yue
# legacy: self.w = [bend_cell.pin['b1'].width,bend_cell.pin['a1'].width]
self.w = [bend_cell.pin['opt_b1'].width,bend_cell.pin['opt_a1'].width]
self.w_crack = 0.002
self.cell = self.generate_gds()
def generate_gds(self):
with nd.Cell(instantiate=False) as C:
bend_sz = [ abs(self.bend_cell.pin['a0'].x - self.bend_cell.pin['b0'].x)
,abs(self.bend_cell.pin['a0'].y - self.bend_cell.pin['b0'].y)]
if (self.layer==None):
if (self.A_bend==90):
nd.strt(length=self.dLx+self.w_crack,width=self.w[1],xs=self.xs).put(-self.dLx/2-self.w_crack/2,-self.dLy/2-bend_sz[1],0)
self.bend_cell.put(-self.dLx/2,-self.dLy/2-bend_sz[1],0,flip=0)
nd.strt(length=self.dLy+self.w_crack,width=self.w[0],xs=self.xs).put( self.dLx/2+bend_sz[0],-self.dLy/2-self.w_crack/2,90)
self.bend_cell.put( self.dLx/2,-self.dLy/2-bend_sz[1],180,flip=1)
nd.strt(length=self.dLx+self.w_crack,width=self.w[1],xs=self.xs).put(-self.dLx/2-self.w_crack/2, self.dLy/2+bend_sz[1],0)
self.bend_cell.put(-self.dLx/2, self.dLy/2+bend_sz[1],0,flip=1)
nd.strt(length=self.dLy+self.w_crack,width=self.w[0],xs=self.xs).put(-self.dLx/2-bend_sz[0],-self.dLy/2-self.w_crack/2,90)
self.bend_cell.put( self.dLx/2, self.dLy/2+bend_sz[1],180,flip=0)
elif (self.A_bend==0 or self.A_bend==360): ## in this case, dy is not used
temp = nd.strt(length=self.dLx,width=self.w[0],xs=self.xs).put(-self.dLx/2,-self.dLy/2-bend_sz[1],0)
sp_r = self.bend_cell.put()
sp_l = self.bend_cell.put(temp.pin['a0'].xya(),flip=1)
temp = nd.strt(length=np.abs(sp_r.pin['b0'].x-sp_l.pin['b0'].x),width=sp_r.pin['b0'].width,xs=self.xs).put()
else:
if (self.A_bend==90):
nd.strt(length=self.dLx,width=self.w[0],layer=self.layer).put(-self.dLx/2,-self.dLy/2-bend_sz[1],0)
temp = self.bend_cell.put()
temp = nd.strt(length=self.dLy,width=self.w[1],layer=self.layer).put()
temp = self.bend_cell.put('b0',temp.pin['b0'].xya(),flip=1)
temp = nd.strt(length=self.dLx,width=self.w[0],layer=self.layer).put(temp.pin['a0'].xya())
temp = self.bend_cell.put()
temp = nd.strt(length=self.dLy,width=self.w[1],layer=self.layer).put()
temp = self.bend_cell.put('b0',temp.pin['b0'].xya(),flip=1)
elif (self.A_bend==0 or self.A_bend==360): ## in this case, dy is not used
temp = nd.strt(length=self.dLx,width=self.w[0],layer=self.layer).put(-self.dLx/2,-self.dLy/2-bend_sz[1],0)
sp_r = self.bend_cell.put()
sp_l = self.bend_cell.put(temp.pin['a0'].xya(),flip=1)
temp = nd.strt(length=np.abs(sp_r.pin['b0'].x-sp_l.pin['b0'].x),width=sp_r.pin['b0'].width,layer=self.layer).put()
nd.Pin(name="r1",width=self.w[0]).put(0,-self.dLy/2-bend_sz[1],0)
nd.Pin(name="r3",width=self.w[0]).put(0, self.dLy/2+bend_sz[1],180)
nd.Pin(name="r2",width=self.w[1]).put(-self.dLx/2-bend_sz[0], 0, 90)
nd.Pin(name="r4",width=self.w[1]).put( self.dLx/2+bend_sz[0], 0,-90)
sz = [2*bend_sz[0]+self.dLx,2*bend_sz[1]+self.dLy]
self.sz = sz
return C