def run_script(self, filename, p1=None, p2=None): """ Run .pyxs script filename : str path to the .pyxs script """ view = Application.instance().main_window().current_view() if not view: raise UserWarning("No view open for running the pyxs script") if p1 is None or p2 is None: app = Application.instance() scr_view = app.main_window().current_view() # type: LayoutView scr_view_idx = app.main_window().current_view_index if not scr_view: MessageBox.critical( "Error", "No view open for creating the cross-" "section from", MessageBox.b_ok(), ) return False rulers = [] for a in scr_view.each_annotation(): rulers.append(a) if len(rulers) == 0: MessageBox.critical( "Error", "No ruler present for the cross " "section line", MessageBox.b_ok(), ) return None p1_arr, p2_arr, ruler_text_arr = [], [], [] for ruler in rulers: p1_arr.append(ruler.p1) p2_arr.append(ruler.p2) ruler_text_arr.append(ruler.text().split('.')[0]) else: p1_arr, p2_arr, ruler_text_arr = [p1], [p2], [''] scr_view_idx = None target_views = [] for p1_, p2_, text_ in zip(p1_arr, p2_arr, ruler_text_arr): if scr_view_idx: # return to the original view to run it again app.main_window().select_view(scr_view_idx) view = XSectionGenerator(filename).run(p1_, p2_, text_) target_views.append(view) return target_views
def run(self, p1, p2, ruler_text=None): """ Parameters ---------- ruler_text : str identifier to be used to name a new cross-section cell Returns ------- LayoutView """ self._target_view = None self._target_cell_name = "PYXS: " + ruler_text if ruler_text else "XSECTION" self._cell_file_name = "PYXS_" + ruler_text if ruler_text else "XSECTION" self._setup(p1, p2) self._update_basic_regions() text = None try: with open(self._file_name, 'r') as file: text = file.read() except Exception as e: MessageBox.critical("Error", "Error reading file {}. \n\nError: {}" .format(self._file_name, e), MessageBox.b_ok()) return None if text is None: MessageBox.critical("Error", "Error reading file {}." .format(self._file_name), MessageBox.b_ok()) return None # prepare variables to be visible in the script locals_ = dir(self) locals_dict = {} for attr in locals_: if attr[0] != '_': locals_dict.update({attr: getattr(self, attr)}) try: exec(text, locals_dict) except Exception as e: # For development # print(e.__traceback__.) # print(dir(e)) MessageBox.critical("Error", str(e), MessageBox.b_ok()) # pass return None Application.instance().main_window().cm_lv_add_missing() # @@@ self._finalize_view() return self._target_view
def run(self): """ The basic generation method """ if not self._setup(): return None self._update_basic_regions() text = None with open(self._file_path) as file: text = file.read() if not text: MessageBox.critical("Error", "Error reading file #{self._file_path}", MessageBox.b_ok()) return None # prepare variables to be visible in the script locals_ = dir(self) locals_dict = {} for attr in locals_: if attr[0] != '_': locals_dict.update({attr: getattr(self, attr)}) try: exec(text, locals_dict) except Exception as e: # For development # print(e.__traceback__.) # print(dir(e)) MessageBox.critical("Error", str(e), MessageBox.b_ok()) # pass return None Application.instance().main_window().cm_lv_add_missing() # @@@ if self._lyp_file: self._target_view.load_layer_props(self._lyp_file) self._target_view.zoom_fit() self._target_layout.write(self._target_gds_file_name) info(' len(bulk.data) = {}'.format(len(self._bulk.data))) self._tech_str = '# This file was generated automatically by pyxs.\n\n'\ + layer_to_tech_str(255, self._bulk.data[0], 'Substrate') + self._tech_str with open(self._target_tech_file_name, 'w') as f: f.write(self._tech_str) return None
def _on_triggered_callback(): """ Load pyxs script menu action. Load new .pyxs file and run it. """ view = Application.instance().main_window().current_view() if not view: MessageBox.critical( "Error", "No view open for creating the cross-" "section from", MessageBox.b_ok(), ) return None filename = FileDialog.get_open_file_name( "Select cross-section script", "", "XSection Scripts (*.pyxs);;All Files (*)", ) # run the script and save it if filename.has_value(): self.run_script(filename.value()) self.make_mru(filename.value())
def _setup(self, p1, p2): """ Parameters ---------- p1 : Point first point of the ruler p2 : Point second point of the ruler """ # locate the layout app = Application.instance() view = app.main_window().current_view() # LayoutView if not view: MessageBox.critical( "Error", "No view open for creating the cross-" "section from", MessageBox.b_ok(), ) return False cv = view.cellview(view.active_cellview_index()) # CellView if not cv.is_valid(): MessageBox.critical("Error", "The selected layout is not valid", MessageBox.b_ok()) return False self._cv = cv # CellView self._layout = cv.layout() # Layout self._dbu = self._layout.dbu self._cell = cv.cell_index # int # get the start and end points in database units and micron p1_dbu = Point.from_dpoint(p1 * (1.0 / self._dbu)) p2_dbu = Point.from_dpoint(p2 * (1.0 / self._dbu)) self._line_dbu = Edge(p1_dbu, p2_dbu) # Edge describing the ruler # initialize height and depth self._extend = int_floor(2.0 / self._dbu + 0.5) # 2 um in dbu self._delta = 10 self._height = int_floor(2.0 / self._dbu + 0.5) # 2 um in dbu self._depth = int_floor(2.0 / self._dbu + 0.5) # 2 um in dbu self._below = int_floor(2.0 / self._dbu + 0.5) # 2 um in dbu info(' XSG._dbu is: {}'.format(self._dbu)) info(' XSG._extend is: {}'.format(self._extend)) info(' XSG._delta is: {}'.format(self._delta)) info(' XSG._height is: {}'.format(self._height)) info(' XSG._depth is: {}'.format(self._depth)) info(' XSG._below is: {}'.format(self._below)) return True
def run_script(self, filename): """ Run .pyxs script filename : str path to the .pyxs script """ view = Application.instance().main_window().current_view() if not view: raise UserWarning("No view open for running the pyxs script") # cv = view.cellview(view.active_cellview_index()) XSectionGenerator(filename).run()
def _on_triggered_callback(): """ Load pyxs script menu action. Load new .pyxs file and run it. """ view = Application.instance().main_window().current_view() if not view: raise UserWarning("No view open for running the pyxs script") filename = FileDialog.get_open_file_name( "Select cross-section script", "", "XSection Scripts (*.pyxs);;All Files (*)") # run the script and save it if filename.has_value(): self.run_script(filename.value()) self.make_mru(filename.value())
def _create_new_layout(self, cell_name_extension=None): if cell_name_extension: cell_name = '{} ({})'.format(self._target_cell_name, cell_name_extension) else: cell_name = self._target_cell_name # create a new layout for the output app = Application.instance() main_window = app.main_window() cv = main_window.create_layout(1) # type: CellView cell = cv.layout().add_cell(cell_name) # type: Cell self._target_view = main_window.current_view() # type: LayoutView self._target_view.select_cell(cell, 0) self._target_layout = cv.layout() # type: Layout self._target_layout.dbu = self._dbu self._target_cell = cell # type: cell self._is_target_layout_created = True
def __init__(self): app = Application.instance() mw = app.main_window() def _on_triggered_callback(): """ Load pyxs script menu action. Load new .pyxs file and run it. """ view = Application.instance().main_window().current_view() if not view: raise UserWarning("No view open for running the pyxs script") filename = FileDialog.get_open_file_name( "Select cross-section script", "", "XSection Scripts (*.pyxs);;All Files (*)") # run the script and save it if filename.has_value(): self.run_script(filename.value()) self.make_mru(filename.value()) def _XSectionMRUAction_callback(script): """ *.pyxs menu action Load selected .pyxs file and run it. Parameters ---------- script : str """ self.run_script(script) self.make_mru(script) # Create pyxs submenu in Tools menu = mw.menu() if not menu.is_valid("tools_menu.pyxs3D_script_group"): menu.insert_separator("tools_menu.end", "pyxs3D_script_group") menu.insert_menu("tools_menu.end", "pyxs3D_script_submenu", "pyxs3D") # Create Load XSectionpy Script item in XSection (py) global pyxs_script_load_menuhandler pyxs_script_load_menuhandler = MenuHandler("Load pyxs script", _on_triggered_callback) menu.insert_item("tools_menu.pyxs3D_script_submenu.end", "pyxs3D_script_load", pyxs_script_load_menuhandler) menu.insert_separator("tools_menu.pyxs3D_script_submenu.end.end", "pyxs3D_script_mru_group") # Create list of existing pyxs scripts item in pyxs self._mru_actions = [] for i in range(N_PYXS_SCRIPTS_MAX): a = XSectionMRUAction(_XSectionMRUAction_callback) self._mru_actions.append(a) menu.insert_item("tools_menu.pyxs3D_script_submenu.end", "pyxs3D_script_mru{}".format(i), a) a.script = None # try to save the MRU list to $HOME/.klayout-processing-mru i = 0 home = os.getenv("HOME", None) or os.getenv("HOMESHARE", None) global pyxs_scripts if pyxs_scripts: for i, script in enumerate(pyxs_scripts.split(":")): if i < len(self._mru_actions): self._mru_actions[i].script = script elif home: fn = home + "\\.klayout-pyxs-scripts" try: with open(fn, "r") as file: for line in file.readlines(): match = re.match('<mru>(.*)<\/mru>', line) if match: if i < len(self._mru_actions): self._mru_actions[i].script = match.group(1) i += 1 except: pass
def _setup(self): # locate the layout app = Application.instance() view = app.main_window().current_view() # LayoutView if not view: MessageBox.critical( "Error", "No view open for creating the cross " "section from", MessageBox.b_ok()) return False # locate the (single) ruler rulers = [] n_rulers = 0 for a in view.each_annotation(): # Use only rulers with "plain line" style # print(a.style) # print(Annotation.StyleLine) # if a.style == Annotation.StyleLine: rulers.append(a) n_rulers += 1 # if n_rulers == 0 or n_rulers >= 2: # MessageBox.info("No rulers", # "Number of rulers is not equal to one. " # "Will be exporting the whole layout", # pya.MessageBox.b_ok()) # if n_rulers == 1: # MessageBox.info( # "Box export", "One ruler is present for the cross " # "section line. Will be exporting only shapes in the box", # pya.MessageBox.b_ok()) cv = view.cellview(view.active_cellview_index()) # CellView if not cv.is_valid(): MessageBox.critical("Error", "The selected layout is not valid", MessageBox.b_ok()) return False self._cv = cv # CellView self._layout = cv.layout() # Layout self._dbu = self._layout.dbu self._cell = cv.cell_index # int if n_rulers == 1: # get the start and end points in database units and micron p1_dbu = Point.from_dpoint(rulers[0].p1 * (1.0 / self._dbu)) p2_dbu = Point.from_dpoint(rulers[0].p2 * (1.0 / self._dbu)) self._box_dbu = Box(p1_dbu, p2_dbu) # box describing the ruler else: # TODO: choose current cell, not top cell top_cell = self._layout.top_cell() p1_dbu = (top_cell.bbox().p1 * (1.0 / self._dbu)).dup() p1_dbu = top_cell.bbox().p1.dup() p2_dbu = (top_cell.bbox().p2 * (1.0 / self._dbu)).dup() p2_dbu = top_cell.bbox().p2.dup() self._box_dbu = Box(p1_dbu, p2_dbu) # box describing the top cell info('XSG._box_dbu to be used is: {}'.format(self._box_dbu)) # create a new layout for the output cv = app.main_window().create_layout(1) cell = cv.layout().add_cell("XSECTION") self._target_view = app.main_window().current_view() self._target_view.select_cell(cell, 0) self._target_layout = cv.layout() self._target_layout.dbu = self._dbu self._target_cell = cell # initialize height and depth self._extend = int_floor(2.0 / self._dbu + 0.5) # 2 um in dbu self._delta = 10 self._height = int_floor(2.0 / self._dbu + 0.5) # 2 um in dbu self._depth = int_floor(2.0 / self._dbu + 0.5) # 2 um in dbu self._below = int_floor(2.0 / self._dbu + 0.5) # 2 um in dbu info(' XSG._dbu is: {}'.format(self._dbu)) info(' XSG._extend is: {}'.format(self._extend)) info(' XSG._delta is: {}'.format(self._delta)) info(' XSG._height is: {}'.format(self._height)) info(' XSG._depth is: {}'.format(self._depth)) info(' XSG._below is: {}'.format(self._below)) return True
def __init__(self, menu_name='pyxs'): self._menu_name = menu_name app = Application.instance() mw = app.main_window() if mw is None: print('none') return def _on_triggered_callback(): """ Load pyxs script menu action. Load new .pyxs file and run it. """ view = Application.instance().main_window().current_view() if not view: MessageBox.critical( "Error", "No view open for creating the cross-" "section from", MessageBox.b_ok(), ) return None filename = FileDialog.get_open_file_name( "Select cross-section script", "", "XSection Scripts (*.pyxs);;All Files (*)", ) # run the script and save it if filename.has_value(): self.run_script(filename.value()) self.make_mru(filename.value()) def _XSectionMRUAction_callback(script): """ *.pyxs menu action Load selected .pyxs file and run it. Parameters ---------- script : str """ self.run_script(script) self.make_mru(script) # Create pyxs submenu in Tools menu = mw.menu() if not menu.is_valid("tools_menu.{}_script_group".format( self._menu_name)): menu.insert_separator("tools_menu.end", "{}_script_group".format(self._menu_name)) menu.insert_menu( "tools_menu.end", "{}_script_submenu".format(self._menu_name), self._menu_name, ) # Create Load XSection.py Script item in XSection (py) # global pyxs_script_load_menuhandler self.pyxs_script_load_menuhandler = MenuHandler( "Load pyxs script", _on_triggered_callback) menu.insert_item( "tools_menu.{}_script_submenu.end".format(self._menu_name), "{}_script_load".format(self._menu_name), self.pyxs_script_load_menuhandler, ) menu.insert_separator( "tools_menu.{}_script_submenu.end.end".format(self._menu_name), "{}_script_mru_group".format(self._menu_name), ) # Create list of existing pyxs scripts item in pyxs self._mru_actions = [] for i in range(N_PYXS_SCRIPTS_MAX): a = XSectionMRUAction(_XSectionMRUAction_callback) self._mru_actions.append(a) menu.insert_item( "tools_menu.{}_script_submenu.end".format(self._menu_name), "{}_script_mru{}".format(self._menu_name, i), a, ) a.script = None # try to save the MRU list to $HOME/.klayout-pyxs-scripts i = 0 home = os.getenv("HOME", None) or os.getenv("HOMESHARE", None) global pyxs_scripts if pyxs_scripts: for i, script in enumerate(pyxs_scripts.split(":")): if i < len(self._mru_actions): self._mru_actions[i].script = script elif home: fn = os.path.join(home, '.klayout-pyxs-scripts') try: with open(fn, "r") as file: for line in file.readlines(): match = re.match('<mru>(.*)<\/mru>', line) if match: if i < len(self._mru_actions): self._mru_actions[i].script = match.group(1) i += 1 except: pass