Coverage for klayout_pex/common/capacitance_matrix.py: 96%
49 statements
« prev ^ index » next coverage.py v7.6.9, created at 2024-12-17 17:24 +0000
« prev ^ index » next coverage.py v7.6.9, created at 2024-12-17 17:24 +0000
1#
2# --------------------------------------------------------------------------------
3# SPDX-FileCopyrightText: 2024 Martin Jan Köhler and Harald Pretl
4# Johannes Kepler University, Institute for Integrated Circuits.
5#
6# This file is part of KPEX
7# (see https://github.com/martinjankoehler/klayout-pex).
8#
9# This program is free software: you can redistribute it and/or modify
10# it under the terms of the GNU General Public License as published by
11# the Free Software Foundation, either version 3 of the License, or
12# (at your option) any later version.
13#
14# This program is distributed in the hope that it will be useful,
15# but WITHOUT ANY WARRANTY; without even the implied warranty of
16# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17# GNU General Public License for more details.
18#
19# You should have received a copy of the GNU General Public License
20# along with this program. If not, see <http://www.gnu.org/licenses/>.
21# SPDX-License-Identifier: GPL-3.0-or-later
22# --------------------------------------------------------------------------------
23#
24from __future__ import annotations
26import copy
27from dataclasses import dataclass
28from typing import *
31@dataclass
32class CapacitanceMatrix:
33 conductor_names: List[str] # NOTE FasterCap generates [g_1, g_2, ...]
34 rows: List[List[float]] # NOTE: in µm
36 def __getitem__(self, key):
37 return self.rows.__getitem__(key)
39 def __setitem__(self, key, value):
40 self.rows.__setitem__(key, value)
42 @property
43 def dimension(self):
44 return len(self.conductor_names)
46 @classmethod
47 def parse_csv(cls, path: str, separator: str = ';'):
48 with open(path, 'r') as f:
49 lines = f.readlines()
50 if len(lines) < 2:
51 raise Exception(f"Capacitance Matrix CSV must at least have 2 lines: "
52 f"{path}")
53 conductor_names = [cell.strip() for cell in lines[0].split(sep=separator)]
54 rows = []
55 for line in lines[1:]:
56 row = [float(cell.strip()) for cell in line.split(sep=separator)]
57 rows.append(row)
58 return CapacitanceMatrix(conductor_names=conductor_names,
59 rows=rows)
61 def write_csv(self, output_path: str, separator: str = ';'):
62 with open(output_path, 'w') as f:
63 header_line = separator.join(self.conductor_names)
64 f.write(header_line)
65 f.write('\n')
67 for row in self.rows:
68 cells = ['%.12g' % cell for cell in row]
69 row_line = separator.join(cells)
70 f.write(row_line)
71 f.write('\n')
73 def averaged_off_diagonals(self) -> CapacitanceMatrix:
74 c = copy.deepcopy(self)
75 for i in range(len(self.rows)):
76 for j in range(len(self.conductor_names)):
77 if j <= i:
78 continue
79 v1 = self[i][j]
80 v2 = self[j][i]
81 avg = (v1 + v2) / 2
82 # print(f"i={i} j={j}, avg({v1}, {v2}) == {avg}")
83 c[i][j] = avg
84 c[j][i] = avg
85 return c