Home Forums Nazca Get global pin coordinates

Viewing 5 posts - 1 through 5 (of 5 total)
  • Author
    Posts
  • #6610
    Dominik
    Participant

    Dear all,

    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!

    Best regards,

    Dominik

    #6612
    Ronald
    Keymaster

    Dear Dominik,

    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.

    Ronald

    #6613
    Dominik
    Participant

    Dear Ronald,

    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,

    Dominik

    #6614
    Ronald
    Keymaster

    Dear Dominik,

    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’).

    Ronald

    #6697
    lorenzo_btbw
    Participant

    Dear Ronald,

    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:

    • top_cell
      • sub_cell
        • Device

    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)

    Import_gds[‘top_cell’].put()

    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?

    thank you

    Kind regards,

    Lorenzo

    • This reply was modified 2 years, 8 months ago by lorenzo_btbw.
Viewing 5 posts - 1 through 5 (of 5 total)
  • You must be logged in to reply to this topic.