Coverage for tests/klayout/shapes_pb2_converter_test.py: 100%

126 statements  

« prev     ^ index     » next       coverage.py v7.11.0, created at 2025-10-31 20:14 +0000

1# 

2# -------------------------------------------------------------------------------- 

3# SPDX-FileCopyrightText: 2024-2025 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/iic-jku/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# 

24 

25import allure 

26import unittest 

27 

28import klayout.db as kdb 

29import klayout_pex_protobuf.kpex.geometry.shapes_pb2 as shapes_pb2 

30from klayout_pex.klayout.shapes_pb2_converter import ShapesConverter 

31 

32from klayout_pex.log import ( 

33 LogLevel, 

34 set_log_level, 

35) 

36 

37 

38@allure.parent_suite("Unit Tests") 

39@allure.tag("Geometry", "Shapes", "KLayout") 

40class ShapesConverterTest(unittest.TestCase): 

41 @classmethod 

42 def setUpClass(cls): 

43 set_log_level(LogLevel.DEBUG) 

44 

45 def setUp(self): 

46 self.dbu = 0.001 

47 

48 def test_klayout_point(self): 

49 conv = ShapesConverter(self.dbu) 

50 

51 p_pb = shapes_pb2.Point() 

52 p_pb.x = 10 

53 p_pb.y = 20 

54 

55 p_kly = conv.klayout_point(p_pb) 

56 self.assertEqual(p_pb.x, p_kly.x) 

57 self.assertEqual(p_pb.y, p_kly.y) 

58 

59 def test_klayout_point_to_pb(self): 

60 conv = ShapesConverter(self.dbu) 

61 

62 p_kly = kdb.Point(10, 20) 

63 p_pb = shapes_pb2.Point() 

64 conv.klayout_point_to_pb(p_kly, p_pb) 

65 self.assertEqual(p_kly.x, p_pb.x) 

66 self.assertEqual(p_kly.y, p_pb.y) 

67 

68 def test_klayout_box(self): 

69 conv = ShapesConverter(self.dbu) 

70 

71 sh_pb = shapes_pb2.Shape() 

72 sh_pb.kind = shapes_pb2.Shape.Kind.SHAPE_KIND_BOX 

73 sh_pb.box.lower_left.x = 10 

74 sh_pb.box.lower_left.y = 20 

75 sh_pb.box.upper_right.x = 750 

76 sh_pb.box.upper_right.y = 300 

77 

78 b_kly = conv.klayout_box(sh_pb.box) 

79 self.assertEqual(sh_pb.box.lower_left.x, b_kly.left) 

80 self.assertEqual(sh_pb.box.lower_left.y, b_kly.bottom) 

81 self.assertEqual(sh_pb.box.upper_right.x, b_kly.right) 

82 self.assertEqual(sh_pb.box.upper_right.y, b_kly.top) 

83 

84 def test_klayout_box_to_pb(self): 

85 conv = ShapesConverter(self.dbu) 

86 

87 b_kly = kdb.Box(10, 20, 750, 300) 

88 sh_pb = shapes_pb2.Shape() 

89 conv.klayout_box_to_pb(b_kly, sh_pb) 

90 self.assertEqual(shapes_pb2.Shape.Kind.SHAPE_KIND_BOX, sh_pb.kind) 

91 self.assertEqual(b_kly.left, sh_pb.box.lower_left.x) 

92 self.assertEqual(b_kly.bottom, sh_pb.box.lower_left.y) 

93 self.assertEqual(b_kly.right, sh_pb.box.upper_right.x) 

94 self.assertEqual(b_kly.top, sh_pb.box.upper_right.y) 

95 

96 def test_klayout_box_to_pb__with_properties(self): 

97 conv = ShapesConverter(self.dbu) 

98 

99 b_kly = kdb.BoxWithProperties(kdb.Box(10, 20, 750, 300), {'net': 'VDD'}) 

100 sh_pb = shapes_pb2.Shape() 

101 conv.klayout_box_to_pb(b_kly, sh_pb) 

102 self.assertEqual(b_kly.property('net'), sh_pb.box.net) 

103 

104 def test_klayout_polygon(self): 

105 conv = ShapesConverter(self.dbu) 

106 

107 sh_pb = shapes_pb2.Shape() 

108 sh_pb.kind = shapes_pb2.Shape.Kind.SHAPE_KIND_POLYGON 

109 p0 = sh_pb.polygon.hull_points.add() 

110 p0.x = 10 

111 p0.y = 20 

112 p1 = sh_pb.polygon.hull_points.add() 

113 p1.x = 10 

114 p1.y = 30 

115 p2 = sh_pb.polygon.hull_points.add() 

116 p2.x = 750 

117 p2.y = 30 

118 p3 = sh_pb.polygon.hull_points.add() 

119 p3.x = 750 

120 p3.y = 20 

121 

122 pg_kly = conv.klayout_polygon(sh_pb.polygon) 

123 pt_kly = list(pg_kly.each_point_hull()) 

124 

125 self.assertEqual(p0.x, pt_kly[0].x) 

126 self.assertEqual(p0.y, pt_kly[0].y) 

127 self.assertEqual(p1.x, pt_kly[1].x) 

128 self.assertEqual(p1.y, pt_kly[1].y) 

129 self.assertEqual(p2.x, pt_kly[2].x) 

130 self.assertEqual(p2.y, pt_kly[2].y) 

131 self.assertEqual(p3.x, pt_kly[3].x) 

132 self.assertEqual(p3.y, pt_kly[3].y) 

133 

134 def test_klayout_polygon_to_pb(self): 

135 conv = ShapesConverter(self.dbu) 

136 

137 pt_kly = [ 

138 kdb.Point(10, 20), 

139 kdb.Point(10, 30), 

140 kdb.Point(750, 30), 

141 kdb.Point(750, 20), 

142 ] 

143 

144 pg_kly = kdb.PolygonWithProperties( 

145 kdb.Polygon(pt_kly), 

146 {'net': 'VSS'} 

147 ) 

148 

149 sh_pb = shapes_pb2.Shape() 

150 conv.klayout_polygon_to_pb(pg_kly, sh_pb) 

151 pt_pb = sh_pb.polygon.hull_points 

152 self.assertEqual(shapes_pb2.Shape.Kind.SHAPE_KIND_POLYGON, sh_pb.kind) 

153 self.assertEqual('VSS', sh_pb.polygon.net) 

154 self.assertEqual(pt_kly[0].x, pt_pb[0].x) 

155 self.assertEqual(pt_kly[0].y, pt_pb[0].y) 

156 self.assertEqual(pt_kly[1].x, pt_pb[1].x) 

157 self.assertEqual(pt_kly[1].y, pt_pb[1].y) 

158 

159 def test_klayout_region(self): 

160 conv = ShapesConverter(self.dbu) 

161 

162 r_pb = shapes_pb2.Region() 

163 sh_pb = r_pb.shapes.add() 

164 sh_pb.kind = shapes_pb2.Shape.Kind.SHAPE_KIND_POLYGON 

165 p0 = sh_pb.polygon.hull_points.add() 

166 p0.x = 10 

167 p0.y = 20 

168 p1 = sh_pb.polygon.hull_points.add() 

169 p1.x = 10 

170 p1.y = 30 

171 p2 = sh_pb.polygon.hull_points.add() 

172 p2.x = 750 

173 p2.y = 30 

174 p3 = sh_pb.polygon.hull_points.add() 

175 p3.x = 750 

176 p3.y = 20 

177 

178 r_kly = conv.klayout_region(r_pb) 

179 self.assertEqual(1, r_kly.count()) 

180 pg_kly = list(r_kly.each())[0] 

181 pt_kly = list(pg_kly.each_point_hull()) 

182 self.assertEqual(p0.x, pt_kly[0].x) 

183 self.assertEqual(p0.y, pt_kly[0].y) 

184 self.assertEqual(p1.x, pt_kly[1].x) 

185 self.assertEqual(p1.y, pt_kly[1].y) 

186 self.assertEqual(p2.x, pt_kly[2].x) 

187 self.assertEqual(p2.y, pt_kly[2].y) 

188 self.assertEqual(p3.x, pt_kly[3].x) 

189 self.assertEqual(p3.y, pt_kly[3].y)