コード例 #1
0
    def make_branch_device_array(self, spacing, _widths, array_height,
                                 array_width, array_spacing, len_inner,
                                 len_outer, n_membranes, layers):
        if not (type(layers) == list):
            layers = [layers]
        if not (type(_widths) == list):
            _widths = [_widths]
        for l in layers:
            i = -1
            j = 0
            manydevices = Cell("ManyDevices")
            for width in _widths:
                device = self.make_branch_device(width, spacing, len_inner,
                                                 len_outer, n_membranes, l)
                [[x_min, y_min], [x_max, y_max]] = device.bounding_box
                x_size = abs(x_max - x_min)
                y_size = abs(y_max - y_min)

                i += 1
                if i % 3 == 0:
                    j += 1  # Move to array to next line
                    i = 0  # Restart at left

                nx = int(array_width / (x_size + spacing))
                ny = int(array_height / (y_size + spacing))

                devices = CellArray(device, nx, ny,
                                    (x_size + spacing, y_size + spacing))
                devices.translate((-(nx - 1) * (x_size + spacing) / 2.,
                                   -(ny - 1) * (y_size + spacing) / 2.))
                device_array = Cell("DeviceArray")
                device_array.add(devices)
                # Make the labels for each array of devices
                text = Label(
                    'w/s/l\n%i/%.1f/%i' % (width * 1000, spacing, len_outer),
                    5)
                lbl_vertical_offset = 1.40
                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
                # TODO: Finish this below
                device_array.add(text)
                manydevices.add(
                    device_array,
                    origin=((array_width + array_spacing) * i,
                            (array_height + 2. * array_spacing) * j -
                            array_spacing / 2.))

            self.add(manydevices,
                     origin=(-i * (array_width + array_spacing) / 2,
                             -(j + 1.5) * (array_height + array_spacing) / 2))
コード例 #2
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<<
コード例 #3
0
 def frame_label(self, label_txt, size, beam):
     text = Label(label_txt, size, layer=beam)
     lblVertOffset = 0.4
     text.translate(
         tuple(np.array(-text.bounding_box.mean(0))))  # Center justify label
     lbl_cell = Cell('frame_label')
     lbl_cell.add(text)
     self.add(lbl_cell, origin=(0, self.size_y * lblVertOffset / 2.))
コード例 #4
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

                    pitch_v = pitch / np.cos(np.deg2rad(rot_angle))
                    #                    widthV = width / np.cos(np.deg2rad(rotAngle))
                    nx = int(array_width / (length + spacing))
                    ny = 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, nx, ny, (length + spacing, pitch_v))
                    slits.translate((-(nx - 1) * (length + spacing) / 2., -(ny - 1) * pitch_v / 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.))

        self.add(manyslits,
                 origin=(-i * (array_width + array_spacing) / 2, -(j + 1.5) * (
                         array_height + array_spacing) / 2))
コード例 #5
0
    def add_chip_labels(self):
        wafer_lbl = PATTERN + '\n' + WAFER_ID
        text = Label(wafer_lbl, 20., 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)

        self.block_up.add(chip_lbl_cell, origin=(0, -3000))
        self.block_down.add(chip_lbl_cell, origin=(0, 3000))
コード例 #6
0
    def add_chip_labels(self):
        wafer_lbl = PATTERN + '\n' + WAFER_ID
        text = Label(wafer_lbl, 20., 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 = (self.block_size[0]/2., self.block_size[1]/2.)
        for block in self.blocks:
            block.add(chip_lbl_cell, origin=(center_x, center_y - 4850))
コード例 #7
0
def slit_elongation_array(pitches, spacing, widths, lengths, rot_angle,
                          array_height, 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]
    for l in layers:
        j = -1
        manyslits = Cell("SlitArray")
        slitarray = Cell("SlitArray")
        pitch = pitches[0]
        width = widths[0]
        j += 1
        i = -1
        x_length = 0
        slit = Cell("Slits")
        for length in lengths:
            spacing = length / 5. + 0.1
            i += 1
            pitch_v = pitch / np.cos(np.deg2rad(rot_angle))
            n_y = int(array_height / pitch_v)
            # Define the slits
            if x_length == 0:
                translation = (length / 2., 0)
                x_length += length
            else:
                translation = (x_length + spacing + length / 2., 0)
                x_length += 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(rot_angle)
            slit.add(rect)
        slits = CellArray(slit, 1, n_y, (0, pitch_v))
        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)
        lbl_vert_offset = 1.4
        text.translate(
            tuple(
                np.array(-text.bounding_box.mean(0)) +
                np.array((0, array_height /
                          lbl_vert_offset))))  # Center justify label
        slitarray.add(text)
        manyslits.add(slitarray)
    return manyslits
コード例 #8
0
    def add_chip_labels(self):
        wafer_lbl = PATTERN + '\n' + WAFER_ID
        text = Label(wafer_lbl, 3., layer=l_smBeam)
        text.translate(tuple(
            np.array(-text.bounding_box.mean(0))))  # Center justify label
        chip_lbl_cell = Cell('chip_label')
        chip_lbl_cell.add(text)

        # 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
            origin += np.array([0, -2850])
            self.add(chip_lbl_cell, origin=origin)
コード例 #9
0
    def make_shape_array(self, array_size, shape_area, shape_pitch, type, layer, skew, toplabels=False,
                         sidelabels=False):
        num_of_shapes = int(np.ceil(array_size / shape_pitch))
        base_cell = Cell('Base')

        if 'tris' in type.lower():
            triangle_side = np.sqrt(shape_area / np.sqrt(3) * 4)
            tri_shape = scale(RegPolygon([0, 0], triangle_side, 3, layer=layer), [skew, 1.0])
            tri_cell = Cell('Tri')
            tri_cell.add(tri_shape)
            if 'right' in type.lower():
                base_cell.add(tri_cell, rotation=0)
            elif 'left' in type.lower():
                base_cell.add(tri_cell, rotation=-180)
            elif 'down' in type.lower():
                base_cell.add(tri_cell, rotation=30)  # not working for skew yet
            elif 'up' in type.lower():
                base_cell.add(tri_cell, rotation=-30)  # not working for skew yet
        elif type.lower() == "circles":
            circ_radius = np.sqrt(shape_area / np.pi)
            circ = scale(Disk([0, 0], circ_radius, layer=layer), [skew, 1.0])
            base_cell.add(circ)
        elif type.lower() == 'hexagons':
            hex_side = np.sqrt(shape_area / 6. / np.sqrt(3) * 4)
            hex_shape = scale(RegPolygon([0, 0], hex_side, 6, layer=layer), [skew, 1.0])
            hex_cell = Cell('Hex')
            hex_cell.add(hex_shape)
            base_cell.add(hex_cell, rotation=0)

        shape_array = CellArray(base_cell, num_of_shapes, num_of_shapes, [shape_pitch, shape_pitch])
        shape_array_cell = Cell('Shape Array')
        shape_array_cell.add(shape_array)

        lbl_dict = {'hexagons': 'hex', 'circles': 'circ', 'tris_right': 'triR', 'tris_left': 'triL'}

        if toplabels:
            text = Label('{}'.format(lbl_dict[type.lower()]), 2, layer=layer)
            lblVertOffset = 0.8
            text.translate(
                tuple(np.array(-text.bounding_box.mean(0)) + np.array((
                    array_size / 2., array_size / lblVertOffset))))  # Center justify label
            shape_array_cell.add(text)
        if sidelabels:
            text = Label('a={:.0f}knm2'.format(shape_area * 1000), 2, layer=layer)
            lblHorizOffset = 1.5
            text.translate(
                tuple(np.array(-text.bounding_box.mean(0)) + np.array((
                    -array_size / lblHorizOffset, array_size / 2.))))  # Center justify label
            shape_array_cell.add(text)

        return shape_array_cell
コード例 #10
0
def make_shape_array(array_size,
                     shape_area,
                     shape_pitch,
                     type,
                     layer,
                     labels=True):
    num_of_shapes = int(np.ceil(array_size / shape_pitch))
    base_cell = Cell('Base')

    if 'tris' in type.lower():
        triangle_side = np.sqrt(shape_area / np.sqrt(3) * 4)
        tri_shape = RegPolygon([0, 0], triangle_side, 3, layer=layer)
        tri_cell = Cell('Tri')
        tri_cell.add(tri_shape)
        if 'right' in type.lower():
            base_cell.add(tri_cell, rotation=0)
        elif 'left' in type.lower():
            base_cell.add(tri_cell, rotation=60)
        elif 'down' in type.lower():
            base_cell.add(tri_cell, rotation=30)
        elif 'up' in type.lower():
            base_cell.add(tri_cell, rotation=-30)
    elif type.lower() == "circles":
        circ_radius = np.sqrt(shape_area / np.pi)
        circ = Disk([0, 0], circ_radius, layer=layer)
        base_cell.add(circ)
    elif type.lower() == 'hexagons':
        hex_side = np.sqrt(shape_area / 6. / np.sqrt(3) * 4)
        hex_shape = RegPolygon([0, 0], hex_side, 6, layer=layer)
        hex_cell = Cell('Hex')
        hex_cell.add(hex_shape)
        base_cell.add(hex_cell, rotation=0)

    shape_array = CellArray(base_cell, num_of_shapes, num_of_shapes,
                            [shape_pitch, shape_pitch])
    shape_array_cell = Cell('Shape Array')
    shape_array_cell.add(shape_array)

    if labels:
        text = Label('{}'.format(type), 2, layer=l_smBeam)
        lblVertOffset = 0.8
        text.translate(
            tuple(
                np.array(-text.bounding_box.mean(0)) +
                np.array((array_size / 2., array_size /
                          lblVertOffset))))  # Center justify label

        shape_array_cell.add(text)

    return shape_array_cell
コード例 #11
0
 def add_block_labels(self, layers):
     txtSize = 2000
     for (i, pt) in enumerate(self.block_pts):
         origin = (pt + np.array([0.5, 0.5])) * self.block_size
         blk_lbl = self.blockcols[pt[0]] + self.blockrows[pt[1]]
         for l in layers:
             txt = Label(blk_lbl, txtSize, layer=l)
         bbox = txt.bounding_box
         offset = np.array(pt)
         txt.translate(-np.mean(bbox, 0))  # Center text around origin
         lbl_cell = Cell("lbl_" + blk_lbl)
         lbl_cell.add(txt)
         origin += np.array([0, 0])
         self.add(lbl_cell, origin=origin)
コード例 #12
0
    def add_chip_labels(self):
        wafer_lbl = PATTERN + "\n" + WAFER_ID
        text = Label(wafer_lbl, 20., 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 - 200))
            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)
コード例 #13
0
    def add_block_labels(self, layers, quasi_unique_labels=False):
        if type(layers) is not list:
            layers = [layers]

        txtSize = 800

        if quasi_unique_labels:
            unique_label_string = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890'
            possible_labels = [
                "".join(x)
                for x in itertools.product(unique_label_string, repeat=2)
            ]

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

            blockids = list(blockids_set)
            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.))

        else:
            for (i, pt) in enumerate(self.block_pts):
                origin = (pt + np.array([0.5, 0.5])) * self.block_size
                blk_lbl = self.blockcols[pt[0]] + self.blockrows[pt[1]]
                for l in layers:
                    txt = Label(blk_lbl, txtSize, layer=l_lgBeam)
                    bbox = txt.bounding_box
                    offset = np.array(pt)
                    txt.translate(
                        -np.mean(bbox, 0))  # Center text around origin
                    lbl_cell = Cell("lbl_" + blk_lbl)
                    lbl_cell.add(txt)
                    origin += np.array([0, 2000])  # Translate it up by 2mm
                    self.add(lbl_cell, origin=origin)
コード例 #14
0
    def makeSlitArray(self, pitches, spacing, widths, lengths, rotAngle,
                      arrayHeight, arrayWidth, arraySpacing, 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]
        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
                    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, length), 5)
                    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.))

        self.add(manyslits,
                 origin=(-i * (arrayWidth + arraySpacing) / 2,
                         -(j + 1.5) * (arrayHeight + arraySpacing) / 2))
コード例 #15
0
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
コード例 #16
0
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
コード例 #17
0
    def make_shape_array(self,
                         array_size,
                         shape_area,
                         shape_pitch,
                         type,
                         layer,
                         skew,
                         toplabels=False,
                         sidelabels=False):
        """

        :param array_size:
        :param shape_area:
        :param shape_pitch:
        :param type:
        :param layer:
        :param skew:
        :param toplabels:
        :param sidelabels:
        :return:
        """
        num_of_shapes = int(np.ceil(array_size / shape_pitch))
        base_cell = Cell('Base')

        if 'tri' in type.lower():
            triangle_side = np.sqrt(shape_area / np.sqrt(3) * 4)
            tri_shape = scale(
                RegPolygon([0, 0], triangle_side, 3, layer=layer), [skew, 1.0])
            tri_cell = Cell('Tri')
            tri_cell.add(tri_shape)
            if 'right' in type.lower():
                base_cell.add(tri_cell, rotation=0)
            elif 'left' in type.lower():
                base_cell.add(tri_cell, rotation=-180)
            elif 'down' in type.lower():
                base_cell.add(tri_cell,
                              rotation=30)  # not working for skew yet
            elif 'up' in type.lower():
                base_cell.add(tri_cell,
                              rotation=-30)  # not working for skew yet
        elif type.lower() == "circle":
            circ_radius = np.sqrt(shape_area / np.pi)
            circ = scale(Disk([0, 0], circ_radius, layer=layer), [skew, 1.0])
            base_cell.add(circ)
        elif type.lower() == 'hexagon':
            hex_side = np.sqrt(shape_area / 6. / np.sqrt(3) * 4)
            hex_shape = scale(RegPolygon([0, 0], hex_side, 6, layer=layer),
                              [skew, 1.0])
            hex_cell = Cell('Hex')
            hex_cell.add(hex_shape)
            base_cell.add(hex_cell, rotation=0)
        elif type.lower() == 'square':
            sq_side = np.sqrt(shape_area)
            sq_shape = scale(
                Rectangle([-sq_side / 2., -sq_side / 2.],
                          [sq_side / 2., sq_side / 2.],
                          layer=layer), [skew, 1.0])
            sq_cell = Cell('Square')
            sq_cell.add(sq_shape)
            base_cell.add(sq_cell, rotation=0)

        shape_array = CellArray(base_cell, num_of_shapes, num_of_shapes,
                                [shape_pitch, shape_pitch])
        shape_array_cell = Cell('Shape Array')
        shape_array_cell.add(shape_array)

        lbl_dict = {
            'hexagon': 'hex',
            'circle': 'circ',
            'tris_right': 'triR',
            'tris_left': 'triL',
            'square': 'sqr'
        }

        if toplabels:
            text = Label('p={:.0f}nm'.format(shape_pitch * 1000),
                         10.,
                         layer=l_lgBeam)
            lblVertOffset = 0.8
            text.translate(
                tuple(
                    np.array(-text.bounding_box.mean(0)) +
                    np.array((array_size / 2., array_size /
                              lblVertOffset))))  # Center justify label
            shape_array_cell.add(text)
        if sidelabels:
            text = Label('s={:.0f}nm'.format(np.sqrt(shape_area) * 1000),
                         10.,
                         layer=l_lgBeam)
            lblHorizOffset = 1.5
            text.translate(
                tuple(
                    np.array(-text.bounding_box.mean(0)) +
                    np.array((-array_size / lblHorizOffset,
                              array_size / 2.))))  # Center justify label
            shape_array_cell.add(text)

        return shape_array_cell
コード例 #18
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
                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
コード例 #19
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

            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
コード例 #20
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)
コード例 #21
0
    def add_block_labels(self,
                         layers,
                         unique_ids=False,
                         save_ids=True,
                         load_ids=True):
        if type(layers) is not list:
            layers = [layers]

        h = self.upTris[0].bounds[3] - self.upTris[0].bounds[1]
        sl_lattice = self.trisize + self.block_gap / np.tan(np.deg2rad(30))
        h_lattice = np.sqrt(3.) / 2. * sl_lattice
        base = h_lattice

        txtSize = 1000
        blockids = []

        if not unique_ids:
            for (i, tri) in enumerate(self.upTris + self.downTris):
                lbl_col = self.blockcols[np.round(tri.centroid.x, 8)]
                lbl_row = self.blockrows[base *
                                         round(float(tri.bounds[1]) / base)]
                blockids.append(str(lbl_col) + str(lbl_row))
        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.upTris + self.downTris):
                    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)

        block_labels = Cell('BlockLabels')
        for (i, tri) in enumerate(self.upTris + self.downTris):
            blockid = blockids[i]
            blocklabel = Cell('LBL_B_' + blockid)
            for l in layers:
                txt = Label(blockid, 1000, layer=l)
                bbox = txt.bounding_box
                offset = np.array(tri.centroid)
                txt.translate(-np.mean(bbox, 0))  # Center text around origin
                txt.translate(offset)  # Translate it to bottom of wafer
                blocklabel.add(txt)
                block_labels.add(blocklabel)
            self.add(block_labels)
コード例 #22
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)
コード例 #23
0
    def add_block_labels(self,
                         layers,
                         unique_labels=False,
                         save_ids=True,
                         load_ids=True):
        if type(layers) is not list:
            layers = [layers]

        txtSize = 800
        db_IDs = {}

        master_db = '../../../ChipIDs_DB.json'
        if os.path.isfile(master_db):
            with open(master_db, 'r') as f:
                try:
                    db_IDs = json.load(f)
                    db_label_set = set([
                        item for sublist in list(db_IDs.values())
                        for item in sublist
                    ])

                    # Check if wafer is in the loaded database
                    if load_ids and WAFER_ID in db_IDs:
                        blockids = db_IDs[WAFER_ID]
                    else:
                        load_ids = False
                # 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!")
                    load_ids = False

        # Otherwise generate the IDs on the spot, still taking into account the database labels to avoid duplicates
        if not load_ids:
            if unique_labels:
                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 - db_label_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)

            else:
                blockids = []
                for (i, pt) in enumerate(self.block_pts):
                    blockids.append(self.blockcols[pt[0]] +
                                    self.blockrows[pt[1]])

        # TODO: Save it to a master list of all the IDs for easy searching!
        # Check if the wafer ID already exists in the database, if not create new entry
        # Save the labels to a file
        if save_ids:
            # with open(filename_ids, 'w+') as f:
            #     with open(master_db, 'a+') as f2:
            #         for item in blockids:
            #             f.write("%s\n" % item)
            #             f2.write("%s\n" % item)

            db_IDs.update({WAFER_ID: blockids})
            with open(master_db, 'w') as f:
                indent = 4

        # 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.))
コード例 #24
0
def make_branch_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
        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
                y_spacing = (length + pitch) * np.sin(np.deg2rad(60))
                n_x = int(array_width / x_spacing)
                n_x2 = int((array_width - x_spacing / 2.) / x_spacing)
                n_y = np.round(array_height / 2. / y_spacing)
                n_y2 = np.round((array_height - y_spacing / 2.) / 2. / y_spacing)
                shape_array = CellArray(branch, n_x, n_y, (x_spacing, y_spacing * 2.), origin=(
                    -(n_x * x_spacing - pitch) / 2., -(2. * n_y * y_spacing - pitch * np.sin(np.deg2rad(60))) / 2.))
                if n_x == n_x2:
                    translation = (x_spacing / 2. - (n_x2 * x_spacing - pitch) / 2.,
                                   y_spacing - (2. * n_y * y_spacing - pitch * np.sin(np.deg2rad(60))) / 2.)
                else:
                    translation = (-(n_x2 * x_spacing - pitch) / 2.,
                                   y_spacing - (2. * n_y * y_spacing - pitch * np.sin(np.deg2rad(60))) / 2.)

                shape_array2 = CellArray(branch, n_x2, n_y2, (x_spacing, y_spacing * 2.),
                                         origin=translation)

                branch_array = Cell('BranchArray-{:.2f}/{:.3f}/{:.1f}-lwp'.format(length, width, spacing))
                branch_array.add(shape_array)
                branch_array.add(shape_array2)

                text = Label('w/p/l\n{:.0f}/{:.1f}/{:.1f}'.format(width * 1000, pitch, 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
コード例 #25
0
    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))
コード例 #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 / 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
コード例 #27
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)
    def make_tapered_cross_array(self, _nom_width, _taper_widths, _length,
                                 _taper_length, nx, ny, spacing_structs,
                                 spacing_arrays, rot_angle, layers):

        if not (type(layers) == list):
            layers = [layers]
        if not (type(_taper_widths) == list):
            _taper_widths = [_taper_widths]

        if type(_nom_width
                ) == list:  # Only accept a single membrane width for now
            _nom_width = _nom_width[0]
        if type(_length
                ) == list:  # Only accept a single membrane length for now
            _length = _length[0]
        if type(_taper_length
                ) == list:  # Only accept a single taper length for now
            _taper_length = _taper_length[0]

        layer = layers[0]

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

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

        membrane_cell = Cell('Testing')

        # fix the taper length, put this in a loop and iterate over various combined taper width values

        for j, tw_vert in enumerate(_taper_widths):
            for i, tw_horiz in enumerate(_taper_widths):
                # Define a single cross
                cross = self.make_tapered_cross(_nom_width, _nom_width,
                                                tw_horiz, tw_vert, _length,
                                                _length, _taper_length,
                                                _taper_length, layer)
                # Define the cross array
                cross_array = Cell("TaperedCrossArray_{:.0f}_{:.0f}".format(
                    tw_horiz * 1000, tw_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(_taper_widths):
            text_string = 'TW{:.0f}'.format(width * 1000)
            text = Label(text_string, 5, layer=layer)
            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)

        # Make label for the whole field
        frame_lbl = Cell("Cell_Label")
        text_string = 'NomW {:.0f}, TL {:.0f}'.format(_nom_width * 1000,
                                                      _taper_length * 1000)
        text = Label(text_string, 5, layer=layer)
        text.translate(tuple(np.array(-text.bounding_box.mean(0))))
        frame_lbl.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))
        centered_cell.add(frame_lbl, origin=(0, -200))
        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)