示例#1
0
    def gds(self, filename=None, view=False, extra=0, units="nms"):
        """Writes the geometry to the gds file.

        Parameters
        ----------
        filename : str, optional
            Location to save file to. Defaults to None.
        extra : int, optional
            Extra straight portion to add to ends of waveguides to make room in simulation
            (units same as units parameter). Defaults to 0.
        units : {'microns' or 'nms'}, optional
            Units to save gds file in. Defaults to microns.
        view : bool, optional
            Whether to visually show gds file. Defaults to False.
        """
        # check to make sure the geometry isn't an array
        if len(self._clean_args(None)[0]) != 1:
            raise ValueError(
                "You have changing geometries, making gds doesn't make sense")

        if units == "nms":
            scale = 1e-3
        elif units == "microns":
            scale = 1
        else:
            raise ValueError("Invalid units")

        # scale to proper units
        sc_radius = self.radius * scale
        sc_gap = self.gap * scale
        sc_width = self.width * scale
        sc_length = self.length * scale

        # write to GDS
        pathTop = gdspy.Path(
            sc_width,
            (-sc_length / 2, 2 * sc_radius + sc_width / 2 + sc_gap / 2))
        pathTop.segment(sc_length, "+x")
        pathTop.turn(sc_radius, "rr")
        pathTop.segment(sc_length, "-x")
        pathTop.turn(sc_radius, "rr")

        pathBottom = gdspy.Path(
            sc_width,
            (-sc_radius - sc_width / 2 - sc_length / 2,
             -sc_gap / 2 - sc_width / 2),
        )
        pathBottom.segment(2 * (sc_radius + sc_width / 2) + sc_length, "+x")

        gdspy.current_library = gdspy.GdsLibrary()
        path_cell = gdspy.Cell("C0")
        path_cell.add(pathTop)
        path_cell.add(pathBottom)

        if view:
            gdspy.LayoutViewer(cells="C0")

        if filename is not None:
            writer = gdspy.GdsWriter(filename, unit=1.0e-6, precision=1.0e-9)
            writer.write_cell(path_cell)
            writer.close()
示例#2
0
def test_writer_gds(tmpdir):
    lib = gdspy.GdsLibrary()
    c1 = gdspy.Cell("gw_rw_gds_1")
    c1.add(gdspy.Rectangle((0, -1), (1, 2), 2, 4))
    c1.add(gdspy.Label("label", (1, -1), "w", 45, 1.5, True, 5, 6))
    c2 = gdspy.Cell("gw_rw_gds_2")
    c2.add(gdspy.Round((0, 0), 1, number_of_points=32, max_points=20))
    c3 = gdspy.Cell("gw_rw_gds_3")
    c3.add(gdspy.CellReference(c1, (0, 1), -90, 2, True))
    c4 = gdspy.Cell("gw_rw_gds_4")
    c4.add(gdspy.CellArray(c2, 2, 3, (1, 4), (-1, -2), 180, 0.5, True))
    lib.add((c1, c2, c3, c4))

    fname1 = str(tmpdir.join("test1.gds"))
    writer1 = gdspy.GdsWriter(fname1, name="lib", unit=2e-3, precision=1e-5)
    for c in lib.cells.values():
        writer1.write_cell(c)
    writer1.close()
    lib1 = gdspy.GdsLibrary(unit=1e-3)
    lib1.read_gds(
        fname1,
        units="convert",
        rename={"gw_rw_gds_1": "1"},
        layers={2: 4},
        datatypes={4: 2},
        texttypes={6: 7},
    )
    assert lib1.name == "lib"
    assert len(lib1.cells) == 4
    assert set(lib1.cells.keys()) == {"1", "gw_rw_gds_2", "gw_rw_gds_3", "gw_rw_gds_4"}
    c = lib1.cells["1"]
    assert len(c.polygons) == len(c.labels) == 1
    assert c.polygons[0].area() == 12.0
    assert c.polygons[0].layers == [4]
    assert c.polygons[0].datatypes == [2]
    assert c.labels[0].text == "label"
    assert c.labels[0].position[0] == 2 and c.labels[0].position[1] == -2
    assert c.labels[0].anchor == 4
    assert c.labels[0].rotation == 45
    assert c.labels[0].magnification == 1.5
    assert c.labels[0].x_reflection == True
    assert c.labels[0].layer == 5
    assert c.labels[0].texttype == 7

    c = lib1.cells["gw_rw_gds_2"]
    assert len(c.polygons) == 2
    assert isinstance(c.polygons[0], gdspy.Polygon) and isinstance(
        c.polygons[1], gdspy.Polygon
    )

    c = lib1.cells["gw_rw_gds_3"]
    assert len(c.references) == 1
    assert isinstance(c.references[0], gdspy.CellReference)
    assert c.references[0].ref_cell == lib1.cells["1"]
    assert c.references[0].origin[0] == 0 and c.references[0].origin[1] == 2
    assert c.references[0].rotation == -90
    assert c.references[0].magnification == 2
    assert c.references[0].x_reflection == True

    c = lib1.cells["gw_rw_gds_4"]
    assert len(c.references) == 1
    assert isinstance(c.references[0], gdspy.CellArray)
    assert c.references[0].ref_cell == lib1.cells["gw_rw_gds_2"]
    assert c.references[0].origin[0] == -2 and c.references[0].origin[1] == -4
    assert c.references[0].rotation == 180
    assert c.references[0].magnification == 0.5
    assert c.references[0].x_reflection == True
    assert c.references[0].spacing[0] == 2 and c.references[0].spacing[1] == 8
    assert c.references[0].columns == 2
    assert c.references[0].rows == 3

    fname2 = str(tmpdir.join("test2.gds"))
    with open(fname2, "wb") as fout:
        writer2 = gdspy.GdsWriter(fout, name="lib2", unit=2e-3, precision=1e-5)
        for c in lib.cells.values():
            writer2.write_cell(c)
        writer2.close()
    with open(fname2, "rb") as fin:
        lib2 = gdspy.GdsLibrary()
        lib2.read_gds(fin)
    assert lib2.name == "lib2"
    assert len(lib2.cells) == 4
n = 20  # loop counter
gap_step = (gap1 - gap0) / (n - 1)  #sweep gap parameter

alL = 350  #aligment distance to device

final_pos = numpy.array([
    (2 * r1 + sec_gap + taper_l + taper_ii_l) * 2 + iii_v_l, (n * d)
])

hw = 3.0  #nicr heater width
hh = 20.0  #nicr heater height
ang = pi / 6.0  # 30° heater
sqr = 10.0

httiaucell = gdspy.Cell('Heater_Ti_Au')


def nicrheat(layer_num, center, radius, hw, hh, ang, sqr):
    pos1 = (center[0] - radius * sin(ang), center[1] - radius * cos(ang))
    pos2 = (center[0] + radius * sin(ang), center[1] - radius * cos(ang))

    nch1 = gdspy.Round(center,
                       radius + hw / 2,
                       radius - hw / 2,
                       initial_angle=-ang - pi / 2.0,
                       final_angle=ang - pi / 2.0,
                       layer=layer_num,
                       max_points=4094,
                       number_of_points=0.1)
    nch2 = gdspy.Rectangle((pos1[0] + hw, pos1[1]), (pos1[0], pos1[1] - hh),
示例#4
0
        self.add(path_clad)

    def __build_ports(self):
        # Portlist format:
        # example: example:  {'port':(x_position, y_position), 'direction': 'NORTH'}
        self.portlist["input"] = {"port": (0, 0), "direction": "WEST"}
        self.portlist["output"] = {
            "port": (self.length, 0),
            "direction": "EAST"
        }


if __name__ == "__main__":
    from . import *

    top = gdspy.Cell("top")
    wgt_strip = WaveguideTemplate(bend_radius=50,
                                  wg_type="strip",
                                  wg_width=0.7)
    wgt_slot = WaveguideTemplate(bend_radius=50,
                                 wg_type="slot",
                                 wg_width=0.7,
                                 slot=0.2)

    wg1 = Waveguide([(0, 0), (100, 100)], wgt_strip)
    tk.add(top, wg1)

    ycoup = StripSlotYConverter(wgt_strip,
                                wgt_slot,
                                10.0,
                                0.2,
示例#5
0
# wlow, llow = [39.81, 4051.32]  # Low Z section
whigh, lhigh = [2, 4051.32]  # High Z section

rcav, rlow, rhigh = [50, 50, 50]

# layers
sub_layer = 0
dot_layer = 1
cond_layer = 2
rem_layer = 3

# Start making resonator geometry
############################################################################

# # Setup gds cell and gds object
poly_cell = gdspy.Cell('POLYGONS')
rs = Shapes(poly_cell)

# Substrate coordinate list
sub = rs.rect(sub_x, sub_y, wrhead_xoff, wrhead_yoff)
substrate = gdspy.Polygon(sub, layer=sub_layer)

# Dots
layout = LayoutComponents(poly_cell, sub_x, sub_y, layer=dot_layer)
dots = layout.antidot_array(wrhead_xoff, wrhead_yoff, 10, 30, 0)

coords = lambda x, dx=0: x + dx
lcav1, lcav2, arcc = cavlengths(lc, rcav)
# xb_strt,yb_strt = [coords(sub_x/2-arcc),coords(sub_y/2)]
xb_strt, yb_strt = [
    coords(sub_x / 2, wrhead_xoff),
from numpy import *
import gdspy
import gdslib
import os
deviceName = '2016Mar29_Resonators'
device = gdspy.Cell(deviceName)
print(os.getcwd())
# print(os.chdir("C:/Users/Michael/Dropbox/GitHub/PainterQubits/devMichael/AutoCAD/gdspy"))
# FREQUENCY DESIGN
# [1] Coplanar Waveguide Circuits, Components, and Systems by Rainee Simons
c = 3E8
er = 11.9  # Substrate dielectric constant
ereff = (1 + er) / 2
# [1] Eq. 2.30

# BOUNDARY DEFINITIONS
# Boundary of section of chip containing features
device.add(gdspy.Rectangle((0, 0), (10000, 5000), layer=1))

# Boundary of the entire 1 cm chip
device.add(gdspy.Rectangle((0, 0), (10000, 10000), layer=2))

# Approximate clip placement area
device.add(gdspy.Rectangle((2500, 7000), (7500, 10000), layer=3))

# Stitch
for i in range(0, 1250):
    device.add(gdspy.Rectangle((0, 8 * i), (10000, 8 * i + 4), layer=7))
    device.add(gdspy.Rectangle((8 * i, 0), (8 * i + 4, 10000), layer=7))

# FEEDLINE
示例#7
0
    cavity_cell.add(cav1)
    cavity_cell.add(cav2)
    cavity_cell.add(cav3)
    cavity_cell.add(
        cav12)  # Cell: Cavity; Objects: coupled rings, ring trenching

    # --------- Taper sections --------------------------- #

    return (wg_cell, cavity_cell)


#waveguidex = draw(-1)[4]
#waveguidey = draw(-2)[5]
#
#
combined_cell = gdspy.Cell('COMB1')
#combined_cell2=gdspy.Cell('COMB2')

#(wv,cc,gratc,nfc,wgx,wgy) = draw(gap0+gap_step*(ii))
#combined_cell.add(gdspy.CellReference(wv,origin=(0,-ii*d)))
#combined_cell.add(gdspy.CellReference(wv,origin=(2*wgx + 2*(taper_ii_l)+iii_v_l, wgy-ii*d ),rotation=180, x_reflection=True))
for ii in range(0, n, 1):

    (wv, cc) = draw(gap0 + gap_step * (ii))

    combined_cell.add(gdspy.CellReference(wv, origin=(0, -ii * d)))
    combined_cell.add(gdspy.CellReference(cc, origin=(0, -ii * d)))

## ------------------------------------------------------------------ ##
##	OUTPUT															  ##
## ------------------------------------------------------------------ ##
示例#8
0
def test_robustpath2(target):
    cell = gdspy.Cell("test")
    rp = gdspy.RobustPath((0, 0), [0.1, 0.2, 0.1], 0.15, layer=[1, 2, 3])
    assert len(rp) == 0
    rp.segment((1, 0))
    rp.segment((1, 1), 0.1, 0.05)
    rp.segment((1, 1), [0.2, 0.1, 0.1], -0.05, True)
    rp.segment((-1, 1), 0.2, [-0.2, 0, 0.3], True)
    rp.arc(2, 0, 0.5 * numpy.pi)
    rp.arc(3, 0.7 * numpy.pi, numpy.pi, 0.1, 0)
    rp.arc(2, 0.4 * numpy.pi, -0.4 * numpy.pi, [0.1, 0.2, 0.1], [0.2, 0, -0.2])
    rp.turn(1, -0.3 * numpy.pi)
    rp.turn(1, "rr", 0.15)
    rp.turn(0.5, "l", [0.05, 0.1, 0.05], [0.15, 0, -0.15])
    assert len(rp) == 10
    cell.add(rp)
    rp = gdspy.RobustPath((-5, 6), 0.8, layer=20, ends="round", tolerance=1e-4)
    rp.segment((1, 1), 0.1, relative=True)
    cell.add(rp)
    rp = gdspy.RobustPath((-5, 6),
                          0.8,
                          layer=21,
                          ends="extended",
                          tolerance=1e-4)
    rp.segment((1, 1), 0.1, relative=True)
    cell.add(rp)
    rp = gdspy.RobustPath((-5, 6),
                          0.8,
                          layer=22,
                          ends=(0.1, 0.2),
                          tolerance=1e-4)
    rp.segment((1, 1), 0.1, relative=True)
    cell.add(rp)
    rp = gdspy.RobustPath((-5, 6),
                          0.8,
                          layer=23,
                          ends="smooth",
                          tolerance=1e-4)
    rp.segment((1, 1), 0.1, relative=True)
    cell.add(rp)
    rp = gdspy.RobustPath((-3, 6), 0.8, layer=10, ends="round", tolerance=1e-5)
    rp.segment((1, 0), 0.1, relative=True)
    rp.segment((0, 1), 0.8, relative=True)
    cell.add(rp)
    rp = gdspy.RobustPath((-3, 6),
                          0.8,
                          layer=11,
                          ends="extended",
                          tolerance=1e-5)
    rp.segment((1, 0), 0.1, relative=True)
    rp.segment((0, 1), 0.8, relative=True)
    cell.add(rp)
    rp = gdspy.RobustPath((-3, 6),
                          0.8,
                          layer=12,
                          ends="smooth",
                          tolerance=1e-5)
    rp.segment((1, 0), 0.1, relative=True)
    rp.segment((0, 1), 0.8, relative=True)
    cell.add(rp)
    rp = gdspy.RobustPath((-3, 8), 0.1, layer=13, ends="round", tolerance=1e-5)
    rp.segment((1, 0), 0.8, relative=True)
    rp.segment((0, 1), 0.1, relative=True)
    cell.add(rp)
    rp = gdspy.RobustPath((-3, 8),
                          0.1,
                          layer=14,
                          ends=(0.2, 0.2),
                          tolerance=1e-5)
    rp.segment((1, 0), 0.8, relative=True)
    rp.segment((0, 1), 0.1, relative=True)
    cell.add(rp)
    rp = gdspy.RobustPath((-3, 8),
                          0.1,
                          layer=15,
                          ends="smooth",
                          tolerance=1e-5)
    rp.segment((1, 0), 0.8, relative=True)
    rp.segment((0, 1), 0.1, relative=True)
    cell.add(rp)
    rp = gdspy.RobustPath((5, 2), [0.05, 0.1, 0.2], [-0.2, 0, 0.4],
                          layer=[4, 5, 6])
    rp.parametric(lambda u: numpy.array((5.5 + 3 * u, 2 + 3 * u**2)),
                  relative=False)
    rp.segment((0, 1), relative=True)
    rp.parametric(
        lambda u: numpy.array((2 * numpy.cos(0.5 * numpy.pi * u) - 2, 3 * numpy
                               .sin(0.5 * numpy.pi * u))),
        width=[0.2, 0.1, 0.05],
        offset=[-0.3, 0, 0.3],
    )
    rp.parametric(lambda u: numpy.array((-2 * u, 0)), width=0.1, offset=0.2)
    rp.bezier([(-3, 0), (-2, -3), (0, -4), (0, -5)], offset=[-0.2, 0, 0.2])
    rp.bezier(
        [(4.5, 0), (1, -1), (1, 5), (3, 2), (5, 2)],
        width=[0.05, 0.1, 0.2],
        offset=[-0.2, 0, 0.4],
        relative=False,
    )
    cell.add(rp)
    rp = gdspy.RobustPath((2, -1), 0.1, layer=7, tolerance=1e-4, max_points=0)
    rp.smooth(
        [(1, 0), (1, -1), (0, -1)],
        angles=[numpy.pi / 3, None, -2 / 3.0 * numpy.pi, None],
        cycle=True,
    )
    cell.add(rp)
    rp = gdspy.RobustPath((2.5, -1.5), 0.1, layer=8)
    rp.smooth(
        [(3, -1.5), (4, -2), (5, -1), (6, -2), (7, -1.5), (7.5, -1.5)],
        relative=False,
        width=0.2,
    )
    cell.add(rp)
    assertsame(target["RobustPath2"], cell)
max_val = np.max(np.abs(Ey))
plt.contour(eps_r.T, levels=[(epsr_max+1)/2])
im = plt.imshow(np.real(Ey.T*np.exp(1j*3)), cmap='RdBu', aspect='auto', vmin=-max_val, vmax=max_val)
divider = make_axes_locatable(ax)
cax = divider.append_axes('right', size='5%', pad=0.05)
cbar = plt.colorbar(im, cax=cax, orientation='vertical');

if Get_gds:
    # create folder if needed
    if not os.path.exists(foldername):
        os.makedirs(foldername)
    
    # how many periods do you want to convert into a gds file
    n_periods = 20
    eps_new = np.concatenate((np.ones((Nx,2)), np.tile(eps_r, (1,n_periods)),
                              np.ones((Nx,2))), axis=1)
    
    # make sure that the gds files are named uniquely
    try:
        gds_number = gds_number + 1
    except NameError: gds_number = 0
    cell = gy.Cell('eps'+str(gds_number))
    
    contour_level = 10  # pick a value between epsr_min and epsr_max
    for points in find_contours(eps_new, contour_level):
        cell.add(gy.Polygon(points).fracture())
    
    # write gds file
    gy.write_gds(foldername+'\\gds_file.gds', [cell.name], unit=dL)
    
示例#10
0
number = 5  # number of Zlow-Zhigh cascades from each side of the resonator

w_c = 4  # C finger width
h_c = 0  # C finger height
w_sep = 4  # C finger separation
h_sep = 66  # C finger vertical distance from ground plane fingers to resonator
delta_x = 0  # offset for starting point of C fingers


c_gap = 2
c_length = 50
## End of parameters ##

#%% creation of basic PBG structure with lambda/2 resonator

cell = gdspy.Cell('PGB')

k = 0
for i in range(number):

    Zlow1 = gdspy.Rectangle((0 + k * (l_Zlow + l_Zhigh), 0),
                            (l_Zlow + k * (l_Zlow + l_Zhigh), t_Zlow))

    Zhigh1 = gdspy.Rectangle((l_Zlow + k * (l_Zlow + l_Zhigh), (t_Zlow - t_Zhigh) / 2.),
                             (l_Zlow + l_Zhigh + k * (l_Zlow + l_Zhigh), (t_Zlow - t_Zhigh) / 2. + t_Zhigh))
#    cell.add(Zlow1)
#    cell.add(Zhigh1)
    k = k + 1

res = gdspy.Rectangle((k * (l_Zlow + l_Zhigh), (t_Zlow - t_res) / 2.),
                      (k * (l_Zlow + l_Zhigh) + l_res, (t_Zlow - t_res) / 2. + t_res))
示例#11
0
def nanowire_binary(number,
                    width,
                    pitch,
                    length,
                    n,
                    m,
                    is_interrupt,
                    device_shape,
                    pals_length,
                    itr,
                    elec_width,
                    pin_length=60):
    """
    用于绘制任意大小,并联根数的纳米线版图,python版本:2.7.14,3.3,只画方形器件
    长度单位:μm
    width 单根纳米线宽度
    length 纳米线长度,同时是纳米线区域的半径  
    pitch 纳米线周期宽度
    itr 计数纳米线根数
    n:并联纳米线根数
    m:二级并联根数
    pals_length:二级并联长度
    elec_width MA6光刻电极宽度
    """
    length = float(length)
    width = float(width)
    pitch = float(pitch)
    n = int(n)
    is_interrupt = int(is_interrupt)
    device_shape = int(device_shape)
    pals_length = float(pals_length)
    elec_width = int(elec_width)
    pin_length = float(pin_length)

    minedge = 10
    maxdiameter = length + 2 * minedge  #外围结构为5um,设置纳米线电子束曝光尺寸大小
    Cellname = "nanowire" + str(itr)
    single_cell = gdspy.Cell(Cellname, exclude_from_current=True)
    mark = itr
    #gdspy.GdsLibrary.add(single_cell,overwrite_duplication = True)

    if is_interrupt == 1 and pals_length < pitch - width:
        print("并联长度过小")
        return single_cell
    if length + minedge > maxdiameter:
        print("纳米线长度设置应小于等于50μm")
        return single_cell  #返回空的cell
    if is_interrupt == 1 and pals_length > length:
        print("纳米线并联长度应小于直径")
        return single_cell  #返回空的cell

    total = int(length / pitch)
    """
    #根据并联纳米线根数和纳米线间距来微调纳米线直径
    """
    if n < 1 or m < 1:
        print("纳米线小于1,n应该>=1")
        return single_cell
    elif type(n) == float:
        print('纳米线并联数应为>=1的整数')
        return single_cell
    unnece = total % (n * m)  #多余的纳米线根数
    itr = int(total / n / m)  #纳米线周期
    if unnece > int(n / 2):
        total = (itr + 1) * n * m
    else:
        total = itr * n * m

    a = (elec_width - length) / pin_length / 2
    if a - int(a) > 0.8:
        a = int(a) + 2
    else:
        a = int(a) + 1

    oldl = length
    length = total * pitch
    print("对纳米线" + Cellname +
          "长度进行了微调:原始值{},微调后值{},".format(oldl, total * pitch))
    #   length = total*pitch
    #    total1 = total
    half = total / 2
    """
    绘制纳米线核心区域
    两步绘制:
    计算调整圆的直径,确定圆的刻蚀线终点
    1 绘制中心圆区域
    2,绘制隔离线
    """
    #步骤一1
    if device_shape == 0:
        edge = shape.circle(pitch * total, width, pitch, total, half)
#        iso = shape.circleiso(length,width,n)
#        equ_area = shape.circle_equ(length,maxdiameter,width,pitch,total,half)
    elif device_shape == 1:
        edge = shape.squire(pitch * total, width, pitch, total, half)


#        iso = shape.squireiso(length,width,n)
#        equ_area = shape.squire_equ(length,maxdiameter,width,pitch,total,half)
#    single_cell.add(iso[0])
#    single_cell.add(iso[1])
#
#    #绘制外围等效曝光区
#    for i in equ_area:
#        for j in i:
#            single_cell.add(gdspy.Rectangle(*j,layer = 1,datatype = 1))
#

#纳米线核心区域点阵
    startpoint = edge[0]
    finalpoint = edge[1]

    i = 0
    location = numpy.linspace(0, total, int(total / n) + 1)  #二级并联线位置
    location1 = numpy.linspace(0, total, int(total / n / m) + 1)  #隔离线位置
    j = 1.0  #direction
    max_length = 0
    m1 = m
    while i < len(startpoint) - n * 2:  #调整并联单元长度相等
        m = 0
        while m < n and i < len(startpoint):
            if i == 0:  #保证0点的线存在
                startpoint[i] = (startpoint[i - m + 1][0], startpoint[i][1])
                finalpoint[i] = (finalpoint[i - m + 1][0], finalpoint[i][1])
            startpoint[i] = (startpoint[i - m][0], startpoint[i][1])
            finalpoint[i] = (finalpoint[i - m][0], finalpoint[i][1])
            m = m + 1
            i = i + 1
    i = 0
    while i < len(startpoint):  #计算最大圆直径
        if is_interrupt == 1 and n > 1:
            step = pals_length  #
            single_length = abs(finalpoint[i][0] - startpoint[i][0])
            if (int(single_length / step) + 1) * step - length < n * pitch:
                single_length = int(single_length / step + 1) * step
            else:
                single_length = int(single_length / step) * step
            if numpy.sqrt(single_length**2 / 4 + startpoint[i][1]**2
                          ) > max_length and device_shape == 0:  #圆形的隔离圆大小需要修改
                max_length = numpy.sqrt(
                    (single_length**2 / 4 + startpoint[i][1]**2))
            startpoint[i] = (-single_length / 2, startpoint[i][1])
            finalpoint[i] = (single_length / 2, finalpoint[i][1])
        i = i + 1
    max_length = 2 * max_length
    if max_length < pitch * total:
        max_length = pitch * total  #保证外切圆直径为离散值后的最大直径
    maxdiameter = max_length + 2 * minedge  #调整最大曝光区域
    if maxdiameter <= pin_length:
        maxdiameter = pin_length

    i = 0
    while i < len(startpoint):  #i=0,和total对应在x=0位置
        if 0 == 1:
            j = -j
        else:  #每隔30um绘制一个断点
            if is_interrupt == 1 and n > 1:
                step = pals_length  #
                k = 0
                if i not in location:
                    while (k + 1) * step < finalpoint[i][0] - startpoint[i][0]:
                        steppoint1 = (startpoint[i][0] + k * step,
                                      startpoint[i][1])
                        steppoint2 = (startpoint[i][0] + (k + 1) * step -
                                      width * (n - 1), finalpoint[i][1])
                        polym = gdspy.Rectangle(steppoint1,
                                                steppoint2,
                                                layer=1,
                                                datatype=1)
                        polym.fillet(pitch - width, points_per_2pi=20)
                        single_cell.add(polym)
                        k = k + 1
                    else:
                        steppoint1 = (startpoint[i][0] + k * step,
                                      startpoint[i][1])
                        steppoint2 = finalpoint[i]
                        polym = gdspy.Rectangle(steppoint1,
                                                steppoint2,
                                                layer=1,
                                                datatype=1)
                        polym.fillet(pitch - width, points_per_2pi=20)
                        single_cell.add(polym)
            else:
                if i not in location:
                    polym = gdspy.Rectangle(startpoint[i],
                                            finalpoint[i],
                                            layer=1,
                                            datatype=1)
                    polym.fillet((pitch - width) / 2, points_per_2pi=20)
                    single_cell.add(polym)
        if i in location:
            if i in location1:
                startpoint[i] = (j * startpoint[i][0], startpoint[i][1])
                if device_shape == 0:
                    finalpoint[i] = (j * numpy.sqrt((max_length / 2 + 3)**2 -
                                                    ((half - i) * pitch)**2),
                                     finalpoint[i][1])
                elif device_shape == 1:
                    finalpoint[i] = (j * (max_length / 2 + 3),
                                     finalpoint[i][1])
                    j = -j
            polym = gdspy.Rectangle(startpoint[i],
                                    finalpoint[i],
                                    layer=1,
                                    datatype=1)
            polym.fillet((pitch - width) / 2, points_per_2pi=20)
            single_cell.add(polym)
        i = i + 1

    if device_shape == 0:
        iso = shape.circleiso(max_length, width, n)
        equ_area = shape.circle_equ(max_length, maxdiameter, width, pitch,
                                    total, half)
    elif device_shape == 1:
        iso = shape.squireiso(max_length, width, n)
        equ_area = shape.squire_equ(max_length, maxdiameter, width, pitch,
                                    total, half)
    single_cell.add(iso[0])
    single_cell.add(iso[1])

    #绘制外围等效曝光区

    layer = {'layer': 1, 'datatype': 1}  #定义图层
    for i in equ_area:
        for j in i:
            single_cell.add(gdspy.Rectangle(*j, **layer))

    #纳米线核心区域点阵
    startpoint = edge[0]
    finalpoint = edge[1]
    """
    电极线结构
    pitch 纳米线间距,即周期
    width:纳米线宽度
    length 纳米线长度,电极宽度设置为2um,在并联纳米线总宽宽度>1μm后,
    电极宽度调整为(n+4)*width
    预曝光区域,宽度设置为5μm
    曝光长度设置为length/2+5,pitch与纳米线一致
    """
    length = max_length  #将length改为划出纳米线调整后的最大直径
    total = int((maxdiameter / 2 - length / 2 - 1) / pitch)
    i = 0
    m = m1
    if n * m * width >= 1:
        half_elecwidth = (n * m + 4) * width
    else:
        half_elecwidth = 1
    old = half_elecwidth

    while i <= total - 1:
        if i <= int(n * m * width / pitch) + 1:
            half_elecwidth = max_length / 2 + 3
        else:
            half_elecwidth = old
        elec1 = gdspy.Rectangle(
            (half_elecwidth, i * pitch + length / 2),
            (maxdiameter / 2, i * pitch + length / 2 + pitch - width), **layer)
        single_cell.add(elec1)
        elec2 = gdspy.Rectangle(
            (-half_elecwidth, i * pitch + length / 2),
            (-maxdiameter / 2, i * pitch + length / 2 + pitch - width),
            **layer)
        single_cell.add(elec2)
        elec3 = gdspy.Rectangle(
            (-half_elecwidth, (-i - 1) * pitch - length / 2),
            (-maxdiameter / 2, -i * pitch - length / 2 - (pitch - width)),
            **layer)
        single_cell.add(elec3)
        elec4 = gdspy.Rectangle(
            (half_elecwidth, (-i - 1) * pitch - length / 2),
            (maxdiameter / 2, -i * pitch - length / 2 - (pitch - width)),
            **layer)
        single_cell.add(elec4)
        i = i + 1
    """
    隔离线,宽度1um,伸出纳米线区域elec_width/2+pin_ength
    """
    #    length = oldl   #需要原始直径值

    if elec_width / 2 > length / 2 + pin_length - 10:
        a = (elec_width / 2 - length / 2 - pin_length) / pin_length
        if a - int(a) > 0.9:
            a = int(a) + 2
        else:
            a = int(a) + 1
        halflen = pin_length * (a + 1) + length / 2
    else:
        halflen = length / 2 + pin_length
    edgelen = maxdiameter / 2  #纳米线区域边界
    insulate1 = gdspy.Rectangle((half_elecwidth, edgelen - 1),
                                (halflen, edgelen), **layer)
    single_cell.add(insulate1)
    insulate2 = gdspy.Rectangle((-half_elecwidth, edgelen - 1),
                                (-halflen, edgelen), **layer)
    single_cell.add(insulate2)
    insulate3 = gdspy.Rectangle((-half_elecwidth, -edgelen + 1),
                                (-halflen, -edgelen), **layer)
    single_cell.add(insulate3)
    insulate4 = gdspy.Rectangle((half_elecwidth, -edgelen + 1),
                                (halflen, -edgelen), **layer)
    single_cell.add(insulate4)

    insulate5 = gdspy.Rectangle((edgelen - 1, halflen), (edgelen, -halflen),
                                **layer)
    single_cell.add(insulate5)
    insulate6 = gdspy.Rectangle((-edgelen + 1, halflen), (-edgelen, -halflen),
                                **layer)
    single_cell.add(insulate6)
    """
    绘制拼接场外围尺寸,固定等效曝光区域宽10μm
    位置在边界处:pin_length-minedge
    """
    """
    length = oldl  # oldl=原始length,保证被整场分割而不滑移。允许出现边界处拼接场存在。
    layer_useless = {'layer': 3, 'datatype': 3}
    out = gdspy.Rectangle((-length / 2 - pin_length, -maxdiameter / 2),  # 左边
                          (-length / 2 - pin_length + 1, maxdiameter / 2),
                          **layer_useless
                          )
    single_cell.add(out)
    out = gdspy.Rectangle((length / 2 + pin_length, -maxdiameter / 2),  # 右边
                          (length / 2 + pin_length - 1, maxdiameter / 2),
                          **layer_useless
                          )
    single_cell.add(out)
    out = gdspy.Rectangle((-maxdiameter / 2, length / 2 + pin_length),  # 上左
                          (-half_elecwidth, length / 2 + pin_length - 1),
                          **layer_useless
                          )
    single_cell.add(out)
    out = gdspy.Rectangle((maxdiameter / 2, length / 2 + pin_length),  # 上右
                          (half_elecwidth, length / 2 + pin_length - 1),
                          **layer_useless
                          )
    single_cell.add(out)
    out = gdspy.Rectangle((-maxdiameter / 2, -length / 2 - pin_length),  # 下左
                          (-half_elecwidth, -length / 2 - pin_length + 1),
                          **layer_useless
                          )
    single_cell.add(out)
    out = gdspy.Rectangle((maxdiameter / 2, -length / 2 - pin_length),  # 下右
                          (half_elecwidth, -length / 2 - pin_length + 1),
                          **layer_useless
                          )
    single_cell.add(out)
    """
    """
    对准标记
    4umX100μm大小十字
    位置,-500um,500um
    """
    markers = [1, 9, 41, 73, 81]
    if mark in markers:
        cross = gdspy.Rectangle((-450, 498), (-550, 502), **layer)
        single_cell.add(cross)
        cross = gdspy.Rectangle((-498, 450), (-502, 550), **layer)
        single_cell.add(cross)
    """
    编号
    """
    text = gdspy.Text(str(number), 20, (1000, 300), **layer)
    single_cell.add(text)

    merged = gdspy.fast_boolean(gdspy.Rectangle(
        (-maxdiameter / 2, -maxdiameter / 2),
        (maxdiameter / 2, maxdiameter / 2)),
                                gdspy.CellReference(single_cell),
                                'not',
                                max_points=190)

    # Offset the path shape by 0.5 and add it to the cell.
    single_cell.add(merged)

    return single_cell
示例#12
0
def memory_benchmark():
    proc = psutil.Process()
    total = 100000
    print(f"\nMemory usage per object for {total} objects.")

    def print_row(*vals, hsep=False):
        columns = [20, 16, 16, 9]
        print(
            "|",
            vals[0].ljust(columns[0]),
            "|",
            " | ".join(v.center(c) for v, c in zip(vals[1:], columns[1:])),
            "|",
        )
        if hsep:
            print(
                "|",
                ":" + "-" * (columns[0] - 1),
                "|",
                " | ".join(":" + "-" * (c - 2) + ":" for c in columns[1:]),
                "|",
            )

    print_row(
        "Object",
        "Gdspy " + gdspy.__version__,
        "Gdstk " + gdstk.__version__,
        "Reduction",
        hsep=True,
    )

    def mem_test(func):
        start_mem = proc.memory_info()
        r = [func(i) for i in range(total)]
        end_mem = proc.memory_info()
        return (end_mem.vms - start_mem.vms) / total, r

    data = []
    gdspy_cell = gdspy.Cell("TEMP", exclude_from_current=True)
    gdstk_cell = gdstk.Cell("TEMP")
    for obj, gdspy_func, gdstk_func in [
        (
            "Rectangle",
            lambda i: gdspy.Rectangle((i, i), (i + 1, i + 1)),
            lambda i: gdstk.rectangle((i, i), (i + 1, i + 1)),
        ),
        (
            "Circle (r = 10)",
            lambda i: gdspy.Round((0, 10 * i), 10),
            lambda i: gdstk.ellipse((0, 10 * i), 10),
        ),
        (
            "FlexPath segment",
            lambda i: gdspy.FlexPath([(i, i + 1), (i + 1, i)], 0.1),
            lambda i: gdstk.FlexPath([(i, i + 1), (i + 1, i)], 0.1),
        ),
        (
            "FlexPath arc",
            lambda i: gdspy.FlexPath([(10 * i, 0)], 0.1).arc(10, 0, numpy.pi),
            lambda i: gdstk.FlexPath([(10 * i, 0)], 0.1).arc(10, 0, numpy.pi),
        ),
        (
            "RobustPath segment",
            lambda i: gdspy.RobustPath((i, i + 1), 0.1).segment((i + 1, i)),
            lambda i: gdstk.RobustPath((i, i + 1), 0.1).segment((i + 1, i)),
        ),
        (
            "RobustPath arc",
            lambda i: gdspy.RobustPath((10 * i, 0), 0.1).arc(10, 0, numpy.pi),
            lambda i: gdstk.RobustPath((10 * i, 0), 0.1).arc(10, 0, numpy.pi),
        ),
        (
            "Label",
            lambda i: gdspy.Label(str(i), (i, i)),
            lambda i: gdstk.Label(str(i), (i, i)),
        ),
        (
            "Reference",
            lambda i: gdspy.CellReference(gdspy_cell, (0, 0)),
            lambda i: gdstk.Reference(gdstk_cell, (0, 0)),
        ),
        (
            "Reference (array)",
            lambda i: gdspy.CellArray(gdspy_cell, (0, 0), 1, 1, (0, 0)),
            lambda i: gdstk.Reference(gdstk_cell, (0, 0), rows=1, columns=1),
        ),
        (
            "Cell",
            lambda i: gdspy.Cell(str(i), exclude_from_current=True),
            lambda i: gdstk.Cell(str(i)),
        ),
    ]:
        gdspy_mem, gdspy_data = mem_test(gdspy_func)
        data.append(gdspy_data)
        gdstk_mem, gdstk_data = mem_test(gdstk_func)
        data.append(gdstk_data)
        print_row(
            obj,
            prefix_format(gdspy_mem, unit="B", base="bin"),
            prefix_format(gdstk_mem, unit="B", base="bin"),
            f"{100 - 100 * gdstk_mem / gdspy_mem:.0f}%",
        )
示例#13
0
def test_mirror():
    ps = gdspy.PolygonSet([[(0, 0), (1, 0), (1, 2), (0, 2)]])
    ps.mirror((-1, 1), (1, -1))
    tgt = gdspy.PolygonSet([[(0, 0), (-2, 0), (-2, -1), (0, -1)]])
    assertsame(gdspy.Cell("test").add(ps), gdspy.Cell("TGT").add(tgt))
示例#14
0
def test_translate():
    ps = gdspy.PolygonSet([[(0, 0), (1, 0), (1, 2), (0, 2)]])
    ps.translate(-1, -2)
    tgt = gdspy.PolygonSet([[(-1, -2), (0, -2), (0, 0), (-1, 0)]])
    assertsame(gdspy.Cell("test").add(ps), gdspy.Cell("TGT").add(tgt))
示例#15
0
#  Boost Software License - Version 1.0.  See the accompanying       #
#  LICENSE file or <http://www.boost.org/LICENSE_1_0.txt>            #
#                                                                    #
######################################################################

import numpy
import gdspy

print('Using gdspy module version ' + gdspy.__version__)

# ------------------------------------------------------------------ #
#      POLYGONS
# ------------------------------------------------------------------ #

# First we need a cell to add the polygons to.
poly_cell = gdspy.Cell('POLYGONS')

# We define the polygon through its vertices.
points = [(0, 0), (2, 2), (2, 6), (-6, 6), (-6, -6), (-4, -4), (-4, 4), (0, 4)]

# Create the polygon on layer 1.
poly1 = gdspy.Polygon(points, 1)

# Add the new polygon to the cell.
poly_cell.add(poly1)

# Create another polygon from the same set of points, but rotate it
# 180 degrees and add it to the cell.
poly2 = gdspy.Polygon(points, 1).rotate(numpy.pi)
poly_cell.add(poly2)
示例#16
0
    def gds(self,
            filename=None,
            extra=0,
            units='microns',
            view=False,
            sbend_h=0,
            sbend_v=0):
        #check to make sure the geometry isn't an array
        if len(self.clean_args(None)[0]) != 1:
            raise ValueError(
                "You have changing geometries, making gds doesn't make sense")

        if units == 'nms':
            scale = 1
        elif units == 'microns':
            scale = 10**-3
        else:
            raise ValueError('Invalid units')

        #scale to proper units
        sc_zmin = self.zmin * scale
        sc_zmax = self.zmax * scale
        sc_width = self.width * scale
        cL = (sc_zmax - sc_zmin)
        cH = self.gap(self.zmin) * scale / 2

        #make parametric functions
        paraTop = lambda x: (x * (sc_zmax - sc_zmin) + sc_zmin, scale * self.
                             gap(x * (self.zmax - self.zmin) + self.zmin
                                 ) / 2 + sc_width / 2)
        paraBottom = lambda x: (x * (sc_zmax - sc_zmin) + sc_zmin, -scale *
                                self.gap(x * (self.zmax - self.zmin) + self.
                                         zmin) / 2 - sc_width / 2)
        #dparaTop    = lambda x: (sc_zmax-sc_zmin, scale*(self.zmax-self.zmin)*self.dgap(x*(self.zmax-self.zmin)+self.zmin)/2)
        #dparaBottom = lambda x: (sc_zmax-sc_zmin, -scale*(self.zmax-self.zmin)*self.dgap(x*(self.zmax-self.zmin)+self.zmin)/2)

        sbend = False
        if sbend_h != 0 and sbend_v != 0:
            sbend = True
        sbendDown = lambda x: (sbend_h * x, -sbend_v / 2 *
                               (1 - np.cos(np.pi * x)))
        sbendUp = lambda x: (sbend_h * x, sbend_v / 2 *
                             (1 - np.cos(np.pi * x)))
        dsbendDown = lambda x: (sbend_h, -np.pi * sbend_v / 2 * np.sin(np.pi *
                                                                       x))
        dsbendUp = lambda x: (sbend_h, np.pi * sbend_v / 2 * np.sin(np.pi * x))

        #write to GDS
        pathTop = gdspy.Path(
            sc_width, (sc_zmin - extra - sbend_h, cH + sc_width / 2 + sbend_v))
        pathTop.segment(extra, '+x')
        if sbend: pathTop.parametric(sbendDown, dsbendDown)
        pathTop.parametric(paraTop, relative=False)
        if sbend: pathTop.parametric(sbendUp, dsbendUp)
        pathTop.segment(extra, '+x')

        pathBottom = gdspy.Path(
            sc_width,
            (sc_zmin - extra - sbend_h, -cH - sc_width / 2 - sbend_v))
        pathBottom.segment(extra, '+x')
        if sbend: pathBottom.parametric(sbendUp, dsbendUp)
        pathBottom.parametric(paraBottom, relative=False)
        if sbend: pathBottom.parametric(sbendDown, dsbendDown)
        pathBottom.segment(extra, '+x')

        gdspy.current_library = gdspy.GdsLibrary()
        path_cell = gdspy.Cell('C0')
        path_cell.add(pathTop)
        path_cell.add(pathBottom)

        if view:
            gdspy.LayoutViewer(cells='C0')

        if filename is not None:
            writer = gdspy.GdsWriter(filename, unit=1.0e-6, precision=1.0e-9)
            writer.write_cell(path_cell)
            writer.close()
示例#17
0
def test_hobby1(target):
    cell = gdspy.Cell("test", True)
    c = gdspy.Curve(0, 0, tolerance=1e-3)
    c.i([(1, 0), (1, 1), (0, 1)])
    cell.add(gdspy.Polygon(c.get_points(), layer=1))
    c = gdspy.Curve(2, 0, tolerance=1e-3)
    c.i([(1, 0), (1, 1), (0, 1)], angles=[numpy.pi / 3, None, None, None])
    cell.add(gdspy.Polygon(c.get_points(), layer=3))
    c = gdspy.Curve(4, 0, tolerance=1e-3)
    c.i([(1, 0), (1, 1), (0, 1)],
        angles=[None, None, None, 2 / 3.0 * numpy.pi])
    cell.add(gdspy.Polygon(c.get_points(), layer=5))
    c = gdspy.Curve(0, 2, tolerance=1e-3)
    c.i([(1, 0), (1, 1), (0, 1)],
        angles=[numpy.pi / 3, None, None, 3 / 4.0 * numpy.pi])
    cell.add(gdspy.Polygon(c.get_points(), layer=7))
    c = gdspy.Curve(2, 2, tolerance=1e-3)
    c.i([(1, 0), (1, 1), (0, 1)], angles=[None, None, numpy.pi / 2, None])
    cell.add(gdspy.Polygon(c.get_points(), layer=9))
    c = gdspy.Curve(4, 2, tolerance=1e-3)
    c.i([(1, 0), (1, 1), (0, 1)], angles=[None, 0, None, None])
    cell.add(gdspy.Polygon(c.get_points(), layer=11))
    c = gdspy.Curve(0, 4, tolerance=1e-3)
    c.i([(1, 0), (1, 1), (0, 1)], angles=[None, 0, None, -numpy.pi / 2])
    cell.add(gdspy.Polygon(c.get_points(), layer=13))
    c = gdspy.Curve(2, 4, tolerance=1e-3)
    c.i([(1, 0), (1, 1), (0, 1)], angles=[None, 0, -numpy.pi, -numpy.pi / 2])
    cell.add(gdspy.Polygon(c.get_points(), layer=15))
    c = gdspy.Curve(4, 4, tolerance=1e-3)
    c.i([(1, 0), (1, 1), (0, 1)],
        angles=[-numpy.pi / 4, 0, numpy.pi / 2, -numpy.pi])
    cell.add(gdspy.Polygon(c.get_points(), layer=17))

    c = gdspy.Curve(0, 0, tolerance=1e-3)
    c.i([(1, 0), (1, 1), (0, 1)], cycle=True)
    cell.add(gdspy.Polygon(c.get_points(), layer=2))
    c = gdspy.Curve(2, 0, tolerance=1e-3)
    c.i([(1, 0), (1, 1), (0, 1)],
        angles=[numpy.pi / 3, None, None, None],
        cycle=True)
    cell.add(gdspy.Polygon(c.get_points(), layer=4))
    c = gdspy.Curve(4, 0, tolerance=1e-3)
    c.i(
        [(1, 0), (1, 1), (0, 1)],
        angles=[None, None, None, 2 / 3.0 * numpy.pi],
        cycle=True,
    )
    cell.add(gdspy.Polygon(c.get_points(), layer=6))
    c = gdspy.Curve(0, 2, tolerance=1e-3)
    c.i(
        [(1, 0), (1, 1), (0, 1)],
        angles=[numpy.pi / 3, None, None, 3 / 4.0 * numpy.pi],
        cycle=True,
    )
    cell.add(gdspy.Polygon(c.get_points(), layer=8))
    c = gdspy.Curve(2, 2, tolerance=1e-3)
    c.i([(1, 0), (1, 1), (0, 1)],
        angles=[None, None, numpy.pi / 2, None],
        cycle=True)
    cell.add(gdspy.Polygon(c.get_points(), layer=10))
    c = gdspy.Curve(4, 2, tolerance=1e-3)
    c.i([(1, 0), (1, 1), (0, 1)], angles=[None, 0, None, None], cycle=True)
    cell.add(gdspy.Polygon(c.get_points(), layer=12))
    c = gdspy.Curve(0, 4, tolerance=1e-3)
    c.i([(1, 0), (1, 1), (0, 1)],
        angles=[None, 0, None, -numpy.pi / 2],
        cycle=True)
    cell.add(gdspy.Polygon(c.get_points(), layer=14))
    c = gdspy.Curve(2, 4, tolerance=1e-3)
    c.i([(1, 0), (1, 1), (0, 1)],
        angles=[None, 0, -numpy.pi, -numpy.pi / 2],
        cycle=True)
    cell.add(gdspy.Polygon(c.get_points(), layer=16))
    c = gdspy.Curve(4, 4, tolerance=1e-3)
    c.i(
        [(1, 0), (1, 1), (0, 1)],
        angles=[-numpy.pi / 4, 0, numpy.pi / 2, -numpy.pi],
        cycle=True,
    )
    cell.add(gdspy.Polygon(c.get_points(), layer=18))
    assertsame(target["Hobby1"], cell)
示例#18
0
    def gds(self,
            filename=None,
            view=False,
            extra=0,
            units='nms',
            sbend_h=0,
            sbend_v=0):
        #check to make sure the geometry isn't an array
        if len(self.clean_args(None)[0]) != 1:
            raise ValueError(
                "You have changing geometries, making gds doesn't make sense")

        if units == 'nms':
            scale = 1
        elif units == 'microns':
            scale = 10**-3
        else:
            raise ValueError('Invalid units')

        #scale to proper units
        sc_width = self.width * scale
        sc_gap = self.gap * scale
        sc_length = self.length * scale
        sc_H = self.H * scale
        sc_V = self.V * scale

        #make parametric functions
        sbendDown = lambda x: (sc_H * x, -sc_V / 2 * (1 - np.cos(np.pi * x)))
        sbendUp = lambda x: (sc_H * x, sc_V / 2 * (1 - np.cos(np.pi * x)))
        dsbendDown = lambda x: (sc_H, -np.pi * sc_V / 2 * np.sin(np.pi * x))
        dsbendUp = lambda x: (sc_H, np.pi * sc_V / 2 * np.sin(np.pi * x))

        sbend = False
        if sbend_h != 0 and sbend_v != 0:
            sbend = True
        sbendDownExtra = lambda x: (sbend_h * x, -sbend_v / 2 *
                                    (1 - np.cos(np.pi * x)))
        sbendUpExtra = lambda x: (sbend_h * x, sbend_v / 2 *
                                  (1 - np.cos(np.pi * x)))
        dsbendDownExtra = lambda x: (sbend_h, -np.pi * sbend_v / 2 * np.sin(
            np.pi * x))
        dsbendUpExtra = lambda x: (sbend_h, np.pi * sbend_v / 2 * np.sin(np.pi
                                                                         * x))

        #write to GDS
        pathTop = gdspy.Path(sc_width,
                             (-sc_length / 2 - sc_H - sbend_h - extra,
                              sc_V + sbend_v + sc_width / 2 + sc_gap / 2))
        pathTop.segment(extra, '+x')
        if sbend: pathTop.parametric(sbendDownExtra, dsbendDownExtra)
        pathTop.parametric(sbendDown, dsbendDown)
        pathTop.segment(sc_length, '+x')
        pathTop.parametric(sbendUp, dsbendUp)
        if sbend: pathTop.parametric(sbendUpExtra, dsbendUpExtra)
        pathTop.segment(extra, '+x')

        pathBottom = gdspy.Path(sc_width,
                                (-sc_length / 2 - sc_H - sbend_h - extra,
                                 -sc_V - sbend_v - sc_width / 2 - sc_gap / 2))
        pathBottom.segment(extra, '+x')
        if sbend: pathBottom.parametric(sbendUpExtra, dsbendUpExtra)
        pathBottom.parametric(sbendUp, dsbendUp)
        pathBottom.segment(sc_length, '+x')
        pathBottom.parametric(sbendDown, dsbendDown)
        if sbend: pathBottom.parametric(sbendDownExtra, dsbendDownExtra)
        pathBottom.segment(extra, '+x')

        gdspy.current_library = gdspy.GdsLibrary()
        path_cell = gdspy.Cell('C0')
        path_cell.add(pathTop)
        path_cell.add(pathBottom)

        if view:
            gdspy.LayoutViewer(cells='C0')

        if filename is not None:
            writer = gdspy.GdsWriter(filename, unit=1.0e-6, precision=1.0e-9)
            writer.write_cell(path_cell)
            writer.close()
gap_step = (gap1 - gap0) / (n - 1)  #sweep gap parameter

alL = 350  #aligment distance to device

final_pos = numpy.array([
    (2 * r1 + sec_gap + taper_l + taper_ii_l) * 2 + iii_v_l, (n * d)
])

hw = 3.0  #nicr heater width
hh = 30.0  #nicr heater height
ang = pi / 12.0  # 30° heater
sqr = 10.0

spec4 = 1
pcavc = (1, 1)
nccell = gdspy.Cell('Heater_Ni_Cr')
combined_cell = gdspy.Cell('COMB1')


def nicrheat(layer_num, center, radius, hw, hh, ang, sqr):
    pos1 = (center[0] - radius * sin(2.0 * ang),
            center[1] - radius * cos(2.0 * ang))
    pos2 = (center[0] + radius * sin(2.0 * ang),
            center[1] - radius * cos(2.0 * ang))

    nch1 = gdspy.Round(center,
                       radius + hw / 2,
                       radius - hw / 2,
                       initial_angle=-ang - pi / 2.0,
                       final_angle=ang - pi / 2.0,
                       layer=layer_num,
示例#20
0
def test_flexpath4(target):
    cell = gdspy.Cell("test")
    fp = gdspy.FlexPath(
        [(0, 0)],
        [0.1, 0.2, 0.1],
        0.15,
        layer=[1, 2, 3],
        corners=["natural", "miter", "bevel"],
    )
    fp.segment((1, 0))
    fp.segment((1, 1), 0.1, 0.05)
    fp.segment((1, 1), [0.2, 0.1, 0.1], -0.05, True)
    fp.segment((-1, 1), 0.2, [-0.2, 0, 0.3], True)
    fp.arc(2, 0, 0.5 * numpy.pi)
    fp.arc(3, 0.5 * numpy.pi, numpy.pi, 0.1, 0)
    fp.arc(1, 0.4 * numpy.pi, -0.4 * numpy.pi, [0.1, 0.2, 0.1], [0.2, 0, -0.2])
    fp.turn(1, 0.4 * numpy.pi)
    fp.turn(1, "ll", 0.15, 0)
    fp.turn(0.5, "r", [0.1, 0.05, 0.1], [0.15, 0, -0.15])
    cell.add(fp)
    fp = gdspy.FlexPath([(-5, 6)], 0.8, layer=20, ends="round", tolerance=1e-4)
    fp.segment((1, 1), 0.1, relative=True)
    cell.add(fp)
    fp = gdspy.FlexPath([(-5, 6)],
                        0.8,
                        layer=21,
                        ends="extended",
                        tolerance=1e-4)
    fp.segment((1, 1), 0.1, relative=True)
    cell.add(fp)
    fp = gdspy.FlexPath([(-5, 6)],
                        0.8,
                        layer=22,
                        ends=(0.1, 0.2),
                        tolerance=1e-4)
    fp.segment((1, 1), 0.1, relative=True)
    cell.add(fp)
    fp = gdspy.FlexPath([(-5, 6)],
                        0.8,
                        layer=23,
                        ends="smooth",
                        tolerance=1e-4)
    fp.segment((1, 1), 0.1, relative=True)
    cell.add(fp)
    fp = gdspy.FlexPath([(-3, 6)],
                        0.8,
                        layer=10,
                        corners="round",
                        ends="round",
                        tolerance=1e-5)
    fp.segment((1, 0), 0.1, relative=True)
    fp.segment((0, 1), 0.8, relative=True)
    cell.add(fp)
    fp = gdspy.FlexPath([(-3, 6)],
                        0.8,
                        layer=11,
                        corners="smooth",
                        ends="extended",
                        tolerance=1e-5)
    fp.segment((1, 0), 0.1, relative=True)
    fp.segment((0, 1), 0.8, relative=True)
    cell.add(fp)
    fp = gdspy.FlexPath([(-3, 6)],
                        0.8,
                        layer=12,
                        corners="smooth",
                        ends="smooth",
                        tolerance=1e-5)
    fp.segment((1, 0), 0.1, relative=True)
    fp.segment((0, 1), 0.8, relative=True)
    cell.add(fp)
    fp = gdspy.FlexPath([(-3, 8)],
                        0.1,
                        layer=13,
                        corners="round",
                        ends="round",
                        tolerance=1e-5)
    fp.segment((1, 0), 0.8, relative=True)
    fp.segment((0, 1), 0.1, relative=True)
    cell.add(fp)
    fp = gdspy.FlexPath([(-3, 8)],
                        0.1,
                        layer=14,
                        corners="smooth",
                        ends=(0.2, 0.2),
                        tolerance=1e-5)
    fp.segment((1, 0), 0.8, relative=True)
    fp.segment((0, 1), 0.1, relative=True)
    cell.add(fp)
    fp = gdspy.FlexPath([(-3, 8)],
                        0.1,
                        layer=15,
                        corners="round",
                        ends="smooth",
                        tolerance=1e-5)
    fp.segment((1, 0), 0.8, relative=True)
    fp.segment((0, 1), 0.1, relative=True)
    cell.add(fp)
    fp = gdspy.FlexPath([(5, 2)], [0.05, 0.1, 0.2], [-0.2, 0, 0.4],
                        layer=[4, 5, 6])
    fp.parametric(lambda u: numpy.array((5.5 + 3 * u, 2 + 3 * u**2)),
                  relative=False)
    fp.segment((0, 1), relative=True)
    fp.parametric(
        lambda u: numpy.array((2 * numpy.cos(0.5 * numpy.pi * u) - 2, 3 * numpy
                               .sin(0.5 * numpy.pi * u))),
        [0.2, 0.1, 0.05],
        [-0.3, 0, 0.3],
    )
    fp.parametric(lambda u: numpy.array((-2 * u, 0)), 0.1, 0.2)
    fp.bezier([(-3, 0), (-2, -3), (0, -4), (0, -5)], offset=[-0.2, 0, 0.2])
    fp.bezier(
        [(5, 0), (1, -1), (1, 5), (3, 2), (5, 2)],
        [0.05, 0.1, 0.2],
        [-0.2, 0, 0.4],
        relative=False,
    )
    cell.add(fp)
    fp = gdspy.FlexPath([(2, -1)], 0.1, layer=7, tolerance=1e-5, max_points=0)
    fp.smooth(
        [(1, 0), (1, -1), (0, -1)],
        angles=[numpy.pi / 3, None, -2 / 3.0 * numpy.pi, None],
        cycle=True,
    )
    cell.add(fp)
    fp = gdspy.FlexPath([(2.5, -1.5)], 0.1, layer=8)
    fp.smooth(
        [(3, -1.5), (4, -2), (5, -1), (6, -2), (7, -1.5), (7.5, -1.5)],
        relative=False,
        width=0.2,
    )
    cell.add(fp)
    assertsame(target["FlexPath4"], cell)
示例#21
0
def draw(gap):

    ## ------------------------------------------------------------------ ##
    ##	Define Cells						      ##
    ## ------------------------------------------------------------------ ##
    wg_cell = []
    nofill_cell = []
    cavity_cell = []
    gccell = []

    del (wg_cell, nofill_cell, cavity_cell, gccell)

    ## Cell containing the waveguides
    wg_cell = gdspy.Cell('WAVEGUIDES' + str((n - 1) * (gap - gap0) /
                                            (gap1 - gap0)))

    ## Cell containing microrings
    cavity_cell = gdspy.Cell('CAV' + str((n - 1) * (gap - gap0) /
                                         (gap1 - gap0)))

    ## ------------------------------------------------------------------ ##
    ##	Layer Specification					      ##
    ## ------------------------------------------------------------------ ##

    spec = {'layer': 37, 'datatype': 4}  # Fully etched SOI: waveguide core
    spec2 = {
        'layer': 37,
        'datatype': 5
    }  # Fully etched SOI: waveguide cladding (trench around core)
    spec3 = {
        'layer': 1158,
        'datatype': 0
    }  # Area not to be filled with dummies (SOI,Poly or metal)

    ## ------------------------------------------------------------------ ##
    ##	Objects Design				        	      ##
    ## ------------------------------------------------------------------ ##

    #------ Waveguide+taper   -----------------------------------------------#

    waveguide = gdspy.Path(wg_w, (-sec_gap, 0))
    waveguide.segment(2 * r1 + 2 * c_w2, '+x', **spec)

    #------ Coupled Microrings   -----------------------------------------------#
    r2 = (r1 - wg_w - 3.0 * gap / 2.0) / 2.0
    pcavc = (waveguide.x - r1 - c_w2, waveguide.y - gap - 0.5 * wg_w - r1)
    cav1 = gdspy.Round((pcavc[0], pcavc[1]),
                       r1,
                       r1 - wg_w,
                       max_points=4094,
                       number_of_points=0.1,
                       **spec)
    cav2 = gdspy.Round((pcavc[0] + r2 + 0.5 * gap, pcavc[1]),
                       r2,
                       r2 - wg_w,
                       max_points=4094,
                       number_of_points=0.1,
                       **spec)
    cav3 = gdspy.Round((pcavc[0] - r2 - 0.5 * gap, pcavc[1]),
                       r2,
                       r2 - wg_w,
                       max_points=4094,
                       number_of_points=0.1,
                       **spec)

    #------ Trench Arond waveguides   -----------------------------------------------#

    waveguide2 = gdspy.Path(wg_w2, (-sec_gap, 0))
    waveguide2.segment(2 * r1 + 2 * c_w2, '+x', **spec2)

    #------ Trench Arond coupled rings   -----------------------------------------------#

    cav12 = gdspy.Rectangle((pcavc[0] - r1 - c_w2, pcavc[1] - r1 - c_w2),
                            (pcavc[0] + r1 + c_w2, pcavc[1] + r1 + c_w2),
                            **spec2)

    #nofillc=gdspy.Rectangle( (waveguide.x-sec_gap-r1-taper_l-r1-wg_w2,waveguide.y-gap-0.5*wg_w-r1*2*(1.5-cos(pi/8.0))-r1-wg_w2),(waveguide.x-sec_gap-r1-taper_l+r1+wg_w2,waveguide.y-gap-0.5*wg_w-r1*2*(1.5-cos(pi/8.0))+r1+wg_w2),**spec3)
    #nofillw=gdspy.Rectangle( (-bragg_offset,-bragg_nofill/2.0-bragg_nfoffset),(waveguide.x,waveguide.y+bragg_nofill/2.0-bragg_nfoffset),**spec3)

    ## ------------------------------------------------------------------ ##
    ##	Adding Objects into Cells				        	      ##
    ## ------------------------------------------------------------------ ##

    wg_cell.add(waveguide)
    wg_cell.add(
        waveguide2
    )  # Cell: Waveguide; Objects: waveguide+taper, waveguide trenching

    cavity_cell.add(cav1)
    cavity_cell.add(cav2)
    cavity_cell.add(cav3)
    cavity_cell.add(
        cav12)  # Cell: Cavity; Objects: coupled rings, ring trenching

    # --------- Taper sections --------------------------- #

    return (wg_cell, cavity_cell)
示例#22
0
    chord_angle = 2 * math.asin(flat_size / diameter)
    center = Vector((diameter / 2, diameter / 2, 0))

    # Then, calculate the start and stop angles for an arc
    initial_angle = -chord_angle / 2 + 3 * math.pi / 2
    final_angle = chord_angle / 2 - math.pi / 2

    # Find the positions of the start and the end
    start_vect = Vector((diameter, diameter / 2, 0))
    start_vect = gen_rotate_matrix(math.degrees(initial_angle),
                                   center) @ start_vect

    curve = gdspy.Curve(*start_vect.xy, tolerance=10)
    curve.arc(diameter / 2, initial_angle, final_angle)
    return gdspy.Polygon(curve.get_points(), layer=layer)


if __name__ == "__main__":
    doc = gdspy.GdsLibrary()
    mark = elionix_mark(doc)
    elionix_4block(doc, mark)
    render_text.render_to_block(doc, "NW200311_0001")
    arrow_cell = gdspy.Cell("arrow")
    arrow_cell.add(arrow(Vector((0, 0, 0))))
    doc.add(arrow_cell)
    die_marker(doc, name="die_marker")
    wire_section(doc, "a")
    draw_wafer(doc)
    with open("test.gds", "wb") as f:
        doc.write_gds(f)
示例#23
0
"""

import gdspy
from Modules.ModuleResonator import TwirledSpiral, Cpw_twirled
import numpy as np

Centre = (0, 0)
L = 0.75e-3
W = 500e-9
I = 10.085e-6

carac = {"layer": 0, "datatype": 3}
ab = TwirledSpiral(Centre, L, W, I, [0, 0])
a = gdspy.FlexPath(ab[0], W * 1e6, **carac).rotate(np.pi / 2, (ab[0][0]))
b = gdspy.FlexPath(ab[1], W * 1e6, **carac).rotate(np.pi / 2, (ab[0][0]))
testcell = gdspy.Cell("testcell")
testcell.add(a)
testcell.add(b)

#Dimensions of one resonator (see in vjws journal 26/02/21 for graphical explanation of formula)
Lsize = ab[1][-1][1] - ab[0][-1][1] + W * 1e6
#Height of the resonator
Hsize = ab[0][-1][0] - ab[1][-1][0]

Hr = Hsize * 1e-6  #height of resonator in SI units
Lr = Lsize * 1e-6  #length of resonator in SI units
center_first = ab[0][0]

Sr = 1e-6

#Generating the ground plane + cpw
示例#24
0
def gen_gds(poly_coords: List[np.ndarray],
            filepath: str,
            extra_structures: List[np.ndarray] = None,
            deembed: bool = True) -> None:
    """Generate GDS given a list of polygon coordinates.

    Output GDS has units of microns and precision in nanometers.

    Args:
        poly_coords: List of polygon coordinates. Elements of list are
            n x 2 numpy.ndarrays. Assumes coordinates in nanometers.
        filepath: Name of the filepath to output gds file.
        extra_structures: List of polygons to be added to the gds that are
            not part of the levelset function.
        deembed: Boolean to control if polygon deembeding will occur or not.
    """
    poly_cell = gdspy.Cell("POLYGONS", exclude_from_current=True)

    test_points = []
    gds_polygons = []

    # Convert polygon coordinates from nanometers to microns since
    # output is in microns.
    poly_coords = [np.array(poly) / NM_PER_UM for poly in poly_coords]

    for polygon in poly_coords:
        test_points.append(tuple(polygon[0]))
        gds_polygons.append(gdspy.Polygon(polygon, 0))

    if deembed:

        containment_mx = []
        for polygon in gds_polygons:
            containment_mx.append(gdspy.inside(test_points, [polygon]))

        # Subtract by identity matrix since polygon_i trivially contains
        # polygon_i.
        containment_mx = np.array(containment_mx) - np.eye(len(gds_polygons))
        # overlap_list[i] tells how many polygons are contained in polygon i.
        overlap_list = np.sum(containment_mx, axis=1)

        overlap_num = 0
        while sum(overlap_list) != 0:

            overlap_num = overlap_num + 1

            # We loop until there are no longer any more polygons of a specific
            # overlap number before going to the next overlap number.
            #
            # The reasoning for this is as we begin to delete polygons,
            # the overlap number changes and so polygons which were of
            # overlap_num > 1, may become polygons of overlap_num = 1.
            #
            # np.where(overlap_list==overlap_num)[0].size is how we see if
            # any polygons satisfy the current overlap number.

            target_polys = np.where(overlap_list == overlap_num)[0]
            while target_polys.size != 0:

                # We iterate through each polygon in our polygon list until no
                # polygon satisfies the current overlap number.
                for i in target_polys[::-1]:
                    containment_list = np.nonzero(containment_mx[i, :])[0]
                    for j in containment_list[::-1]:
                        # The boolean 'not' operation is performed here.
                        # We replace polygon[i] of the two polygons with the
                        # result of the operation and delete polygon[j].
                        gds_polygons[i] = gdspy.fast_boolean(gds_polygons[i],
                                                             gds_polygons[j],
                                                             'not',
                                                             layer=0)
                        gds_polygons[j] = None
                        test_points[j] = None

                for k in range(len(gds_polygons) - 1, -1, -1):
                    if gds_polygons[k] is None:
                        del gds_polygons[k]
                        del test_points[k]

                containment_mx = []
                for polygon in gds_polygons:
                    containment_mx.append(gdspy.inside(test_points, [polygon]))

                containment_mx = np.array(containment_mx) - np.eye(
                    len(gds_polygons))
                overlap_list = np.sum(containment_mx, axis=1)

                target_polys = np.where(overlap_list == overlap_num)[0]

    for polygon in gds_polygons:
        poly_cell.add(polygon)

    if extra_structures is not None:
        for extra_polygon in extra_structures:
            poly_cell.add(gdspy.Polygon(extra_polygon, 0))

    gdspy.write_gds(filepath, cells=[poly_cell], unit=1.0e-6, precision=1.0e-9)
name = (os.path.abspath(os.path.dirname(os.sys.argv[0]))) + os.sep + 'devices'

print('Creating layout')

## ------------------------------------------------------------------ ##
##  DRAWING                                                           ##
## ------------------------------------------------------------------ ##

# Layers
layer_vector = [
    1
]  # order: disks, bullseye mod a, bullseye mod wRing, idmarks, working area, align marks

# Create a cell for the unit element
unit_cell1 = gdspy.Cell('testcell')

for x in range(0, 19):
    unit_cell1.add(draw_waveguide(1, (0, 0.01 * x), x, 19))

## ------------------------------------------------------------------ ##
##  OUTPUT                                                            ##
## ------------------------------------------------------------------ ##

## Output the layout to a GDSII file (default to all created cells).
## Set the units we used to micrometers and the precision to nanometers.
gdspy.gds_print(name + '.gds', unit=1.0e-6, precision=1.0e-9)
print('Sample gds file saved: ' + name + '.gds')

## ------------------------------------------------------------------ ##
##  VIEWER                                                            ##
示例#26
0
                    l.text,
                    font=font,
                    fill=color[(l.layer, l.texttype)])
    img = img.resize((width, height), Image.ANTIALIAS)
    name = 'docs/_static/' + (cell.name if name is None else name) + '.png'
    print('Saving', name)
    img.save(name)


if __name__ == "__main__":
    # Polygons
    # Create a polygon from a list of vertices
    points = [(0, 0), (2, 2), (2, 6), (-6, 6), (-6, -6), (-4, -4), (-4, 4),
              (0, 4)]
    poly = gdspy.Polygon(points)
    draw(gdspy.Cell('polygons').add(poly))

    # Holes
    # Manually connect the hole to the outer boundary
    cutout = gdspy.Polygon([(0, 0), (5, 0), (5, 5), (0, 5), (0, 0), (2, 2),
                            (2, 3), (3, 3), (3, 2), (2, 2)])
    draw(gdspy.Cell('holes').add(cutout))

    # Circles
    # Circle centered at (0, 0), with radius 2 and tolerance 0.1
    circle = gdspy.Round((0, 0), 2, tolerance=0.01)

    # To create an ellipse, simply pass a list with 2 radii.
    # Because the tolerance is small (resulting a large number of
    # vertices), the ellipse is fractured in 2 polygons.
    ellipse = gdspy.Round((4, 0), [1, 2], tolerance=1e-4)
示例#27
0
def test_rw_gds(tmpdir):
    lib = gdspy.GdsLibrary('lib')
    c1 = gdspy.Cell('gl_rw_gds_1', True)
    c1.add(gdspy.Rectangle((0, -1), (1, 2), 2, 4))
    c1.add(gdspy.Label('label', (1, -1), 'w', 45, 1.5, True, 5, 6))
    c2 = gdspy.Cell('gl_rw_gds_2', True)
    c2.add(gdspy.Round((0, 0), 1, number_of_points=32, max_points=20))
    c3 = gdspy.Cell('gl_rw_gds_3', True)
    c3.add(gdspy.CellReference(c1, (0, 1), -90, 2, True))
    c4 = gdspy.Cell('gl_rw_gds_4', True)
    c4.add(gdspy.CellArray(c2, 2, 3, (1, 4), (-1, -2), 180, 0.5, True))
    lib.add((c1, c2, c3, c4))

    fname1 = str(tmpdir.join('test1.gds'))
    lib.write_gds(fname1, unit=2e-3, precision=1e-5)
    lib1 = gdspy.GdsLibrary()
    lib1.read_gds(fname1, 1e-3, {'gl_rw_gds_1': '1'}, {2: 4}, {4: 2}, {6: 7})
    assert lib1.name == 'lib'
    assert len(lib1.cell_dict) == 4
    assert set(lib1.cell_dict.keys()) == {
        '1', 'gl_rw_gds_2', 'gl_rw_gds_3', 'gl_rw_gds_4'
    }
    c = lib1.cell_dict['1']
    assert len(c.elements) == len(c.labels) == 1
    assert c.elements[0].area() == 12.0
    assert c.elements[0].layer == 4
    assert c.elements[0].datatype == 2
    assert c.labels[0].text == 'label'
    assert c.labels[0].position[0] == 2 and c.labels[0].position[1] == -2
    assert c.labels[0].anchor == 4
    assert c.labels[0].rotation == 45
    assert c.labels[0].magnification == 1.5
    assert c.labels[0].x_reflection == True
    assert c.labels[0].layer == 5
    assert c.labels[0].texttype == 7

    c = lib1.cell_dict['gl_rw_gds_2']
    assert len(c.elements) == 2
    assert isinstance(c.elements[0], gdspy.Polygon) \
           and isinstance(c.elements[1], gdspy.Polygon)

    c = lib1.cell_dict['gl_rw_gds_3']
    assert len(c.elements) == 1
    assert isinstance(c.elements[0], gdspy.CellReference)
    assert c.elements[0].ref_cell == lib1.cell_dict['1']
    assert c.elements[0].origin[0] == 0 and c.elements[0].origin[1] == 2
    assert c.elements[0].rotation == -90
    assert c.elements[0].magnification == 2
    assert c.elements[0].x_reflection == True

    c = lib1.cell_dict['gl_rw_gds_4']
    assert len(c.elements) == 1
    assert isinstance(c.elements[0], gdspy.CellArray)
    assert c.elements[0].ref_cell == lib1.cell_dict['gl_rw_gds_2']
    assert c.elements[0].origin[0] == -2 and c.elements[0].origin[1] == -4
    assert c.elements[0].rotation == 180
    assert c.elements[0].magnification == 0.5
    assert c.elements[0].x_reflection == True
    assert c.elements[0].spacing[0] == 2 and c.elements[0].spacing[1] == 8
    assert c.elements[0].columns == 2
    assert c.elements[0].rows == 3

    fname2 = str(tmpdir.join('test2.gds'))
    lib.name = 'lib2'
    with open(fname2, 'wb') as fout:
        lib.write_gds(fout, unit=2e-3, precision=1e-5)
    with open(fname2, 'rb') as fin:
        lib2 = gdspy.GdsLibrary()
        lib2.read_gds(fin)
    assert lib2.name == 'lib2'
    assert len(lib2.cell_dict) == 4
示例#28
0
def create_sim_space(
    gds_fg_name: str,
    gds_bg_name: str,
    sim_width: float = 8000,  # size of sim_space
    box_width: float = 4000,  # size of our editing structure
    wg_width: float = 600,
    buffer_len: float = 1500,  # not sure we'll need
    dx: int = 40,
    num_pmls: int = 10,
    visualize: bool = False,
) -> optplan.SimulationSpace:
    """Creates the simulation space.

    The simulation space contains information about the boundary conditions,
    gridding, and design region of the simulation.

    Args:
        gds_fg_name: Location to save foreground GDS.
        gds_bg_name: Location to save background GDS.
        etch_frac: Etch fraction of the grating. 1.0 indicates a fully-etched
            grating.
        box_thickness: Thickness of BOX layer in nm.
        wg_width: Width of the waveguide.
        buffer_len: Buffer distance to put between grating and the end of the
            simulation region. This excludes PMLs.
        dx: Grid spacing to use.
        num_pmls: Number of PML layers to use on each side.
        visualize: If `True`, draws the polygons of the GDS file.

    Returns:
        A `SimulationSpace` description.
    """
    # Calculate the simulation size, including  PMLs
    # TODO change the first part of ech dimension to be equal
    sim_size = [
        sim_width + 2 * buffer_len + dx * num_pmls,
        sim_width + 2 * buffer_len + dx * num_pmls
    ]
    # First, we use `gdspy` to draw the waveguides and shapes that we would
    # like to use. Instead of programmatically generating a GDS file using
    # `gdspy`, we could also simply provide a GDS file (e.g. drawn using
    # KLayout).

    # Declare some constants to represent the different layers.
    # Not sure if we need layers
    LAYER = 100

    # Create rectangles corresponding to the waveguide, the BOX layer, and the
    # design region. We extend the rectangles outside the simulation region
    # by multiplying locations by a factor of 1.1.

    # We distinguish between the top part of the waveguide (which is etched)
    # and the bottom part of the waveguide (which is not etched).

    # TODO define our single waveguide and surface, I don't believe it will be etched.
    # Switch x and y temporarily to try and get better direction for field - change top to bottom
    # Add an exit
    waveguide_top = gdspy.Rectangle((-1.1 * sim_size[0] / 2, -wg_width / 2),
                                    (-box_width / 2, wg_width / 2), LAYER)

    waveguide_bottom = gdspy.Rectangle((box_width / 2, -wg_width / 2),
                                       (1.1 * sim_size[0] / 2, wg_width / 2),
                                       LAYER)

    design_region = gdspy.Rectangle(
        (-box_width / 2, -box_width / 2),
        (box_width / 2, box_width / 2),  # extend region?
        LAYER)

    # Generate the foreground and background GDS files.
    gds_fg = gdspy.Cell("FOREGROUND", exclude_from_current=True)
    gds_fg.add(waveguide_top)
    gds_fg.add(waveguide_bottom)
    gds_fg.add(design_region)

    # I guess we keep this the same and not include the design_region
    gds_bg = gdspy.Cell("BACKGROUND", exclude_from_current=True)
    gds_bg.add(waveguide_top)
    gds_bg.add(waveguide_bottom)

    gdspy.write_gds(gds_fg_name, [gds_fg], unit=1e-9, precision=1e-9)
    gdspy.write_gds(gds_bg_name, [gds_bg], unit=1e-9, precision=1e-9)

    # The BOX layer/silicon device interface is set at `z = 0`.
    #
    # Describe materials in each layer.

    # 1) Silicon Nitride

    # Note that the layer numbering in the GDS file is arbitrary. Layer 300 is a dummy
    # layer; it is used for layers that only have one material (i.e. the
    # background and foreground indices are identical) so the actual structure
    # used does not matter.

    # Will need to define out material, just silicon nitride
    # Remove the etching stuff
    # Can define Si3N4 - the material we want to use
    # Fix: try to make multiple layers, but all the same?
    air = optplan.Material(index=optplan.ComplexNumber(real=1))
    stack = [
        optplan.GdsMaterialStackLayer(
            foreground=air,
            background=air,
            gds_layer=[100, 0],
            extents=[
                -10000, -110
            ],  # will probably need to define a better thickness for our layer
        ),
        optplan.GdsMaterialStackLayer(
            foreground=optplan.Material(mat_name="Si3N4"),
            background=air,
            gds_layer=[100, 0],
            extents=[
                -110, 110
            ],  # will probably need to define a better thickness for our layer
        ),
    ]

    mat_stack = optplan.GdsMaterialStack(
        # Any region of the simulation that is not specified is filled with
        # air.
        background=air,
        stack=stack,
    )

    # these define the entire region you wish to scan in the z -direction, not sure for us
    # as we don't require etching or layers
    # will probably change this as thickness may be wrong

    # Create a simulation space for both continuous and discrete optimization.
    # TODO too large a space takes too long to process - may need blue bear
    simspace = optplan.SimulationSpace(
        name="simspace",
        mesh=optplan.UniformMesh(dx=dx),
        eps_fg=optplan.GdsEps(gds=gds_fg_name, mat_stack=mat_stack),
        eps_bg=optplan.GdsEps(gds=gds_bg_name, mat_stack=mat_stack),
        # Note that we explicitly set the simulation region. Anything
        # in the GDS file outside of the simulation extents will not be drawn.
        sim_region=optplan.Box3d(
            center=[0, 0, 0],
            extents=[6000, 6000,
                     40],  # this is what's messing things up, needs to be 2D
        ),  # changing the size too much creates an error
        selection_matrix_type="direct_lattice",  # or uniform
        # PMLs are applied on x- and z-axes. No PMLs are applied along y-axis
        # because it is the axis of translational symmetry.
        pml_thickness=[num_pmls, num_pmls, num_pmls, num_pmls, 0,
                       0],  # may need to edit this, make z the 0 axis
    )

    if visualize:
        # To visualize permittivity distribution, we actually have to
        # construct the simulation space object.
        import matplotlib.pyplot as plt
        from spins.invdes.problem_graph.simspace import get_fg_and_bg

        context = workspace.Workspace()
        eps_fg, eps_bg = get_fg_and_bg(context.get_object(simspace),
                                       label=1070)  #edit here

        def plot(x):
            plt.imshow(np.abs(x)[:, 0, :].T.squeeze(), origin="lower")

        plt.figure()
        plt.subplot(3, 1, 1)
        plot(eps_fg[2])
        plt.title("eps_fg")

        plt.subplot(3, 1, 2)
        plot(eps_bg[2])
        plt.title("eps_bg")

        plt.subplot(3, 1, 3)
        plot(eps_fg[2] - eps_bg[2])
        plt.title("design region")
        plt.show()
    return simspace
def draw(gap):

    ## ------------------------------------------------------------------ ##
    ##	Define Cells						      ##
    ## ------------------------------------------------------------------ ##
    wg_cell = []
    nofill_cell = []
    cavity_cell = []
    gccell = []
    httiaucell = []
    htnicrcell = []

    del (wg_cell, nofill_cell, cavity_cell, gccell, httiaucell, htnicrcell)

    ## Cell containing the waveguides
    wg_cell = gdspy.Cell('WAVEGUIDES' + str(2 * n * (gap - gap0) /
                                            (gap0 + gap1)))

    ## Cell containing no fill area
    nofill_cell = gdspy.Cell('NOFILL' + str(2 * n * (gap - gap0) /
                                            (gap0 + gap1)))

    ## Cell containing microrings
    cavity_cell = gdspy.Cell('CAV' + str(2 * n * (gap - gap0) / (gap0 + gap1)))

    ## Cell containing bragg couplings

    gc = gdspy.GdsImport('GC_mod.gds',
                         rename={
                             'q':
                             'COUPLERGRATING' + str(2 * n * (gap - gap0) /
                                                    (gap0 + gap1))
                         },
                         layers={10158: 1158})

    gccell = gc.extract('COUPLERGRATING' + str(2 * n * (gap - gap0) /
                                               (gap0 + gap1)))

    ## Aligment Cell

    am = gdspy.GdsImport('aligment_mark.gds',
                         rename={
                             'Alignment_Mark':
                             'Alignment_Mark' + str(2 * n * (gap - gap0) /
                                                    (gap0 + gap1))
                         })

    amcell = am.extract('Alignment_Mark' + str(2 * n * (gap - gap0) /
                                               (gap0 + gap1)))

    ## NiCr Heater Cell

    nccell = gdspy.Cell('Heater_Ni_Cr' + str(2 * n * (gap - gap0) /
                                             (gap0 + gap1)))

    ## ------------------------------------------------------------------ ##
    ##	Layer Specification					      ##
    ## ------------------------------------------------------------------ ##

    spec = {'layer': 37, 'datatype': 4}  # Fully etched SOI: waveguide core
    spec2 = {
        'layer': 37,
        'datatype': 5
    }  # Fully etched SOI: waveguide cladding (trench around core)
    spec3 = {
        'layer': 1158,
        'datatype': 0
    }  # Area not to be filled with dummies (SOI,Poly or metal)
    spec4 = {'layer': 1, 'datatype': 0}  # NiCr mask

    ## ------------------------------------------------------------------ ##
    ##	Objects Design				        	      ##
    ## ------------------------------------------------------------------ ##

    #------ Waveguide+taper   -----------------------------------------------#

    waveguide = gdspy.Path(wg_w, (-sec_gap, 0))
    waveguide.segment(sec_gap, '+x', **spec)
    waveguide.segment(r1 * (1 - 2 * sin(pi / 8.0)), '+x', **spec)
    waveguide.turn(r1,
                   -pi / 8.0,
                   max_points=4094,
                   number_of_points=0.1,
                   **spec)
    waveguide.turn(r1, pi / 8.0, max_points=4094, number_of_points=0.1, **spec)
    waveguide.turn(r1, pi / 8.0, max_points=4094, number_of_points=0.1, **spec)
    waveguide.turn(r1,
                   -pi / 8.0,
                   max_points=4094,
                   number_of_points=0.1,
                   **spec)
    waveguide.segment(r1 * (1 - 2 * sin(pi / 8.0)), '+x', **spec)
    waveguide.segment(sec_gap, '+x', **spec)
    waveguide.segment(taper_l, '+x', final_width=taper_w, **spec)

    #------ No tilling region   -----------------------------------------------#
    nofill = gdspy.Path(nofill_w, (waveguide.x - taper_l, waveguide.y))
    nofill.segment(taper_l + taper_ii_l + iii_v_l / 2.0, '+x', **spec3)

    #------ Coupled Microrings   -----------------------------------------------#
    r2 = (r1 - wg_w - 3.0 * gap / 2.0) / 2.0
    pcavc = (waveguide.x - sec_gap - r1 - taper_l,
             waveguide.y - gap - 0.5 * wg_w - r1 * 2 * (1.5 - cos(pi / 8.0)))
    cav1 = gdspy.Round((pcavc[0], pcavc[1]),
                       r1,
                       r1 - wg_w,
                       max_points=4094,
                       number_of_points=0.1,
                       **spec)
    cav2 = gdspy.Round((pcavc[0] + r2 + 0.5 * gap, pcavc[1]),
                       r2,
                       r2 - wg_w,
                       max_points=4094,
                       number_of_points=0.1,
                       **spec)
    cav3 = gdspy.Round((pcavc[0] - r2 - 0.5 * gap, pcavc[1]),
                       r2,
                       r2 - wg_w,
                       max_points=4094,
                       number_of_points=0.1,
                       **spec)

    #------ Trench Arond waveguides   -----------------------------------------------#

    waveguide2 = gdspy.Path(wg_w2, (-sec_gap, 0))
    waveguide2.segment(sec_gap, '+x', **spec2)
    waveguide2.segment(r1 * (1 - 2 * sin(pi / 8.0)), '+x', **spec2)
    waveguide2.turn(r1,
                    -pi / 8.0,
                    max_points=4094,
                    number_of_points=0.1,
                    **spec2)
    waveguide2.turn(r1,
                    pi / 8.0,
                    max_points=4094,
                    number_of_points=0.1,
                    **spec2)
    waveguide2.turn(r1,
                    pi / 8.0,
                    max_points=4094,
                    number_of_points=0.1,
                    **spec2)
    waveguide2.turn(r1,
                    -pi / 8.0,
                    max_points=4094,
                    number_of_points=0.1,
                    **spec2)
    waveguide2.segment(r1 * (1 - 2 * sin(pi / 8.0)), '+x', **spec2)
    waveguide2.segment(sec_gap, '+x', **spec2)
    waveguide2.segment(taper_l, '+x', **spec2)

    #------ Trench Arond coupled rings   -----------------------------------------------#

    cav12 = gdspy.Rectangle((pcavc[0] - r1 - c_w2, pcavc[1] - r1 - c_w2),
                            (pcavc[0] + r1 + c_w2, pcavc[1] + r1 + c_w2),
                            **spec2)

    #nofillc=gdspy.Rectangle( (waveguide.x-sec_gap-r1-taper_l-r1-wg_w2,waveguide.y-gap-0.5*wg_w-r1*2*(1.5-cos(pi/8.0))-r1-wg_w2),(waveguide.x-sec_gap-r1-taper_l+r1+wg_w2,waveguide.y-gap-0.5*wg_w-r1*2*(1.5-cos(pi/8.0))+r1+wg_w2),**spec3)
    #nofillw=gdspy.Rectangle( (-bragg_offset,-bragg_nofill/2.0-bragg_nfoffset),(waveguide.x,waveguide.y+bragg_nofill/2.0-bragg_nfoffset),**spec3)

    #------ NiCr Heater  -----------------------------------------------#
    nch = nicrheat(spec4['layer'], pcavc, r1, hw, hh, ang, sqr)
    #nch = gdspy.Rectangle( (pcavc[0]-r1-c_w2,pcavc[1]-r1-c_w2),(pcavc[0]+r1+c_w2,pcavc[1]+r1+c_w2),**spec4)

    ## ------------------------------------------------------------------ ##
    ##	Adding Objects into Cells				        	      ##
    ## ------------------------------------------------------------------ ##

    wg_cell.add(waveguide)
    wg_cell.add(
        waveguide2
    )  # Cell: Waveguide; Objects: waveguide+taper, waveguide trenching

    nofill_cell.add(nofill)  #Cell: No fill; Objects: No tilling region

    cavity_cell.add(cav1)
    cavity_cell.add(cav2)
    cavity_cell.add(cav3)
    cavity_cell.add(
        cav12)  # Cell: Cavity; Objects: coupled rings, ring trenching

    nccell.add(nch)

    waveguidex = waveguide.x
    waveguidey = waveguide.y

    # --------- Taper sections --------------------------- #

    return (wg_cell, cavity_cell, gccell, nofill_cell, waveguidex, waveguidey,
            amcell, nccell)
示例#30
0
                    i = len(polys) - 1
                    while i >= 0:
                        if gdspy.inside(poly[:1], [polys[i]],
                                        precision=0.1 * tolerance)[0]:
                            p = polys.pop(i)
                            poly = gdspy.boolean([p], [poly],
                                                 'xor',
                                                 precision=0.1 * tolerance,
                                                 max_points=0).polygons[0]
                            break
                        elif gdspy.inside(polys[i][:1], [poly],
                                          precision=0.1 * tolerance)[0]:
                            p = polys.pop(i)
                            poly = gdspy.boolean([p], [poly],
                                                 'xor',
                                                 precision=0.1 * tolerance,
                                                 max_points=0).polygons[0]
                        i -= 1
                xmax = max(xmax, poly[:, 0].max())
                polys.append(poly)
    return polys


if __name__ == "__main__":
    fp = FontProperties(family='serif', style='italic')
    text = gdspy.PolygonSet(render_text('Text rendering', 10, font_prop=fp),
                            layer=1)
    gdspy.Cell('TXT').add(text)
    gdspy.write_gds('fonts.gds')
    gdspy.LayoutViewer()