Not signed in (Sign In)

Vanilla 1.1.4 is a product of Lussumo. More Information: Documentation, Community Support.

    • CommentAuthorjerry3k
    • CommentTimeOct 16th 2013
     
    I have a die populated 12000 times on a layout and struggling to extract the coordinates to txt file which can be used for probing these devices!
    Any suggestions, scripts etc.
    THanks
    • CommentAuthorMatthias
    • CommentTimeOct 17th 2013 edited
     

    Hi,

    you'll always need some probe shape in your die cell that defines that point you want to measure your location at. A text will do, but you can use box as well. Then the following script prints the coordinates of the centers of that probe shape (I assume, it is on layer 1, datatype 0 and your top cell is "TOP"):

    ly = RBA::Application::instance.main_window.current_view.active_cellview.layout
    
    layer = 1
    datatype = 0
    topcell = "TOP"
    
    input = ly.layer_indices.find { |li| lp = ly.get_info(li); lp.layer == layer && lp.datatype = datatype }
    input || raise("Input layer not found")
    
    si = ly.cell(ly.cell_by_name(topcell)).begin_shapes_rec(input)
    while !si.at_end?
      bbox = si.shape.bbox.transformed(si.trans)
      puts "#{'%.3f'%(bbox.center.x*ly.dbu)},#{'%.3f'%(bbox.center.y*ly.dbu)}"
      si.next
    end
    

    Matthias

    • CommentAuthoractivcirk
    • CommentTimeOct 21st 2014
     
    Could you explain a bit more what you mean by probe shape? Are you saying to put a box on an unused layer on the locations that the probes will hit? Is it possible to associate a name with the location, like "circuit1", "circuit2", etc?
    • CommentAuthorMatthias
    • CommentTimeOct 21st 2014
     

    Yes, a box can serve as such a probe shape. You should use an unused layer so you don't interfere with mask or other layout.

    Texts (Labels) provide a way to convey more information than just a coordinate. In addition to their position they carry a text string and a orientation. In the above example "si.shape.is_text?" can be used to ask whether the probe shape is a text. In that case, you can ask the text Shape object for the text string (si.shape.text_string) and the text's position and orientation in it's containing cell (si.shape.text_trans).

    In addition, texts are often neutral with respect to mask layout, so it may be possible to add them on an existing mask layer.

    Matthias

    • CommentAuthorphil
    • CommentTimeAug 5th 2015 edited
     
    hello
    I'd like using the same script to extract coordinates and names of features from a GDS .
    this script is fine to have coordinates , but I 'm unable to modify it to have coordinates AND names.
    Could you explain to have both at the same time?
    thanks
    phil
    • CommentAuthordavidnhutch
    • CommentTimeAug 5th 2015 edited
     

    By 'names' you mean the text string of a text you have placed at some xy location?

    If so, modifying the script above gives

    ly = RBA::Application::instance.main_window.current_view.active_cellview.layout
    
    layer = 1
    datatype = 0
    topcell = "TOP"
    
    input = ly.layer_indices.find { |li| lp = ly.get_info(li); lp.layer == layer && lp.datatype = datatype }
    input || raise("Input layer not found")
    
    si = ly.cell(ly.cell_by_name(topcell)).begin_shapes_rec(input)
    
    si.next if !si.shape.is_text? # If it's not a text then skip it
    
    # Otherwise, display its string and xy location
    while !si.at_end?
      bbox = si.shape.bbox.transformed(si.trans)
      string = si.shape.text_string
      puts "#{string}: #{'%.3f'%(bbox.center.x*ly.dbu)},#{'%.3f'%(bbox.center.y*ly.dbu)}"
      si.next
    end
    
    • CommentAuthorphil
    • CommentTimeAug 6th 2015
     
    ok thanks
    it is what I want....but it's not working for my project
    I'm not very familiar with Klayout and ruby..sorry
    In fact , I want to have , in this example for "TOP" , names of cell , under "TOP" in the hierarchy and coordinates
    However , I have all coordinates.
    I don't know if it's possible?
    • CommentAuthordavidnhutch
    • CommentTimeAug 6th 2015 edited
     

    I am still not sure I understand. So you want text strings and positions or you want cell (actually instance) positions?

    If the latter, So let's say you have "TOP" and instanced several times you have cell "CHILD1" and again instanced several times you have cell "CHILD2". So you want to print out the CHILD1 and CHILD2 coordinates? Something like:

    CHILD1 instance found at (123,456)
    CHILD1 instance found at (111,222)
    CHILD2 instance found at (1,2)
    ...
    

    Or do you mean you want the text strings and coords, but you want them to be grouped by the cell they appear in? Something like:

    In CHILD1 I found a text, string = "blah", at (12,3)
    In CHILD2 I found a text, string = "another one", at (4,5)
    ...
    

    If not, please give an example of the output you want.

    • CommentAuthorphil
    • CommentTimeAug 6th 2015
     
    ok
    I want something like that

    CHILD1 instance found at (123,456)
    CHILD1 instance found at (111,222)
    CHILD2 instance found at (1,2)
    ...
    my aim is to provide to my stepper guys a file with all feature and coordinates from a GDS to make stepper job.
    our GDS are "simply".
    sometimes one cell , like "TOP" with features in

    cells

    TOP
    long
    right
    big
    etc...
    and this , for 1 to 5 layers

    long instance found at (123,456)
    long instance found at (111,222)
    big instance found at (1,2)
    big instance found at (2,2)
    big instance found at (3,2)
    big instance found at (4,2)
    rignt instance found at (1,2)
    etc...
    we could have 600 features positions

    phil
    • CommentAuthordavidnhutch
    • CommentTimeAug 6th 2015 edited
     

    I see, sorry. Then I'd do it this way. This iterates over the child instances, so it will get CHILD1 and CHILD2 but not GRANDCHILD1 etc.

    ly = RBA::Application::instance.main_window.current_view.active_cellview.layout
    
    topcell = "TOP"
    
    parent_cell = ly.cell(ly.cell_by_name(topcell))
    
    parent_cell.each_inst { |inst| # Iterate over all the child instances
      x = inst.trans.disp.x
      y = inst.trans.disp.y
      name = inst.cell.name
      puts "#{name} at #{'%.3f'%(x*ly.dbu)}, #{'%.3f'%(y*ly.dbu)}" # multiply by dbu in order to print coords in micron
    }
    
    • CommentAuthorphil
    • CommentTimeAug 6th 2015
     
    OK just one thing again
    as it's for stepper , I need one file by level ( for each photo level)
    is it possible to add it?
    previous is right , missing just to use it by level.( I need to lauch macro as manytime as I have levels in my GDS - OK for me)
    many thanks
    phil
    • CommentAuthorphil
    • CommentTimeAug 6th 2015
     
    again me
    I prefer to have center of feature
    with first version , it was OK
    (bbox = si.shape.bbox.transformed(si.trans)
    puts "#{'%.3f'%(bbox.center.x*ly.dbu)},#{'%.3f'%(bbox.center.y*ly.dbu)}")
  1.  

    If you want the center of the cell's bounding box then replace the x = ... and y = ... with:

    x = inst.bbox.center.x
    y = inst.bbox.center.y
    
    • CommentAuthorphil
    • CommentTimeAug 6th 2015
     
    thanks,it's OK for 99% of my features

    I'm seeing a other pb for the other 1%

    when we created a GDS , sometimes we took a group of features with mouse and copy them changing coordinates.
    in this case, all created features have the same coordinates
    with the macro,I have only one information about this feature and its postion is wrong (in real I have 1O diffents features
    I have some informations when I click on the feature:
    - position of cell origin
    - array instance (row/column)

    is it possible with these information to retrieve coordinates of all my same feature ( make by array row/column 5x6 for example?)
  2.  

    Your question is not clear to me. Is it possible for you to upload a simple test GDS file somewhere and post a link?

    Then, tell me the expected output of the script. Then I can bridge the gap.

    • CommentAuthorphil
    • CommentTimeAug 7th 2015 edited
     
    ok
    this is an example
    you can see that all cell name "test" has same position
    difference is done by array


    https://e-nautia.com/share/17328-xc2hbr8u
    • CommentAuthordavidnhutch
    • CommentTimeAug 7th 2015 edited
     

    Thanks. So to confirm, you want it to report 5*6 = 30 xy locations, where each location is the centerx and centery of one of the elements of the "Test" array?

    There is no one-line solution I think - these will have to be calculated based on the bottom-left instance's xy. So if the bottom-left instance has 'centerx' and 'centery' then the x,y of the i-th, j-th instance is something like

    num_rows.times{ |i| 
      num_cols.times{ |j|
        x = centerx + pitch*j
        y = centery + pitch*i
      }
    }
    

    Anyway before going too far down that road let me know if I understand correctly.

    • CommentAuthorMatthias
    • CommentTimeAug 7th 2015
     

    Hi all,

    @David: thanks for taking care of that again.

    I'm a bit confused too. What exactly is the requirement?

    Matthias

    • CommentAuthorphil
    • CommentTimeAug 17th 2015
     
    hi sorry I was on holidays
    the requirement is to have all coordinates ( center x:y) of any cells from a gds
    problem is that designer create gds by cut and copy ( with some features )and all this features have same x:y
    the only difference is in information about cell when we click on it:

    - position of cell origin --> same
    - array instance (row/column)--> different

    my question is : is it possible to have the "True coordinates" of all cells?

    I think that David's comment is in the good way
    thanks
    phil
  3.  

    Hi Phil,

    Sorry, it's still not clear to me.. If you could just manually type out the desired output from a small & simple test gds file, that would help.

    For example, you could take the test file you linked to earlier (or, preferably, one even simpler than that), then manually type what you want the output to be. (e.g. "I want the output to be: Cell1 @ (0,100); Cell2 @ (100,200); Cell2 @ (300,300), ..."

    Then I can see the test gds file, I can see the desired output, and I or someone else can tell you how to get from one to the other.

    Thanks,

    David

    • CommentAuthorphil
    • CommentTimeAug 17th 2015
     
    ok
    I want this output

    Test at 0.000, -0.035
    Test at 100.000, -0.035
    Test at 2000.000, -0.035
    Test at 50000.000, -0.035
    carP2 at -132125.840, -107.160
    carP2 at -123218.480, -107.160
    carP2 at -114311.120, -107.160
    carP2 at -105403.760, -107.160
    carP2 at -96496.400, -107.160
    carP2 at -87589.040, -107.160
    carP2 at -78681.680, -107.160
    carP2 at -69774.320, -107.160
    carP2 at -60866.960, -107.160
    carP2 at -51959.600, -107.160

    link for gds :
    https://e-nautia.com/share/18354-lnhl158g

    in this gds , we have 2 cells:
    carP2 --> OK for all positions , previous macros find them
    TEST --> 30 diffents positions to find

    phil
    • CommentAuthordavidnhutch
    • CommentTimeAug 19th 2015 edited
     

    I understand now. Any time there is an instance array rather than just an instance, you want each of the array elements' positions.

    It's possible there is a slight inconsistency in the desired output you typed. If you manually break the array into elements via the GUI and just run the original code you get the following (though possibly in a different order):

    Test at -124331.9, -0.035
    Test at -124331.9, 55711.475
    Test at -124331.9, 111422.985
    Test at -124331.9, -111423.055
    Test at -124331.9, -55711.545
    Test at -74599.14, -0.035
    Test at -74599.14, 55711.475
    Test at -74599.14, 111422.985
    Test at -74599.14, -111423.055
    Test at -74599.14, -55711.545
    Test at -24866.38, -111423.055
    Test at -24866.38, -55711.545
    Test at -24866.38, -0.035
    Test at -24866.38, 55711.475
    Test at -24866.38, 111422.985
    Test at 24866.38, -111423.055
    Test at 24866.38, -55711.545
    Test at 24866.38, -0.035
    Test at 24866.38, 55711.475
    Test at 24866.38, 111422.985
    Test at 74599.14, -0.035
    Test at 74599.14, 55711.475
    Test at 74599.14, 111422.985
    Test at 74599.14, -111423.055
    Test at 74599.14, -55711.545
    Test at 124331.9, -0.035
    Test at 124331.9, 55711.475
    Test at 124331.9, 111422.985
    Test at 124331.9, -111423.055
    Test at 124331.9, -55711.545
    carP2 at -132125.840, -107.160
    carP2 at -123218.480, -107.160
    carP2 at -114311.120, -107.160
    carP2 at -105403.760, -107.160
    carP2 at -96496.400, -107.160
    carP2 at -87589.040, -107.160
    carP2 at -78681.680, -107.160
    carP2 at -69774.320, -107.160
    carP2 at -60866.960, -107.160
    carP2 at -51959.600, -107.160
    ...
    

    i.e. the above are ALL bounding box centers. However you typed:

    Test at 0.000, -0.035
    Test at 100.000, -0.035
    Test at 2000.000, -0.035
    Test at 50000.000, -0.035
    ...
    

    When I compare this to the GDS it appears that you are looking for the array elements' origins rather than bounding box center, because that's the only way you can get a value of (0.000, -0.035).

    Anyway here is the code and it assumes you want the instance bbox center but the instance array elements' origins. If that was a typo and you truly want the bounding box centers in all cases, you can modify it.

    Please check my math in the

    x = x0 + a.x*j + a.y*j
    y = y0 + b.x*i + b.y*i
    

    lines, I'm not 100% sure I have that correct. For example you might want to swap the i's and j's, I haven't carefully checked. But at least now you have the general idea of how to use "inst.is_regular_array?" and can modify it for your purposes.

    ly = RBA::Application::instance.main_window.current_view.active_cellview.layout
    
    topcell = "gds"
    parent_cell = ly.cell(ly.cell_by_name(topcell))
    
    parent_cell.each_inst { |inst| # Iterate over all the child instances
    
      if inst.is_regular_array?
    
        a,b,na,nb = inst.a, inst.b, inst.na, inst.nb
        x0,y0 = inst.bbox.center.x, inst.bbox.center.y # The xy position of the primary (bottom-left in this case) element
    
        na.times { |i|
          nb.times { |j|
    
            x = x0 + a.x*j + a.y*j
            y = y0 + b.x*i + b.y*i
            puts "#{inst.cell.name} at #{'%.3f'%(x*ly.dbu)}, #{'%.3f'%(y*ly.dbu)}"
    
          }
        }
    
      else
        x = inst.bbox.center.x
        y = inst.bbox.center.y
        puts "#{inst.cell.name} at #{'%.3f'%(x*ly.dbu)}, #{'%.3f'%(y*ly.dbu)}"
      end
    
    }
    

    produces:

    carP2 at -132125.840, -107.160
    carP2 at -123218.480, -107.160
    carP2 at -114311.120, -107.160
    carP2 at -105403.760, -107.160
    carP2 at -96496.400, -107.160
    carP2 at -87589.040, -107.160
    carP2 at -78681.680, -107.160
    carP2 at -69774.320, -107.160
    carP2 at -60866.960, -107.160
    carP2 at -51959.600, -107.160
    carP2 at -36371.720, -107.160
    carP2 at -27464.360, -107.160
    carP2 at -18557.000, -107.160
    carP2 at -9649.640, -107.160
    carP2 at -742.280, -107.160
    carP2 at 8165.080, -107.160
    carP2 at 17072.440, -107.160
    carP2 at 25979.800, -107.160
    carP2 at 34887.160, -107.160
    carP2 at 43794.520, -107.160
    carP2 at 59382.400, -107.160
    carP2 at 68289.760, -107.160
    carP2 at 77197.120, -107.160
    carP2 at 86104.480, -107.160
    carP2 at 95011.840, -107.160
    carP2 at 103919.200, -107.160
    carP2 at 112826.560, -107.160
    carP2 at 121733.920, -107.160
    carP2 at 130641.280, -107.160
    carP2 at 139548.640, -107.160
    Test at 0.000, -0.035
    Test at 55711.510, -0.035
    Test at 111423.020, -0.035
    Test at 167134.530, -0.035
    Test at 222846.040, -0.035
    Test at 278557.550, -0.035
    Test at 0.000, 49732.725
    Test at 55711.510, 49732.725
    Test at 111423.020, 49732.725
    Test at 167134.530, 49732.725
    Test at 222846.040, 49732.725
    Test at 278557.550, 49732.725
    Test at 0.000, 99465.485
    Test at 55711.510, 99465.485
    Test at 111423.020, 99465.485
    Test at 167134.530, 99465.485
    Test at 222846.040, 99465.485
    Test at 278557.550, 99465.485
    Test at 0.000, 149198.245
    Test at 55711.510, 149198.245
    Test at 111423.020, 149198.245
    Test at 167134.530, 149198.245
    Test at 222846.040, 149198.245
    Test at 278557.550, 149198.245
    Test at 0.000, 198931.005
    Test at 55711.510, 198931.005
    Test at 111423.020, 198931.005
    Test at 167134.530, 198931.005
    Test at 222846.040, 198931.005
    Test at 278557.550, 198931.005
    carP2 at 25979.800, 55604.340
    carP2 at 34887.160, 55604.340
    carP2 at 43794.520, 55604.340
    carP2 at 8165.080, 111315.840
    carP2 at 17072.440, 111315.840
    carP2 at 25979.800, 111315.840
    carP2 at 34887.160, 111315.840
    carP2 at 43794.520, 111315.840
    carP2 at 59382.400, 55604.340
    carP2 at 68289.760, 55604.340
    carP2 at 77197.120, 55604.340
    carP2 at 86104.480, 55604.340
    carP2 at 95011.840, 55604.340
    carP2 at 103919.200, 55604.340
    carP2 at 112826.560, 55604.340
    carP2 at 121733.920, 55604.340
    carP2 at 130641.280, 55604.340
    carP2 at 139548.640, 55604.340
    carP2 at 59382.400, 111315.840
    carP2 at 68289.760, 111315.840
    carP2 at 77197.120, 111315.840
    carP2 at 86104.480, 111315.840
    carP2 at 95011.840, 111315.840
    carP2 at 103919.200, 111315.840
    carP2 at 112826.560, 111315.840
    carP2 at 121733.920, 111315.840
    carP2 at 130641.280, 111315.840
    carP2 at 139548.640, 111315.840
    carP2 at 8165.080, 55604.340
    carP2 at 17072.440, 55604.340
    carP2 at -96496.400, 111315.840
    carP2 at -87589.040, 111315.840
    carP2 at -78681.680, 111315.840
    carP2 at -69774.320, 111315.840
    carP2 at -36371.720, 55604.340
    carP2 at -27464.360, 55604.340
    carP2 at -18557.000, 55604.340
    carP2 at -9649.640, 55604.340
    carP2 at -742.280, 55604.340
    carP2 at -36371.720, 111315.840
    carP2 at -27464.360, 111315.840
    carP2 at -18557.000, 111315.840
    carP2 at -9649.640, 111315.840
    carP2 at -742.280, 111315.840
    carP2 at -60866.960, 55604.340
    carP2 at -51959.600, 55604.340
    carP2 at -60866.960, 111315.840
    carP2 at -51959.600, 111315.840
    carP2 at -132125.840, 55604.340
    carP2 at -123218.480, 55604.340
    carP2 at -114311.120, 55604.340
    carP2 at -105403.760, 55604.340
    carP2 at -96496.400, 55604.340
    carP2 at -87589.040, 55604.340
    carP2 at -78681.680, 55604.340
    carP2 at -69774.320, 55604.340
    carP2 at -132125.840, 111315.840
    carP2 at -123218.480, 111315.840
    carP2 at -114311.120, 111315.840
    carP2 at -105403.760, 111315.840
    carP2 at -123218.480, -111530.160
    carP2 at -114311.120, -111530.160
    carP2 at -105403.760, -111530.160
    carP2 at -96496.400, -111530.160
    carP2 at -87589.040, -111530.160
    carP2 at -78681.680, -111530.160
    carP2 at -69774.320, -111530.160
    carP2 at -132125.840, -55818.660
    carP2 at -123218.480, -55818.660
    carP2 at -114311.120, -55818.660
    carP2 at -105403.760, -55818.660
    carP2 at -60866.960, -111530.160
    carP2 at -36371.720, -111530.160
    carP2 at -27464.360, -111530.160
    carP2 at -18557.000, -111530.160
    carP2 at -9649.640, -111530.160
    carP2 at -742.280, -111530.160
    carP2 at -36371.720, -55818.660
    carP2 at -27464.360, -55818.660
    carP2 at -18557.000, -55818.660
    carP2 at -9649.640, -55818.660
    carP2 at -742.280, -55818.660
    carP2 at -51959.600, -111530.160
    carP2 at -60866.960, -55818.660
    carP2 at -51959.600, -55818.660
    carP2 at -96496.400, -55818.660
    carP2 at -87589.040, -55818.660
    carP2 at -78681.680, -55818.660
    carP2 at -69774.320, -55818.660
    carP2 at -132125.840, -111530.160
    carP2 at 68289.760, -111530.160
    carP2 at 77197.120, -111530.160
    carP2 at 86104.480, -111530.160
    carP2 at 95011.840, -111530.160
    carP2 at 103919.200, -111530.160
    carP2 at 112826.560, -111530.160
    carP2 at 121733.920, -111530.160
    carP2 at 130641.280, -111530.160
    carP2 at 139548.640, -111530.160
    carP2 at 59382.400, -55818.660
    carP2 at 68289.760, -55818.660
    carP2 at 77197.120, -55818.660
    carP2 at 86104.480, -55818.660
    carP2 at 95011.840, -55818.660
    carP2 at 103919.200, -55818.660
    carP2 at 112826.560, -55818.660
    carP2 at 121733.920, -55818.660
    carP2 at 130641.280, -55818.660
    carP2 at 139548.640, -55818.660
    carP2 at 8165.080, -55818.660
    carP2 at 17072.440, -55818.660
    carP2 at 25979.800, -55818.660
    carP2 at 34887.160, -55818.660
    carP2 at 43794.520, -55818.660
    carP2 at 8165.080, -111530.160
    carP2 at 17072.440, -111530.160
    carP2 at 25979.800, -111530.160
    carP2 at 34887.160, -111530.160
    carP2 at 43794.520, -111530.160
    carP2 at 59382.400, -111530.160
    
    • CommentAuthorphil
    • CommentTimeAug 19th 2015
     
    hi
    I think that last datas aren't good.

    this one, first seems OK
    (Test at -124331.9, -0.035
    Test at -124331.9, 55711.475
    Test at -124331.9, 111422.985
    Test at -124331.9, -111423.055
    Test at -124331.9, -55711.545
    Test at -74599.14, -0.035
    Test at -74599.14, 55711.475
    Test at -74599.14, 111422.985
    Test at -74599.14, -111423.055
    Test at -74599.14, -55711.545
    Test at -24866.38, -111423.055
    Test at -24866.38, -55711.545
    Test at -24866.38, -0.035
    Test at -24866.38, 55711.475
    Test at -24866.38, 111422.985
    Test at 24866.38, -111423.055
    Test at 24866.38, -55711.545
    Test at 24866.38, -0.035
    Test at 24866.38, 55711.475
    Test at 24866.38, 111422.985
    Test at 74599.14, -0.035
    Test at 74599.14, 55711.475
    Test at 74599.14, 111422.985
    Test at 74599.14, -111423.055
    Test at 74599.14, -55711.545
    Test at 124331.9, -0.035
    Test at 124331.9, 55711.475
    Test at 124331.9, 111422.985
    Test at 124331.9, -111423.055
    Test at 124331.9, -55711.545)

    this datas not:
    (Test at 55711.510, -0.035
    Test at 111423.020, -0.035
    Test at 167134.530, -0.035
    Test at 222846.040, -0.035
    Test at 278557.550, -0.035
    Test at 0.000, 49732.725
    Test at 55711.510, 49732.725
    Test at 111423.020, 49732.725
    Test at 167134.530, 49732.725
    Test at 222846.040, 49732.725
    Test at 278557.550, 49732.725)


    because datas are between -/+150000 ; it seems that your first version is good.

    I write this , just to provide you an example , datas are wrong
    (i.e. the above are ALL bounding box centers. However you typed:
    Test at 0.000, -0.035
    Test at 100.000, -0.035
    Test at 2000.000, -0.035
    Test at 50000.000, -0.035)
    ...
  4.  

    Play with the lines that say

    x = x0 + a.x*j + a.y*j
    y = y0 + b.x*i + b.y*i
    

    I must have it calculated wrong.

    x0, y0 is the position of the bottom-left one.

    a is the row vector (consists of x and y numbers. To get the x number you just use a.x as you see above, etc.)

    b is the col vector (consists of x and y numbers)

    na is the number in the row direction

    nb is the number in the column direction.

    If you play with those lines and correct my sloppy work :-) I think it will surely work

    • CommentAuthorphil
    • CommentTimeAug 21st 2015
     
    ok thanks
    I send you a feedback as possible
    • CommentAuthorMatthias
    • CommentTimeAug 24th 2015 edited
     

    Hi phil and David,

    the array resolution should be

    x = x0 + a.x*i + b.x*j
    y = y0 + a.y*i + b.y*j
    

    because a is the vector which forms the "a" axis and b is the vector which forms the "b" axis.

    Thanks,

    Matthias

    • CommentAuthorphil
    • CommentTimeSep 10th 2015
     
    hi
    it's OK for me
    I tested the script on a real GDS , and the results are good.
    maybe I could optimized the macro with the size of each cell.

    cell TOP = center ( 75.000 ; 54.000 ) and cell size ( 12 ; 5.7)
    • CommentAuthorphil
    • CommentTimeOct 1st 2015
     
    Hi
    I'd like to add boxes size to the following code : height and width

    ************************************

    ly = RBA::Application::instance.main_window.current_view.active_cellview.layout

    topcell = "TOP"

    parent_cell = ly.cell(ly.cell_by_name(topcell))

    parent_cell.each_inst { |inst| # Iterate over all the child instances
    x = inst.trans.disp.x
    y = inst.trans.disp.y
    name = inst.cell.name
    puts "#{name} at #{'%.3f'%(x*ly.dbu)}, #{'%.3f'%(y*ly.dbu)}" # multiply by dbu in order to print coords in micron
    }
    **************************************
    output will be something like that:

    cell at -3653.000, -2773.000 ; witdh (x) = 2233 and height (y) = 555555


    thanks for your help
    • CommentAuthordavidnhutch
    • CommentTimeOct 2nd 2015 edited
     

    =

    w = inst.bbox.width
    h = inst.bbox.height
    puts "#{name} at #{'%.3f'%(x*ly.dbu)}, #{'%.3f'%(y*ly.dbu)} ; width (x) = #{'%.3f'%(w*ly.dbu)} and height (y) = #{'%.3f'%(h*ly.dbu)}"
    
    • CommentAuthorvikasg
    • CommentTimeJul 15th 2016
     
    Hi All,

    I wanted to request some help on this already lengthy exchange. I was able to use the code that Matthias posted on Oct 17th 2013 with a slight modification based on the exchange after that:

    si = ly.cell(ly.cell_by_name(topcell)).begin_shapes_rec(input)
    while !si.at_end?
    bbox = si.shape.bbox.transformed(si.trans)
    name = si.cell.name
    puts "#{name},#{'%.3f'%(bbox.center.x*ly.dbu)},#{'%.3f'%(bbox.center.y*ly.dbu)}"
    si.next
    end

    In the code above, I have added in the "name" of the cell where the shape was found. Unfortunately this code only gives me the final leaf cell name where the shape on the layer requested was found. Hence this reports as follows:

    Final Leaf Cell 1, centerx1, centery1
    Final Leaf Cell 2, centerx2, centery2
    etc.

    I was looking to list down the entire path from the top cell to the final leaf cell for the shape found. For e.g.

    Top Cell: Cell Level 1: Cell Level 2: Cell Level 3: Final Leaf Cell 1, centerx1, centery1
    Top Cell: Cell Level 1: Cell Level 2: Final Leaf Cell2, centerx2, centery2
    etc.

    As can be seen from example above, the different leaf cells may be in different levels of hierarchy in the GDS.

    I tried looking for a method under the Cell class to see if there was any way of reporting the hierarchy of the cell. Unfortunately I have not been successful and any help would be much appreciated.

    Thanks,

    Vikas
    • CommentAuthorMatthias
    • CommentTimeJul 18th 2016 edited
     

    Hi Vikas,

    please see my mail. Here is my reply for others:

    The RecursiveShapeIterator does not have a feature to access the instantiation path, although internally this information is available. You have access to the combined transformation along that path, but if you need to full instantiation path, you'll need to code the shape iteration explicitly: iterate the shapes on the top cell, then repeat the process for each child, applying the child's instance transformation to the shapes of the children. Recursively descend into the hierarchy any you will get the same results than for the RecursiveShapeIterator, but with a chance to report the instantiation path.

    Matthias

    • CommentAuthorvikasg
    • CommentTimeJul 20th 2016
     
    I was able to make some progress on this with some help from pieces of code found on the site and on-line. I wanted to specifically attribute the basic code to what I found on the following link and in this chain:
    http://www.klayout.org/svn-public/klayout-resources/trunk/scripts/write_childcells.rbm

    I am posting the code for which I still need some help. The code below reports the branch cell (2nd level of hierarchy) and the final leaf cell with the x & y center of the layer shapes for the layer index = 32. Unfortunately, the x & y center is with respect to the branch cell instantiation rather than the top cell instantiation. I think I have already killed a lot of brain cells reaching this point and was hoping that someone could point to the "trivial" change I am missing and need to make to report the x & y with respect to the top cell instead of the branch cell.

    Thanks,

    Vikas

    mw = RBA::Application::instance.main_window
    lv = mw.current_view # layout view
    ly = lv.active_cellview.layout # layout
    cv = lv.cellview(lv.active_cellview_index)

    level = 2
    cells_to_write = {} # defined as a hash
    layer = 100 # layer index = 32 which is hard coded for now below
    datatype = 0

    # input = ly.layer_indices.find { |li| lp = ly.get_info(li); lp.layer == layer && lp.datatype = datatype }

    def get_cells_at_hierarchy_level(layout, from_cell, level, cells)
    from_cell.each_child_cell do |cc|
    input = 32
    si = layout.cell(layout.cell_name(cc)).begin_shapes_rec(input)
    while !si.at_end?
    bbox = si.shape.bbox.transformed(si.trans)
    name = si.cell.name
    puts "#{layout.cell_name(cc)}, #{name}, #{'%.3f'%(bbox.center.x*layout.dbu)}, #{'%.3f'%(bbox.center.y*layout.dbu)}"
    si.next
    end
    if level == 1
    cells[cc] = 1
    else
    get_cells_at_hierarchy_level(layout, layout.cell(cc), level - 1, cells)
    end
    end
    end

    get_cells_at_hierarchy_level(cv.layout, cv.cell, level, cells_to_write)
    • CommentAuthorMatthias
    • CommentTimeJul 28th 2016 edited
     

    Hi Vikas,

    The code is hard to read since it lacks the indents (hint: use four blanks in front of each line that are supposed to be formatted as code).

    But basically the code is quite good. You just need to add the following:

    1.) To get the layer index for a given layer/datatype pair, use layer_index = ly.layer(layer, datatype)

    2.) Add a current-cell to top-cell transformation to the get_cells_at_hierarchy_level method. For the top cell, this transformation is unity:

    def get_cells_at_hierarchy_level(layout, from_cell, level, cells, trans)
      ..
    end
    
    # use a unity transformation for the top cell
    get_cells_at_hierarchy_level(cv.layout, cv.cell, level, cells_to_write, RBA::CplxTrans::new)
    

    3.) Iterate over instances instead of the child cells:

    from_cell.each_inst do |inst|
      cell = inst.cell
      ..
    end
    

    When a cell is instantiated twice, you will visit this cell two times. each_child_cell only does so once.

    4.) Inside this function when you call get_cells_at_hierarchy_level recursively combine the given transformation with that of the instance:

    get_cells_at_hierarchy_level(layout, layout.cell(cc), level - 1, cells, trans * inst.cplx_trans)
    

    5.) You don't need to recursively iterate over the shapes, since you have coded the same yourself:

    cell.shapes(layer_index).each do |s|
      bbox = s.bbox.transformed(trans)
      name = cell.name
      ... print bbox, cell name etc. ...
    end
    

    Matthias

    • CommentAuthorvikasg
    • CommentTimeAug 5th 2016
     
    Danke Matthias!
    • CommentAuthorVaVoom
    • CommentTimeJun 23rd 2017
     
    How can you adapt the code to extract the lower left and upper right x,y coordinates (in the Box Properties)? I tried replacing center with lower.left as well as upper.right and it didn't work.

    puts "#{'%.3f'%(bbox.center.x*ly.dbu)},#{'%.3f'%(bbox.center.y*ly.dbu)}"

    replace with:
    puts "#{'%.3f'%(bbox.lower.left.x*ly.dbu)},#{'%.3f'%(bbox.lower.left.y*ly.dbu)}"

    Basically, I'm trying to extract the corners coordinates of my bond pads from the GDS.

    Thanks!