Issue with Text instance "propagation" in Pcell macro

edited July 2013 in Ruby Scripting
Hi Matthias,
i encounter an issue with the TEXT instacne when used in Pcell macro, called alignedcontrol.lsa.
The issue is a bit complicated to describe, so i will try to be as clear as possible
I have written a Pcell macro to create some alignment marks for layout
here is a part of the script (can't post everything, the whole script is quite huge)
The TEXT basic onject is used for numbering of the alignement mark

I use this Pcell into a design saved as a gds file.
This gds file is used as a library (instance again) to create a mapping of the design .
in this file i also use the TEXT instance (-in another cell) for numbering of the design within the mapping.
If i do that it ended up with the TEXT value (as well as attributes, like layer, size, etc) of the PCELL object of the library being replaced by one (often the first in the cell list) of the TEXT object used for mapping numbering.
Actually, the cell list show clearly that the hierarchy propagation is lost
(for example my librairie is named foo, the cell in this librarie is named bar
in the foo.gds library i then have the following hierarchy

bar
->alignecontrole.fia
--->alignecontrol.basic.text( blabla)

in the mapping i should have
mapping
-> foo.bar
-->foo.alignecontrol.fia
--->foo.alignecontrol.basic.text( blabla)
numbering
->basic.text(titi)
->basic.text(toto)

etc
but i have

mapping
->foo.bar
-->foo.fia
--->basic.text(titi) (or toto)
numbering
->basic.text(titi)
->basic.text(toto)


As if hierarchy propagation was lost somewhere.
actually the files and hierarchy i use is a bit more complicated but i can't share it.
(i can howvere send some screenshots, privately of the hierarchy and of the issue)






I can provide some screenshot of the issue for better explanation
Do you think that this is linked to a bad "protection" of the variable in my macros or another issue?


# The library where we will put the PCell into


AligneControle.constants.member?(:Lsa) && remove_const(:Lsa)
AligneControle.constants.member?(:AligneControle) && remove_const(:AligneControle)

# The PCell declaration for the circle
class Lsa < PCellDeclarationHelper

include RBA

def initialize

# Important: initialize the super class
super

# declare the parameters
param(:fl, TypeLayer, "Layer Lsa", :default => LayerInfo::new(1, 0))
param(:finv,TypeBoolean, "Lsa polarité inverse?",:default => false)

# param(:s, TypeShape, "", :default => DPoint::new(0, 0))
# param(:r, TypeDouble, "Radius", :default => 0.1)
# param(:n, TypeInt, "Number of points", :default => 64)
# this hidden parameter is used to determine whether the radius has changed
# or the "s" handle has been moved
# param(:ru, TypeDouble, "Radius", :default => 0.0, :hidden => true)
# param(:inv,TypeBoolean, "inverse?",:default => false)
end

def display_text_impl
# Provide a descriptive text for the cell
"Lsa(L=#{fl.to_s})"
end

def coerce_parameters_impl

# We employ coerce_parameters_impl to decide whether the handle or the
# numeric parameter has changed (by comparing against the effective
# radius ru) and set ru to the effective radius. We also update the
# numerical value or the shape, depending on which on has not changed.
# rs = nil
# if s.is_a?(DPoint)
# compute distance in micron
# rs = s.distance(DPoint::new(0, 0))
# end
# if rs && (r-ru).abs < 1e-6
# set_ru rs
# set_r rs
#else
# set_ru r
#set_s DPoint::new(-r, 0)
#end

# n must be larger or equal than 4
#n > 4 || (set_n 4)
r =25
end

def can_create_from_shape_impl
# Implement the "Create PCell from shape" protocol: we can use any shape which
# has a finite bounding box
shape.is_box? || shape.is_polygon? || shape.is_path?
end

def parameters_from_shape_impl
# Implement the "Create PCell from shape" protocol: we set r and l from the shape's
# bounding box width and layer


set_r shape.bbox.width*layout.dbu / 2
set_fl layout.get_info(layer)
end

def transformation_from_shape_impl
# Implement the "Create PCell from shape" protocol: we use the center of the shape's
# bounding box to determine the transformation
Trans.new(shape.bbox.center)
end

def produce_impl


# This is the main part of the implementation: create the layout

# fetch the parameters


# if larg
# f_ib = 3.5
# f_b = 3.0
# else
# f_b = 1.0
# f_ib = 1.0
# end


# find the lib
lib = RBA::Library.library_by_name("Basic")
lib || raise("Unknown lib 'Basic'")

# find the pcell
pcell_decl = lib.layout.pcell_declaration("TEXT")
pcell_decl || raise("Unknown PCell 'TEXT'")

layer = fl.layer
datatype = fl.datatype

if !finv

param = {"text" => fl.layer.to_s, "layer" =>RBA::LayerInfo::new(layer, datatype), "mag"=>15, "inverse"=> false}
pv = pcell_decl.get_parameters.collect do |p|
param[p.name] || p.default
end


# Lsa
pts3 = [[[-62, -26],
[-62, -22],
[-58, -22],
[-58, -26]],
[[-42, -26],
[-42, -22],
[-38, -22],
[-38, -26]],
[[-22, -26],
[-22, -22],
[-18, -22],
[-18, -26]],
[[-2, -26],
[-2, -22],
[2, -22],
[2, -26]],
[[18, -26],
[18, -22],
[22, -22],
[22, -26]],
[[38, -26],
[38, -22],
[42, -22],
[42, -26]],
[[58, -26],
[58, -22],
[62, -22],
[62, -26]],
[[-62, -18],
[-62, -14],
[-58, -14],
[-58, -18]],
[[-42, -18],
[-42, -14],
[-38, -14],
[-38, -18]],
[[-22, -18],
[-22, -14],
[-18, -14],
[-18, -18]],
[[-2, -18],
[-2, -14],
[2, -14],
[2, -18]],
[[18, -18],
[18, -14],
[22, -14],
[22, -18]],
[[38, -18],
[38, -14],
[42, -14],
[42, -18]],
[[58, -18],
[58, -14],
[62, -14],
[62, -18]],
[[-62, -10],
[-62, -6],
[-58, -6],
[-58, -10]],
[[-42, -10],
[-42, -6],
[-38, -6],
[-38, -10]],
[[-22, -10],
[-22, -6],
[-18, -6],
[-18, -10]],
[[-2, -10],
[-2, -6],
[2, -6],
[2, -10]],
[[18, -10],
[18, -6],
[22, -6],
[22, -10]],
[[38, -10],
[38, -6],
[42, -6],
[42, -10]],
[[58, -10],
[58, -6],
[62, -6],
[62, -10]],
[[-62, -2],
[-62, 2],
[-58, 2],
[-58, -2]],
[[-42, -2],
[-42, 2],
[-38, 2],
[-38, -2]],
[[-22, -2],
[-22, 2],
[-18, 2],
[-18, -2]],
[[-2, -2],
[-2, 2],
[2, 2],
[2, -2]],
[[18, -2],
[18, 2],
[22, 2],
[22, -2]],
[[38, -2],
[38, 2],
[42, 2],
[42, -2]],
[[58, -2],
[58, 2],
[62, 2],
[62, -2]],
[[-62, 6],
[-62, 10],
[-58, 10],
[-58, 6]],
[[-42, 6],
[-42, 10],
[-38, 10],
[-38, 6]],
[[-22, 6],
[-22, 10],
[-18, 10],
[-18, 6]],
[[-2, 6],
[-2, 10],
[2, 10],
[2, 6]],
[[18, 6],
[18, 10],
[22, 10],
[22, 6]],
[[38, 6],
[38, 10],
[42, 10],
[42, 6]],
[[58, 6],
[58, 10],
[62, 10],
[62, 6]],
[[-62, 14],
[-62, 18],
[-58, 18],
[-58, 14]],
[[-42, 14],
[-42, 18],
[-38, 18],
[-38, 14]],
[[-22, 14],
[-22, 18],
[-18, 18],
[-18, 14]],
[[-2, 14],
[-2, 18],
[2, 18],
[2, 14]],
[[18, 14],
[18, 18],
[22, 18],
[22, 14]],
[[38, 14],
[38, 18],
[42, 18],
[42, 14]],
[[58, 14],
[58, 18],
[62, 18],
[62, 14]],
[[-62, 22],
[-62, 26],
[-58, 26],
[-58, 22]],
[[-42, 22],
[-42, 26],
[-38, 26],
[-38, 22]],
[[-22, 22],
[-22, 26],
[-18, 26],
[-18, 22]],
[[-2, 22],
[-2, 26],
[2, 26],
[2, 22]],
[[18, 22],
[18, 26],
[22, 26],
[22, 22]],
[[38, 22],
[38, 26],
[42, 26],
[42, 22]],
[[58, 22],
[58, 26],
[62, 26],
[62, 22]]
]

pts3.each { |pp|
pointlist = []
pp.each { |p| pointlist.push(Point.from_dpoint(DPoint.new( p[0]/layout.dbu, p[1]/layout.dbu ) )) }
cell.shapes(fl_layer).insert(Polygon.new(pointlist))
}
else

param = {"text" => fl.layer.to_s, "layer" =>RBA::LayerInfo::new(layer, datatype), "mag"=>15, "inverse"=> true}
pv = pcell_decl.get_parameters.collect do |p|
param[p.name] || p.default
end

# LSA inverse
pts3 = [ [-90, -35],
[-90, 35],
[90, 35],
[90, 26],
[-62, 26],
[-62, 22],
[-58, 22],
[-58, 26],
[-42, 26],
[-42, 22],
[-38, 22],
[-38, 26],
[-22, 26],
[-22, 22],
[-18, 22],
[-18, 26],
[-2, 26],
[-2, 22],
[2, 22],
[2, 26],
[18, 26],
[18, 22],
[22, 22],
[22, 26],
[38, 26],
[38, 22],
[42, 22],
[42, 26],
[58, 26],
[58, 22],
[62, 22],
[62, 26],
[90, 26],
[90, 18],
[-62, 18],
[-62, 14],
[-58, 14],
[-58, 18],
[-42, 18],
[-42, 14],
[-38, 14],
[-38, 18],
[-22, 18],
[-22, 14],
[-18, 14],
[-18, 18],
[-2, 18],
[-2, 14],
[2, 14],
[2, 18],
[18, 18],
[18, 14],
[22, 14],
[22, 18],
[38, 18],
[38, 14],
[42, 14],
[42, 18],
[58, 18],
[58, 14],
[62, 14],
[62, 18],
[90, 18],
[90, 10],
[-62, 10],
[-62, 6],
[-58, 6],
[-58, 10],
[-42, 10],
[-42, 6],
[-38, 6],
[-38, 10],
[-22, 10],
[-22, 6],
[-18, 6],
[-18, 10],
[-2, 10],
[-2, 6],
[2, 6],
[2, 10],
[18, 10],
[18, 6],
[22, 6],
[22, 10],
[38, 10],
[38, 6],
[42, 6],
[42, 10],
[58, 10],
[58, 6],
[62, 6],
[62, 10],
[90, 10],
[90, 2],
[-62, 2],
[-62, -2],
[-58, -2],
[-58, 2],
[-42, 2],
[-42, -2],
[-38, -2],
[-38, 2],
[-22, 2],
[-22, -2],
[-18, -2],
[-18, 2],
[-2, 2],
[-2, -2],
[2, -2],
[2, 2],
[18, 2],
[18, -2],
[22, -2],
[22, 2],
[38, 2],
[38, -2],
[42, -2],
[42, 2],
[58, 2],
[58, -2],
[62, -2],
[62, 2],
[90, 2],
[90, -6],
[-62, -6],
[-62, -10],
[-58, -10],
[-58, -6],
[-42, -6],
[-42, -10],
[-38, -10],
[-38, -6],
[-22, -6],
[-22, -10],
[-18, -10],
[-18, -6],
[-2, -6],
[-2, -10],
[2, -10],
[2, -6],
[18, -6],
[18, -10],
[22, -10],
[22, -6],
[38, -6],
[38, -10],
[42, -10],
[42, -6],
[58, -6],
[58, -10],
[62, -10],
[62, -6],
[90, -6],
[90, -14],
[-62, -14],
[-62, -18],
[-58, -18],
[-58, -14],
[-42, -14],
[-42, -18],
[-38, -18],
[-38, -14],
[-22, -14],
[-22, -18],
[-18, -18],
[-18, -14],
[-2, -14],
[-2, -18],
[2, -18],
[2, -14],
[18, -14],
[18, -18],
[22, -18],
[22, -14],
[38, -14],
[38, -18],
[42, -18],
[42, -14],
[58, -14],
[58, -18],
[62, -18],
[62, -14],
[90, -14],
[90, -22],
[-62, -22],
[-62, -26],
[-58, -26],
[-58, -22],
[-42, -22],
[-42, -26],
[-38, -26],
[-38, -22],
[-22, -22],
[-22, -26],
[-18, -26],
[-18, -22],
[-2, -22],
[-2, -26],
[2, -26],
[2, -22],
[18, -22],
[18, -26],
[22, -26],
[22, -22],
[38, -22],
[38, -26],
[42, -26],
[42, -22],
[58, -22],
[58, -26],
[62, -26],
[62, -22],
[90, -22],
[90, -35]
]

# pts3.each { |pp|
pointlist = []
pts3.each { |p| pointlist.push(Point.from_dpoint(DPoint.new( p[0]/layout.dbu, p[1]/layout.dbu ) )) }
cell.shapes(fl_layer).insert(Polygon.new(pointlist))
# }
end

# create a PCell variant cell
pcell_var = cell.layout.add_pcell_variant(lib, pcell_decl.id, pv)
x = 97.5/layout.dbu
y = 3/layout.dbu
t = RBA::Trans::new(0,false, x, y)
pcell_inst = cell.insert(RBA::CellInstArray::new(pcell_var, t))




end


end

Comments

  • edited July 2013
    Hi again Matthias

    Forget it, i dig a bit more in the issue. Looks like it is not related to the Pcell at all, but to the way i use my libraries.
    actually, i often open the library, then the top file, make some mods (often it is deletion) in the library, reload the library (using the script you provided me a while to create library "on the fly") and then reload the top file, save it..etc
    it appears that this way of doing create teh issue (the inital top hiearchy file is clean, it only degrades when doing some mods in the library, while the top hierarchy is opened, on the fly) Perhaps some variables/memory/pointers mixing take place when doing that and this mixing create teh issue
    I think i should change my bad habits and modify the library at a time, then close klayout and reopen it with the top file, so that klayout start clean.

    Joël
  • edited November -1

    Hi Joel,

    thanks for mentioning the last fact - as was already trying to dig into the issue :-)

    I hope I understood the problem description, but
    I can imagine that refreshing of the library messes up the references to the TEXT instances. Internally, the BASIC library keeps track of the TEXT instances to cache the computed layout. Apparently this scheme does not properly consider the origin of the TEXT cells (lib/alignment lib and original).

    Frankly, dynamic update of library cells by refreshing was not the primary design goal and I imagine your use case is not designed into the system properly.

    I guess it's pretty difficult to reproduce but I'll give it a try. Please let me know when you still encounter issues even if restarting KLayout - in that case that is a serious problem.

    Regards and thanks for the report,

    Matthias

  • edited November -1
    Hi Matthias,

    looks like all is fine when doing things "cleanly" (that is avoid opening libraries and top files and ...)
    The bug is not that easy to reproduce indeed...

    Regards and thanks fopr this awfull tool.

    Joël
Sign In or Register to comment.