Array to instances converter

For any quite strange reason, I cannot send to the e beam an GDS with arrays.
Is there any simple functionality that changes the whole array to individual cell instances?

I know that this functionality can be easily implemented in a script but... this is maybe a nice thing to implement in KLayout native code.

Comments

  • edited November -1

    Hello,

    You're right. That functionality is missing currently. I'll take that as a suggestion for the next major release.

    For separating single instances out of arrays there is the "make cell variant" function. In you case, that is not an appropriate replacement for the missing array conversion function.

    A simple solution for your problem may be to save the layout to a format that does not support arrays (i.e. CIF) and load it again.

    Another solution is to simply flatten the array.

    Regards,

    Matthias

  • edited June 2014

    Is there a way to resolve arrays in Ruby? I see "Resolve Arrays" in the menu, but in particular I'm trying to resolve only non-orthogonal arrays. (Because the mask-writer tool I use does not support non-orthogonal arrays while KLayout does.)

  • edited November -1

    Hi David,

    I know that there are tools assuming a stricter interpretation of GDS - along with restrictions on cell name length, layer numbers and so on. Some are even stricter: rows have to be rows and columns have to be columns and the row vectors has to point right while the column vector has to point upward.

    Maybe it's worth incorporating array resolution into the GDS output options. So far, the solution was simply not to use features not supported by other tools.

    Right now, there is a solution through a script, of course :-)

    # Resolve non-orthogonal arrays into single arrays
    
    lv = RBA::LayoutView::current
    lv || raise("No layout loaded")
    
    cv = RBA::CellView::active
    ly = cv.layout
    
    module RBA
    
      # Extend the RBA::Instance class by a predicate indicating the
      # need for resolving it 
      class Instance
    
        def non_ortho?
    
          if self.na <= 1 && self.nb <= 1
            return false
          end
          a_norm = self.na > 1 ? self.a : RBA::Point::new
          b_norm = self.nb > 1 ? self.b : RBA::Point::new
          if a_norm.x == 0 && b_norm.y == 0
            return false
          end
          if a_norm.y == 0 && b_norm.x == 0
            return false
          end
          return true
    
        end
    
      end
    
    end
    
    begin 
    
      lv.transaction("Replace non-orthogonal arrays")
    
      puts "Replacing non-orthogonal arrays ..."
    
      ly.each_cell do |cell|
    
        cell.each_inst do |inst|
    
          if inst.non_ortho?
    
            n = 0
    
            inst.na.times do |ia|
              inst.nb.times do |ib|
                d = inst.a * ia + inst.b * ib
                if inst.is_complex?
                  ca = RBA::CellInstArray::new(inst.cell_index, RBA::CplxTrans::new(d.x, d.y) * inst.cplx_trans)
                else
                  ca = RBA::CellInstArray::new(inst.cell_index, RBA::Trans::new(d.x, d.y) * inst.trans)
                end
                if inst.has_prop_id?
                  cell.insert(ca, inst.prop_id)
                else
                  cell.insert(ca)
                end
                n += 1
              end
            end
    
            puts "Replaced #{cell.name}:#{inst.to_s} by #{n} individual instances ..."
    
            inst.delete
    
          end
    
        end  
    
      end
    
    ensure
      lv.commit
    end
    

    Best regards,

    Matthias

  • edited November -1

    Wow, nice script and works perfectly. Thanks!

    I like how you extend RBA::Instance class. I am slowly coming to the realization that this is the "Ruby" way (or OO way) of doing things, so this is a good reminder.

Sign In or Register to comment.