pyedb 0.50.0__py3-none-any.whl → 0.51.2__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of pyedb might be problematic. Click here for more details.

Files changed (75) hide show
  1. pyedb/__init__.py +1 -1
  2. pyedb/configuration/cfg_ports_sources.py +79 -239
  3. pyedb/configuration/configuration.py +27 -0
  4. pyedb/dotnet/clr_module.py +9 -3
  5. pyedb/dotnet/database/cell/hierarchy/component.py +3 -3
  6. pyedb/dotnet/database/cell/layout.py +10 -1
  7. pyedb/dotnet/database/dotnet/database.py +0 -2
  8. pyedb/dotnet/database/edb_data/padstacks_data.py +13 -0
  9. pyedb/dotnet/database/layout_validation.py +17 -13
  10. pyedb/dotnet/database/modeler.py +0 -1
  11. pyedb/dotnet/edb.py +7 -1
  12. pyedb/generic/design_types.py +183 -62
  13. pyedb/grpc/database/components.py +604 -652
  14. pyedb/grpc/database/control_file.py +597 -155
  15. pyedb/grpc/database/definition/component_def.py +17 -14
  16. pyedb/grpc/database/definition/materials.py +27 -27
  17. pyedb/grpc/database/definition/package_def.py +8 -8
  18. pyedb/grpc/database/definition/padstack_def.py +31 -33
  19. pyedb/grpc/database/definitions.py +36 -2
  20. pyedb/grpc/database/geometry/arc_data.py +5 -5
  21. pyedb/grpc/database/geometry/point_3d_data.py +3 -3
  22. pyedb/grpc/database/geometry/polygon_data.py +5 -5
  23. pyedb/grpc/database/hfss.py +412 -395
  24. pyedb/grpc/database/hierarchy/component.py +67 -58
  25. pyedb/grpc/database/hierarchy/pin_pair_model.py +6 -6
  26. pyedb/grpc/database/hierarchy/pingroup.py +13 -11
  27. pyedb/grpc/database/hierarchy/s_parameter_model.py +1 -1
  28. pyedb/grpc/database/hierarchy/spice_model.py +1 -1
  29. pyedb/grpc/database/layers/layer.py +2 -2
  30. pyedb/grpc/database/layers/stackup_layer.py +26 -23
  31. pyedb/grpc/database/layout/layout.py +12 -12
  32. pyedb/grpc/database/layout/voltage_regulator.py +8 -8
  33. pyedb/grpc/database/layout_validation.py +58 -7
  34. pyedb/grpc/database/modeler.py +248 -245
  35. pyedb/grpc/database/net/differential_pair.py +4 -4
  36. pyedb/grpc/database/net/extended_net.py +7 -8
  37. pyedb/grpc/database/net/net.py +57 -46
  38. pyedb/grpc/database/nets.py +362 -116
  39. pyedb/grpc/database/padstacks.py +259 -178
  40. pyedb/grpc/database/ports/ports.py +23 -17
  41. pyedb/grpc/database/primitive/padstack_instance.py +45 -30
  42. pyedb/grpc/database/primitive/path.py +6 -6
  43. pyedb/grpc/database/primitive/polygon.py +9 -9
  44. pyedb/grpc/database/primitive/primitive.py +21 -21
  45. pyedb/grpc/database/primitive/rectangle.py +1 -1
  46. pyedb/grpc/database/simulation_setup/hfss_advanced_settings.py +1 -1
  47. pyedb/grpc/database/simulation_setup/hfss_general_settings.py +1 -1
  48. pyedb/grpc/database/simulation_setup/hfss_settings_options.py +1 -1
  49. pyedb/grpc/database/simulation_setup/hfss_simulation_settings.py +6 -6
  50. pyedb/grpc/database/simulation_setup/hfss_simulation_setup.py +2 -2
  51. pyedb/grpc/database/simulation_setup/raptor_x_simulation_settings.py +2 -2
  52. pyedb/grpc/database/simulation_setup/raptor_x_simulation_setup.py +1 -1
  53. pyedb/grpc/database/simulation_setup/siwave_simulation_setup.py +3 -3
  54. pyedb/grpc/database/siwave.py +226 -214
  55. pyedb/grpc/database/source_excitations.py +307 -40
  56. pyedb/grpc/database/stackup.py +461 -283
  57. pyedb/grpc/database/terminal/bundle_terminal.py +12 -12
  58. pyedb/grpc/database/terminal/edge_terminal.py +6 -5
  59. pyedb/grpc/database/terminal/padstack_instance_terminal.py +13 -13
  60. pyedb/grpc/database/terminal/pingroup_terminal.py +12 -12
  61. pyedb/grpc/database/terminal/point_terminal.py +6 -6
  62. pyedb/grpc/database/terminal/terminal.py +26 -26
  63. pyedb/grpc/database/utility/heat_sink.py +5 -5
  64. pyedb/grpc/database/utility/hfss_extent_info.py +21 -21
  65. pyedb/grpc/database/utility/layout_statistics.py +13 -13
  66. pyedb/grpc/database/utility/rlc.py +3 -3
  67. pyedb/grpc/database/utility/sources.py +1 -1
  68. pyedb/grpc/database/utility/sweep_data_distribution.py +1 -1
  69. pyedb/grpc/edb.py +542 -739
  70. pyedb/grpc/edb_init.py +50 -3
  71. {pyedb-0.50.0.dist-info → pyedb-0.51.2.dist-info}/METADATA +1 -1
  72. {pyedb-0.50.0.dist-info → pyedb-0.51.2.dist-info}/RECORD +74 -75
  73. pyedb/grpc/database/utility/simulation_configuration.py +0 -3305
  74. {pyedb-0.50.0.dist-info → pyedb-0.51.2.dist-info}/LICENSE +0 -0
  75. {pyedb-0.50.0.dist-info → pyedb-0.51.2.dist-info}/WHEEL +0 -0
pyedb/grpc/edb.py CHANGED
@@ -20,10 +20,40 @@
20
20
  # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
21
  # SOFTWARE.
22
22
 
23
- """This module contains the ``Edb`` class.
24
-
25
- This module is implicitly loaded in HFSS 3D Layout when launched.
26
-
23
+ """Provides the main interface for interacting with Ansys Electronics Desktop Database (EDB).
24
+
25
+ This module contains the ``Edb`` class which serves as the primary interface for:
26
+ - Creating and managing EDB projects
27
+ - Importing/exporting layout files
28
+ - Configuring stackups, materials, and components
29
+ - Setting up simulations (HFSS, SIwave, RaptorX)
30
+ - Performing cutout operations
31
+ - Generating ports and excitations
32
+ - Parametrizing designs
33
+ - Exporting to various formats (IPC2581, HFSS, Q3D)
34
+
35
+ Key Functionality:
36
+ - Database initialization and management
37
+ - Layout manipulation and cutout generation
38
+ - Material and stackup configuration
39
+ - Net and component management
40
+ - Simulation setup and execution
41
+ - Design parametrization and optimization
42
+
43
+ Examples
44
+ --------
45
+ Basic EDB initialization:
46
+ >>> from pyedb.grpc.edb import Edb
47
+ >>> edb = Edb(edbpath="myproject.aedb")
48
+
49
+ Importing a board file:
50
+ >>> edb.import_layout_file("my_board.brd")
51
+
52
+ Creating a cutout:
53
+ >>> edb.cutout(signal_list=["Net1", "Net2"], reference_list=["GND"])
54
+
55
+ Exporting to HFSS:
56
+ >>> edb.export_hfss(r"C:\output_folder")
27
57
  """
28
58
 
29
59
  from itertools import combinations
@@ -102,100 +132,60 @@ from pyedb.workflow import Workflow
102
132
 
103
133
 
104
134
  class Edb(EdbInit):
105
- """Provides the EDB application interface.
135
+ """Main class for interacting with Ansys Electronics Desktop Database (EDB).
106
136
 
107
- This module inherits all objects that belong to EDB.
137
+ Provides comprehensive control over EDB projects including:
138
+ - Project creation/management
139
+ - Layout import/export
140
+ - Material/stackup configuration
141
+ - Component/net management
142
+ - Simulation setup
143
+ - Cutout operations
144
+ - Parameterization
108
145
 
109
146
  Parameters
110
147
  ----------
111
- edbpath : str, optional
112
- Full path to the ``aedb`` folder. The variable can also contain
113
- the path to a layout to import. Allowed formats are BRD, MCM,
114
- XML (IPC2581), GDS, ODB++(TGZ and ZIP) and DXF. The default is ``None``.
115
- For GDS import, the Ansys control file (also XML) should have the same
116
- name as the GDS file. Only the file extension differs.
148
+ edbpath : str or Path, optional
149
+ Full path to AEDB folder or layout file to import. Supported formats:
150
+ BRD, MCM, XML (IPC2581), GDS, ODB++ (TGZ/ZIP), DXF.
151
+ Default creates new AEDB in documents folder.
117
152
  cellname : str, optional
118
- Name of the cell to select. The default is ``None``.
153
+ Specific cell to open. Default opens first cell.
119
154
  isreadonly : bool, optional
120
- Whether to open EBD in read-only mode when it is
121
- owned by HFSS 3D Layout. The default is ``False``.
155
+ Open in read-only mode. Default False.
122
156
  edbversion : str, int, float, optional
123
- Version of EDB to use. The default is ``None``.
124
- Examples of input values are ``232``, ``23.2``, ``2023.2``, ``"2023.2"``.
157
+ EDB version (e.g., "2023.2", 232, 23.2). Default uses latest.
125
158
  isaedtowned : bool, optional
126
- Whether to launch EDB from HFSS 3D Layout. The
127
- default is ``False``.
128
- oproject : optional
129
- Reference to the AEDT project object.
159
+ Launch from HFSS 3D Layout. Default False.
160
+ oproject : object, optional
161
+ Reference to AEDT project object.
130
162
  student_version : bool, optional
131
- Whether to open the AEDT student version. The default is ``False.``
163
+ Use student version. Default False.
164
+ use_ppe : bool, optional
165
+ Use PPE license. Default False.
132
166
  control_file : str, optional
133
- Path to the XML file. The default is ``None``, in which case an attempt is made to find
134
- the XML file in the same directory as the board file. To succeed, the XML file and board file
135
- must have the same name. Only the extension differs.
167
+ XML control file path for import.
136
168
  map_file : str, optional
137
- Layer map .map file.
169
+ Layer map file for import.
138
170
  technology_file : str, optional
139
- Full path to technology file to be converted to xml before importing or xml.
140
- Supported by GDS format only.
141
- layer_filter:str,optional
142
- Layer filter .txt file.
171
+ Technology file for import (GDS only).
172
+ layer_filter : str, optional
173
+ Layer filter file for import.
174
+ remove_existing_aedt : bool, optional
175
+ Remove existing AEDT project files. Default False.
143
176
  restart_rpc_server : bool, optional
144
- ``True`` RPC server is terminated and restarted. This will close all open EDB. RPC server is running on single
145
- instance loading all EDB, enabling this option should be used with caution but can be a solution to release
146
- memory in case the server is draining resources. Default value is ``False``.
177
+ Restart gRPC server. Use with caution. Default False.
147
178
 
148
179
  Examples
149
180
  --------
150
- Create :class:`Edb <pyedb.grpc.edb.Edb>` object.
151
-
152
- >>> from pyedb.grpc.edb import Edb as Edb
153
- >>> app = Edb()
154
-
155
- Add a new variable named "s1" to the ``Edb`` instance.
156
-
157
- >>> app['s1'] = "0.25 mm"
158
- >>> app['s1']
159
- >>> 0.00025
160
-
161
- Create an ``Edb`` object and open the specified project.
162
-
163
- >>> app = Edb(edbpath="myfile.aedb")
164
-
165
- Create an ``Edb`` object from GDS and control files.
166
- The XML control file resides in the same directory as the GDS file: (myfile.xml).
167
-
168
- >>> app = Edb("/path/to/file/myfile.gds")
169
-
170
- Loading Ansys layout
171
-
172
- >>> from ansys.aedt.core.generic.general_methods import generate_unique_folder_name
173
- >>> import pyedb.misc.downloads as downloads
174
- >>> temp_folder = generate_unique_folder_name()
175
- >>> targetfile = downloads.download_file("edb/ANSYS-HSD_V1.aedb", destination=temp_folder)
176
- >>> from pyedb.grpc.edb import Edb as Edb
177
- >>> edbapp = Edb(edbpath=targetfile)
178
-
179
- Retrieving signal nets dictionary
180
-
181
- >>> edbapp.nets.signal
182
-
183
- Retrieving layers
184
-
185
- >>> edbapp.stackup.layers
181
+ Create new EDB:
182
+ >>> edb = Edb()
186
183
 
187
- Retrieving all component instances
188
-
189
- >>> edbapp.components.instances
190
-
191
- Retrieving all padstacks definitions
192
-
193
- >>> edbapp.padstacks.definitions
194
-
195
- Retrieving component pins
196
-
197
- >>> edbapp.components["U1"].pins
184
+ Open existing AEDB:
185
+ >>> edb = Edb("myproject.aedb")
198
186
 
187
+ Import board file:
188
+ >>> edb = Edb("my_board.brd")
199
189
  """
200
190
 
201
191
  def __init__(
@@ -309,38 +299,39 @@ class Edb(EdbInit):
309
299
  self._layout_instance = None
310
300
 
311
301
  def __enter__(self):
302
+ """Context manager entry."""
312
303
  return self
313
304
 
314
305
  def __exit__(self, ex_type, ex_value, ex_traceback):
306
+ """Context manager exit. Closes EDB and cleans up resources."""
315
307
  self._signal_handler(ex_type, ex_value)
316
308
 
317
309
  def __getitem__(self, variable_name):
318
- """Get a variable to the Edb project. The variable can be project using ``$`` prefix or
319
- it can be a design variable, in which case the ``$`` is omitted.
310
+ """Get project or design variable value.
320
311
 
321
312
  Parameters
322
313
  ----------
323
314
  variable_name : str
315
+ Variable name with '$' for project variables.
324
316
 
325
317
  Returns
326
318
  -------
327
- variable object.
328
-
319
+ float or None
320
+ Variable value if exists, else None.
329
321
  """
330
322
  if self.variable_exists(variable_name):
331
323
  return self.variables[variable_name]
332
324
  return
333
325
 
334
326
  def __setitem__(self, variable_name, variable_value):
335
- """Set a variable to the Edb project. The variable can be project using ``$`` prefix or
336
- it can be a design variable, in which case the ``$`` is omitted.
327
+ """Set project or design variable.
337
328
 
338
329
  Parameters
339
330
  ----------
340
331
  variable_name : str
341
- variable name.
342
- variable_value : str, float, int.
343
- variable value.
332
+ Variable name (with '$' prefix for project variables).
333
+ variable_value : str, float, int, list/tuple
334
+ Value with units. List/tuple format: [value, description]
344
335
  """
345
336
  type_error_message = "Allowed values are str, numeric or two-item list with variable description."
346
337
  if type(variable_value) in [
@@ -387,23 +378,6 @@ class Edb(EdbInit):
387
378
  except:
388
379
  self.logger.info(f"Failed to delete AEDT project-related file {file}.")
389
380
 
390
- def _clean_variables(self):
391
- """Initialize internal variables and perform garbage collection."""
392
- self.grpc = True
393
- self._materials = None
394
- self._components = None
395
- self._core_primitives = None
396
- self._stackup = None
397
- self._padstack = None
398
- self._siwave = None
399
- self._hfss = None
400
- self._nets = None
401
- self._layout_instance = None
402
- self._variables = None
403
- self._active_cell = None
404
- self._layout = None
405
- self._configuration = None
406
-
407
381
  def _init_objects(self):
408
382
  self._components = Components(self)
409
383
  self._stackup = Stackup(self, self.layout.layer_collection)
@@ -419,53 +393,56 @@ class Edb(EdbInit):
419
393
 
420
394
  @property
421
395
  def cell_names(self) -> [str]:
422
- """Cell name container.
396
+ """List of all cell names in the database.
423
397
 
424
398
  Returns
425
399
  -------
426
- list of cell names : List[str]
400
+ list[str]
401
+ Names of all circuit cells.
427
402
  """
428
403
  return [cell.name for cell in self.active_db.top_circuit_cells]
429
404
 
430
405
  @property
431
406
  def design_variables(self) -> dict[str, float]:
432
- """Get all edb design variables.
407
+ """All design variables in active cell.
433
408
 
434
409
  Returns
435
410
  -------
436
- variable dictionary : Dict[str, variable_name: float, variable_value]
411
+ dict[str, float]
412
+ Variable names and values.
437
413
  """
438
414
  return {i: self.active_cell.get_variable_value(i).value for i in self.active_cell.get_all_variable_names()}
439
415
 
440
416
  @property
441
417
  def project_variables(self) -> dict[str, float]:
442
- """Get all project variables.
418
+ """All project variables in database.
443
419
 
444
420
  Returns
445
421
  -------
446
- variables dictionary : dict[str, variable_name: float, variable_value]
447
-
422
+ dict[str, float]
423
+ Variable names and values.
448
424
  """
449
425
  return {i: self.active_db.get_variable_value(i).value for i in self.active_db.get_all_variable_names()}
450
426
 
451
427
  @property
452
428
  def layout_validation(self) -> LayoutValidation:
453
- """Return LayoutValidation object.
429
+ """Layout validation utilities.
454
430
 
455
431
  Returns
456
432
  -------
457
433
  :class:`LayoutValidation <pyedb.grpc.database.layout_validation.LayoutValidation>`
434
+ Tools for design rule checking and layout validation.
458
435
  """
459
436
  return LayoutValidation(self)
460
437
 
461
438
  @property
462
439
  def variables(self) -> dict[str, float]:
463
- """Get all Edb variables.
440
+ """All variables (project + design) in database.
464
441
 
465
442
  Returns
466
443
  -------
467
- variables dictionary : Dict[str: float]
468
-
444
+ dict[str, float]
445
+ Combined dictionary of all variables.
469
446
  """
470
447
  all_vars = dict()
471
448
  for i, j in self.project_variables.items():
@@ -476,23 +453,24 @@ class Edb(EdbInit):
476
453
 
477
454
  @property
478
455
  def terminals(self) -> dict[str, Terminal]:
479
- """Get terminals belonging to active layout.
456
+ """Terminals in active layout.
480
457
 
481
458
  Returns
482
459
  -------
483
- Dict : Dict[str: :class:`Terminal <pyedb.grpc.database.terminal.terminal.Terminal>`],
460
+ dict[str, :class:`Terminal <pyedb.grpc.database.terminal.terminal.Terminal>`]
461
+ Terminal names and objects.
484
462
  """
485
463
  return {i.name: i for i in self.layout.terminals}
486
464
 
487
465
  @property
488
466
  def excitations(self) -> dict[str, GapPort]:
489
- """Get all layout excitations.
467
+ """All layout excitations.
490
468
 
491
469
  Returns
492
470
  -------
493
- Dict: Dict[str: :class:`<pyedb.grpc.database.port.GapPort>`]
471
+ dict[str, :class:`GapPort <pyedb.grpc.database.ports.ports.GapPort>`]
472
+ Excitation names and objects.
494
473
  """
495
-
496
474
  terms = [term for term in self.layout.terminals if term.boundary_type == "port"]
497
475
  temp = {}
498
476
  for term in terms:
@@ -504,13 +482,12 @@ class Edb(EdbInit):
504
482
 
505
483
  @property
506
484
  def ports(self) -> dict[str, GapPort]:
507
- """Get all ports.
485
+ """All ports in design.
508
486
 
509
487
  Returns
510
488
  -------
511
- port dictionary : Dict[str: :class:`GapPort <pyedb.grpc.database.ports.GapPort>` or
512
- :class:`WavePort <pyedb.grpc.database.ports.WavePort>`]
513
-
489
+ dict[str, Union[:class:`GapPort`, :class:`WavePort`, :class:`CoaxPort`]]
490
+ Port names and objects.
514
491
  """
515
492
  terminals = [term for term in self.layout.terminals if not term.is_reference_terminal]
516
493
  ports = {}
@@ -538,34 +515,34 @@ class Edb(EdbInit):
538
515
 
539
516
  @property
540
517
  def excitations_nets(self) -> [str]:
541
- """Get all net names with excitation defined.
518
+ """Nets with excitations defined.
542
519
 
543
520
  Returns
544
521
  -------
545
- List[str]
546
- List of net name.
522
+ list[str]
523
+ Net names with excitations.
547
524
  """
548
525
  return list(set([i.net.name for i in self.layout.terminals if not i.is_reference_terminal]))
549
526
 
550
527
  @property
551
528
  def sources(self) -> dict[str, Terminal]:
552
- """Get all layout sources.
529
+ """All layout sources.
553
530
 
554
531
  Returns
555
532
  -------
556
- Dict: Dic[str, :class:`Terminal <pyedb.grpc.database.terminal.terminal.Terminal>`]
533
+ dict[str, :class:`Terminal <pyedb.grpc.database.terminal.terminal.Terminal>`]
534
+ Source names and objects.
557
535
  """
558
536
  return self.terminals
559
537
 
560
538
  @property
561
539
  def voltage_regulator_modules(self):
562
- """Get all voltage regulator modules
540
+ """Voltage regulator modules in design.
563
541
 
564
542
  Returns
565
543
  -------
566
- List of voltage regulator modules.
567
- List[:class:`VoltageRegulator <pyedb.grpc.database.layout.voltage_regulator.VoltageRegulator>`]
568
-
544
+ dict[str, :class:`VoltageRegulator <pyedb.grpc.database.layout.voltage_regulator.VoltageRegulator>`]
545
+ VRM names and objects.
569
546
  """
570
547
  vrms = self.layout.voltage_regulators
571
548
  _vrms = {}
@@ -575,28 +552,34 @@ class Edb(EdbInit):
575
552
 
576
553
  @property
577
554
  def probes(self) -> dict[str, Terminal]:
578
- """Get all layout probes.
555
+ """All layout probes.
579
556
 
580
557
  Returns
581
558
  -------
582
- Dictionary of probes.
583
- Dict[str, :class:`Terminal <pyedb.grpc.database.terminal.terminal.Terminal>`
559
+ dict[str, :class:`Terminal <pyedb.grpc.database.terminal.terminal.Terminal>`]
560
+ Probe names and objects.
584
561
  """
585
562
  terms = [term for term in self.layout.terminals if term.boundary_type.value == 8]
586
563
  return {ter.name: ter for ter in terms}
587
564
 
588
- def open_edb(self, restart_rpc_server=False) -> bool:
589
- """Open EDB.
565
+ def open(self, restart_rpc_server=False) -> bool:
566
+ """Open EDB database.
590
567
 
591
568
  Returns
592
569
  -------
593
- bool: `True` when succeed `False` if failed.
570
+ bool
571
+ True if successful, False otherwise.
572
+
573
+ Examples
574
+ --------
575
+ Open an existing EDB database:
576
+ >>> edb = Edb("myproject.aedb")
594
577
  """
595
578
  self.standalone = self.standalone
596
579
  n_try = 10
597
580
  while not self.db and n_try:
598
581
  try:
599
- self.open(
582
+ self._open(
600
583
  self.edbpath,
601
584
  self.isreadonly,
602
585
  restart_rpc_server=restart_rpc_server,
@@ -626,12 +609,27 @@ class Edb(EdbInit):
626
609
  self.logger.error("Builder was not initialized.")
627
610
  return True
628
611
 
629
- def create_edb(self, restart_rpc_server=False) -> bool:
630
- """Create EDB.
612
+ def open_edb(self, restart_rpc_server=False) -> bool:
613
+ """Open EDB database.
614
+
615
+ .. deprecated:: 0.50.1
616
+ Use :func:`open` instead.
631
617
 
632
618
  Returns
633
619
  -------
634
- bool: `True` when succeed `False` if failed.
620
+ bool
621
+ True if successful, False otherwise.
622
+ """
623
+ warnings.warn("`open_edb` is deprecated use `open` instead.", DeprecationWarning)
624
+ return self.open(restart_rpc_server)
625
+
626
+ def create(self, restart_rpc_server=False) -> any:
627
+ """Create new EDB database.
628
+
629
+ Returns
630
+ -------
631
+ bool
632
+ True if successful, False otherwise.
635
633
  """
636
634
  from ansys.edb.core.layout.cell import Cell as GrpcCell
637
635
  from ansys.edb.core.layout.cell import CellType as GrpcCellType
@@ -640,7 +638,7 @@ class Edb(EdbInit):
640
638
  n_try = 10
641
639
  while not self.db and n_try:
642
640
  try:
643
- self.create(self.edbpath, restart_rpc_server=restart_rpc_server)
641
+ self._create(self.edbpath, restart_rpc_server=restart_rpc_server)
644
642
  n_try -= 1
645
643
  except Exception as e:
646
644
  self.logger.error(e.args[0])
@@ -655,9 +653,22 @@ class Edb(EdbInit):
655
653
  )
656
654
  if self._active_cell:
657
655
  self._init_objects()
658
- return True
656
+ return self
659
657
  return None
660
658
 
659
+ def create_edb(self, restart_rpc_server=False) -> bool:
660
+ """
661
+ .. deprecated:: 0.50.1
662
+ Use :func:`create` instead.
663
+
664
+ Returns
665
+ -------
666
+ bool
667
+ True if successful, False otherwise.
668
+ """
669
+ warnings.warn("`create_edb` is deprecated use `create` instead.", DeprecationWarning)
670
+ return self.create(restart_rpc_server)
671
+
661
672
  def import_layout_pcb(
662
673
  self,
663
674
  input_file,
@@ -669,38 +680,33 @@ class Edb(EdbInit):
669
680
  tech_file=None,
670
681
  layer_filter=None,
671
682
  ):
672
- """Import a board file and generate an ``edb.def`` file in the working directory.
673
-
674
- .. deprecated:: 0.42.0
675
- Use :func:`import_layout_file` method instead.
683
+ """Import layout file and generate AEDB.
676
684
 
677
- This function supports all AEDT formats, including DXF, GDS, SML (IPC2581), BRD, MCM, SIP, ZIP and TGZ.
685
+ Supported formats: BRD, MCM, XML (IPC2581), GDS, ODB++ (TGZ/ZIP), DXF
678
686
 
679
687
  Parameters
680
688
  ----------
681
689
  input_file : str
682
- Full path to the board file.
690
+ Full path to input file.
683
691
  working_dir : str, optional
684
- Directory in which to create the ``aedb`` folder. The name given to the AEDB file
685
- is the same as the name of the board file.
692
+ Output directory for AEDB.
686
693
  anstranslator_full_path : str, optional
687
- Full path to the Ansys translator. The default is ``""``.
688
- use_ppe : bool
689
- Whether to use the PPE License. The default is ``False``.
694
+ Path to Ansys translator executable.
695
+ use_ppe : bool, optional
696
+ Use PPE license. Default False.
690
697
  control_file : str, optional
691
- Path to the XML file. The default is ``None``, in which case an attempt is made to find
692
- the XML file in the same directory as the board file. To succeed, the XML file and board file
693
- must have the same name. Only the extension differs.
698
+ XML control file path.
694
699
  tech_file : str, optional
695
- Technology file. The file can be *.ircx, *.vlc.tech, or *.itf
700
+ Technology file path.
696
701
  map_file : str, optional
697
- Layer map .map file.
698
- layer_filter:str,optional
699
- Layer filter .txt file.
702
+ Layer map file path.
703
+ layer_filter : str, optional
704
+ Layer filter file path.
700
705
 
701
706
  Returns
702
707
  -------
703
- Full path to the AEDB file : str
708
+ str or bool
709
+ AEDB path if successful, False otherwise.
704
710
  """
705
711
  self.logger.warning("import_layout_pcb method is deprecated, use import_layout_file instead.")
706
712
  return self.import_layout_file(
@@ -755,6 +761,13 @@ class Edb(EdbInit):
755
761
  -------
756
762
  Full path to the AEDB file : str
757
763
 
764
+ Examples
765
+ --------
766
+ Import a BRD file:
767
+ >>> edb.import_layout_file("my_board.brd", r"C:/project")
768
+
769
+ Import a GDS file with control file:
770
+ >>> edb.import_layout_file("layout.gds", control_file="control.xml")
758
771
  """
759
772
  self._components = None
760
773
  self._core_primitives = None
@@ -802,29 +815,24 @@ class Edb(EdbInit):
802
815
  return self.open_edb()
803
816
 
804
817
  def export_to_ipc2581(self, ipc_path=None, units="MILLIMETER") -> str:
805
- """Create an XML IPC2581 file from the active EDB.
806
-
807
- .. note::
808
- The method works only in CPython because of some limitations on Ironpython in XML parsing and
809
- because it's time-consuming.
810
- This method is still being tested and may need further debugging.
811
- Any feedback is welcome. Back drills and custom pads are not supported yet.
818
+ """Export design to IPC2581 format.
812
819
 
813
820
  Parameters
814
821
  ----------
815
822
  ipc_path : str, optional
816
- Path to the XML IPC2581 file. The default is ``None``, in which case
817
- an attempt is made to find the XML IPC2581 file in the same directory
818
- as the active EDB. To succeed, the XML IPC2581 file and the active
819
- EDT must have the same name. Only the extension differs.
823
+ Output XML file path. Default: <edb_path>.xml.
820
824
  units : str, optional
821
- Units of the XML IPC2581 file. Options are ``"millimeter"``,
822
- ``"inch"``, and ``"micron"``. The default is ``"millimeter"``.
825
+ Output units ("millimeter", "inch", "micron"). Default millimeter.
823
826
 
824
827
  Returns
825
828
  -------
826
- bool: `True` if successful, `False` if failed.
829
+ str or bool
830
+ Output file path if successful, False otherwise.
827
831
 
832
+ Examples
833
+ --------
834
+ Export to IPC2581 format:
835
+ >>> edb.export_to_ipc2581("output.xml")
828
836
  """
829
837
  if units.lower() not in ["millimeter", "inch", "micron"]: # pragma no cover
830
838
  self.logger.warning("The wrong unit is entered. Setting to the default, millimeter.")
@@ -848,30 +856,26 @@ class Edb(EdbInit):
848
856
 
849
857
  @property
850
858
  def configuration(self) -> Configuration:
851
- """Edb project configuration from a file.
859
+ """Project configuration manager.
852
860
 
853
861
  Returns
854
862
  -------
855
- :class:`Configuration <pyedb.configuration.configuration.Configuration>`.
863
+ :class:`Configuration <pyedb.configuration.configuration.Configuration>`
864
+ Configuration file interface.
856
865
  """
857
866
  if not self._configuration:
858
867
  self._configuration = Configuration(self)
859
868
  return self._configuration
860
869
 
861
870
  def edb_exception(self, ex_value, tb_data):
862
- """Write the trace stack to AEDT when a Python error occurs.
871
+ """Log Python exceptions to EDB logger.
863
872
 
864
873
  Parameters
865
874
  ----------
866
- ex_value :
867
-
868
- tb_data :
869
-
870
-
871
- Returns
872
- -------
873
- None
874
-
875
+ ex_value : Exception
876
+ Exception value.
877
+ tb_data : traceback
878
+ Traceback object.
875
879
  """
876
880
  tb_trace = traceback.format_tb(tb_data)
877
881
  tblist = tb_trace[0].split("\n")
@@ -881,26 +885,40 @@ class Edb(EdbInit):
881
885
 
882
886
  @property
883
887
  def active_db(self):
884
- """Database object.
888
+ """Active database object.
885
889
 
886
890
  Returns
887
891
  -------
888
- :class:`Database <ansys.edb.core.database.Database>`.
892
+ :class:`ansys.edb.core.database.Database`
893
+ Current database instance.
889
894
  """
890
895
  return self.db
891
896
 
892
897
  @property
893
898
  def active_cell(self):
894
- """Active cell.
899
+ """Active cell in the database.
895
900
 
896
901
  Returns
897
902
  -------
898
- :class:`Cell <ansys.edb.core.layout.cell.Cell>`.
903
+ :class:`ansys.edb.core.layout.cell.Cell`
904
+ Currently active cell.
899
905
  """
900
906
  return self._active_cell
901
907
 
902
908
  @active_cell.setter
903
909
  def active_cell(self, value):
910
+ """Set active cell by name or object.
911
+
912
+ Parameters
913
+ ----------
914
+ value : str or ansys.edb.core.layout.cell.Cell
915
+ Cell name or object to set as active.
916
+
917
+ Raises
918
+ ------
919
+ ValueError
920
+ If cell not found in database.
921
+ """
904
922
  if isinstance(value, str):
905
923
  _cell = [cell for cell in self.circuit_cells if cell.name == value]
906
924
  if _cell:
@@ -918,17 +936,12 @@ class Edb(EdbInit):
918
936
 
919
937
  @property
920
938
  def components(self) -> Components:
921
- """Edb Components methods and properties.
939
+ """Component management interface.
922
940
 
923
941
  Returns
924
942
  -------
925
- :class:`Components <pyedb.grpc.database.components.Components>`.
926
-
927
- Examples
928
- --------
929
- >>> from pyedb import Edb
930
- >>> edbapp = Edb("myproject.aedb")
931
- >>> comp = edbapp.components.get_component_by_name("J1")
943
+ :class:`Components <pyedb.grpc.database.components.Components>`
944
+ Component manipulation tools.
932
945
  """
933
946
  if not self._components and self.active_db:
934
947
  self._components = Components(self)
@@ -936,19 +949,12 @@ class Edb(EdbInit):
936
949
 
937
950
  @property
938
951
  def stackup(self) -> Stackup:
939
- """Stackup manager.
952
+ """Stackup management interface.
940
953
 
941
954
  Returns
942
955
  -------
943
956
  :class:`Stackup <pyedb.grpc.database.stackup.Stackup>`
944
-
945
- Examples
946
- --------
947
- >>> from pyedb.grpc.edb import Edb
948
- >>> edbapp = Edb("myproject.aedb")
949
- >>> edbapp.stackup.layers["TOP"].thickness = 4e-5
950
- >>> edbapp.stackup.layers["TOP"].thickness == 4e-05
951
- >>> edbapp.stackup.add_layer("Diel", "GND", layer_type="dielectric", thickness="0.1mm", material="FR4_epoxy")
957
+ Layer stack configuration tools.
952
958
  """
953
959
  if self.active_db:
954
960
  self._stackup = Stackup(self, self.active_cell.layout.layer_collection)
@@ -956,30 +962,24 @@ class Edb(EdbInit):
956
962
 
957
963
  @property
958
964
  def source_excitation(self) -> SourceExcitation:
959
- """Returns layout source excitations.
965
+ """Source excitation management.
960
966
 
961
967
  Returns
962
968
  -------
963
- :class:`SourceExcitation <pyedb.grpc.database.source_excitations.SourceExcitation>`.
969
+ :class:`SourceExcitation <pyedb.grpc.database.source_excitations.SourceExcitation>`
970
+ Source and port creation tools.
964
971
  """
965
972
  if self.active_db:
966
973
  return self._source_excitation
967
974
 
968
975
  @property
969
976
  def materials(self) -> Materials:
970
- """Material Database.
977
+ """Material database interface.
971
978
 
972
979
  Returns
973
980
  -------
974
- :class:`Materials <pyedb.grpc.database.definition.materials.Materials>`.
975
-
976
- Examples
977
- --------
978
- >>> from pyedb import Edb
979
- >>> edbapp = Edb()
980
- >>> edbapp.materials.add_material("air", permittivity=1.0)
981
- >>> edbapp.materials.add_debye_material("debye_mat", 5, 3, 0.02, 0.05, 1e5, 1e9)
982
- >>> edbapp.materials.add_djordjevicsarkar_material("djord_mat", 3.3, 0.02, 3.3)
981
+ :class:`Materials <pyedb.grpc.database.definition.materials.Materials>`
982
+ Material definition and management.
983
983
  """
984
984
  if self.active_db:
985
985
  self._materials = Materials(self)
@@ -987,40 +987,25 @@ class Edb(EdbInit):
987
987
 
988
988
  @property
989
989
  def padstacks(self) -> Padstacks:
990
- """Returns padstack object.
991
-
990
+ """Padstack management interface.
992
991
 
993
992
  Returns
994
993
  -------
995
- :class:`Padstacks <pyedb.grpc.database.padstack.Padstacks>`.
996
-
997
- Examples
998
- --------
999
- >>> from pyedb import Edb
1000
- >>> edbapp = Edb("myproject.aedb")
1001
- >>> p = edbapp.padstacks.create(padstackname="myVia_bullet", antipad_shape="Bullet")
1002
- >>> edbapp.padstacks.get_pad_parameters(
1003
- >>> ... p, "TOP", edbapp.padstacks.pad_type.RegularPad
1004
- >>> ... )
994
+ :class:`Padstacks <pyedb.grpc.database.padstack.Padstacks>`
995
+ Padstack definition and editing.
1005
996
  """
1006
-
1007
997
  if not self._padstack and self.active_db:
1008
998
  self._padstack = Padstacks(self)
1009
999
  return self._padstack
1010
1000
 
1011
1001
  @property
1012
1002
  def siwave(self) -> Siwave:
1013
- """Returns SIWave object.
1003
+ """SIwave simulation interface.
1014
1004
 
1015
1005
  Returns
1016
1006
  -------
1017
- :class:`Siwave <pyedb.grpc.database.siwave.Siwave>`.
1018
-
1019
- Examples
1020
- --------
1021
- >>> from pyedb import Edb
1022
- >>> edbapp = Edb("myproject.aedb")
1023
- >>> p2 = edbapp.siwave.create_circuit_port_on_net("U2A5", "V3P3_S0", "U2A5", "GND", 50, "test")
1007
+ :class:`Siwave <pyedb.grpc.database.siwave.Siwave>`
1008
+ SIwave analysis setup tools.
1024
1009
  """
1025
1010
  if not self._siwave and self.active_db:
1026
1011
  self._siwave = Siwave(self)
@@ -1028,19 +1013,12 @@ class Edb(EdbInit):
1028
1013
 
1029
1014
  @property
1030
1015
  def hfss(self) -> Hfss:
1031
- """Returns HFSS object.
1016
+ """HFSS simulation interface.
1032
1017
 
1033
1018
  Returns
1034
1019
  -------
1035
- :class:`Hfss <pyedb.grpc.database.hfss.Hfss>`.
1036
-
1037
- Examples
1038
- --------
1039
- >>> from pyedb import Edb
1040
- >>> edbapp = Edb("myproject.aedb")
1041
- >>> sim_config = edbapp.new_simulation_configuration()
1042
- >>> sim_config.mesh_freq = "10Ghz"
1043
- >>> edbapp.hfss.configure_hfss_analysis_setup(sim_config)
1020
+ :class:`Hfss <pyedb.grpc.database.hfss.Hfss>`
1021
+ HFSS analysis setup tools.
1044
1022
  """
1045
1023
  if not self._hfss and self.active_db:
1046
1024
  self._hfss = Hfss(self)
@@ -1048,74 +1026,50 @@ class Edb(EdbInit):
1048
1026
 
1049
1027
  @property
1050
1028
  def nets(self) -> Nets:
1051
- """Returns nets object.
1029
+ """Net management interface.
1052
1030
 
1053
1031
  Returns
1054
1032
  -------
1055
- :class:`Nets <pyedb.grpc.database.nets.Nets>`.
1056
-
1057
- Examples
1058
- --------
1059
- >>> from pyedb import Edb
1060
- >>> edbapp = Edb"myproject.aedb")
1061
- >>> edbapp.nets.find_or_create_net("GND")
1062
- >>> edbapp.nets.find_and_fix_disjoint_nets("GND", keep_only_main_net=True)
1033
+ :class:`Nets <pyedb.grpc.database.nets.Nets>`
1034
+ Net manipulation tools.
1063
1035
  """
1064
-
1065
1036
  if not self._nets and self.active_db:
1066
1037
  self._nets = Nets(self)
1067
1038
  return self._nets
1068
1039
 
1069
1040
  @property
1070
1041
  def net_classes(self) -> NetClass:
1071
- """Returns net classes object.
1042
+ """Net class management.
1072
1043
 
1073
1044
  Returns
1074
1045
  -------
1075
- :class:`NetClass <pyedb.grpc.database.net.net_class.NetClass>`.
1076
-
1077
- Examples
1078
- --------
1079
- >>> from pyedb import Edb
1080
- >>> edbapp = Edb("myproject.aedb")
1081
- >>> edbapp.net_classes
1046
+ dict[str, :class:`NetClass <pyedb.grpc.database.net.net_class.NetClass>`]
1047
+ Net class names and objects.
1082
1048
  """
1083
-
1084
1049
  if self.active_db:
1085
1050
  return {net.name: NetClass(self, net) for net in self.active_layout.net_classes}
1086
1051
 
1087
1052
  @property
1088
1053
  def extended_nets(self) -> ExtendedNets:
1089
- """Returns extended nets.
1054
+ """Extended net management.
1090
1055
 
1091
1056
  Returns
1092
1057
  -------
1093
- :class:`ExtendedNets <pyedb.grpc.database.net.extended_net.ExtendedNets>`.
1094
-
1095
- Examples
1096
- --------
1097
- >>> from pyedb import Edb
1098
- >>> edbapp = Edb("myproject.aedb")
1099
- >>> edbapp.extended_nets
1058
+ :class:`ExtendedNets <pyedb.grpc.database.net.extended_net.ExtendedNets>`
1059
+ Extended net tools.
1100
1060
  """
1101
-
1102
1061
  if not self._extended_nets:
1103
1062
  self._extended_nets = ExtendedNets(self)
1104
1063
  return self._extended_nets
1105
1064
 
1106
1065
  @property
1107
1066
  def differential_pairs(self) -> DifferentialPairs:
1108
- """Returns differential pairs.
1067
+ """Differential pair management.
1109
1068
 
1110
1069
  Returns
1111
1070
  -------
1112
- :class:`DifferentialPairs <pyedb.grpc.database.net.differential_par.DifferentialPairs>`.
1113
-
1114
- Examples
1115
- --------
1116
- >>> from pyedb import Edb
1117
- >>> edbapp = Edb("myproject.aedb")
1118
- >>> edbapp.differential_pairs
1071
+ :class:`DifferentialPairs <pyedb.grpc.database.net.differential_par.DifferentialPairs>`
1072
+ Differential pair tools.
1119
1073
  """
1120
1074
  if not self._differential_pairs and self.active_db:
1121
1075
  self._differential_pairs = DifferentialPairs(self)
@@ -1123,17 +1077,12 @@ class Edb(EdbInit):
1123
1077
 
1124
1078
  @property
1125
1079
  def modeler(self) -> Modeler:
1126
- """Returns primitives modeler object.
1080
+ """Geometry modeling interface.
1127
1081
 
1128
1082
  Returns
1129
1083
  -------
1130
- :class:`Modeler <pyedb.grpc.database.modeler.Modeler>`.
1131
-
1132
- Examples
1133
- --------
1134
- >>> from pyedb import Edb
1135
- >>> edbapp = Edb("myproject.aedb")
1136
- >>> top_prims = edbapp.modeler.primitives_by_layer["TOP"]
1084
+ :class:`Modeler <pyedb.grpc.database.modeler.Modeler>`
1085
+ Geometry creation and editing.
1137
1086
  """
1138
1087
  if not self._modeler and self.active_db:
1139
1088
  self._modeler = Modeler(self)
@@ -1141,46 +1090,51 @@ class Edb(EdbInit):
1141
1090
 
1142
1091
  @property
1143
1092
  def layout(self) -> Layout:
1144
- """Returns Layout object.
1093
+ """Layout access interface.
1145
1094
 
1146
1095
  Returns
1147
1096
  -------
1148
- :class:`Layout <pyedb.grpc.database.layout.layout.Layout>`.
1097
+ :class:`Layout <pyedb.grpc.database.layout.layout.Layout>`
1098
+ Layout manipulation tools.
1149
1099
  """
1150
1100
  return Layout(self)
1151
1101
 
1152
1102
  @property
1153
1103
  def active_layout(self) -> Layout:
1154
- """Active layout.
1104
+ """Active layout access.
1155
1105
 
1156
1106
  Returns
1157
1107
  -------
1158
- :class:`Layout <pyedb.grpc.database.layout.layout.Layout>`.
1108
+ :class:`Layout <pyedb.grpc.database.layout.layout.Layout>`
1109
+ Current layout tools.
1159
1110
  """
1160
1111
  return self.layout
1161
1112
 
1162
1113
  @property
1163
1114
  def layout_instance(self):
1164
- """Returns Layout Instance object.
1115
+ """Layout instance object.
1165
1116
 
1166
1117
  Returns
1167
1118
  -------
1168
1119
  :class:`LayoutInstance <ansys.edb.core.layout_instance.layout_instance.LayoutInstance>`
1120
+ Current layout instance.
1169
1121
  """
1170
1122
  if not self._layout_instance:
1171
1123
  self._layout_instance = self.layout.layout_instance
1172
1124
  return self._layout_instance
1173
1125
 
1174
1126
  def get_connected_objects(self, layout_object_instance):
1175
- """Returns connected objects.
1127
+ """Get objects connected to a layout object.
1128
+
1129
+ Parameters
1130
+ ----------
1131
+ layout_object_instance :
1132
+ Target layout object.
1176
1133
 
1177
1134
  Returns
1178
1135
  -------
1179
- list[:class:`PadstackInstance <pyedb.grpc.database.primitive.padstack_instance.PadstackInstance>`,
1180
- :class:`Path <pyedb.grpc.database.primitive.path.Path>`,
1181
- :class:`Rectangle <pyedb.grpc.database.primitive.rectangle.Rectangle>`,
1182
- :class:`Circle <pyedb.grpc.database.primitive.circle.Circle>`,
1183
- :class:`Polygon <pyedb.grpc.database.primitive.polygon.Polygon>`]
1136
+ list
1137
+ Connected objects (padstacks, paths, polygons, etc.).
1184
1138
  """
1185
1139
  from ansys.edb.core.terminal.padstack_instance_terminal import (
1186
1140
  PadstackInstanceTerminal as GrpcPadstackInstanceTerminal,
@@ -1213,39 +1167,40 @@ class Edb(EdbInit):
1213
1167
  return temp
1214
1168
 
1215
1169
  def point_3d(self, x, y, z=0.0):
1216
- """Compute the Edb 3d Point Data.
1170
+ """Create 3D point.
1217
1171
 
1218
1172
  Parameters
1219
1173
  ----------
1220
- x : float, int or str
1221
- X value.
1222
- y : float, int or str
1223
- Y value.
1224
- z : float, int or str, optional
1225
- Z value.
1174
+ x : float, int, str
1175
+ X coordinate.
1176
+ y : float, int, str
1177
+ Y coordinate.
1178
+ z : float, int, str, optional
1179
+ Z coordinate.
1226
1180
 
1227
1181
  Returns
1228
1182
  -------
1229
1183
  :class:`Point3DData <pyedb.grpc.database.geometry.point_3d_data.Point3DData>`
1184
+ 3D point object.
1230
1185
  """
1231
1186
  from pyedb.grpc.database.geometry.point_3d_data import Point3DData
1232
1187
 
1233
1188
  return Point3DData(x, y, z)
1234
1189
 
1235
1190
  def point_data(self, x, y=None):
1236
- """Compute the Edb Point Data.
1191
+ """Create 2D point.
1237
1192
 
1238
1193
  Parameters
1239
1194
  ----------
1240
- x : float, int or str
1241
- X value.
1242
- y : float, int or str, optional
1243
- Y value.
1244
-
1195
+ x : float, int, str or PointData
1196
+ X coordinate or PointData object.
1197
+ y : float, int, str, optional
1198
+ Y coordinate.
1245
1199
 
1246
1200
  Returns
1247
1201
  -------
1248
1202
  :class:`PointData <pyedb.grpc.database.geometry.point_data.PointData>`
1203
+ 2D point object.
1249
1204
  """
1250
1205
  from pyedb.grpc.database.geometry.point_data import PointData
1251
1206
 
@@ -1254,18 +1209,6 @@ class Edb(EdbInit):
1254
1209
  else:
1255
1210
  return PointData(x, y)
1256
1211
 
1257
- @staticmethod
1258
- def _is_file_existing_and_released(filename) -> bool:
1259
- if os.path.exists(filename):
1260
- try:
1261
- os.rename(filename, filename + "_")
1262
- os.rename(filename + "_", filename)
1263
- return True
1264
- except OSError as e:
1265
- return False
1266
- else:
1267
- return False
1268
-
1269
1212
  @staticmethod
1270
1213
  def _is_file_existing(filename) -> bool:
1271
1214
  if os.path.exists(filename):
@@ -1273,18 +1216,6 @@ class Edb(EdbInit):
1273
1216
  else:
1274
1217
  return False
1275
1218
 
1276
- def _wait_for_file_release(self, timeout=30, file_to_release=None) -> bool:
1277
- if not file_to_release:
1278
- file_to_release = os.path.join(self.edbpath)
1279
- tstart = time.time()
1280
- while True:
1281
- if self._is_file_existing_and_released(file_to_release):
1282
- return True
1283
- elif time.time() - tstart > timeout:
1284
- return False
1285
- else:
1286
- time.sleep(0.250)
1287
-
1288
1219
  def _wait_for_file_exists(self, timeout=30, file_to_release=None, wait_count=4):
1289
1220
  if not file_to_release:
1290
1221
  file_to_release = os.path.join(self.edbpath)
@@ -1304,93 +1235,80 @@ class Edb(EdbInit):
1304
1235
  time.sleep(0.250)
1305
1236
 
1306
1237
  def close_edb(self) -> bool:
1307
- """Close EDB and cleanup variables.
1238
+ """Close EDB and clean up resources.
1239
+
1240
+ ..deprecated:: 0.51.0
1241
+ Use: func:`close` instead.
1308
1242
 
1309
1243
  Returns
1310
1244
  -------
1311
- bool: `True` when successful, `False` when failed.
1245
+ bool
1246
+ True if successful, False otherwise.
1247
+
1248
+ Examples
1249
+ --------
1250
+ Close the EDB session:
1251
+ >>> edb.close_edb()
1312
1252
  """
1313
- self.close()
1314
- start_time = time.time()
1315
- self._wait_for_file_release()
1316
- elapsed_time = time.time() - start_time
1317
- self.logger.info("EDB file release time: {0:.2f}ms".format(elapsed_time * 1000.0))
1318
- self._clean_variables()
1319
- return True
1253
+ warnings.warn("Use method close instead.", DeprecationWarning)
1254
+ return self.close()
1320
1255
 
1321
1256
  def save_edb(self) -> bool:
1322
- """Save the EDB file.
1257
+ """Save current EDB database.
1258
+
1259
+ ..deprecated:: 0.51.0
1260
+ Use: func:`save` instead.
1323
1261
 
1324
1262
  Returns
1325
1263
  -------
1326
- bool: `True` when successful, `False` when failed.
1264
+ bool
1265
+ True if successful, False otherwise.
1266
+
1267
+ Examples
1268
+ --------
1269
+ Save the current EDB:
1270
+ >>> edb.save_edb()
1327
1271
  """
1328
- self.save()
1329
- start_time = time.time()
1330
- self._wait_for_file_release()
1331
- elapsed_time = time.time() - start_time
1332
- self.logger.info("EDB file save time: {0:.2f}ms".format(elapsed_time * 1000.0))
1333
- return True
1272
+ warnings.warn("Use method save instead.", DeprecationWarning)
1273
+ return self.save()
1334
1274
 
1335
1275
  def save_edb_as(self, fname) -> bool:
1336
- """Save the EDB file as another file.
1276
+ """Save EDB database to new location.
1277
+
1278
+ ..deprecated:: 0.51.0
1279
+ Use: func:`save_as` instead.
1337
1280
 
1338
1281
  Parameters
1339
1282
  ----------
1340
1283
  fname : str
1341
- Name of the new file to save to.
1284
+ New AEDB path.
1342
1285
 
1343
1286
  Returns
1344
1287
  -------
1345
- bool: `True` when successful, `False` when failed.
1288
+ bool
1289
+ True if successful, False otherwise.
1290
+
1291
+ Examples
1292
+ --------
1293
+ Save EDB to new location:
1294
+ >>> edb.save_edb_as("new_location.aedb")
1346
1295
  """
1347
- self.save_as(fname)
1348
- start_time = time.time()
1349
- self._wait_for_file_release()
1350
- elapsed_time = time.time() - start_time
1351
- self.logger.info("EDB file save time: {0:.2f}ms".format(elapsed_time * 1000.0))
1352
- self.edbpath = self.directory
1353
- self.log_name = os.path.join(
1354
- os.path.dirname(fname), "pyedb_" + os.path.splitext(os.path.split(fname)[-1])[0] + ".log"
1355
- )
1356
- return True
1296
+ warnings.warn("Use method save_as instead.", DeprecationWarning)
1297
+ return self.save_as(fname)
1357
1298
 
1358
1299
  def execute(self, func):
1359
- """Execute a function.
1300
+ """Execute EDB utility command (Not implemented in gRPC).
1360
1301
 
1361
1302
  Parameters
1362
1303
  ----------
1363
1304
  func : str
1364
- Function to execute.
1365
-
1366
-
1367
- Returns
1368
- -------
1369
- bool: `True` when successful, `False` when failed.
1305
+ Command to execute.
1370
1306
  """
1371
1307
  # return self.edb_api.utility.utility.Command.Execute(func)
1372
1308
  pass
1373
1309
 
1374
1310
  def import_cadence_file(self, inputBrd, WorkDir=None, anstranslator_full_path="", use_ppe=False):
1375
- """Import a board file and generate an ``edb.def`` file in the working directory.
1376
-
1377
- Parameters
1378
- ----------
1379
- inputBrd : str
1380
- Full path to the board file.
1381
- WorkDir : str, optional
1382
- Directory in which to create the ``aedb`` folder. The default value is ``None``,
1383
- in which case the AEDB file is given the same name as the board file. Only
1384
- the extension differs.
1385
- anstranslator_full_path : str, optional
1386
- Full path to the Ansys translator.
1387
- use_ppe : bool, optional
1388
- Whether to use the PPE License. The default is ``False``.
1389
-
1390
- Returns
1391
- -------
1392
- bool: `True` when successful, `False` when failed.
1393
- """
1311
+ """Import Cadence board file (Deprecated - use import_layout_file)."""
1394
1312
  if self.import_layout_pcb(
1395
1313
  inputBrd,
1396
1314
  working_dir=WorkDir,
@@ -1411,32 +1329,24 @@ class Edb(EdbInit):
1411
1329
  map_file=None,
1412
1330
  layer_filter=None,
1413
1331
  ):
1414
- """Import a GDS file and generate an ``edb.def`` file in the working directory.
1415
-
1416
- ..note::
1417
- ANSYS license is necessary to run the translator.
1332
+ """Import GDS file.
1418
1333
 
1419
1334
  Parameters
1420
1335
  ----------
1421
1336
  inputGDS : str
1422
- Full path to the GDS file.
1337
+ GDS file path.
1423
1338
  anstranslator_full_path : str, optional
1424
- Full path to the Ansys translator.
1339
+ Ansys translator path.
1425
1340
  use_ppe : bool, optional
1426
- Whether to use the PPE License. The default is ``False``.
1341
+ Use PPE license. Default False.
1427
1342
  control_file : str, optional
1428
- Path to the XML file. The default is ``None``, in which case an attempt is made to find
1429
- the XML file in the same directory as the GDS file. To succeed, the XML file and GDS file must
1430
- have the same name. Only the extension differs.
1343
+ XML control file.
1431
1344
  tech_file : str, optional
1432
- Technology file. For versions<2024.1 it uses Helic to convert tech file to xml and then imports
1433
- the gds. Works on Linux only.
1434
- For versions>=2024.1 it can directly parse through supported foundry tech files.
1345
+ Technology file.
1435
1346
  map_file : str, optional
1436
1347
  Layer map file.
1437
- layer_filter:str,optional
1348
+ layer_filter : str, optional
1438
1349
  Layer filter file.
1439
-
1440
1350
  """
1441
1351
  control_file_temp = os.path.join(tempfile.gettempdir(), os.path.split(inputGDS)[-1][:-3] + "xml")
1442
1352
  if float(self.edbversion) < 2024.1:
@@ -1737,114 +1647,72 @@ class Edb(EdbInit):
1737
1647
  keep_lines_as_path=False,
1738
1648
  include_voids_in_extents=False,
1739
1649
  ):
1740
- """Create a cutout using an approach entirely based on PyAEDT.
1741
- This method replaces all legacy cutout methods in PyAEDT.
1742
- It does in sequence:
1743
- - delete all nets not in list,
1744
- - create a extent of the nets,
1745
- - check and delete all vias not in the extent,
1746
- - check and delete all the primitives not in extent,
1747
- - check and intersect all the primitives that intersect the extent.
1650
+ """Create layout cutout with various options.
1748
1651
 
1749
1652
  Parameters
1750
1653
  ----------
1751
- signal_list : list
1752
- List of signal strings.
1654
+ signal_list : list, optional
1655
+ Signal nets to include.
1753
1656
  reference_list : list, optional
1754
- List of references to add. The default is ``["GND"]``.
1657
+ Reference nets to include.
1755
1658
  extent_type : str, optional
1756
- Type of the extension. Options are ``"Conforming"``, ``"ConvexHull"``, and
1757
- ``"Bounding"``. The default is ``"Conforming"``.
1758
- expansion_size : float, str, optional
1759
- Expansion size ratio in meters. The default is ``0.002``.
1659
+ Cutout type ("Conforming", "ConvexHull", "Bounding").
1660
+ expansion_size : float, optional
1661
+ Boundary expansion size (meters).
1760
1662
  use_round_corner : bool, optional
1761
- Whether to use round corners. The default is ``False``.
1663
+ Use rounded corners. Default False.
1762
1664
  output_aedb_path : str, optional
1763
- Full path and name for the new AEDB file. If None, then current aedb will be cutout.
1665
+ Output AEDB path.
1764
1666
  open_cutout_at_end : bool, optional
1765
- Whether to open the cutout at the end. The default is ``True``.
1667
+ Open cutout when finished. Default True.
1766
1668
  use_pyaedt_cutout : bool, optional
1767
- Whether to use new PyAEDT cutout method or EDB API method.
1768
- New method is faster than native API method since it benefits of multithread.
1669
+ Use PyAEDT cutout method. Default True.
1769
1670
  number_of_threads : int, optional
1770
- Number of thread to use. Default is 4. Valid only if ``use_pyaedt_cutout`` is set to ``True``.
1671
+ Thread count for PyAEDT cutout.
1771
1672
  use_pyaedt_extent_computing : bool, optional
1772
- Whether to use legacy extent computing (experimental) or EDB API.
1673
+ Use PyAEDT extent computation. Default True.
1773
1674
  extent_defeature : float, optional
1774
- Defeature the cutout before applying it to produce simpler geometry for mesh (Experimental).
1775
- It applies only to Conforming bounding box. Default value is ``0`` which disable it.
1675
+ Geometry simplification factor.
1776
1676
  remove_single_pin_components : bool, optional
1777
- Remove all Single Pin RLC after the cutout is completed. Default is `False`.
1778
- custom_extent : list
1779
- Points list defining the cutout shape. This setting will override `extent_type` field.
1780
- custom_extent_units : str
1781
- Units of the point list. The default is ``"mm"``. Valid only if `custom_extend` is provided.
1677
+ Remove single-pin components. Default False.
1678
+ custom_extent : list, optional
1679
+ Custom polygon points for cutout.
1680
+ custom_extent_units : str, optional
1681
+ Units for custom_extent points.
1782
1682
  include_partial_instances : bool, optional
1783
- Whether to include padstack instances that have bounding boxes intersecting with point list polygons.
1784
- This operation may slow down the cutout export.Valid only if `custom_extend` and
1785
- `use_pyaedt_cutout` is provided.
1786
- keep_voids : bool
1787
- Boolean used for keep or not the voids intersecting the polygon used for clipping the layout.
1788
- Default value is ``True``, ``False`` will remove the voids.Valid only if `custom_extend` is provided.
1683
+ Include partial padstack instances. Default False.
1684
+ keep_voids : bool, optional
1685
+ Preserve voids in cutout. Default True.
1789
1686
  check_terminals : bool, optional
1790
- Whether to check for all reference terminals and increase extent to include them into the cutout.
1791
- This applies to components which have a model (spice, touchstone or netlist) associated.
1687
+ Verify terminal references. Default False.
1792
1688
  include_pingroups : bool, optional
1793
- Whether to check for all pingroups terminals and increase extent to include them into the cutout.
1794
- It requires ``check_terminals``.
1689
+ Include pin groups. Default False.
1795
1690
  expansion_factor : int, optional
1796
- The method computes a float representing the largest number between
1797
- the dielectric thickness or trace width multiplied by the expansion_factor factor.
1798
- The trace width search is limited to nets with ports attached. Works only if `use_pyaedt_cutout`.
1799
- Default is `0` to disable the search.
1691
+ Auto-expansion factor. Default 0 (disabled).
1800
1692
  maximum_iterations : int, optional
1801
- Maximum number of iterations before stopping a search for a cutout with an error.
1802
- Default is `10`.
1693
+ Max auto-expansion iterations. Default 10.
1803
1694
  preserve_components_with_model : bool, optional
1804
- Whether to preserve all pins of components that have associated models (Spice or NPort).
1805
- This parameter is applicable only for a PyAEDT cutout (except point list).
1695
+ Keep components with models. Default False.
1806
1696
  simple_pad_check : bool, optional
1807
- Whether to use the center of the pad to find the intersection with extent or use the bounding box.
1808
- Second method is much slower and requires to disable multithread on padstack removal.
1809
- Default is `True`.
1697
+ Use simplified pad checking. Default True.
1810
1698
  keep_lines_as_path : bool, optional
1811
- Whether to keep the lines as Path after they are cutout or convert them to PolygonData.
1812
- This feature works only in Electronics Desktop (3D Layout).
1813
- If the flag is set to ``True`` it can cause issues in SiWave once the Edb is imported.
1814
- Default is ``False`` to generate PolygonData of cut lines.
1699
+ Preserve paths as lines. Default False.
1815
1700
  include_voids_in_extents : bool, optional
1816
- Whether to compute and include voids in pyaedt extent before the cutout. Cutout time can be affected.
1817
- It works only with Conforming cutout.
1818
- Default is ``False`` to generate extent without voids.
1819
-
1701
+ Include voids in extent calculation. Default False.
1820
1702
 
1821
1703
  Returns
1822
1704
  -------
1823
- List
1824
- List of coordinate points defining the extent used for clipping the design. If failed, return an empty
1825
- list.
1705
+ list or bool
1706
+ Cutout boundary points if successful, False otherwise.
1826
1707
 
1827
1708
  Examples
1828
1709
  --------
1829
- >>> from pyedb import Edb
1830
- >>> edb = Edb(r'C:\\test.aedb', edbversion="2022.2")
1831
- >>> edb.logger.info_timer("Edb Opening")
1832
- >>> edb.logger.reset_timer()
1833
- >>> start = time.time()
1834
- >>> signal_list = []
1835
- >>> for net in edb.nets.netlist:
1836
- >>> if "3V3" in net:
1837
- >>> signal_list.append(net)
1838
- >>> power_list = ["PGND"]
1839
- >>> edb.cutout(signal_list=signal_list, reference_list=power_list, extent_type="Conforming")
1840
- >>> end_time = str((time.time() - start)/60)
1841
- >>> edb.logger.info("Total legacy cutout time in min %s", end_time)
1842
- >>> edb.nets.plot(signal_list, None, color_by_net=True)
1843
- >>> edb.nets.plot(power_list, None, color_by_net=True)
1844
- >>> edb.save_edb()
1845
- >>> edb.close_edb()
1846
-
1710
+ Create a basic cutout:
1711
+ >>> edb.cutout(signal_list=["Net1"], reference_list=["GND"])
1847
1712
 
1713
+ Create cutout with custom polygon:
1714
+ >>> custom_poly = [[0,0], [10e-3,0], [10e-3,10e-3], [0,10e-3]]
1715
+ >>> edb.cutout(custom_extent=custom_poly)
1848
1716
  """
1849
1717
  if expansion_factor > 0:
1850
1718
  expansion_size = self.calculate_initial_extent(expansion_factor)
@@ -1921,7 +1789,7 @@ class Edb(EdbInit):
1921
1789
  break
1922
1790
  self.close_edb()
1923
1791
  self.edbpath = legacy_path
1924
- self.open_edb()
1792
+ self.open()
1925
1793
  i += 1
1926
1794
  expansion = expansion_size * i
1927
1795
  if working_cutout:
@@ -2007,15 +1875,15 @@ class Edb(EdbInit):
2007
1875
  # _cutout.simulation_setups = self.active_cell.simulation_setups see bug #433 status.
2008
1876
  _dbCells = [_cutout]
2009
1877
  if output_aedb_path:
2010
- db2 = self.create(output_aedb_path)
2011
- _success = db2.save()
2012
- _dbCells = _dbCells
1878
+ from ansys.edb.core.database import Database as GrpcDatabase
1879
+
1880
+ db2 = GrpcDatabase.create(output_aedb_path)
2013
1881
  db2.copy_cells(_dbCells) # Copies cutout cell/design to db2 project
2014
- if len(list(db2.circuit_cells)) > 0:
2015
- for net in db2.circuit_cells[0].layout.nets:
1882
+ if len(list(db2.top_circuit_cells)) > 0:
1883
+ for net in db2.top_circuit_cells[0].layout.nets:
2016
1884
  if not net.name in included_nets_list:
2017
1885
  net.delete()
2018
- _success = db2.save()
1886
+ db2.save()
2019
1887
  for c in self.active_db.top_circuit_cells:
2020
1888
  if c.name == _cutout.name:
2021
1889
  c.delete()
@@ -2041,7 +1909,7 @@ class Edb(EdbInit):
2041
1909
  for _cmp in _cmps:
2042
1910
  _cmp.delete()
2043
1911
  except:
2044
- self._logger.error("Failed to remove single pin components.")
1912
+ self.logger.error("Failed to remove single pin components.")
2045
1913
  db2.close()
2046
1914
  source = os.path.join(output_aedb_path, "edb.def.tmp")
2047
1915
  target = os.path.join(output_aedb_path, "edb.def")
@@ -2493,7 +2361,9 @@ class Edb(EdbInit):
2493
2361
 
2494
2362
  _dbCells = [_cutout]
2495
2363
  if output_aedb_path:
2496
- db2 = self.create(output_aedb_path)
2364
+ from ansys.edb.core.database import Database as GrpcDatabase
2365
+
2366
+ db2 = GrpcDatabase.create(output_aedb_path)
2497
2367
  db2.save()
2498
2368
  cell_copied = db2.copy_cells(_dbCells) # Copies cutout cell/design to db2 project
2499
2369
  cell = cell_copied[0]
@@ -2503,7 +2373,7 @@ class Edb(EdbInit):
2503
2373
  if c.name == _cutout.name:
2504
2374
  c.delete()
2505
2375
  if open_cutout_at_end: # pragma: no cover
2506
- _success = db2.save()
2376
+ db2.save()
2507
2377
  self._db = db2
2508
2378
  self.edbpath = output_aedb_path
2509
2379
  self._active_cell = cell
@@ -2568,37 +2438,30 @@ class Edb(EdbInit):
2568
2438
  aedt_file_name=None,
2569
2439
  hidden=False,
2570
2440
  ):
2571
- """Export EDB to HFSS.
2441
+ """Export to HFSS project.
2572
2442
 
2573
2443
  Parameters
2574
2444
  ----------
2575
2445
  path_to_output : str
2576
- Full path and name for saving the AEDT file.
2446
+ Output directory.
2577
2447
  net_list : list, optional
2578
- List of nets to export if only certain ones are to be exported.
2579
- The default is ``None``, in which case all nets are eported.
2448
+ Nets to export.
2580
2449
  num_cores : int, optional
2581
- Number of cores to use for the export. The default is ``None``.
2450
+ Processing cores to use.
2582
2451
  aedt_file_name : str, optional
2583
- Name of the AEDT output file without the ``.aedt`` extension. The default is ``None``,
2584
- in which case the default name is used.
2452
+ Custom AEDT filename.
2585
2453
  hidden : bool, optional
2586
- Open Siwave in embedding mode. User will only see Siwave Icon but UI will be hidden.
2454
+ Run Siwave in background. Default False.
2587
2455
 
2588
2456
  Returns
2589
2457
  -------
2590
2458
  str
2591
- Full path to the AEDT file.
2459
+ Path to generated AEDT file.
2592
2460
 
2593
2461
  Examples
2594
2462
  --------
2595
-
2596
- >>> from pyedb import Edb
2597
- >>> edb = Edb(edbpath=r"C:\temp\myproject.aedb", edbversion="2023.2")
2598
-
2599
- >>> options_config = {'UNITE_NETS' : 1, 'LAUNCH_Q3D' : 0}
2600
- >>> edb.write_export3d_option_config_file(r"C:\temp", options_config)
2601
- >>> edb.export_hfss(r"C:\temp")
2463
+ Export to HFSS project:
2464
+ >>> edb.export_hfss(r"C:/output", net_list=["SignalNet"])
2602
2465
  """
2603
2466
  siwave_s = SiwaveSolve(self.edbpath, aedt_installer_path=self.base_path)
2604
2467
  return siwave_s.export_3d_cad("HFSS", path_to_output, net_list, num_cores, aedt_file_name, hidden=hidden)
@@ -2611,38 +2474,31 @@ class Edb(EdbInit):
2611
2474
  aedt_file_name=None,
2612
2475
  hidden=False,
2613
2476
  ):
2614
- """Export EDB to Q3D.
2477
+ """Export to Q3D project.
2615
2478
 
2616
2479
  Parameters
2617
2480
  ----------
2618
2481
  path_to_output : str
2619
- Full path and name for saving the AEDT file.
2482
+ Output directory.
2620
2483
  net_list : list, optional
2621
- List of nets to export only if certain ones are to be exported.
2622
- The default is ``None``, in which case all nets are eported.
2484
+ Nets to export.
2623
2485
  num_cores : int, optional
2624
- Number of cores to use for the export. The default is ``None``.
2486
+ Processing cores to use.
2625
2487
  aedt_file_name : str, optional
2626
- Name of the AEDT output file without the ``.aedt`` extension. The default is ``None``,
2627
- in which case the default name is used.
2488
+ Custom AEDT filename.
2628
2489
  hidden : bool, optional
2629
- Open Siwave in embedding mode. User will only see Siwave Icon but UI will be hidden.
2490
+ Run Siwave in background. Default False.
2630
2491
 
2631
2492
  Returns
2632
2493
  -------
2633
2494
  str
2634
- Full path to the AEDT file.
2495
+ Path to generated AEDT file.
2635
2496
 
2636
2497
  Examples
2637
2498
  --------
2638
-
2639
- >>> from pyedb import Edb
2640
- >>> edb = Edb(edbpath=r"C:\temp\myproject.aedb", edbversion="2021.2")
2641
- >>> options_config = {'UNITE_NETS' : 1, 'LAUNCH_Q3D' : 0}
2642
- >>> edb.write_export3d_option_config_file(r"C:\temp", options_config)
2643
- >>> edb.export_q3d(r"C:\temp")
2499
+ Export to Q3D project:
2500
+ >>> edb.export_q3d(r"C:/output")
2644
2501
  """
2645
-
2646
2502
  siwave_s = SiwaveSolve(self.edbpath, aedt_installer_path=self.base_path)
2647
2503
  return siwave_s.export_3d_cad(
2648
2504
  "Q3D",
@@ -2661,38 +2517,30 @@ class Edb(EdbInit):
2661
2517
  aedt_file_name=None,
2662
2518
  hidden=False,
2663
2519
  ):
2664
- """Export EDB to Maxwell 3D.
2520
+ """Export to Maxwell project.
2665
2521
 
2666
2522
  Parameters
2667
2523
  ----------
2668
2524
  path_to_output : str
2669
- Full path and name for saving the AEDT file.
2525
+ Output directory.
2670
2526
  net_list : list, optional
2671
- List of nets to export only if certain ones are to be
2672
- exported. The default is ``None``, in which case all nets are exported.
2527
+ Nets to export.
2673
2528
  num_cores : int, optional
2674
- Number of cores to use for the export. The default is ``None.``
2529
+ Processing cores to use.
2675
2530
  aedt_file_name : str, optional
2676
- Name of the AEDT output file without the ``.aedt`` extension. The default is ``None``,
2677
- in which case the default name is used.
2531
+ Custom AEDT filename.
2678
2532
  hidden : bool, optional
2679
- Open Siwave in embedding mode. User will only see Siwave Icon but UI will be hidden.
2533
+ Run Siwave in background. Default False.
2680
2534
 
2681
2535
  Returns
2682
2536
  -------
2683
2537
  str
2684
- Full path to the AEDT file.
2538
+ Path to generated AEDT file.
2685
2539
 
2686
2540
  Examples
2687
2541
  --------
2688
-
2689
- >>> from pyedb import Edb
2690
-
2691
- >>> edb = Edb(edbpath=r"C:\temp\myproject.aedb", edbversion="2021.2")
2692
-
2693
- >>> options_config = {'UNITE_NETS' : 1, 'LAUNCH_Q3D' : 0}
2694
- >>> edb.write_export3d_option_config_file(r"C:\temp", options_config)
2695
- >>> edb.export_maxwell(r"C:\temp")
2542
+ Export to Maxwell project:
2543
+ >>> edb.export_maxwell(r"C:/output")
2696
2544
  """
2697
2545
  siwave_s = SiwaveSolve(self.edbpath, aedt_installer_path=self.base_path)
2698
2546
  return siwave_s.export_3d_cad(
@@ -2705,12 +2553,17 @@ class Edb(EdbInit):
2705
2553
  )
2706
2554
 
2707
2555
  def solve_siwave(self):
2708
- """Close EDB and solve it with Siwave.
2556
+ """Solve with SIwave.
2709
2557
 
2710
2558
  Returns
2711
2559
  -------
2712
2560
  str
2713
- Siwave project path.
2561
+ Path to SIwave project.
2562
+
2563
+ Examples
2564
+ --------
2565
+ Solve with SIwave:
2566
+ >>> edb.solve_siwave()
2714
2567
  """
2715
2568
  process = SiwaveSolve(self.edbpath, aedt_version=self.edbversion)
2716
2569
  try:
@@ -2733,35 +2586,35 @@ class Edb(EdbInit):
2733
2586
  power_tree=True,
2734
2587
  loop_res=True,
2735
2588
  ):
2736
- """Close EDB and solve it with Siwave.
2589
+ """Export SIwave DC results.
2737
2590
 
2738
2591
  Parameters
2739
2592
  ----------
2740
2593
  siwave_project : str
2741
- Siwave full project name.
2594
+ SIwave project path.
2742
2595
  solution_name : str
2743
- Siwave DC Analysis name.
2596
+ DC analysis name.
2744
2597
  output_folder : str, optional
2745
- Ouptu folder where files will be downloaded.
2598
+ Custom output folder.
2746
2599
  html_report : bool, optional
2747
- Either if generate or not html report. Default is `True`.
2600
+ Generate HTML report. Default True.
2748
2601
  vias : bool, optional
2749
- Either if generate or not vias report. Default is `True`.
2602
+ Export vias report. Default True.
2750
2603
  voltage_probes : bool, optional
2751
- Either if generate or not voltage probe report. Default is `True`.
2604
+ Export voltage probes. Default True.
2752
2605
  current_sources : bool, optional
2753
- Either if generate or not current source report. Default is `True`.
2606
+ Export current sources. Default True.
2754
2607
  voltage_sources : bool, optional
2755
- Either if generate or not voltage source report. Default is `True`.
2608
+ Export voltage sources. Default True.
2756
2609
  power_tree : bool, optional
2757
- Either if generate or not power tree image. Default is `True`.
2610
+ Export power tree. Default True.
2758
2611
  loop_res : bool, optional
2759
- Either if generate or not loop resistance report. Default is `True`.
2612
+ Export loop resistance. Default True.
2760
2613
 
2761
2614
  Returns
2762
2615
  -------
2763
2616
  list[str]
2764
- List of files generated.
2617
+ Generated report files.
2765
2618
  """
2766
2619
  process = SiwaveSolve(self.edbpath, aedt_version=self.edbversion)
2767
2620
  try:
@@ -2783,11 +2636,17 @@ class Edb(EdbInit):
2783
2636
  )
2784
2637
 
2785
2638
  def variable_exists(self, variable_name):
2786
- """Check if a variable exists or not.
2639
+ """Check if variable exists.
2640
+
2641
+ Parameters
2642
+ ----------
2643
+ variable_name : str
2644
+ Variable name.
2787
2645
 
2788
2646
  Returns
2789
2647
  -------
2790
2648
  bool
2649
+ True if variable exists.
2791
2650
  """
2792
2651
  if "$" in variable_name:
2793
2652
  if variable_name.index("$") == 0:
@@ -2801,15 +2660,17 @@ class Edb(EdbInit):
2801
2660
  return False
2802
2661
 
2803
2662
  def get_variable(self, variable_name):
2804
- """Return Variable Value if variable exists.
2663
+ """Get variable value.
2805
2664
 
2806
2665
  Parameters
2807
2666
  ----------
2808
- variable_name
2667
+ variable_name : str
2668
+ Variable name.
2809
2669
 
2810
2670
  Returns
2811
2671
  -------
2812
- float
2672
+ float or bool
2673
+ Variable value if exists, else False.
2813
2674
  """
2814
2675
  if self.variable_exists(variable_name):
2815
2676
  if "$" in variable_name:
@@ -2822,30 +2683,21 @@ class Edb(EdbInit):
2822
2683
  return False
2823
2684
 
2824
2685
  def add_project_variable(self, variable_name, variable_value, description=None) -> bool:
2825
- """Add a variable to database. The variable will have the prefix `$`.
2686
+ """Add project variable.
2826
2687
 
2827
2688
  Parameters
2828
2689
  ----------
2829
2690
  variable_name : str
2830
- Name of the variable. Name can be provided without ``$`` prefix.
2691
+ Variable name (auto-prefixed with '$').
2831
2692
  variable_value : str, float
2832
- Value of the variable with units.
2833
- description : str, optional.
2834
- Add variable description.
2693
+ Variable value with units.
2694
+ description : str, optional
2695
+ Variable description.
2835
2696
 
2836
2697
  Returns
2837
2698
  -------
2838
2699
  bool
2839
-
2840
- Examples
2841
- --------
2842
-
2843
- >>> from pyedb import Edb
2844
- >>> edb_app = Edb()
2845
- >>> boolean_1, ant_length = edb_app.add_project_variable("my_local_variable", "1cm")
2846
- >>> print(edb_app["$my_local_variable"]) #using getitem
2847
- >>> edb_app["$my_local_variable"] = "1cm" #using setitem
2848
-
2700
+ True if successful, False if variable exists.
2849
2701
  """
2850
2702
  if not variable_name.startswith("$"):
2851
2703
  variable_name = f"${variable_name}"
@@ -2859,37 +2711,23 @@ class Edb(EdbInit):
2859
2711
  return False
2860
2712
 
2861
2713
  def add_design_variable(self, variable_name, variable_value, is_parameter=False, description=None) -> bool:
2862
- """Add a variable to edb. The variable can be a design one or a project variable (using ``$`` prefix).
2714
+ """Add design variable.
2863
2715
 
2864
2716
  Parameters
2865
2717
  ----------
2866
2718
  variable_name : str
2867
- Name of the variable. To added the variable as a project variable, the name
2868
- must begin with ``$``.
2719
+ Variable name.
2869
2720
  variable_value : str, float
2870
- Value of the variable with units.
2721
+ Variable value with units.
2871
2722
  is_parameter : bool, optional
2872
- Whether to add the variable as a local variable. The default is ``False``.
2873
- When ``True``, the variable is added as a parameter default.
2723
+ Add as local variable. Default False.
2874
2724
  description : str, optional
2875
- Add variable description.
2725
+ Variable description.
2876
2726
 
2877
2727
  Returns
2878
2728
  -------
2879
- bool.
2880
-
2881
- Examples
2882
- --------
2883
-
2884
- >>> from pyedb import Edb
2885
- >>> edb_app = Edb()
2886
- >>> boolean_1, ant_length = edb_app.add_design_variable("my_local_variable", "1cm")
2887
- >>> print(edb_app["my_local_variable"]) #using getitem
2888
- >>> edb_app["my_local_variable"] = "1cm" #using setitem
2889
- >>> boolean_2, para_length = edb_app.change_design_variable_value("my_parameter", "1m", is_parameter=True
2890
- >>> boolean_3, project_length = edb_app.change_design_variable_value("$my_project_variable", "1m")
2891
-
2892
-
2729
+ bool
2730
+ True if successful, False if variable exists.
2893
2731
  """
2894
2732
  if variable_name.startswith("$"):
2895
2733
  variable_name = variable_name[1:]
@@ -2903,27 +2741,14 @@ class Edb(EdbInit):
2903
2741
  return False
2904
2742
 
2905
2743
  def change_design_variable_value(self, variable_name, variable_value):
2906
- """Change a variable value.
2744
+ """Update variable value.
2907
2745
 
2908
2746
  Parameters
2909
2747
  ----------
2910
2748
  variable_name : str
2911
- Name of the variable.
2749
+ Variable name.
2912
2750
  variable_value : str, float
2913
- Value of the variable with units.
2914
-
2915
- Returns
2916
- -------
2917
- bool.
2918
-
2919
- Examples
2920
- --------
2921
-
2922
- >>> from pyedb import Edb
2923
- >>> edb_app = Edb()
2924
- >>> boolean, ant_length = edb_app.add_design_variable("ant_length", "1cm")
2925
- >>> boolean, ant_length = edb_app.change_design_variable_value("ant_length", "1m")
2926
- >>> print(edb_app["ant_length"]) #using getitem
2751
+ New value with units.
2927
2752
  """
2928
2753
  if self.variable_exists(variable_name):
2929
2754
  if variable_name in self.db.get_all_variable_names():
@@ -2932,54 +2757,44 @@ class Edb(EdbInit):
2932
2757
  self.active_cell.set_variable_value(variable_name, GrpcValue(variable_value))
2933
2758
 
2934
2759
  def get_bounding_box(self) -> list[list[float, float], list[float, float]]:
2935
- """Get the layout bounding box.
2760
+ """Get layout bounding box.
2936
2761
 
2937
2762
  Returns
2938
2763
  -------
2939
- list[float]
2940
- Bounding box as a [lower-left X, lower-left Y, upper-right X, upper-right Y] in meters.
2764
+ list
2765
+ [[min_x, min_y], [max_x, max_y]] in meters.
2941
2766
  """
2942
2767
  lay_inst_polygon_data = [obj_inst.get_bbox() for obj_inst in self.layout_instance.query_layout_obj_instances()]
2943
2768
  layout_bbox = GrpcPolygonData.bbox_of_polygons(lay_inst_polygon_data)
2944
2769
  return [[layout_bbox[0].x.value, layout_bbox[0].y.value], [layout_bbox[1].x.value, layout_bbox[1].y.value]]
2945
2770
 
2946
2771
  def get_statistics(self, compute_area=False):
2947
- """Get the EDBStatistics object.
2772
+ """Get layout statistics.
2773
+
2774
+ Parameters
2775
+ ----------
2776
+ compute_area : bool, optional
2777
+ Calculate net areas. Default False.
2948
2778
 
2949
2779
  Returns
2950
2780
  -------
2951
2781
  :class:`LayoutStatistics <pyedb.grpc.database.utility.layout_statistics.LayoutStatistics>`
2782
+ Layout statistics report.
2952
2783
  """
2953
2784
  return self.modeler.get_layout_statistics(evaluate_area=compute_area, net_list=None)
2954
2785
 
2955
2786
  def are_port_reference_terminals_connected(self, common_reference=None):
2956
- """Check if all terminal references in design are connected.
2957
- If the reference nets are different, there is no hope for the terminal references to be connected.
2958
- After we have identified a common reference net we need to loop the terminals again to get
2959
- the correct reference terminals that uses that net.
2787
+ """Check if port reference terminals are connected.
2960
2788
 
2961
2789
  Parameters
2962
2790
  ----------
2963
2791
  common_reference : str, optional
2964
- Common Reference name. If ``None`` it will be searched in ports terminal.
2965
- If a string is passed then all excitations must have such reference assigned.
2792
+ Reference net name to check.
2966
2793
 
2967
2794
  Returns
2968
2795
  -------
2969
2796
  bool
2970
- Either if the ports are connected to reference_name or not.
2971
-
2972
- Examples
2973
- --------
2974
- >>> from pyedb import Edb
2975
- >>>edb = Edb()
2976
- >>> edb.hfss.create_edge_port_vertical(prim_1_id, ["-66mm", "-4mm"], "port_ver")
2977
- >>> edb.hfss.create_edge_port_horizontal(
2978
- >>> ... prim_1_id, ["-60mm", "-4mm"], prim_2_id, ["-59mm", "-4mm"], "port_hori", 30, "Lower"
2979
- >>> ... )
2980
- >>> edb.hfss.create_wave_port(traces[0].id, trace_paths[0][0], "wave_port")
2981
- >>> edb.cutout(["Net1"])
2982
- >>> assert edb.are_port_reference_terminals_connected()
2797
+ True if all port references are connected.
2983
2798
  """
2984
2799
  all_sources = [i for i in self.excitations.values() if not isinstance(i, (WavePort, GapPort, BundleWavePort))]
2985
2800
  all_sources.extend([i for i in self.sources.values()])
@@ -2987,7 +2802,10 @@ class Edb(EdbInit):
2987
2802
  return True
2988
2803
  self.logger.reset_timer()
2989
2804
  if not common_reference:
2990
- common_reference = list(set([i.reference_net.name for i in all_sources if i.reference_net.name]))
2805
+ ref_terminals = [term for term in all_sources if term.is_reference_terminal]
2806
+ common_reference = list(
2807
+ set([i.reference_terminal.net.name for i in all_sources if i.is_reference_terminal])
2808
+ )
2991
2809
  if len(common_reference) > 1:
2992
2810
  self.logger.error("More than 1 reference found.")
2993
2811
  return False
@@ -3137,17 +2955,18 @@ class Edb(EdbInit):
3137
2955
  )
3138
2956
 
3139
2957
  def create_raptorx_setup(self, name=None) -> RaptorXSimulationSetup:
3140
- """Create an RaptorX simulation setup from a template.
2958
+ """Create RaptorX analysis setup (2024R2+ only).
3141
2959
 
3142
2960
  Parameters
3143
2961
  ----------
3144
2962
  name : str, optional
3145
- Setup name.
2963
+ Setup name. Auto-generated if None.
3146
2964
 
3147
2965
  Returns
3148
2966
  -------
3149
- :class:`RaptorXSimulationSetup <legacy.database.edb_data.raptor_x_simulation_setup_data.RaptorXSimulationSetup>`
3150
-
2967
+ :class:`RaptorXSimulationSetup
2968
+ <pyedb.grpc.database.simulation_setup.raptor_x_simulation_setup.RaptorXSimulationSetup>`
2969
+ RaptorX setup or False if unsupported.
3151
2970
  """
3152
2971
  from ansys.edb.core.simulation_setup.raptor_x_simulation_setup import (
3153
2972
  RaptorXSimulationSetup as GrpcRaptorXSimulationSetup,
@@ -3191,28 +3010,20 @@ class Edb(EdbInit):
3191
3010
  pass
3192
3011
 
3193
3012
  def create_siwave_syz_setup(self, name=None, **kwargs) -> SiwaveSimulationSetup:
3194
- """Create a setup from a template.
3013
+ """Create SIwave SYZ analysis setup.
3195
3014
 
3196
3015
  Parameters
3197
3016
  ----------
3198
3017
  name : str, optional
3199
- Setup name.
3018
+ Setup name. Auto-generated if None.
3019
+ **kwargs
3020
+ Setup properties to modify.
3200
3021
 
3201
3022
  Returns
3202
3023
  -------
3203
3024
  :class:`SiwaveSimulationSetup
3204
3025
  <pyedb.grpc.database.simulation_setup.siwave_simulation_setup.SiwaveSimulationSetup>`
3205
-
3206
- Examples
3207
- --------
3208
- >>> from pyedb import Edb
3209
- >>> edbapp = Edb()
3210
- >>> setup1 = edbapp.create_siwave_syz_setup("setup1")
3211
- >>> setup1.add_frequency_sweep(frequency_sweep=[
3212
- ... ["linear count", "0", "1kHz", 1],
3213
- ... ["log scale", "1kHz", "0.1GHz", 10],
3214
- ... ["linear scale", "0.1GHz", "10GHz", "0.1GHz"],
3215
- ... ])
3026
+ SYZ analysis setup.
3216
3027
  """
3217
3028
  if not name:
3218
3029
  name = generate_unique_name("Siwave_SYZ")
@@ -3228,25 +3039,20 @@ class Edb(EdbInit):
3228
3039
  return self.setups[name]
3229
3040
 
3230
3041
  def create_siwave_dc_setup(self, name=None, **kwargs) -> GrpcSIWaveDCIRSimulationSetup:
3231
- """Create a setup from a template.
3042
+ """Create SIwave DC analysis setup.
3232
3043
 
3233
3044
  Parameters
3234
3045
  ----------
3235
3046
  name : str, optional
3236
- Setup name.
3047
+ Setup name. Auto-generated if None.
3048
+ **kwargs
3049
+ Setup properties to modify.
3237
3050
 
3238
3051
  Returns
3239
3052
  -------
3240
3053
  :class:`SIWaveDCIRSimulationSetup
3241
3054
  <pyedb.grpc.database.simulation_setup.siwave_dcir_simulation_setup.SIWaveDCIRSimulationSetup>`
3242
-
3243
- Examples
3244
- --------
3245
- >>> from pyedb import Edb
3246
- >>> edbapp = Edb()
3247
- >>> setup1 = edbapp.create_siwave_dc_setup("setup1")
3248
- >>> setup1.mesh_bondwires = True
3249
-
3055
+ DC analysis setup.
3250
3056
  """
3251
3057
  if not name:
3252
3058
  name = generate_unique_name("Siwave_DC")
@@ -3274,7 +3080,7 @@ class Edb(EdbInit):
3274
3080
  for port in self.excitations.values():
3275
3081
  nets.append(port.net.name)
3276
3082
  for port in self.sources.values():
3277
- nets.append(port.net_name)
3083
+ nets.append(port.net.name)
3278
3084
  nets = list(set(nets))
3279
3085
  max_width = 0
3280
3086
  for net in nets:
@@ -3633,51 +3439,58 @@ class Edb(EdbInit):
3633
3439
  expand_voids_size=0,
3634
3440
  via_offset=True,
3635
3441
  ):
3636
- """Assign automatically design and project variables with current values.
3442
+ """Automatically parametrize design elements.
3637
3443
 
3638
3444
  Parameters
3639
3445
  ----------
3640
3446
  layers : bool, optional
3641
- Enable layer thickness parametrization. Default value is ``True``.
3447
+ Parametrize layer thicknesses. Default True.
3642
3448
  materials : bool, optional
3643
- Enable material parametrization. Default value is ``True``.
3449
+ Parametrize material properties. Default True.
3644
3450
  via_holes : bool, optional
3645
- Enable via diameter parametrization. Default value is ``True``.
3451
+ Parametrize via holes. Default True.
3646
3452
  pads : bool, optional
3647
- Enable pads size parametrization. Default value is ``True``.
3453
+ Parametrize pads. Default True.
3648
3454
  antipads : bool, optional
3649
- Enable anti pads size parametrization. Default value is ``True``.
3455
+ Parametrize antipads. Default True.
3650
3456
  traces : bool, optional
3651
- Enable trace width parametrization. Default value is ``True``.
3652
- layer_filter : str, List(str), optional
3653
- Enable layer filter. Default value is ``None``, all layers are parametrized.
3654
- material_filter : str, List(str), optional
3655
- Enable material filter. Default value is ``None``, all material are parametrized.
3656
- padstack_definition_filter : str, List(str), optional
3657
- Enable padstack definition filter. Default value is ``None``, all padsatcks are parametrized.
3658
- trace_net_filter : str, List(str), optional
3659
- Enable nets filter for trace width parametrization. Default value is ``None``, all layers are parametrized.
3457
+ Parametrize trace widths. Default True.
3458
+ layer_filter : list, optional
3459
+ Layers to include. All if None.
3460
+ material_filter : list, optional
3461
+ Materials to include. All if None.
3462
+ padstack_definition_filter : list, optional
3463
+ Padstacks to include. All if None.
3464
+ trace_net_filter : list, optional
3465
+ Nets to parametrize. All if None.
3660
3466
  use_single_variable_for_padstack_definitions : bool, optional
3661
- Whether to use a single design variable for each padstack definition or a variable per pad layer.
3662
- Default value is ``True``.
3467
+ Single variable per padstack. Default True.
3663
3468
  use_relative_variables : bool, optional
3664
- Whether if use an absolute variable for each trace, padstacks and layers or a delta variable instead.
3665
- Default value is ``True``.
3469
+ Use delta variables. Default True.
3666
3470
  output_aedb_path : str, optional
3667
- Full path and name for the new AEDB file. If None, then current aedb will be cutout.
3471
+ Output AEDB path.
3668
3472
  open_aedb_at_end : bool, optional
3669
- Whether to open the cutout at the end. The default is ``True``.
3473
+ Open AEDB when finished. Default True.
3670
3474
  expand_polygons_size : float, optional
3671
- Expansion size on polygons. Polygons will be expanded in all directions. The default is ``0``.
3475
+ Polygon expansion size. Default 0.
3672
3476
  expand_voids_size : float, optional
3673
- Expansion size on polygon voids. Polygons voids will be expanded in all directions. The default is ``0``.
3477
+ Void expansion size. Default 0.
3674
3478
  via_offset : bool, optional
3675
- Whether if offset the via position or not. The default is ``True``.
3479
+ Parametrize via positions. Default True.
3676
3480
 
3677
3481
  Returns
3678
3482
  -------
3679
- List(str)
3680
- List of all parameter name created.
3483
+ list[str]
3484
+ Created parameter names.
3485
+
3486
+ Examples
3487
+ --------
3488
+ Parametrize design elements:
3489
+ >>> params = edb.auto_parametrize_design(
3490
+ ... layers=True,
3491
+ ... materials=True,
3492
+ ... trace_net_filter=["Clock"]
3493
+ ... )
3681
3494
  """
3682
3495
  edb_original_path = self.edbpath
3683
3496
  if output_aedb_path:
@@ -3904,41 +3717,27 @@ class Edb(EdbInit):
3904
3717
  output_edb=None,
3905
3718
  launching_box_thickness="100um",
3906
3719
  ):
3907
- """Generate EDB design to be consumed by PyAEDT to generate arbitrary wave ports shapes.
3908
- This model has to be considered as merged onto another one. The current opened design must have voids
3909
- surrounding the pad-stacks where wave ports terminal will be created. THe open design won't be edited, only
3910
- primitives like voids and pads-stack definition included in the voids are collected to generate a new design.
3720
+ """Create simplified model for arbitrary wave port generation.
3911
3721
 
3912
3722
  Parameters
3913
3723
  ----------
3914
3724
  temp_directory : str
3915
- Temporary directory used during the method execution.
3916
-
3917
- mounting_side : str
3918
- Gives the orientation to be considered for the current design. 2 options are available ``"top"`` and
3919
- ``"bottom". Default value is ``"top"``. If ``"top"`` is selected the method will voids at the top signal
3920
- layer, and the bottom layer if ``"bottom"`` is used.
3921
-
3922
- signal_nets : List[str], optional
3923
- Provides the nets to be included for the model creation. Default value is ``None``. If None is provided,
3924
- all nets will be included.
3925
-
3926
- terminal_diameter : float, str, optional
3927
- When ``None``, the terminal diameter is evaluated at each pads-tack instance found inside the voids. The top
3928
- or bottom layer pad diameter will be taken, depending on ``mounting_side`` selected. If value is provided,
3929
- it will overwrite the evaluated diameter.
3930
-
3725
+ Working directory.
3726
+ mounting_side : str, optional
3727
+ Board orientation ("top" or "bottom").
3728
+ signal_nets : list, optional
3729
+ Nets to include. All if None.
3730
+ terminal_diameter : float, optional
3731
+ Custom terminal diameter. Auto-calculated if None.
3931
3732
  output_edb : str, optional
3932
- The output EDB absolute. If ``None`` the edb is created in the ``temp_directory`` as default name
3933
- `"waveport_model.aedb"``
3934
-
3935
- launching_box_thickness : float, str, optional
3936
- Launching box thickness used for wave ports. Default value is ``"100um"``.
3733
+ Output AEDB path.
3734
+ launching_box_thickness : str, optional
3735
+ Wave port box thickness.
3937
3736
 
3938
3737
  Returns
3939
3738
  -------
3940
3739
  bool
3941
- ``True`` when succeeded, ``False`` if failed.
3740
+ True if successful, False otherwise.
3942
3741
  """
3943
3742
  if not temp_directory:
3944
3743
  self.logger.error("Temp directory must be provided when creating model foe arbitrary wave port")
@@ -4059,11 +3858,12 @@ class Edb(EdbInit):
4059
3858
 
4060
3859
  @property
4061
3860
  def definitions(self):
4062
- """Returns Definitions class.
3861
+ """EDB definitions access.
4063
3862
 
4064
3863
  Returns
4065
3864
  -------
4066
3865
  :class:`Definitions <pyedb.grpc.database.definitions.Definitions>`
3866
+ Definitions interface.
4067
3867
  """
4068
3868
  from pyedb.grpc.database.definitions import Definitions
4069
3869
 
@@ -4071,28 +3871,31 @@ class Edb(EdbInit):
4071
3871
 
4072
3872
  @property
4073
3873
  def workflow(self):
4074
- """Returns workflow class.
3874
+ """Workflow automation interface.
4075
3875
 
4076
3876
  Returns
4077
- ------
3877
+ -------
4078
3878
  :class:`Workflow <pyedb.workflow.Workflow>`
3879
+ Workflow automation tools.
4079
3880
  """
4080
3881
  return Workflow(self)
4081
3882
 
4082
3883
  def export_gds_comp_xml(self, comps_to_export, gds_comps_unit="mm", control_path=None):
4083
- """Exports an XML file with selected components information for use in a GDS import.
3884
+ """Export component data to GDS XML control file.
3885
+
4084
3886
  Parameters
4085
3887
  ----------
4086
3888
  comps_to_export : list
4087
- List of components whose information will be exported to xml file.
3889
+ Components to export.
4088
3890
  gds_comps_unit : str, optional
4089
- GDS_COMPONENTS section units. Default is ``"mm"``.
3891
+ Output units. Default "mm".
4090
3892
  control_path : str, optional
4091
- Path for outputting the XML file.
3893
+ Output XML path.
3894
+
4092
3895
  Returns
4093
3896
  -------
4094
3897
  bool
4095
- ``True`` when successful, ``False`` when failed.
3898
+ True if successful, False otherwise.
4096
3899
  """
4097
3900
  from pyedb.generic.general_methods import ET
4098
3901