def init_regions(self): self.connections = [DPoint(0, 0), self.dr] self.start = DPoint(0, 0) self.end = self.start + self.dr alpha = atan2(self.dr.y, self.dr.x) self.angle_connections = [alpha, alpha] alpha_trans = ICplxTrans().from_dtrans( DCplxTrans(1, alpha * 180 / pi, False, self.start)) metal_poly = DSimplePolygon([ DPoint(0, -self.width / 2), DPoint(self.dr.abs(), -self.width / 2), DPoint(self.dr.abs(), self.width / 2), DPoint(0, self.width / 2) ]) self.connection_edges = [3, 1] self.metal_region.insert(pya.SimplePolygon().from_dpoly(metal_poly)) if (self.gap != 0): self.empty_region.insert( pya.Box( Point().from_dpoint(DPoint(0, self.width / 2)), Point().from_dpoint( DPoint(self.dr.abs(), self.width / 2 + self.gap)))) self.empty_region.insert( pya.Box( Point().from_dpoint(DPoint(0, -self.width / 2 - self.gap)), Point().from_dpoint(DPoint(self.dr.abs(), -self.width / 2)))) self.metal_region.transform(alpha_trans) self.empty_region.transform(alpha_trans)
def find_path_mur( self, start, end, Nx=15, Ny=15 ): self.start_last = start self.end_last = end self.Nx = Nx self.Ny = Ny self.width = self.bbox.width()/Nx self.height = self.bbox.height()/Ny self.field = np.full( (self.Nx,self.Ny), -1, dtype=np.int32 ) field_start = Point( int(start.x/self.width), int(start.y/self.height) ) field_end = Point( int(end.x/self.width), int(end.y/self.height) ) self._prepare_wall() in_propogation = True self.field[ field_start.x,field_start.y ] = 0 field_back_buffer = np.copy( self.field ) print( self.field, "\n\n" ) while( self.field[ field_end.x, field_end.y] == -1 and in_propogation): for x in range( 0,Nx ): for y in range( 0,Ny ): if( self.field[x,y] >= 0 ): for dx in [-1,0,1]: for dy in [-1,0,1]: if( (x + dx) >= Nx or (x + dx < 0) or (y + dy) >= Ny or (y + dy < 0) ): continue if( dy == 0 and dx == 0 ): continue elif( self.field[x + dx,y + dy] == -1 ): field_back_buffer[x+dx,y+dy] = self.field[x,y] + 1 if( np.array_equal( self.field, field_back_buffer ) ): in_propogation = False np.copyto( self.field, field_back_buffer ) print( self.field, "\n\n" ) path = [] if( self.field[ field_end.x, field_end.y ] > 0 ): current = Point( field_end.x, field_end.y ) while( True ): for dx in [-1,0,1]: isNext = False for dy in [-1,0,1]: if( (current.x + dx) >= Nx or (current.x + dx < 0) or (current.y + dy) >= Ny or (current.y + dy < 0) ): continue elif( current == Point(0,0) ): return path else: if( self.field[ current.x + dx, current.y + dy ] == (self.field[current.x,current.y] - 1) ): path.append(current.dup()) current.x += dx current.y += dy isNext = True break if( isNext ): break else: print( "No path is founded" ) return None
def draw_pinning_holes(self): selection_region = Region( pya.Box(Point(100e3, 100e3), Point(101e3, 101e3))) tmp_ph = self.region_ph.dup() other_regs = tmp_ph.select_not_interacting(selection_region) reg_to_fill = self.region_ph.select_interacting(selection_region) filled_reg = fill_holes(reg_to_fill) self.region_ph = filled_reg + other_regs
def _prepare_wall(self): self.wall = [] for Z0 in self.objects: if (isinstance(Z0, CPW) and Z0.dr.abs() != 0): for ny in range(0, self.Ny): for nx in range(0, self.Nx): x = nx * self.width y = ny * self.height w = Z0.width drLeft = DPoint(-Z0.dr.y, Z0.dr.x) * (1 / Z0.dr.abs()) box = pya.DBox(DPoint(x, y), DPoint(x + self.width, y + self.height)) if ((box.left - abs(drLeft.x) * 2 * Z0.b / 2) > Z0.end.x or (box.right + abs(drLeft.x) * 2 * Z0.b / 2) < Z0.start.x): continue if ((box.bottom - abs(drLeft.y) * 2 * Z0.b / 2) > Z0.end.y or (box.top + abs(drLeft.y) * 2 * Z0.b / 2) < Z0.start.y): continue self.wall.append(Point(nx, ny)) for pt in self.wall: self.field[pt.x, pt.y] = -2
def pin(w,pin_text, trans, LayerPinRecN, dbu, cell): """ w: Waveguide Width, e.g., 500 (in dbu) pin_text: Pin Text, e.g., "pin1" trans: e.g., trans = Trans(0, False, 0, 0) - first number is 0, 1, 2, or 3. pinrec: PinRec Layer, e.g., layout.layer(TECHNOLOGY['PinRec'])) devrec: DevRec Layer, e.g., layout.layer(TECHNOLOGY['DevRec'])) """ # Create the pin, as short paths: from SiEPIC._globals import PIN_LENGTH pin = trans*Path([Point(-PIN_LENGTH/2, 0), Point(PIN_LENGTH/2, 0)], w) cell.shapes(LayerPinRecN).insert(pin) text = Text (pin_text, trans) shape = cell.shapes(LayerPinRecN).insert(text) shape.text_size = w*0.8 print("Done drawing the layout for - pin" )
def init_regions(self): self.metal_regions["photo"] = Region() self.empty_regions["photo"] = Region() self.connections = [DPoint(0, 0), self.dr] self.start = DPoint(0, 0) self.end = self.start + self.dr alpha = atan2(self.dr.y, self.dr.x) self.angle_connections = [alpha, alpha] alpha_trans = ICplxTrans().from_dtrans( DCplxTrans(1, alpha * 180 / pi, False, self.start)) self.metal_regions['photo'].insert( pya.Box(Point().from_dpoint(DPoint(0, -self.width / 2)), Point().from_dpoint(DPoint(self.dr.abs(), self.width / 2)))) self.empty_regions['photo'].insert( pya.Box( Point().from_dpoint(DPoint(0, self.width / 2)), Point().from_dpoint( DPoint(self.dr.abs(), self.width / 2 + self.gap)))) self.empty_regions['photo'].insert( pya.Box( Point().from_dpoint(DPoint(0, -self.width / 2 - self.gap)), Point().from_dpoint(DPoint(self.dr.abs(), -self.width / 2)))) self.metal_regions['photo'].transform(alpha_trans) self.empty_regions['photo'].transform(alpha_trans) self.metal_region = self.metal_regions['photo'] self.empty_region = self.empty_regions['photo']
def init_regions(self): self.metal_regions["photo"] = Region() self.empty_regions["photo"] = Region() self.metal_regions["bridges"] = Region() self.empty_regions["bridges"] = Region() self.metal_regions["bridge_patches"] = Region() self.empty_regions["bridge_patches"] = Region() self.connections = [DPoint(0, 0), self.dr] self.start = DPoint(0, 0) self.end = self.start + self.dr alpha = atan2(self.dr.y, self.dr.x) self.angle_connections = [alpha, alpha] alpha_trans = ICplxTrans().from_dtrans( DCplxTrans(1, alpha * 180 / pi, False, self.start)) self.metal_regions["photo"].insert( pya.Box(Point().from_dpoint(DPoint(0, -self.width / 2)), Point().from_dpoint(DPoint(self.dr.abs(), self.width / 2)))) self.empty_regions["photo"].insert( pya.Box( Point().from_dpoint(DPoint(0, self.width / 2)), Point().from_dpoint( DPoint(self.dr.abs(), self.width / 2 + self.gap)))) self.empty_regions["photo"].insert( pya.Box( Point().from_dpoint(DPoint(0, -self.width / 2 - self.gap)), Point().from_dpoint(DPoint(self.dr.abs(), -self.width / 2)))) self.metal_regions["photo"].transform(alpha_trans) self.empty_regions["photo"].transform(alpha_trans) if self.dr.x == 0: N_bridges = int((self.dr.y - self._bridge_interval) // self._bridge_interval + 1) for i in range(N_bridges): ab = Airbridge(self.start + DPoint( 0, (self._bridge_interval / 2 + i * self._bridge_interval) * sign(self.dr.y)), trans_in=DTrans.R90) self.metal_regions["bridges"] += ab.metal_regions["bridges"] self.metal_regions["bridges"] += ab.metal_regions[ "bridge_patches"] elif self.dr.y == 0: N_bridges = int((self.dr.x - self._bridge_interval) // self._bridge_interval + 1) print("N_bridges", N_bridges) for i in range(N_bridges): bridge_pos = self.start + DPoint( (self._bridge_interval / 2 + i * self._bridge_interval) * sign(self.dr.x), 0) ab = Airbridge(bridge_pos, trans_in=None) self.metal_regions["bridges"] += ab.metal_regions["bridges"] self.metal_regions["bridge_patches"] += ab.metal_regions[ "bridge_patches"]
origin = DPoint(0, 0) width = 20e3 gap = 25e3 Z0 = CPW(width, gap, origin + DPoint(0.5e6, 0.5e6), origin + DPoint(1e6, 0.5e6)) Z0.place(cell, layer_i) start = DPoint(0, 0) end = DPoint(1e6, 1e6) ## pathfinding START ## pf = Path_finder(Z0, bbox=CHIP.box) path = pf.find_path_mur(start, end, 100, 100) ## pathfinding END ## ### DRAW SECTION START ### for y in range(0, pf.Ny): for x in range(0, pf.Nx): if (pf.field[x, y] == -2): cell.shapes(layer_j).insert(pya.Box().from_dbox( pya.DBox(DPoint(x * pf.width, y * pf.height), DPoint((x + 1) * pf.width, (y + 1) * pf.height)))) if (Point(x, y) not in path): cell.shapes(layer_i).insert(pya.Box().from_dbox( pya.DBox(DPoint(x * pf.width, y * pf.height), DPoint((x + 1) * pf.width, (y + 1) * pf.height)))) ### DRAW SECTION END ### lv.zoom_fit() ### MAIN FUNCTION END ###
info = pya.LayerInfo(1, 0) info2 = pya.LayerInfo(2, 0) layer_photo = layout.layer(info) layer_el = layout.layer(info2) # clear this cell and layer cell.clear() # setting layout view #lv.select_cell(cell.cell_index(), 0) lv.add_missing_layers() #Constants ground = pya.Box(Point(-CHIP.dx / 2, -CHIP.dy / 2), Point(CHIP.dx / 2, CHIP.dy / 2)) canvas = Region(ground) ebeam = Region() #Transmon parameters xmon_cpw_params = CPWParameters(20e3, 10e3) arms_vert_len = 144.3e3 arms_hor_len = 200e3 JJ_site_span = 8e3 h_JJ = 278 w_JJ = 150 asymmetry = 0.5
layer_info_photo = pya.LayerInfo(10,0) layer_info_el = pya.LayerInfo(1,0) layer_photo = layout.layer( layer_info_photo ) layer_el = layout.layer( layer_info_el ) # clear this cell and layer cell.clear() # setting layout view if lv: lv.select_cell(cell.cell_index(), 0) lv.add_missing_layers() ## DRAWING SECTION START ## cell.shapes( layer_photo ).insert( pya.Box( Point(0,0), Point( CHIP.dx, CHIP.dy ) ) ) origin = DPoint( 0,0 ) contact_L = 1e6 # main drive line coplanar width = 24.1e3 gap = 12.95e3 p1 = DPoint( 0 + contact_L, CHIP.dy/2 ) p2 = DPoint( CHIP.dx - contact_L, CHIP.dy/2 ) Z0 = CPW( width, gap, p1, p2 ) Z0.place( cell, layer_photo ) # left contact pad width1 = CHIP.width*2 gap1 = CHIP.gap*2
layer_info_photo = pya.LayerInfo(10,0) layer_info_el = pya.LayerInfo(1,0) layer_photo = layout.layer( layer_info_photo ) layer_el = layout.layer( layer_info_el ) # clear this cell and layer cell.clear() # setting layout view lv.select_cell(cell.cell_index(), 0) lv.add_missing_layers() ## DRAWING SECTION START ## cell.shapes( layer_photo ).insert( pya.Box( Point(0,0), Point( CHIP.dx, CHIP.dy ) ) ) origin = DPoint( 0,0 ) contact_L = 1e6 # main drive line coplanar width = 24.1e3 gap = 12.95e3 y = 0.2*CHIP.dy p1 = DPoint( 0, y ) p2 = DPoint( CHIP.dx, y ) Z0 = CPW( width, gap, p1, p2 ) Z0.place( cell, layer_photo ) # resonator
info = pya.LayerInfo(1, 0) info2 = pya.LayerInfo(2, 0) layer_photo = layout.layer(info) layer_el = layout.layer(info2) # clear this cell and layer cell.clear() # setting layout view #lv.select_cell(cell.cell_index(), 0) lv.add_missing_layers() #Constants ground = pya.Box(Point(-(CHIP.dx + 100e3), -(CHIP.dy + 100e3) * 2), Point(CHIP.dx + 100e3, (CHIP.dy + 100e3) * 2)) canvas = Region(ground) ebeam = Region() #Transmon parameters xmon_cpw_params = CPWParameters(20e3, 10e3) arms_vert_len = 144.3e3 arms_hor_len = 200e3 JJ_site_span = 8e3 h_JJ = 238 w_JJ = 150
layer_info_photo = pya.LayerInfo(10, 0) layer_info_el = pya.LayerInfo(1, 0) layer_photo = layout.layer(layer_info_photo) layer_el = layout.layer(layer_info_el) # clear this cell and layer cell.clear() # setting layout view lv.select_cell(cell.cell_index(), 0) lv.add_missing_layers() ## DRAWING SECTION START ## cell.shapes(layer_photo).insert( pya.Box(Point(0, 0), Point(CHIP.dx, CHIP.dy))) origin = DPoint(0, 0) contact_L = 1e6 # main drive line coplanar width = 24.1e3 gap = 12.95e3 p1 = DPoint(0 + contact_L, CHIP.dy / 2) p2 = DPoint(CHIP.dx - contact_L, CHIP.dy / 2) Z0 = CPW(width, gap, p1, p2) Z0.place(cell, layer_photo) # left contact pad width1 = CHIP.width * 2 gap1 = CHIP.gap * 2
info = pya.LayerInfo(1, 0) info2 = pya.LayerInfo(2, 0) layer_photo = layout.layer(info) layer_el = layout.layer(info2) # clear this cell and layer cell.clear() # setting layout view #lv.select_cell(cell.cell_index(), 0) lv.add_missing_layers() #Constants ground = pya.Box(Point(-CHIP.dx / 2, -CHIP.dy / 2), Point(CHIP.dx / 2, CHIP.dy / 2)) canvas = Region(ground) ebeam = Region() feed_cpw_params = CPWParameters(20e3, 10e3) md_cpw_params = CPWParameters(7e3, 4e3) fc_cpw_params = CPWParameters(7e3, 4e3) ### DRAW SECTION START ### cp1 = Contact_Pad(origin=DPoint(-CHIP.dx / 2, -CHIP.dy / 4), feedline_cpw_params=md_cpw_params) cp1.place(canvas)
cross_lens = [125e3] cross_gnd_gaps = [20e3] xmon_dX = 2 * cross_lens[0] + cross_widths[0] + 2 * cross_gnd_gaps[0] xmon_distances = [1e3 * x for x in range(393, 394, 10)] from itertools import product pars = product(cross_widths, cross_lens, cross_gnd_gaps, xmon_distances) for cross_width, cross_len, cross_gnd_gap, xmon_distance in pars: # clear this cell and layer cell.clear() xmon_dX = 2 * cross_len + cross_width + 2 * cross_gnd_gap CHIP.dx = 5 * xmon_dX + xmon_distance CHIP.dy = 5 * xmon_dX + xmon_distance CHIP.center = DPoint(CHIP.dx / 2, CHIP.dy / 2) chip_box = pya.Box(Point(0, 0), Point(CHIP.dx, CHIP.dy)) cell.shapes(layer_photo).insert(chip_box) xmon_cross1 = Xmon_cross(CHIP.center + DPoint(-xmon_distance / 2, 0), cross_width, cross_len, cross_gnd_gap) xmon_cross1.place(cell, layer_photo) xmon_cross2 = Xmon_cross(CHIP.center + DPoint(xmon_distance / 2, 0), cross_width, cross_len, cross_gnd_gap) xmon_cross2.place(cell, layer_photo) ## DRAWING SECTION END ## # lv.zoom_fit() ### MATLAB COMMANDER SECTION START ### ml_terminal = SonnetLab()
def layout_waveguide4(cell, dpath, waveguide_type, debug=True): if debug: print('SiEPIC.utils.layout.layout_waveguide4: ') print(' - waveguide_type: %s' % (waveguide_type)) # get the path and clean it up layout = cell.layout() dbu = layout.dbu dpath = dpath.to_itype(dbu) dpath.unique_points() pts = dpath.get_points() dpts = dpath.get_dpoints() # Load the technology and all waveguide types from SiEPIC.utils import load_Waveguides_by_Tech technology_name = layout.technology_name waveguide_types = load_Waveguides_by_Tech(technology_name) if debug: print(' - technology_name: %s' % (technology_name)) print(' - waveguide_types: %s' % (waveguide_types)) # Load parameters for the chosen waveguide type params = [t for t in waveguide_types if t['name'] == waveguide_type] if type(params) == type([]) and len(params) > 0: params = params[0] else: print('error: waveguide type not found in PDK waveguides') raise Exception( 'error: waveguide type (%s) not found in PDK waveguides' % waveguide_type) # compound waveguide types: if 'compound_waveguide' in params: # find the singlemode and multimode waveguides: if 'singlemode' in params['compound_waveguide']: singlemode = params['compound_waveguide']['singlemode'] else: raise Exception( 'error: waveguide type (%s) does not have singlemode defined' % waveguide_type) if 'multimode' in params['compound_waveguide']: multimode = params['compound_waveguide']['multimode'] else: raise Exception( 'error: waveguide type (%s) does not have multimode defined' % waveguide_type) params_singlemode = [ t for t in waveguide_types if t['name'] == singlemode ] params_multimode = [ t for t in waveguide_types if t['name'] == multimode ] if type(params_singlemode) == type([]) and len(params_singlemode) > 0: params_singlemode = params_singlemode[0] else: raise Exception( 'error: waveguide type (%s) not found in PDK waveguides' % singlemode) if type(params_multimode) == type([]) and len(params_multimode) > 0: params_multimode = params_multimode[0] else: raise Exception( 'error: waveguide type (%s) not found in PDK waveguides' % multimode) # find the taper if 'taper_library' in params[ 'compound_waveguide'] and 'taper_cell' in params[ 'compound_waveguide']: taper = layout.create_cell( params['compound_waveguide']['taper_cell'], params['compound_waveguide']['taper_library']) if not taper: raise Exception( 'Cannot import cell %s : %s' % (params['compound_waveguide']['taper_cell'], params['compound_waveguide']['taper_library'])) else: raise Exception( 'error: waveguide type (%s) does not have taper cell and library defined' % waveguide_type) from pya import Trans, CellInstArray ''' find sections of waveguides that are larger than (2 x radius + 2 x taper_length) - insert two tapers - insert multimode straight section - insert singlemode waveguides (including bends) before ''' import math from SiEPIC.extend import to_itype from pya import Point radius = to_itype(params_singlemode['radius'], dbu) taper_length = taper.find_pins()[0].center.distance( taper.find_pins()[1].center) min_length = 2 * radius + 2 * taper_length offset = radius wg_sm_segment_pts = [] wg_last = 0 waveguide_length = 0 for ii in range(1, len(dpts)): start_point = dpts[ii - 1] end_point = dpts[ii] distance_points = end_point.distance(start_point) if distance_points < min_length: # single mode segment, keep track if ii == 1: wg_sm_segment_pts.append(pts[ii - 1]) wg_sm_segment_pts.append(pts[ii]) if ii == len(pts) - 1: subcell = layout.create_cell("Waveguide_sm_%s" % ii) cell.insert(CellInstArray(subcell.cell_index(), Trans())) waveguide_length += layout_waveguide3(subcell, wg_sm_segment_pts, params_singlemode, debug=True) else: # insert two tapers and multimode waveguide angle = math.atan2( (end_point.y - start_point.y), (end_point.x - start_point.x)) / math.pi * 180 if ii == 1: wg_first = offset else: wg_first = 0 if ii == len(pts) - 1: wg_last = offset if round(angle) % 360 == 270.0: t = Trans(Trans.R270, start_point.x, start_point.y - offset + wg_first) t2 = Trans(Trans.R90, end_point.x, end_point.y + offset - wg_last) wg_start_pt = Point( start_point.x, start_point.y - offset - taper_length + wg_first) wg_end_pt = Point( end_point.x, end_point.y + offset + taper_length - wg_last) if round(angle) % 360 == 90.0: t = Trans(Trans.R90, start_point.x, start_point.y + offset - wg_first) t2 = Trans(Trans.R270, end_point.x, end_point.y - offset + wg_last) wg_start_pt = Point( start_point.x, start_point.y + offset + taper_length - wg_first) wg_end_pt = Point( end_point.x, end_point.y - offset - taper_length + wg_last) if round(angle) % 360 == 180.0: t = Trans(Trans.R180, start_point.x - offset + wg_first, start_point.y) t2 = Trans(Trans.R0, end_point.x + offset - wg_last, end_point.y) wg_start_pt = Point( start_point.x - offset - taper_length + wg_first, start_point.y) wg_end_pt = Point( end_point.x + offset + taper_length - wg_last, end_point.y) if round(angle) % 360 == 0.0: t = Trans(Trans.R0, start_point.x + offset - wg_first, start_point.y) t2 = Trans(Trans.R180, end_point.x - offset + wg_last, end_point.y) wg_start_pt = Point( start_point.x + offset + taper_length - wg_first, start_point.y) wg_end_pt = Point( end_point.x - offset - taper_length + wg_last, end_point.y) inst_taper = cell.insert(CellInstArray(taper.cell_index(), t)) inst_taper = cell.insert(CellInstArray(taper.cell_index(), t2)) waveguide_length += taper_length * 2 subcell = layout.create_cell("Waveguide_mm_%s" % ii) cell.insert(CellInstArray(subcell.cell_index(), Trans())) waveguide_length += layout_waveguide3(subcell, [wg_start_pt, wg_end_pt], params_multimode, debug=True) # compound segment if ii > 1: wg_sm_segment_pts.append(t.disp.to_p()) subcell = layout.create_cell("Waveguide_sm_%s" % ii) cell.insert(CellInstArray(subcell.cell_index(), Trans())) waveguide_length += layout_waveguide3(subcell, wg_sm_segment_pts, params_singlemode, debug=True) wg_sm_segment_pts = [t2.disp.to_p(), pts[ii]] else: wg_sm_segment_pts = [t2.disp.to_p(), pts[ii]] else: # primitive waveguide type waveguide_length = layout_waveguide3(cell, pts, params, debug=True) return waveguide_length
def layout_waveguide3(cell, pts, params, debug=True): if debug: print('SiEPIC.utils.layout.layout_waveguide3: ') layout = cell.layout() dbu = layout.dbu technology_name = layout.technology_name from SiEPIC.utils import get_technology_by_name TECHNOLOGY = get_technology_by_name(technology_name) from SiEPIC.extend import to_itype wg_width = to_itype(params['width'], dbu) radius = float(params['radius']) model = params['model'] cellName = 'Waveguide2' CML = params['CML'] if debug: print(' - waveguide params: %s' % (params)) if 'compound_waveguide' in params: print('error: this function cannot handle compound waveguides') raise Exception( 'error: this function cannot handle compound waveguides (%s)' % waveguide_type) # draw the waveguide waveguide_length = layout_waveguide2( TECHNOLOGY, layout, cell, [wg['layer'] for wg in params['component']], [wg['width'] for wg in params['component']], [wg['offset'] for wg in params['component']], pts, radius, params['adiabatic'], params['bezier']) # Draw the marking layers from SiEPIC.utils import angle_vector LayerPinRecN = layout.layer(TECHNOLOGY['PinRec']) make_pin(cell, 'opt1', pts[0], wg_width, LayerPinRecN, angle_vector(pts[0] - pts[1]) % 360) make_pin(cell, 'opt2', pts[-1], wg_width, LayerPinRecN, angle_vector(pts[-1] - pts[-2]) % 360) from pya import Trans, Text, Path, Point ''' t1 = Trans(angle_vector(pts[0]-pts[1])/90, False, pts[0]) cell.shapes(LayerPinRecN).insert(Path([Point(-10, 0), Point(10, 0)], wg_width).transformed(t1)) cell.shapes(LayerPinRecN).insert(Text("opt1", t1, 0.3/dbu, -1)) t = Trans(angle_vector(pts[-1]-pts[-2])/90, False, pts[-1]) cell.shapes(LayerPinRecN).insert(Path([Point(-10, 0), Point(10, 0)], wg_width).transformed(t)) cell.shapes(LayerPinRecN).insert(Text("opt2", t, 0.3/dbu, -1)) ''' LayerDevRecN = layout.layer(TECHNOLOGY['DevRec']) # Compact model information angle_vec = angle_vector(pts[0] - pts[1]) / 90 halign = 0 # left angle = 0 dpt = Point(0, 0) if angle_vec == 0: # horizontal halign = 2 # right angle = 0 dpt = Point(0, 0.2 * wg_width) if angle_vec == 2: # horizontal halign = 0 # left angle = 0 dpt = Point(0, 0.2 * wg_width) if angle_vec == 1: # vertical halign = 2 # right angle = 1 dpt = Point(0.2 * wg_width, 0) if angle_vec == -1: # vertical halign = 0 # left angle = 1 dpt = Point(0.2 * wg_width, 0) pt2 = pts[0] + dpt pt3 = pts[0] - dpt pt4 = pts[0] - 6 * dpt pt5 = pts[0] + 2 * dpt t = Trans(angle, False, pt3) text = Text('Lumerical_INTERCONNECT_library=Design kits/%s' % CML, t, 0.1 * wg_width, -1) text.halign = halign shape = cell.shapes(LayerDevRecN).insert(text) t = Trans(angle, False, pt2) text = Text('Component=%s' % model, t, 0.1 * wg_width, -1) text.halign = halign shape = cell.shapes(LayerDevRecN).insert(text) t = Trans(angle, False, pt5) text = Text('cellName=%s' % cellName, t, 0.1 * wg_width, -1) text.halign = halign shape = cell.shapes(LayerDevRecN).insert(text) t = Trans(angle, False, pts[0]) pts_txt = str([[round(p.to_dtype(dbu).x, 3), round(p.to_dtype(dbu).y, 3)] for p in pts]).replace(', ', ',') text = Text( 'Spice_param:wg_length=%.9f wg_width=%.3g points="%s" radius=%.3g' % (waveguide_length * 1e-6, wg_width * 1e-9, pts_txt, radius * 1e-6), t, 0.1 * wg_width, -1) text.halign = halign shape = cell.shapes(LayerDevRecN).insert(text) t = Trans(angle, False, pt4) text = Text('Length=%.3f (microns)' % (waveguide_length), t, 0.5 * wg_width, -1) text.halign = halign shape = cell.shapes(LayerDevRecN).insert(text) return waveguide_length
def make_pin(cell, name, center, w, layer, direction, debug=False): ''' Makes a pin that SiEPIC-Tools will recognize cell: which cell to draw it in name: text label for the pin center: location, int [x,y] w: pin width layer: layout.layer() type direction = 0: right 90: up 180: left 270: down Units: intput can be float for microns, or int for nm ''' from SiEPIC.extend import to_itype from pya import Point, DPoint import numpy dbu = cell.layout().dbu if type(w) == type(float()): w = to_itype(w, dbu) if debug: print('SiEPIC.utils.layout.make_pin: w converted to %s' % w) else: if debug: print('SiEPIC.utils.layout.make_pin: w %s' % w) # print(type(center[0])) if type(center) == type(Point()) or type(center) == type(DPoint()): center = [center.x, center.y] if type(center[0]) == type(float()) or type(center[0]) == type( numpy.float64()): center[0] = to_itype(center[0], dbu) center[1] = to_itype(center[1], dbu) if debug: print('SiEPIC.utils.layout.make_pin: center converted to %s' % (center)) else: if debug: print('SiEPIC.utils.layout.make_pin: center %s' % (center)) from SiEPIC._globals import PIN_LENGTH as pin_length direction = direction % 360 if direction not in [0, 90, 180, 270]: raise ('error in make_pin: direction must be one of [0, 90, 180, 270]') # text label t = pya.Trans(pya.Trans.R0, center[0], center[1]) text = pya.Text(name, t) shape = cell.shapes(layer).insert(text) shape.text_dsize = float(w * dbu / 2) shape.text_valign = 1 if direction == 0: p1 = pya.Point(center[0] - pin_length / 2, center[1]) p2 = pya.Point(center[0] + pin_length / 2, center[1]) shape.text_halign = 2 if direction == 90: p1 = pya.Point(center[0], center[1] - pin_length / 2) p2 = pya.Point(center[0], center[1] + pin_length / 2) shape.text_halign = 2 shape.text_rot = 1 if direction == 180: p1 = pya.Point(center[0] + pin_length / 2, center[1]) p2 = pya.Point(center[0] - pin_length / 2, center[1]) shape.text_halign = 3 if direction == 270: p1 = pya.Point(center[0], center[1] + pin_length / 2) p2 = pya.Point(center[0], center[1] - pin_length / 2) shape.text_halign = 3 shape.text_rot = 1 pin = pya.Path([p1, p2], w) cell.shapes(layer).insert(pin)
fpLayerN = cell_top.layout().layer(lib[layer_floorplan]) TextLayerN = cell_top.layout().layer(lib[layer_text]) # Draw the floor plan ly_height = 350 ly_width = 600 cell_top.shapes(fpLayerN).insert(Box(0, 0, ly_width / dbu, ly_height / dbu)) #%%Import Grating couplers GC_imported = ly.create_cell("Grating_Coupler_13deg_TE_1550_Oxide", pdk).cell_index() GC_pitch = 127 t = Trans(Trans.R0, 0.5 * ly_width / dbu, (0.5 * ly_height - GC_pitch / 2) / dbu) cell_top.insert( CellInstArray(GC_imported, t, DPoint(0, GC_pitch).to_itype(dbu), Point(0, 0), 2, 1)) #%%draw waveguide connecting grating couplers path = [[0.5 * ly_width, 0.5 * ly_height - GC_pitch / 2]] # start point path.append([0.5 * ly_width + 50, 0.5 * ly_height - GC_pitch / 2]) path.append([0.5 * ly_width + 50, 0.5 * ly_height + GC_pitch / 2]) path.append([0.5 * ly_width, 0.5 * ly_height + GC_pitch / 2]) # end point path = DPath([DPoint(each[0], each[1]) for each in path], 0.5) path = path.to_itype(dbu) pts = path.get_points() widths = [0.5] layers = ['Waveguide'] offset = [0] radius = 15