It looks like you're new here. If you want to get involved, click one of these buttons!
Hello, I am creating layouts using some inputs, such as the pitch of a structure. I am finding that the same numerical value is treated differently when dealing with shapes, cells, and cell instances. Is there a way to resolve this so I can simply use the same units for my whole python script?
For example:
import pya
layout = pya.CellView.active().layout() #use current layout
cd=10
example_shape=pya.DPolygon([pya.DPoint(0,0), pya.DPoint(0,cd),pya.DPoint(cd,cd),pya.DPoint(cd,0)])
example_cell=layout.create_cell("Example cell")
example_cell.shapes(layout.layer(1,0)).insert(example_shape)
print(example_shape.bbox().width())
print(example_cell.bbox().width())
returns answers 1000x different for the two print statements!
It gets especially pesky when I use the same dimension (cd) for instancing arrays.
example_cell_two=layout.create_cell("Example cell two")
example_cell_two.insert(pya.CellInstArray(example_cell.cell_index(), pya.DCplxTrans(1,0,0,0,0)))
example_cell_two.insert(pya.CellInstArray(example_cell.cell_index(), pya.DCplxTrans(1,0,0,0,2*cd)))
Instead of placing two squares at a distance equal to their own size, the two squares are placed nearly overlapping.
I have played with different Trans-family functions and haven't found one that fixes the issue, perhaps because the cell is already 1000x larger than the shape.
Comments
Did you inspect the returned objects of both? They aren't the same. One is a DBox and the other a Box.
There are 2 types of geometric objects. Integer based ones (Polygon/Edge/Box/...) and float based ones (DPolygon/DEdge/DBox/...). GDSII (and I think for obvious reasons OASIS too) uses an integer based database. Whenever you insert the objects into a cell they will be converted to an integer based form. So when you insert a DBox into a celll/shapes object and retrieve it back, you will get a Box object. This is because when you insert it, klayout has to snap it to the grid, so there is no reason to preserve the float based object.
Good base principle I also had to learn the hard way: Unless you know absolutely what you are doing, stay away from the complex transformations; they can do amazing things, but it is most likely not what you want. So, stick to (D)Trans. And also a good principle: If your object is int based use int based trans (Trans) and if the object is float based, use float based trans (DTrans). You can mix them because either python or klayout will implicitly convert them for you but under the assumption dbu == 1 which is most likely not true as you won't have a micrometer based grid (default is 0.001 so 1nm afaik). So for your example:
should give you what you want.
I also suggest to take a peek at the manual for the geometric API. It will give you some good basis: https://www.klayout.de/doc-qt5/programming/geometry_api.html
Thank you for the explanation. Your fix works and I appreciate getting to know why Klayout behaves the way it does.