Change DBU when copying two layouts from one to the other

edited August 2012 in KLayout Support
Hi Matthias,
I started to use scripting for my work recently. It is a very powerful tool for manipulating GDS layouts. But I stuck on copy of two layouts if they have different DBUs. Is there a simple way to do that, or I have to extract all shapes and then make scaling? Thanks a lot in advance.

Best regards,
TsannBim

Comments

  • edited 11:28PM

    Hello,

    right now the easiest way to convert a layout to a different database unit is to write it to a temporary file and use the options provided by the '''writer''' to scale the layout:

    ly = ... # layout to write
    new_dbu = ... # new database unit to use
    
    options = RBA::SaveLayoutOptions::new
    options.dbu = new_dbu
    ly.write("tmp.oas", false, options)
    

    You'll get a new layout file "tmp.oas" which will have the desired target database unit. You can then read the layout again.

    That is some workaround for the lack of some simple function to scale a layout. Scaling a layout in-place is possible but slower since you'd have to do the scaling object by object.

    Regards,

    Matthias

  • edited 11:28PM
    Hi Matthias,
    Many thanks for your help. Ok, but your solution is a workaround, that means you plan to make a function for that? By the way, I am learning the KLayout objects and their methods/properties and also the way to control them, could you please show me how to deal with scaling of shapes one by one. Thanks again.

    Regards,
    Tsann-Bim
  • edited 11:28PM

    Hi,

    I'll put the scaling function on my TODO list, but it has grown pretty long now. So I can't promise such a function soon.

    If you want to scale a layout in code, here is a sample:

    ly = ... # layout to scale
    new_dbu = ... # new database unit
    
    # compute the scale factor and set the new DBU
    sf = ly.dbu / new_dbu
    ly.dbu = new_dbu
    
    # prepare a transformation with pure scaling
    t = RBA::CplxTrans.new(sf)
    
    # iterate over all cells
    ly.each_cell do |cell|
    
      # scale all layers - that's the easy part 
      ly.layer_indices.each do |li|
        shapes = cell.shapes(li)
        shapes.each do |s|
          shapes.transform(s, t)
        end
      end
    
      # scaling the instances is not that simple because using the transform method of
      # RBA::Cell would create a magnified instance and not just scale the displacements
      # TODO: cell instance properties are lost in that simple implementation
      cell.each_inst do |inst|
        i = inst.cell_inst
        trans = (i.is_complex? ? i.cplx_trans : i.trans).dup  # using dup we create an object we can modify
        trans.disp = trans.disp * sf
        if i.is_regular_array?
          cell.replace(inst, RBA::CellInstArray.new(inst.cell_index, trans, i.a * sf, i.b * sf, i.na, i.nb))
        else
          cell.replace(inst, RBA::CellInstArray.new(inst.cell_index, trans))
        end
      end
    
    end
    

    best regards,

    Matthias

  • edited 11:28PM
    Matthias,
    That is pretty clear and straightforward, and very helpful to me. Thank you so much for your kind help. Again, it is a great support from you.

    Best regards,
    Tsann-Bim
Sign In or Register to comment.