How to extract the coordinates of an object or specific shape or cell from the layout?

edited October 2013 in General
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
«1

Comments

  • edited October 2013

    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

  • edited November -1
    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?
  • edited November -1

    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

  • edited August 2015
    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
  • edited August 2015

    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
    
  • edited November -1
    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?
  • edited August 2015

    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.

  • edited November -1
    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
  • edited August 2015

    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
    }
    
  • edited November -1
    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
  • edited November -1
    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)}")
  • edited November -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
    
  • edited November -1
    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?)
  • edited November -1

    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.

  • edited August 2015
    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
  • edited August 2015

    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.

  • edited November -1

    Hi all,

    @David: thanks for taking care of that again.

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

    Matthias

  • edited November -1
    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
  • edited November -1

    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

  • edited November -1
    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
  • edited August 2015

    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
    
  • edited November -1
    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)
    ...
  • edited November -1

    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

  • edited November -1
    ok thanks
    I send you a feedback as possible
  • edited August 2015

    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

  • edited November -1
    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)
  • edited November -1
    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
  • edited October 2015

    =

    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)}"
    
  • edited November -1
    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
  • edited July 2016

    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

Sign In or Register to comment.