Hi
I am trying to write a code to iterate through all texts in a GDS and deliver global coordinates as well as the full path within the GDS hierarchy.
The 1st assignment is easy using the begin_shapes iterator, and it works well.
iter = active_layout.begin_shapes(active_layout.top_cell.cell_index, layer.current.layer_index) # RecursiveShapeIterator
while !iter.at_end?
if iter.shape.is_text?
t = iter.shape.text.transformed(iter.itrans) # t is the text transformed into the top cell:
TextObjRefArray.addCoordinates(iter.shape,(t.trans.disp.x*active_layout.dbu).to_s,(t.trans.disp.y*active_layout.dbu).to_s)
TextObjRefArray.addTxt(iter.shape,iter.shape.text.string)
end #if
iter.next
end #while
….
However, once finding a text shape and its global coordinates, I don’t find a way to tell its full path (recall that a single shape can be called from many combinations in the hierarchy path. I want only the single, correct one.)
I also tried to go the other way, writing a recursive function to iterate through the hierarcy tree and locate all texts. That worked, but then, I could not get global transformation easily.
Is there a solution for that?
Thank!
Allon
PS: Using Klayout revision 0.23.1
Comments
Hi Allon,
the
RecusiveShapeIterator
keeps the path internally, but right now it's not accessible through Ruby. Writing your own recursive search is a feasible solution for this problem.To get the global transformation you just need to multiple all transformations leading to the cell the text is contained in:
Here
trans1
is the transformation of the first instance (top cell to first child),trans2
the one leading from the first child to the second and so on.Matthias
Just for reference, here is what I have in mind (it seems to be working on klayout 0.23.1)
I guess this is your intension, right?
Any helpful comment you have in mind?
module ListLabels
include RBA
def ListLabels.getLabels_ver2(aLayout, anInstance, textLayerIndex,parentPath="",aTrans=RBA::Trans::new(0,false,0,0)) #returns cell objects of a cell
# function that iterates through the GDS file, and extract the labels:
# aLayout is an object of class Layout
# anInstance is an Intance object. It can get either the topcell Cell instsance and later on Instance objects
# textLayerIndex is an integer number pointing to the layer index in the corresponding layout view
# parentPath is a text with the path of the parent cell
#convert anInstance to cell in order to support topcell
if anInstance.class.to_s == "RBA::Cell"
aCell=anInstance
else
aCell=anInstance.cell
end #if
aCell.each_shape(textLayerIndex) do |shape|
if shape.is_text?
$aFile.puts "#{shape.text.string} ; #{(aTrans*shape.text.trans).disp.x*aLayout.dbu}; #{(aTrans*shape.text.trans).disp.y*aLayout.dbu} ; #{parentPath}"
end #if
end #shape iterator
if aCell.child_instances >0
aCell.each_inst {|anInstanceIterator| getLabels_ver2(aLayout,anInstanceIterator,textLayerIndex,parentPath+"|"+anInstanceIterator.cell.name,aTrans*anInstanceIterator.cplx_trans.s_trans)}
end
end #def
#File handler
$aFile=File.open("~/temp/test/listkl.txt","w")
$aFile=$stdout unless defined?($aFile)
active_layout = RBA::CellView::active.layout #current layout
lv=Application::instance.main_window.current_view #current layout view
lv.selected_layers.each do |layer| #iterates through each layer selected in the layer pallete
#recursive Iteration through all shapes in layout in order to know which instance called each shape
ListLabels.getLabels_ver2(active_layout,active_layout.top_cell,layer.current.layer_index,active_layout.top_cell.name)
end # do
$aFile.close if defined?($aFile)
end #module
Hi,
a bit hard to read because of missing formatting, but it looks right.
(BTW: you can format code by using the Markdown formatting: just indent the code lines with four blanks).
One remark: you can use "RBA::CplxTrans" instead of "RBA::Trans" as well. This will also capture the cases of scaling instances and rotations by arbitrary angles.
Matthias