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

        txtSize = 400
        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. + 000)) #Shifted by 0.0 mm in y. ???
            rot_angle = 0

            _width = widths_1x1
            _length = lengths_1x1
            _slit = 1
            _pitch = [pitch_std,pitch_std,pitch_std]

        #Coordinates of the large field and Marker positioning geometry
        lg_orig_x, lg_orig_y =  -outer_margin - lgField_size/2 - (lgField_num-lg_col)*lgField_spacing, - outer_margin - lgField_size/2 - (lg_row+1)*lgField_spacing
        lgMark_margin = 50.
        lgMark_position = lgField_size/2 - lgMark_margin

        #Large Field 
        lgField = Frame("LargeField", (lgField_size, lgField_size), [])  # Create the large write field
        lgField.make_align_markers(10., 200., (lgMark_position, lgMark_position), l_markers, joy_markers=True, camps_markers=True)
        lgField_label = Label(lg_label, 40., position = (lg_orig_x-250, lg_orig_y + lgField_size/2 - 100), layer=l_lgBeam)

        # Middle Fields Definition
        mdCell = Cell("Middle Cell")
        md_spac_fact = 0.1      # Max 4x4 Middle Fields
        md_size_x = ((1 - md_spac_fact*(1 + md_num_col))*lgField_size)/md_num_col
        md_size_y = ((1 - md_spac_fact*(1 + md_num_row))*lgField_size)/md_num_row
        if md_num_col > 1:
            sp_col = md_num_col -1
        else:
            sp_col = 1
        if md_num_row > 1:
            sp_row = md_num_row -1
        else:
            sp_row = 1
        md_spacing_x = md_size_x + (md_spac_fact*lgField_size)*(md_num_col - 1)/sp_col
示例#3
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)

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

        array_pitch = ny * (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
                # 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)
示例#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

                    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...
        if rot_angle == 45:  # TODO: fix this ugly thing
            hacky_offset_x = 200
            hacky_offset_y = -25
        elif rot_angle == 90:
            hacky_offset_x = 356
            hacky_offset_y = 96.5
        else:
            hacky_offset_x = 0
            hacky_offset_y = 0

        self.add(manyslits,
                 origin=(-i * (array_width + array_spacing) / 2 +
                         hacky_offset_x, -(j + 1.5) *
                         (array_height + array_spacing) / 2 + hacky_offset_y),
                 rotation=rot_angle)
    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)
                    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))
    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)