Compute Layer Area false false true calc_area tools_menu.end ruby # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # DESCRIPTION: Compute total area of all shapes on a layer. # # Run the script with # klayout -rm calc_area_hier.lym ... # or put the script as "calc_area_hier.lym" into the installation path (on Unix for version <=0.21: # set $KLAYOUTPATH to the installation folder). # # The script will install a new menu item in the Tools menu: "Compute Layer Area". # It will compute the area of all shapes (not considering overlaps) of the selected layer in the current cell. # class CellCount def initialize(layout, cell) @layout = layout @cell = cell @called_cells = {} cell.called_cells.each do |c| @called_cells[c] = true end @called_cells[cell.cell_index] = true @cache = {} end def inst_count(cell) n = @cache[cell.cell_index] if !n cell.each_parent_inst do |pi| if @called_cells[pi.parent_cell_index] n ||= 0 n += pi.inst.size * inst_count(@layout.cell(pi.parent_cell_index)) end end n ||= 1 @cache[cell.cell_index] = n end return n end private @layout @cell @called_cells @cache end # Main functionality app = RBA::Application.instance mw = app.main_window lv = mw.current_view if !lv raise "No view selected" end cv = lv.active_cellview if !cv || !cv.is_valid? raise "No cell selected" end sel_layers = lv.selected_layers if !sel_layers || sel_layers.size == 0 raise "No layer(s) selected" end cc = CellCount::new(cv.layout, cv.cell) t = "Area of layers in um^2:\n\n" sel_layers.each do |l| li = l.current.layer_index if cv.layout.is_valid_layer?(li) cells = cv.cell.called_cells cells.push(cv.cell.cell_index) atot = 0 cells.each do |ci| c = cv.layout.cell(ci) a = 0 c.shapes(li).each do |s| if s.is_path? || s.is_polygon? || s.is_box? a += s.polygon.area end end atot += cc.inst_count(c) * a end t += sprintf(" %-10s\t", l.current.source(true).to_s) + sprintf("%.2f", (atot * cv.layout.dbu * cv.layout.dbu)) + "\n" end end RBA::MessageBox.info("Calculated Area Per Layer", t, RBA::MessageBox::b_ok)