pyedb 0.41.0__py3-none-any.whl → 0.42.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.
- pyedb/__init__.py +1 -1
- pyedb/configuration/cfg_boundaries.py +12 -3
- pyedb/configuration/cfg_components.py +333 -97
- pyedb/configuration/cfg_general.py +6 -4
- pyedb/configuration/cfg_pin_groups.py +18 -8
- pyedb/configuration/cfg_setup.py +139 -65
- pyedb/configuration/configuration.py +26 -11
- pyedb/dotnet/database/cell/terminal/padstack_instance_terminal.py +5 -0
- pyedb/dotnet/database/cell/terminal/point_terminal.py +12 -0
- pyedb/dotnet/database/cell/terminal/terminal.py +0 -14
- pyedb/dotnet/database/dotnet/database.py +2 -0
- pyedb/dotnet/database/siwave.py +4 -1
- pyedb/dotnet/database/utilities/simulation_setup.py +8 -3
- pyedb/dotnet/edb.py +2 -5
- pyedb/grpc/database/components.py +1 -2
- pyedb/grpc/database/hierarchy/component.py +9 -1
- pyedb/grpc/database/hierarchy/s_parameter_model.py +2 -2
- pyedb/grpc/database/hierarchy/spice_model.py +4 -0
- pyedb/grpc/database/utility/hfss_extent_info.py +31 -20
- {pyedb-0.41.0.dist-info → pyedb-0.42.0.dist-info}/METADATA +1 -1
- {pyedb-0.41.0.dist-info → pyedb-0.42.0.dist-info}/RECORD +23 -23
- {pyedb-0.41.0.dist-info → pyedb-0.42.0.dist-info}/LICENSE +0 -0
- {pyedb-0.41.0.dist-info → pyedb-0.42.0.dist-info}/WHEEL +0 -0
pyedb/configuration/cfg_setup.py
CHANGED
|
@@ -53,14 +53,9 @@ class CfgSetup(CfgBase):
|
|
|
53
53
|
def _apply_freq_sweep(self, edb_setup):
|
|
54
54
|
for i in self.freq_sweep:
|
|
55
55
|
f_set = []
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
for f in i.frequencies:
|
|
60
|
-
f_set.append([f.distribution, f.start, f.stop, f.increment])
|
|
61
|
-
else:
|
|
62
|
-
kw[attr] = getattr(i, attr)
|
|
63
|
-
edb_setup.add_sweep(i.name, frequency_set=f_set, **kw)
|
|
56
|
+
for f in i.frequencies:
|
|
57
|
+
f_set.append([f.distribution, f.start, f.stop, f.increment])
|
|
58
|
+
edb_setup.add_sweep(i.name, frequency_set=f_set, sweep_type=i.type)
|
|
64
59
|
|
|
65
60
|
|
|
66
61
|
class CfgSIwaveACSetup(CfgSetup):
|
|
@@ -183,62 +178,141 @@ class CfgSetups:
|
|
|
183
178
|
continue
|
|
184
179
|
|
|
185
180
|
stp = {}
|
|
186
|
-
if
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
181
|
+
if self._pedb.grpc:
|
|
182
|
+
from ansys.edb.core.simulation_setup.mesh_operation import (
|
|
183
|
+
LengthMeshOperation as GrpcLengthMeshOperation,
|
|
184
|
+
)
|
|
185
|
+
|
|
186
|
+
s_type = s.type.name.lower()
|
|
187
|
+
if s_type == "hfss":
|
|
188
|
+
for p_name in CfgHFSSSetup(self._pedb).__dict__:
|
|
189
|
+
if p_name.startswith("_"):
|
|
190
|
+
continue
|
|
191
|
+
elif p_name == "type":
|
|
192
|
+
stp[p_name] = s.type.name.lower()
|
|
193
|
+
elif p_name == "f_adapt":
|
|
194
|
+
stp[p_name] = s.settings.general.single_frequency_adaptive_solution.adaptive_frequency
|
|
195
|
+
elif p_name == "max_num_passes":
|
|
196
|
+
stp[p_name] = s.settings.general.single_frequency_adaptive_solution.max_passes
|
|
197
|
+
elif p_name == "max_mag_delta_s":
|
|
198
|
+
stp[p_name] = s.settings.general.single_frequency_adaptive_solution.max_delta
|
|
199
|
+
elif p_name == "freq_sweep":
|
|
200
|
+
f_sweep = []
|
|
201
|
+
for sw in s.sweep_data:
|
|
202
|
+
sweep_data = {}
|
|
203
|
+
for sw_p_name in CfgSweepData().__dict__:
|
|
204
|
+
if sw_p_name == "frequencies":
|
|
205
|
+
pass # Frequencies cannot be read from EDB
|
|
206
|
+
else:
|
|
207
|
+
sweep_data[sw_p_name] = getattr(sw, sw_p_name)
|
|
208
|
+
f_sweep.append(sweep_data)
|
|
209
|
+
stp["freq_sweep"] = f_sweep
|
|
210
|
+
elif p_name == "mesh_operations":
|
|
211
|
+
mops = []
|
|
212
|
+
for i in s.mesh_operations:
|
|
213
|
+
mop = {}
|
|
214
|
+
for mop_p_name in CfgLengthMeshOperation().__dict__:
|
|
215
|
+
if mop_p_name == "type":
|
|
216
|
+
if isinstance(i, GrpcLengthMeshOperation):
|
|
217
|
+
mop[mop_p_name] = "length"
|
|
218
|
+
elif mop_p_name == "nets_layers_list":
|
|
219
|
+
mop[mop_p_name] = i.__dict__["_net_layer_info"]
|
|
220
|
+
elif mop_p_name == "restrict_length":
|
|
221
|
+
mop[mop_p_name] = i.__dict__["_restrict_max_length"]
|
|
222
|
+
else:
|
|
223
|
+
mop[mop_p_name] = i.__dict__[f"_{mop_p_name}"]
|
|
224
|
+
mops.append(mop)
|
|
225
|
+
stp["mesh_operations"] = mops
|
|
226
|
+
else:
|
|
227
|
+
stp[p_name] = getattr(s, p_name)
|
|
228
|
+
|
|
229
|
+
elif s_type == "siwave_ac":
|
|
230
|
+
for p_name in CfgSIwaveACSetup(self._pedb).__dict__:
|
|
231
|
+
if p_name.startswith("_"):
|
|
232
|
+
continue
|
|
233
|
+
elif p_name == "freq_sweep":
|
|
234
|
+
pass # Bug in EDB API
|
|
235
|
+
else:
|
|
236
|
+
stp[p_name] = getattr(s, p_name)
|
|
237
|
+
elif s_type == "siwave_dc":
|
|
238
|
+
for p_name in CfgSIwaveDCSetup(self._pedb).__dict__:
|
|
239
|
+
if p_name.startswith("_"):
|
|
240
|
+
continue
|
|
241
|
+
elif p_name == "freq_sweep":
|
|
242
|
+
pass
|
|
243
|
+
elif p_name == "dc_ir_settings":
|
|
244
|
+
dc_ir_s = {}
|
|
245
|
+
for dcir_p_name in CfgDcIrSettings().__dict__:
|
|
246
|
+
dc_ir_s[dcir_p_name] = getattr(s.dc_ir_settings, dcir_p_name)
|
|
247
|
+
stp["dc_ir_settings"] = dc_ir_s
|
|
248
|
+
elif p_name == "dc_slider_position":
|
|
249
|
+
stp[p_name] = getattr(s.dc_settings, p_name)
|
|
250
|
+
else:
|
|
251
|
+
stp[p_name] = getattr(s, p_name)
|
|
252
|
+
else:
|
|
253
|
+
for _, s in self._pedb.setups.items():
|
|
254
|
+
if float(self._pedb.edbversion) < 2025.1:
|
|
255
|
+
if not s.type == "hfss":
|
|
256
|
+
self._pedb.logger.warning("Only HFSS setups are exported in 2024 R2 and earlier version.")
|
|
257
|
+
continue
|
|
258
|
+
if s.type == "hfss":
|
|
259
|
+
for p_name in CfgHFSSSetup(self._pedb).__dict__:
|
|
260
|
+
if p_name.startswith("_"):
|
|
261
|
+
continue
|
|
262
|
+
elif p_name == "type":
|
|
263
|
+
stp[p_name] = s.type
|
|
264
|
+
elif p_name == "f_adapt":
|
|
265
|
+
stp[p_name] = list(s.adaptive_settings.adaptive_frequency_data_list)[
|
|
266
|
+
0
|
|
267
|
+
].adaptive_frequency
|
|
268
|
+
elif p_name == "max_num_passes":
|
|
269
|
+
stp[p_name] = list(s.adaptive_settings.adaptive_frequency_data_list)[0].max_passes
|
|
270
|
+
elif p_name == "max_mag_delta_s":
|
|
271
|
+
stp[p_name] = list(s.adaptive_settings.adaptive_frequency_data_list)[0].max_delta
|
|
272
|
+
elif p_name == "freq_sweep":
|
|
273
|
+
f_sweep = []
|
|
274
|
+
for sw in s.sweeps.items():
|
|
275
|
+
sweep_data = {}
|
|
276
|
+
for sw_p_name in CfgSweepData().__dict__:
|
|
277
|
+
if sw_p_name == "frequencies":
|
|
278
|
+
pass # Frequencies cannot be read from EDB
|
|
279
|
+
else:
|
|
280
|
+
sweep_data[sw_p_name] = getattr(sw[1], sw_p_name)
|
|
281
|
+
f_sweep.append(sweep_data)
|
|
282
|
+
stp["freq_sweep"] = f_sweep
|
|
283
|
+
elif p_name == "mesh_operations":
|
|
284
|
+
mops = []
|
|
285
|
+
for _, i in s.mesh_operations.items():
|
|
286
|
+
mop = {}
|
|
287
|
+
for mop_p_name in CfgLengthMeshOperation().__dict__:
|
|
288
|
+
mop[mop_p_name] = getattr(i, mop_p_name)
|
|
289
|
+
mops.append(mop)
|
|
290
|
+
stp["mesh_operations"] = mops
|
|
291
|
+
else:
|
|
292
|
+
stp[p_name] = getattr(s, p_name)
|
|
293
|
+
|
|
294
|
+
elif s.type == "siwave_ac":
|
|
295
|
+
for p_name in CfgSIwaveACSetup(self._pedb).__dict__:
|
|
296
|
+
if p_name.startswith("_"):
|
|
297
|
+
continue
|
|
298
|
+
elif p_name == "freq_sweep":
|
|
299
|
+
pass # Bug in EDB API
|
|
300
|
+
else:
|
|
301
|
+
stp[p_name] = getattr(s, p_name)
|
|
302
|
+
elif s.type == "siwave_dc":
|
|
303
|
+
for p_name in CfgSIwaveDCSetup(self._pedb).__dict__:
|
|
304
|
+
if p_name.startswith("_"):
|
|
305
|
+
continue
|
|
306
|
+
elif p_name == "freq_sweep":
|
|
307
|
+
pass
|
|
308
|
+
elif p_name == "dc_ir_settings":
|
|
309
|
+
dc_ir_s = {}
|
|
310
|
+
for dcir_p_name in CfgDcIrSettings().__dict__:
|
|
311
|
+
dc_ir_s[dcir_p_name] = getattr(s.dc_ir_settings, dcir_p_name)
|
|
312
|
+
stp["dc_ir_settings"] = dc_ir_s
|
|
313
|
+
elif p_name == "dc_slider_position":
|
|
314
|
+
stp[p_name] = getattr(s.dc_settings, p_name)
|
|
315
|
+
else:
|
|
316
|
+
stp[p_name] = getattr(s, p_name)
|
|
243
317
|
setups.append(stp)
|
|
244
318
|
return setups
|
|
@@ -147,19 +147,34 @@ class Configuration:
|
|
|
147
147
|
cfg_pdef.api.set_parameters_to_edb()
|
|
148
148
|
else:
|
|
149
149
|
temp_pdef_data = {}
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
150
|
+
if self._pedb.grpc:
|
|
151
|
+
from ansys.edb.core.definition.padstack_def_data import (
|
|
152
|
+
PadType as GrpcPadType,
|
|
153
|
+
)
|
|
154
|
+
|
|
155
|
+
for pdef_name, pdef in self._pedb.padstacks.definitions.items():
|
|
156
|
+
for layer in pdef.data.layer_names:
|
|
157
|
+
result = pdef.data.get_pad_parameters(layer, GrpcPadType.REGULAR_PAD)
|
|
158
|
+
if len(result) == 4:
|
|
159
|
+
# polygon based
|
|
160
|
+
temp_pdef_data[pdef_name] = pdef.data
|
|
161
|
+
break
|
|
162
|
+
else:
|
|
163
|
+
for pdef_name, pdef in self._pedb.padstacks.definitions.items():
|
|
164
|
+
pdef_data = pdef._padstack_def_data
|
|
165
|
+
for lyr_name in list(pdef_data.GetLayerNames()):
|
|
166
|
+
result = pdef_data.GetPadParametersValue(
|
|
157
167
|
lyr_name, self._pedb._edb.Definition.PadType.RegularPad
|
|
158
168
|
)
|
|
159
|
-
flag,
|
|
160
|
-
if flag:
|
|
161
|
-
|
|
162
|
-
|
|
169
|
+
flag, pad_shape, params, offset_x, offset_y, rotation = result
|
|
170
|
+
if flag is False:
|
|
171
|
+
result = pdef_data.GetPolygonalPadParameters(
|
|
172
|
+
lyr_name, self._pedb._edb.Definition.PadType.RegularPad
|
|
173
|
+
)
|
|
174
|
+
flag, polygon_data, offset_x, offset_y, rotation = result
|
|
175
|
+
if flag:
|
|
176
|
+
temp_pdef_data[pdef_name] = pdef_data
|
|
177
|
+
break
|
|
163
178
|
self.cfg_data.stackup.apply()
|
|
164
179
|
for pdef_name, pdef_data in temp_pdef_data.items():
|
|
165
180
|
pdef = self._pedb.padstacks.definitions[pdef_name]
|
|
@@ -43,6 +43,11 @@ class PadstackInstanceTerminal(Terminal):
|
|
|
43
43
|
return EDBPadstackInstance(edb_padstack_instance[1], self._pedb).position
|
|
44
44
|
return False
|
|
45
45
|
|
|
46
|
+
@property
|
|
47
|
+
def location(self):
|
|
48
|
+
"""Location of the padstack instance."""
|
|
49
|
+
return self.position
|
|
50
|
+
|
|
46
51
|
def create(self, padstack_instance, name=None, layer=None, is_ref=False):
|
|
47
52
|
"""Create an edge terminal.
|
|
48
53
|
|
|
@@ -78,3 +78,15 @@ class PointTerminal(Terminal):
|
|
|
78
78
|
layer = self._pedb.stackup.layers[value]._edb_layer
|
|
79
79
|
point_data = self._pedb.point_data(*self.location)
|
|
80
80
|
self._edb_object.SetParameters(point_data, layer)
|
|
81
|
+
|
|
82
|
+
@property
|
|
83
|
+
def location(self):
|
|
84
|
+
"""Location of the terminal."""
|
|
85
|
+
|
|
86
|
+
_, point_data, _ = self._edb_object.GetParameters()
|
|
87
|
+
return [point_data.X.ToDouble(), point_data.Y.ToDouble()]
|
|
88
|
+
|
|
89
|
+
@location.setter
|
|
90
|
+
def location(self, value):
|
|
91
|
+
layer = self.layer
|
|
92
|
+
self._edb_object.SetParameters(self._pedb.point_data(*value), layer._edb_object)
|
|
@@ -107,20 +107,6 @@ class Terminal(Connectable):
|
|
|
107
107
|
"""Get layer of the terminal."""
|
|
108
108
|
return self._pedb.logger.error("Cannot determine terminal layer")
|
|
109
109
|
|
|
110
|
-
@property
|
|
111
|
-
def location(self):
|
|
112
|
-
"""Location of the terminal."""
|
|
113
|
-
try:
|
|
114
|
-
_, point_data, _ = self._edb_object.GetParameters()
|
|
115
|
-
return [point_data.X.ToDouble(), point_data.Y.ToDouble()]
|
|
116
|
-
except:
|
|
117
|
-
self._pedb.logger.error("Cannot determine terminal location")
|
|
118
|
-
|
|
119
|
-
@location.setter
|
|
120
|
-
def location(self, value):
|
|
121
|
-
layer = self.layer
|
|
122
|
-
self._edb_object.SetParameters(self._pedb.point_data(*value), layer._edb_object)
|
|
123
|
-
|
|
124
110
|
@property
|
|
125
111
|
def is_circuit_port(self):
|
|
126
112
|
"""Whether it is a circuit port."""
|
pyedb/dotnet/database/siwave.py
CHANGED
|
@@ -811,6 +811,7 @@ class EdbSiwave(object):
|
|
|
811
811
|
|
|
812
812
|
def add_siwave_syz_analysis(
|
|
813
813
|
self,
|
|
814
|
+
name=None,
|
|
814
815
|
accuracy_level=1,
|
|
815
816
|
decade_count=10,
|
|
816
817
|
sweeptype=1,
|
|
@@ -823,6 +824,8 @@ class EdbSiwave(object):
|
|
|
823
824
|
|
|
824
825
|
Parameters
|
|
825
826
|
----------
|
|
827
|
+
name : str optional
|
|
828
|
+
Setup name.
|
|
826
829
|
accuracy_level : int, optional
|
|
827
830
|
Level of accuracy of SI slider. The default is ``1``.
|
|
828
831
|
decade_count : int
|
|
@@ -849,7 +852,7 @@ class EdbSiwave(object):
|
|
|
849
852
|
:class:`pyedb.dotnet.database.edb_data.siwave_simulation_setup_data.SiwaveSYZSimulationSetup`
|
|
850
853
|
Setup object class.
|
|
851
854
|
"""
|
|
852
|
-
setup = self._pedb.create_siwave_syz_setup()
|
|
855
|
+
setup = self._pedb.create_siwave_syz_setup(name=name)
|
|
853
856
|
sweep = "linear count"
|
|
854
857
|
if sweeptype == 2:
|
|
855
858
|
sweep = "log scale"
|
|
@@ -239,7 +239,7 @@ class SimulationSetup(object):
|
|
|
239
239
|
"""List of frequency sweeps."""
|
|
240
240
|
return {i.name: i for i in self.sim_setup_info.sweep_data_list}
|
|
241
241
|
|
|
242
|
-
def add_sweep(self, name, frequency_set: list = None, **kwargs):
|
|
242
|
+
def add_sweep(self, name, frequency_set: list = None, sweep_type: str = "interpolation", **kwargs):
|
|
243
243
|
"""Add frequency sweep.
|
|
244
244
|
|
|
245
245
|
Parameters
|
|
@@ -248,7 +248,8 @@ class SimulationSetup(object):
|
|
|
248
248
|
Name of the frequency sweep. The default is ``None``.
|
|
249
249
|
frequency_set : list, optional
|
|
250
250
|
List of frequency points. The default is ``None``.
|
|
251
|
-
|
|
251
|
+
sweep_type : str, optional
|
|
252
|
+
Sweep type. The default is ``"interpolation"``. Options are ``"discrete"``,"discrete"``.
|
|
252
253
|
Returns
|
|
253
254
|
-------
|
|
254
255
|
|
|
@@ -265,7 +266,7 @@ class SimulationSetup(object):
|
|
|
265
266
|
for k, v in kwargs.items():
|
|
266
267
|
if k in dir(sweep_data):
|
|
267
268
|
setattr(sweep_data, k, v)
|
|
268
|
-
sweep_data.
|
|
269
|
+
sweep_data.type = sweep_type
|
|
269
270
|
|
|
270
271
|
if frequency_set is None:
|
|
271
272
|
sweep_type = "linear_scale"
|
|
@@ -285,6 +286,10 @@ class SimulationSetup(object):
|
|
|
285
286
|
self._update_setup()
|
|
286
287
|
return sweep_data
|
|
287
288
|
|
|
289
|
+
def delete(self):
|
|
290
|
+
"""Delete current simulation setup."""
|
|
291
|
+
self._pedb.layout.cell.DeleteSimulationSetup(self.name)
|
|
292
|
+
|
|
288
293
|
def _add_frequency_sweep(self, sweep_data):
|
|
289
294
|
"""Add a frequency sweep.
|
|
290
295
|
|
pyedb/dotnet/edb.py
CHANGED
|
@@ -278,7 +278,7 @@ class Edb(Database):
|
|
|
278
278
|
if self.active_cell:
|
|
279
279
|
self.logger.info("EDB initialized.")
|
|
280
280
|
else:
|
|
281
|
-
|
|
281
|
+
raise AttributeError("Failed to initialize DLLs.")
|
|
282
282
|
|
|
283
283
|
def __enter__(self):
|
|
284
284
|
return self
|
|
@@ -549,10 +549,7 @@ class Edb(Database):
|
|
|
549
549
|
self.run_as_standalone(self.standalone)
|
|
550
550
|
|
|
551
551
|
# self.logger.info("EDB Standalone %s", self.standalone)
|
|
552
|
-
|
|
553
|
-
self.open(self.edbpath, self.isreadonly)
|
|
554
|
-
except Exception as e:
|
|
555
|
-
self.logger.error("Builder is not Initialized.")
|
|
552
|
+
self.open(self.edbpath, self.isreadonly)
|
|
556
553
|
if not self.active_db:
|
|
557
554
|
self.logger.warning("Error Opening db")
|
|
558
555
|
self._active_cell = None
|
|
@@ -2274,8 +2274,7 @@ class Components(object):
|
|
|
2274
2274
|
pingroup = PinGroup.create(self._active_layout, group_name, pins)
|
|
2275
2275
|
|
|
2276
2276
|
if pingroup.is_null: # pragma: no cover
|
|
2277
|
-
|
|
2278
|
-
return False
|
|
2277
|
+
raise RuntimeError(f"Failed to create pin group {group_name}.")
|
|
2279
2278
|
else:
|
|
2280
2279
|
for pin in pins:
|
|
2281
2280
|
if not pin.net.is_null:
|
|
@@ -41,6 +41,7 @@ from ansys.edb.core.hierarchy.pin_pair_model import PinPairModel as GrpcPinPairM
|
|
|
41
41
|
from ansys.edb.core.hierarchy.sparameter_model import (
|
|
42
42
|
SParameterModel as GrpcSParameterModel,
|
|
43
43
|
)
|
|
44
|
+
from ansys.edb.core.hierarchy.spice_model import SPICEModel as GrpcSPICEModel
|
|
44
45
|
from ansys.edb.core.primitive.primitive import PadstackInstance as GrpcPadstackInstance
|
|
45
46
|
from ansys.edb.core.terminal.terminals import (
|
|
46
47
|
PadstackInstanceTerminal as GrpcPadstackInstanceTerminal,
|
|
@@ -49,6 +50,7 @@ from ansys.edb.core.utility.rlc import Rlc as GrpcRlc
|
|
|
49
50
|
from ansys.edb.core.utility.value import Value as GrpcValue
|
|
50
51
|
|
|
51
52
|
from pyedb.grpc.database.hierarchy.pin_pair_model import PinPairModel
|
|
53
|
+
from pyedb.grpc.database.hierarchy.s_parameter_model import SparamModel
|
|
52
54
|
from pyedb.grpc.database.hierarchy.spice_model import SpiceModel
|
|
53
55
|
from pyedb.grpc.database.layers.stackup_layer import StackupLayer
|
|
54
56
|
from pyedb.grpc.database.primitive.padstack_instance import PadstackInstance
|
|
@@ -204,7 +206,13 @@ class Component(GrpcComponentGroup):
|
|
|
204
206
|
:class:`Model <ansys.edb.core.hierarchy.model.Model>`
|
|
205
207
|
|
|
206
208
|
"""
|
|
207
|
-
|
|
209
|
+
|
|
210
|
+
if isinstance(self.component_property.model, GrpcSPICEModel):
|
|
211
|
+
return SpiceModel(edb_object=self.component_property.model.msg)
|
|
212
|
+
elif isinstance(self.component_property.model, GrpcSParameterModel):
|
|
213
|
+
return SparamModel(edb_object=self.component_property.model.msg)
|
|
214
|
+
else:
|
|
215
|
+
return self.component_property.model
|
|
208
216
|
|
|
209
217
|
@model.setter
|
|
210
218
|
def model(self, value):
|
|
@@ -28,6 +28,6 @@ from ansys.edb.core.hierarchy.sparameter_model import (
|
|
|
28
28
|
class SparamModel(GrpcSParameterModel): # pragma: no cover
|
|
29
29
|
"""Manage :class:`SParameterModel <ansys.edb.core.hierarchy.sparameter_model.SParameterModel>`"""
|
|
30
30
|
|
|
31
|
-
def __init__(self,
|
|
31
|
+
def __init__(self, edb_object):
|
|
32
32
|
super().__init__(self.msg)
|
|
33
|
-
self._edb_model =
|
|
33
|
+
self._edb_model = edb_object
|
|
@@ -81,12 +81,12 @@ class HfssExtentInfo(GrpcHfssExtentInfo):
|
|
|
81
81
|
float
|
|
82
82
|
Air box horizontal extent value.
|
|
83
83
|
"""
|
|
84
|
-
return self._hfss_extent_info.
|
|
84
|
+
return self._hfss_extent_info.airbox_horizontal[0]
|
|
85
85
|
|
|
86
86
|
@air_box_horizontal_extent.setter
|
|
87
87
|
def air_box_horizontal_extent(self, value):
|
|
88
88
|
hfss_extent = self._hfss_extent_info
|
|
89
|
-
hfss_extent.
|
|
89
|
+
hfss_extent.airbox_horizontal = (float(value), True)
|
|
90
90
|
self._update_hfss_extent_info(hfss_extent)
|
|
91
91
|
|
|
92
92
|
@property
|
|
@@ -98,12 +98,12 @@ class HfssExtentInfo(GrpcHfssExtentInfo):
|
|
|
98
98
|
bool.
|
|
99
99
|
|
|
100
100
|
"""
|
|
101
|
-
return self._hfss_extent_info.
|
|
101
|
+
return self._hfss_extent_info.airbox_vertical_positive[1]
|
|
102
102
|
|
|
103
103
|
@air_box_positive_vertical_extent_enabled.setter
|
|
104
104
|
def air_box_positive_vertical_extent_enabled(self, value):
|
|
105
105
|
hfss_exent = self._hfss_extent_info
|
|
106
|
-
hfss_exent.
|
|
106
|
+
hfss_exent.airbox_vertical_positive = (0.15, value)
|
|
107
107
|
self._update_hfss_extent_info(hfss_exent)
|
|
108
108
|
|
|
109
109
|
@property
|
|
@@ -116,12 +116,12 @@ class HfssExtentInfo(GrpcHfssExtentInfo):
|
|
|
116
116
|
Air box positive vertical extent value.
|
|
117
117
|
|
|
118
118
|
"""
|
|
119
|
-
return self._hfss_extent_info.
|
|
119
|
+
return self._hfss_extent_info.airbox_vertical_positive[0]
|
|
120
120
|
|
|
121
121
|
@air_box_positive_vertical_extent.setter
|
|
122
122
|
def air_box_positive_vertical_extent(self, value):
|
|
123
123
|
hfss_extent = self._hfss_extent_info
|
|
124
|
-
hfss_extent.
|
|
124
|
+
hfss_extent.airbox_vertical_positive = (float(value), True)
|
|
125
125
|
self._update_hfss_extent_info(hfss_extent)
|
|
126
126
|
|
|
127
127
|
@property
|
|
@@ -133,12 +133,12 @@ class HfssExtentInfo(GrpcHfssExtentInfo):
|
|
|
133
133
|
bool.
|
|
134
134
|
|
|
135
135
|
"""
|
|
136
|
-
return self._hfss_extent_info.
|
|
136
|
+
return self._hfss_extent_info.airbox_vertical_negative[1]
|
|
137
137
|
|
|
138
138
|
@air_box_negative_vertical_extent_enabled.setter
|
|
139
139
|
def air_box_negative_vertical_extent_enabled(self, value):
|
|
140
140
|
hfss_extent = self._hfss_extent_info
|
|
141
|
-
hfss_extent.
|
|
141
|
+
hfss_extent.airbox_vertical_negative = (0.15, value)
|
|
142
142
|
self._update_hfss_extent_info(hfss_extent)
|
|
143
143
|
|
|
144
144
|
@property
|
|
@@ -151,12 +151,12 @@ class HfssExtentInfo(GrpcHfssExtentInfo):
|
|
|
151
151
|
Air box negative vertical extent value.
|
|
152
152
|
|
|
153
153
|
"""
|
|
154
|
-
return self._hfss_extent_info.
|
|
154
|
+
return self._hfss_extent_info.airbox_vertical_negative[0]
|
|
155
155
|
|
|
156
156
|
@air_box_negative_vertical_extent.setter
|
|
157
157
|
def air_box_negative_vertical_extent(self, value):
|
|
158
158
|
hfss_extent = self._hfss_extent_info
|
|
159
|
-
hfss_extent.
|
|
159
|
+
hfss_extent.airbox_vertical_negative = (float(value), True)
|
|
160
160
|
self._update_hfss_extent_info(hfss_extent)
|
|
161
161
|
|
|
162
162
|
@property
|
|
@@ -183,7 +183,7 @@ class HfssExtentInfo(GrpcHfssExtentInfo):
|
|
|
183
183
|
-------
|
|
184
184
|
:class:`Polygon <pyedb.grpc.database.primitive.polygon.Polygon>`
|
|
185
185
|
"""
|
|
186
|
-
return
|
|
186
|
+
return super().dielectric_base_polygon
|
|
187
187
|
|
|
188
188
|
@dielectric_base_polygon.setter
|
|
189
189
|
def dielectric_base_polygon(self, value):
|
|
@@ -216,12 +216,12 @@ class HfssExtentInfo(GrpcHfssExtentInfo):
|
|
|
216
216
|
float
|
|
217
217
|
Dielectric extent size value.
|
|
218
218
|
"""
|
|
219
|
-
return self._hfss_extent_info.
|
|
219
|
+
return self._hfss_extent_info.dielectric[0]
|
|
220
220
|
|
|
221
221
|
@dielectric_extent_size.setter
|
|
222
222
|
def dielectric_extent_size(self, value):
|
|
223
223
|
hfss_extent = self._hfss_extent_info
|
|
224
|
-
hfss_extent.
|
|
224
|
+
hfss_extent.dielectric = (value, True)
|
|
225
225
|
self._update_hfss_extent_info(hfss_extent)
|
|
226
226
|
|
|
227
227
|
@property
|
|
@@ -256,6 +256,17 @@ class HfssExtentInfo(GrpcHfssExtentInfo):
|
|
|
256
256
|
@extent_type.setter
|
|
257
257
|
def extent_type(self, value):
|
|
258
258
|
hfss_extent = self._hfss_extent_info
|
|
259
|
+
if isinstance(value, str):
|
|
260
|
+
if value.lower() == "bounding_box":
|
|
261
|
+
value = GrpcHfssExtentInfo.HFSSExtentInfoType.BOUNDING_BOX
|
|
262
|
+
elif value.lower() == "conforming":
|
|
263
|
+
value = GrpcHfssExtentInfo.HFSSExtentInfoType.CONFORMING
|
|
264
|
+
elif value.lower() == "convex_hul":
|
|
265
|
+
value = GrpcHfssExtentInfo.HFSSExtentInfoType.CONVEX_HUL
|
|
266
|
+
elif value.lower() == "polygon":
|
|
267
|
+
value = GrpcHfssExtentInfo.HFSSExtentInfoType.POLYGON
|
|
268
|
+
else:
|
|
269
|
+
raise f"Invalid extent type : {value}"
|
|
259
270
|
hfss_extent.extent_type = value
|
|
260
271
|
self._update_hfss_extent_info(hfss_extent)
|
|
261
272
|
|
|
@@ -328,7 +339,7 @@ class HfssExtentInfo(GrpcHfssExtentInfo):
|
|
|
328
339
|
self._update_hfss_extent_info(hfss_extent)
|
|
329
340
|
|
|
330
341
|
@property
|
|
331
|
-
def
|
|
342
|
+
def pml_radiation_factor(self):
|
|
332
343
|
"""PML Radiation level to calculate the thickness of boundary.
|
|
333
344
|
|
|
334
345
|
Returns
|
|
@@ -337,12 +348,12 @@ class HfssExtentInfo(GrpcHfssExtentInfo):
|
|
|
337
348
|
Boundary thickness value.
|
|
338
349
|
|
|
339
350
|
"""
|
|
340
|
-
return
|
|
351
|
+
return self._hfss_extent_info.radiation_level.value
|
|
341
352
|
|
|
342
|
-
@
|
|
343
|
-
def
|
|
353
|
+
@pml_radiation_factor.setter
|
|
354
|
+
def pml_radiation_factor(self, value):
|
|
344
355
|
hfss_extent = self._hfss_extent_info
|
|
345
|
-
hfss_extent.
|
|
356
|
+
hfss_extent.radiation_level = GrpcValue(value)
|
|
346
357
|
self._update_hfss_extent_info(hfss_extent)
|
|
347
358
|
|
|
348
359
|
@property
|
|
@@ -373,12 +384,12 @@ class HfssExtentInfo(GrpcHfssExtentInfo):
|
|
|
373
384
|
Truncate air box at ground.
|
|
374
385
|
|
|
375
386
|
"""
|
|
376
|
-
return self._hfss_extent_info.
|
|
387
|
+
return self._hfss_extent_info.airbox_truncate_at_ground
|
|
377
388
|
|
|
378
389
|
@truncate_air_box_at_ground.setter
|
|
379
390
|
def truncate_air_box_at_ground(self, value):
|
|
380
391
|
hfss_extent = self._hfss_extent_info
|
|
381
|
-
hfss_extent.
|
|
392
|
+
hfss_extent.airbox_truncate_at_ground = value
|
|
382
393
|
self._update_hfss_extent_info(hfss_extent)
|
|
383
394
|
|
|
384
395
|
@property
|