CellView::filename invalidation

Hi all,

I am encountering an issue with the CellView::filename status. When I read a file with MainWindow::load_layout the return of pya.CellView().active().filename() gets the filepath associated with the layout behind the cellview as described in the doc.

When I try to read a file with the following way the return of that getter is empty:

main_window = pya.Application.instance().main_window()
main_window.create_view()
layout = pya.Layout()
layout.read(filepath)
main_window.current_view().show_layout(layout, False)
...
pya.CellView().active().filename() # returns empty string

I am missing something, or if it is a bug (?), do I have alternatives to set the filepath on the layout?

Comments

  • I think this is not a bug but a design specification or policy.

    I have tried to understand this problem as follows, but I am not sure.
    I hope @Matthias will give us the correct answers.


    Case-A: empty string

    #-------------------------------------------------------------
    # Ref. https://www.klayout.de/forum/discussion/2420/
    # Sub. CellView::filename invalidation
    #
    # File: Forum2420A.py
    #       More or less the same as the code from crizos
    #-------------------------------------------------------------
    import os
    import pya
    
    design = os.environ['HOME'] + "/KLayout/ringo.gds"
    
    layout = pya.Layout()
    layout.read(design)
    """
    [1] A 'layout' object can be created manually.
    In this case, the 'layout' object is populated with the 'design' file.
    But if needed, it can be further modified like this
      layout.add_cell("XYZ")
      :
      :
    before displaying its contents.
    
    This means that the bond between the 'layout' object and
    the original 'design' filename is essentially loose.
    """
    
    main_window = pya.Application.instance().main_window()
    lvidx = main_window.create_view()
    print("LayoutView Idx=%d" % lvidx)
    current_view = main_window.view(lvidx)
    
    cvidx = current_view.show_layout(layout, False)
    #                    ^^^^^^^^^^^^^^^^^^^
    # [2] Showing the contents of the 'layout' object is possible as long as it exists.
    print("CellView Idx=%d" % cvidx)
    
    cv = current_view.active_cellview()
    fname = cv.filename()
    # [3] But this call returns an empty string due to the potential loose bond.
    print( "fname=%s" % fname )
    
    """
    Console
    
    Running macro /Users/sekigawa/.klayout/pymacros/Forum2420A.py
    LayoutView Idx=0
    CellView Idx=0
    fname=
    """
    
    

    Case-B: non-empty string

    #-------------------------------------------------------------
    # Ref. https://www.klayout.de/forum/discussion/2420/
    # Sub. CellView::filename invalidation
    #
    # File: Forum2420B.py
    #-------------------------------------------------------------
    import os
    import pya
    
    design = os.environ['HOME'] + "/KLayout/ringo.gds"
    
    main_window = pya.Application.instance().main_window()
    mode = 1 # into a new view
    cv = main_window.load_layout(design, mode)
    #                ^^^^^^^^^^^^^^^^^^^
    # [1] The bond between the 'design' file and the cell view is tight.
    
    fname = cv.filename()
    # [2] This call can retrieve the 'design' file name.
    print( "fname=%s" % fname )
    
    """
    Console
    
    Running macro /Users/sekigawa/.klayout/pymacros/Forum2420B.py
    fname=/Users/sekigawa/KLayout/ringo.gds
    """
    
    

    Case-C: non-empty string

    #-------------------------------------------------------------
    # Ref. https://www.klayout.de/forum/discussion/2420/
    # Sub. CellView::filename invalidation
    #
    # File: Forum2420C.py
    #-------------------------------------------------------------
    import os
    import pya
    
    design = os.environ['HOME'] + "/KLayout/ringo.gds"
    
    main_window = pya.Application.instance().main_window()
    lvidx = main_window.create_view()
    print("LayoutView Idx=%d" % lvidx)
    current_view = main_window.view(lvidx)
    
    cvidx = current_view.load_layout(design, True)
    #                    ^^^^^^^^^^^^^^^^^^^
    # [1] The bond between the 'design' file and the cell view is tight.
    print("CellView Idx=%d" % cvidx)
    
    cv = current_view.active_cellview()
    fname = cv.filename()
    # [2] This call can retrieve the 'design' file name.
    print( "fname=%s" % fname )
    
    """
    Console
    
    Running macro /Users/sekigawa/.klayout/pymacros/Forum2420C.py
    LayoutView Idx=0
    CellView Idx=0
    fname=/Users/sekigawa/KLayout/ringo.gds
    """
    
    
  • Hi @sekigawa,

    Thank you for your input in this matter.

    I tend to believe that this is more of a bug since the info of the loaded filepath has been used as input to pya.Layout object in initialization, and cannot be retrieved somehow as far as I know (please correct me if I am wrong).

    This is also something that concerns me, and I believe is due to the same reason (empty CellView::filename):

    layout = pya.Layout()
    layout.read(filepath)
    main_window.current_view().show_layout(layout, False)
    # edit something just to switch "CellView::is_dirty" to "True"
    main_window.call_menu('cm_save') # same as "Ctrl+S" - will prompt to set "new" file path to save the changes
    
  • Hi @crizos,

    The Layout object does not store the file path. Only the CellView does. You can load a file into a Layout, but when you transfer it into the view, the file name is not known. This is also the reason why filename is not an attribute of the Layout object.

    The correct way to load a layout is using LayoutView#load_layout. This will transfer the file path into the CellView.

    Matthias

  • edited November 2023

    Hi @Matthias,

    Let's say that we have the following scenarios:

    Scenario A: filename invalidation - empty string

    main_window = pya.Application.instance().main_window()
    main_window.load_layout(gds_path, 0)
    
    layoutview = main_window.current_view()
    cellview = layoutview.active_cellview()
    layout = cellview.layout()
    layout_dup = layout.dup()
    
    layoutview.show_layout(layout_dup, False)
    cellview.filename() # will return empty string
    

    In the above scenario I've never changed the original filepath of the layout, so I would expect that I could still retrieve it somehow.

    Scenario B: filename invalidation - missing (?) filename

    main_window = pya.Application.instance().main_window()
    main_window.load_layout(gds_path, 0)
    
    layoutview = main_window.current_view()
    cellview = layoutview.active_cellview()
    layout = cellview.layout()
    
    layout.read(gds_path_dummy)
    cellview.filename() # will return only the initial gds_path and ignore the gds_path_dummy
    

    I believe the filename() should be attached at least in the initial filepath given for the loaded/showed layout, independent of how someone chose to do so. Ideally, filename() should return a list of all the filepaths used in each respective cellview.

    Chris

  • edited November 2023

    No, Layout does not carry the filename. Layout is the geometry database, and filename is not an attribute of it. In the same way, layer colors are not attributes of the Layout object but something that belongs to LayoutView in that case.

    The object representing the file is the CellView, not Layout and this is why CellView has the filename attribute, not Layout. In the same spirit for example the file watcher, which informs KLayout about file changes, is attached to the CellView, not Layout.

    So in scenario A, you take a Layout, dup it and create a new Layout. The first object does have the file name, so the new copy will not have one too. When you show the new layout, it is the same geometry, but not the same "thing" in the sense of the same file. It is something fresh and as you substitute the first CellView ("False" for the add_cellview argument), cellview will point to the new entry not having a file name.

    In scenario B, you also address the Layout object only. Again, this object does not carry the file name and loading something into it is changing the geometry, but does not modify the filename attribute of the 'CellView'. The right way to create a file-attached layout is LayoutView#load_layout. This creates a 'CellView' associated with a specific file.

    There is no direct way to manipulate a CellView to load a specific file. You have to use LayoutView methods to create cell views (load_layout, show_layout) to reload file (reload_layout) or to close a cell view (erase_cellview, equivalent to CellView#close).

    Matthias

Sign In or Register to comment.