Use klayout in batch mode

edited May 2012 in General
Dear all,

I would like to use klayout to convert GDS into DXF and/ or PDF. Using the GUI this is simple (using Save As or Print). However I like to do this conversion from command line.
I found no hint whether the RBA is suitable for this.

Regards
Achim

Comments

  • edited May 2012

    Hi Achim,

    It can be solved with Ruby, but for conversion of layout to DXF there may be a very simple alternative solution: when you build KLayout yourself, beside the "klayout" binary, some other binaries are built as well, mainly for test purposes. One of these binaries is "strm2dxf". This is a very simple tool that converts and input format to a DXF file (i.e "strm2dxf a.gds b.dxf"). The sourcecode is in strm2dxf.cc, so it can be modified if required.

    This tool basically uses the same code than KLayout itself, so the results should be the same.

    Best regards,

    Matthias

  • edited November -1
    Hi Matthias

    thanks for the reply I'll check.

    However, meanwhile I played around a bit with Ruby Scripting (its my very first time using Ruby)

    I have attached my results, it would be nice if your or someone else could comment.
    I have 2 open item:
    - I would no hint how a Postscript or PDF could be created by script
    the print functionality of the GUI migth be sufficient, but I did not find any hint
    how to access this function from Ruby script
    - how can I write output to shell, neither puts nor $stdout.write seem to work
    (at least on Windows, as I am travelling today)



    filename = "path/to/my.gds"
    filename_out = filename+".dxf"

    # get handle to klayout instance
    app = RBA::Application.instance
    mw = app.main_window

    # open layout in read only
    fid = mw.load_layout(filename, 0)
    lv = mw.current_view
    cv = lv.active_cellview
    lay = cv.layout
    top = cv.cell_index
    top_name = lay.cell_name(top)

    # select his cell as the top cell, fit all
    # and switch on all hierarchy levels
    lv.select_cell_path( [top], 0 )
    lv.zoom_fit
    lv.max_hier

    # write debug info to file
    fid = File.open("dummy.txt", "w")
    fid.puts("found top cell #{top_name}")
    fid.puts("index of top cell in CellView index #{top}")

    # create new SaveLayoutOptions object
    # output format is DXF, all option keep default
    opt = RBA::SaveLayoutOptions.new
    opt.format="DXF"

    # save DXF,
    lv.save_as(0, # cell index, for some reason it needs to be "0"
    filename_out, # file name
    0, # do not gzip output
    opt)

    # run the application
    RBA::Application.instance.exec
  • edited May 2012

    Hi Achim,

    that is not that bad :-)

    On Windows, KLayout has to be compiled as Console application to see the output - but that is a difficult issue. In the next release, it will be possible to run a script in some kind of debugger where you can puts and set breakpoints and so on.

    Here is very simple version of the script:

    lay = RBA::Layout.new
    lay.read("myfile.gds")
    opt = RBA::SaveLayoutOptions.new
    opt.format="DXF"
    lay.write("myfile.dxf", false, opt)
    

    Run this script with the -r option of KLayout, and it will not start but rather execute the script like a ruby interpreter and it will terminate when the script ends.

    You can equip the script with variables and set the variables from the command line with the -rd option.

    The Print function does not save PDF but rather creates an image and sends that to the printer. You can dump a layout as a image file by script as well using LayoutView::save_image.

    Best regards,

    Matthias

  • edited November -1
    Hi Matthias,

    I would like to add a question to the PDF export:
    Do you see a possibility to create a .eps or pdf file containing a vector drawing of the layout rather than a bitmap?

    thx, thomas
  • edited November -1
    Hi Matthias,

    I tried to follow the example you post to do a layer conversion in batch mode, however stuck on how to read layer map file, could you please teach me how to do that? thanks.

    lay = RBA::Layout.new
    loadopt = RBA::LoadLayoutOptions.new

    loadopt.set_layer_map ?? (I don't know the method to set layer map file for LoadLayoutOptions)

    lay.read("from.gds")
    lay.write("to.gds")

    Best Regards,
    --
    chhung
  • edited June 2012

    Hi Thomas,

    I have experimented with vector graphics output but I found that very inefficient for even simple layouts. I know there are a lot of tools out there which do a simple GDS to postscript conversion (google for "GDS to postscript conversion"), but when it comes to larger layouts, the tricky part is to simplify the information so the PostScript (or SVG for example) renderer won't get stuck. That is the point where vector formats are no longer useful.

    Best regards,

    Matthias

  • edited November -1

    Hi chhung,

    The method to install a layer mapping table is "set_layer_map", that's right. It expects a "LayerMap" object which you create and fill with the layer map like this:

    lm = RBA::LayerMap::new
    
    # (This sample reads layer 17:0 on layer 1:0)
    # First, create a target layer with layer/datatype 1:0:
    l1 = lay.insert_layer(RBA::LayerInfo::new(1, 0))
    # Then, redirect every shape on 17:0 to that layer
    lm.map(RBA::LayerInfo::new(17, 0), l1)
    
    # ... do that for other layers
    
    # Install the layer mapping table. The second parameter indicates whether
    # the reader should read layers not mentioned in the mapping object also
    # (with their original layer/datatype). 
    loadopt.set_layer_map(lm, true)
    

    Hopefully that helps.

    Best regards,

    Matthias

  • edited June 2012
    Hi Matthias,

    We followed the steps you post to try and it works fine, and now we have another two questions.
    1. Once we execute klayout to load the RBA code we write, it shows "klayout: cannot connect to X server" if we didn't setup environment parameter: DISPLAY , we tried to add "-z" option and didn't help.

    2. Is it possible to load a layer mapping file from RBA code, instead of specifying every mapping layers (l1=lay.insert_layer , lm.map and l2=lay.insert_layer , lm.map)?

    Really appreciate your kindly help and support, thanks~
    --
    chhung
  • edited November -1

    Hi chhung,

    Regarding the DISPLAY: unfortunately KLayout currently requires a DISPLAY variable even if started with -z. The reason is that Qt's QApplication object wants to have a DISPLAY when it is created, even though KLayout doesn't open a window. I don't know whether it's possible to avoid that. Until I know better, maybe it is possible to provide a X11 connection in any case. For example, if you run KLayout on a remote server without display, it may be possible to use ssh with X11 forwarding ("ssh -X ..").

    And no, it's not possible yet to load a layer mapping file directly (but that's a good suggestion). Right now, you have to parse the file using Ruby code and feed the LayerMap/Layout object with the content.

    Best regards,

    Matthias

  • edited June 2012
    Hi Matthias,

    The problem is not every users connect to workstation via XDMCP with Xserver, if they connect and run the Ruby code with telnet/rexec from Windows, they would get the message and stick on it.

    Anyway... we would try to find if any other solution to avoid that, really appreciate your kindly support and the detail explanation, thanks~

    Best Regards,
    --
    chhung
  • edited November -1

    Hi chhung,

    I see the point about the DISPLAY. It's however not easy to fix. It would be possible to provide a subset of the functionality without a DISPLAY, but that is somewhat limited (i.e it's not possible to create images from layouts). But I'll consider providing such an option in the future.

    Best regards,

    Matthias

  • edited November -1
    Hi All,

    Would "xvfb" work here?

    Regards,

    Z
  • edited November -1

    Hi Z,

    thank you for the hint. Maybe that is a solution.

    In fact, it is not important to have a working X11 server, since KLayout does not open a window in batch mode. It's only Qt which is trying to initialize itself by connecting to the server.

    Best regards,

    Matthias

  • edited November -1
    Hi, Matthias,

    There is a useful function "Adjust Origin" under the Klayout tool menu.
    I have lots of gds files have to been adjust origin to the left down corner.
    Could you please tell me how to run this function in the batch mode?

    Regards,
    Canny
  • edited August 2012

    Hi Canny,

    unfortunately not all functions are available as script methods. One of them is "adjust origin". Since it is more like a "beautification" of a cell, I did not consider it work making a script method out of that.

    However, here's a script that emulates that function:

    ly = RBA::Layout.new
    ly.read($input)
    
    cell = ly.cell(ly.cell_by_name($cell))
    bbox = cell.bbox
    trans = RBA::Trans.new(RBA::Point.new(-bbox.left, -bbox.bottom))
    
    cell.each_inst do |inst|
      cell.transform(inst, trans)
    end
    ly.layer_indices.each do |li|
      cell.shapes(li).each do |shape|
        cell.shapes(li).transform(shape, trans)
      end
    end
    
    ly.write($output)
    

    Use it with KLayout this way (assuming the script is called "adjust_origin.rb"):

    klayout -e -rd cell=TOP -rd input=x.gds -rd output=xout.gds -r adjust_origin.rb
    

    Please note the "-e" which places KLayout in edit mode (without that the script won't work).
    This sample call converts cell "TOP" of "x.gds" such that the lower left corner of the
    cell's bounding box will be located on (0,0). The result is written to xout.gds.

    Best regards,

    Matthias

  • edited November -1
    Hi, Matthias,

    Thanks for the help and your suggestion works very well.
    But I have antoher question, I tried to run layer conversion in batch mode and add some save option in the code.

    My simple RBA code is as following

    lay = RBA::Layout.new
    loadopt = RBA::LoadLayoutOptions.new
    lm = RBA::LayerMap::new
    l1 = lay.insert_layer(RBA::LayerInfo::new(1, 0))
    lm.map(RBA::LayerInfo::new(1, 0), l1)
    l2 = lay.insert_layer(RBA::LayerInfo::new(2, 0))
    lm.map(RBA::LayerInfo::new(2, 0), l2)
    loadopt.set_layer_map(lm, false)
    lay.read("test.oas", loadopt)
    saveopt = RBA::SaveLayoutOptions.new
    saveopt.no_empty_cells=true
    lay.write("test_layerconv.oas", false, saveopt)

    But the result file is always gds2 format.
    So I tried to add another save option in the last 2nd line

    saveopt.format=OASIS

    and use comment (testlayerconv.rb is the file of my code)
    klayout -e -t -z -r ./testlayerconv.rb

    it shows the error
    *** ERROR: Ruby error: 'uninitialized constant OASIS' (NameError)

    Please kindly give some hint of how to use the save option

    Regards,
    Canny
  • edited September 2012

    Hi Canny,

    the correct line is

    saveopt.format = "OASIS"
    

    (note the quotes). The format is a string, not a constant.

    The extension of the file name does not matter. In version 0.22 you can use the following function to set the format according to the file name extension:

    gzip = saveopt.set_format_from_filename(filename)
    

    Regards,

    Matthias

  • edited November -1

    Hi Matthias,

    I have a question maybe related with the topic.

    How to know the file format if open a file without file extension in klayout GUI and command mode ?

    For example:
    If I open a file named "ABC" and klayout success open that, then I click File => Layout Properties, it didn't show the format info and I don't know how to identify the format.

    Best Regards,

    chhung

  • edited November -1
    Hi Matthias,

    Thank you, and I understand it.

    Regards,
    Canny
  • edited September 2012

    Hi chhung,

    Actually there is no good way of knowing that. You can tell indirectly from the meta information in "Layout Statistics" (0.22) or "Layout Properties" (0.21): for example, a GDS file will have a "user unit" while a OASIS file has none.

    When saving, KLayout chooses the format from the file extension and explicitly asks for the format before saving the file. I did not consider it important to keep the information about the original format, but if it is, I may add a meta information to the file stating the original format.

    Best regards,

    Matthias

  • edited September 2012
    Hi, Matthias,

    I have another question of the "adjust origin like" script
    I tried to change the adjust point to bbox center and I modified the 6th line of the script

    from

    trans = RBA::Trans.new(RBA::Point.new(-bbox.left, -bbox.bottom))

    to

    trans = RBA::Trans.new(RBA::Point.new(-bbox.center, -bbox.center))

    But it shows the error message like the following
    *** ERROR: Ruby error: 'undefined method `-@' for 429100,480725:RBA::Point' (NoMethodError)

    I want to check if I make the mistake of the setting with the RBA index DBox, but the page http://www.klayout.de/rba_DBox.html seems be removed.

    Please kindly help it.

    Regards,
    Canny
  • edited September 2012

    Hi Canny,

    the documentation has been reworked in the course of the 0.22 release. The reason is that now the documentation is available both online and offline in KLayout's new help system and the RBA documentation and manual and aligned.

    You still find the old documentation under http://www.klayout.de/0.21/rba_DBox.html and the new one (for 0.22) under http://www.klayout.de/doc/code/class_DBox.html.

    Regarding your Ruby problem: I think you can solve that issue by using

    trans = RBA::Trans.new(RBA::Point.new(-bbox.center.x, -bbox.center.y))
    

    (note the .x and .y).

    Regards,

    Matthias

  • edited November -1
    Hi, Matthias,

    Very appreciate your help. I understand it.

    Regards,
    Canny
  • HI @Matthias
    ==it can be solved with Ruby, but for conversion of layout to DXF there may be a very simple alternative solution: when you build KLayout yourself, beside the "klayout" binary, some other binaries are built as well, mainly for test purposes. One of these binaries is "strm2dxf". This is a very simple tool that converts and input format to a DXF file (i.e "strm2dxf a.gds b.dxf"). The sourcecode is in strm2dxf.cc, so it can be modified if required.==

    I have downloaded the latest klayout version, but I cannot find the strm2dxf tool. Can you give me some help?

  • Earlier in the thread the desire for a PDF report got as
    far as sending to printer, not file. But at least on the
    Windows side "Save to PDF" and "Microsoft Print to
    PDF" are pretty much universal options. But tending
    to appear after the print job has gone out to the
    system print handler.

    Could a slightly more clever script change system
    printer to such an application, maybe query the path
    to save and filename to build the print-command-line,
    do the job, and get the desired report?

Sign In or Register to comment.