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.

Files changed (107) hide show
  1. pyedb/__init__.py +1 -1
  2. pyedb/configuration/cfg_data.py +3 -0
  3. pyedb/configuration/cfg_operations.py +2 -2
  4. pyedb/configuration/cfg_ports_sources.py +1 -1
  5. pyedb/configuration/cfg_terminals.py +232 -0
  6. pyedb/configuration/configuration.py +146 -3
  7. pyedb/dotnet/clr_module.py +1 -2
  8. pyedb/dotnet/database/Variables.py +56 -41
  9. pyedb/dotnet/database/cell/layout.py +5 -1
  10. pyedb/dotnet/database/cell/primitive/primitive.py +2 -2
  11. pyedb/dotnet/database/cell/terminal/bundle_terminal.py +12 -0
  12. pyedb/dotnet/database/cell/terminal/pingroup_terminal.py +1 -1
  13. pyedb/dotnet/database/cell/terminal/terminal.py +38 -0
  14. pyedb/dotnet/database/components.py +55 -52
  15. pyedb/dotnet/database/dotnet/database.py +1 -0
  16. pyedb/dotnet/database/edb_data/control_file.py +6 -3
  17. pyedb/dotnet/database/edb_data/nets_data.py +3 -3
  18. pyedb/dotnet/database/edb_data/padstacks_data.py +5 -2
  19. pyedb/dotnet/database/edb_data/ports.py +0 -25
  20. pyedb/dotnet/database/edb_data/primitives_data.py +3 -3
  21. pyedb/dotnet/database/edb_data/raptor_x_simulation_setup_data.py +18 -19
  22. pyedb/dotnet/database/edb_data/simulation_configuration.py +3 -3
  23. pyedb/dotnet/database/hfss.py +9 -8
  24. pyedb/dotnet/database/layout_validation.py +6 -3
  25. pyedb/dotnet/database/materials.py +1 -3
  26. pyedb/dotnet/database/modeler.py +7 -3
  27. pyedb/dotnet/database/nets.py +27 -19
  28. pyedb/dotnet/database/padstack.py +91 -2
  29. pyedb/dotnet/database/sim_setup_data/io/siwave.py +1 -1
  30. pyedb/dotnet/database/siwave.py +4 -3
  31. pyedb/dotnet/database/stackup.py +50 -26
  32. pyedb/dotnet/database/utilities/heatsink.py +0 -1
  33. pyedb/dotnet/database/utilities/simulation_setup.py +7 -5
  34. pyedb/dotnet/database/utilities/siwave_cpa_simulation_setup.py +1 -0
  35. pyedb/dotnet/database/utilities/siwave_simulation_setup.py +5 -2
  36. pyedb/dotnet/edb.py +41 -36
  37. pyedb/exceptions.py +1 -2
  38. pyedb/extensions/create_cell_array.py +408 -0
  39. pyedb/generic/data_handlers.py +17 -28
  40. pyedb/generic/design_types.py +25 -38
  41. pyedb/generic/filesystem.py +9 -4
  42. pyedb/generic/general_methods.py +6 -7
  43. pyedb/generic/plot.py +2 -2
  44. pyedb/generic/settings.py +4 -0
  45. pyedb/grpc/database/_typing.py +0 -0
  46. pyedb/grpc/database/components.py +30 -11
  47. pyedb/grpc/database/control_file.py +14 -35
  48. pyedb/grpc/database/definition/materials.py +1 -1
  49. pyedb/grpc/database/definition/package_def.py +6 -3
  50. pyedb/grpc/database/definition/padstack_def.py +4 -7
  51. pyedb/grpc/database/hfss.py +1 -4
  52. pyedb/grpc/database/hierarchy/component.py +3 -4
  53. pyedb/grpc/database/hierarchy/pingroup.py +16 -3
  54. pyedb/grpc/database/layers/layer.py +1 -2
  55. pyedb/grpc/database/layers/stackup_layer.py +42 -19
  56. pyedb/grpc/database/layout/layout.py +117 -28
  57. pyedb/grpc/database/layout/voltage_regulator.py +6 -1
  58. pyedb/grpc/database/layout_validation.py +7 -4
  59. pyedb/grpc/database/modeler.py +241 -256
  60. pyedb/grpc/database/net/differential_pair.py +9 -2
  61. pyedb/grpc/database/net/extended_net.py +24 -9
  62. pyedb/grpc/database/net/net.py +14 -5
  63. pyedb/grpc/database/net/net_class.py +24 -7
  64. pyedb/grpc/database/nets.py +11 -43
  65. pyedb/grpc/database/padstacks.py +92 -16
  66. pyedb/grpc/database/primitive/bondwire.py +3 -67
  67. pyedb/grpc/database/primitive/circle.py +42 -3
  68. pyedb/grpc/database/primitive/padstack_instance.py +17 -19
  69. pyedb/grpc/database/primitive/path.py +154 -5
  70. pyedb/grpc/database/primitive/polygon.py +75 -9
  71. pyedb/grpc/database/primitive/primitive.py +2 -2
  72. pyedb/grpc/database/primitive/rectangle.py +105 -4
  73. pyedb/grpc/database/simulation_setup/hfss_general_settings.py +0 -2
  74. pyedb/grpc/database/simulation_setup/hfss_settings_options.py +0 -4
  75. pyedb/grpc/database/simulation_setup/siwave_cpa_simulation_setup.py +4 -2
  76. pyedb/grpc/database/simulation_setup/sweep_data.py +1 -3
  77. pyedb/grpc/database/siwave.py +6 -13
  78. pyedb/grpc/database/source_excitations.py +49 -57
  79. pyedb/grpc/database/stackup.py +50 -27
  80. pyedb/grpc/database/terminal/bundle_terminal.py +10 -3
  81. pyedb/grpc/database/terminal/pingroup_terminal.py +8 -1
  82. pyedb/grpc/database/terminal/terminal.py +19 -8
  83. pyedb/grpc/database/utility/heat_sink.py +0 -1
  84. pyedb/grpc/database/utility/hfss_extent_info.py +2 -2
  85. pyedb/grpc/database/utility/value.py +1 -0
  86. pyedb/grpc/database/utility/xml_control_file.py +6 -3
  87. pyedb/grpc/edb.py +33 -24
  88. pyedb/grpc/edb_init.py +1 -0
  89. pyedb/grpc/rpc_session.py +4 -3
  90. pyedb/ipc2581/ecad/cad_data/layer_feature.py +6 -2
  91. pyedb/ipc2581/ecad/cad_data/step.py +1 -1
  92. pyedb/ipc2581/ipc2581.py +8 -7
  93. pyedb/libraries/common.py +3 -4
  94. pyedb/libraries/rf_libraries/base_functions.py +7 -16
  95. pyedb/libraries/rf_libraries/planar_antennas.py +3 -21
  96. pyedb/misc/downloads.py +1 -0
  97. pyedb/misc/misc.py +5 -2
  98. pyedb/misc/siw_feature_config/emc_rule_checker_settings.py +1 -1
  99. pyedb/misc/utilities.py +0 -1
  100. pyedb/modeler/geometry_operators.py +9 -8
  101. pyedb/siwave.py +4 -6
  102. pyedb/siwave_core/__init__.py +0 -0
  103. pyedb/siwave_core/cpa/__init__.py +0 -0
  104. {pyedb-0.55.0.dist-info → pyedb-0.57.0.dist-info}/METADATA +3 -3
  105. {pyedb-0.55.0.dist-info → pyedb-0.57.0.dist-info}/RECORD +107 -102
  106. {pyedb-0.55.0.dist-info → pyedb-0.57.0.dist-info}/WHEEL +0 -0
  107. {pyedb-0.55.0.dist-info → pyedb-0.57.0.dist-info}/licenses/LICENSE +0 -0
@@ -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(random.choice(char_set) for _ in range(int(length)))
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
- if isinstance(element_list, list):
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
- if only_string:
89
- non_string_entries = [x for x in element_list if type(x) is not str]
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('R47')
135
+ >>> from_rkm("R47")
147
136
  '0.47'
148
137
 
149
- >>> from_rkm('4R7')
138
+ >>> from_rkm("4R7")
150
139
  '4.7'
151
140
 
152
- >>> from_rkm('470R')
141
+ >>> from_rkm("470R")
153
142
  '470'
154
143
 
155
- >>> from_rkm('4K7')
144
+ >>> from_rkm("4K7")
156
145
  '4.7k'
157
146
 
158
- >>> from_rkm('47K')
147
+ >>> from_rkm("47K")
159
148
  '47k'
160
149
 
161
- >>> from_rkm('47K3')
150
+ >>> from_rkm("47K3")
162
151
  '47.3k'
163
152
 
164
- >>> from_rkm('470K')
153
+ >>> from_rkm("470K")
165
154
  '470k'
166
155
 
167
- >>> from_rkm('4M7')
156
+ >>> from_rkm("4M7")
168
157
  '4.7M'
169
158
 
170
159
  """
@@ -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
- edbversion : str, optional
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
 
@@ -1,8 +1,10 @@
1
1
  import os
2
- import random
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
- self._scratch_path = os.path.normpath(os.path.join(local_path, "scratch" + "".join(random.sample(char_set, 6))))
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
- pass
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
  """
@@ -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
- pass
134
- args = [func.__name__] + [i for i in args_name if i not in ["self"]]
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
- "+".join(args)
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(random.choice(char_set) for _ in range(n))
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
- pass
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
- hosting_component_location = pins[0].component.transform
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
- new_cmp.component_type = GrpcComponentType.OTHER
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
- new_cmp.transform = hosting_component_location
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._pedb.padstacks.get_instances(refdes)
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'C:\my_edb_file.aedb'
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
- >>> tech_file="/path/to/tech.t",
62
- >>> edbversion="2025.2",
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
- pass
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
- pass
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', " f"'rectangle', and 'polygon'."
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." f"Defaulting to copper"
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)
@@ -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