pyedb 0.55.0__py3-none-any.whl → 0.57.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 (107) hide show
  1. pyedb/__init__.py +1 -1
  2. pyedb/configuration/cfg_data.py +3 -0
  3. pyedb/configuration/cfg_operations.py +2 -2
  4. pyedb/configuration/cfg_ports_sources.py +1 -1
  5. pyedb/configuration/cfg_terminals.py +232 -0
  6. pyedb/configuration/configuration.py +146 -3
  7. pyedb/dotnet/clr_module.py +1 -2
  8. pyedb/dotnet/database/Variables.py +56 -41
  9. pyedb/dotnet/database/cell/layout.py +5 -1
  10. pyedb/dotnet/database/cell/primitive/primitive.py +2 -2
  11. pyedb/dotnet/database/cell/terminal/bundle_terminal.py +12 -0
  12. pyedb/dotnet/database/cell/terminal/pingroup_terminal.py +1 -1
  13. pyedb/dotnet/database/cell/terminal/terminal.py +38 -0
  14. pyedb/dotnet/database/components.py +55 -52
  15. pyedb/dotnet/database/dotnet/database.py +1 -0
  16. pyedb/dotnet/database/edb_data/control_file.py +6 -3
  17. pyedb/dotnet/database/edb_data/nets_data.py +3 -3
  18. pyedb/dotnet/database/edb_data/padstacks_data.py +5 -2
  19. pyedb/dotnet/database/edb_data/ports.py +0 -25
  20. pyedb/dotnet/database/edb_data/primitives_data.py +3 -3
  21. pyedb/dotnet/database/edb_data/raptor_x_simulation_setup_data.py +18 -19
  22. pyedb/dotnet/database/edb_data/simulation_configuration.py +3 -3
  23. pyedb/dotnet/database/hfss.py +9 -8
  24. pyedb/dotnet/database/layout_validation.py +6 -3
  25. pyedb/dotnet/database/materials.py +1 -3
  26. pyedb/dotnet/database/modeler.py +7 -3
  27. pyedb/dotnet/database/nets.py +27 -19
  28. pyedb/dotnet/database/padstack.py +91 -2
  29. pyedb/dotnet/database/sim_setup_data/io/siwave.py +1 -1
  30. pyedb/dotnet/database/siwave.py +4 -3
  31. pyedb/dotnet/database/stackup.py +50 -26
  32. pyedb/dotnet/database/utilities/heatsink.py +0 -1
  33. pyedb/dotnet/database/utilities/simulation_setup.py +7 -5
  34. pyedb/dotnet/database/utilities/siwave_cpa_simulation_setup.py +1 -0
  35. pyedb/dotnet/database/utilities/siwave_simulation_setup.py +5 -2
  36. pyedb/dotnet/edb.py +41 -36
  37. pyedb/exceptions.py +1 -2
  38. pyedb/extensions/create_cell_array.py +408 -0
  39. pyedb/generic/data_handlers.py +17 -28
  40. pyedb/generic/design_types.py +25 -38
  41. pyedb/generic/filesystem.py +9 -4
  42. pyedb/generic/general_methods.py +6 -7
  43. pyedb/generic/plot.py +2 -2
  44. pyedb/generic/settings.py +4 -0
  45. pyedb/grpc/database/_typing.py +0 -0
  46. pyedb/grpc/database/components.py +30 -11
  47. pyedb/grpc/database/control_file.py +14 -35
  48. pyedb/grpc/database/definition/materials.py +1 -1
  49. pyedb/grpc/database/definition/package_def.py +6 -3
  50. pyedb/grpc/database/definition/padstack_def.py +4 -7
  51. pyedb/grpc/database/hfss.py +1 -4
  52. pyedb/grpc/database/hierarchy/component.py +3 -4
  53. pyedb/grpc/database/hierarchy/pingroup.py +16 -3
  54. pyedb/grpc/database/layers/layer.py +1 -2
  55. pyedb/grpc/database/layers/stackup_layer.py +42 -19
  56. pyedb/grpc/database/layout/layout.py +117 -28
  57. pyedb/grpc/database/layout/voltage_regulator.py +6 -1
  58. pyedb/grpc/database/layout_validation.py +7 -4
  59. pyedb/grpc/database/modeler.py +241 -256
  60. pyedb/grpc/database/net/differential_pair.py +9 -2
  61. pyedb/grpc/database/net/extended_net.py +24 -9
  62. pyedb/grpc/database/net/net.py +14 -5
  63. pyedb/grpc/database/net/net_class.py +24 -7
  64. pyedb/grpc/database/nets.py +11 -43
  65. pyedb/grpc/database/padstacks.py +92 -16
  66. pyedb/grpc/database/primitive/bondwire.py +3 -67
  67. pyedb/grpc/database/primitive/circle.py +42 -3
  68. pyedb/grpc/database/primitive/padstack_instance.py +17 -19
  69. pyedb/grpc/database/primitive/path.py +154 -5
  70. pyedb/grpc/database/primitive/polygon.py +75 -9
  71. pyedb/grpc/database/primitive/primitive.py +2 -2
  72. pyedb/grpc/database/primitive/rectangle.py +105 -4
  73. pyedb/grpc/database/simulation_setup/hfss_general_settings.py +0 -2
  74. pyedb/grpc/database/simulation_setup/hfss_settings_options.py +0 -4
  75. pyedb/grpc/database/simulation_setup/siwave_cpa_simulation_setup.py +4 -2
  76. pyedb/grpc/database/simulation_setup/sweep_data.py +1 -3
  77. pyedb/grpc/database/siwave.py +6 -13
  78. pyedb/grpc/database/source_excitations.py +49 -57
  79. pyedb/grpc/database/stackup.py +50 -27
  80. pyedb/grpc/database/terminal/bundle_terminal.py +10 -3
  81. pyedb/grpc/database/terminal/pingroup_terminal.py +8 -1
  82. pyedb/grpc/database/terminal/terminal.py +19 -8
  83. pyedb/grpc/database/utility/heat_sink.py +0 -1
  84. pyedb/grpc/database/utility/hfss_extent_info.py +2 -2
  85. pyedb/grpc/database/utility/value.py +1 -0
  86. pyedb/grpc/database/utility/xml_control_file.py +6 -3
  87. pyedb/grpc/edb.py +33 -24
  88. pyedb/grpc/edb_init.py +1 -0
  89. pyedb/grpc/rpc_session.py +4 -3
  90. pyedb/ipc2581/ecad/cad_data/layer_feature.py +6 -2
  91. pyedb/ipc2581/ecad/cad_data/step.py +1 -1
  92. pyedb/ipc2581/ipc2581.py +8 -7
  93. pyedb/libraries/common.py +3 -4
  94. pyedb/libraries/rf_libraries/base_functions.py +7 -16
  95. pyedb/libraries/rf_libraries/planar_antennas.py +3 -21
  96. pyedb/misc/downloads.py +1 -0
  97. pyedb/misc/misc.py +5 -2
  98. pyedb/misc/siw_feature_config/emc_rule_checker_settings.py +1 -1
  99. pyedb/misc/utilities.py +0 -1
  100. pyedb/modeler/geometry_operators.py +9 -8
  101. pyedb/siwave.py +4 -6
  102. pyedb/siwave_core/__init__.py +0 -0
  103. pyedb/siwave_core/cpa/__init__.py +0 -0
  104. {pyedb-0.55.0.dist-info → pyedb-0.57.0.dist-info}/METADATA +3 -3
  105. {pyedb-0.55.0.dist-info → pyedb-0.57.0.dist-info}/RECORD +107 -102
  106. {pyedb-0.55.0.dist-info → pyedb-0.57.0.dist-info}/WHEEL +0 -0
  107. {pyedb-0.55.0.dist-info → pyedb-0.57.0.dist-info}/licenses/LICENSE +0 -0
@@ -28,8 +28,7 @@ from ansys.edb.core.database import ProductIdType as GrpcProductIdType
28
28
  from ansys.edb.core.geometry.point_data import PointData as GrpcPointData
29
29
  from ansys.edb.core.geometry.polygon_data import PolygonData as GrpcPolygonData
30
30
  from ansys.edb.core.hierarchy.pin_group import PinGroup as GrpcPinGroup
31
- from ansys.edb.core.hierarchy.structure3d import MeshClosure as GrpcMeshClosure
32
- from ansys.edb.core.hierarchy.structure3d import Structure3D as GrpcStructure3D
31
+ from ansys.edb.core.hierarchy.structure3d import MeshClosure as GrpcMeshClosure, Structure3D as GrpcStructure3D
33
32
  from ansys.edb.core.primitive.padstack_instance import (
34
33
  PadstackInstance as GrpcPadstackInstance,
35
34
  )
@@ -144,7 +143,7 @@ class PadstackInstance(GrpcPadstackInstance):
144
143
  True if success, False otherwise.
145
144
  """
146
145
  warnings.warn(
147
- "`set_backdrill_top` is deprecated. Use `set_back_drill_by_depth` or " "`set_back_drill_by_layer` instead.",
146
+ "`set_backdrill_top` is deprecated. Use `set_back_drill_by_depth` or `set_back_drill_by_layer` instead.",
148
147
  DeprecationWarning,
149
148
  )
150
149
  if isinstance(drill_depth, str):
@@ -179,8 +178,7 @@ class PadstackInstance(GrpcPadstackInstance):
179
178
  True if success, False otherwise.
180
179
  """
181
180
  warnings.warn(
182
- "`set_backdrill_bottom` is deprecated. Use `set_back_drill_by_depth` or "
183
- "`set_back_drill_by_layer` instead.",
181
+ "`set_backdrill_bottom` is deprecated. Use `set_back_drill_by_depth` or `set_back_drill_by_layer` instead.",
184
182
  DeprecationWarning,
185
183
  )
186
184
  if isinstance(drill_depth, str):
@@ -826,21 +824,21 @@ class PadstackInstance(GrpcPadstackInstance):
826
824
  rad_l = rad_large
827
825
 
828
826
  layout = self._pedb.active_layout
829
- cloned_circle = Circle.create(
830
- layout,
831
- self.start_layer,
832
- self.net,
833
- Value(self.position[0]),
834
- Value(self.position[1]),
835
- Value(rad_u),
827
+ cloned_circle = Circle(self._pedb).create(
828
+ layout=layout,
829
+ layer=self.start_layer,
830
+ net=self.net,
831
+ center_x=Value(self.position[0]),
832
+ center_y=Value(self.position[1]),
833
+ radius=Value(rad_u),
836
834
  )
837
- cloned_circle2 = Circle.create(
838
- layout,
839
- self.stop_layer,
840
- self.net,
841
- Value(self.position[0]),
842
- Value(self.position[1]),
843
- Value(rad_l),
835
+ cloned_circle2 = Circle(self._pedb).create(
836
+ layout=layout,
837
+ layer=self.stop_layer,
838
+ net=self.net,
839
+ center_x=Value(self.position[0]),
840
+ center_y=Value(self.position[1]),
841
+ radius=Value(rad_l),
844
842
  )
845
843
 
846
844
  s3d = GrpcStructure3D.create(layout, generate_unique_name("via3d_" + self.aedt_name.replace("via_", ""), n=3))
@@ -20,19 +20,25 @@
20
20
  # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
21
  # SOFTWARE.
22
22
  import math
23
+ from typing import Union
23
24
 
24
25
  from ansys.edb.core.geometry.polygon_data import PolygonData as GrpcPolygonData
25
- from ansys.edb.core.primitive.path import Path as GrpcPath
26
- from ansys.edb.core.primitive.path import PathCornerType as GrpcPatCornerType
26
+ from ansys.edb.core.primitive.path import (
27
+ Path as GrpcPath,
28
+ PathCornerType as GrpcPatCornerType,
29
+ PathEndCapType as GrpcPathEndCapType,
30
+ )
27
31
 
32
+ from pyedb.grpc.database.layers.layer import Layer
28
33
  from pyedb.grpc.database.primitive.primitive import Primitive
29
34
  from pyedb.grpc.database.utility.value import Value
30
35
 
31
36
 
32
37
  class Path(GrpcPath, Primitive):
33
- def __init__(self, pedb, edb_object):
34
- GrpcPath.__init__(self, edb_object.msg)
35
- Primitive.__init__(self, pedb, edb_object)
38
+ def __init__(self, pedb, edb_object=None):
39
+ if edb_object:
40
+ GrpcPath.__init__(self, edb_object.msg)
41
+ Primitive.__init__(self, pedb, edb_object)
36
42
  self._edb_object = edb_object
37
43
  self._pedb = pedb
38
44
 
@@ -72,6 +78,105 @@ class Path(GrpcPath, Primitive):
72
78
  path_length += self.width / 2
73
79
  return round(path_length, 9)
74
80
 
81
+ def create(
82
+ self,
83
+ layout=None,
84
+ layer: Union[str, Layer] = None,
85
+ net: Union[str, "Net"] = None,
86
+ width: float = 100e-6,
87
+ end_cap1: str = "flat",
88
+ end_cap2: str = "flat",
89
+ corner_style: str = "sharp",
90
+ points: Union[list, GrpcPolygonData] = None,
91
+ ):
92
+ """
93
+ Create a path in the specified layout, layer, and net with the given parameters.
94
+
95
+ Parameters
96
+ ----------
97
+ layout : Layout, optional
98
+ The layout in which the path will be created. If not provided, the active layout of the `pedb` instance
99
+ will be used.
100
+ layer : Union[str, Layer], optional
101
+ The layer in which the path will be created. This parameter is required and must be specified.
102
+ net : Union[str, Net], optional
103
+ The net to which the path will belong. If not provided, the path will not be associated with a net.
104
+ width : float, optional
105
+ The width of the path in meters. The default value is `100e-6`.
106
+ end_cap1 : str, optional
107
+ The style of the first end cap. Options are `"flat"`, `"round"`, `"extended"`, and `"clipped"`.
108
+ The default value is `"flat"`.
109
+ end_cap2 : str, optional
110
+ The style of the second end cap. Options are `"flat"`, `"round"`, `"extended"`, and `"clipped"`.
111
+ The default value is `"flat"`.
112
+ corner_style : str, optional
113
+ The style of the path corners. Options are `"sharp"`, `"round"`, and `"mitter"`.
114
+ The default value is `"sharp"`.
115
+ points : Union[list, GrpcPolygonData], optional
116
+ The points defining the path. This can be a list of points or an instance of `GrpcPolygonData`.
117
+ This parameter is required and must be specified.
118
+
119
+ Returns
120
+ -------
121
+ :class:`Path <pyedb.grpc.database.primitive.path.Path>`
122
+ The created path object.
123
+
124
+ Raises
125
+ ------
126
+ ValueError
127
+ If the `points` parameter is not provided.
128
+
129
+ Notes
130
+ -----
131
+ - If `points` is provided as a list, it will be converted to a `GrpcPolygonData` object.
132
+ - The created path is added to the modeler primitives of the `pedb` instance.
133
+
134
+ """
135
+ if layout is None:
136
+ layout = self._pedb.active_layout
137
+ end_cap_mapping = {
138
+ "flat": GrpcPathEndCapType.FLAT,
139
+ "round": GrpcPathEndCapType.ROUND,
140
+ "extended": GrpcPathEndCapType.EXTENDED,
141
+ "clipped": GrpcPathEndCapType.CLIPPED,
142
+ }
143
+ corner_style_mapping = {
144
+ "round": GrpcPatCornerType.ROUND,
145
+ "mitter": GrpcPatCornerType.MITER,
146
+ "sharp": GrpcPatCornerType.SHARP,
147
+ }
148
+ if isinstance(end_cap1, str):
149
+ end_cap1 = end_cap_mapping[end_cap1.lower()]
150
+ if isinstance(end_cap2, str):
151
+ end_cap2 = end_cap_mapping[end_cap2.lower()]
152
+ if isinstance(corner_style, str):
153
+ corner_style = corner_style_mapping[corner_style.lower()]
154
+ if not points:
155
+ raise ValueError("Points are required to create a path.")
156
+ if isinstance(points, list):
157
+ points = GrpcPolygonData(points=points)
158
+ self._edb_object = super().create(
159
+ layout=layout,
160
+ layer=layer,
161
+ net=net,
162
+ width=Value(width),
163
+ end_cap1=end_cap1,
164
+ end_cap2=end_cap2,
165
+ corner_style=corner_style,
166
+ points=points,
167
+ )
168
+
169
+ # keeping cache synced
170
+ new_path = Path(self._pedb, self._edb_object)
171
+ self._pedb.modeler._add_primitive(new_path)
172
+ return new_path
173
+
174
+ def delete(self):
175
+ """Delete the path object."""
176
+ # keeping cache synced
177
+ self._pedb.modeler._remove_primitive(self)
178
+ super().delete()
179
+
75
180
  def add_point(self, x, y, incremental=True) -> bool:
76
181
  """Add a point at the end of the path.
77
182
 
@@ -344,3 +449,47 @@ class Path(GrpcPath, Primitive):
344
449
  "sharp": GrpcPatCornerType.SHARP,
345
450
  }
346
451
  self.corner_style = mapping[corner_type]
452
+
453
+ @property
454
+ def end_cap1(self) -> str:
455
+ """Path's start style as string.
456
+
457
+ Returns
458
+ -------
459
+ str
460
+ Values supported for the setter `"flat"`, `"round"`, `"extended"`
461
+
462
+ """
463
+ return self.get_end_cap_style()[0].name.lower()
464
+
465
+ @end_cap1.setter
466
+ def end_cap1(self, end_cap_style):
467
+ if isinstance(end_cap_style, str):
468
+ mapping = {
469
+ "flat": GrpcPathEndCapType.FLAT,
470
+ "round": GrpcPathEndCapType.ROUND,
471
+ "extended": GrpcPathEndCapType.EXTENDED,
472
+ }
473
+ self.set_end_cap_style(mapping[end_cap_style], self.get_end_cap_style()[1].value)
474
+
475
+ @property
476
+ def end_cap2(self) -> str:
477
+ """Path's end style as string.
478
+
479
+ Returns
480
+ -------
481
+ str
482
+ Values supported for the setter `"flat"`, `"round"`, `"extended"`
483
+
484
+ """
485
+ return self.get_end_cap_style()[1].name.lower()
486
+
487
+ @end_cap2.setter
488
+ def end_cap2(self, end_cap_style):
489
+ if isinstance(end_cap_style, str):
490
+ mapping = {
491
+ "flat": GrpcPathEndCapType.FLAT,
492
+ "round": GrpcPathEndCapType.ROUND,
493
+ "extended": GrpcPathEndCapType.EXTENDED,
494
+ }
495
+ self.set_end_cap_style(self.get_end_cap_style()[0].value, mapping[end_cap_style])
@@ -22,19 +22,23 @@
22
22
 
23
23
 
24
24
  import math
25
+ from typing import Union
25
26
 
26
27
  from ansys.edb.core.geometry.point_data import PointData as GrpcPointData
27
28
  from ansys.edb.core.geometry.polygon_data import PolygonData as GrpcPolygonData
28
29
  from ansys.edb.core.primitive.polygon import Polygon as GrpcPolygon
29
30
 
31
+ from pyedb.grpc.database.layers.layer import Layer
32
+ from pyedb.grpc.database.layout.layout import Layout
30
33
  from pyedb.grpc.database.primitive.primitive import Primitive
31
34
  from pyedb.grpc.database.utility.value import Value
32
35
 
33
36
 
34
37
  class Polygon(GrpcPolygon, Primitive):
35
- def __init__(self, pedb, edb_object):
36
- GrpcPolygon.__init__(self, edb_object.msg)
37
- Primitive.__init__(self, pedb, edb_object)
38
+ def __init__(self, pedb, edb_object=None):
39
+ if edb_object:
40
+ GrpcPolygon.__init__(self, edb_object.msg)
41
+ Primitive.__init__(self, pedb, edb_object)
38
42
  self._pedb = pedb
39
43
 
40
44
  @property
@@ -59,6 +63,67 @@ class Polygon(GrpcPolygon, Primitive):
59
63
  """
60
64
  return self.polygon_data.has_self_intersections()
61
65
 
66
+ def create(
67
+ self, layout: Layout = None, layer: Union[str, Layer] = None, net: Union[str, "Net"] = None, polygon_data=None
68
+ ):
69
+ """
70
+ Create a polygon in the specified layout, layer, and net using the provided polygon data.
71
+
72
+ Parameters
73
+ ----------
74
+ layout : Layout, optional
75
+ The layout in which the polygon will be created. If not provided, the active layout of the `pedb`
76
+ instance will be used.
77
+ layer : Union[str, Layer], optional
78
+ The layer in which the polygon will be created. This parameter is required and must be specified.
79
+ net : Union[str, Net], optional
80
+ The net to which the polygon will belong. If not provided, the polygon will not be associated with a
81
+ net.
82
+ polygon_data : list or GrpcPolygonData, optional
83
+ The data defining the polygon. This can be a list of points or an instance of `GrpcPolygonData`.
84
+ This parameter is required and must be specified.
85
+
86
+ Returns
87
+ -------
88
+ :class:`Polygon <ansys.edb.core.primitive.polygon.Polygon>`
89
+ The created polygon object.
90
+
91
+ Raises
92
+ ------
93
+ ValueError
94
+ If the `layer` parameter is not provided.
95
+ ValueError
96
+ If the `polygon_data` parameter is not provided.
97
+
98
+ Notes
99
+ -----
100
+ - If `polygon_data` is provided as a list, it will be converted to a `GrpcPolygonData` object.
101
+ - The created polygon is added to the modeler primitives of the `pedb` instance.
102
+
103
+ """
104
+ if not layout:
105
+ layout = self._pedb.active_layout
106
+ if not layer:
107
+ raise ValueError("Layer is required to create a polygon.")
108
+ if not polygon_data:
109
+ raise ValueError("Polygon data or point list is required to create a polygon.")
110
+ if isinstance(polygon_data, list):
111
+ polygon_data = GrpcPolygonData(polygon_data)
112
+
113
+ # call into the gRPC layer to actually create the polygon
114
+ edb_object = super().create(layout=layout, layer=layer, net=net, polygon_data=polygon_data)
115
+ new_polygon = Polygon(self._pedb, edb_object)
116
+ # keep modeler cache in sync
117
+ self._pedb.modeler._add_primitive(new_polygon)
118
+
119
+ return new_polygon
120
+
121
+ def delete(self):
122
+ """Delete polygon from layout."""
123
+ # keeping cache in sync
124
+ self._pedb.modeler._remove_primitive(self)
125
+ super().delete()
126
+
62
127
  def fix_self_intersections(self) -> list[any]:
63
128
  """Remove self intersections if they exist.
64
129
 
@@ -88,13 +153,14 @@ class Polygon(GrpcPolygon, Primitive):
88
153
  Cloned polygon.
89
154
 
90
155
  """
156
+ voids = self.voids
91
157
  polygon_data = self.polygon_data
92
- duplicated_polygon = self.create(
158
+ cloned_polygon = self.create(
93
159
  layout=self._pedb.active_layout, layer=self.layer, net=self.net, polygon_data=polygon_data
94
160
  )
95
- for void in self.voids:
96
- duplicated_polygon.add_void(void)
97
- return duplicated_polygon
161
+ for void in voids:
162
+ cloned_polygon.add_void(void)
163
+ return cloned_polygon
98
164
 
99
165
  def duplicate_across_layers(self, layers) -> bool:
100
166
  """Duplicate across layer a primitive object.
@@ -271,6 +337,6 @@ class Polygon(GrpcPolygon, Primitive):
271
337
  return False
272
338
 
273
339
  def add_void(self, polygon):
274
- if isinstance(polygon, list):
340
+ if isinstance(polygon, list) or isinstance(polygon, GrpcPolygonData):
275
341
  polygon = self._pedb.modeler.create_polygon(points=polygon, layer_name=self.layer.name)
276
- return self._edb_object.add_void(polygon._edb_object)
342
+ return self._edb_object.add_void(polygon)
@@ -39,8 +39,8 @@ class Primitive(GrpcPrimitive):
39
39
  >>> from pyedb import Edb
40
40
  >>> edb = Edb(myedb, edbversion="2021.2")
41
41
  >>> edb_prim = edb.modeler.primitives[0]
42
- >>> edb_prim.is_void # Class Property
43
- >>> edb_prim.IsVoid() # EDB Object Property
42
+ >>> edb_prim.is_void # Class Property
43
+ >>> edb_prim.IsVoid() # EDB Object Property
44
44
  """
45
45
 
46
46
  def __init__(self, pedb, edb_object):
@@ -21,11 +21,14 @@
21
21
  # SOFTWARE.
22
22
 
23
23
 
24
+ from typing import Union
25
+
24
26
  from ansys.edb.core.primitive.rectangle import (
27
+ Rectangle as GrpcRectangle,
25
28
  RectangleRepresentationType as GrpcRectangleRepresentationType,
26
29
  )
27
- from ansys.edb.core.primitive.rectangle import Rectangle as GrpcRectangle
28
30
 
31
+ from pyedb.grpc.database.layers.layer import Layer
29
32
  from pyedb.grpc.database.primitive.primitive import Primitive
30
33
  from pyedb.grpc.database.utility.value import Value
31
34
 
@@ -33,9 +36,10 @@ from pyedb.grpc.database.utility.value import Value
33
36
  class Rectangle(GrpcRectangle, Primitive):
34
37
  """Class representing a rectangle object."""
35
38
 
36
- def __init__(self, pedb, edb_object):
37
- Primitive.__init__(self, pedb, edb_object)
38
- GrpcRectangle.__init__(self, edb_object.msg)
39
+ def __init__(self, pedb, edb_object=None):
40
+ if edb_object:
41
+ Primitive.__init__(self, pedb, edb_object)
42
+ GrpcRectangle.__init__(self, edb_object.msg)
39
43
  self._pedb = pedb
40
44
  self._mapping_representation_type = {
41
45
  "center_width_height": GrpcRectangleRepresentationType.CENTER_WIDTH_HEIGHT,
@@ -71,6 +75,103 @@ class Rectangle(GrpcRectangle, Primitive):
71
75
  else:
72
76
  super().representation_type = self._mapping_representation_type[value]
73
77
 
78
+ def create(
79
+ self,
80
+ layout=None,
81
+ layer: Union[str, Layer] = None,
82
+ net: Union[str, "Net"] = None,
83
+ rep_type: str = "center_width_height",
84
+ param1: float = None,
85
+ param2: float = None,
86
+ param3: float = None,
87
+ param4: float = None,
88
+ corner_rad: float = 0.0,
89
+ rotation: float = 0.0,
90
+ ):
91
+ """
92
+ Create a rectangle primitive in the specified layout, layer, and net with the given parameters.
93
+
94
+ Parameters
95
+ ----------
96
+ layout : Layout, optional
97
+ The layout in which the rectangle will be created. If not provided, the active layout of the `pedb` instance
98
+ will be used.
99
+ layer : Union[str, Layer], optional
100
+ The layer in which the rectangle will be created. This parameter is required and must be specified.
101
+ net : Union[str, Net], optional
102
+ The net to which the rectangle will belong. This parameter is required and must be specified.
103
+ rep_type : str, optional
104
+ The representation type of the rectangle. Options are `"center_width_height"` or `"lower_left_upper_right"`.
105
+ The default value is `"center_width_height"`.
106
+ param1 : float, optional
107
+ The first parameter defining the rectangle. Its meaning depends on the `rep_type`.
108
+ param2 : float, optional
109
+ The second parameter defining the rectangle. Its meaning depends on the `rep_type`.
110
+ param3 : float, optional
111
+ The third parameter defining the rectangle. Its meaning depends on the `rep_type`.
112
+ param4 : float, optional
113
+ The fourth parameter defining the rectangle. Its meaning depends on the `rep_type`.
114
+ corner_rad : float, optional
115
+ The corner radius of the rectangle. The default value is `0.0`.
116
+ rotation : float, optional
117
+ The rotation angle of the rectangle in degrees. The default value is `0.0`.
118
+
119
+ Returns
120
+ -------
121
+ Rectangle
122
+ The created rectangle primitive.
123
+
124
+ Raises
125
+ ------
126
+ ValueError
127
+ If the `layer` parameter is not provided.
128
+ ValueError
129
+ If the `net` parameter is not provided.
130
+
131
+ Notes
132
+ -----
133
+ - The created rectangle is added to the modeler primitives of the `pedb` instance.
134
+ - The `rep_type` determines how the parameters are interpreted:
135
+ - `"center_width_height"`: `param1` and `param2` represent the center coordinates, while `param3` and
136
+ `param4` represent the width and height.
137
+ - `"lower_left_upper_right"`: `param1` and `param2` represent the lower-left corner coordinates, while
138
+ `param3` and `param4` represent the upper-right corner coordinates.
139
+ """
140
+ if not layout:
141
+ layout = self._pedb.active_layout
142
+ if not layer:
143
+ raise ValueError("Layer must be provided.")
144
+ if not net:
145
+ raise ValueError("Net must be provided.")
146
+
147
+ rep_type_mapping = {
148
+ "center_width_height": GrpcRectangleRepresentationType.CENTER_WIDTH_HEIGHT,
149
+ "lower_left_upper_right": GrpcRectangleRepresentationType.LOWER_LEFT_UPPER_RIGHT,
150
+ }
151
+ rep_type = rep_type_mapping.get(rep_type, GrpcRectangleRepresentationType.INVALID_RECT_TYPE)
152
+ edb_object = super().create(
153
+ layout=layout,
154
+ layer=layer,
155
+ net=net,
156
+ rep_type=rep_type,
157
+ param1=Value(param1),
158
+ param2=Value(param2),
159
+ param3=Value(param3),
160
+ param4=Value(param4),
161
+ corner_rad=Value(corner_rad),
162
+ rotation=Value(rotation),
163
+ )
164
+ # keep cache synced
165
+ new_rect = Rectangle(self._pedb, edb_object)
166
+ self._pedb.modeler._add_primitive(new_rect)
167
+ return new_rect
168
+
169
+ def delete(self):
170
+ """Delete the rectangle primitive from the layout."""
171
+ # Remove from cache
172
+ self._pedb.modeler._remove_primitive(self)
173
+ super().delete()
174
+
74
175
  def get_parameters(self):
75
176
  """Get coordinates parameters.
76
177
 
@@ -23,8 +23,6 @@
23
23
 
24
24
  from ansys.edb.core.simulation_setup.hfss_simulation_settings import (
25
25
  AdaptType as GrpcAdaptType,
26
- )
27
- from ansys.edb.core.simulation_setup.hfss_simulation_settings import (
28
26
  HFSSGeneralSettings as GrpcHFSSGeneralSettings,
29
27
  )
30
28
 
@@ -23,11 +23,7 @@
23
23
 
24
24
  from ansys.edb.core.simulation_setup.hfss_simulation_settings import (
25
25
  BasisFunctionOrder as GrpcBasisFunctionOrder,
26
- )
27
- from ansys.edb.core.simulation_setup.hfss_simulation_settings import (
28
26
  HFSSSettingsOptions as GrpcHFSSSettingsOptions,
29
- )
30
- from ansys.edb.core.simulation_setup.hfss_simulation_settings import (
31
27
  SolverType as GrpcSolverType,
32
28
  )
33
29
 
@@ -1,7 +1,6 @@
1
1
  from ansys.edb.core.database import ProductIdType as GrpcProductIdType
2
2
  from ansys.edb.core.utility.value import Value as GrpcValue
3
3
 
4
- import pyedb.siwave_core.cpa.simulation_setup_data_model
5
4
  from pyedb.siwave_core.cpa.simulation_setup_data_model import SIwaveCpaSetup, Vrm
6
5
  from pyedb.siwave_core.product_properties import SIwaveProperties
7
6
 
@@ -190,11 +189,13 @@ class ChannelSetup:
190
189
  Raises:
191
190
  ValueError: If the input is not a list.
192
191
  """
192
+ from pyedb.siwave_core.cpa.simulation_setup_data_model import Vrm
193
+
193
194
  if not isinstance(value, list):
194
195
  raise ValueError("vrm setter must have list as input.")
195
196
  vrm_str = ""
196
197
  for vrm in value:
197
- if isinstance(vrm, pyedb.siwave_core.cpa.simulation_setup_data_model.Vrm):
198
+ if isinstance(vrm, Vrm):
198
199
  if vrm_str:
199
200
  vrm_str += "*"
200
201
  vrm_str += vrm.name
@@ -757,6 +758,7 @@ class SIWaveCPASimulationSetup:
757
758
  self._pedb = pedb
758
759
  self._channel_setup = ChannelSetup(pedb)
759
760
  self._solver_options = SolverOptions(pedb)
761
+ self.type = "cpa"
760
762
  if isinstance(siwave_cpa_setup_class, SIwaveCpaSetup):
761
763
  self._apply_cfg_object(siwave_cpa_setup_class)
762
764
  else:
@@ -22,11 +22,9 @@
22
22
 
23
23
  from ansys.edb.core.simulation_setup.simulation_setup import (
24
24
  Distribution as GrpcDistribution,
25
- )
26
- from ansys.edb.core.simulation_setup.simulation_setup import (
27
25
  FrequencyData as GrpcFrequencyData,
26
+ SweepData as GrpcSweepData,
28
27
  )
29
- from ansys.edb.core.simulation_setup.simulation_setup import SweepData as GrpcSweepData
30
28
 
31
29
 
32
30
  class SweepData(GrpcSweepData):
@@ -24,6 +24,7 @@
24
24
  This module contains these classes: ``CircuitPort``, ``CurrentSource``, ``EdbSiwave``,
25
25
  ``PinGroup``, ``ResistorSource``, ``Source``, ``SourceType``, and ``VoltageSource``.
26
26
  """
27
+
27
28
  import os
28
29
  from typing import Any, Dict, Optional, Union
29
30
  import warnings
@@ -31,11 +32,9 @@ import warnings
31
32
  from ansys.edb.core.database import ProductIdType as GrpcProductIdType
32
33
  from ansys.edb.core.simulation_setup.simulation_setup import (
33
34
  Distribution as GrpcDistribution,
34
- )
35
- from ansys.edb.core.simulation_setup.simulation_setup import (
36
35
  FrequencyData as GrpcFrequencyData,
36
+ SweepData as GrpcSweepData,
37
37
  )
38
- from ansys.edb.core.simulation_setup.simulation_setup import SweepData as GrpcSweepData
39
38
 
40
39
  from pyedb.grpc.database.simulation_setup.siwave_cpa_simulation_setup import (
41
40
  SIWaveCPASimulationSetup,
@@ -335,7 +334,7 @@ class Siwave(object):
335
334
  Use :func:`pyedb.grpc.core.excitations._check_gnd` instead.
336
335
  """
337
336
  warnings.warn(
338
- "`_check_gnd` is deprecated and is now located here " "`pyedb.grpc.core.excitations._check_gnd` instead.",
337
+ "`_check_gnd` is deprecated and is now located here `pyedb.grpc.core.excitations._check_gnd` instead.",
339
338
  DeprecationWarning,
340
339
  )
341
340
  return self._pedb.source_excitation._check_gnd(component_name)
@@ -563,9 +562,7 @@ class Siwave(object):
563
562
  >>> success = edbapp.siwave.create_exec_file(add_ac=True, add_syz=True)
564
563
  >>> # Create exec file with Touchstone export
565
564
  >>> success = edbapp.siwave.create_exec_file(
566
- ... add_ac=True,
567
- ... export_touchstone=True,
568
- ... touchstone_file_path="C:/temp/my_touchstone.s2p"
565
+ ... add_ac=True, export_touchstone=True, touchstone_file_path="C:/temp/my_touchstone.s2p"
569
566
  ... )
570
567
  """
571
568
  workdir = os.path.dirname(self._pedb.edbpath)
@@ -644,17 +641,13 @@ class Siwave(object):
644
641
  >>> from pyedb import Edb
645
642
  >>> edbapp = Edb("myaedbfolder", edbversion="2021.2")
646
643
  >>> # Add SYZ analysis with linear sweep from 1kHz to 10GHz
647
- >>> setup = edbapp.siwave.add_siwave_syz_analysis(
648
- ... start_freq=1e3,
649
- ... stop_freq=10e9,
650
- ... distribution="linear"
651
- ... )
644
+ >>> setup = edbapp.siwave.add_siwave_syz_analysis(start_freq=1e3, stop_freq=10e9, distribution="linear")
652
645
  >>> # Add SYZ analysis with decade sweep
653
646
  >>> setup = edbapp.siwave.add_siwave_syz_analysis(
654
647
  ... start_freq=1e3,
655
648
  ... stop_freq=10e9,
656
649
  ... distribution="decade_count",
657
- ... step_freq=10 # 10 points per decade
650
+ ... step_freq=10, # 10 points per decade
658
651
  ... )
659
652
  """
660
653
  setup = self._pedb.create_siwave_syz_setup()