pyedb 0.10.0__py3-none-any.whl → 0.11.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 (36) hide show
  1. pyedb/__init__.py +1 -1
  2. pyedb/configuration/cfg_boundaries.py +115 -0
  3. pyedb/configuration/cfg_components.py +205 -0
  4. pyedb/configuration/cfg_data.py +38 -15
  5. pyedb/configuration/cfg_general.py +34 -0
  6. pyedb/{dotnet/sim_setup_data/data/siw_dc_ir_settings.py → configuration/cfg_nets.py} +18 -21
  7. pyedb/configuration/cfg_padstacks.py +125 -0
  8. pyedb/configuration/cfg_pin_groups.py +58 -0
  9. pyedb/configuration/cfg_ports_sources.py +164 -0
  10. pyedb/configuration/cfg_s_parameter_models.py +60 -0
  11. pyedb/configuration/cfg_setup.py +201 -0
  12. pyedb/configuration/cfg_spice_models.py +49 -0
  13. pyedb/configuration/configuration.py +37 -532
  14. pyedb/dotnet/edb.py +32 -4
  15. pyedb/dotnet/edb_core/components.py +43 -0
  16. pyedb/dotnet/edb_core/edb_data/hfss_pi_simulation_setup_data.py +465 -0
  17. pyedb/dotnet/edb_core/edb_data/padstacks_data.py +17 -1
  18. pyedb/dotnet/edb_core/edb_data/raptor_x_simulation_setup_data.py +0 -4
  19. pyedb/dotnet/edb_core/edb_data/siwave_simulation_setup_data.py +4 -2
  20. pyedb/dotnet/edb_core/edb_data/sources.py +21 -5
  21. pyedb/dotnet/edb_core/edb_data/terminals.py +2 -1
  22. pyedb/dotnet/edb_core/layout.py +13 -8
  23. pyedb/dotnet/edb_core/padstack.py +23 -3
  24. pyedb/dotnet/edb_core/sim_setup_data/__init__.py +3 -0
  25. pyedb/dotnet/edb_core/sim_setup_data/data/__init__.py +3 -0
  26. pyedb/dotnet/edb_core/sim_setup_data/data/siw_dc_ir_settings.py +235 -0
  27. pyedb/dotnet/edb_core/siwave.py +2 -1
  28. pyedb/dotnet/edb_core/stackup.py +38 -29
  29. pyedb/dotnet/edb_core/utilities/simulation_setup.py +16 -7
  30. pyedb/siwave.py +32 -6
  31. pyedb/siwave_core/icepak.py +153 -0
  32. {pyedb-0.10.0.dist-info → pyedb-0.11.0.dist-info}/METADATA +2 -2
  33. {pyedb-0.10.0.dist-info → pyedb-0.11.0.dist-info}/RECORD +35 -22
  34. pyedb/configuration/cfg_ports.py +0 -149
  35. {pyedb-0.10.0.dist-info → pyedb-0.11.0.dist-info}/LICENSE +0 -0
  36. {pyedb-0.10.0.dist-info → pyedb-0.11.0.dist-info}/WHEEL +0 -0
@@ -309,13 +309,18 @@ class PinGroup(object):
309
309
  @pyedb_function_handler
310
310
  def get_terminal(self, name=None, create_new_terminal=False):
311
311
  """Terminal."""
312
-
312
+ warnings.warn("Use new property :func:`terminal` instead.", DeprecationWarning)
313
313
  if create_new_terminal:
314
314
  term = self._create_terminal(name)
315
315
  else:
316
- from pyedb.dotnet.edb_core.edb_data.terminals import PinGroupTerminal
316
+ return self.terminal
317
+
318
+ @property
319
+ def terminal(self):
320
+ """Terminal."""
321
+ from pyedb.dotnet.edb_core.edb_data.terminals import PinGroupTerminal
317
322
 
318
- term = PinGroupTerminal(self._pedb, self._edb_pin_group.GetPinGroupTerminal())
323
+ term = PinGroupTerminal(self._pedb, self._edb_pin_group.GetPinGroupTerminal())
319
324
  return term if not term.is_null else None
320
325
 
321
326
  @pyedb_function_handler()
@@ -332,17 +337,28 @@ class PinGroup(object):
332
337
  -------
333
338
  :class:`pyedb.dotnet.edb_core.edb_data.terminals.PinGroupTerminal`
334
339
  """
340
+ warnings.warn("`_create_terminal` is deprecated. Use `create_terminal` instead.", DeprecationWarning)
341
+
335
342
  terminal = self.get_terminal()
336
343
  if terminal:
337
344
  return terminal
345
+ else:
346
+ return self.create_terminal(name)
338
347
 
348
+ @pyedb_function_handler()
349
+ def create_terminal(self, name=None):
350
+ """Create a terminal.
351
+
352
+ Parameters
353
+ ----------
354
+ name : str, optional
355
+ Name of the terminal.
356
+ """
339
357
  if not name:
340
358
  name = generate_unique_name(self.name)
341
-
342
359
  from pyedb.dotnet.edb_core.edb_data.terminals import PinGroupTerminal
343
360
 
344
361
  term = PinGroupTerminal(self._pedb)
345
-
346
362
  term = term.create(name, self.net_name, self.name)
347
363
  return term
348
364
 
@@ -643,9 +643,10 @@ class PinGroupTerminal(Terminal):
643
643
  -------
644
644
  :class:`pyedb.dotnet.edb_core.edb_data.terminals.PinGroupTerminal`
645
645
  """
646
+ net_obj = self._pedb.edb_api.cell.net.find_by_name(self._pedb.active_layout, net_name)
646
647
  term = self._pedb.edb_api.cell.terminal.PinGroupTerminal.Create(
647
648
  self._pedb.active_layout,
648
- self._pedb.nets[net_name].net_object,
649
+ net_obj.api_object,
649
650
  name,
650
651
  self._pedb.siwave.pin_groups[pin_group_name]._edb_object,
651
652
  is_ref,
@@ -152,10 +152,12 @@ class EdbLayout(object):
152
152
  for lay in self.layers:
153
153
  _primitives_by_layer[lay] = []
154
154
  for i in self._layout.primitives:
155
- lay = i.GetLayer().GetName()
156
- if not lay:
155
+ try:
156
+ lay = i.GetLayer().GetName()
157
+ _primitives_by_layer[lay].append(cast(i, self._pedb))
158
+ except:
159
+ self._logger.warning(f"Failed to get layer on primitive {i.id}, skipping.")
157
160
  continue
158
- _primitives_by_layer[lay].append(cast(i, self._pedb))
159
161
  return _primitives_by_layer
160
162
 
161
163
  @property
@@ -233,11 +235,14 @@ class EdbLayout(object):
233
235
  """
234
236
  objinst = []
235
237
  for el in self.polygons:
236
- if el.GetLayer().GetName() == layer_name:
237
- if net_list and el.GetNet().GetName() in net_list:
238
- objinst.append(el)
239
- else:
240
- objinst.append(el)
238
+ try:
239
+ if el.GetLayer().GetName() == layer_name:
240
+ if net_list and el.GetNet().GetName() in net_list:
241
+ objinst.append(el)
242
+ else:
243
+ objinst.append(el)
244
+ except:
245
+ self._logger.warning(f"Failed to retrieve layer on polygon {el.id}")
241
246
  return objinst
242
247
 
243
248
  @pyedb_function_handler()
@@ -236,7 +236,7 @@ class EdbPadstacks(object):
236
236
 
237
237
  """
238
238
  padstack_instances = {}
239
- for _, edb_padstack_instance in self._pedb.padstacks.instances.items():
239
+ for _, edb_padstack_instance in self.instances.items():
240
240
  if edb_padstack_instance.aedt_name:
241
241
  padstack_instances[edb_padstack_instance.aedt_name] = EDBPadstackInstance(
242
242
  edb_padstack_instance, self._pedb
@@ -1353,7 +1353,15 @@ class EdbPadstacks(object):
1353
1353
  return True
1354
1354
 
1355
1355
  @pyedb_function_handler()
1356
- def get_instances(self, name=None, pid=None, definition_name=None, net_name=None):
1356
+ def get_instances(
1357
+ self,
1358
+ name=None,
1359
+ pid=None,
1360
+ definition_name=None,
1361
+ net_name=None,
1362
+ component_reference_designator=None,
1363
+ component_pin=None,
1364
+ ):
1357
1365
  """Get padstack instances by conditions.
1358
1366
 
1359
1367
  Parameters
@@ -1366,7 +1374,8 @@ class EdbPadstacks(object):
1366
1374
  Name of the padstack definition.
1367
1375
  net_name : str, optional
1368
1376
  The net name to be used for filtering padstack instances.
1369
-
1377
+ component_pin: str, optional
1378
+ Pin Number of the component.
1370
1379
  Returns
1371
1380
  -------
1372
1381
  list
@@ -1386,6 +1395,17 @@ class EdbPadstacks(object):
1386
1395
  if net_name:
1387
1396
  net_name = net_name if isinstance(net_name, list) else [net_name]
1388
1397
  instances = [inst for inst in instances if inst.net_name in net_name]
1398
+ if component_reference_designator:
1399
+ refdes = (
1400
+ component_reference_designator
1401
+ if isinstance(component_reference_designator, list)
1402
+ else [component_reference_designator]
1403
+ )
1404
+ instances = [inst for inst in instances if inst.component]
1405
+ instances = [inst for inst in instances if inst.component.refdes in refdes]
1406
+ if component_pin:
1407
+ component_pin = component_pin if isinstance(component_pin, list) else [component_pin]
1408
+ instances = [inst for inst in instances if inst.pin_number in component_pin]
1389
1409
  return instances
1390
1410
 
1391
1411
  @pyedb_function_handler()
@@ -0,0 +1,3 @@
1
+ from pathlib import Path
2
+
3
+ workdir = Path(__file__).parent
@@ -0,0 +1,3 @@
1
+ from pathlib import Path
2
+
3
+ workdir = Path(__file__).parent
@@ -0,0 +1,235 @@
1
+ # Copyright (C) 2023 - 2024 ANSYS, Inc. and/or its affiliates.
2
+ # SPDX-License-Identifier: MIT
3
+ #
4
+ #
5
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ # of this software and associated documentation files (the "Software"), to deal
7
+ # in the Software without restriction, including without limitation the rights
8
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ # copies of the Software, and to permit persons to whom the Software is
10
+ # furnished to do so, subject to the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be included in all
13
+ # copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ # SOFTWARE.
22
+
23
+ from pyedb.dotnet.edb_core.general import (
24
+ convert_netdict_to_pydict,
25
+ convert_pydict_to_netdict,
26
+ )
27
+
28
+
29
+ class SiwaveDCIRSettings:
30
+ """Class for DC IR settings."""
31
+
32
+ def __init__(self, parent):
33
+ self._parent = parent
34
+
35
+ @property
36
+ def export_dc_thermal_data(self):
37
+ """Export DC Thermal Data.
38
+
39
+ Returns
40
+ -------
41
+ bool
42
+ ``True`` when activated, ``False`` deactivated.
43
+ """
44
+ return self._parent.get_sim_setup_info.SimulationSettings.DCIRSettings.ExportDCThermalData
45
+
46
+ @export_dc_thermal_data.setter
47
+ def export_dc_thermal_data(self, value):
48
+ edb_setup_info = self._parent.get_sim_setup_info
49
+ edb_setup_info.SimulationSettings.DCIRSettings.ExportDCThermalData = value
50
+ self._parent._edb_object = self._parent._set_edb_setup_info(edb_setup_info)
51
+ self._parent._update_setup()
52
+
53
+ @property
54
+ def import_thermal_data(self):
55
+ """Import Thermal Data.
56
+
57
+ Returns
58
+ -------
59
+ bool
60
+ ``True`` when activated, ``False`` deactivated.
61
+ """
62
+ return self._parent.get_sim_setup_info.SimulationSettings.DCIRSettings.ImportThermalData
63
+
64
+ @import_thermal_data.setter
65
+ def import_thermal_data(self, value):
66
+ edb_setup_info = self._parent.get_sim_setup_info
67
+ edb_setup_info.SimulationSettings.DCIRSettings.ImportThermalData = value
68
+ self._parent._edb_object = self._parent._set_edb_setup_info(edb_setup_info)
69
+ self._parent._update_setup()
70
+
71
+ @property
72
+ def dc_report_show_active_devices(self):
73
+ """DC Report Show Active Devices.
74
+
75
+ Returns
76
+ -------
77
+ bool
78
+ ``True`` when activated, ``False`` deactivated.
79
+ """
80
+ return self._parent.get_sim_setup_info.SimulationSettings.DCIRSettings.DCReportShowActiveDevices
81
+
82
+ @dc_report_show_active_devices.setter
83
+ def dc_report_show_active_devices(self, value):
84
+ edb_setup_info = self._parent.get_sim_setup_info
85
+ edb_setup_info.SimulationSettings.DCIRSettings.DCReportShowActiveDevices = value
86
+ self._parent._edb_object = self._parent._set_edb_setup_info(edb_setup_info)
87
+ self._parent._update_setup()
88
+
89
+ @property
90
+ def per_pin_use_pin_format(self):
91
+ """Per Pin Use Pin Format.
92
+
93
+ Returns
94
+ -------
95
+ bool
96
+ ``True`` when activated, ``False`` deactivated.
97
+ """
98
+ return self._parent.get_sim_setup_info.SimulationSettings.DCIRSettings.PerPinUsePinFormat
99
+
100
+ @per_pin_use_pin_format.setter
101
+ def per_pin_use_pin_format(self, value):
102
+ edb_setup_info = self._parent.get_sim_setup_info
103
+ edb_setup_info.SimulationSettings.DCIRSettings.PerPinUsePinFormat = value
104
+ self._parent._edb_object = self._parent._set_edb_setup_info(edb_setup_info)
105
+ self._parent._update_setup()
106
+
107
+ @property
108
+ def use_loop_res_for_per_pin(self):
109
+ """Use loop Res Per Pin.
110
+
111
+ Returns
112
+ -------
113
+ bool
114
+ ``True`` when activated, ``False`` deactivated.
115
+ """
116
+ return self._parent.get_sim_setup_info.SimulationSettings.DCIRSettings.UseLoopResForPerPin
117
+
118
+ @use_loop_res_for_per_pin.setter
119
+ def use_loop_res_for_per_pin(self, value):
120
+ edb_setup_info = self._parent.get_sim_setup_info
121
+ edb_setup_info.SimulationSettings.DCIRSettings.UseLoopResForPerPin = value
122
+ self._parent._edb_object = self._parent._set_edb_setup_info(edb_setup_info)
123
+ self._parent._update_setup()
124
+
125
+ @property
126
+ def dc_report_config_file(self):
127
+ """DC Report Config File.
128
+
129
+ Returns
130
+ -------
131
+ str
132
+ path to the DC report configuration file.
133
+ """
134
+ return self._parent.get_sim_setup_info.SimulationSettings.DCIRSettings.DCReportConfigFile
135
+
136
+ @dc_report_config_file.setter
137
+ def dc_report_config_file(self, value):
138
+ edb_setup_info = self._parent.get_sim_setup_info
139
+ edb_setup_info.SimulationSettings.DCIRSettings.DCReportConfigFile = value
140
+ self._parent._edb_object = self._parent._set_edb_setup_info(edb_setup_info)
141
+ self._parent._update_setup()
142
+
143
+ @property
144
+ def full_dc_report_path(self):
145
+ """Full DC Report Path.
146
+
147
+ Returns
148
+ -------
149
+ str
150
+ full path to the DC report file.
151
+ """
152
+ return self._parent.get_sim_setup_info.SimulationSettings.DCIRSettings.FullDCReportPath
153
+
154
+ @full_dc_report_path.setter
155
+ def full_dc_report_path(self, value):
156
+ edb_setup_info = self._parent.get_sim_setup_info
157
+ edb_setup_info.SimulationSettings.DCIRSettings.FullDCReportPath = value
158
+ self._parent._edb_object = self._parent._set_edb_setup_info(edb_setup_info)
159
+ self._parent._update_setup()
160
+
161
+ @property
162
+ def icepak_temp_file(self):
163
+ """Icepack Temp File.
164
+
165
+ Returns
166
+ -------
167
+ str
168
+ path to the temp Icepak file.
169
+ """
170
+ return self._parent.get_sim_setup_info.SimulationSettings.DCIRSettings.IcepakTempFile
171
+
172
+ @icepak_temp_file.setter
173
+ def icepak_temp_file(self, value):
174
+ edb_setup_info = self._parent.get_sim_setup_info
175
+ edb_setup_info.SimulationSettings.DCIRSettings.IcepakTempFile = value
176
+ self._parent._edb_object = self._parent._set_edb_setup_info(edb_setup_info)
177
+ self._parent._update_setup()
178
+
179
+ @property
180
+ def per_pin_res_path(self):
181
+ """Per Pin Res Path.
182
+
183
+ Returns
184
+ -------
185
+ str
186
+ path for per pin res.
187
+ """
188
+ return self._parent.get_sim_setup_info.SimulationSettings.DCIRSettings.PerPinResPath
189
+
190
+ @per_pin_res_path.setter
191
+ def per_pin_res_path(self, value):
192
+ edb_setup_info = self._parent.get_sim_setup_info
193
+ edb_setup_info.SimulationSettings.DCIRSettings.PerPinResPath = value
194
+ self._parent._edb_object = self._parent._set_edb_setup_info(edb_setup_info)
195
+ self._parent._update_setup()
196
+
197
+ @property
198
+ def via_report_path(self):
199
+ """Via Report Path.
200
+
201
+ Returns
202
+ -------
203
+ str
204
+ path for the Via Report.
205
+ """
206
+ return self._parent.get_sim_setup_info.SimulationSettings.DCIRSettings.ViaReportPath
207
+
208
+ @via_report_path.setter
209
+ def via_report_path(self, value):
210
+ edb_setup_info = self._parent.get_sim_setup_info
211
+ edb_setup_info.SimulationSettings.DCIRSettings.ViaReportPath = value
212
+ self._parent._edb_object = self._parent._set_edb_setup_info(edb_setup_info)
213
+ self._parent._update_setup()
214
+
215
+ @property
216
+ def source_terms_to_ground(self):
217
+ """A dictionary of SourceName, NodeToGround pairs,
218
+ where NodeToGround is one of 0 (unspecified), 1 (negative), 2 (positive).
219
+
220
+
221
+ Returns
222
+ -------
223
+ dict <str, int>
224
+ str: source name,
225
+ int: node to ground pairs, 0 (unspecified), 1 (negative), 2 (positive) .
226
+ """
227
+ temp = self._parent.get_sim_setup_info.SimulationSettings.DCIRSettings.SourceTermsToGround
228
+ return convert_netdict_to_pydict(temp)
229
+
230
+ @source_terms_to_ground.setter
231
+ def source_terms_to_ground(self, value):
232
+ edb_setup_info = self._parent.get_sim_setup_info
233
+ edb_setup_info.SimulationSettings.DCIRSettings.SourceTermsToGround = convert_pydict_to_netdict(value)
234
+ self._parent._edb_object = self._parent._set_edb_setup_info(edb_setup_info)
235
+ self._parent._update_setup()
@@ -1261,7 +1261,8 @@ class EdbSiwave(object):
1261
1261
  if edb_pingroup.IsNull(): # pragma: no cover
1262
1262
  return False
1263
1263
  else:
1264
- edb_pingroup.SetNet(pins[0].GetNet())
1264
+ names = [i for i in pins if i.GetNet().GetName()]
1265
+ edb_pingroup.SetNet(names[0].GetNet())
1265
1266
  return group_name, self.pin_groups[group_name]
1266
1267
 
1267
1268
  @pyedb_function_handler()
@@ -73,11 +73,12 @@ class LayerCollection(object):
73
73
 
74
74
  def __init__(self, pedb, edb_object=None):
75
75
  self._pedb = pedb
76
- self._edb_object = (
77
- self._pedb.edb_api.cell._cell.LayerCollection(edb_object)
78
- if edb_object
79
- else self._pedb.edb_api.cell._cell.LayerCollection()
80
- )
76
+
77
+ if edb_object:
78
+ self._edb_object = self._pedb.edb_api.cell._cell.LayerCollection(edb_object)
79
+ else:
80
+ self._edb_object = self._pedb.edb_api.cell._cell.LayerCollection()
81
+
81
82
  self._layer_type_set_mapping = {
82
83
  "stackup_layer_set": self._pedb.edb_api.cell.layer_type_set.StackupLayerSet,
83
84
  "signal_ayer_et": self._pedb.edb_api.cell.layer_type_set.SignalLayerSet,
@@ -304,6 +305,24 @@ class LayerCollection(object):
304
305
  temp.append([obj.id, obj.name])
305
306
  return temp
306
307
 
308
+ @property
309
+ def layers(self):
310
+ """Retrieve the dictionary of layers.
311
+
312
+ Returns
313
+ -------
314
+ Dict[str, :class:`pyedb.dotnet.edb_core.edb_data.layer_data.LayerEdbClass`]
315
+ """
316
+ _lays = OrderedDict()
317
+ layer_list = list(self._edb_object.Layers(self._pedb.edb_api.cell.layer_type_set.AllLayerSet))
318
+ for l in layer_list:
319
+ name = l.GetName()
320
+ if not l.IsStackupLayer():
321
+ _lays[name] = LayerEdbClass(self._pedb, l, name=name)
322
+ else:
323
+ _lays[name] = StackupLayerEdbClass(self._pedb, l, name=name)
324
+ return _lays
325
+
307
326
 
308
327
  class Stackup(LayerCollection):
309
328
  """Manages EDB methods for stackup accessible from `Edb.stackup` property."""
@@ -632,23 +651,6 @@ class Stackup(LayerCollection):
632
651
  layer_list = list(self._layer_collection.Layers(self._pedb.edb_api.cell.layer_type_set.AllLayerSet))
633
652
  return [i.Clone() for i in layer_list]
634
653
 
635
- @property
636
- def layers(self):
637
- """Retrieve the dictionary of layers.
638
-
639
- Returns
640
- -------
641
- Dict[str, :class:`pyedb.dotnet.edb_core.edb_data.layer_data.LayerEdbClass`]
642
- """
643
- _lays = OrderedDict()
644
- for l in self._edb_layer_list:
645
- name = l.GetName()
646
- if not l.IsStackupLayer():
647
- _lays[name] = LayerEdbClass(self._pedb, l, name=name)
648
- else:
649
- _lays[name] = StackupLayerEdbClass(self._pedb, l, name=name)
650
- return _lays
651
-
652
654
  @property
653
655
  def signal_layers(self):
654
656
  """Retrieve the dictionary of signal layers.
@@ -742,8 +744,9 @@ class Stackup(LayerCollection):
742
744
  _lc.AddStackupLayerAtElevation(layer_clone)
743
745
  elif operation == "non_stackup":
744
746
  _lc.AddLayerBottom(layer_clone)
745
- self._pedb.layout.layer_collection = _lc
746
- self.refresh_layer_collection()
747
+ if self.auto_refresh:
748
+ self._pedb.layout.layer_collection = _lc
749
+ self.refresh_layer_collection()
747
750
  return True
748
751
 
749
752
  @pyedb_function_handler()
@@ -1042,11 +1045,15 @@ class Stackup(LayerCollection):
1042
1045
  def _export_layer_stackup_to_json(self, output_file=None, include_material_with_layer=False):
1043
1046
  if not include_material_with_layer:
1044
1047
  material_out = {}
1045
- for k, v in self._pedb.materials.materials.items():
1046
- material_out[k] = v._json_format()
1048
+ for material_name, material in self._pedb.materials.materials.items():
1049
+ material_out[material_name] = material.to_dict()
1047
1050
  layers_out = {}
1048
1051
  for k, v in self.stackup_layers.items():
1049
- layers_out[k] = v._json_format()
1052
+ data = v._json_format()
1053
+ # FIXME: Update the API to avoid providing following information to our users
1054
+ del data["pedb"]
1055
+ del data["edb_object"]
1056
+ layers_out[k] = data
1050
1057
  if v.material in self._pedb.materials.materials:
1051
1058
  layer_material = self._pedb.materials.materials[v.material]
1052
1059
  if not v.dielectric_fill:
@@ -1054,9 +1061,9 @@ class Stackup(LayerCollection):
1054
1061
  else:
1055
1062
  dielectric_fill = self._pedb.materials.materials[v.dielectric_fill]
1056
1063
  if include_material_with_layer:
1057
- layers_out[k]["material"] = layer_material._json_format()
1064
+ layers_out[k]["material"] = layer_material.to_dict()
1058
1065
  if dielectric_fill:
1059
- layers_out[k]["dielectric_fill"] = dielectric_fill._json_format()
1066
+ layers_out[k]["dielectric_fill"] = dielectric_fill.to_dict()
1060
1067
  if not include_material_with_layer:
1061
1068
  stackup_out = {"materials": material_out, "layers": layers_out}
1062
1069
  else:
@@ -2345,6 +2352,8 @@ class Stackup(LayerCollection):
2345
2352
  for i in temp_dict.keys():
2346
2353
  value = temp.get(i, None)
2347
2354
  if value:
2355
+ if i == "Thickness":
2356
+ value = str(round(float(value), 6)) + length_unit
2348
2357
  value = "signal" if value == "conductor" else value
2349
2358
  if i == "Color":
2350
2359
  value = [int(x * 255) for x in list(colors.to_rgb(value))]
@@ -57,6 +57,7 @@ class BaseSimulationSetup(object):
57
57
  "kQ3D": None,
58
58
  "kNumSetupTypes": None,
59
59
  "kRaptorX": self._pedb.simsetupdata.RaptorX.RaptorXSimulationSettings,
60
+ "kHFSSPI": self._pedb.simsetupdata.HFSSPISimulationSettings,
60
61
  }
61
62
  if self._edb_object:
62
63
  self._name = self._edb_object.GetName()
@@ -73,7 +74,10 @@ class BaseSimulationSetup(object):
73
74
  setup_type = self._setup_type_mapping[self._setup_type]
74
75
  edb_setup_info = self._pedb.simsetupdata.SimSetupInfo[setup_type]()
75
76
  edb_setup_info.Name = name
76
- if edb_setup_info.get_SimSetupType().ToString() == "kRaptorX":
77
+ if (
78
+ edb_setup_info.get_SimSetupType().ToString() == "kRaptorX"
79
+ or edb_setup_info.get_SimSetupType().ToString() == "kHFSSPI"
80
+ ):
77
81
  self._edb_setup_info = edb_setup_info
78
82
  self._edb_object = self._set_edb_setup_info(edb_setup_info)
79
83
  self._update_setup()
@@ -99,9 +103,10 @@ class BaseSimulationSetup(object):
99
103
  "kQ3D": None,
100
104
  "kNumSetupTypes": None,
101
105
  }
102
- version = self._pedb.edbversion.split(".")
103
- if int(version[0]) == 2024 and int(version[1]) == 2 or int(version[0]) > 2024:
104
- setup_type_mapping["kRaptorX"] = utility.RaptorXSimulationSetup
106
+ if self._pedb.edbversion:
107
+ version = self._pedb.edbversion.split(".")
108
+ if int(version[0]) == 2024 and int(version[1]) == 2 or int(version[0]) > 2024:
109
+ setup_type_mapping["kRaptorX"] = utility.RaptorXSimulationSetup
105
110
  setup_utility = setup_type_mapping[self._setup_type]
106
111
  return setup_utility(edb_setup_info)
107
112
 
@@ -167,7 +172,11 @@ class BaseSimulationSetup(object):
167
172
  def frequency_sweeps(self):
168
173
  """List of frequency sweeps."""
169
174
  temp = {}
170
- for i in list(self.get_sim_setup_info.SweepDataList):
175
+ if self.setup_type in ("kRaptorX", "kHFSSPI"):
176
+ sweep_data_list = self._edb_setup_info.SweepDataList
177
+ else:
178
+ sweep_data_list = self.get_sim_setup_info.SweepDataList
179
+ for i in list(sweep_data_list):
171
180
  temp[i.Name] = EdbFrequencySweep(self, None, i.Name, i)
172
181
  return temp
173
182
 
@@ -180,12 +189,12 @@ class BaseSimulationSetup(object):
180
189
  sweep_data: EdbFrequencySweep
181
190
  """
182
191
  self._sweep_list[sweep_data.name] = sweep_data
183
- if self.setup_type == "kRaptorX":
192
+ if self.setup_type in ["kRaptorX", "kHFSSPI"]:
184
193
  edb_setup_info = self._edb_setup_info
185
194
  else:
186
195
  edb_setup_info = self.get_sim_setup_info
187
196
 
188
- if self._setup_type in ["kSIwave", "kHFSS", "kRaptorX"]:
197
+ if self._setup_type in ["kSIwave", "kHFSS", "kRaptorX", "kHFSSPI"]:
189
198
  for _, v in self._sweep_list.items():
190
199
  edb_setup_info.SweepDataList.Add(v._edb_object)
191
200
 
pyedb/siwave.py CHANGED
@@ -11,7 +11,7 @@ from __future__ import absolute_import # noreorder
11
11
  import os
12
12
  import pkgutil
13
13
  import sys
14
- import time
14
+ import warnings
15
15
 
16
16
  from pyedb.dotnet.clr_module import _clr
17
17
  from pyedb.edb_logger import pyedb_logger
@@ -22,6 +22,7 @@ from pyedb.generic.general_methods import (
22
22
  pyedb_function_handler,
23
23
  )
24
24
  from pyedb.misc.misc import list_installed_ansysem
25
+ from pyedb.siwave_core.icepak import Icepak
25
26
 
26
27
 
27
28
  class Siwave(object): # pragma no cover
@@ -215,6 +216,10 @@ class Siwave(object): # pragma no cover
215
216
  """Project."""
216
217
  return self._oproject
217
218
 
219
+ @property
220
+ def icepak(self):
221
+ return Icepak(self)
222
+
218
223
  @pyedb_function_handler()
219
224
  def open_project(self, proj_path=None):
220
225
  """Open a project.
@@ -334,17 +339,38 @@ class Siwave(object): # pragma no cover
334
339
  bool
335
340
  ``True`` when successful, ``False`` when failed.
336
341
 
342
+ """
343
+ warnings.warn("Use new property :func:`export_dc_simulation_report` instead.", DeprecationWarning)
344
+ return self.export_dc_simulation_report(simulation_name, file_path, bkground_color)
345
+
346
+ @pyedb_function_handler()
347
+ def export_dc_simulation_report(self, simulation_name, file_path, background_color="White"):
348
+ """Export the Siwave DC simulation report.
349
+
350
+ Parameters
351
+ ----------
352
+ simulation_name : str
353
+ Name of the setup.
354
+ file_path : str
355
+ Path to the exported report.
356
+ background_color : str, optional
357
+ Color of the report's background. The default is ``"White"``.
358
+
359
+ Returns
360
+ -------
361
+ bool
362
+ ``True`` when successful, ``False`` when failed.
363
+
337
364
  """
338
365
  self.oproject.ScrExportDcSimReportScaling("All", "All", -1, -1, False)
339
- self.oproject.ScrExportDcSimReport(simulation_name, bkground_color, file_path)
340
- while not os.path.exists(file_path):
341
- time.sleep(0.1)
342
- return True
366
+ flag = self.oproject.ScrExportDcSimReport(simulation_name, background_color, file_path)
367
+ return True if flag == 0 else False
343
368
 
344
369
  @pyedb_function_handler
345
- def run_dc_simulation(self):
370
+ def run_dc_simulation(self, export_dc_power_data_to_icepak=False):
346
371
  """Run DC simulation."""
347
372
  self._logger.info("Running DC simulation.")
373
+ self.oproject.ScrExportDcPowerDataToIcepak(export_dc_power_data_to_icepak)
348
374
  return self.oproject.ScrRunDcSimulation(1)
349
375
 
350
376
  @pyedb_function_handler