It looks like you're new here. If you want to get involved, click one of these buttons!
Hi All,
I wrote a script to swap cells with cells (with the same cell name) from another file. The script is working in my test cases but I was wondering if there could be a better way of doing this or there might be some bugs in my script
Usage is:
swap_cells.py -in input.gds -out output.gds -files file1.gds,file2.gds,...
Code:
def main():
opts = getOpts()
if not os.path.isfile(opts.in_file):
print("[ERROR]",opts.in_file,"does not exist!")
exit(1)
in_file_name = os.path.basename(opts.in_file)
files = []
subcells = {}
if not opts.out_file:
print("[ERROR] Please specify output file!")
exit(1)
outputFile = opts.out_file
#split files string and add to files list
#keep the top cell names of the loaded files in subcells dictionary
for file in opts.files.split(','):
if not os.path.isfile(file):
print("[ERROR]",file,"does not exist!")
exit(1)
else:
files.append(file)
subcell = Path(file).stem
subcells[subcell]=1
#Load the main input file
print("[INFO] Reading",opts.in_file,"...")
layout = pya.Layout()
layout.read(opts.in_file)
top_cell = layout.top_cell()
#Empty the content of subcells to be swapped
for cell in layout.each_cell():
cell_name = layout.cell_name(cell.cell_index())
if cell_name in subcells:
cell.clear_shapes()
cell.clear_insts()
#Delete orphaned cells
deleteOrphaned(layout,top_cell)
#Load the files containing cells to be swapped
for file in files:
print("[INFO] Reading",file,"...")
layout.read(file)
#Delete orphaned cells
deleteOrphaned(layout,top_cell)
#Write output file
layout.write(outputFile)
print("[INFO] Swapped cells in:",outputFile)
def deleteOrphaned(layout,top_cell):
top_cell_name = layout.cell_name(top_cell.cell_index())
orphaned= []
for cell in layout.each_top_cell():
cell_name = layout.cell_name(cell)
if cell_name != top_cell_name:
cell_obj = layout.cell(cell)
orphaned.append(cell_obj)
for cell_obj in orphaned:
cell_obj.prune_cell()
def getOpts():
parser = argparse.ArgumentParser(description="Swaps cells in layout file with cells from other files")
parser.add_argument('-in', action='store', dest='in_file',required=True,
help='Input Layout File')
parser.add_argument('-out', action='store',dest='out_file',required=True,
help='Output Layout File')
parser.add_argument('-files', required=True, action='store',
type=str, help='Comma-separated list of swap layout File')
return parser.parse_args()
if __name__ == "__main__":
main()
Comments
@world_locus Thanks a lot for sharing this script.
The script doesn't look bad. Specifically you're very right not to call "prune_cell" inside the search loop in "deleteOrphaned". Deleting cells while you loop over them is often crashing KLayout. Some weakness of the API. Very good you took care of that!
The approach of substituting cells by reading a file into an existing layout works, but it has some disadvantages:
To overcome the issue, the solution is to load the second layout into a separate pya.Layout object and transfer the cells from there into the first layout using "Cell#copy_tree". You have to do this in a loop. This works, but with the current API this will not duplicate child cells shared between substitution cells in the replacement layout. This can be mitigated as well in the next major release with a "multi-cell" copy function.
Kind regards,
Matthias
Thank your very much for the feedback Matthias. In my case DBUs of the layout files are the same but cell name conflict might be possible.
I look forward to the next major release.