pyedb 0.54.0__py3-none-any.whl → 0.56.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 -8
- pyedb/configuration/cfg_boundaries.py +69 -151
- pyedb/configuration/cfg_components.py +201 -460
- pyedb/configuration/cfg_data.py +4 -2
- pyedb/configuration/cfg_general.py +13 -36
- pyedb/configuration/cfg_modeler.py +2 -1
- pyedb/configuration/cfg_nets.py +21 -35
- pyedb/configuration/cfg_operations.py +22 -151
- pyedb/configuration/cfg_package_definition.py +56 -112
- pyedb/configuration/cfg_padstacks.py +292 -688
- pyedb/configuration/cfg_pin_groups.py +32 -79
- pyedb/configuration/cfg_ports_sources.py +19 -6
- pyedb/configuration/cfg_s_parameter_models.py +67 -172
- pyedb/configuration/cfg_setup.py +102 -295
- pyedb/configuration/configuration.py +64 -5
- pyedb/dotnet/database/Variables.py +26 -19
- pyedb/dotnet/database/cell/connectable.py +38 -9
- pyedb/dotnet/database/cell/hierarchy/component.py +28 -28
- pyedb/dotnet/database/cell/hierarchy/model.py +1 -1
- pyedb/dotnet/database/cell/layout.py +63 -2
- pyedb/dotnet/database/cell/layout_obj.py +2 -2
- pyedb/dotnet/database/cell/primitive/path.py +6 -8
- pyedb/dotnet/database/cell/primitive/primitive.py +3 -24
- pyedb/dotnet/database/cell/terminal/edge_terminal.py +2 -2
- pyedb/dotnet/database/cell/terminal/padstack_instance_terminal.py +1 -1
- pyedb/dotnet/database/cell/terminal/pingroup_terminal.py +1 -1
- pyedb/dotnet/database/cell/terminal/point_terminal.py +1 -1
- pyedb/dotnet/database/cell/terminal/terminal.py +24 -24
- pyedb/dotnet/database/cell/voltage_regulator.py +0 -21
- pyedb/dotnet/database/components.py +137 -124
- pyedb/dotnet/database/definition/component_def.py +4 -4
- pyedb/dotnet/database/definition/component_model.py +1 -1
- pyedb/dotnet/database/definition/package_def.py +2 -3
- pyedb/dotnet/database/dotnet/database.py +3 -199
- pyedb/dotnet/database/dotnet/primitive.py +3 -3
- pyedb/dotnet/database/edb_data/control_file.py +5 -5
- pyedb/dotnet/database/edb_data/hfss_extent_info.py +6 -6
- pyedb/dotnet/database/edb_data/layer_data.py +23 -23
- pyedb/dotnet/database/edb_data/padstacks_data.py +63 -88
- pyedb/dotnet/database/edb_data/primitives_data.py +5 -5
- pyedb/dotnet/database/edb_data/sources.py +6 -6
- pyedb/dotnet/database/edb_data/variables.py +1 -1
- pyedb/dotnet/database/geometry/point_data.py +14 -10
- pyedb/dotnet/database/geometry/polygon_data.py +3 -3
- pyedb/dotnet/database/hfss.py +46 -48
- pyedb/dotnet/database/layout_validation.py +14 -11
- pyedb/dotnet/database/materials.py +10 -11
- pyedb/dotnet/database/modeler.py +97 -91
- pyedb/dotnet/database/nets.py +19 -22
- pyedb/dotnet/database/padstack.py +171 -83
- pyedb/dotnet/database/siwave.py +42 -42
- pyedb/dotnet/database/stackup.py +140 -72
- pyedb/dotnet/database/utilities/heatsink.py +4 -4
- pyedb/dotnet/database/utilities/obj_base.py +2 -2
- pyedb/dotnet/database/utilities/simulation_setup.py +2 -2
- pyedb/dotnet/database/utilities/value.py +16 -16
- pyedb/dotnet/edb.py +230 -152
- pyedb/edb_logger.py +12 -27
- pyedb/extensions/create_cell_array.py +394 -0
- pyedb/extensions/via_design_backend.py +6 -3
- pyedb/generic/data_handlers.py +6 -7
- pyedb/generic/design_types.py +81 -30
- pyedb/generic/filesystem.py +5 -2
- pyedb/generic/general_methods.py +2 -122
- pyedb/generic/process.py +44 -108
- pyedb/generic/settings.py +79 -19
- pyedb/grpc/database/components.py +26 -4
- pyedb/grpc/database/control_file.py +5 -5
- pyedb/grpc/database/definition/materials.py +1 -1
- pyedb/grpc/database/definition/package_def.py +3 -3
- pyedb/grpc/database/definition/padstack_def.py +53 -0
- pyedb/grpc/database/geometry/polygon_data.py +1 -1
- pyedb/grpc/database/layout/layout.py +81 -5
- pyedb/grpc/database/layout_validation.py +5 -5
- pyedb/grpc/database/modeler.py +24 -16
- pyedb/grpc/database/net/net.py +15 -14
- pyedb/grpc/database/nets.py +70 -0
- pyedb/grpc/database/padstacks.py +122 -17
- pyedb/grpc/database/primitive/padstack_instance.py +175 -7
- pyedb/grpc/database/primitive/polygon.py +2 -2
- pyedb/grpc/database/simulation_setup/siwave_cpa_simulation_setup.py +3 -2
- pyedb/grpc/database/siwave.py +1 -1
- pyedb/grpc/database/source_excitations.py +12 -5
- pyedb/grpc/database/stackup.py +1 -1
- pyedb/grpc/database/terminal/bundle_terminal.py +1 -1
- pyedb/grpc/database/terminal/padstack_instance_terminal.py +1 -1
- pyedb/grpc/database/terminal/pingroup_terminal.py +1 -1
- pyedb/grpc/database/utility/value.py +1 -0
- pyedb/grpc/database/utility/xml_control_file.py +5 -5
- pyedb/grpc/edb.py +80 -30
- pyedb/grpc/edb_init.py +3 -3
- pyedb/grpc/rpc_session.py +14 -13
- pyedb/libraries/common.py +366 -0
- pyedb/libraries/rf_libraries/base_functions.py +1358 -0
- pyedb/libraries/rf_libraries/planar_antennas.py +628 -0
- pyedb/misc/decorators.py +61 -0
- pyedb/misc/misc.py +0 -13
- pyedb/modeler/geometry_operators.py +6 -6
- pyedb/siwave.py +6 -8
- pyedb/siwave_core/__init__.py +0 -0
- pyedb/siwave_core/cpa/__init__.py +0 -0
- {pyedb-0.54.0.dist-info → pyedb-0.56.0.dist-info}/METADATA +1 -2
- {pyedb-0.54.0.dist-info → pyedb-0.56.0.dist-info}/RECORD +105 -98
- {pyedb-0.54.0.dist-info → pyedb-0.56.0.dist-info}/WHEEL +0 -0
- {pyedb-0.54.0.dist-info → pyedb-0.56.0.dist-info}/licenses/LICENSE +0 -0
pyedb/dotnet/edb.py
CHANGED
|
@@ -48,7 +48,6 @@ from pyedb.dotnet.database.cell.layout import Layout
|
|
|
48
48
|
from pyedb.dotnet.database.cell.terminal.terminal import Terminal
|
|
49
49
|
from pyedb.dotnet.database.components import Components
|
|
50
50
|
import pyedb.dotnet.database.dotnet.database
|
|
51
|
-
from pyedb.dotnet.database.dotnet.database import Database
|
|
52
51
|
from pyedb.dotnet.database.edb_data.design_options import EdbDesignOptions
|
|
53
52
|
from pyedb.dotnet.database.edb_data.ports import (
|
|
54
53
|
BundleWavePort,
|
|
@@ -93,23 +92,18 @@ from pyedb.dotnet.database.utilities.siwave_simulation_setup import (
|
|
|
93
92
|
SiwaveSimulationSetup,
|
|
94
93
|
)
|
|
95
94
|
from pyedb.dotnet.database.utilities.value import Value
|
|
96
|
-
from pyedb.edb_logger import pyedb_logger
|
|
97
95
|
from pyedb.generic.constants import AEDT_UNITS, SolverType, unit_converter
|
|
98
|
-
from pyedb.generic.general_methods import
|
|
99
|
-
generate_unique_name,
|
|
100
|
-
get_string_version,
|
|
101
|
-
is_linux,
|
|
102
|
-
is_windows,
|
|
103
|
-
)
|
|
96
|
+
from pyedb.generic.general_methods import generate_unique_name, is_linux, is_windows
|
|
104
97
|
from pyedb.generic.process import SiwaveSolve
|
|
105
98
|
from pyedb.generic.settings import settings
|
|
106
99
|
from pyedb.ipc2581.ipc2581 import Ipc2581
|
|
100
|
+
from pyedb.misc.decorators import execution_timer
|
|
107
101
|
from pyedb.modeler.geometry_operators import GeometryOperators
|
|
108
102
|
from pyedb.siwave_core.product_properties import SIwaveProperties
|
|
109
103
|
from pyedb.workflow import Workflow
|
|
110
104
|
|
|
111
105
|
|
|
112
|
-
class Edb
|
|
106
|
+
class Edb:
|
|
113
107
|
"""Provides the EDB application interface.
|
|
114
108
|
|
|
115
109
|
This module inherits all objects that belong to EDB.
|
|
@@ -127,7 +121,7 @@ class Edb(Database):
|
|
|
127
121
|
isreadonly : bool, optional
|
|
128
122
|
Whether to open EBD in read-only mode when it is
|
|
129
123
|
owned by HFSS 3D Layout. The default is ``False``.
|
|
130
|
-
|
|
124
|
+
version : str, int, float, optional
|
|
131
125
|
Version of EDB to use. The default is ``None``.
|
|
132
126
|
Examples of input values are ``232``, ``23.2``, ``2023.2``, ``"2023.2"``.
|
|
133
127
|
isaedtowned : bool, optional
|
|
@@ -183,15 +177,28 @@ class Edb(Database):
|
|
|
183
177
|
|
|
184
178
|
"""
|
|
185
179
|
|
|
180
|
+
_db = None
|
|
181
|
+
|
|
182
|
+
@property
|
|
183
|
+
def logger(self):
|
|
184
|
+
return settings.logger
|
|
185
|
+
|
|
186
|
+
@property
|
|
187
|
+
def version(self):
|
|
188
|
+
return settings.specified_version
|
|
189
|
+
|
|
190
|
+
@property
|
|
191
|
+
def base_path(self):
|
|
192
|
+
return settings.aedt_installation_path
|
|
193
|
+
|
|
194
|
+
@execution_timer("EDB initialization")
|
|
186
195
|
def __init__(
|
|
187
196
|
self,
|
|
188
197
|
edbpath: Union[str, Path] = None,
|
|
189
198
|
cellname: str = None,
|
|
190
199
|
isreadonly: bool = False,
|
|
191
|
-
edbversion: str = None,
|
|
192
200
|
isaedtowned: bool = False,
|
|
193
201
|
oproject=None,
|
|
194
|
-
student_version: bool = False,
|
|
195
202
|
use_ppe: bool = False,
|
|
196
203
|
control_file: str = None,
|
|
197
204
|
map_file: str = None,
|
|
@@ -199,16 +206,15 @@ class Edb(Database):
|
|
|
199
206
|
layer_filter: str = None,
|
|
200
207
|
remove_existing_aedt: bool = False,
|
|
201
208
|
):
|
|
202
|
-
self._logger = pyedb_logger
|
|
203
209
|
now = datetime.now()
|
|
204
210
|
self.logger.info(f"Star initializing Edb {now.time()}")
|
|
205
211
|
|
|
206
212
|
if isinstance(edbpath, Path):
|
|
207
213
|
edbpath = str(edbpath)
|
|
208
214
|
|
|
209
|
-
edbversion = get_string_version(edbversion)
|
|
210
215
|
self._clean_variables()
|
|
211
|
-
|
|
216
|
+
self.__initialization()
|
|
217
|
+
|
|
212
218
|
self.standalone = True
|
|
213
219
|
self.oproject = oproject
|
|
214
220
|
self._main = sys.modules["__main__"]
|
|
@@ -261,9 +267,8 @@ class Edb(Database):
|
|
|
261
267
|
map_file=map_file,
|
|
262
268
|
):
|
|
263
269
|
raise AttributeError("Translation was unsuccessful")
|
|
264
|
-
return False
|
|
265
270
|
if settings.enable_local_log_file and self.log_name:
|
|
266
|
-
self.
|
|
271
|
+
self.logger.add_file_logger(self.log_name, "Edb")
|
|
267
272
|
self.logger.info("EDB %s was created correctly from %s file.", self.edbpath, edbpath)
|
|
268
273
|
elif edbpath[-3:] in ["brd", "mcm", "sip", "gds", "xml", "dxf", "tgz", "anf"]:
|
|
269
274
|
self.edbpath = edbpath[:-4] + ".aedb"
|
|
@@ -278,28 +283,25 @@ class Edb(Database):
|
|
|
278
283
|
map_file=map_file,
|
|
279
284
|
):
|
|
280
285
|
raise AttributeError("Translation was unsuccessful")
|
|
281
|
-
return False
|
|
282
286
|
if settings.enable_local_log_file and self.log_name:
|
|
283
|
-
self.
|
|
287
|
+
self.logger.add_file_logger(self.log_name, "Edb")
|
|
284
288
|
self.logger.info("EDB %s was created correctly from %s file.", self.edbpath, edbpath[-2:])
|
|
285
289
|
elif edbpath.endswith("edb.def"):
|
|
286
290
|
self.edbpath = os.path.dirname(edbpath)
|
|
287
291
|
if settings.enable_local_log_file and self.log_name:
|
|
288
|
-
self.
|
|
292
|
+
self.logger.add_file_logger(self.log_name, "Edb")
|
|
289
293
|
self.open_edb()
|
|
290
294
|
elif not os.path.exists(os.path.join(self.edbpath, "edb.def")):
|
|
291
295
|
self.create_edb()
|
|
292
296
|
if settings.enable_local_log_file and self.log_name:
|
|
293
|
-
self.
|
|
297
|
+
self.logger.add_file_logger(self.log_name, "Edb")
|
|
294
298
|
self.logger.info("EDB %s created correctly.", self.edbpath)
|
|
295
299
|
elif ".aedb" in edbpath:
|
|
296
300
|
self.edbpath = edbpath
|
|
297
301
|
if settings.enable_local_log_file and self.log_name:
|
|
298
|
-
self.
|
|
302
|
+
self.logger.add_file_logger(self.log_name, "Edb")
|
|
299
303
|
self.open_edb()
|
|
300
|
-
if self.active_cell:
|
|
301
|
-
self.logger.info(f"EDB initialized.Time lapse {datetime.now() - now}")
|
|
302
|
-
else:
|
|
304
|
+
if not self.active_cell:
|
|
303
305
|
raise AttributeError("Failed to initialize DLLs.")
|
|
304
306
|
|
|
305
307
|
def __enter__(self):
|
|
@@ -351,6 +353,35 @@ class Edb(Database):
|
|
|
351
353
|
if description: # Add the variable description if a two-item list is passed for variable_value.
|
|
352
354
|
self.__getitem__(variable_name).description = description
|
|
353
355
|
|
|
356
|
+
def __initialization(self):
|
|
357
|
+
self.logger.info(f"Edb version {self.version}")
|
|
358
|
+
|
|
359
|
+
"""Initialize DLLs."""
|
|
360
|
+
from pyedb import __version__
|
|
361
|
+
from pyedb.dotnet.clr_module import _clr, edb_initialized
|
|
362
|
+
|
|
363
|
+
if not edb_initialized: # pragma: no cover
|
|
364
|
+
raise RuntimeWarning("Failed to initialize Dlls.")
|
|
365
|
+
self.logger.info(f"Logger is initialized. Log file is saved to {self.logger.log_file}.")
|
|
366
|
+
self.logger.info("legacy v%s", __version__)
|
|
367
|
+
self.logger.info("Python version %s", sys.version)
|
|
368
|
+
|
|
369
|
+
sys.path.append(self.base_path)
|
|
370
|
+
|
|
371
|
+
_clr.AddReference("Ansys.Ansoft.Edb")
|
|
372
|
+
_clr.AddReference("Ansys.Ansoft.EdbBuilderUtils")
|
|
373
|
+
_clr.AddReference("Ansys.Ansoft.SimSetupData")
|
|
374
|
+
os.environ["ECAD_TRANSLATORS_INSTALL_DIR"] = self.base_path
|
|
375
|
+
oaDirectory = os.path.join(self.base_path, "common", "oa")
|
|
376
|
+
os.environ["ANSYS_OADIR"] = oaDirectory
|
|
377
|
+
os.environ["PATH"] = "{};{}".format(os.environ["PATH"], self.base_path)
|
|
378
|
+
edb = __import__("Ansys.Ansoft.Edb")
|
|
379
|
+
edbbuilder = __import__("Ansys.Ansoft.EdbBuilderUtils")
|
|
380
|
+
self.simSetup = __import__("Ansys.Ansoft.SimSetupData")
|
|
381
|
+
self._edb = edb.Ansoft.Edb
|
|
382
|
+
self.edbutils = edbbuilder.Ansoft.EdbBuilderUtils
|
|
383
|
+
self.simsetupdata = self.simSetup.Ansoft.SimSetupData.Data
|
|
384
|
+
|
|
354
385
|
def _check_remove_project_files(self, edbpath: str, remove_existing_aedt: bool) -> None:
|
|
355
386
|
aedt_file = os.path.splitext(edbpath)[0] + ".aedt"
|
|
356
387
|
files = [aedt_file, aedt_file + ".lock"]
|
|
@@ -403,10 +434,8 @@ class Edb(Database):
|
|
|
403
434
|
|
|
404
435
|
def value(self, val):
|
|
405
436
|
"""Convert a value into a pyedb value."""
|
|
406
|
-
if isinstance(val, self._edb.Utility.Value)
|
|
407
|
-
|
|
408
|
-
else:
|
|
409
|
-
return Value(self, self.core.utility.value(val))
|
|
437
|
+
val_ = val if isinstance(val, self._edb.Utility.Value) else self.edb_value(val)
|
|
438
|
+
return Value(self, val_)
|
|
410
439
|
|
|
411
440
|
@property
|
|
412
441
|
def grpc(self):
|
|
@@ -422,7 +451,7 @@ class Edb(Database):
|
|
|
422
451
|
list of cell names : List[str]
|
|
423
452
|
"""
|
|
424
453
|
names = []
|
|
425
|
-
for cell in self.
|
|
454
|
+
for cell in [i for i in list(self._db.CircuitCells)]:
|
|
426
455
|
names.append(cell.GetName())
|
|
427
456
|
return names
|
|
428
457
|
|
|
@@ -439,6 +468,10 @@ class Edb(Database):
|
|
|
439
468
|
d_var[i] = Variable(self, i)
|
|
440
469
|
return d_var
|
|
441
470
|
|
|
471
|
+
@property
|
|
472
|
+
def ansys_em_path(self):
|
|
473
|
+
return self.base_path
|
|
474
|
+
|
|
442
475
|
@property
|
|
443
476
|
def project_variables(self):
|
|
444
477
|
"""Get all project variables.
|
|
@@ -449,7 +482,7 @@ class Edb(Database):
|
|
|
449
482
|
|
|
450
483
|
"""
|
|
451
484
|
p_var = dict()
|
|
452
|
-
for i in self.
|
|
485
|
+
for i in self._db.GetVariableServer().GetAllVariableNames():
|
|
453
486
|
p_var[i] = Variable(self, i)
|
|
454
487
|
return p_var
|
|
455
488
|
|
|
@@ -567,6 +600,7 @@ class Edb(Database):
|
|
|
567
600
|
temp[name] = val
|
|
568
601
|
return temp
|
|
569
602
|
|
|
603
|
+
@execution_timer("open_edb")
|
|
570
604
|
def open_edb(self):
|
|
571
605
|
"""Open EDB.
|
|
572
606
|
|
|
@@ -575,32 +609,32 @@ class Edb(Database):
|
|
|
575
609
|
``True`` when succeed ``False`` if failed : bool
|
|
576
610
|
"""
|
|
577
611
|
# self.logger.info("EDB Path is %s", self.edbpath)
|
|
578
|
-
# self.logger.info("EDB Version is %s", self.
|
|
579
|
-
# if self.
|
|
612
|
+
# self.logger.info("EDB Version is %s", self.version)
|
|
613
|
+
# if self.version > "2023.1":
|
|
580
614
|
# self.standalone = False
|
|
581
615
|
|
|
582
|
-
self.
|
|
616
|
+
self.core.Database.SetRunAsStandAlone(self.standalone)
|
|
617
|
+
self._db = self.core.Database.Open(
|
|
618
|
+
self.edbpath,
|
|
619
|
+
self.isreadonly,
|
|
620
|
+
)
|
|
621
|
+
if self._db.IsNull():
|
|
622
|
+
raise AttributeError(f"Failed to open edb file {self.edbpath}")
|
|
583
623
|
|
|
584
|
-
|
|
585
|
-
self.open(self.edbpath, self.isreadonly)
|
|
586
|
-
if not self.active_db:
|
|
587
|
-
self.logger.warning("Error Opening db")
|
|
588
|
-
self._active_cell = None
|
|
589
|
-
return None
|
|
590
|
-
self.logger.info("Database {} Opened in {}".format(os.path.split(self.edbpath)[-1], self.edbversion))
|
|
624
|
+
self.logger.info("Database {} Opened in {}".format(os.path.split(self.edbpath)[-1], self.version))
|
|
591
625
|
|
|
592
626
|
self._active_cell = None
|
|
593
627
|
if self.cellname:
|
|
594
|
-
for cell in list(self.
|
|
628
|
+
for cell in [i for i in list(self._db.TopCircuitCells)]:
|
|
595
629
|
if cell.GetName() == self.cellname:
|
|
596
630
|
self._active_cell = cell
|
|
597
631
|
if self._active_cell is None:
|
|
598
|
-
for cell in list(self.
|
|
632
|
+
for cell in [i for i in list(self._db.CircuitCells)]:
|
|
599
633
|
if cell.GetName() == self.cellname:
|
|
600
634
|
self._active_cell = cell
|
|
601
635
|
# if self._active_cell is still None, set it to default cell
|
|
602
636
|
if self._active_cell is None:
|
|
603
|
-
self._active_cell = list(self.
|
|
637
|
+
self._active_cell = list(self._db.TopCircuitCells)[0]
|
|
604
638
|
self.logger.info("Cell %s Opened", self._active_cell.GetName())
|
|
605
639
|
if self._active_cell:
|
|
606
640
|
self._init_objects()
|
|
@@ -610,6 +644,17 @@ class Edb(Database):
|
|
|
610
644
|
|
|
611
645
|
return True
|
|
612
646
|
|
|
647
|
+
@property
|
|
648
|
+
def core(self):
|
|
649
|
+
"""Edb Dotnet Api class.
|
|
650
|
+
|
|
651
|
+
Returns
|
|
652
|
+
-------
|
|
653
|
+
:class:`pyedb.dotnet.database.dotnet.database.CellDotNet`
|
|
654
|
+
"""
|
|
655
|
+
return self._edb
|
|
656
|
+
|
|
657
|
+
@execution_timer("create_edb")
|
|
613
658
|
def create_edb(self):
|
|
614
659
|
"""Create EDB.
|
|
615
660
|
|
|
@@ -617,18 +662,20 @@ class Edb(Database):
|
|
|
617
662
|
-------
|
|
618
663
|
``True`` when succeed ``False`` if failed : bool
|
|
619
664
|
"""
|
|
620
|
-
# if self.
|
|
665
|
+
# if self.version > "2023.1":
|
|
621
666
|
# self.standalone = False
|
|
622
667
|
|
|
623
|
-
self.
|
|
624
|
-
|
|
625
|
-
|
|
668
|
+
self.core.Database.SetRunAsStandAlone(self.standalone)
|
|
669
|
+
|
|
670
|
+
self._db = self.core.Database.Create(self.edbpath)
|
|
671
|
+
|
|
672
|
+
if not self._db:
|
|
626
673
|
self.logger.warning("Error creating the database.")
|
|
627
674
|
self._active_cell = None
|
|
628
675
|
return None
|
|
629
676
|
if not self.cellname:
|
|
630
677
|
self.cellname = generate_unique_name("Cell")
|
|
631
|
-
self._active_cell = self.core.
|
|
678
|
+
self._active_cell = self.core.Cell.Cell.Create(self._db, self.core.Cell.CellType.CircuitCell, self.cellname)
|
|
632
679
|
if self._active_cell:
|
|
633
680
|
self._init_objects()
|
|
634
681
|
return True
|
|
@@ -690,6 +737,7 @@ class Edb(Database):
|
|
|
690
737
|
layer_filter,
|
|
691
738
|
)
|
|
692
739
|
|
|
740
|
+
@execution_timer("import_layout_file")
|
|
693
741
|
def import_layout_file(
|
|
694
742
|
self,
|
|
695
743
|
input_file,
|
|
@@ -770,8 +818,7 @@ class Edb(Database):
|
|
|
770
818
|
cmd_translator.append('-f="{}"'.format(layer_filter))
|
|
771
819
|
subprocess.run(cmd_translator)
|
|
772
820
|
if not os.path.exists(os.path.join(working_dir, aedb_name)):
|
|
773
|
-
|
|
774
|
-
return False
|
|
821
|
+
raise RuntimeWarning(f"Translator failed. command : {' '.join(cmd_translator)}")
|
|
775
822
|
else:
|
|
776
823
|
self.logger.info("Translation correctly completed")
|
|
777
824
|
self.edbpath = os.path.join(working_dir, aedb_name)
|
|
@@ -853,7 +900,7 @@ class Edb(Database):
|
|
|
853
900
|
@property
|
|
854
901
|
def active_db(self):
|
|
855
902
|
"""Database object."""
|
|
856
|
-
return self.
|
|
903
|
+
return self._db
|
|
857
904
|
|
|
858
905
|
@property
|
|
859
906
|
def active_cell(self):
|
|
@@ -911,7 +958,7 @@ class Edb(Database):
|
|
|
911
958
|
>>> edbapp = Edb("myproject.aedb")
|
|
912
959
|
>>> comp = edbapp.components.get_component_by_name("J1")
|
|
913
960
|
"""
|
|
914
|
-
if not self._components and self.
|
|
961
|
+
if not self._components and self._db:
|
|
915
962
|
self._components = Components(self)
|
|
916
963
|
return self._components
|
|
917
964
|
|
|
@@ -926,7 +973,7 @@ class Edb(Database):
|
|
|
926
973
|
mess = "`core_stackup` is deprecated.\n"
|
|
927
974
|
mess += " Use `app.stackup` directly to instantiate new stackup methods."
|
|
928
975
|
warnings.warn(mess, DeprecationWarning)
|
|
929
|
-
if not self._stackup and self.
|
|
976
|
+
if not self._stackup and self._db:
|
|
930
977
|
self._stackup = Stackup(self)
|
|
931
978
|
return self._stackup
|
|
932
979
|
|
|
@@ -974,7 +1021,7 @@ class Edb(Database):
|
|
|
974
1021
|
>>> edbapp.materials.add_debye_material("debye_mat", 5, 3, 0.02, 0.05, 1e5, 1e9)
|
|
975
1022
|
>>> edbapp.materials.add_djordjevicsarkar_material("djord_mat", 3.3, 0.02, 3.3)
|
|
976
1023
|
"""
|
|
977
|
-
if not self._materials and self.
|
|
1024
|
+
if not self._materials and self._db:
|
|
978
1025
|
self._materials = Materials(self)
|
|
979
1026
|
return self._materials
|
|
980
1027
|
|
|
@@ -1022,7 +1069,7 @@ class Edb(Database):
|
|
|
1022
1069
|
>>> ... )
|
|
1023
1070
|
"""
|
|
1024
1071
|
|
|
1025
|
-
if not self._padstack and self.
|
|
1072
|
+
if not self._padstack and self._db:
|
|
1026
1073
|
self._padstack = EdbPadstacks(self)
|
|
1027
1074
|
return self._padstack
|
|
1028
1075
|
|
|
@@ -1060,7 +1107,7 @@ class Edb(Database):
|
|
|
1060
1107
|
>>> edbapp = Edb("myproject.aedb")
|
|
1061
1108
|
>>> p2 = edbapp.siwave.create_circuit_port_on_net("U2A5", "V3P3_S0", "U2A5", "GND", 50, "test")
|
|
1062
1109
|
"""
|
|
1063
|
-
if not self._siwave and self.
|
|
1110
|
+
if not self._siwave and self._db:
|
|
1064
1111
|
self._siwave = EdbSiwave(self)
|
|
1065
1112
|
return self._siwave
|
|
1066
1113
|
|
|
@@ -1104,7 +1151,7 @@ class Edb(Database):
|
|
|
1104
1151
|
>>> sim_config.mesh_freq = "10Ghz"
|
|
1105
1152
|
>>> edbapp.hfss.configure_hfss_analysis_setup(sim_config)
|
|
1106
1153
|
"""
|
|
1107
|
-
if not self._hfss and self.
|
|
1154
|
+
if not self._hfss and self._db:
|
|
1108
1155
|
self._hfss = EdbHfss(self)
|
|
1109
1156
|
return self._hfss
|
|
1110
1157
|
|
|
@@ -1145,7 +1192,7 @@ class Edb(Database):
|
|
|
1145
1192
|
>>> edbapp.nets.find_and_fix_disjoint_nets("GND", keep_only_main_net=True)
|
|
1146
1193
|
"""
|
|
1147
1194
|
|
|
1148
|
-
if not self._nets and self.
|
|
1195
|
+
if not self._nets and self._db:
|
|
1149
1196
|
raise Exception("")
|
|
1150
1197
|
self._nets = EdbNets(self)
|
|
1151
1198
|
return self._nets
|
|
@@ -1165,7 +1212,7 @@ class Edb(Database):
|
|
|
1165
1212
|
>>> edbapp.net_classes
|
|
1166
1213
|
"""
|
|
1167
1214
|
|
|
1168
|
-
if self.
|
|
1215
|
+
if self._db:
|
|
1169
1216
|
return EdbNetClasses(self)
|
|
1170
1217
|
|
|
1171
1218
|
@property
|
|
@@ -1183,7 +1230,7 @@ class Edb(Database):
|
|
|
1183
1230
|
>>> edbapp.extended_nets
|
|
1184
1231
|
"""
|
|
1185
1232
|
|
|
1186
|
-
if self.
|
|
1233
|
+
if self._db:
|
|
1187
1234
|
return EdbExtendedNets(self)
|
|
1188
1235
|
|
|
1189
1236
|
@property
|
|
@@ -1200,7 +1247,7 @@ class Edb(Database):
|
|
|
1200
1247
|
>>> edbapp = Edb("myproject.aedb")
|
|
1201
1248
|
>>> edbapp.differential_pairs
|
|
1202
1249
|
"""
|
|
1203
|
-
if self.
|
|
1250
|
+
if self._db:
|
|
1204
1251
|
return EdbDifferentialPairs(self)
|
|
1205
1252
|
else: # pragma: no cover
|
|
1206
1253
|
return
|
|
@@ -1239,7 +1286,7 @@ class Edb(Database):
|
|
|
1239
1286
|
>>> edbapp = Edb("myproject.aedb")
|
|
1240
1287
|
>>> top_prims = edbapp.modeler.primitives_by_layer["TOP"]
|
|
1241
1288
|
"""
|
|
1242
|
-
if not self._core_primitives and self.
|
|
1289
|
+
if not self._core_primitives and self._db:
|
|
1243
1290
|
self._core_primitives = Modeler(self)
|
|
1244
1291
|
return self._core_primitives
|
|
1245
1292
|
|
|
@@ -1359,12 +1406,12 @@ class Edb(Database):
|
|
|
1359
1406
|
VoltageProbe,
|
|
1360
1407
|
) = range(0, 9)
|
|
1361
1408
|
|
|
1362
|
-
def edb_value(self,
|
|
1409
|
+
def edb_value(self, value, var_server=None):
|
|
1363
1410
|
"""Convert a value to an EDB value. Value can be a string, float or integer. Mainly used in internal calls.
|
|
1364
1411
|
|
|
1365
1412
|
Parameters
|
|
1366
1413
|
----------
|
|
1367
|
-
|
|
1414
|
+
value : str, float, int
|
|
1368
1415
|
|
|
1369
1416
|
|
|
1370
1417
|
Returns
|
|
@@ -1372,7 +1419,26 @@ class Edb(Database):
|
|
|
1372
1419
|
Instance of `Edb.Utility.Value`
|
|
1373
1420
|
|
|
1374
1421
|
"""
|
|
1375
|
-
|
|
1422
|
+
if isinstance(value, self.core.Utility.Value):
|
|
1423
|
+
return value
|
|
1424
|
+
if var_server:
|
|
1425
|
+
return self.core.Utility.Value(value, var_server)
|
|
1426
|
+
if isinstance(value, (int, float)):
|
|
1427
|
+
return self.core.Utility.Value(value)
|
|
1428
|
+
m1 = re.findall(r"(?<=[/+-/*//^/(/[])([a-z_A-Z/$]\w*)", str(value).replace(" ", ""))
|
|
1429
|
+
m2 = re.findall(r"^([a-z_A-Z/$]\w*)", str(value).replace(" ", ""))
|
|
1430
|
+
val_decomposed = list(set(m1).union(m2))
|
|
1431
|
+
if not val_decomposed:
|
|
1432
|
+
return self.core.Utility.Value(value)
|
|
1433
|
+
var_server_db = self._db.GetVariableServer()
|
|
1434
|
+
var_names = var_server_db.GetAllVariableNames()
|
|
1435
|
+
var_server_cell = self.active_cell.GetVariableServer()
|
|
1436
|
+
var_names_cell = var_server_cell.GetAllVariableNames()
|
|
1437
|
+
if set(val_decomposed).intersection(var_names_cell):
|
|
1438
|
+
return self.core.Utility.Value(value, var_server_cell)
|
|
1439
|
+
if set(val_decomposed).intersection(var_names):
|
|
1440
|
+
return self.core.Utility.Value(value, var_server_db)
|
|
1441
|
+
return self.core.Utility.Value(value)
|
|
1376
1442
|
|
|
1377
1443
|
def point_3d(self, x, y, z=0.0):
|
|
1378
1444
|
"""Compute the Edb 3d Point Data.
|
|
@@ -1390,7 +1456,25 @@ class Edb(Database):
|
|
|
1390
1456
|
-------
|
|
1391
1457
|
``Geometry.Point3DData``.
|
|
1392
1458
|
"""
|
|
1393
|
-
return self.core.
|
|
1459
|
+
return self.core.Geometry.Point3DData(self.edb_value(x), self.edb_value(y), self.edb_value(z))
|
|
1460
|
+
|
|
1461
|
+
def copy_cells(self, cells_to_copy):
|
|
1462
|
+
"""Copy Cells from other Databases or this Database into this Database.
|
|
1463
|
+
|
|
1464
|
+
Parameters
|
|
1465
|
+
----------
|
|
1466
|
+
cells_to_copy : list[:class:`Cell <ansys.edb.layout.Cell>`]
|
|
1467
|
+
Cells to copy.
|
|
1468
|
+
|
|
1469
|
+
Returns
|
|
1470
|
+
-------
|
|
1471
|
+
list[:class:`Cell <ansys.edb.layout.Cell>`]
|
|
1472
|
+
New Cells created in this Database.
|
|
1473
|
+
"""
|
|
1474
|
+
if not isinstance(cells_to_copy, list):
|
|
1475
|
+
cells_to_copy = [cells_to_copy]
|
|
1476
|
+
_dbCells = convert_py_list_to_net_list(cells_to_copy)
|
|
1477
|
+
return self._db.CopyCells(_dbCells)
|
|
1394
1478
|
|
|
1395
1479
|
def point_data(self, x, y=None):
|
|
1396
1480
|
"""Compute the Edb Point Data.
|
|
@@ -1408,9 +1492,9 @@ class Edb(Database):
|
|
|
1408
1492
|
``Geometry.PointData``.
|
|
1409
1493
|
"""
|
|
1410
1494
|
if y is None:
|
|
1411
|
-
return self.core.
|
|
1495
|
+
return self.core.Geometry.PointData(self.edb_value(x))
|
|
1412
1496
|
else:
|
|
1413
|
-
return self.core.
|
|
1497
|
+
return self.core.Geometry.PointData(self.edb_value(x), self.edb_value(y))
|
|
1414
1498
|
|
|
1415
1499
|
def _is_file_existing_and_released(self, filename):
|
|
1416
1500
|
if os.path.exists(filename):
|
|
@@ -1474,6 +1558,7 @@ class Edb(Database):
|
|
|
1474
1558
|
warnings.warn("Use new property :func:`close` instead.", DeprecationWarning)
|
|
1475
1559
|
return self.close()
|
|
1476
1560
|
|
|
1561
|
+
@execution_timer("Close Edb file")
|
|
1477
1562
|
def close(self, **kwargs):
|
|
1478
1563
|
"""Close EDB and cleanup variables.
|
|
1479
1564
|
|
|
@@ -1483,14 +1568,11 @@ class Edb(Database):
|
|
|
1483
1568
|
``True`` when successful, ``False`` when failed.
|
|
1484
1569
|
|
|
1485
1570
|
"""
|
|
1486
|
-
|
|
1571
|
+
self._db.Close()
|
|
1487
1572
|
|
|
1488
1573
|
if self.log_name and settings.enable_local_log_file:
|
|
1489
|
-
self.
|
|
1490
|
-
start_time = time.time()
|
|
1574
|
+
self.logger.remove_all_file_loggers()
|
|
1491
1575
|
self._wait_for_file_release()
|
|
1492
|
-
elapsed_time = time.time() - start_time
|
|
1493
|
-
self.logger.info("EDB file release time: {0:.2f}ms".format(elapsed_time * 1000.0))
|
|
1494
1576
|
self._clean_variables()
|
|
1495
1577
|
return True
|
|
1496
1578
|
|
|
@@ -1509,6 +1591,7 @@ class Edb(Database):
|
|
|
1509
1591
|
warnings.warn("Use new method :func:`save` instead.", DeprecationWarning)
|
|
1510
1592
|
return self.save()
|
|
1511
1593
|
|
|
1594
|
+
@execution_timer("Save Edb file")
|
|
1512
1595
|
def save(self):
|
|
1513
1596
|
"""Save the EDB file.
|
|
1514
1597
|
|
|
@@ -1519,11 +1602,8 @@ class Edb(Database):
|
|
|
1519
1602
|
|
|
1520
1603
|
"""
|
|
1521
1604
|
|
|
1522
|
-
|
|
1523
|
-
start_time = time.time()
|
|
1605
|
+
self._db.Save()
|
|
1524
1606
|
self._wait_for_file_release()
|
|
1525
|
-
elapsed_time = time.time() - start_time
|
|
1526
|
-
self.logger.info("EDB file save time: {0:.2f}ms".format(elapsed_time * 1000.0))
|
|
1527
1607
|
return True
|
|
1528
1608
|
|
|
1529
1609
|
def save_edb_as(self, path):
|
|
@@ -1547,7 +1627,8 @@ class Edb(Database):
|
|
|
1547
1627
|
warnings.warn("Use new property :func:`save_as` instead.", DeprecationWarning)
|
|
1548
1628
|
return self.save_as(path)
|
|
1549
1629
|
|
|
1550
|
-
|
|
1630
|
+
@execution_timer("EDB file save")
|
|
1631
|
+
def save_as(self, path):
|
|
1551
1632
|
"""Save the EDB file as another file.
|
|
1552
1633
|
|
|
1553
1634
|
Parameters
|
|
@@ -1562,22 +1643,19 @@ class Edb(Database):
|
|
|
1562
1643
|
|
|
1563
1644
|
"""
|
|
1564
1645
|
origin_name = "pyedb_" + os.path.splitext(os.path.split(self.edbpath)[-1])[0]
|
|
1565
|
-
|
|
1566
|
-
start_time = time.time()
|
|
1646
|
+
self._db.SaveAs(path, "")
|
|
1567
1647
|
self._wait_for_file_release()
|
|
1568
|
-
|
|
1569
|
-
self.logger.info("EDB file save time: {0:.2f}ms".format(elapsed_time * 1000.0))
|
|
1570
|
-
self.edbpath = self.directory
|
|
1648
|
+
self.edbpath = self._db.GetDirectory()
|
|
1571
1649
|
if self.log_name:
|
|
1572
|
-
self.
|
|
1650
|
+
self.logger.remove_file_logger(os.path.splitext(os.path.split(self.log_name)[-1])[0])
|
|
1573
1651
|
|
|
1574
1652
|
self.log_name = os.path.join(
|
|
1575
1653
|
os.path.dirname(path),
|
|
1576
1654
|
"pyedb_" + os.path.splitext(os.path.split(path)[-1])[0] + ".log",
|
|
1577
1655
|
)
|
|
1578
1656
|
if settings.enable_local_log_file:
|
|
1579
|
-
self.
|
|
1580
|
-
self.
|
|
1657
|
+
self.logger.add_file_logger(self.log_name, "Edb")
|
|
1658
|
+
self.logger.remove_file_logger(origin_name)
|
|
1581
1659
|
return True
|
|
1582
1660
|
|
|
1583
1661
|
def execute(self, func):
|
|
@@ -1644,7 +1722,7 @@ class Edb(Database):
|
|
|
1644
1722
|
):
|
|
1645
1723
|
if extent_type in [
|
|
1646
1724
|
"Conforming",
|
|
1647
|
-
self.core.
|
|
1725
|
+
self.core.Geometry.ExtentType.Conforming,
|
|
1648
1726
|
1,
|
|
1649
1727
|
]:
|
|
1650
1728
|
if use_pyaedt_extent:
|
|
@@ -1662,7 +1740,7 @@ class Edb(Database):
|
|
|
1662
1740
|
else:
|
|
1663
1741
|
_poly = self.layout.expanded_extent(
|
|
1664
1742
|
net_signals,
|
|
1665
|
-
self.core.
|
|
1743
|
+
self.core.Geometry.ExtentType.Conforming,
|
|
1666
1744
|
expansion_size,
|
|
1667
1745
|
False,
|
|
1668
1746
|
use_round_corner,
|
|
@@ -1670,12 +1748,12 @@ class Edb(Database):
|
|
|
1670
1748
|
)
|
|
1671
1749
|
elif extent_type in [
|
|
1672
1750
|
"Bounding",
|
|
1673
|
-
self.core.
|
|
1751
|
+
self.core.Geometry.ExtentType.BoundingBox,
|
|
1674
1752
|
0,
|
|
1675
1753
|
]:
|
|
1676
1754
|
_poly = self.layout.expanded_extent(
|
|
1677
1755
|
net_signals,
|
|
1678
|
-
self.core.
|
|
1756
|
+
self.core.Geometry.ExtentType.BoundingBox,
|
|
1679
1757
|
expansion_size,
|
|
1680
1758
|
False,
|
|
1681
1759
|
use_round_corner,
|
|
@@ -1696,7 +1774,7 @@ class Edb(Database):
|
|
|
1696
1774
|
else:
|
|
1697
1775
|
_poly = self.layout.expanded_extent(
|
|
1698
1776
|
net_signals,
|
|
1699
|
-
self.core.
|
|
1777
|
+
self.core.Geometry.ExtentType.Conforming,
|
|
1700
1778
|
expansion_size,
|
|
1701
1779
|
False,
|
|
1702
1780
|
use_round_corner,
|
|
@@ -1778,7 +1856,7 @@ class Edb(Database):
|
|
|
1778
1856
|
pass
|
|
1779
1857
|
finally:
|
|
1780
1858
|
unite_polys.extend(list(obj_data))
|
|
1781
|
-
_poly_unite = self.core.
|
|
1859
|
+
_poly_unite = self.core.Geometry.PolygonData.Unite(convert_py_list_to_net_list(unite_polys))
|
|
1782
1860
|
if len(_poly_unite) == 1:
|
|
1783
1861
|
self.logger.info("Correctly computed Extension at first iteration.")
|
|
1784
1862
|
return _poly_unite[0]
|
|
@@ -1849,7 +1927,7 @@ class Edb(Database):
|
|
|
1849
1927
|
if smart_cut:
|
|
1850
1928
|
objs_data = self._smart_cut(reference_list, expansion_size)
|
|
1851
1929
|
_polys.extend(objs_data)
|
|
1852
|
-
_poly = self.core.
|
|
1930
|
+
_poly = self.core.Geometry.PolygonData.GetConvexHullOfPolygons(convert_py_list_to_net_list(_polys))
|
|
1853
1931
|
_poly = _poly.Expand(expansion_size, tolerance, round_corner, round_extension)[0]
|
|
1854
1932
|
return _poly
|
|
1855
1933
|
|
|
@@ -1970,7 +2048,7 @@ class Edb(Database):
|
|
|
1970
2048
|
Examples
|
|
1971
2049
|
--------
|
|
1972
2050
|
>>> from pyedb import Edb
|
|
1973
|
-
>>> edb = Edb(r'C:\\test.aedb',
|
|
2051
|
+
>>> edb = Edb(r'C:\\test.aedb', version="2022.2")
|
|
1974
2052
|
>>> edb.logger.info_timer("Edb Opening")
|
|
1975
2053
|
>>> edb.logger.reset_timer()
|
|
1976
2054
|
>>> start = time.time()
|
|
@@ -2025,7 +2103,7 @@ class Edb(Database):
|
|
|
2025
2103
|
legacy_path = self.edbpath
|
|
2026
2104
|
if expansion_factor > 0 and not custom_extent:
|
|
2027
2105
|
start = time.time()
|
|
2028
|
-
self.
|
|
2106
|
+
self.save()
|
|
2029
2107
|
dummy_path = self.edbpath.replace(".aedb", "_smart_cutout_temp.aedb")
|
|
2030
2108
|
working_cutout = False
|
|
2031
2109
|
i = 1
|
|
@@ -2171,7 +2249,7 @@ class Edb(Database):
|
|
|
2171
2249
|
_dbCells = [_cutout]
|
|
2172
2250
|
|
|
2173
2251
|
if output_aedb_path:
|
|
2174
|
-
db2 = self.
|
|
2252
|
+
db2 = self.core.Database.Create(output_aedb_path)
|
|
2175
2253
|
_success = db2.Save()
|
|
2176
2254
|
_dbCells = convert_py_list_to_net_list(_dbCells)
|
|
2177
2255
|
db2.CopyCells(_dbCells) # Copies cutout cell/design to db2 project
|
|
@@ -2180,7 +2258,7 @@ class Edb(Database):
|
|
|
2180
2258
|
if not net.GetName() in included_nets_list:
|
|
2181
2259
|
net.Delete()
|
|
2182
2260
|
_success = db2.Save()
|
|
2183
|
-
for c in list(self.
|
|
2261
|
+
for c in list(self._db.TopCircuitCells):
|
|
2184
2262
|
if c.GetName() == _cutout.GetName():
|
|
2185
2263
|
c.Delete()
|
|
2186
2264
|
if open_cutout_at_end: # pragma: no cover
|
|
@@ -2205,7 +2283,7 @@ class Edb(Database):
|
|
|
2205
2283
|
for _cmp in _cmps:
|
|
2206
2284
|
_cmp.Delete()
|
|
2207
2285
|
except:
|
|
2208
|
-
self.
|
|
2286
|
+
self.logger.error("Failed to remove single pin components.")
|
|
2209
2287
|
db2.Close()
|
|
2210
2288
|
source = os.path.join(output_aedb_path, "edb.def.tmp")
|
|
2211
2289
|
target = os.path.join(output_aedb_path, "edb.def")
|
|
@@ -2310,7 +2388,7 @@ class Edb(Database):
|
|
|
2310
2388
|
from concurrent.futures import ThreadPoolExecutor
|
|
2311
2389
|
|
|
2312
2390
|
if output_aedb_path:
|
|
2313
|
-
self.
|
|
2391
|
+
self.save_as(output_aedb_path)
|
|
2314
2392
|
self.logger.info("Cutout Multithread started.")
|
|
2315
2393
|
expansion_size = self.edb_value(expansion_size).ToDouble()
|
|
2316
2394
|
|
|
@@ -2422,7 +2500,7 @@ class Edb(Database):
|
|
|
2422
2500
|
pins_to_preserve=pins_to_preserve,
|
|
2423
2501
|
inlcude_voids_in_extents=inlcude_voids_in_extents,
|
|
2424
2502
|
)
|
|
2425
|
-
if extent_type in ["Conforming", self.core.
|
|
2503
|
+
if extent_type in ["Conforming", self.core.Geometry.ExtentType.Conforming, 1]:
|
|
2426
2504
|
if extent_defeature > 0:
|
|
2427
2505
|
_poly = _poly.Defeature(extent_defeature)
|
|
2428
2506
|
_poly1 = _poly.CreateFromArcs(_poly.GetArcData(), True)
|
|
@@ -2433,7 +2511,7 @@ class Edb(Database):
|
|
|
2433
2511
|
self.logger.info(f"Number of voids included:{len(list(_poly1.Holes))}")
|
|
2434
2512
|
_poly = _poly1
|
|
2435
2513
|
if not _poly or _poly.IsNull():
|
|
2436
|
-
self.
|
|
2514
|
+
self.logger.error("Failed to create Extent.")
|
|
2437
2515
|
return []
|
|
2438
2516
|
self.logger.info_timer("Extent Creation")
|
|
2439
2517
|
self.logger.reset_timer()
|
|
@@ -2630,7 +2708,7 @@ class Edb(Database):
|
|
|
2630
2708
|
Examples
|
|
2631
2709
|
--------
|
|
2632
2710
|
>>> from pyedb import Edb
|
|
2633
|
-
>>> edb = Edb(r'C:\\test.aedb',
|
|
2711
|
+
>>> edb = Edb(r'C:\\test.aedb', version="2022.2")
|
|
2634
2712
|
>>> edb.logger.info_timer("Edb Opening")
|
|
2635
2713
|
>>> edb.logger.reset_timer()
|
|
2636
2714
|
>>> start = time.time()
|
|
@@ -2687,10 +2765,10 @@ class Edb(Database):
|
|
|
2687
2765
|
via.pin.Delete()
|
|
2688
2766
|
if netlist:
|
|
2689
2767
|
nets = [net.net_obj for net in temp_edb.layout.nets if net.name in netlist]
|
|
2690
|
-
_poly = temp_edb.layout.expanded_extent(nets, self.core.
|
|
2768
|
+
_poly = temp_edb.layout.expanded_extent(nets, self.core.Geometry.ExtentType.Conforming, 0.0, True, True, 1)
|
|
2691
2769
|
else:
|
|
2692
2770
|
nets = [net.api_object for net in temp_edb.layout.nets if "gnd" in net.name.lower()]
|
|
2693
|
-
_poly = temp_edb.layout.expanded_extent(nets, self.core.
|
|
2771
|
+
_poly = temp_edb.layout.expanded_extent(nets, self.core.Geometry.ExtentType.Conforming, 0.0, True, True, 1)
|
|
2694
2772
|
temp_edb.close_edb()
|
|
2695
2773
|
if _poly:
|
|
2696
2774
|
return _poly
|
|
@@ -2808,7 +2886,7 @@ class Edb(Database):
|
|
|
2808
2886
|
for pad in list(self.padstacks.definitions.keys()):
|
|
2809
2887
|
if pad == p.padstack_definition:
|
|
2810
2888
|
padstack = self.padstacks.definitions[pad].edb_padstack
|
|
2811
|
-
padstack_instance = self.core.
|
|
2889
|
+
padstack_instance = self.core.Cell.primitive.padstack_instance.create(
|
|
2812
2890
|
_cutout.GetLayout(),
|
|
2813
2891
|
net,
|
|
2814
2892
|
p.name,
|
|
@@ -2831,7 +2909,7 @@ class Edb(Database):
|
|
|
2831
2909
|
center_y,
|
|
2832
2910
|
radius,
|
|
2833
2911
|
) = void_circle.primitive_object.GetParameters(0.0, 0.0, 0.0)
|
|
2834
|
-
cloned_circle = self.core.
|
|
2912
|
+
cloned_circle = self.core.Cell.primitive.circle.create(
|
|
2835
2913
|
layout,
|
|
2836
2914
|
void_circle.layer_name,
|
|
2837
2915
|
void_circle.net,
|
|
@@ -2841,7 +2919,7 @@ class Edb(Database):
|
|
|
2841
2919
|
)
|
|
2842
2920
|
cloned_circle.SetIsNegative(True)
|
|
2843
2921
|
elif void_circle.type == "Polygon":
|
|
2844
|
-
cloned_polygon = self.core.
|
|
2922
|
+
cloned_polygon = self.core.Cell.primitive.polygon.create(
|
|
2845
2923
|
layout,
|
|
2846
2924
|
void_circle.layer_name,
|
|
2847
2925
|
void_circle.net,
|
|
@@ -2871,7 +2949,7 @@ class Edb(Database):
|
|
|
2871
2949
|
|
|
2872
2950
|
_dbCells = [_cutout]
|
|
2873
2951
|
if output_aedb_path:
|
|
2874
|
-
db2 = self.
|
|
2952
|
+
db2 = self.core.Database.Create(output_aedb_path)
|
|
2875
2953
|
if not db2.Save():
|
|
2876
2954
|
self.logger.error("Failed to create new Edb. Check if the path already exists and remove it.")
|
|
2877
2955
|
return []
|
|
@@ -2880,7 +2958,7 @@ class Edb(Database):
|
|
|
2880
2958
|
cell = list(cell_copied)[0]
|
|
2881
2959
|
cell.SetName(os.path.basename(output_aedb_path[:-5]))
|
|
2882
2960
|
db2.Save()
|
|
2883
|
-
for c in list(self.
|
|
2961
|
+
for c in list(self._db.TopCircuitCells):
|
|
2884
2962
|
if c.GetName() == _cutout.GetName():
|
|
2885
2963
|
c.Delete()
|
|
2886
2964
|
if open_cutout_at_end: # pragma: no cover
|
|
@@ -3027,13 +3105,13 @@ class Edb(Database):
|
|
|
3027
3105
|
--------
|
|
3028
3106
|
|
|
3029
3107
|
>>> from pyedb import Edb
|
|
3030
|
-
>>> edb = Edb(edbpath="C:\\temp\\myproject.aedb",
|
|
3108
|
+
>>> edb = Edb(edbpath="C:\\temp\\myproject.aedb", version="2023.2")
|
|
3031
3109
|
|
|
3032
3110
|
>>> options_config = {'UNITE_NETS' : 1, 'LAUNCH_Q3D' : 0}
|
|
3033
3111
|
>>> edb.write_export3d_option_config_file(r"C:\\temp", options_config)
|
|
3034
3112
|
>>> edb.export_hfss(r"C:\\temp")
|
|
3035
3113
|
"""
|
|
3036
|
-
siwave_s = SiwaveSolve(self
|
|
3114
|
+
siwave_s = SiwaveSolve(self)
|
|
3037
3115
|
return siwave_s.export_3d_cad("HFSS", path_to_output, net_list, num_cores, aedt_file_name, hidden=hidden)
|
|
3038
3116
|
|
|
3039
3117
|
def export_q3d(
|
|
@@ -3070,13 +3148,13 @@ class Edb(Database):
|
|
|
3070
3148
|
--------
|
|
3071
3149
|
|
|
3072
3150
|
>>> from pyedb import Edb
|
|
3073
|
-
>>> edb = Edb(edbpath="C:\\temp\\myproject.aedb",
|
|
3151
|
+
>>> edb = Edb(edbpath="C:\\temp\\myproject.aedb", version="2021.2")
|
|
3074
3152
|
>>> options_config = {'UNITE_NETS' : 1, 'LAUNCH_Q3D' : 0}
|
|
3075
3153
|
>>> edb.write_export3d_option_config_file("C:\\temp", options_config)
|
|
3076
3154
|
>>> edb.export_q3d("C:\\temp")
|
|
3077
3155
|
"""
|
|
3078
3156
|
|
|
3079
|
-
siwave_s = SiwaveSolve(self
|
|
3157
|
+
siwave_s = SiwaveSolve(self)
|
|
3080
3158
|
return siwave_s.export_3d_cad(
|
|
3081
3159
|
"Q3D",
|
|
3082
3160
|
path_to_output,
|
|
@@ -3121,13 +3199,13 @@ class Edb(Database):
|
|
|
3121
3199
|
|
|
3122
3200
|
>>> from pyedb import Edb
|
|
3123
3201
|
|
|
3124
|
-
>>> edb = Edb(edbpath="C:\\temp\\myproject.aedb",
|
|
3202
|
+
>>> edb = Edb(edbpath="C:\\temp\\myproject.aedb", version="2021.2")
|
|
3125
3203
|
|
|
3126
3204
|
>>> options_config = {'UNITE_NETS' : 1, 'LAUNCH_Q3D' : 0}
|
|
3127
3205
|
>>> edb.write_export3d_option_config_file("C:\\temp", options_config)
|
|
3128
3206
|
>>> edb.export_maxwell("C:\\temp")
|
|
3129
3207
|
"""
|
|
3130
|
-
siwave_s = SiwaveSolve(self
|
|
3208
|
+
siwave_s = SiwaveSolve(self)
|
|
3131
3209
|
return siwave_s.export_3d_cad(
|
|
3132
3210
|
"Maxwell",
|
|
3133
3211
|
path_to_output,
|
|
@@ -3145,11 +3223,8 @@ class Edb(Database):
|
|
|
3145
3223
|
str
|
|
3146
3224
|
Siwave project path.
|
|
3147
3225
|
"""
|
|
3148
|
-
process = SiwaveSolve(self
|
|
3149
|
-
|
|
3150
|
-
self.close()
|
|
3151
|
-
except:
|
|
3152
|
-
pass
|
|
3226
|
+
process = SiwaveSolve(self)
|
|
3227
|
+
self.close()
|
|
3153
3228
|
process.solve()
|
|
3154
3229
|
return self.edbpath[:-5] + ".siw"
|
|
3155
3230
|
|
|
@@ -3196,11 +3271,8 @@ class Edb(Database):
|
|
|
3196
3271
|
list
|
|
3197
3272
|
List of files generated.
|
|
3198
3273
|
"""
|
|
3199
|
-
process = SiwaveSolve(self
|
|
3200
|
-
|
|
3201
|
-
self.close()
|
|
3202
|
-
except:
|
|
3203
|
-
pass
|
|
3274
|
+
process = SiwaveSolve(self)
|
|
3275
|
+
self.close()
|
|
3204
3276
|
return process.export_dc_report(
|
|
3205
3277
|
siwave_project,
|
|
3206
3278
|
solution_name,
|
|
@@ -3226,7 +3298,7 @@ class Edb(Database):
|
|
|
3226
3298
|
"""
|
|
3227
3299
|
if "$" in variable_name:
|
|
3228
3300
|
if variable_name.index("$") == 0:
|
|
3229
|
-
var_server = self.
|
|
3301
|
+
var_server = self._db.GetVariableServer()
|
|
3230
3302
|
|
|
3231
3303
|
else:
|
|
3232
3304
|
var_server = self.active_cell.GetVariableServer()
|
|
@@ -3239,6 +3311,17 @@ class Edb(Database):
|
|
|
3239
3311
|
return True, var_server
|
|
3240
3312
|
return False, var_server
|
|
3241
3313
|
|
|
3314
|
+
def get_all_variable_names(self):
|
|
3315
|
+
"""Method added for compatibility with grpc.
|
|
3316
|
+
|
|
3317
|
+
Returns
|
|
3318
|
+
-------
|
|
3319
|
+
List[Str]
|
|
3320
|
+
List of variables name.
|
|
3321
|
+
|
|
3322
|
+
"""
|
|
3323
|
+
return list(self.variable_exists("")[1].GetAllVariableNames())
|
|
3324
|
+
|
|
3242
3325
|
def get_variable(self, variable_name):
|
|
3243
3326
|
"""Return Variable Value if variable exists.
|
|
3244
3327
|
|
|
@@ -3457,8 +3540,8 @@ class Edb(Database):
|
|
|
3457
3540
|
):
|
|
3458
3541
|
self.logger.info("Cutout processed.")
|
|
3459
3542
|
old_cell = self.active_cell.FindByName(
|
|
3460
|
-
self.
|
|
3461
|
-
self.core.
|
|
3543
|
+
self._db,
|
|
3544
|
+
self.core.Cell.CellType.CircuitCell,
|
|
3462
3545
|
old_cell_name,
|
|
3463
3546
|
)
|
|
3464
3547
|
if old_cell:
|
|
@@ -3798,7 +3881,7 @@ class Edb(Database):
|
|
|
3798
3881
|
if name in self.setups:
|
|
3799
3882
|
self.logger.error("Setup name already used in the layout")
|
|
3800
3883
|
return False
|
|
3801
|
-
version = self.
|
|
3884
|
+
version = self.version.split(".")
|
|
3802
3885
|
if int(version[0]) >= 2024 and int(version[-1]) >= 2 or int(version[0]) > 2024:
|
|
3803
3886
|
setup = RaptorXSimulationSetup(self).create(name)
|
|
3804
3887
|
return setup
|
|
@@ -3823,8 +3906,7 @@ class Edb(Database):
|
|
|
3823
3906
|
if name in self.setups:
|
|
3824
3907
|
self.logger.error("Setup name already used in the layout")
|
|
3825
3908
|
return False
|
|
3826
|
-
version
|
|
3827
|
-
if float(self.edbversion) < 2024.2:
|
|
3909
|
+
if float(self.version) < 2024.2:
|
|
3828
3910
|
self.logger.error("HFSSPI simulation only supported with Ansys release 2024R2 and higher")
|
|
3829
3911
|
return False
|
|
3830
3912
|
return HFSSPISimulationSetup(self, name=name)
|
|
@@ -3890,6 +3972,7 @@ class Edb(Database):
|
|
|
3890
3972
|
setattr(setup, k, v)
|
|
3891
3973
|
return setup
|
|
3892
3974
|
|
|
3975
|
+
@execution_timer("calculate_initial_extent")
|
|
3893
3976
|
def calculate_initial_extent(self, expansion_factor):
|
|
3894
3977
|
"""Compute a float representing the larger number between the dielectric thickness or trace width
|
|
3895
3978
|
multiplied by the nW factor. The trace width search is limited to nets with ports attached.
|
|
@@ -3950,7 +4033,7 @@ class Edb(Database):
|
|
|
3950
4033
|
edb_zones = {}
|
|
3951
4034
|
if not self.setups:
|
|
3952
4035
|
self.siwave.add_siwave_syz_analysis()
|
|
3953
|
-
self.
|
|
4036
|
+
self.save()
|
|
3954
4037
|
for zone_primitive in zone_primitives:
|
|
3955
4038
|
edb_zone_path = os.path.join(
|
|
3956
4039
|
working_directory,
|
|
@@ -3958,7 +4041,7 @@ class Edb(Database):
|
|
|
3958
4041
|
)
|
|
3959
4042
|
shutil.copytree(self.edbpath, edb_zone_path)
|
|
3960
4043
|
poly_data = zone_primitive.GetPolygonData()
|
|
3961
|
-
if self.
|
|
4044
|
+
if self._db.GetVersion()[0] >= 10:
|
|
3962
4045
|
edb_zones[edb_zone_path] = (zone_primitive.GetZoneId(), poly_data)
|
|
3963
4046
|
elif len(zone_primitives) == len(zone_ids):
|
|
3964
4047
|
edb_zones[edb_zone_path] = (zone_ids[0], poly_data)
|
|
@@ -3996,7 +4079,7 @@ class Edb(Database):
|
|
|
3996
4079
|
defined_ports = {}
|
|
3997
4080
|
project_connexions = None
|
|
3998
4081
|
for edb_path, zone_info in zone_dict.items():
|
|
3999
|
-
edb = Edb(
|
|
4082
|
+
edb = Edb(edbpath=edb_path)
|
|
4000
4083
|
edb.cutout(
|
|
4001
4084
|
use_pyaedt_cutout=True,
|
|
4002
4085
|
custom_extent=zone_info[1],
|
|
@@ -4568,10 +4651,9 @@ class Edb(Database):
|
|
|
4568
4651
|
``True`` when succeeded, ``False`` if failed.
|
|
4569
4652
|
"""
|
|
4570
4653
|
if not temp_directory:
|
|
4571
|
-
|
|
4572
|
-
return False
|
|
4654
|
+
raise RuntimeWarning("Temp directory must be provided when creating model foe arbitrary wave port")
|
|
4573
4655
|
if mounting_side not in ["top", "bottom"]:
|
|
4574
|
-
|
|
4656
|
+
raise RuntimeWarning(
|
|
4575
4657
|
"Mounting side must be provided and only `top` or `bottom` are supported. Setting to "
|
|
4576
4658
|
"`top` will take the top layer from the current design as reference. Setting to `bottom` "
|
|
4577
4659
|
"will take the bottom one."
|
|
@@ -4604,11 +4686,10 @@ class Edb(Database):
|
|
|
4604
4686
|
if poly.layer_name == reference_layer and poly.type == "Polygon" and poly.has_voids
|
|
4605
4687
|
]
|
|
4606
4688
|
if not polys:
|
|
4607
|
-
|
|
4689
|
+
raise RuntimeWarning(
|
|
4608
4690
|
f"No polygon found with voids on layer {reference_layer} during model creation for "
|
|
4609
4691
|
f"arbitrary wave ports"
|
|
4610
4692
|
)
|
|
4611
|
-
return False
|
|
4612
4693
|
void_padstacks = []
|
|
4613
4694
|
for poly in polys:
|
|
4614
4695
|
for void in poly.voids:
|
|
@@ -4623,11 +4704,10 @@ class Edb(Database):
|
|
|
4623
4704
|
void_padstacks.append((void, [self.padstacks.instances[edb_id] for edb_id in included_instances]))
|
|
4624
4705
|
|
|
4625
4706
|
if not void_padstacks:
|
|
4626
|
-
|
|
4707
|
+
raise RuntimeWarning(
|
|
4627
4708
|
"No padstack instances found inside evaluated voids during model creation for arbitrary" "waveports"
|
|
4628
4709
|
)
|
|
4629
|
-
|
|
4630
|
-
cloned_edb = Edb(edbpath=output_edb, edbversion=self.edbversion)
|
|
4710
|
+
cloned_edb = Edb(edbpath=output_edb)
|
|
4631
4711
|
|
|
4632
4712
|
cloned_edb.stackup.add_layer(
|
|
4633
4713
|
layer_name="ports",
|
|
@@ -4681,7 +4761,7 @@ class Edb(Database):
|
|
|
4681
4761
|
net_name=inst.net_name,
|
|
4682
4762
|
)
|
|
4683
4763
|
if not _temp_circle:
|
|
4684
|
-
|
|
4764
|
+
raise RuntimeWarning(
|
|
4685
4765
|
f"Failed to create circle for terminal during create_model_for_arbitrary_wave_ports"
|
|
4686
4766
|
)
|
|
4687
4767
|
cloned_edb.save_as(output_edb)
|
|
@@ -4764,7 +4844,6 @@ class Edb(Database):
|
|
|
4764
4844
|
bool
|
|
4765
4845
|
``True`` when successful, ``False`` when failed.
|
|
4766
4846
|
"""
|
|
4767
|
-
self.save()
|
|
4768
4847
|
if not results:
|
|
4769
4848
|
results = self.edbpath[:-5] + "_compare_results"
|
|
4770
4849
|
os.mkdir(results)
|
|
@@ -4774,11 +4853,10 @@ class Edb(Database):
|
|
|
4774
4853
|
cmd_input = [mono_path, command, input_file, self.edbpath, results]
|
|
4775
4854
|
else:
|
|
4776
4855
|
cmd_input = [command, input_file, self.edbpath, results]
|
|
4777
|
-
subprocess.run(cmd_input)
|
|
4778
|
-
|
|
4779
|
-
|
|
4780
|
-
self.logger.error("Comparison execution failed")
|
|
4781
|
-
return False
|
|
4856
|
+
p = subprocess.run(cmd_input)
|
|
4857
|
+
if p.returncode == 0:
|
|
4858
|
+
return str(Path(self.base_path).joinpath("EDBDiff.exe"))
|
|
4782
4859
|
else:
|
|
4783
|
-
|
|
4784
|
-
|
|
4860
|
+
raise RuntimeError(
|
|
4861
|
+
"EDBDiff.exe execution failed. Please check if the executable is present in the base path."
|
|
4862
|
+
)
|