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
« 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#
25import allure
26import unittest
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
32from klayout_pex.log import (
33 LogLevel,
34 set_log_level,
35)
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)
45 def setUp(self):
46 self.dbu = 0.001
48 def test_klayout_point(self):
49 conv = ShapesConverter(self.dbu)
51 p_pb = shapes_pb2.Point()
52 p_pb.x = 10
53 p_pb.y = 20
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)
59 def test_klayout_point_to_pb(self):
60 conv = ShapesConverter(self.dbu)
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)
68 def test_klayout_box(self):
69 conv = ShapesConverter(self.dbu)
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
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)
84 def test_klayout_box_to_pb(self):
85 conv = ShapesConverter(self.dbu)
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)
96 def test_klayout_box_to_pb__with_properties(self):
97 conv = ShapesConverter(self.dbu)
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)
104 def test_klayout_polygon(self):
105 conv = ShapesConverter(self.dbu)
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
122 pg_kly = conv.klayout_polygon(sh_pb.polygon)
123 pt_kly = list(pg_kly.each_point_hull())
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)
134 def test_klayout_polygon_to_pb(self):
135 conv = ShapesConverter(self.dbu)
137 pt_kly = [
138 kdb.Point(10, 20),
139 kdb.Point(10, 30),
140 kdb.Point(750, 30),
141 kdb.Point(750, 20),
142 ]
144 pg_kly = kdb.PolygonWithProperties(
145 kdb.Polygon(pt_kly),
146 {'net': 'VSS'}
147 )
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)
159 def test_klayout_region(self):
160 conv = ShapesConverter(self.dbu)
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
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)