XOR two layout without GUI

edited May 2013 in Ruby Scripting
Hi,
Thanks for great Klayout. It give us much help.
We could use Verify->XOR in GUI, loading two layouts, setup tilts, 8 threading and output to other layout. It works very well.
Now, could we use any script to do it? We have some layouts need to verify XOR and script could give us much help.
Could you show us an example? Or point us the reference documents ?

Thanks for your great klayout again.

Dion

Comments

  • edited November -1

    Hi Dion,

    I am sorry, but right now the full functionality of the XOR tool is not available through the scripting interface.

    It can be emulated by the layer processing framework for example, but without the multi-threading and tiling feature.

    It's on my schedule, but for the next major release earliest.

    Regards,

    Matthias

  • edited May 2013
    Hi Dion:
    Matthias had provided the layer_process.rbm macro file. You can detach it and follow his comment to use klayout -rm layer_process.rbm on the tools menu bar.
    http://www.klayout.de/useful_scripts.html

    Here is two layers xor example. You can detach and save as xor.rbm. Then, the xor will be shown on the menu bar tools/processing script/xor.

    ##-- script start ------
    layer_1 = "1/0"
    layer_2 = "2/0"
    result = "3/0"
    A = input(layer_1)
    B = input(layer_2)
    C = A.xor(B)
    C.output(result)
    ##---- script end ------

    Although Matthias did not recommend to use the older ruby script on version 0.22 or late, yet I still like to write the script via simple editor evinroment.
    Sincerely,
    arided
  • edited November -1

    Hi Arided,

    thanks for mentioning this. The script should work on older versions like 0.21 as well, but I'd recommend using a recent version for better performance and higher stability.

    Regards,

    Matthias

  • sebseb
    edited November -1
    Hi there,

    Sorry to dig out a old post (but as Matthias is mentionning it in his plan...) is there any update on using XOR tool via scripting?


    Thanks,
    Seb
  • edited November -1

    Hi Seb,

    The "layer processing framework" has turned into the DRC feature. XOR can be done as part of this functionality now.

    Here is a sample:

    # Performs an XOR between the first and second loaded layout
    # (from the same panel)
    # Layers listed in "layers" are considered
    
    # Layer numbers and datatypes
    layers = [
      [ 1, 0 ],
      [ 2, 0 ],
      [ 3, 0 ],
    ]
    
    l1 = layout("@1")
    l2 = layout("@2")
    
    report("XOR")
    
    layers.each do |l,d|
      (l1.input(l, d) ^ l2.input(l, d)).output("XOR #{l}/#{d}")
    end
    

    If you want the layers to be derived automatically, you can use this code:

    # Performs an XOR between the first and second loaded layout
    # (from the same panel)
    # All layers are considered
    
    l1 = layout("@1")
    l2 = layout("@2")
    
    report("XOR")
    
    layers = []
    [ l1.layout, l2.layout ].each do |layout|
      layout.layer_indices.each do |index|
        info = layout.get_info(index)
        layers << [info.layer, info.datatype ]
      end
    end
    
    layers.sort.uniq.each do |l,d|
      (l1.input(l, d) ^ l2.input(l, d)).output("XOR #{l}/#{d}")
    end
    

    Matthias

  • sebseb
    edited March 2016
    Hi Matthias,

    Thank you very much for your answer. I'm sorry to still have some (basic) questions on the XOR usage...

    As I want to run the script in command line (something like "klayout -b -r xor.rb -rd gds1=test1.gds -rd gds2=test2.gds" that output a xor.gds) I've starting to modify your example like this:

    layout = RBA::Layout::new
    layout.read($gds1)

    layout2 = RBA::Layout::new
    layout2.read($gds2)

    # Just to check that both gds are loaded
    printf("Top cell name....: %s\n", layout.top_cell.name)
    printf("Top cell name....: %s\n", layout2.top_cell.name)


    layers = []
    [ layout, layout2 ].each do |layout|
    layout.layer_indices.each do |index|
    info = layout.get_info(index)
    layers << [info.layer, info.datatype ]
    end
    end

    printf("Layers indices : %s\n", layers.sort.uniq )

    #report("XOR")

    layers.sort.uniq.each do |l,d|
    (layout.input(l, d) ^ layout2.input(l, d)).output("XOR #{l}/#{d}")
    end

    I guess that the way I load the gds is not correct because I have a complain on the report method (undefined), and if I comment it (just to go on) I have a complain on input method not defined...

    So If you can give me some tips or point me to the documentation on this feature I would be grateful :op

    Thanks,
    Seb

    Edit: Sorry can't figure out how to format quoted piece of code :o/
  • edited March 2016

    Hi seb,

    the forum uses "Markdown" markup. You can format code by adding four blanks before every line you want to quote.

    Regarding you code, you need to be careful not to mix two concepts: DRC scripts and Ruby scripts.

    If you want to run a DRC script standalone you need to save it with the suffix ".drc" and run it in KLayout like klayout -b -r xor.drc ....

    Your script is a mixture between both slangs. Basically this is possible because DRC scripts are built atop of usual Ruby scripts. However, DRC scripts use their own methods and objects which are build atop of RBA objects.

    You can see the difference for example here:

    # This is plain RBA script:
    
    layout = RBA::Layout::new
    layout.read($gds1)
    
    layout.layer_indices.each do 
      ...
    end
    
    # This is the DRC equivalent:
    
    l = layout($gds)
    l.layout.layer_indices.each do 
      ...
    end
    

    In fact, in DRC scripts, the "Layout" object is a DRC-specific layout object which - along with a RBA::Layout - carries additional information the DRC engine requires. But you can access the RBA::Layout object inside a DRC layout object with the layout method as seen in the second example above.

    Given that, the DRC code for the standalone XOR looks like this:

    # Save as "xor.drc" and run with:
    #   klayout -b -r xor.drc -rd gds1=a.gds -rd gds2=b.gds -rd out=out.gds
    #
    # Useful options:
    #
    # * verbose log:
    #   verbose 
    #
    # * enable tiling:
    #   tiles(1.mm, 1.mm)
    #
    # * use 4 cores in parallel (with tiles):
    #   threads(4)
    #
    
    l1 = layout($gds1)
    l2 = layout($gds2)
    
    target($out)
    
    layers = []
    [ l1, l2 ].each do |l|
      l.layout.layer_indices.each do |index|
        info = l.layout.get_info(index)
        layers << [info.layer, info.datatype ]
      end
    end
    
    # collect layers
    layers.sort.uniq.each do |l,d|
      log "Running XOR between #{l}/#{d} .."
      (l1.input(l, d) ^ l2.input(l, d)).output(l, d)
    end
    

    Regards,

    Matthias

  • sebseb
    edited November -1
    Hi Matthias,

    Thanks a lot, this is exactly what I was trying to do.

    Now it's more clear about DRC / Ruby script difference, should be useful for a next script.

    Regards,
    Seb
Sign In or Register to comment.