RBA code to get coordinate

edited August 2012 in General

Hi Matthias,

Sorry to bother you again, I'm trying to extract text coordinate from a database, however encountered the transformation issue and have no idea how to solve it, could you please help to check where I made mistakes? thanks.

The partial codes:

(0..(layout.cells-1)).each do |ci|
  cell = layout.cell(ci)
  cell.shapes(l1).each do |shape|
      text = shape.text
      #position = text.trans.trans(text.trans.disp)*layout.dbu
      position = (text.trans.disp)*layout.dbu
      printf("%s (%.3f,%.3f)\n", text.string, position.x, position.y)
  end
end

If I use the marked code, it would transfer the coordinate to a strange value.

If I use current code, it would show the coordinates of all texts with the same result.

Best Regards,

chhung

Comments

  • edited September 2012

    Hi chhung,

    I guess the problem is caused because when you multiply a Point object with a double value (the DBU), it still stays an integer coordinate point object.

    For example:

    RBA::Point.new(100,200)*0.1 -> RBA::Point(10,20)
    

    But:

    RBA::Point.new(100,200)*0.001 -> RBA::Point(0,0)
    

    because 100 times 0.001 is 0.1 which will render 0 when rounded to integer. The same happens to 200 times 0.001.

    To solve this, you could either scale both coordinates explicitly, i.e.

    xpos = text.trans.disp.x*layout.dbu
    ypos = text.trans.disp.y*layout.dbu
    

    In that case, Ruby will convert the integers to floating-point itself.
    Or you convert the "disp" attribute to a DPoint which uses floating-point coordinates:

    position = RBA::DPoint::from_ipoint(text.trans.disp)*layout.dbu
    

    Best regards,

    Matthias

  • edited September 2012

    Hi Matthias,

    The whole code as follow, I'd like to read the specified layer with text, and print all the coordinates of texts.
    However the result of the code doesn't work as I think.

    This code would extract all the text with the same coordinates like:

    TEXT1 (152.000,29.000)
    TEXT2 (152.000,29.000)
    TEXT3 (152.000,29.000)
    TEXT4 (152.000,29.000)
    TEXT5 (152.000,29.000)
    

    However all the coordinates could be display correctly in klayout properties window.

    layout = RBA::Layout.new
    
    loadopt = RBA::LoadLayoutOptions.new
    lm = RBA::LayerMap::new
    
    l1 = layout.insert_layer(RBA::LayerInfo::new(1, 1))
    lm.map(RBA::LayerInfo::new(60, 0), l1)
    
    loadopt.set_layer_map(lm, false)
    layout.read("test.gds", loadopt)
    
    (0..(layout.cells-1)).each do |ci|
      cell = layout.cell(ci)
      cell.shapes(l1).each do |shape|
        text = shape.text
        position = text.trans.disp*layout.dbu
        printf("%s (%.3f,%.3f)\n", text.string, position.x, position.y)
      end
    end
    

    Best Regards,

    chhung

  • edited 12:18AM

    Hi chhung,

    first, I'd apply the changes suggested above. I'd also suggest to use Layout#each_cell to iterate over all cells and test for shape.is_text? before using shape.text.

    But the reason for the problem appears to be something different. I suspect that the texts are in different cells and the coordinate you are looking for must be transformed into the top cell. Maybe the text coordinates are actually all the same but the cells they are in are instantiated differently. Can you confirm that, i.e. by printing the cell name before the texts?

    Best regards,

    Matthias

  • edited September 2012

    Hi Matthias,

    I modified the codes as follow:

    layout.each_cell do |cell|
      cell.shapes(l1).each do |shape|
        if shape.is_text?
          text = shape.text
          xpos = text.trans.disp.x*layout.dbu
          ypos = text.trans.disp.y*layout.dbu
          printf("%s: %s (%.3f,%.3f)\n", layout.cell_name(cell.cell_index), text.string, xpos, ypos)
        end
      end
    end
    

    And it prints the results:

    TEXT1: TEXT1 (152.000,29.500)
    TEXT2: TEXT2 (152.000,29.500)
    TEXT3: TEXT3 (152.000,29.500)
    TEXT4: TEXT4 (152.000,29.500)
    TEXT5: TEXT5 (152.000,29.500)
    

    The layout hierarchy should be like:

    TOP=>TEXT1(CELL)=>TEXT1(TEXT)
       =>TEXT2(CELL)=>TEXT2(TEXT)
       =>TEXT3(CELL)=>TEXT3(TEXT)
       =>TEXT4(CELL)=>TEXT4(TEXT)
       =>TEXT5(CELL)=>TEXT5(TEXT)
    

    I think I have to add a trans.trans to convert the coordinate of every text with their parent cell's coordinate, however I have no idea how to do that. @_@

    Best Regards,

    chhung

  • edited September 2012

    Hi chhung,

    the easiest solution is to flatten the layout. After that there is no hierarchy and the text coordinates should correspond to the coordinates as seen from the top cell. But that modifies the layout and bloats up you data potentially.

    A more convenient method is to use the RecursiveShapeIterator object. It is delivered by Layout#begin_shapes:

    ly = ... # layout to get the shapes from
    topcell = ... # index of the top cell where to start
    layer = ... # index of the layer
    
    iter = ly.begin_shapes(topcell, layer)
    while !iter.at_end? 
      if iter.shape.is_text?
        t = iter.shape.text.transformed_cplx(iter.trans)
        # t is the text transformed into the top cell:
        puts "pos: "+(t.trans.disp.x*ly.dbu).to_s+","+(t.trans.disp.y*ly.dbu)
      end
      iter.next
    end
    

    Best regards,

    Matthias

  • edited September 2012

    Hi Matthias,

    Really appreciate for your kindly help, I've solved this issue via your code.

    I tried the flatten method and found the performance would be much slower than RecursiveShapeIterator, so it might be better use on small files.

    About the t.disp.x and t.disp.y , I guess it's typo of t.trans.disp.x and y.

    Anyway, thank you~ :)

    Best Regards,

    chhung

  • edited 12:18AM

    Hi chhung,

    you're right, it's t.trans.disp, not t.disp.

    I corrected my post above already.

    Thanks and best regards,

    Matthias

Sign In or Register to comment.