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
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"):
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?
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.
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
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?
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.
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
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
}
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
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)}")
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?)
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.
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
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.
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
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
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)
...
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
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.
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.
Comments
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"):
Matthias
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
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
By 'names' you mean the text string of a text you have placed at some xy location?
If so, modifying the script above gives
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?
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:
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:
If not, please give an example of the output you want.
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
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.
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
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)}")
If you want the center of the cell's bounding box then replace the x = ... and y = ... with:
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?)
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.
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
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
Anyway before going too far down that road let me know if I understand correctly.
Hi all,
@David: thanks for taking care of that again.
I'm a bit confused too. What exactly is the requirement?
Matthias
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
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
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
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):
i.e. the above are ALL bounding box centers. However you typed:
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
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.
produces:
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)
...
Play with the lines that say
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
I send you a feedback as possible
Hi phil and David,
the array resolution should be
because a is the vector which forms the "a" axis and b is the vector which forms the "b" axis.
Thanks,
Matthias
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)
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
=
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
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