It looks like you're new here. If you want to get involved, click one of these buttons!
Hello,
My question arose in the context of the path returned from ROUND_PATH, which seems to be in microns, rather than database units like all the other objects...
iter = cell.begin_shapes_rec(layer)
while not(iter.at_end()):
if iter.shape().is_polygon():
if iter.cell().basic_name() == "ROUND_PATH":
subcell = iter.cell()
trans = iter.trans() # CplxTrans object of the instance
itrans = iter.itrans() # ICplxTrans object of the instance, integer version
print "trans: %s, itrans: %s" % (trans, itrans)
# apply itrans on path
DPath = subcell.pcell_parameters_by_name()["path"] # DPath object
ipath = pya.Path.from_dpath(DPath) # Construct an integer-coordinate path from a floating-point coordinate one
print "%s: In cell {%s}, DPath -- %s -- Path -- %s" % (i, iter.cell().name, DPath, ipath)
The above returns a path in microns, e.g., (0,0;10,0;10,10), rather than dbu, e.g., (0,0;10000,0;10000,10000)
....
Originally, I thought I could use the built-in functions to convert from dbu to microns.
I think I understand now that what I have below doesn't accomplish this -- namely this conversion is just a datatype conversion:
I am trying to convert from coordinates in database units (integer) to floating point in user units (microns). My understanding is that the path and points defined below, where I have 10 microns, it should be converted to 10000. But that's not the case. It just gets rounded.
Do I need to going through point by point and multiply by 1000 myself?
The documentation states: All floating-point type objects have class methods like "from_i.." (i.e. DBox#from_ibox) which convert integer-coordinate type objects to floating-point type ones without loss of precision. The reverse path is opened by using the "from_d.." class methods of the integer-type objects (i.e. Box#from_dbox). These methods however require some rounding and are therefore responsible for a potential distortion of the geometry of the object.
import pya
# http://www.klayout.de/doc/programming/geometry_api.html#h2-339
ly = pya.Application.instance().main_window().current_view().active_cellview().layout()
dbu = ly.dbu
print dbu
dpoints = [ [0,0], [10.01,0], [10.01,10] ]
dpoints=n.array(dpoints)/dbu
a1 = []
for p in dpoints:
a1.append (pya.DPoint(p[0], p[1]))
dpath = pya.DPath(a1, 0.5/dbu)
ipath = pya.Path.from_dpath(dpath) # Construct an integer-coordinate path from a floating-point coordinate one
print "dpath -- %s -- ipath -- %s" % (dpath, ipath)
dpoint = pya.DPoint(10.333/dbu, 23.4/dbu)
# http://klayout.de/doc/code/class_Point.html
ipoint = pya.Point.from_dpoint(dpoint) # Create a double point from an integer point (???)
print "dpoint -- %s -- ipoint -- %s" % (dpoint, ipoint)
and the output
0.001
dpath -- (0,0;10010,0;10010,10000) w=500 bx=0 ex=0 r=false -- ipath -- (0,0;10010,0;10010,10000) w=500 bx=0 ex=0 r=false
dpoint -- 10333,23400 -- ipoint -- 10333,23400
Comments
It seems like I can just scale the values returned by the PCell "ROUND_PATH"
and get it back to dbu rather than microns...
Hi Lukas,
Oh yes ... maybe I forgot to mention this. The Path object is supposed to be micron units rather than database units.
To convert an integer-typed path to a DPath in database units, you can also use the transformation, which will convert the type to DPath at the same time (the plain multiplication doesn't):
The PCell's parameters are supposed to be independent from the database unit. For example the circle radius is given in micron units, not in database units. The reason is that the PCell code is not necessarily executed in a context with the same database unit than the target layout. The PCell lives in a separate library which comes with it's own database unit. So having micrometer units ensures that the PCell physically looks the same in the library and in the target layout.
Best regards,
Matthias
Good point. It makes sense to use microns for PCells.