def makeYShapes(self, length, width, rotAngle, spacing, Nx, Ny, layers): if not (type(layers) == list): layers = [layers] pt1 = np.array((0, -width / 2.)) pt2 = np.array((length, width / 2.)) slit = Cell("Slit") for l in layers: rect = Rectangle(pt1, pt2, layer=l) slit.add(rect) shape = Cell('Shapes') shape.add(slit, rotation=0 + rotAngle) shape.add(slit, rotation=120 + rotAngle) shape.add(slit, rotation=240 + rotAngle) # CellArray(slit, Nx, Ny,(length + spacing, pitchV)) xspacing = length + spacing yspacing = (length + spacing) * np.sin(np.deg2rad(60)) shapearray = CellArray( shape, Nx, Ny / 2, (xspacing, yspacing * 2.), origin=(-(Nx * xspacing - spacing) / 2., -(Ny * yspacing - spacing * np.sin(np.deg2rad(60))) / 2.)) shapearray2 = CellArray( shape, Nx, Ny / 2, (xspacing, yspacing * 2.), origin=( xspacing / 2. - (Nx * xspacing - spacing) / 2., yspacing - (Ny * yspacing - spacing * np.sin(np.deg2rad(60))) / 2.)) allshapes = Cell('All Shapes') allshapes.add(shapearray) allshapes.add(shapearray2) self.add(allshapes)
def make_theory_cell(wafer_orient='111'): ''' Makes the theory cell and returns ir as a cell''' # Pitch Dependence PitchDep = Cell('PitchDependence') arrayHeight = 20. arrayWidth = 20. arraySpacing = 10. spacing = 0.5 length = [arrayWidth] widths = [0.020, 0.040, 0.080, 0.140, 0.220, 0.320] #widths = [0.008, 0.016, 0.024, 0.032, 0.040, 0.048] pitches = [1.0, 2.0, 4.0] 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 * 1.5 * arrayWidth, j * 1.5 * arrayHeight)) TopCell = Cell('GrowthTheoryTopCell') TopCell.add(PitchDep, origin=(0., 0.)) # # TODO: Add the branched growth shapes return TopCell
def make_arm(width, length, layer, cell_name='branch'): membrane = Path([(0, 0), (length, 0)], width=width, layer=layer) membrane_cell = Cell('Membrane_w{:.0f}'.format(width * 1000)) membrane_cell.add(membrane) cell = Cell(cell_name) cell.add(membrane_cell) return cell
def make_many_shapes(self, array_size, shape_areas, pitch, shapes, skew, layer): 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 shape in shapes: 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(shapes) - 1) / 2., offset_y * (len(skews) - 1) / 2.))
def branch_shape_array(self, length, width, rot_angle, spacing, n_x, n_y, layers): if not (type(layers) == list): layers = [layers] pt1 = np.array((0, -width / 2.)) pt2 = np.array((length, width / 2.)) slit = Cell("Slit") for l in layers: rect = Rectangle(pt1, pt2, layer=l) slit.add(rect) shape = Cell('Branches-{}/{}/{}-lwp'.format(length, width, spacing)) shape.add(slit, rotation=0 + rot_angle) shape.add(slit, rotation=120 + rot_angle) shape.add(slit, rotation=240 + rot_angle) x_spacing = length + spacing y_spacing = (length + spacing) * np.sin(np.deg2rad(60)) shape_array = CellArray(shape, n_x, np.ceil(n_y / 2.), (x_spacing, y_spacing * 2.), origin=( -(n_x * x_spacing - spacing) / 2., -(n_y * y_spacing - spacing * np.sin(np.deg2rad(60))) / 2.)) shape_array2 = CellArray(shape, n_x, np.ceil(n_y / 2.), (x_spacing, y_spacing * 2.), origin=( x_spacing / 2. - (n_x * x_spacing - spacing) / 2., y_spacing - (n_y * y_spacing - spacing * np.sin(np.deg2rad(60))) / 2.)) all_shapes = Cell('BranchArray-{}/{}/{}-lwp'.format(length, width, spacing)) all_shapes.add(shape_array) all_shapes.add(shape_array2) return all_shapes
def make_theory_cell(wafer_orient='111'): ''' Makes the theory cell and returns ir as a cell''' # Pitch Dependence PitchDep = Cell('PitchDependence') arrayHeight = 5. arrayWidth = arrayHeight * 2. arraySpacing = 10. spacing = 0.5 length = [arrayWidth] widths = [0.050, 0.100, 0.150, 0.200, 0.250] wire_spacings = [0.100, 0.200, 0.400] for j, width in enumerate(widths): for i, wire_spacing in enumerate(wire_spacings): PitchDep.add(makeSlitArray2(wire_spacing + width, spacing, width, length, 0, arrayHeight, arrayWidth, arraySpacing, l_smBeam), origin=(i * 30, j * 20)) TopCell = Cell('GrowthTheoryTopCell') TopCell.add(PitchDep, origin=(0., 0.)) # # TODO: Add the branched growth shapes return TopCell
def add_tem_nanowires(self): size = 500 y_offset = 1300 shapes_big = make_shape_array(size, 0.02, 0.75, 'hexagons', l_smBeam, labels=False) shapes_small = make_shape_array(size, 0.005, 0.75, 'hexagons', l_smBeam, labels=False) # Changed this wrt BM4.4 tem_shapes = Cell('TEMShapes') # tem_shapes.add(shapes_big, origin=(2200 - size / 2., y_offset - size / 2.)) tem_shapes.add(shapes_small, origin=(-2200 - size / 2., y_offset - size / 2.)) for x, y in self.upCenters: self.add(tem_shapes, origin=(x, y)) for x, y in self.downCenters: self.add(tem_shapes, origin=( x, y - 2 * y_offset)) # Don't rotate because of directionality
def add_theory_cell(self): theory_cells = Cell('TheoryCells') theory_cells.add(make_theory_cell(), origin=(-200, 0)) theory_cells.add(make_theory_cell_br(), origin=(200, 0)) self.block_up.add(theory_cells, origin=(0, 1300)) self.block_down.add(theory_cells, origin=(0, -1300))
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.))
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))
def make_basel_align_marks(self, points, layers, mk_width=5): if not (type(layers) == list): layers = [layers] wafer_rad = self.wafer_r tri_height = np.sqrt(3.) / 2. * self.trisize # Shift the points from the old dicing lines to make the dashed dicing lines points1 = np.array(points) + (self.trisize / 2., 0.) points2 = np.array(points) + (self.trisize / 4., tri_height / 2.) new_pts = np.vstack((points1, points2)) # Create a lineshape of the boundary of the circle c = self.waferShape.boundary # Create a set (unordered with unique entries) dicing_lines = set() # For each point in the lattice, create three lines (one along each direction) for x, y in new_pts: l0 = LineString([(-4. * wafer_rad, y), (4. * wafer_rad, y)]) l1 = rotateshape(l0, 60, origin=(x, y)) l2 = rotateshape(l0, -60, origin=(x, y)) # See where these lines intersect the wafer outline i0 = c.intersection(l0) i1 = c.intersection(l1) i2 = c.intersection(l2) if not i0.geoms == []: p0s = tuple(map(tuple, np.round((i0.geoms[0].coords[0], i0.geoms[ 1].coords[0])))) dicing_lines.add(p0s) # Add these points to a unique unordered set if not i1.geoms == []: p1s = tuple(map(tuple, np.round((i1.geoms[0].coords[0], i1.geoms[ 1].coords[0])))) dicing_lines.add(p1s) if not i2.geoms == []: p2s = tuple(map(tuple, np.round((i2.geoms[0].coords[0], i2.geoms[ 1].coords[0])))) dicing_lines.add(p2s) hpoints1 = np.array(points) + (self.trisize / 8., tri_height / 4. + 300.) hpoints2 = np.array(points) + (-self.trisize / 8., -tri_height / 4. - 450.) hpoints = np.vstack((hpoints1, hpoints2)) # Make horizontal lines to cleave each mini-triangle chip and make it fit in the 6x6mm chip holder in Basel for x, y in hpoints: l0 = LineString([(-4. * wafer_rad, y), (4. * wafer_rad, y)]) # See where this line intersects the wafer outline i0 = c.intersection(l0) if not i0.geoms == []: p0s = tuple(map(tuple, np.round((i0.geoms[0].coords[0], i0.geoms[ 1].coords[0])))) dicing_lines.add(p0s) # Add these points to a unique unordered set # At the end of the loop, the set will contain a list of point pairs which can be used to make the dicing marks dmarks = Cell('DIC_MRKS') for l in layers: for p1, p2 in dicing_lines: # dicing_line = Path([p1, p2], width=mkWidth,layer=l) dicing_line = dashed_line(p1, p2, 500, mk_width, l) dmarks.add(dicing_line) self.add(dmarks)
def add_theory_cells(self): theory_cells = Cell('TheoryCells') theory_cells.add(make_theory_cell(wafer_orient='100'), origin=(50, 0)) # theory_cells.add(make_theory_cell_3br(), origin=(0, 0)) # theory_cells.add(make_theory_cell_4br(), origin=(400, 0)) center_x, center_y = (self.block_size[0] / 2., self.block_size[1] / 2.) for block in self.blocks: block.add(theory_cells, origin=(center_x, center_y - 4000))
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))
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))
def add_theory_cell(self): theory_cells = Cell('TheoryCells') theory_cells.add(make_theory_cell(), origin=(-200, 0)) theory_cells.add(make_theory_cell_br(), origin=(200, 0)) for x, y in self.upCenters: self.add(theory_cells, origin=(x, y + 1300)) for x, y in self.downCenters: self.add(theory_cells, origin=( x, y - 1300 )) # Don't rotate because of directionality of branched membranes
def processCheck_CleavingMark(self, yPosition, layers): if not (type(layers) == list): layers = [layers] for l in layers: pt1 = (100, yPosition) pt2 = (2000, yPosition) pt3 = (-1100, yPosition) pt4 = (-2800, yPosition) line1 = Path([pt1, pt2], width=10, layer=l) line2 = Path([pt3, pt4], width=10, layer=l) cMarkCell = Cell('Cleaving Mark') cMarkCell.add(line1) cMarkCell.add(line2) self.add(cMarkCell)
def add_theory_cells(self): theory_cells = Cell('TheoryCells') theory_cells.add(make_theory_cell(wafer_orient='100'), origin=(70, 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=(20, -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))
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)
def makeArrowShape(self, length, width, rotAngle, spacing, Nx, Ny, layers): if not (type(layers) == list): layers = [layers] pt1 = np.array((-width * 0.3, -width / 2.)) pt2 = np.array((length, width / 2.)) slit = Cell("Slit") for l in layers: rect = Rectangle(pt1, pt2, layer=l) slit.add(rect) shape = Cell('Shapes') shape.add(slit, rotation=-120) shape.add(slit, rotation=120) xspacing = (width + spacing) / np.cos(np.deg2rad(30)) yspacing = (length + spacing / 2.) * np.sin(np.deg2rad(60)) shapearray = CellArray(shape, Nx, Ny, (xspacing, yspacing * 2.), origin=(-(Nx * xspacing - spacing) / 2., -(Ny * yspacing - spacing) / 2.)) allshapes = Cell('All Shapes') allshapes.add(shapearray) # allshapes.add(shapearray2) # allshapes.add(shape) self.add(allshapes)
def makeXShape(self, length, width, rotAngle, spacing, Nx, Ny, layers): if not (type(layers) == list): layers = [layers] pt1 = np.array((-length / 2., -width / 2.)) pt2 = np.array((length / 2., width / 2.)) slit = Cell("Slit") for l in layers: rect = Rectangle(pt1, pt2, layer=l) slit.add(rect) shape = Cell('Shapes') shape.add(slit, rotation=60) shape.add(slit, rotation=120) xspacing = (length + spacing) * np.cos(np.deg2rad(60)) yspacing = (length + spacing) * np.sin(np.deg2rad(60)) shapearray = CellArray(shape, Nx, Ny, (xspacing, yspacing), origin=(-(Nx * xspacing - spacing) / 2., -(Ny * yspacing - spacing) / 2.)) # shapearray2 = CellArray(shape, Nx, Ny/2,(xspacing,yspacing*2.),origin=(xspacing/2.-(Nx*xspacing-spacing)/2.,yspacing-(Ny*yspacing-spacing*np.tan(np.deg2rad(60)))/2.)) # shapearray = CellArray(shape, Nx, Ny,(xspacing,yspacing)) # shapearray.rotate(rotAngle) # shapearray.translate((-shapearray.bounding_box.mean(0)[0]/2.,-shapearray.bounding_box.mean(0)[1]/2.)) allshapes = Cell('All Shapes') allshapes.add(shapearray) # allshapes.add(shapearray2) # allshapes.add(shape) self.add(allshapes)
def make_branch(length, width, layers, rot_angle=0): slit = Cell("Slit") for l in layers: membrane = Path([(0, 0), (length, 0)], width=width, layer=l) membrane_cell = Cell('Membrane_w{:.0f}'.format(width * 1000)) membrane_cell.add(membrane) slit.add(membrane_cell) branch = Cell('Branch-{:.0f}/{:.2f}-wl'.format(width, length)) branch.add(slit, rotation=0 + rot_angle) branch.add(slit, rotation=90 + rot_angle) branch.add(slit, rotation=180 + rot_angle) branch.add(slit, rotation=270 + rot_angle) return branch
def add_tem_membranes(self, widths, length, pitch, layer): tem_membranes = Cell('TEM_Membranes') n = 3 curr_y = 0 for width in widths: membrane = Path([(-length / 2., 0), (length / 2., 0)], width=width, layer=layer) membrane_cell = Cell('Membrane_w{:.0f}'.format(width * 1000)) membrane_cell.add(membrane) membrane_array = CellArray(membrane_cell, 1, n, (0, pitch)) membrane_array_cell = Cell('MembraneArray_w{:.0f}'.format(width * 1000)) membrane_array_cell.add(membrane_array) tem_membranes.add(membrane_array_cell, origin=(0, curr_y)) curr_y += n * pitch n2 = 5 tem_membranes2 = Cell('Many_TEM_Membranes') tem_membranes2.add( CellArray(tem_membranes, 1, n2, (0, n * len(widths) * pitch))) self.block_up.add(tem_membranes2, origin=(0, -2000)) # self.block_up.add(tem_membranes2, origin=(0, -1400), rotation=90) self.block_down.add(tem_membranes2, origin=(0, 2000))
def add_tem_membranes(self, widths, length, pitch, layer): tem_membranes = Cell('TEM_Membranes') n = 5 curr_y = 0 for width in widths: membrane = Path([(-length / 2., 0), (length / 2., 0)], width=width, layer=layer) membrane_cell = Cell('Membrane_w{:.0f}'.format(width * 1000)) membrane_cell.add(membrane) membrane_array = CellArray(membrane_cell, 1, n, (0, pitch)) membrane_array_cell = Cell('MembraneArray_w{:.0f}'.format(width * 1000)) membrane_array_cell.add(membrane_array) tem_membranes.add(membrane_array_cell, origin=(0, curr_y)) curr_y += n * pitch n2 = 3 tem_membranes2 = Cell('Many_TEM_Membranes') tem_membranes2.add( CellArray(tem_membranes, 1, n2, (0, n * len(widths) * pitch))) # Add it in all the cells for (i, pt) in enumerate(self.block_pts): origin = (pt + np.array([0.5, 0.5])) * self.block_size self.add(tem_membranes2, origin=origin)
def 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)
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 add_tem_membranes(self, widths, length, pitch, layer): tem_membranes = Cell('TEM_Membranes') n = 4 curr_y = 0 for width in widths: membrane = Path([(-length / 2., 0), (length / 2., 0)], width=width, layer=layer) membrane_cell = Cell('Membrane_w{:.0f}'.format(width * 1000)) membrane_cell.add(membrane) membrane_array = CellArray(membrane_cell, 1, n, (0, pitch)) membrane_array_cell = Cell('MembraneArray_w{:.0f}'.format(width * 1000)) membrane_array_cell.add(membrane_array) tem_membranes.add(membrane_array_cell, origin=(0, curr_y)) curr_y += n * pitch n2 = 3 tem_membranes2 = Cell('Many_TEM_Membranes') tem_membranes2.add( CellArray(tem_membranes, 1, n2, (0, n * len(widths) * pitch))) center_x, center_y = (5000, 5000) for block in self.blocks: block.add(tem_membranes2, origin=(center_x, center_y + 2000)) block.add(tem_membranes2, origin=(center_x, center_y + 1500), rotation=45)
def 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)
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))
def make_align_markers(self, t, w, position, layers, cross=False, auto_marks=False): if not (type(layers) == list): layers = [layers] self.align_markers = Cell("AlignMarkers") self.align_marker = Cell("AlignMarker") for l in layers: if not cross: am0 = Rectangle((-w / 2., -w / 2.), (w / 2., w / 2.), layer=l) self.align_marker.add(am0) elif cross: crosspts = [(0, 0), (w / 2., 0), (w / 2., t), (t, t), (t, w / 2), (0, w / 2), (0, 0)] crosspts.extend( tuple(map(tuple, (-np.array(crosspts)).tolist()))) # 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.)] am0 = Boundary(crosspts, layer=l) # Create gdsCAD shape self.align_marker.add(am0) # am1 = Polygon(crosspts) #Create shapely polygon for later calculation if auto_marks: # automatic alignment marks for the e-beam tool auto_mark_rect = Rectangle((-10., -10.), (10., 10.), layer=l) auto_mark = Cell("AutoMark") auto_mark.add(auto_mark_rect) self.align_marker.add(auto_mark, origin=(100, 100)) self.align_marker.add(auto_mark, origin=(-100, 100)) self.align_marker.add(auto_mark, origin=(100, -100)) self.align_marker.add(auto_mark, origin=(-100, -100)) self.align_markers.add(self.align_marker, origin=tuple(np.array(position) * [1, 1])) self.align_markers.add(self.align_marker, origin=tuple(np.array(position) * [-1, 1])) self.align_markers.add(self.align_marker, origin=tuple(np.array(position) * [1, -1])) self.align_markers.add(self.align_marker, origin=tuple(np.array(position) * [-1, -1])) self.add(self.align_markers)
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)