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
@@ -35,9 +35,12 @@ Examples
35
35
 
36
36
  """
37
37
 
38
- from __future__ import absolute_import # noreorder
39
- from __future__ import division
38
+ from __future__ import (
39
+ absolute_import, # noreorder
40
+ division,
41
+ )
40
42
 
43
+ import ast
41
44
  import os
42
45
  import re
43
46
  import types
@@ -181,13 +184,15 @@ class CSVDataset:
181
184
  if variable in key_string:
182
185
  found_variable = True
183
186
  break
184
- assert found_variable, "Input string {} is not a key of the data dictionary.".format(variable)
187
+ if not found_variable:
188
+ raise KeyError(f"Input string {variable} is not a key of the data dictionary.")
185
189
  data_out._data[variable] = self._data[key_string]
186
190
  data_out._header.append(variable)
187
191
  return data_out
188
192
 
189
193
  def __add__(self, other): # pragma: no cover
190
- assert self.number_of_columns == other.number_of_columns, "Inconsistent number of columns"
194
+ if self.number_of_columns != other.number_of_columns:
195
+ raise ValueError("Number of columns is inconsistent.")
191
196
  # Create a new object to return, avoiding changing the original inputs
192
197
  new_dataset = CSVDataset()
193
198
  # Add empty columns to new_dataset
@@ -222,7 +227,8 @@ class CSVDataset:
222
227
  for column in other.data:
223
228
  self._data[column] = []
224
229
 
225
- assert self.number_of_columns == other.number_of_columns, "Inconsistent number of columns"
230
+ if self.number_of_columns != other.number_of_columns:
231
+ raise ValueError("Number of columns is inconsistent.")
226
232
 
227
233
  # Append the data from 'other'
228
234
  for column, row_data in other.data.items():
@@ -490,13 +496,13 @@ class VariableManager(object):
490
496
  --------
491
497
  >>> hfss = Hfss()
492
498
  >>> print(hfss.variable_manager.decompose("5mm"))
493
- >>> (5.0, 'mm')
499
+ >>> (5.0, "mm")
494
500
  >>> hfss["v1"] = "3N"
495
501
  >>> print(hfss.variable_manager.decompose("v1"))
496
- >>> (3.0, 'N')
502
+ >>> (3.0, "N")
497
503
  >>> hfss["v2"] = "2*v1"
498
504
  >>> print(hfss.variable_manager.decompose("v2"))
499
- >>> (6.0, 'N')
505
+ >>> (6.0, "N")
500
506
  """
501
507
  if variable_value in self.independent_variable_names:
502
508
  val, unit = decompose_variable_value(self[variable_value].expression)
@@ -1006,8 +1012,13 @@ class VariableManager(object):
1006
1012
  creating the property if it does not already exist. Also make
1007
1013
  it read-only and hidden and add a description.
1008
1014
 
1009
- >>> aedtapp.variable_manager.set_variable(variable_name="p2", expression="10mm", readonly=True, hidden=True,
1010
- ... description="This is the description of this variable.")
1015
+ >>> aedtapp.variable_manager.set_variable(
1016
+ ... variable_name="p2",
1017
+ ... expression="10mm",
1018
+ ... readonly=True,
1019
+ ... hidden=True,
1020
+ ... description="This is the description of this variable.",
1021
+ ... )
1011
1022
 
1012
1023
  Set the value of the project variable ``$p1`` to ``"30mm"``,
1013
1024
  creating the variable if it does not exist.
@@ -1070,8 +1081,8 @@ class VariableManager(object):
1070
1081
  desktop_object.Undo()
1071
1082
  self._logger.clear_messages()
1072
1083
  return
1073
- except:
1074
- pass
1084
+ except Exception:
1085
+ self._logger.debug(f"Something went wrong when deleting '{variable_name}'.")
1075
1086
  else:
1076
1087
  raise Exception("Unhandled input type to the design property or project variable.") # pragma: no cover
1077
1088
 
@@ -1201,8 +1212,8 @@ class VariableManager(object):
1201
1212
  ]
1202
1213
  )
1203
1214
  return True
1204
- except:
1205
- pass
1215
+ except Exception:
1216
+ self._logger.debug("Failed to change desktop object property.")
1206
1217
  return False
1207
1218
 
1208
1219
  def delete_variable(self, var_name): # pragma: no cover
@@ -1241,8 +1252,8 @@ class VariableManager(object):
1241
1252
  ],
1242
1253
  ]
1243
1254
  )
1244
- except: # pragma: no cover
1245
- pass
1255
+ except Exception: # pragma: no cover
1256
+ self._logger.debug("Failed to change desktop object property.")
1246
1257
  else:
1247
1258
  self._cleanup_variables()
1248
1259
  return True
@@ -1341,9 +1352,10 @@ class Variable(object):
1341
1352
  self._value = self._calculated_value
1342
1353
  # If units have been specified, check for a conflict and otherwise use the specified unit system
1343
1354
  if units:
1344
- assert not self._units, "The unit specification {} is inconsistent with the identified units {}.".format(
1345
- specified_units, self._units
1346
- )
1355
+ if self._units and self._units != specified_units:
1356
+ raise RuntimeError(
1357
+ f"The unit specification {specified_units} is inconsistent with the identified units {self._units}."
1358
+ )
1347
1359
  self._units = specified_units
1348
1360
 
1349
1361
  if not si_value and is_number(self._value):
@@ -1407,8 +1419,8 @@ class Variable(object):
1407
1419
  if result:
1408
1420
  break
1409
1421
  i += 1
1410
- except:
1411
- pass
1422
+ except Exception:
1423
+ self._app.logger.debug(f"Failed to set property '{prop}' value.")
1412
1424
 
1413
1425
  def _get_prop_val(self, prop): # pragma: no cover
1414
1426
  if self._app.design_type == "Maxwell Circuit":
@@ -1428,8 +1440,8 @@ class Variable(object):
1428
1440
  else:
1429
1441
  name = "LocalVariables"
1430
1442
  return self._app.get_oo_object(self._aedt_obj, "{}/{}".format(name, self._variable_name)).GetPropValue(prop)
1431
- except:
1432
- pass
1443
+ except Exception:
1444
+ self._app.logger.debug(f"Failed to get property '{prop}' value.")
1433
1445
 
1434
1446
  @property
1435
1447
  def name(self): # pragma: no cover
@@ -1638,7 +1650,7 @@ class Variable(object):
1638
1650
  def numeric_value(self): # pragma: no cover
1639
1651
  """Numeric part of the expression as a float value."""
1640
1652
  if is_array(self._value):
1641
- return list(eval(self._value))
1653
+ return list(ast.literal_eval(self._value))
1642
1654
  try:
1643
1655
  var_obj = self._aedt_obj.GetChildObject("Variables").GetChildObject(self._variable_name)
1644
1656
  val, _ = decompose_variable_value(var_obj.GetPropEvaluatedValue("EvaluatedValue"))
@@ -1704,7 +1716,7 @@ class Variable(object):
1704
1716
  >>> hfss = Hfss()
1705
1717
  >>> hfss["v1"] = "3N"
1706
1718
  >>> print(hfss.variable_manager["v1"].decompose("v1"))
1707
- >>> (3.0, 'N')
1719
+ >>> (3.0, "N")
1708
1720
 
1709
1721
  """
1710
1722
  return decompose_variable_value(self.evaluated_value)
@@ -1730,9 +1742,10 @@ class Variable(object):
1730
1742
 
1731
1743
  """
1732
1744
  new_unit_system = unit_system(units)
1733
- assert (
1734
- new_unit_system == self.unit_system
1735
- ), "New unit system {0} is inconsistent with the current unit system {1}."
1745
+ if new_unit_system != self.unit_system:
1746
+ raise ValueError(
1747
+ f"New unit system {new_unit_system} is inconsistent with the current unit system {self.unit_system}."
1748
+ )
1736
1749
  self._units = units
1737
1750
  return self
1738
1751
 
@@ -1755,9 +1768,9 @@ class Variable(object):
1755
1768
  >>> from pyedb.dotnet.database.Variables import Variable
1756
1769
 
1757
1770
  >>> v = Variable("10W")
1758
- >>> assert v.format("f") == '10.000000W'
1759
- >>> assert v.format("06.2f") == '010.00W'
1760
- >>> assert v.format("6.2f") == ' 10.00W'
1771
+ >>> assert v.format("f") == "10.000000W"
1772
+ >>> assert v.format("06.2f") == "010.00W"
1773
+ >>> assert v.format("6.2f") == " 10.00W"
1761
1774
 
1762
1775
  """
1763
1776
  return ("{0:" + format + "}{1}").format(self.numeric_value, self._units)
@@ -1803,7 +1816,8 @@ class Variable(object):
1803
1816
  >>> assert result_3.unit_system == "Power"
1804
1817
 
1805
1818
  """
1806
- assert is_number(other) or isinstance(other, Variable), "Multiplier must be a scalar quantity or a variable."
1819
+ if not is_number(other) and not isinstance(other, Variable):
1820
+ raise ValueError("Multiplier must be a scalar quantity or a variable.")
1807
1821
  if is_number(other):
1808
1822
  result_value = self.numeric_value * other
1809
1823
  result_units = self.units
@@ -1847,10 +1861,10 @@ class Variable(object):
1847
1861
  >>> assert result.unit_system == "Current"
1848
1862
 
1849
1863
  """
1850
- assert isinstance(other, Variable), "You can only add a variable with another variable."
1851
- assert (
1852
- self.unit_system == other.unit_system
1853
- ), "Only ``Variable`` objects with the same unit system can be added."
1864
+ if not isinstance(other, Variable):
1865
+ raise ValueError("You can only add a variable with another variable.")
1866
+ if self.unit_system != other.unit_system:
1867
+ raise ValueError("Only Variable objects with the same unit system can be added.")
1854
1868
  result_value = self.value + other.value
1855
1869
  result_units = SI_UNITS[self.unit_system]
1856
1870
  # If the units of the two operands are different, return SI-Units
@@ -1888,10 +1902,10 @@ class Variable(object):
1888
1902
  >>> assert result_2.unit_system == "Current"
1889
1903
 
1890
1904
  """
1891
- assert isinstance(other, Variable), "You can only subtract a variable from another variable."
1892
- assert (
1893
- self.unit_system == other.unit_system
1894
- ), "Only ``Variable`` objects with the same unit system can be subtracted."
1905
+ if not isinstance(other, Variable):
1906
+ raise ValueError("You can only subtract a variable from another variable.")
1907
+ if self.unit_system != other.unit_system:
1908
+ raise ValueError("Only Variable objects with the same unit system can be subtracted.")
1895
1909
  result_value = self.value - other.value
1896
1910
  result_units = SI_UNITS[self.unit_system]
1897
1911
  # If the units of the two operands are different, return SI-Units
@@ -1933,7 +1947,8 @@ class Variable(object):
1933
1947
  >>> assert result_1.unit_system == "Current"
1934
1948
 
1935
1949
  """
1936
- assert is_number(other) or isinstance(other, Variable), "Divisor must be a scalar quantity or a variable."
1950
+ if not is_number(other) and not isinstance(other, Variable):
1951
+ raise ValueError("Divisor must be a scalar quantity or a variable.")
1937
1952
  if is_number(other):
1938
1953
  result_value = self.numeric_value / other
1939
1954
  result_units = self.units
@@ -23,6 +23,7 @@
23
23
  """
24
24
  This module contains these classes: `EdbLayout` and `Shape`.
25
25
  """
26
+
26
27
  from typing import List, Union
27
28
 
28
29
  from pyedb.dotnet.database.cell.hierarchy.component import EDBComponent
@@ -55,6 +56,8 @@ from pyedb.dotnet.database.utilities.obj_base import ObjBase
55
56
 
56
57
 
57
58
  def primitive_cast(pedb, edb_object):
59
+ if not hasattr(edb_object, "GetPrimitiveType"):
60
+ return
58
61
  if edb_object.GetPrimitiveType().ToString() == "Rectangle":
59
62
  return EdbRectangle(edb_object, pedb)
60
63
  elif edb_object.GetPrimitiveType().ToString() == "Circle":
@@ -234,7 +237,7 @@ class Layout(ObjBase):
234
237
  primitives = list(self._edb_object.Primitives)
235
238
  if len(primitives) != len(self._primitives):
236
239
  self._primitives = [primitive_cast(self._pedb, p) for p in primitives]
237
- return self._primitives
240
+ return [p for p in self._primitives if p is not None] # non stackup primitives are None
238
241
 
239
242
  @property
240
243
  def primitives_by_aedt_name(self) -> dict:
@@ -406,6 +409,7 @@ class Layout(ObjBase):
406
409
  """
407
410
  candidates = self.padstack_instances
408
411
  if instance_id is not None:
412
+ instance_id = int(instance_id)
409
413
  value = instance_id if isinstance(instance_id, list) else [instance_id]
410
414
  candidates = [i for i in candidates if i.id in value]
411
415
 
@@ -39,8 +39,8 @@ class Primitive(Connectable):
39
39
  >>> from pyedb import Edb
40
40
  >>> edb = Edb(myedb, edbversion="2021.2")
41
41
  >>> edb_prim = edb.modeler.primitives[0]
42
- >>> edb_prim.is_void # Class Property
43
- >>> edb_prim.IsVoid() # EDB Object Property
42
+ >>> edb_prim.is_void # Class Property
43
+ >>> edb_prim.IsVoid() # EDB Object Property
44
44
  """
45
45
 
46
46
  def __init__(self, pedb, edb_object):
@@ -22,6 +22,7 @@
22
22
 
23
23
  from pyedb.dotnet.database.cell.terminal.edge_terminal import EdgeTerminal
24
24
  from pyedb.dotnet.database.cell.terminal.terminal import Terminal
25
+ from pyedb.dotnet.database.general import convert_py_list_to_net_list
25
26
 
26
27
 
27
28
  class BundleTerminal(Terminal):
@@ -46,3 +47,14 @@ class BundleTerminal(Terminal):
46
47
  def decouple(self):
47
48
  """Ungroup a bundle of terminals."""
48
49
  return self._edb_object.Ungroup()
50
+
51
+ @classmethod
52
+ def create(cls, pedb, name, terminals):
53
+ terminal_list = [pedb.terminals[i]._edb_object for i in terminals]
54
+ edb_list = convert_py_list_to_net_list(terminal_list, pedb._edb.Cell.Terminal.Terminal)
55
+ _edb_boundle_terminal = pedb._edb.Cell.Terminal.BundleTerminal.Create(edb_list)
56
+ _edb_boundle_terminal.SetName(name)
57
+ pos, neg = list(_edb_boundle_terminal.GetTerminals())
58
+ pos.SetName(name + ":T1")
59
+ neg.SetName(name + ":T2")
60
+ return pedb.terminals[name]
@@ -57,7 +57,7 @@ class PinGroupTerminal(Terminal):
57
57
  )
58
58
  term = PinGroupTerminal(self._pedb, term)
59
59
  if term.is_null:
60
- msg = f"Failed to create terminal. "
60
+ msg = f"Failed to create terminal {name}."
61
61
  if name in self._pedb.terminals:
62
62
  msg += f"Terminal {name} already exists."
63
63
  raise ValueError(msg)
@@ -56,6 +56,12 @@ class Terminal(Connectable):
56
56
  "PinGroupTerminal": self._pedb.core.Cell.Terminal.TerminalType.PinGroupTerminal,
57
57
  }
58
58
 
59
+ self._source_term_to_ground_mapping = {
60
+ "kNoGround": self._pedb.core.Cell.Terminal.SourceTermToGround.kNoGround,
61
+ "kNegative": self._pedb.core.Cell.Terminal.SourceTermToGround.kNegative,
62
+ "kPositive": self._pedb.core.Cell.Terminal.SourceTermToGround.kPositive,
63
+ }
64
+
59
65
  @property
60
66
  def _hfss_port_property(self):
61
67
  """HFSS port property."""
@@ -444,3 +450,35 @@ class Terminal(Connectable):
444
450
  @phase.setter
445
451
  def phase(self, value):
446
452
  self._edb_object.SetSourcePhase(self._edb.Utility.Value(value))
453
+
454
+ @property
455
+ def amplitude(self):
456
+ """Property added for grpc compatibility"""
457
+ return self.magnitude
458
+
459
+ @property
460
+ def source_amplitude(self):
461
+ """Property added for grpc compatibility"""
462
+ return self.magnitude
463
+
464
+ @source_amplitude.setter
465
+ def source_amplitude(self, value):
466
+ self.magnitude = value
467
+
468
+ @property
469
+ def source_phase(self):
470
+ """Property added for grpc compatibility"""
471
+ return self.phase
472
+
473
+ @source_phase.setter
474
+ def source_phase(self, value):
475
+ self.phase = value
476
+
477
+ @property
478
+ def terminal_to_ground(self):
479
+ return self._edb_object.GetTerminalToGround().ToString()
480
+
481
+ @terminal_to_ground.setter
482
+ def terminal_to_ground(self, value):
483
+ obj = self._source_term_to_ground_mapping[value]
484
+ self._edb_object.SetTerminalToGround(obj)
@@ -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
@@ -541,16 +540,17 @@ class Components(object):
541
540
 
542
541
  Examples
543
542
  --------
544
- >>> edb1 = Edb(edbpath=targetfile1, edbversion="2021.2")
543
+ >>> edb1 = Edb(edbpath=targetfile1, edbversion="2021.2")
545
544
  >>> hosting_cmp = edb1.components.get_component_by_name("U100")
546
545
  >>> mounted_cmp = edb2.components.get_component_by_name("BGA")
547
546
  >>> vector, rotation, solder_ball_height = edb1.components.get_component_placement_vector(
548
- ... mounted_component=mounted_cmp,
549
- ... hosting_component=hosting_cmp,
550
- ... mounted_component_pin1="A12",
551
- ... mounted_component_pin2="A14",
552
- ... hosting_component_pin1="A12",
553
- ... hosting_component_pin2="A14")
547
+ ... mounted_component=mounted_cmp,
548
+ ... hosting_component=hosting_cmp,
549
+ ... mounted_component_pin1="A12",
550
+ ... mounted_component_pin2="A14",
551
+ ... hosting_component_pin1="A12",
552
+ ... hosting_component_pin2="A14",
553
+ ... )
554
554
  """
555
555
  m_pin1_pos = [0.0, 0.0]
556
556
  m_pin2_pos = [0.0, 0.0]
@@ -1002,12 +1002,6 @@ class Components(object):
1002
1002
  ]
1003
1003
  pin_layers = cmp_pins[0].GetPadstackDef().GetData().GetLayerNames()
1004
1004
  if port_type == SourceType.CoaxPort:
1005
- if not solder_balls_height:
1006
- solder_balls_height = self.instances[component.GetName()].solder_ball_height
1007
- if not solder_balls_size:
1008
- solder_balls_size = self.instances[component.GetName()].solder_ball_diameter[0]
1009
- if not solder_balls_mid_size:
1010
- solder_balls_mid_size = self.instances[component.GetName()].solder_ball_diameter[1]
1011
1005
  if not ref_pins:
1012
1006
  self._logger.error(
1013
1007
  "No reference pins found on component. You might consider"
@@ -1016,40 +1010,51 @@ class Components(object):
1016
1010
  )
1017
1011
  return False
1018
1012
  pad_params = self._padstack.get_pad_parameters(pin=cmp_pins[0], layername=pin_layers[0], pad_type=0)
1019
- if not pad_params[0] == 7:
1020
- if not solder_balls_size: # pragma no cover
1021
- sball_diam = min([self._pedb.edb_value(val).ToDouble() for val in pad_params[1]])
1022
- sball_mid_diam = sball_diam
1013
+
1014
+ # If at least one of the solderball arguments is not None, calculate the rest and set solderballs
1015
+ if not (not solder_balls_height and not solder_balls_size and not solder_balls_mid_size):
1016
+ if not solder_balls_height:
1017
+ solder_balls_height = self.instances[component.GetName()].solder_ball_height
1018
+ if not solder_balls_size:
1019
+ solder_balls_size = self.instances[component.GetName()].solder_ball_diameter[0]
1020
+ if not solder_balls_mid_size:
1021
+ solder_balls_mid_size = self.instances[component.GetName()].solder_ball_diameter[1]
1022
+
1023
+ if not pad_params[0] == 7:
1024
+ if not solder_balls_size: # pragma no cover
1025
+ sball_diam = min([self._pedb.edb_value(val).ToDouble() for val in pad_params[1]])
1026
+ sball_mid_diam = sball_diam
1027
+ else: # pragma no cover
1028
+ sball_diam = solder_balls_size
1029
+ if solder_balls_mid_size:
1030
+ sball_mid_diam = solder_balls_mid_size
1031
+ else:
1032
+ sball_mid_diam = solder_balls_size
1033
+ if not solder_balls_height: # pragma no cover
1034
+ solder_balls_height = 2 * sball_diam / 3
1023
1035
  else: # pragma no cover
1024
- sball_diam = solder_balls_size
1036
+ if not solder_balls_size:
1037
+ bbox = pad_params[1]
1038
+ sball_diam = min([abs(bbox[2] - bbox[0]), abs(bbox[3] - bbox[1])]) * 0.8
1039
+ else:
1040
+ sball_diam = solder_balls_size
1041
+ if not solder_balls_height:
1042
+ solder_balls_height = 2 * sball_diam / 3
1025
1043
  if solder_balls_mid_size:
1026
1044
  sball_mid_diam = solder_balls_mid_size
1027
1045
  else:
1028
- sball_mid_diam = solder_balls_size
1029
- if not solder_balls_height: # pragma no cover
1030
- solder_balls_height = 2 * sball_diam / 3
1031
- else: # pragma no cover
1032
- if not solder_balls_size:
1033
- bbox = pad_params[1]
1034
- sball_diam = min([abs(bbox[2] - bbox[0]), abs(bbox[3] - bbox[1])]) * 0.8
1035
- else:
1036
- sball_diam = solder_balls_size
1037
- if not solder_balls_height:
1038
- solder_balls_height = 2 * sball_diam / 3
1039
- if solder_balls_mid_size:
1040
- sball_mid_diam = solder_balls_mid_size
1041
- else:
1042
- sball_mid_diam = sball_diam
1043
- sball_shape = "Cylinder"
1044
- if not sball_diam == sball_mid_diam:
1045
- sball_shape = "Spheroid"
1046
- self.set_solder_ball(
1047
- component=component,
1048
- sball_height=solder_balls_height,
1049
- sball_diam=sball_diam,
1050
- sball_mid_diam=sball_mid_diam,
1051
- shape=sball_shape,
1052
- )
1046
+ sball_mid_diam = sball_diam
1047
+ sball_shape = "Cylinder"
1048
+ if not sball_diam == sball_mid_diam:
1049
+ sball_shape = "Spheroid"
1050
+ self.set_solder_ball(
1051
+ component=component,
1052
+ sball_height=solder_balls_height,
1053
+ sball_diam=sball_diam,
1054
+ sball_mid_diam=sball_mid_diam,
1055
+ shape=sball_shape,
1056
+ )
1057
+
1053
1058
  for pin in cmp_pins:
1054
1059
  self._padstack.create_coax_port(padstackinstance=pin, name=port_name)
1055
1060
 
@@ -1265,7 +1270,7 @@ class Components(object):
1265
1270
  Examples
1266
1271
  --------
1267
1272
  >>> from pyedb import Edb
1268
- >>> edb_file = r'C:\my_edb_file.aedb'
1273
+ >>> edb_file = r"C:\my_edb_file.aedb"
1269
1274
  >>> edb = Edb(edb_file)
1270
1275
  >>> for cmp in list(edb.components.instances.keys()):
1271
1276
  >>> edb.components.deactivate_rlc_component(component=cmp, create_circuit_port=False)
@@ -1745,9 +1750,9 @@ class Components(object):
1745
1750
 
1746
1751
  >>> from pyedb import Edb
1747
1752
  >>> edbapp = Edb("myaedbfolder")
1748
- >>> edbapp.components.set_component_model("A1", model_type="Spice",
1749
- ... modelpath="pathtospfile",
1750
- ... modelname="spicemodelname")
1753
+ >>> edbapp.components.set_component_model(
1754
+ ... "A1", model_type="Spice", modelpath="pathtospfile", modelname="spicemodelname"
1755
+ ... )
1751
1756
 
1752
1757
  """
1753
1758
  if not modelname:
@@ -2147,9 +2152,7 @@ class Components(object):
2147
2152
 
2148
2153
  >>> from pyedb import Edb
2149
2154
  >>> edbapp = Edb("myaedbfolder")
2150
- >>> edbapp.components.set_component_rlc(
2151
- ... "R1", res_value=50, ind_value=1e-9, cap_value=1e-12, isparallel=False
2152
- ... )
2155
+ >>> edbapp.components.set_component_rlc("R1", res_value=50, ind_value=1e-9, cap_value=1e-12, isparallel=False)
2153
2156
 
2154
2157
  """
2155
2158
  if res_value is None and ind_value is None and cap_value is None:
@@ -21,6 +21,7 @@
21
21
  # SOFTWARE.
22
22
 
23
23
  """Database."""
24
+
24
25
  import re
25
26
 
26
27
  from pyedb.dotnet.database.general import convert_py_list_to_net_list
@@ -123,7 +123,7 @@ class ControlProperty:
123
123
  float(value)
124
124
  self.type = 0
125
125
  except TypeError:
126
- pass
126
+ self.type = -1
127
127
 
128
128
  def _write_xml(self, root):
129
129
  try:
@@ -133,8 +133,11 @@ class ControlProperty:
133
133
  double.text = str(self.value)
134
134
  else:
135
135
  pass
136
- except:
137
- pass
136
+ except Exception as e:
137
+ settings.logger.error(
138
+ f"A(n) {type(e).__name__} error occurred while attempting to create a new sub-element {self.name} "
139
+ f"for element {root}: {str(e)}"
140
+ )
138
141
 
139
142
 
140
143
  class ControlFileMaterial:
@@ -37,8 +37,8 @@ class EDBNetsData(NetDotNet):
37
37
  >>> from pyedb import Edb
38
38
  >>> edb = Edb(myedb, edbversion="2021.2")
39
39
  >>> edb_net = edb.nets.nets["GND"]
40
- >>> edb_net.name # Class Property
41
- >>> edb_net.name # EDB Object Property
40
+ >>> edb_net.name # Class Property
41
+ >>> edb_net.name # EDB Object Property
42
42
  """
43
43
 
44
44
  def __init__(self, raw_net, core_app):
@@ -220,7 +220,7 @@ class EDBExtendedNetData(ExtendedNetDotNet):
220
220
  >>> from pyedb import Edb
221
221
  >>> edb = Edb(myedb, edbversion="2021.2")
222
222
  >>> edb_extended_net = edb.nets.extended_nets["GND"]
223
- >>> edb_extended_net.name # Class Property
223
+ >>> edb_extended_net.name # Class Property
224
224
  """
225
225
 
226
226
  def __init__(self, core_app, raw_extended_net=None):
@@ -1740,8 +1740,11 @@ class EDBPadstackInstance(Connectable):
1740
1740
  hole_diam = 0
1741
1741
  try: # pragma no cover
1742
1742
  hole_diam = padstack_def.hole_properties[0]
1743
- except: # pragma no cover
1744
- pass
1743
+ except Exception as e: # pragma no cover
1744
+ self._pedb.logger.error(
1745
+ f"Failed to access first element of hole_properties attribute of object "
1746
+ f"{padstack_def} - Hole diameter is set to default value 0 - {type(e).__name__}: {str(e)}"
1747
+ )
1745
1748
  if hole_diam: # pragma no cover
1746
1749
  hole_finished_size = padstack_def.hole_finished_size
1747
1750
  via_length = (
@@ -49,36 +49,11 @@ class GapPort(EdgeTerminal):
49
49
  def __init__(self, pedb, edb_object):
50
50
  super().__init__(pedb, edb_object)
51
51
 
52
- @property
53
- def magnitude(self):
54
- """Magnitude."""
55
- return self._edb_object.GetSourceAmplitude().ToDouble()
56
-
57
- @property
58
- def source_amplitude(self):
59
- """Property added for grpc compatibility"""
60
- return self.magnitude
61
-
62
- @property
63
- def source_phase(self):
64
- """Property added for grpc compatibility"""
65
- return self.phase
66
-
67
- @property
68
- def phase(self):
69
- """Phase."""
70
- return self._edb_object.GetSourcePhase().ToDouble()
71
-
72
52
  @property
73
53
  def renormalize(self):
74
54
  """Whether renormalize is active."""
75
55
  return self._edb_object.GetPortPostProcessingProp().DoRenormalize
76
56
 
77
- @property
78
- def deembed(self):
79
- """Inductance value of the deembed gap port."""
80
- return self._edb_object.GetPortPostProcessingProp().DoDeembedGapL
81
-
82
57
  @property
83
58
  def renormalize_z0(self):
84
59
  """Renormalize Z0 value (real, imag)."""
@@ -358,9 +358,9 @@ class EDBArcs(object):
358
358
  >>> from pyedb import Edb
359
359
  >>> edb = Edb(myedb, edbversion="2021.2")
360
360
  >>> prim_arcs = edb.modeler.primitives[0].arcs
361
- >>> prim_arcs.center # arc center
362
- >>> prim_arcs.points # arc point list
363
- >>> prim_arcs.mid_point # arc mid point
361
+ >>> prim_arcs.center # arc center
362
+ >>> prim_arcs.points # arc point list
363
+ >>> prim_arcs.mid_point # arc mid point
364
364
  """
365
365
 
366
366
  def __init__(self, app, arc):