technology not applied to LoadLayoutOptions() called from a package script

edited September 2023 in General

In my Package layoutDD (see https://github.com/wsteffe/layoutDD/blob/master/klayout_dot_config/python/layoutDD/loaders.py) I have the following function:

def importDXF():
    import os
    from . import mapLayers, saveActiveCell
    dxfPath      = pya.FileDialog.ask_open_file_name("Choose your file.", '.', "DXF (*.dxf)")
    mainWindow   = pya.Application.instance().main_window()
    layoutView   = mainWindow.view(mainWindow.create_view())
    option       = pya.LoadLayoutOptions()
    cellViewId   = layoutView.load_layout(dxfPath,option, 2)
   ...

I am calling it from a command after having selected my PCB technology which was defined with:

  • Database Unit = 1um
  • DXF file unit = 1000 um
  • ....

The loaded file appears as if the dxf unit were um (instead of mm):

I get a the proper scaling when I am using the klayout built in open command (from File Menu) with PCB technology selected as in the image. In this case the scale at left lower corner displays 20000 um (instead of 20 um).

Comments

  • Hi @wsteffe,

    if you explicitly pass a LoadLayoutOptions object, "load_layout" will take the default settings which will include 1µm DXF units.

    In order to use the reader options from a technology, this should work:

    # replace "tech_name" by the name of the technology you want to use
    layoutView.load_layout(dxfPath, "tech_name")
    

    Matthias

  • Hi Matthias, but a fixed tech name encoded in the python script wouldn't be very useful.
    Isn't it possible to get the tech name from the application ? I mean something like:
    pya.Application.instance().current_technology()

  • To better explain I would like that my call
    layoutView.load_layout(dxfPath,option, 2)
    made use the technology selected in the mainwindow, that is the technology pointed by the red arrow in next image:

    Actually I can't understand why this isn't the default behaviour. It is so for the builtin command File/Open but not for a package script.
    In my opinion it would be better if the package worked in the same way. If somebody wanted the other way (I mean the current way) in the package script he could simply write:
    layoutView.load_layout(dxfPath, "Default")

  • Ii doesn't work even with tech_name explicilely set in the script. I have just changed a few script lines (see loaders.py in https://github.com/wsteffe/layoutDD/tree/master/klayout_dot_config/python/layoutDD) to:

    cellViewId   = layoutView.load_layout(dxfPath,"PCB")
    cellView     = layoutView.cellview(cellViewId)
    

    The scale is still wrong

  • Hi @wsteffe,

    you can get the current technology with:

    pya.MainWindow.instance().initial_technology
    

    In order to gets the right DXF unit, it must be set accordingly in your technology. I can't see where I can find the "PCB" technology you mention above, so I cannot check. But I just confimed that the reader options from the technology are not used if you employ "load_layout(path, tech)". Instead, the default reader options are used. I guess it is easy to change if needed.

    However, there is an easy workaround - just pass the technology-specific reader options explicitly:

    tech_name = "PCB"
    tech = pya.Technology.technology_by_name(tech_name)
    layoutView.load_layout(path, tech.load_layout_options, tech_name)
    

    Regards,

    Matthias

  • edited October 2023

    Hi Matthias, thanks for clarification.
    PCB technlogy was created by me in Klayout/Manage Technology. It is the same as default apart of DXF file unit=1000 um in reader Options.

    But I have solved my problem trough a slight change of the design flow:

    The dxf file is initially opened using normal Open Command from File menu.
    Then you may use "Import Layout" from the layoutDD menu which is made available in the layoutDD package. This command:

    • Maps the Layers Names to (ln,dt) using lexicographical order saving the result in "fname.gds"+"fname.lyp".
      It also saves a flattened version of "fname.dxf" (named "fname_flat.dxf") which is subsenquetntly used for the subdomain
      generation (cmd "Make Subdomain")
    • Creates a second cellView in the same panel which is associated to the files "partition.gds" +"partition.lyp" .

    In the following you have to use "Open DD Project" from layoutDD selecting "fname.gds".
    This command regenetates the views and the data structure created with the other commands of layoutDD manu.
    The subdomains are generated from polygons stored in the cells of the partitions layout and from the visible layers of the imported document.
    The generated subdomains are stored in dxf format in a subfolder named "Subdomains".
    Partition cells are created with command "Create New Region" and are named "Region1" Region2".
    Clipping polygons are drawn by thew user on layer (0,0) of the associated cell.

  • Hi Matthias, I said too early I solved my problem.
    The dxf file is imported with the right scale but I still need the dxf_unit inside of my code in order to check if a clypping polygon
    is touching a dxf shape defined in the ezdxf entity (see lines 119-121 of file: https://github.com/wsteffe/layoutDD/blob/master/klayout_dot_config/python/layoutDD/subdomains.py.

    At the moment I have used your last suggestion:

    tech_name = "PCB"
    tech = pya.Technology.technology_by_name(tech_name)
    options=tech.load_layout_options
    dxf_unit=options.dxf_unit
    

    It works but it is not general.
    I would like to know the dxf_unit applied when the user opened and imported the dxf file.

  • Hi @wsteffe,

    That information unfortunately is not directly available. It is used while reading, but once that is done, the information is not recorded.

    You can obtain the information Indirectly through the technology attached to the layout:

    if layout.technology() is not None:
      dxf_unit = layout.technology().load_layout_options.dxf_unit
      ...
    

    This however only works if the layout is associated with a technology.

    A real solution was to record the DXF unit during reading in a layout meta data entry.

    Matthias

  • Hi Matthias, thanks for suggestion.
    It worked well. I am assuming as a requirement that the imported layout has an associated technology.

  • edited November 2023

    Hi Matthias,
    I have switced to using also gds format (before I was reading all the input data from a single dxf file) and I am not more able to retrieve dxf_unit after reloading the gds file with the code:

    dxf_unit = layout.technology().load_layout_options.dxf_unit

    I have seen that this code line works if I call it in the import() function of my layoutDD package just after having opened the gds file with Klayout GUI. But it doesn't work in the openProject() function defined in layoutDD package which uses the same code after reloading the gds file.

    I have also tried with the following code:

            def saveActiveCell():
                layoutView    = pya.Application.instance().main_window().current_view()
                cellView      = layoutView.active_cellview()
                layout        = cellView.layout()
                cell          = cellView.cell
                cellIndex     = cellView.index()
                filePath      = cellView.active().filename().replace("\\", "/")
                filePath,fext = os.path.splitext(filePath)
                option        = pya.SaveLayoutOptions()
                option.format = "GDS2"
                option.select_all_layers()
    
                if cell:
                    layoutView.save_as(cellIndex,f"{filePath}.gds", option)
                    layoutView.save_layer_props(f"{filePath}.lyp")
    
        def importLayout():
             .....
             dxf_unit  = mainLayout.technology().load_layout_options.dxf_unit
             mainLayout.add_meta_info(pya.LayoutMetaInfo("dxf_unit", dxf_unit))
             dxf_unit2   = mainLayout.meta_info_value("dxf_unit")   #this line is just to check that metadata was written      
             ...
             saveActiveCell()
    
        def openProject():
             gdsPath      = pya.FileDialog.ask_open_file_name("Choose your file.", '.', "GDS2 (*.gds)")
             gdsPath      = gdsPath.replace("\\", "/")
             mainWindow   = pya.Application.instance().main_window()
             mainCellView  = mainWindow.load_layout(gdsPath,1)
             mainLayout    = mainCellView.layout()
             filePath,fext  = os.path.splitext(gdsPath)
             lypPath= filePath+".lyp"
             layoutView  = pya.LayoutView.current()
             layoutView.load_layer_props(lypPath)
             dxf_unit    = mainLayout.meta_info_value("dxf_unit")
    

    But the meta_info is not saved

  • I got around the problem by saving/loading used tech file in the project folder.
    But now I have a problem in windows system because in this platform the tech file is not properly loaded or not properly associated with the layout (as better explained in another post).

  • Hi @wsteffe ,

    The way to persist the meta info is explained here: https://www.klayout.de/doc-qt5/code/class_LayoutMetaInfo.html.

    You need to declare it persisted:

    ly = RBA::Layout::new
    
    mi = RBA::LayoutMetaInfo::new("the-answer", 42.0)
    mi.persisted = true   # NOTE: declare as persisted
    ly.add_meta_info(mi)
    
    # will now hold this piece of meta information:
    ly.write("to.gds")
    

    Beware that this gives GDS files which are standard compatible but are enriched with KLayout specific information and that may look slightly weird in other systems (i.e. having a special additional top cell).

    Matthias

Sign In or Register to comment.