pyedb 0.8.1__py3-none-any.whl → 0.9.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 CHANGED
@@ -44,7 +44,7 @@ deprecation_warning()
44
44
  #
45
45
 
46
46
  pyedb_path = os.path.dirname(__file__)
47
- __version__ = "0.8.1"
47
+ __version__ = "0.9.0"
48
48
  version = __version__
49
49
 
50
50
  #
pyedb/dotnet/edb.py CHANGED
@@ -57,6 +57,9 @@ from pyedb.dotnet.edb_core.edb_data.ports import (
57
57
  GapPort,
58
58
  WavePort,
59
59
  )
60
+ from pyedb.dotnet.edb_core.edb_data.raptor_x_simulation_setup_data import (
61
+ RaptorXSimulationSetup,
62
+ )
60
63
  from pyedb.dotnet.edb_core.edb_data.simulation_configuration import (
61
64
  SimulationConfiguration,
62
65
  )
@@ -174,15 +177,16 @@ class Edb(Database):
174
177
 
175
178
  def __init__(
176
179
  self,
177
- edbpath=None,
178
- cellname=None,
179
- isreadonly=False,
180
- edbversion=None,
181
- isaedtowned=False,
180
+ edbpath: str = None,
181
+ cellname: str = None,
182
+ isreadonly: bool = False,
183
+ edbversion: str = None,
184
+ isaedtowned: bool = False,
182
185
  oproject=None,
183
- student_version=False,
184
- use_ppe=False,
185
- technology_file=None,
186
+ student_version: bool = False,
187
+ use_ppe: bool = False,
188
+ technology_file: str = None,
189
+ remove_existing_aedt: bool = False,
186
190
  ):
187
191
  edbversion = get_string_version(edbversion)
188
192
  self._clean_variables()
@@ -213,17 +217,8 @@ class Edb(Database):
213
217
  os.path.dirname(edbpath),
214
218
  "pyedb_" + os.path.splitext(os.path.split(edbpath)[-1])[0] + ".log",
215
219
  )
216
- aedt_file = os.path.splitext(edbpath)[0] + ".aedt"
217
- files = [aedt_file, aedt_file + ".lock"]
218
- for file in files:
219
- if os.path.isfile(file):
220
- try:
221
- shutil.rmtree(file)
222
- self.logger.info(f"Removing {file} to allow loading EDB file.")
223
- except:
224
- self.logger.info(
225
- f"Failed to delete {file} which is located at the same location as the EDB file."
226
- )
220
+ if not isreadonly:
221
+ self._check_remove_project_files(edbpath, remove_existing_aedt)
227
222
 
228
223
  if isaedtowned and (inside_desktop or settings.remote_rpc_session):
229
224
  self.open_edb_inside_aedt()
@@ -311,6 +306,22 @@ class Edb(Database):
311
306
  if description: # Add the variable description if a two-item list is passed for variable_value.
312
307
  self.__getitem__(variable_name).description = description
313
308
 
309
+ def _check_remove_project_files(self, edbpath: str, remove_existing_aedt: bool) -> None:
310
+ aedt_file = os.path.splitext(edbpath)[0] + ".aedt"
311
+ files = [aedt_file, aedt_file + ".lock"]
312
+ for file in files:
313
+ if os.path.isfile(file):
314
+ if not remove_existing_aedt:
315
+ self.logger.warning(
316
+ f"AEDT project-related file {file} exists and may need to be deleted before opening the EDB in HFSS 3D Layout." # noqa: E501
317
+ )
318
+ else:
319
+ try:
320
+ os.unlink(file)
321
+ self.logger.info(f"Deleted AEDT project-related file {file}.")
322
+ except:
323
+ self.logger.info(f"Failed to delete AEDT project-related file {file}.")
324
+
314
325
  def _clean_variables(self):
315
326
  """Initialize internal variables and perform garbage collection."""
316
327
  self._materials = None
@@ -3584,6 +3595,8 @@ class Edb(Database):
3584
3595
  setups[i.GetName()] = SiwaveSYZSimulationSetup(self, i)
3585
3596
  elif i.GetType() == self.edb_api.utility.utility.SimulationSetupType.kSIWaveDCIR:
3586
3597
  setups[i.GetName()] = SiwaveDCSimulationSetup(self, i)
3598
+ elif i.GetType() == self.edb_api.utility.utility.SimulationSetupType.kRaptorX:
3599
+ setups[i.GetName()] = RaptorXSimulationSetup(self, i)
3587
3600
  return setups
3588
3601
 
3589
3602
  @property
@@ -3639,9 +3652,35 @@ class Edb(Database):
3639
3652
  if name in self.setups:
3640
3653
  self.logger.info("setup already exists")
3641
3654
  return False
3655
+ elif not name:
3656
+ name = generate_unique_name("setup")
3642
3657
  setup = HfssSimulationSetup(self).create(name)
3643
3658
  return setup
3644
3659
 
3660
+ def create_raptorx_setup(self, name=None):
3661
+ """Create an RaptorX simulation setup from a template.
3662
+
3663
+ Parameters
3664
+ ----------
3665
+ name : str, optional
3666
+ Setup name.
3667
+
3668
+ Returns
3669
+ -------
3670
+ :class:`legacy.edb_core.edb_data.raptor_x_simulation_setup_data.RaptorXSimulationSetup`
3671
+
3672
+ """
3673
+ if name in self.setups:
3674
+ self.logger.error("Setup name already used in the layout")
3675
+ return False
3676
+ version = self.edbversion.split(".")
3677
+ if int(version[0]) >= 2024 and int(version[-1]) >= 2 or int(version[0]) > 2024:
3678
+ setup = RaptorXSimulationSetup(self).create(name)
3679
+ return setup
3680
+ else:
3681
+ self.logger.error("RaptorX simulation only supported with Ansys release 2024R2 and higher")
3682
+ return False
3683
+
3645
3684
  @pyedb_function_handler()
3646
3685
  def create_siwave_syz_setup(self, name=None):
3647
3686
  """Create a setup from a template.
@@ -0,0 +1,520 @@
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
+ # FITNE SS 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.edb_data.edbvalue import EdbValue
24
+ from pyedb.dotnet.edb_core.general import convert_py_list_to_net_list
25
+ from pyedb.dotnet.edb_core.utilities.simulation_setup import (
26
+ BaseSimulationSetup,
27
+ EdbFrequencySweep,
28
+ )
29
+ from pyedb.generic.data_handlers import pyedb_function_handler
30
+ from pyedb.generic.general_methods import generate_unique_name
31
+
32
+
33
+ class RaptorXSimulationSetup(BaseSimulationSetup):
34
+ """Manages EDB methods for RaptorX simulation setup."""
35
+
36
+ def __init__(self, pedb, edb_object=None):
37
+ super().__init__(pedb, edb_object)
38
+ self._pedb = pedb
39
+ self._setup_type = "kRaptorX"
40
+ self._edb_setup_info = None
41
+ self.logger = self._pedb.logger
42
+
43
+ @pyedb_function_handler
44
+ def create(self, name=None):
45
+ """Create an HFSS setup."""
46
+ self._name = name
47
+ self._create(name)
48
+ return self
49
+
50
+ @property
51
+ def setup_type(self):
52
+ return self._setup_type
53
+
54
+ @property
55
+ def settings(self):
56
+ return RaptorXSimulationSettings(self._edb_setup_info, self._pedb)
57
+
58
+ @property
59
+ def enabled(self):
60
+ return self.settings.enabled
61
+
62
+ @enabled.setter
63
+ def enabled(self, value):
64
+ self.settings.enabled = value
65
+
66
+ @property
67
+ def position(self):
68
+ return self._edb_setup_info.Position
69
+
70
+ @position.setter
71
+ def position(self, value):
72
+ if isinstance(value, int):
73
+ self._edb_setup_info.Position = value
74
+ else:
75
+ self.logger.error(f"RaptorX setup position input setter must be an integer. Provided value {value}")
76
+
77
+ @property
78
+ def frequency_sweeps(self):
79
+ return list(self._edb_setup_info.SweepDataList)
80
+
81
+ @pyedb_function_handler()
82
+ def add_frequency_sweep(self, name=None, frequency_sweep=None):
83
+ """Add frequency sweep.
84
+
85
+ Parameters
86
+ ----------
87
+ name : str, optional
88
+ Name of the frequency sweep.
89
+ frequency_sweep : list, optional
90
+ List of frequency points.
91
+
92
+ Returns
93
+ -------
94
+ :class:`pyedb.dotnet.edb_core.edb_data.hfss_simulation_setup_data.EdbFrequencySweep`
95
+
96
+ Examples
97
+ --------
98
+ >>> setup1 = edbapp.create_hfss_setup("setup1")
99
+ >>> setup1.add_frequency_sweep(frequency_sweep=[
100
+ ... ["linear count", "0", "1kHz", 1],
101
+ ... ["log scale", "1kHz", "0.1GHz", 10],
102
+ ... ["linear scale", "0.1GHz", "10GHz", "0.1GHz"],
103
+ ... ])
104
+ """
105
+ if name in self.frequency_sweeps:
106
+ return False
107
+ if not name:
108
+ name = generate_unique_name("sweep")
109
+ return EdbFrequencySweep(self, frequency_sweep, name)
110
+
111
+
112
+ class RaptorXSimulationSettings(object):
113
+ def __init__(self, edb_setup_info, pedb):
114
+ self._pedb = pedb
115
+ self.logger = self._pedb.logger
116
+ self._edb_setup_info = edb_setup_info
117
+ self._simulation_settings = edb_setup_info.SimulationSettings
118
+ self._general_settings = RaptorXGeneralSettings(self._edb_setup_info, self._pedb)
119
+ self._advanced_settings = RaptorXSimulationAdvancedSettings(self._edb_setup_info, self._pedb)
120
+ self._simulation_settings = self._edb_setup_info.SimulationSettings
121
+
122
+ @property
123
+ def general_settings(self):
124
+ return self._general_settings
125
+
126
+ @property
127
+ def advanced_settings(self):
128
+ return self._advanced_settings
129
+
130
+ @property
131
+ def enabled(self):
132
+ return self._simulation_settings.Enabled
133
+
134
+ @enabled.setter
135
+ def enabled(self, value):
136
+ if isinstance(value, bool):
137
+ self._simulation_settings.Enabled = value
138
+ else:
139
+ self.logger.error(f"RaptorX setup enabled setter input must be a boolean. Provided value {value}")
140
+
141
+
142
+ class RaptorXGeneralSettings(object):
143
+ def __init__(self, edb_setup_info, pedb):
144
+ self._general_settings = edb_setup_info.SimulationSettings.GeneralSettings
145
+ self._pedb = pedb
146
+ self.logger = self._pedb.logger
147
+
148
+ @property
149
+ def global_temperature(self):
150
+ """The simulation temperature. Units: C"""
151
+ return self._general_settings.GlobalTemperature
152
+
153
+ @global_temperature.setter
154
+ def global_temperature(self, value):
155
+ self._general_settings.GlobalTemperature = EdbValue(value).tofloat
156
+
157
+ @property
158
+ def max_frequency(self):
159
+ return self._general_settings.MaxFrequency
160
+
161
+ @max_frequency.setter
162
+ def max_frequency(self, value):
163
+ """This allows user to specify the maximum simulation frequency, a parameter which controls how tight the model
164
+ mesh will be. User can override the default meshing frequency as defined by Max Frequency using the Advanced
165
+ settings > MeshFrequency. Example: "10GHz".
166
+ """
167
+ self._general_settings.MaxFrequency = EdbValue(value).tostring
168
+
169
+
170
+ class RaptorXSimulationAdvancedSettings(object):
171
+ def __init__(self, edb_setup_info, pedb):
172
+ self._edb_setup_info = edb_setup_info
173
+ self._advanced_settings = edb_setup_info.SimulationSettings.AdvancedSettings
174
+ self._pedb = pedb
175
+ self.logger = self._pedb.logger
176
+
177
+ @property
178
+ def auto_removal_sliver_poly(self):
179
+ return self._advanced_settings.AutoRemovalSliverPoly
180
+
181
+ @auto_removal_sliver_poly.setter
182
+ def auto_removal_sliver_poly(self, value):
183
+ self._advanced_settings.AutoRemovalSliverPoly = EdbValue(value).tofloat
184
+
185
+ @property
186
+ def cell_per_wave_length(self):
187
+ """This setting describes the number of cells that fit under each wavelength. The wavelength is
188
+ calculated according to the Max Frequency or the Mesh Frequency, unless specified by user through
189
+ this setting. E.g. Setting Cells/Wavelength to 20 means that an object will be divided into 10 cells
190
+ if its width or length is 1/2 wavelengths.
191
+ Units: unitless.
192
+ """
193
+ return self._advanced_settings.CellsPerWavelength
194
+
195
+ @cell_per_wave_length.setter
196
+ def cell_per_wave_length(self, value):
197
+ if isinstance(value, int):
198
+ self._advanced_settings.CellsPerWavelength = value
199
+ else:
200
+ self.logger.error(f"RaptorX cell_per_wave_length setter input must be an integer, value provided {value}")
201
+
202
+ @property
203
+ def edge_mesh(self):
204
+ """This option controls both, the thickness and the width of the exterior conductor filament.
205
+ When specified, it prevails over the Mesh Frequency or Max Frequency during mesh calculation.
206
+ Example: "0.8um".
207
+ """
208
+ return self._advanced_settings.EdgeMesh
209
+
210
+ @edge_mesh.setter
211
+ def edge_mesh(self, value):
212
+ self._advanced_settings.EdgeMesh = EdbValue(value).tostring
213
+
214
+ @property
215
+ def eliminate_slit_per_hole(self):
216
+ """This is a setting that internally simplifies layouts with strain relief or thermal relief slits and
217
+ holes. It will examine each hole separately against the whole polygon it belongs to.
218
+ If the area of the hole is below the threshold defined in this setting, then the hole will be filled.
219
+ Units: unitless.
220
+ """
221
+ return self._advanced_settings.EliminateSlitPerHoles
222
+
223
+ @eliminate_slit_per_hole.setter
224
+ def eliminate_slit_per_hole(self, value):
225
+ self._advanced_settings.EliminateSlitPerHoles = EdbValue(value).tofloat
226
+
227
+ @property
228
+ def mesh_frequency(self):
229
+ """User can override the default meshing applied by setting a custom frequency for mesh generation.
230
+ Example: "1GHz".
231
+ """
232
+ return self._advanced_settings.MeshFrequency
233
+
234
+ @mesh_frequency.setter
235
+ def mesh_frequency(self, value):
236
+ self._advanced_settings.MeshFrequency = EdbValue(value).tostring
237
+
238
+ @property
239
+ def net_settings_options(self):
240
+ """A list of Name, Value pairs that stores advanced option."""
241
+ return [val for val in list(self._advanced_settings.NetSettingsOptions)]
242
+
243
+ @net_settings_options.setter
244
+ def net_settings_options(self, value):
245
+ if isinstance(value, list):
246
+ self._advanced_settings.NetSettingsOptions = convert_py_list_to_net_list(value)
247
+ else:
248
+ self.logger.error(
249
+ f"RaptorX setup net_settings_options input setter must be a list. " f"Provided value {value}"
250
+ )
251
+
252
+ @property
253
+ def override_shrink_fac(self):
254
+ """Set the shrink factor explicitly, that is, review what-if scenarios of migrating to half-node
255
+ technologies.
256
+ Units: unitless.
257
+ """
258
+ return self._advanced_settings.OverrideShrinkFac
259
+
260
+ @override_shrink_fac.setter
261
+ def override_shrink_fac(self, value):
262
+ self._advanced_settings.OverrideShrinkFac = EdbValue(value).tofloat
263
+
264
+ @property
265
+ def plane_projection_factor(self):
266
+ """To eliminate unnecessary mesh complexity of "large" metal planes and improve overall extraction time,
267
+ user can define the mesh of certain planes using a combination of the Plane Projection Factor and
268
+ settings of the Nets Advanced Options.
269
+ Units: unitless.
270
+ """
271
+ return self._advanced_settings.PlaneProjectionFactor
272
+
273
+ @plane_projection_factor.setter
274
+ def plane_projection_factor(self, value):
275
+ self._advanced_settings.PlaneProjectionFactor = EdbValue(value).tofloat
276
+
277
+ @property
278
+ def use_accelerate_via_extraction(self):
279
+ """Setting this option will simplify/merge neighboring vias before sending the layout for processing
280
+ to the mesh engine and to the EM engine.
281
+ """
282
+ return self._advanced_settings.UseAccelerateViaExtraction
283
+
284
+ @use_accelerate_via_extraction.setter
285
+ def use_accelerate_via_extraction(self, value):
286
+ if isinstance(value, bool):
287
+ self._advanced_settings.UseAccelerateViaExtraction = value
288
+ else:
289
+ self.logger.error(
290
+ "RaptorX setup use_accelerate_via_extraction setter input must be boolean." f"Provided value {value}"
291
+ )
292
+
293
+ @property
294
+ def use_auto_removal_sliver_poly(self):
295
+ """Setting this option simplifies layouts by aligning slightly misaligned overlapping polygons."""
296
+ return self._advanced_settings.UseAutoRemovalSliverPoly
297
+
298
+ @use_auto_removal_sliver_poly.setter
299
+ def use_auto_removal_sliver_poly(self, value):
300
+ if isinstance(value, bool):
301
+ self._advanced_settings.UseAutoRemovalSliverPoly = value
302
+ else:
303
+ self.logger.error(
304
+ f"RaptorX setup use_auto_removal_sliver_poly setter must be a boolean. " f"Provided value {value}"
305
+ )
306
+
307
+ @property
308
+ def use_cells_per_wavelength(self):
309
+ """This setting describes the number of cells that fit under each wavelength. The wavelength is calculated
310
+ according to the Max Frequency or the Mesh Frequency, unless specified by user through this setting.
311
+ """
312
+ return self._advanced_settings.UseCellsPerWavelength
313
+
314
+ @use_cells_per_wavelength.setter
315
+ def use_cells_per_wavelength(self, value):
316
+ if isinstance(value, bool):
317
+ self._advanced_settings.UseCellsPerWavelength = value
318
+ else:
319
+ self.logger.error(f"RaptorX setup use_cells_per_wavelength setter must be boolean. Provided value {value}")
320
+
321
+ @property
322
+ def use_edge_mesh(self):
323
+ """This option controls both, the thickness and the width of the exterior conductor filament.
324
+ When checked, it prevails over the Mesh Frequency or Max Frequency during mesh calculation.
325
+ """
326
+ return self._advanced_settings.UseEdgeMesh
327
+
328
+ @use_edge_mesh.setter
329
+ def use_edge_mesh(self, value):
330
+ if isinstance(value, bool):
331
+ self._advanced_settings.UseEdgeMesh = value
332
+ else:
333
+ self.logger.error(f"RaptorX setup use_edge_mesh setter must be a boolean. Provided value {value}")
334
+
335
+ @property
336
+ def use_eliminate_slit_per_holes(self):
337
+ """This is a setting that internally simplifies layouts with strain relief or thermal relief slits and
338
+ holes.
339
+ """
340
+ return self._advanced_settings.UseEliminateSlitPerHoles
341
+
342
+ @use_eliminate_slit_per_holes.setter
343
+ def use_eliminate_slit_per_holes(self, value):
344
+ if isinstance(value, bool):
345
+ self._advanced_settings.UseEliminateSlitPerHoles = value
346
+ else:
347
+ self.logger.error(
348
+ f"RaptorX setup use_eliminate_slit_per_holes setter must be a boolean. " f"Provided value {value}"
349
+ )
350
+
351
+ @property
352
+ def use_enable_advanced_cap_effects(self):
353
+ """Applies all the capacitance related effects such as Conformal Dielectrics, Loading Effect,
354
+ Dielectric Damage.
355
+ """
356
+ return self._advanced_settings.UseEnableAdvancedCapEffects
357
+
358
+ @use_enable_advanced_cap_effects.setter
359
+ def use_enable_advanced_cap_effects(self, value):
360
+ if isinstance(value, bool):
361
+ self._advanced_settings.UseEnableAdvancedCapEffects = value
362
+ else:
363
+ self.logger.error(
364
+ f"RaptorX setup use_enable_advanced_cap_effects setter must be a boolean. " f"Provided value {value}"
365
+ )
366
+
367
+ @property
368
+ def use_enable_etch_transform(self):
369
+ """Pre-distorts the layout based on the foundry rules, applying the conductor's bias (positive/negative –
370
+ deflation/inflation) at the conductor edges due to unavoidable optical effects in the manufacturing process.
371
+ """
372
+ return self._advanced_settings.UseEnableEtchTransform
373
+
374
+ @use_enable_etch_transform.setter
375
+ def use_enable_etch_transform(self, value):
376
+ if isinstance(value, bool):
377
+ self._advanced_settings.UseEnableEtchTransform = value
378
+ else:
379
+ self.logger.error(
380
+ f"RaptorX setup use_enable_etch_transform setter must be a boolean. " f"Provided value {value}"
381
+ )
382
+
383
+ @property
384
+ def use_enable_hybrid_extraction(self):
385
+ """This setting allows the modelling engine to separate the layout into two parts in an attempt to
386
+ decrease the complexity of EM modelling.
387
+ """
388
+ return self._edb_setup_info.UseEnableHybridExtraction
389
+
390
+ @use_enable_hybrid_extraction.setter
391
+ def use_enable_hybrid_extraction(self, value):
392
+ if isinstance(value, bool):
393
+ self._advanced_settings.UseEnableHybridExtraction = value
394
+ else:
395
+ self.logger.error(
396
+ f"RaptorX setup use_enable_hybrid_extraction setter must be a boolean. " f"Provided value {value}"
397
+ )
398
+
399
+ @property
400
+ def use_enable_substrate_network_extraction(self):
401
+ """This setting models substrate coupling effects using an equivalent distributed RC network."""
402
+ return self._advanced_settings.UseEnableSubstrateNetworkExtraction
403
+
404
+ @use_enable_substrate_network_extraction.setter
405
+ def use_enable_substrate_network_extraction(self, value):
406
+ if isinstance(value, bool):
407
+ self._advanced_settings.UseEnableSubstrateNetworkExtraction = value
408
+ else:
409
+ self.logger.error(
410
+ f"RaptorX setup use_enable_substrate_network_extraction setter must be a boolean. "
411
+ f"Provided value {value}"
412
+ )
413
+
414
+ @property
415
+ def use_extract_floating_metals_dummy(self):
416
+ """Enables modeling of floating metals as dummy fills. Captures the effect of dummy fill by extracting
417
+ the effective capacitance between any pairs of metal segments in the design, in the presence of each
418
+ individual dummy metal islands. This setting cannot be used with UseExtractFloatingMetalsFloating.
419
+ """
420
+ return self._advanced_settings.UseExtractFloatingMetalsDummy
421
+
422
+ @use_extract_floating_metals_dummy.setter
423
+ def use_extract_floating_metals_dummy(self, value):
424
+ if isinstance(value, bool):
425
+ self._advanced_settings.UseExtractFloatingMetalsDummy = value
426
+ else:
427
+ self.logger.error(
428
+ f"RaptorX setup use_extract_floating_metals_dummy setter must be a boolean. " f"Provided value {value}"
429
+ )
430
+
431
+ @property
432
+ def use_extract_floating_metals_floating(self):
433
+ """Enables modeling of floating metals as floating nets. Floating metal are grouped into a single entity
434
+ and treated as an independent net. This setting cannot be used with UseExtractFloatingMetalsDummy.
435
+ """
436
+ return self._advanced_settings.UseExtractFloatingMetalsFloating
437
+
438
+ @use_extract_floating_metals_floating.setter
439
+ def use_extract_floating_metals_floating(self, value):
440
+ if isinstance(value, bool):
441
+ self._advanced_settings.UseExtractFloatingMetalsFloating = value
442
+ else:
443
+ self.logger.error(
444
+ f"RaptorX setup use_extract_floating_metals_floating setter must be a boolean. "
445
+ f"Provided value {value}"
446
+ )
447
+
448
+ @property
449
+ def use_lde(self):
450
+ """
451
+ Takes into account the variation of resistivity as a function of a conductor’s drawn width and spacing to
452
+ its neighbors or as a function of its local density, due to dishing, slotting, cladding thickness, and so
453
+ on.
454
+ """
455
+ return self._advanced_settings.UseLDE
456
+
457
+ @use_lde.setter
458
+ def use_lde(self, value):
459
+ if isinstance(value, bool):
460
+ self._advanced_settings.UseLDE = value
461
+ else:
462
+ self.logger.error(f"RaptorX setup use_lde setter must be a boolean. Provided value {value}")
463
+
464
+ @property
465
+ def use_mesh_frequency(self):
466
+ """
467
+ User can override the default meshing applied by the mesh engine by checking this option and setting a
468
+ custom frequency for mesh generation.
469
+ """
470
+ return self._advanced_settings.UseMeshFrequency
471
+
472
+ @use_mesh_frequency.setter
473
+ def use_mesh_frequency(self, value):
474
+ if isinstance(value, bool):
475
+ self._advanced_settings.UseMeshFrequency = value
476
+ else:
477
+ self.logger.error(f"RaptorX setup use_mesh_frequency setter must be a boolean. Provided value {value}")
478
+
479
+ @property
480
+ def use_override_shrink_fac(self):
481
+ """Set the shrink factor explicitly, that is, review what-if scenarios of migrating to half-node
482
+ technologies.
483
+ """
484
+ return self._advanced_settings.UseOverrideShrinkFac
485
+
486
+ @use_override_shrink_fac.setter
487
+ def use_override_shrink_fac(self, value):
488
+ if isinstance(value, bool):
489
+ self._advanced_settings.UseOverrideShrinkFac = value
490
+ else:
491
+ self.logger.error(f"RaptorX setup use_override_shrink_fac setter must be a boolean. Provided value {value}")
492
+
493
+ @property
494
+ def use_plane_projection_factor(self):
495
+ """To eliminate unnecessary mesh complexity of "large" metal planes and improve overall
496
+ extraction time, user can define the mesh of certain planes using a combination of the Plane Projection
497
+ Factor and settings of the Nets Advanced Options.
498
+ """
499
+ return self._advanced_settings.UsePlaneProjectionFactor
500
+
501
+ @use_plane_projection_factor.setter
502
+ def use_plane_projection_factor(self, value):
503
+ if isinstance(value, bool):
504
+ self._advanced_settings.UsePlaneProjectionFactor = value
505
+ else:
506
+ self.logger.error(
507
+ f"RaptorX setup use_plane_projection_factor setter must be a boolean. " f"Provided value {value}"
508
+ )
509
+
510
+ @property
511
+ def use_relaxed_z_axis(self):
512
+ """Enabling this option provides a simplified mesh along the z-axis."""
513
+ return self._advanced_settings.UseRelaxedZAxis
514
+
515
+ @use_relaxed_z_axis.setter
516
+ def use_relaxed_z_axis(self, value):
517
+ if isinstance(value, bool):
518
+ self._advanced_settings.UseRelaxedZAxis = value
519
+ else:
520
+ self.logger.error(f"RaptorX setup use_relaxed_z_axis setter must be a boolean. " f"Provided value {value}")
@@ -26,6 +26,8 @@ This module contains the `EdbPadstacks` class.
26
26
  import math
27
27
  import warnings
28
28
 
29
+ import rtree
30
+
29
31
  from pyedb.dotnet.clr_module import Array
30
32
  from pyedb.dotnet.edb_core.edb_data.padstacks_data import (
31
33
  EDBPadstack,
@@ -1460,3 +1462,54 @@ class EdbPadstacks(object):
1460
1462
  pin_dict = {GeometryOperators.points_distance(positive_pin.position, p.position): p for p in pinlist}
1461
1463
  pinlist = [pin[1] for pin in sorted(pin_dict.items())[:max_limit]]
1462
1464
  return pinlist
1465
+
1466
+ @pyedb_function_handler()
1467
+ def get_padstack_instances_rtree_index(self, nets=None):
1468
+ """Returns padstack instances Rtree index.
1469
+
1470
+ Parameters
1471
+ ----------
1472
+ nets : str or list, optional
1473
+ net name of list of nets name applying filtering on padstack instances selection. If ``None`` is provided
1474
+ all instances are included in the index. Default value is ``None``.
1475
+
1476
+ Returns
1477
+ -------
1478
+ Rtree index object.
1479
+
1480
+ """
1481
+ if isinstance(nets, str):
1482
+ nets = [nets]
1483
+ padstack_instances_index = rtree.index.Index()
1484
+ if nets:
1485
+ instances = [inst for inst in list(self.instances.values()) if inst.net_name in nets]
1486
+ else:
1487
+ instances = list(self.instances.values())
1488
+ for inst in instances:
1489
+ padstack_instances_index.insert(inst.id, inst.position)
1490
+ return padstack_instances_index
1491
+
1492
+ @pyedb_function_handler()
1493
+ def get_padstack_instances_intersecting_bounding_box(self, bounding_box, nets=None):
1494
+ """Returns the list of padstack instances ID intersecting a given bounding box and nets.
1495
+
1496
+ Parameters
1497
+ ----------
1498
+ bounding_box : tuple or list.
1499
+ bounding box, [x1, y1, x2, y2]
1500
+ nets : str or list, optional
1501
+ net name of list of nets name applying filtering on padstack instances selection. If ``None`` is provided
1502
+ all instances are included in the index. Default value is ``None``.
1503
+
1504
+ Returns
1505
+ -------
1506
+ List of padstack instances ID intersecting the bounding box.
1507
+ """
1508
+ if not bounding_box:
1509
+ raise Exception("No bounding box was provided")
1510
+ index = self.get_padstack_instances_rtree_index(nets=nets)
1511
+ if not len(bounding_box) == 4:
1512
+ raise Exception("The bounding box length must be equal to 4")
1513
+ if isinstance(bounding_box, list):
1514
+ bounding_box = tuple(bounding_box)
1515
+ return list(index.intersection(bounding_box))
@@ -56,6 +56,7 @@ class BaseSimulationSetup(object):
56
56
  "kDDRwizard": None,
57
57
  "kQ3D": None,
58
58
  "kNumSetupTypes": None,
59
+ "kRaptorX": self._pedb.simsetupdata.RaptorX.RaptorXSimulationSettings,
59
60
  }
60
61
  if self._edb_object:
61
62
  self._name = self._edb_object.GetName()
@@ -72,6 +73,8 @@ class BaseSimulationSetup(object):
72
73
  setup_type = self._setup_type_mapping[self._setup_type]
73
74
  edb_setup_info = self._pedb.simsetupdata.SimSetupInfo[setup_type]()
74
75
  edb_setup_info.Name = name
76
+ if edb_setup_info.get_SimSetupType().ToString() == "kRaptorX":
77
+ self._edb_setup_info = edb_setup_info
75
78
  self._edb_object = self._set_edb_setup_info(edb_setup_info)
76
79
  self._update_setup()
77
80
 
@@ -96,6 +99,9 @@ class BaseSimulationSetup(object):
96
99
  "kQ3D": None,
97
100
  "kNumSetupTypes": None,
98
101
  }
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
99
105
  setup_utility = setup_type_mapping[self._setup_type]
100
106
  return setup_utility(edb_setup_info)
101
107
 
@@ -122,9 +128,8 @@ class BaseSimulationSetup(object):
122
128
 
123
129
  @enabled.setter
124
130
  def enabled(self, value):
125
- edb_setup_info = self.get_sim_setup_info
126
- edb_setup_info.SimulationSettings.Enabled = value
127
- self._edb_object = self._set_edb_setup_info(edb_setup_info)
131
+ self.get_sim_setup_info.SimulationSettings.Enabled = value
132
+ self._edb_object = self._set_edb_setup_info(self.get_sim_setup_info)
128
133
  self._update_setup()
129
134
 
130
135
  @property
@@ -175,9 +180,12 @@ class BaseSimulationSetup(object):
175
180
  sweep_data: EdbFrequencySweep
176
181
  """
177
182
  self._sweep_list[sweep_data.name] = sweep_data
178
- edb_setup_info = self.get_sim_setup_info
183
+ if self.setup_type == "kRaptorX":
184
+ edb_setup_info = self._edb_setup_info
185
+ else:
186
+ edb_setup_info = self.get_sim_setup_info
179
187
 
180
- if self._setup_type in ["kSIwave", "kHFSS"]:
188
+ if self._setup_type in ["kSIwave", "kHFSS", "kRaptorX"]:
181
189
  for _, v in self._sweep_list.items():
182
190
  edb_setup_info.SweepDataList.Add(v._edb_object)
183
191
 
@@ -197,14 +205,13 @@ class BaseSimulationSetup(object):
197
205
  self._sweep_list.pop(name)
198
206
 
199
207
  fsweep = []
200
- for k, val in self.frequency_sweeps.items():
201
- if not k == name:
202
- fsweep.append(val)
203
- self.get_sim_setup_info.SweepDataList.Clear()
204
- for i in fsweep:
205
- self.get_sim_setup_info.SweepDataList.Add(i._edb_object)
206
- self._update_setup()
207
- return True if name in self.frequency_sweeps else False
208
+ if self.frequency_sweeps:
209
+ fsweep = [val for key, val in self.frequency_sweeps.items() if not key == name]
210
+ self.get_sim_setup_info.SweepDataList.Clear()
211
+ for i in fsweep:
212
+ self.get_sim_setup_info.SweepDataList.Add(i._edb_object)
213
+ self._update_setup()
214
+ return True if name in self.frequency_sweeps else False
208
215
 
209
216
  @pyedb_function_handler()
210
217
  def add_frequency_sweep(self, name=None, frequency_sweep=None):
@@ -722,6 +729,8 @@ class EdbFrequencySweep(object):
722
729
  ["linear scale", "0.1GHz", "10GHz", "0.1GHz"],
723
730
  ]
724
731
  temp = []
732
+ if isinstance(frequency_list, list) and not isinstance(frequency_list[0], list):
733
+ frequency_list = [frequency_list]
725
734
  for i in frequency_list:
726
735
  if i[0] == "linear count":
727
736
  temp.extend(list(self._edb_sweep_data.SetFrequencies(i[1], i[2], i[3])))
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: pyedb
3
- Version: 0.8.1
3
+ Version: 0.9.0
4
4
  Summary: Higher-Level Pythonic Ansys Electronics Data Base
5
5
  Author-email: "ANSYS, Inc." <pyansys.core@ansys.com>
6
6
  Maintainer-email: PyEDB developers <simon.vandenbrouck@ansys.com>
@@ -21,6 +21,7 @@ Requires-Dist: ansys-pythonnet >= 3.1.0rc3
21
21
  Requires-Dist: dotnetcore2 ==3.1.23;platform_system=='Linux'
22
22
  Requires-Dist: pydantic>=2.6.4,<2.8
23
23
  Requires-Dist: toml == 0.10.2
24
+ Requires-Dist: Rtree >= 1.2.0
24
25
  Requires-Dist: ansys-sphinx-theme>=0.10.0,<0.16 ; extra == "doc"
25
26
  Requires-Dist: imageio>=2.30.0,<2.35 ; extra == "doc"
26
27
  Requires-Dist: ipython>=8.13.0,<8.24 ; extra == "doc"
@@ -1,10 +1,10 @@
1
- pyedb/__init__.py,sha256=E32CaYS36_mPebFR8emGgxai-TPaWHCWwE9WpMwLBIs,1520
1
+ pyedb/__init__.py,sha256=-PeC-ezpiaDf1K0QUwu4B6kfQtg_3GxtEASzpnqsK2c,1520
2
2
  pyedb/edb_logger.py,sha256=yNkXnoL2me7ubLT6O6r6ElVnkZ1g8fmfFYC_2XJZ1Sw,14950
3
3
  pyedb/exceptions.py,sha256=n94xluzUks6BA24vd_L6HkrvoP_H_l6__hQmqzdCyPo,111
4
4
  pyedb/siwave.py,sha256=ilUsA74QKy7VpRfmfvRrcVZhPAsyfgXHZm0SDDHiGBE,11576
5
5
  pyedb/dotnet/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
6
6
  pyedb/dotnet/clr_module.py,sha256=Mo13Of3DVSA5HR-5xZEXOiHApIKy52CUxtJ2gPkEu1A,3406
7
- pyedb/dotnet/edb.py,sha256=wbzl9083scWVoWkYG5lQshBPuTnQlIiBq0P8x9zblik,169971
7
+ pyedb/dotnet/edb.py,sha256=OqZ7-tBRkzvgZLxELBW6b9BIJ8l2Eil6BIPA_1pj274,171632
8
8
  pyedb/dotnet/application/Variables.py,sha256=nov1kIyJO25iz8pvbU3MK1meMpRLwtISmzYqJhc7Ouo,79042
9
9
  pyedb/dotnet/application/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
10
10
  pyedb/dotnet/edb_core/__init__.py,sha256=nIRLJ8VZLcMAp12zmGsnZ5x2BEEl7q_Kj_KAOXxVjpQ,52
@@ -18,7 +18,7 @@ pyedb/dotnet/edb_core/materials.py,sha256=xYfud7EWDmK6O_hvANRqzFjp8ZqJdM0AJ8KYhU
18
18
  pyedb/dotnet/edb_core/net_class.py,sha256=lr-7Z0Q1A2fshxwjrIOmQSZnEBYe0NoxuUuJT6vYdyA,11857
19
19
  pyedb/dotnet/edb_core/nets.py,sha256=EK-jjRFvRX_NtqMQ46ebJbv9HOvP1uYK_EZ3jPnmxB0,43882
20
20
  pyedb/dotnet/edb_core/obj_base.py,sha256=lufR0sZj0QfZ2wlNvLL6aM1KVqCNY2A7taPPdWcK20w,3312
21
- pyedb/dotnet/edb_core/padstack.py,sha256=XT7S_RgOtYAr4G67EKXbbxsDeb6wMHC6Y_YMDljuMR4,54540
21
+ pyedb/dotnet/edb_core/padstack.py,sha256=h9NYecM5_Z00KeMkli-Sm97btbvnJsz2COSmyWfoVHA,56581
22
22
  pyedb/dotnet/edb_core/siwave.py,sha256=wdLAKiz0Qhiktz3OPekBQtw_y2Kb8Vyk19QdF-FcUVU,62356
23
23
  pyedb/dotnet/edb_core/stackup.py,sha256=vFHc9uroqdb193uHHNVRa1rxy-9Oe76eQZ98X2Kfx54,115372
24
24
  pyedb/dotnet/edb_core/cell/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -47,6 +47,7 @@ pyedb/dotnet/edb_core/edb_data/nets_data.py,sha256=iULEOUsn3sfLT5FVY_4lMWTm0KzC-
47
47
  pyedb/dotnet/edb_core/edb_data/padstacks_data.py,sha256=T7m7s5KAZB-gZ9wrPw6k2Yoon6uwCfJSOeg2hvyX1LI,78754
48
48
  pyedb/dotnet/edb_core/edb_data/ports.py,sha256=FYxB2rDUtN_OsYAbodXbc5mA_d0BUebmin_B5kkUw3U,9223
49
49
  pyedb/dotnet/edb_core/edb_data/primitives_data.py,sha256=veMDPCb6T84KZ_xgo52g7vHxObsx-Y2ysWXBS2CqZpQ,48155
50
+ pyedb/dotnet/edb_core/edb_data/raptor_x_simulation_setup_data.py,sha256=FPQ1myUhmBAyyAsqPQZnr0Y-_k-tvq-JhQtESp3ea0g,21065
50
51
  pyedb/dotnet/edb_core/edb_data/simulation_configuration.py,sha256=0U5sHLn8rvQFOveRQE3Y84TGk0-DUfOnbvEO6Iffya4,99967
51
52
  pyedb/dotnet/edb_core/edb_data/siwave_simulation_setup_data.py,sha256=fPmdhh6t6HM2pE_mQCT0ZQYO-PkqhwumwiuRUNEn00Q,42354
52
53
  pyedb/dotnet/edb_core/edb_data/sources.py,sha256=XmdpOdlpBa3QiYFY0cRtVIolt4nvUR9Ptk5YnRVvU4c,15342
@@ -58,7 +59,7 @@ pyedb/dotnet/edb_core/geometry/point_data.py,sha256=hC9cRuSnX4cwg09Jr0ZK7ZTjFf_4
58
59
  pyedb/dotnet/edb_core/geometry/polygon_data.py,sha256=K1jwj6gXm4KFqrPGJmtc49bSDZl1ytmrLdJ81VEJtco,2990
59
60
  pyedb/dotnet/edb_core/utilities/__init__.py,sha256=8jByHkoaowAYQTCww-zRrTQmN061fLz_OHjTLSrzQQY,58
60
61
  pyedb/dotnet/edb_core/utilities/heatsink.py,sha256=7G7Yx9TxbL5EAiR51MnhdRiAQBVf-d0hKsXDw5OYX2Q,2220
61
- pyedb/dotnet/edb_core/utilities/simulation_setup.py,sha256=uQMKL4cwWQkPD53BENHF9uyt1NxtPW0dMVAOPdI8gUM,23967
62
+ pyedb/dotnet/edb_core/utilities/simulation_setup.py,sha256=WuAY_eC3gISpp6aVcF_rgezQQqifvPdEQZGyyRUFpTY,24639
62
63
  pyedb/dotnet/sim_setup_data/data/siw_dc_ir_settings.py,sha256=urJvgBJOgF3Td527z98vdqAtBBKC3yomcAL3fOTt7xs,1931
63
64
  pyedb/generic/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
64
65
  pyedb/generic/constants.py,sha256=prWLZH0-SeBIVK6LHZ4SGZFQCofuym2TuQYfdqwhuSQ,28956
@@ -131,7 +132,7 @@ pyedb/misc/siw_feature_config/emc/net_tags.py,sha256=HVYOQacmaLr6Mvf7FqZhqbhtqJL
131
132
  pyedb/misc/siw_feature_config/emc/tag_library.py,sha256=yUK4w3hequU017E2DbkA4KE2MWIh1R6bfJBrevlDx6g,1557
132
133
  pyedb/misc/siw_feature_config/emc/xml_generic.py,sha256=55X-V0OxWq-v7FTiDVjaZif8V_2xxsvJlJ8bs9Bf61I,2521
133
134
  pyedb/modeler/geometry_operators.py,sha256=LDqEaeerw9H8Yva-SJhX3Afdni08OciO9t5G0c_tdqs,66820
134
- pyedb-0.8.1.dist-info/LICENSE,sha256=qQWivZ12ETN5l3QxvTARY-QI5eoRRlyHdwLlAj0Bg5I,1089
135
- pyedb-0.8.1.dist-info/WHEEL,sha256=EZbGkh7Ie4PoZfRQ8I0ZuP9VklN_TvcZ6DSE5Uar4z4,81
136
- pyedb-0.8.1.dist-info/METADATA,sha256=msQ9v6ZCjdGNLCwZmjC71Meue38wfQiFsgJhZTJIh3M,8320
137
- pyedb-0.8.1.dist-info/RECORD,,
135
+ pyedb-0.9.0.dist-info/LICENSE,sha256=qQWivZ12ETN5l3QxvTARY-QI5eoRRlyHdwLlAj0Bg5I,1089
136
+ pyedb-0.9.0.dist-info/WHEEL,sha256=EZbGkh7Ie4PoZfRQ8I0ZuP9VklN_TvcZ6DSE5Uar4z4,81
137
+ pyedb-0.9.0.dist-info/METADATA,sha256=agt4Ryp5D6tkoEv2hdVvEvo15DvymqpK-71wsXOrTps,8350
138
+ pyedb-0.9.0.dist-info/RECORD,,
File without changes
File without changes