def add_tem_nanowires(self):
        size = 500
        y_offset = 1000
        shapes_big = make_shape_array(size,
                                      0.02,
                                      0.5,
                                      'Tris_right',
                                      l_smBeam,
                                      labels=False)
        shapes_small = make_shape_array(size,
                                        0.005,
                                        0.5,
                                        'Tris_right',
                                        l_smBeam,
                                        labels=False)
        tem_shapes = Cell('TEMShapes')
        # tem_shapes.add(shapes_big, origin=(2200 - size / 2., y_offset - size / 2.))
        tem_shapes.add(shapes_small, origin=(-size / 2., -size / 2.))

        self.block_up.add(tem_shapes, origin=(-2200, y_offset))
        self.block_down.add(tem_shapes, origin=(2200, -y_offset))
예제 #2
0
    def add_chip_labels(self):
        wafer_lbl = PATTERN + "\n" + WAFER_ID
        text = Label(wafer_lbl, 40., layer=l_lgBeam)
        text.translate(tuple(
            np.array(-text.bounding_box.mean(0))))  # Center justify label
        chip_lbl_cell = Cell('chip_label')
        chip_lbl_cell.add(text)

        center_x, center_y = (5000, 5000)
        for block in self.blocks:
            block.add(chip_lbl_cell, origin=(center_x, center_y - 300))
            block.add(chip_lbl_cell, origin=(center_x, center_y - 4500))
            block.add(chip_lbl_cell,
                      origin=(center_x + 4500, center_y),
                      rotation=90)
            block.add(chip_lbl_cell,
                      origin=(center_x, center_y + 4500),
                      rotation=180)
            block.add(chip_lbl_cell,
                      origin=(center_x - 4500, center_y),
                      rotation=270)
예제 #3
0
    def add_theory_cells(self):

        theory_cells = Cell('TheoryCells')
        theory_cells.add(make_theory_cell(wafer_orient='100'),
                         origin=(-400, 0))
        theory_cells.add(make_theory_cell_3br(), origin=(0, 0))
        theory_cells.add(make_theory_cell_4br(), origin=(400, 0))

        theory_cells.add(make_theory_cell(wafer_orient='100'),
                         origin=(-500, -400),
                         rotation=45)
        theory_cells.add(make_theory_cell_3br(),
                         origin=(-50, -400),
                         rotation=45)
        theory_cells.add(make_theory_cell_4br(),
                         origin=(370, -400),
                         rotation=45)

        center_x, center_y = (5000, 5000)
        for block in self.blocks:
            block.add(theory_cells, origin=(center_x, center_y - 1700))
예제 #4
0
 def makeAlignMarkers(self, t, w, position, layers, cross=False):
     if not (type(layers) == list): layers = [layers]
     self.aMarkers = Cell("AlignMarkers")
     for l in layers:
         if not (cross):
             am1 = Rectangle((-w / 2., -w / 2.), (w / 2., w / 2.), layer=l)
         elif cross:
             h = w
             crosspts = [(-t / 2., t / 2.), (-t / 2., h / 2.), (t / 2., h / 2.),
                         (t / 2., t / 2.), (w / 2., t / 2.), (w / 2., -t / 2.),
                         (t / 2., -t / 2.), (t / 2., -h / 2.),
                         (-t / 2., -h / 2.), (-t / 2., -t / 2.),
                         (-w / 2., -t / 2.), (-w / 2., t / 2.)]
             am1 = Boundary(crosspts, layer=l)  # Create gdsCAD shape
             # am1 = Polygon(crosspts) #Create shapely polygon for later calculation
         am1 = am1.translate(tuple(position))  # 850,850
         am2 = am1.copy().scale((-1, 1))  # Reflect in x-axis
         am3 = am1.copy().scale((1, -1))  # Reflect in y-axis
         am4 = am1.copy().scale((-1, -1))  # Reflect in both x and y-axis
         self.aMarkers.add([am1, am2, am3, am4])
         self.add(self.aMarkers)
예제 #5
0
    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_many_shapes(self, array_size, shape_areas, pitches, shape, skew,
                         layer):
        """

        :param array_size:
        :param shape_areas:
        :param pitches:
        :param shape:
        :param skew:
        :param layer:
        :return:
        """
        if (type(shape) == list):
            shape = shape[0]
        offset_x = array_size * 1.25
        offset_y = array_size * 1.25
        cur_y = 0
        many_shape_cell = Cell('ManyShapes')
        for area in shape_areas:
            cur_x = 0
            for pitch in pitches:
                write_top_labels = cur_y == 0
                write_side_labels = cur_x == 0
                s_array = self.make_shape_array(array_size,
                                                area,
                                                pitch,
                                                shape,
                                                layer,
                                                skew,
                                                toplabels=write_top_labels,
                                                sidelabels=write_side_labels)
                many_shape_cell.add(s_array,
                                    origin=(cur_x - array_size / 2.,
                                            cur_y - array_size / 2.))
                cur_x += offset_x
            cur_y -= offset_y
        self.add(many_shape_cell,
                 origin=(-offset_x * (len(pitches) - 1) / 2.,
                         offset_y * (len(shape_areas) - 1) / 2.))
예제 #7
0
# Standard values (used when these params are not varying)
width_std = 0.05
pitch_std = 1.
length_std = 10.

# Definition of the parameters
widths_1x1 = widths_1x2 = [0.02, 0.04, 0.08, 0.1, 0.12, 0.14, 0.16,
                           0.2]  # 8 widths
lengths_1x1 = lengths_1x2 = lengths_2x2 = [
    0.25, 0.5, 1., 2., 5., 8., 10., 12.
]  # 8 lenghts
pitches_2x1 = [0.5, 1., 2.]  # 3 pitches
num_slits_2x1 = [2, 6, 10, 14, 18, 22, 26]  # 8 multiple slits
# 28 slits is the maximum for the chosen geometry
topCell = Cell("TopCell")
sm_writer = False
lg_label = ""

# Crate large field array following the geometry set at the beginning.
for lg_row in range(0, lgField_num):
    for lg_col in range(0, lgField_num):

        # Array of Middle Fields and Parameters of the Small Fields
        if (lg_row + 1 == 1
                and lg_col + 1 == 1):  # In LF 1x1, an MF array of:  1x1
            md_num_row, md_num_col = 1, 1

            sm_writer = True
            lg_label = "Single Slit - 0deg\nPitch = " + str(pitch_std) + "um"
            rot_angle = 0
def make_theory_cell_3br():
    ''' Makes the theory cell and returns it as a cell'''
    # Growth Theory Slit Elongation
    pitch = [0.500]
    lengths = list(np.logspace(-3, 0, 20) * 8.0)  # Logarithmic
    widths = [0.044, 0.028, 0.016, 0.012, 0.008]
    # TheorySlitElong = Cell('LenWidthDependence')
    # arrayHeight = 20.
    # arraySpacing = 30.
    # spacing = 10.
    #
    # TheorySlitElong.add(
    #     slit_elongation_array(pitch, spacing, widths[0], lengths, 0., arrayHeight, arraySpacing, l_smBeam))
    # TheorySlitElong.add(
    #     slit_elongation_array(pitch, spacing, widths[1], lengths, 0., arrayHeight, arraySpacing, l_smBeam),
    #     origin=(0, -30))
    # TheorySlitElong.add(
    #     slit_elongation_array(pitch, spacing, widths[2], lengths, 0., arrayHeight, arraySpacing, l_smBeam),
    #     origin=(0, -60))
    # TheorySlitElong.add(
    #     slit_elongation_array(pitch, spacing, widths[3], lengths, 0., arrayHeight, arraySpacing, l_smBeam),
    #     origin=(0, -90))
    # TheorySlitElong.add(
    #     slit_elongation_array(pitch, spacing, widths[4], lengths, 0., arrayHeight, arraySpacing, l_smBeam),
    #     origin=(0, -120))

    # Length Dependence
    LenWidDep = Cell('LenWidDependence')
    pitch = [0.5]
    lengths = list(np.logspace(-2, 0, 9) * 4.0)  # Logarithmic
    widths = [0.060, 0.040, 0.020]
    arrayHeight = 20.
    arrayWidth = arrayHeight
    arraySpacing = 30.
    spacing = 0.5

    for i, length in enumerate(lengths):
        for j, width in enumerate(widths):
            LenWidDep.add(make_branch_array(pitch, width, length,
                                            ['pitch', 'width', 'length'],
                                            spacing, 0, arrayHeight,
                                            arrayWidth, arraySpacing,
                                            l_smBeam),
                          origin=(i * 30, j * 30))

    # Make rotating slits
    shape_len = 3.
    shape_wid = 0.040
    N = 13  # number of shapes in the 120 degree arc
    N_rows = 2
    angle_sweep = 180
    wheel_rad = 45.
    wheel1 = Cell('RotDependence_LongSlits')
    for i in range(N_rows):
        angle_offset = (i % 2) * 7.5
        _angle_sweep = 180. - (i % 2) * 15.
        _N = int(N * _angle_sweep / angle_sweep) + (i % 2)
        angle_ref = False
        if i == 0:
            angle_ref = True
        wheel1.add(
            make_rotating_branch_devices(shape_len,
                                         shape_wid,
                                         _N,
                                         wheel_rad + i * shape_len * 3.,
                                         l_smBeam,
                                         angle_sweep=_angle_sweep,
                                         angle_ref=angle_ref,
                                         angle_offset=angle_offset))

    wheel2 = Cell('RotDependence_ShortSlits')
    angle_sweep = -180
    wheel2.add(
        make_rotating_slits(2,
                            0.040,
                            91,
                            6. * 2,
                            l_smBeam,
                            angle_ref='100',
                            angle_sweep=angle_sweep))
    for i in range(10):  # number of concentric rings to make
        wheel2.add(
            make_rotating_slits(2,
                                0.040,
                                91, (7.2 + i * 1.2) * 2,
                                l_smBeam,
                                angle_sweep=angle_sweep))

    # Pitch Dependence
    PitchDep = Cell('PitchDependence')
    # pitches = list(np.round(np.logspace(-1, 1, 10), 1))  # Logarithmic
    pitches = [0.500, 1.000, 2.000, 4.000]
    widths = [0.020, 0.040, 0.080, 0.140, 0.220, 0.320]
    length = [2.]
    arrayHeight = 20.
    arrayWidth = arrayHeight
    arraySpacing = 30.
    spacing = 0.5

    for j, width in enumerate(widths):
        for i, pitch in enumerate(reversed(pitches)):
            PitchDep.add(make_branch_array(pitch, width, length,
                                           ['pitch', 'width', 'length'],
                                           spacing, 0, arrayHeight, arrayWidth,
                                           arraySpacing, l_smBeam),
                         origin=(j * 30, i * 30))
    # # Make arrays of various shapes
    # hexagon_array = make_shape_array(20, 0.02, 0.75, 'Hexagons', l_smBeam)
    # circles_array = make_shape_array(20, 0.02, 0.75, 'Circles', l_smBeam)
    # triangle_down_array = make_shape_array(20, 0.02, 0.75, 'Tris_down', l_smBeam)
    # triangle_up_array = make_shape_array(20, 0.02, 0.75, 'Tris_up', l_smBeam)

    # Merry Christmas!
    xmas_texts = [
        LineLabel('Merry Christmas!',
                  2,
                  style='gothgbt',
                  line_width=0.044,
                  layer=l_smBeam),
        LineLabel('Merry Christmas!',
                  2,
                  style='italict',
                  line_width=0.044,
                  layer=l_smBeam),
        LineLabel('Merry Christmas!',
                  2,
                  style='scriptc',
                  line_width=0.044,
                  layer=l_smBeam),
        LineLabel('Merry Christmas!',
                  2,
                  style='scripts',
                  line_width=0.044,
                  layer=l_smBeam),
        LineLabel('Merry Christmas!',
                  2,
                  style='romanc',
                  line_width=0.044,
                  layer=l_smBeam),
        LineLabel('Merry Christmas!',
                  2,
                  style='romand',
                  line_width=0.044,
                  layer=l_smBeam)
    ]

    xmax_cell = Cell('MerryChristmas')
    for i, xmas_text in enumerate(xmas_texts):
        xmas_text.translate(
            tuple(
                np.array(-xmas_text.bounding_box.mean(0)) +
                np.array([20, -80 - i * 10.])))  # Center justify label
        xmax_cell.add(xmas_text)

    TopCell = Cell('GrowthTheoryTopCell')
    TopCell.add(wheel1, origin=(-100., -60.))
    TopCell.add(wheel2, origin=(-100., -65.))
    TopCell.add(PitchDep, origin=(-200., -280.))
    # TopCell.add3(TheorySlitElong, origin=(-250., -50))
    TopCell.add(LenWidDep, origin=(-200., -50.))
    # TopCell.add(hexagon_array, origin=(-100., -50))
    # TopCell.add(circles_array, origin=(-75., -50.))
    # TopCell.add(triangle_down_array, origin=(-50., -50))
    # TopCell.add(triangle_up_array, origin=(-25., -50))
    TopCell.add(xmax_cell, origin=(0, 50))
    return TopCell
예제 #9
0
    def add_contacts(self, layers):
        corner_pos = pad_size / 2
        finger_width = 20.
        finger_length = 80.
        n_cont = smField_num + 1

        contact_pads = Cell('Contact_Pads')
        pad = Rectangle((-corner_pos, -corner_pos), (corner_pos, corner_pos),
                        layer=layers)
        pad_cell = Cell('Pad_Cell')
        pad_cell.add(pad)
        finger = Rectangle((-finger_width / 2, -finger_length / 2),
                           (finger_width / 2, finger_length / 2),
                           layer=layers)
        finger_cell = Cell('Finger Cell')
        finger_cell.add(finger)
        n_finger = n_cont - 1

        pad_array = CellArray(pad_cell,
                              n_cont,
                              n_cont, (sm_spacing, sm_spacing),
                              origin=(0, 0))
        finger_array1 = CellArray(finger_cell,
                                  n_finger,
                                  n_finger, (sm_spacing, sm_spacing),
                                  origin=(corner_pos - finger_width,
                                          +corner_pos + finger_length / 2))
        finger_array2 = CellArray(
            finger_cell,
            n_finger,
            n_finger, (sm_spacing, sm_spacing),
            origin=(sm_spacing - corner_pos + finger_width,
                    sm_spacing - corner_pos - finger_length / 2))
        finger_array3 = CellArray(
            finger_cell,
            n_finger,
            n_finger, (sm_spacing, sm_spacing),
            rotation=90,
            origin=((n_cont - 1) * sm_spacing - corner_pos - finger_length / 2,
                    corner_pos - finger_width))
        finger_array4 = CellArray(
            finger_cell,
            n_finger,
            n_finger, (sm_spacing, sm_spacing),
            rotation=90,
            origin=((n_cont - 2) * sm_spacing + corner_pos + finger_length / 2,
                    sm_spacing - corner_pos + finger_width))

        contact_pads.add(pad_array)
        contact_pads.add(finger_array1)
        contact_pads.add(finger_array2)
        contact_pads.add(finger_array3)
        contact_pads.add(finger_array4)

        center = -0.5 * ((n_cont - 1) * smField_size + (n_cont - 1) * pad_size)
        for block in self.blocks:
            for n in range(0, lgField_num):
                for i in range(0, lgField_num):
                    block.add(contact_pads,
                              origin=(center + (n + 1) * lgField_spacing,
                                      center + (i + 1) * lgField_spacing))
def make_qp():
    ''' Makes the theory cell and returns it as a cell'''
    widths = [0.028, 0.044]
    qp_spacing = 60

    TopCell = Cell('QuantumPlayground_TopCell')

    for i, nm_width in enumerate(widths):
        cell_XShape = makeShape_X(1.0, 10, nm_width, 3, l_smBeam)
        cell_XShapeNoBuffer = makeShape_X(1.0, 10, nm_width, 0, l_smBeam)
        cell_StarShape = makeShape_Star(1.0, 10, nm_width, 3, l_smBeam)
        cell_StarShapeNoBuffer = makeShape_Star(1.0, 10, nm_width, 0, l_smBeam)
        cell_HashTag = makeShape_HashTag(3.0, 1.0, 5, nm_width, l_smBeam)
        cell_HashTagNoBuffer = makeShape_HashTag(3.0, 10.0, 5, nm_width,
                                                 l_smBeam)
        cell_Window = makeShape_Window(3.0, 1.0, 12, nm_width, l_smBeam)
        cell_WindowNoBuffer = makeShape_Window(3.0, 100.0, 12, nm_width,
                                               l_smBeam)
        cell_Triangle = makeShape_Triangle(1.0, 5, nm_width, 1.0, 3, l_smBeam)
        cell_TriangleNoBuffer = makeShape_Triangle(10.0, 5, nm_width, 1.0, 0,
                                                   l_smBeam)
        cell_AB_Diamond = makeShape_ABDiamond(1.0, 3, nm_width, 1.0, 3,
                                              l_smBeam)
        cell_AB_DiamondNoBuffer = makeShape_ABDiamond(10.0, 3, nm_width, 1.0,
                                                      0, l_smBeam)
        cell_AB_Hexagon = makeShape_ABHexagon(1.0, 2, nm_width, 2.0, 3,
                                              l_smBeam)
        cell_AB_HexagonNoBuffer = makeShape_ABHexagon(10.0, 2, nm_width, 2.0,
                                                      0, l_smBeam)

        QP = Cell('QuantumPlayground_W{:.0f}'.format(nm_width * 1000))
        QP.add(cell_AB_Diamond, origin=(-30, 30))
        QP.add(cell_AB_DiamondNoBuffer, origin=(-10, 30))
        QP.add(cell_XShape, origin=(-30, 10))
        QP.add(cell_XShapeNoBuffer, origin=(-10, 10))
        QP.add(cell_HashTag, origin=(-30, -10))
        QP.add(cell_HashTagNoBuffer, origin=(-10, -10))
        QP.add(cell_Triangle, origin=(-30, -30))
        QP.add(cell_TriangleNoBuffer, origin=(-10, -30))
        QP.add(cell_AB_Hexagon, origin=(10, 30))
        QP.add(cell_AB_HexagonNoBuffer, origin=(30, 30))
        QP.add(cell_StarShape, origin=(10, 10))
        QP.add(cell_StarShapeNoBuffer, origin=(30, 10))
        QP.add(cell_Window, origin=(10, -10))
        QP.add(cell_WindowNoBuffer, origin=(30, -10))

        TopCell.add(QP, origin=(-qp_spacing + 2 * i * qp_spacing, qp_spacing))

        # SMALL Aharonov Bohm devices
        cell_Triangle_sm = makeShape_Triangle(1.0, 1, nm_width, 1.0, 5,
                                              l_smBeam)
        cell_TriangleNoBuffer_sm = makeShape_Triangle(10.0, 1, nm_width, 1.0,
                                                      0, l_smBeam)
        cell_AB_Diamond_sm = makeShape_ABDiamond(1.0, 1, nm_width, 1.0, 5,
                                                 l_smBeam)
        cell_AB_DiamondNoBuffer_sm = makeShape_ABDiamond(
            10.0, 1, nm_width, 1.0, 0, l_smBeam)
        cell_AB_Hexagon_sm = makeShape_ABHexagon(1.0, 1, nm_width, 1.0, 5,
                                                 l_smBeam)
        cell_AB_HexagonNoBuffer_sm = makeShape_ABHexagon(
            10.0, 1, nm_width, 1.0, 0, l_smBeam)

        QP_sm = Cell('QuantumPlayground_W{:.0f}'.format(nm_width * 1000))
        QP_sm.add(cell_AB_Diamond_sm, origin=(-30, 30))
        QP_sm.add(cell_AB_DiamondNoBuffer_sm, origin=(-10, 30))
        QP_sm.add(cell_XShape, origin=(-30, 10))
        QP_sm.add(cell_XShapeNoBuffer, origin=(-10, 10))
        QP_sm.add(cell_HashTag, origin=(-30, -10))
        QP_sm.add(cell_HashTagNoBuffer, origin=(-10, -10))
        QP_sm.add(cell_Triangle_sm, origin=(-30, -30))
        QP_sm.add(cell_TriangleNoBuffer_sm, origin=(-10, -30))
        QP_sm.add(cell_AB_Hexagon_sm, origin=(10, 30))
        QP_sm.add(cell_AB_HexagonNoBuffer_sm, origin=(30, 30))
        QP_sm.add(cell_StarShape, origin=(10, 10))
        QP_sm.add(cell_StarShapeNoBuffer, origin=(30, 10))
        QP_sm.add(cell_Window, origin=(10, -10))
        QP_sm.add(cell_WindowNoBuffer, origin=(30, -10))

        TopCell.add(QP_sm,
                    origin=(-qp_spacing + 2 * i * qp_spacing, -qp_spacing))

    return TopCell
def make_branch_array(x_vars, y_vars, stat_vars, var_names, spacing, rot_angle,
                      array_height, array_width, array_spacing, layers):
    array_angle = 25  # 60 for 111
    if len(var_names) != 3:
        raise Exception('Error! Need to have three variable names.')
    if not (type(layers) == list):
        layers = [layers]
    if not (type(x_vars) == list):
        x_vars = [x_vars]
    if not (type(y_vars) == list):
        y_vars = [y_vars]
    if not (type(stat_vars) == list):
        stat_vars = [stat_vars]

    x_var_name = var_names[0]
    y_var_name = var_names[1]
    stat_var_name = var_names[2]

    for l in layers:
        j = -1
        manybranches = Cell("ManyBranches")
        for x_var in x_vars:
            j += 1
            i = -1
            for y_var in y_vars:
                i += 1
                if i % 3 == 0:
                    j += 1  # Move to array to next line
                    i = 0  # Restart at left

                var_dict = {
                    x_var_name: x_var,
                    y_var_name: y_var,
                    stat_var_name: stat_vars[0]
                }
                pitch = var_dict['pitch']
                width = var_dict['width']
                length = var_dict['length']
                branch = make_branch(length,
                                     width,
                                     layers,
                                     rot_angle=rot_angle)

                # x_spacing = (length + pitch) * np.cos(np.deg2rad(array_angle))
                # y_spacing = (length + pitch) * np.sin(np.deg2rad(array_angle))
                # n_x = int(array_width / x_spacing)
                # n_y = int(array_width / y_spacing)
                # shape_array = CellArray(branch, n_x, n_y, (x_spacing, y_spacing), origin=(
                #     -(n_x * x_spacing - pitch * np.cos(np.deg2rad(array_angle))) / 2.,
                #     -(n_y * y_spacing - pitch * np.sin(np.deg2rad(array_angle))) / 2.))

                branch_array = Cell(
                    'BranchArray-{:.0f}/{:.0f}/{:.2f}-wpl'.format(
                        width, spacing, length))
                # branch_array.add(shape_array)

                dir1 = pitch
                dir2 = length + 2 * pitch
                pts = generate_lattice([array_height, array_width],
                                       [[dir1, dir2], [dir2, dir1]])
                for pt in pts:
                    pt += np.array([-array_width / 2., -array_height / 2.])
                    branch_array.add(branch, origin=pt)

                if length * 1000 % 1000 == 0:
                    text = Label('w/p/l\n{:.0f}/{:.0f}/{:.0f}'.format(
                        width * 1000, pitch * 1000, length),
                                 2,
                                 layer=l_smBeam)
                elif length * 1000 % 100 == 0:
                    text = Label('w/p/l\n{:.0f}/{:.0f}/{:.1f}'.format(
                        width * 1000, pitch * 1000, length),
                                 2,
                                 layer=l_smBeam)
                else:
                    text = Label('w/p/l\n{:.0f}/{:.0f}/{:.2f}'.format(
                        width * 1000, pitch * 1000, length),
                                 2,
                                 layer=l_smBeam)

                lbl_vert_offset = 1.35
                if j % 2 == 0:
                    text.translate(
                        tuple(
                            np.array(-text.bounding_box.mean(0)) +
                            np.array((0, -array_height / lbl_vert_offset)))
                    )  # Center justify label
                else:
                    text.translate(
                        tuple(
                            np.array(-text.bounding_box.mean(0)) +
                            np.array((0, array_height / lbl_vert_offset)))
                    )  # Center justify label
                branch_array.add(text)
                manybranches.add(
                    branch_array,
                    origin=((array_width + array_spacing) * i,
                            (array_height + 2. * array_spacing) * j -
                            array_spacing / 2.))
    return manybranches
예제 #12
0
    def make_finger_contacts(self, slit_length, length, nslit, pitch,
                             rot_angle, layers):
        global margin

        margin = 2.5
        cont_to_cent = 60.
        global fing_width
        fing_width = 1.

        global rad_angle
        rad_angle = rot_angle / 180 * np.pi

        fing_ext_length = cont_to_cent - (slit_length / 2 -
                                          margin) * np.cos(rad_angle)
        fing_ext_hook = 30. + nslit / 2 * pitch + np.sin(
            rad_angle) * slit_length / 2
        fing_int_length = cont_to_cent + nslit / 2 * pitch + np.sin(
            rot_angle) * length + margin
        cont_conn_length = 2 * margin

        global fake_slit_length
        fake_slit_length = cont_to_cent - fing_ext_length - length - margin - fing_width / 2

        contact = Cell(" FingerContact")

        triangle = RegPolygon((0, 0), cont_conn_length, 3, layer=layers)
        conn_triangle = Cell("ConnTriangle")
        conn_triangle.add(triangle)

        finger_rect = Rectangle((-fing_ext_length / 2., -fing_width / 2),
                                (fing_ext_length / 2., fing_width / 2),
                                layer=layers)
        finger_ext = Cell("Finger")
        finger_ext.add(finger_rect)

        hook = Rectangle((-fing_ext_hook / 2., -fing_width / 2),
                         (fing_ext_hook / 2., fing_width / 2),
                         layer=layers)
        hook_finger = Cell("ContactFinger")
        hook_finger.add(hook)

        finger_middle = Rectangle((-fing_int_length / 2., -fing_width / 2),
                                  (fing_int_length / 2., fing_width / 2),
                                  layer=layers)
        finger_int = Cell("Middle Finger")
        finger_int.add(finger_middle)

        # Relative coordinates for horizontal elements (origin = center of the triangle)
        h_finger_to_triangle_x = fing_ext_length / 2
        h_hook_to_triangle_x = fing_ext_length - fing_width / 2
        h_hook_to_triangle_y = -fing_ext_hook / 2 + fing_width / 2

        # Relative coordinates for vertical elements (origin = center of the triangle)
        v_finger_to_triangle_x = fing_int_length / 2

        cont_ext = Cell("ExternalContact")
        cont_ext.add(conn_triangle)
        cont_ext.add(finger_ext, origin=(h_finger_to_triangle_x, 0))
        cont_ext.add(hook_finger,
                     origin=(h_hook_to_triangle_x, h_hook_to_triangle_y),
                     rotation=90)

        cont_int = Cell("InternalContact")
        cont_int.add(conn_triangle)
        cont_int.add(finger_int, origin=(v_finger_to_triangle_x, 0))

        # Coordinates Horizontal and Vertical Contacts into the small field
        hor_x = -cont_to_cent
        hor_y = cont_to_cent / 2 - margin
        vert_x = (-length - fing_width / 2) * np.cos(rad_angle) - (
            1 - np.cos(rad_angle)) * (fing_width / 2)
        vert_y = cont_to_cent

        contact.add(cont_ext, origin=(hor_x, hor_y))
        contact.add(cont_int, origin=(vert_x, vert_y), rotation=-90)

        self.add(contact)
        self.add(contact, rotation=180)
        return
예제 #13
0
centerLeftAlignField.make_align_markers(2.,
                                        20., (180., 180.),
                                        l_lgBeam,
                                        joy_markers=True)
centerLeftAlignField.add(quantum_playground)

centerRightAlignField = Frame("CenterRightAlignField",
                              (smFrameSize, smFrameSize), [])
centerRightAlignField.make_align_markers(2.,
                                         20., (180., 180.),
                                         l_lgBeam,
                                         joy_markers=True)
centerRightAlignField.add(quantum_playground, rotation=45)

# Add everything together to a top cell
topCell = Cell("TopCell")
topCell.add(lgField)
smFrameSpacing = 400  # Spacing between the three small frames
dx = smFrameSpacing + smFrameSize
dy = smFrameSpacing + smFrameSize
topCell.add(smField1, origin=(-dx / 2., dy / 2.))
topCell.add(smField2, origin=(dx / 2., dy / 2.))
topCell.add(smField3, origin=(-dx / 2., -dy / 2.))
topCell.add(smField4, origin=(dx / 2., -dy / 2.))
topCell.add(centerLeftAlignField, origin=(-dx / 2, 0.))
topCell.add(centerRightAlignField, origin=(dx / 2, 0.))
topCell.add(centerAlignField, origin=(0., 0.))
topCell.spacing = np.array([4000., 4000.])

# %%Create the layout and output GDS file
layout = Layout('LIBRARY')
예제 #14
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)
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
예제 #16
0
    def make_slit_patterns(self, sflabels, _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
                    slit = Cell("Slit_w{:.0f}".format(width * 1000))
                    slit_path = Path([(-length / 2., 0), (length / 2., 0)],
                                     width=width,
                                     layer=l)
                    slit.add(slit_path)
                    slits = CellArray(slit, nx, ny, (length + spacing, pitch))
                    slits.translate((-(nx - 1) * (length + spacing) / 2.,
                                     -(ny - 1) * pitch / 2.))
                    slit_array = Cell("SlitArray_w{:.0f}".format(width * 1000))
                    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.))

        specific_label = Label(sflabels, 20, layer=l)
        specific_label.translate(
            (-lbl_vertical_offset * smMarkerPosition,
             -lbl_vertical_offset * smMarkerPosition))  # Center Small Field
        slit_array.add(specific_label)

        # 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
        elif rot_angle == 180:
            hacky_offset_x = 260
            hacky_offset_y = 452
        elif rot_angle == 270 or rot_angle == -90:
            hacky_offset_x = -96.5
            hacky_offset_y = 356
        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)
예제 #17
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
예제 #18
0
    def add_contacts(self, pad_size, finger_width, finger_length, layers):
        contact_frames = [2, 4, 6, 8]
        spacing = pad_size / 2
        for frame in contact_frames:
            frame_length = (10 - frame) * 1000
            n_cont = int((frame_length) / (pad_size + spacing)) - 1

            corner_pos = pad_size / 2

            contact_pads = Cell('Contact_Pads')
            pad = Rectangle((-corner_pos, -corner_pos),
                            (corner_pos, corner_pos),
                            layer=layers)
            pad_cell = Cell('Pad_Cell')
            pad_cell.add(pad)
            finger = Rectangle((-finger_width / 2, -finger_length / 2),
                               (finger_width / 2, finger_length / 2),
                               layer=layers)
            finger_cell = Cell('Finger Cell')
            finger_cell.add(finger)

            curr_x = (10000 - ((n_cont - 1) * (pad_size + spacing))) / 2
            curr_y = (10000 - frame_length) / 2
            pad_array = CellArray(pad_cell,
                                  n_cont,
                                  1, (pad_size + spacing, pad_size + spacing),
                                  origin=(curr_x, curr_y))
            finger_array_tr = CellArray(
                finger_cell,
                n_cont,
                1, (pad_size + spacing, pad_size + spacing),
                origin=(curr_x - pad_size / 2 + finger_width,
                        curr_y + corner_pos + finger_length / 2))
            finger_array_tl = CellArray(
                finger_cell,
                n_cont,
                1, (pad_size + spacing, pad_size + spacing),
                origin=(curr_x + pad_size / 2 - finger_width,
                        curr_y + corner_pos + finger_length / 2))
            finger_array_br = CellArray(
                finger_cell,
                n_cont,
                1, (pad_size + spacing, pad_size + spacing),
                origin=(curr_x - pad_size / 2 + finger_width,
                        curr_y - corner_pos - finger_length / 2))
            finger_array_bl = CellArray(
                finger_cell,
                n_cont,
                1, (pad_size + spacing, pad_size + spacing),
                origin=(curr_x + pad_size / 2 - finger_width,
                        curr_y - corner_pos - finger_length / 2))

            contact_pads.add(pad_array)
            if frame < 8:
                contact_pads.add(finger_array_tr)
                contact_pads.add(finger_array_tl)
            if frame > 2:
                contact_pads.add(finger_array_br)
                contact_pads.add(finger_array_bl)

            for block in self.blocks:
                block.add(contact_pads)
                block.add(contact_pads, origin=(10000, 0), rotation=90)
                block.add(contact_pads, origin=(10000, 10000), rotation=180)
                block.add(contact_pads, origin=(0, 10000), rotation=270)
예제 #19
0
def make_theory_cell(wafer_orient='111'):
    ''' Makes the theory cell and returns ir as a cell'''
    # Growth Theory Slit Elongation
    pitch = [1.0]
    lengths = list(np.logspace(-3, 0, 20) * 8.0)  # Logarithmic
    widths = [0.020, 0.040, 0.080, 0.140, 0.220]
    TheorySlitElong = Cell('LenWidthDependence')
    arrayHeight = 20.
    arraySpacing = 30.
    spacing = 10.

    TheorySlitElong.add(
        makeSlitArray(pitch, spacing, widths[0], lengths, 0., arrayHeight,
                      arraySpacing, l_smBeam))
    TheorySlitElong.add(makeSlitArray(pitch, spacing, widths[1], lengths, 0.,
                                      arrayHeight, arraySpacing, l_smBeam),
                        origin=(0, -30))
    TheorySlitElong.add(makeSlitArray(pitch, spacing, widths[2], lengths, 0.,
                                      arrayHeight, arraySpacing, l_smBeam),
                        origin=(0, -60))
    TheorySlitElong.add(makeSlitArray(pitch, spacing, widths[3], lengths, 0.,
                                      arrayHeight, arraySpacing, l_smBeam),
                        origin=(0, -90))
    TheorySlitElong.add(makeSlitArray(pitch, spacing, widths[4], lengths, 0.,
                                      arrayHeight, arraySpacing, l_smBeam),
                        origin=(0, -120))

    # Length Dependence
    LenWidDep = Cell('LenWidDependence')
    pitch = [1.0]
    lengths = list(np.logspace(-3, 0, 10) * 8.0)  # Logarithmic
    widths = [0.040, 0.080, 0.140]
    arrayHeight = 20.
    arrayWidth = arrayHeight
    arraySpacing = 30.
    spacing = 0.5

    for i, length in enumerate(lengths):
        for j, width in enumerate(widths):
            LenWidDep.add(makeSlitArray3(pitch, spacing, width, length, 0,
                                         arrayHeight, arrayWidth, arraySpacing,
                                         l_smBeam),
                          origin=(i * 30, j * 30))

    # Make rotating slits
    wheel1 = Cell('RotDependence_LongSlits')
    wheel1.add(
        make_rotating_slits(5,
                            0.040,
                            361,
                            6. * 5,
                            l_smBeam,
                            angle_ref=wafer_orient))
    wheel1.add(make_rotating_slits(5, 0.040, 433, 7.2 * 5, l_smBeam))
    wheel1.add(make_rotating_slits(5, 0.040, 505, 8.4 * 5, l_smBeam))

    wheel2 = Cell('RotDependence_ShortSlits')
    wheel2.add(
        make_rotating_slits(2,
                            0.040,
                            201,
                            6. * 2,
                            l_smBeam,
                            angle_ref=wafer_orient))
    for i in range(10):  # number of concentric rings to make
        wheel2.add(
            make_rotating_slits(2, 0.040, 201, (7.2 + i * 1.2) * 2, l_smBeam))

    # Pitch Dependence
    PitchDep = Cell('PitchDependence')
    # pitches = list(np.round(np.logspace(-1, 1, 10), 1))  # Logarithmic
    pitches = [0.500, 1.000, 2.000, 4.000]
    widths = [0.020, 0.040, 0.080, 0.140, 0.220, 0.320]
    length = [20.]
    arrayHeight = 20.
    arrayWidth = arrayHeight
    arraySpacing = 30.
    spacing = 0.5

    for j, width in enumerate(widths):
        for i, pitch in enumerate(reversed(pitches)):
            PitchDep.add(makeSlitArray2(pitch, spacing, width, length, 0,
                                        arrayHeight, arrayWidth, arraySpacing,
                                        l_smBeam),
                         origin=(j * 30, i * 30))

    # Make arrays of various shapes
    manyshapes = make_many_shapes(
        20, [0.005, 0.01, 0.015, 0.02], 0.75,
        ['Hexagons', 'Circles', 'Tris_left', 'Tris_right'], l_smBeam)

    TopCell = Cell('GrowthTheoryTopCell')
    TopCell.add(wheel1, origin=(-170., -50.))
    TopCell.add(wheel2, origin=(-70., -50.))
    TopCell.add(PitchDep, origin=(-200., -280.))
    TopCell.add(TheorySlitElong, origin=(-250., 75.))
    TopCell.add(LenWidDep, origin=(-200., -50.))
    TopCell.add(manyshapes, origin=(0, -30))

    # TODO: Add the branched growth shapes

    return TopCell
예제 #20
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 / 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("Slits")
                slit.add(membrane_cell, rotation=rotAngle)
                if Nx <= 1:
                    slits = CellArray(slit, Nx, Ny, (length, pitchV))
                    slits.translate((0, -(Ny - 1) * (pitchV) / 2.))
                else:
                    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),
                             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
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
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
예제 #23
0
    def add_contacts(self, md_size_x, md_size_y, layers):
        smField_num_x = int((md_size_x) / sm_spacing - 1)
        smField_num_y = int((md_size_y) / sm_spacing - 1)

        corner_pos = pad_size / 2
        finger_width = 20.
        finger_length = 80.
        n_cont_x = smField_num_x + 1
        n_cont_y = smField_num_y + 1

        contact_pads = Cell('Contact_Pads')
        pad = Rectangle((-corner_pos, -corner_pos), (corner_pos, corner_pos),
                        layer=layers)
        pad_cell = Cell('Pad_Cell')
        pad_cell.add(pad)
        finger = Rectangle((-finger_width / 2, -finger_length / 2),
                           (finger_width / 2, finger_length / 2),
                           layer=layers)
        finger_cell = Cell('Finger Cell')
        finger_cell.add(finger)
        n_finger_x = n_cont_x - 1
        n_finger_y = n_cont_y - 1

        pad_array = CellArray(pad_cell,
                              n_cont_x,
                              n_cont_y, (sm_spacing, sm_spacing),
                              origin=(0, 0))
        finger_array1 = CellArray(finger_cell,
                                  n_finger_x,
                                  n_finger_y, (sm_spacing, sm_spacing),
                                  origin=(corner_pos - finger_width,
                                          corner_pos + finger_length / 2))
        finger_array2 = CellArray(
            finger_cell,
            n_finger_x,
            n_finger_y, (sm_spacing, sm_spacing),
            origin=(sm_spacing - corner_pos + finger_width,
                    sm_spacing - corner_pos - finger_length / 2))
        finger_array3 = CellArray(finger_cell,
                                  n_finger_y,
                                  n_finger_x, (sm_spacing, sm_spacing),
                                  rotation=90,
                                  origin=((n_cont_x - 1) * sm_spacing -
                                          corner_pos - finger_length / 2,
                                          corner_pos - finger_width))
        finger_array4 = CellArray(
            finger_cell,
            n_finger_y,
            n_finger_x, (sm_spacing, sm_spacing),
            rotation=90,
            origin=((n_cont_x - 2) * sm_spacing + corner_pos +
                    finger_length / 2, sm_spacing - corner_pos + finger_width))

        contact_pads.add(pad_array)
        contact_pads.add(finger_array1)
        contact_pads.add(finger_array2)
        contact_pads.add(finger_array3)
        contact_pads.add(finger_array4)

        center_x = -0.5 * ((n_cont_x - 1) * smField_size +
                           (n_cont_x - 1) * pad_size)
        center_y = -0.5 * ((n_cont_y - 1) * smField_size +
                           (n_cont_y - 1) * pad_size)

        self.add(contact_pads, origin=(center_x, center_y))
        return smField_num_x, smField_num_y
def make_theory_cell(wafer_orient='111'):
    ''' Makes the theory cell and returns ir as a cell'''
    # Growth Theory Slit Elongation
    pitch = [0.500]
    lengths = list(np.logspace(-3, 0, 20) * 8.0)  # Logarithmic
    widths = [0.044, 0.028, 0.016, 0.012, 0.008]
    TheorySlitElong = Cell('LenWidthDependence')
    arrayHeight = 20.
    arraySpacing = 30.
    spacing = 10.

    TheorySlitElong.add(
        makeSlitArray(pitch, spacing, widths[0], lengths, 0., arrayHeight,
                      arraySpacing, l_smBeam))
    TheorySlitElong.add(makeSlitArray(pitch, spacing, widths[1], lengths, 0.,
                                      arrayHeight, arraySpacing, l_smBeam),
                        origin=(0, -30))
    TheorySlitElong.add(makeSlitArray(pitch, spacing, widths[2], lengths, 0.,
                                      arrayHeight, arraySpacing, l_smBeam),
                        origin=(0, -60))
    TheorySlitElong.add(makeSlitArray(pitch, spacing, widths[3], lengths, 0.,
                                      arrayHeight, arraySpacing, l_smBeam),
                        origin=(0, -90))
    TheorySlitElong.add(makeSlitArray(pitch, spacing, widths[4], lengths, 0.,
                                      arrayHeight, arraySpacing, l_smBeam),
                        origin=(0, -120))

    # Length Dependence
    LenWidDep = Cell('LenWidDependence')
    pitch = [1.0]
    # lengths = list(np.logspace(-3, 0, 10) * 8.0)  # Logarithmic
    lengths = [
        0.008, 0.037, 0.170, 0.370, 0.800, 1.300, 1.700, 2.700, 3.700, 8.000
    ]
    widths = [0.044, 0.016, 0.008]
    arrayHeight = 20.
    arrayWidth = arrayHeight
    arraySpacing = 30.
    spacing = 0.5

    for i, length in enumerate(lengths):
        for j, width in enumerate(widths):
            LenWidDep.add(makeSlitArray3(pitch, spacing, width, length, 0,
                                         arrayHeight, arrayWidth, arraySpacing,
                                         l_smBeam),
                          origin=(i * 30, j * 30))

    # Second length dependence with pitch 500nm
    pitch = [0.5]
    LenWidDep2 = Cell('LenWidDependence2')
    for i, length in enumerate(lengths):
        for j, width in enumerate(widths):
            LenWidDep2.add(makeSlitArray3(pitch, spacing, width, length, 0,
                                          arrayHeight, arrayWidth,
                                          arraySpacing, l_smBeam),
                           origin=(i * 30, j * 30))

    # Make rotating slits
    wheel1 = Cell('RotDependence_LongSlits')
    wheel1.add(
        make_rotating_slits(5, 0.044, 361, 6. * 5, l_smBeam, angle_ref=True))
    wheel1.add(make_rotating_slits(5, 0.044, 433, 7.2 * 5, l_smBeam))
    wheel1.add(make_rotating_slits(5, 0.044, 505, 8.4 * 5, l_smBeam))

    wheel2 = Cell('RotDependence_ShortSlits')
    wheel2.add(
        make_rotating_slits(2, 0.044, 200, 6. * 2, l_smBeam, angle_ref=True))
    for i in range(10):  # number of concentric rings to make
        wheel2.add(
            make_rotating_slits(2, 0.044, 200, (7.2 + i * 1.2) * 2, l_smBeam))

    # Pitch Dependence
    PitchDep = Cell('PitchDependence')
    pitches = list(np.round(np.logspace(-1, 1, 10), 1))  # Logarithmic
    length = [3.]
    widths = [0.054, 0.044, 0.028, 0.016, 0.008]
    arrayHeight = 20.
    arrayWidth = arrayHeight
    arraySpacing = 30.
    spacing = 0.5

    for j, width in enumerate(widths):
        for i, pitch in enumerate(pitches):
            PitchDep.add(makeSlitArray2(pitch, spacing, width, length, 0,
                                        arrayHeight, arrayWidth, arraySpacing,
                                        l_smBeam),
                         origin=(i * 30, j * 30))
    # Make arrays of various shapes
    hexagon_array = make_shape_array(20, 0.02, 0.75, 'Hexagons', l_smBeam)
    circles_array = make_shape_array(20, 0.02, 0.75, 'Circles', l_smBeam)
    triangle_down_array = make_shape_array(20, 0.02, 0.75, 'Tris_down',
                                           l_smBeam)
    triangle_up_array = make_shape_array(20, 0.02, 0.75, 'Tris_up', l_smBeam)

    TopCell = Cell('GrowthTheoryTopCell')
    TopCell.add(wheel1, origin=(-100., -100.))
    TopCell.add(wheel2, origin=(0., -100.))
    TopCell.add(PitchDep, origin=(-200., -350.))
    TopCell.add(TheorySlitElong, origin=(-250., -50))
    TopCell.add(LenWidDep, origin=(-200., -50.))
    TopCell.add(LenWidDep2, origin=(-200., 50.))
    TopCell.add(hexagon_array, origin=(-100., -40))
    TopCell.add(circles_array, origin=(-75., -40.))
    TopCell.add(triangle_down_array, origin=(-50., -40))
    TopCell.add(triangle_up_array, origin=(-25., -40))

    # TODO: Add the branched growth shapes

    return TopCell
    def add_block_labels(self,
                         layers,
                         unique_ids=False,
                         save_ids=True,
                         load_ids=True):
        if type(layers) is not list:
            layers = [layers]

        txtSize = 1000
        blockids = []

        if not unique_ids:
            for (i, pt) in enumerate(self.block_pts):
                blockids.append(self.blockcols[pt[0]] + self.blockrows[pt[1]])
        else:
            existing_ids = {}
            existing_id_set = set()
            # Load the previously-used IDs from a JSON file
            if load_ids:
                master_db = '../../../ChipIDs_DB.json'
                if os.path.isfile(master_db):
                    with open(master_db, 'r') as f:
                        try:
                            existing_ids = json.load(f)
                            existing_id_set = set([
                                item for sublist in list(existing_ids.values())
                                for item in sublist
                            ])

                            # Check if wafer is in the loaded database
                            if load_ids and WAFER_ID in existing_ids:
                                blockids = existing_ids[WAFER_ID]

                        # If there is a reading error then proceed with a warning
                        except json.decoder.JSONDecodeError:
                            print(
                                "Json Error: Couldn't load chip IDs from database!"
                            )
                            existing_id_set = set()

            # If the IDs haven't already been set by loading them from the database
            if not blockids:
                # Generate some new IDs, but only use the ones that haven't previously been used
                unique_label_string = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890'
                possible_label_set = set([
                    "".join(x)
                    for x in itertools.product(unique_label_string, repeat=2)
                ])
                possible_label_set = possible_label_set - existing_id_set  # Remove chip lbls from the set of possible lbls

                blockids_set = set()
                while len(blockids_set) < len(self.blocks):
                    blockids_set.add(random_choice(list(possible_label_set)))

                blockids = list(blockids_set)

        # Save the labels to a file
        if save_ids:
            existing_ids.update({WAFER_ID: blockids})
            json_string = json.dumps(existing_ids)
            json_string = json_string.replace(
                "], ", "],\n")  # Make the file a bit easier to read in notepad
            with open(master_db, 'w') as f:
                f.write(json_string)

        # Write the labels to the cells
        for i, block in enumerate(self.blocks):
            blocklabel = Cell('LBL_B_' + blockids[i])
            for l in layers:
                txt = Label(blockids[i], txtSize, layer=l)
                bbox = txt.bounding_box
                offset = (0, 0)
                txt.translate(-np.mean(bbox, 0))  # Center text around origin
                txt.translate(offset)  # Translate it to bottom of wafer
                blocklabel.add(txt)
                block.add(blocklabel,
                          origin=(self.block_size[0] / 2.,
                                  self.block_size[1] / 2. - 400))
def make_slit_array(x_vars, y_vars, stat_vars, var_names, spacing, rot_angle,
                    array_height, array_width, array_spacing, layers):
    if len(var_names) != 3:
        raise Exception('Error! Need to have three variable names.')
    if not (type(layers) == list):
        layers = [layers]
    if not (type(x_vars) == list):
        x_vars = [x_vars]
    if not (type(y_vars) == list):
        y_vars = [y_vars]
    if not (type(stat_vars) == list):
        stat_vars = [stat_vars]

    x_var_name = var_names[0]
    y_var_name = var_names[1]
    stat_var_name = var_names[2]

    for l in layers:
        j = -1
        manyslits = Cell("SlitArray")
        for x_var in x_vars:
            j += 1
            i = -1
            for y_var in y_vars:
                i += 1
                if i % 3 == 0:
                    j += 1  # Move to array to next line
                    i = 0  # Restart at left

                var_dict = {
                    x_var_name: x_var,
                    y_var_name: y_var,
                    stat_var_name: stat_vars[0]
                }
                pitch = var_dict['pitch']
                width = var_dict['width']
                length = var_dict['length']

                pitch_v = pitch / np.cos(np.deg2rad(rot_angle))
                #                    widthV = width / np.cos(np.deg2rad(rotAngle))
                n_x = int(array_width / (length + spacing))
                n_y = int(array_height / pitch_v)
                # Define the slits
                slit = Cell("Slits")
                rect = Rectangle((-length / 2., -width / 2.),
                                 (length / 2., width / 2.),
                                 layer=l)
                rect = rect.copy().rotate(rot_angle)
                slit.add(rect)
                slits = CellArray(slit, n_x, n_y, (length + spacing, pitch_v))
                slits.translate((-(n_x - 1) * (length + spacing) / 2.,
                                 -(n_y - 1) * pitch_v / 2.))
                slit_array = Cell("SlitArray")
                slit_array.add(slits)
                text = Label('w/p/l\n%i/%i/%i' %
                             (width * 1000, pitch * 1000, length * 1000),
                             2,
                             layer=l_smBeam)
                lbl_vert_offset = 1.35
                if j % 2 == 0:
                    text.translate(
                        tuple(
                            np.array(-text.bounding_box.mean(0)) +
                            np.array((0, -array_height / lbl_vert_offset)))
                    )  # Center justify label
                else:
                    text.translate(
                        tuple(
                            np.array(-text.bounding_box.mean(0)) +
                            np.array((0, array_height / lbl_vert_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.))
    return manyslits
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

            pt1 = np.array((-length / 2., -width / 2.)) + translation
            pt2 = np.array((length / 2., width / 2.)) + translation
            rect = Rectangle(pt1, pt2, layer=l)
            rect = rect.copy().rotate(rotAngle)
            slit.add(rect)
        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_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
예제 #29
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
                    slit = Cell("Slits")
                    rect = Rectangle((-length / 2., -width / 2.),
                                     (length / 2., width / 2.),
                                     layer=l)
                    slit.add(rect)
                    slits = CellArray(slit, 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...
        hacky_offset_x = 200 if rot_angle == 45 else 0  # TODO: fix this ugly thing
        hacky_offset_y = -25 if rot_angle == 45 else 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)
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
                slit = Cell("Slits")
                rect = Rectangle((-length / 2., -width / 2.),
                                 (length / 2., width / 2.),
                                 layer=l)
                rect = rect.copy().rotate(rotAngle)
                slit.add(rect)
                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 * 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