From 49cf9b815afa5238a0bcfcccb20856e2c208bd25 Mon Sep 17 00:00:00 2001 From: Lukas Chrostowski Date: Mon, 4 Nov 2024 19:54:15 -0800 Subject: [PATCH] new function: cells_containing_bb_layers return a list of cell names that contain black box layer polygons --- klayout_dot_config/python/SiEPIC/scripts.py | 44 ++++++++++++++++++- .../test_scripts_replace_cell.py | 25 +++-------- 2 files changed, 50 insertions(+), 19 deletions(-) diff --git a/klayout_dot_config/python/SiEPIC/scripts.py b/klayout_dot_config/python/SiEPIC/scripts.py index a30a1c0a..983328e2 100644 --- a/klayout_dot_config/python/SiEPIC/scripts.py +++ b/klayout_dot_config/python/SiEPIC/scripts.py @@ -3075,6 +3075,48 @@ def button(self): wdg.show() +def check_bb_geometries(topcell, BB_layerinfo=pya.LayerInfo(998,0), verbose=True): + ''' + Check if there are any Black Box layers in the layout. + Returns: + Count: number of different shapes + Args: + topcell: pya.Cell + BB_layerinfo: pya.LayerInfo + ''' + layout = topcell.layout() + layer_bb = layout.layer(BB_layerinfo) # hard coded for the GSiP PDK + r1 = pya.Region(topcell.begin_shapes_rec(layer_bb)) + diff_count = 0 + if not r1.is_empty(): + diff_count = r1.size() + if verbose: + print( + f" - SiEPIC.scripts.check_bb_geometries: {r1.size()} Black Box geometry(ies) found in {topcell.name} on layer {layout.get_info(layer_bb)}." + ) + else: + if verbose: + print('Black box replacement -- success -- no black box layers remaining.') + return diff_count + +def cells_containing_bb_layers(topcell, BB_layerinfo=pya.LayerInfo(998,0), verbose=True): + ''' + return a list of cell names that contain black box polygons + Args: + topcell: pya.Cell + BB_layerinfo: pya.LayerInfo + ''' + layout = topcell.layout() + iter1 = pya.RecursiveShapeIterator(layout, topcell, layout.layer(BB_layerinfo) ) + cells = [] + while not iter1.at_end(): + cells.append (iter1.cell().name) + if verbose: + print(" - %s" % iter1.cell().name) + iter1.next() + # return unique cell names + return sorted(list(set(cells))) + def layout_diff(cell1, cell2, tol = 1, verbose=True): ''' Check two cells to make sure they are identical, within a tolerance. @@ -3135,7 +3177,7 @@ def layout_diff(cell1, cell2, tol = 1, verbose=True): return diff_count -def replace_cell(layout, cell_x_name = None, cell_y_name=None, cell_y_file=None, cell_y_library=None, cell_ref_bb = None, Exact = True, RequiredCharacter = '$', run_layout_diff = True, debug = False): +def replace_cell(layout, cell_x_name = None, cell_y_name=None, cell_y_file=None, cell_y_library=None, cell_ref_bb = None, Exact = True, RequiredCharacter = '$', run_layout_diff = False, debug = False): ''' SiEPIC-Tools: scripts.replace_cell Search and replace: cell_x with cell_y diff --git a/klayout_dot_config/python/SiEPIC/tests/test_replace_cell/test_scripts_replace_cell.py b/klayout_dot_config/python/SiEPIC/tests/test_replace_cell/test_scripts_replace_cell.py index b5343aa4..a29cc220 100644 --- a/klayout_dot_config/python/SiEPIC/tests/test_replace_cell/test_scripts_replace_cell.py +++ b/klayout_dot_config/python/SiEPIC/tests/test_replace_cell/test_scripts_replace_cell.py @@ -29,7 +29,7 @@ def test_replace_cell(): raise Exception("Errors", "This example requires SiEPIC-Tools version 0.5.4 or greater.") - from SiEPIC.scripts import replace_cell, delete_extra_topcells + from SiEPIC.scripts import replace_cell, delete_extra_topcells, cells_containing_bb_layers, check_bb_geometries # The circuit layout that contains BB cells path = os.path.dirname(os.path.realpath(__file__)) @@ -51,20 +51,6 @@ def test_replace_cell(): ly_wb.read(file_wb) cell_wb = ly_wb.top_cell() ''' - def check_bb_geometries(layout): - ''' - check if there are any Black Box layers in the layout - ''' - layer_bb = layout.layer(pya.LayerInfo(998,0)) # hard coded for the GSiP PDK - r1 = pya.Region(top_cell.begin_shapes_rec(layer_bb)) - diff_count = 0 - if not r1.is_empty(): - diff_count = r1.size() - print( - f" - SiEPIC.scripts.layout_diff: {r1.size()} Black Box geometry(ies) found in {top_cell.name} on layer {layout.get_info(layer_bb)}." - ) - return diff_count - # Check -- exact replacement (without $) if 1: @@ -77,7 +63,8 @@ def check_bb_geometries(layout): ) print('replaced %s' %count) assert count == 1 - assert check_bb_geometries(layout) == 1 + assert check_bb_geometries(top_cell) == 1 + assert cells_containing_bb_layers(top_cell) == ['ebeam_y_adiabatic_500pin$1'] file_out = os.path.join(path,'example_replaced.gds') delete_extra_topcells(layout, top_cell.name) @@ -106,7 +93,8 @@ def check_bb_geometries(layout): ) print('replaced %s' %count) assert count == 2 - assert check_bb_geometries(layout) == 0 + assert check_bb_geometries(top_cell) == 0 + assert cells_containing_bb_layers(top_cell) == [] file_out = os.path.join(path,'example_replaced2.gds') delete_extra_topcells(layout, top_cell.name) @@ -134,8 +122,9 @@ def check_bb_geometries(layout): ) print('replaced %s' %count) assert count == 2 - assert check_bb_geometries(layout) == 0 + assert check_bb_geometries(top_cell) == 0 assert error == False + assert cells_containing_bb_layers(top_cell) == [] # Check -- Run BB reference (changed) vs. design layout difference, non-exact replacement (with $) if 1: