def select_instances(cell=None): lv = pya.Application.instance().main_window().current_view() if lv == None: raise Exception("No view selected") if cell is None: ly = lv.active_cellview().layout() if ly == None: raise Exception("No active layout") cell = lv.active_cellview().cell if cell == None: raise Exception("No active cell") else: ly = cell.layout() selection = lv.object_selection if selection == []: for instance in cell.each_inst(): selection.append(pya.ObjectInstPath()) selection[-1].top = cell.cell_index() selection[-1].append_path(pya.InstElement.new(instance)) lv.object_selection = selection else: lv.object_selection = [o for o in selection if o.is_cell_inst()] return lv.object_selection
def select_paths_m(layers, cell=None, verbose=None): lv = pya.Application.instance().main_window().current_view() if lv == None: raise Exception("No view selected") if cell is None: ly = lv.active_cellview().layout() if ly == None: raise Exception("No active layout") cell = lv.active_cellview().cell if cell == None: raise Exception("No active cell") else: ly = cell.layout() selection = lv.object_selection if verbose: print("SiEPIC.utils.select_paths: selection, before: %s" % lv.object_selection) if selection == []: for layer, layer_str_name in layers: # run through all the layers inputted into the function (allows for multiple path layer selections) itr = cell.begin_shapes_rec(ly.layer(layer)) while not (itr.at_end()): if verbose: print("SiEPIC.utils.select_paths: itr: %s" % itr) if itr.shape().is_path() and not itr.cell().pcell_parameters( ): # must be a path and not a pcell print('Name: ' + str(itr.cell().pcell_parameters())) if verbose: print("SiEPIC.utils.select_paths: path: %s" % itr.shape()) selection.append(pya.ObjectInstPath()) selection[-1].layer = ly.layer(layer) selection[-1].shape = itr.shape() selection[-1].top = cell.cell_index() selection[-1].cv_index = 0 itr.next() #for o in selection: # set the LayerName property if the object (path) does not already have a LayerName # if not o.shape.property('LayerName'): # check for LayerName property # o.shape.set_property('LayerName', layer_str_name) # add LayerName propery if not present lv.object_selection = selection # set the return item equal to selection after all loops are finished else: lv.object_selection = [ o for o in selection if (not o.is_cell_inst() and not o.shape.cell.pcell_parameters()) and o.shape.is_path() ] # must be a path and not a pcell if verbose: print("SiEPIC.utils.select_paths: selection, after: %s" % lv.object_selection) return lv.object_selection
def select_paths(layer, cell=None, verbose=None): if verbose: print("SiEPIC.utils.select_paths: layer: %s" % layer) lv = pya.Application.instance().main_window().current_view() if lv == None: raise Exception("No view selected") if cell is None: ly = lv.active_cellview().layout() if ly == None: raise Exception("No active layout") cell = lv.active_cellview().cell if cell == None: raise Exception("No active cell") else: ly = cell.layout() selection = lv.object_selection if verbose: print("SiEPIC.utils.select_paths: selection, before: %s" % lv.object_selection) if selection == []: itr = cell.begin_shapes_rec(ly.layer(layer)) itr_count = 0 while not (itr.at_end()): # if verbose: # print("SiEPIC.utils.select_paths: itr: %s" % itr) itr_count += 1 if itr.shape().is_path(): if verbose: print("SiEPIC.utils.select_paths: path: %s" % itr.shape()) selection.append(pya.ObjectInstPath()) selection[-1].layer = ly.layer(layer) selection[-1].shape = itr.shape() selection[-1].top = cell.cell_index() selection[-1].cv_index = 0 itr.next() if verbose: print("SiEPIC.utils.select_paths: # shapes founded: %s" % itr_count) lv.object_selection = selection else: lv.object_selection = [ o for o in selection if (not o.is_cell_inst()) and o.shape.is_path() ] if verbose: print("SiEPIC.utils.select_paths: selection, after: %s" % lv.object_selection) return lv.object_selection
def wireguide_to_path(cell=None): from . import _globals from .utils import get_layout_variables if cell is None: TECHNOLOGY, lv, ly, cell = get_layout_variables() else: TECHNOLOGY, lv, _, _ = get_layout_variables() ly = cell.layout() lv.transaction("wireguide to path") # record objects to delete: to_delete = [] wireguides = select_wireguides(cell) selection = [] for obj in wireguides: # path from wireguide guiding shape wireguide = obj.inst() layer_list = wireguide.cell.pcell_parameter( 'layers' ) # get the list of layers in the wireguide pcell (should only be one) original_layer = ly.layer( TECHNOLOGY[layer_list[0]] ) # convert layer to understandable type for future functions from ._globals import KLAYOUT_VERSION if KLAYOUT_VERSION > 24: path = wireguide.cell.pcell_parameters_by_name()['path'] else: # wireguide path and width from Wireguide PCell path1 = wireguide.cell.pcell_parameters_by_name()['path'] path = pya.Path() path.width = wireguide.cell.pcell_parameters_by_name( )['width'] / TECHNOLOGY['dbu'] pts = [] for pt in [pt1 for pt1 in (path1).each_point()]: if type(pt) == pya.Point: # for instantiated PCell pts.append(pya.Point()) else: # for wireguide from path pts.append(pya.Point().from_dpoint( pt * (1 / TECHNOLOGY['dbu']))) path.points = pts selection.append(pya.ObjectInstPath()) selection[-1].layer = original_layer # DPath.transformed requires DTrans. wireguide.trans is a Trans object if KLAYOUT_VERSION > 24: selection[-1].shape = cell.shapes(original_layer).insert( path.transformed(wireguide.trans.to_dtype(TECHNOLOGY['dbu']))) else: selection[-1].shape = cell.shapes(original_layer).insert( path.transformed( pya.Trans(wireguide.trans.disp.x, wireguide.trans.disp.y))) selection[-1].top = obj.top selection[-1].cv_index = obj.cv_index # deleting the instance was ok, but would leave the cell which ends up as # an uninstantiated top cell to_delete.append(obj.inst()) # deleting instance or cell should be done outside of the for loop, # otherwise each deletion changes the instance pointers in KLayout's # internal structure [t.delete() for t in to_delete] # Clear the layout view selection, since we deleted some objects (but # others may still be selected): lv.clear_object_selection() # Select the newly added objects lv.object_selection = selection # Record a transaction, to enable "undo" lv.commit()
def path_to_wireguide(cell=None, lv_commit=True, verbose=False, select_wireguides=False): from . import _globals TECHNOLOGY, lv, ly, top_cell = get_layout_variables_m() if not cell: cell = top_cell if verbose: print("SiEPIC.scripts path_to_wireguide()") if lv_commit: lv.transaction("Path to Wireguide") layers_to_select = list() for key in TECHNOLOGY.keys(): if 'Wireguide' in key: layers_to_select.append((TECHNOLOGY[key], key)) print(key) selected_paths = select_paths_m( layers_to_select, cell, verbose=verbose) # find all paths on the selected layers if verbose: print("SiEPIC.scripts path_to_wireguide(): selected_paths = %s" % selected_paths) selection = [] warning = pya.QMessageBox() warning.setStandardButtons(pya.QMessageBox.Yes | pya.QMessageBox.Cancel) warning.setDefaultButton(pya.QMessageBox.Yes) params = { 'radius': 0, 'width': 2, 'adiabatic': False, 'bezier': '0', 'offset': 0 } # set parameters if verbose: print("SiEPIC.scripts path_to_wireguide(): params = %s" % params) for obj in selected_paths: path = obj.shape.path dbu = obj.layout().dbu # get the database units params[ 'width'] = path.width * dbu # adjust the width and save for wireguide creation if obj.shape.property( 'LayerName' ): # check if obj has LayerName (for no mouse selections) input_layer_name = obj.shape.property( 'LayerName') # save layer name for wireguide creation else: # find the name of the layer if not specified (for mouse selections) lv = pya.Application.instance().main_window().current_view() ly = lv.active_cellview().layout() dbu = ly.dbu lp_found = None iter = lv.begin_layers() # loop through all layers while not iter.at_end(): lp = iter.current() if lp.cellview() == obj.cv_index and lp.layer_index( ) == obj.layer: # find specified layer within the layer loop lp_found = lp # save layer properties iter.next() input_layer_name = lp_found.name # save layer name for wireguide creation path.unique_points() if not path.is_manhattan_endsegments(): warning.setText( "Warning: Wireguide segments (first, last) are not Manhattan (vertical, horizontal)." ) warning.setInformativeText("Do you want to Proceed?") if (pya.QMessageBox_StandardButton( warning.exec_()) == pya.QMessageBox.Cancel): return if not path.is_manhattan(): warning.setText( "Error: Wireguide segments are not Manhattan (vertical, horizontal). This is not supported in SiEPIC-Tools." ) warning.setInformativeText("Do you want to Proceed?") if (pya.QMessageBox_StandardButton( warning.exec_()) == pya.QMessageBox.Cancel): return if not path.radius_check(params['radius'] / TECHNOLOGY['dbu']): warning.setText( "Warning: One of the wireguide segments has insufficient length to accommodate the desired bend radius." ) warning.setInformativeText("Do you want to Proceed?") if (pya.QMessageBox_StandardButton( warning.exec_()) == pya.QMessageBox.Cancel): return path.snap_m(cell.find_pins()) Dpath = path.to_dtype(TECHNOLOGY['dbu']) width_devrec = params[ 'width'] + _globals.WG_DEVREC_SPACE * 2 # get DevRec width based on the wireguide width found earlier try: pcell = ly.create_cell( "Wireguide", TECHNOLOGY['technology_name'], { "path": Dpath, # input parameters "radius": params['radius'], "width": params['width'], "adiab": params['adiabatic'], "bezier": params['bezier'], "layers": [input_layer_name] + [ 'DevRec' ], # set the layer as the same as the path that the wireguide came from (along with DevRec) "widths": [params['width']] + [width_devrec], "offsets": [params['offset']] + [0] }) print( "SiEPIC.metal_menu_helper.path_to_wireguide(): Wireguide from %s, %s" % (TECHNOLOGY['technology_name'], pcell)) except: pass if not pcell: try: pcell = ly.create_cell( "Wireguide", "SiEPIC General", { "path": Dpath, # input parameters "radius": params['radius'], "width": params['width'], "adiab": params['adiabatic'], "bezier": params['bezier'], "layers": [input_layer_name] + [ 'DevRec' ], # set the layer as the same as the path that the wireguide came from (along with DevRec) "widths": [params['width']] + [width_devrec], "offsets": [params['offset']] + [0] }) print( "SiEPIC.metal_menu_helper.path_to_wireguide(): Wireguide from SiEPIC General, %s" % pcell) except: pass if not pcell: raise Exception( "'Wireguide' in 'SiEPIC General' library is not available. Check that the library was loaded successfully." ) selection.append(pya.ObjectInstPath()) selection[-1].top = obj.top selection[-1].append_path( pya.InstElement.new( cell.insert( pya.CellInstArray(pcell.cell_index(), pya.Trans(pya.Trans.R0, 0, 0))))) obj.shape.delete() lv.clear_object_selection() if select_wireguides: lv.object_selection = selection if lv_commit: lv.commit()