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

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 

25 

26import copy 

27from dataclasses import dataclass 

28from typing import * 

29 

30 

31@dataclass 

32class CapacitanceMatrix: 

33 conductor_names: List[str] # NOTE FasterCap generates [g_1, g_2, ...] 

34 rows: List[List[float]] # NOTE: in µm 

35 

36 def __getitem__(self, key): 

37 return self.rows.__getitem__(key) 

38 

39 def __setitem__(self, key, value): 

40 self.rows.__setitem__(key, value) 

41 

42 @property 

43 def dimension(self): 

44 return len(self.conductor_names) 

45 

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) 

60 

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') 

66 

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') 

72 

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