script to swap cells with cells from another file

edited January 12 in Python scripting

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:

    • It will not work properly if the second layout does not have the same DBU than the first one. You will not get a warning.
    • If the first layout has cells with the same name than some of the second layout, this will also merged these cells and you won't see a warning. This usually spoils your layout. So a name conflict is a serious risk. The next major release will provide better control over the conflict handling, so this risk can be mitigated.

    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

Sign In or Register to comment.