pyedb 0.18.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 +2 -1
  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.18.0.dist-info → pyedb-0.19.0.dist-info}/METADATA +8 -8
  27. {pyedb-0.18.0.dist-info → pyedb-0.19.0.dist-info}/RECORD +29 -29
  28. {pyedb-0.18.0.dist-info → pyedb-0.19.0.dist-info}/LICENSE +0 -0
  29. {pyedb-0.18.0.dist-info → pyedb-0.19.0.dist-info}/WHEEL +0 -0
@@ -65,14 +65,16 @@ class Configuration:
65
65
  """
66
66
  if isinstance(config_file, dict):
67
67
  data = config_file
68
- elif os.path.isfile(config_file):
69
- with open(config_file, "r") as f:
70
- if config_file.endswith(".json"):
71
- data = json.load(f)
72
- elif config_file.endswith(".toml"):
73
- data = toml.load(f)
74
- else: # pragma: no cover
75
- return False
68
+ else:
69
+ config_file = str(config_file)
70
+ if os.path.isfile(config_file):
71
+ with open(config_file, "r") as f:
72
+ if config_file.endswith(".json"):
73
+ data = json.load(f)
74
+ elif config_file.endswith(".toml"):
75
+ data = toml.load(f)
76
+ else: # pragma: no cover
77
+ return False
76
78
 
77
79
  if not append: # pragma: no cover
78
80
  self.data = {}
@@ -120,16 +122,13 @@ class Configuration:
120
122
  self.cfg_data.padstacks.apply()
121
123
 
122
124
  # Configure pin groups
123
- for pin_group in self.cfg_data.pin_groups:
124
- pin_group.apply()
125
+ self.cfg_data.pin_groups.apply()
125
126
 
126
127
  # Configure ports
127
- for port in self.cfg_data.ports:
128
- port.create()
128
+ self.cfg_data.ports.apply()
129
129
 
130
130
  # Configure sources
131
- for source in self.cfg_data.sources:
132
- source.create()
131
+ self.cfg_data.sources.apply()
133
132
 
134
133
  # Configure setup
135
134
  self.cfg_data.setups.apply()
@@ -271,12 +270,30 @@ class Configuration:
271
270
  data["package_definitions"] = self.cfg_data.package_definitions.get_data_from_db()
272
271
  if kwargs.get("setups", False):
273
272
  data["setups"] = self.cfg_data.setups.get_data_from_db()
273
+ if kwargs.get("sources", False):
274
+ data["sources"] = self.cfg_data.sources.get_data_from_db()
275
+ if kwargs.get("ports", False):
276
+ data["ports"] = self.cfg_data.ports.get_data_from_db()
274
277
  if kwargs.get("components", False):
275
278
  data["components"] = self.cfg_data.components.get_data_from_db()
279
+ if kwargs.get("nets", False):
280
+ data["nets"] = self.cfg_data.nets.get_data_from_db()
281
+ if kwargs.get("pin_groups", False):
282
+ data["pin_groups"] = self.cfg_data.pin_groups.get_data_from_db()
276
283
 
277
284
  return data
278
285
 
279
- def export(self, file_path, stackup=True, package_definitions=True, setups=True):
286
+ def export(
287
+ self,
288
+ file_path,
289
+ stackup=True,
290
+ package_definitions=True,
291
+ setups=True,
292
+ sources=True,
293
+ ports=True,
294
+ nets=True,
295
+ pin_groups=True,
296
+ ):
280
297
  """Export the configuration data from layout to a file.
281
298
 
282
299
  Parameters
@@ -285,14 +302,31 @@ class Configuration:
285
302
  File path to export the configuration data.
286
303
  stackup : bool
287
304
  Whether to export stackup or not.
288
-
305
+ package_definitions : bool
306
+ Whether to export package definitions or not.
307
+ setups : bool
308
+ Whether to export setups or not.
309
+ sources : bool
310
+ Whether to export sources or not.
311
+ ports : bool
312
+ Whether to export ports or not.
313
+ nets : bool
314
+ Whether to export nets.
289
315
  Returns
290
316
  -------
291
317
  bool
292
318
  """
293
319
  file_path = file_path if isinstance(file_path, Path) else Path(file_path)
294
320
  file_path = file_path if file_path.suffix == ".json" else file_path.with_suffix(".json")
295
- data = self.get_data_from_db(stackup=stackup, package_definitions=package_definitions, setups=setups)
321
+ data = self.get_data_from_db(
322
+ stackup=stackup,
323
+ package_definitions=package_definitions,
324
+ setups=setups,
325
+ sources=sources,
326
+ ports=ports,
327
+ nets=nets,
328
+ pin_groups=pin_groups,
329
+ )
296
330
  with open(file_path, "w") as f:
297
331
  json.dump(data, f, ensure_ascii=False, indent=4)
298
332
  return True if os.path.isfile(file_path) else False
pyedb/dotnet/edb.py CHANGED
@@ -510,6 +510,7 @@ class Edb(Database):
510
510
  def sources(self):
511
511
  """Get all layout sources."""
512
512
  terms = [term for term in self.layout.terminals if int(term.GetBoundaryType()) in [3, 4, 7]]
513
+ terms = [term for term in terms if not term.IsReferenceTerminal()]
513
514
  return {ter.GetName(): ExcitationSources(self, ter) for ter in terms}
514
515
 
515
516
  @property
@@ -3743,7 +3744,7 @@ class Edb(Database):
3743
3744
  if float(self.edbversion) < 2024.2:
3744
3745
  self.logger.error("HFSSPI simulation only supported with Ansys release 2024R2 and higher")
3745
3746
  return False
3746
- return HFSSPISimulationSetup(self).create(name)
3747
+ return HFSSPISimulationSetup(self, name=name)
3747
3748
 
3748
3749
  def create_siwave_syz_setup(self, name=None, **kwargs):
3749
3750
  """Create a setup from a template.
@@ -23,9 +23,11 @@
23
23
  """
24
24
  This module contains these classes: `EdbLayout` and `Shape`.
25
25
  """
26
-
27
26
  from pyedb.dotnet.edb_core.cell.primitive import Bondwire
28
27
  from pyedb.dotnet.edb_core.edb_data.nets_data import EDBNetsData
28
+ from pyedb.dotnet.edb_core.edb_data.padstacks_data import EDBPadstackInstance
29
+ from pyedb.dotnet.edb_core.edb_data.sources import PinGroup
30
+ from pyedb.dotnet.edb_core.general import convert_py_list_to_net_list
29
31
  from pyedb.dotnet.edb_core.layout import EdbLayout
30
32
 
31
33
 
@@ -65,6 +67,11 @@ class Layout(EdbLayout):
65
67
  if i.GetPrimitiveType().ToString() == "Bondwire"
66
68
  ]
67
69
 
70
+ @property
71
+ def padstack_instances(self):
72
+ """Get all padstack instances in a list."""
73
+ return [EDBPadstackInstance(i, self._pedb) for i in self._edb_object.PadstackInstances]
74
+
68
75
  def create_bondwire(
69
76
  self,
70
77
  definition_name,
@@ -129,3 +136,43 @@ class Layout(EdbLayout):
129
136
  end_y=self._pedb.edb_value(end_y),
130
137
  net=self.nets[net]._edb_object,
131
138
  )
139
+
140
+ def find_object_by_id(self, value: int):
141
+ """Find a Connectable object by Database ID.
142
+
143
+ Parameters
144
+ ----------
145
+ value : int
146
+ """
147
+ obj = self._pedb._edb.Cell.Connectable.FindById(self._edb_object, value)
148
+ if obj.GetObjType().ToString() == "PadstackInstance":
149
+ return EDBPadstackInstance(obj, self._pedb)
150
+
151
+ def create_pin_group(self, name: str, pins_by_id: list[int] = None, pins_by_aedt_name: list[str] = None):
152
+ """Create a PinGroup.
153
+
154
+ Parameters
155
+ name : str,
156
+ Name of the PinGroup.
157
+ pins_by_id : list[int] or None
158
+ List of pins by ID.
159
+ pins_by_aedt_name : list[str] or None
160
+ List of pins by AEDT name.
161
+ """
162
+ pins = []
163
+
164
+ if pins_by_id is not None:
165
+ for p in pins_by_id:
166
+ pins.append(self.find_object_by_id(p._edb_object))
167
+ else:
168
+ p_inst = self.padstack_instances
169
+ while True:
170
+ p = p_inst.pop(0)
171
+ if p.aedt_name in pins_by_aedt_name:
172
+ pins.append(p._edb_object)
173
+ pins_by_aedt_name.remove(p.aedt_name)
174
+ if len(pins_by_aedt_name) == 0:
175
+ break
176
+
177
+ obj = self._edb.cell.hierarchy.pin_group.Create(self._edb_object, name, convert_py_list_to_net_list(pins))
178
+ return PinGroup(name, obj, self._pedb)
@@ -86,3 +86,13 @@ class PadstackInstanceTerminal(Terminal):
86
86
  terminal = PadstackInstanceTerminal(self._pedb, terminal)
87
87
 
88
88
  return terminal if not terminal.is_null else False
89
+
90
+ def _get_parameters(self):
91
+ """Gets the parameters of the padstack instance terminal."""
92
+ _, padstack_inst, layer_obj = self._edb_object.GetParameters()
93
+ return padstack_inst, layer_obj
94
+
95
+ @property
96
+ def padstack_instance(self):
97
+ p_inst, _ = self._get_parameters()
98
+ return self._pedb.modeler.find_object_by_id(p_inst.GetId())
@@ -57,3 +57,8 @@ class PinGroupTerminal(Terminal):
57
57
  )
58
58
  term = PinGroupTerminal(self._pedb, term)
59
59
  return term if not term.is_null else False
60
+
61
+ def pin_group(self):
62
+ """Gets the pin group the terminal refers to."""
63
+ name = self._edb_object.GetPinGroup().GetName()
64
+ return self._pedb.siwave.pin_groups[name]
@@ -60,14 +60,3 @@ class PointTerminal(Terminal):
60
60
  )
61
61
  terminal = PointTerminal(self._pedb, terminal)
62
62
  return terminal if not terminal.is_null else False
63
-
64
- @property
65
- def ref_terminal(self):
66
- """Get reference terminal."""
67
-
68
- terminal = Terminal(self._pedb, self._edb_object.GetReferenceTerminal())
69
- return terminal if not terminal.is_null else False
70
-
71
- @ref_terminal.setter
72
- def ref_terminal(self, value):
73
- self._edb_object.SetReferenceTerminal(value._edb_object)
@@ -217,6 +217,21 @@ class Terminal(Connectable):
217
217
  def boundary_type(self, value):
218
218
  self._edb_object.SetBoundaryType(self._boundary_type_mapping[value])
219
219
 
220
+ @property
221
+ def is_port(self):
222
+ """Whether it is a port."""
223
+ return True if self.boundary_type == "PortBoundary" else False
224
+
225
+ @property
226
+ def is_current_source(self):
227
+ """Whether it is a current source."""
228
+ return True if self.boundary_type == "kCurrentSource" else False
229
+
230
+ @property
231
+ def is_voltage_source(self):
232
+ """Whether it is a voltage source."""
233
+ return True if self.boundary_type == "kVoltageSource" else False
234
+
220
235
  @property
221
236
  def impedance(self):
222
237
  """Impedance of the port."""
@@ -235,7 +250,8 @@ class Terminal(Connectable):
235
250
  def ref_terminal(self):
236
251
  """Get reference terminal."""
237
252
 
238
- terminal = Terminal(self._pedb, self._edb_object.GetReferenceTerminal())
253
+ edb_terminal = self._edb_object.GetReferenceTerminal()
254
+ terminal = self._pedb.terminals[edb_terminal.GetName()]
239
255
  if not terminal.is_null:
240
256
  return terminal
241
257
 
@@ -444,3 +460,21 @@ class Terminal(Connectable):
444
460
  pin_obj = pin
445
461
  if pin_obj:
446
462
  return EDBPadstackInstance(pin_obj, self._pedb)
463
+
464
+ @property
465
+ def magnitude(self):
466
+ """Get the magnitude of the source."""
467
+ return self._edb_object.GetSourceAmplitude().ToDouble()
468
+
469
+ @magnitude.setter
470
+ def magnitude(self, value):
471
+ self._edb_object.SetSourceAmplitude(self._edb.utility.value(value))
472
+
473
+ @property
474
+ def phase(self):
475
+ """Get the phase of the source."""
476
+ return self._edb_object.GetSourcePhase().ToDouble()
477
+
478
+ @phase.setter
479
+ def phase(self, value):
480
+ self._edb_object.SetSourcePhase(self._edb.utility.value(value))
@@ -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)