From 466fd04b009aec784c10f86c58d8e3e8a0ae2bc3 Mon Sep 17 00:00:00 2001 From: PietroCampana Date: Tue, 4 Jun 2024 11:31:42 +0200 Subject: [PATCH 1/5] minimal solution --- klayout_package/python/kqcircuits/util/layout_to_code.py | 5 +++-- klayout_package/python/scripts/macros/0system/0reload.lym | 8 ++++++-- 2 files changed, 9 insertions(+), 4 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..46e10274e 100644 --- a/klayout_package/python/kqcircuits/util/layout_to_code.py +++ b/klayout_package/python/kqcircuits/util/layout_to_code.py @@ -16,6 +16,7 @@ # Please see our contribution agreements for individuals (meetiqm.com/iqm-individual-contributor-license-agreement) # and organizations (meetiqm.com/iqm-organization-contributor-license-agreement). +from math import isinf from sys import float_info import textwrap @@ -358,7 +359,7 @@ def get_node_params(node: Node): def extract_pcell_data_from_views(): - """Remove all PCells and return their data. + """Remove all KQCircuits PCells and return their data. 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 @@ -372,7 +373,7 @@ def extract_pcell_data_from_views(): pcells = [] for inst in top_cell.each_inst(): pc = inst.pcell_declaration() - if pc: + if isinstance(pc, Element): params = inst.pcell_parameters_by_name() def_params = pc.__class__.get_schema() for k, v in def_params.items(): diff --git a/klayout_package/python/scripts/macros/0system/0reload.lym b/klayout_package/python/scripts/macros/0system/0reload.lym index f44a4db9d..079ab784a 100644 --- a/klayout_package/python/scripts/macros/0system/0reload.lym +++ b/klayout_package/python/scripts/macros/0system/0reload.lym @@ -41,7 +41,11 @@ 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) -restore_pcells_to_views(views) +try: + load_libraries(flush=True) + restore_pcells_to_views(views) +except: + restore_pcells_to_views(views) + raise RuntimeError("Failed to reload all KQCircuits libraries, restoring current view.") From 254bd8bc6bca19a900e1769db787d4b6ecdf4aed Mon Sep 17 00:00:00 2001 From: PietroCampana Date: Tue, 4 Jun 2024 11:53:39 +0200 Subject: [PATCH 2/5] remove unneeded import --- klayout_package/python/kqcircuits/util/layout_to_code.py | 1 - 1 file changed, 1 deletion(-) diff --git a/klayout_package/python/kqcircuits/util/layout_to_code.py b/klayout_package/python/kqcircuits/util/layout_to_code.py index 46e10274e..8e9862df5 100644 --- a/klayout_package/python/kqcircuits/util/layout_to_code.py +++ b/klayout_package/python/kqcircuits/util/layout_to_code.py @@ -16,7 +16,6 @@ # Please see our contribution agreements for individuals (meetiqm.com/iqm-individual-contributor-license-agreement) # and organizations (meetiqm.com/iqm-organization-contributor-license-agreement). -from math import isinf from sys import float_info import textwrap From f40aa853f58621e51e5bc279d52de175956c014e Mon Sep 17 00:00:00 2001 From: PietroCampana Date: Tue, 4 Jun 2024 13:01:11 +0200 Subject: [PATCH 3/5] separate collection of pcells data and instances deletion --- .../python/kqcircuits/util/layout_to_code.py | 14 ++++++++++++-- .../python/scripts/macros/0system/0reload.lym | 8 ++++---- 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/klayout_package/python/kqcircuits/util/layout_to_code.py b/klayout_package/python/kqcircuits/util/layout_to_code.py index 8e9862df5..57af4240d 100644 --- a/klayout_package/python/kqcircuits/util/layout_to_code.py +++ b/klayout_package/python/kqcircuits/util/layout_to_code.py @@ -357,8 +357,19 @@ def get_node_params(node: Node): return node_params, elem +def remove_kqc_pcells(): + """Remove all KQCircuits PCells.""" + + main_window = pya.Application.instance().main_window() + for vid in range(main_window.views()): + top_cell = main_window.view(vid).active_cellview().cell + for inst in top_cell.each_inst(): + if isinstance(inst.pcell_declaration(), Element): + inst.delete() + + def extract_pcell_data_from_views(): - """Remove all KQCircuits PCells and return their data. + """Iterate over all KQCircuits PCells and return their data. 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 @@ -379,7 +390,6 @@ def extract_pcell_data_from_views(): if params[k] == v.default: del params[k] pcells.append((pc.__class__, inst.dtrans, params)) - inst.delete() views.append(pcells) return views diff --git a/klayout_package/python/scripts/macros/0system/0reload.lym b/klayout_package/python/scripts/macros/0system/0reload.lym index 079ab784a..5eab63758 100644 --- a/klayout_package/python/scripts/macros/0system/0reload.lym +++ b/klayout_package/python/scripts/macros/0system/0reload.lym @@ -38,14 +38,14 @@ 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 +from kqcircuits.util.layout_to_code import remove_kqc_pcells, extract_pcell_data_from_views, restore_pcells_to_views views = extract_pcell_data_from_views() try: load_libraries(flush=True) - restore_pcells_to_views(views) except: - restore_pcells_to_views(views) - raise RuntimeError("Failed to reload all KQCircuits libraries, restoring current view.") + raise RuntimeError("Failed to reload KQCircuits libraries, keeping current views.") +remove_kqc_pcells() +restore_pcells_to_views(views) From 109d7c4bac726836cc278df958e9eafc28ae6752 Mon Sep 17 00:00:00 2001 From: PietroCampana Date: Fri, 7 Jun 2024 12:45:52 +0200 Subject: [PATCH 4/5] prevent duplicated instances and reload cells before deleting libraries --- .../python/kqcircuits/util/layout_to_code.py | 25 +++++++------------ .../python/kqcircuits/util/library_helper.py | 4 ++- .../python/scripts/macros/0system/0reload.lym | 7 +++--- 3 files changed, 16 insertions(+), 20 deletions(-) diff --git a/klayout_package/python/kqcircuits/util/layout_to_code.py b/klayout_package/python/kqcircuits/util/layout_to_code.py index 57af4240d..072f97f4c 100644 --- a/klayout_package/python/kqcircuits/util/layout_to_code.py +++ b/klayout_package/python/kqcircuits/util/layout_to_code.py @@ -357,26 +357,18 @@ def get_node_params(node: Node): return node_params, elem -def remove_kqc_pcells(): - """Remove all KQCircuits PCells.""" - - main_window = pya.Application.instance().main_window() - for vid in range(main_window.views()): - top_cell = main_window.view(vid).active_cellview().cell - for inst in top_cell.each_inst(): - if isinstance(inst.pcell_declaration(), Element): - inst.delete() - - def extract_pcell_data_from_views(): - """Iterate over all KQCircuits 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 @@ -384,6 +376,7 @@ def extract_pcell_data_from_views(): for inst in top_cell.each_inst(): pc = inst.pcell_declaration() 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(): @@ -392,7 +385,7 @@ def extract_pcell_data_from_views(): pcells.append((pc.__class__, inst.dtrans, params)) 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 5eab63758..feb2e6a35 100644 --- a/klayout_package/python/scripts/macros/0system/0reload.lym +++ b/klayout_package/python/scripts/macros/0system/0reload.lym @@ -38,14 +38,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 remove_kqc_pcells, extract_pcell_data_from_views, restore_pcells_to_views +from kqcircuits.util.layout_to_code import extract_pcell_data_from_views, restore_pcells_to_views -views = extract_pcell_data_from_views() +views, instances = extract_pcell_data_from_views() try: load_libraries(flush=True) except: raise RuntimeError("Failed to reload KQCircuits libraries, keeping current views.") -remove_kqc_pcells() +for inst in instances: + inst.delete() restore_pcells_to_views(views) From 4452d412cd3472b88841387dfa0ca1e0d3531431 Mon Sep 17 00:00:00 2001 From: pietro Date: Sat, 8 Jun 2024 22:58:52 +0200 Subject: [PATCH 5/5] More informative exception and prevent non-deleted child instances --- .../python/kqcircuits/util/layout_to_code.py | 2 +- .../python/scripts/macros/0system/0reload.lym | 10 ++++++---- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/klayout_package/python/kqcircuits/util/layout_to_code.py b/klayout_package/python/kqcircuits/util/layout_to_code.py index 072f97f4c..f446cb5de 100644 --- a/klayout_package/python/kqcircuits/util/layout_to_code.py +++ b/klayout_package/python/kqcircuits/util/layout_to_code.py @@ -362,7 +362,7 @@ def extract_pcell_data_from_views(): 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 + ``(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. """ diff --git a/klayout_package/python/scripts/macros/0system/0reload.lym b/klayout_package/python/scripts/macros/0system/0reload.lym index feb2e6a35..0c35d1f7c 100644 --- a/klayout_package/python/scripts/macros/0system/0reload.lym +++ b/klayout_package/python/scripts/macros/0system/0reload.lym @@ -41,12 +41,14 @@ 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, instances = extract_pcell_data_from_views() -try: - load_libraries(flush=True) -except: - raise RuntimeError("Failed to reload KQCircuits libraries, keeping current 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)