basically layer index and layer properties are two different items - one is the related to the layout database and one to the view. To find the layer properties for a layer index, you'll need the LayerPropertiesIterator object and the following code
layer_index = ... # The layer index
cv_index = ... # The cellview index for which you are looking up the layer
lv = ... # The LayoutView object
lp_found = nil
iter = lv.begin_layers
while !iter.at_end?
lp = iter.current
if lp.cv_index == cv_index && lp.layer_index == layer_index
lp_found = lp
end
iter.next
end
# lp_found gives the LayerPropertiesNode object with the display properties or
# nil if the layer is not in the list
Should this code still work in version 0.23.10? With this code, I get a undefined method 'cv_index' for #<RBA::LayerPropertiesNode:0x0000000712f704> error. Here is the code:
def self.get_layer_name2(layer_index)
lv = Application::instance.main_window.current_view
cv_index = lv.active_cellview_index
iter = lv.begin_layers
while !iter.at_end?
lp = iter.current
if lp.cv_index == cv_index && lp.layer_index == layer_index
return lp
end
iter.next
end
return nil
end
The .cellview method belongs to class LayerProperties, for which LayerPropertiesNode is a child. I just tried it in the following code and it seems to work.
include RBA
app = Application.instance
mw = app.main_window
lv = mw.current_view
cv = lv.active_cellview
cv_index = cv.cell_index
ly = cv.layout
dbu = ly.dbu
layer_index = 0 # The layer index
lp_found = nil
iter = lv.begin_layers
while !iter.at_end?
lp = iter.current
if lp.cellview == cv_index && lp.layer_index == layer_index
lp_found = lp
end
iter.next
end
if lp_found.nil?
p "Not found"
else
p "Found. Has dither pattern index = #{lp_found.dither_pattern}"
end
Thanks for your help David, I have changed your code slightly (and removed a small error where you had cv_index = cv.cell_index) to create a get_layer_name function as follows:
def self.get_layer_name(layer_index)
lv = Application::instance.main_window.current_view
cv = lv.active_cellview
cv_index = lv.active_cellview_index
iter = lv.begin_layers
while !iter.at_end?
lp = iter.current
if lp.cellview == cv_index && lp.layer_index == layer_index
return lp.name
end
iter.next
end
return "<unknown layer #{layer_index}>"
end
This works fine now for primitive geometry (boxes, polygons etc.) but I have trouble getting it to work with layer parameters on PCells - is the layer member of a PCellParameterDeclaration object the same as the layer_index in my code above?
Do illustrate my problem, here is the rest of this module's code:
class MyObserver < Observer
def signal
mw = RBA::Application::instance.main_window
lv = mw.current_view
info = ""
lv.each_object_selected do |sel|
if !sel.is_cell_inst?
layer_index = sel.layer
layer_name = LayerTest2::get_layer_name(layer_index)
info = "layer index #{layer_index} = #{layer_name}\n"
info += "Press Cancel to un-register observer."
elsif sel.is_cell_inst?
inst = sel.inst
cell = inst.cell
info += "#{cell.basic_name}:\n"
if cell.is_pcell_variant?(inst)
pcell_declaration = cell.pcell_declaration(inst)
pcell_declaration.get_parameters.each_with_index do |pd, pd_idx|
if !pd.hidden? || !pd.readonly?
info += (" #{pd.name}") # - #{pd.description}
value = cell.pcell_parameters(inst)[pd_idx]
case pd.type
when RBA::PCellParameterDeclaration::TypeLayer
info += " = #{LayerTest2::get_layer_name(value.layer)}\n"
else
begin
info += " = #{value}\n"
rescue
info += "<unsupported type>\n"
end
end
end
end
end
info += "\n"
end
result = RBA::QMessageBox::information(mw, "Layer", info, RBA::QMessageBox::Ok.to_i | RBA::QMessageBox::Cancel.to_i)
if result == RBA::QMessageBox::Cancel.to_i
lv.remove_selection_changed_observer(self)
end
end
end
end
observer = MyObserver::new
Application::instance.main_window.current_view.add_selection_changed_observer(observer)
This opens a dialog showing either the layer_index and the layer name (if a primitive object is selected) or a list of parameters of a selected PCell instance. For some reason, the layer names returned by my get_layer_name function are not always correct when I select PCell instances, making me wonder if I am getting the right index there.
My test layout includes just a bunch of polygons, rectangles and paths for the "primitive" case, as well as some BASIC.CIRCLE PCell instances (using different layer settings) for the "complex" case.
sorry for the late reply ... I'm simply too overloaded currently.
For PCell's the concept of a layer is a very different one. A PCell parameter has to be something abstract, since it's valid across instances of an layout.
Layer indexes are assigned by the system incrementally. Whenever the program requires a new layer, it will use the next index available. The actual stream representation of the layer (GDS/OASIS layer/datatype, CIF/DXF/LEF layer name) is stored as annotated information in RBA::LayerInfo objects. When you work with layers in the layer, the layer index is used to uniquely identify the layer and in order to get the layer info, you can use RBA::Layout::get_info(layer_index), which renders a RBA::LayerInfo object.
A PCell parameter, being an abstract entity without knowledge about the actual layout it's used in, stores a RBA::LayerInfo object. RBA::LayerInfo.layer gives the GDS layer number which only by chance is coincident with the layer index. If you need the layer index you can find the layer for a given RBA::LayerInfo object by using RBA::Layout::find_layer:
# instead of value.layer, use:
cell.layout.find_layer(value)
Thanks a lot for your continued support and this great software! Apparently I keep getting confused about the manifold relationships between GDS layer numbers, layer names in .lyp files and layer indices used in the layout database. I guess I should have realised that the documentation already mentions that the "value" of a PCell parameter of TypeLayer is a LayerInfo object...
Using your advice, I changed the following line in my code from above,
info += " = #{LayerTest2::get_layer_name(value.layer)}\n"
to the following:
layer_index = cell.layout.find_layer(value)
info += " = #{LayerTest2::get_layer_name(layer_index)}\n"
Comments
Hi Laurent,
basically layer index and layer properties are two different items - one is the related to the layout database and one to the view. To find the layer properties for a layer index, you'll need the LayerPropertiesIterator object and the following code
Regards,
Matthias
Hi Matthias,
Should this code still work in version 0.23.10? With this code, I get a
undefined method 'cv_index' for #<RBA::LayerPropertiesNode:0x0000000712f704>
error. Here is the code:Any help would be appreciated.
Thanks, FriendFX
Use
instead of
The .cellview method belongs to class LayerProperties, for which LayerPropertiesNode is a child. I just tried it in the following code and it seems to work.
David
Hi David,
thanks again :-)
I wonder whether the code above ever worked. Maybe it was a typo and nobody noticed. "cellview" is the right method, not "cv_index".
Matthias
(Of course that was a joke -- nobody's being paid to do this which makes Matthias's software all the more impressive!)
Hi again.
Thanks for your help David, I have changed your code slightly (and removed a small error where you had
cv_index = cv.cell_index
) to create aget_layer_name
function as follows:This works fine now for primitive geometry (boxes, polygons etc.) but I have trouble getting it to work with layer parameters on PCells - is the
layer
member of aPCellParameterDeclaration
object the same as thelayer_index
in my code above?Do illustrate my problem, here is the rest of this module's code:
This opens a dialog showing either the layer_index and the layer name (if a primitive object is selected) or a list of parameters of a selected PCell instance. For some reason, the layer names returned by my
get_layer_name
function are not always correct when I select PCell instances, making me wonder if I am getting the right index there.My test layout includes just a bunch of polygons, rectangles and paths for the "primitive" case, as well as some BASIC.CIRCLE PCell instances (using different
layer
settings) for the "complex" case.Hi friendfx,
sorry for the late reply ... I'm simply too overloaded currently.
For PCell's the concept of a layer is a very different one. A PCell parameter has to be something abstract, since it's valid across instances of an layout.
Layer indexes are assigned by the system incrementally. Whenever the program requires a new layer, it will use the next index available. The actual stream representation of the layer (GDS/OASIS layer/datatype, CIF/DXF/LEF layer name) is stored as annotated information in RBA::LayerInfo objects. When you work with layers in the layer, the layer index is used to uniquely identify the layer and in order to get the layer info, you can use RBA::Layout::get_info(layer_index), which renders a RBA::LayerInfo object.
A PCell parameter, being an abstract entity without knowledge about the actual layout it's used in, stores a RBA::LayerInfo object. RBA::LayerInfo.layer gives the GDS layer number which only by chance is coincident with the layer index. If you need the layer index you can find the layer for a given RBA::LayerInfo object by using RBA::Layout::find_layer:
(disclaimer: untested)
Matthias
Hi Matthias,
Thanks a lot for your continued support and this great software! Apparently I keep getting confused about the manifold relationships between GDS layer numbers, layer names in .lyp files and layer indices used in the layout database. I guess I should have realised that the documentation already mentions that the "value" of a PCell parameter of TypeLayer is a LayerInfo object...
Using your advice, I changed the following line in my code from above,
to the following:
Which works perfectly now!