pyedb 0.2.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 (128) hide show
  1. pyedb/__init__.py +17 -0
  2. pyedb/dotnet/__init__.py +0 -0
  3. pyedb/dotnet/application/Variables.py +2261 -0
  4. pyedb/dotnet/application/__init__.py +0 -0
  5. pyedb/dotnet/clr_module.py +103 -0
  6. pyedb/dotnet/edb.py +4237 -0
  7. pyedb/dotnet/edb_core/__init__.py +1 -0
  8. pyedb/dotnet/edb_core/cell/__init__.py +0 -0
  9. pyedb/dotnet/edb_core/cell/hierarchy/__init__.py +0 -0
  10. pyedb/dotnet/edb_core/cell/hierarchy/model.py +66 -0
  11. pyedb/dotnet/edb_core/components.py +2669 -0
  12. pyedb/dotnet/edb_core/configuration.py +423 -0
  13. pyedb/dotnet/edb_core/definition/__init__.py +0 -0
  14. pyedb/dotnet/edb_core/definition/component_def.py +166 -0
  15. pyedb/dotnet/edb_core/definition/component_model.py +30 -0
  16. pyedb/dotnet/edb_core/definition/definition_obj.py +18 -0
  17. pyedb/dotnet/edb_core/definition/definitions.py +12 -0
  18. pyedb/dotnet/edb_core/dotnet/__init__.py +0 -0
  19. pyedb/dotnet/edb_core/dotnet/database.py +1218 -0
  20. pyedb/dotnet/edb_core/dotnet/layout.py +238 -0
  21. pyedb/dotnet/edb_core/dotnet/primitive.py +1517 -0
  22. pyedb/dotnet/edb_core/edb_data/__init__.py +0 -0
  23. pyedb/dotnet/edb_core/edb_data/components_data.py +938 -0
  24. pyedb/dotnet/edb_core/edb_data/connectable.py +113 -0
  25. pyedb/dotnet/edb_core/edb_data/control_file.py +1268 -0
  26. pyedb/dotnet/edb_core/edb_data/design_options.py +35 -0
  27. pyedb/dotnet/edb_core/edb_data/edbvalue.py +45 -0
  28. pyedb/dotnet/edb_core/edb_data/hfss_extent_info.py +330 -0
  29. pyedb/dotnet/edb_core/edb_data/hfss_simulation_setup_data.py +1607 -0
  30. pyedb/dotnet/edb_core/edb_data/layer_data.py +576 -0
  31. pyedb/dotnet/edb_core/edb_data/nets_data.py +281 -0
  32. pyedb/dotnet/edb_core/edb_data/obj_base.py +19 -0
  33. pyedb/dotnet/edb_core/edb_data/padstacks_data.py +2080 -0
  34. pyedb/dotnet/edb_core/edb_data/ports.py +287 -0
  35. pyedb/dotnet/edb_core/edb_data/primitives_data.py +1397 -0
  36. pyedb/dotnet/edb_core/edb_data/simulation_configuration.py +2914 -0
  37. pyedb/dotnet/edb_core/edb_data/simulation_setup.py +716 -0
  38. pyedb/dotnet/edb_core/edb_data/siwave_simulation_setup_data.py +1205 -0
  39. pyedb/dotnet/edb_core/edb_data/sources.py +514 -0
  40. pyedb/dotnet/edb_core/edb_data/terminals.py +632 -0
  41. pyedb/dotnet/edb_core/edb_data/utilities.py +148 -0
  42. pyedb/dotnet/edb_core/edb_data/variables.py +91 -0
  43. pyedb/dotnet/edb_core/general.py +181 -0
  44. pyedb/dotnet/edb_core/hfss.py +1646 -0
  45. pyedb/dotnet/edb_core/layout.py +1244 -0
  46. pyedb/dotnet/edb_core/layout_validation.py +272 -0
  47. pyedb/dotnet/edb_core/materials.py +939 -0
  48. pyedb/dotnet/edb_core/net_class.py +335 -0
  49. pyedb/dotnet/edb_core/nets.py +1215 -0
  50. pyedb/dotnet/edb_core/padstack.py +1389 -0
  51. pyedb/dotnet/edb_core/siwave.py +1427 -0
  52. pyedb/dotnet/edb_core/stackup.py +2703 -0
  53. pyedb/edb_logger.py +396 -0
  54. pyedb/generic/__init__.py +0 -0
  55. pyedb/generic/constants.py +1063 -0
  56. pyedb/generic/data_handlers.py +320 -0
  57. pyedb/generic/design_types.py +104 -0
  58. pyedb/generic/filesystem.py +150 -0
  59. pyedb/generic/general_methods.py +1535 -0
  60. pyedb/generic/plot.py +1840 -0
  61. pyedb/generic/process.py +285 -0
  62. pyedb/generic/settings.py +224 -0
  63. pyedb/ipc2581/__init__.py +0 -0
  64. pyedb/ipc2581/bom/__init__.py +0 -0
  65. pyedb/ipc2581/bom/bom.py +21 -0
  66. pyedb/ipc2581/bom/bom_item.py +32 -0
  67. pyedb/ipc2581/bom/characteristics.py +37 -0
  68. pyedb/ipc2581/bom/refdes.py +16 -0
  69. pyedb/ipc2581/content/__init__.py +0 -0
  70. pyedb/ipc2581/content/color.py +38 -0
  71. pyedb/ipc2581/content/content.py +55 -0
  72. pyedb/ipc2581/content/dictionary_color.py +29 -0
  73. pyedb/ipc2581/content/dictionary_fill.py +28 -0
  74. pyedb/ipc2581/content/dictionary_line.py +30 -0
  75. pyedb/ipc2581/content/entry_color.py +13 -0
  76. pyedb/ipc2581/content/entry_line.py +14 -0
  77. pyedb/ipc2581/content/fill.py +15 -0
  78. pyedb/ipc2581/content/layer_ref.py +10 -0
  79. pyedb/ipc2581/content/standard_geometries_dictionary.py +72 -0
  80. pyedb/ipc2581/ecad/__init__.py +0 -0
  81. pyedb/ipc2581/ecad/cad_data/__init__.py +0 -0
  82. pyedb/ipc2581/ecad/cad_data/assembly_drawing.py +26 -0
  83. pyedb/ipc2581/ecad/cad_data/cad_data.py +37 -0
  84. pyedb/ipc2581/ecad/cad_data/component.py +41 -0
  85. pyedb/ipc2581/ecad/cad_data/drill.py +30 -0
  86. pyedb/ipc2581/ecad/cad_data/feature.py +54 -0
  87. pyedb/ipc2581/ecad/cad_data/layer.py +41 -0
  88. pyedb/ipc2581/ecad/cad_data/layer_feature.py +151 -0
  89. pyedb/ipc2581/ecad/cad_data/logical_net.py +32 -0
  90. pyedb/ipc2581/ecad/cad_data/outline.py +25 -0
  91. pyedb/ipc2581/ecad/cad_data/package.py +104 -0
  92. pyedb/ipc2581/ecad/cad_data/padstack_def.py +38 -0
  93. pyedb/ipc2581/ecad/cad_data/padstack_hole_def.py +24 -0
  94. pyedb/ipc2581/ecad/cad_data/padstack_instance.py +62 -0
  95. pyedb/ipc2581/ecad/cad_data/padstack_pad_def.py +26 -0
  96. pyedb/ipc2581/ecad/cad_data/path.py +89 -0
  97. pyedb/ipc2581/ecad/cad_data/phy_net.py +80 -0
  98. pyedb/ipc2581/ecad/cad_data/pin.py +31 -0
  99. pyedb/ipc2581/ecad/cad_data/polygon.py +169 -0
  100. pyedb/ipc2581/ecad/cad_data/profile.py +40 -0
  101. pyedb/ipc2581/ecad/cad_data/stackup.py +31 -0
  102. pyedb/ipc2581/ecad/cad_data/stackup_group.py +42 -0
  103. pyedb/ipc2581/ecad/cad_data/stackup_layer.py +21 -0
  104. pyedb/ipc2581/ecad/cad_data/step.py +275 -0
  105. pyedb/ipc2581/ecad/cad_header.py +33 -0
  106. pyedb/ipc2581/ecad/ecad.py +19 -0
  107. pyedb/ipc2581/ecad/spec.py +46 -0
  108. pyedb/ipc2581/history_record.py +37 -0
  109. pyedb/ipc2581/ipc2581.py +387 -0
  110. pyedb/ipc2581/logistic_header.py +25 -0
  111. pyedb/misc/__init__.py +0 -0
  112. pyedb/misc/aedtlib_personalib_install.py +14 -0
  113. pyedb/misc/downloads.py +322 -0
  114. pyedb/misc/misc.py +67 -0
  115. pyedb/misc/pyedb.runtimeconfig.json +13 -0
  116. pyedb/misc/siw_feature_config/__init__.py +0 -0
  117. pyedb/misc/siw_feature_config/emc/__init__.py +0 -0
  118. pyedb/misc/siw_feature_config/emc/component_tags.py +46 -0
  119. pyedb/misc/siw_feature_config/emc/net_tags.py +37 -0
  120. pyedb/misc/siw_feature_config/emc/tag_library.py +62 -0
  121. pyedb/misc/siw_feature_config/emc/xml_generic.py +78 -0
  122. pyedb/misc/siw_feature_config/emc_rule_checker_settings.py +179 -0
  123. pyedb/misc/utilities.py +27 -0
  124. pyedb/modeler/geometry_operators.py +2082 -0
  125. pyedb-0.2.0.dist-info/LICENSE +21 -0
  126. pyedb-0.2.0.dist-info/METADATA +208 -0
  127. pyedb-0.2.0.dist-info/RECORD +128 -0
  128. pyedb-0.2.0.dist-info/WHEEL +4 -0
@@ -0,0 +1,632 @@
1
+ import re
2
+
3
+ from pyedb.dotnet.edb_core.edb_data.connectable import Connectable
4
+ from pyedb.dotnet.edb_core.edb_data.padstacks_data import EDBPadstackInstance
5
+ from pyedb.dotnet.edb_core.edb_data.primitives_data import cast
6
+ from pyedb.dotnet.edb_core.general import convert_py_list_to_net_list
7
+ from pyedb.generic.general_methods import generate_unique_name, pyedb_function_handler
8
+
9
+
10
+ class Terminal(Connectable):
11
+ def __init__(self, pedb, edb_object=None):
12
+ super().__init__(pedb, edb_object)
13
+ self._reference_object = None
14
+
15
+ self._boundary_type_mapping = {
16
+ "InvalidBoundary": self._pedb.edb_api.cell.terminal.BoundaryType.InvalidBoundary,
17
+ "PortBoundary": self._pedb.edb_api.cell.terminal.BoundaryType.PortBoundary,
18
+ "PecBoundary": self._pedb.edb_api.cell.terminal.BoundaryType.PecBoundary,
19
+ "RlcBoundary": self._pedb.edb_api.cell.terminal.BoundaryType.RlcBoundary,
20
+ "kCurrentSource": self._pedb.edb_api.cell.terminal.BoundaryType.kCurrentSource,
21
+ "kVoltageSource": self._pedb.edb_api.cell.terminal.BoundaryType.kVoltageSource,
22
+ "kNexximGround": self._pedb.edb_api.cell.terminal.BoundaryType.kNexximGround,
23
+ "kNexximPort": self._pedb.edb_api.cell.terminal.BoundaryType.kNexximPort,
24
+ "kDcTerminal": self._pedb.edb_api.cell.terminal.BoundaryType.kDcTerminal,
25
+ "kVoltageProbe": self._pedb.edb_api.cell.terminal.BoundaryType.kVoltageProbe,
26
+ }
27
+
28
+ self._terminal_type_mapping = {
29
+ "InvalidTerminal": self._pedb.edb_api.cell.terminal.TerminalType.InvalidTerminal,
30
+ "EdgeTerminal": self._pedb.edb_api.cell.terminal.TerminalType.EdgeTerminal,
31
+ "PointTerminal": self._pedb.edb_api.cell.terminal.TerminalType.PointTerminal,
32
+ "TerminalInstanceTerminal": self._pedb.edb_api.cell.terminal.TerminalType.TerminalInstanceTerminal,
33
+ "PadstackInstanceTerminal": self._pedb.edb_api.cell.terminal.TerminalType.PadstackInstanceTerminal,
34
+ "BundleTerminal": self._pedb.edb_api.cell.terminal.TerminalType.BundleTerminal,
35
+ "PinGroupTerminal": self._pedb.edb_api.cell.terminal.TerminalType.PinGroupTerminal,
36
+ }
37
+
38
+ self._terminal_mapping = {
39
+ "EdgeTerminal": EdgeTerminal,
40
+ "PointTerminal": PointTerminal,
41
+ "PadstackInstanceTerminal": PadstackInstanceTerminal,
42
+ "BundleTerminal": BundleTerminal,
43
+ "PinGroupTerminal": PinGroupTerminal,
44
+ }
45
+
46
+ @property
47
+ def _hfss_port_property(self):
48
+ """HFSS port property."""
49
+ hfss_prop = re.search(r"HFSS\(.*?\)", self._edb_properties)
50
+ p = {}
51
+ if hfss_prop:
52
+ hfss_type = re.search(r"'HFSS Type'='([^']+)'", hfss_prop.group())
53
+ orientation = re.search(r"'Orientation'='([^']+)'", hfss_prop.group())
54
+ horizontal_ef = re.search(r"'Horizontal Extent Factor'='([^']+)'", hfss_prop.group())
55
+ vertical_ef = re.search(r"'Vertical Extent Factor'='([^']+)'", hfss_prop.group())
56
+ radial_ef = re.search(r"'Radial Extent Factor'='([^']+)'", hfss_prop.group())
57
+ pec_w = re.search(r"'PEC Launch Width'='([^']+)'", hfss_prop.group())
58
+
59
+ p["HFSS Type"] = hfss_type.group(1) if hfss_type else ""
60
+ p["Orientation"] = orientation.group(1) if orientation else ""
61
+ p["Horizontal Extent Factor"] = float(horizontal_ef.group(1)) if horizontal_ef else ""
62
+ p["Vertical Extent Factor"] = float(vertical_ef.group(1)) if vertical_ef else ""
63
+ p["Radial Extent Factor"] = float(radial_ef.group(1)) if radial_ef else ""
64
+ p["PEC Launch Width"] = pec_w.group(1) if pec_w else ""
65
+ else:
66
+ p["HFSS Type"] = ""
67
+ p["Orientation"] = ""
68
+ p["Horizontal Extent Factor"] = ""
69
+ p["Vertical Extent Factor"] = ""
70
+ p["Radial Extent Factor"] = ""
71
+ p["PEC Launch Width"] = ""
72
+ return p
73
+
74
+ @_hfss_port_property.setter
75
+ def _hfss_port_property(self, value):
76
+ txt = []
77
+ for k, v in value.items():
78
+ txt.append("'{}'='{}'".format(k, v))
79
+ txt = ",".join(txt)
80
+ self._edb_properties = "HFSS({})".format(txt)
81
+
82
+ @property
83
+ def hfss_type(self):
84
+ """HFSS port type."""
85
+ return self._hfss_port_property["HFSS Type"]
86
+
87
+ @hfss_type.setter
88
+ def hfss_type(self, value):
89
+ p = self._hfss_port_property
90
+ p["HFSS Type"] = value
91
+ self._hfss_port_property = p
92
+
93
+ @property
94
+ def is_circuit_port(self):
95
+ """Whether it is a circuit port."""
96
+ return self._edb_object.GetIsCircuitPort()
97
+
98
+ @is_circuit_port.setter
99
+ def is_circuit_port(self, value):
100
+ self._edb_object.SetIsCircuitPort(value)
101
+
102
+ @property
103
+ def _port_post_processing_prop(self):
104
+ """Get port post processing properties."""
105
+ return self._edb_object.GetPortPostProcessingProp()
106
+
107
+ @_port_post_processing_prop.setter
108
+ def _port_post_processing_prop(self, value):
109
+ self._edb_object.SetPortPostProcessingProp(value)
110
+
111
+ @property
112
+ def do_renormalize(self):
113
+ """Determine whether port renormalization is enabled."""
114
+ return self._port_post_processing_prop.DoRenormalize
115
+
116
+ @do_renormalize.setter
117
+ def do_renormalize(self, value):
118
+ ppp = self._port_post_processing_prop
119
+ ppp.DoRenormalize = value
120
+ self._port_post_processing_prop = ppp
121
+
122
+ @property
123
+ def name(self):
124
+ """Port Name.
125
+
126
+ Returns
127
+ -------
128
+ str
129
+ """
130
+ return self._edb_object.GetName()
131
+
132
+ @name.setter
133
+ def name(self, value):
134
+ if isinstance(value, str):
135
+ if not any(port for port in list(self._pedb.excitations.keys()) if port == value):
136
+ self._edb_object.SetName(value)
137
+ else:
138
+ self._pedb.logger.warning("An existing port already has this same name. A port name must be unique.")
139
+
140
+ @property
141
+ def net_name(self):
142
+ """Net name.
143
+
144
+ Returns
145
+ -------
146
+ str
147
+ """
148
+ return self.net.name
149
+
150
+ @property
151
+ def terminal_type(self):
152
+ """Terminal Type.
153
+
154
+ Returns
155
+ -------
156
+ int
157
+ """
158
+ return self._edb_object.GetTerminalType().ToString()
159
+
160
+ @terminal_type.setter
161
+ def terminal_type(self, value):
162
+ self._edb_object.GetTerminalType(self._terminal_type_mapping[value])
163
+
164
+ @property
165
+ def boundary_type(self):
166
+ """Boundary type.
167
+
168
+ Returns
169
+ -------
170
+ str
171
+ InvalidBoundary, PortBoundary, PecBoundary, RlcBoundary, kCurrentSource, kVoltageSource, kNexximGround,
172
+ kNexximPort, kDcTerminal, kVoltageProbe
173
+ """
174
+ return self._edb_object.GetBoundaryType().ToString()
175
+
176
+ @boundary_type.setter
177
+ def boundary_type(self, value):
178
+ self._edb_object.SetBoundaryType(self._boundary_type_mapping[value])
179
+
180
+ @property
181
+ def impedance(self):
182
+ """Impedance of the port."""
183
+ return self._edb_object.GetImpedance().ToDouble()
184
+
185
+ @impedance.setter
186
+ def impedance(self, value):
187
+ self._edb_object.SetImpedance(self._pedb.edb_value(value))
188
+
189
+ @property
190
+ def is_reference_terminal(self):
191
+ """Whether it is a reference terminal."""
192
+ return self._edb_object.IsReferenceTerminal()
193
+
194
+ @property
195
+ def ref_terminal(self):
196
+ """Get reference terminal."""
197
+
198
+ terminal = Terminal(self._pedb, self._edb_object.GetReferenceTerminal())
199
+ if not terminal.is_null:
200
+ return self._terminal_mapping[terminal.terminal_type](self._pedb, terminal._edb_object)
201
+
202
+ @ref_terminal.setter
203
+ def ref_terminal(self, value):
204
+ self._edb_object.SetReferenceTerminal(value._edb_object)
205
+
206
+ @property
207
+ def reference_object(self): # pragma : no cover
208
+ """This returns the object assigned as reference. It can be a primitive or a padstack instance.
209
+
210
+
211
+ Returns
212
+ -------
213
+ :class:`dotnet.edb_core.edb_data.padstacks_data.EDBPadstackInstance` or
214
+ :class:`pyedb.dotnet.edb_core.edb_data.primitives_data.EDBPrimitives`
215
+ """
216
+ if not self._reference_object:
217
+ term = self._edb_object
218
+
219
+ if self.terminal_type == self._pedb.edb_api.cell.terminal.TerminalType.EdgeTerminal:
220
+ edges = self._edb_object.GetEdges()
221
+ edgeType = edges[0].GetEdgeType()
222
+ if edgeType == self._pedb.edb_api.cell.terminal.EdgeType.PadEdge:
223
+ self._reference_object = self.get_pad_edge_terminal_reference_pin()
224
+ else:
225
+ self._reference_object = self.get_edge_terminal_reference_primitive()
226
+ elif self.terminal_type == "PinGroupTerminal":
227
+ self._reference_object = self.get_pin_group_terminal_reference_pin()
228
+ elif self.terminal_type == "PointTerminal":
229
+ self._reference_object = self.get_point_terminal_reference_primitive()
230
+ elif self.terminal_type == "PadstackInstanceTerminal":
231
+ self._reference_object = self.get_padstack_terminal_reference_pin()
232
+ else:
233
+ self._pedb.logger.warning("Invalid Terminal Type={}".format(term.GetTerminalType()))
234
+
235
+ return self._reference_object
236
+
237
+ @property
238
+ def reference_net_name(self):
239
+ """Net name to which reference_object belongs."""
240
+ ref_obj = self._reference_object if self._reference_object else self.reference_object
241
+ if ref_obj:
242
+ return ref_obj.net_name
243
+
244
+ return ""
245
+
246
+ @pyedb_function_handler()
247
+ def get_padstack_terminal_reference_pin(self, gnd_net_name_preference=None): # pragma : no cover
248
+ """Get a list of pad stacks instances and serves Coax wave ports,
249
+ pingroup terminals, PadEdge terminals.
250
+
251
+ Parameters
252
+ ----------
253
+ gnd_net_name_preference : str, optional
254
+ Preferred reference net name.
255
+
256
+ Returns
257
+ -------
258
+ :class:`dotnet.edb_core.edb_data.padstack_data.EDBPadstackInstance`
259
+ """
260
+
261
+ if self._edb_object.GetIsCircuitPort():
262
+ return self.get_pin_group_terminal_reference_pin()
263
+ _, padStackInstance, _ = self._edb_object.GetParameters()
264
+
265
+ # Get the pastack instance of the terminal
266
+ compInst = self._edb_object.GetComponent()
267
+ pins = self._pedb.components.get_pin_from_component(compInst.GetName())
268
+ return self._get_closest_pin(padStackInstance, pins, gnd_net_name_preference)
269
+
270
+ @pyedb_function_handler()
271
+ def get_pin_group_terminal_reference_pin(self, gnd_net_name_preference=None): # pragma : no cover
272
+ """Return a list of pins and serves terminals connected to pingroups.
273
+
274
+ Parameters
275
+ ----------
276
+ gnd_net_name_preference : str, optional
277
+ Preferred reference net name.
278
+
279
+ Returns
280
+ -------
281
+ :class:`dotnet.edb_core.edb_data.padstack_data.EDBPadstackInstance`
282
+ """
283
+
284
+ refTerm = self._edb_object.GetReferenceTerminal()
285
+ if self._edb_object.GetTerminalType() == self._pedb.edb_api.cell.terminal.TerminalType.PinGroupTerminal:
286
+ padStackInstance = self._edb_object.GetPinGroup().GetPins()[0]
287
+ pingroup = refTerm.GetPinGroup()
288
+ refPinList = pingroup.GetPins()
289
+ return self._get_closest_pin(padStackInstance, refPinList, gnd_net_name_preference)
290
+ elif (
291
+ self._edb_object.GetTerminalType() == self._pedb.edb_api.cell.terminal.TerminalType.PadstackInstanceTerminal
292
+ ):
293
+ _, padStackInstance, _ = self._edb_object.GetParameters()
294
+ if refTerm.GetTerminalType() == self._pedb.edb_api.cell.terminal.TerminalType.PinGroupTerminal:
295
+ pingroup = refTerm.GetPinGroup()
296
+ refPinList = pingroup.GetPins()
297
+ return self._get_closest_pin(padStackInstance, refPinList, gnd_net_name_preference)
298
+ else:
299
+ try:
300
+ _, refTermPSI, _ = refTerm.GetParameters()
301
+ return EDBPadstackInstance(refTermPSI, self._pedb)
302
+ except AttributeError:
303
+ return None
304
+ return None
305
+
306
+ @pyedb_function_handler()
307
+ def get_edge_terminal_reference_primitive(self): # pragma : no cover
308
+ """Check and return a primitive instance that serves Edge ports,
309
+ wave ports and coupled edge ports that are directly connedted to primitives.
310
+
311
+ Returns
312
+ -------
313
+ :class:`pyedb.dotnet.edb_core.edb_data.primitives_data.EDBPrimitives`
314
+ """
315
+
316
+ ref_layer = self._edb_object.GetReferenceLayer()
317
+ edges = self._edb_object.GetEdges()
318
+ _, _, point_data = edges[0].GetParameters()
319
+ X = point_data.X
320
+ Y = point_data.Y
321
+ shape_pd = self._pedb.edb_api.geometry.point_data(X, Y)
322
+ layer_name = ref_layer.GetName()
323
+ for primitive in self._pedb.layout.primitives:
324
+ if primitive.GetLayer().GetName() == layer_name or not layer_name:
325
+ prim_shape_data = primitive.GetPolygonData()
326
+ if prim_shape_data.PointInPolygon(shape_pd):
327
+ return cast(primitive, self._pedb)
328
+ return None # pragma: no cover
329
+
330
+ @pyedb_function_handler()
331
+ def get_point_terminal_reference_primitive(self): # pragma : no cover
332
+ """Find and return the primitive reference for the point terminal or the padstack instance.
333
+
334
+ Returns
335
+ -------
336
+ :class:`dotnet.edb_core.edb_data.padstacks_data.EDBPadstackInstance` or
337
+ :class:`pyedb.dotnet.edb_core.edb_data.primitives_data.EDBPrimitives`
338
+ """
339
+
340
+ ref_term = self._edb_object.GetReferenceTerminal() # return value is type terminal
341
+ _, point_data, layer = ref_term.GetParameters()
342
+ X = point_data.X
343
+ Y = point_data.Y
344
+ shape_pd = self._pedb.edb_api.geometry.point_data(X, Y)
345
+ layer_name = layer.GetName()
346
+ for primitive in self._pedb.layout.primitives:
347
+ if primitive.GetLayer().GetName() == layer_name:
348
+ prim_shape_data = primitive.GetPolygonData()
349
+ if prim_shape_data.PointInPolygon(shape_pd):
350
+ return cast(primitive, self._pedb)
351
+ for vias in self._pedb.padstacks.instances.values():
352
+ if layer_name in vias.layer_range_names:
353
+ plane = self._pedb.modeler.Shape(
354
+ "rectangle", pointA=vias.position, pointB=vias.padstack_definition.bounding_box[1]
355
+ )
356
+ rectangle_data = vias._pedb.modeler.shape_to_polygon_data(plane)
357
+ if rectangle_data.PointInPolygon(shape_pd):
358
+ return vias
359
+ return None
360
+
361
+ @pyedb_function_handler()
362
+ def get_pad_edge_terminal_reference_pin(self, gnd_net_name_preference=None):
363
+ """Get the closest pin padstack instances and serves any edge terminal connected to a pad.
364
+
365
+ Parameters
366
+ ----------
367
+ gnd_net_name_preference : str, optional
368
+ Preferred reference net name. Optianal, default is `None` which will auto compute the gnd name.
369
+
370
+ Returns
371
+ -------
372
+ :class:`pyedb.dotnet.edb_core.edb_data.padstacks_data.EDBPadstackInstance`
373
+ """
374
+ comp_inst = self._edb_object.GetComponent()
375
+ pins = self._pedb.components.get_pin_from_component(comp_inst.GetName())
376
+ try:
377
+ edges = self._edb_object.GetEdges()
378
+ except AttributeError:
379
+ return None
380
+ _, pad_edge_pstack_inst, _, _ = edges[0].GetParameters()
381
+ return self._get_closest_pin(pad_edge_pstack_inst, pins, gnd_net_name_preference)
382
+
383
+ @pyedb_function_handler()
384
+ def _get_closest_pin(self, ref_pin, pin_list, gnd_net=None):
385
+ _, pad_stack_inst_point, _ = ref_pin.GetPositionAndRotation() # get the xy of the padstack
386
+ if gnd_net is not None:
387
+ power_ground_net_names = [gnd_net]
388
+ else:
389
+ power_ground_net_names = [net for net in self._pedb.nets.power_nets.keys()]
390
+ comp_ref_pins = [i for i in pin_list if i.GetNet().GetName() in power_ground_net_names]
391
+ if len(comp_ref_pins) == 0: # pragma: no cover
392
+ self._pedb.logger.error(
393
+ "Terminal with PadStack Instance Name {} component has no reference pins.".format(ref_pin.GetName())
394
+ )
395
+ return None
396
+ closest_pin_distance = None
397
+ pin_obj = None
398
+ for pin in comp_ref_pins: # find the distance to all the pins to the terminal pin
399
+ if pin.GetName() == ref_pin.GetName(): # skip the reference psi
400
+ continue # pragma: no cover
401
+ _, pin_point, _ = pin.GetPositionAndRotation()
402
+ distance = pad_stack_inst_point.Distance(pin_point)
403
+ if closest_pin_distance is None:
404
+ closest_pin_distance = distance
405
+ pin_obj = pin
406
+ elif closest_pin_distance < distance:
407
+ continue
408
+ else:
409
+ closest_pin_distance = distance
410
+ pin_obj = pin
411
+ if pin_obj:
412
+ return EDBPadstackInstance(pin_obj, self._pedb)
413
+
414
+
415
+ class EdgeTerminal(Terminal):
416
+ def __init__(self, pedb, edb_object):
417
+ super().__init__(pedb, edb_object)
418
+
419
+ @pyedb_function_handler()
420
+ def couple_ports(self, port):
421
+ """Create a bundle wave port.
422
+
423
+ Parameters
424
+ ----------
425
+ port : :class:`dotnet.edb_core.ports.WavePort`, :class:`dotnet.edb_core.ports.GapPort`, list, optional
426
+ Ports to be added.
427
+
428
+ Returns
429
+ -------
430
+ :class:`dotnet.edb_core.ports.BundleWavePort`
431
+
432
+ """
433
+ if not isinstance(port, (list, tuple)):
434
+ port = [port]
435
+ temp = [self._edb_object]
436
+ temp.extend([i._edb_object for i in port])
437
+ edb_list = convert_py_list_to_net_list(temp, self._edb.cell.terminal.Terminal)
438
+ _edb_bundle_terminal = self._edb.cell.terminal.BundleTerminal.Create(edb_list)
439
+ return self._pedb.ports[self.name]
440
+
441
+
442
+ class BundleTerminal(Terminal):
443
+ """Manages bundle terminal properties.
444
+
445
+ Parameters
446
+ ----------
447
+ pedb : pyedb.edb.Edb
448
+ EDB object from the ``Edblib`` library.
449
+ edb_object : Ansys.Ansoft.Edb.Cell.Terminal.BundleTerminal
450
+ BundleTerminal instance from EDB.
451
+ """
452
+
453
+ def __init__(self, pedb, edb_object):
454
+ super().__init__(pedb, edb_object)
455
+
456
+ @property
457
+ def terminals(self):
458
+ """Get terminals belonging to this excitation."""
459
+ return [EdgeTerminal(self._pedb, i) for i in list(self._edb_object.GetTerminals())]
460
+
461
+ @property
462
+ def name(self):
463
+ return self.terminals[0].name
464
+
465
+ @pyedb_function_handler()
466
+ def decouple(self):
467
+ """Ungroup a bundle of terminals."""
468
+ return self._edb_object.Ungroup()
469
+
470
+
471
+ class PadstackInstanceTerminal(Terminal):
472
+ """Manages bundle terminal properties."""
473
+
474
+ def __init__(self, pedb, edb_object):
475
+ super().__init__(pedb, edb_object)
476
+
477
+ @property
478
+ def position(self):
479
+ """Return terminal position.
480
+ Returns
481
+ -------
482
+ Position [x,y] : [float, float]
483
+ """
484
+ edb_padstack_instance = self._edb_object.GetParameters()
485
+ if edb_padstack_instance[0]:
486
+ return EDBPadstackInstance(edb_padstack_instance[1], self._pedb).position
487
+ return False
488
+
489
+ def create(self, padstack_instance, name=None, layer=None, is_ref=False):
490
+ """Create an edge terminal.
491
+
492
+ Parameters
493
+ ----------
494
+ prim_id : int
495
+ Primitive ID.
496
+ point_on_edge : list
497
+ Coordinate of the point to define the edge terminal.
498
+ The point must be on the target edge but not on the two
499
+ ends of the edge.
500
+ terminal_name : str, optional
501
+ Name of the terminal. The default is ``None``, in which case the
502
+ default name is assigned.
503
+ is_ref : bool, optional
504
+ Whether it is a reference terminal. The default is ``False``.
505
+
506
+ Returns
507
+ -------
508
+ Edb.Cell.Terminal.EdgeTerminal
509
+ """
510
+ if not name:
511
+ pin_name = padstack_instance._edb_object.GetName()
512
+ refdes = padstack_instance.component.refdes
513
+ name = "{}_{}".format(refdes, pin_name)
514
+ name = generate_unique_name(name)
515
+
516
+ if not layer:
517
+ layer = padstack_instance.start_layer
518
+
519
+ layer_obj = self._pedb.stackup.signal_layers[layer]
520
+
521
+ terminal = self._edb.cell.terminal.PadstackInstanceTerminal.Create(
522
+ self._pedb.active_layout,
523
+ self.net.net_object,
524
+ name,
525
+ padstack_instance._edb_object,
526
+ layer_obj._edb_layer,
527
+ isRef=is_ref,
528
+ )
529
+ terminal = PadstackInstanceTerminal(self._pedb, terminal)
530
+
531
+ return terminal if not terminal.is_null else False
532
+
533
+
534
+ class PointTerminal(Terminal):
535
+ """Manages point terminal properties."""
536
+
537
+ def __init__(self, pedb, edb_object=None):
538
+ super().__init__(pedb, edb_object)
539
+
540
+ @pyedb_function_handler
541
+ def create(self, name, net, location, layer, is_ref=False):
542
+ """Create a point terminal.
543
+
544
+ Parameters
545
+ ----------
546
+ name : str
547
+ Name of the terminal.
548
+ net : str
549
+ Name of the net.
550
+ location : list
551
+ Location of the terminal.
552
+ layer : str
553
+ Name of the layer.
554
+ is_ref : bool, optional
555
+ Whether it is a reference terminal.
556
+
557
+ Returns
558
+ -------
559
+ :class:`pyedb.dotnet.edb_core.edb_data.terminals.PointTerminal`
560
+ """
561
+ terminal = self._pedb.edb_api.cell.terminal.PointTerminal.Create(
562
+ self._pedb.active_layout,
563
+ self._pedb.nets[net].net_object,
564
+ name,
565
+ self._pedb.point_data(*location),
566
+ self._pedb.stackup[layer]._edb_layer,
567
+ is_ref,
568
+ )
569
+ terminal = PointTerminal(self._pedb, terminal)
570
+ return terminal if not terminal.is_null else False
571
+
572
+ @property
573
+ def location(self):
574
+ """Location of the terminal."""
575
+ layer = list(self._pedb.stackup.layers.values())[0]._edb_layer
576
+ _, point_data, _ = self._edb_object.GetParameters(None, layer)
577
+ return [point_data.X.ToDouble(), point_data.Y.ToDouble()]
578
+
579
+ @location.setter
580
+ def location(self, value):
581
+ layer = self.layer
582
+ self._edb_object.SetParameters(self._pedb.point_data(*value), layer)
583
+
584
+ @property
585
+ def layer(self):
586
+ """Get layer of the terminal."""
587
+ point_data = self._pedb.point_data(0, 0)
588
+ layer = list(self._pedb.stackup.layers.values())[0]._edb_layer
589
+ if self._edb_object.GetParameters(point_data, layer):
590
+ return layer
591
+
592
+ @layer.setter
593
+ def layer(self, value):
594
+ layer = self._pedb.stackup.layers[value]._edb_layer
595
+ point_data = self._pedb.point_data(*self.location)
596
+ self._edb_object.SetParameters(point_data, layer)
597
+
598
+
599
+ class PinGroupTerminal(Terminal):
600
+ """Manages pin group terminal properties."""
601
+
602
+ def __init__(self, pedb, edb_object=None):
603
+ super().__init__(pedb, edb_object)
604
+
605
+ @pyedb_function_handler
606
+ def create(self, name, net_name, pin_group_name, is_ref=False):
607
+ """Create a pin group terminal.
608
+
609
+ Parameters
610
+ ----------
611
+ name : str
612
+ Name of the terminal.
613
+ net_name : str
614
+ Name of the net.
615
+ pin_group_name : str,
616
+ Name of the pin group.
617
+ is_ref : bool, optional
618
+ Whether it is a reference terminal. The default is ``False``.
619
+
620
+ Returns
621
+ -------
622
+ :class:`pyedb.dotnet.edb_core.edb_data.terminals.PinGroupTerminal`
623
+ """
624
+ term = self._pedb.edb_api.cell.terminal.PinGroupTerminal.Create(
625
+ self._pedb.active_layout,
626
+ self._pedb.nets[net_name].net_object,
627
+ name,
628
+ self._pedb.siwave.pin_groups[pin_group_name]._edb_object,
629
+ is_ref,
630
+ )
631
+ term = PinGroupTerminal(self._pedb, term)
632
+ return term if not term.is_null else False