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_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 make_rotating_slits(length, width, N, radius, layers, angleRef=False): cell = Cell('RotatingSlits') if not (type(layers) == list): layers = [layers] allslits = Cell('All Slits') angles = np.linspace(0, 360, N) # radius = length*12. translation = (radius, 0) pt1 = np.array((-length / 2., -width / 2.)) + translation pt2 = np.array((length / 2., width / 2.)) + translation slit = Cell("Slit") for l in layers: rect = Rectangle(pt1, pt2, layer=l) slit.add(rect) for angle in angles: allslits.add(slit.copy(), rotation=angle) cell.add(allslits) if angleRef: labelCell = Cell('AngleLabels') lineCell = Cell('Line') pt1 = (-radius * 0.9, 0) pt2 = (radius * 0.9, 0) line = Path([pt1, pt2], width=width, layer=l) dLine = dashed_line(pt1, pt2, 2, width, l) lineCell.add(line) labelCell.add(lineCell, rotation=0) labelCell.add(lineCell, rotation=60) labelCell.add(lineCell, rotation=-60) labelCell.add(dLine, rotation=30) labelCell.add(dLine, rotation=90) labelCell.add(dLine, rotation=-30) cell.add(labelCell) return cell
def add_sub_dicing_ticks(self, length, thickness, layers): if not (type(layers) == list): layers = [layers] l = layers[0] _h = self.upTris[0].bounds[3] - self.upTris[0].bounds[1] _w = self.upTris[0].bounds[2] - self.upTris[0].bounds[0] y_bottom = self.upTris[0].bounds[1] y_centroid = self.upTris[0].centroid.y offset = y_centroid - y_bottom mark = Path([(0, 0), (0, -length)], width=thickness, layer=l) mark_cell = Cell('SubDicingTick') mark_cell.add(mark) tri_sub_dMarks = Cell('TriSubDMarks') tri_sub_dMarks.add(mark_cell, rotation=30, origin=(0, offset)) tri_sub_dMarks.add(mark_cell, rotation=-30, origin=(0, offset)) tri_sub_dMarks.add(mark_cell, rotation=30, origin=(_w / 4., offset - _h / 2.)) tri_sub_dMarks.add(mark_cell, rotation=90, origin=(_w / 4., offset - _h / 2.)) tri_sub_dMarks.add(mark_cell, rotation=-30, origin=(-_w / 4., offset - _h / 2.)) tri_sub_dMarks.add(mark_cell, rotation=-90, origin=(-_w / 4., offset - _h / 2.)) # Horizontal marks # This is a mess... should fix it later. Past Martin says sorry... tri_sub_dMarks.add(mark_cell, rotation=-90, origin=(_w * 3. / 8. - 300., offset - _h / 4. - _h / 20.)) tri_sub_dMarks.add(mark_cell, rotation=90, origin=(-_w * 3. / 8. + 300., offset - _h / 4. - _h / 20.)) tri_sub_dMarks.add(mark_cell, rotation=-90, origin=(_w * 1. / 8. + 300., offset - _h * 3. / 4. + _h / 20.)) tri_sub_dMarks.add(mark_cell, rotation=90, origin=(-_w * 1. / 8. - 300., offset - _h * 3. / 4. + _h / 20.)) for tri in self.downTris: tri_center = np.array(tri.centroid) self.add(tri_sub_dMarks, origin=tri_center) for tri in self.upTris: tri_center = np.array(tri.centroid) self.add(tri_sub_dMarks, origin=tri_center, rotation=180)
def dashed_line(pt1, pt2, dashlength, width, layer): line = LineString((pt1, pt2)) dash_pts = np.arange(0, line.length, dashlength).tolist() if len(dash_pts) % 2 == 1: # Odd number dash_pts.append(line.length) # Add last point on line dash_pts = list( map(line.interpolate, dash_pts)) # Interpolate points along this line to make dashes dash_pts = [pt.xy for pt in dash_pts] dash_pts = np.reshape(dash_pts, (-1, 2, 2)) lines = [ Path(list(linepts), width=width, layer=layer) for linepts in dash_pts ] dline = Cell('DASHLINE') dline.add(lines) return dline
def make_rotating_branches(length, width, N, radius, layers, angle_sweep=360, angle_ref=False, angle_offset=0): cell = Cell('RotatingBranches') if not (type(layers) == list): layers = [layers] allslits = Cell('All Slits') angles = np.linspace(0, angle_sweep, N) translation = (radius, 0) pt1 = np.array((-length / 2., -width / 2.)) + translation pt2 = np.array((length / 2., width / 2.)) + translation branch = make_branch(length, width, layers) for element in branch.elements: element.origin = [radius, 0] for angle in angles: allslits.add(branch.copy(), rotation=angle_offset + angle) cell.add(allslits) for l in layers: if angle_ref: labelCell = Cell('AngleLabels') lineCell = Cell('Line') pt1 = (0, 0) pt2 = (radius * 0.9, 0) line = Path([pt1, pt2], width=width, layer=l) dLine = dashed_line(pt1, pt2, 2, width, l) lineCell.add(line) rot_angle = 0 while True: if abs(rot_angle) > abs(angle_sweep): break if abs(rot_angle) % 60 == 0: labelCell.add(lineCell, rotation=rot_angle) if (abs(rot_angle) - 30) % 60 == 0: labelCell.add(dLine, rotation=rot_angle) rot_angle += np.sign(angle_sweep) * 15 cell.add(labelCell) return cell
def make_rotating_slits(length, width, N, radius, layers, angle_sweep=360, angle_ref=False): cell = Cell('RotatingSlits') if not (type(layers) == list): layers = [layers] allslits = Cell('All Slits') angles = np.linspace(0, angle_sweep, N) # radius = length*12. translation = (radius, 0) pt1 = np.array((-length / 2., -width / 2.)) + translation pt2 = np.array((length / 2., width / 2.)) + translation slit = Cell("Slit") for l in layers: rect = Rectangle(pt1, pt2, layer=l) slit.add(rect) for angle in angles: allslits.add(slit.copy(), rotation=angle) cell.add(allslits) for l in layers: if angle_ref: label_cell = Cell('AngleLabels') line_cell = Cell('Line') pt1 = (0, 0) pt2 = (radius * 0.9, 0) line = Path([pt1, pt2], width=width, layer=l) d_line = dashed_line(pt1, pt2, 2, width, l) line_cell.add(line) rot_angle = 0 while True: if abs(rot_angle) > abs(angle_sweep): break if abs(rot_angle) % 60 == 0: label_cell.add(line_cell, rotation=rot_angle) if (abs(rot_angle) - 30) % 60 == 0: label_cell.add(d_line, rotation=rot_angle) rot_angle += np.sign(angle_sweep) * 15 cell.add(label_cell) return cell
def add_dicing_marks(self, layers, mkWidth=100): """ Create dicing marks """ if not (type(layers) == list): layers = [layers] # Define the array and wafer parameters gap = self.block_gap wafer_r = self.wafer_r sl_tri = self.trisize sl_lattice = sl_tri + gap / np.tan(np.deg2rad(30)) h_lattice = np.sqrt(3.) / 2. * sl_lattice # Create the lattice of the "up" facing triangles points = self.createPtLattice(2. * wafer_r, sl_lattice / 2., h_lattice) points = [np.array(elem) for elem in points] points = points + np.array([ -sl_lattice / 2., 0 ]) # Shift lattice so we can cleave the wafer at y=0 points = points + np.array( self.blockOffset) # Shift by point from MC search (if applicable) points = [ point for point in points if (Point(point).distance(Point(0, 0)) < wafer_r) ] import pylab as plt # Plot points x, y = list(zip(*points)) plt.plot(x, y, 'ko') # Create a lineshape of the boundary of the circle c = self.waferShape.boundary # Create a set (unordered with unique entries) dicinglines = set() # For each point in the lattice, create three lines (one along each direction) for x, y in points: l0 = LineString([(-4. * wafer_r, y), (4. * wafer_r, 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) p0s = tuple( map(tuple, np.round((i0.geoms[0].coords[0], i0.geoms[1].coords[0])))) p1s = tuple( map(tuple, np.round((i1.geoms[0].coords[0], i1.geoms[1].coords[0])))) p2s = tuple( map(tuple, np.round((i2.geoms[0].coords[0], i2.geoms[1].coords[0])))) # Add these points to a unique unordered set dicinglines.add(p0s) dicinglines.add(p1s) dicinglines.add(p2s) # At the end of the loop, the set will contain a list of point pairs which can be uesd to make the dicing marks dmarks = Cell('DIC_MRKS') for l in layers: for p1, p2 in dicinglines: dicingline = Path([p1, p2], width=mkWidth, layer=l) dmarks.add(dicingline) self.add(dmarks) return points