From 609d0abbbcd11c91d7e71a9593bb45770b1449b1 Mon Sep 17 00:00:00 2001 From: Pietro Campana <92092559+PietroCampana@users.noreply.github.com> Date: Mon, 10 Jun 2024 10:51:49 +0200 Subject: [PATCH] Fix "Reload Libraries macro issues" (#95) Reload Libraries macro issues resolved * Non-KQC elements placed on the layout no longer cause errors * Better error handling, for example if there are compilation errors in the KQC code --- .../python/kqcircuits/util/layout_to_code.py | 17 ++++++++++------- .../python/kqcircuits/util/library_helper.py | 4 +++- .../python/scripts/macros/0system/0reload.lym | 11 +++++++++-- 3 files changed, 22 insertions(+), 10 deletions(-) diff --git a/klayout_package/python/kqcircuits/util/layout_to_code.py b/klayout_package/python/kqcircuits/util/layout_to_code.py index 40026e670..f446cb5de 100644 --- a/klayout_package/python/kqcircuits/util/layout_to_code.py +++ b/klayout_package/python/kqcircuits/util/layout_to_code.py @@ -358,31 +358,34 @@ def get_node_params(node: Node): def extract_pcell_data_from_views(): - """Remove all PCells and return their data. + """Iterate over all KQCircuits PCells and return their data and instances. - Returns: A list of lists. Each element corresponds to a view in KLayout and it is a list of - ``(type, location, parameters)`` tuples. These tuples completely describe the type, position and - parameters of a single PCell in the "Top Cell" of this view. + Returns: a tuple (views, instances) where + views: a list of lists. Each element corresponds to a view in KLayout and it is a list of + ``(type, location, parameters)`` tuples. These tuples completely describe the type, position + and parameters of a single PCell in the "Top Cell" of this view. + instances: flattened list of all instances of KQCircuits PCells found. """ views = [] + instances = [] main_window = pya.Application.instance().main_window() for vid in range(main_window.views()): top_cell = main_window.view(vid).active_cellview().cell pcells = [] for inst in top_cell.each_inst(): pc = inst.pcell_declaration() - if pc: + if isinstance(pc, Element): + instances.append(inst) params = inst.pcell_parameters_by_name() def_params = pc.__class__.get_schema() for k, v in def_params.items(): if params[k] == v.default: del params[k] pcells.append((pc.__class__, inst.dtrans, params)) - inst.delete() views.append(pcells) - return views + return views, instances def restore_pcells_to_views(views): diff --git a/klayout_package/python/kqcircuits/util/library_helper.py b/klayout_package/python/kqcircuits/util/library_helper.py index b8f17fddb..0f6f9180d 100644 --- a/klayout_package/python/kqcircuits/util/library_helper.py +++ b/klayout_package/python/kqcircuits/util/library_helper.py @@ -84,6 +84,8 @@ def load_libraries(flush=False, path=""): Returns: A dictionary of libraries that have been loaded, keys are library names and values are libraries. """ + # Try reloading all pcells before deleting libraries, otherwise classes are lost in case of errors + all_pcell_classes = _get_all_pcell_classes(flush, path) if flush: delete_all_libraries() @@ -95,7 +97,7 @@ def load_libraries(flush=False, path=""): if lib_path == path: return {key: value[0] for key, value in _kqc_libraries.items()} - for cls in _get_all_pcell_classes(flush, path): + for cls in all_pcell_classes: library_name = cls.LIBRARY_NAME library_path = cls.LIBRARY_PATH diff --git a/klayout_package/python/scripts/macros/0system/0reload.lym b/klayout_package/python/scripts/macros/0system/0reload.lym index f44a4db9d..0c35d1f7c 100644 --- a/klayout_package/python/scripts/macros/0system/0reload.lym +++ b/klayout_package/python/scripts/macros/0system/0reload.lym @@ -40,8 +40,15 @@ Note that this does not reload the ``defaults`` file. from kqcircuits.util.library_helper import load_libraries from kqcircuits.util.layout_to_code import extract_pcell_data_from_views, restore_pcells_to_views -views = extract_pcell_data_from_views() -load_libraries(flush=True) +views, instances = extract_pcell_data_from_views() +for inst in instances: + inst.delete() +try: + load_libraries(flush=True) +except Exception as e: + restore_pcells_to_views(views) + raise RuntimeError("Failed to reload KQCircuits libraries and redraw cells." + + f"\nThe following exception was raised: \n{type(e).__name__}: {e}") restore_pcells_to_views(views)