Region inserted in layout is empty / not shown

edited October 6 in Python scripting

Hello,
At the end of the script below, I create a new Region from two different layouts. What happens is:

  • A new layout is created and a new cell named "XOR" is created in this layout. --> OK
  • Region r is created, with the correct non-zero area (when ra and rb differ). --> OK
  • A layer is created with the expected layer number... but that layer remains empty!

Could you explain why the layer is not populated and what should be done to obtain the result?
Oliver

"""Compare designs."""
A_cell, B_cell = None, None

mv = pya.MainWindow.instance()

for lv_idx in range(mv.views()):
  lv = mv.view(lv_idx)
  print(f"Open LayoutView {lv_idx}: " + lv.title)

  for cv_idx in range(lv.cellviews()):
    cv = lv.cellview(cv_idx)
    print(f"Search cell in CellView {cv_idx}: " + cv.name)

    if cv.name == "Test_A.gds":
      A_ly = cv.layout()
      A_cell = A_ly.cell("TOP")
      print("-> A_cell found.")

    if cv.name == "Test_B.gds":
      B_ly = cv.layout()
      B_cell = B_ly.cell("TOP")
      print("-> B_cell found.")


if (A_cell is None) or (B_cell is None):
  raise RuntimeError("Error: Target cells were not found.")
else:
  print("--> Target cells were found.")

LAYER_PAIRS =  [[ (19,0), (19,0) ]]

cv = mv.create_layout(mode=1)
ly = cv.layout()
cell = ly.create_cell("XOR")

for (a,b) in LAYER_PAIRS:
  a_idx = A_ly.find_layer(a)
  b_idx = B_ly.find_layer(b)

  ra = pya.Region(A_cell.begin_shapes_rec(a_idx))
  print("Region a: ", ra.area())
  rb = pya.Region(B_cell.begin_shapes_rec(b_idx))
  print("Region b: ", rb.area())
  r = ra ^ rb
  print("Region a^b: ", r.area())

  idx = ly.layer(a)
  cell.shapes(idx).insert(r)

Comments

  • You'll need to add this to the end of your script:

      ...
      idx = ly.layer(a)
      cell.shapes(idx).insert(r)
    
      #new code
      # select the top cell in the view, set up the view's layer list and
      # fit the viewport to the extensions of our layout
      mv.current_view().select_cell(cell.cell_index(), 0)
      mv.current_view().add_missing_layers()
      mv.current_view().zoom_fit
    

    This is from the first example here:
    https://www.klayout.de/doc-qt5/programming/database_api.html

    As for why - my understanding is since the LayoutView controls the view and appearance of data it'll need to be updated if something changes, unlike if you just write to a GDS file.

    LayoutView documentation: https://www.klayout.de/doc-qt5/programming/application_api.html#k_3

    Hope this helps.

  • Thank you very much!
    Your made me understand my problem: I was blind to the fact that the cell created was not selected! I thus completed my script with an equivalent of what you wrote:

    cv.cell_name = cell.name
    lv = cv.view()
    lv.add_missing_layers()
    lv.zoom_fit()
    
  • edited October 10

    Very good. Thanks @blueman_44 for providing the answer.

    For the explanation about "add_missing_layers": KLayout's layer list is not an exact copy of the layers stored in the database. It is quite common to have layer tables that only present "known" layers, i.e. ones that are legal for use in a specific PDK. By default (i.e. without a layer properties file), all layers are shown, but not automatically. The layer list need to be synchronized with the database. Inside the editor features for example, this happens automatically. Also when you load a file. But not when you create layers dynamically. That is what happens under the hood during ly.layer(a). "add_missing_layers" will do that synchronization for you: it will create default entries for all database layers that are not mapped in the layer list.

    Matthias

Sign In or Register to comment.