Converting OASIS file to PNG image file

Is there any way to programmatically convert an OASIS file to a PNG image file? I know that within the UI I can open OASIS and then do File>Screenshot, but I'd like a way to do if from within Python if possible. Thanks!!!

Comments

  • There is a related discussion ongoing: https://www.klayout.de/forum/discussion/1711/screenshot-with-all-the-layer-and-screenshot-only-one-layer#latest

    From there you can learn a lot about Python coded image generation scripts and it has a fancy version of a screenshot tool :)

    If by "Python" you mean the Python module on PyPI, it also has a LayoutView class and can bascially do the same.

    Matthias

  • Thank you for your response Matthias! I should have explained my issue better. We will be running on a system without graphics support so are unable to open the Klayout UI. I'd like to be able to make calls to KLayout from the command line to perform the oasis to image conversion. Does Klayout expose this functionality outside of the UI? Thank you!!!

  • edited August 2024

    I'd advise to use the Python module. It provides a stripped-down version of the LayoutView class which can render OASIS to PNG without a graphics device.

    Just do

    pip install klayout
    

    There is a demo web component (https://pypi.org/project/kweb/) that uses this technique to render layout on a HTTP server interactively through a WebSockets connection.

    Matthias

  • edited August 2024

    Hi chrisl,

    I hope the attached sample script from my toolbox will help you understand.

    -----------------------------------------------------------------------------------------------------
    oas2png-new.py
      << To convert OASIS file(s) to PNG file(s) with the help of KLayout Python Module>>
    
    $ [python3] oas2png-new.py                             (default)
        <-i|--input <OASIS file(s)>>                       ('')
        <-l|--lyp   <layer property file>>                 ('')
        [-t|--topcell <top cell name>]                     ('')
        [-p|--postfix <pfstr>] ex. ${_output_}${pfstr}.png ('')
        [-c|--conf  <KLayout's config file>]               (Linux & Mac: $HOME/.klayout/klayoutrc)
                                                           (Windows: %USERPROFILE%\klayout\klayoutrc)
        [-x|--sizex <image pixel size in X>]               (1000)
        [-y|--sizey <image pixel size in Y>]               (1000)
        [-b|--noborder] : without the image border         (disabled)
        [-d|--debug  <level>]                              (0)
        [-?|--?] : print this usage and exit               (disabled)
        You may use the -i option multiple times, including a wild card.
            ex. -i abc.oas  -i xzy.oas -i "*.oas" (-i '*.oas' in mac zsh)
    -----------------------------------------------------------------------------------------------------
    

    I have tested the code on Mac, Linux, and Windows 10.
    Note: the [-c|--conf <KLayout's config file>] option is now effective. Replaced the attachment.


    Sample Run

    MyHost{sekigawa}(1)$ ./oas2png-new.py -i "inv*.oas" -i ringo.oas -l invKazzzS.lyp
    ### <0001> Generating <inv2.png> from OASIS <inv2.oas> ...
    ### <0002> Generating <inv2a.png> from OASIS <inv2a.oas> ...
    ### <0003> Generating <inv2b.png> from OASIS <inv2b.oas> ...
    ### <0004> Generating <inv2c.png> from OASIS <inv2c.oas> ...
    ### <0005> Generating <inv2d.png> from OASIS <inv2d.oas> ...
    ### <0006> Generating <inv2e.png> from OASIS <inv2e.oas> ...
    ### <0007> Generating <inv2f.png> from OASIS <inv2f.oas> ...
    ### <0008> Generating <inv2g.png> from OASIS <inv2g.oas> ...
    ### <0009> Generating <ringo.png> from OASIS <ringo.oas> ...
    >>> Elapsed Time = 0.513 [sec] >>>
    
    MyHost{sekigawa}(2)$ ./oas2png-new.py -i ringo.oas -l invKazzzS.lyp -y 500
    ### <0001> Generating <ringo.png> from OASIS <ringo.oas> ...
    >>> Elapsed Time = 0.047 [sec] >>
    


    Kazzz-S

  • edited August 2024

    Cont.

    Fixed a problem in Windows and re-attached the ZIP file (2024-08-06).
    Sorry about the inconvenience.

  • Cont.

    I found and fixed a fatal bug (cell hierarchy level is not checked), then re-attached the ZIP file (2024-08-07).
    Sorry about the inconvenience once again.

  • Hi @sekigawa,

    thank you very much for providing these scripts! It is very much appreciated :)

    Just for my understanding - the fatal bug is not something inside KLayout, isn't it?

    Thanks,

    Matthias

  • edited August 2024

    Hi @Matthias,

    The bug was not inside KLayout; I misused an API function.

    Incorrect:

      :
      cellview.set_cell(topcellIdx)
      layoutview.max_hier_levels = layoutview.max_hier_levels + 1 <===
      # layoutview.max_hier_levels is not automatically set by layoutview.load_layout(); Hence, always, layoutview.max_hier_levels == 1
      layoutview.zoom_fit()
      :
    

    Correct:

      :
      cellview.set_cell(topcellIdx)
      layoutview.max_hier_levels = layout.cell(topcellIdx).hierarchy_levels() + 1 <===
      layoutview.zoom_fit()
      :
    

    Regards,
    Kazzz-S

  • Very good. Thanks for the explanation! :)

    Matthias

  • edited August 2024

    I will check it out! thank you so much @sekigawa and @Matthias!!!

  • @sekigawa I made a small change to remove the requirement for the layer file as I only have OASIS to work with and the images convert with no issue! Thank you so much! The converted image looks the same as the one imported via KLayout as hoped for! :)

  • Traceback (most recent call last):
    File "D:\gds_to_image\oas2png-new.py", line 453, in
    main()
    File "D:\gds_to_image\oas2png-new.py", line 440, in main
    ProcessOneOASISFile( configdic, item, count )
    File "D:\gds_to_image\oas2png-new.py", line 278, in ProcessOneOASISFile
    layoutview.load_layer_props( LayerPorpFile )
    RuntimeError: Unable to open file: D:\gds_to_image\invKazzzS.lyp (errno=2) in LayoutViewBase.load_layer_props

    Hello, I got this error, where is invKazzzS.lyp file?

  • You need to provide your own *.lyp for OASIS files.
    If you want to trace the above sample run, please use the attached files.

  • edited February 15


    Just wanted to follow up on this - @sekigawa - Is there way on the .conf file to setup a dither pattern that can be importer into oas2png, for example the current .conf file has a bunch of configdic options that get imported (background-color etc.) but the dither pattern and layer color is automatically cycled? Thanks!

  • Hi @Nanobot,

    I searched the klayout config file for dither as follows.

    % grep dither klayoutrc
     <l2ndb-marker-dither-pattern>1</l2ndb-marker-dither-pattern>
     <nt-marker-dither-pattern>-1</nt-marker-dither-pattern>
     <rdb-marker-dither-pattern>-1</rdb-marker-dither-pattern>
     <sel-dither-pattern>1</sel-dither-pattern>
     <transient-sel-dither-pattern>-1</transient-sel-dither-pattern>
    

    These *-dither-patter tags are related to the marker DB and not the ordinary layers.
    The dither-pattern tag seems unsupported; therefore, your last line, -->, won't work.

    If you edit your .lyp file to include layer colors and dither patterns explicitly, you can get them in output PNGs.
    Otherwise, the default patterns will be automatically cycled.
    That's my understanding.

    Kazzz-S

  • Ok, Thanks Kazzz-S for the quick response, is that a limitation of the python script? Just trying to see if there is a way to do a global constant dither pattern irrespective of the layer. Perhaps @mathias can help with some insight?

  • I went through all the options on the conf file and curious if there is a document/link somewhere that has list of configfic keys that I can pass. @sekigawa @mathias

  • edited February 19

    Hi @Nanobot,

    The following are related to your interests.

    1. https://www.klayout.de/lyp_format.html
    2. https://www.klayout.de/doc-qt5/code/class_Dispatcher.html#method13

    Kazzz-S

    from klayout import lay
    
    def print_formatted_table(strings, columns):
        """
        Prints a list of strings in a formatted table with a specified number of columns. (By ChatGPT)
    
        :param strings: List of strings to be formatted.
        :param columns: Number of columns in the output table.
        """
        if not strings or columns <= 0:
            return
    
        # Calculate the number of rows required
        rows = (len(strings) + columns - 1) // columns
    
        # Determine the maximum width for each column
        col_width = max(len(s) for s in strings) + 2
    
        # Print formatted table
        for i in range(rows):
            row_items = [strings[j] if j < len(strings) else "" for j in range(i, len(strings), rows)]
            print("".join(s.ljust(col_width) for s in row_items))
    
    def main():
        dispatcher   = lay.Dispatcher()
        config_names = sorted( dispatcher.get_config_names() )
        found        = []
        for cname in sorted(config_names):
            if "dither" in cname:
                found.append(cname)
        print_formatted_table(config_names, 3)
        print("")
        print(found)
    
    if __name__ == '__main__':
        main()
    
    absolute-units                      edit-inst-rows                      line-style-palette
    abstract-mode-enabled               edit-inst-scale                     markers-visible
    abstract-mode-width                 edit-max-shapes-of-instances        min-inst-label-size
    apply-text-trans                    edit-move-angle-mode                mouse-wheel-mode
    background-color                    edit-path-ext-type                  no-stipple
    bitmap-caching                      edit-path-ext-var-begin             pan-distance
    bitmap-oversampling                 edit-path-ext-var-end               paste-display-mode
    cell-list-sorting                   edit-path-width                     ruler-color
    child-context-color                 edit-pcell-show-parameter-names     ruler-grid-snap
    child-context-dimming               edit-show-shapes-of-instances       ruler-halo
    child-context-enabled               edit-snap-objects-to-grid           ruler-obj-snap
    child-context-hollow                edit-snap-to-objects                ruler-snap-mode
    clear-ruler-new-cell                edit-text-halign                    ruler-snap-range
    color-palette                       edit-text-size                      ruler-templates-v2
    combine-mode                        edit-text-string                    rulers
    context-color                       edit-text-valign                    search-range
    context-dimming                     edit-top-level-selection            search-range-box
    context-hollow                      fit-new-cell                        sel-color
    copy-cell-mode                      flat-cell-list                      sel-dither-pattern
    crosshair-cursor-color              full-hierarchy-new-cell             sel-halo
    crosshair-cursor-enabled            global-trans                        sel-inside-pcells-mode
    crosshair-cursor-line-style         grid-axis-color                     sel-line-style
    current-lib-view                    grid-color                          sel-line-width
    current-ruler-template              grid-grid-color                     sel-transient-mode
    dbu-units                           grid-ruler-color                    sel-vertex-size
    default-add-other-layers            grid-show-ruler                     show-properties
    default-font-size                   grid-style0                         split-cell-list
    default-layer-properties            grid-style1                         split-lib-views
    default-text-size                   grid-style2                         stipple-offset
    draw-array-border-instances         grid-visible                        stipple-palette
    drawing-workers                     guiding-shape-color                 subres-mode
    drop-small-cells                    guiding-shape-line-width            test-shapes-in-view
    drop-small-cells-condition          guiding-shape-vertex-size           text-color
    drop-small-cells-value              guiding-shape-visible               text-font
    edit-connect-angle-mode             hide-empty-layers                   text-lazy-rendering
    edit-grid                           highres-mode                        text-point-mode
    edit-hier-copy-mode                 image-cache-size                    text-visible
    edit-inst-angle                     images-visible                      tracking-cursor-color
    edit-inst-array                     initial-hier-depth                  tracking-cursor-enabled
    edit-inst-cell-name                 inst-color                          transient-sel-color
    edit-inst-column_x                  inst-label-font                     transient-sel-dither-pattern
    edit-inst-column_y                  inst-label-transform                transient-sel-halo
    edit-inst-columns                   inst-visible                        transient-sel-line-style
    edit-inst-mirror                    layer-visibility-follows-selection  transient-sel-line-width
    edit-inst-place-origin              layers-always-show-layout-index     transient-sel-vertex-size
    edit-inst-row_x                     layers-always-show-ld
    edit-inst-row_y                     layers-always-show-source
    
    ['sel-dither-pattern', 'transient-sel-dither-pattern']
    
Sign In or Register to comment.