Skip to content

Commit

Permalink
Merge pull request #230 from SiEPIC/replace_cell
Browse files Browse the repository at this point in the history
Replace cell
  • Loading branch information
lukasc-ubc authored Nov 5, 2024
2 parents cce6dd4 + 2df15a0 commit 49e30c8
Show file tree
Hide file tree
Showing 8 changed files with 105 additions and 61 deletions.
56 changes: 54 additions & 2 deletions klayout_dot_config/python/SiEPIC/scripts.py
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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
Expand All @@ -3158,6 +3200,13 @@ def replace_cell(layout, cell_x_name = None, cell_y_name=None, cell_y_file=None,
Basename, Basename* NO: Basename_extension
Basename, Basename* YES: DifferentName
'''

# Find the cell name from the cell_ref_bb
if not cell_x_name:
if cell_ref_bb:
cell_x_name = cell_ref_bb.name
else:
raise Exception ('missing replacement cell name')

import os
if debug:
Expand All @@ -3179,7 +3228,10 @@ def replace_cell(layout, cell_x_name = None, cell_y_name=None, cell_y_file=None,

# Find the cells that need replacement (cell_x)
# find cell name exactly matching cell_x_name
cells_x = [layout.cell(cell_x_name)]
if layout.cell(cell_x_name):
cells_x = [layout.cell(cell_x_name)]
else:
cells_x = []
if not Exact:
# replacement for all cells that:
# 1) cell name exact matching cell_x_name, OR
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@
"""

def test_replace_cell():
def test_replace_cell(show_klive=False):
'''
show_klive: True to open the layout in KLayout using KLive
'''

import pya
Expand All @@ -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__))
Expand All @@ -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:
Expand All @@ -77,18 +63,17 @@ 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)
layout.write(file_out)
try:
if show_klive:
# Display the layout in KLayout, using KLayout Package "klive", which needs to be installed in the KLayout Application
if Python_Env == 'Script':
from SiEPIC.utils import klive
klive.show(file_out, technology='EBeam')
except:
pass
os.remove(file_out)


Expand All @@ -106,18 +91,17 @@ 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)
layout.write(file_out)
try:
if show_klive:
# Display the layout in KLayout, using KLayout Package "klive", which needs to be installed in the KLayout Application
if Python_Env == 'Script':
from SiEPIC.utils import klive
klive.show(file_out, technology='EBeam')
except:
pass
os.remove(file_out)

# Check -- Run BB reference vs. design layout difference, non-exact replacement (with $)
Expand All @@ -134,8 +118,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:
Expand All @@ -157,4 +142,4 @@ def check_bb_geometries(layout):
assert error == True

if __name__ == "__main__":
test_replace_cell()
test_replace_cell(show_klive=True)
11 changes: 6 additions & 5 deletions klayout_dot_config/tech/GSiP/pymacros/tests/test_FaML.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"""

def test_FaML_two():
def test_FaML_two(show_klive=False):
'''
--- Simple MZI, tested using Facet-Attached Micro Lenses (FaML) ---
Expand Down Expand Up @@ -102,13 +102,14 @@ def test_FaML_two():
print('Number of errors: %s' % num_errors)

# Display the layout in KLayout, using KLayout Package "klive", which needs to be installed in the KLayout Application
if Python_Env == 'Script':
from SiEPIC.utils import klive
klive.show(file_out, lyrdb_filename=file_lyrdb, technology=tech_name)
if show_klive:
if Python_Env == 'Script':
from SiEPIC.utils import klive
klive.show(file_out, lyrdb_filename=file_lyrdb, technology=tech_name)
os.remove(file_out)

if num_errors > 0:
raise Exception ('Errors found in test_FaML_two')

if __name__ == "__main__":
test_FaML_two()
test_FaML_two(show_klive=True)
11 changes: 6 additions & 5 deletions klayout_dot_config/tech/GSiP/pymacros/tests/test_SiEPIC_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ def test_create_cell2():
topcell.insert(CellInstArray(cell_y.cell_index(), t))


def test_waveguide_length():
def test_waveguide_length(show_klive=False):
import pya
import SiEPIC
from SiEPIC._globals import Python_Env
Expand Down Expand Up @@ -124,9 +124,10 @@ def test_waveguide_length():

# Display in KLayout
from SiEPIC._globals import Python_Env
if Python_Env == 'Script':
from SiEPIC.utils import klive
klive.show(file_out, technology=tech_name, keep_position=True)
if show_klive:
if Python_Env == 'Script':
from SiEPIC.utils import klive
klive.show(file_out, technology=tech_name, keep_position=True)
os.remove(file_out)


Expand All @@ -137,4 +138,4 @@ def test_waveguide_length():
if __name__ == "__main__":
test_load_layout()
test_create_cell2()
test_waveguide_length()
test_waveguide_length(show_klive=True)
20 changes: 11 additions & 9 deletions klayout_dot_config/tech/GSiP/pymacros/tests/test_bezier.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@

from pya import *

def test_bezier_bends():
def test_bezier_bends(show_klive=False):
designer_name = 'Test_Bezier_bend'
top_cell_name = 'GSiP_%s' % designer_name

Expand Down Expand Up @@ -124,15 +124,16 @@ def test_bezier_bends():

# Display in KLayout
from SiEPIC._globals import Python_Env
if Python_Env == 'Script':
from SiEPIC.utils import klive
klive.show(file_out, technology=tech_name, keep_position=True)
if show_klive:
if Python_Env == 'Script':
from SiEPIC.utils import klive
klive.show(file_out, technology=tech_name, keep_position=True)
os.remove(file_out)
# Plot
# cell.plot() # in the browser


def test_bezier_tapers():
def test_bezier_tapers(show_klive=False):
designer_name = 'Test_Bezier_tapers'
top_cell_name = 'GSiP_%s' % designer_name

Expand Down Expand Up @@ -220,9 +221,10 @@ def test_bezier_tapers():

# Display in KLayout
from SiEPIC._globals import Python_Env
if Python_Env == 'Script':
from SiEPIC.utils import klive
klive.show(file_out, technology=tech_name, keep_position=True)
if show_klive:
if Python_Env == 'Script':
from SiEPIC.utils import klive
klive.show(file_out, technology=tech_name, keep_position=True)
os.remove(file_out)

# Plot
Expand All @@ -231,5 +233,5 @@ def test_bezier_tapers():

if __name__ == "__main__":
# test_bezier_bends()
test_bezier_tapers()
test_bezier_tapers(show_klive=True)

Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"""

def test_coupler_array():
def test_coupler_array(show_klive=False):
'''
--- Simple MZI, tested using Facet-Attached Micro Lenses (FaML) ---
Expand Down Expand Up @@ -101,13 +101,14 @@ def test_coupler_array():
print('Number of errors: %s' % num_errors)

# Display the layout in KLayout, using KLayout Package "klive", which needs to be installed in the KLayout Application
if Python_Env == 'Script':
from SiEPIC.utils import klive
klive.show(file_out, lyrdb_filename=file_lyrdb, technology=tech_name)
if show_klive:
if Python_Env == 'Script':
from SiEPIC.utils import klive
klive.show(file_out, lyrdb_filename=file_lyrdb, technology=tech_name)
os.remove(file_out)

if num_errors > 0:
raise Exception ('Errors found in test_coupler_array')

if __name__ == "__main__":
test_coupler_array()
test_coupler_array(show_klive=True)
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

from pya import *

def example_circuit():
def example_circuit(show_klive=False):
designer_name = 'Test'
top_cell_name = 'GSiP_%s' % designer_name

Expand Down Expand Up @@ -122,9 +122,10 @@ def example_circuit():

# Display in KLayout
from SiEPIC._globals import Python_Env
if Python_Env == 'Script':
from SiEPIC.utils import klive
klive.show(file_out, technology=tech_name, keep_position=True)
if show_klive:
if Python_Env == 'Script':
from SiEPIC.utils import klive
klive.show(file_out, technology=tech_name, keep_position=True)
os.remove(file_out)

# Plot
Expand All @@ -143,5 +144,5 @@ def test_example_circuit():
assert example_circuit() == 0

if __name__ == "__main__":
example_circuit()
example_circuit(show_klive=True)

Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

from pya import *

def test_all_library_cells():
def test_all_library_cells(show_klive=False):
designer_name = 'Test'
top_cell_name = 'GSiP_%s' % designer_name

Expand Down Expand Up @@ -54,7 +54,8 @@ def test_all_library_cells():
if c.is_empty() or c.bbox().area() == 0:
raise Exception('Empty cell: %s' % c.name)

topcell.show()
if show_klive:
topcell.show()

# Verify
num_errors = layout_check(cell=topcell, verify_DFT=False, verbose=False, GUI=True)
Expand All @@ -64,4 +65,4 @@ def test_all_library_cells():


if __name__ == "__main__":
test_all_library_cells()
test_all_library_cells(show_klive=True)

0 comments on commit 49e30c8

Please sign in to comment.