pyedb 0.27.0__py3-none-any.whl → 0.29.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.
Files changed (34) hide show
  1. pyedb/__init__.py +1 -1
  2. pyedb/configuration/cfg_boundaries.py +44 -74
  3. pyedb/configuration/cfg_common.py +1 -1
  4. pyedb/configuration/cfg_components.py +31 -105
  5. pyedb/configuration/cfg_data.py +4 -9
  6. pyedb/configuration/cfg_operations.py +19 -13
  7. pyedb/configuration/cfg_padstacks.py +66 -89
  8. pyedb/configuration/cfg_pin_groups.py +7 -8
  9. pyedb/configuration/cfg_ports_sources.py +4 -2
  10. pyedb/configuration/cfg_s_parameter_models.py +85 -29
  11. pyedb/configuration/configuration.py +48 -13
  12. pyedb/dotnet/application/Variables.py +43 -41
  13. pyedb/dotnet/edb.py +12 -4
  14. pyedb/dotnet/edb_core/cell/hierarchy/component.py +199 -0
  15. pyedb/dotnet/edb_core/cell/layout.py +4 -1
  16. pyedb/dotnet/edb_core/cell/primitive/primitive.py +2 -0
  17. pyedb/dotnet/edb_core/cell/terminal/pingroup_terminal.py +3 -3
  18. pyedb/dotnet/edb_core/cell/terminal/terminal.py +4 -3
  19. pyedb/dotnet/edb_core/definition/component_def.py +17 -1
  20. pyedb/dotnet/edb_core/definition/component_model.py +0 -4
  21. pyedb/dotnet/edb_core/edb_data/hfss_extent_info.py +3 -3
  22. pyedb/dotnet/edb_core/edb_data/nets_data.py +10 -7
  23. pyedb/dotnet/edb_core/edb_data/padstacks_data.py +301 -45
  24. pyedb/dotnet/edb_core/edb_data/primitives_data.py +2 -2
  25. pyedb/dotnet/edb_core/general.py +11 -0
  26. pyedb/dotnet/edb_core/layout_validation.py +3 -3
  27. pyedb/dotnet/edb_core/modeler.py +5 -2
  28. pyedb/dotnet/edb_core/nets.py +162 -181
  29. pyedb/edb_logger.py +1 -1
  30. pyedb/siwave.py +33 -7
  31. {pyedb-0.27.0.dist-info → pyedb-0.29.0.dist-info}/METADATA +5 -5
  32. {pyedb-0.27.0.dist-info → pyedb-0.29.0.dist-info}/RECORD +34 -34
  33. {pyedb-0.27.0.dist-info → pyedb-0.29.0.dist-info}/LICENSE +0 -0
  34. {pyedb-0.27.0.dist-info → pyedb-0.29.0.dist-info}/WHEEL +0 -0
@@ -444,6 +444,7 @@ class EdbNets(object):
444
444
  codes.append(79)
445
445
  objects_lists.append([vertices, codes, "b", "Outline", 1.0, 1.5, "contour"])
446
446
  n_label += 1
447
+ layer_colors = {i: k.color for i, k in self._pedb.stackup.layers.items()}
447
448
  top_layer = list(self._pedb.stackup.signal_layers.keys())[0]
448
449
  bottom_layer = list(self._pedb.stackup.signal_layers.keys())[-1]
449
450
  if plot_components_on_top or plot_components_on_bottom:
@@ -481,206 +482,186 @@ class EdbNets(object):
481
482
  objects_lists.append([vertices, codes, label_colors[label], None, 1.0, 2.0, "contour"])
482
483
  nc += 1
483
484
  self._logger.debug("Plotted {} component(s)".format(nc))
484
-
485
- for path in self._pedb.modeler.paths:
486
- if path.is_void:
485
+ for prim in self._pedb.modeler.primitives:
486
+ if prim.is_void:
487
487
  continue
488
- net_name = path.net_name
489
- layer_name = path.layer_name
488
+ net_name = prim.net_name
489
+ layer_name = prim.layer_name
490
490
  if nets and (net_name not in nets or layer_name not in layers):
491
491
  continue
492
- try:
493
- x, y = path.points()
494
- except ValueError:
495
- x = None
496
- if not x:
497
- continue
498
- create_label = False
499
- if not color_by_net:
500
- label = "Layer " + layer_name
501
- if label not in label_colors:
502
- try:
503
- color = path.layer.GetColor()
504
- c = (
505
- float(color.Item1 / 255),
506
- float(color.Item2 / 255),
507
- float(color.Item3 / 255),
508
- )
509
- except:
510
- c = list(CSS4_COLORS.keys())[color_index]
492
+ prim_type = prim.primitive_type
493
+ if prim_type == "path":
494
+ try:
495
+ x, y = prim.points()
496
+ except ValueError:
497
+ x = None
498
+ if not x:
499
+ continue
500
+ create_label = False
501
+ if not color_by_net:
502
+ label = "Layer " + layer_name
503
+ if label not in label_colors:
504
+ try:
505
+ color = layer_colors[layer_name]
506
+ c = (
507
+ float(color[0] / 255),
508
+ float(color[1] / 255),
509
+ float(color[2] / 255),
510
+ )
511
+ except:
512
+ c = list(CSS4_COLORS.keys())[color_index]
513
+ color_index += 1
514
+ if color_index >= len(CSS4_COLORS):
515
+ color_index = 0
516
+ label_colors[label] = c
517
+ create_label = True
518
+ else:
519
+ label = "Net " + net_name
520
+ if label not in label_colors:
521
+ label_colors[label] = list(CSS4_COLORS.keys())[color_index]
511
522
  color_index += 1
512
523
  if color_index >= len(CSS4_COLORS):
513
524
  color_index = 0
514
- label_colors[label] = c
515
- create_label = True
516
- else:
517
- label = "Net " + net_name
518
- if label not in label_colors:
519
- label_colors[label] = list(CSS4_COLORS.keys())[color_index]
520
- color_index += 1
521
- if color_index >= len(CSS4_COLORS):
522
- color_index = 0
523
- create_label = True
524
-
525
- if create_label and n_label <= max_labels:
526
- objects_lists.append([x, y, label_colors[label], label, 0.4, "fill"])
527
- n_label += 1
528
- else:
529
- objects_lists.append([x, y, label_colors[label], None, 0.4, "fill"])
525
+ create_label = True
530
526
 
531
- for poly in self._pedb.modeler.polygons:
532
- if poly.is_void:
533
- continue
534
- net_name = poly.net_name
535
- layer_name = poly.layer_name
536
- if nets and (net_name != "" and net_name not in nets or layer_name not in layers):
537
- continue
538
- xt, yt = poly.points()
539
- if not xt:
540
- continue
541
- x, y = GeometryOperators.orient_polygon(xt, yt, clockwise=True)
542
- vertices = [(i, j) for i, j in zip(x, y)]
543
- codes = [2 for _ in vertices]
544
- codes[0] = 1
545
- vertices.append((0, 0))
546
- codes.append(79)
527
+ if create_label and n_label <= max_labels:
528
+ objects_lists.append([x, y, label_colors[label], label, 0.4, "fill"])
529
+ n_label += 1
530
+ else:
531
+ objects_lists.append([x, y, label_colors[label], None, 0.4, "fill"])
532
+ elif prim_type == "polygon":
533
+ xt, yt = prim.points()
534
+ if not xt:
535
+ continue
536
+ x, y = GeometryOperators.orient_polygon(xt, yt, clockwise=True)
537
+ vertices = [(i, j) for i, j in zip(x, y)]
538
+ codes = [2 for _ in vertices]
539
+ codes[0] = 1
540
+ vertices.append((0, 0))
541
+ codes.append(79)
547
542
 
548
- for void in poly.voids:
549
- xvt, yvt = void.points()
550
- if xvt:
551
- xv, yv = GeometryOperators.orient_polygon(xvt, yvt, clockwise=False)
552
- tmpV = [(i, j) for i, j in zip(xv, yv)]
553
- vertices.extend(tmpV)
554
- tmpC = [2 for _ in tmpV]
555
- tmpC[0] = 1
556
- codes.extend(tmpC)
557
- vertices.append((0, 0))
558
- codes.append(79)
559
-
560
- create_label = False
561
- if not color_by_net:
562
- label = "Layer " + layer_name
563
- if label not in label_colors:
564
- try:
565
- color = poly.GetLayer().GetColor()
566
- c = (
567
- float(color.Item1 / 255),
568
- float(color.Item2 / 255),
569
- float(color.Item3 / 255),
570
- )
571
- except:
572
- c = list(CSS4_COLORS.keys())[color_index]
543
+ for void in prim.voids:
544
+ xvt, yvt = void.points()
545
+ if xvt:
546
+ xv, yv = GeometryOperators.orient_polygon(xvt, yvt, clockwise=False)
547
+ tmpV = [(i, j) for i, j in zip(xv, yv)]
548
+ vertices.extend(tmpV)
549
+ tmpC = [2 for _ in tmpV]
550
+ tmpC[0] = 1
551
+ codes.extend(tmpC)
552
+ vertices.append((0, 0))
553
+ codes.append(79)
554
+
555
+ create_label = False
556
+ if not color_by_net:
557
+ label = "Layer " + layer_name
558
+ if label not in label_colors:
559
+ try:
560
+ color = layer_colors[layer_name]
561
+ c = (
562
+ float(color[0] / 255),
563
+ float(color[1] / 255),
564
+ float(color[2] / 255),
565
+ )
566
+ except:
567
+ c = list(CSS4_COLORS.keys())[color_index]
568
+ color_index += 1
569
+ if color_index >= len(CSS4_COLORS):
570
+ color_index = 0
571
+ label_colors[label] = c
572
+ create_label = True
573
+ else:
574
+ label = "Net " + net_name
575
+ if label not in label_colors:
576
+ label_colors[label] = list(CSS4_COLORS.keys())[color_index]
573
577
  color_index += 1
574
578
  if color_index >= len(CSS4_COLORS):
575
579
  color_index = 0
576
- label_colors[label] = c
577
- create_label = True
578
- else:
579
- label = "Net " + net_name
580
- if label not in label_colors:
581
- label_colors[label] = list(CSS4_COLORS.keys())[color_index]
582
- color_index += 1
583
- if color_index >= len(CSS4_COLORS):
584
- color_index = 0
585
- create_label = True
586
-
587
- if create_label and n_label <= max_labels:
588
- if layer_name == "Outline":
589
- objects_lists.append([vertices, codes, label_colors[label], label, 1.0, 2.0, "contour"])
580
+ create_label = True
581
+
582
+ if create_label and n_label <= max_labels:
583
+ if layer_name == "Outline":
584
+ objects_lists.append([vertices, codes, label_colors[label], label, 1.0, 2.0, "contour"])
585
+ else:
586
+ objects_lists.append([vertices, codes, label_colors[label], label, 0.4, "path"])
587
+ n_label += 1
590
588
  else:
591
- objects_lists.append([vertices, codes, label_colors[label], label, 0.4, "path"])
592
- n_label += 1
593
- else:
594
- if layer_name == "Outline":
595
- objects_lists.append([vertices, codes, label_colors[label], None, 1.0, 2.0, "contour"])
589
+ if layer_name == "Outline":
590
+ objects_lists.append([vertices, codes, label_colors[label], None, 1.0, 2.0, "contour"])
591
+ else:
592
+ objects_lists.append([vertices, codes, label_colors[label], None, 0.4, "path"])
593
+ elif prim_type == "circle":
594
+ x, y = prim.points()
595
+ if not x:
596
+ continue
597
+ create_label = False
598
+ if not color_by_net:
599
+ label = "Layer " + layer_name
600
+ if label not in label_colors:
601
+ try:
602
+ color = layer_colors[layer_name]
603
+ c = (
604
+ float(color[0] / 255),
605
+ float(color[1] / 255),
606
+ float(color[2] / 255),
607
+ )
608
+ except:
609
+ c = list(CSS4_COLORS.keys())[color_index]
610
+ color_index += 1
611
+ if color_index >= len(CSS4_COLORS):
612
+ color_index = 0
613
+ label_colors[label] = c
614
+ create_label = True
596
615
  else:
597
- objects_lists.append([vertices, codes, label_colors[label], None, 0.4, "path"])
598
-
599
- for circle in self._pedb.modeler.circles:
600
- if circle.is_void:
601
- continue
602
- net_name = circle.net_name
603
- layer_name = circle.layer_name
604
- if nets and (net_name not in nets or layer_name not in layers):
605
- continue
606
- x, y = circle.points()
607
- if not x:
608
- continue
609
- create_label = False
610
- if not color_by_net:
611
- label = "Layer " + layer_name
612
- if label not in label_colors:
613
- try:
614
- color = circle.layer.GetColor()
615
- c = (
616
- float(color.Item1 / 255),
617
- float(color.Item2 / 255),
618
- float(color.Item3 / 255),
619
- )
620
- except:
621
- c = list(CSS4_COLORS.keys())[color_index]
616
+ label = "Net " + net_name
617
+ if label not in label_colors:
618
+ label_colors[label] = list(CSS4_COLORS.keys())[color_index]
622
619
  color_index += 1
623
620
  if color_index >= len(CSS4_COLORS):
624
621
  color_index = 0
625
- label_colors[label] = c
626
- create_label = True
627
- else:
628
- label = "Net " + net_name
629
- if label not in label_colors:
630
- label_colors[label] = list(CSS4_COLORS.keys())[color_index]
631
- color_index += 1
632
- if color_index >= len(CSS4_COLORS):
633
- color_index = 0
634
- create_label = True
635
-
636
- if create_label and n_label <= max_labels:
637
- objects_lists.append([x, y, label_colors[label], label, 0.4, "fill"])
638
- n_label += 1
639
- else:
640
- objects_lists.append([x, y, label_colors[label], None, 0.4, "fill"])
622
+ create_label = True
641
623
 
642
- for rect in self._pedb.modeler.rectangles:
643
- if rect.is_void:
644
- continue
645
- net_name = rect.net_name
646
- layer_name = rect.layer_name
647
- if nets and (net_name not in nets or layer_name not in layers):
648
- continue
649
- x, y = rect.points()
650
- if not x:
651
- continue
652
- create_label = False
653
- if not color_by_net:
654
- label = "Layer " + layer_name
655
- if label not in label_colors:
656
- try:
657
- color = rect.layer.GetColor()
658
- c = (
659
- float(color.Item1 / 255),
660
- float(color.Item2 / 255),
661
- float(color.Item3 / 255),
662
- )
663
- except:
664
- c = list(CSS4_COLORS.keys())[color_index]
624
+ if create_label and n_label <= max_labels:
625
+ objects_lists.append([x, y, label_colors[label], label, 0.4, "fill"])
626
+ n_label += 1
627
+ else:
628
+ objects_lists.append([x, y, label_colors[label], None, 0.4, "fill"])
629
+ elif prim_type == "rectangle":
630
+ x, y = prim.points()
631
+ if not x:
632
+ continue
633
+ create_label = False
634
+ if not color_by_net:
635
+ label = "Layer " + layer_name
636
+ if label not in label_colors:
637
+ try:
638
+ color = layer_colors[layer_name]
639
+ c = (
640
+ float(color[0] / 255),
641
+ float(color[1] / 255),
642
+ float(color[2] / 255),
643
+ )
644
+ except:
645
+ c = list(CSS4_COLORS.keys())[color_index]
646
+ color_index += 1
647
+ if color_index >= len(CSS4_COLORS):
648
+ color_index = 0
649
+ label_colors[label] = c
650
+ create_label = True
651
+ else:
652
+ label = "Net " + net_name
653
+ if label not in label_colors:
654
+ label_colors[label] = list(CSS4_COLORS.keys())[color_index]
665
655
  color_index += 1
666
656
  if color_index >= len(CSS4_COLORS):
667
657
  color_index = 0
668
- label_colors[label] = c
669
- create_label = True
670
- else:
671
- label = "Net " + net_name
672
- if label not in label_colors:
673
- label_colors[label] = list(CSS4_COLORS.keys())[color_index]
674
- color_index += 1
675
- if color_index >= len(CSS4_COLORS):
676
- color_index = 0
677
- create_label = True
678
-
679
- if create_label and n_label <= max_labels:
680
- objects_lists.append([x, y, label_colors[label], label, 0.4, "fill"])
681
- n_label += 1
682
- else:
683
- objects_lists.append([x, y, label_colors[label], None, 0.4, "fill"])
658
+ create_label = True
659
+
660
+ if create_label and n_label <= max_labels:
661
+ objects_lists.append([x, y, label_colors[label], label, 0.4, "fill"])
662
+ n_label += 1
663
+ else:
664
+ objects_lists.append([x, y, label_colors[label], None, 0.4, "fill"])
684
665
 
685
666
  end_time = time.time() - start_time
686
667
  self._logger.info("Nets Point Generation time %s seconds", round(end_time, 3))
@@ -782,7 +763,7 @@ class EdbNets(object):
782
763
  fig_size_y = board_size_y * fig_size_x / board_size_x
783
764
  size = (fig_size_x, fig_size_y)
784
765
 
785
- plot_matplotlib(
766
+ return plot_matplotlib(
786
767
  plot_data=object_lists,
787
768
  size=size,
788
769
  show_legend=show_legend,
pyedb/edb_logger.py CHANGED
@@ -417,7 +417,7 @@ class EdbLogger(object):
417
417
 
418
418
  logger = logging.getLogger("Global")
419
419
  if any("aedt_logger" in str(i) for i in logger.filters):
420
- from pyaedt.generic.settings import settings as pyaedt_settings
420
+ from ansys.aedt.core.generic.settings import settings as pyaedt_settings
421
421
 
422
422
  from pyedb.generic.settings import settings as pyaedb_settings
423
423
 
pyedb/siwave.py CHANGED
@@ -15,6 +15,7 @@ import shutil
15
15
  import sys
16
16
  import tempfile
17
17
  import time
18
+ from typing import Optional, Union
18
19
  import warnings
19
20
 
20
21
  from pyedb import Edb
@@ -53,6 +54,15 @@ def wait_export_folder(flag, folder_path, time_sleep=0.5):
53
54
  time.sleep(time_sleep)
54
55
 
55
56
 
57
+ def parser_file_path(file_path):
58
+ if isinstance(file_path, Path):
59
+ file_path = str(file_path)
60
+
61
+ if not Path(file_path).root:
62
+ file_path = str(Path().cwd() / file_path)
63
+ return file_path
64
+
65
+
56
66
  class Siwave(object): # pragma no cover
57
67
  """Initializes SIwave based on the inputs provided and manages SIwave release and closing.
58
68
 
@@ -264,9 +274,9 @@ class Siwave(object): # pragma no cover
264
274
  ``True`` when successful, ``False`` when failed.
265
275
 
266
276
  """
267
-
268
- if os.path.exists(proj_path):
269
- open_result = self.oSiwave.OpenProject(proj_path)
277
+ file_path = parser_file_path(proj_path)
278
+ if os.path.exists(file_path):
279
+ open_result = self.oSiwave.OpenProject(file_path)
270
280
  self._oproject = self.oSiwave.GetActiveProject()
271
281
  return open_result
272
282
  else:
@@ -306,6 +316,22 @@ class Siwave(object): # pragma no cover
306
316
  self.oproject.Save()
307
317
  return True
308
318
 
319
+ def save(self, file_path: Optional[Union[str, Path]]):
320
+ """Save the project.
321
+
322
+ Parameters
323
+ ----------
324
+ file_path : str, optional
325
+ Full path to the project. The default is ``None``.
326
+ """
327
+
328
+ if file_path:
329
+ file_path = parser_file_path(file_path)
330
+ file_path = str(Path(file_path).with_suffix(".siw"))
331
+ self.oproject.ScrSaveProjectAs(file_path)
332
+ else:
333
+ self.oproject.Save()
334
+
309
335
  def close_project(self, save_project=False):
310
336
  """Close the project.
311
337
 
@@ -494,6 +520,8 @@ class Siwave(object): # pragma no cover
494
520
  """
495
521
  if isinstance(file_path, Path):
496
522
  file_path = str(file_path)
523
+ if not Path(file_path).root:
524
+ file_path = str(Path().cwd() / file_path)
497
525
  flag = self.oproject.ScrImportEDB(file_path)
498
526
  # self.save_project(self.di)
499
527
  if flag == 0:
@@ -510,8 +538,7 @@ class Siwave(object): # pragma no cover
510
538
  file_path : str
511
539
  Path to the configuration file.
512
540
  """
513
- if isinstance(file_path, Path):
514
- file_path = str(file_path)
541
+ file_path = parser_file_path(file_path)
515
542
 
516
543
  # temp_folder = tempfile.TemporaryDirectory(suffix=".ansys")
517
544
  # temp_edb = os.path.join(temp_folder.name, "temp.aedb")
@@ -536,8 +563,7 @@ class Siwave(object): # pragma no cover
536
563
  file_path : str
537
564
  Path to the configuration file.
538
565
  """
539
- if isinstance(file_path, Path):
540
- file_path = str(file_path)
566
+ file_path = parser_file_path(file_path)
541
567
 
542
568
  temp_folder = tempfile.TemporaryDirectory(suffix=".ansys")
543
569
  temp_edb = os.path.join(temp_folder.name, "temp.aedb")
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: pyedb
3
- Version: 0.27.0
3
+ Version: 0.29.0
4
4
  Summary: Higher-Level Pythonic Ansys Electronics Data Base
5
5
  Author-email: "ANSYS, Inc." <pyansys.core@ansys.com>
6
6
  Maintainer-email: PyEDB developers <simon.vandenbrouck@ansys.com>
@@ -19,9 +19,9 @@ Requires-Dist: cffi>=1.16.0,<1.18; platform_system=='Linux'
19
19
  Requires-Dist: pywin32 >= 303;platform_system=='Windows'
20
20
  Requires-Dist: ansys-pythonnet >= 3.1.0rc3
21
21
  Requires-Dist: dotnetcore2 ==3.1.23;platform_system=='Linux'
22
- Requires-Dist: numpy>=1.20.0,<2.2
22
+ Requires-Dist: numpy>=1.20.0,<2
23
23
  Requires-Dist: pandas>=1.1.0,<2.3
24
- Requires-Dist: pydantic>=2.6.4,<2.9
24
+ Requires-Dist: pydantic>=2.6.4,<2.10
25
25
  Requires-Dist: Rtree >= 1.2.0
26
26
  Requires-Dist: toml == 0.10.2
27
27
  Requires-Dist: scikit-rf
@@ -37,8 +37,8 @@ Requires-Dist: numpydoc>=1.5.0,<1.9 ; extra == "doc"
37
37
  Requires-Dist: pypandoc>=1.10.0,<1.14 ; extra == "doc"
38
38
  Requires-Dist: recommonmark ; extra == "doc"
39
39
  Requires-Dist: Sphinx>=7.1.0,<8.1 ; extra == "doc"
40
- Requires-Dist: sphinx-autobuild==2024.2.4 ; extra == "doc" and ( python_version == '3.8')
41
- Requires-Dist: sphinx-autobuild==2024.2.4 ; extra == "doc" and ( python_version > '3.8')
40
+ Requires-Dist: sphinx-autobuild==2021.3.14 ; extra == "doc" and ( python_version == '3.8')
41
+ Requires-Dist: sphinx-autobuild==2024.9.19 ; extra == "doc" and ( python_version > '3.8')
42
42
  Requires-Dist: sphinx-copybutton>=0.5.0,<0.6 ; extra == "doc"
43
43
  Requires-Dist: sphinx-gallery>=0.14.0,<0.18 ; extra == "doc"
44
44
  Requires-Dist: sphinx_design>=0.4.0,<0.7 ; extra == "doc"