pyedb 0.22.1__py3-none-any.whl → 0.24.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of pyedb might be problematic. Click here for more details.

Files changed (41) hide show
  1. pyedb/__init__.py +1 -1
  2. pyedb/configuration/cfg_components.py +1 -1
  3. pyedb/configuration/cfg_ports_sources.py +3 -3
  4. pyedb/configuration/configuration.py +2 -2
  5. pyedb/dotnet/edb.py +55 -56
  6. pyedb/dotnet/edb_core/cell/hierarchy/component.py +1 -1
  7. pyedb/dotnet/edb_core/cell/hierarchy/hierarchy_obj.py +11 -0
  8. pyedb/dotnet/edb_core/cell/layout.py +30 -23
  9. pyedb/dotnet/edb_core/cell/layout_obj.py +0 -9
  10. pyedb/dotnet/edb_core/cell/primitive/__init__.py +3 -0
  11. pyedb/dotnet/edb_core/cell/{primitive.py → primitive/bondwire.py} +1 -146
  12. pyedb/dotnet/edb_core/cell/primitive/path.py +351 -0
  13. pyedb/dotnet/edb_core/cell/primitive/primitive.py +895 -0
  14. pyedb/dotnet/edb_core/cell/terminal/bundle_terminal.py +0 -4
  15. pyedb/dotnet/edb_core/cell/terminal/edge_terminal.py +1 -1
  16. pyedb/dotnet/edb_core/cell/terminal/terminal.py +1 -1
  17. pyedb/dotnet/edb_core/components.py +26 -18
  18. pyedb/dotnet/edb_core/dotnet/database.py +1 -23
  19. pyedb/dotnet/edb_core/dotnet/primitive.py +3 -139
  20. pyedb/dotnet/edb_core/edb_data/nets_data.py +1 -11
  21. pyedb/dotnet/edb_core/edb_data/padstacks_data.py +12 -38
  22. pyedb/dotnet/edb_core/edb_data/primitives_data.py +56 -868
  23. pyedb/dotnet/edb_core/edb_data/simulation_configuration.py +0 -18
  24. pyedb/dotnet/edb_core/geometry/polygon_data.py +43 -0
  25. pyedb/dotnet/edb_core/hfss.py +27 -23
  26. pyedb/dotnet/edb_core/layout_validation.py +3 -3
  27. pyedb/dotnet/edb_core/materials.py +1 -1
  28. pyedb/dotnet/edb_core/modeler.py +65 -82
  29. pyedb/dotnet/edb_core/nets.py +8 -7
  30. pyedb/dotnet/edb_core/padstack.py +16 -17
  31. pyedb/dotnet/edb_core/siwave.py +2 -2
  32. pyedb/dotnet/edb_core/stackup.py +64 -87
  33. pyedb/ipc2581/ecad/cad_data/layer_feature.py +1 -1
  34. pyedb/ipc2581/ecad/cad_data/polygon.py +2 -2
  35. pyedb/ipc2581/ecad/cad_data/step.py +3 -3
  36. pyedb/ipc2581/ipc2581.py +2 -2
  37. pyedb/siwave.py +99 -0
  38. {pyedb-0.22.1.dist-info → pyedb-0.24.0.dist-info}/METADATA +3 -3
  39. {pyedb-0.22.1.dist-info → pyedb-0.24.0.dist-info}/RECORD +41 -38
  40. {pyedb-0.22.1.dist-info → pyedb-0.24.0.dist-info}/LICENSE +0 -0
  41. {pyedb-0.22.1.dist-info → pyedb-0.24.0.dist-info}/WHEEL +0 -0
@@ -0,0 +1,351 @@
1
+ # Copyright (C) 2023 - 2024 ANSYS, Inc. and/or its affiliates.
2
+ # SPDX-License-Identifier: MIT
3
+ #
4
+ #
5
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ # of this software and associated documentation files (the "Software"), to deal
7
+ # in the Software without restriction, including without limitation the rights
8
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ # copies of the Software, and to permit persons to whom the Software is
10
+ # furnished to do so, subject to the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be included in all
13
+ # copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ # SOFTWARE.
22
+ import math
23
+
24
+ from pyedb.dotnet.edb_core.cell.primitive.primitive import Primitive
25
+ from pyedb.dotnet.edb_core.general import convert_py_list_to_net_list
26
+ from pyedb.dotnet.edb_core.geometry.point_data import PointData
27
+
28
+
29
+ class Path(Primitive):
30
+ def __init__(self, pedb, edb_object=None):
31
+ super().__init__(pedb, edb_object)
32
+
33
+ @property
34
+ def width(self):
35
+ """Path width.
36
+
37
+ Returns
38
+ -------
39
+ float
40
+ Path width or None.
41
+ """
42
+ return self._edb_object.GetWidth()
43
+
44
+ @width.setter
45
+ def width(self, value):
46
+ self.primitive_object.SetWidth(self._pedb.edb_value(value))
47
+
48
+ def get_end_cap_style(self):
49
+ """Get path end cap styles.
50
+
51
+ Returns
52
+ -------
53
+ tuple[
54
+ :class:`PathEndCapType`,
55
+ :class:`PathEndCapType`
56
+ ]
57
+
58
+ Returns a tuple of the following format:
59
+
60
+ **(end_cap1, end_cap2)**
61
+
62
+ **end_cap1** : End cap style of path start end cap.
63
+
64
+ **end_cap2** : End cap style of path end cap.
65
+ """
66
+ return self._edb_object.GetEndCapStyle()
67
+
68
+ def set_end_cap_style(self, end_cap1, end_cap2):
69
+ """Set path end cap styles.
70
+
71
+ Parameters
72
+ ----------
73
+ end_cap1: :class:`PathEndCapType`
74
+ End cap style of path start end cap.
75
+ end_cap2: :class:`PathEndCapType`
76
+ End cap style of path end cap.
77
+ """
78
+ self._edb_object.SetEndCapStyle(end_cap1, end_cap2)
79
+
80
+ @property
81
+ def length(self):
82
+ """Path length in meters.
83
+
84
+ Returns
85
+ -------
86
+ float
87
+ Path length in meters.
88
+ """
89
+ center_line_arcs = list(self._edb_object.GetCenterLine().GetArcData())
90
+ path_length = 0.0
91
+ for arc in center_line_arcs:
92
+ path_length += arc.GetLength()
93
+ if self.get_end_cap_style()[0]:
94
+ if not self.get_end_cap_style()[1].value__ == 1:
95
+ path_length += self.width / 2
96
+ if not self.get_end_cap_style()[2].value__ == 1:
97
+ path_length += self.width / 2
98
+ return path_length
99
+
100
+ def add_point(self, x, y, incremental=False):
101
+ """Add a point at the end of the path.
102
+
103
+ Parameters
104
+ ----------
105
+ x: str, int, float
106
+ X coordinate.
107
+ y: str, in, float
108
+ Y coordinate.
109
+ incremental: bool
110
+ Add point incrementally. If True, coordinates of the added point is incremental to the last point.
111
+ The default value is ``False``.
112
+
113
+ Returns
114
+ -------
115
+ bool
116
+ """
117
+ center_line = self._edb_object.GetCenterLine()
118
+
119
+ if incremental:
120
+ x = self._pedb.edb_value(x)
121
+ y = self._pedb.edb_value(y)
122
+ last_point = list(center_line.Points)[-1]
123
+ x = "({})+({})".format(x, last_point.X.ToString())
124
+ y = "({})+({})".format(y, last_point.Y.ToString())
125
+ center_line.AddPoint(PointData(self._pedb, x=x, y=y)._edb_object)
126
+ return self._edb_object.SetCenterLine(center_line)
127
+
128
+ def get_center_line(self, to_string=False):
129
+ """Get the center line of the trace.
130
+
131
+ Parameters
132
+ ----------
133
+ to_string : bool, optional
134
+ Type of return. The default is ``"False"``.
135
+
136
+ Returns
137
+ -------
138
+ list
139
+
140
+ """
141
+ if to_string:
142
+ return [[p.X.ToString(), p.Y.ToString()] for p in list(self._edb_object.GetCenterLine().Points)]
143
+ else:
144
+ return [[p.X.ToDouble(), p.Y.ToDouble()] for p in list(self._edb_object.GetCenterLine().Points)]
145
+
146
+ def clone(self):
147
+ """Clone a primitive object with keeping same definition and location.
148
+
149
+ Returns
150
+ -------
151
+ bool
152
+ ``True`` when successful, ``False`` when failed.
153
+ """
154
+ center_line = self.center_line
155
+ width = self.width
156
+ corner_style = self.corner_style
157
+ end_cap_style = self.get_end_cap_style()
158
+ cloned_path = self._app.edb_api.cell.primitive.path.create(
159
+ self._app.active_layout,
160
+ self.layer_name,
161
+ self.net,
162
+ width,
163
+ end_cap_style[1],
164
+ end_cap_style[2],
165
+ corner_style,
166
+ center_line,
167
+ )
168
+ if cloned_path:
169
+ return cloned_path
170
+
171
+ #
172
+
173
+ def create_edge_port(
174
+ self,
175
+ name,
176
+ position="End",
177
+ port_type="Wave",
178
+ reference_layer=None,
179
+ horizontal_extent_factor=5,
180
+ vertical_extent_factor=3,
181
+ pec_launch_width="0.01mm",
182
+ ):
183
+ """
184
+
185
+ Parameters
186
+ ----------
187
+ name : str
188
+ Name of the port.
189
+ position : str, optional
190
+ Position of the port. The default is ``"End"``, in which case the port is created at the end of the trace.
191
+ Options are ``"Start"`` and ``"End"``.
192
+ port_type : str, optional
193
+ Type of the port. The default is ``"Wave"``, in which case a wave port is created. Options are ``"Wave"``
194
+ and ``"Gap"``.
195
+ reference_layer : str, optional
196
+ Name of the references layer. The default is ``None``. Only available for gap port.
197
+ horizontal_extent_factor : int, optional
198
+ Horizontal extent factor of the wave port. The default is ``5``.
199
+ vertical_extent_factor : int, optional
200
+ Vertical extent factor of the wave port. The default is ``3``.
201
+ pec_launch_width : float, str, optional
202
+ Perfect electrical conductor width of the wave port. The default is ``"0.01mm"``.
203
+
204
+ Returns
205
+ -------
206
+ :class:`dotnet.edb_core.edb_data.sources.ExcitationPorts`
207
+
208
+ Examples
209
+ --------
210
+ >>> edbapp = pyedb.dotnet.Edb("myproject.aedb")
211
+ >>> sig = appedb.modeler.create_trace([[0, 0], ["9mm", 0]], "TOP", "1mm", "SIG", "Flat", "Flat")
212
+ >>> sig.create_edge_port("pcb_port", "end", "Wave", None, 8, 8)
213
+
214
+ """
215
+ center_line = self.get_center_line()
216
+ pos = center_line[-1] if position.lower() == "end" else center_line[0]
217
+
218
+ if port_type.lower() == "wave":
219
+ return self._app.hfss.create_wave_port(
220
+ self.id, pos, name, 50, horizontal_extent_factor, vertical_extent_factor, pec_launch_width
221
+ )
222
+ else:
223
+ return self._app.hfss.create_edge_port_vertical(self.id, pos, name, 50, reference_layer)
224
+
225
+ def create_via_fence(self, distance, gap, padstack_name, net_name="GND"):
226
+ """Create via fences on both sides of the trace.
227
+
228
+ Parameters
229
+ ----------
230
+ distance: str, float
231
+ Distance between via fence and trace center line.
232
+ gap: str, float
233
+ Gap between vias.
234
+ padstack_name: str
235
+ Name of the via padstack.
236
+ net_name: str, optional
237
+ Name of the net.
238
+
239
+ Returns
240
+ -------
241
+ """
242
+
243
+ def getAngle(v1, v2): # pragma: no cover
244
+ v1_mag = math.sqrt(v1[0] ** 2 + v1[1] ** 2)
245
+ v2_mag = math.sqrt(v2[0] ** 2 + v2[1] ** 2)
246
+ dotsum = v1[0] * v2[0] + v1[1] * v2[1]
247
+ if v1[0] * v2[1] - v1[1] * v2[0] > 0:
248
+ scale = 1
249
+ else:
250
+ scale = -1
251
+ dtheta = scale * math.acos(dotsum / (v1_mag * v2_mag))
252
+
253
+ return dtheta
254
+
255
+ def getLocations(line, gap): # pragma: no cover
256
+ location = [line[0]]
257
+ residual = 0
258
+
259
+ for n in range(len(line) - 1):
260
+ x0, y0 = line[n]
261
+ x1, y1 = line[n + 1]
262
+ length = math.sqrt((x1 - x0) ** 2 + (y1 - y0) ** 2)
263
+ dx, dy = (x1 - x0) / length, (y1 - y0) / length
264
+ x = x0 - dx * residual
265
+ y = y0 - dy * residual
266
+ length = length + residual
267
+ while length >= gap:
268
+ x += gap * dx
269
+ y += gap * dy
270
+ location.append((x, y))
271
+ length -= gap
272
+
273
+ residual = length
274
+ return location
275
+
276
+ def getParalletLines(pts, distance): # pragma: no cover
277
+ leftline = []
278
+ rightline = []
279
+
280
+ x0, y0 = pts[0]
281
+ x1, y1 = pts[1]
282
+ vector = (x1 - x0, y1 - y0)
283
+ orientation1 = getAngle((1, 0), vector)
284
+
285
+ leftturn = orientation1 + math.pi / 2
286
+ righrturn = orientation1 - math.pi / 2
287
+ leftPt = (x0 + distance * math.cos(leftturn), y0 + distance * math.sin(leftturn))
288
+ leftline.append(leftPt)
289
+ rightPt = (x0 + distance * math.cos(righrturn), y0 + distance * math.sin(righrturn))
290
+ rightline.append(rightPt)
291
+
292
+ for n in range(1, len(pts) - 1):
293
+ x0, y0 = pts[n - 1]
294
+ x1, y1 = pts[n]
295
+ x2, y2 = pts[n + 1]
296
+
297
+ v1 = (x1 - x0, y1 - y0)
298
+ v2 = (x2 - x1, y2 - y1)
299
+ dtheta = getAngle(v1, v2)
300
+ orientation1 = getAngle((1, 0), v1)
301
+
302
+ leftturn = orientation1 + dtheta / 2 + math.pi / 2
303
+ righrturn = orientation1 + dtheta / 2 - math.pi / 2
304
+
305
+ distance2 = distance / math.sin((math.pi - dtheta) / 2)
306
+ leftPt = (x1 + distance2 * math.cos(leftturn), y1 + distance2 * math.sin(leftturn))
307
+ leftline.append(leftPt)
308
+ rightPt = (x1 + distance2 * math.cos(righrturn), y1 + distance2 * math.sin(righrturn))
309
+ rightline.append(rightPt)
310
+
311
+ x0, y0 = pts[-2]
312
+ x1, y1 = pts[-1]
313
+
314
+ vector = (x1 - x0, y1 - y0)
315
+ orientation1 = getAngle((1, 0), vector)
316
+ leftturn = orientation1 + math.pi / 2
317
+ righrturn = orientation1 - math.pi / 2
318
+ leftPt = (x1 + distance * math.cos(leftturn), y1 + distance * math.sin(leftturn))
319
+ leftline.append(leftPt)
320
+ rightPt = (x1 + distance * math.cos(righrturn), y1 + distance * math.sin(righrturn))
321
+ rightline.append(rightPt)
322
+ return leftline, rightline
323
+
324
+ distance = self._pedb.edb_value(distance).ToDouble()
325
+ gap = self._pedb.edb_value(gap).ToDouble()
326
+ center_line = self.get_center_line()
327
+ leftline, rightline = getParalletLines(center_line, distance)
328
+ for x, y in getLocations(rightline, gap) + getLocations(leftline, gap):
329
+ self._pedb.padstacks.place([x, y], padstack_name, net_name=net_name)
330
+
331
+ @property
332
+ def center_line(self):
333
+ """:class:`PolygonData <ansys.edb.geometry.PolygonData>`: Center line for this Path."""
334
+ edb_center_line = self._edb_object.GetCenterLine()
335
+ return [[pt.X.ToDouble(), pt.Y.ToDouble()] for pt in list(edb_center_line.Points)]
336
+
337
+ @center_line.setter
338
+ def center_line(self, value):
339
+ if isinstance(value, list):
340
+ points = [self._pedb.point_data(i[0], i[1]) for i in value]
341
+ polygon_data = self._edb.geometry.polygon_data.dotnetobj(convert_py_list_to_net_list(points), False)
342
+ self._edb_object.SetCenterLine(polygon_data)
343
+
344
+ @property
345
+ def corner_style(self):
346
+ """:class:`PathCornerType`: Path's corner style."""
347
+ return self._edb_object.GetCornerStyle()
348
+
349
+ @corner_style.setter
350
+ def corner_style(self, corner_type):
351
+ self._edb_object.SetCornerStyle(corner_type)