def add_contacts(self, layers): corner_pos = pad_size/2 finger_width = 20. finger_length = 80. n_cont = smField_num + 1 contact_pads = Cell('Contact_Pads') pad = Rectangle((-corner_pos,-corner_pos), (corner_pos,corner_pos), layer=layers) pad_cell = Cell('Pad_Cell') pad_cell.add(pad) finger = Rectangle((-finger_width/2,-finger_length/2), (finger_width/2,finger_length/2), layer=layers) finger_cell = Cell('Finger Cell') finger_cell.add(finger) n_finger = n_cont - 1 pad_array = CellArray(pad_cell, n_cont, n_cont, (sm_spacing, sm_spacing), origin = (0, 0)) finger_array1 = CellArray(finger_cell, n_finger, n_finger, (sm_spacing, sm_spacing), origin=(corner_pos - finger_width, +corner_pos + finger_length/2)) finger_array2 = CellArray(finger_cell, n_finger, n_finger, (sm_spacing, sm_spacing), origin=(sm_spacing -corner_pos + finger_width, sm_spacing -corner_pos - finger_length/2)) finger_array3 = CellArray(finger_cell, n_finger, n_finger, (sm_spacing, sm_spacing), rotation = 90, origin=((n_cont-1)*sm_spacing - corner_pos - finger_length/2, corner_pos - finger_width)) finger_array4 = CellArray(finger_cell, n_finger, n_finger, (sm_spacing, sm_spacing), rotation = 90, origin=((n_cont-2)*sm_spacing + corner_pos + finger_length/2, sm_spacing -corner_pos + finger_width)) contact_pads.add(pad_array) contact_pads.add(finger_array1) contact_pads.add(finger_array2) contact_pads.add(finger_array3) contact_pads.add(finger_array4) center = -0.5*((n_cont-1)*smField_size + (n_cont-1)*pad_size) for block in self.blocks: for n in range (0, lgField_num): for i in range (0, lgField_num): block.add(contact_pads, origin = (center + (n+1)*lgField_spacing, center+ (i+1)*lgField_spacing))
def make_align_markers(self, t, w, position, layers, joy_markers=False, camps_markers=False): if not (type(layers) == list): layers = [layers] top_mk_cell = Cell('AlignmentMark') for l in layers: if not joy_markers: am0 = Rectangle((-w / 2., -w / 2.), (w / 2., w / 2.), layer=l) rect_mk_cell = Cell("RectMarker") rect_mk_cell.add(am0) top_mk_cell.add(rect_mk_cell) elif joy_markers: 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()))) am0 = Boundary(crosspts, layer=l) # Create gdsCAD shape joy_mk_cell = Cell("JOYMarker") joy_mk_cell.add(am0) top_mk_cell.add(joy_mk_cell) if camps_markers: emw = 20. # 20 um e-beam marker width camps_mk = Rectangle((-emw / 2., -emw / 2.), (emw / 2., emw / 2.), layer=l) camps_mk_cell = Cell("CAMPSMarker") camps_mk_cell.add(camps_mk) top_mk_cell.add(camps_mk_cell, origin=[100., 100.]) top_mk_cell.add(camps_mk_cell, origin=[100., -100.]) top_mk_cell.add(camps_mk_cell, origin=[-100., 100.]) top_mk_cell.add(camps_mk_cell, origin=[-100., -100.]) self.align_markers = Cell("AlignMarkers") self.align_markers.add(top_mk_cell, origin=np.array(position) * np.array([1, -1])) self.align_markers.add(top_mk_cell, origin=np.array(position) * np.array([-1, -1])) self.align_markers.add(top_mk_cell, origin=np.array(position) * np.array([1, 1])) self.align_markers.add(top_mk_cell, origin=np.array(position) * np.array([-1, 1])) self.add(self.align_markers)
def add_prealignment_markers(self, layers, mrkr_size=9): if mrkr_size % 2 == 0: # Number is even, but we need odd numbers mrkr_size += 1 if type(layers) is not list: layers = [layers] for l in layers: rect_size = 10. # 10 um large PAMM rectangles marker_rect = Rectangle([-rect_size / 2., -rect_size / 2.], [rect_size / 2., rect_size / 2.], layer=l) marker = Cell('10umMarker') marker.add(marker_rect) # Make one arm of the PAMM array marker_arm = Cell('PAMM_Arm') # Define the positions of the markers, they increase in spacing by 1 um each time: mrkr_positions = [ 75 * n + (n - 1) * n // 2 for n in range(1, (mrkr_size - 1) // 2 + 1) ] for pos in mrkr_positions: marker_arm.add(marker, origin=[pos, 0]) # Build the final PAMM Marker pamm_cell = Cell('PAMM_Marker') pamm_cell.add(marker) # Center marker pamm_cell.add(marker_arm) # Right arm pamm_cell.add(marker_arm, rotation=180) # Left arm pamm_cell.add(marker_arm, rotation=90) # Top arm pamm_cell.add(marker_arm, rotation=-90) # Bottom arm for pos in mrkr_positions: pamm_cell.add(marker_arm, origin=[pos, 0], rotation=90) # Top arms pamm_cell.add(marker_arm, origin=[-pos, 0], rotation=90) pamm_cell.add(marker_arm, origin=[pos, 0], rotation=-90) # Bottom arms pamm_cell.add(marker_arm, origin=[-pos, 0], rotation=-90) # Make the 4 tick marks that mark the center of the array h = 30. w = 100. tick_mrk = Rectangle([-w / 2., -h / 2.], [w / 2, h / 2.], layer=l) tick_mrk_cell = Cell("TickMark") tick_mrk_cell.add(tick_mrk) pos = mrkr_positions[-1] + 75 + w / 2. pamm_cell.add(tick_mrk_cell, origin=[pos, 0]) pamm_cell.add(tick_mrk_cell, origin=[-pos, 0]) pamm_cell.add(tick_mrk_cell, origin=[0, pos], rotation=90) pamm_cell.add(tick_mrk_cell, origin=[0, -pos], rotation=90) all_pamms = Cell('AllPAMMs') all_pamms.add(pamm_cell, origin=[2000, 0]) all_pamms.add(pamm_cell, origin=[-2000, 0]) # 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(all_pamms, origin=origin)
def make_finger_contacts(self, slit_length, length, nslit, pitch, rot_angle, layers): global margin margin = 2.5 cont_to_cent = 60. fing_width = 1. rad_angle = rot_angle/180*np.pi fing_ext_length = cont_to_cent - (slit_length/2-margin)*np.cos(rad_angle) fing_ext_hook = 30. + nslit/2 * pitch + np.sin(rad_angle)*slit_length/2 fing_int_length = cont_to_cent + nslit/2 * pitch + np.sin(rot_angle)*length + margin cont_conn_length = 2*margin contact = Cell(" FingerContact") triangle = RegPolygon((0,0), cont_conn_length, 3, layer = layers) conn_triangle = Cell("ConnTriangle") conn_triangle.add(triangle) finger_rect = Rectangle((-fing_ext_length / 2., -fing_width/2), (fing_ext_length / 2., fing_width/2), layer = layers) finger_ext = Cell("Finger") finger_ext.add(finger_rect) hook = Rectangle(( -fing_ext_hook / 2., -fing_width/2), (fing_ext_hook / 2., fing_width/2), layer = layers) hook_finger = Cell("ContactFinger") hook_finger.add(hook) finger_middle = Rectangle((-fing_int_length / 2., -fing_width/2), (fing_int_length / 2., fing_width/2), layer = layers) finger_int = Cell("Middle Finger") finger_int.add(finger_middle) # Relative coordinates for horizontal elements (origin = center of the triangle) h_finger_to_triangle_x = fing_ext_length/2 h_hook_to_triangle_x = fing_ext_length - fing_width/2 h_hook_to_triangle_y = -fing_ext_hook/2 + fing_width/2 # Relative coordinates for vertical elements (origin = center of the triangle) v_finger_to_triangle_x = fing_int_length/2 cont_ext = Cell("ExternalContact") cont_ext.add(conn_triangle) cont_ext.add(finger_ext, origin = (h_finger_to_triangle_x, 0)) cont_ext.add(hook_finger, origin =(h_hook_to_triangle_x, h_hook_to_triangle_y), rotation = 90) cont_int = Cell("InternalContact") cont_int.add(conn_triangle) cont_int.add(finger_int, origin = (v_finger_to_triangle_x, 0)) # Coordinates Horizontal and Vertical Contacts into the small field hor_x = -cont_to_cent hor_y = cont_to_cent/2-margin vert_x = (-length - fing_width/2)*np.cos(rad_angle) - (1-np.cos(rad_angle))*(fing_width/2) vert_y = cont_to_cent contact.add(cont_ext, origin = (hor_x, hor_y)) contact.add(cont_int, origin = (vert_x, vert_y), rotation = -90) self.add(contact) self.add(contact, rotation = 180) return
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 add_prealignment_markers(self, layers, mrkr_size=7): #TO BE ADJUSTED if mrkr_size % 2 == 0: # Number is even, but we need odd numbers mrkr_size += 1 if type(layers) is not list: layers = [layers] for l in layers: rect_size = 10. # 10 um large PAMM rectangles marker_rect = Rectangle([-rect_size / 2., -rect_size / 2.], [rect_size / 2., rect_size / 2.], layer=l) # Coordinates marker = Cell('10umMarker') marker.add(marker_rect) # Make one arm of the PAMM array marker_arm = Cell('PAMM_Arm') # Define the positions of the markers, they increase in spacing by 1 um each time: mrkr_positions = [ 50 * n + (n - 1) * n // 2 for n in range(1, (mrkr_size - 1) // 2 + 1) ] for pos in mrkr_positions: marker_arm.add(marker, origin=[pos, 0]) # Build the final PAMM Marker pamm_cell = Cell('PAMM_Marker') pamm_cell.add(marker) # Center marker pamm_cell.add(marker_arm) # Right arm pamm_cell.add(marker_arm, rotation=180) # Left arm pamm_cell.add(marker_arm, rotation=90) # Top arm pamm_cell.add(marker_arm, rotation=-90) # Bottom arm for pos in mrkr_positions: pamm_cell.add(marker_arm, origin=[pos, 0], rotation=90) # Top arms pamm_cell.add(marker_arm, origin=[-pos, 0], rotation=90) pamm_cell.add(marker_arm, origin=[pos, 0], rotation=-90) # Bottom arms pamm_cell.add(marker_arm, origin=[-pos, 0], rotation=-90) # Make the 4 tick marks that mark the center of the array h = 15. w = 50. tick_mrk = Rectangle([-w / 2., -h / 2.], [w / 2, h / 2.], layer=l) tick_mrk_cell = Cell("TickMark") tick_mrk_cell.add(tick_mrk) pos = mrkr_positions[-1] + 75 + w / 2. pamm_cell.add(tick_mrk_cell, origin=[pos, 0]) pamm_cell.add(tick_mrk_cell, origin=[-pos, 0]) pamm_cell.add(tick_mrk_cell, origin=[0, pos], rotation=90) pamm_cell.add(tick_mrk_cell, origin=[0, -pos], rotation=90) center_x, center_y = (5000, 5000) # Positioning onto the chip for block in self.blocks: block.add(pamm_cell, origin=(center_x + 2000, center_y)) block.add(pamm_cell, origin=(center_x - 2000, center_y)) block.add(pamm_cell, origin=(center_x, center_y + 2000))
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
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 make_align_markers(self, t, w, position, layers, cross=False, auto_align_marks=True): if not (type(layers) == list): layers = [layers] self.align_markers = Cell("AlignMarks_Four") align_mark = Cell("AlignMarks_Corner") for l in layers: if not cross: am0 = Rectangle((-w / 2., -w / 2.), (w / 2., w / 2.), layer=l) 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()))) am0 = Boundary(crosspts, layer=l) # Create gdsCAD shape align_cross = Cell('AlignCross') align_cross.add(am0) align_mark.add(align_cross) if auto_align_marks: aa_mark = Rectangle((-10, -10), (10, 10), layer=l) auto_mark = Cell('AutoAlignMark') auto_mark.add(aa_mark) four_marks = Cell('FourAAMarks') pos = [100., 100.] four_marks.add(auto_mark, origin=tuple(np.array(pos) * [1, 1])) four_marks.add(auto_mark, origin=tuple(np.array(pos) * [-1, 1])) four_marks.add(auto_mark, origin=tuple(np.array(pos) * [1, -1])) four_marks.add(auto_mark, origin=tuple(np.array(pos) * [-1, -1])) align_mark.add(four_marks) self.align_markers.add(align_mark, origin=tuple(np.array(position) * [1, 1])) self.align_markers.add(align_mark, origin=tuple(np.array(position) * [-1, 1])) self.align_markers.add(align_mark, origin=tuple(np.array(position) * [1, -1])) self.align_markers.add(align_mark, origin=tuple(np.array(position) * [-1, -1])) self.add(self.align_markers)
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 makeYShape(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 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 makeAlignMarkers(self, t, w, position, layers, cross=False): if not (type(layers) == list): layers = [layers] self.aMarkers = Cell("AlignMarkers") for l in layers: if not (cross): am0 = Rectangle((-w / 2., -w / 2.), (w / 2., w / 2.), layer=l) 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 # am1 = Polygon(crosspts) #Create shapely polygon for later calculation am1 = am0.copy().translate(tuple(np.array(position) * [1, 1])) # 850,850 am2 = am0.copy().translate(tuple(np.array(position) * [-1, 1])) # 850,850 am3 = am0.copy().translate(tuple(np.array(position) * [1, -1])) # 850,850 am4 = am0.copy().translate(tuple(np.array(position) * [-1, -1])) # 850,850 # am4 = am0.copy().scale((-1, -1)) #Reflect in both x and y-axis self.aMarkers.add([am1, am2, am3, am4]) self.add(self.aMarkers)
def make_rotating_slits(length, width, N, radius, layers, angle_ref=None, angle_sweep=360): """ :param length: Length of the slits in the circle :param width: Width of the slits in the circle :param N: Number of slits going around the circle :param radius: Radius of the circle :param layers: Layers to write the slits in :param angle_ref: if None, no angle reference lines are added. If '111' then add reference lines at 30/60 degrees. If '100' then add reference lines at 45/90 degrees. :return: """ 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) if angle_ref: 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) if angle_ref == '111': 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) elif angle_ref == '100': labelCell.add(lineCell, rotation=0) labelCell.add(lineCell, rotation=90) labelCell.add(dLine, rotation=45) labelCell.add(dLine, rotation=135) cell.add(labelCell) return cell
def add_contacts(self, md_size_x, md_size_y, layers): smField_num_x = int((md_size_x)/sm_spacing-1) smField_num_y = int((md_size_y)/sm_spacing-1) corner_pos = pad_size/2 finger_width = 20. finger_length = 80. n_cont_x = smField_num_x + 1 n_cont_y = smField_num_y + 1 contact_pads = Cell('Contact_Pads') pad = Rectangle((-corner_pos,-corner_pos), (corner_pos,corner_pos), layer=layers) pad_cell = Cell('Pad_Cell') pad_cell.add(pad) finger = Rectangle((-finger_width/2,-finger_length/2), (finger_width/2,finger_length/2), layer=layers) finger_cell = Cell('Finger Cell') finger_cell.add(finger) n_finger_x = n_cont_x - 1 n_finger_y = n_cont_y - 1 pad_array = CellArray(pad_cell, n_cont_x, n_cont_y, (sm_spacing, sm_spacing), origin = (0, 0)) finger_array1 = CellArray(finger_cell, n_finger_x, n_finger_y, (sm_spacing, sm_spacing), origin=(corner_pos - finger_width, corner_pos + finger_length/2)) finger_array2 = CellArray(finger_cell, n_finger_x, n_finger_y, (sm_spacing, sm_spacing), origin=(sm_spacing -corner_pos + finger_width, sm_spacing -corner_pos - finger_length/2)) finger_array3 = CellArray(finger_cell, n_finger_y, n_finger_x, (sm_spacing, sm_spacing), rotation = 90, origin=((n_cont_x-1)*sm_spacing - corner_pos - finger_length/2, corner_pos - finger_width)) finger_array4 = CellArray(finger_cell, n_finger_y, n_finger_x, (sm_spacing, sm_spacing), rotation = 90, origin=((n_cont_x-2)*sm_spacing + corner_pos + finger_length/2, sm_spacing -corner_pos + finger_width)) contact_pads.add(pad_array) contact_pads.add(finger_array1) contact_pads.add(finger_array2) contact_pads.add(finger_array3) contact_pads.add(finger_array4) center_x = -0.5*((n_cont_x-1)*smField_size + (n_cont_x-1)*pad_size) center_y = -0.5*((n_cont_y-1)*smField_size + (n_cont_y-1)*pad_size) self.add(contact_pads, origin = (center_x, center_y)) return smField_num_x, smField_num_y
def make_branch(length, width, layers, rot_angle=0): 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) branch = Cell('Branch-{}/{}-lw'.format(length, width)) branch.add(slit, rotation=0 + rot_angle) branch.add(slit, rotation=120 + rot_angle) branch.add(slit, rotation=240 + rot_angle) return branch
def processCheck_Slits(self, position, arrayWidth, slitWidth, pitch, length, rotation, layers): if not (type(layers) == list): layers = [layers] Nx = int(arrayWidth / pitch) Ny = 1 for l in layers: # Define the slits slit = Cell("Slits") rect = Rectangle((-slitWidth / 2., -length / 2.), (slitWidth / 2., length / 2.), layer=l) slit.add(rect) slits = CellArray(slit, Nx, Ny, (pitch, 0)) slits.translate((-(Nx) * (pitch) / 2., 0.)) slits.translate(position) slitarray = Cell("ProcessCheckingSlits") slitarray.add(slits) self.add(slitarray)
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 makeAlignMarkers(self, t, w, position, layers, cross=False): if not (type(layers) == list): layers = [layers] self.aMarkers = Cell("AlignMarkers") for l in layers: if not (cross): am1 = Rectangle((-w / 2., -w / 2.), (w / 2., w / 2.), layer=l) elif cross: h = w crosspts = [(-t / 2., t / 2.), (-t / 2., h / 2.), (t / 2., h / 2.), (t / 2., t / 2.), (w / 2., t / 2.), (w / 2., -t / 2.), (t / 2., -t / 2.), (t / 2., -h / 2.), (-t / 2., -h / 2.), (-t / 2., -t / 2.), (-w / 2., -t / 2.), (-w / 2., t / 2.)] am1 = Boundary(crosspts, layer=l) # Create gdsCAD shape # am1 = Polygon(crosspts) #Create shapely polygon for later calculation am1 = am1.translate(tuple(position)) # 850,850 am2 = am1.copy().scale((-1, 1)) # Reflect in x-axis am3 = am1.copy().scale((1, -1)) # Reflect in y-axis am4 = am1.copy().scale((-1, -1)) # Reflect in both x and y-axis self.aMarkers.add([am1, am2, am3, am4]) self.add(self.aMarkers)
def make_slit_array(self, _pitches, spacing, _widths, _lengths, rot_angle, array_height, array_width, array_spacing, layers): if not (type(layers) == list): layers = [layers] if not (type(_pitches) == list): _pitches = [_pitches] if not (type(_lengths) == list): _lengths = [_lengths] if not (type(_widths) == list): _widths = [_widths] manyslits = i = j = None for l in layers: i = -1 j = -1 manyslits = Cell("SlitArray") pitch = _pitches[0] for length in _lengths: j += 1 i = -1 for width in _widths: # for pitch in pitches: i += 1 if i % 3 == 0: j += 1 # Move to array to next line i = 0 # Restart at left nx = int(array_width / (length + spacing)) ny = int(array_height / pitch) # Define the slits slit = Cell("Slits") rect = Rectangle((-length / 2., -width / 2.), (length / 2., width / 2.), layer=l) slit.add(rect) slits = CellArray(slit, nx, ny, (length + spacing, pitch)) slits.translate((-(nx - 1) * (length + spacing) / 2., -(ny - 1) * pitch / 2.)) slit_array = Cell("SlitArray") slit_array.add(slits) text = Label('w/p/l\n%i/%i/%i' % (width * 1000, pitch, length), 5, layer=l) lbl_vertical_offset = 1.35 if j % 2 == 0: text.translate( tuple( np.array(-text.bounding_box.mean(0)) + np.array((0, -array_height / lbl_vertical_offset)) )) # Center justify label else: text.translate( tuple( np.array(-text.bounding_box.mean(0)) + np.array((0, array_height / lbl_vertical_offset )))) # Center justify label slit_array.add(text) manyslits.add( slit_array, origin=((array_width + array_spacing) * i, (array_height + 2. * array_spacing) * j - array_spacing / 2.)) # This is an ugly hack to center rotated slits, should fix this properly... hacky_offset_x = 200 if rot_angle == 45 else 0 # TODO: fix this ugly thing hacky_offset_y = -25 if rot_angle == 45 else 0 self.add(manyslits, origin=(-i * (array_width + array_spacing) / 2 + hacky_offset_x, -(j + 1.5) * (array_height + array_spacing) / 2 + hacky_offset_y), rotation=rot_angle)
def 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))
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
def make_slit_array(x_vars, y_vars, stat_vars, var_names, spacing, rot_angle, array_height, array_width, array_spacing, layers): if len(var_names) != 3: raise Exception('Error! Need to have three variable names.') if not (type(layers) == list): layers = [layers] if not (type(x_vars) == list): x_vars = [x_vars] if not (type(y_vars) == list): y_vars = [y_vars] if not (type(stat_vars) == list): stat_vars = [stat_vars] x_var_name = var_names[0] y_var_name = var_names[1] stat_var_name = var_names[2] for l in layers: j = -1 manyslits = Cell("SlitArray") for x_var in x_vars: j += 1 i = -1 for y_var in y_vars: i += 1 if i % 3 == 0: j += 1 # Move to array to next line i = 0 # Restart at left var_dict = { x_var_name: x_var, y_var_name: y_var, stat_var_name: stat_vars[0] } pitch = var_dict['pitch'] width = var_dict['width'] length = var_dict['length'] pitch_v = pitch / np.cos(np.deg2rad(rot_angle)) # widthV = width / np.cos(np.deg2rad(rotAngle)) n_x = int(array_width / (length + spacing)) n_y = int(array_height / pitch_v) # Define the slits slit = Cell("Slits") rect = Rectangle((-length / 2., -width / 2.), (length / 2., width / 2.), layer=l) rect = rect.copy().rotate(rot_angle) slit.add(rect) slits = CellArray(slit, n_x, n_y, (length + spacing, pitch_v)) slits.translate((-(n_x - 1) * (length + spacing) / 2., -(n_y - 1) * pitch_v / 2.)) slit_array = Cell("SlitArray") slit_array.add(slits) text = Label('w/p/l\n%i/%i/%i' % (width * 1000, pitch * 1000, length * 1000), 2, layer=l_smBeam) lbl_vert_offset = 1.35 if j % 2 == 0: text.translate( tuple( np.array(-text.bounding_box.mean(0)) + np.array((0, -array_height / lbl_vert_offset))) ) # Center justify label else: text.translate( tuple( np.array(-text.bounding_box.mean(0)) + np.array((0, array_height / lbl_vert_offset))) ) # Center justify label slit_array.add(text) manyslits.add(slit_array, origin=((array_width + array_spacing) * i, (array_height + 2. * array_spacing) * j - array_spacing / 2.)) return manyslits
def add_contacts(self, pad_size, finger_width, finger_length, layers): corner_pos = pad_size / 2 n_ext = 12 n_int = n_ext - 1 spacing = 7000 / (n_ext + 2) n_inner = 3 spacing_inner = (1000 - pad_size) / (n_inner - 1) contact_pads = Cell('Contact_Pads') pad = Rectangle((-corner_pos, -corner_pos), (corner_pos, corner_pos), layer=layers) pad_cell = Cell('Pad_Cell') pad_cell.add(pad) finger = Rectangle((-finger_width / 2, -finger_length / 2), (finger_width / 2, finger_length / 2), layer=layers) finger_cell = Cell('Finger Cell') finger_cell.add(finger) curr_x = (10000 - ((n_ext - 1) * spacing)) / 2 curr_y = 1500 - 2 * spacing + corner_pos pad_array_ext = CellArray(pad_cell, n_ext, 1, (spacing, pad_size * 1.5), origin=(curr_x, curr_y)) finger_array_ext = CellArray(finger_cell, n_ext, 1, (spacing, pad_size * 1.5), origin=(curr_x, curr_y + corner_pos + finger_length / 2)) pad_array_int = CellArray(pad_cell, n_int, 1, (spacing, pad_size * 1.5), origin=(curr_x + spacing / 2, curr_y + spacing)) finger_array_int = CellArray( finger_cell, n_int, 1, (spacing, pad_size * 1.5), origin=(curr_x + spacing / 2, curr_y + spacing + corner_pos + finger_length / 2)) curr_x = curr_y = 3000 - ((n_inner - 1) * spacing_inner / 2) pad_array_inner = CellArray(pad_cell, n_inner, n_inner, (spacing_inner, spacing_inner), origin=(curr_x, curr_y)) # finger_array_inner = CellArray(finger_cell, 2, 2, (spacing, pad_size*1.5), origin=(2700, 2700)) contact_pads.add(pad_array_ext) contact_pads.add(pad_array_int) contact_pads.add(pad_array_inner) contact_pads.add(finger_array_ext) contact_pads.add(finger_array_int) # contact_pads.add(finger_array_inner) for block in self.blocks: block.add(contact_pads) block.add(contact_pads, origin=(10000, 0), rotation=90) block.add(contact_pads, origin=(10000, 10000), rotation=180) block.add(contact_pads, origin=(0, 10000), rotation=270)
topCell.add(smField3, origin=(-dx / 2., -dy / 2.)) topCell.add(smField4, origin=(dx / 2., -dy / 2.)) topCell.add(centerAlignField, origin=(dx / 2., 0.)) topCell.add(qp_cell, origin=(dx / 2., 0.)) # Create the layout and output GDS file layout = Layout('LIBRARY', precision=1e-10) wafer = MBEWafer('MembranesWafer', wafer_r=wafer_r, cells=[topCell], cell_gap=CELL_GAP, mkWidth=tDicingMarks, cellsAtEdges=False) file_string = str(waferVer) filename = file_string.replace(' ', '_') # Add pattern for ellipsometry check of SiO2 etching size = 2000 rect = Rectangle((size / 2., size / 2.), (-size / 2., -size / 2.), layer=10) rectCell = Cell('EtchCheckSquare') rectCell.add(rect) rect_layout = Layout('LIBRARY') rect_layout.add(rectCell) rect_layout.save(filename + '_etchCheck.gds') rect_layout.add(rectCell) layout.add(wafer) layout.save(filename + '.gds') # Output down chip for doing aligned jobs layout_down = Layout('LIBRARY') layout_down.add(wafer.block_down) layout_down.save(filename + '_downblock.gds')
def make_arm(width, length, layer, cell_name='branch'): cell = Cell(cell_name) rect = Rectangle((0, -width / 2.), (length, width / 2.), layer=layer) cell.add(rect) return cell
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
def makeSlitArray(pitches, spacing, widths, lengths, rotAngle, arrayHeight, arraySpacing, layers): ''' Give it a single pitch and width and it will generate an array for all the lengths ''' if not (type(layers) == list): layers = [layers] if not (type(pitches) == list): pitches = [pitches] if not (type(lengths) == list): lengths = [lengths] if not (type(widths) == list): widths = [widths] for l in layers: i = -1 j = -1 manyslits = Cell("SlitArray") slitarray = Cell("SlitArray") pitch = pitches[0] width = widths[0] j += 1 i = -1 xlength = 0 slit = Cell("Slits") for length in lengths: spacing = length / 5. + 0.1 i += 1 pitchV = pitch / np.cos(np.deg2rad(rotAngle)) # widthV = width / np.cos(np.deg2rad(rotAngle)) # Nx = int(arrayWidth / (length + spacing)) Ny = int(arrayHeight / (pitchV)) # Define the slits if xlength == 0: translation = (length / 2., 0) xlength += length else: translation = (xlength + spacing + length / 2., 0) xlength += length + spacing pt1 = np.array((-length / 2., -width / 2.)) + translation pt2 = np.array((length / 2., width / 2.)) + translation rect = Rectangle(pt1, pt2, layer=l) rect = rect.copy().rotate(rotAngle) slit.add(rect) slits = CellArray(slit, 1, Ny, (0, pitchV)) # slits.translate((-(Nx - 1) * (length + spacing) / 2., -(Ny - 1)* (pitchV) / 2.)) slits.translate( (-slits.bounding_box[1, 0] / 2., -slits.bounding_box[1, 1] / 2.)) slitarray.add(slits) text = Label('w/p\n%i/%i' % (width * 1000, pitch * 1000), 2, layer=l_smBeam) lblVertOffset = 1.4 text.translate( tuple( np.array(-text.bounding_box.mean(0)) + np.array((0, arrayHeight / lblVertOffset)))) # Center justify label slitarray.add(text) # manyslits.add(slitarray,origin=((arrayWidth + arraySpacing) * i, (arrayHeight + 2.*arraySpacing) * j-arraySpacing/2.)) manyslits.add(slitarray) # self.add(manyslits, origin=(-i * (arrayWidth + arraySpacing) / 2, -j * (arrayHeight + arraySpacing) / 2)) # self.add(manyslits) return manyslits
def add_contacts(self, pad_size, finger_width, finger_length, layers): contact_frames = [2, 4, 6, 8] spacing = pad_size / 2 for frame in contact_frames: frame_length = (10 - frame) * 1000 n_cont = int((frame_length) / (pad_size + spacing)) - 1 corner_pos = pad_size / 2 contact_pads = Cell('Contact_Pads') pad = Rectangle((-corner_pos, -corner_pos), (corner_pos, corner_pos), layer=layers) pad_cell = Cell('Pad_Cell') pad_cell.add(pad) finger = Rectangle((-finger_width / 2, -finger_length / 2), (finger_width / 2, finger_length / 2), layer=layers) finger_cell = Cell('Finger Cell') finger_cell.add(finger) curr_x = (10000 - ((n_cont - 1) * (pad_size + spacing))) / 2 curr_y = (10000 - frame_length) / 2 pad_array = CellArray(pad_cell, n_cont, 1, (pad_size + spacing, pad_size + spacing), origin=(curr_x, curr_y)) finger_array_tr = CellArray( finger_cell, n_cont, 1, (pad_size + spacing, pad_size + spacing), origin=(curr_x - pad_size / 2 + finger_width, curr_y + corner_pos + finger_length / 2)) finger_array_tl = CellArray( finger_cell, n_cont, 1, (pad_size + spacing, pad_size + spacing), origin=(curr_x + pad_size / 2 - finger_width, curr_y + corner_pos + finger_length / 2)) finger_array_br = CellArray( finger_cell, n_cont, 1, (pad_size + spacing, pad_size + spacing), origin=(curr_x - pad_size / 2 + finger_width, curr_y - corner_pos - finger_length / 2)) finger_array_bl = CellArray( finger_cell, n_cont, 1, (pad_size + spacing, pad_size + spacing), origin=(curr_x + pad_size / 2 - finger_width, curr_y - corner_pos - finger_length / 2)) contact_pads.add(pad_array) if frame < 8: contact_pads.add(finger_array_tr) contact_pads.add(finger_array_tl) if frame > 2: contact_pads.add(finger_array_br) contact_pads.add(finger_array_bl) for block in self.blocks: block.add(contact_pads) block.add(contact_pads, origin=(10000, 0), rotation=90) block.add(contact_pads, origin=(10000, 10000), rotation=180) block.add(contact_pads, origin=(0, 10000), rotation=270)