pyedb 0.17.0__py3-none-any.whl → 0.19.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 (29) hide show
  1. pyedb/__init__.py +1 -1
  2. pyedb/configuration/cfg_data.py +8 -11
  3. pyedb/configuration/cfg_nets.py +14 -0
  4. pyedb/configuration/cfg_pin_groups.py +57 -20
  5. pyedb/configuration/cfg_ports_sources.py +248 -60
  6. pyedb/configuration/configuration.py +51 -17
  7. pyedb/dotnet/edb.py +92 -28
  8. pyedb/dotnet/edb_core/cell/layout.py +48 -1
  9. pyedb/dotnet/edb_core/cell/terminal/padstack_instance_terminal.py +10 -0
  10. pyedb/dotnet/edb_core/cell/terminal/pingroup_terminal.py +5 -0
  11. pyedb/dotnet/edb_core/cell/terminal/point_terminal.py +0 -11
  12. pyedb/dotnet/edb_core/cell/terminal/terminal.py +35 -1
  13. pyedb/dotnet/edb_core/components.py +74 -18
  14. pyedb/dotnet/edb_core/dotnet/primitive.py +9 -6
  15. pyedb/dotnet/edb_core/edb_data/padstacks_data.py +8 -4
  16. pyedb/dotnet/edb_core/edb_data/ports.py +0 -18
  17. pyedb/dotnet/edb_core/edb_data/primitives_data.py +1 -1
  18. pyedb/dotnet/edb_core/padstack.py +10 -1
  19. pyedb/dotnet/edb_core/sim_setup_data/data/sim_setup_info.py +42 -3
  20. pyedb/dotnet/edb_core/sim_setup_data/data/simulation_settings.py +92 -158
  21. pyedb/dotnet/edb_core/sim_setup_data/data/siw_dc_ir_settings.py +22 -22
  22. pyedb/dotnet/edb_core/sim_setup_data/io/siwave.py +76 -76
  23. pyedb/dotnet/edb_core/utilities/hfss_simulation_setup.py +23 -94
  24. pyedb/dotnet/edb_core/utilities/simulation_setup.py +40 -38
  25. pyedb/dotnet/edb_core/utilities/siwave_simulation_setup.py +26 -17
  26. {pyedb-0.17.0.dist-info → pyedb-0.19.0.dist-info}/METADATA +8 -8
  27. {pyedb-0.17.0.dist-info → pyedb-0.19.0.dist-info}/RECORD +29 -29
  28. {pyedb-0.17.0.dist-info → pyedb-0.19.0.dist-info}/LICENSE +0 -0
  29. {pyedb-0.17.0.dist-info → pyedb-0.19.0.dist-info}/WHEEL +0 -0
@@ -766,20 +766,44 @@ class Components(object):
766
766
  >>> edb.close_edb()
767
767
  """
768
768
 
769
- if isinstance(pins, str) or isinstance(pins, EDBPadstackInstance):
769
+ if isinstance(pins, str):
770
770
  pins = [pins]
771
+ elif isinstance(pins, EDBPadstackInstance):
772
+ pins = [pins.name]
771
773
  if isinstance(reference_pins, str):
772
774
  reference_pins = [reference_pins]
773
- if isinstance(refdes, str) or isinstance(refdes, EDBComponent):
775
+ if isinstance(reference_pins, list):
776
+ _temp = []
777
+ for ref_pin in reference_pins:
778
+ if isinstance(ref_pin, int):
779
+ if ref_pin in self._padstack.instances:
780
+ _temp.append(self._padstack.instances[ref_pin])
781
+ elif isinstance(ref_pin, str):
782
+ if ref_pin in self.instances[refdes].pins:
783
+ _temp.append(self.instances[refdes].pins[ref_pin])
784
+ else:
785
+ p = [pp for pp in list(self._padstack.instances.values()) if pp.name == ref_pin]
786
+ if p:
787
+ _temp.append(p)
788
+ elif isinstance(ref_pin, EDBPadstackInstance):
789
+ _temp.append(ref_pin.name)
790
+ reference_pins = _temp
791
+ elif isinstance(reference_pins, int):
792
+ if reference_pins in self._padstack.instances:
793
+ reference_pins = self._padstack.instances[reference_pins]
794
+ if isinstance(refdes, str):
774
795
  refdes = self.instances[refdes]
796
+ elif isinstance(refdes, self._pedb._edb.Cell.Hierarchy.Component):
797
+ refdes = EDBComponent(self._pedb, refdes)
798
+ refdes_pins = refdes.pins
775
799
  if any(refdes.rlc_values):
776
800
  return self.deactivate_rlc_component(component=refdes, create_circuit_port=True)
777
801
  if len([pin for pin in pins if isinstance(pin, str)]) == len(pins):
778
802
  cmp_pins = []
779
803
  for pin_name in pins:
780
- cmp_pin = [pin for pin in list(refdes.pins.values()) if pin_name == pin.name]
804
+ cmp_pin = [pin for pin in list(refdes_pins.values()) if pin_name == pin.name]
781
805
  if not cmp_pin:
782
- cmp_pin = [pin for pin in list(refdes.pins.values()) if pin_name == pin.name.split("-")[1]]
806
+ cmp_pin = [pin for pin in list(refdes_pins.values()) if pin_name == pin.name.split("-")[1]]
783
807
  if cmp_pin:
784
808
  cmp_pins.append(cmp_pin[0])
785
809
  if not cmp_pins:
@@ -793,15 +817,15 @@ class Components(object):
793
817
  if len([pin for pin in reference_pins if isinstance(pin, str)]) == len(reference_pins):
794
818
  ref_cmp_pins = []
795
819
  for ref_pin_name in reference_pins:
796
- cmp_ref_pin = [pin for pin in list(refdes.pins.values()) if ref_pin_name == pin.name]
797
- if not cmp_ref_pin:
798
- cmp_ref_pin = [pin for pin in list(refdes.pins.values()) if ref_pin_name == pin.name.split("-")[1]]
799
- if cmp_ref_pin:
800
- ref_cmp_pins.append(cmp_ref_pin[0])
820
+ if ref_pin_name in refdes_pins:
821
+ ref_cmp_pins.append(refdes_pins[ref_pin_name])
822
+ elif "-" in ref_pin_name and ref_pin_name.split("-")[1] in refdes_pins:
823
+ ref_cmp_pins.append(refdes_pins[ref_pin_name.split("-")[1]])
801
824
  if not ref_cmp_pins:
802
825
  return
803
826
  reference_pins = ref_cmp_pins
804
- if not len([pin for pin in reference_pins if isinstance(pin, EDBPadstackInstance)]) == len(reference_pins):
827
+ if not reference_pins:
828
+ self._logger.error("No reference pins found.")
805
829
  return
806
830
  if len(pins) > 1:
807
831
  pec_boundary = False
@@ -883,7 +907,7 @@ class Components(object):
883
907
  solder_balls_size : float, optional
884
908
  Solder balls diameter. When provided auto evaluation based on padstack size will be disabled.
885
909
  solder_balls_mid_size : float, optional
886
- Solder balls mid diameter. When provided if value is different than solder balls size, spheroid shape will
910
+ Solder balls mid-diameter. When provided if value is different than solder balls size, spheroid shape will
887
911
  be switched.
888
912
 
889
913
  Returns
@@ -904,11 +928,11 @@ class Components(object):
904
928
  if isinstance(component, str):
905
929
  component = self.instances[component].edbcomponent
906
930
  if not solder_balls_height:
907
- solder_balls_height = self.components[component.GetName()].solder_ball_height
931
+ solder_balls_height = self.instances[component.GetName()].solder_ball_height
908
932
  if not solder_balls_size:
909
- solder_balls_size = self.components[component.GetName()].solder_ball_diameter[0]
933
+ solder_balls_size = self.instances[component.GetName()].solder_ball_diameter[0]
910
934
  if not solder_balls_mid_size:
911
- solder_balls_mid_size = self.components[component.GetName()].solder_ball_diameter[1]
935
+ solder_balls_mid_size = self.instances[component.GetName()].solder_ball_diameter[1]
912
936
  if not isinstance(net_list, list):
913
937
  net_list = [net_list]
914
938
  for net in net_list:
@@ -934,6 +958,18 @@ class Components(object):
934
958
  return False
935
959
  pin_layers = cmp_pins[0].GetPadstackDef().GetData().GetLayerNames()
936
960
  if port_type == SourceType.CoaxPort:
961
+ ref_pins = [
962
+ p
963
+ for p in list(component.LayoutObjs)
964
+ if int(p.GetObjType()) == 1 and p.GetNet().GetName() in reference_net
965
+ ]
966
+ if not ref_pins:
967
+ self._logger.error(
968
+ "No reference pins found on component. You might consider"
969
+ "using Circuit port instead since reference pins can be extended"
970
+ "outside the component automatically when not found."
971
+ )
972
+ return False
937
973
  pad_params = self._padstack.get_pad_parameters(pin=cmp_pins[0], layername=pin_layers[0], pad_type=0)
938
974
  if not pad_params[0] == 7:
939
975
  if not solder_balls_size: # pragma no cover
@@ -981,17 +1017,25 @@ class Components(object):
981
1017
  for p in ref_pins:
982
1018
  if not p.IsLayoutPin():
983
1019
  p.SetIsLayoutPin(True)
984
- if len(ref_pins) == 0:
985
- self._logger.info("No reference pin found on component {}.".format(component.GetName()))
1020
+ if not ref_pins:
1021
+ self._logger.warning("No reference pins found on component, the closest pin will be selected.")
1022
+ do_pingroup = False
986
1023
  if do_pingroup:
987
1024
  if len(ref_pins) == 1:
1025
+ ref_pins.is_pin = True
988
1026
  ref_pin_group_term = self._create_terminal(ref_pins[0])
989
1027
  else:
1028
+ for pin in ref_pins:
1029
+ pin.is_pin = True
990
1030
  ref_pin_group = self.create_pingroup_from_pins(ref_pins)
991
1031
  if not ref_pin_group:
1032
+ self._logger.error(f"Failed to create reference pin group on component {component.GetName()}.")
992
1033
  return False
993
- ref_pin_group_term = self._create_pin_group_terminal(ref_pin_group, isref=True)
1034
+ ref_pin_group_term = self._create_pin_group_terminal(ref_pin_group, isref=False)
994
1035
  if not ref_pin_group_term:
1036
+ self._logger.error(
1037
+ f"Failed to create reference pin group terminal on component {component.GetName()}"
1038
+ )
995
1039
  return False
996
1040
  for net in net_list:
997
1041
  pins = [pin for pin in cmp_pins if pin.GetNet().GetName() == net]
@@ -1013,7 +1057,19 @@ class Components(object):
1013
1057
  for net in net_list:
1014
1058
  pins = [pin for pin in cmp_pins if pin.GetNet().GetName() == net]
1015
1059
  for pin in pins:
1016
- self.create_port_on_pins(component, pin, ref_pins)
1060
+ if ref_pins:
1061
+ self.create_port_on_pins(component, pin, ref_pins)
1062
+ else:
1063
+ _pin = EDBPadstackInstance(pin, self._pedb)
1064
+ ref_pin = _pin.get_reference_pins(
1065
+ reference_net=reference_net[0], max_limit=1, component_only=False, search_radius=3e-3
1066
+ )
1067
+ if ref_pin:
1068
+ self.create_port_on_pins(
1069
+ component,
1070
+ [EDBPadstackInstance(pin, self._pedb).name],
1071
+ [EDBPadstackInstance(ref_pin[0], self._pedb).id],
1072
+ )
1017
1073
  return True
1018
1074
 
1019
1075
  def _create_terminal(self, pin, term_name=None):
@@ -837,9 +837,8 @@ class PathDotNet(PrimitiveDotNet):
837
837
  net = net.api_object
838
838
  width = self._app.edb_api.utility.value(width)
839
839
  if isinstance(points, list):
840
- points = self._app.edb_api.geometry.polygon_data.api_class(
841
- convert_py_list_to_net_list([self._app.geometry.point_data(i) for i in points]), False
842
- )
840
+ points = convert_py_list_to_net_list([self._app.point_data(i[0], i[1]) for i in points])
841
+ points = self._app.edb_api.geometry.polygon_data.dotnetobj(points)
843
842
  return PathDotNet(
844
843
  self._app, self.api.Path.Create(layout, layer, net, width, end_cap1, end_cap2, corner_style, points)
845
844
  )
@@ -847,11 +846,15 @@ class PathDotNet(PrimitiveDotNet):
847
846
  @property
848
847
  def center_line(self):
849
848
  """:class:`PolygonData <ansys.edb.geometry.PolygonData>`: Center line for this Path."""
850
- return self.prim_obj.GetCenterLine()
849
+ edb_center_line = self.prim_obj.GetCenterLine()
850
+ return [[pt.X.ToDouble(), pt.Y.ToDouble()] for pt in list(edb_center_line.Points)]
851
851
 
852
852
  @center_line.setter
853
- def center_line(self, center_line):
854
- self.prim_obj.SetCenterLineMessage(center_line)
853
+ def center_line(self, value):
854
+ if isinstance(value, list):
855
+ points = [self._pedb.point_data(i[0], i[1]) for i in value]
856
+ polygon_data = self._edb.geometry.polygon_data.dotnetobj(convert_py_list_to_net_list(points), False)
857
+ self.prim_obj.SetCenterLine(polygon_data)
855
858
 
856
859
  @property
857
860
  def end_cap_style(self):
@@ -1678,11 +1678,9 @@ class EDBPadstackInstance(Primitive):
1678
1678
  def name(self):
1679
1679
  """Padstack Instance Name. If it is a pin, the syntax will be like in AEDT ComponentName-PinName."""
1680
1680
  if self.is_pin:
1681
- comp_name = self._edb_padstackinstance.GetComponent().GetName()
1682
- pin_name = self._edb_padstackinstance.GetName()
1683
- return "-".join([comp_name, pin_name])
1681
+ return self.aedt_name
1684
1682
  else:
1685
- return self._edb_padstackinstance.GetName()
1683
+ return self.component_pin
1686
1684
 
1687
1685
  @name.setter
1688
1686
  def name(self, value):
@@ -1725,6 +1723,12 @@ class EDBPadstackInstance(Primitive):
1725
1723
  @property
1726
1724
  def pin_number(self):
1727
1725
  """Get pin number."""
1726
+ warnings.warn("`pin_number` is deprecated. Use `component_pin` method instead.", DeprecationWarning)
1727
+ return self.component_pin
1728
+
1729
+ @property
1730
+ def component_pin(self):
1731
+ """Get component pin."""
1728
1732
  return self._edb_padstackinstance.GetName()
1729
1733
 
1730
1734
  @property
@@ -198,24 +198,6 @@ class ExcitationSources(Terminal):
198
198
  def __init__(self, pedb, edb_terminal):
199
199
  Terminal.__init__(self, pedb, edb_terminal)
200
200
 
201
- @property
202
- def magnitude(self):
203
- """Get the magnitude of the source."""
204
- return self._edb_object.GetSourceAmplitude().ToDouble()
205
-
206
- @magnitude.setter
207
- def magnitude(self, value):
208
- self._edb_object.SetSourceAmplitude(self._edb.utility.value(value))
209
-
210
- @property
211
- def phase(self):
212
- """Get the phase of the source."""
213
- return self._edb_object.GetSourcePhase().ToDouble()
214
-
215
- @phase.setter
216
- def phase(self, value):
217
- self._edb_object.SetSourcePhase(self._edb.utility.value(value))
218
-
219
201
 
220
202
  class BundleWavePort(BundleTerminal):
221
203
  """Manages bundle wave port properties.
@@ -631,7 +631,7 @@ class EdbPath(EDBPrimitives, PathDotNet):
631
631
  float
632
632
  Path length in meters.
633
633
  """
634
- center_line_arcs = list(self.center_line.GetArcData())
634
+ center_line_arcs = list(self.api_object.GetCenterLine().GetArcData())
635
635
  path_length = 0.0
636
636
  for arc in center_line_arcs:
637
637
  path_length += arc.GetLength()
@@ -241,6 +241,15 @@ class EdbPadstacks(object):
241
241
  )
242
242
  return padstack_instances
243
243
 
244
+ def find_instance_by_id(self, value: int):
245
+ """Find a padstack instance by database id.
246
+
247
+ Parameters
248
+ ----------
249
+ value : int
250
+ """
251
+ return self._pedb.modeler.find_object_by_id(value)
252
+
244
253
  @property
245
254
  def pins(self):
246
255
  """Dictionary of all pins instances (belonging to component).
@@ -1441,7 +1450,7 @@ class EdbPadstacks(object):
1441
1450
  instances = [inst for inst in instances if inst.component.refdes in refdes]
1442
1451
  if component_pin:
1443
1452
  component_pin = component_pin if isinstance(component_pin, list) else [component_pin]
1444
- instances = [inst for inst in instances if inst.pin_number in component_pin]
1453
+ instances = [inst for inst in instances if inst.component_pin in component_pin]
1445
1454
  return instances
1446
1455
 
1447
1456
  def get_padstack_instance_by_net_name(self, net_name):
@@ -20,6 +20,9 @@
20
20
  # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
21
  # SOFTWARE.
22
22
 
23
+ from pyedb.dotnet.edb_core.sim_setup_data.data.simulation_settings import ( # HFSSSimulationSettings
24
+ HFSSPISimulationSettings,
25
+ )
23
26
  from pyedb.dotnet.edb_core.sim_setup_data.data.sweep_data import SweepData
24
27
 
25
28
 
@@ -58,17 +61,53 @@ class SimSetupInfo:
58
61
  else:
59
62
  self._edb_object = edb_object
60
63
 
64
+ @property
65
+ def name(self):
66
+ return self._edb_object.Name
67
+
68
+ @name.setter
69
+ def name(self, name):
70
+ self._edb_object.Name = name
71
+
61
72
  @property
62
73
  def position(self):
63
74
  return self._edb_object.Position
64
75
 
65
76
  @property
66
77
  def sim_setup_type(self):
67
- return self._edb_object.SimSetupType
78
+ """
79
+ "kHFSS": self._pedb.simsetupdata.HFSSSimulationSettings,
80
+ "kPEM": None,
81
+ "kSIwave": self._pedb.simsetupdata.SIwave.SIWSimulationSettings,
82
+ "kLNA": None,
83
+ "kTransient": None,
84
+ "kQEye": None,
85
+ "kVEye": None,
86
+ "kAMI": None,
87
+ "kAnalysisOption": None,
88
+ "kSIwaveDCIR": self._pedb.simsetupdata.SIwave.SIWDCIRSimulationSettings,
89
+ "kSIwaveEMI": None,
90
+ "kHFSSPI": self._pedb.simsetupdata.HFSSPISimulationSettings,
91
+ "kDDRwizard": None,
92
+ "kQ3D": None,
93
+ "kNumSetupTypes": None,
94
+ """
95
+
96
+ return self._edb_object.SimSetupType.ToString()
68
97
 
69
98
  @property
70
99
  def simulation_settings(self):
71
- return self._edb_object.SimulationSettings
100
+ if self.sim_setup_type == "kHFSS":
101
+ return self._edb_object.SimulationSettings
102
+ # todo refactor HFSS
103
+ # return HFSSSimulationSettings(self._pedb, self.sim_setup, self._edb_object.SimulationSettings)
104
+ elif self.sim_setup_type == "kHFSSPI":
105
+ return HFSSPISimulationSettings(self._pedb, self.sim_setup, self._edb_object.SimulationSettings)
106
+ elif self.sim_setup_type == "kSIwave": # todo refactor
107
+ return self._edb_object.SimulationSettings
108
+
109
+ elif self.sim_setup_type == "kSIwaveDCIR": # todo refactor
110
+ return self._edb_object.SimulationSettings
72
111
 
73
112
  @property
74
113
  def sweep_data_list(self):
@@ -77,5 +116,5 @@ class SimSetupInfo:
77
116
  ]
78
117
 
79
118
  def add_sweep_data(self, sweep_data):
80
- sweep_data.sim_setup = self.sim_setup
119
+ sweep_data._sim_setup = self.sim_setup
81
120
  self._edb_object.SweepDataList.Add(sweep_data._edb_object)