예제 #1
0
    def make_slits_reservoir(self, nslit, pitch, width, contact_distance, layers): # 5 additional slits as material reservoir
        res_slit = 5

        gap = contact_distance + 2. + 2.  
        res_length = (length - gap - 2.5*margin)/2 
        res_width = width
        res_pitch = pitch

        resField = Cell("resField")

        reservoir = Cell("Single Reservoir")
        res_path = Path([(-res_length / 2., 0), (res_length / 2., 0)], width = res_width, layer = layers)
        reservoir.add(res_path)

        reservoirs= CellArray(reservoir, 2, res_slit, spacing = (res_length + gap, res_pitch))
        reservoirs.translate((-(res_length + gap)/2,0))
        res_array = Cell("Multiple Slit")
        res_array.add(reservoirs)
        resField.add(res_array, origin=(0,0), rotation=rot_angle)

        if contact_distance > margin:
            add_slit = Cell("Additional Reservoir")
            add_res_path = Path([(-(contact_distance - 0.8*margin) / 2., 0), ((contact_distance - 0.8*margin) / 2., 0)], width = res_width, layer = layers)
            add_slit.add(add_res_path)

            add_reservoir = CellArray(add_slit, 1, res_slit, spacing = (0, res_pitch))
            add_reservoir.translate((0,0))
            add_res_array = Cell("Additional Multiple Slit")
            add_res_array.add(add_reservoir)
            resField.add(add_res_array, origin=(0,0), rotation=rot_angle)



        self.add(resField, origin= (0,(nslit+1) * pitch/2 ))
        self.add(resField, origin= (0, -((nslit+1+(2*(res_slit-1))) * pitch/2 )))
def make_rotating_slits(length,
                        width,
                        N,
                        radius,
                        layers,
                        angle_ref=None,
                        angle_sweep=360):
    """

    :param length: Length of the slits in the circle
    :param width: Width of the slits in the circle
    :param N: Number of slits going around the circle
    :param radius: Radius of the circle
    :param layers: Layers to write the slits in
    :param angle_ref: if None, no angle reference lines are added. If '111' then add reference lines at 30/60 degrees. If '100' then add reference lines at 45/90 degrees.
    :return:
    """
    cell = Cell('RotatingSlits')
    if not (type(layers) == list): layers = [layers]
    allslits = Cell('All Slits')
    angles = np.linspace(0, angle_sweep, N)
    #        radius = length*12.
    translation = (radius, 0)
    for l in layers:
        # rect = Rectangle(pt1, pt2, layer=l)
        membrane = Path([(-length / 2., 0), (length / 2., 0)],
                        width=width,
                        layer=l)
        membrane_cell = Cell('Membrane_w{:.0f}'.format(width * 1000))
        membrane_cell.add(membrane)
        slit = Cell("Slit")
        slit.add(membrane_cell, origin=translation)
        for angle in angles:
            allslits.add(slit, rotation=angle)
        cell.add(allslits)

        if angle_ref:
            labelCell = Cell('AngleLabels')
            lineCell = Cell('Line')
            pt1 = (-radius * 0.9, 0)
            pt2 = (radius * 0.9, 0)
            line = Path([pt1, pt2], width=width, layer=l)
            dLine = dashed_line(pt1, pt2, 2, width, l)
            lineCell.add(line)
            labelCell.add(lineCell, rotation=0)
            if angle_ref == '111':
                labelCell.add(lineCell, rotation=60)
                labelCell.add(lineCell, rotation=-60)
                labelCell.add(dLine, rotation=30)
                labelCell.add(dLine, rotation=90)
                labelCell.add(dLine, rotation=-30)
            elif angle_ref == '100':
                labelCell.add(lineCell, rotation=0)
                labelCell.add(lineCell, rotation=90)
                labelCell.add(dLine, rotation=45)
                labelCell.add(dLine, rotation=135)
            cell.add(labelCell)

        return cell
예제 #3
0
def makeShape_Star(pitch, length, width, n_buffers, layer):
    """
    Makes star shaped branched structures for quantum transport experiments
    :param pitch: Center-to-center distance between slits
    :param length: Length of the crossing slits
    :param width: Width of the slits
    :param n_buffers: Number of slits to put around (buffer) the crossing slits
    :param layer: GDS layer to put the pattern on
    :return: Cell with the desired pattern on it
    """
    longline = Path([(-length / 2., 0), (length / 2., 0)],
                    width=width,
                    layer=layer)
    shortline = Path([(0, 0), (length / 2., 0)], width=width, layer=layer)
    long_slit = Cell('LongSlit')
    long_slit.add(longline)
    short_slit = Cell('ShortSlit')
    short_slit.add(shortline)

    starShape = Cell('StarShape')
    starShape.add(long_slit, rotation=0)
    starShape.add(long_slit, rotation=-45)
    starShape.add(long_slit, rotation=45)

    if n_buffers <= 0:
        return starShape

    sideBufferNM = Cell('X_Buffer')
    sideBufferNM.add(short_slit, rotation=0)
    sideBufferNM.add(short_slit, rotation=90)

    allBuffers = Cell('X_AllBufferNMs')
    for i in range(n_buffers):
        allBuffers.add(sideBufferNM, origin=((i + 1) * pitch, (i + 1) * pitch))

    starShape.add(allBuffers, rotation=45)
    starShape.add(allBuffers, rotation=225)

    smallBuffer = Cell('SmX_Buffer')
    for i in range(n_buffers):
        smallBuffer.add(
            short_slit,
            rotation=0,
            origin=((i + 1) * pitch * (1 + 2 * np.cos(np.deg2rad(45))),
                    (i + 1) * pitch))
        smallBuffer.add(
            short_slit,
            rotation=45,
            origin=((i + 1) * pitch * (1 + 2 * np.cos(np.deg2rad(45))),
                    (i + 1) * pitch))

    starShape.add(smallBuffer)
    starShape.add(smallBuffer, rotation=-45)
    starShape.add(smallBuffer, rotation=180)
    starShape.add(smallBuffer, rotation=135)

    return starShape
 def processCheck_CleavingMark(self, yPosition, layers):
     if not (type(layers) == list): layers = [layers]
     for l in layers:
         pt1 = (100, yPosition)
         pt2 = (2000, yPosition)
         pt3 = (-1100, yPosition)
         pt4 = (-2800, yPosition)
         line1 = Path([pt1, pt2], width=10, layer=l)
         line2 = Path([pt3, pt4], width=10, layer=l)
         cMarkCell = Cell('Cleaving Mark')
         cMarkCell.add(line1)
         cMarkCell.add(line2)
         self.add(cMarkCell)
예제 #5
0
    def add_cleave_xsection_nws(self):
        pitches = [0.5, 1., 2., 4.]
        widths = [10., 20., 40., 60., 100., 160., 240.]
        n_membranes = 10
        length = 50
        spacing = 10

        cleave_xsection_cell = Cell("CleaveCrossSection")

        y_offset = 0
        for pitch in pitches:
            for width in widths:
                nm_cell = Cell("P{:.0f}W{:.0f}".format(pitch, width))
                slit = Path([(-length / 2., 0), (length / 2., 0)], width=width / 1000., layer=l_smBeam)
                nm_cell.add(slit)
                nm_cell_array = Cell("P{:.0f}W{:.0f}_Array".format(pitch, width))
                tmp = CellArray(nm_cell, 1.0, n_membranes, [0, pitch])
                nm_cell_array.add(tmp)
                cleave_xsection_cell.add(nm_cell_array, origin=(0, y_offset + pitch * n_membranes))
                y_offset += pitch * n_membranes + spacing

                text = Label("P{:.1f}W{:.0f}".format(pitch, width), 1.0, layer=l_smBeam)
                text.translate(tuple(np.array(-text.bounding_box.mean(0))))  # Center justify label
                txt_cell = Cell("lbl_P{:.1f}W{:.0f}".format(pitch, width))
                txt_cell.add(text)
                cleave_xsection_cell.add(txt_cell, origin=(length * 0.75, y_offset - 8.0))
                cleave_xsection_cell.add(txt_cell, origin=(-length * 0.75, y_offset - 8.0))

            y_offset += spacing * 3

        center_x, center_y = (5000, 5000)
        for block in self.blocks:
            block.add(cleave_xsection_cell, origin=(center_x + 1150, center_y - 463))
            # block.add(cleave_xsection_cell, origin=(center_x - 350, center_y + 350), rotation=45.)    # >> VP_mod: disabled <<
            block.add(cleave_xsection_cell, origin=(center_x + 463, center_y - 1150), rotation=90.)   # >> VP_mod: disabled<<
    def add_tem_membranes(self, widths, length, pitch, layer):

        tem_membranes = Cell('TEM_Membranes')

        n = 3
        curr_y = 0
        for width in widths:
            membrane = Path([(-length / 2., 0), (length / 2., 0)],
                            width=width,
                            layer=layer)
            membrane_cell = Cell('Membrane_w{:.0f}'.format(width * 1000))
            membrane_cell.add(membrane)
            membrane_array = CellArray(membrane_cell, 1, n, (0, pitch))
            membrane_array_cell = Cell('MembraneArray_w{:.0f}'.format(width *
                                                                      1000))
            membrane_array_cell.add(membrane_array)
            tem_membranes.add(membrane_array_cell, origin=(0, curr_y))
            curr_y += n * pitch

        n2 = 5
        tem_membranes2 = Cell('Many_TEM_Membranes')
        tem_membranes2.add(
            CellArray(tem_membranes, 1, n2, (0, n * len(widths) * pitch)))

        self.block_up.add(tem_membranes2, origin=(0, -2000))
        # self.block_up.add(tem_membranes2, origin=(0, -1400), rotation=90)

        self.block_down.add(tem_membranes2, origin=(0, 2000))
예제 #7
0
    def add_tem_membranes(self, widths, length, pitch, layer):
        tem_membranes = Cell('TEM_Membranes')
        n = 4
        curr_y = 0
        for width in widths:
            membrane = Path([(-length / 2., 0), (length / 2., 0)],
                            width=width,
                            layer=layer)
            membrane_cell = Cell('Membrane_w{:.0f}'.format(width * 1000))
            membrane_cell.add(membrane)
            membrane_array = CellArray(membrane_cell, 1, n, (0, pitch))
            membrane_array_cell = Cell('MembraneArray_w{:.0f}'.format(width *
                                                                      1000))
            membrane_array_cell.add(membrane_array)
            tem_membranes.add(membrane_array_cell, origin=(0, curr_y))
            curr_y += n * pitch

        n2 = 3
        tem_membranes2 = Cell('Many_TEM_Membranes')
        tem_membranes2.add(
            CellArray(tem_membranes, 1, n2, (0, n * len(widths) * pitch)))

        center_x, center_y = (5000, 5000)
        for block in self.blocks:
            block.add(tem_membranes2, origin=(center_x, center_y + 2000))
            block.add(tem_membranes2,
                      origin=(center_x, center_y + 1500),
                      rotation=45)
    def makeXShape(self, length, width, rotAngle, spacing, Nx, Ny, layers):
        if not (type(layers) == list): layers = [layers]
        slit = Cell("Slit")
        for l in layers:
            membrane = Path([(-length / 2., 0), (length / 2., 0)],
                            width=width,
                            layer=l)
            membrane_cell = Cell('Membrane_w{:.0f}'.format(width * 1000))
            membrane_cell.add(membrane)
            slit.add(membrane_cell)
        shape = Cell('Shapes')
        shape.add(slit, rotation=60)
        shape.add(slit, rotation=120)

        xspacing = (length + spacing) * np.cos(np.deg2rad(60))
        yspacing = (length + spacing) * np.sin(np.deg2rad(60))
        shapearray = CellArray(shape,
                               Nx,
                               Ny, (xspacing, yspacing),
                               origin=(-(Nx * xspacing - spacing) / 2.,
                                       -(Ny * yspacing - spacing) / 2.))
        #            shapearray2 = CellArray(shape, Nx, Ny/2,(xspacing,yspacing*2.),origin=(xspacing/2.-(Nx*xspacing-spacing)/2.,yspacing-(Ny*yspacing-spacing*np.tan(np.deg2rad(60)))/2.))
        #            shapearray = CellArray(shape, Nx, Ny,(xspacing,yspacing))
        #            shapearray.rotate(rotAngle)
        #            shapearray.translate((-shapearray.bounding_box.mean(0)[0]/2.,-shapearray.bounding_box.mean(0)[1]/2.))

        allshapes = Cell('All Shapes')
        allshapes.add(shapearray)
        #            allshapes.add(shapearray2)
        #            allshapes.add(shape)
        self.add(allshapes)
    def add_tem_membranes(self, widths, length, pitch, layer):
        tem_membranes = Cell('TEM_Membranes')
        n = 5
        curr_y = 0
        for width in widths:
            membrane = Path([(-length / 2., 0), (length / 2., 0)],
                            width=width,
                            layer=layer)
            membrane_cell = Cell('Membrane_w{:.0f}'.format(width * 1000))
            membrane_cell.add(membrane)
            membrane_array = CellArray(membrane_cell, 1, n, (0, pitch))
            membrane_array_cell = Cell('MembraneArray_w{:.0f}'.format(width *
                                                                      1000))
            membrane_array_cell.add(membrane_array)
            tem_membranes.add(membrane_array_cell, origin=(0, curr_y))
            curr_y += n * pitch

        n2 = 3
        tem_membranes2 = Cell('Many_TEM_Membranes')
        tem_membranes2.add(
            CellArray(tem_membranes, 1, n2, (0, n * len(widths) * pitch)))

        # Add it in all the cells
        for (i, pt) in enumerate(self.block_pts):
            origin = (pt + np.array([0.5, 0.5])) * self.block_size
            self.add(tem_membranes2, origin=origin)
def make_arm(width, length, layer, cell_name='branch'):
    membrane = Path([(0, 0), (length, 0)], width=width, layer=layer)
    membrane_cell = Cell('Membrane_w{:.0f}'.format(width * 1000))
    membrane_cell.add(membrane)
    cell = Cell(cell_name)
    cell.add(membrane_cell)
    return cell
    def add_cleave_xsection_nws(self):
        pitches = [1., 2., 4.]
        widths = [10., 15., 20., 30., 40., 50.]
        n_membranes = 10
        length = 50
        spacing = 10

        cleave_xsection_cell = Cell("CleaveCrossSection")

        y_offset = 0
        for pitch in pitches:
            for width in widths:
                nm_cell = Cell("P{:.0f}W{:.0f}".format(pitch, width))
                slit = Path([(-length / 2., 0), (length / 2., 0)], width=width / 1000., layer=l_smBeam)
                nm_cell.add(slit)
                nm_cell_array = Cell("P{:.0f}W{:.0f}_Array".format(pitch, width))
                tmp = CellArray(nm_cell, 1.0, n_membranes, [0, pitch])
                nm_cell_array.add(tmp)
                cleave_xsection_cell.add(nm_cell_array, origin=(0, y_offset + pitch * n_membranes))
                y_offset += pitch * n_membranes + spacing
            y_offset += spacing * 3

        center_x, center_y = (5000, 5000)
        for block in self.blocks:
            block.add(cleave_xsection_cell, origin=(center_x + 1150, center_y - 340))
            block.add(cleave_xsection_cell, origin=(center_x - 500, center_y + 500), rotation=45.)
            block.add(cleave_xsection_cell, origin=(center_x + 340, center_y - 1150), rotation=90.)
    def makeYShapes(self, length, width, rotAngle, spacing, Nx, Ny, layers):
        if not (type(layers) == list): layers = [layers]
        slit = Cell("Slit")
        for l in layers:
            membrane = Path([(-length / 2., 0), (length / 2., 0)],
                            width=width,
                            layer=l)
            membrane_cell = Cell('Membrane_w{:.0f}'.format(width * 1000))
            membrane_cell.add(membrane)
            slit.add(membrane_cell)
        shape = Cell('Shapes')
        shape.add(slit, rotation=0 + rotAngle)
        shape.add(slit, rotation=120 + rotAngle)
        shape.add(slit, rotation=240 + rotAngle)

        #            CellArray(slit, Nx, Ny,(length + spacing, pitchV))
        xspacing = length + spacing
        yspacing = (length + spacing) * np.sin(np.deg2rad(60))
        shapearray = CellArray(
            shape,
            Nx,
            Ny / 2, (xspacing, yspacing * 2.),
            origin=(-(Nx * xspacing - spacing) / 2.,
                    -(Ny * yspacing - spacing * np.sin(np.deg2rad(60))) / 2.))
        shapearray2 = CellArray(
            shape,
            Nx,
            Ny / 2, (xspacing, yspacing * 2.),
            origin=(xspacing / 2. - (Nx * xspacing - spacing) / 2., yspacing -
                    (Ny * yspacing - spacing * np.sin(np.deg2rad(60))) / 2.))

        allshapes = Cell('All Shapes')
        allshapes.add(shapearray)
        allshapes.add(shapearray2)
        self.add(allshapes)
def makeShape_X(pitch, length, width, n_buffers, layer):
    """
    Makes X shaped branched structures for quantum transport experiments
    :param pitch: Center-to-center distance between slits
    :param length: Length of the crossing slits
    :param width: Width of the slits
    :param n_buffers: Number of slits to put around (buffer) the crossing slits
    :param layer: GDS layer to put the pattern on
    :return: Cell with the desired pattern on it
    """
    longline = Path([(-length / 2., 0), (length / 2., 0)],
                    width=width,
                    layer=layer)
    shortline = Path([(0, 0), (length / 2., 0)], width=width, layer=layer)
    long_slit = Cell('LongSlit')
    long_slit.add(longline)
    short_slit = Cell('ShortSlit')
    short_slit.add(shortline)

    xShape = Cell('XShape')
    xShape.add(long_slit, rotation=60)
    xShape.add(long_slit, rotation=120)

    if n_buffers <= 0:
        return xShape

    sideBufferNM = Cell('X_SideBufferNM')
    sideBufferNM.add(short_slit, rotation=60)
    sideBufferNM.add(short_slit, rotation=-60)

    topBufferNM = Cell('X_TopBufferNM')
    topBufferNM.add(short_slit, rotation=60)
    topBufferNM.add(short_slit, rotation=120)

    for i in range(n_buffers):
        xShape.add(sideBufferNM,
                   origin=((i + 1) * pitch / np.sin(np.deg2rad(60)), 0))
        xShape.add(sideBufferNM,
                   origin=(-(i + 1) * pitch / np.sin(np.deg2rad(60)), 0),
                   rotation=180)
        xShape.add(topBufferNM,
                   origin=(0, (i + 1) * pitch / np.cos(np.deg2rad(60))))
        xShape.add(topBufferNM,
                   origin=(0, -(i + 1) * pitch / np.cos(np.deg2rad(60))),
                   rotation=180)

    return xShape
    def add_subdicing_marks(self, length, width, layers):
        if type(layers) is not list:
            layers = [layers]

        for l in layers:
            mark_cell = Cell("SubdicingMark")
            line = Path([[0, 0], [0, length]], width=width, layer=l)
            mark_cell.add(line)

            for block in self.blocks:
                block.add(mark_cell, origin=(self.block_size[0] / 2., 0), rotation=0)
                block.add(mark_cell, origin=(0, self.block_size[1] / 2.), rotation=-90)
                block.add(mark_cell, origin=(self.block_size[0], self.block_size[1] / 2.), rotation=90)
                block.add(mark_cell, origin=(self.block_size[0] / 2., self.block_size[1]), rotation=180)
def make_branch(length, width, layers, rot_angle=0):
    slit = Cell("Slit")
    for l in layers:
        membrane = Path([(0, 0), (length, 0)], width=width, layer=l)
        membrane_cell = Cell('Membrane_w{:.0f}'.format(width * 1000))
        membrane_cell.add(membrane)
        slit.add(membrane_cell)

    branch = Cell('Branch-{:.0f}/{:.2f}-wl'.format(width, length))
    branch.add(slit, rotation=0 + rot_angle)
    # branch.add(slit, rotation=90 + rot_angle)
    branch.add(slit, rotation=180 + rot_angle)
    branch.add(slit, rotation=270 + rot_angle)
    return branch
def make_rotating_branches(length,
                           width,
                           N,
                           radius,
                           layers,
                           angle_sweep=360,
                           angle_ref=False,
                           angle_offset=0):
    cell = Cell('RotatingBranches')
    if not (type(layers) == list):
        layers = [layers]
    allslits = Cell('All Slits')
    angles = np.linspace(0, angle_sweep, N)
    translation = (radius, 0)
    pt1 = np.array((-length / 2., -width / 2.)) + translation
    pt2 = np.array((length / 2., width / 2.)) + translation

    branch = make_branch(length, width, layers)
    for element in branch.elements:
        element.origin = [radius, 0]
    for angle in angles:
        allslits.add(branch.copy(), rotation=angle_offset + angle)
    cell.add(allslits)

    for l in layers:
        if angle_ref:
            labelCell = Cell('AngleLabels')
            lineCell = Cell('Line')
            pt1 = (0, 0)
            pt2 = (radius * 0.9, 0)
            line = Path([pt1, pt2], width=width, layer=l)
            dLine = dashed_line(pt1, pt2, 2, width, l)
            lineCell.add(line)

            rot_angle = 0
            while True:
                if abs(rot_angle) > abs(angle_sweep):
                    break
                if abs(rot_angle) % 60 == 0:
                    labelCell.add(lineCell, rotation=rot_angle)
                if (abs(rot_angle) - 30) % 60 == 0:
                    labelCell.add(dLine, rotation=rot_angle)
                rot_angle += np.sign(angle_sweep) * 15
            cell.add(labelCell)
    return cell
def make_rotating_slits(length,
                        width,
                        N,
                        radius,
                        layers,
                        angle_sweep=360,
                        angle_ref=False):
    cell = Cell('RotatingSlits')
    if not (type(layers) == list): layers = [layers]
    allslits = Cell('All Slits')
    angles = np.linspace(0, angle_sweep, N)
    #        radius = length*12.
    translation = (radius, 0)
    pt1 = np.array((-length / 2., -width / 2.)) + translation
    pt2 = np.array((length / 2., width / 2.)) + translation
    slit = Cell("Slit")
    for l in layers:
        rect = Rectangle(pt1, pt2, layer=l)
        slit.add(rect)
        for angle in angles:
            allslits.add(slit.copy(), rotation=angle)
        cell.add(allslits)

    for l in layers:
        if angle_ref:
            label_cell = Cell('AngleLabels')
            line_cell = Cell('Line')
            pt1 = (0, 0)
            pt2 = (radius * 0.9, 0)
            line = Path([pt1, pt2], width=width, layer=l)
            d_line = dashed_line(pt1, pt2, 2, width, l)
            line_cell.add(line)

            rot_angle = 0
            while True:
                if abs(rot_angle) > abs(angle_sweep):
                    break
                if abs(rot_angle) % 60 == 0:
                    label_cell.add(line_cell, rotation=rot_angle)
                if (abs(rot_angle) - 30) % 60 == 0:
                    label_cell.add(d_line, rotation=rot_angle)
                rot_angle += np.sign(angle_sweep) * 15
            cell.add(label_cell)
    return cell
예제 #18
0
    def make_slits(self, length, width, nslit, pitch, rot_angle, layers):
        """
        Define a single slit or a slit array with a given length, width and pitch
        """
        slitField = Cell("slitField")

        slit = Cell("Single Slit")
        slit_path = Path([(-length / 2., 0), (length / 2., 0)], width = width, layer = layers)
        slit.add(slit_path)
        
        if nslit == 1:
            slitField.add(slit, origin=(0,0), rotation=rot_angle)
        elif nslit > 1:
            slits = CellArray(slit, 1, nslit, (0,pitch))
            slits.translate((0, -(nslit-1) * pitch / 2.))
            slit_array = Cell("Multiple Slit")
            slit_array.add(slits)
            slitField.add(slit_array, origin=(0,0), rotation=rot_angle)
        else:
            print("Error in the number of slits. Check the internal code"*50)
            quit()
        self.add(slitField)
def makeShape_ABDiamond(pitch, length, width, contactlength, n_outer_buf,
                        layer):
    """
    Makes Aharonov Bohm diamond shape
    :param pitch: pitch of nanomembranes
    :param length: quadrilateral side length
    :param width: width of the membranes
    :param contactlength: length of membrane coming from triangle to contact
    :param n_outer_buf: number of outer buffers to add
    :param layer: layer to write the structures in
    :return: cell with triangle shape in it
    """
    diamondshape = Cell("DiamondShape")

    line = Cell('DiamondLine')

    height = length * np.sqrt(3.) / 2.
    pt1 = (-length / 2., 0)
    pt2 = (length / 2., 0)

    shape_half = Cell('DiamondShapeHalf')

    # Make the main quadrilateral with contact area
    line_cell = Cell('LineCell')
    contactline_cell = Cell('ContactLineCell')
    line = Path([(-length / 2., 0), (length / 2., 0)],
                width=width,
                layer=layer)
    contactline = Path([(-length / 2., 0), (length / 2. + contactlength, 0)],
                       width=width,
                       layer=layer)
    line_cell.add(line)
    contactline_cell.add(contactline)
    shape_half.add(line_cell, origin=(-length / 2., 0), rotation=60)
    shape_half.add(contactline_cell, origin=(length / 4., height / 2.))

    n_inner_buf = int(height / 2. / pitch) + 1

    # Make the inner buffer triangles
    for i in range(1, n_inner_buf):
        line_cell = Cell('LineCell')
        slit_len = length - 2 * pitch * 2. / np.sqrt(3) * i
        line = Path([(-slit_len / 2., 0), (slit_len / 2., 0)],
                    width=width,
                    layer=layer)
        line_cell.add(line)
        shape_half.add(line_cell,
                       origin=(length / 4. - pitch / np.sqrt(3) * i,
                               height / 2 - i * pitch))
        shape_half.add(line_cell,
                       origin=(-length / 2. + pitch * 2. / np.sqrt(3) * i, 0),
                       rotation=60)

    # Make the outer buffer membranes
    for i in range(1, n_outer_buf + 1):
        line_cell = Cell('LineCell')
        contactline_cell = Cell('ContactBufferCell')
        slit_len = length + 2 * pitch * 2. / np.sqrt(3) * i
        line = Path([(-slit_len / 2. + 2 * pitch / np.sqrt(3) * (i + 1), 0),
                     (slit_len / 2., 0)],
                    width=width,
                    layer=layer)
        contactline = Path([(-slit_len / 2., 0), (slit_len / 2., 0)],
                           width=width,
                           layer=layer)
        line_cell.add(line)
        contactline_cell.add(contactline)
        shape_half.add(line_cell,
                       origin=(-length / 2. - pitch * 2. / np.sqrt(3) * i, 0),
                       rotation=60)
        shape_half.add(contactline_cell,
                       origin=(length / 4. + pitch / np.sqrt(3) * i,
                               height / 2 + i * pitch))

    diamondshape.add(shape_half, rotation=0)
    diamondshape.add(shape_half, rotation=180)

    return diamondshape
def makeShape_HashTag(hashtag_pitch, buffer_pitch, length, width, layer):
    """
    Makes hashtag-shaped branched structures for quantum transport experiments
    :param hashtag_pitch: Center-to-center distance between slits in the hashtag
    :param buffer_pitch: Center-to-center distance between the buffer membranes
    :param length: Length of the crossing slits
    :param width: Width of the slits
    :param n_buffers: Number of slits to put around (buffer) the crossing slits
    :param layer: GDS layer to put the pattern on
    :return: Cell with the desired pattern on it
    """
    dx_big = hashtag_pitch / 2. / np.tan(np.deg2rad(60))
    dy_big = hashtag_pitch / 2.
    dx_small = buffer_pitch / np.tan(np.deg2rad(60))
    dy_small = buffer_pitch

    longline = Path([(-length / 2., 0), (length / 2., 0)],
                    width=width,
                    layer=layer)
    x_dist = hashtag_pitch / np.sin(np.deg2rad(60))

    long_slit = Cell('LongSlit')
    long_slit.add(longline)

    hashtagShape = Cell('HashtagShape')
    hashtagShape.add(long_slit, origin=(-dx_big, -dy_big))
    hashtagShape.add(long_slit, origin=(dx_big, dy_big))
    hashtagShape.add(long_slit, origin=(-x_dist / 2., 0), rotation=60)
    hashtagShape.add(long_slit, origin=(x_dist / 2., 0), rotation=60)

    n_buffers = int(hashtag_pitch / buffer_pitch) - 1

    if n_buffers <= 0:
        return hashtagShape

    shortline = Path([(-x_dist / 2. + buffer_pitch, 0),
                      (x_dist / 2. - buffer_pitch, 0)],
                     width=width,
                     layer=layer)
    short_slit = Cell('ShortSlit')
    short_slit.add(shortline)

    buffers = Cell("HashtagBuffers")

    if n_buffers % 2 == 1:  # odd number of buffer slits
        buffers.add(shortline)
        n_buffers -= 1

    for i in range(n_buffers // 2):
        buffers.add(short_slit,
                    origin=(dx_big - (i + 1) * dx_small,
                            dy_big - (i + 1) * dy_small))
        buffers.add(short_slit,
                    origin=(-dx_big + (i + 1) * dx_small,
                            -dy_big + (i + 1) * dy_small))

    # There is definitely a sexier way of implementing the buffers on the outside of the hashtag...
    # This is a bit of a hacky quick fix, not so elegant as the buffers extend out too much usually...
    bufferRow = Cell("BufferRow")
    len_buffer = x_dist - 2 * buffer_pitch
    bufferRow.add(buffers)
    bufferRow.add(buffers,
                  origin=(x_dist / 2. + buffer_pitch + len_buffer / 2., 0))
    bufferRow.add(buffers,
                  origin=(-x_dist / 2. - buffer_pitch - len_buffer / 2., 0))

    hashtagShape.add(bufferRow)
    hashtagShape.add(bufferRow, origin=(2 * dx_big, 2 * dy_big))
    hashtagShape.add(bufferRow, origin=(-2 * dx_big, -2 * dy_big))

    return hashtagShape
def makeShape_Window(frame_pitch, buffer_pitch, length, width, layer):
    """
    Makes window-shaped branched structures for quantum transport experiments
    :param frame_pitch: Center-to-center distance between slits in the window
    :param buffer_pitch: Center-to-center distance between the buffer membranes
    :param length: Length of the crossing slits
    :param width: Width of the slits
    :param n_buffers: Number of slits to put around (buffer) the crossing slits
    :param layer: GDS layer to put the pattern on
    :return: Cell with the desired pattern on it
    """
    dx_big = frame_pitch / 2. / np.tan(np.deg2rad(60))
    dy_big = frame_pitch / 2.
    dx_small = buffer_pitch / np.tan(np.deg2rad(60))
    dy_small = buffer_pitch

    longline = Path([(-length / 2., 0), (length / 2., 0)],
                    width=width,
                    layer=layer)
    x_dist = frame_pitch / np.sin(np.deg2rad(60))

    long_slit = Cell('LongSlit')
    long_slit.add(longline)

    windowShape = Cell('WindowShape')
    windowShape.add(long_slit, origin=(-dx_big, -dy_big))
    windowShape.add(long_slit, origin=(dx_big, dy_big))
    windowShape.add(long_slit, origin=(-3 * dx_big, -3 * dy_big))
    windowShape.add(long_slit, origin=(3 * dx_big, 3 * dy_big))
    windowShape.add(long_slit, origin=(-x_dist / 2., 0), rotation=60)
    windowShape.add(long_slit, origin=(x_dist / 2., 0), rotation=60)
    windowShape.add(long_slit, origin=(-3 * x_dist / 2., 0), rotation=60)
    windowShape.add(long_slit, origin=(3 * x_dist / 2., 0), rotation=60)

    n_buffers = int(frame_pitch / buffer_pitch) - 1

    buffers = Cell("WindowBuffers")

    if n_buffers <= 0:
        return windowShape

    shortline = Path([(-x_dist / 2. + buffer_pitch, 0),
                      (x_dist / 2. - buffer_pitch, 0)],
                     width=width,
                     layer=layer)
    short_slit = Cell('ShortSlit')
    short_slit.add(shortline)

    if n_buffers % 2 == 1:  # odd number of buffer slits
        buffers.add(shortline)
        n_buffers -= 1

    for i in range(n_buffers // 2):
        buffers.add(short_slit,
                    origin=(dx_big - (i + 1) * dx_small,
                            dy_big - (i + 1) * dy_small))
        buffers.add(short_slit,
                    origin=(-dx_big + (i + 1) * dx_small,
                            -dy_big + (i + 1) * dy_small))

    bufferRow = Cell("BufferRow")
    len_buffer = x_dist - 2 * buffer_pitch
    v1 = (x_dist / 2. + buffer_pitch + len_buffer / 2., 0)
    bufferRow.add(buffers)
    bufferRow.add(buffers, origin=(v1[0], v1[1]))
    bufferRow.add(buffers, origin=(-v1[0], -v1[1]))

    v2 = (2 * dx_big, 2 * dy_big)
    windowShape.add(bufferRow)
    windowShape.add(bufferRow, origin=(v2[0], v2[1]))
    windowShape.add(bufferRow, origin=(-v2[0], -v2[1]))
    windowShape.add(bufferRow, origin=(2 * v2[0], 2 * v2[1]))
    windowShape.add(bufferRow, origin=(-2 * v2[0], -2 * v2[1]))

    bufferCol = Cell("BufferCol")
    bufferCol.add(buffers)
    bufferCol.add(buffers, origin=(v2[0], v2[1]))
    bufferCol.add(buffers, origin=(-v2[0], -v2[1]))
    bufferCol.add(buffers, origin=(2 * v2[0], 2 * v2[1]))
    bufferCol.add(buffers, origin=(-2 * v2[0], -2 * v2[1]))
    windowShape.add(bufferCol, origin=(2 * v1[0], 2 * v1[1]))
    windowShape.add(bufferCol, origin=(-2 * v1[0], -2 * v1[1]))

    return windowShape
예제 #22
0
    def make_branch_array(self, _widths, _lengths, nx, ny, spacing_structs,
                          spacing_arrays, rot_angle, layers):
        if not (type(layers) == list):
            layers = [layers]
        if not (type(_lengths) == list):
            _lengths = [_lengths]
        if not (type(_widths) == list):
            _widths = [_widths]
        l = layers[0]
        _length = _lengths[0]

        manyslits = i = j = None

        slits = []
        for width in _widths:
            slit = Cell("Slit_{:.0f}".format(width * 1000))
            line = Path([[-_length / 2., 0], [_length / 2., 0]],
                        width=width,
                        layer=l)
            slit.add(line)
            slits.append(slit)

        buffers = self.make_branch_device(0.08,
                                          1.0,
                                          _lengths[0] / 2.,
                                          _lengths[0] / 2.,
                                          4,
                                          layers[0],
                                          buffers_only=True)

        many_crosses = Cell("CrossArray")
        x_pos = 0
        y_pos = 0

        array_pitch = (ny - 1) * (
            length + spacing_structs) - spacing_structs + spacing_arrays

        for j, width_vert in enumerate(_widths[::-1]):
            for i, width_horiz in enumerate(_widths):
                # Define a single cross
                cross = Cell("Cross_{:.0f}_{:.0f}".format(
                    width_horiz * 1000, width_vert * 1000))
                cross.add(slits[i])  # Horizontal slit
                cross.add(slits[j], rotation=90)  # Vertical slit
                cross.add(buffers)
                # Define the cross array
                cross_array = Cell("CrossArray_{:.0f}_{:.0f}".format(
                    width_horiz * 1000, width_vert * 1000))
                slit_array = CellArray(
                    cross, nx, ny,
                    (_length + spacing_structs, _length + spacing_structs))
                slit_array.translate(
                    (-(nx - 1) * (_length + spacing_structs) / 2.,
                     (-(ny - 1) * (_length + spacing_structs) / 2.)))
                cross_array.add(slit_array)
                many_crosses.add(cross_array, origin=(x_pos, y_pos))
                x_pos += array_pitch
            y_pos += array_pitch
            x_pos = 0

        # Make the labels
        lbl_cell = Cell("Lbl_Cell")
        for i, width in enumerate(_widths):
            text_string = 'W{:.0f}'.format(width * 1000)
            text = Label(text_string, 5, layer=l)
            text.translate(tuple(np.array(-text.bounding_box.mean(0))))
            x_offset = -1.5 * array_pitch + i * array_pitch
            text.translate(np.array((x_offset, 0)))  # Center justify label
            lbl_cell.add(text)

        centered_cell = Cell('Centered_Cell')
        bbox = np.mean(many_crosses.bounding_box, 0)  # Get center of cell

        centered_cell.add(many_crosses, origin=tuple(-bbox))
        lbl_vertical_offset = 1.5
        centered_cell.add(lbl_cell, origin=(0, -bbox[1] * lbl_vertical_offset))
        centered_cell.add(lbl_cell,
                          origin=(-bbox[1] * lbl_vertical_offset, 0),
                          rotation=90)

        self.add(centered_cell, rotation=rot_angle)
예제 #23
0
 def make_arm(self, width, length, layer, cell_name='branch'):
     cell = Cell(cell_name)
     line = Path([[0, 0], [length, 0]], width=width, layer=layer)
     cell.add(line)
     return cell
예제 #24
0
    def make_slit_array(self, _pitches, spacing, _widths, _lengths, rot_angle,
                        array_height, array_width, array_spacing, layers):
        if not (type(layers) == list):
            layers = [layers]
        if not (type(_pitches) == list):
            _pitches = [_pitches]
        if not (type(_lengths) == list):
            _lengths = [_lengths]
        if not (type(_widths) == list):
            _widths = [_widths]
        manyslits = i = j = None
        for l in layers:
            i = -1
            j = -1
            manyslits = Cell("SlitArray")
            pitch = _pitches[0]
            for length in _lengths:
                j += 1
                i = -1

                for width in _widths:
                    # for pitch in pitches:
                    i += 1
                    if i % 3 == 0:
                        j += 1  # Move to array to next line
                        i = 0  # Restart at left

                    nx = int(array_width / (length + spacing))
                    ny = int(array_height / pitch)
                    # Define the slits
                    nm_cell = Cell("P{:.0f}W{:.0f}".format(pitch, width))
                    slit = Path([(-length / 2., 0), (length / 2., 0)],
                                width=width,
                                layer=l_smBeam)
                    nm_cell.add(slit)
                    slits = CellArray(nm_cell, nx, ny,
                                      (length + spacing, pitch))
                    slits.translate((-(nx - 1) * (length + spacing) / 2.,
                                     -(ny - 1) * pitch / 2.))
                    slit_array = Cell("SlitArray")
                    slit_array.add(slits)
                    text = Label('w/p/l\n%i/%i/%i' %
                                 (width * 1000, pitch, length),
                                 5,
                                 layer=l)
                    lbl_vertical_offset = 1.35
                    if j % 2 == 0:
                        text.translate(
                            tuple(
                                np.array(-text.bounding_box.mean(0)) +
                                np.array((0,
                                          -array_height / lbl_vertical_offset))
                            ))  # Center justify label
                    else:
                        text.translate(
                            tuple(
                                np.array(-text.bounding_box.mean(0)) +
                                np.array((0, array_height / lbl_vertical_offset
                                          ))))  # Center justify label
                    slit_array.add(text)
                    manyslits.add(
                        slit_array,
                        origin=((array_width + array_spacing) * i,
                                (array_height + 2. * array_spacing) * j -
                                array_spacing / 2.))

        # This is an ugly hack to center rotated slits, should fix this properly...
        if rot_angle == 45:  # TODO: fix this ugly thing
            hacky_offset_x = 200
            hacky_offset_y = -25
        elif rot_angle == 90:
            hacky_offset_x = 356
            hacky_offset_y = 96.5
        else:
            hacky_offset_x = 0
            hacky_offset_y = 0

        self.add(manyslits,
                 origin=(-i * (array_width + array_spacing) / 2 +
                         hacky_offset_x, -(j + 1.5) *
                         (array_height + array_spacing) / 2 + hacky_offset_y),
                 rotation=rot_angle)
예제 #25
0
def makeSlitArray3(pitches, spacing, widths, lengths, rotAngle, arrayHeight,
                   arrayWidth, arraySpacing, layers):
    '''
    Give it a single pitch and arrays for spacings/widths and it will generate an array for all the combinations
    Makes seperate frame for each pitch
    '''
    if not (type(layers) == list): layers = [layers]
    if not (type(pitches) == list): pitches = [pitches]
    if not (type(lengths) == list): lengths = [lengths]
    if not (type(widths) == list): widths = [widths]
    for l in layers:
        i = -1
        j = -1
        manyslits = Cell("SlitArray")
        length = lengths[0]
        spacing = length / 5. + 0.1  # Set the spacing between arrays
        for pitch in pitches:
            j += 1
            i = -1

            for width in widths:
                #            for pitch in pitches:
                i += 1
                if i % 3 == 0:
                    j += 1  # Move to array to next line
                    i = 0  # Restart at left
                pitchV = pitch / np.cos(np.deg2rad(rotAngle))
                #                    widthV = width / np.cos(np.deg2rad(rotAngle))
                Nx = int(arrayWidth / (length + spacing))
                Ny = int(arrayHeight / (pitchV))
                # Define the slits
                membrane = Path([(-length / 2., 0), (length / 2., 0)],
                                width=width,
                                layer=l)
                membrane_cell = Cell('Membrane_w{:.0f}_l{:.0f}'.format(
                    width * 1000, length * 1000))
                membrane_cell.add(membrane)
                slit = Cell('Slit_w{:.0f}_l{:.0f}_r{:.0f}'.format(
                    width * 1000, length * 1000, rotAngle))
                slit.add(membrane_cell, rotation=rotAngle)
                slits = CellArray(membrane_cell, Nx, Ny,
                                  (length + spacing, pitchV))
                slits.translate((-(Nx - 1) * (length + spacing) / 2.,
                                 -(Ny - 1) * (pitchV) / 2.))
                slitarray = Cell("SlitArray")
                slitarray.add(slits)
                text = Label('w/p/l\n%i/%i/%i' %
                             (width * 1000, pitch * 1000, length * 1000),
                             2,
                             layer=l_smBeam)
                lblVertOffset = 1.35
                if j % 2 == 0:
                    text.translate(
                        tuple(
                            np.array(-text.bounding_box.mean(0)) +
                            np.array((0, -arrayHeight /
                                      lblVertOffset))))  # Center justify label
                else:
                    text.translate(
                        tuple(
                            np.array(-text.bounding_box.mean(0)) +
                            np.array((0, arrayHeight /
                                      lblVertOffset))))  # Center justify label
                slitarray.add(text)
                manyslits.add(slitarray,
                              origin=((arrayWidth + arraySpacing) * i,
                                      (arrayHeight + 2. * arraySpacing) * j -
                                      arraySpacing / 2.))
    return manyslits
예제 #26
0
def makeSlitArray2(pitches, spacing, widths, lengths, rotAngle, arrayHeight,
                   arrayWidth, arraySpacing, layers):
    '''
    Give it a single pitch and lengths/widths and it will generate an array for all the combinations
    Makes seperate frame for each length value
    '''
    if not (type(layers) == list): layers = [layers]
    if not (type(pitches) == list): pitches = [pitches]
    if not (type(lengths) == list): lengths = [lengths]
    if not (type(widths) == list): widths = [widths]
    for l in layers:
        i = -1
        j = -1
        manyslits = Cell("SlitArray")
        pitch = pitches[0]
        for length in lengths:
            j += 1
            i = -1

            for width in widths:
                #            for pitch in pitches:
                i += 1
                if i % 3 == 0:
                    j += 1  # Move to array to next line
                    i = 0  # Restart at left

                pitchV = pitch
                #                    widthV = width / np.cos(np.deg2rad(rotAngle))
                Nx = int(arrayWidth / (length + spacing))
                Ny = int(arrayHeight / (pitchV))
                # Define the slits
                slit = Cell("Slits")
                line = Path([[-length / 2., 0], [length / 2., 0]],
                            width=width,
                            layer=l)
                slit.add(line)
                slits = CellArray(slit, Nx, Ny, (length + spacing, pitchV))
                slits.translate((-(Nx - 1) * (length + spacing) / 2.,
                                 -(Ny - 1) * (pitchV) / 2.))
                slitarray = Cell("SlitArray")
                slitarray.add(slits)
                text = Label('w/p/l\n%i/%i/%i' %
                             (width * 1000, pitch * 1000, length),
                             1,
                             layer=l_smBeam)
                lblVertOffset = 1.5
                if j % 2 == 0:
                    text.translate(
                        tuple(
                            np.array(-text.bounding_box.mean(0)) +
                            np.array((arrayWidth / 2., -arrayHeight /
                                      lblVertOffset))))  # Center justify label
                else:
                    text.translate(
                        tuple(
                            np.array(-text.bounding_box.mean(0)) +
                            np.array((arrayWidth / 2., arrayHeight /
                                      lblVertOffset))))  # Center justify label
                slitarray.add(text)
                manyslits.add(
                    slitarray,
                    origin=((arrayWidth + arraySpacing) * i,
                            (arrayHeight + arraySpacing) * j - arraySpacing))
    return manyslits
def makeShape_ABHexagon(pitch, length, width, contactlength, n_outer_buf,
                        layer):
    """
    Makes Aharonov Bohm hexagon shape
    :param pitch: pitch of nanomembranes
    :param length: hexagon side length
    :param width: width of the membranes
    :param contactlength: length of membrane coming from triangle to contact
    :param n_outer_buf: number of outer buffers to add
    :param layer: layer to write the structures in
    :return: cell with triangle shape in it
    """
    hexagonshape = Cell("HexagonShape")

    line = Cell('HexagonLine')

    height = length * np.sqrt(3.) / 2.
    pt1 = (-length / 2., 0)
    pt2 = (length / 2., 0)

    shape_half = Cell('HexagonShapeHalf')

    # Make the main quadrilateral with contact area
    line_cell = Cell('LineCell')
    contactline_cell = Cell('ContactLineCell')
    line = Path([(-length / 2., 0), (length / 2., 0)],
                width=width,
                layer=layer)
    contactline = Path([(-length / 2., 0), (length / 2. + contactlength, 0)],
                       width=width,
                       layer=layer)
    line_cell.add(line)
    contactline_cell.add(contactline)
    shape_half.add(line_cell,
                   origin=(-3 * length / 4., height / 2.),
                   rotation=60)
    shape_half.add(line_cell,
                   origin=(3 * length / 4., height / 2.),
                   rotation=-60)
    shape_half.add(contactline_cell, origin=(0, height))

    n_inner_buf = int(height / pitch) + 1

    # Make the inner buffer hexagons
    for i in range(1, n_inner_buf):
        line_cell = Cell('LineCell')
        slit_len = length - 2 * pitch / np.sqrt(3) * i
        line = Path([(-slit_len / 2., 0), (slit_len / 2., 0)],
                    width=width,
                    layer=layer)
        line_cell.add(line)
        shape_half.add(line_cell,
                       origin=(-3 * slit_len / 4.,
                               (height - (i * pitch)) / 2.),
                       rotation=60)
        shape_half.add(line_cell,
                       origin=(3 * slit_len / 4., (height - (i * pitch)) / 2.),
                       rotation=-60)
        shape_half.add(line_cell, origin=(0, height - (i * pitch)))

    # Make the outer buffer membranes
    for i in range(1, n_outer_buf + 1):
        line_cell = Cell('LineCell')
        contactline_cell = Cell('ContactLineBuffer')
        shortline_cell = Cell('ShortLineBuffer')
        slit_len = length + 2 * pitch / np.sqrt(3) * i
        line = Path([(-slit_len / 2., 0), (slit_len / 2., 0)],
                    width=width,
                    layer=layer)
        shortline = Path([(2 * pitch / np.sqrt(3) *
                           (i + 1) - slit_len / 2., 0), (slit_len / 2., 0)],
                         width=width,
                         layer=layer)
        contactline = Path([(-slit_len / 2., 0),
                            (slit_len / 2. + contactlength, 0)],
                           width=width,
                           layer=layer)
        line_cell.add(line)
        contactline_cell.add(contactline)
        shortline_cell.add(shortline)
        shape_half.add(line_cell,
                       origin=(-3 * slit_len / 4.,
                               (height + (i * pitch)) / 2.),
                       rotation=60)
        shape_half.add(shortline_cell,
                       origin=(3 * slit_len / 4., (height + (i * pitch)) / 2.),
                       rotation=-60)
        shape_half.add(contactline_cell, origin=(0, height + (i * pitch)))

    hexagonshape.add(shape_half, rotation=0)
    hexagonshape.add(shape_half, rotation=180)

    return hexagonshape
예제 #28
0
def makeSlitArray(pitches, spacing, widths, lengths, rotAngle, arrayHeight,
                  arraySpacing, layers):
    '''
    Give it a single pitch and width and it will generate an array for all the lengths
    '''
    if not (type(layers) == list): layers = [layers]
    if not (type(pitches) == list): pitches = [pitches]
    if not (type(lengths) == list): lengths = [lengths]
    if not (type(widths) == list): widths = [widths]
    for l in layers:
        i = -1
        j = -1
        manyslits = Cell("SlitArray")
        slitarray = Cell("SlitArray")
        pitch = pitches[0]
        width = widths[0]
        j += 1
        i = -1
        xlength = 0
        slit = Cell("Slits")
        for length in lengths:
            spacing = length / 5. + 0.1
            i += 1
            pitchV = pitch / np.cos(np.deg2rad(rotAngle))
            #            widthV = width / np.cos(np.deg2rad(rotAngle))
            #            Nx = int(arrayWidth / (length + spacing))
            Ny = int(arrayHeight / (pitchV))
            # Define the slits
            if xlength == 0:
                translation = (length / 2., 0)
                xlength += length
            else:
                translation = (xlength + spacing + length / 2., 0)
                xlength += length + spacing

            membrane = Path([(-length / 2., 0), (length / 2., 0)],
                            width=width,
                            layer=l)
            membrane_cell = Cell('Membrane_w{:.0f}'.format(width * 1000))
            membrane_cell.add(membrane)
            slit.add(membrane_cell, origin=translation, rotation=rotAngle)
        slits = CellArray(slit, 1, Ny, (0, pitchV))
        # slits.translate((-(Nx - 1) * (length + spacing) / 2., -(Ny - 1)* (pitchV) / 2.))
        slits.translate(
            (-slits.bounding_box[1, 0] / 2., -slits.bounding_box[1, 1] / 2.))

        slitarray.add(slits)
        text = Label('w/p\n%i/%i' % (width * 1000, pitch * 1000),
                     2,
                     layer=l_smBeam)
        lblVertOffset = 1.4
        text.translate(
            tuple(
                np.array(-text.bounding_box.mean(0)) +
                np.array((0, arrayHeight /
                          lblVertOffset))))  # Center justify label
        slitarray.add(text)
        #            manyslits.add(slitarray,origin=((arrayWidth + arraySpacing) * i, (arrayHeight + 2.*arraySpacing) * j-arraySpacing/2.))
        manyslits.add(slitarray)

    # self.add(manyslits, origin=(-i * (arrayWidth + arraySpacing) / 2, -j * (arrayHeight + arraySpacing) / 2))
    #    self.add(manyslits)
    return manyslits
def makeShape_Triangle(pitch, length, width, contactlength, n_outer_buf,
                       layer):
    """
    Makes triangle shape
    :param pitch: pitch of nanomembranes
    :param length: length of triangle side
    :param width: width of the membranes
    :param contactlength: length of membrane coming from triangle to contact
    :param n_outer_buf: number of outer buffers to add
    :param layer: layer to write the structures in
    :return: cell with triangle shape in it
    """
    triangleshape = Cell("TriangleShape")

    line = Cell('TriLine')

    height = length * np.sqrt(3.) / 2.
    pt1 = (-length / 2., 0)
    pt2 = (length / 2., 0)
    pt3 = (0, height)
    centroid = (np.mean([pt1[0], pt2[0],
                         pt3[0]]), np.mean([pt1[1], pt2[1], pt3[1]]))

    tri_arm = Cell('TriangleArms')

    # Make the main triangle with contact area
    line_cell = Cell('LineCell')
    line = Path([(-length / 2. - contactlength, 0), (length / 2., 0)],
                width=width,
                layer=layer)
    line_cell.add(line)
    tri_arm.add(line_cell, origin=(0, 0))

    n_inner_buf = int(centroid[1] / pitch) + 1

    # Make the inner buffer triangles
    for i in range(1, n_inner_buf):
        line_cell = Cell('LineCell')
        slit_len = length - 2 * pitch / np.tan(np.deg2rad(30)) * i
        line = Path([(-slit_len / 2., 0), (slit_len / 2., 0)],
                    width=width,
                    layer=layer)
        line_cell.add(line)
        tri_arm.add(line_cell, origin=(0, -i * pitch))

    # Make the outer buffer membranes
    for i in range(1, n_outer_buf + 1):
        line_cell = Cell('LineCell')
        line = Path([(-length / 2. - contactlength -
                      pitch / np.tan(np.deg2rad(30)) * i, 0),
                     (length / 2. + pitch / np.tan(np.deg2rad(30)) * i -
                      pitch / np.cos(np.deg2rad(30)) * (i + 1), 0)],
                    width=width,
                    layer=layer)
        line_cell.add(line)
        tri_arm.add(line_cell, origin=(0, i * pitch))

    tri_arm_offcenter = Cell('TriArmOffCenter')
    tri_arm_offcenter.add(tri_arm, origin=centroid)

    triangleshape.add(tri_arm_offcenter, rotation=0)
    triangleshape.add(tri_arm_offcenter, rotation=120)
    triangleshape.add(tri_arm_offcenter, rotation=240)

    return triangleshape
예제 #30
0
    def make_slits_reservoir(
            self, length, width, nslit, pitch, contact_distance,
            layers):  # 5 additional slits as material reservoir
        res_slit = 5
        slit_margin = 0.5

        res_width = width
        res_pitch = pitch

        resField = Cell("resField")

        # Outer reservoir
        outer_res = Cell("Outer Reservoir")
        out_res_length = (margin - fing_width - slit_margin)
        outer_res_path = Path([(-out_res_length / 2, 0),
                               (out_res_length / 2, 0)],
                              width=res_width,
                              layer=layers)
        outer_res.add(outer_res_path)

        out_gap = length - margin + slit_margin
        out_x_spac = (out_res_length + out_gap) / np.cos(rad_angle)
        out_y_spac = res_pitch

        out_reservoirs = CellArray(outer_res,
                                   2,
                                   res_slit,
                                   spacing=(out_x_spac, out_y_spac))
        out_x_transl = -(out_res_length + out_gap) / (
            2 * np.cos(rad_angle)) + (slit_margin) * np.sin(rad_angle)
        out_reservoirs.translate((out_x_transl, 0))
        out_res_array = Cell("Multiple Slit")
        out_res_array.add(out_reservoirs)
        resField.add(out_res_array, origin=(0, 0), rotation=rot_angle)

        # Main reservoir
        reservoir = Cell("Single Reservoir")
        res_length = fake_slit_length
        res_path = Path([(-res_length / 2., 0), (res_length / 2., 0)],
                        width=res_width,
                        layer=layers)
        reservoir.add(res_path)

        gap = contact_distance + 2 * (slit_margin + fing_width)
        x_spac = (res_length + gap) / np.cos(rad_angle)
        y_spac = res_pitch

        reservoirs = CellArray(reservoir,
                               2,
                               res_slit,
                               spacing=(x_spac, y_spac))
        x_transl = -(res_length + gap) / (2 * np.cos(rad_angle)) + (
            slit_margin) * np.sin(rad_angle)
        reservoirs.translate((x_transl, 0))
        res_array = Cell("Multiple Slit")
        res_array.add(reservoirs)
        resField.add(res_array, origin=(0, 0), rotation=rot_angle)

        # Inner reservoir
        if contact_distance > slit_margin:
            add_slit = Cell("Additional Reservoir")
            add_res_path = Path([(-(contact_distance - 0.5) / 2., 0),
                                 ((contact_distance - 0.5) / 2., 0)],
                                width=res_width,
                                layer=layers)
            add_slit.add(add_res_path)

            add_reservoir = CellArray(add_slit,
                                      1,
                                      res_slit,
                                      spacing=(0, res_pitch))
            add_reservoir.translate((0, 0))
            add_res_array = Cell("Additional Multiple Slit")
            add_res_array.add(add_reservoir)
            resField.add(add_res_array, origin=(0, 0), rotation=rot_angle)

        self.add(resField,
                 origin=(0, (nslit + 1) * pitch / 2) / np.cos(rad_angle))
        self.add(resField,
                 origin=(0, -((nslit + 1 + (2 * (res_slit - 1))) * pitch / 2) /
                         np.cos(rad_angle)))