pyedb 0.55.0__py3-none-any.whl → 0.57.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_operations.py +2 -2
- pyedb/configuration/cfg_ports_sources.py +1 -1
- 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 +56 -41
- 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 +55 -52
- pyedb/dotnet/database/dotnet/database.py +1 -0
- pyedb/dotnet/database/edb_data/control_file.py +6 -3
- pyedb/dotnet/database/edb_data/nets_data.py +3 -3
- pyedb/dotnet/database/edb_data/padstacks_data.py +5 -2
- 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/hfss.py +9 -8
- pyedb/dotnet/database/layout_validation.py +6 -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 +91 -2
- pyedb/dotnet/database/sim_setup_data/io/siwave.py +1 -1
- pyedb/dotnet/database/siwave.py +4 -3
- pyedb/dotnet/database/stackup.py +50 -26
- pyedb/dotnet/database/utilities/heatsink.py +0 -1
- 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 +5 -2
- pyedb/dotnet/edb.py +41 -36
- pyedb/exceptions.py +1 -2
- pyedb/extensions/create_cell_array.py +408 -0
- pyedb/generic/data_handlers.py +17 -28
- pyedb/generic/design_types.py +25 -38
- pyedb/generic/filesystem.py +9 -4
- pyedb/generic/general_methods.py +6 -7
- pyedb/generic/plot.py +2 -2
- pyedb/generic/settings.py +4 -0
- pyedb/grpc/database/_typing.py +0 -0
- pyedb/grpc/database/components.py +30 -11
- pyedb/grpc/database/control_file.py +14 -35
- pyedb/grpc/database/definition/materials.py +1 -1
- pyedb/grpc/database/definition/package_def.py +6 -3
- pyedb/grpc/database/definition/padstack_def.py +4 -7
- pyedb/grpc/database/hfss.py +1 -4
- pyedb/grpc/database/hierarchy/component.py +3 -4
- 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 +117 -28
- pyedb/grpc/database/layout/voltage_regulator.py +6 -1
- pyedb/grpc/database/layout_validation.py +7 -4
- pyedb/grpc/database/modeler.py +241 -256
- 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 +92 -16
- pyedb/grpc/database/primitive/bondwire.py +3 -67
- pyedb/grpc/database/primitive/circle.py +42 -3
- pyedb/grpc/database/primitive/padstack_instance.py +17 -19
- pyedb/grpc/database/primitive/path.py +154 -5
- pyedb/grpc/database/primitive/polygon.py +75 -9
- 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/siwave_cpa_simulation_setup.py +4 -2
- pyedb/grpc/database/simulation_setup/sweep_data.py +1 -3
- pyedb/grpc/database/siwave.py +6 -13
- pyedb/grpc/database/source_excitations.py +49 -57
- pyedb/grpc/database/stackup.py +50 -27
- pyedb/grpc/database/terminal/bundle_terminal.py +10 -3
- pyedb/grpc/database/terminal/pingroup_terminal.py +8 -1
- pyedb/grpc/database/terminal/terminal.py +19 -8
- pyedb/grpc/database/utility/heat_sink.py +0 -1
- pyedb/grpc/database/utility/hfss_extent_info.py +2 -2
- pyedb/grpc/database/utility/value.py +1 -0
- pyedb/grpc/database/utility/xml_control_file.py +6 -3
- pyedb/grpc/edb.py +33 -24
- pyedb/grpc/edb_init.py +1 -0
- pyedb/grpc/rpc_session.py +4 -3
- 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/downloads.py +1 -0
- pyedb/misc/misc.py +5 -2
- pyedb/misc/siw_feature_config/emc_rule_checker_settings.py +1 -1
- pyedb/misc/utilities.py +0 -1
- pyedb/modeler/geometry_operators.py +9 -8
- pyedb/siwave.py +4 -6
- pyedb/siwave_core/__init__.py +0 -0
- pyedb/siwave_core/cpa/__init__.py +0 -0
- {pyedb-0.55.0.dist-info → pyedb-0.57.0.dist-info}/METADATA +3 -3
- {pyedb-0.55.0.dist-info → pyedb-0.57.0.dist-info}/RECORD +107 -102
- {pyedb-0.55.0.dist-info → pyedb-0.57.0.dist-info}/WHEEL +0 -0
- {pyedb-0.55.0.dist-info → pyedb-0.57.0.dist-info}/licenses/LICENSE +0 -0
pyedb/generic/data_handlers.py
CHANGED
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
from decimal import Decimal
|
|
3
3
|
import json
|
|
4
4
|
import math
|
|
5
|
-
import random
|
|
6
5
|
import re
|
|
6
|
+
import secrets
|
|
7
7
|
import string
|
|
8
8
|
|
|
9
9
|
from pyedb.generic.general_methods import settings
|
|
@@ -54,7 +54,7 @@ def random_string(length=6, only_digits=False, char_set=None): # pragma: no cov
|
|
|
54
54
|
char_set = string.digits
|
|
55
55
|
else:
|
|
56
56
|
char_set = string.ascii_uppercase + string.digits
|
|
57
|
-
random_str = "".join(
|
|
57
|
+
random_str = "".join(secrets.choice(char_set) for _ in range(int(length)))
|
|
58
58
|
return random_str
|
|
59
59
|
|
|
60
60
|
|
|
@@ -72,24 +72,13 @@ def unique_string_list(element_list, only_string=True): # pragma: no cover
|
|
|
72
72
|
-------
|
|
73
73
|
|
|
74
74
|
"""
|
|
75
|
-
if element_list:
|
|
76
|
-
|
|
77
|
-
element_list = set(element_list)
|
|
78
|
-
elif isinstance(element_list, str):
|
|
79
|
-
element_list = [element_list]
|
|
80
|
-
else:
|
|
81
|
-
error_message = "Invalid list data"
|
|
82
|
-
try:
|
|
83
|
-
error_message += " {}".format(element_list)
|
|
84
|
-
except:
|
|
85
|
-
pass
|
|
86
|
-
raise Exception(error_message)
|
|
75
|
+
if isinstance(element_list, str):
|
|
76
|
+
element_list = [element_list]
|
|
87
77
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
assert not non_string_entries, "Invalid list entries {} are not a string!".format(non_string_entries)
|
|
78
|
+
if only_string and any(not isinstance(x, str) for x in element_list):
|
|
79
|
+
raise TypeError("Invalid list entries, some elements are not of type string.")
|
|
91
80
|
|
|
92
|
-
return element_list
|
|
81
|
+
return list(set(element_list))
|
|
93
82
|
|
|
94
83
|
|
|
95
84
|
def string_list(element_list): # pragma: no cover
|
|
@@ -104,10 +93,10 @@ def string_list(element_list): # pragma: no cover
|
|
|
104
93
|
-------
|
|
105
94
|
|
|
106
95
|
"""
|
|
96
|
+
if not isinstance(element_list, (str, list)):
|
|
97
|
+
raise TypeError("Input must be a list or a string")
|
|
107
98
|
if isinstance(element_list, str):
|
|
108
99
|
element_list = [element_list]
|
|
109
|
-
else:
|
|
110
|
-
assert isinstance(element_list, str), "Input must be a list or a string"
|
|
111
100
|
return element_list
|
|
112
101
|
|
|
113
102
|
|
|
@@ -143,28 +132,28 @@ def from_rkm(code): # pragma: no cover
|
|
|
143
132
|
|
|
144
133
|
Examples
|
|
145
134
|
--------
|
|
146
|
-
>>> from_rkm(
|
|
135
|
+
>>> from_rkm("R47")
|
|
147
136
|
'0.47'
|
|
148
137
|
|
|
149
|
-
>>> from_rkm(
|
|
138
|
+
>>> from_rkm("4R7")
|
|
150
139
|
'4.7'
|
|
151
140
|
|
|
152
|
-
>>> from_rkm(
|
|
141
|
+
>>> from_rkm("470R")
|
|
153
142
|
'470'
|
|
154
143
|
|
|
155
|
-
>>> from_rkm(
|
|
144
|
+
>>> from_rkm("4K7")
|
|
156
145
|
'4.7k'
|
|
157
146
|
|
|
158
|
-
>>> from_rkm(
|
|
147
|
+
>>> from_rkm("47K")
|
|
159
148
|
'47k'
|
|
160
149
|
|
|
161
|
-
>>> from_rkm(
|
|
150
|
+
>>> from_rkm("47K3")
|
|
162
151
|
'47.3k'
|
|
163
152
|
|
|
164
|
-
>>> from_rkm(
|
|
153
|
+
>>> from_rkm("470K")
|
|
165
154
|
'470k'
|
|
166
155
|
|
|
167
|
-
>>> from_rkm(
|
|
156
|
+
>>> from_rkm("4M7")
|
|
168
157
|
'4.7M'
|
|
169
158
|
|
|
170
159
|
"""
|
pyedb/generic/design_types.py
CHANGED
|
@@ -32,18 +32,15 @@ if TYPE_CHECKING:
|
|
|
32
32
|
|
|
33
33
|
|
|
34
34
|
@overload
|
|
35
|
-
def Edb(*, grpc: Literal[True], **kwargs) -> "EdbGrpc":
|
|
36
|
-
...
|
|
35
|
+
def Edb(*, grpc: Literal[True], **kwargs) -> "EdbGrpc": ...
|
|
37
36
|
|
|
38
37
|
|
|
39
38
|
@overload
|
|
40
|
-
def Edb(*, grpc: Literal[False] = False, **kwargs) -> "EdbDotnet":
|
|
41
|
-
...
|
|
39
|
+
def Edb(*, grpc: Literal[False] = False, **kwargs) -> "EdbDotnet": ...
|
|
42
40
|
|
|
43
41
|
|
|
44
42
|
@overload
|
|
45
|
-
def Edb(*, grpc: bool, **kwargs) -> Union["EdbGrpc", "EdbDotnet"]:
|
|
46
|
-
...
|
|
43
|
+
def Edb(*, grpc: bool, **kwargs) -> Union["EdbGrpc", "EdbDotnet"]: ...
|
|
47
44
|
|
|
48
45
|
|
|
49
46
|
# lazy imports
|
|
@@ -57,9 +54,11 @@ def Edb(
|
|
|
57
54
|
oproject=None,
|
|
58
55
|
student_version=False,
|
|
59
56
|
use_ppe=False,
|
|
57
|
+
map_file=None,
|
|
60
58
|
technology_file=None,
|
|
61
59
|
grpc=False,
|
|
62
60
|
control_file=None,
|
|
61
|
+
layer_filter=None,
|
|
63
62
|
):
|
|
64
63
|
"""Provides the EDB application interface.
|
|
65
64
|
|
|
@@ -78,7 +77,7 @@ def Edb(
|
|
|
78
77
|
isreadonly : bool, optional
|
|
79
78
|
Whether to open EBD in read-only mode when it is
|
|
80
79
|
owned by HFSS 3D Layout. The default is ``False``.
|
|
81
|
-
|
|
80
|
+
version : str, optional
|
|
82
81
|
Version of EDB to use. The default is ``"2021.2"``.
|
|
83
82
|
isaedtowned : bool, optional
|
|
84
83
|
Whether to launch EDB from HFSS 3D Layout. The
|
|
@@ -87,10 +86,20 @@ def Edb(
|
|
|
87
86
|
Reference to the AEDT project object.
|
|
88
87
|
student_version : bool, optional
|
|
89
88
|
Whether to open the AEDT student version. The default is ``False.``
|
|
89
|
+
use_ppe : bool, optional
|
|
90
|
+
Whether to use PPE license. The default is ``False``.
|
|
90
91
|
technology_file : str, optional
|
|
91
92
|
Full path to technology file to be converted to xml before importing or xml. Supported by GDS format only.
|
|
92
93
|
grpc : bool, optional
|
|
93
94
|
Whether to enable gRPC. Default value is ``False``.
|
|
95
|
+
layer_filter: str,optional
|
|
96
|
+
Layer filter .txt file.
|
|
97
|
+
map_file : str, optional
|
|
98
|
+
Layer map .map file.
|
|
99
|
+
control_file : str, optional
|
|
100
|
+
Path to the XML file. The default is ``None``, in which case an attempt is made to find
|
|
101
|
+
the XML file in the same directory as the board file. To succeed, the XML file and board file
|
|
102
|
+
must have the same name. Only the extension differs.
|
|
94
103
|
|
|
95
104
|
Returns
|
|
96
105
|
-------
|
|
@@ -155,17 +164,10 @@ def Edb(
|
|
|
155
164
|
4. Simulation Setup
|
|
156
165
|
|
|
157
166
|
# Create SIwave SYZ setup
|
|
158
|
-
>>> syz_setup = edb.create_siwave_syz_setup(
|
|
159
|
-
>>> name="GHz_Setup",
|
|
160
|
-
>>> start_freq="1GHz",
|
|
161
|
-
>>> stop_freq="10GHz"
|
|
162
|
-
>>> )
|
|
167
|
+
>>> syz_setup = edb.create_siwave_syz_setup(name="GHz_Setup", start_freq="1GHz", stop_freq="10GHz")
|
|
163
168
|
|
|
164
169
|
# Create SIwave DC setup
|
|
165
|
-
>>> dc_setup = edb.create_siwave_dc_setup(
|
|
166
|
-
>>> name="DC_Analysis",
|
|
167
|
-
>>> use_dc_point=True
|
|
168
|
-
>>> )
|
|
170
|
+
>>> dc_setup = edb.create_siwave_dc_setup(name="DC_Analysis", use_dc_point=True)
|
|
169
171
|
|
|
170
172
|
# Solve with SIwave
|
|
171
173
|
>>> edb.solve_siwave()
|
|
@@ -196,17 +198,10 @@ def Edb(
|
|
|
196
198
|
7. Port Creation
|
|
197
199
|
|
|
198
200
|
# Create wave port between two pins
|
|
199
|
-
>>> wave_port = edb.source_excitation.create_port(
|
|
200
|
-
>>> positive_terminal=pin1,
|
|
201
|
-
>>> negative_terminal=pin2,
|
|
202
|
-
>>> port_type="Wave"
|
|
203
|
-
>>> )
|
|
201
|
+
>>> wave_port = edb.source_excitation.create_port(positive_terminal=pin1, negative_terminal=pin2, port_type="Wave")
|
|
204
202
|
|
|
205
203
|
# Create lumped port
|
|
206
|
-
>>> lumped_port = edb.source_excitation.create_port(
|
|
207
|
-
>>> positive_terminal=via_terminal,
|
|
208
|
-
>>> port_type="Lumped"
|
|
209
|
-
>>> )
|
|
204
|
+
>>> lumped_port = edb.source_excitation.create_port(positive_terminal=via_terminal, port_type="Lumped")
|
|
210
205
|
|
|
211
206
|
8. Component Management
|
|
212
207
|
|
|
@@ -219,12 +214,7 @@ def Edb(
|
|
|
219
214
|
9. Parametrization
|
|
220
215
|
|
|
221
216
|
# Auto-parametrize design elements
|
|
222
|
-
>>> params = edb.auto_parametrize_design(
|
|
223
|
-
>>> traces=True,
|
|
224
|
-
>>> pads=True,
|
|
225
|
-
>>> antipads=True,
|
|
226
|
-
>>> use_relative_variables=True
|
|
227
|
-
>>> )
|
|
217
|
+
>>> params = edb.auto_parametrize_design(traces=True, pads=True, antipads=True, use_relative_variables=True)
|
|
228
218
|
>>> print("Created parameters:", params)
|
|
229
219
|
|
|
230
220
|
10. Design Statistics
|
|
@@ -243,11 +233,7 @@ def Edb(
|
|
|
243
233
|
12. Differential Pairs
|
|
244
234
|
|
|
245
235
|
# Create differential pair
|
|
246
|
-
>>> edb.differential_pairs.create(
|
|
247
|
-
>>> positive_net="USB_P",
|
|
248
|
-
>>> negative_net="USB_N",
|
|
249
|
-
>>> name="USB_DP"
|
|
250
|
-
>>> )
|
|
236
|
+
>>> edb.differential_pairs.create(positive_net="USB_P", negative_net="USB_N", name="USB_DP")
|
|
251
237
|
|
|
252
238
|
13. Workflow Automation
|
|
253
239
|
|
|
@@ -263,7 +249,6 @@ def Edb(
|
|
|
263
249
|
if grpc is False and settings.edb_dll_path is not None:
|
|
264
250
|
# Check if the user specified a .dll path
|
|
265
251
|
settings.logger.info(f"Force to use .dll from {settings.edb_dll_path} defined in settings.")
|
|
266
|
-
settings.specified_version = "unknown"
|
|
267
252
|
elif version is None:
|
|
268
253
|
if settings.specified_version is not None:
|
|
269
254
|
settings.logger.info(f"Use {settings.specified_version} defined in settings.")
|
|
@@ -324,8 +309,10 @@ def Edb(
|
|
|
324
309
|
isaedtowned=isaedtowned,
|
|
325
310
|
oproject=oproject,
|
|
326
311
|
use_ppe=use_ppe,
|
|
327
|
-
technology_file=technology_file,
|
|
328
312
|
control_file=control_file,
|
|
313
|
+
map_file=map_file,
|
|
314
|
+
technology_file=technology_file,
|
|
315
|
+
layer_filter=layer_filter,
|
|
329
316
|
)
|
|
330
317
|
|
|
331
318
|
|
pyedb/generic/filesystem.py
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import os
|
|
2
|
-
import
|
|
2
|
+
import secrets
|
|
3
3
|
import shutil
|
|
4
4
|
import string
|
|
5
5
|
|
|
6
|
+
from pyedb.generic.settings import settings
|
|
7
|
+
|
|
6
8
|
|
|
7
9
|
def search_files(dirname, pattern="*"):
|
|
8
10
|
"""Search for files inside a directory given a specific pattern.
|
|
@@ -44,7 +46,10 @@ class Scratch:
|
|
|
44
46
|
self._volatile = volatile
|
|
45
47
|
self._cleaned = True
|
|
46
48
|
char_set = string.ascii_uppercase + string.digits
|
|
47
|
-
|
|
49
|
+
generator = secrets.SystemRandom()
|
|
50
|
+
self._scratch_path = os.path.normpath(
|
|
51
|
+
os.path.join(local_path, "scratch" + "".join(secrets.SystemRandom.sample(generator, char_set, 6)))
|
|
52
|
+
)
|
|
48
53
|
if os.path.exists(self._scratch_path):
|
|
49
54
|
try:
|
|
50
55
|
self.remove()
|
|
@@ -62,8 +67,8 @@ class Scratch:
|
|
|
62
67
|
try:
|
|
63
68
|
# TODO check why on Anaconda 3.7 get errors with os.path.exists
|
|
64
69
|
shutil.rmtree(self._scratch_path, ignore_errors=True)
|
|
65
|
-
except:
|
|
66
|
-
|
|
70
|
+
except Exception:
|
|
71
|
+
settings.logger.error(f"An error occurred while removing {self._scratch_path}")
|
|
67
72
|
|
|
68
73
|
def copyfile(self, src_file, dst_filename=None):
|
|
69
74
|
"""
|
pyedb/generic/general_methods.py
CHANGED
|
@@ -35,8 +35,8 @@ import itertools
|
|
|
35
35
|
import logging
|
|
36
36
|
import math
|
|
37
37
|
import os
|
|
38
|
-
import random
|
|
39
38
|
import re
|
|
39
|
+
import secrets
|
|
40
40
|
import string
|
|
41
41
|
import sys
|
|
42
42
|
import tempfile
|
|
@@ -118,7 +118,6 @@ def _exception(ex_info, func, args, kwargs, message="Type Error"):
|
|
|
118
118
|
if message_to_print:
|
|
119
119
|
_write_mes("Last Electronics Desktop Message - " + message_to_print)
|
|
120
120
|
|
|
121
|
-
args_name = []
|
|
122
121
|
try:
|
|
123
122
|
args_dict = _get_args_dicts(func, args, kwargs)
|
|
124
123
|
first_time_log = True
|
|
@@ -129,13 +128,13 @@ def _exception(ex_info, func, args, kwargs, message="Type Error"):
|
|
|
129
128
|
_write_mes("Method arguments: ")
|
|
130
129
|
first_time_log = False
|
|
131
130
|
_write_mes(" {} = {} ".format(el, args_dict[el]))
|
|
132
|
-
except:
|
|
133
|
-
|
|
134
|
-
|
|
131
|
+
except Exception:
|
|
132
|
+
settings.logger.error(f"An error occurred while parsing and logging an error with method {func.__name__}.")
|
|
133
|
+
|
|
135
134
|
if not func.__name__.startswith("_"):
|
|
136
135
|
_write_mes(
|
|
137
136
|
"Check Online documentation on: https://edb.docs.pyansys.com/version/stable/search.html?q={}".format(
|
|
138
|
-
|
|
137
|
+
func.__name__
|
|
139
138
|
)
|
|
140
139
|
)
|
|
141
140
|
|
|
@@ -254,7 +253,7 @@ def generate_unique_name(rootname, suffix="", n=6):
|
|
|
254
253
|
|
|
255
254
|
"""
|
|
256
255
|
char_set = string.ascii_uppercase + string.digits
|
|
257
|
-
uName = "".join(
|
|
256
|
+
uName = "".join(secrets.choice(char_set) for _ in range(n))
|
|
258
257
|
unique_name = rootname + "_" + uName
|
|
259
258
|
if suffix:
|
|
260
259
|
unique_name += "_" + suffix
|
pyedb/generic/plot.py
CHANGED
|
@@ -24,8 +24,8 @@ except ImportError:
|
|
|
24
24
|
"The Matplotlib module is required to run some functionalities of PostProcess.\n"
|
|
25
25
|
"Install with \n\npip install matplotlib\n\nRequires CPython."
|
|
26
26
|
)
|
|
27
|
-
except:
|
|
28
|
-
|
|
27
|
+
except Exception:
|
|
28
|
+
warnings.warn("Unknown error occurred while attempting to import Matplotlib.")
|
|
29
29
|
|
|
30
30
|
|
|
31
31
|
def plot_matplotlib(
|
pyedb/generic/settings.py
CHANGED
|
@@ -21,6 +21,7 @@
|
|
|
21
21
|
# SOFTWARE.
|
|
22
22
|
|
|
23
23
|
import os
|
|
24
|
+
from pathlib import Path
|
|
24
25
|
import re
|
|
25
26
|
import sys
|
|
26
27
|
import time
|
|
@@ -248,6 +249,9 @@ class Settings(object):
|
|
|
248
249
|
@edb_dll_path.setter
|
|
249
250
|
def edb_dll_path(self, value):
|
|
250
251
|
if os.path.exists(value):
|
|
252
|
+
ver = Path(value).parts[-2]
|
|
253
|
+
version, release = ver[-3:-1], ver[-1]
|
|
254
|
+
self.specified_version = f"20{version}.{release}"
|
|
251
255
|
self._edb_dll_path = value
|
|
252
256
|
|
|
253
257
|
@property
|
|
File without changes
|
|
@@ -20,9 +20,8 @@
|
|
|
20
20
|
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
21
|
# SOFTWARE.
|
|
22
22
|
|
|
23
|
-
"""This module contains the `Components` class.
|
|
23
|
+
"""This module contains the `Components` class."""
|
|
24
24
|
|
|
25
|
-
"""
|
|
26
25
|
import codecs
|
|
27
26
|
import json
|
|
28
27
|
import math
|
|
@@ -31,8 +30,7 @@ import re
|
|
|
31
30
|
from typing import Any, Dict, List, Optional, Tuple, Union
|
|
32
31
|
import warnings
|
|
33
32
|
|
|
34
|
-
from ansys.edb.core.definition.die_property import DieOrientation as GrpDieOrientation
|
|
35
|
-
from ansys.edb.core.definition.die_property import DieType as GrpcDieType
|
|
33
|
+
from ansys.edb.core.definition.die_property import DieOrientation as GrpDieOrientation, DieType as GrpcDieType
|
|
36
34
|
from ansys.edb.core.definition.solder_ball_property import (
|
|
37
35
|
SolderballShape as GrpcSolderballShape,
|
|
38
36
|
)
|
|
@@ -996,8 +994,7 @@ class Components(object):
|
|
|
996
994
|
"""
|
|
997
995
|
component_definition = ComponentDef.find(self._db, name)
|
|
998
996
|
if component_definition.is_null:
|
|
999
|
-
from ansys.edb.core.layout.cell import Cell as GrpcCell
|
|
1000
|
-
from ansys.edb.core.layout.cell import CellType as GrpcCellType
|
|
997
|
+
from ansys.edb.core.layout.cell import Cell as GrpcCell, CellType as GrpcCellType
|
|
1001
998
|
|
|
1002
999
|
foot_print_cell = GrpcCell.create(self._pedb.active_db, GrpcCellType.FOOTPRINT_CELL, name)
|
|
1003
1000
|
component_definition = ComponentDef.create(self._db, name, fp=foot_print_cell)
|
|
@@ -1065,6 +1062,9 @@ class Components(object):
|
|
|
1065
1062
|
ComponentGroup as GrpcComponentGroup,
|
|
1066
1063
|
)
|
|
1067
1064
|
|
|
1065
|
+
if not pins:
|
|
1066
|
+
raise ValueError("Pins must be a list of PadstackInstance objects.")
|
|
1067
|
+
|
|
1068
1068
|
if not component_name:
|
|
1069
1069
|
component_name = generate_unique_name("Comp_")
|
|
1070
1070
|
if component_part_name:
|
|
@@ -1074,7 +1074,12 @@ class Components(object):
|
|
|
1074
1074
|
if not compdef:
|
|
1075
1075
|
return False
|
|
1076
1076
|
new_cmp = GrpcComponentGroup.create(self._active_layout, component_name, compdef.name)
|
|
1077
|
-
|
|
1077
|
+
if hasattr(pins[0], "component") and pins[0].component:
|
|
1078
|
+
hosting_component_location = None
|
|
1079
|
+
if not pins[0].component.is_null:
|
|
1080
|
+
hosting_component_location = pins[0].component.transform
|
|
1081
|
+
else:
|
|
1082
|
+
hosting_component_location = None
|
|
1078
1083
|
if not len(pins) == len(compdef.component_pins):
|
|
1079
1084
|
self._pedb.logger.error(
|
|
1080
1085
|
f"Number on pins {len(pins)} does not match component definition number "
|
|
@@ -1092,7 +1097,18 @@ class Components(object):
|
|
|
1092
1097
|
if new_cmp_layer_name in self._pedb.stackup.signal_layers:
|
|
1093
1098
|
new_cmp_placement_layer = self._pedb.stackup.signal_layers[new_cmp_layer_name]
|
|
1094
1099
|
new_cmp.placement_layer = new_cmp_placement_layer
|
|
1095
|
-
|
|
1100
|
+
if r_value:
|
|
1101
|
+
new_cmp.component_type = GrpcComponentType.RESISTOR
|
|
1102
|
+
is_rlc = True
|
|
1103
|
+
elif c_value:
|
|
1104
|
+
new_cmp.component_type = GrpcComponentType.CAPACITOR
|
|
1105
|
+
is_rlc = True
|
|
1106
|
+
elif l_value:
|
|
1107
|
+
new_cmp.component_type = GrpcComponentType.INDUCTOR
|
|
1108
|
+
is_rlc = True
|
|
1109
|
+
else:
|
|
1110
|
+
new_cmp.component_type = GrpcComponentType.OTHER
|
|
1111
|
+
is_rlc = False
|
|
1096
1112
|
if is_rlc and len(pins) == 2:
|
|
1097
1113
|
rlc = GrpcRlc()
|
|
1098
1114
|
rlc.is_parallel = is_parallel
|
|
@@ -1125,7 +1141,8 @@ class Components(object):
|
|
|
1125
1141
|
component_property = new_cmp.component_property
|
|
1126
1142
|
component_property.model = rlc_model
|
|
1127
1143
|
new_cmp.component_property = component_property
|
|
1128
|
-
|
|
1144
|
+
if hosting_component_location:
|
|
1145
|
+
new_cmp.transform = hosting_component_location
|
|
1129
1146
|
new_edb_comp = Component(self._pedb, new_cmp)
|
|
1130
1147
|
self._cmp[new_cmp.name] = new_edb_comp
|
|
1131
1148
|
return new_edb_comp
|
|
@@ -1666,7 +1683,9 @@ class Components(object):
|
|
|
1666
1683
|
if comp.partname == part_name:
|
|
1667
1684
|
pass
|
|
1668
1685
|
else:
|
|
1669
|
-
pinlist = self.
|
|
1686
|
+
pinlist = list(self.instances[refdes].pins.values())
|
|
1687
|
+
if not pinlist:
|
|
1688
|
+
continue
|
|
1670
1689
|
if not part_name in self.definitions:
|
|
1671
1690
|
comp_def = ComponentDef.create(self._db, part_name, None)
|
|
1672
1691
|
# for pin in range(len(pinlist)):
|
|
@@ -2208,7 +2227,7 @@ class Components(object):
|
|
|
2208
2227
|
Examples
|
|
2209
2228
|
--------
|
|
2210
2229
|
>>> from pyedb import Edb
|
|
2211
|
-
>>> edb_file = r
|
|
2230
|
+
>>> edb_file = r"C:\my_edb_file.aedb"
|
|
2212
2231
|
>>> edb = Edb(edb_file)
|
|
2213
2232
|
>>> for cmp in list(edb.components.instances.keys()):
|
|
2214
2233
|
>>> edb.components.deactivate_rlc_component(component=cmp, create_circuit_port=False)
|
|
@@ -58,40 +58,26 @@ def convert_technology_file(tech_file, edbversion=None, control_file=None):
|
|
|
58
58
|
-------
|
|
59
59
|
# Example 1: Converting a technology file to control file
|
|
60
60
|
>>> converted_file = convert_technology_file(
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
>>> control_file="/path/to/output.xml"
|
|
64
|
-
>>> )
|
|
61
|
+
... tech_file="/path/to/tech.t", edbversion="2025.2", control_file="/path/to/output.xml"
|
|
62
|
+
... )
|
|
65
63
|
>>> if converted_file:
|
|
66
64
|
>>> print(f"Converted to: {converted_file}")
|
|
67
65
|
|
|
68
66
|
# Example 2: Creating a material
|
|
69
67
|
>>> from pyedb import ControlFileMaterial
|
|
70
|
-
>>> material = ControlFileMaterial(
|
|
71
|
-
>>> "Copper",
|
|
72
|
-
>>> {"Permittivity": 1.0, "Conductivity": 5.8e7}
|
|
73
|
-
>>> )
|
|
68
|
+
>>> material = ControlFileMaterial("Copper", {"Permittivity": 1.0, "Conductivity": 5.8e7})
|
|
74
69
|
|
|
75
70
|
# Example 3: Creating a dielectric layer
|
|
76
71
|
>>> from pyedb import ControlFileDielectric
|
|
77
|
-
>>> dielectric = ControlFileDielectric(
|
|
78
|
-
>>> "Core",
|
|
79
|
-
>>> {"Thickness": "0.2mm", "Material": "FR4"}
|
|
80
|
-
>>> )
|
|
72
|
+
>>> dielectric = ControlFileDielectric("Core", {"Thickness": "0.2mm", "Material": "FR4"})
|
|
81
73
|
|
|
82
74
|
# Example 4: Creating a signal layer
|
|
83
75
|
>>> from pyedb import ControlFileLayer
|
|
84
|
-
>>> signal_layer = ControlFileLayer(
|
|
85
|
-
>>> "TopLayer",
|
|
86
|
-
>>> {"Type": "signal", "Material": "Copper", "Thickness": "0.035mm"}
|
|
87
|
-
>>> )
|
|
76
|
+
>>> signal_layer = ControlFileLayer("TopLayer", {"Type": "signal", "Material": "Copper", "Thickness": "0.035mm"})
|
|
88
77
|
|
|
89
78
|
# Example 5: Creating a via layer
|
|
90
79
|
>>> from pyedb import ControlFileVia
|
|
91
|
-
>>> via_layer = ControlFileVia(
|
|
92
|
-
>>> "Via1",
|
|
93
|
-
>>> {"StartLayer": "TopLayer", "StopLayer": "BottomLayer"}
|
|
94
|
-
>>> )
|
|
80
|
+
>>> via_layer = ControlFileVia("Via1", {"StartLayer": "TopLayer", "StopLayer": "BottomLayer"})
|
|
95
81
|
>>> via_layer.create_via_group = True
|
|
96
82
|
>>> via_layer.tolerance = "0.1mm"
|
|
97
83
|
|
|
@@ -111,11 +97,7 @@ def convert_technology_file(tech_file, edbversion=None, control_file=None):
|
|
|
111
97
|
|
|
112
98
|
# Example 8: Setting up simulation extents
|
|
113
99
|
>>> from pyedb import ControlExtent
|
|
114
|
-
>>> extent = ControlExtent(
|
|
115
|
-
>>> type="Conforming",
|
|
116
|
-
>>> diel_hactor=0.3,
|
|
117
|
-
>>> airbox_hfactor=0.5
|
|
118
|
-
>>> )
|
|
100
|
+
>>> extent = ControlExtent(type="Conforming", diel_hactor=0.3, airbox_hfactor=0.5)
|
|
119
101
|
|
|
120
102
|
# Example 9: Creating circuit ports
|
|
121
103
|
>>> from pyedb import ControlCircuitPt
|
|
@@ -142,17 +124,11 @@ def convert_technology_file(tech_file, edbversion=None, control_file=None):
|
|
|
142
124
|
|
|
143
125
|
# Example 13: Frequency sweep configuration
|
|
144
126
|
>>> from pyedb import ControlFileSweep
|
|
145
|
-
>>> sweep = ControlFileSweep(
|
|
146
|
-
>>> "Sweep1", "1GHz", "10GHz", "0.1GHz",
|
|
147
|
-
>>> "Interpolating", "LinearStep", True
|
|
148
|
-
>>> )
|
|
127
|
+
>>> sweep = ControlFileSweep("Sweep1", "1GHz", "10GHz", "0.1GHz", "Interpolating", "LinearStep", True)
|
|
149
128
|
|
|
150
129
|
# Example 14: Mesh operation setup
|
|
151
130
|
>>> from pyedb import ControlFileMeshOp
|
|
152
|
-
>>> mesh_op = ControlFileMeshOp(
|
|
153
|
-
>>> "FineMesh", "Region1", "MeshOperationSkinDepth",
|
|
154
|
-
>>> {"Net1": "TopLayer"}
|
|
155
|
-
>>> )
|
|
131
|
+
>>> mesh_op = ControlFileMeshOp("FineMesh", "Region1", "MeshOperationSkinDepth", {"Net1": "TopLayer"})
|
|
156
132
|
>>> mesh_op.skin_depth = "1um"
|
|
157
133
|
|
|
158
134
|
# Example 15: Simulation setup configuration
|
|
@@ -290,8 +266,11 @@ class ControlProperty:
|
|
|
290
266
|
double.text = str(self.value)
|
|
291
267
|
else:
|
|
292
268
|
pass
|
|
293
|
-
except:
|
|
294
|
-
|
|
269
|
+
except Exception as e:
|
|
270
|
+
settings.logger.error(
|
|
271
|
+
f"A(n) {type(e).__name__} error occurred while attempting to create a new sub-element {self.name} "
|
|
272
|
+
f"for element {root}: {str(e)}"
|
|
273
|
+
)
|
|
295
274
|
|
|
296
275
|
|
|
297
276
|
class ControlFileMaterial:
|
|
@@ -34,9 +34,9 @@ from ansys.edb.core.definition.djordjecvic_sarkar_model import (
|
|
|
34
34
|
DjordjecvicSarkarModel as GrpcDjordjecvicSarkarModel,
|
|
35
35
|
)
|
|
36
36
|
from ansys.edb.core.definition.material_def import (
|
|
37
|
+
MaterialDef as GrpcMaterialDef,
|
|
37
38
|
MaterialProperty as GrpcMaterialProperty,
|
|
38
39
|
)
|
|
39
|
-
from ansys.edb.core.definition.material_def import MaterialDef as GrpcMaterialDef
|
|
40
40
|
from ansys.edb.core.definition.multipole_debye_model import (
|
|
41
41
|
MultipoleDebyeModel as GrpcMultipoleDebyeModel,
|
|
42
42
|
)
|
|
@@ -193,8 +193,11 @@ class PackageDef(GrpcPackageDef):
|
|
|
193
193
|
"""
|
|
194
194
|
try:
|
|
195
195
|
return HeatSink(self._pedb, super().heat_sink)
|
|
196
|
-
except:
|
|
197
|
-
|
|
196
|
+
except Exception as e:
|
|
197
|
+
settings.logger.error(
|
|
198
|
+
f"A(n) {type(e).__name__} error occurred while attempting to access 'heatsink' "
|
|
199
|
+
f"property for object {self}: {str(e)}"
|
|
200
|
+
)
|
|
198
201
|
|
|
199
202
|
@property
|
|
200
203
|
@deprecated_property
|
|
@@ -222,9 +225,9 @@ class PackageDef(GrpcPackageDef):
|
|
|
222
225
|
Fin thickness.
|
|
223
226
|
"""
|
|
224
227
|
from ansys.edb.core.utility.heat_sink import (
|
|
228
|
+
HeatSink as GrpcHeatSink,
|
|
225
229
|
HeatSinkFinOrientation as GrpcHeatSinkFinOrientation,
|
|
226
230
|
)
|
|
227
|
-
from ansys.edb.core.utility.heat_sink import HeatSink as GrpcHeatSink
|
|
228
231
|
|
|
229
232
|
if fin_orientation == "x_oriented":
|
|
230
233
|
fin_orientation = GrpcHeatSinkFinOrientation.X_ORIENTED
|
|
@@ -26,15 +26,12 @@ import warnings
|
|
|
26
26
|
from ansys.edb.core.definition.padstack_def import PadstackDef as GrpcPadstackDef
|
|
27
27
|
from ansys.edb.core.definition.padstack_def_data import (
|
|
28
28
|
PadGeometryType as GrpcPadGeometryType,
|
|
29
|
-
)
|
|
30
|
-
from ansys.edb.core.definition.padstack_def_data import (
|
|
31
29
|
PadstackHoleRange as GrpcPadstackHoleRange,
|
|
30
|
+
PadType as GrpcPadType,
|
|
32
31
|
)
|
|
33
|
-
from ansys.edb.core.definition.padstack_def_data import PadType as GrpcPadType
|
|
34
32
|
import ansys.edb.core.geometry.polygon_data
|
|
35
33
|
from ansys.edb.core.geometry.polygon_data import PolygonData as GrpcPolygonData
|
|
36
|
-
from ansys.edb.core.hierarchy.structure3d import MeshClosure as GrpcMeshClosure
|
|
37
|
-
from ansys.edb.core.hierarchy.structure3d import Structure3D as GrpcStructure3D
|
|
34
|
+
from ansys.edb.core.hierarchy.structure3d import MeshClosure as GrpcMeshClosure, Structure3D as GrpcStructure3D
|
|
38
35
|
from ansys.edb.core.primitive.circle import Circle as GrpcCircle
|
|
39
36
|
|
|
40
37
|
from pyedb.generic.general_methods import generate_unique_name
|
|
@@ -127,7 +124,7 @@ class PadProperties:
|
|
|
127
124
|
self._update_pad_parameters_parameters(geom_type=GrpcPadGeometryType.PADGEOMTYPE_POLYGON)
|
|
128
125
|
else:
|
|
129
126
|
raise ValueError(
|
|
130
|
-
f"Unsupported pad shape: {value}. Supported shapes are 'circle',
|
|
127
|
+
f"Unsupported pad shape: {value}. Supported shapes are 'circle', 'rectangle', and 'polygon'."
|
|
131
128
|
)
|
|
132
129
|
|
|
133
130
|
@property
|
|
@@ -771,7 +768,7 @@ class PadstackDef(GrpcPadstackDef):
|
|
|
771
768
|
s3d.add_member(cloned_circle2)
|
|
772
769
|
if not self.data.material.value:
|
|
773
770
|
self._pedb.logger.warning(
|
|
774
|
-
f"Padstack definution {self.name} has no material defined.
|
|
771
|
+
f"Padstack definution {self.name} has no material defined.Defaulting to copper"
|
|
775
772
|
)
|
|
776
773
|
self.data.material = "copper"
|
|
777
774
|
s3d.set_material(self.data.material.value)
|
pyedb/grpc/database/hfss.py
CHANGED
|
@@ -23,6 +23,7 @@
|
|
|
23
23
|
"""
|
|
24
24
|
This module contains the ``EdbHfss`` class.
|
|
25
25
|
"""
|
|
26
|
+
|
|
26
27
|
import math
|
|
27
28
|
import warnings
|
|
28
29
|
|
|
@@ -1259,11 +1260,7 @@ class Hfss(object):
|
|
|
1259
1260
|
)
|
|
1260
1261
|
from ansys.edb.core.simulation_setup.simulation_setup import (
|
|
1261
1262
|
Distribution as GrpcDistribution,
|
|
1262
|
-
)
|
|
1263
|
-
from ansys.edb.core.simulation_setup.simulation_setup import (
|
|
1264
1263
|
FrequencyData as GrpcFrequencyData,
|
|
1265
|
-
)
|
|
1266
|
-
from ansys.edb.core.simulation_setup.simulation_setup import (
|
|
1267
1264
|
SweepData as GrpcSweepData,
|
|
1268
1265
|
)
|
|
1269
1266
|
|