how to import the cell which shares the same subcell with other cell over python scripting?

Hi, I'm recently trying to import two cells like this:

It seems that the subcell named *$1 is totally the different new cell.
How to import this kind of cells with the subcells that already exist in the cell list of the layout?

Comments

  • Hi Ryan354
    I have met this and the way I did is:

    I copy the cell to target gds file if any subcell exist ready in target cell the name of subcell will be changed(add more $# to end) after that I use "search and replace" instance to replace subcell with $# by subcell without $#. I don't use script.

    dai

  • @Ryan354,

    how are you importing these cells? By script?

    Matthias

  • yes, by script only.

  • edited September 2020

    I've found a way in the forum to create the cell and copy the cell tree to the current layout as the subcell for instance, and the reference top cell which already exists in the current layout can be used again for instance instead of creating the same new cell named with '*$1'. However, it doesn't work for the subcell. Here're my script:

    Class Template(object):

    def __init__(self, filePath, current_layout):
        self.filePath = filePath
        self.layout = current_layout
        self.initial_top_cell = self.layout.top_cell()
        self.ref_layout = pya.Layout()
        self.ref_layout.read(self.filePath)
        if self.layout.cell(self.ref_layout.top_cell().name) == None:
            self.cell_ptr = self.layout.create_cell(self.ref_layout.top_cell().name)
            self.cell_ptr.copy_tree(self.ref_layout.top_cell())
        else: 
            self.cell_ptr = self.layout.cell(self.ref_layout.top_cell().name)
    
    def insert_instance(...):
        ......
        ......
    

    Class Circuit(Template):

    def __init__(self, filePath, current_layout):
        super(Circuit, self).__init__(filePath = filePath, current_layout= current_layout)
    
    def ......
        ......
    

    It seems that the code should be modified with the use of 'for' loop @ if-else script region, but I don't know how to do it. Can you help me with this??

  • @Ryan354,

    I'm sorry, but I don't really understand the problem.

    I guess you mean the following: if you import two cells using "copy_tree" in two different calls, the same subcell will appear twice in the target layout. You want to avoid this and have the common subcell copied only once.

    Is that what you want to have?

    If so, here is my reply:

    Currently, this behaviour is a side effect of "copy_tree" as by definition it will entirely duplicate the tree on each call. There is no knowledge which cells are already copied, so this method cannot know what cells to skip.

    A multi-cell-copy feature is in preparation, but it's not ready to be released yet. This feature will allow specifying multiple cells for copy and doing so will make it reuse common subcells.

    Matthias

  • Yes, that's what I mean.

    Thanks for your reply.

  • Hi,

    I pushed the corresponding feature to 0.26.8 and it's released already.

    Solution:

    The solution consists of two methods: Cellmapping#for_multi_cells_full will create the target structure and prepare a mapping table and Layout#copy_tree_shapes will copy the shapes.

    Here is some sample code:

    l = ... # source layout
    lt = ... # target layout
    
    target_cells = ... # array of cell indexes to which cells to copy (in target layout)
    source_cell = ... # array of cell indexes from which cells to copy (in source layout)
    
    # NOTE: target_cells.size must be equal to source_cells.size
    
    # Prepare a cell mapping (this will also create the necessary subcells in the target layout)
    cm = RBA::CellMapping::new
    cm.for_multi_cells_full(lt, target_cells, l, source_cells)
    
    # Copy the cell's shapes
    lt.copy_tree_shapes(l, cm)
    

    (taken from https://github.com/KLayout/klayout/issues/639)

    Matthias

  • Thanks for your reply.

    by the script above, it seems that the cell indexes are needed for the mapping action.

    Can you provide a simple example (including the step of the assignment of target/source cell indexes)?

    Is there a way equivalent to replacing the '*$1' subcell by the one without '$1', just like the action 'replace cell' by right-click of mouse?

  • You get cell indexes from Cell object using "cell_index()" on the Cell object. Cell indexes are basically equivalent to Cell objects, but they don't suffer from object lifetime issues.

    With the new method you will not get "$x" cells. Except if there is a reason for that. Don't try to "fix" this, this might create weird errors.

  • I try to write a python sample, but I got "Segmentation fault" error when call copy_tree_shapes.
    Can you help me to find the problem ? Thank you.

    import pya
    cell_names = [ "A", "B" ]
    
    source = pya.Layout()
    source.read("input.gds")
    
    target = pya.Layout()
    
    source_cells = list()
    target_cells = list()
    for cell in cell_names:
        source_cells.append(source.cell_by_name(cell))
        target_cells.append(target .create_cell(cell).cell_index() )
    
    cm = pya.CellMapping()
    cm.for_multi_cells_full(source, source_cells, target, target_cells)
    target.copy_tree_shapes(source, cm)
    
    target .write("output.gds")
    
  • "for_multi_cells_full" takes first the target and then the source layout/cell combinations.

    So it should be:

    cm.for_multi_cells_full(target, target_cells, source)
    

    Matthias

  • Thanks for your reply. After change code as below, it works
    cm.for_multi_cells_full(source, source_cells, target, target_cells)
    --> cm.for_multi_cells_full( target, target_cells, source, source_cells)

    I use the the example of this below page and change to python, the example may need to be modified ? Thanks~
    https://www.klayout.de/doc-qt4/code/class_CellMapping.html

  • You're right. Thanks for this hint!

    Matthias

Sign In or Register to comment.