pyedb 0.56.0__py3-none-any.whl → 0.58.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.
- pyedb/__init__.py +1 -1
- pyedb/configuration/cfg_data.py +3 -0
- pyedb/configuration/cfg_pin_groups.py +2 -0
- pyedb/configuration/cfg_terminals.py +232 -0
- pyedb/configuration/configuration.py +146 -3
- pyedb/dotnet/clr_module.py +1 -2
- pyedb/dotnet/database/Variables.py +30 -22
- pyedb/dotnet/database/cell/hierarchy/component.py +2 -8
- pyedb/dotnet/database/cell/layout.py +5 -1
- pyedb/dotnet/database/cell/primitive/primitive.py +2 -2
- pyedb/dotnet/database/cell/terminal/bundle_terminal.py +12 -0
- pyedb/dotnet/database/cell/terminal/pingroup_terminal.py +1 -1
- pyedb/dotnet/database/cell/terminal/terminal.py +38 -0
- pyedb/dotnet/database/components.py +15 -19
- pyedb/dotnet/database/dotnet/database.py +1 -0
- pyedb/dotnet/database/edb_data/control_file.py +19 -8
- pyedb/dotnet/database/edb_data/nets_data.py +3 -3
- pyedb/dotnet/database/edb_data/padstacks_data.py +39 -14
- pyedb/dotnet/database/edb_data/ports.py +0 -25
- pyedb/dotnet/database/edb_data/primitives_data.py +3 -3
- pyedb/dotnet/database/edb_data/raptor_x_simulation_setup_data.py +18 -19
- pyedb/dotnet/database/edb_data/simulation_configuration.py +3 -3
- pyedb/dotnet/database/edb_data/sources.py +21 -2
- pyedb/dotnet/database/general.py +1 -6
- pyedb/dotnet/database/hfss.py +9 -8
- pyedb/dotnet/database/layout_validation.py +14 -3
- pyedb/dotnet/database/materials.py +1 -3
- pyedb/dotnet/database/modeler.py +7 -3
- pyedb/dotnet/database/nets.py +27 -19
- pyedb/dotnet/database/padstack.py +4 -2
- pyedb/dotnet/database/sim_setup_data/io/siwave.py +54 -1
- pyedb/dotnet/database/siwave.py +4 -3
- pyedb/dotnet/database/stackup.py +55 -58
- pyedb/dotnet/database/utilities/heatsink.py +0 -1
- pyedb/dotnet/database/utilities/hfss_simulation_setup.py +81 -0
- pyedb/dotnet/database/utilities/simulation_setup.py +7 -5
- pyedb/dotnet/database/utilities/siwave_cpa_simulation_setup.py +1 -0
- pyedb/dotnet/database/utilities/siwave_simulation_setup.py +264 -13
- pyedb/dotnet/edb.py +65 -47
- pyedb/exceptions.py +1 -2
- pyedb/extensions/create_cell_array.py +67 -49
- pyedb/generic/data_handlers.py +13 -23
- pyedb/generic/design_types.py +9 -35
- pyedb/generic/filesystem.py +4 -2
- pyedb/generic/general_methods.py +28 -41
- pyedb/generic/plot.py +8 -23
- pyedb/generic/process.py +78 -10
- pyedb/grpc/database/_typing.py +0 -0
- pyedb/grpc/database/components.py +14 -13
- pyedb/grpc/database/control_file.py +27 -40
- pyedb/grpc/database/definition/materials.py +1 -1
- pyedb/grpc/database/definition/package_def.py +6 -3
- pyedb/grpc/database/definition/padstack_def.py +14 -12
- pyedb/grpc/database/hfss.py +1 -4
- pyedb/grpc/database/hierarchy/component.py +5 -13
- pyedb/grpc/database/hierarchy/pingroup.py +16 -3
- pyedb/grpc/database/layers/layer.py +1 -2
- pyedb/grpc/database/layers/stackup_layer.py +42 -19
- pyedb/grpc/database/layout/layout.py +43 -27
- pyedb/grpc/database/layout/voltage_regulator.py +6 -1
- pyedb/grpc/database/layout_validation.py +5 -2
- pyedb/grpc/database/modeler.py +254 -252
- pyedb/grpc/database/net/differential_pair.py +9 -2
- pyedb/grpc/database/net/extended_net.py +24 -9
- pyedb/grpc/database/net/net.py +14 -5
- pyedb/grpc/database/net/net_class.py +24 -7
- pyedb/grpc/database/nets.py +11 -43
- pyedb/grpc/database/padstacks.py +67 -119
- pyedb/grpc/database/primitive/bondwire.py +3 -67
- pyedb/grpc/database/primitive/circle.py +42 -3
- pyedb/grpc/database/primitive/padstack_instance.py +58 -31
- pyedb/grpc/database/primitive/path.py +160 -11
- pyedb/grpc/database/primitive/polygon.py +73 -7
- pyedb/grpc/database/primitive/primitive.py +2 -2
- pyedb/grpc/database/primitive/rectangle.py +105 -4
- pyedb/grpc/database/simulation_setup/hfss_general_settings.py +0 -2
- pyedb/grpc/database/simulation_setup/hfss_settings_options.py +0 -4
- pyedb/grpc/database/simulation_setup/hfss_simulation_setup.py +79 -0
- pyedb/grpc/database/simulation_setup/siwave_cpa_simulation_setup.py +1 -0
- pyedb/grpc/database/simulation_setup/sweep_data.py +1 -3
- pyedb/grpc/database/siwave.py +6 -13
- pyedb/grpc/database/source_excitations.py +46 -63
- pyedb/grpc/database/stackup.py +55 -60
- pyedb/grpc/database/terminal/bundle_terminal.py +10 -3
- pyedb/grpc/database/terminal/padstack_instance_terminal.py +9 -11
- pyedb/grpc/database/terminal/pingroup_terminal.py +8 -1
- pyedb/grpc/database/terminal/point_terminal.py +30 -0
- pyedb/grpc/database/terminal/terminal.py +35 -10
- pyedb/grpc/database/utility/heat_sink.py +0 -1
- pyedb/grpc/database/utility/hfss_extent_info.py +2 -2
- pyedb/grpc/database/utility/xml_control_file.py +19 -8
- pyedb/grpc/edb.py +63 -32
- pyedb/grpc/edb_init.py +1 -0
- pyedb/ipc2581/ecad/cad_data/layer_feature.py +6 -2
- pyedb/ipc2581/ecad/cad_data/step.py +1 -1
- pyedb/ipc2581/ipc2581.py +8 -7
- pyedb/libraries/common.py +3 -4
- pyedb/libraries/rf_libraries/base_functions.py +7 -16
- pyedb/libraries/rf_libraries/planar_antennas.py +3 -21
- pyedb/misc/aedtlib_personalib_install.py +2 -2
- pyedb/misc/downloads.py +19 -3
- pyedb/misc/misc.py +5 -2
- pyedb/misc/siw_feature_config/emc_rule_checker_settings.py +3 -2
- pyedb/misc/siw_feature_config/xtalk_scan/scan_config.py +0 -1
- pyedb/misc/utilities.py +0 -1
- pyedb/modeler/geometry_operators.py +3 -2
- {pyedb-0.56.0.dist-info → pyedb-0.58.0.dist-info}/METADATA +6 -7
- {pyedb-0.56.0.dist-info → pyedb-0.58.0.dist-info}/RECORD +110 -108
- {pyedb-0.56.0.dist-info → pyedb-0.58.0.dist-info}/WHEEL +0 -0
- {pyedb-0.56.0.dist-info → pyedb-0.58.0.dist-info}/licenses/LICENSE +0 -0
pyedb/grpc/database/stackup.py
CHANGED
|
@@ -41,15 +41,18 @@ from ansys.edb.core.definition.solder_ball_property import (
|
|
|
41
41
|
from ansys.edb.core.geometry.point3d_data import Point3DData as GrpcPoint3DData
|
|
42
42
|
from ansys.edb.core.hierarchy.cell_instance import CellInstance as GrpcCellInstance
|
|
43
43
|
from ansys.edb.core.hierarchy.component_group import ComponentType as GrpcComponentType
|
|
44
|
-
from ansys.edb.core.layer.layer import LayerType as GrpcLayerType
|
|
45
|
-
from ansys.edb.core.layer.layer import TopBottomAssociation as GrpcTopBottomAssociation
|
|
44
|
+
from ansys.edb.core.layer.layer import LayerType as GrpcLayerType, TopBottomAssociation as GrpcTopBottomAssociation
|
|
46
45
|
from ansys.edb.core.layer.layer_collection import (
|
|
46
|
+
LayerCollection as GrpcLayerCollection,
|
|
47
47
|
LayerCollectionMode as GrpcLayerCollectionMode,
|
|
48
|
+
LayerTypeSet as GrpcLayerTypeSet,
|
|
48
49
|
)
|
|
49
|
-
from ansys.edb.core.layer.layer_collection import LayerCollection as GrpcLayerCollection
|
|
50
|
-
from ansys.edb.core.layer.layer_collection import LayerTypeSet as GrpcLayerTypeSet
|
|
51
50
|
from ansys.edb.core.layer.stackup_layer import StackupLayer as GrpcStackupLayer
|
|
52
51
|
from ansys.edb.core.layout.mcad_model import McadModel as GrpcMcadModel
|
|
52
|
+
from defusedxml.ElementTree import parse as defused_parse
|
|
53
|
+
import matplotlib.colors as colors
|
|
54
|
+
import numpy as np
|
|
55
|
+
import pandas as pd
|
|
53
56
|
|
|
54
57
|
from pyedb.generic.general_methods import ET, generate_unique_name
|
|
55
58
|
from pyedb.grpc.database.layers.layer import Layer
|
|
@@ -57,24 +60,6 @@ from pyedb.grpc.database.layers.stackup_layer import StackupLayer
|
|
|
57
60
|
from pyedb.grpc.database.utility.value import Value
|
|
58
61
|
from pyedb.misc.aedtlib_personalib_install import write_pretty_xml
|
|
59
62
|
|
|
60
|
-
colors = None
|
|
61
|
-
pd = None
|
|
62
|
-
np = None
|
|
63
|
-
try:
|
|
64
|
-
import matplotlib.colors as colors
|
|
65
|
-
except ImportError:
|
|
66
|
-
colors = None
|
|
67
|
-
|
|
68
|
-
try:
|
|
69
|
-
import numpy as np
|
|
70
|
-
except ImportError:
|
|
71
|
-
np = None
|
|
72
|
-
|
|
73
|
-
try:
|
|
74
|
-
import pandas as pd
|
|
75
|
-
except ImportError:
|
|
76
|
-
pd = None
|
|
77
|
-
|
|
78
63
|
logger = logging.getLogger(__name__)
|
|
79
64
|
|
|
80
65
|
|
|
@@ -128,8 +113,9 @@ class LayerCollection(GrpcLayerCollection):
|
|
|
128
113
|
--------
|
|
129
114
|
>>> from pyedb import Edb
|
|
130
115
|
>>> edb = Edb()
|
|
131
|
-
>>> top_layer = edb.stackup.add_layer_top(
|
|
132
|
-
... material="copper"
|
|
116
|
+
>>> top_layer = edb.stackup.add_layer_top(
|
|
117
|
+
... "NewTopLayer", layer_type="signal", thickness="0.1mm", material="copper"
|
|
118
|
+
... )
|
|
133
119
|
"""
|
|
134
120
|
thickness = Value(0.0)
|
|
135
121
|
if "thickness" in kwargs:
|
|
@@ -167,8 +153,9 @@ class LayerCollection(GrpcLayerCollection):
|
|
|
167
153
|
--------
|
|
168
154
|
>>> from pyedb import Edb
|
|
169
155
|
>>> edb = Edb()
|
|
170
|
-
>>> bot_layer = edb.stackup.add_layer_bottom(
|
|
171
|
-
... material="copper"
|
|
156
|
+
>>> bot_layer = edb.stackup.add_layer_bottom(
|
|
157
|
+
... "NewBottomLayer", layer_type="signal", thickness="0.1mm", material="copper"
|
|
158
|
+
... )
|
|
172
159
|
"""
|
|
173
160
|
thickness = Value(0.0)
|
|
174
161
|
layer_type_map = {"dielectric": GrpcLayerType.DIELECTRIC_LAYER, "signal": GrpcLayerType.SIGNAL_LAYER}
|
|
@@ -564,9 +551,6 @@ class Stackup(LayerCollection):
|
|
|
564
551
|
>>> edb = Edb()
|
|
565
552
|
>>> edb.stackup.create_symmetric_stackup(layer_count=4)
|
|
566
553
|
"""
|
|
567
|
-
if not np:
|
|
568
|
-
self._pedb.logger.error("Numpy is needed. Please, install it first.")
|
|
569
|
-
return False
|
|
570
554
|
if not layer_count % 2 == 0:
|
|
571
555
|
return False
|
|
572
556
|
|
|
@@ -1023,10 +1007,6 @@ class Stackup(LayerCollection):
|
|
|
1023
1007
|
return self.export(fpath, file_format=file_format, include_material_with_layer=include_material_with_layer)
|
|
1024
1008
|
|
|
1025
1009
|
def _export_layer_stackup_to_csv_xlsx(self, fpath: Optional[str] = None, file_format: Optional[str] = None) -> bool:
|
|
1026
|
-
if not pd:
|
|
1027
|
-
self._pedb.logger.error("Pandas is needed. Please, install it first.")
|
|
1028
|
-
return False
|
|
1029
|
-
|
|
1030
1010
|
data = {
|
|
1031
1011
|
"Type": [],
|
|
1032
1012
|
"Material": [],
|
|
@@ -1189,8 +1169,11 @@ class Stackup(LayerCollection):
|
|
|
1189
1169
|
sball_prop = cmp_prop.solder_ball_property
|
|
1190
1170
|
sball_prop.placement = GrpcSolderballPlacement.ABOVE_PADSTACK
|
|
1191
1171
|
cmp_prop.solder_ball_property = sball_prop
|
|
1192
|
-
except:
|
|
1193
|
-
|
|
1172
|
+
except Exception as e:
|
|
1173
|
+
self._logger.warning(
|
|
1174
|
+
f"A(n) {type(e).__name__} error occurred while attempting to update "
|
|
1175
|
+
f"solder_ball_property for component {cmp}: {str(e)}"
|
|
1176
|
+
)
|
|
1194
1177
|
if cmp_type == GrpcComponentType.IC:
|
|
1195
1178
|
die_prop = cmp_prop.die_property
|
|
1196
1179
|
chip_orientation = die_prop.die_orientation
|
|
@@ -1236,8 +1219,11 @@ class Stackup(LayerCollection):
|
|
|
1236
1219
|
try:
|
|
1237
1220
|
if val.solder_ball_height and val.placement_layer == layer_name:
|
|
1238
1221
|
height = val.solder_ball_height
|
|
1239
|
-
except:
|
|
1240
|
-
|
|
1222
|
+
except Exception as e:
|
|
1223
|
+
self._logger.error(
|
|
1224
|
+
f"A(n) {type(e).__name__} error occurred while attempting to retrieve solder_height "
|
|
1225
|
+
f"for layer {layer_name} - Default value of 0.0 is returned: {str(e)}"
|
|
1226
|
+
)
|
|
1241
1227
|
return height
|
|
1242
1228
|
|
|
1243
1229
|
def _remove_solder_pec(self, layer_name):
|
|
@@ -1330,15 +1316,21 @@ class Stackup(LayerCollection):
|
|
|
1330
1316
|
>>> mounted_cmp = edb2.components.get_component_by_name("BGA")
|
|
1331
1317
|
|
|
1332
1318
|
>>> vector, rotation, solder_ball_height = edb1.components.get_component_placement_vector(
|
|
1333
|
-
...
|
|
1334
|
-
...
|
|
1335
|
-
...
|
|
1336
|
-
...
|
|
1337
|
-
...
|
|
1338
|
-
...
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
...
|
|
1319
|
+
... mounted_component=mounted_cmp,
|
|
1320
|
+
... hosting_component=hosting_cmp,
|
|
1321
|
+
... mounted_component_pin1="A12",
|
|
1322
|
+
... mounted_component_pin2="A14",
|
|
1323
|
+
... hosting_component_pin1="A12",
|
|
1324
|
+
... hosting_component_pin2="A14",
|
|
1325
|
+
... )
|
|
1326
|
+
>>> edb2.stackup.place_in_layout(
|
|
1327
|
+
... edb1.active_cell,
|
|
1328
|
+
... angle=0.0,
|
|
1329
|
+
... offset_x=vector[0],
|
|
1330
|
+
... offset_y=vector[1],
|
|
1331
|
+
... flipped_stackup=False,
|
|
1332
|
+
... place_on_top=True,
|
|
1333
|
+
... )
|
|
1342
1334
|
"""
|
|
1343
1335
|
# if flipped_stackup and place_on_top or (not flipped_stackup and not place_on_top):
|
|
1344
1336
|
self.adjust_solder_dielectrics()
|
|
@@ -1418,9 +1410,14 @@ class Stackup(LayerCollection):
|
|
|
1418
1410
|
>>> edb2 = Edb(edbpath=targetfile2, edbversion="2021.2")
|
|
1419
1411
|
>>> hosting_cmp = edb1.components.get_component_by_name("U100")
|
|
1420
1412
|
>>> mounted_cmp = edb2.components.get_component_by_name("BGA")
|
|
1421
|
-
>>> edb2.stackup.place_in_layout(
|
|
1422
|
-
...
|
|
1423
|
-
...
|
|
1413
|
+
>>> edb2.stackup.place_in_layout(
|
|
1414
|
+
... edb1.active_cell,
|
|
1415
|
+
... angle=0.0,
|
|
1416
|
+
... offset_x="1mm",
|
|
1417
|
+
... offset_y="2mm",
|
|
1418
|
+
... flipped_stackup=False,
|
|
1419
|
+
... place_on_top=True,
|
|
1420
|
+
... )
|
|
1424
1421
|
"""
|
|
1425
1422
|
_angle = angle * math.pi / 180.0
|
|
1426
1423
|
|
|
@@ -1678,9 +1675,14 @@ class Stackup(LayerCollection):
|
|
|
1678
1675
|
--------
|
|
1679
1676
|
>>> edb1 = Edb(edbpath=targetfile1, edbversion="2021.2")
|
|
1680
1677
|
>>> a3dcomp_path = "connector.a3dcomp"
|
|
1681
|
-
>>> edb1.stackup.place_a3dcomp_3d_placement(
|
|
1682
|
-
...
|
|
1683
|
-
...
|
|
1678
|
+
>>> edb1.stackup.place_a3dcomp_3d_placement(
|
|
1679
|
+
... a3dcomp_path,
|
|
1680
|
+
... angle=0.0,
|
|
1681
|
+
... offset_x="1mm",
|
|
1682
|
+
... offset_y="2mm",
|
|
1683
|
+
... flipped_stackup=False,
|
|
1684
|
+
... place_on_top=True,
|
|
1685
|
+
... )
|
|
1684
1686
|
"""
|
|
1685
1687
|
rotation_axis_from = GrpcPoint3DData(1.0, 0.0, 0.0)
|
|
1686
1688
|
_angle = angle * math.pi / 180.0
|
|
@@ -1932,10 +1934,6 @@ class Stackup(LayerCollection):
|
|
|
1932
1934
|
bool
|
|
1933
1935
|
``True`` when successful.
|
|
1934
1936
|
"""
|
|
1935
|
-
if not pd:
|
|
1936
|
-
self._pedb.logger.error("Pandas is needed. You must install it first.")
|
|
1937
|
-
return False
|
|
1938
|
-
|
|
1939
1937
|
df = pd.read_csv(file_path, index_col=0)
|
|
1940
1938
|
|
|
1941
1939
|
for name in self.layers.keys(): # pragma: no cover
|
|
@@ -2204,10 +2202,7 @@ class Stackup(LayerCollection):
|
|
|
2204
2202
|
bool
|
|
2205
2203
|
``True`` when successful.
|
|
2206
2204
|
"""
|
|
2207
|
-
|
|
2208
|
-
self._pedb.logger.error("Matplotlib is needed. Please, install it first.")
|
|
2209
|
-
return False
|
|
2210
|
-
tree = ET.parse(file_path)
|
|
2205
|
+
tree = defused_parse(file_path)
|
|
2211
2206
|
root = tree.getroot()
|
|
2212
2207
|
stackup = root.find("Stackup")
|
|
2213
2208
|
stackup_dict = {}
|
|
@@ -20,15 +20,20 @@
|
|
|
20
20
|
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
21
|
# SOFTWARE.
|
|
22
22
|
|
|
23
|
+
from __future__ import annotations
|
|
24
|
+
|
|
25
|
+
from typing import TYPE_CHECKING
|
|
26
|
+
|
|
27
|
+
if TYPE_CHECKING:
|
|
28
|
+
from pyedb.grpc.database.hierarchy.component import Component
|
|
29
|
+
from pyedb.grpc.database.net.net import Net
|
|
23
30
|
from ansys.edb.core.terminal.bundle_terminal import BundleTerminal as GrpcBundleTerminal
|
|
24
31
|
from ansys.edb.core.terminal.terminal import (
|
|
32
|
+
HfssPIType as GrpcHfssPIType,
|
|
25
33
|
SourceTermToGroundType as GrpcSourceTermToGroundType,
|
|
26
34
|
)
|
|
27
|
-
from ansys.edb.core.terminal.terminal import HfssPIType as GrpcHfssPIType
|
|
28
35
|
|
|
29
|
-
from pyedb.grpc.database.hierarchy.component import Component
|
|
30
36
|
from pyedb.grpc.database.layers.layer import Layer
|
|
31
|
-
from pyedb.grpc.database.net.net import Net
|
|
32
37
|
from pyedb.grpc.database.terminal.terminal import Terminal
|
|
33
38
|
from pyedb.grpc.database.utility.rlc import Rlc
|
|
34
39
|
from pyedb.grpc.database.utility.value import Value
|
|
@@ -77,6 +82,7 @@ class BundleTerminal(GrpcBundleTerminal):
|
|
|
77
82
|
-------
|
|
78
83
|
:class:`Component <pyedb.grpc.database.hierarchy.component.Component`
|
|
79
84
|
"""
|
|
85
|
+
|
|
80
86
|
return Component(self._pedb, self.component)
|
|
81
87
|
|
|
82
88
|
@property
|
|
@@ -102,6 +108,7 @@ class BundleTerminal(GrpcBundleTerminal):
|
|
|
102
108
|
-------
|
|
103
109
|
:class:`Net <pyedb.grpc.database.net.net.Net>`
|
|
104
110
|
"""
|
|
111
|
+
|
|
105
112
|
return Net(self._pedb, self.net)
|
|
106
113
|
|
|
107
114
|
@property
|
|
@@ -37,16 +37,6 @@ class PadstackInstanceTerminal(GrpcPadstackInstanceTerminal):
|
|
|
37
37
|
super().__init__(edb_object.msg)
|
|
38
38
|
self._pedb = pedb
|
|
39
39
|
|
|
40
|
-
@property
|
|
41
|
-
def boundary_type(self) -> str:
|
|
42
|
-
"""Boundary type.
|
|
43
|
-
|
|
44
|
-
Returns
|
|
45
|
-
-------
|
|
46
|
-
str : boundary type.
|
|
47
|
-
"""
|
|
48
|
-
return super().boundary_type.name.lower()
|
|
49
|
-
|
|
50
40
|
@property
|
|
51
41
|
def position(self) -> list[float]:
|
|
52
42
|
"""Terminal position.
|
|
@@ -193,7 +183,15 @@ class PadstackInstanceTerminal(GrpcPadstackInstanceTerminal):
|
|
|
193
183
|
"rlc": GrpcBoundaryType.RLC,
|
|
194
184
|
"pec": GrpcBoundaryType.PEC,
|
|
195
185
|
}
|
|
196
|
-
|
|
186
|
+
if isinstance(value, str):
|
|
187
|
+
key = value.lower()
|
|
188
|
+
else:
|
|
189
|
+
key = value.name.lower()
|
|
190
|
+
new_boundary_type = mapping.get(key)
|
|
191
|
+
if new_boundary_type is None:
|
|
192
|
+
valid_types = ", ".join(mapping.keys())
|
|
193
|
+
raise ValueError(f"Invalid boundary type '{value}'. Valid types are: {valid_types}")
|
|
194
|
+
super(PadstackInstanceTerminal, self.__class__).boundary_type.__set__(self, new_boundary_type)
|
|
197
195
|
|
|
198
196
|
@property
|
|
199
197
|
def is_port(self) -> bool:
|
|
@@ -20,12 +20,17 @@
|
|
|
20
20
|
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
21
|
# SOFTWARE.
|
|
22
22
|
|
|
23
|
+
from __future__ import annotations
|
|
24
|
+
|
|
25
|
+
from typing import TYPE_CHECKING
|
|
26
|
+
|
|
27
|
+
if TYPE_CHECKING:
|
|
28
|
+
from pyedb.grpc.database.net.net import Net
|
|
23
29
|
from ansys.edb.core.terminal.pin_group_terminal import (
|
|
24
30
|
PinGroupTerminal as GrpcPinGroupTerminal,
|
|
25
31
|
)
|
|
26
32
|
from ansys.edb.core.terminal.terminal import BoundaryType as GrpcBoundaryType
|
|
27
33
|
|
|
28
|
-
from pyedb.grpc.database.net.net import Net
|
|
29
34
|
from pyedb.grpc.database.utility.value import Value
|
|
30
35
|
from pyedb.misc.decorators import deprecated_property
|
|
31
36
|
|
|
@@ -151,6 +156,8 @@ class PinGroupTerminal(GrpcPinGroupTerminal):
|
|
|
151
156
|
Terminal Net object.
|
|
152
157
|
|
|
153
158
|
"""
|
|
159
|
+
from pyedb.grpc.database.net.net import Net
|
|
160
|
+
|
|
154
161
|
return Net(self._pedb, super().net)
|
|
155
162
|
|
|
156
163
|
@net.setter
|
|
@@ -22,9 +22,20 @@
|
|
|
22
22
|
|
|
23
23
|
from ansys.edb.core.geometry.point_data import PointData as GrpcPointData
|
|
24
24
|
from ansys.edb.core.terminal.point_terminal import PointTerminal as GrpcPointTerminal
|
|
25
|
+
from ansys.edb.core.terminal.terminal import BoundaryType as GrpcBoundaryType
|
|
25
26
|
|
|
26
27
|
from pyedb.grpc.database.utility.value import Value
|
|
27
28
|
|
|
29
|
+
mapping_boundary_type = {
|
|
30
|
+
"port": GrpcBoundaryType.PORT,
|
|
31
|
+
"dc_terminal": GrpcBoundaryType.DC_TERMINAL,
|
|
32
|
+
"voltage_probe": GrpcBoundaryType.VOLTAGE_PROBE,
|
|
33
|
+
"voltage_source": GrpcBoundaryType.VOLTAGE_SOURCE,
|
|
34
|
+
"current_source": GrpcBoundaryType.CURRENT_SOURCE,
|
|
35
|
+
"rlc": GrpcBoundaryType.RLC,
|
|
36
|
+
"pec": GrpcBoundaryType.PEC,
|
|
37
|
+
}
|
|
38
|
+
|
|
28
39
|
|
|
29
40
|
class PointTerminal(GrpcPointTerminal):
|
|
30
41
|
"""Manages point terminal properties."""
|
|
@@ -33,6 +44,25 @@ class PointTerminal(GrpcPointTerminal):
|
|
|
33
44
|
super().__init__(edb_object.msg)
|
|
34
45
|
self._pedb = pedb
|
|
35
46
|
|
|
47
|
+
@property
|
|
48
|
+
def boundary_type(self):
|
|
49
|
+
"""Boundary type.
|
|
50
|
+
|
|
51
|
+
Returns
|
|
52
|
+
-------
|
|
53
|
+
str : boundary type.
|
|
54
|
+
|
|
55
|
+
"""
|
|
56
|
+
return super().boundary_type.name.lower()
|
|
57
|
+
|
|
58
|
+
@boundary_type.setter
|
|
59
|
+
def boundary_type(self, value):
|
|
60
|
+
if isinstance(value, str):
|
|
61
|
+
value = mapping_boundary_type.get(value.lower(), None)
|
|
62
|
+
if not isinstance(value, GrpcBoundaryType):
|
|
63
|
+
raise ValueError("Value must be a string or BoundaryType enum.")
|
|
64
|
+
super(PointTerminal, self.__class__).boundary_type.__set__(self, value)
|
|
65
|
+
|
|
36
66
|
@property
|
|
37
67
|
def location(self) -> list[float]:
|
|
38
68
|
"""Terminal position.
|
|
@@ -20,17 +20,34 @@
|
|
|
20
20
|
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
21
|
# SOFTWARE.
|
|
22
22
|
|
|
23
|
+
from __future__ import annotations
|
|
24
|
+
|
|
25
|
+
from typing import TYPE_CHECKING
|
|
26
|
+
|
|
27
|
+
if TYPE_CHECKING:
|
|
28
|
+
from pyedb.grpc.database.primitive.padstack_instance import PadstackInstance
|
|
23
29
|
import re
|
|
24
30
|
|
|
25
31
|
from ansys.edb.core.terminal.edge_terminal import EdgeType as GrpcEdgeType
|
|
26
|
-
from ansys.edb.core.terminal.terminal import
|
|
27
|
-
|
|
28
|
-
|
|
32
|
+
from ansys.edb.core.terminal.terminal import (
|
|
33
|
+
BoundaryType as GrpcBoundaryType,
|
|
34
|
+
Terminal as GrpcTerminal,
|
|
35
|
+
TerminalType as GrpcTerminalType,
|
|
36
|
+
)
|
|
29
37
|
|
|
30
|
-
from pyedb.grpc.database.primitive.padstack_instance import PadstackInstance
|
|
31
38
|
from pyedb.grpc.database.primitive.primitive import Primitive
|
|
32
39
|
from pyedb.grpc.database.utility.value import Value
|
|
33
40
|
|
|
41
|
+
mapping_boundary_type = {
|
|
42
|
+
"port": GrpcBoundaryType.PORT,
|
|
43
|
+
"dc_terminal": GrpcBoundaryType.DC_TERMINAL,
|
|
44
|
+
"voltage_probe": GrpcBoundaryType.VOLTAGE_PROBE,
|
|
45
|
+
"voltage_source": GrpcBoundaryType.VOLTAGE_SOURCE,
|
|
46
|
+
"current_source": GrpcBoundaryType.CURRENT_SOURCE,
|
|
47
|
+
"rlc": GrpcBoundaryType.RLC,
|
|
48
|
+
"pec": GrpcBoundaryType.PEC,
|
|
49
|
+
}
|
|
50
|
+
|
|
34
51
|
|
|
35
52
|
class Terminal(GrpcTerminal):
|
|
36
53
|
def __init__(self, pedb, edb_object):
|
|
@@ -195,7 +212,11 @@ class Terminal(GrpcTerminal):
|
|
|
195
212
|
|
|
196
213
|
@boundary_type.setter
|
|
197
214
|
def boundary_type(self, value):
|
|
198
|
-
|
|
215
|
+
if isinstance(value, str):
|
|
216
|
+
value = mapping_boundary_type.get(value.lower(), None)
|
|
217
|
+
if not isinstance(value, GrpcBoundaryType):
|
|
218
|
+
raise ValueError("Value must be a string or BoundaryType enum.")
|
|
219
|
+
super(Terminal, self.__class__).boundary_type.__set__(self, value)
|
|
199
220
|
|
|
200
221
|
@property
|
|
201
222
|
def is_port(self) -> bool:
|
|
@@ -243,7 +264,7 @@ class Terminal(GrpcTerminal):
|
|
|
243
264
|
|
|
244
265
|
@impedance.setter
|
|
245
266
|
def impedance(self, value):
|
|
246
|
-
self.impedance
|
|
267
|
+
super(Terminal, self.__class__).impedance.__set__(self, self._pedb.value(value))
|
|
247
268
|
|
|
248
269
|
@property
|
|
249
270
|
def reference_object(self) -> any:
|
|
@@ -364,13 +385,17 @@ class Terminal(GrpcTerminal):
|
|
|
364
385
|
return (primitive, self._pedb)
|
|
365
386
|
return None # pragma: no cover
|
|
366
387
|
|
|
367
|
-
def get_point_terminal_reference_primitive(self) -> Primitive:
|
|
368
|
-
"""
|
|
388
|
+
def get_point_terminal_reference_primitive(self) -> Primitive:
|
|
389
|
+
"""
|
|
390
|
+
Find and return the primitive reference for the point terminal or the padstack instance.
|
|
369
391
|
|
|
370
392
|
Returns
|
|
371
393
|
-------
|
|
372
|
-
|
|
373
|
-
|
|
394
|
+
Primitive or PadstackInstance
|
|
395
|
+
The primitive reference for the point terminal or the padstack instance.
|
|
396
|
+
Returns an instance of :class:`PadstackInstance
|
|
397
|
+
<pyedb.grpc.database.primitive.padstack_instance.PadstackInstance>`
|
|
398
|
+
or :class:`Primitive <pyedb.grpc.database.primitive.primitive.Primitive>`.
|
|
374
399
|
"""
|
|
375
400
|
|
|
376
401
|
ref_term = self.reference_terminal # return value is type terminal
|
|
@@ -21,10 +21,10 @@
|
|
|
21
21
|
# SOFTWARE.
|
|
22
22
|
|
|
23
23
|
from ansys.edb.core.utility.hfss_extent_info import (
|
|
24
|
+
HfssExtentInfo as GrpcHfssExtentInfo,
|
|
24
25
|
HFSSExtentInfoType as GrpcHfssExtentInfoType,
|
|
26
|
+
OpenRegionType as GrpcOpenRegionType,
|
|
25
27
|
)
|
|
26
|
-
from ansys.edb.core.utility.hfss_extent_info import HfssExtentInfo as GrpcHfssExtentInfo
|
|
27
|
-
from ansys.edb.core.utility.hfss_extent_info import OpenRegionType as GrpcOpenRegionType
|
|
28
28
|
from ansys.edb.core.utility.value import Value as GrpcValue
|
|
29
29
|
|
|
30
30
|
|
|
@@ -23,9 +23,11 @@
|
|
|
23
23
|
import copy
|
|
24
24
|
import os
|
|
25
25
|
import re
|
|
26
|
-
import subprocess
|
|
26
|
+
import subprocess # nosec B404
|
|
27
27
|
import sys
|
|
28
28
|
|
|
29
|
+
from defusedxml.ElementTree import parse as defused_parse
|
|
30
|
+
|
|
29
31
|
from pyedb.generic.general_methods import ET, env_path, env_value, is_linux
|
|
30
32
|
from pyedb.generic.settings import settings
|
|
31
33
|
from pyedb.misc.aedtlib_personalib_install import write_pretty_xml
|
|
@@ -35,6 +37,11 @@ from pyedb.misc.misc import list_installed_ansysem
|
|
|
35
37
|
def convert_technology_file(tech_file, edbversion=None, control_file=None):
|
|
36
38
|
"""Convert a technology file to edb control file (xml).
|
|
37
39
|
|
|
40
|
+
.. warning::
|
|
41
|
+
Do not execute this function with untrusted function argument, environment
|
|
42
|
+
variables or pyedb global settings.
|
|
43
|
+
See the :ref:`security guide<ref_security_consideration>` for details.
|
|
44
|
+
|
|
38
45
|
Parameters
|
|
39
46
|
----------
|
|
40
47
|
tech_file : str
|
|
@@ -98,10 +105,11 @@ def convert_technology_file(tech_file, edbversion=None, control_file=None):
|
|
|
98
105
|
]
|
|
99
106
|
commands.append(command)
|
|
100
107
|
commands.append(["rm", "-r", vlc_file_name + ".aedb"])
|
|
101
|
-
my_env = os.environ.copy()
|
|
102
108
|
for command in commands:
|
|
103
|
-
|
|
104
|
-
|
|
109
|
+
try:
|
|
110
|
+
subprocess.run(command, check=True) # nosec
|
|
111
|
+
except subprocess.CalledProcessError as e: # nosec
|
|
112
|
+
raise RuntimeError("An error occurred while converting a technology file to edb control file") from e
|
|
105
113
|
if os.path.exists(control_file):
|
|
106
114
|
settings.logger.info("Xml file created.")
|
|
107
115
|
return control_file
|
|
@@ -122,7 +130,7 @@ class ControlProperty:
|
|
|
122
130
|
float(value)
|
|
123
131
|
self.type = 0
|
|
124
132
|
except TypeError:
|
|
125
|
-
|
|
133
|
+
self.type = -1
|
|
126
134
|
|
|
127
135
|
def _write_xml(self, root):
|
|
128
136
|
try:
|
|
@@ -132,8 +140,11 @@ class ControlProperty:
|
|
|
132
140
|
double.text = str(self.value)
|
|
133
141
|
else:
|
|
134
142
|
pass
|
|
135
|
-
except:
|
|
136
|
-
|
|
143
|
+
except Exception as e:
|
|
144
|
+
settings.logger.error(
|
|
145
|
+
f"A(n) {type(e).__name__} error occurred while attempting to create a new sub-element {self.name} "
|
|
146
|
+
f"for element {root}: {str(e)}"
|
|
147
|
+
)
|
|
137
148
|
|
|
138
149
|
|
|
139
150
|
class ControlFileMaterial:
|
|
@@ -1185,7 +1196,7 @@ class ControlFile:
|
|
|
1185
1196
|
-------
|
|
1186
1197
|
bool
|
|
1187
1198
|
"""
|
|
1188
|
-
tree =
|
|
1199
|
+
tree = defused_parse(xml_input)
|
|
1189
1200
|
root = tree.getroot()
|
|
1190
1201
|
for el in root:
|
|
1191
1202
|
if el.tag == "Stackup":
|