pyedb 0.50.1__py3-none-any.whl → 0.52.0__py3-none-any.whl

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

Potentially problematic release.


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

Files changed (37) hide show
  1. pyedb/__init__.py +1 -1
  2. pyedb/configuration/cfg_ports_sources.py +79 -239
  3. pyedb/configuration/configuration.py +213 -340
  4. pyedb/dotnet/clr_module.py +9 -3
  5. pyedb/dotnet/database/cell/layout.py +10 -1
  6. pyedb/dotnet/database/dotnet/database.py +0 -2
  7. pyedb/dotnet/database/edb_data/padstacks_data.py +8 -2
  8. pyedb/dotnet/database/layout_validation.py +20 -26
  9. pyedb/dotnet/database/modeler.py +0 -1
  10. pyedb/dotnet/database/stackup.py +4 -3
  11. pyedb/dotnet/edb.py +42 -2
  12. pyedb/generic/design_types.py +183 -62
  13. pyedb/grpc/database/__init__.py +0 -1
  14. pyedb/grpc/database/components.py +110 -0
  15. pyedb/grpc/database/control_file.py +150 -17
  16. pyedb/grpc/database/definition/materials.py +7 -7
  17. pyedb/grpc/database/definitions.py +36 -2
  18. pyedb/grpc/database/hfss.py +15 -0
  19. pyedb/grpc/database/hierarchy/component.py +10 -2
  20. pyedb/grpc/database/hierarchy/pin_pair_model.py +1 -1
  21. pyedb/grpc/database/layout_validation.py +58 -7
  22. pyedb/grpc/database/net/differential_pair.py +2 -1
  23. pyedb/grpc/database/nets.py +233 -4
  24. pyedb/grpc/database/padstacks.py +97 -0
  25. pyedb/grpc/database/primitive/padstack_instance.py +1 -1
  26. pyedb/grpc/database/primitive/polygon.py +1 -1
  27. pyedb/grpc/database/siwave.py +63 -3
  28. pyedb/grpc/database/source_excitations.py +317 -50
  29. pyedb/grpc/database/stackup.py +107 -2
  30. pyedb/grpc/database/terminal/point_terminal.py +2 -2
  31. pyedb/grpc/database/terminal/terminal.py +1 -1
  32. pyedb/grpc/edb.py +190 -224
  33. pyedb/grpc/edb_init.py +54 -5
  34. {pyedb-0.50.1.dist-info → pyedb-0.52.0.dist-info}/METADATA +4 -4
  35. {pyedb-0.50.1.dist-info → pyedb-0.52.0.dist-info}/RECORD +37 -37
  36. {pyedb-0.50.1.dist-info → pyedb-0.52.0.dist-info}/LICENSE +0 -0
  37. {pyedb-0.50.1.dist-info → pyedb-0.52.0.dist-info}/WHEEL +0 -0
pyedb/grpc/edb.py CHANGED
@@ -178,13 +178,13 @@ class Edb(EdbInit):
178
178
 
179
179
  Examples
180
180
  --------
181
- Create new EDB:
181
+ >>> # Create new EDB:
182
182
  >>> edb = Edb()
183
183
 
184
- Open existing AEDB:
184
+ >>> # Open existing AEDB:
185
185
  >>> edb = Edb("myproject.aedb")
186
186
 
187
- Import board file:
187
+ >>> # Import board file:
188
188
  >>> edb = Edb("my_board.brd")
189
189
  """
190
190
 
@@ -378,23 +378,6 @@ class Edb(EdbInit):
378
378
  except:
379
379
  self.logger.info(f"Failed to delete AEDT project-related file {file}.")
380
380
 
381
- def _clean_variables(self):
382
- """Initialize internal variables and perform garbage collection."""
383
- self.grpc = True
384
- self._materials = None
385
- self._components = None
386
- self._core_primitives = None
387
- self._stackup = None
388
- self._padstack = None
389
- self._siwave = None
390
- self._hfss = None
391
- self._nets = None
392
- self._layout_instance = None
393
- self._variables = None
394
- self._active_cell = None
395
- self._layout = None
396
- self._configuration = None
397
-
398
381
  def _init_objects(self):
399
382
  self._components = Components(self)
400
383
  self._stackup = Stackup(self, self.layout.layer_collection)
@@ -503,7 +486,7 @@ class Edb(EdbInit):
503
486
 
504
487
  Returns
505
488
  -------
506
- dict[str, Union[:class:`GapPort`, :class:`WavePort`, :class:`CoaxPort`]]
489
+ dict[str, list[:class:`GapPort` or :class:`WavePort` or :class:`CoaxPort`]]
507
490
  Port names and objects.
508
491
  """
509
492
  terminals = [term for term in self.layout.terminals if not term.is_reference_terminal]
@@ -579,19 +562,24 @@ class Edb(EdbInit):
579
562
  terms = [term for term in self.layout.terminals if term.boundary_type.value == 8]
580
563
  return {ter.name: ter for ter in terms}
581
564
 
582
- def open_edb(self, restart_rpc_server=False) -> bool:
565
+ def open(self, restart_rpc_server=False) -> bool:
583
566
  """Open EDB database.
584
567
 
585
568
  Returns
586
569
  -------
587
570
  bool
588
571
  True if successful, False otherwise.
572
+
573
+ Examples
574
+ --------
575
+ >>> # Open an existing EDB database:
576
+ >>> edb = Edb("myproject.aedb")
589
577
  """
590
578
  self.standalone = self.standalone
591
579
  n_try = 10
592
580
  while not self.db and n_try:
593
581
  try:
594
- self.open(
582
+ self._open(
595
583
  self.edbpath,
596
584
  self.isreadonly,
597
585
  restart_rpc_server=restart_rpc_server,
@@ -621,7 +609,21 @@ class Edb(EdbInit):
621
609
  self.logger.error("Builder was not initialized.")
622
610
  return True
623
611
 
624
- def create_edb(self, restart_rpc_server=False) -> bool:
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.
617
+
618
+ Returns
619
+ -------
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:
625
627
  """Create new EDB database.
626
628
 
627
629
  Returns
@@ -636,7 +638,7 @@ class Edb(EdbInit):
636
638
  n_try = 10
637
639
  while not self.db and n_try:
638
640
  try:
639
- self.create(self.edbpath, restart_rpc_server=restart_rpc_server)
641
+ self._create(self.edbpath, restart_rpc_server=restart_rpc_server)
640
642
  n_try -= 1
641
643
  except Exception as e:
642
644
  self.logger.error(e.args[0])
@@ -651,9 +653,22 @@ class Edb(EdbInit):
651
653
  )
652
654
  if self._active_cell:
653
655
  self._init_objects()
654
- return True
656
+ return self
655
657
  return None
656
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
+
657
672
  def import_layout_pcb(
658
673
  self,
659
674
  input_file,
@@ -746,6 +761,12 @@ class Edb(EdbInit):
746
761
  -------
747
762
  Full path to the AEDB file : str
748
763
 
764
+ Examples
765
+ --------
766
+ >>> # Import a BRD file:
767
+ >>> edb.import_layout_file("my_board.brd", r"C:/project")
768
+ >>> # Import a GDS file with control file:
769
+ >>> edb.import_layout_file("layout.gds", control_file="control.xml")
749
770
  """
750
771
  self._components = None
751
772
  self._core_primitives = None
@@ -806,6 +827,11 @@ class Edb(EdbInit):
806
827
  -------
807
828
  str or bool
808
829
  Output file path if successful, False otherwise.
830
+
831
+ Examples
832
+ --------
833
+ >>> # Export to IPC2581 format:
834
+ >>> edb.export_to_ipc2581("output.xml")
809
835
  """
810
836
  if units.lower() not in ["millimeter", "inch", "micron"]: # pragma no cover
811
837
  self.logger.warning("The wrong unit is entered. Setting to the default, millimeter.")
@@ -1182,18 +1208,6 @@ class Edb(EdbInit):
1182
1208
  else:
1183
1209
  return PointData(x, y)
1184
1210
 
1185
- @staticmethod
1186
- def _is_file_existing_and_released(filename) -> bool:
1187
- if os.path.exists(filename):
1188
- try:
1189
- os.rename(filename, filename + "_")
1190
- os.rename(filename + "_", filename)
1191
- return True
1192
- except OSError as e:
1193
- return False
1194
- else:
1195
- return False
1196
-
1197
1211
  @staticmethod
1198
1212
  def _is_file_existing(filename) -> bool:
1199
1213
  if os.path.exists(filename):
@@ -1201,18 +1215,6 @@ class Edb(EdbInit):
1201
1215
  else:
1202
1216
  return False
1203
1217
 
1204
- def _wait_for_file_release(self, timeout=30, file_to_release=None) -> bool:
1205
- if not file_to_release:
1206
- file_to_release = os.path.join(self.edbpath)
1207
- tstart = time.time()
1208
- while True:
1209
- if self._is_file_existing_and_released(file_to_release):
1210
- return True
1211
- elif time.time() - tstart > timeout:
1212
- return False
1213
- else:
1214
- time.sleep(0.250)
1215
-
1216
1218
  def _wait_for_file_exists(self, timeout=30, file_to_release=None, wait_count=4):
1217
1219
  if not file_to_release:
1218
1220
  file_to_release = os.path.join(self.edbpath)
@@ -1234,57 +1236,40 @@ class Edb(EdbInit):
1234
1236
  def close_edb(self) -> bool:
1235
1237
  """Close EDB and clean up resources.
1236
1238
 
1239
+ ..deprecated:: 0.51.0
1240
+ Use :func:`close` instead.
1241
+
1237
1242
  Returns
1238
1243
  -------
1239
1244
  bool
1240
1245
  True if successful, False otherwise.
1246
+
1247
+ Examples
1248
+ --------
1249
+ Close the EDB session:
1250
+ >>> edb.close_edb()
1241
1251
  """
1242
- self.close()
1243
- start_time = time.time()
1244
- self._wait_for_file_release()
1245
- elapsed_time = time.time() - start_time
1246
- self.logger.info("EDB file release time: {0:.2f}ms".format(elapsed_time * 1000.0))
1247
- self._clean_variables()
1248
- return True
1252
+ warnings.warn("Use method close instead.", DeprecationWarning)
1253
+ return self.close()
1249
1254
 
1250
1255
  def save_edb(self) -> bool:
1251
1256
  """Save current EDB database.
1252
1257
 
1253
- Returns
1254
- -------
1255
- bool
1256
- True if successful, False otherwise.
1258
+ ..deprecated:: 0.51.0
1259
+ Use :func:`save` instead.
1260
+
1257
1261
  """
1258
- self.save()
1259
- start_time = time.time()
1260
- self._wait_for_file_release()
1261
- elapsed_time = time.time() - start_time
1262
- self.logger.info("EDB file save time: {0:.2f}ms".format(elapsed_time * 1000.0))
1263
- return True
1262
+ warnings.warn("Use method save instead.", DeprecationWarning)
1263
+ return self.save()
1264
1264
 
1265
1265
  def save_edb_as(self, fname) -> bool:
1266
1266
  """Save EDB database to new location.
1267
1267
 
1268
- Parameters
1269
- ----------
1270
- fname : str
1271
- New AEDB path.
1272
-
1273
- Returns
1274
- -------
1275
- bool
1276
- True if successful, False otherwise.
1268
+ ..deprecated:: 0.51.0
1269
+ Use :func:`save_as` instead.
1277
1270
  """
1278
- self.save_as(fname)
1279
- start_time = time.time()
1280
- self._wait_for_file_release()
1281
- elapsed_time = time.time() - start_time
1282
- self.logger.info("EDB file save time: {0:.2f}ms".format(elapsed_time * 1000.0))
1283
- self.edbpath = self.directory
1284
- self.log_name = os.path.join(
1285
- os.path.dirname(fname), "pyedb_" + os.path.splitext(os.path.split(fname)[-1])[0] + ".log"
1286
- )
1287
- return True
1271
+ warnings.warn("Use method save_as instead.", DeprecationWarning)
1272
+ return self.save_as(fname)
1288
1273
 
1289
1274
  def execute(self, func):
1290
1275
  """Execute EDB utility command (Not implemented in gRPC).
@@ -1297,8 +1282,12 @@ class Edb(EdbInit):
1297
1282
  # return self.edb_api.utility.utility.Command.Execute(func)
1298
1283
  pass
1299
1284
 
1300
- def import_cadence_file(self, inputBrd, WorkDir=None, anstranslator_full_path="", use_ppe=False):
1301
- """Import Cadence board file (Deprecated - use import_layout_file)."""
1285
+ def import_cadence_file(self, inputBrd, WorkDir=None, anstranslator_full_path="", use_ppe=False) -> bool:
1286
+ """Import Cadence board file.
1287
+
1288
+ .. deprecated:: 0.50
1289
+ Use :func:`import_layout_file` instead.
1290
+ """
1302
1291
  if self.import_layout_pcb(
1303
1292
  inputBrd,
1304
1293
  working_dir=WorkDir,
@@ -1694,6 +1683,14 @@ class Edb(EdbInit):
1694
1683
  -------
1695
1684
  list or bool
1696
1685
  Cutout boundary points if successful, False otherwise.
1686
+
1687
+ Examples
1688
+ --------
1689
+ >>> # Create a basic cutout:
1690
+ >>> edb.cutout(signal_list=["Net1"], reference_list=["GND"])
1691
+ >>> # Create cutout with custom polygon:
1692
+ >>> custom_poly = [[0,0], [10e-3,0], [10e-3,10e-3], [0,10e-3]]
1693
+ >>> edb.cutout(custom_extent=custom_poly)
1697
1694
  """
1698
1695
  if expansion_factor > 0:
1699
1696
  expansion_size = self.calculate_initial_extent(expansion_factor)
@@ -1770,7 +1767,7 @@ class Edb(EdbInit):
1770
1767
  break
1771
1768
  self.close_edb()
1772
1769
  self.edbpath = legacy_path
1773
- self.open_edb()
1770
+ self.open()
1774
1771
  i += 1
1775
1772
  expansion = expansion_size * i
1776
1773
  if working_cutout:
@@ -1856,15 +1853,15 @@ class Edb(EdbInit):
1856
1853
  # _cutout.simulation_setups = self.active_cell.simulation_setups see bug #433 status.
1857
1854
  _dbCells = [_cutout]
1858
1855
  if output_aedb_path:
1859
- db2 = self.create(output_aedb_path)
1860
- _success = db2.save()
1861
- _dbCells = _dbCells
1856
+ from ansys.edb.core.database import Database as GrpcDatabase
1857
+
1858
+ db2 = GrpcDatabase.create(output_aedb_path)
1862
1859
  db2.copy_cells(_dbCells) # Copies cutout cell/design to db2 project
1863
- if len(list(db2.circuit_cells)) > 0:
1864
- for net in db2.circuit_cells[0].layout.nets:
1860
+ if len(list(db2.top_circuit_cells)) > 0:
1861
+ for net in db2.top_circuit_cells[0].layout.nets:
1865
1862
  if not net.name in included_nets_list:
1866
1863
  net.delete()
1867
- _success = db2.save()
1864
+ db2.save()
1868
1865
  for c in self.active_db.top_circuit_cells:
1869
1866
  if c.name == _cutout.name:
1870
1867
  c.delete()
@@ -1890,7 +1887,7 @@ class Edb(EdbInit):
1890
1887
  for _cmp in _cmps:
1891
1888
  _cmp.delete()
1892
1889
  except:
1893
- self._logger.error("Failed to remove single pin components.")
1890
+ self.logger.error("Failed to remove single pin components.")
1894
1891
  db2.close()
1895
1892
  source = os.path.join(output_aedb_path, "edb.def.tmp")
1896
1893
  target = os.path.join(output_aedb_path, "edb.def")
@@ -2342,7 +2339,9 @@ class Edb(EdbInit):
2342
2339
 
2343
2340
  _dbCells = [_cutout]
2344
2341
  if output_aedb_path:
2345
- db2 = self.create(output_aedb_path)
2342
+ from ansys.edb.core.database import Database as GrpcDatabase
2343
+
2344
+ db2 = GrpcDatabase.create(output_aedb_path)
2346
2345
  db2.save()
2347
2346
  cell_copied = db2.copy_cells(_dbCells) # Copies cutout cell/design to db2 project
2348
2347
  cell = cell_copied[0]
@@ -2352,7 +2351,7 @@ class Edb(EdbInit):
2352
2351
  if c.name == _cutout.name:
2353
2352
  c.delete()
2354
2353
  if open_cutout_at_end: # pragma: no cover
2355
- _success = db2.save()
2354
+ db2.save()
2356
2355
  self._db = db2
2357
2356
  self.edbpath = output_aedb_path
2358
2357
  self._active_cell = cell
@@ -2436,6 +2435,11 @@ class Edb(EdbInit):
2436
2435
  -------
2437
2436
  str
2438
2437
  Path to generated AEDT file.
2438
+
2439
+ Examples
2440
+ --------
2441
+ >>> # Export to HFSS project:
2442
+ >>> edb.export_hfss(r"C:/output", net_list=["SignalNet"])
2439
2443
  """
2440
2444
  siwave_s = SiwaveSolve(self.edbpath, aedt_installer_path=self.base_path)
2441
2445
  return siwave_s.export_3d_cad("HFSS", path_to_output, net_list, num_cores, aedt_file_name, hidden=hidden)
@@ -2467,6 +2471,11 @@ class Edb(EdbInit):
2467
2471
  -------
2468
2472
  str
2469
2473
  Path to generated AEDT file.
2474
+
2475
+ Examples
2476
+ --------
2477
+ >>> # Export to Q3D project:
2478
+ >>> edb.export_q3d(r"C:/output")
2470
2479
  """
2471
2480
  siwave_s = SiwaveSolve(self.edbpath, aedt_installer_path=self.base_path)
2472
2481
  return siwave_s.export_3d_cad(
@@ -2505,6 +2514,11 @@ class Edb(EdbInit):
2505
2514
  -------
2506
2515
  str
2507
2516
  Path to generated AEDT file.
2517
+
2518
+ Examples
2519
+ --------
2520
+ >>> # Export to Maxwell project:
2521
+ >>> edb.export_maxwell(r"C:/output")
2508
2522
  """
2509
2523
  siwave_s = SiwaveSolve(self.edbpath, aedt_installer_path=self.base_path)
2510
2524
  return siwave_s.export_3d_cad(
@@ -2523,6 +2537,11 @@ class Edb(EdbInit):
2523
2537
  -------
2524
2538
  str
2525
2539
  Path to SIwave project.
2540
+
2541
+ Examples
2542
+ --------
2543
+ >>> # Solve with SIwave:
2544
+ >>> edb.solve_siwave()
2526
2545
  """
2527
2546
  process = SiwaveSolve(self.edbpath, aedt_version=self.edbversion)
2528
2547
  try:
@@ -2721,7 +2740,7 @@ class Edb(EdbInit):
2721
2740
  Returns
2722
2741
  -------
2723
2742
  list
2724
- [[min_x, min_y], [max_x, max_y]] in meters.
2743
+ list[list[min_x, min_y], list[max_x, max_y]] in meters.
2725
2744
  """
2726
2745
  lay_inst_polygon_data = [obj_inst.get_bbox() for obj_inst in self.layout_instance.query_layout_obj_instances()]
2727
2746
  layout_bbox = GrpcPolygonData.bbox_of_polygons(lay_inst_polygon_data)
@@ -2761,7 +2780,10 @@ class Edb(EdbInit):
2761
2780
  return True
2762
2781
  self.logger.reset_timer()
2763
2782
  if not common_reference:
2764
- common_reference = list(set([i.reference_net.name for i in all_sources if i.reference_net.name]))
2783
+ ref_terminals = [term for term in all_sources if term.is_reference_terminal]
2784
+ common_reference = list(
2785
+ set([i.reference_terminal.net.name for i in all_sources if i.is_reference_terminal])
2786
+ )
2765
2787
  if len(common_reference) > 1:
2766
2788
  self.logger.error("More than 1 reference found.")
2767
2789
  return False
@@ -2821,10 +2843,10 @@ class Edb(EdbInit):
2821
2843
 
2822
2844
  Returns
2823
2845
  -------
2824
- Dict[str,: class:`pyedb.grpc.database.simulation_setup.hfss_simulation_setup.HfssSimulationSetup`] or
2825
- Dict[str,: class:`pyedb.grpc.database.simulation_setup.siwave_simulation_setup.SiwaveSimulationSetup`] or
2826
- Dict[str,: class:`SIWaveDCIRSimulationSetup`] or
2827
- Dict[str,: class:`pyedb.grpc.database.simulation_setup.raptor_x_simulation_setup.RaptorXSimulationSetup`]
2846
+ Dict[str,:class:`HfssSimulationSetup`] or
2847
+ Dict[str,:class:`SiwaveSimulationSetup`] or
2848
+ Dict[str,:class:`SIWaveDCIRSimulationSetup`] or
2849
+ Dict[str,:class:`RaptorXSimulationSetup`]
2828
2850
 
2829
2851
  """
2830
2852
  self._setups = {}
@@ -2875,8 +2897,7 @@ class Edb(EdbInit):
2875
2897
 
2876
2898
  Returns
2877
2899
  -------
2878
- Dict[str,:class:`SiwaveSimulationSetup
2879
- <pyedb.grpc.database.simulation_setup.siwave_simulation_setup.SiwaveSimulationSetup>`]
2900
+ Dict[str,:class:`SiwaveSimulationSetup`]
2880
2901
  """
2881
2902
  return {name: i for name, i in self.setups.items() if isinstance(i, SiwaveSimulationSetup)}
2882
2903
 
@@ -2887,16 +2908,6 @@ class Edb(EdbInit):
2887
2908
 
2888
2909
  . deprecated:: pyedb 0.30.0
2889
2910
  Use :func:`pyedb.grpc.core.hfss.add_setup` instead.
2890
-
2891
- Parameters
2892
- ----------
2893
- name : str, optional
2894
- Setup name.
2895
-
2896
- Returns
2897
- -------
2898
- :class:`HfssSimulationSetup <legacy.database.edb_data.hfss_simulation_setup_data.HfssSimulationSetup>`
2899
-
2900
2911
  """
2901
2912
  warnings.warn(
2902
2913
  "`create_hfss_setup` is deprecated and is now located here " "`pyedb.grpc.core.hfss.add_setup` instead.",
@@ -2920,8 +2931,7 @@ class Edb(EdbInit):
2920
2931
 
2921
2932
  Returns
2922
2933
  -------
2923
- :class:`RaptorXSimulationSetup
2924
- <pyedb.grpc.database.simulation_setup.raptor_x_simulation_setup.RaptorXSimulationSetup>`
2934
+ :class:`RaptorXSimulationSetup`
2925
2935
  RaptorX setup or False if unsupported.
2926
2936
  """
2927
2937
  from ansys.edb.core.simulation_setup.raptor_x_simulation_setup import (
@@ -2977,8 +2987,7 @@ class Edb(EdbInit):
2977
2987
 
2978
2988
  Returns
2979
2989
  -------
2980
- :class:`SiwaveSimulationSetup
2981
- <pyedb.grpc.database.simulation_setup.siwave_simulation_setup.SiwaveSimulationSetup>`
2990
+ :class:`SiwaveSimulationSetup`
2982
2991
  SYZ analysis setup.
2983
2992
  """
2984
2993
  if not name:
@@ -3006,8 +3015,7 @@ class Edb(EdbInit):
3006
3015
 
3007
3016
  Returns
3008
3017
  -------
3009
- :class:`SIWaveDCIRSimulationSetup
3010
- <pyedb.grpc.database.simulation_setup.siwave_dcir_simulation_setup.SIWaveDCIRSimulationSetup>`
3018
+ :class:`SIWaveDCIRSimulationSetup`
3011
3019
  DC analysis setup.
3012
3020
  """
3013
3021
  if not name:
@@ -3036,7 +3044,7 @@ class Edb(EdbInit):
3036
3044
  for port in self.excitations.values():
3037
3045
  nets.append(port.net.name)
3038
3046
  for port in self.sources.values():
3039
- nets.append(port.net_name)
3047
+ nets.append(port.net.name)
3040
3048
  nets = list(set(nets))
3041
3049
  max_width = 0
3042
3050
  for net in nets:
@@ -3051,8 +3059,8 @@ class Edb(EdbInit):
3051
3059
  self.logger.info(f"The W factor is {expansion_factor}, The initial extent = {max_width}")
3052
3060
  return max_width
3053
3061
 
3054
- def copy_zones(self, working_directory=None):
3055
- """Copy multizone EDB project to one new edb per zone.
3062
+ def copy_zones(self, working_directory=None) -> dict[str, tuple[int, GrpcPolygonData]]:
3063
+ """Copy multi-zone EDB project to one new edb per zone.
3056
3064
 
3057
3065
  Parameters
3058
3066
  ----------
@@ -3061,7 +3069,8 @@ class Edb(EdbInit):
3061
3069
 
3062
3070
  Returns
3063
3071
  -------
3064
- dict[str, [int,: class:`PolygonData <ansys.edb.core.geometry.polygon_data.PolygonData>`]]
3072
+ dict[str, tuple[int,:class:`PolygonData <ansys.edb.core.geometry.polygon_data.PolygonData>`]]
3073
+
3065
3074
  Return a dictionary with edb path as key and tuple Zone Id as first item and EDB polygon Data defining
3066
3075
  the region as second item.
3067
3076
 
@@ -3080,7 +3089,7 @@ class Edb(EdbInit):
3080
3089
  edb_zones = {}
3081
3090
  if not self.setups:
3082
3091
  self.siwave.add_siwave_syz_analysis()
3083
- self.save_edb()
3092
+ self.save()
3084
3093
  for zone_primitive in zone_primitives:
3085
3094
  if zone_primitive:
3086
3095
  edb_zone_path = os.path.join(working_directory, f"{zone_primitive.id}_{os.path.basename(self.edbpath)}")
@@ -3114,10 +3123,9 @@ class Edb(EdbInit):
3114
3123
 
3115
3124
  Returns
3116
3125
  -------
3117
- Dict[str: str] or List[str]
3118
- first dictionary defined_ports with edb name as key and existing port name list as value. Those ports are the
3119
- ones defined before processing the multizone clipping.
3120
- second is the list of connected port.
3126
+ dict[str: str] or list[str]
3127
+ first dictionary defined_ports with edb name as key and existing port name list as value. Those ports are
3128
+ the ones defined before processing the multizone clipping. the second is the list of connected port.
3121
3129
 
3122
3130
  """
3123
3131
  terminals = {}
@@ -3236,29 +3244,8 @@ class Edb(EdbInit):
3236
3244
  """Create a port.
3237
3245
 
3238
3246
  ..deprecated:: 0.51.0
3239
- Use: func:`create_port` has been move to source_excitation.create_port.
3247
+ Use :func:`create_port` has been moved to source_excitation.create_port.
3240
3248
 
3241
- Parameters
3242
- ----------
3243
- terminal : class:`pyedb.dotnet.database.edb_data.terminals.EdgeTerminal`,
3244
- class:`pyedb.grpc.database.terminals.PadstackInstanceTerminal`,
3245
- class:`pyedb.grpc.database.terminals.PointTerminal`,
3246
- class:`pyedb.grpc.database.terminals.PinGroupTerminal`,
3247
- Positive terminal of the port.
3248
- ref_terminal : class:`pyedb.grpc.database.terminals.EdgeTerminal`,
3249
- class:`pyedb.grpc.database.terminals.PadstackInstanceTerminal`,
3250
- class:`pyedb.grpc.database.terminals.PointTerminal`,
3251
- class:`pyedb.grpc.database.terminals.PinGroupTerminal`,
3252
- optional
3253
- Negative terminal of the port.
3254
- is_circuit_port : bool, optional
3255
- Whether it is a circuit port. The default is ``False``.
3256
- name: str, optional
3257
- Name of the created port. The default is None, a random name is generated.
3258
- Returns
3259
- -------
3260
- list: [:class:`GapPort <pyedb.grpc.database.ports.ports.GapPort`>,
3261
- :class:`WavePort <pyedb.grpc.database.ports.ports.WavePort>`].
3262
3249
  """
3263
3250
 
3264
3251
  warnings.warn("Use create_port from edb.source_excitation.create_port", DeprecationWarning)
@@ -3268,24 +3255,8 @@ class Edb(EdbInit):
3268
3255
  """Create a voltage probe.
3269
3256
 
3270
3257
  ..deprecated:: 0.50.0
3271
- Use: func:`create_voltage_probe` located in edb.source_excitation.create_voltage_probe instead.
3272
-
3273
- Parameters
3274
- ----------
3275
- terminal : :class:`EdgeTerminal <pyedb.grpc.database.terminals.EdgeTerminal>`,
3276
- :class:`PadstackInstanceTerminal <pyedb.grpc.database.terminals.PadstackInstanceTerminal>`,
3277
- :class:`PointTerminal <pyedb.grpc.database.terminals.PointTerminal>`,
3278
- :class:`PinGroupTerminal <pyedb.grpc.database.terminals.PinGroupTerminal>`,
3279
- Positive terminal of the port.
3280
- ref_terminal : :class:`EdgeTerminal <pyedb.grpc.database.terminals.EdgeTerminal>`,
3281
- :class:`pyedb.grpc.database.terminals.PadstackInstanceTerminal`,
3282
- :class:`PadstackInstanceTerminal <pyedb.grpc.database.terminals.PointTerminal>`,
3283
- :class:`PinGroupTerminal <pyedb.grpc.database.terminals.PinGroupTerminal>`,
3284
- Negative terminal of the probe.
3258
+ Use :func:`create_voltage_probe` has been moved to edb.source_excitation.create_voltage_probe.
3285
3259
 
3286
- Returns
3287
- -------
3288
- :class:`Terminal <pyedb.dotnet.database.edb_data.terminals.Terminal>`
3289
3260
  """
3290
3261
  warnings.warn("Use create_voltage_probe located in edb.source_excitation instead", DeprecationWarning)
3291
3262
  return self.source_excitation.create_voltage_probe(terminal, ref_terminal)
@@ -3294,24 +3265,8 @@ class Edb(EdbInit):
3294
3265
  """Create a voltage source.
3295
3266
 
3296
3267
  ..deprecated:: 0.50.0
3297
- Use: func:`create_voltage_source` located in edb.source_excitation.create_voltage_source instead.
3268
+ Use: func:`create_voltage_source` has been moved to edb.source_excitation.create_voltage_source.
3298
3269
 
3299
- Parameters
3300
- ----------
3301
- terminal : :class:`EdgeTerminal <pyedb.grpc.database.terminals.EdgeTerminal>`,
3302
- :class:`PadstackInstanceTerminal <pyedb.grpc.database.terminals.PadstackInstanceTerminal>`,
3303
- :class:`PointTerminal <pyedb.grpc.database.terminals.PointTerminal>`,
3304
- :class:`PinGroupTerminal <pyedb.grpc.database.terminals.PinGroupTerminal>`,
3305
- Positive terminal of the source.
3306
- ref_terminal : :class:`EdgeTerminal <pyedb.grpc.database.terminals.EdgeTerminal>`,
3307
- :class:`pyedb.grpc.database.terminals.PadstackInstanceTerminal`,
3308
- :class:`PadstackInstanceTerminal <pyedb.grpc.database.terminals.PointTerminal>`,
3309
- :class:`PinGroupTerminal <pyedb.grpc.database.terminals.PinGroupTerminal>`,
3310
- Negative terminal of the source.
3311
-
3312
- Returns
3313
- -------
3314
- class:`ExcitationSources <legacy.database.edb_data.ports.ExcitationSources>`
3315
3270
  """
3316
3271
  warnings.warn(
3317
3272
  "use create_voltage_source located in edb.source_excitation.create_voltage_source instead",
@@ -3323,24 +3278,8 @@ class Edb(EdbInit):
3323
3278
  """Create a current source.
3324
3279
 
3325
3280
  ..deprecated:: 0.50.0
3326
- Use: func:`create_current_source` located in edb.source_excitation.create_current_source instead.
3281
+ Use :func:`create_current_source` has been moved to edb.source_excitation.create_current_source.
3327
3282
 
3328
- Parameters
3329
- ----------
3330
- terminal : :class:`EdgeTerminal <pyedb.grpc.database.terminals.EdgeTerminal>`,
3331
- :class:`PadstackInstanceTerminal <pyedb.grpc.database.terminals.PadstackInstanceTerminal>`,
3332
- :class:`PointTerminal <pyedb.grpc.database.terminals.PointTerminal>`,
3333
- :class:`PinGroupTerminal <pyedb.grpc.database.terminals.PinGroupTerminal>`,
3334
- Positive terminal of the source.
3335
- ref_terminal : :class:`EdgeTerminal <pyedb.grpc.database.terminals.EdgeTerminal>`,
3336
- :class:`pyedb.grpc.database.terminals.PadstackInstanceTerminal`,
3337
- :class:`PadstackInstanceTerminal <pyedb.grpc.database.terminals.PointTerminal>`,
3338
- :class:`PinGroupTerminal <pyedb.grpc.database.terminals.PinGroupTerminal>`,
3339
- Negative terminal of the source.
3340
-
3341
- Returns
3342
- -------
3343
- :class:`ExcitationSources <legacy.database.edb_data.ports.ExcitationSources>`
3344
3283
  """
3345
3284
  warnings.warn(
3346
3285
  "use create_current_source located in edb.source_excitation.create_current_source instead",
@@ -3352,22 +3291,7 @@ class Edb(EdbInit):
3352
3291
  """Place terminal between two points.
3353
3292
 
3354
3293
  ..deprecated:: 0.50.0
3355
- Use: func:`get_point_terminal` located in edb.source_excitation.get_point_terminal instead.
3356
-
3357
- Parameters
3358
- ----------
3359
- name : str,
3360
- Name of the terminal.
3361
- net_name : str
3362
- Name of the net.
3363
- location : list
3364
- Location of the terminal.
3365
- layer : str,
3366
- Layer of the terminal.
3367
-
3368
- Returns
3369
- -------
3370
- :class:`PointTerminal <pyedb.grpc.database.terminal.point_terminal.PointTerminal>`
3294
+ Use: func:`get_point_terminal` has been moved to edb.source_excitation.get_point_terminal.
3371
3295
  """
3372
3296
 
3373
3297
  warnings.warn(
@@ -3438,10 +3362,18 @@ class Edb(EdbInit):
3438
3362
  -------
3439
3363
  list[str]
3440
3364
  Created parameter names.
3365
+
3366
+ Examples
3367
+ --------
3368
+ Parametrize design elements:
3369
+ >>> params = edb.auto_parametrize_design(
3370
+ >>> layers=True,
3371
+ >>> materials=True,
3372
+ >>> trace_net_filter=["Clock"])
3441
3373
  """
3442
3374
  edb_original_path = self.edbpath
3443
3375
  if output_aedb_path:
3444
- self.save_edb_as(output_aedb_path)
3376
+ self.save_as(output_aedb_path)
3445
3377
  if isinstance(trace_net_filter, str):
3446
3378
  trace_net_filter = [trace_net_filter]
3447
3379
  parameters = []
@@ -3629,10 +3561,10 @@ class Edb(EdbInit):
3629
3561
  void.expand(expand_voids_size, round_corners=False)
3630
3562
 
3631
3563
  if not open_aedb_at_end and self.edbpath != edb_original_path:
3632
- self.save_edb()
3633
- self.close_edb()
3564
+ self.save()
3565
+ self.close()
3634
3566
  self.edbpath = edb_original_path
3635
- self.open_edb()
3567
+ self.open()
3636
3568
  return parameters
3637
3569
 
3638
3570
  @staticmethod
@@ -3868,3 +3800,37 @@ class Edb(EdbInit):
3868
3800
  ET.indent(tree, space="\t", level=0)
3869
3801
  tree.write(control_path)
3870
3802
  return True if os.path.exists(control_path) else False
3803
+
3804
+ def compare(self, input_file, results=""):
3805
+ """Compares current open database with another one.
3806
+
3807
+ Parameters
3808
+ ----------
3809
+ input_file : str
3810
+ Path to the edb file.
3811
+ results: str, optional
3812
+ Path to directory in which results will be saved. If no path is given, a new "_compare_results"
3813
+ directory will be created with the same naming and path as the .aedb folder.
3814
+ Returns
3815
+ -------
3816
+ bool
3817
+ ``True`` when successful, ``False`` when failed.
3818
+ """
3819
+ self.save()
3820
+ if not results:
3821
+ results = self.edbpath[:-5] + "_compare_results"
3822
+ os.mkdir(results)
3823
+ command = os.path.join(self.base_path, "EDBDiff.exe")
3824
+ if is_linux:
3825
+ mono_path = os.path.join(self.base_path, "common/mono/Linux64/bin/mono")
3826
+ cmd_input = [mono_path, command, input_file, self.edbpath, results]
3827
+ else:
3828
+ cmd_input = [command, input_file, self.edbpath, results]
3829
+ subprocess.run(cmd_input)
3830
+
3831
+ if not os.path.exists(os.path.join(results, "EDBDiff.csv")):
3832
+ self.logger.error("Comparison execution failed")
3833
+ return False
3834
+ else:
3835
+ self.logger.info("Comparison correctly completed")
3836
+ return True