How to compel shapes and cells to use the same units

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

  • edited October 2022

    returns answers 1000x different for the two print statements!

    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.

    It gets especially pesky when I use the same dimension (cd) for instancing arrays.

    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:

    example_cell_two=layout.create_cell("Example cell two")
    example_cell_two.insert(pya.CellInstArray(example_cell.cell_index(), pya.Trans(0,False,0,0)))
    example_cell_two.insert(pya.CellInstArray(example_cell.cell_index(), pya.Trans(0,False,0,2*cd)))
    

    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.

Sign In or Register to comment.