21 October 2021 at 20:17 #6610DominikParticipant
When I finish the layout, I also want to export the coordinates of certain Pins. For example, I have a device with two grating couplers and respective Pins ‘gc1’ and ‘gc2’ where the grating couplers are. I want to export the coordinates of these pins where they are in the GDS.
However, the coordinates of ‘gc1’ and ‘gc2’ are only with respect to the cell where they are instantiated in, but not to the top cell of the GDS.
Is there an easy way to get the global coordinates of these pins, i.e. the coordinates of the pins with the total accumulated transformation?
For better understanding, I can provide this minimal example:
import nazca as nd # Define device with pins 'gc1' and 'gc2' with nd.Cell(name='Device') as cell_device: gc1 = nd.taper(length=10, width1=5, width2=1).put(0) nd.strt(width=1, length=80).put() gc2 = nd.taper(length=10, width1=1, width2=5).put() nd.Pin('gc1').put(gc1.pin['a0']) nd.Pin('gc2').put(gc2.pin['b0']) # Intermediate cell, shift device by 10 in y-direction with nd.Cell(name='Cell_Intermediate') as cell_intermediate: mycell = cell_device.put(0, 10) # Top cell, shift intermediate cell by 10 in y-direction with nd.Cell(name='Cell_Top') as cell_top: cell_intermediate.put(0, 10) # Printed values are (0,10) and (100,10) # But want to consider total transformation, i.e. (0,20), (100,20) print(mycell.pin['gc1'].fxy()) print(mycell.pin['gc2'].fxy()) nd.export_gds(cell_top)
Thank you very much for your answer!
Dominik21 October 2021 at 20:40 #6612RonaldKeymaster
The cell_iter() can be of help. It can locate all elements in a celltree with respect to a topcell.
Place this before nd.export_gds():
for params in nd.cell_iter(cell_top): if params.cell_start: # check if we are on a cell_open pass (or check for a cell_close). if params.cell.cell_name == "Device": # check if we are in the right cell pointer, flip = params.transflip_glob # get cell's translation (pointer) and flip w.r.t. cell_top for name, pin in params.cell.pin.items(): # print all pin names and locations print(name, pointer.copy().move_ptr(pin.pointer))) # add pin position in the cell to the cell translation. # output: org Pointer: (x = 0.00, y = 20.00, a = 0.00°) gc1 Pointer: (x = 0.00, y = 20.00, a = 180.00°) gc2 Pointer: (x = 100.00, y = 20.00, a = 180.00°) a0 Pointer: (x = 0.00, y = 20.00, a = 360.00°) b0 Pointer: (x = 0.00, y = 20.00, a = 360.00°)
The .copy() is needed to not change the original pointer with the .move_ptr().
The ‘org’ pin is always created as cell origin.
The ‘a0’ and ‘b0’ pins are default Nazca pins. You can get rid of those using cell_device.default_pins(‘gc1’, ‘gc2’) inside the cell_device cell definition.
Ronald22 October 2021 at 16:50 #6613DominikParticipant
Thank you for your answer, this was very helpful! However, one issue was left: If I create multiple instances of e.g. cell_intermediate, only the coordinates of one instance are reported. But I could solve this by setting revisit=true at cell_iter().
Thanks again and best regards,
Dominik22 October 2021 at 20:30 #6614RonaldKeymaster
You are correct. Thanks for adding that. The cell_iter() by default will not drill down identical branch signatures more than once. In case you would like to visit all branch copies, e.g. to find all instances, the revisit=True will indeed visit the whole cell_tree. Hence, revisit identical branch signatures, mounted on different parts of the celltree. Another way to visit all instances is to use cell_iter(…, flat=True) or cell_iter(…, hierarchy=’flat’).
Ronald4 February 2022 at 11:19 #6697lorenzo_btbwParticipant
I hope this is the correct thread. I have a gds with sub-cells and I want to add structures coded in nazca inside some subcells. So let’s say the gds has a tree like this:
whereas my coded cell is ‘Nazca_device’.
I want to add an instance of ‘Device’ in ‘Nazca_device’. I use:
Import_gds = load_gds(filename=’top_cell’, asdict=True, topcellsonly=False)
cell_top = ‘top_cell’
to have the full tree. By using the script you wrote in #6612, I can locate the position of ‘org pointer’ of ‘Device’ respect the top cell ‘top_cell’.
for params in nd.cell_iter(cell_top):
if params.cell_start: # check if we are on a cell_open pass (or check for a cell_close).
if params.cell.cell_name == “Device”: # check if we are in the right cell
pointer, flip = params.transflip_glob # get cell’s translation (pointer) and flip w.r.t. cell_top
for name, pin in params.cell.pin.items(): # print all pin names and locations
print(name, pointer.copy().move_ptr(pin.pointer)) # add pin position in the cell to the cell translation.
But I’d like instead to add pins to the cell ‘Device’ and then put an instance of ‘Nazca_device’ in ‘Device’. How can I do that?
- This reply was modified 10 months ago by lorenzo_btbw.
- You must be logged in to reply to this topic.