Code for the Clip Tool

edited January 2013 in Ruby Scripting
Hi

I should work with the "Clip Toll", I want to know if it possible to write this in Ruby script code that receive parameters and will automatically cut it.
could you please teach me how to write it with batch ruby script?

Regards
Lital

Comments

  • edited November -1

    Hi Lital,

    Here's some code that does this:

    input_file = "t10.gds"
    output_file = "t10_clip.gds"
    top_cell = "RINGO"
    
    clip_box = RBA::Box::new(0, 0, 5000, 5000)
    
    ly = RBA::Layout.new
    ly.read(input_file)
    
    clip_cell = ly.clip(ly.cell_by_name(top_cell), clip_box)
    
    options = RBA::SaveLayoutOptions.new
    options.add_cell(clip_cell)
    ly.write(output_file, false, options)
    

    This sample will read "t10.gds", clip a box of 5x5 micrometer from top cell "RINGO" and save the results to "t10_clip.gds". Please adjust the names and sizes.

    Save this code as "clip.rb" and run it with:

    klayout -z -r path_to/clip.rb
    

    Best regards,

    Matthias

  • edited November -1
    Hi

    First, thanks for the help and explanations.
    I want to know, is there a place where I could learn from the beginning the script language?

    And another question - In the code you gave me, Is it possible to get the points of intersection of the GDS when running the script? How can I implement this code?

    thanks a lot
    Lital
  • edited February 2013

    Hi Lital,

    there is a introduction into script programming here. You'll need some introduction into the Ruby programming language as well. There is a lot out in the net, a good starting point may be Ruby in twenty minutes.

    Regarding the second question: what do you mean by "points of intersection of the GDS"?

    Matthias

  • edited November -1
    Hi,

    Thanks for the links, I'll use them.

    What I meant to-
    in this part of the script above:
    "clip_box = RBA::Box::new(0, 0, 5000, 5000)"
    how can I change it in order to get the point "(0, 0, 5000, 5000)" - outside of the script? (maybe by send of external variables?)
    Is it possible at all?

    Thanks again
    Lital
  • edited February 2013

    Hi Lital,

    you have many choices. For example you could read them from a configuration file, get them with an input dialog etc.

    The easiest solution is to pass them in the command line, i.e.

    c = $coordinates.split(",").collect { |c| c.to_i }
    c.size == 4 || raise("Coordinate list must have four entries")
    clip_box = RBA::Box::new(*c)
    

    With this code you can pass the coordinates via the command line by defining the variable "coordinates" with the "-rd" option:

    klayout ... -rd coordinates="0,0,5000,5000"
    

    Please note that the coordinates are "xleft, ybottom, xright, ytop" in database units.

    Regards,

    Matthias

  • edited November -1
    Hi,

    Thanks again, everything is working well :-)

    Now, after clipped the GDS, I would like to do "XOR" between two clip pieces by using Ruby script, can you help me?
    I started learning Ruby, but such code is very complicated...

    Thanks
    Lital
  • edited November -1

    Hi Lital,

    here's some sketch. The basic issue is that after the clip, the cells are not necessarily aligned. You have to know how to align them.

    # assume you have two clips in cell "CLIP1" and "CLIP2"
    # with cell objects clip1 and clip2
    # coming from regions clip_box1 and clip_box2
    
    # create two temporary cells to shift the clip cells to align them
    # create a new cell
    tmp_cell1 = layout.cell(layout.add_cell("TMP1"))
    s1 = RBA::Point::new(-clip_box1.left, -clip_box1.bottom)
    tmp_cell1.insert(RBA::CellInstArray::new(clip1.cell_index, RBA::Trans::new(s1)))
    
    tmp_cell2 = layout.cell(layout.add_cell("TMP2"))
    s2 = RBA::Point::new(-clip_box2.left, -clip_box2.bottom)
    tmp_cell2.insert(RBA::CellInstArray::new(clip2.cell_index, RBA::Trans::new(s2)))
    
    # create an output cell
    out_cell = layout.cell(layout.add_cell("OUT"))
    
    # now we can use the ShapeProcessor to do the XOR:
    sp = RBA::ShapeProcessor::new
    
    layout.layer_indices.each do |li|
      sp.boolean(layout, tmp_cell1, li, layout, tmp_cell2, li, out_cell.shapes(li), RBA::EdgeProcessor::ModeXor, true, true, true)
    end
    
    # you can delete the temporary cells now ...
    

    Regards,

    matthias

  • edited November -1
    Hi Matthias

    I try now to use yours Xor code but I have some problems
    I want to use that script as own script (and not as continue for the Clip.rb)
    so I get data in this way:

    clip1= $clip1.split.collect
    clip2= $clip2.split.collect

    Is it right to do that? Do I need to do any conversion?

    What did you mean at: "coming from regions clip_box1 and clip_box2"- are the clip_box1 & clip_box2 should also be sent as external data?

    while i'm running the xor script i get that error:
    *** ERROR: NameError: undefined local variable or method `layout' for main:Object
    This mistake is about the line:
    "tmp_cell1 = layout.cell(layout.add_cell("TMP1"))"

    Do you know what is the error? (as I see it, it's should be kind of function, isn't it?)

    I would appreciate it if you could help me again

    Regards,
    Lital
  • edited November -1

    Hi Lital,

    I'm afraid I don't understand the question. What kind of objects are $clip1 and $clip2?

    "comning from" means that these cells have been created using the "clip" method. The output of the the clip method always is a new cell which holds the clipped rectangular region of the original layout.

    The code above is not a full script, it's just a sketch of the core code. You have to provide an input layout object through the "layout" variable as well as two cell objects. You can use similar to the first piece from 15th of January. In that case the layout variable was called "ly".

    Regards,

    Matthias

  • yccycc
    edited November -1
    Hi Matthias,

    I'm trying to build a script to clip gds with given box coordinates with your code in first replay.
    But I can't get full hierarchy levels in my clipped gds.
    Could you please give me some demo or instructions?

    ------ below is my code -------
    rect_drawn = RBA::Box::new($xLB.to_f, $yLB.to_f, $xRT.to_f, $yRT.to_f)
    clip_cell = layout.clip(layout.cell_by_name(topcellname), rect_drawn)
    options = RBA::SaveLayoutOptions.new
    options.add_cell(clip_cell)
    layout.write($img_dir+"/"+$output_file, false, options)
    -------------------------------
  • edited November -1

    Hi ycc,

    here is some tested code. It produces a clip from the rectangle -1mm, -1mm to +1mm, +1mm (for database unit 0.001µm). Please note that the rectangle coordinates must be given in database units:

    layout = RBA::CellView::active.layout
    
    clip_rect = RBA::Box::new(-1000000, -1000000, 1000000, 1000000)
    clip_cell = layout.clip(layout.cell("TOP").cell_index, clip_rect)
    options = RBA::SaveLayoutOptions.new
    options.add_cell(clip_cell)
    layout.write("clip.gds", false, options)
    

    This code produces hierarchical clips. It looks pretty close to your code, so I wonder what's wrong. Maybe the rectangle coordinate are not given in database units?

    Matthias

  • edited November -1
    Hi Matthias,

    I tryed your last code and it's working for me without the last line.
    I have a new cell TOP$1 when I run the code.

    But if I activate the last line I have an error (errono=13) in Layout::write (Class RuntimeError).
    The probleme is that Klayout can't open the file "clip.gds".

    Regards,
    euzada
  • edited November -1

    Hi,

    please replace the file name by a valid path - without any path, the program will probably try to write to the installation directory which does not make a lot of sense.

    The new top cell is always created. If you don't want to have this cell, you can try using "clip_into" which allows clipping into a new layout.

    Matthias

Sign In or Register to comment.